Skip to content

Commit 069be9b

Browse files
committed
Add port validator to ensure configurable ports are valid
Signed-off-by: Lan Luo <[email protected]>
1 parent c33622c commit 069be9b

File tree

7 files changed

+115
-6
lines changed

7 files changed

+115
-6
lines changed

cmd/antrea-agent/options.go

+13-6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"fmt"
1919
"net"
2020
"os"
21+
"strconv"
2122
"strings"
2223
"time"
2324

@@ -34,6 +35,7 @@ import (
3435
agentconfig "antrea.io/antrea/pkg/config/agent"
3536
"antrea.io/antrea/pkg/features"
3637
"antrea.io/antrea/pkg/ovs/ovsconfig"
38+
"antrea.io/antrea/pkg/util/checks"
3739
"antrea.io/antrea/pkg/util/env"
3840
"antrea.io/antrea/pkg/util/flowexport"
3941
"antrea.io/antrea/pkg/util/ip"
@@ -193,7 +195,7 @@ func (o *Options) setDefaults() {
193195
if o.config.OVSRunDir == "" {
194196
o.config.OVSRunDir = ovsconfig.DefaultOVSRunDir
195197
}
196-
if o.config.APIPort == 0 {
198+
if !checks.IsValidPort(o.config.APIPort) {
197199
o.config.APIPort = apis.AntreaAgentAPIPort
198200
}
199201
if o.config.NodeType == "" {
@@ -430,13 +432,13 @@ func (o *Options) setK8sNodeDefaultOptions() {
430432
if o.config.AntreaProxy.DefaultLoadBalancerMode == "" {
431433
o.config.AntreaProxy.DefaultLoadBalancerMode = config.LoadBalancerModeNAT.String()
432434
}
433-
if o.config.ClusterMembershipPort == 0 {
435+
if !checks.IsValidPort(o.config.ClusterMembershipPort) {
434436
o.config.ClusterMembershipPort = apis.AntreaAgentClusterMembershipPort
435437
}
436438
if o.config.EnablePrometheusMetrics == nil {
437439
o.config.EnablePrometheusMetrics = ptr.To(true)
438440
}
439-
if o.config.WireGuard.Port == 0 {
441+
if !checks.IsValidPort(o.config.WireGuard.Port) {
440442
o.config.WireGuard.Port = apis.WireGuardListenPort
441443
}
442444

@@ -534,6 +536,10 @@ func (o *Options) validateK8sNodeOptions() error {
534536
o.config.TunnelType != ovsconfig.GRETunnel && o.config.TunnelType != ovsconfig.STTTunnel {
535537
return fmt.Errorf("tunnel type %s is invalid", o.config.TunnelType)
536538
}
539+
// Zero for tunnelPort means Antrea will use the assigned IANA port for a given tunnel protocol.
540+
if o.config.TunnelPort != 0 && !checks.IsValidPort(int(o.config.TunnelPort)) {
541+
return fmt.Errorf("tunnel port %d is invalid", o.config.TunnelPort)
542+
}
537543
ok, encryptionMode := config.GetTrafficEncryptionModeFromStr(o.config.TrafficEncryptionMode)
538544
if !ok {
539545
return fmt.Errorf("TrafficEncryptionMode %s is unknown", o.config.TrafficEncryptionMode)
@@ -605,8 +611,9 @@ func (o *Options) validateK8sNodeOptions() error {
605611

606612
if o.config.DNSServerOverride != "" {
607613
hostPort := ip.AppendPortIfMissing(o.config.DNSServerOverride, "53")
608-
_, _, err := net.SplitHostPort(hostPort)
609-
if err != nil {
614+
_, port, err := net.SplitHostPort(hostPort)
615+
portNum, parseErr := strconv.Atoi(port)
616+
if err != nil || !checks.IsValidPort(portNum) || parseErr != nil {
610617
return fmt.Errorf("dnsServerOverride %s is invalid: %v", o.config.DNSServerOverride, err)
611618
}
612619
o.dnsServerOverride = hostPort
@@ -706,7 +713,7 @@ func (o *Options) setExternalNodeDefaultOptions() {
706713
func (o *Options) setMulticlusterDefaultOptions() {
707714
_, trafficEncryptionModeType := config.GetTrafficEncryptionModeFromStr(o.config.Multicluster.TrafficEncryptionMode)
708715
if trafficEncryptionModeType == config.TrafficEncryptionModeWireGuard {
709-
if o.config.Multicluster.WireGuard.Port == 0 {
716+
if !checks.IsValidPort(o.config.Multicluster.WireGuard.Port) {
710717
o.config.Multicluster.WireGuard.Port = apis.MulticlusterWireGuardListenPort
711718
}
712719
}

cmd/antrea-agent/options_linux_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ func TestMulticlusterOptions(t *testing.T) {
8888
FeatureGates: map[string]bool{"Multicluster": tt.featureGate},
8989
TrafficEncapMode: tt.encapMode,
9090
Multicluster: tt.mcConfig,
91+
TunnelPort: 6081,
9192
}
9293
if tt.encryptionMode != "" {
9394
config.TrafficEncryptionMode = tt.encryptionMode

pkg/util/checks/checks.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2025 Antrea Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package checks
16+
17+
// IsValidPort checks if the given port number is within the valid range of 1 to 65535.
18+
func IsValidPort(port int) bool {
19+
if port < 1 || port > 65535 {
20+
return false
21+
}
22+
return true
23+
}

pkg/util/checks/checks_test.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2025 Antrea Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package checks
16+
17+
import (
18+
"testing"
19+
20+
"github.com/stretchr/testify/assert"
21+
)
22+
23+
func TestIsValidPort(t *testing.T) {
24+
tests := []struct {
25+
name string
26+
port int
27+
expected bool
28+
}{
29+
{
30+
name: "invalid port 0",
31+
port: 0,
32+
expected: false,
33+
},
34+
{
35+
name: "invalid port 70000",
36+
port: 70000,
37+
expected: false,
38+
},
39+
{
40+
name: "valid port",
41+
port: 65500,
42+
expected: true,
43+
},
44+
}
45+
46+
for _, tc := range tests {
47+
t.Run(tc.name, func(t *testing.T) {
48+
result := IsValidPort(tc.port)
49+
assert.Equal(t, tc.expected, result)
50+
})
51+
}
52+
}

pkg/util/flowexport/flowexport.go

+6
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ package flowexport
1717
import (
1818
"fmt"
1919
"regexp"
20+
"strconv"
2021
"strings"
2122
"time"
2223

2324
flowaggregatorconfig "antrea.io/antrea/pkg/config/flowaggregator"
25+
"antrea.io/antrea/pkg/util/checks"
2426
)
2527

2628
// ParseFlowCollectorAddr parses the flow collector address input for flow exporter and aggregator
@@ -44,6 +46,10 @@ func ParseFlowCollectorAddr(addr string, defaultPort string, defaultProtocol str
4446
port = defaultPort
4547
} else {
4648
port = strSlice[1]
49+
portNum, err := strconv.Atoi(port)
50+
if !checks.IsValidPort(portNum) || err != nil {
51+
port = defaultPort
52+
}
4753
}
4854
if (strSlice[2] != "tls") && (strSlice[2] != "tcp") && (strSlice[2] != "udp") {
4955
return host, port, proto, fmt.Errorf("connection over %s transport proto is not supported", strSlice[2])

pkg/util/flowexport/flowexport_test.go

+14
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,20 @@ func TestParseFlowCollectorAddr(t *testing.T) {
6767
expectedProto: "tcp",
6868
expectedError: nil,
6969
},
70+
{
71+
addr: "flow-aggregator/flow-aggregator:str:tcp",
72+
expectedHost: "flow-aggregator/flow-aggregator",
73+
expectedPort: defaultFlowCollectorPort,
74+
expectedProto: "tcp",
75+
expectedError: nil,
76+
},
77+
{
78+
addr: "flow-aggregator/flow-aggregator:78900:tcp",
79+
expectedHost: "flow-aggregator/flow-aggregator",
80+
expectedPort: defaultFlowCollectorPort,
81+
expectedProto: "tcp",
82+
expectedError: nil,
83+
},
7084
{
7185
addr: ":abbbsctp::",
7286
expectedHost: "",

pkg/util/k8s/client.go

+6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"fmt"
1919
"net"
2020
"os"
21+
"strconv"
2122
"strings"
2223

2324
discovery "k8s.io/api/discovery/v1"
@@ -33,6 +34,7 @@ import (
3334

3435
mcclientset "antrea.io/antrea/multicluster/pkg/client/clientset/versioned"
3536
crdclientset "antrea.io/antrea/pkg/client/clientset/versioned"
37+
"antrea.io/antrea/pkg/util/checks"
3638
)
3739

3840
const (
@@ -125,6 +127,10 @@ func OverrideKubeAPIServer(kubeAPIServerOverride string) {
125127
host = hostPort
126128
port = "443"
127129
}
130+
portNum, err := strconv.Atoi(port)
131+
if !checks.IsValidPort(portNum) || err != nil {
132+
port = "443"
133+
}
128134
os.Setenv(kubeServiceHostEnvKey, host)
129135
os.Setenv(kubeServicePortEnvKey, port)
130136
}

0 commit comments

Comments
 (0)