policy: add ICMP protocols to default and export constants
When ACL rules don't specify a protocol, Headscale now defaults to [TCP, UDP, ICMP, ICMPv6] instead of just [TCP, UDP], matching Tailscale's behavior. Also export protocol number constants (ProtocolTCP, ProtocolUDP, etc.) for use in external test packages, renaming the string protocol constants to ProtoNameTCP, ProtoNameUDP, etc. to avoid conflicts. This resolves 78 ICMP-related TODOs in the Tailscale compatibility tests, reducing the total from 165 to 87. Updates #3036
This commit is contained in:
parent
53d17aa321
commit
f735502eae
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
|
|
||||||
|
- **ACL Policy**: Add ICMP and IPv6-ICMP protocols to default filter rules and export protocol constants [#3036](https://github.com/juanfont/headscale/pull/3036)
|
||||||
- **ACL Policy**: Fix autogroup:self handling for tagged nodes - tagged nodes no longer incorrectly receive autogroup:self filter rules [#3036](https://github.com/juanfont/headscale/pull/3036)
|
- **ACL Policy**: Fix autogroup:self handling for tagged nodes - tagged nodes no longer incorrectly receive autogroup:self filter rules [#3036](https://github.com/juanfont/headscale/pull/3036)
|
||||||
|
|
||||||
## 0.28.0 (2026-02-04)
|
## 0.28.0 (2026-02-04)
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/juanfont/headscale/hscontrol/policy"
|
"github.com/juanfont/headscale/hscontrol/policy"
|
||||||
"github.com/juanfont/headscale/hscontrol/policy/policyutil"
|
"github.com/juanfont/headscale/hscontrol/policy/policyutil"
|
||||||
|
v2 "github.com/juanfont/headscale/hscontrol/policy/v2"
|
||||||
"github.com/juanfont/headscale/hscontrol/types"
|
"github.com/juanfont/headscale/hscontrol/types"
|
||||||
"github.com/juanfont/headscale/hscontrol/util"
|
"github.com/juanfont/headscale/hscontrol/util"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
@ -223,7 +224,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||||||
Ports: tailcfg.PortRangeAny,
|
Ports: tailcfg.PortRangeAny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IPProto: []int{6, 17},
|
IPProto: []int{v2.ProtocolTCP, v2.ProtocolUDP, v2.ProtocolICMP, v2.ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SrcIPs: []string{
|
SrcIPs: []string{
|
||||||
@ -238,7 +239,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||||||
Ports: tailcfg.PortRangeAny,
|
Ports: tailcfg.PortRangeAny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IPProto: []int{6, 17},
|
IPProto: []int{v2.ProtocolTCP, v2.ProtocolUDP, v2.ProtocolICMP, v2.ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -374,12 +375,12 @@ func TestReduceFilterRules(t *testing.T) {
|
|||||||
Ports: tailcfg.PortRangeAny,
|
Ports: tailcfg.PortRangeAny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IPProto: []int{6, 17},
|
IPProto: []int{v2.ProtocolTCP, v2.ProtocolUDP, v2.ProtocolICMP, v2.ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SrcIPs: []string{"100.64.0.1/32", "100.64.0.2/32", "fd7a:115c:a1e0::1/128", "fd7a:115c:a1e0::2/128"},
|
SrcIPs: []string{"100.64.0.1/32", "100.64.0.2/32", "fd7a:115c:a1e0::1/128", "fd7a:115c:a1e0::2/128"},
|
||||||
DstPorts: hsExitNodeDestForTest,
|
DstPorts: hsExitNodeDestForTest,
|
||||||
IPProto: []int{6, 17},
|
IPProto: []int{v2.ProtocolTCP, v2.ProtocolUDP, v2.ProtocolICMP, v2.ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -483,7 +484,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||||||
Ports: tailcfg.PortRangeAny,
|
Ports: tailcfg.PortRangeAny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IPProto: []int{6, 17},
|
IPProto: []int{v2.ProtocolTCP, v2.ProtocolUDP, v2.ProtocolICMP, v2.ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SrcIPs: []string{"100.64.0.1/32", "100.64.0.2/32", "fd7a:115c:a1e0::1/128", "fd7a:115c:a1e0::2/128"},
|
SrcIPs: []string{"100.64.0.1/32", "100.64.0.2/32", "fd7a:115c:a1e0::1/128", "fd7a:115c:a1e0::2/128"},
|
||||||
@ -519,7 +520,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||||||
{IP: "200.0.0.0/5", Ports: tailcfg.PortRangeAny},
|
{IP: "200.0.0.0/5", Ports: tailcfg.PortRangeAny},
|
||||||
{IP: "208.0.0.0/4", Ports: tailcfg.PortRangeAny},
|
{IP: "208.0.0.0/4", Ports: tailcfg.PortRangeAny},
|
||||||
},
|
},
|
||||||
IPProto: []int{6, 17},
|
IPProto: []int{v2.ProtocolTCP, v2.ProtocolUDP, v2.ProtocolICMP, v2.ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -595,7 +596,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||||||
Ports: tailcfg.PortRangeAny,
|
Ports: tailcfg.PortRangeAny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IPProto: []int{6, 17},
|
IPProto: []int{v2.ProtocolTCP, v2.ProtocolUDP, v2.ProtocolICMP, v2.ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SrcIPs: []string{"100.64.0.1/32", "100.64.0.2/32", "fd7a:115c:a1e0::1/128", "fd7a:115c:a1e0::2/128"},
|
SrcIPs: []string{"100.64.0.1/32", "100.64.0.2/32", "fd7a:115c:a1e0::1/128", "fd7a:115c:a1e0::2/128"},
|
||||||
@ -609,7 +610,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||||||
Ports: tailcfg.PortRangeAny,
|
Ports: tailcfg.PortRangeAny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IPProto: []int{6, 17},
|
IPProto: []int{v2.ProtocolTCP, v2.ProtocolUDP, v2.ProtocolICMP, v2.ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -685,7 +686,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||||||
Ports: tailcfg.PortRangeAny,
|
Ports: tailcfg.PortRangeAny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IPProto: []int{6, 17},
|
IPProto: []int{v2.ProtocolTCP, v2.ProtocolUDP, v2.ProtocolICMP, v2.ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SrcIPs: []string{"100.64.0.1/32", "100.64.0.2/32", "fd7a:115c:a1e0::1/128", "fd7a:115c:a1e0::2/128"},
|
SrcIPs: []string{"100.64.0.1/32", "100.64.0.2/32", "fd7a:115c:a1e0::1/128", "fd7a:115c:a1e0::2/128"},
|
||||||
@ -699,7 +700,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||||||
Ports: tailcfg.PortRangeAny,
|
Ports: tailcfg.PortRangeAny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IPProto: []int{6, 17},
|
IPProto: []int{v2.ProtocolTCP, v2.ProtocolUDP, v2.ProtocolICMP, v2.ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -767,7 +768,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||||||
Ports: tailcfg.PortRangeAny,
|
Ports: tailcfg.PortRangeAny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IPProto: []int{6, 17},
|
IPProto: []int{v2.ProtocolTCP, v2.ProtocolUDP, v2.ProtocolICMP, v2.ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -103,7 +103,7 @@ func TestParsing(t *testing.T) {
|
|||||||
{IP: "::/0", Ports: tailcfg.PortRange{First: 3389, Last: 3389}},
|
{IP: "::/0", Ports: tailcfg.PortRange{First: 3389, Last: 3389}},
|
||||||
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
||||||
},
|
},
|
||||||
IPProto: []int{protocolTCP, protocolUDP},
|
IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
@ -157,21 +157,21 @@ func TestParsing(t *testing.T) {
|
|||||||
DstPorts: []tailcfg.NetPortRange{
|
DstPorts: []tailcfg.NetPortRange{
|
||||||
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
||||||
},
|
},
|
||||||
IPProto: []int{protocolTCP},
|
IPProto: []int{ProtocolTCP},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SrcIPs: []string{"0.0.0.0/0", "::/0"},
|
SrcIPs: []string{"0.0.0.0/0", "::/0"},
|
||||||
DstPorts: []tailcfg.NetPortRange{
|
DstPorts: []tailcfg.NetPortRange{
|
||||||
{IP: "100.100.100.100/32", Ports: tailcfg.PortRange{First: 53, Last: 53}},
|
{IP: "100.100.100.100/32", Ports: tailcfg.PortRange{First: 53, Last: 53}},
|
||||||
},
|
},
|
||||||
IPProto: []int{protocolUDP},
|
IPProto: []int{ProtocolUDP},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SrcIPs: []string{"0.0.0.0/0", "::/0"},
|
SrcIPs: []string{"0.0.0.0/0", "::/0"},
|
||||||
DstPorts: []tailcfg.NetPortRange{
|
DstPorts: []tailcfg.NetPortRange{
|
||||||
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
||||||
},
|
},
|
||||||
IPProto: []int{protocolICMP, protocolIPv6ICMP},
|
IPProto: []int{ProtocolICMP, ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
@ -205,7 +205,7 @@ func TestParsing(t *testing.T) {
|
|||||||
DstPorts: []tailcfg.NetPortRange{
|
DstPorts: []tailcfg.NetPortRange{
|
||||||
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
||||||
},
|
},
|
||||||
IPProto: []int{protocolTCP, protocolUDP},
|
IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
@ -242,7 +242,7 @@ func TestParsing(t *testing.T) {
|
|||||||
Ports: tailcfg.PortRange{First: 5400, Last: 5500},
|
Ports: tailcfg.PortRange{First: 5400, Last: 5500},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IPProto: []int{protocolTCP, protocolUDP},
|
IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
@ -282,7 +282,7 @@ func TestParsing(t *testing.T) {
|
|||||||
DstPorts: []tailcfg.NetPortRange{
|
DstPorts: []tailcfg.NetPortRange{
|
||||||
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
||||||
},
|
},
|
||||||
IPProto: []int{protocolTCP, protocolUDP},
|
IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
@ -316,7 +316,7 @@ func TestParsing(t *testing.T) {
|
|||||||
DstPorts: []tailcfg.NetPortRange{
|
DstPorts: []tailcfg.NetPortRange{
|
||||||
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
||||||
},
|
},
|
||||||
IPProto: []int{protocolTCP, protocolUDP},
|
IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
@ -350,7 +350,7 @@ func TestParsing(t *testing.T) {
|
|||||||
DstPorts: []tailcfg.NetPortRange{
|
DstPorts: []tailcfg.NetPortRange{
|
||||||
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
|
||||||
},
|
},
|
||||||
IPProto: []int{protocolTCP, protocolUDP},
|
IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1281,21 +1281,21 @@ func (a SSHAction) MarshalJSON() ([]byte, error) {
|
|||||||
type Protocol string
|
type Protocol string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ProtocolICMP Protocol = "icmp"
|
ProtocolNameICMP Protocol = "icmp"
|
||||||
ProtocolIGMP Protocol = "igmp"
|
ProtocolNameIGMP Protocol = "igmp"
|
||||||
ProtocolIPv4 Protocol = "ipv4"
|
ProtocolNameIPv4 Protocol = "ipv4"
|
||||||
ProtocolIPInIP Protocol = "ip-in-ip"
|
ProtocolNameIPInIP Protocol = "ip-in-ip"
|
||||||
ProtocolTCP Protocol = "tcp"
|
ProtocolNameTCP Protocol = "tcp"
|
||||||
ProtocolEGP Protocol = "egp"
|
ProtocolNameEGP Protocol = "egp"
|
||||||
ProtocolIGP Protocol = "igp"
|
ProtocolNameIGP Protocol = "igp"
|
||||||
ProtocolUDP Protocol = "udp"
|
ProtocolNameUDP Protocol = "udp"
|
||||||
ProtocolGRE Protocol = "gre"
|
ProtocolNameGRE Protocol = "gre"
|
||||||
ProtocolESP Protocol = "esp"
|
ProtocolNameESP Protocol = "esp"
|
||||||
ProtocolAH Protocol = "ah"
|
ProtocolNameAH Protocol = "ah"
|
||||||
ProtocolIPv6ICMP Protocol = "ipv6-icmp"
|
ProtocolNameIPv6ICMP Protocol = "ipv6-icmp"
|
||||||
ProtocolSCTP Protocol = "sctp"
|
ProtocolNameSCTP Protocol = "sctp"
|
||||||
ProtocolFC Protocol = "fc"
|
ProtocolNameFC Protocol = "fc"
|
||||||
ProtocolWildcard Protocol = "*"
|
ProtocolNameWildcard Protocol = "*"
|
||||||
)
|
)
|
||||||
|
|
||||||
// String returns the string representation of the Protocol.
|
// String returns the string representation of the Protocol.
|
||||||
@ -1306,33 +1306,33 @@ func (p Protocol) String() string {
|
|||||||
// Description returns the human-readable description of the Protocol.
|
// Description returns the human-readable description of the Protocol.
|
||||||
func (p Protocol) Description() string {
|
func (p Protocol) Description() string {
|
||||||
switch p {
|
switch p {
|
||||||
case ProtocolICMP:
|
case ProtocolNameICMP:
|
||||||
return "Internet Control Message Protocol"
|
return "Internet Control Message Protocol"
|
||||||
case ProtocolIGMP:
|
case ProtocolNameIGMP:
|
||||||
return "Internet Group Management Protocol"
|
return "Internet Group Management Protocol"
|
||||||
case ProtocolIPv4:
|
case ProtocolNameIPv4:
|
||||||
return "IPv4 encapsulation"
|
return "IPv4 encapsulation"
|
||||||
case ProtocolTCP:
|
case ProtocolNameTCP:
|
||||||
return "Transmission Control Protocol"
|
return "Transmission Control Protocol"
|
||||||
case ProtocolEGP:
|
case ProtocolNameEGP:
|
||||||
return "Exterior Gateway Protocol"
|
return "Exterior Gateway Protocol"
|
||||||
case ProtocolIGP:
|
case ProtocolNameIGP:
|
||||||
return "Interior Gateway Protocol"
|
return "Interior Gateway Protocol"
|
||||||
case ProtocolUDP:
|
case ProtocolNameUDP:
|
||||||
return "User Datagram Protocol"
|
return "User Datagram Protocol"
|
||||||
case ProtocolGRE:
|
case ProtocolNameGRE:
|
||||||
return "Generic Routing Encapsulation"
|
return "Generic Routing Encapsulation"
|
||||||
case ProtocolESP:
|
case ProtocolNameESP:
|
||||||
return "Encapsulating Security Payload"
|
return "Encapsulating Security Payload"
|
||||||
case ProtocolAH:
|
case ProtocolNameAH:
|
||||||
return "Authentication Header"
|
return "Authentication Header"
|
||||||
case ProtocolIPv6ICMP:
|
case ProtocolNameIPv6ICMP:
|
||||||
return "Internet Control Message Protocol for IPv6"
|
return "Internet Control Message Protocol for IPv6"
|
||||||
case ProtocolSCTP:
|
case ProtocolNameSCTP:
|
||||||
return "Stream Control Transmission Protocol"
|
return "Stream Control Transmission Protocol"
|
||||||
case ProtocolFC:
|
case ProtocolNameFC:
|
||||||
return "Fibre Channel"
|
return "Fibre Channel"
|
||||||
case ProtocolWildcard:
|
case ProtocolNameWildcard:
|
||||||
return "Wildcard (not supported - use specific protocol)"
|
return "Wildcard (not supported - use specific protocol)"
|
||||||
default:
|
default:
|
||||||
return "Unknown Protocol"
|
return "Unknown Protocol"
|
||||||
@ -1344,42 +1344,43 @@ func (p Protocol) Description() string {
|
|||||||
func (p Protocol) parseProtocol() ([]int, bool) {
|
func (p Protocol) parseProtocol() ([]int, bool) {
|
||||||
switch p {
|
switch p {
|
||||||
case "":
|
case "":
|
||||||
// Empty protocol applies to TCP and UDP traffic only
|
// Empty protocol applies to TCP, UDP, ICMP, and ICMPv6 traffic
|
||||||
return []int{protocolTCP, protocolUDP}, false
|
// This matches Tailscale's behavior for protocol defaults
|
||||||
case ProtocolWildcard:
|
return []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, false
|
||||||
|
case ProtocolNameWildcard:
|
||||||
// Wildcard protocol - defensive handling (should not reach here due to validation)
|
// Wildcard protocol - defensive handling (should not reach here due to validation)
|
||||||
return nil, false
|
return nil, false
|
||||||
case ProtocolIGMP:
|
case ProtocolNameIGMP:
|
||||||
return []int{protocolIGMP}, true
|
return []int{ProtocolIGMP}, true
|
||||||
case ProtocolIPv4, ProtocolIPInIP:
|
case ProtocolNameIPv4, ProtocolNameIPInIP:
|
||||||
return []int{protocolIPv4}, true
|
return []int{ProtocolIPv4}, true
|
||||||
case ProtocolTCP:
|
case ProtocolNameTCP:
|
||||||
return []int{protocolTCP}, false
|
return []int{ProtocolTCP}, false
|
||||||
case ProtocolEGP:
|
case ProtocolNameEGP:
|
||||||
return []int{protocolEGP}, true
|
return []int{ProtocolEGP}, true
|
||||||
case ProtocolIGP:
|
case ProtocolNameIGP:
|
||||||
return []int{protocolIGP}, true
|
return []int{ProtocolIGP}, true
|
||||||
case ProtocolUDP:
|
case ProtocolNameUDP:
|
||||||
return []int{protocolUDP}, false
|
return []int{ProtocolUDP}, false
|
||||||
case ProtocolGRE:
|
case ProtocolNameGRE:
|
||||||
return []int{protocolGRE}, true
|
return []int{ProtocolGRE}, true
|
||||||
case ProtocolESP:
|
case ProtocolNameESP:
|
||||||
return []int{protocolESP}, true
|
return []int{ProtocolESP}, true
|
||||||
case ProtocolAH:
|
case ProtocolNameAH:
|
||||||
return []int{protocolAH}, true
|
return []int{ProtocolAH}, true
|
||||||
case ProtocolSCTP:
|
case ProtocolNameSCTP:
|
||||||
return []int{protocolSCTP}, false
|
return []int{ProtocolSCTP}, false
|
||||||
case ProtocolICMP:
|
case ProtoNameICMP:
|
||||||
return []int{protocolICMP, protocolIPv6ICMP}, true
|
return []int{ProtocolICMP, ProtocolIPv6ICMP}, true
|
||||||
default:
|
default:
|
||||||
// Try to parse as a numeric protocol number
|
// Try to parse as a numeric protocol number
|
||||||
// This should not fail since validation happened during unmarshaling
|
// This should not fail since validation happened during unmarshaling
|
||||||
protocolNumber, _ := strconv.Atoi(string(p))
|
protocolNumber, _ := strconv.Atoi(string(p))
|
||||||
|
|
||||||
// Determine if wildcard is needed based on protocol number
|
// Determine if wildcard is needed based on protocol number
|
||||||
needsWildcard := protocolNumber != protocolTCP &&
|
needsWildcard := protocolNumber != ProtocolTCP &&
|
||||||
protocolNumber != protocolUDP &&
|
protocolNumber != ProtocolUDP &&
|
||||||
protocolNumber != protocolSCTP
|
protocolNumber != ProtocolSCTP
|
||||||
|
|
||||||
return []int{protocolNumber}, needsWildcard
|
return []int{protocolNumber}, needsWildcard
|
||||||
}
|
}
|
||||||
@ -1403,11 +1404,11 @@ func (p *Protocol) UnmarshalJSON(b []byte) error {
|
|||||||
// validate checks if the Protocol is valid.
|
// validate checks if the Protocol is valid.
|
||||||
func (p Protocol) validate() error {
|
func (p Protocol) validate() error {
|
||||||
switch p {
|
switch p {
|
||||||
case "", ProtocolICMP, ProtocolIGMP, ProtocolIPv4, ProtocolIPInIP,
|
case "", ProtocolNameICMP, ProtocolNameIGMP, ProtocolNameIPv4, ProtocolNameIPInIP,
|
||||||
ProtocolTCP, ProtocolEGP, ProtocolIGP, ProtocolUDP, ProtocolGRE,
|
ProtocolNameTCP, ProtocolNameEGP, ProtocolNameIGP, ProtocolNameUDP, ProtocolNameGRE,
|
||||||
ProtocolESP, ProtocolAH, ProtocolSCTP:
|
ProtocolNameESP, ProtocolNameAH, ProtocolNameSCTP:
|
||||||
return nil
|
return nil
|
||||||
case ProtocolWildcard:
|
case ProtocolNameWildcard:
|
||||||
// Wildcard "*" is not allowed - Tailscale rejects it
|
// Wildcard "*" is not allowed - Tailscale rejects it
|
||||||
return fmt.Errorf("proto name \"*\" not known; use protocol number 0-255 or protocol name (icmp, tcp, udp, etc.)")
|
return fmt.Errorf("proto name \"*\" not known; use protocol number 0-255 or protocol name (icmp, tcp, udp, etc.)")
|
||||||
default:
|
default:
|
||||||
@ -1439,19 +1440,19 @@ func (p Protocol) MarshalJSON() ([]byte, error) {
|
|||||||
|
|
||||||
// Protocol constants matching the IANA numbers
|
// Protocol constants matching the IANA numbers
|
||||||
const (
|
const (
|
||||||
protocolICMP = 1 // Internet Control Message
|
ProtocolICMP = 1 // Internet Control Message
|
||||||
protocolIGMP = 2 // Internet Group Management
|
ProtocolIGMP = 2 // Internet Group Management
|
||||||
protocolIPv4 = 4 // IPv4 encapsulation
|
ProtocolIPv4 = 4 // IPv4 encapsulation
|
||||||
protocolTCP = 6 // Transmission Control
|
ProtocolTCP = 6 // Transmission Control
|
||||||
protocolEGP = 8 // Exterior Gateway Protocol
|
ProtocolEGP = 8 // Exterior Gateway Protocol
|
||||||
protocolIGP = 9 // any private interior gateway (used by Cisco for their IGRP)
|
ProtocolIGP = 9 // any private interior gateway (used by Cisco for their IGRP)
|
||||||
protocolUDP = 17 // User Datagram
|
ProtocolUDP = 17 // User Datagram
|
||||||
protocolGRE = 47 // Generic Routing Encapsulation
|
ProtocolGRE = 47 // Generic Routing Encapsulation
|
||||||
protocolESP = 50 // Encap Security Payload
|
ProtocolESP = 50 // Encap Security Payload
|
||||||
protocolAH = 51 // Authentication Header
|
ProtocolAH = 51 // Authentication Header
|
||||||
protocolIPv6ICMP = 58 // ICMP for IPv6
|
ProtocolIPv6ICMP = 58 // ICMP for IPv6
|
||||||
protocolSCTP = 132 // Stream Control Transmission Protocol
|
ProtocolSCTP = 132 // Stream Control Transmission Protocol
|
||||||
protocolFC = 133 // Fibre Channel
|
ProtocolFC = 133 // Fibre Channel
|
||||||
)
|
)
|
||||||
|
|
||||||
type ACL struct {
|
type ACL struct {
|
||||||
@ -2114,7 +2115,7 @@ func unmarshalPolicy(b []byte) (*Policy, error) {
|
|||||||
// can have specific ports. All other protocols should only use wildcard ports.
|
// can have specific ports. All other protocols should only use wildcard ports.
|
||||||
func validateProtocolPortCompatibility(protocol Protocol, destinations []AliasWithPorts) error {
|
func validateProtocolPortCompatibility(protocol Protocol, destinations []AliasWithPorts) error {
|
||||||
// Only TCP, UDP, and SCTP support specific ports
|
// Only TCP, UDP, and SCTP support specific ports
|
||||||
supportsSpecificPorts := protocol == ProtocolTCP || protocol == ProtocolUDP || protocol == ProtocolSCTP || protocol == ""
|
supportsSpecificPorts := protocol == ProtocolNameTCP || protocol == ProtocolNameUDP || protocol == ProtocolNameSCTP || protocol == ""
|
||||||
|
|
||||||
if supportsSpecificPorts {
|
if supportsSpecificPorts {
|
||||||
return nil // No validation needed for these protocols
|
return nil // No validation needed for these protocols
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user