tstest/natlab: allow sensible default construction of networks.

Add a test for LAN->LAN traffic.

Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
David Anderson 2020-07-03 00:52:58 +00:00
parent 9cd4e65191
commit f2e5da916a
2 changed files with 68 additions and 12 deletions

View File

@ -34,8 +34,9 @@ func mustPrefix(s string) netaddr.IPPrefix {
// NewInternet returns a network that simulates the internet. // NewInternet returns a network that simulates the internet.
func NewInternet() *Network { func NewInternet() *Network {
return &Network{ return &Network{
v4Pool: mustPrefix("203.0.113.0/24"), // documentation netblock that looks Internet-y Name: "internet",
v6Pool: mustPrefix("fc00:52::/64"), Prefix4: mustPrefix("203.0.113.0/24"), // documentation netblock that looks Internet-y
Prefix6: mustPrefix("fc00:52::/64"),
pushRoutes: []netaddr.IPPrefix{ pushRoutes: []netaddr.IPPrefix{
mustPrefix("0.0.0.0/0"), mustPrefix("0.0.0.0/0"),
mustPrefix("::/0"), mustPrefix("::/0"),
@ -44,9 +45,9 @@ func NewInternet() *Network {
} }
type Network struct { type Network struct {
name string Name string
v4Pool netaddr.IPPrefix Prefix4 netaddr.IPPrefix
v6Pool netaddr.IPPrefix Prefix6 netaddr.IPPrefix
pushRoutes []netaddr.IPPrefix pushRoutes []netaddr.IPPrefix
@ -69,13 +70,16 @@ func (n *Network) addMachineLocked(ip netaddr.IP, m *Machine) {
func (n *Network) allocIPv4(m *Machine) netaddr.IP { func (n *Network) allocIPv4(m *Machine) netaddr.IP {
n.mu.Lock() n.mu.Lock()
defer n.mu.Unlock() defer n.mu.Unlock()
if n.Prefix4.IsZero() {
return netaddr.IP{}
}
if n.lastV4.IsZero() { if n.lastV4.IsZero() {
n.lastV4 = n.v4Pool.IP n.lastV4 = n.Prefix4.IP
} }
a := n.lastV4.As16() a := n.lastV4.As16()
addOne(&a, 15) addOne(&a, 15)
n.lastV4 = netaddr.IPFrom16(a) n.lastV4 = netaddr.IPFrom16(a)
if !n.v4Pool.Contains(n.lastV4) { if !n.Prefix4.Contains(n.lastV4) {
panic("pool exhausted") panic("pool exhausted")
} }
n.addMachineLocked(n.lastV4, m) n.addMachineLocked(n.lastV4, m)
@ -85,13 +89,16 @@ func (n *Network) allocIPv4(m *Machine) netaddr.IP {
func (n *Network) allocIPv6(m *Machine) netaddr.IP { func (n *Network) allocIPv6(m *Machine) netaddr.IP {
n.mu.Lock() n.mu.Lock()
defer n.mu.Unlock() defer n.mu.Unlock()
if n.Prefix6.IsZero() {
return netaddr.IP{}
}
if n.lastV6.IsZero() { if n.lastV6.IsZero() {
n.lastV6 = n.v6Pool.IP n.lastV6 = n.Prefix6.IP
} }
a := n.lastV6.As16() a := n.lastV6.As16()
addOne(&a, 15) addOne(&a, 15)
n.lastV6 = netaddr.IPFrom16(a) n.lastV6 = netaddr.IPFrom16(a)
if !n.v6Pool.Contains(n.lastV6) { if !n.Prefix6.Contains(n.lastV6) {
panic("pool exhausted") panic("pool exhausted")
} }
n.addMachineLocked(n.lastV6, m) n.addMachineLocked(n.lastV6, m)
@ -235,6 +242,15 @@ func (m *Machine) Attach(interfaceName string, n *Network) *Interface {
m.interfaces = append(m.interfaces, f) m.interfaces = append(m.interfaces, f)
if n.pushRoutes == nil {
if !n.Prefix4.IsZero() {
n.pushRoutes = append(n.pushRoutes, n.Prefix4)
}
if !n.Prefix6.IsZero() {
n.pushRoutes = append(n.pushRoutes, n.Prefix6)
}
}
for _, pfx := range n.pushRoutes { for _, pfx := range n.pushRoutes {
m.routes = append(m.routes, routeEntry{ m.routes = append(m.routes, routeEntry{
prefix: pfx, prefix: pfx,

View File

@ -46,9 +46,6 @@ func TestSendPacket(t *testing.T) {
ifFoo := foo.Attach("eth0", internet) ifFoo := foo.Attach("eth0", internet)
ifBar := bar.Attach("enp0s1", internet) ifBar := bar.Attach("enp0s1", internet)
t.Logf("foo IP: %v, %v", ifFoo.V4(), ifFoo.V6())
t.Logf("bar IP: %v, %v", ifBar.V4(), ifBar.V6())
fooAddr := netaddr.IPPort{IP: ifFoo.V4(), Port: 123} fooAddr := netaddr.IPPort{IP: ifFoo.V4(), Port: 123}
barAddr := netaddr.IPPort{IP: ifBar.V4(), Port: 456} barAddr := netaddr.IPPort{IP: ifBar.V4(), Port: 456}
@ -79,3 +76,46 @@ func TestSendPacket(t *testing.T) {
t.Errorf("addr = %q; want %q", addr, fooAddr) t.Errorf("addr = %q; want %q", addr, fooAddr)
} }
} }
func TestLAN(t *testing.T) {
// TODO: very duplicate-ey with the previous test, but important
// right now to test explicit construction of Networks.
lan := Network{
Name: "lan1",
Prefix4: mustPrefix("192.168.0.0/24"),
}
foo := NewMachine("foo")
bar := NewMachine("bar")
ifFoo := foo.Attach("eth0", &lan)
ifBar := bar.Attach("eth0", &lan)
fooPC, err := foo.ListenPacket("udp4", ":123")
if err != nil {
t.Fatal(err)
}
barPC, err := bar.ListenPacket("udp4", ":456")
if err != nil {
t.Fatal(err)
}
const msg = "message"
barAddr := netaddr.IPPort{IP: ifBar.V4(), Port: 456}
if _, err := fooPC.WriteTo([]byte(msg), barAddr.UDPAddr()); err != nil {
t.Fatal(err)
}
buf := make([]byte, 1500)
n, addr, err := barPC.ReadFrom(buf)
if err != nil {
t.Fatal(err)
}
buf = buf[:n]
if string(buf) != msg {
t.Errorf("read %q; want %q", buf, msg)
}
fooAddr := netaddr.IPPort{IP: ifFoo.V4(), Port: 123}
if addr.String() != fooAddr.String() {
t.Errorf("addr = %q; want %q", addr, fooAddr)
}
}