net/tstun: refactor peerConfig to allow storing more details
This refactors the peerConfig struct to allow storing more details about a peer and not just the masq addresses. To be used in a follow up change. As a side effect, this also makes the DNAT logic on the inbound packet stricter. Previously it would only match against the packets dst IP, not it also takes the src IP into consideration. The beahvior is at parity with the SNAT case. Updates tailscale/corp#19623 Co-authored-by: Andrew Dunham <andrew@du.nham.ca> Signed-off-by: Maisem Ali <maisem@tailscale.com> Change-Id: I5f40802bebbf0f055436eb8824e4511d0052772d
This commit is contained in:
@ -551,7 +551,7 @@ func TestPeerAPIBypass(t *testing.T) {
|
||||
tt.w.SetFilter(tt.filter)
|
||||
tt.w.disableTSMPRejected = true
|
||||
tt.w.logf = t.Logf
|
||||
if got := tt.w.filterPacketInboundFromWireGuard(p, nil); got != tt.want {
|
||||
if got := tt.w.filterPacketInboundFromWireGuard(p, nil, nil); got != tt.want {
|
||||
t.Errorf("got = %v; want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
@ -581,7 +581,7 @@ func TestFilterDiscoLoop(t *testing.T) {
|
||||
|
||||
p := new(packet.Parsed)
|
||||
p.Decode(pkt)
|
||||
got := tw.filterPacketInboundFromWireGuard(p, nil)
|
||||
got := tw.filterPacketInboundFromWireGuard(p, nil, nil)
|
||||
if got != filter.DropSilently {
|
||||
t.Errorf("got %v; want DropSilently", got)
|
||||
}
|
||||
@ -592,7 +592,7 @@ func TestFilterDiscoLoop(t *testing.T) {
|
||||
memLog.Reset()
|
||||
pp := new(packet.Parsed)
|
||||
pp.Decode(pkt)
|
||||
got = tw.filterPacketOutboundToWireGuard(pp)
|
||||
got = tw.filterPacketOutboundToWireGuard(pp, nil)
|
||||
if got != filter.DropSilently {
|
||||
t.Errorf("got %v; want DropSilently", got)
|
||||
}
|
||||
@ -653,11 +653,17 @@ func TestPeerCfg_NAT(t *testing.T) {
|
||||
publicIP = netip.MustParseAddr("2001:4860:4860::8888")
|
||||
}
|
||||
|
||||
type dnatTest struct {
|
||||
src netip.Addr
|
||||
dst netip.Addr
|
||||
want netip.Addr // new destination after DNAT
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
wcfg *wgcfg.Config
|
||||
snatMap map[netip.Addr]netip.Addr // dst -> src
|
||||
dnatMap map[netip.Addr]netip.Addr
|
||||
dnat []dnatTest
|
||||
}{
|
||||
{
|
||||
name: "no-cfg",
|
||||
@ -667,10 +673,10 @@ func TestPeerCfg_NAT(t *testing.T) {
|
||||
peer2IP: selfNativeIP,
|
||||
subnetIP: selfNativeIP,
|
||||
},
|
||||
dnatMap: map[netip.Addr]netip.Addr{
|
||||
selfNativeIP: selfNativeIP,
|
||||
selfEIP1: selfEIP1,
|
||||
selfEIP2: selfEIP2,
|
||||
dnat: []dnatTest{
|
||||
{selfNativeIP, selfNativeIP, selfNativeIP},
|
||||
{peer1IP, selfEIP1, selfEIP1},
|
||||
{peer2IP, selfEIP2, selfEIP2},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -679,19 +685,19 @@ func TestPeerCfg_NAT(t *testing.T) {
|
||||
Addresses: selfAddrs,
|
||||
Peers: []wgcfg.Peer{
|
||||
node(peer1IP, noIP),
|
||||
node(peer2IP, selfEIP1),
|
||||
node(peer2IP, selfEIP2),
|
||||
},
|
||||
},
|
||||
snatMap: map[netip.Addr]netip.Addr{
|
||||
peer1IP: selfNativeIP,
|
||||
peer2IP: selfEIP1,
|
||||
peer2IP: selfEIP2,
|
||||
subnetIP: selfNativeIP,
|
||||
},
|
||||
dnatMap: map[netip.Addr]netip.Addr{
|
||||
selfNativeIP: selfNativeIP,
|
||||
selfEIP1: selfNativeIP,
|
||||
selfEIP2: selfEIP2,
|
||||
subnetIP: subnetIP,
|
||||
dnat: []dnatTest{
|
||||
{selfNativeIP, selfNativeIP, selfNativeIP},
|
||||
{peer1IP, selfEIP1, selfEIP1},
|
||||
{peer2IP, selfEIP2, selfNativeIP}, // NATed
|
||||
{peer2IP, subnetIP, subnetIP},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -708,11 +714,11 @@ func TestPeerCfg_NAT(t *testing.T) {
|
||||
peer2IP: selfEIP2,
|
||||
subnetIP: selfNativeIP,
|
||||
},
|
||||
dnatMap: map[netip.Addr]netip.Addr{
|
||||
selfNativeIP: selfNativeIP,
|
||||
selfEIP1: selfNativeIP,
|
||||
selfEIP2: selfNativeIP,
|
||||
subnetIP: subnetIP,
|
||||
dnat: []dnatTest{
|
||||
{selfNativeIP, selfNativeIP, selfNativeIP},
|
||||
{peer1IP, selfEIP1, selfNativeIP},
|
||||
{peer2IP, selfEIP2, selfNativeIP},
|
||||
{peer2IP, subnetIP, subnetIP},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -729,11 +735,11 @@ func TestPeerCfg_NAT(t *testing.T) {
|
||||
peer2IP: selfEIP2,
|
||||
subnetIP: selfEIP2,
|
||||
},
|
||||
dnatMap: map[netip.Addr]netip.Addr{
|
||||
selfNativeIP: selfNativeIP,
|
||||
selfEIP1: selfNativeIP,
|
||||
selfEIP2: selfNativeIP,
|
||||
subnetIP: subnetIP,
|
||||
dnat: []dnatTest{
|
||||
{selfNativeIP, selfNativeIP, selfNativeIP},
|
||||
{peer1IP, selfEIP1, selfNativeIP},
|
||||
{peer2IP, selfEIP2, selfNativeIP},
|
||||
{peer2IP, subnetIP, subnetIP},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -750,11 +756,11 @@ func TestPeerCfg_NAT(t *testing.T) {
|
||||
peer2IP: selfEIP2,
|
||||
publicIP: selfEIP2,
|
||||
},
|
||||
dnatMap: map[netip.Addr]netip.Addr{
|
||||
selfNativeIP: selfNativeIP,
|
||||
selfEIP1: selfNativeIP,
|
||||
selfEIP2: selfNativeIP,
|
||||
subnetIP: subnetIP,
|
||||
dnat: []dnatTest{
|
||||
{selfNativeIP, selfNativeIP, selfNativeIP},
|
||||
{peer1IP, selfEIP1, selfNativeIP},
|
||||
{peer2IP, selfEIP2, selfNativeIP},
|
||||
{peer2IP, subnetIP, subnetIP},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -771,11 +777,11 @@ func TestPeerCfg_NAT(t *testing.T) {
|
||||
peer2IP: selfNativeIP,
|
||||
subnetIP: selfNativeIP,
|
||||
},
|
||||
dnatMap: map[netip.Addr]netip.Addr{
|
||||
selfNativeIP: selfNativeIP,
|
||||
selfEIP1: selfEIP1,
|
||||
selfEIP2: selfEIP2,
|
||||
subnetIP: subnetIP,
|
||||
dnat: []dnatTest{
|
||||
{selfNativeIP, selfNativeIP, selfNativeIP},
|
||||
{peer1IP, selfEIP1, selfEIP1},
|
||||
{peer2IP, selfEIP2, selfEIP2},
|
||||
{peer2IP, subnetIP, subnetIP},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -792,25 +798,25 @@ func TestPeerCfg_NAT(t *testing.T) {
|
||||
peer2IP: selfEIP2,
|
||||
publicIP: selfEIP2,
|
||||
},
|
||||
dnatMap: map[netip.Addr]netip.Addr{
|
||||
selfNativeIP: selfNativeIP,
|
||||
selfEIP2: selfNativeIP,
|
||||
subnetIP: subnetIP,
|
||||
dnat: []dnatTest{
|
||||
{selfNativeIP, selfNativeIP, selfNativeIP},
|
||||
{peer2IP, selfEIP2, selfNativeIP},
|
||||
{peer2IP, subnetIP, subnetIP},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(fmt.Sprintf("%v/%v", addrFam, tc.name), func(t *testing.T) {
|
||||
pcfg := peerConfigFromWGConfig(tc.wcfg)
|
||||
pcfg := peerConfigTableFromWGConfig(tc.wcfg)
|
||||
for peer, want := range tc.snatMap {
|
||||
if got := pcfg.selectSrcIP(selfNativeIP, peer); got != want {
|
||||
t.Errorf("selectSrcIP[%v]: got %v; want %v", peer, got, want)
|
||||
}
|
||||
}
|
||||
for dstIP, want := range tc.dnatMap {
|
||||
if got := pcfg.mapDstIP(dstIP); got != want {
|
||||
t.Errorf("mapDstIP[%v]: got %v; want %v", dstIP, got, want)
|
||||
for i, dt := range tc.dnat {
|
||||
if got := pcfg.mapDstIP(dt.src, dt.dst); got != dt.want {
|
||||
t.Errorf("dnat[%d]: mapDstIP[%v, %v]: got %v; want %v", i, dt.src, dt.dst, got, dt.want)
|
||||
}
|
||||
}
|
||||
if t.Failed() {
|
||||
|
Reference in New Issue
Block a user