mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
tstest/natlab: add dual stack with blackholed IPv4
This reproduces the bug report from https://github.com/tailscale/tailscale/issues/13346 It does not yet fix it. Updates #13346 Change-Id: Ia5af7b0481a64a37efe259c798facdda6d9da618 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
aeb15dea30
commit
c4d0237e5c
@ -115,6 +115,17 @@ func easyAnd6(c *vnet.Config) *vnet.Node {
|
|||||||
vnet.EasyNAT))
|
vnet.EasyNAT))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func v6AndBlackholedIPv4(c *vnet.Config) *vnet.Node {
|
||||||
|
n := c.NumNodes() + 1
|
||||||
|
nw := c.AddNetwork(
|
||||||
|
fmt.Sprintf("2.%d.%d.%d", n, n, n), // public IP
|
||||||
|
fmt.Sprintf("192.168.%d.1/24", n),
|
||||||
|
v6cidr(n),
|
||||||
|
vnet.EasyNAT)
|
||||||
|
nw.SetBlackholedIPv4(true)
|
||||||
|
return c.AddNode(nw)
|
||||||
|
}
|
||||||
|
|
||||||
func just6(c *vnet.Config) *vnet.Node {
|
func just6(c *vnet.Config) *vnet.Node {
|
||||||
n := c.NumNodes() + 1
|
n := c.NumNodes() + 1
|
||||||
return c.AddNode(c.AddNetwork(v6cidr(n))) // public IPv6 prefix
|
return c.AddNode(c.AddNetwork(v6cidr(n))) // public IPv6 prefix
|
||||||
@ -482,6 +493,20 @@ func TestSingleJustIPv6(t *testing.T) {
|
|||||||
nt.runTest(just6)
|
nt.runTest(just6)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var knownBroken = flag.Bool("known-broken", false, "run known-broken tests")
|
||||||
|
|
||||||
|
// TestSingleDualStackButBrokenIPv4 tests a dual-stack node with broken
|
||||||
|
// (blackholed) IPv4.
|
||||||
|
//
|
||||||
|
// See https://github.com/tailscale/tailscale/issues/13346
|
||||||
|
func TestSingleDualBrokenIPv4(t *testing.T) {
|
||||||
|
if !*knownBroken {
|
||||||
|
t.Skip("skipping known-broken test; set --known-broken to run; see https://github.com/tailscale/tailscale/issues/13346")
|
||||||
|
}
|
||||||
|
nt := newNatTest(t)
|
||||||
|
nt.runTest(v6AndBlackholedIPv4)
|
||||||
|
}
|
||||||
|
|
||||||
func TestJustIPv6(t *testing.T) {
|
func TestJustIPv6(t *testing.T) {
|
||||||
nt := newNatTest(t)
|
nt := newNatTest(t)
|
||||||
nt.runTest(just6, just6)
|
nt.runTest(just6, just6)
|
||||||
|
@ -272,9 +272,10 @@ type Network struct {
|
|||||||
|
|
||||||
wanIP6 netip.Prefix // global unicast router in host bits; CIDR is /64 delegated to LAN
|
wanIP6 netip.Prefix // global unicast router in host bits; CIDR is /64 delegated to LAN
|
||||||
|
|
||||||
wanIP4 netip.Addr // IPv4 WAN IP, if any
|
wanIP4 netip.Addr // IPv4 WAN IP, if any
|
||||||
lanIP4 netip.Prefix
|
lanIP4 netip.Prefix
|
||||||
nodes []*Node
|
nodes []*Node
|
||||||
|
breakWAN4 bool // whether to break WAN IPv4 connectivity
|
||||||
|
|
||||||
svcs set.Set[NetworkService]
|
svcs set.Set[NetworkService]
|
||||||
|
|
||||||
@ -282,6 +283,12 @@ type Network struct {
|
|||||||
err error // carried error
|
err error // carried error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetBlackholedIPv4 sets whether the network should blackhole all IPv4 traffic
|
||||||
|
// out to the Internet. (DHCP etc continues to work on the LAN.)
|
||||||
|
func (n *Network) SetBlackholedIPv4(v bool) {
|
||||||
|
n.breakWAN4 = v
|
||||||
|
}
|
||||||
|
|
||||||
func (n *Network) CanV4() bool {
|
func (n *Network) CanV4() bool {
|
||||||
return n.lanIP4.IsValid() || n.wanIP4.IsValid()
|
return n.lanIP4.IsValid() || n.wanIP4.IsValid()
|
||||||
}
|
}
|
||||||
@ -353,6 +360,7 @@ func (s *Server) initFromConfig(c *Config) error {
|
|||||||
v6: conf.wanIP6.IsValid(),
|
v6: conf.wanIP6.IsValid(),
|
||||||
wanIP4: conf.wanIP4,
|
wanIP4: conf.wanIP4,
|
||||||
lanIP4: conf.lanIP4,
|
lanIP4: conf.lanIP4,
|
||||||
|
breakWAN4: conf.breakWAN4,
|
||||||
nodesByIP4: map[netip.Addr]*node{},
|
nodesByIP4: map[netip.Addr]*node{},
|
||||||
nodesByMAC: map[MAC]*node{},
|
nodesByMAC: map[MAC]*node{},
|
||||||
logf: logger.WithPrefix(s.logf, fmt.Sprintf("[net-%v] ", conf.mac)),
|
logf: logger.WithPrefix(s.logf, fmt.Sprintf("[net-%v] ", conf.mac)),
|
||||||
|
@ -514,6 +514,7 @@ type network struct {
|
|||||||
wanIP6 netip.Prefix // router's WAN IPv6, if any, as a /64.
|
wanIP6 netip.Prefix // router's WAN IPv6, if any, as a /64.
|
||||||
wanIP4 netip.Addr // router's LAN IPv4, if any
|
wanIP4 netip.Addr // router's LAN IPv4, if any
|
||||||
lanIP4 netip.Prefix // router's LAN IP + CIDR (e.g. 192.168.2.1/24)
|
lanIP4 netip.Prefix // router's LAN IP + CIDR (e.g. 192.168.2.1/24)
|
||||||
|
breakWAN4 bool // break WAN IPv4 connectivity
|
||||||
nodesByIP4 map[netip.Addr]*node // by LAN IPv4
|
nodesByIP4 map[netip.Addr]*node // by LAN IPv4
|
||||||
nodesByMAC map[MAC]*node
|
nodesByMAC map[MAC]*node
|
||||||
logf func(format string, args ...any)
|
logf func(format string, args ...any)
|
||||||
@ -1104,6 +1105,10 @@ func (n *network) HandleUDPPacket(p UDPPacket) {
|
|||||||
Length: len(buf),
|
Length: len(buf),
|
||||||
InterfaceIndex: n.wanInterfaceID,
|
InterfaceIndex: n.wanInterfaceID,
|
||||||
}, buf)
|
}, buf)
|
||||||
|
if p.Dst.Addr().Is4() && n.breakWAN4 {
|
||||||
|
// Blackhole the packet.
|
||||||
|
return
|
||||||
|
}
|
||||||
dst := n.doNATIn(p.Src, p.Dst)
|
dst := n.doNATIn(p.Src, p.Dst)
|
||||||
if !dst.IsValid() {
|
if !dst.IsValid() {
|
||||||
n.logf("Warning: NAT dropped packet; no mapping for %v=>%v", p.Src, p.Dst)
|
n.logf("Warning: NAT dropped packet; no mapping for %v=>%v", p.Src, p.Dst)
|
||||||
@ -1239,6 +1244,10 @@ func (n *network) HandleEthernetPacketForRouter(ep EthernetPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if toForward && n.s.shouldInterceptTCP(packet) {
|
if toForward && n.s.shouldInterceptTCP(packet) {
|
||||||
|
if flow.dst.Is4() && n.breakWAN4 {
|
||||||
|
// Blackhole the packet.
|
||||||
|
return
|
||||||
|
}
|
||||||
var base *layers.BaseLayer
|
var base *layers.BaseLayer
|
||||||
proto := header.IPv4ProtocolNumber
|
proto := header.IPv4ProtocolNumber
|
||||||
if v4, ok := packet.Layer(layers.LayerTypeIPv4).(*layers.IPv4); ok {
|
if v4, ok := packet.Layer(layers.LayerTypeIPv4).(*layers.IPv4); ok {
|
||||||
@ -1324,6 +1333,10 @@ func (n *network) handleUDPPacketForRouter(ep EthernetPacket, udp *layers.UDP, t
|
|||||||
}
|
}
|
||||||
|
|
||||||
if toForward {
|
if toForward {
|
||||||
|
if dstIP.Is4() && n.breakWAN4 {
|
||||||
|
// Blackhole the packet.
|
||||||
|
return
|
||||||
|
}
|
||||||
src := netip.AddrPortFrom(srcIP, uint16(udp.SrcPort))
|
src := netip.AddrPortFrom(srcIP, uint16(udp.SrcPort))
|
||||||
dst := netip.AddrPortFrom(dstIP, uint16(udp.DstPort))
|
dst := netip.AddrPortFrom(dstIP, uint16(udp.DstPort))
|
||||||
buf, err := n.serializedUDPPacket(src, dst, udp.Payload, nil)
|
buf, err := n.serializedUDPPacket(src, dst, udp.Payload, nil)
|
||||||
|
Loading…
Reference in New Issue
Block a user