Skip to content

Commit 0d2462a

Browse files
committed
add support for ipv6
1 parent 7bc0b6e commit 0d2462a

File tree

18 files changed

+574
-133
lines changed

18 files changed

+574
-133
lines changed

apis/v1alpha1/nginxproxy_types.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1010

1111
// NginxProxy is a configuration object that is attached to a GatewayClass parametersRef. It provides a way
1212
// to configure global settings for all Gateways defined from the GatewayClass.
13-
type NginxProxy struct { //nolint:govet // standard field alignment, don't change it
13+
type NginxProxy struct {
1414
metav1.TypeMeta `json:",inline"`
1515
metav1.ObjectMeta `json:"metadata,omitempty"`
1616

@@ -27,12 +27,31 @@ type NginxProxyList struct {
2727
Items []NginxProxy `json:"items"`
2828
}
2929

30+
// IPFamilyType specifies the IP family to be used by the server.
31+
//
32+
// +kubebuilder:validation:Enum=dual;ipv4;ipv6
33+
type IPFamilyType string
34+
35+
const (
36+
// Dual specifies that the server will use both IPv4 and IPv6.
37+
Dual IPFamilyType = "dual"
38+
// IPv4 specifies that the server will use only IPv4.
39+
IPv4 IPFamilyType = "ipv4"
40+
// IPv6 specifies that the server will use only IPv6.
41+
IPv6 IPFamilyType = "ipv6"
42+
)
43+
3044
// NginxProxySpec defines the desired state of the NginxProxy.
3145
type NginxProxySpec struct {
3246
// Telemetry specifies the OpenTelemetry configuration.
3347
//
3448
// +optional
3549
Telemetry *Telemetry `json:"telemetry,omitempty"`
50+
// IPFamily specifies the IP family to be used by the server.
51+
// Default is "dual", meaning the server will use both IPv4 and IPv6.
52+
//
53+
// +optional
54+
IPFamily IPFamilyType `json:"ipFamily,omitempty"`
3655
// DisableHTTP2 defines if http2 should be disabled for all servers.
3756
// Default is false, meaning http2 will be enabled for all servers.
3857
//

charts/nginx-gateway-fabric/values.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ nginx:
8686
config:
8787
{}
8888
# disableHTTP2: false
89+
# ipFamily: dual
8990
# telemetry:
9091
# exporter:
9192
# endpoint: otel-collector.default.svc:4317

config/crd/bases/gateway.nginx.org_nginxproxies.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ spec:
5252
DisableHTTP2 defines if http2 should be disabled for all servers.
5353
Default is false, meaning http2 will be enabled for all servers.
5454
type: boolean
55+
ipFamily:
56+
description: |-
57+
IPFamily specifies the IP family to be used by the server.
58+
Default is "dual", meaning the server will use both IPv4 and IPv6.
59+
enum:
60+
- dual
61+
- ipv4
62+
- ipv6
63+
type: string
5564
telemetry:
5665
description: Telemetry specifies the OpenTelemetry configuration.
5766
properties:

deploy/crds.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,15 @@ spec:
697697
DisableHTTP2 defines if http2 should be disabled for all servers.
698698
Default is false, meaning http2 will be enabled for all servers.
699699
type: boolean
700+
ipFamily:
701+
description: |-
702+
IPFamily specifies the IP family to be used by the server.
703+
Default is "dual", meaning the server will use both IPv4 and IPv6.
704+
enum:
705+
- dual
706+
- ipv4
707+
- ipv6
708+
type: string
700709
telemetry:
701710
description: Telemetry specifies the OpenTelemetry configuration.
702711
properties:

docs/developer/quickstart.md

+19
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,29 @@ This will build the docker images `nginx-gateway-fabric:<your-user>` and `nginx-
114114

115115
1. Create a `kind` cluster:
116116

117+
To create a `kind` cluster with IPv4 enabled:
118+
117119
```makefile
118120
make create-kind-cluster
119121
```
120122

123+
To create a `kind` cluster with IPv6 or Dual IPFamily enabled, use this `config.yaml`:
124+
125+
```yaml
126+
kind: Cluster
127+
apiVersion: kind.x-k8s.io/v1alpha4
128+
nodes:
129+
- role: control-plane
130+
networking:
131+
ipFamily: dual
132+
# ipFamily: ipv6
133+
apiServerAddress: 127.0.0.1
134+
```
135+
136+
```shell
137+
kind create cluster --config ~/cluster.yaml
138+
```
139+
121140
2. Load the previously built images onto your `kind` cluster:
122141

123142
```shell

internal/mode/static/nginx/config/http/config.go

+7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ type Server struct {
1010
IsDefaultHTTP bool
1111
IsDefaultSSL bool
1212
GRPC bool
13+
IPFamily IPFamily
14+
}
15+
16+
// IPFamily holds the IP family configuration for all servers.
17+
type IPFamily struct {
18+
IPv4 bool
19+
IPv6 bool
1320
}
1421

1522
// Location holds all configuration for an HTTP location.

internal/mode/static/nginx/config/servers.go

+36-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99
gotemplate "text/template"
1010

11+
ngfAPI "github.com/nginxinc/nginx-gateway-fabric/apis/v1alpha1"
1112
"github.com/nginxinc/nginx-gateway-fabric/internal/framework/helpers"
1213
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/http"
1314
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane"
@@ -58,7 +59,8 @@ var grpcBaseHeaders = []http.Header{
5859
}
5960

6061
func executeServers(conf dataplane.Configuration) []executeResult {
61-
servers, httpMatchPairs := createServers(conf.HTTPServers, conf.SSLServers)
62+
ipFamily := getIPFamily(conf.BaseHTTPConfig)
63+
servers, httpMatchPairs := createServers(conf.HTTPServers, conf.SSLServers, ipFamily)
6264

6365
serverResult := executeResult{
6466
dest: httpConfigFile,
@@ -86,6 +88,18 @@ func executeServers(conf dataplane.Configuration) []executeResult {
8688
return allResults
8789
}
8890

91+
// getIPFamily returns whether the server should be configured for IPv4, IPv6, or both.
92+
func getIPFamily(baseHTTPConfig dataplane.BaseHTTPConfig) http.IPFamily {
93+
switch ip := baseHTTPConfig.IPFamily; ip {
94+
case ngfAPI.IPv4:
95+
return http.IPFamily{IPv4: true}
96+
case ngfAPI.IPv6:
97+
return http.IPFamily{IPv6: true}
98+
}
99+
100+
return http.IPFamily{IPv4: true, IPv6: true}
101+
}
102+
89103
func createAdditionFileResults(conf dataplane.Configuration) []executeResult {
90104
uniqueAdditions := make(map[string][]byte)
91105

@@ -141,30 +155,39 @@ func createIncludes(additions []dataplane.Addition) []string {
141155
return includes
142156
}
143157

144-
func createServers(httpServers, sslServers []dataplane.VirtualServer) ([]http.Server, httpMatchPairs) {
158+
func createServers(
159+
httpServers,
160+
sslServers []dataplane.VirtualServer,
161+
ipFamily http.IPFamily,
162+
) ([]http.Server, httpMatchPairs) {
145163
servers := make([]http.Server, 0, len(httpServers)+len(sslServers))
146164
finalMatchPairs := make(httpMatchPairs)
147165

148166
for serverID, s := range httpServers {
149-
httpServer, matchPairs := createServer(s, serverID)
167+
httpServer, matchPairs := createServer(s, serverID, ipFamily)
150168
servers = append(servers, httpServer)
151169
maps.Copy(finalMatchPairs, matchPairs)
152170
}
153171

154172
for serverID, s := range sslServers {
155-
sslServer, matchPair := createSSLServer(s, serverID)
173+
sslServer, matchPair := createSSLServer(s, serverID, ipFamily)
156174
servers = append(servers, sslServer)
157175
maps.Copy(finalMatchPairs, matchPair)
158176
}
159177

160178
return servers, finalMatchPairs
161179
}
162180

163-
func createSSLServer(virtualServer dataplane.VirtualServer, serverID int) (http.Server, httpMatchPairs) {
181+
func createSSLServer(
182+
virtualServer dataplane.VirtualServer,
183+
serverID int,
184+
ipFamily http.IPFamily,
185+
) (http.Server, httpMatchPairs) {
164186
if virtualServer.IsDefault {
165187
return http.Server{
166188
IsDefaultSSL: true,
167189
Port: virtualServer.Port,
190+
IPFamily: ipFamily,
168191
}, nil
169192
}
170193

@@ -180,14 +203,20 @@ func createSSLServer(virtualServer dataplane.VirtualServer, serverID int) (http.
180203
Port: virtualServer.Port,
181204
GRPC: grpc,
182205
Includes: createIncludes(virtualServer.Additions),
206+
IPFamily: ipFamily,
183207
}, matchPairs
184208
}
185209

186-
func createServer(virtualServer dataplane.VirtualServer, serverID int) (http.Server, httpMatchPairs) {
210+
func createServer(
211+
virtualServer dataplane.VirtualServer,
212+
serverID int,
213+
ipFamily http.IPFamily,
214+
) (http.Server, httpMatchPairs) {
187215
if virtualServer.IsDefault {
188216
return http.Server{
189217
IsDefaultHTTP: true,
190218
Port: virtualServer.Port,
219+
IPFamily: ipFamily,
191220
}, nil
192221
}
193222

@@ -199,6 +228,7 @@ func createServer(virtualServer dataplane.VirtualServer, serverID int) (http.Ser
199228
Port: virtualServer.Port,
200229
GRPC: grpc,
201230
Includes: createIncludes(virtualServer.Additions),
231+
IPFamily: ipFamily,
202232
}, matchPairs
203233
}
204234

internal/mode/static/nginx/config/servers_template.go

+20
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,50 @@ js_preload_object matches from /etc/nginx/conf.d/matches.json;
55
{{- range $s := . -}}
66
{{ if $s.IsDefaultSSL -}}
77
server {
8+
{{- if $s.IPFamily.IPv4 }}
89
listen {{ $s.Port }} ssl default_server;
10+
{{- end }}
11+
{{- if $s.IPFamily.IPv6 }}
12+
listen [::]:{{ $s.Port }} ssl default_server;
13+
{{- end }}
914
1015
ssl_reject_handshake on;
1116
}
1217
{{- else if $s.IsDefaultHTTP }}
1318
server {
19+
{{- if $s.IPFamily.IPv4 }}
1420
listen {{ $s.Port }} default_server;
21+
{{- end }}
22+
{{- if $s.IPFamily.IPv6 }}
23+
listen [::]:{{ $s.Port }} default_server;
24+
{{- end }}
1525
1626
default_type text/html;
1727
return 404;
1828
}
1929
{{- else }}
2030
server {
2131
{{- if $s.SSL }}
32+
{{- if $s.IPFamily.IPv4 }}
2233
listen {{ $s.Port }} ssl;
34+
{{- end }}
35+
{{- if $s.IPFamily.IPv6 }}
36+
listen [::]:{{ $s.Port }} ssl;
37+
{{- end }}
2338
ssl_certificate {{ $s.SSL.Certificate }};
2439
ssl_certificate_key {{ $s.SSL.CertificateKey }};
2540
2641
if ($ssl_server_name != $host) {
2742
return 421;
2843
}
2944
{{- else }}
45+
{{- if $s.IPFamily.IPv4 }}
3046
listen {{ $s.Port }};
3147
{{- end }}
48+
{{- if $s.IPFamily.IPv6 }}
49+
listen [::]:{{ $s.Port }};
50+
{{- end }}
51+
{{- end }}
3252
3353
server_name {{ $s.ServerName }};
3454

0 commit comments

Comments
 (0)