Repository: scionproto/scion
Pull request #3729 (2020-04-24 07:22:30)

rename overlay -> underlay in code
Overlay was a confusing naming to many, because it actually refers to underlay.

Apply this rename everywhere that is not externally breaking.

This is an API breaking change.
Configurations should not be broken.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/scionproto/scion/3729)
<!-- Reviewable:end -->



Patch:
diff --git a/go/border/BUILD.bazel b/go/border/BUILD.bazel
index 862ed8725..f820778ef 100644
--- a/go/border/BUILD.bazel
+++ b/go/border/BUILD.bazel
@@ -30,13 +30,13 @@ go_library(
         "//go/lib/infra/modules/itopo:go_default_library",
         "//go/lib/layers:go_default_library",
         "//go/lib/log:go_default_library",
-        "//go/lib/overlay/conn:go_default_library",
         "//go/lib/prom:go_default_library",
         "//go/lib/ringbuf:go_default_library",
         "//go/lib/scmp:go_default_library",
         "//go/lib/scrypto:go_default_library",
         "//go/lib/serrors:go_default_library",
         "//go/lib/topology:go_default_library",
+        "//go/lib/underlay/conn:go_default_library",
         "//go/proto:go_default_library",
         "@com_github_burntsushi_toml//:go_default_library",
         "@com_github_syndtr_gocapability//capability:go_default_library",
@@ -64,12 +64,12 @@ go_test(
         "//go/border/rpkt:go_default_library",
         "//go/lib/common:go_default_library",
         "//go/lib/log:go_default_library",
-        "//go/lib/overlay/conn:go_default_library",
-        "//go/lib/overlay/conn/mock_conn:go_default_library",
         "//go/lib/prom:go_default_library",
         "//go/lib/ringbuf:go_default_library",
         "//go/lib/serrors:go_default_library",
         "//go/lib/topology:go_default_library",
+        "//go/lib/underlay/conn:go_default_library",
+        "//go/lib/underlay/conn/mock_conn:go_default_library",
         "//go/lib/xtest:go_default_library",
         "@com_github_golang_mock//gomock:go_default_library",
         "@com_github_smartystreets_goconvey//convey:go_default_library",
diff --git a/go/border/io.go b/go/border/io.go
index 16d44e53e..d3a68d61d 100644
--- a/go/border/io.go
+++ b/go/border/io.go
@@ -32,9 +32,9 @@ import (
 	"github.com/scionproto/scion/go/lib/common"
 	"github.com/scionproto/scion/go/lib/fatal"
 	"github.com/scionproto/scion/go/lib/log"
-	"github.com/scionproto/scion/go/lib/overlay/conn"
 	"github.com/scionproto/scion/go/lib/ringbuf"
 	"github.com/scionproto/scion/go/lib/serrors"
+	"github.com/scionproto/scion/go/lib/underlay/conn"
 )
 
 const (
diff --git a/go/border/rctrl/ifstate.go b/go/border/rctrl/ifstate.go
index 1c36a9eb0..e314d4f19 100644
--- a/go/border/rctrl/ifstate.go
+++ b/go/border/rctrl/ifstate.go
@@ -88,7 +88,7 @@ func genIFStateReq() error {
 			errors = append(errors, common.NewBasicError("Writing IFStateReq", err, "dst", dst))
 			continue
 		}
-		logger.Debug("Sent IFStateReq", "dst", dst, "overlayDst", a)
+		logger.Debug("Sent IFStateReq", "dst", dst, "underlayDst", a)
 		cl.Result = metrics.Success
 		metrics.Control.SentIFStateReq(cl).Inc()
 	}
diff --git a/go/border/rctrl/revinfo.go b/go/border/rctrl/revinfo.go
index 2a8b300d6..aa49c1d08 100644
--- a/go/border/rctrl/revinfo.go
+++ b/go/border/rctrl/revinfo.go
@@ -88,5 +88,5 @@ func fwdRevInfo(sRevInfo *path_mgmt.SignedRevInfo, dstHost addr.HostSVC) {
 	}
 	cl.Result = metrics.Success
 	metrics.Control.SentRevInfos(cl).Inc()
-	logger.Debug("Sent RevInfo", "dst", dst, "overlayDst", dst.NextHop)
+	logger.Debug("Sent RevInfo", "dst", dst, "underlayDst", dst.NextHop)
 }
diff --git a/go/border/rctx/BUILD.bazel b/go/border/rctx/BUILD.bazel
index a4a03217b..45f0bae53 100644
--- a/go/border/rctx/BUILD.bazel
+++ b/go/border/rctx/BUILD.bazel
@@ -16,8 +16,8 @@ go_library(
         "//go/lib/assert:go_default_library",
         "//go/lib/common:go_default_library",
         "//go/lib/log:go_default_library",
-        "//go/lib/overlay/conn:go_default_library",
         "//go/lib/ringbuf:go_default_library",
         "//go/lib/scrypto:go_default_library",
+        "//go/lib/underlay/conn:go_default_library",
     ],
 )
diff --git a/go/border/rctx/io.go b/go/border/rctx/io.go
index bcbca233e..fa2e77b09 100644
--- a/go/border/rctx/io.go
+++ b/go/border/rctx/io.go
@@ -23,8 +23,8 @@ import (
 	"github.com/scionproto/scion/go/lib/assert"
 	"github.com/scionproto/scion/go/lib/common"
 	"github.com/scionproto/scion/go/lib/log"
-	"github.com/scionproto/scion/go/lib/overlay/conn"
 	"github.com/scionproto/scion/go/lib/ringbuf"
+	"github.com/scionproto/scion/go/lib/underlay/conn"
 )
 
 // SockFunc is a function that is started as a goroutine by
