tailcfg: add Node.SelfNodeV4MasqAddrForThisPeer

This only adds the field, to be used in a future commit.

Updates tailscale/corp#8020

Co-authored-by: Melanie Warrick <warrick@tailscale.com>
Signed-off-by: Maisem Ali <maisem@tailscale.com>
maisem/k8s-cache
Maisem Ali 1 year ago committed by Maisem Ali
parent 583e86b7df
commit f61b306133

@ -95,7 +95,8 @@ type CapabilityVersion int
// - 56: 2023-01-24: Client understands CapabilityDebugTSDNSResolution // - 56: 2023-01-24: Client understands CapabilityDebugTSDNSResolution
// - 57: 2023-01-25: Client understands CapabilityBindToInterfaceByRoute // - 57: 2023-01-25: Client understands CapabilityBindToInterfaceByRoute
// - 58: 2023-03-10: Client retries lite map updates before restarting map poll. // - 58: 2023-03-10: Client retries lite map updates before restarting map poll.
const CurrentCapabilityVersion CapabilityVersion = 58 // - 59: 2023-03-16: Client understands Peers[].SelfNodeV4MasqAddrForThisPeer
const CurrentCapabilityVersion CapabilityVersion = 59
type StableID string type StableID string
@ -273,6 +274,21 @@ type Node struct {
// the client, this is calculated client-side based on a timestamp sent // the client, this is calculated client-side based on a timestamp sent
// from control, to avoid clock skew issues. // from control, to avoid clock skew issues.
Expired bool `json:",omitempty"` Expired bool `json:",omitempty"`
// SelfNodeV4MasqAddrForThisPeer is the IPv4 that this peer knows the current node as.
// It may be empty if the peer knows the current node by its native
// IPv4 address.
// This field is only populated in a MapResponse for peers and not
// for the current node.
//
// If set, it should be used to masquerade traffic originating from the
// current node to this peer. The masquerade address is only relevant
// for this peer and not for other peers.
//
// This only applies to traffic originating from the current node to the
// peer or any of its subnets. Traffic originating from subnet routes will
// not be masqueraded (e.g. in case of --snat-subnet-routes).
SelfNodeV4MasqAddrForThisPeer netip.Addr `json:",omitempty"`
} }
// DisplayName returns the user-facing name for a node which should // DisplayName returns the user-facing name for a node which should
@ -1698,7 +1714,8 @@ func (n *Node) Equal(n2 *Node) bool {
n.computedHostIfDifferent == n2.computedHostIfDifferent && n.computedHostIfDifferent == n2.computedHostIfDifferent &&
n.ComputedNameWithHost == n2.ComputedNameWithHost && n.ComputedNameWithHost == n2.ComputedNameWithHost &&
eqStrings(n.Tags, n2.Tags) && eqStrings(n.Tags, n2.Tags) &&
n.Expired == n2.Expired n.Expired == n2.Expired &&
n.SelfNodeV4MasqAddrForThisPeer == n2.SelfNodeV4MasqAddrForThisPeer
} }
func eqBoolPtr(a, b *bool) bool { func eqBoolPtr(a, b *bool) bool {

@ -98,6 +98,7 @@ var _NodeCloneNeedsRegeneration = Node(struct {
ComputedNameWithHost string ComputedNameWithHost string
DataPlaneAuditLogID string DataPlaneAuditLogID string
Expired bool Expired bool
SelfNodeV4MasqAddrForThisPeer netip.Addr
}{}) }{})
// Clone makes a deep copy of Hostinfo. // Clone makes a deep copy of Hostinfo.

@ -349,7 +349,7 @@ func TestNodeEqual(t *testing.T) {
"Capabilities", "Capabilities",
"UnsignedPeerAPIOnly", "UnsignedPeerAPIOnly",
"ComputedName", "computedHostIfDifferent", "ComputedNameWithHost", "ComputedName", "computedHostIfDifferent", "ComputedNameWithHost",
"DataPlaneAuditLogID", "Expired", "DataPlaneAuditLogID", "Expired", "SelfNodeV4MasqAddrForThisPeer",
} }
if have := fieldsOf(reflect.TypeOf(Node{})); !reflect.DeepEqual(have, nodeHandles) { if have := fieldsOf(reflect.TypeOf(Node{})); !reflect.DeepEqual(have, nodeHandles) {
t.Errorf("Node.Equal check might be out of sync\nfields: %q\nhandled: %q\n", t.Errorf("Node.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
@ -534,6 +534,16 @@ func TestNodeEqual(t *testing.T) {
&Node{}, &Node{},
false, false,
}, },
{
&Node{},
&Node{SelfNodeV4MasqAddrForThisPeer: netip.MustParseAddr("100.64.0.1")},
false,
},
{
&Node{SelfNodeV4MasqAddrForThisPeer: netip.MustParseAddr("100.64.0.1")},
&Node{SelfNodeV4MasqAddrForThisPeer: netip.MustParseAddr("100.64.0.1")},
true,
},
} }
for i, tt := range tests { for i, tt := range tests {
got := tt.a.Equal(tt.b) got := tt.a.Equal(tt.b)

@ -176,6 +176,9 @@ func (v NodeView) ComputedName() string { return v.ж.ComputedName
func (v NodeView) ComputedNameWithHost() string { return v.ж.ComputedNameWithHost } func (v NodeView) ComputedNameWithHost() string { return v.ж.ComputedNameWithHost }
func (v NodeView) DataPlaneAuditLogID() string { return v.ж.DataPlaneAuditLogID } func (v NodeView) DataPlaneAuditLogID() string { return v.ж.DataPlaneAuditLogID }
func (v NodeView) Expired() bool { return v.ж.Expired } func (v NodeView) Expired() bool { return v.ж.Expired }
func (v NodeView) SelfNodeV4MasqAddrForThisPeer() netip.Addr {
return v.ж.SelfNodeV4MasqAddrForThisPeer
}
func (v NodeView) Equal(v2 NodeView) bool { return v.ж.Equal(v2.ж) } func (v NodeView) Equal(v2 NodeView) bool { return v.ж.Equal(v2.ж) }
// A compilation failure here means this code must be regenerated, with the command at the top of this file. // A compilation failure here means this code must be regenerated, with the command at the top of this file.
@ -210,6 +213,7 @@ var _NodeViewNeedsRegeneration = Node(struct {
ComputedNameWithHost string ComputedNameWithHost string
DataPlaneAuditLogID string DataPlaneAuditLogID string
Expired bool Expired bool
SelfNodeV4MasqAddrForThisPeer netip.Addr
}{}) }{})
// View returns a readonly view of Hostinfo. // View returns a readonly view of Hostinfo.

@ -575,8 +575,8 @@ func TestGetTypeHasher(t *testing.T) {
{ {
name: "tailcfg.Node", name: "tailcfg.Node",
val: &tailcfg.Node{}, val: &tailcfg.Node{},
out: "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", out: "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
out32: "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", out32: "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
}, },
} }
for _, tt := range tests { for _, tt := range tests {

Loading…
Cancel
Save