diff --git a/go/border/rctx/rctx.go b/go/border/rctx/rctx.go
index 0282991e1..33046f247 100644
--- a/go/border/rctx/rctx.go
+++ b/go/border/rctx/rctx.go
@@ -88,13 +88,13 @@ func (ctx *Ctx) ResolveSVC(svc addr.HostSVC) ([]*net.UDPAddr, error) {
 // ResolveSVCAny resolves an anycast SVC address (i.e. a single instance of a local
 // infrastructure service).
 func (ctx *Ctx) ResolveSVCAny(svc addr.HostSVC) (*net.UDPAddr, error) {
-	return ctx.Conf.Topo.OverlayAnycast(svc)
+	return ctx.Conf.Topo.UnderlayAnycast(svc)
 }
 
 // ResolveSVCMulti resolves a multicast SVC address (i.e. one packet per machine hosting
 // instances for a local infrastructure service).
 func (ctx *Ctx) ResolveSVCMulti(svc addr.HostSVC) ([]*net.UDPAddr, error) {
-	return ctx.Conf.Topo.OverlayMulticast(svc)
+	return ctx.Conf.Topo.UnderlayMulticast(svc)
 }
 
 // Get returns a pointer to the current router context.
diff --git a/go/border/rpkt/route.go b/go/border/rpkt/route.go
index 628d10ce1..b711e6e71 100644
--- a/go/border/rpkt/route.go
+++ b/go/border/rpkt/route.go
@@ -81,7 +81,7 @@ func (rp *RtrPkt) RouteResolveSVC() (HookResult, error) {
 		return HookError, err
 	}
 	for _, dst := range addrs {
-		// FIXME(sgmonroy) Choose LocSock based on overlay type for dual-stack support
+		// FIXME(sgmonroy) Choose LocSock based on underlay type for dual-stack support
 		rp.Egress = append(rp.Egress, EgressPair{S: rp.Ctx.LocSockOut, Dst: dst})
 	}
 	return HookContinue, nil
@@ -116,8 +116,8 @@ func (rp *RtrPkt) forwardFromExternal() (HookResult, error) {
 	if onLastSeg && rp.dstIA.Equal(rp.Ctx.Conf.IA) {
 		// Destination is a host in the local ISD-AS.
 		if rp.dstHost.IP() == nil {
-			// Not an IP address, cannot build an overlay with this
-			return HookError, common.NewBasicError("invalid overlay L3 address", nil,
+			// Not an IP address, cannot build an underlay with this
+			return HookError, common.NewBasicError("invalid underlay L3 address", nil,
 				"addr", rp.dstHost)
 		}
 		dst := &net.UDPAddr{
diff --git a/go/border/rpkt/rpkt.go b/go/border/rpkt/rpkt.go
index 2123bd36f..bbc4216a7 100644
--- a/go/border/rpkt/rpkt.go
+++ b/go/border/rpkt/rpkt.go
@@ -70,7 +70,7 @@ type RtrPkt struct {
 	TimeIn time.Time
 	// DirFrom is the direction from which the packet was received. (RECV)
 	DirFrom rcmn.Dir
-	// Ingress contains the incoming overlay metadata the packet arrived with, and the (list of)
+	// Ingress contains the incoming underlay metadata the packet arrived with, and the (list of)
 	// interface(s) it arrived on. (RECV)
 	Ingress addrIFPair
 	// Egress is a list of function & address pairs that determine how and where to the packet will
@@ -154,7 +154,7 @@ func (rp *RtrPkt) Release() {
 	}
 }
 
-// addrIFPair contains the overlay destination/source addresses, as well as the
+// addrIFPair contains the underlay destination/source addresses, as well as the
 // list of associated interface IDs.
 type addrIFPair struct {
 	Dst     *net.UDPAddr
@@ -164,7 +164,7 @@ type addrIFPair struct {
 }
 
 // EgressPair contains the output function to send a packet with, along with an
-// overlay destination address.
+// underlay destination address.
 type EgressPair struct {
 	S   *rctx.Sock
 	Dst *net.UDPAddr
diff --git a/go/border/setup-posix.go b/go/border/setup-posix.go
index af67c34b2..86c17aa10 100644
--- a/go/border/setup-posix.go
+++ b/go/border/setup-posix.go
@@ -23,9 +23,9 @@ import (
 	"github.com/scionproto/scion/go/border/rctx"
 	"github.com/scionproto/scion/go/lib/common"
 	"github.com/scionproto/scion/go/lib/log"
-	"github.com/scionproto/scion/go/lib/overlay/conn"
 	"github.com/scionproto/scion/go/lib/ringbuf"
 	"github.com/scionproto/scion/go/lib/topology"
+	"github.com/scionproto/scion/go/lib/underlay/conn"
 )
 
 const PosixSock brconf.SockType = "posix"
diff --git a/go/cs/beaconing/handler.go b/go/cs/beaconing/handler.go
index 1d65a1c69..7fcd23a75 100644
--- a/go/cs/beaconing/handler.go
+++ b/go/cs/beaconing/handler.go
@@ -202,7 +202,7 @@ func (h *handler) verifySegment(segment *seg.PathSegment) error {
 	svcToQuery := &snet.SVCAddr{
 		IA:      snetPeer.IA,
 		Path:    peerPath.Path(),
-		NextHop: peerPath.OverlayNextHop(),
+		NextHop: peerPath.UnderlayNextHop(),
 		SVC:     addr.SvcBS,
 	}
 	return segverifier.VerifySegment(h.request.Context(), h.verifier, svcToQuery, segment)
diff --git a/go/cs/handlers/segreg.go b/go/cs/handlers/segreg.go
index 4be04adce..68e17c282 100644
--- a/go/cs/handlers/segreg.go
+++ b/go/cs/handlers/segreg.go
@@ -95,7 +95,7 @@ func (h *segRegHandler) Handle() *infra.HandlerResult {
 	svcToQuery := &snet.SVCAddr{
 		IA:      snetPeer.IA,
 		Path:    peerPath.Path(),
-		NextHop: peerPath.OverlayNextHop(),
+		NextHop: peerPath.UnderlayNextHop(),
 		SVC:     addr.SvcBS,
 	}
 	segs := seghandler.Segments{
diff --git a/go/cs/handlers/segsync.go b/go/cs/handlers/segsync.go
index 411dc0eb3..72d2cddc9 100644
--- a/go/cs/handlers/segsync.go
+++ b/go/cs/handlers/segsync.go
@@ -92,7 +92,7 @@ func (h *syncHandler) Handle() *infra.HandlerResult {
 	svcToQuery := &snet.SVCAddr{
 		IA:      snetPeer.IA,
 		Path:    peerPath.Path(),
-		NextHop: peerPath.OverlayNextHop(),
+		NextHop: peerPath.UnderlayNextHop(),
 		SVC:     addr.SvcPS,
 	}
 
diff --git a/go/cs/segutil/router.go b/go/cs/segutil/router.go
index 0924e608e..873d634a4 100644
--- a/go/cs/segutil/router.go
+++ b/go/cs/segutil/router.go
@@ -82,14 +82,14 @@ func (r *Router) translate(comb *combinator.Path, dst addr.IA) (path, error) {
 	if err := sp.InitOffsets(); err != nil {
 		return path{}, err
 	}
-	nextHop, ok := r.Pather.TopoProvider.Get().OverlayNextHop(comb.Interfaces[0].IfID)
+	nextHop, ok := r.Pather.TopoProvider.Get().UnderlayNextHop(comb.Interfaces[0].IfID)
 	if !ok {
 		return path{}, serrors.New("Unable to find first-hop BR for path",
 			"ifid", comb.Interfaces[0].IfID)
 	}
 	p := path{
 		interfaces: make([]pathInterface, 0, len(comb.Interfaces)),
-		overlay:    nextHop,
+		underlay:   nextHop,
 		spath:      sp,
 		mtu:        comb.Mtu,
 		expiry:     comb.ComputeExpTime(),
@@ -102,7 +102,7 @@ func (r *Router) translate(comb *combinator.Path, dst addr.IA) (path, error) {
 
 type path struct {
 	interfaces []pathInterface
-	overlay    *net.UDPAddr
+	underlay   *net.UDPAddr
 	spath      *spath.Path
 	mtu        uint16
 	expiry     time.Time
@@ -121,14 +121,14 @@ func (p path) Fingerprint() snet.PathFingerprint {
 	return snet.PathFingerprint(h.Sum(nil))
 }
 
-func (p path) OverlayNextHop() *net.UDPAddr {
-	if p.overlay == nil {
+func (p path) UnderlayNextHop() *net.UDPAddr {
+	if p.underlay == nil {
 		return nil
 	}
 	return &net.UDPAddr{
-		IP:   append(p.overlay.IP[:0:0], p.overlay.IP...),
-		Port: p.overlay.Port,
-		Zone: p.overlay.Zone,
+		IP:   append(p.underlay.IP[:0:0], p.underlay.IP...),
+		Port: p.underlay.Port,
+		Zone: p.underlay.Zone,
 	}
 }
 
@@ -168,8 +168,8 @@ func (p path) Expiry() time.Time {
 func (p path) Copy() snet.Path {
 	return path{
 		interfaces: append(p.interfaces[:0:0], p.interfaces...),
-		overlay:    p.OverlayNextHop(), // creates copy
-		spath:      p.Path(),           // creates copy
+		underlay:   p.UnderlayNextHop(), // creates copy
+		spath:      p.Path(),            // creates copy
 		mtu:        p.mtu,
 		expiry:     p.expiry,
 	}
@@ -178,7 +178,7 @@ func (p path) Copy() snet.Path {
 func (p path) String() string {
 	hops := p.fmtInterfaces()
 	return fmt.Sprintf("Hops: [%s] MTU: %d, NextHop: %s",
-		strings.Join(hops, ">"), p.mtu, p.overlay)
+		strings.Join(hops, ">"), p.mtu, p.underlay)
 }
 
 func (p path) fmtInterfaces() []string {
diff --git a/go/dispatcher/config/config.go b/go/dispatcher/config/config.go
index 9b227efd7..aa3fda27a 100644
--- a/go/dispatcher/config/config.go
+++ b/go/dispatcher/config/config.go
@@ -46,8 +46,8 @@ type Dispatcher struct {
 	ApplicationSocket string `toml:"application_socket,omitempty"`
 	// Socket file permissions when created; read from octal. (default 0770)
 	SocketFileMode util.FileMode `toml:"socket_file_mode,omitempty"`
-	// OverlayPort is the native port opened by the dispatcher (default 30041)
-	OverlayPort int `toml:"underlay_port,omitempty"`
+	// UnderlayPort is the native port opened by the dispatcher (default 30041)
+	UnderlayPort int `toml:"underlay_port,omitempty"`
 	// DeleteSocket specifies whether the dispatcher should delete the
 	// socket file prior to attempting to create a new one.
 	DeleteSocket bool `toml:"delete_socket,omitempty"`
@@ -63,8 +63,8 @@ func (cfg *Config) Validate() error {
 	if cfg.Dispatcher.SocketFileMode == 0 {
 		cfg.Dispatcher.SocketFileMode = reliable.DefaultDispSocketFileMode
 	}
-	if cfg.Dispatcher.OverlayPort == 0 {
-		cfg.Dispatcher.OverlayPort = topology.EndhostPort
+	if cfg.Dispatcher.UnderlayPort == 0 {
+		cfg.Dispatcher.UnderlayPort = topology.EndhostPort
 	}
 	if cfg.Dispatcher.ID == "" {
 		return serrors.New("id must be set")
diff --git a/go/dispatcher/dispatcher/BUILD.bazel b/go/dispatcher/dispatcher/BUILD.bazel
index 44594ada0..f0eb900f4 100644
--- a/go/dispatcher/dispatcher/BUILD.bazel
+++ b/go/dispatcher/dispatcher/BUILD.bazel
@@ -4,9 +4,9 @@ go_library(
     name = "go_default_library",
     srcs = [
         "dispatcher.go",
-        "overlay.go",
         "scmp.go",
         "table.go",
+        "underlay.go",
     ],
     importpath = "github.com/scionproto/scion/go/dispatcher/dispatcher",
     visibility = ["//visibility:public"],
@@ -20,17 +20,17 @@ go_library(
         "//go/lib/l4:go_default_library",
         "//go/lib/layers:go_default_library",
         "//go/lib/log:go_default_library",
-        "//go/lib/overlay/conn:go_default_library",
         "//go/lib/ringbuf:go_default_library",
         "//go/lib/scmp:go_default_library",
         "//go/lib/serrors:go_default_library",
         "//go/lib/spkt:go_default_library",
+        "//go/lib/underlay/conn:go_default_library",
     ],
 )
 
 go_test(
     name = "go_default_test",
-    srcs = ["overlay_test.go"],
+    srcs = ["underlay_test.go"],
     embed = [":go_default_library"],
     deps = [
         "//go/lib/addr:go_default_library",
diff --git a/go/dispatcher/dispatcher/dispatcher.go b/go/dispatcher/dispatcher/dispatcher.go
index bdfdeb372..c1b01bc91 100644
--- a/go/dispatcher/dispatcher/dispatcher.go
+++ b/go/dispatcher/dispatcher/dispatcher.go
@@ -13,11 +13,11 @@ import (
 	"github.com/scionproto/scion/go/lib/common"
 	"github.com/scionproto/scion/go/lib/hpkt"
 	"github.com/scionproto/scion/go/lib/log"
-	"github.com/scionproto/scion/go/lib/overlay/conn"
 	"github.com/scionproto/scion/go/lib/ringbuf"
 	"github.com/scionproto/scion/go/lib/scmp"
 	"github.com/scionproto/scion/go/lib/serrors"
 	"github.com/scionproto/scion/go/lib/spkt"
+	"github.com/scionproto/scion/go/lib/underlay/conn"
 )
 
 // OverflowLoggingInterval is the minimum amount of time that needs to
@@ -71,7 +71,7 @@ func (as *Server) Serve() error {
 	go func() {
 		defer log.HandlePanic()
 		netToRingDataplane := &NetToRingDataplane{
-			OverlayConn:  as.ipv4Conn,
+			UnderlayConn: as.ipv4Conn,
 			RoutingTable: as.routingTable,
 		}
 		errChan <- netToRingDataplane.Run()
@@ -79,7 +79,7 @@ func (as *Server) Serve() error {
 	go func() {
 		defer log.HandlePanic()
 		netToRingDataplane := &NetToRingDataplane{
-			OverlayConn:  as.ipv6Conn,
+			UnderlayConn: as.ipv6Conn,
 			RoutingTable: as.routingTable,
 		}
 		errChan <- netToRingDataplane.Run()
@@ -139,7 +139,7 @@ func (ac *Conn) Write(pkt *respool.Packet) (int, error) {
 	if err := registerIfSCMPRequest(ac.regReference, &pkt.Info); err != nil {
 		log.Warn("SCMP Request ID error, packet still sent", "err", err)
 	}
-	return pkt.SendOnConn(ac.conn, pkt.OverlayRemote)
+	return pkt.SendOnConn(ac.conn, pkt.UnderlayRemote)
 }
 
 func (ac *Conn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
@@ -148,7 +148,7 @@ func (ac *Conn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
 		return 0, nil, serrors.New("Connection closed")
 	}
 	n = pkt.CopyTo(p)
-	addr = pkt.OverlayRemote
+	addr = pkt.UnderlayRemote
 	pkt.Free()
 	return
 }
@@ -191,7 +191,7 @@ func (ac *Conn) SetWriteDeadline(t time.Time) error {
 	panic("not implemented")
 }
 
-// openConn opens an overlay socket that tracks additional socket information
+// openConn opens an underlay socket that tracks additional socket information
 // such as packets dropped due to buffer full.
 //
 // Note that Go-style dual-stacked IPv4/IPv6 connections are not supported. If
@@ -219,7 +219,7 @@ func openConn(network, address string, p SocketMetaHandler) (net.PacketConn, err
 		return nil, common.NewBasicError("unable to open conn", err)
 	}
 
-	return &overlayConnWrapper{Conn: c, Handler: p}, nil
+	return &underlayConnWrapper{Conn: c, Handler: p}, nil
 }
 
 // registerIfSCMPRequest registers the ID of the SCMP Request, if it is an
@@ -243,17 +243,17 @@ func registerIfSCMPRequest(ref registration.RegReference, packet *spkt.ScnPkt) e
 	return nil
 }
 
-// overlayConnWrapper wraps a specialized overlay conn into a net.PacketConn
+// underlayConnWrapper wraps a specialized underlay conn into a net.PacketConn
 // implementation. Only *net.UDPAddr addressing is supported.
-type overlayConnWrapper struct {
-	// Conn is the wrapped overlay connection object.
+type underlayConnWrapper struct {
+	// Conn is the wrapped underlay connection object.
 	conn.Conn
 	// Handler is used to customize how the connection treats socket
 	// metadata.
 	Handler SocketMetaHandler
 }
 
-func (o *overlayConnWrapper) ReadFrom(p []byte) (int, net.Addr, error) {
+func (o *underlayConnWrapper) ReadFrom(p []byte) (int, net.Addr, error) {
 	n, meta, err := o.Conn.Read(common.RawBytes(p))
 	if meta == nil {
 		return n, nil, err
@@ -262,7 +262,7 @@ func (o *overlayConnWrapper) ReadFrom(p []byte) (int, net.Addr, error) {
 	return n, meta.Src, err
 }
 
-func (o *overlayConnWrapper) WriteTo(p []byte, a net.Addr) (int, error) {
+func (o *underlayConnWrapper) WriteTo(p []byte, a net.Addr) (int, error) {
 	udpAddr, ok := a.(*net.UDPAddr)
 	if !ok {
 		return 0, common.NewBasicError("address is not UDP", nil, "addr", a)
@@ -270,23 +270,23 @@ func (o *overlayConnWrapper) WriteTo(p []byte, a net.Addr) (int, error) {
 	return o.Conn.WriteTo(common.RawBytes(p), udpAddr)
 }
 
-func (o *overlayConnWrapper) Close() error {
+func (o *underlayConnWrapper) Close() error {
 	return o.Conn.Close()
 }
 
-func (o *overlayConnWrapper) LocalAddr() net.Addr {
+func (o *underlayConnWrapper) LocalAddr() net.Addr {
 	return o.Conn.LocalAddr()
 }
 
-func (o *overlayConnWrapper) SetDeadline(t time.Time) error {
+func (o *underlayConnWrapper) SetDeadline(t time.Time) error {
 	return o.Conn.SetDeadline(t)
 }
 
-func (o *overlayConnWrapper) SetReadDeadline(t time.Time) error {
+func (o *underlayConnWrapper) SetReadDeadline(t time.Time) error {
 	return o.Conn.SetReadDeadline(t)
 }
 
-func (o *overlayConnWrapper) SetWriteDeadline(t time.Time) error {
+func (o *underlayConnWrapper) SetWriteDeadline(t time.Time) error {
 	return o.Conn.SetWriteDeadline(t)
 }
 
diff --git a/go/dispatcher/dispatcher/overlay.go b/go/dispatcher/dispatcher/underlay.go
similarity index 94%
rename from go/dispatcher/dispatcher/overlay.go
rename to go/dispatcher/dispatcher/underlay.go
index 252026d00..cca6e541a 100644
--- a/go/dispatcher/dispatcher/overlay.go
+++ b/go/dispatcher/dispatcher/underlay.go
@@ -38,13 +38,13 @@ const (
 	ErrMalformedL4Quote           common.ErrMsg = "malformed L4 quote"
 )
 
-// NetToRingDataplane reads SCION packets from the overlay socket, routes them
+// NetToRingDataplane reads SCION packets from the underlay socket, routes them
 // to determine the destination process, and then enqueues the packets on the
 // application's ingress ring.
 //
-// The rings are used to provide non-blocking IO for the overlay receiver.
+// The rings are used to provide non-blocking IO for the underlay receiver.
 type NetToRingDataplane struct {
-	OverlayConn  net.PacketConn
+	UnderlayConn net.PacketConn
 	RoutingTable *IATable
 }
 
@@ -55,8 +55,8 @@ func (dp *NetToRingDataplane) Run() error {
 		// let the GC take care of this situation as they should be fairly
 		// rare.
 
-		if err := pkt.DecodeFromConn(dp.OverlayConn); err != nil {
-			log.Warn("error receiving next packet from overlay conn", "err", err)
+		if err := pkt.DecodeFromConn(dp.UnderlayConn); err != nil {
+			log.Warn("error receiving next packet from underlay conn", "err", err)
 			continue
 		}
 
@@ -183,7 +183,7 @@ type SVCDestination addr.HostSVC
 
 func (d SVCDestination) Send(dp *NetToRingDataplane, pkt *respool.Packet) {
 	// FIXME(scrye): This should deliver to the correct IP address, based on
-	// information found in the overlay IP header.
+	// information found in the underlay IP header.
 	routingEntries := dp.RoutingTable.LookupService(pkt.Info.DstIA, addr.HostSVC(d), nil)
 	if len(routingEntries) == 0 {
 		metrics.M.AppNotFoundErrors().Inc()
@@ -256,9 +256,9 @@ func (h SCMPHandlerDestination) Send(dp *NetToRingDataplane, pkt *respool.Packet
 		).Inc()
 	}
 
-	_, err = dp.OverlayConn.WriteTo(b[:n], pkt.OverlayRemote)
+	_, err = dp.UnderlayConn.WriteTo(b[:n], pkt.UnderlayRemote)
 	if err != nil {
-		log.Warn("Unable to write to overlay socket.", "err", err)
+		log.Warn("Unable to write to underlay socket.", "err", err)
 		return
 	}
 	respool.PutBuffer(b)
diff --git a/go/dispatcher/dispatcher/overlay_test.go b/go/dispatcher/dispatcher/underlay_test.go
similarity index 100%
rename from go/dispatcher/dispatcher/overlay_test.go
rename to go/dispatcher/dispatcher/underlay_test.go
diff --git a/go/dispatcher/internal/registration/svctable.go b/go/dispatcher/internal/registration/svctable.go
index 8c9863181..566cb44bb 100644
--- a/go/dispatcher/internal/registration/svctable.go
+++ b/go/dispatcher/internal/registration/svctable.go
@@ -180,7 +180,7 @@ func (t *svcTable) anycast(svc addr.HostSVC, ip net.IP) (interface{}, bool) {
 	if !ok {
 		return nil, false
 	}
-	// XXX(scrye): This is a workaround s.t. a simple overlay socket
+	// XXX(scrye): This is a workaround s.t. a simple underlay socket
 	// that does not return IP-header information can still be used to
 	// deliver to SVC addresses. Once IP-header information is passed
 	// into the app, searching for nil should not return an entry.
diff --git a/go/dispatcher/internal/respool/packet.go b/go/dispatcher/internal/respool/packet.go
index a5b0b1c89..e159d748c 100644
--- a/go/dispatcher/internal/respool/packet.go
+++ b/go/dispatcher/internal/respool/packet.go
@@ -41,8 +41,8 @@ func GetPacket() *Packet {
 // (including hidden fields), so callers should only write to freshly created
 // packets, and readers should take care never to mutate data.
 type Packet struct {
-	Info          spkt.ScnPkt
-	OverlayRemote *net.UDPAddr
+	Info           spkt.ScnPkt
+	UnderlayRemote *net.UDPAddr
 
 	// buffer contains the raw slice that other fields reference
 	buffer common.RawBytes
@@ -113,7 +113,7 @@ func (pkt *Packet) DecodeFromConn(conn net.PacketConn) error {
 	pkt.buffer = pkt.buffer[:n]
 	metrics.M.NetReadBytes().Add(float64(n))
 
-	pkt.OverlayRemote = readExtra.(*net.UDPAddr)
+	pkt.UnderlayRemote = readExtra.(*net.UDPAddr)
 	if err = hpkt.ParseScnPkt(&pkt.Info, pkt.buffer); err != nil {
 		metrics.M.NetReadPkts(
 			metrics.IncomingPacket{
@@ -135,7 +135,7 @@ func (pkt *Packet) DecodeFromReliableConn(conn net.PacketConn) error {
 	if readExtra == nil {
 		return serrors.New("missing next-hop")
 	}
-	pkt.OverlayRemote = readExtra.(*net.UDPAddr)
+	pkt.UnderlayRemote = readExtra.(*net.UDPAddr)
 
 	// XXX(scrye): We ignore the return value of packet parsing on egress
 	// because some tests (e.g., the Python SCMP error test) rely on being able
@@ -153,5 +153,5 @@ func (pkt *Packet) SendOnConn(conn net.PacketConn, address net.Addr) (int, error
 func (pkt *Packet) reset() {
 	pkt.buffer = pkt.buffer[:cap(pkt.buffer)]
 	pkt.Info = spkt.ScnPkt{}
-	pkt.OverlayRemote = nil
+	pkt.UnderlayRemote = nil
 }
diff --git a/go/dispatcher/main.go b/go/dispatcher/main.go
index e29fffe09..9a84e9d2f 100644
--- a/go/dispatcher/main.go
+++ b/go/dispatcher/main.go
@@ -80,7 +80,7 @@ func realMain() int {
 			cfg.Dispatcher.DeleteSocket,
 			cfg.Dispatcher.ApplicationSocket,
 			os.FileMode(cfg.Dispatcher.SocketFileMode),
-			cfg.Dispatcher.OverlayPort,
+			cfg.Dispatcher.UnderlayPort,
 		)
 		if err != nil {
 			fatal.Fatal(err)
@@ -128,7 +128,7 @@ func setupBasic() error {
 }
 
 func RunDispatcher(deleteSocketFlag bool, applicationSocket string, socketFileMode os.FileMode,
-	overlayPort int) error {
+	underlayPort int) error {
 
 	if deleteSocketFlag {
 		if err := deleteSocket(cfg.Dispatcher.ApplicationSocket); err != nil {
@@ -136,11 +136,11 @@ func RunDispatcher(deleteSocketFlag bool, applicationSocket string, socketFileMo
 		}
 	}
 	dispatcher := &network.Dispatcher{
-		OverlaySocket:     fmt.Sprintf(":%d", overlayPort),
+		UnderlaySocket:    fmt.Sprintf(":%d", underlayPort),
 		ApplicationSocket: applicationSocket,
 		SocketFileMode:    socketFileMode,
 	}
-	log.Debug("Dispatcher starting", "appSocket", applicationSocket, "overlayPort", overlayPort)
+	log.Debug("Dispatcher starting", "appSocket", applicationSocket, "underlayPort", underlayPort)
 	return dispatcher.ListenAndServe()
 }
 
diff --git a/go/dispatcher/network/app_socket.go b/go/dispatcher/network/app_socket.go
index 7fa68b71b..3375b590e 100644
--- a/go/dispatcher/network/app_socket.go
+++ b/go/dispatcher/network/app_socket.go
@@ -160,7 +160,7 @@ func (h *AppConnHandler) sendConfirmation(b common.RawBytes, c *reliable.Confirm
 }
 
 // RunAppToNetDataplane moves packets from the application's socket to the
-// overlay socket.
+// underlay socket.
 func (h *AppConnHandler) RunAppToNetDataplane() {
 
 	for {
@@ -184,7 +184,7 @@ func (h *AppConnHandler) RunAppToNetDataplane() {
 		n, err := h.DispConn.Write(pkt)
 		if err != nil {
 			metrics.M.NetWriteErrors().Inc()
-			h.Logger.Error("[app->network] Overlay socket error", "err", err)
+			h.Logger.Error("[app->network] Underlay socket error", "err", err)
 		} else {
 			metrics.M.NetWriteBytes().Add(float64(n))
 			metrics.M.NetWritePkts().Inc()
@@ -202,7 +202,7 @@ func (h *AppConnHandler) RunRingToAppDataplane() {
 			// Ring was closed because app shut down its data socket
 			return
 		}
-		n, err := pkt.SendOnConn(h.Conn, pkt.OverlayRemote)
+		n, err := pkt.SendOnConn(h.Conn, pkt.UnderlayRemote)
 		if err != nil {
 			metrics.M.AppWriteErrors().Inc()
 			h.Logger.Error("[network->app] App connection error.", "err", err)
diff --git a/go/dispatcher/network/dispatcher.go b/go/dispatcher/network/dispatcher.go
index 46197c4d3..cb8ec3452 100644
--- a/go/dispatcher/network/dispatcher.go
+++ b/go/dispatcher/network/dispatcher.go
@@ -24,13 +24,13 @@ import (
 )
 
 type Dispatcher struct {
-	OverlaySocket     string
+	UnderlaySocket    string
 	ApplicationSocket string
 	SocketFileMode    os.FileMode
 }
 
 func (d *Dispatcher) ListenAndServe() error {
-	dispServer, err := dispatcher.NewServer(d.OverlaySocket, nil, nil)
+	dispServer, err := dispatcher.NewServer(d.UnderlaySocket, nil, nil)
 	if err != nil {
 		return err
 	}
diff --git a/go/examples/pingpong/pingpong.go b/go/examples/pingpong/pingpong.go
index e2af5f625..81339673a 100644
--- a/go/examples/pingpong/pingpong.go
+++ b/go/examples/pingpong/pingpong.go
@@ -273,7 +273,7 @@ func (c client) setupPath() {
 			LogFatal("No paths available to remote destination")
 		}
 		remote.Path = path.Path()
-		remote.NextHop = path.OverlayNextHop()
+		remote.NextHop = path.UnderlayNextHop()
 	}
 }
 
diff --git a/go/integration/cert_req/main.go b/go/integration/cert_req/main.go
index ac1300610..71c756e08 100644
--- a/go/integration/cert_req/main.go
+++ b/go/integration/cert_req/main.go
@@ -235,5 +235,5 @@ func getRemote() error {
 func getSVCAddress() (*net.UDPAddr, error) {
 	ctx, cancelF := context.WithTimeout(context.Background(), integration.DefaultIOTimeout)
 	defer cancelF()
-	return sciond.TopoQuerier{Connector: integration.SDConn()}.OverlayAnycast(ctx, addr.SvcCS)
+	return sciond.TopoQuerier{Connector: integration.SDConn()}.UnderlayAnycast(ctx, addr.SvcCS)
 }
diff --git a/go/integration/end2end/main.go b/go/integration/end2end/main.go
index 6dbfa4bea..c6eed3b9f 100644
--- a/go/integration/end2end/main.go
+++ b/go/integration/end2end/main.go
@@ -264,7 +264,7 @@ func (c client) getRemote(ctx context.Context, n int) error {
 	path := paths[0]
 	// Extract forwarding path from sciond response
 	remote.Path = path.Path()
-	remote.NextHop = path.OverlayNextHop()
+	remote.NextHop = path.UnderlayNextHop()
 	return nil
 }
 
diff --git a/go/lib/hostinfo/hostinfo.go b/go/lib/hostinfo/hostinfo.go
index 9818d33f8..a7c1b7f96 100644
--- a/go/lib/hostinfo/hostinfo.go
+++ b/go/lib/hostinfo/hostinfo.go
@@ -87,7 +87,7 @@ func (h *Host) UDP() *net.UDPAddr {
 	return nil
 }
 
-func (h *Host) Overlay() *net.UDPAddr {
+func (h *Host) Underlay() *net.UDPAddr {
 	return &net.UDPAddr{IP: h.Host().IP(), Port: int(h.Port)}
 }
 
diff --git a/go/lib/infra/infraenv/infraenv.go b/go/lib/infra/infraenv/infraenv.go
index b63d45f09..95cb3bf74 100644
--- a/go/lib/infra/infraenv/infraenv.go
+++ b/go/lib/infra/infraenv/infraenv.go
@@ -78,7 +78,7 @@ type NetworkConfig struct {
 	// Router is used by various infra modules for path-related operations. A
 	// nil router means only intra-AS traffic is supported.
 	Router snet.Router
-	// SVCRouter is used to discover the overlay addresses of intra-AS SVC
+	// SVCRouter is used to discover the underlay addresses of intra-AS SVC
 	// servers.
 	SVCRouter messenger.LocalSVCRouter
 }
diff --git a/go/lib/infra/messenger/addr.go b/go/lib/infra/messenger/addr.go
index 6e63040a0..aff35551b 100644
--- a/go/lib/infra/messenger/addr.go
+++ b/go/lib/infra/messenger/addr.go
@@ -42,7 +42,7 @@ type AddressRewriter struct {
 	// Router obtains path information to fill in address paths, if they are
 	// required and missing.
 	Router snet.Router
-	// SVCRouter builds overlay addresses for intra-AS SVC traffic, based on
+	// SVCRouter builds underlay addresses for intra-AS SVC traffic, based on
 	// information found in the topology.
 	SVCRouter LocalSVCRouter
 	// Resolver performs SVC resolution if enabled.
@@ -133,7 +133,7 @@ func (r AddressRewriter) buildFullAddress(ctx context.Context,
 			NextHop: snet.CopyUDPAddr(s.NextHop),
 			SVC:     s.SVC,
 		}
-		log.Trace("[Acceptance]", "overlay", ret.NextHop)
+		log.Trace("[Acceptance]", "underlay", ret.NextHop)
 		return ret, nil
 	}
 
@@ -144,16 +144,16 @@ func (r AddressRewriter) buildFullAddress(ctx context.Context,
 	}
 
 	ret.Path = p.Path()
-	ret.NextHop = p.OverlayNextHop()
+	ret.NextHop = p.UnderlayNextHop()
 	defer func() {
-		log.Trace("[Acceptance]", "overlay", ret.NextHop)
+		log.Trace("[Acceptance]", "underlay", ret.NextHop)
 	}()
 
 	// SVC addresses in the local AS get resolved via topology lookup
 	if p.Fingerprint() == "" { //when local AS
-		ov, err := r.SVCRouter.GetOverlay(s.SVC)
+		ov, err := r.SVCRouter.GetUnderlay(s.SVC)
 		if err != nil {
-			return nil, common.NewBasicError("Unable to resolve overlay", err)
+			return nil, common.NewBasicError("Unable to resolve underlay", err)
 		}
 		ret.NextHop = ov
 	}
@@ -221,12 +221,12 @@ func parseReply(reply *svc.Reply) (*net.UDPAddr, error) {
 	return net.ResolveUDPAddr("udp", addressStr)
 }
 
-// LocalSVCRouter is used to construct overlay information for SVC servers
+// LocalSVCRouter is used to construct underlay information for SVC servers
 // running in the local AS.
 type LocalSVCRouter interface {
-	// GetOverlay returns the overlay address of a SVC server of the specified
+	// GetUnderlay returns the underlay address of a SVC server of the specified
 	// type. When multiple servers are available, the choice is random.
-	GetOverlay(svc addr.HostSVC) (*net.UDPAddr, error)
+	GetUnderlay(svc addr.HostSVC) (*net.UDPAddr, error)
 }
 
 // NewSVCRouter build a SVC router backed by topology information from the
@@ -241,6 +241,6 @@ type baseSVCRouter struct {
 	topology topology.Provider
 }
 
-func (r *baseSVCRouter) GetOverlay(svc addr.HostSVC) (*net.UDPAddr, error) {
-	return r.topology.Get().OverlayAnycast(svc)
+func (r *baseSVCRouter) GetUnderlay(svc addr.HostSVC) (*net.UDPAddr, error) {
+	return r.topology.Get().UnderlayAnycast(svc)
 }
diff --git a/go/lib/infra/messenger/mock_messenger/messenger.go b/go/lib/infra/messenger/mock_messenger/messenger.go
index 5f50d4701..a49c88441 100644
--- a/go/lib/infra/messenger/mock_messenger/messenger.go
+++ b/go/lib/infra/messenger/mock_messenger/messenger.go
@@ -37,19 +37,19 @@ func (m *MockLocalSVCRouter) EXPECT() *MockLocalSVCRouterMockRecorder {
 	return m.recorder
 }
 
-// GetOverlay mocks base method
-func (m *MockLocalSVCRouter) GetOverlay(arg0 addr.HostSVC) (*net.UDPAddr, error) {
+// GetUnderlay mocks base method
+func (m *MockLocalSVCRouter) GetUnderlay(arg0 addr.HostSVC) (*net.UDPAddr, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetOverlay", arg0)
+	ret := m.ctrl.Call(m, "GetUnderlay", arg0)
 	ret0, _ := ret[0].(*net.UDPAddr)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
-// GetOverlay indicates an expected call of GetOverlay
-func (mr *MockLocalSVCRouterMockRecorder) GetOverlay(arg0 interface{}) *gomock.Call {
+// GetUnderlay indicates an expected call of GetUnderlay
+func (mr *MockLocalSVCRouterMockRecorder) GetUnderlay(arg0 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOverlay", reflect.TypeOf((*MockLocalSVCRouter)(nil).GetOverlay), arg0)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUnderlay", reflect.TypeOf((*MockLocalSVCRouter)(nil).GetUnderlay), arg0)
 }
 
 // MockResolver is a mock of Resolver interface
diff --git a/go/lib/infra/modules/trust/router.go b/go/lib/infra/modules/trust/router.go
index 5c1484285..9233c2dc5 100644
--- a/go/lib/infra/modules/trust/router.go
+++ b/go/lib/infra/modules/trust/router.go
@@ -76,7 +76,7 @@ func (r AuthRouter) ChooseServer(ctx context.Context, subjectISD addr.ISD) (net.
 	ret := &snet.SVCAddr{
 		IA:      path.Destination(),
 		Path:    path.Path(),
-		NextHop: path.OverlayNextHop(),
+		NextHop: path.UnderlayNextHop(),
 		SVC:     addr.SvcCS,
 	}
 	return ret, nil
diff --git a/go/lib/sciond/apitypes.go b/go/lib/sciond/apitypes.go
index 3fb3d068f..7f2c8aa32 100644
--- a/go/lib/sciond/apitypes.go
+++ b/go/lib/sciond/apitypes.go
@@ -59,8 +59,8 @@ type TopoQuerier struct {
 	Connector Connector
 }
 
-// OverlayAnycast provides any address for the given svc type.
-func (h TopoQuerier) OverlayAnycast(ctx context.Context, svc addr.HostSVC) (*net.UDPAddr, error) {
+// UnderlayAnycast provides any address for the given svc type.
+func (h TopoQuerier) UnderlayAnycast(ctx context.Context, svc addr.HostSVC) (*net.UDPAddr, error) {
 	psvc := svcAddrToProto(svc)
 	if psvc == proto.ServiceType_unset {
 		return nil, serrors.New("invalid svc type", "svc", svc)
@@ -99,7 +99,7 @@ func ifinfoReplyToMap(ifinfoReply *IFInfoReply) map[common.IFIDType]*net.UDPAddr
 
 type Path struct {
 	interfaces []pathInterface
-	overlay    *net.UDPAddr
+	underlay   *net.UDPAddr
 	spath      *spath.Path
 	mtu        uint16
 	expiry     time.Time
@@ -131,10 +131,10 @@ func pathReplyEntryToPath(pe PathReplyEntry, dst addr.IA) (Path, error) {
 	if err := sp.InitOffsets(); err != nil {
 		return Path{}, serrors.WrapStr("path error", err)
 	}
-	overlayAddr := pe.HostInfo.Overlay()
+	underlayAddr := pe.HostInfo.Underlay()
 	p := Path{
 		interfaces: make([]pathInterface, 0, len(pe.Path.Interfaces)),
-		overlay:    overlayAddr,
+		underlay:   underlayAddr,
 		spath:      sp,
 		mtu:        pe.Path.Mtu,
 		expiry:     pe.Path.Expiry(),
@@ -157,14 +157,14 @@ func (p Path) Fingerprint() snet.PathFingerprint {
 	return snet.PathFingerprint(h.Sum(nil))
 }
 
-func (p Path) OverlayNextHop() *net.UDPAddr {
-	if p.overlay == nil {
+func (p Path) UnderlayNextHop() *net.UDPAddr {
+	if p.underlay == nil {
 		return nil
 	}
 	return &net.UDPAddr{
-		IP:   append(p.overlay.IP[:0:0], p.overlay.IP...),
-		Port: p.overlay.Port,
-		Zone: p.overlay.Zone,
+		IP:   append(p.underlay.IP[:0:0], p.underlay.IP...),
+		Port: p.underlay.Port,
+		Zone: p.underlay.Zone,
 	}
 }
 
@@ -204,8 +204,8 @@ func (p Path) Expiry() time.Time {
 func (p Path) Copy() snet.Path {
 	return Path{
 		interfaces: append(p.interfaces[:0:0], p.interfaces...),
-		overlay:    p.OverlayNextHop(), // creates copy
-		spath:      p.Path(),           // creates copy
+		underlay:   p.UnderlayNextHop(), // creates copy
+		spath:      p.Path(),            // creates copy
 		mtu:        p.mtu,
 		expiry:     p.expiry,
 	}
@@ -214,7 +214,7 @@ func (p Path) Copy() snet.Path {
 func (p Path) String() string {
 	hops := p.fmtInterfaces()
 	return fmt.Sprintf("Hops: [%s] MTU: %d, NextHop: %s",
-		strings.Join(hops, ">"), p.mtu, p.overlay)
+		strings.Join(hops, ">"), p.mtu, p.underlay)
 }
 
 func (p Path) fmtInterfaces() []string {
diff --git a/go/lib/sciond/fake/fake.go b/go/lib/sciond/fake/fake.go
index 4d729b25c..72892a780 100644
--- a/go/lib/sciond/fake/fake.go
+++ b/go/lib/sciond/fake/fake.go
@@ -86,7 +86,7 @@ func (p Path) Fingerprint() snet.PathFingerprint {
 	return snet.PathFingerprint(p.JSONFingerprint)
 }
 
-func (p Path) OverlayNextHop() *net.UDPAddr {
+func (p Path) UnderlayNextHop() *net.UDPAddr {
 	return (*net.UDPAddr)(p.JSONNextHop)
 }
 
diff --git a/go/lib/sciond/pathprobe/paths.go b/go/lib/sciond/pathprobe/paths.go
index f869bbfcc..5ec4b27e0 100644
--- a/go/lib/sciond/pathprobe/paths.go
+++ b/go/lib/sciond/pathprobe/paths.go
@@ -148,7 +148,7 @@ func (p Prober) send(scionConn *snet.Conn, path snet.Path) error {
 	addr := &snet.SVCAddr{
 		IA:      p.DstIA,
 		Path:    path.Path(),
-		NextHop: path.OverlayNextHop(),
+		NextHop: path.UnderlayNextHop(),
 		SVC:     addr.SvcNone,
 	}
 	log.Debug("Sending test packet.", "path", fmt.Sprintf("%s", path))
diff --git a/go/lib/snet/BUILD.bazel b/go/lib/snet/BUILD.bazel
index 37b2f501a..686a452a4 100644
--- a/go/lib/snet/BUILD.bazel
+++ b/go/lib/snet/BUILD.bazel
@@ -31,7 +31,7 @@ go_library(
         "//go/lib/sock/reliable:go_default_library",
         "//go/lib/spath:go_default_library",
         "//go/lib/spkt:go_default_library",
-        "//go/lib/topology/overlay:go_default_library",
+        "//go/lib/topology/underlay:go_default_library",
     ],
 )
 
diff --git a/go/lib/snet/addrutil/addrutil.go b/go/lib/snet/addrutil/addrutil.go
index 42c5a902f..5ad3c7873 100644
--- a/go/lib/snet/addrutil/addrutil.go
+++ b/go/lib/snet/addrutil/addrutil.go
@@ -45,11 +45,11 @@ func GetPath(svc addr.HostSVC, ps *seg.PathSegment, topoProv topology.Provider)
 	}
 	topo := topoProv.Get()
 	ifID := hopF.ConsIngress
-	overlayNextHop, ok := topo.OverlayNextHop2(ifID)
+	UnderlayNextHop, ok := topo.UnderlayNextHop2(ifID)
 	if !ok {
 		return nil, common.NewBasicError("unable to find first-hop BR for path", nil, "ifID", ifID)
 	}
-	return &snet.SVCAddr{IA: ps.FirstIA(), Path: p, NextHop: overlayNextHop, SVC: svc}, nil
+	return &snet.SVCAddr{IA: ps.FirstIA(), Path: p, NextHop: UnderlayNextHop, SVC: svc}, nil
 }
 
 // ResolveLocal returns the local IP address used for traffic destined to dst.
diff --git a/go/lib/snet/mock_snet/snet.go b/go/lib/snet/mock_snet/snet.go
index 380ffb7f6..174cdb73a 100644
--- a/go/lib/snet/mock_snet/snet.go
+++ b/go/lib/snet/mock_snet/snet.go
@@ -503,20 +503,6 @@ func (mr *MockPathMockRecorder) MTU() *gomock.Call {
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MTU", reflect.TypeOf((*MockPath)(nil).MTU))
 }
 
-// OverlayNextHop mocks base method
-func (m *MockPath) OverlayNextHop() *net.UDPAddr {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "OverlayNextHop")
-	ret0, _ := ret[0].(*net.UDPAddr)
-	return ret0
-}
-
-// OverlayNextHop indicates an expected call of OverlayNextHop
-func (mr *MockPathMockRecorder) OverlayNextHop() *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OverlayNextHop", reflect.TypeOf((*MockPath)(nil).OverlayNextHop))
-}
-
 // Path mocks base method
 func (m *MockPath) Path() *spath.Path {
 	m.ctrl.T.Helper()
@@ -531,6 +517,20 @@ func (mr *MockPathMockRecorder) Path() *gomock.Call {
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Path", reflect.TypeOf((*MockPath)(nil).Path))
 }
 
+// UnderlayNextHop mocks base method
+func (m *MockPath) UnderlayNextHop() *net.UDPAddr {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UnderlayNextHop")
+	ret0, _ := ret[0].(*net.UDPAddr)
+	return ret0
+}
+
+// UnderlayNextHop indicates an expected call of UnderlayNextHop
+func (mr *MockPathMockRecorder) UnderlayNextHop() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnderlayNextHop", reflect.TypeOf((*MockPath)(nil).UnderlayNextHop))
+}
+
 // MockPathQuerier is a mock of PathQuerier interface
 type MockPathQuerier struct {
 	ctrl     *gomock.Controller
diff --git a/go/lib/snet/path.go b/go/lib/snet/path.go
index bfd78cf71..1ca1b4c6f 100644
--- a/go/lib/snet/path.go
+++ b/go/lib/snet/path.go
@@ -42,9 +42,9 @@ type Path interface {
 	// ASes and BRs. Other metadata, such as MTU or NextHop have no effect
 	// on the fingerprint. Empty string means unknown fingerprint.
 	Fingerprint() PathFingerprint
-	// OverlayNextHop returns the address:port pair of a local-AS overlay
+	// UnderlayNextHop returns the address:port pair of a local-AS underlay
 	// speaker. Usually, this is a border router that will forward the traffic.
-	OverlayNextHop() *net.UDPAddr
+	UnderlayNextHop() *net.UDPAddr
 	// Path returns a raw (data-plane compatible) representation of the path.
 	// The returned path is initialized and ready for use in snet calls that
 	// deal with raw paths.
@@ -79,7 +79,7 @@ type PathInterface interface {
 // objects, notably snet.UDPAddr and snet.SVCAddr.
 type partialPath struct {
 	spath       *spath.Path
-	overlay     *net.UDPAddr
+	underlay    *net.UDPAddr
 	destination addr.IA
 }
 
@@ -87,8 +87,8 @@ func (p *partialPath) Fingerprint() PathFingerprint {
 	return ""
 }
 
-func (p *partialPath) OverlayNextHop() *net.UDPAddr {
-	return p.overlay
+func (p *partialPath) UnderlayNextHop() *net.UDPAddr {
+	return p.underlay
 }
 
 func (p *partialPath) Path() *spath.Path {
@@ -120,7 +120,7 @@ func (p *partialPath) Copy() Path {
 	}
 	return &partialPath{
 		spath:       p.spath.Copy(),
-		overlay:     CopyUDPAddr(p.overlay),
+		underlay:    CopyUDPAddr(p.underlay),
 		destination: p.destination,
 	}
 }
diff --git a/go/lib/snet/svcaddr.go b/go/lib/snet/svcaddr.go
index ec03f202b..0fc67fa7e 100644
--- a/go/lib/snet/svcaddr.go
+++ b/go/lib/snet/svcaddr.go
@@ -52,7 +52,7 @@ func (a *SVCAddr) GetPath() (Path, error) {
 	}
 	return &partialPath{
 		spath:       p,
-		overlay:     a.NextHop,
+		underlay:    a.NextHop,
 		destination: a.IA,
 	}, nil
 }
diff --git a/go/lib/snet/udpaddr.go b/go/lib/snet/udpaddr.go
index 115399d11..379601191 100644
--- a/go/lib/snet/udpaddr.go
+++ b/go/lib/snet/udpaddr.go
@@ -102,7 +102,7 @@ func (a *UDPAddr) GetPath() (Path, error) {
 	}
 	return &partialPath{
 		spath:       p,
-		overlay:     a.NextHop,
+		underlay:    a.NextHop,
 		destination: a.IA,
 	}, nil
 }
diff --git a/go/lib/snet/writer.go b/go/lib/snet/writer.go
index a6b15dc59..7d8ac4e18 100644
--- a/go/lib/snet/writer.go
+++ b/go/lib/snet/writer.go
@@ -25,7 +25,7 @@ import (
 	"github.com/scionproto/scion/go/lib/common"
 	"github.com/scionproto/scion/go/lib/l4"
 	"github.com/scionproto/scion/go/lib/spath"
-	"github.com/scionproto/scion/go/lib/topology/overlay"
+	"github.com/scionproto/scion/go/lib/topology/underlay"
 )
 
 type scionConnWriter struct {
@@ -65,7 +65,7 @@ func (c *scionConnWriter) WriteTo(b []byte, raddr net.Addr) (int, error) {
 		if nextHop == nil && c.base.scionNet.localIA.Equal(a.IA) {
 			nextHop = &net.UDPAddr{
 				IP:   a.Host.IP,
-				Port: overlay.EndhostPort,
+				Port: underlay.EndhostPort,
 				Zone: a.Host.Zone,
 			}
 
diff --git a/go/lib/sock/reliable/frame.go b/go/lib/sock/reliable/frame.go
index f316354aa..a127a6309 100644
--- a/go/lib/sock/reliable/frame.go
+++ b/go/lib/sock/reliable/frame.go
@@ -21,14 +21,14 @@ import (
 	"github.com/scionproto/scion/go/lib/common"
 )
 
-// OverlayPacket contains metadata about a SCION packet going through the
+// UnderlayPacket contains metadata about a SCION packet going through the
 // reliable socket framing protocol.
-type OverlayPacket struct {
+type UnderlayPacket struct {
 	Address *net.UDPAddr
 	Payload []byte
 }
 
-func (p *OverlayPacket) SerializeTo(b []byte) (int, error) {
+func (p *UnderlayPacket) SerializeTo(b []byte) (int, error) {
 	var f frame
 	f.Cookie = expectedCookie
 	f.AddressType = byte(getAddressType(p.Address))
@@ -42,7 +42,7 @@ func (p *OverlayPacket) SerializeTo(b []byte) (int, error) {
 	return f.SerializeTo(b)
 }
 
-func (p *OverlayPacket) DecodeFromBytes(b []byte) error {
+func (p *UnderlayPacket) DecodeFromBytes(b []byte) error {
 	var f frame
 	if err := f.DecodeFromBytes(b); err != nil {
 		return err
diff --git a/go/lib/sock/reliable/reliable.go b/go/lib/sock/reliable/reliable.go
index db26350f9..f18b70408 100644
--- a/go/lib/sock/reliable/reliable.go
+++ b/go/lib/sock/reliable/reliable.go
@@ -269,11 +269,11 @@ func (conn *Conn) readFrom(buf []byte) (int, net.Addr, error) {
 	if err != nil {
 		return 0, nil, err
 	}
-	var p OverlayPacket
+	var p UnderlayPacket
 	p.DecodeFromBytes(conn.readBuffer[:n])
-	var overlayAddr *net.UDPAddr
+	var underlayAddr *net.UDPAddr
 	if p.Address != nil {
-		overlayAddr = &net.UDPAddr{
+		underlayAddr = &net.UDPAddr{
 			IP:   append(p.Address.IP[:0:0], p.Address.IP...),
 			Port: p.Address.Port,
 		}
@@ -282,7 +282,7 @@ func (conn *Conn) readFrom(buf []byte) (int, net.Addr, error) {
 		return 0, nil, serrors.New("buffer too small")
 	}
 	copy(buf, p.Payload)
-	return len(p.Payload), overlayAddr, nil
+	return len(p.Payload), underlayAddr, nil
 }
 
 // WriteTo blocks until it sends buf as a single framed message through conn.
@@ -308,7 +308,7 @@ func (conn *Conn) writeTo(buf []byte, dst net.Addr) (int, error) {
 				"address", fmt.Sprintf("%#v", dst))
 		}
 	}
-	p := &OverlayPacket{Address: udpAddr, Payload: buf}
+	p := &UnderlayPacket{Address: udpAddr, Payload: buf}
 	n, err := p.SerializeTo(conn.writeBuffer)
 	if err != nil {
 		return 0, err
diff --git a/go/lib/svc/resolver.go b/go/lib/svc/resolver.go
index 77cb8e6a4..fdaa01663 100644
--- a/go/lib/svc/resolver.go
+++ b/go/lib/svc/resolver.go
@@ -35,7 +35,7 @@ import (
 // and calling code should not depend on them.
 const (
 	errNilPacket      common.ErrMsg = "packet is nil"
-	errNilOverlay     common.ErrMsg = "overlay is nil"
+	errNilUnderlay    common.ErrMsg = "underlay is nil"
 	errUnsupportedPld common.ErrMsg = "unsupported payload type"
 	errRegistration   common.ErrMsg = "unable to open conn"
 	errWrite          common.ErrMsg = "unable to write"
@@ -94,7 +94,7 @@ func (r *Resolver) LookupSVC(ctx context.Context, p snet.Path, svc addr.HostSVC)
 			Payload: common.RawBytes(r.Payload),
 		},
 	}
-	reply, err := r.getRoundTripper().RoundTrip(ctx, conn, requestPacket, p.OverlayNextHop())
+	reply, err := r.getRoundTripper().RoundTrip(ctx, conn, requestPacket, p.UnderlayNextHop())
 	if err != nil {
 		ext.Error.Set(span, true)
 		return nil, err
@@ -110,11 +110,11 @@ func (r *Resolver) getRoundTripper() RoundTripper {
 }
 
 // RoundTripper does a single SVC resolution request/reply interaction over a
-// connection, using the specified request packet and overlay address.
+// connection, using the specified request packet and underlay address.
 type RoundTripper interface {
 	// RoundTrip performs the round trip interaction.
 	RoundTrip(ctx context.Context, c snet.PacketConn, request *snet.Packet,
-		ov *net.UDPAddr) (*Reply, error)
+		u *net.UDPAddr) (*Reply, error)
 }
 
 // DefaultRoundTripper returns a basic implementation of the RoundTripper
@@ -128,7 +128,7 @@ var _ RoundTripper = (*roundTripper)(nil)
 type roundTripper struct{}
 
 func (roundTripper) RoundTrip(ctx context.Context, c snet.PacketConn, pkt *snet.Packet,
-	ov *net.UDPAddr) (*Reply, error) {
+	u *net.UDPAddr) (*Reply, error) {
 
 	cancelF := ctxconn.CloseConnOnDone(ctx, c)
 	defer cancelF()
@@ -136,11 +136,11 @@ func (roundTripper) RoundTrip(ctx context.Context, c snet.PacketConn, pkt *snet.
 	if pkt == nil {
 		return nil, common.NewBasicError(errNilPacket, nil)
 	}
-	if ov == nil {
-		return nil, common.NewBasicError(errNilOverlay, nil)
+	if u == nil {
+		return nil, common.NewBasicError(errNilUnderlay, nil)
 	}
 
-	if err := c.WriteTo(pkt, ov); err != nil {
+	if err := c.WriteTo(pkt, u); err != nil {
 		return nil, common.NewBasicError(errWrite, err)
 	}
 
@@ -168,7 +168,7 @@ func (roundTripper) RoundTrip(ctx context.Context, c snet.PacketConn, pkt *snet.
 	}
 	reply.ReturnPath = &path{
 		spath:       replyPacket.Path,
-		overlay:     &replyOv,
+		underlay:    &replyOv,
 		destination: replyPacket.Source.IA,
 	}
 	return &reply, nil
@@ -176,7 +176,7 @@ func (roundTripper) RoundTrip(ctx context.Context, c snet.PacketConn, pkt *snet.
 
 type path struct {
 	spath       *spath.Path
-	overlay     *net.UDPAddr
+	underlay    *net.UDPAddr
 	destination addr.IA
 }
 
@@ -184,8 +184,8 @@ func (p *path) Fingerprint() snet.PathFingerprint {
 	return ""
 }
 
-func (p *path) OverlayNextHop() *net.UDPAddr {
-	return p.overlay
+func (p *path) UnderlayNextHop() *net.UDPAddr {
+	return p.underlay
 }
 
 func (p *path) Path() *spath.Path {
@@ -214,7 +214,7 @@ func (p *path) Copy() snet.Path {
 	}
 	return &path{
 		spath:       p.spath.Copy(),
-		overlay:     snet.CopyUDPAddr(p.overlay),
+		underlay:    snet.CopyUDPAddr(p.underlay),
 		destination: p.destination,
 	}
 }
diff --git a/go/lib/svc/svc.go b/go/lib/svc/svc.go
index 87b70d3ac..c103e5758 100644
--- a/go/lib/svc/svc.go
+++ b/go/lib/svc/svc.go
@@ -124,10 +124,10 @@ func (c *resolverPacketConn) ReadFrom(pkt *snet.Packet, ov *net.UDPAddr) error {
 		// goroutine, but because UDP writes rarely block, the current
 		// solution should be good enough for now.
 		r := &Request{
-			Conn:    c.PacketConn,
-			Source:  c.source,
-			Packet:  pkt,
-			Overlay: ov,
+			Conn:     c.PacketConn,
+			Source:   c.source,
+			Packet:   pkt,
+			Underlay: ov,
 		}
 		switch result, err := c.handler.Handle(r); result {
 		case Error:
@@ -143,7 +143,7 @@ func (c *resolverPacketConn) ReadFrom(pkt *snet.Packet, ov *net.UDPAddr) error {
 // RequestHandler handles SCION packets with SVC destination addresses.
 type RequestHandler interface {
 	// Handle replies to SCION packets with SVC destinations coming from the
-	// specified overlay address.
+	// specified underlay address.
 	//
 	// Handle implementantions might panic if the destination is not an SVC
 	// address, so callers should perform the check beforehand.
@@ -154,9 +154,9 @@ type Request struct {
 	// Source is the override value for the source address of the reply packet.
 	Source snet.SCIONAddress
 	// Conn is the connection to send the reply on. Conn must not be nil.
-	Conn    snet.PacketConn
-	Packet  *snet.Packet
-	Overlay *net.UDPAddr
+	Conn     snet.PacketConn
+	Packet   *snet.Packet
+	Underlay *net.UDPAddr
 }
 
 var _ RequestHandler = (*BaseHandler)(nil)
@@ -184,7 +184,7 @@ func (h *BaseHandler) Handle(request *Request) (Result, error) {
 			Payload:     h.getPayload(),
 		},
 	}
-	err = request.Conn.WriteTo(replyPacket, request.Overlay)
+	err = request.Conn.WriteTo(replyPacket, request.Underlay)
 	if err != nil {
 		return Error, err
 	}
diff --git a/go/lib/topology/BUILD.bazel b/go/lib/topology/BUILD.bazel
index 004651e12..8830217c1 100644
--- a/go/lib/topology/BUILD.bazel
+++ b/go/lib/topology/BUILD.bazel
@@ -20,7 +20,7 @@ go_library(
         "//go/lib/serrors:go_default_library",
         "//go/lib/snet:go_default_library",
         "//go/lib/topology/json:go_default_library",
-        "//go/lib/topology/overlay:go_default_library",
+        "//go/lib/topology/underlay:go_default_library",
         "//go/proto:go_default_library",
     ],
 )
@@ -38,7 +38,7 @@ go_test(
         "//go/lib/addr:go_default_library",
         "//go/lib/common:go_default_library",
         "//go/lib/topology/json:go_default_library",
-        "//go/lib/topology/overlay:go_default_library",
+        "//go/lib/topology/underlay:go_default_library",
         "//go/lib/xtest:go_default_library",
         "//go/proto:go_default_library",
         "@com_github_smartystreets_goconvey//convey:go_default_library",
diff --git a/go/lib/topology/interface.go b/go/lib/topology/interface.go
index c20686181..2ab5990bd 100644
--- a/go/lib/topology/interface.go
+++ b/go/lib/topology/interface.go
@@ -65,28 +65,28 @@ type Topology interface {
 	// Multicast returns all addresses for the requested type.
 	Multicast(svc addr.HostSVC) ([]*net.UDPAddr, error)
 
-	// OverlayAnycast returns the overlay address for an arbitrary server of the requested type.
-	OverlayAnycast(svc addr.HostSVC) (*net.UDPAddr, error)
-	// OverlayMulticast returns all overlay addresses for the requested type.
-	OverlayMulticast(svc addr.HostSVC) ([]*net.UDPAddr, error)
-	// OverlayByName returns the overlay address of the server name of the requested type.
+	// UnderlayAnycast returns the underlay address for an arbitrary server of the requested type.
+	UnderlayAnycast(svc addr.HostSVC) (*net.UDPAddr, error)
+	// UnderlayMulticast returns all underlay addresses for the requested type.
+	UnderlayMulticast(svc addr.HostSVC) ([]*net.UDPAddr, error)
+	// UnderlayByName returns the underlay address of the server name of the requested type.
 	//
 	// FIXME(scrye): This isn't really needed. We should also get rid of it.
-	OverlayByName(svc addr.HostSVC, name string) (*net.UDPAddr, error)
-	// OverlayNextHop2 returns the internal overlay address of the router containing the ID. The
-	// return value is encoded as an overlay address.
+	UnderlayByName(svc addr.HostSVC, name string) (*net.UDPAddr, error)
+	// UnderlayNextHop2 returns the internal underlay address of the router containing the ID. The
+	// return value is encoded as an underlay address.
 	//
 	// FIXME(scrye): Remove either this or the other method. A single return type should be
 	// supported.
-	OverlayNextHop2(ifID common.IFIDType) (*net.UDPAddr, bool)
+	UnderlayNextHop2(ifID common.IFIDType) (*net.UDPAddr, bool)
 
-	// OverlayNextHop returns the internal overlay address of the router
+	// UnderlayNextHop returns the internal underlay address of the router
 	// containing the interface ID.
 	//
 	// XXX(scrye): Return value is a shallow copy.
-	OverlayNextHop(ifID common.IFIDType) (*net.UDPAddr, bool)
+	UnderlayNextHop(ifID common.IFIDType) (*net.UDPAddr, bool)
 
-	// MakeHostInfos returns the overlay addresses of all services for the specified service type.
+	// MakeHostInfos returns the underlay addresses of all services for the specified service type.
 	MakeHostInfos(st proto.ServiceType) []net.UDPAddr
 
 	// BR returns information for a specific border router
@@ -171,7 +171,7 @@ func (t *topologyS) InterfaceIDs() []common.IFIDType {
 	return intfs
 }
 
-func (t *topologyS) OverlayNextHop(ifid common.IFIDType) (*net.UDPAddr, bool) {
+func (t *topologyS) UnderlayNextHop(ifid common.IFIDType) (*net.UDPAddr, bool) {
 	ifInfo, ok := t.Topology.IFInfoMap[ifid]
 	if !ok {
 		return nil, false
@@ -179,7 +179,7 @@ func (t *topologyS) OverlayNextHop(ifid common.IFIDType) (*net.UDPAddr, bool) {
 	return copyUDPAddr(ifInfo.InternalAddr), true
 }
 
-func (t *topologyS) OverlayNextHop2(ifid common.IFIDType) (*net.UDPAddr, bool) {
+func (t *topologyS) UnderlayNextHop2(ifid common.IFIDType) (*net.UDPAddr, bool) {
 	ifInfo, ok := t.Topology.IFInfoMap[ifid]
 	if !ok {
 		return nil, false
@@ -267,7 +267,7 @@ func (t *topologyS) Multicast(svc addr.HostSVC) ([]*net.UDPAddr, error) {
 	return addrs, nil
 }
 
-func (t *topologyS) OverlayAnycast(svc addr.HostSVC) (*net.UDPAddr, error) {
+func (t *topologyS) UnderlayAnycast(svc addr.HostSVC) (*net.UDPAddr, error) {
 	names := t.SVCNames(svc)
 	name, err := names.GetRandom()
 	if err != nil {
@@ -282,7 +282,7 @@ func (t *topologyS) OverlayAnycast(svc addr.HostSVC) (*net.UDPAddr, error) {
 		return nil, serrors.Wrap(addr.ErrUnsupportedSVCAddress,
 			scmp.NewError(scmp.C_Routing, scmp.T_R_BadHost, nil, nil), "svc", svc)
 	}
-	underlay, err := t.OverlayByName(svc, name)
+	underlay, err := t.UnderlayByName(svc, name)
 	if err != nil {
 		return nil, serrors.WrapStr("BUG! Selected random service name, but service info not found",
 			err, "service_names", names, "selected_name", name)
@@ -296,7 +296,7 @@ func supportedSVC(svc addr.HostSVC) bool {
 	return b == addr.SvcBS || b == addr.SvcCS || b == addr.SvcPS || b == addr.SvcSIG
 }
 
-func (t *topologyS) OverlayMulticast(svc addr.HostSVC) ([]*net.UDPAddr, error) {
+func (t *topologyS) UnderlayMulticast(svc addr.HostSVC) ([]*net.UDPAddr, error) {
 	st, err := toProtoServiceType(svc)
 	if err != nil {
 		return nil, err
@@ -313,25 +313,25 @@ func (t *topologyS) OverlayMulticast(svc addr.HostSVC) ([]*net.UDPAddr, error) {
 			scmp.NewError(scmp.C_Routing, scmp.T_R_UnreachHost, nil, nil), "svc", svc)
 	}
 
-	// Only select each IP:OverlayPort combination once, s.t. the same message isn't multicasted
+	// Only select each IP:UnderlayPort combination once, s.t. the same message isn't multicasted
 	// multiple times by the remote dispatcher.
-	uniqueOverlayAddrs := make(map[string]*net.UDPAddr)
+	uniqueUnderlayAddrs := make(map[string]*net.UDPAddr)
 	for _, topoAddr := range topoAddrs {
-		overlayAddr := topoAddr.UnderlayAddr()
-		if overlayAddr == nil {
+		underlayAddr := topoAddr.UnderlayAddr()
+		if underlayAddr == nil {
 			continue
 		}
-		uniqueOverlayAddrs[overlayAddr.String()] = overlayAddr
+		uniqueUnderlayAddrs[underlayAddr.String()] = underlayAddr
 	}
 
-	var overlayAddrs []*net.UDPAddr
-	for _, overlayAddr := range uniqueOverlayAddrs {
-		overlayAddrs = append(overlayAddrs, overlayAddr)
+	var underlayAddrs []*net.UDPAddr
+	for _, underlayAddr := range uniqueUnderlayAddrs {
+		underlayAddrs = append(underlayAddrs, underlayAddr)
 	}
-	return overlayAddrs, nil
+	return underlayAddrs, nil
 }
 
-func (t *topologyS) OverlayByName(svc addr.HostSVC, name string) (*net.UDPAddr, error) {
+func (t *topologyS) UnderlayByName(svc addr.HostSVC, name string) (*net.UDPAddr, error) {
 	st, err := toProtoServiceType(svc)
 	if err != nil {
 		return nil, err
@@ -340,11 +340,11 @@ func (t *topologyS) OverlayByName(svc addr.HostSVC, name string) (*net.UDPAddr,
 	if err != nil {
 		return nil, serrors.Wrap(addr.ErrUnsupportedSVCAddress, err, "svc", svc)
 	}
-	overlayAddr := topoAddr.UnderlayAddr()
-	if overlayAddr == nil {
-		return nil, serrors.New("overlay address not found", "svc", svc)
+	underlayAddr := topoAddr.UnderlayAddr()
+	if underlayAddr == nil {
+		return nil, serrors.New("underlay address not found", "svc", svc)
 	}
-	return copyUDPAddr(overlayAddr), nil
+	return copyUDPAddr(underlayAddr), nil
 }
 
 func toProtoServiceType(svc addr.HostSVC) (proto.ServiceType, error) {
diff --git a/go/lib/topology/json/BUILD.bazel b/go/lib/topology/json/BUILD.bazel
index cbd6d419c..3ed7ab50b 100644
--- a/go/lib/topology/json/BUILD.bazel
+++ b/go/lib/topology/json/BUILD.bazel
@@ -20,7 +20,7 @@ go_test(
     deps = [
         "//go/lib/common:go_default_library",
         "//go/lib/scrypto/trc:go_default_library",
-        "//go/lib/topology/overlay:go_default_library",
+        "//go/lib/topology/underlay:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
         "@com_github_stretchr_testify//require:go_default_library",
     ],
diff --git a/go/lib/topology/json/json.go b/go/lib/topology/json/json.go
index df72287e0..a6a732f99 100644
--- a/go/lib/topology/json/json.go
+++ b/go/lib/topology/json/json.go
@@ -34,7 +34,7 @@ type Topology struct {
 	TimestampHuman string `json:"TimestampHuman"`
 	TTL            uint32 `json:"TTL"`
 	IA             string `json:"ISD_AS"`
-	Overlay        string `json:"Overlay"`
+	Underlay       string `json:"Overlay"`
 	MTU            int    `json:"MTU"`
 	// Attributes are the primary AS attributes as described in
 	// https://github.com/scionproto/scion/blob/master/doc/ControlPlanePKI.md#primary-ases
diff --git a/go/lib/topology/mock_topology/topology.go b/go/lib/topology/mock_topology/topology.go
index f75191719..fc42fa56e 100644
--- a/go/lib/topology/mock_topology/topology.go
+++ b/go/lib/topology/mock_topology/topology.go
@@ -195,121 +195,121 @@ func (mr *MockTopologyMockRecorder) Multicast(arg0 interface{}) *gomock.Call {
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Multicast", reflect.TypeOf((*MockTopology)(nil).Multicast), arg0)
 }
 
-// OverlayAnycast mocks base method
-func (m *MockTopology) OverlayAnycast(arg0 addr.HostSVC) (*net.UDPAddr, error) {
+// PublicAddress mocks base method
+func (m *MockTopology) PublicAddress(arg0 addr.HostSVC, arg1 string) *net.UDPAddr {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "OverlayAnycast", arg0)
+	ret := m.ctrl.Call(m, "PublicAddress", arg0, arg1)
 	ret0, _ := ret[0].(*net.UDPAddr)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
+	return ret0
 }
 
-// OverlayAnycast indicates an expected call of OverlayAnycast
-func (mr *MockTopologyMockRecorder) OverlayAnycast(arg0 interface{}) *gomock.Call {
+// PublicAddress indicates an expected call of PublicAddress
+func (mr *MockTopologyMockRecorder) PublicAddress(arg0, arg1 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OverlayAnycast", reflect.TypeOf((*MockTopology)(nil).OverlayAnycast), arg0)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublicAddress", reflect.TypeOf((*MockTopology)(nil).PublicAddress), arg0, arg1)
 }
 
-// OverlayByName mocks base method
-func (m *MockTopology) OverlayByName(arg0 addr.HostSVC, arg1 string) (*net.UDPAddr, error) {
+// SBRAddress mocks base method
+func (m *MockTopology) SBRAddress(arg0 string) *snet.UDPAddr {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "OverlayByName", arg0, arg1)
-	ret0, _ := ret[0].(*net.UDPAddr)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
+	ret := m.ctrl.Call(m, "SBRAddress", arg0)
+	ret0, _ := ret[0].(*snet.UDPAddr)
+	return ret0
 }
 
-// OverlayByName indicates an expected call of OverlayByName
-func (mr *MockTopologyMockRecorder) OverlayByName(arg0, arg1 interface{}) *gomock.Call {
+// SBRAddress indicates an expected call of SBRAddress
+func (mr *MockTopologyMockRecorder) SBRAddress(arg0 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OverlayByName", reflect.TypeOf((*MockTopology)(nil).OverlayByName), arg0, arg1)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SBRAddress", reflect.TypeOf((*MockTopology)(nil).SBRAddress), arg0)
 }
 
-// OverlayMulticast mocks base method
-func (m *MockTopology) OverlayMulticast(arg0 addr.HostSVC) ([]*net.UDPAddr, error) {
+// SVCNames mocks base method
+func (m *MockTopology) SVCNames(arg0 addr.HostSVC) topology.ServiceNames {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "OverlayMulticast", arg0)
-	ret0, _ := ret[0].([]*net.UDPAddr)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
+	ret := m.ctrl.Call(m, "SVCNames", arg0)
+	ret0, _ := ret[0].(topology.ServiceNames)
+	return ret0
 }
 
-// OverlayMulticast indicates an expected call of OverlayMulticast
-func (mr *MockTopologyMockRecorder) OverlayMulticast(arg0 interface{}) *gomock.Call {
+// SVCNames indicates an expected call of SVCNames
+func (mr *MockTopologyMockRecorder) SVCNames(arg0 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OverlayMulticast", reflect.TypeOf((*MockTopology)(nil).OverlayMulticast), arg0)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SVCNames", reflect.TypeOf((*MockTopology)(nil).SVCNames), arg0)
 }
 
-// OverlayNextHop mocks base method
-func (m *MockTopology) OverlayNextHop(arg0 common.IFIDType) (*net.UDPAddr, bool) {
+// UnderlayAnycast mocks base method
+func (m *MockTopology) UnderlayAnycast(arg0 addr.HostSVC) (*net.UDPAddr, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "OverlayNextHop", arg0)
+	ret := m.ctrl.Call(m, "UnderlayAnycast", arg0)
 	ret0, _ := ret[0].(*net.UDPAddr)
-	ret1, _ := ret[1].(bool)
+	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
-// OverlayNextHop indicates an expected call of OverlayNextHop
-func (mr *MockTopologyMockRecorder) OverlayNextHop(arg0 interface{}) *gomock.Call {
+// UnderlayAnycast indicates an expected call of UnderlayAnycast
+func (mr *MockTopologyMockRecorder) UnderlayAnycast(arg0 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OverlayNextHop", reflect.TypeOf((*MockTopology)(nil).OverlayNextHop), arg0)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnderlayAnycast", reflect.TypeOf((*MockTopology)(nil).UnderlayAnycast), arg0)
 }
 
-// OverlayNextHop2 mocks base method
-func (m *MockTopology) OverlayNextHop2(arg0 common.IFIDType) (*net.UDPAddr, bool) {
+// UnderlayByName mocks base method
+func (m *MockTopology) UnderlayByName(arg0 addr.HostSVC, arg1 string) (*net.UDPAddr, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "OverlayNextHop2", arg0)
+	ret := m.ctrl.Call(m, "UnderlayByName", arg0, arg1)
 	ret0, _ := ret[0].(*net.UDPAddr)
-	ret1, _ := ret[1].(bool)
+	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
 
-// OverlayNextHop2 indicates an expected call of OverlayNextHop2
-func (mr *MockTopologyMockRecorder) OverlayNextHop2(arg0 interface{}) *gomock.Call {
+// UnderlayByName indicates an expected call of UnderlayByName
+func (mr *MockTopologyMockRecorder) UnderlayByName(arg0, arg1 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OverlayNextHop2", reflect.TypeOf((*MockTopology)(nil).OverlayNextHop2), arg0)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnderlayByName", reflect.TypeOf((*MockTopology)(nil).UnderlayByName), arg0, arg1)
 }
 
-// PublicAddress mocks base method
-func (m *MockTopology) PublicAddress(arg0 addr.HostSVC, arg1 string) *net.UDPAddr {
+// UnderlayMulticast mocks base method
+func (m *MockTopology) UnderlayMulticast(arg0 addr.HostSVC) ([]*net.UDPAddr, error) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "PublicAddress", arg0, arg1)
-	ret0, _ := ret[0].(*net.UDPAddr)
-	return ret0
+	ret := m.ctrl.Call(m, "UnderlayMulticast", arg0)
+	ret0, _ := ret[0].([]*net.UDPAddr)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
 }
 
-// PublicAddress indicates an expected call of PublicAddress
-func (mr *MockTopologyMockRecorder) PublicAddress(arg0, arg1 interface{}) *gomock.Call {
+// UnderlayMulticast indicates an expected call of UnderlayMulticast
+func (mr *MockTopologyMockRecorder) UnderlayMulticast(arg0 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublicAddress", reflect.TypeOf((*MockTopology)(nil).PublicAddress), arg0, arg1)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnderlayMulticast", reflect.TypeOf((*MockTopology)(nil).UnderlayMulticast), arg0)
 }
 
-// SBRAddress mocks base method
-func (m *MockTopology) SBRAddress(arg0 string) *snet.UDPAddr {
+// UnderlayNextHop mocks base method
+func (m *MockTopology) UnderlayNextHop(arg0 common.IFIDType) (*net.UDPAddr, bool) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SBRAddress", arg0)
-	ret0, _ := ret[0].(*snet.UDPAddr)
-	return ret0
+	ret := m.ctrl.Call(m, "UnderlayNextHop", arg0)
+	ret0, _ := ret[0].(*net.UDPAddr)
+	ret1, _ := ret[1].(bool)
+	return ret0, ret1
 }
 
-// SBRAddress indicates an expected call of SBRAddress
-func (mr *MockTopologyMockRecorder) SBRAddress(arg0 interface{}) *gomock.Call {
+// UnderlayNextHop indicates an expected call of UnderlayNextHop
+func (mr *MockTopologyMockRecorder) UnderlayNextHop(arg0 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SBRAddress", reflect.TypeOf((*MockTopology)(nil).SBRAddress), arg0)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnderlayNextHop", reflect.TypeOf((*MockTopology)(nil).UnderlayNextHop), arg0)
 }
 
-// SVCNames mocks base method
-func (m *MockTopology) SVCNames(arg0 addr.HostSVC) topology.ServiceNames {
+// UnderlayNextHop2 mocks base method
+func (m *MockTopology) UnderlayNextHop2(arg0 common.IFIDType) (*net.UDPAddr, bool) {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SVCNames", arg0)
-	ret0, _ := ret[0].(topology.ServiceNames)
-	return ret0
+	ret := m.ctrl.Call(m, "UnderlayNextHop2", arg0)
+	ret0, _ := ret[0].(*net.UDPAddr)
+	ret1, _ := ret[1].(bool)
+	return ret0, ret1
 }
 
-// SVCNames indicates an expected call of SVCNames
-func (mr *MockTopologyMockRecorder) SVCNames(arg0 interface{}) *gomock.Call {
+// UnderlayNextHop2 indicates an expected call of UnderlayNextHop2
+func (mr *MockTopologyMockRecorder) UnderlayNextHop2(arg0 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SVCNames", reflect.TypeOf((*MockTopology)(nil).SVCNames), arg0)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnderlayNextHop2", reflect.TypeOf((*MockTopology)(nil).UnderlayNextHop2), arg0)
 }
 
 // Writable mocks base method
diff --git a/go/lib/topology/raw.go b/go/lib/topology/raw.go
index 6b59ef0af..f2ad9fe0b 100644
--- a/go/lib/topology/raw.go
+++ b/go/lib/topology/raw.go
@@ -20,7 +20,7 @@ import (
 
 	"github.com/scionproto/scion/go/lib/serrors"
 	jsontopo "github.com/scionproto/scion/go/lib/topology/json"
-	"github.com/scionproto/scion/go/lib/topology/overlay"
+	"github.com/scionproto/scion/go/lib/topology/underlay"
 )
 
 func rawAddrMapToTopoAddr(ram jsontopo.NATSCIONAddressMap) (*TopoAddr, error) {
@@ -135,7 +135,7 @@ func rawBRAddrMapExtractAddressInfo(
 	return nil, false
 }
 
-func rawBRIntfRemoteBRAddr(b *jsontopo.BRInterface, o overlay.Type) (*net.UDPAddr, error) {
+func rawBRIntfRemoteBRAddr(b *jsontopo.BRInterface, o underlay.Type) (*net.UDPAddr, error) {
 	l3, err := net.ResolveIPAddr("ip", b.RemoteUnderlay.Addr)
 	if err != nil {
 		return nil, serrors.WrapStr("could not parse remote IP from string", err,
diff --git a/go/lib/topology/topology.go b/go/lib/topology/topology.go
index 2ba992f70..a3f5a66a9 100644
--- a/go/lib/topology/topology.go
+++ b/go/lib/topology/topology.go
@@ -29,12 +29,12 @@ import (
 	"github.com/scionproto/scion/go/lib/scrypto/trc"
 	"github.com/scionproto/scion/go/lib/serrors"
 	jsontopo "github.com/scionproto/scion/go/lib/topology/json"
-	"github.com/scionproto/scion/go/lib/topology/overlay"
+	"github.com/scionproto/scion/go/lib/topology/underlay"
 	"github.com/scionproto/scion/go/proto"
 )
 
-// EndhostPort is the overlay port that the dispatcher binds to on non-routers.
-const EndhostPort = overlay.EndhostPort
+// EndhostPort is the underlay port that the dispatcher binds to on non-routers.
+const EndhostPort = underlay.EndhostPort
 
 type (
 	// RWTopology is the topology type for applications and libraries that need write
@@ -98,7 +98,7 @@ type (
 		ID           common.IFIDType
 		BRName       string
 		CtrlAddrs    *TopoAddr
-		Underlay     overlay.Type
+		Underlay     underlay.Type
 		InternalAddr *net.UDPAddr
 		Local        *net.UDPAddr
 		Remote       *net.UDPAddr
@@ -181,7 +181,7 @@ func (t *RWTopology) populateMeta(raw *jsontopo.Topology) error {
 	if t.IA.IsWildcard() {
 		return common.NewBasicError("IA contains wildcard", nil, "ia", t.IA)
 	}
-	if _, err = overlay.TypeFromString(raw.Overlay); err != nil {
+	if _, err = underlay.TypeFromString(raw.Underlay); err != nil {
 		return err
 	}
 	t.MTU = raw.MTU
@@ -241,7 +241,7 @@ func (t *RWTopology) populateBR(raw *jsontopo.Topology) error {
 				t.IFInfoMap[ifid] = ifinfo
 				continue
 			}
-			if ifinfo.Underlay, err = overlay.TypeFromString(rawIntf.Underlay); err != nil {
+			if ifinfo.Underlay, err = underlay.TypeFromString(rawIntf.Underlay); err != nil {
 				return serrors.WrapStr("unable to extract underlay type", err)
 			}
 			if ifinfo.Local, err = rawBRIntfTopoBRAddr(rawIntf); err != nil {
@@ -469,7 +469,7 @@ func (i IFInfo) CheckLinks(isCore bool, brName string) error {
 }
 
 func (i IFInfo) String() string {
-	return fmt.Sprintf("IFinfo: Name[%s] IntAddr[%+v] CtrlAddr[%+v] Overlay:%s Local:%+v "+
+	return fmt.Sprintf("IFinfo: Name[%s] IntAddr[%+v] CtrlAddr[%+v] Underlay:%s Local:%+v "+
 		"Remote:%+v Bw:%d IA:%s Type:%v MTU:%d", i.BRName, i.InternalAddr, i.CtrlAddrs, i.Underlay,
 		i.Local, i.Remote, i.Bandwidth, i.IA, i.LinkType, i.MTU)
 }
diff --git a/go/lib/topology/overlay/BUILD.bazel b/go/lib/topology/underlay/BUILD.bazel
similarity index 87%
rename from go/lib/topology/overlay/BUILD.bazel
rename to go/lib/topology/underlay/BUILD.bazel
index a72906b90..521a8eb9f 100644
--- a/go/lib/topology/overlay/BUILD.bazel
+++ b/go/lib/topology/underlay/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
 go_library(
     name = "go_default_library",
     srcs = ["defs.go"],
-    importpath = "github.com/scionproto/scion/go/lib/topology/overlay",
+    importpath = "github.com/scionproto/scion/go/lib/topology/underlay",
     visibility = ["//visibility:public"],
     deps = ["//go/lib/common:go_default_library"],
 )
diff --git a/go/lib/topology/overlay/defs.go b/go/lib/topology/underlay/defs.go
similarity index 90%
rename from go/lib/topology/overlay/defs.go
rename to go/lib/topology/underlay/defs.go
index ece7421b9..4a92bac11 100644
--- a/go/lib/topology/overlay/defs.go
+++ b/go/lib/topology/underlay/defs.go
@@ -13,7 +13,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package overlay
+package underlay
 
 import (
 	"encoding/json"
@@ -39,7 +39,7 @@ const (
 )
 
 const (
-	// EndhostPort is the overlay port that the dispatcher binds to on non-routers. Subject to
+	// EndhostPort is the underlay port that the dispatcher binds to on non-routers. Subject to
 	// change during standardisation.
 	EndhostPort = 30041
 )
@@ -66,7 +66,7 @@ func TypeFromString(s string) (Type, error) {
 	case strings.ToLower(UDPIPv46Name):
 		return UDPIPv46, nil
 	default:
-		return Invalid, common.NewBasicError("Unknown overlay type", nil, "type", s)
+		return Invalid, common.NewBasicError("Unknown underlay type", nil, "type", s)
 	}
 }
 
diff --git a/go/lib/overlay/conn/BUILD.bazel b/go/lib/underlay/conn/BUILD.bazel
similarity index 85%
rename from go/lib/overlay/conn/BUILD.bazel
rename to go/lib/underlay/conn/BUILD.bazel
index 329ce65d8..17e0de165 100644
--- a/go/lib/overlay/conn/BUILD.bazel
+++ b/go/lib/underlay/conn/BUILD.bazel
@@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["conn.go"],
-    importpath = "github.com/scionproto/scion/go/lib/overlay/conn",
+    importpath = "github.com/scionproto/scion/go/lib/underlay/conn",
     visibility = ["//visibility:public"],
     deps = select({
         "@io_bazel_rules_go//go/platform:android": [
@@ -12,7 +12,7 @@ go_library(
             "//go/lib/log:go_default_library",
             "//go/lib/serrors:go_default_library",
             "//go/lib/sockctrl:go_default_library",
-            "//go/lib/topology/overlay:go_default_library",
+            "//go/lib/topology/underlay:go_default_library",
             "@org_golang_x_net//ipv4:go_default_library",
             "@org_golang_x_net//ipv6:go_default_library",
         ],
@@ -22,7 +22,7 @@ go_library(
             "//go/lib/log:go_default_library",
             "//go/lib/serrors:go_default_library",
             "//go/lib/sockctrl:go_default_library",
-            "//go/lib/topology/overlay:go_default_library",
+            "//go/lib/topology/underlay:go_default_library",
             "@org_golang_x_net//ipv4:go_default_library",
             "@org_golang_x_net//ipv6:go_default_library",
         ],
diff --git a/go/lib/overlay/conn/conn.go b/go/lib/underlay/conn/conn.go
similarity index 96%
rename from go/lib/overlay/conn/conn.go
rename to go/lib/underlay/conn/conn.go
index 2063f8298..7df4afe3d 100644
--- a/go/lib/overlay/conn/conn.go
+++ b/go/lib/underlay/conn/conn.go
@@ -15,7 +15,7 @@
 
 // +build go1.9,linux
 
-// Package conn implements overlay sockets with additional metadata on reads.
+// Package conn implements underlay sockets with additional metadata on reads.
 package conn
 
 import (
@@ -33,7 +33,7 @@ import (
 	"github.com/scionproto/scion/go/lib/log"
 	"github.com/scionproto/scion/go/lib/serrors"
 	"github.com/scionproto/scion/go/lib/sockctrl"
-	"github.com/scionproto/scion/go/lib/topology/overlay"
+	"github.com/scionproto/scion/go/lib/topology/underlay"
 )
 
 // ReceiveBufferSize is the default size, in bytes, of receive buffers for
@@ -51,7 +51,7 @@ var sizeIgnore = flag.Bool("overlay.conn.sizeIgnore", true,
 // between ipv4.Message, ipv6.Message and socket.Message.
 type Messages []ipv4.Message
 
-// Conn describes the API for an overlay socket with additional metadata on
+// Conn describes the API for an underlay socket with additional metadata on
 // reads.
 type Conn interface {
 	Read(common.RawBytes) (int, *ReadMeta, error)
@@ -67,7 +67,7 @@ type Conn interface {
 	Close() error
 }
 
-// Config customizes the behavior of an overlay socket.
+// Config customizes the behavior of an underlay socket.
 type Config struct {
 	// ReceiveBufferSize is the size of the operating system receive buffer, in
 	// bytes. If 0, the package constant is used instead.
@@ -81,7 +81,7 @@ func (c *Config) getReceiveBufferSize() int {
 	return ReceiveBufferSize
 }
 
-// New opens a new overlay socket on the specified addresses.
+// New opens a new underlay socket on the specified addresses.
 //
 // The config can be used to customize socket behavior. If config is nil,
 // default values are used.
@@ -133,7 +133,7 @@ func (c *connUDPIPv4) ReadBatch(msgs Messages, metas []ReadMeta) (int, error) {
 		if msg.NN > 0 {
 			c.handleCmsg(msg.OOB[:msg.NN], meta, readTime)
 		}
-		meta.setSrc(c.Remote, msg.Addr.(*net.UDPAddr), overlay.UDPIPv4)
+		meta.setSrc(c.Remote, msg.Addr.(*net.UDPAddr), underlay.UDPIPv4)
 	}
 	return n, err
 }
@@ -186,7 +186,7 @@ func (c *connUDPIPv6) ReadBatch(msgs Messages, metas []ReadMeta) (int, error) {
 		if msg.NN > 0 {
 			c.handleCmsg(msg.OOB[:msg.NN], meta, readTime)
 		}
-		meta.setSrc(c.Remote, msg.Addr.(*net.UDPAddr), overlay.UDPIPv6)
+		meta.setSrc(c.Remote, msg.Addr.(*net.UDPAddr), underlay.UDPIPv6)
 	}
 	return n, err
 }
@@ -383,7 +383,7 @@ func (m *ReadMeta) reset() {
 	m.ReadDelay = 0
 }
 
-func (m *ReadMeta) setSrc(a *net.UDPAddr, raddr *net.UDPAddr, ot overlay.Type) {
+func (m *ReadMeta) setSrc(a *net.UDPAddr, raddr *net.UDPAddr, ot underlay.Type) {
 	if a != nil {
 		m.Src = a
 	} else {
diff --git a/go/lib/overlay/conn/mock_conn/BUILD.bazel b/go/lib/underlay/conn/mock_conn/BUILD.bazel
similarity index 69%
rename from go/lib/overlay/conn/mock_conn/BUILD.bazel
rename to go/lib/underlay/conn/mock_conn/BUILD.bazel
index ba0e013f4..22109a6a9 100644
--- a/go/lib/overlay/conn/mock_conn/BUILD.bazel
+++ b/go/lib/underlay/conn/mock_conn/BUILD.bazel
@@ -3,11 +3,11 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = ["conn.go"],
-    importpath = "github.com/scionproto/scion/go/lib/overlay/conn/mock_conn",
+    importpath = "github.com/scionproto/scion/go/lib/underlay/conn/mock_conn",
     visibility = ["//visibility:public"],
     deps = [
         "//go/lib/common:go_default_library",
-        "//go/lib/overlay/conn:go_default_library",
+        "//go/lib/underlay/conn:go_default_library",
         "@com_github_golang_mock//gomock:go_default_library",
     ],
 )
diff --git a/go/lib/overlay/conn/mock_conn/conn.go b/go/lib/underlay/conn/mock_conn/conn.go
similarity index 97%
rename from go/lib/overlay/conn/mock_conn/conn.go
rename to go/lib/underlay/conn/mock_conn/conn.go
index 15c148820..23585da1f 100644
--- a/go/lib/overlay/conn/mock_conn/conn.go
+++ b/go/lib/underlay/conn/mock_conn/conn.go
@@ -1,5 +1,5 @@
 // Code generated by MockGen. DO NOT EDIT.
-// Source: github.com/scionproto/scion/go/lib/overlay/conn (interfaces: Conn)
+// Source: github.com/scionproto/scion/go/lib/underlay/conn (interfaces: Conn)
 
 // Package mock_conn is a generated GoMock package.
 package mock_conn
@@ -7,7 +7,7 @@ package mock_conn
 import (
 	gomock "github.com/golang/mock/gomock"
 	common "github.com/scionproto/scion/go/lib/common"
-	conn "github.com/scionproto/scion/go/lib/overlay/conn"
+	conn "github.com/scionproto/scion/go/lib/underlay/conn"
 	net "net"
 	reflect "reflect"
 	time "time"
diff --git a/go/pkg/showpaths/showpaths.go b/go/pkg/showpaths/showpaths.go
index d38a8d339..c23ac3f78 100644
--- a/go/pkg/showpaths/showpaths.go
+++ b/go/pkg/showpaths/showpaths.go
@@ -125,7 +125,7 @@ func Run(ctx context.Context, dst addr.IA, cfg Config) (*Result, error) {
 		rpath := Path{
 			FullPath:    path,
 			Fingerprint: path.Fingerprint().String()[:16],
-			NextHop:     path.OverlayNextHop().String(),
+			NextHop:     path.UnderlayNextHop().String(),
 			Expiry:      path.Expiry(),
 			MTU:         path.MTU(),
 			Local:       localIP,
@@ -162,7 +162,7 @@ func findDefaultLocalIP(ctx context.Context, sciondConn sciond.Connector) (net.I
 
 // findAnyHostInLocalAS returns the IP address of some (infrastructure) host in the local AS.
 func findAnyHostInLocalAS(ctx context.Context, sciondConn sciond.Connector) (net.IP, error) {
-	addr, err := sciond.TopoQuerier{Connector: sciondConn}.OverlayAnycast(ctx, addr.SvcBS)
+	addr, err := sciond.TopoQuerier{Connector: sciondConn}.UnderlayAnycast(ctx, addr.SvcBS)
 	if err != nil {
 		return nil, err
 	}
diff --git a/go/sciond/internal/fetcher/fetcher.go b/go/sciond/internal/fetcher/fetcher.go
index a3a0036ba..e9147c6f9 100644
--- a/go/sciond/internal/fetcher/fetcher.go
+++ b/go/sciond/internal/fetcher/fetcher.go
@@ -168,7 +168,7 @@ func (f *fetcher) translate(path *combinator.Path) (sciond.PathReplyEntry, error
 		// In-memory write should never fail
 		panic(err)
 	}
-	nextHop, ok := f.pather.TopoProvider.Get().OverlayNextHop(path.Interfaces[0].IfID)
+	nextHop, ok := f.pather.TopoProvider.Get().UnderlayNextHop(path.Interfaces[0].IfID)
 	if !ok {
 		return sciond.PathReplyEntry{}, serrors.New("unable to find first-hop BR for path",
 			"ifid", path.Interfaces[0].IfID)
diff --git a/go/sciond/internal/servers/handlers.go b/go/sciond/internal/servers/handlers.go
index 42b85201c..0cd0396fb 100644
--- a/go/sciond/internal/servers/handlers.go
+++ b/go/sciond/internal/servers/handlers.go
@@ -171,7 +171,7 @@ func (h *IFInfoRequestHandler) Handle(ctx context.Context, conn net.Conn, src ne
 	if len(ifInfoRequest.IfIDs) == 0 {
 		// Reply with all the IFIDs we know
 		for _, ifid := range topo.InterfaceIDs() {
-			nextHop, ok := topo.OverlayNextHop(ifid)
+			nextHop, ok := topo.UnderlayNextHop(ifid)
 			if !ok {
 				logger.Info("Received IF Info Request, but IFID not found", "ifid", ifid)
 				continue
@@ -184,7 +184,7 @@ func (h *IFInfoRequestHandler) Handle(ctx context.Context, conn net.Conn, src ne
 	} else {
 		// Reply with only the IFIDs the client requested
 		for _, ifid := range ifInfoRequest.IfIDs {
-			nextHop, ok := topo.OverlayNextHop(ifid)
+			nextHop, ok := topo.UnderlayNextHop(ifid)
 			if !ok {
 				logger.Info("Received IF Info Request, but IFID not found", "ifid", ifid)
 				continue
diff --git a/go/sig/egress/session/sessmon.go b/go/sig/egress/session/sessmon.go
index 110843ec6..a50c64f25 100644
--- a/go/sig/egress/session/sessmon.go
+++ b/go/sig/egress/session/sessmon.go
@@ -281,7 +281,7 @@ func (sm *sessMonitor) sendReq() {
 	}
 	raddr := sm.smRemote.Sig.CtrlSnetAddr(
 		sm.smRemote.SessPath.Path().Path(),
-		sm.smRemote.SessPath.Path().OverlayNextHop(),
+		sm.smRemote.SessPath.Path().UnderlayNextHop(),
 	)
 	// XXX(kormat): if this blocks, both the sessMon and egress worker
 	// goroutines will block. Can't just use SetWriteDeadline, as both
diff --git a/go/sig/egress/worker/worker.go b/go/sig/egress/worker/worker.go
index aebc004f6..ca83321d1 100644
--- a/go/sig/egress/worker/worker.go
+++ b/go/sig/egress/worker/worker.go
@@ -201,7 +201,7 @@ func (w *worker) write(f *frame) error {
 		}
 		snetAddr = w.currSig.EncapSnetAddr()
 		snetAddr.Path = w.currPathEntry.Path()
-		snetAddr.NextHop = w.currPathEntry.OverlayNextHop()
+		snetAddr.NextHop = w.currPathEntry.UnderlayNextHop()
 	}
 
 	f.writeHdr(w.sess.ID(), w.epoch, seq)
diff --git a/go/sig/internal/sigconfig/conf.go b/go/sig/internal/sigconfig/conf.go
index ab27d4a92..48604f1cf 100644
--- a/go/sig/internal/sigconfig/conf.go
+++ b/go/sig/internal/sigconfig/conf.go
@@ -99,7 +99,7 @@ type SigConf struct {
 	SrcIP4 net.IP `toml:"src_ipv4,omitempty"`
 	// IPv6 source address hint to put into routing table.
 	SrcIP6 net.IP `toml:"src_ipv6,omitempty"`
-	// DispatcherBypass is the overlay address (e.g. ":30041") to use when bypassing SCION
+	// DispatcherBypass is the underlay address (e.g. ":30041") to use when bypassing SCION
 	// dispatcher. If the field is empty bypass is not done and SCION dispatcher is used
 	// instead.
 	DispatcherBypass string `toml:"disaptcher_bypass,omitempty"`
diff --git a/go/sig/internal/snetmigrate/path.go b/go/sig/internal/snetmigrate/path.go
index 67a677c43..dff01ccbb 100644
--- a/go/sig/internal/snetmigrate/path.go
+++ b/go/sig/internal/snetmigrate/path.go
@@ -32,7 +32,7 @@ func (p *emptyPath) Fingerprint() snet.PathFingerprint {
 	return ""
 }
 
-func (p *emptyPath) OverlayNextHop() *net.UDPAddr {
+func (p *emptyPath) UnderlayNextHop() *net.UDPAddr {
 	return nil
 }
 
diff --git a/go/tools/scmp/main.go b/go/tools/scmp/main.go
index 4bbb32fa4..fc34ba74f 100644
--- a/go/tools/scmp/main.go
+++ b/go/tools/scmp/main.go
@@ -144,7 +144,7 @@ func setPathAndMtu() {
 	path := choosePath()
 	cmn.PathEntry = path
 	cmn.Remote.Path = path.Path()
-	cmn.Remote.NextHop = path.OverlayNextHop()
+	cmn.Remote.NextHop = path.UnderlayNextHop()
 	cmn.Mtu = path.MTU()
 }
 
diff --git a/go/tools/showpaths/paths.go b/go/tools/showpaths/paths.go
index 09e451223..fbdd6b769 100644
--- a/go/tools/showpaths/paths.go
+++ b/go/tools/showpaths/paths.go
@@ -168,7 +168,7 @@ func findDefaultLocalIP(ctx context.Context, sciondConn sciond.Connector) (net.I
 
 // findAnyHostInLocalAS returns the IP address of some (infrastructure) host in the local AS.
 func findAnyHostInLocalAS(ctx context.Context, sciondConn sciond.Connector) (net.IP, error) {
-	addr, err := sciond.TopoQuerier{Connector: sciondConn}.OverlayAnycast(ctx, addr.SvcBS)
+	addr, err := sciond.TopoQuerier{Connector: sciondConn}.UnderlayAnycast(ctx, addr.SvcBS)
 	if err != nil {
 		return nil, err
 	}
diff --git a/tools/gomocks b/tools/gomocks
index 519557665..7469f0836 100755
--- a/tools/gomocks
+++ b/tools/gomocks
@@ -53,7 +53,6 @@ MOCK_TARGETS = [
             "CryptoProvider,DB,KeyRing,Inserter,Recurser,Resolver,Router,RPC"),
         (SCION_PACKAGE_PREFIX + "/go/lib/l4", "L4Header"),
         (SCION_PACKAGE_PREFIX + "/go/lib/log", "Handler,Logger"),
-        (SCION_PACKAGE_PREFIX + "/go/lib/overlay/conn", "Conn"),
         (SCION_PACKAGE_PREFIX + "/go/lib/pathdb", "PathDB,Transaction,ReadWrite"),
         (SCION_PACKAGE_PREFIX + "/go/lib/pathmgr", "Policy,Querier,Resolver"),
         (SCION_PACKAGE_PREFIX + "/go/lib/revcache", "RevCache"),
@@ -65,6 +64,7 @@ MOCK_TARGETS = [
         (SCION_PACKAGE_PREFIX + "/go/lib/svc", "RequestHandler,RoundTripper"),
         (SCION_PACKAGE_PREFIX + "/go/lib/svc/internal/ctxconn", "DeadlineCloser"),
         (SCION_PACKAGE_PREFIX + "/go/lib/topology", "Topology"),
+        (SCION_PACKAGE_PREFIX + "/go/lib/underlay/conn", "Conn"),
         (SCION_PACKAGE_PREFIX + "/go/lib/periodic/internal/metrics", "ExportMetric"),
         (SCION_PACKAGE_PREFIX + "/go/lib/xtest", "Callback"),
         (SCION_PACKAGE_PREFIX + "/go/sciond/internal/fetcher", "Policy"),


Test patch:
diff --git a/go/border/io_test.go b/go/border/io_test.go
index f39ed344e..60c1f7945 100644
--- a/go/border/io_test.go
+++ b/go/border/io_test.go
@@ -27,12 +27,12 @@ import (
 	"github.com/scionproto/scion/go/border/rctx"
 	"github.com/scionproto/scion/go/border/rpkt"
 	"github.com/scionproto/scion/go/lib/log"
-	"github.com/scionproto/scion/go/lib/overlay/conn"
-	"github.com/scionproto/scion/go/lib/overlay/conn/mock_conn"
 	"github.com/scionproto/scion/go/lib/prom"
 	"github.com/scionproto/scion/go/lib/ringbuf"
 	"github.com/scionproto/scion/go/lib/serrors"
 	"github.com/scionproto/scion/go/lib/topology"
+	"github.com/scionproto/scion/go/lib/underlay/conn"
+	"github.com/scionproto/scion/go/lib/underlay/conn/mock_conn"
 )
 
 func TestIsSyscallErrno(t *testing.T) {
diff --git a/go/cs/onehop/sender_test.go b/go/cs/onehop/sender_test.go
index d7b1550de..110c69839 100644
--- a/go/cs/onehop/sender_test.go
+++ b/go/cs/onehop/sender_test.go
@@ -151,7 +151,7 @@ func checkTestPkt(t *testing.T, s *Sender, msg *Msg, pkt *snet.Packet) {
 	SoMsg("path", pkt.Path, ShouldResemble, (*spath.Path)(path))
 }
 
-// testConn is a packet conn that returns an empty overlay address.
+// testConn is a packet conn that returns an empty underlay address.
 type testConn struct {
 	net.PacketConn
 }
diff --git a/go/dispatcher/config/config_test.go b/go/dispatcher/config/config_test.go
index c4603f69b..e44761065 100644
--- a/go/dispatcher/config/config_test.go
+++ b/go/dispatcher/config/config_test.go
@@ -52,6 +52,6 @@ func CheckTestConfig(t *testing.T, cfg *Config, id string) {
 	assert.Equal(t, id, cfg.Dispatcher.ID)
 	assert.Equal(t, reliable.DefaultDispPath, cfg.Dispatcher.ApplicationSocket)
 	assert.Equal(t, reliable.DefaultDispSocketFileMode, int(cfg.Dispatcher.SocketFileMode))
-	assert.Equal(t, topology.EndhostPort, cfg.Dispatcher.OverlayPort)
+	assert.Equal(t, topology.EndhostPort, cfg.Dispatcher.UnderlayPort)
 	assert.False(t, cfg.Dispatcher.DeleteSocket)
 }
diff --git a/go/dispatcher/internal/registration/svctable_test.go b/go/dispatcher/internal/registration/svctable_test.go
index b8b2ab243..dac2124e3 100644
--- a/go/dispatcher/internal/registration/svctable_test.go
+++ b/go/dispatcher/internal/registration/svctable_test.go
@@ -100,7 +100,7 @@ func TestSVCTableOneItem(t *testing.T) {
 		reference, err := table.Register(addr.SvcCS, address, value)
 		xtest.FailOnErr(t, err)
 		Convey("anycasting to nil finds the entry", func() {
-			// XXX(scrye): This is a workaround s.t. a simple overlay socket
+			// XXX(scrye): This is a workaround s.t. a simple underlay socket
 			// that does not return IP-header information can still be used to
 			// deliver to SVC addresses. Once IP-header information is passed
 			// into the app, searching for nil should not return an entry.
diff --git a/go/dispatcher/main_test.go b/go/dispatcher/main_test.go
index 3d3902c97..8fe8de708 100644
--- a/go/dispatcher/main_test.go
+++ b/go/dispatcher/main_test.go
@@ -44,7 +44,7 @@ const (
 
 type TestSettings struct {
 	ApplicationSocket string
-	OverlayPort       int
+	UnderlayPort      int
 }
 
 func InitTestSettings(t *testing.T) *TestSettings {
@@ -54,7 +54,7 @@ func InitTestSettings(t *testing.T) *TestSettings {
 	}
 	return &TestSettings{
 		ApplicationSocket: socketName,
-		OverlayPort:       int(dispatcherTestPort),
+		UnderlayPort:      int(dispatcherTestPort),
 	}
 }
 
@@ -67,41 +67,41 @@ func getSocketName(dir string) (string, error) {
 }
 
 type ClientAddress struct {
-	IA             addr.IA
-	PublicAddress  addr.HostAddr
-	PublicPort     uint16
-	ServiceAddress addr.HostSVC
-	OverlayAddress *net.UDPAddr
-	OverlayPort    uint16
+	IA              addr.IA
+	PublicAddress   addr.HostAddr
+	PublicPort      uint16
+	ServiceAddress  addr.HostSVC
+	UnderlayAddress *net.UDPAddr
+	UnderlayPort    uint16
 }
 
 // Addressing information
 var (
 	commonIA              = xtest.MustParseIA("1-ff00:0:1")
 	commonPublicL3Address = addr.HostFromIP(net.IP{127, 0, 0, 1})
-	commonOverlayAddress  = &net.UDPAddr{IP: net.IP{127, 0, 0, 1}, Port: dispatcherTestPort}
+	commonUnderlayAddress = &net.UDPAddr{IP: net.IP{127, 0, 0, 1}, Port: dispatcherTestPort}
 	clientXAddress        = &ClientAddress{
-		IA:             commonIA,
-		PublicAddress:  commonPublicL3Address,
-		PublicPort:     8080,
-		ServiceAddress: addr.SvcNone,
-		OverlayAddress: commonOverlayAddress,
+		IA:              commonIA,
+		PublicAddress:   commonPublicL3Address,
+		PublicPort:      8080,
+		ServiceAddress:  addr.SvcNone,
+		UnderlayAddress: commonUnderlayAddress,
 	}
 	clientYAddress = &ClientAddress{
-		IA:             commonIA,
-		PublicAddress:  commonPublicL3Address,
-		PublicPort:     8081,
-		ServiceAddress: addr.SvcPS,
-		OverlayAddress: commonOverlayAddress,
+		IA:              commonIA,
+		PublicAddress:   commonPublicL3Address,
+		PublicPort:      8081,
+		ServiceAddress:  addr.SvcPS,
+		UnderlayAddress: commonUnderlayAddress,
 	}
 )
 
 type TestCase struct {
-	Name           string
-	ClientAddress  *ClientAddress
-	TestPackets    []*spkt.ScnPkt
-	OverlayAddress *net.UDPAddr
-	ExpectedPacket *spkt.ScnPkt
+	Name            string
+	ClientAddress   *ClientAddress
+	TestPackets     []*spkt.ScnPkt
+	UnderlayAddress *net.UDPAddr
+	ExpectedPacket  *spkt.ScnPkt
 }
 
 var testCases = []*TestCase{
@@ -121,7 +121,7 @@ var testCases = []*TestCase{
 				Pld: common.RawBytes{1, 2, 3, 4},
 			},
 		},
-		OverlayAddress: clientXAddress.OverlayAddress,
+		UnderlayAddress: clientXAddress.UnderlayAddress,
 		ExpectedPacket: &spkt.ScnPkt{
 			SrcIA:   clientXAddress.IA,
 			DstIA:   clientXAddress.IA,
@@ -152,7 +152,7 @@ var testCases = []*TestCase{
 				Pld: common.RawBytes{5, 6, 7, 8},
 			},
 		},
-		OverlayAddress: clientXAddress.OverlayAddress,
+		UnderlayAddress: clientXAddress.UnderlayAddress,
 		ExpectedPacket: &spkt.ScnPkt{
 			SrcIA:   clientYAddress.IA,
 			DstIA:   clientYAddress.IA,
@@ -168,9 +168,9 @@ var testCases = []*TestCase{
 		},
 	},
 	{
-		Name:           "SCMP::Error, UDP quote",
-		ClientAddress:  clientXAddress,
-		OverlayAddress: clientXAddress.OverlayAddress,
+		Name:            "SCMP::Error, UDP quote",
+		ClientAddress:   clientXAddress,
+		UnderlayAddress: clientXAddress.UnderlayAddress,
 		TestPackets: []*spkt.ScnPkt{
 			{
 				SrcIA:   clientXAddress.IA,
@@ -207,9 +207,9 @@ var testCases = []*TestCase{
 		},
 	},
 	{
-		Name:           "SCMP::Error, SCMP quote",
-		ClientAddress:  clientXAddress,
-		OverlayAddress: clientXAddress.OverlayAddress,
+		Name:            "SCMP::Error, SCMP quote",
+		ClientAddress:   clientXAddress,
+		UnderlayAddress: clientXAddress.UnderlayAddress,
 		TestPackets: []*spkt.ScnPkt{
 			{
 				// Force a SCMP General ID registration to happen, but route it
@@ -289,9 +289,9 @@ var testCases = []*TestCase{
 		},
 	},
 	{
-		Name:           "SCMP::General::EchoRequest",
-		ClientAddress:  clientXAddress,
-		OverlayAddress: clientYAddress.OverlayAddress,
+		Name:            "SCMP::General::EchoRequest",
+		ClientAddress:   clientXAddress,
+		UnderlayAddress: clientYAddress.UnderlayAddress,
 		TestPackets: []*spkt.ScnPkt{
 			{
 				SrcIA:   clientXAddress.IA,
@@ -331,9 +331,9 @@ var testCases = []*TestCase{
 		},
 	},
 	{
-		Name:           "SCMP::General::TraceRouteRequest",
-		ClientAddress:  clientXAddress,
-		OverlayAddress: clientYAddress.OverlayAddress,
+		Name:            "SCMP::General::TraceRouteRequest",
+		ClientAddress:   clientXAddress,
+		UnderlayAddress: clientYAddress.UnderlayAddress,
 		TestPackets: []*spkt.ScnPkt{
 			{
 				SrcIA:   clientXAddress.IA,
@@ -373,9 +373,9 @@ var testCases = []*TestCase{
 		},
 	},
 	{
-		Name:           "SCMP::General::RecordPathRequest",
-		ClientAddress:  clientXAddress,
-		OverlayAddress: clientYAddress.OverlayAddress,
+		Name:            "SCMP::General::RecordPathRequest",
+		ClientAddress:   clientXAddress,
+		UnderlayAddress: clientYAddress.UnderlayAddress,
 		TestPackets: []*spkt.ScnPkt{
 			{
 				SrcIA:   clientXAddress.IA,
@@ -421,7 +421,7 @@ func TestDataplaneIntegration(t *testing.T) {
 
 	go func() {
 		err := RunDispatcher(false, settings.ApplicationSocket, reliable.DefaultDispSocketFileMode,
-			settings.OverlayPort)
+			settings.UnderlayPort)
 		xtest.FailOnErr(t, err, "dispatcher error")
 	}()
 	time.Sleep(defaultWaitDuration)
@@ -458,7 +458,7 @@ func RunTestCase(t *testing.T, tc *TestCase, settings *TestSettings) {
 		xtest.FailOnErr(t, err, "unable to serialize packet for sending")
 		send_buffer = send_buffer[:n]
 
-		_, err = conn.WriteTo(send_buffer, tc.OverlayAddress)
+		_, err = conn.WriteTo(send_buffer, tc.UnderlayAddress)
 		xtest.FailOnErr(t, err, "unable to write message")
 	}
 
diff --git a/go/lib/infra/messenger/addr_test.go b/go/lib/infra/messenger/addr_test.go
index dbbf30697..de91a8b0e 100644
--- a/go/lib/infra/messenger/addr_test.go
+++ b/go/lib/infra/messenger/addr_test.go
@@ -97,7 +97,7 @@ func TestRedirectQUIC(t *testing.T) {
 		path := mock_snet.NewMockPath(ctrl)
 		router.EXPECT().Route(gomock.Any(), gomock.Any()).Return(path, nil)
 		path.EXPECT().Path().Return(nil)
-		path.EXPECT().OverlayNextHop().Return(&net.UDPAddr{IP: net.ParseIP("10.1.1.1")})
+		path.EXPECT().UnderlayNextHop().Return(&net.UDPAddr{IP: net.ParseIP("10.1.1.1")})
 		path.EXPECT().Fingerprint().Return(snet.PathFingerprint("foo"))
 
 		aw := messenger.AddressRewriter{
@@ -131,7 +131,7 @@ func TestRedirectQUIC(t *testing.T) {
 		path := mock_snet.NewMockPath(ctrl)
 		router.EXPECT().Route(gomock.Any(), gomock.Any()).Return(path, nil)
 		path.EXPECT().Path().Return(nil)
-		path.EXPECT().OverlayNextHop().Return(&net.UDPAddr{IP: net.ParseIP("10.1.1.1")})
+		path.EXPECT().UnderlayNextHop().Return(&net.UDPAddr{IP: net.ParseIP("10.1.1.1")})
 		path.EXPECT().Fingerprint().Return(snet.PathFingerprint("foo"))
 
 		aw := messenger.AddressRewriter{
@@ -161,10 +161,10 @@ func TestRedirectQUIC(t *testing.T) {
 		path := mock_snet.NewMockPath(ctrl)
 		router.EXPECT().Route(gomock.Any(), gomock.Any()).Return(path, nil)
 		path.EXPECT().Path().Return(nil)
-		path.EXPECT().OverlayNextHop().Return(&net.UDPAddr{IP: net.ParseIP("10.1.1.1")})
+		path.EXPECT().UnderlayNextHop().Return(&net.UDPAddr{IP: net.ParseIP("10.1.1.1")})
 		path.EXPECT().Fingerprint().Return(snet.PathFingerprint(""))
 		svcRouter := mock_messenger.NewMockLocalSVCRouter(ctrl)
-		svcRouter.EXPECT().GetOverlay(addr.SvcBS).Return(
+		svcRouter.EXPECT().GetUnderlay(addr.SvcBS).Return(
 			&net.UDPAddr{IP: net.ParseIP("10.1.1.1")}, nil,
 		)
 
@@ -233,7 +233,7 @@ func TestBuildFullAddress(t *testing.T) {
 
 		path := mock_snet.NewMockPath(ctrl)
 		path.EXPECT().Path().Return(&spath.Path{})
-		path.EXPECT().OverlayNextHop().Return(&net.UDPAddr{})
+		path.EXPECT().UnderlayNextHop().Return(&net.UDPAddr{})
 		path.EXPECT().Fingerprint().Return(snet.PathFingerprint("foo"))
 		router.EXPECT().Route(gomock.Any(), gomock.Any()).Return(path, nil)
 		input := &snet.SVCAddr{IA: remoteIA, SVC: addr.SvcBS}
@@ -248,7 +248,7 @@ func TestBuildFullAddress(t *testing.T) {
 		assert.NoError(t, err)
 	})
 
-	t.Run("snet address in local AS, overlay address extraction succeeds", func(t *testing.T) {
+	t.Run("snet address in local AS, underlay address extraction succeeds", func(t *testing.T) {
 		ctrl := gomock.NewController(t)
 		defer ctrl.Finish()
 		router := mock_snet.NewMockRouter(ctrl)
@@ -259,27 +259,27 @@ func TestBuildFullAddress(t *testing.T) {
 			SVCRouter: svcRouter,
 		}
 
-		overlayAddr := &net.UDPAddr{
+		underlayAddr := &net.UDPAddr{
 			IP:   net.IP{192, 168, 0, 1},
 			Port: 10,
 		}
-		svcRouter.EXPECT().GetOverlay(addr.SvcBS).Return(overlayAddr, nil)
+		svcRouter.EXPECT().GetUnderlay(addr.SvcBS).Return(underlayAddr, nil)
 
 		path := mock_snet.NewMockPath(ctrl)
 		path.EXPECT().Fingerprint()
 		path.EXPECT().Path()
-		path.EXPECT().OverlayNextHop()
+		path.EXPECT().UnderlayNextHop()
 		router.EXPECT().Route(gomock.Any(), gomock.Any()).Return(path, nil)
 
 		input := &snet.SVCAddr{IA: localIA, SVC: addr.SvcBS}
 		a, err := aw.BuildFullAddress(context.Background(), input)
 
-		want := &snet.SVCAddr{IA: localIA, NextHop: overlayAddr, SVC: addr.SvcBS}
+		want := &snet.SVCAddr{IA: localIA, NextHop: underlayAddr, SVC: addr.SvcBS}
 		assert.Equal(t, a, want)
 		assert.NoError(t, err)
 	})
 
-	t.Run("snet address in local AS, overlay address extraction fails", func(t *testing.T) {
+	t.Run("snet address in local AS, underlay address extraction fails", func(t *testing.T) {
 		ctrl := gomock.NewController(t)
 		defer ctrl.Finish()
 		router := mock_snet.NewMockRouter(ctrl)
@@ -290,12 +290,12 @@ func TestBuildFullAddress(t *testing.T) {
 			SVCRouter: svcRouter,
 		}
 
-		svcRouter.EXPECT().GetOverlay(addr.SvcBS).Return(nil, errors.New("err"))
+		svcRouter.EXPECT().GetUnderlay(addr.SvcBS).Return(nil, errors.New("err"))
 
 		path := mock_snet.NewMockPath(ctrl)
 		path.EXPECT().Fingerprint()
 		path.EXPECT().Path()
-		path.EXPECT().OverlayNextHop()
+		path.EXPECT().UnderlayNextHop()
 		router.EXPECT().Route(gomock.Any(), gomock.Any()).Return(path, nil)
 
 		input := &snet.SVCAddr{IA: localIA, SVC: addr.SvcBS}
@@ -454,7 +454,7 @@ func (t *testPath) Fingerprint() snet.PathFingerprint {
 	panic("not implemented")
 }
 
-func (t *testPath) OverlayNextHop() *net.UDPAddr {
+func (t *testPath) UnderlayNextHop() *net.UDPAddr {
 	panic("not implemented")
 }
 
diff --git a/go/lib/infra/modules/trust/router_test.go b/go/lib/infra/modules/trust/router_test.go
index 0bf9e1485..e7a55a628 100644
--- a/go/lib/infra/modules/trust/router_test.go
+++ b/go/lib/infra/modules/trust/router_test.go
@@ -64,7 +64,7 @@ func TestCSRouterChooseServer(t *testing.T) {
 			Expect: func(_ *mock_trust.MockDB, r *mock_snet.MockRouter, p *mock_snet.MockPath) {
 				p.EXPECT().Path().AnyTimes().Return(&spath.Path{Raw: []byte("isd local path")})
 				p.EXPECT().Destination().AnyTimes().Return(ia110)
-				p.EXPECT().OverlayNextHop().AnyTimes().Return(nil)
+				p.EXPECT().UnderlayNextHop().AnyTimes().Return(nil)
 				r.EXPECT().Route(gomock.Any(), addr.IA{I: 1}).Return(p, nil)
 			},
 		},
@@ -87,7 +87,7 @@ func TestCSRouterChooseServer(t *testing.T) {
 				)
 				p.EXPECT().Path().AnyTimes().Return(&spath.Path{Raw: []byte("remote ISD path")})
 				p.EXPECT().Destination().AnyTimes().Return(ia210)
-				p.EXPECT().OverlayNextHop().AnyTimes().Return(nil)
+				p.EXPECT().UnderlayNextHop().AnyTimes().Return(nil)
 				r.EXPECT().Route(gomock.Any(), addr.IA{I: 2}).Return(p, nil)
 			},
 		},
@@ -100,7 +100,7 @@ func TestCSRouterChooseServer(t *testing.T) {
 				)
 				p.EXPECT().Path().AnyTimes().Return(&spath.Path{Raw: []byte("isd local path")})
 				p.EXPECT().Destination().AnyTimes().Return(ia110)
-				p.EXPECT().OverlayNextHop().AnyTimes().Return(nil)
+				p.EXPECT().UnderlayNextHop().AnyTimes().Return(nil)
 				r.EXPECT().Route(gomock.Any(), addr.IA{I: 1}).Return(p, nil)
 			},
 		},
@@ -114,7 +114,7 @@ func TestCSRouterChooseServer(t *testing.T) {
 				)
 				p.EXPECT().Path().AnyTimes().Return(&spath.Path{Raw: []byte("isd local path")})
 				p.EXPECT().Destination().AnyTimes().Return(ia110)
-				p.EXPECT().OverlayNextHop().AnyTimes().Return(nil)
+				p.EXPECT().UnderlayNextHop().AnyTimes().Return(nil)
 				r.EXPECT().Route(gomock.Any(), addr.IA{I: 1}).Return(p, nil)
 			},
 		},
@@ -149,7 +149,7 @@ func TestCSRouterChooseServer(t *testing.T) {
 				expected := &snet.SVCAddr{
 					IA:      p.Destination(),
 					Path:    p.Path(),
-					NextHop: p.OverlayNextHop(),
+					NextHop: p.UnderlayNextHop(),
 					SVC:     addr.SvcCS,
 				}
 				assert.Equal(t, expected, res)
diff --git a/go/lib/sciond/fake/fake_test.go b/go/lib/sciond/fake/fake_test.go
index f308ca5b1..f39586ceb 100644
--- a/go/lib/sciond/fake/fake_test.go
+++ b/go/lib/sciond/fake/fake_test.go
@@ -107,7 +107,7 @@ func TestPaths(t *testing.T) {
 
 	require.Equal(t, 1, len(paths))
 	assert.Equal(t, "Foo", string(paths[0].Fingerprint()))
-	assert.Equal(t, &net.UDPAddr{IP: net.IP{10, 0, 0, 1}, Port: 80}, paths[0].OverlayNextHop())
+	assert.Equal(t, &net.UDPAddr{IP: net.IP{10, 0, 0, 1}, Port: 80}, paths[0].UnderlayNextHop())
 	assert.Equal(t, fake.DummyPath(), paths[0].Path())
 	assert.Equal(t, []snet.PathInterface{}, paths[0].Interfaces())
 	assert.Equal(t, xtest.MustParseIA("1-ff00:0:1"), paths[0].Destination())
@@ -128,7 +128,7 @@ func TestPaths(t *testing.T) {
 
 	require.Equal(t, 1, len(paths))
 	assert.Equal(t, "Foo2", string(paths[0].Fingerprint()))
-	assert.Equal(t, &net.UDPAddr{IP: net.IP{10, 0, 0, 2}, Port: 80}, paths[0].OverlayNextHop())
+	assert.Equal(t, &net.UDPAddr{IP: net.IP{10, 0, 0, 2}, Port: 80}, paths[0].UnderlayNextHop())
 	assert.Equal(t, fake.DummyPath(), paths[0].Path())
 	assert.Equal(t, []snet.PathInterface{}, paths[0].Interfaces())
 	assert.Equal(t, xtest.MustParseIA("2-ff00:0:2"), paths[0].Destination())
diff --git a/go/lib/sock/reliable/frame_test.go b/go/lib/sock/reliable/frame_test.go
index 1e98cf04a..6c28d164f 100644
--- a/go/lib/sock/reliable/frame_test.go
+++ b/go/lib/sock/reliable/frame_test.go
@@ -23,22 +23,22 @@ import (
 	"github.com/scionproto/scion/go/lib/xtest"
 )
 
-func TestOverlayPacketSerializeTo(t *testing.T) {
+func TestUnderlayPacketSerializeTo(t *testing.T) {
 	type TestCase struct {
 		Name          string
-		Packet        *OverlayPacket
+		Packet        *UnderlayPacket
 		ExpectedData  []byte
 		ExpectedError error
 	}
 	testCases := []TestCase{
 		{
 			Name:         "none type address, no data",
-			Packet:       &OverlayPacket{},
+			Packet:       &UnderlayPacket{},
 			ExpectedData: []byte{0xde, 0, 0xad, 1, 0xbe, 2, 0xef, 3, 0, 0, 0, 0, 0},
 		},
 		{
 			Name: "empty IP address",
-			Packet: &OverlayPacket{
+			Packet: &UnderlayPacket{
 				Address: &net.UDPAddr{},
 			},
 			ExpectedError: ErrNoAddress,
@@ -46,7 +46,7 @@ func TestOverlayPacketSerializeTo(t *testing.T) {
 		},
 		{
 			Name: "IPv4 host, with address, no port, no data",
-			Packet: &OverlayPacket{
+			Packet: &UnderlayPacket{
 				Address: &net.UDPAddr{IP: net.ParseIP("1.2.3.4")},
 			},
 			ExpectedError: ErrNoPort,
@@ -54,7 +54,7 @@ func TestOverlayPacketSerializeTo(t *testing.T) {
 		},
 		{
 			Name: "IPv4 host, with address, with port, no data",
-			Packet: &OverlayPacket{
+			Packet: &UnderlayPacket{
 				Address: &net.UDPAddr{IP: net.ParseIP("10.2.3.4"), Port: 80},
 			},
 			ExpectedData: []byte{0xde, 0, 0xad, 1, 0xbe, 2, 0xef, 3, 1, 0, 0, 0, 0,
@@ -62,7 +62,7 @@ func TestOverlayPacketSerializeTo(t *testing.T) {
 		},
 		{
 			Name: "IPv6 host, with address, with port, no data",
-			Packet: &OverlayPacket{
+			Packet: &UnderlayPacket{
 				Address: &net.UDPAddr{IP: net.ParseIP("2001:db8::1"), Port: 80},
 			},
 			ExpectedData: []byte{0xde, 0, 0xad, 1, 0xbe, 2, 0xef, 3, 2, 0, 0, 0, 0,
@@ -71,7 +71,7 @@ func TestOverlayPacketSerializeTo(t *testing.T) {
 		},
 		{
 			Name: "IPv4 host, with address, big port, no data",
-			Packet: &OverlayPacket{
+			Packet: &UnderlayPacket{
 				Address: &net.UDPAddr{IP: net.ParseIP("10.2.3.4"), Port: 0x1234},
 			},
 			ExpectedData: []byte{0xde, 0, 0xad, 1, 0xbe, 2, 0xef, 3, 1, 0, 0, 0, 0,
@@ -79,7 +79,7 @@ func TestOverlayPacketSerializeTo(t *testing.T) {
 		},
 		{
 			Name: "long payload",
-			Packet: &OverlayPacket{
+			Packet: &UnderlayPacket{
 				Address: &net.UDPAddr{IP: net.ParseIP("1.2.3.4"), Port: 80},
 				Payload: make([]byte, 2000),
 			},
@@ -88,7 +88,7 @@ func TestOverlayPacketSerializeTo(t *testing.T) {
 		},
 		{
 			Name: "good payload",
-			Packet: &OverlayPacket{
+			Packet: &UnderlayPacket{
 				Address: &net.UDPAddr{IP: net.ParseIP("10.2.3.4"), Port: 80},
 				Payload: []byte{10, 5, 6, 7},
 			},
@@ -108,11 +108,11 @@ func TestOverlayPacketSerializeTo(t *testing.T) {
 	})
 }
 
-func TestOverlayPacketDecodeFromBytes(t *testing.T) {
+func TestUnderlayPacketDecodeFromBytes(t *testing.T) {
 	type TestCase struct {
 		Name           string
 		Buffer         []byte
-		ExpectedPacket OverlayPacket
+		ExpectedPacket UnderlayPacket
 		ExpectedError  error
 	}
 	testCases := []TestCase{
@@ -158,7 +158,7 @@ func TestOverlayPacketDecodeFromBytes(t *testing.T) {
 		{
 			Name:   "good packet (none type address)",
 			Buffer: []byte{0xde, 0, 0xad, 1, 0xbe, 2, 0xef, 3, 0, 0, 0, 0, 1, 42},
-			ExpectedPacket: OverlayPacket{
+			ExpectedPacket: UnderlayPacket{
 				Payload: []byte{42},
 			},
 		},
@@ -166,7 +166,7 @@ func TestOverlayPacketDecodeFromBytes(t *testing.T) {
 			Name: "good packet (IPv4)",
 			Buffer: []byte{0xde, 0, 0xad, 1, 0xbe, 2, 0xef, 3, 1, 0, 0, 0, 1,
 				10, 2, 3, 4, 0, 80, 42},
-			ExpectedPacket: OverlayPacket{
+			ExpectedPacket: UnderlayPacket{
 				Address: &net.UDPAddr{IP: net.IP{10, 2, 3, 4}, Port: 80},
 				Payload: []byte{42},
 			},
@@ -176,7 +176,7 @@ func TestOverlayPacketDecodeFromBytes(t *testing.T) {
 			Buffer: []byte{0xde, 0, 0xad, 1, 0xbe, 2, 0xef, 3, 2, 0, 0, 0, 1,
 				0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
 				0, 80, 42},
-			ExpectedPacket: OverlayPacket{
+			ExpectedPacket: UnderlayPacket{
 				Address: &net.UDPAddr{IP: net.ParseIP("2001:db8::1"), Port: 80},
 				Payload: []byte{42},
 			},
@@ -185,7 +185,7 @@ func TestOverlayPacketDecodeFromBytes(t *testing.T) {
 	t.Run("Different packets decode correctly", func(t *testing.T) {
 		for _, tc := range testCases {
 			t.Run(tc.Name, func(t *testing.T) {
-				var p OverlayPacket
+				var p UnderlayPacket
 				err := p.DecodeFromBytes(tc.Buffer)
 				xtest.AssertErrorsIs(t, err, tc.ExpectedError)
 				assert.Equal(t, tc.ExpectedPacket, p)
diff --git a/go/lib/svc/resolver_test.go b/go/lib/svc/resolver_test.go
index fa6460b2d..5a47b515b 100644
--- a/go/lib/svc/resolver_test.go
+++ b/go/lib/svc/resolver_test.go
@@ -43,7 +43,7 @@ func TestResolver(t *testing.T) {
 		dstIA := xtest.MustParseIA("1-ff00:0:2")
 		mockPath := mock_snet.NewMockPath(ctrl)
 		mockPath.EXPECT().Path().Return(nil).AnyTimes()
-		mockPath.EXPECT().OverlayNextHop().Return(nil).AnyTimes()
+		mockPath.EXPECT().UnderlayNextHop().Return(nil).AnyTimes()
 		mockPath.EXPECT().Destination().Return(dstIA).AnyTimes()
 
 		Convey("If opening up port fails, return error and no reply", func() {
@@ -88,25 +88,25 @@ func TestRoundTripper(t *testing.T) {
 	testCases := []struct {
 		Description   string
 		InputPacket   *snet.Packet
-		InputOverlay  *net.UDPAddr
+		InputUnderlay *net.UDPAddr
 		ExpectedError bool
 		ExpectedReply *svc.Reply
 		ConnSetup     func(*mock_snet.MockPacketConn)
 	}{
 		{
 			Description:   "nil packet returns error",
-			InputOverlay:  &net.UDPAddr{},
+			InputUnderlay: &net.UDPAddr{},
 			ExpectedError: true,
 		},
 		{
-			Description:   "nil overlay returns error",
+			Description:   "nil underlay returns error",
 			InputPacket:   &snet.Packet{},
 			ExpectedError: true,
 		},
 		{
 			Description:   "if write fails, return error",
 			InputPacket:   &snet.Packet{},
-			InputOverlay:  &net.UDPAddr{},
+			InputUnderlay: &net.UDPAddr{},
 			ExpectedError: true,
 			ConnSetup: func(c *mock_snet.MockPacketConn) {
 				c.EXPECT().WriteTo(gomock.Any(), gomock.Any()).Return(errors.New("write err"))
@@ -115,7 +115,7 @@ func TestRoundTripper(t *testing.T) {
 		{
 			Description:   "if read fails, return error",
 			InputPacket:   &snet.Packet{},
-			InputOverlay:  &net.UDPAddr{},
+			InputUnderlay: &net.UDPAddr{},
 			ExpectedError: true,
 			ConnSetup: func(c *mock_snet.MockPacketConn) {
 				c.EXPECT().WriteTo(gomock.Any(), gomock.Any()).Return(nil)
@@ -125,7 +125,7 @@ func TestRoundTripper(t *testing.T) {
 		{
 			Description:   "if bad payload type, return error",
 			InputPacket:   &snet.Packet{},
-			InputOverlay:  &net.UDPAddr{},
+			InputUnderlay: &net.UDPAddr{},
 			ExpectedError: true,
 			ConnSetup: func(c *mock_snet.MockPacketConn) {
 				c.EXPECT().WriteTo(gomock.Any(), gomock.Any()).Return(nil)
@@ -140,7 +140,7 @@ func TestRoundTripper(t *testing.T) {
 		{
 			Description:   "if reply cannot be parsed, return error",
 			InputPacket:   &snet.Packet{},
-			InputOverlay:  &net.UDPAddr{},
+			InputUnderlay: &net.UDPAddr{},
 			ExpectedError: true,
 			ConnSetup: func(c *mock_snet.MockPacketConn) {
 				c.EXPECT().WriteTo(gomock.Any(), gomock.Any()).Return(nil)
@@ -153,9 +153,9 @@ func TestRoundTripper(t *testing.T) {
 			},
 		},
 		{
-			Description:  "successful operation",
-			InputPacket:  &snet.Packet{},
-			InputOverlay: &net.UDPAddr{},
+			Description:   "successful operation",
+			InputPacket:   &snet.Packet{},
+			InputUnderlay: &net.UDPAddr{},
 			ConnSetup: func(c *mock_snet.MockPacketConn) {
 				c.EXPECT().WriteTo(gomock.Any(), gomock.Any()).Return(nil)
 				c.EXPECT().ReadFrom(gomock.Any(), gomock.Any()).DoAndReturn(
@@ -184,7 +184,7 @@ func TestRoundTripper(t *testing.T) {
 				}
 				roundTripper := svc.DefaultRoundTripper()
 				reply, err := roundTripper.RoundTrip(context.Background(), conn, tc.InputPacket,
-					tc.InputOverlay)
+					tc.InputUnderlay)
 				xtest.SoMsgError("err", err, tc.ExpectedError)
 				// FIXME(scrye): also test that paths are processed correctly
 				if reply != nil {
diff --git a/go/lib/svc/svc_test.go b/go/lib/svc/svc_test.go
index aec598274..2c8a46000 100644
--- a/go/lib/svc/svc_test.go
+++ b/go/lib/svc/svc_test.go
@@ -240,7 +240,7 @@ func TestDefaultHandler(t *testing.T) {
 		}
 	})
 
-	Convey("Overlay addresses are forwarded", t, func() {
+	Convey("Underlay addresses are forwarded", t, func() {
 		ctrl := gomock.NewController(t)
 		defer ctrl.Finish()
 
@@ -251,10 +251,10 @@ func TestDefaultHandler(t *testing.T) {
 		sender := &svc.BaseHandler{}
 
 		request := &svc.Request{
-			Conn:    conn,
-			Source:  snet.SCIONAddress{},
-			Packet:  packet,
-			Overlay: ov,
+			Conn:     conn,
+			Source:   snet.SCIONAddress{},
+			Packet:   packet,
+			Underlay: ov,
 		}
 		_, err := sender.Handle(request)
 		So(err, ShouldBeNil)
diff --git a/go/lib/topology/json/json_test.go b/go/lib/topology/json/json_test.go
index b88965abe..db5511b44 100644
--- a/go/lib/topology/json/json_test.go
+++ b/go/lib/topology/json/json_test.go
@@ -28,7 +28,7 @@ import (
 	"github.com/scionproto/scion/go/lib/common"
 	"github.com/scionproto/scion/go/lib/scrypto/trc"
 	jsontopo "github.com/scionproto/scion/go/lib/topology/json"
-	"github.com/scionproto/scion/go/lib/topology/overlay"
+	"github.com/scionproto/scion/go/lib/topology/underlay"
 )
 
 var (
@@ -42,7 +42,7 @@ func TestLoadRawFromFile(t *testing.T) {
 		IA:             "6-ff00:0:362",
 		MTU:            1472,
 		Attributes:     []trc.Attribute{trc.Authoritative, trc.Core, trc.Issuing, trc.Voting},
-		Overlay:        overlay.UDPIPv46Name,
+		Underlay:       underlay.UDPIPv46Name,
 		BorderRouters: map[string]*jsontopo.BRInfo{
 			"borderrouter6-f00:0:362-1": {
 				InternalAddrs: jsontopo.UnderlayAddressMap{
diff --git a/go/lib/topology/topology_test.go b/go/lib/topology/topology_test.go
index 5d4c2417c..547d74b22 100644
--- a/go/lib/topology/topology_test.go
+++ b/go/lib/topology/topology_test.go
@@ -28,7 +28,7 @@ import (
 	"github.com/scionproto/scion/go/lib/addr"
 	"github.com/scionproto/scion/go/lib/common"
 	jsontopo "github.com/scionproto/scion/go/lib/topology/json"
-	"github.com/scionproto/scion/go/lib/topology/overlay"
+	"github.com/scionproto/scion/go/lib/topology/underlay"
 	"github.com/scionproto/scion/go/lib/xtest"
 )
 
@@ -148,7 +148,7 @@ func TestIFInfoMap(t *testing.T) {
 				},
 				UnderlayAddress: &net.UDPAddr{IP: net.ParseIP("2001:db8:a0b:12f0::1"), Port: 30041},
 			},
-			Underlay: overlay.UDPIPv4,
+			Underlay: underlay.UDPIPv4,
 			Local: &net.UDPAddr{
 				IP:   net.IP{10, 0, 0, 1},
 				Port: 44997,
@@ -176,7 +176,7 @@ func TestIFInfoMap(t *testing.T) {
 				},
 				UnderlayAddress: &net.UDPAddr{IP: net.ParseIP("2001:db8:a0b:12f0::1"), Port: 30041},
 			},
-			Underlay: overlay.UDPIPv6,
+			Underlay: underlay.UDPIPv6,
 			Local: &net.UDPAddr{
 				IP:   net.ParseIP("2001:db8:a0b:12f0::8"),
 				Port: 44997,
@@ -204,7 +204,7 @@ func TestIFInfoMap(t *testing.T) {
 				},
 				UnderlayAddress: &net.UDPAddr{IP: net.ParseIP("2001:db8:a0b:12f0::1"), Port: 30041},
 			},
-			Underlay: overlay.UDPIPv4,
+			Underlay: underlay.UDPIPv4,
 			Local: &net.UDPAddr{
 				IP:   net.IP{10, 0, 0, 2},
 				Port: 44997,
@@ -238,7 +238,7 @@ func TestIFInfoMap(t *testing.T) {
 					Zone: "some-ctrl-zone",
 				},
 			},
-			Underlay: overlay.UDPIPv6,
+			Underlay: underlay.UDPIPv6,
 			Local: &net.UDPAddr{
 				IP:   net.ParseIP("2001:db8:a0b:12f0::8"),
 				Port: 44897,
@@ -275,7 +275,7 @@ func TestIFInfoMapCoreAS(t *testing.T) {
 				},
 				UnderlayAddress: &net.UDPAddr{IP: net.ParseIP("2001:db8:a0b:12f0::1"), Port: 30041},
 			},
-			Underlay: overlay.UDPIPv4,
+			Underlay: underlay.UDPIPv4,
 			Local: &net.UDPAddr{
 				IP:   net.IP{10, 0, 0, 1},
 				Port: 4997,
@@ -303,7 +303,7 @@ func TestIFInfoMapCoreAS(t *testing.T) {
 				},
 				UnderlayAddress: &net.UDPAddr{IP: net.ParseIP("2001:db8:a0b:12f0::2"), Port: 30041},
 			},
-			Underlay: overlay.UDPIPv6,
+			Underlay: underlay.UDPIPv6,
 			Local: &net.UDPAddr{
 				IP:   net.ParseIP("2001:db8:a0b:12f0::8"),
 				Port: 4997,
@@ -541,7 +541,7 @@ func TestExternalDataPlanePort(t *testing.T) {
 			ExpectedError: assert.Error,
 		},
 		{
-			Name: "Empty with overlay",
+			Name: "Empty with underlay",
 			Raw: &jsontopo.BRInterface{
 				Underlay: "UDP/IPv4",
 			},
diff --git a/go/lib/topology/overlay/defs_test.go b/go/lib/topology/underlay/defs_test.go
similarity index 83%
rename from go/lib/topology/overlay/defs_test.go
rename to go/lib/topology/underlay/defs_test.go
index 5548c71fb..f97534b5b 100644
--- a/go/lib/topology/overlay/defs_test.go
+++ b/go/lib/topology/underlay/defs_test.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package overlay_test
+package underlay_test
 
 import (
 	"encoding/json"
@@ -21,14 +21,14 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
-	"github.com/scionproto/scion/go/lib/topology/overlay"
+	"github.com/scionproto/scion/go/lib/topology/underlay"
 )
 
 func TestTypeUnmarshalJSON(t *testing.T) {
 	type exampleStruct struct {
-		Type overlay.Type `json:"type"`
+		Type underlay.Type `json:"type"`
 	}
 	var e exampleStruct
 	require.NoError(t, json.Unmarshal([]byte(`{"type": "UDP/IPv4"}`), &e))
-	assert.Equal(t, exampleStruct{Type: overlay.UDPIPv4}, e)
+	assert.Equal(t, exampleStruct{Type: underlay.UDPIPv4}, e)
 }