Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
tcp:
- address: 0.0.0.0
connection:
bufferLimit: 50000000
limit:
closeDelay: 10s
value: 3
proxyProtocol:
optional: false
name: envoy-gateway/gateway-1/tls-1
port: 10443
tcpKeepalive:
idleTime: 1200
interval: 60
probes: 3
timeout:
tcp:
idleTimeout: 20m0s
- address: 0.0.0.0
connection:
bufferLimit: 50000000
limit:
closeDelay: 10s
value: 3
proxyProtocol:
optional: false
name: envoy-gateway/gateway-1/tls-2
port: 11443
tcpKeepalive:
idleTime: 1200
interval: 60
probes: 3
timeout:
tcp:
idleTimeout: 20m0s
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
tcp:
- name: tls-passthrough-1
address: 0.0.0.0
port: 10443
tls: {}
routes: []
- name: tls-passthrough-2
address: 0.0.0.0
port: 10443
tls: {}
routes: []
- name: tls-passthrough-3
address: 0.0.0.0
port: 10443
tls: {}
routes: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- name: EmptyCluster
type: STATIC
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
- address:
socketAddress:
address: 0.0.0.0
portValue: 10443
filterChains:
- filters:
- name: envoy.filters.network.connection_limit
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit
delay: 10s
maxConnections: "3"
statPrefix: tcp-10443
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: EmptyCluster
idleTimeout: 1200s
statPrefix: tcp-10443
name: EmptyCluster
listenerFilters:
- name: envoy.filters.listener.proxy_protocol
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.listener.proxy_protocol.v3.ProxyProtocol
maxConnectionsToAcceptPerSocketEvent: 1
name: envoy-gateway/gateway-1/tls-1
perConnectionBufferLimitBytes: 50000000
socketOptions:
- description: socket option to enable tcp keep alive
intValue: "1"
level: "1"
name: "9"
- description: socket option for keep alive probes
intValue: "3"
level: "6"
name: "6"
- description: socket option for keep alive idle time
intValue: "1200"
level: "6"
name: "4"
- description: socket option for keep alive interval
intValue: "60"
level: "6"
name: "5"
- address:
socketAddress:
address: 0.0.0.0
portValue: 11443
filterChains:
- filters:
- name: envoy.filters.network.connection_limit
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit
delay: 10s
maxConnections: "3"
statPrefix: tcp-11443
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: EmptyCluster
idleTimeout: 1200s
statPrefix: tcp-11443
name: EmptyCluster
listenerFilters:
- name: envoy.filters.listener.proxy_protocol
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.listener.proxy_protocol.v3.ProxyProtocol
maxConnectionsToAcceptPerSocketEvent: 1
name: envoy-gateway/gateway-1/tls-2
perConnectionBufferLimitBytes: 50000000
socketOptions:
- description: socket option to enable tcp keep alive
intValue: "1"
level: "1"
name: "9"
- description: socket option for keep alive probes
intValue: "3"
level: "6"
name: "6"
- description: socket option for keep alive idle time
intValue: "1200"
level: "6"
name: "4"
- description: socket option for keep alive interval
intValue: "60"
level: "6"
name: "5"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- name: EmptyCluster-tls-passthrough-1
type: STATIC
- name: EmptyCluster-tls-passthrough-2
type: STATIC
- name: EmptyCluster-tls-passthrough-3
type: STATIC
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
- address:
socketAddress:
address: 0.0.0.0
portValue: 10443
filterChains:
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: EmptyCluster-tls-passthrough-1
statPrefix: tcp-10443
name: EmptyCluster-tls-passthrough-1
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: EmptyCluster-tls-passthrough-2
statPrefix: tcp-10443
name: EmptyCluster-tls-passthrough-2
- filters:
- name: envoy.filters.network.tcp_proxy
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: EmptyCluster-tls-passthrough-3
statPrefix: tcp-10443
name: EmptyCluster-tls-passthrough-3
maxConnectionsToAcceptPerSocketEvent: 1
name: tls-passthrough-1
perConnectionBufferLimitBytes: 32768
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
61 changes: 48 additions & 13 deletions internal/xds/translator/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,8 @@ func (t *Translator) processTCPListenerXdsTranslation(
// errors and return them at the end.
var errs, err error

var sharedEmptyTCPRoute *ir.TCPRoute

for _, tcpListener := range tcpListeners {
// Search for an existing listener, if it does not exist, create one.
xdsListener := findXdsListenerByHostPort(tCtx, tcpListener.Address, tcpListener.Port, corev3.SocketAddress_TCP)
Expand Down Expand Up @@ -822,32 +824,65 @@ func (t *Translator) processTCPListenerXdsTranslation(
}
}

// If there are no routes, add a route without a destination to the listener to create a filter chain
// This is needed because Envoy requires a filter chain to be present in the listener, otherwise it will reject the listener and report a warning
if len(tcpListener.Routes) == 0 {
if findXdsCluster(tCtx, emptyClusterName) == nil {
if err := tCtx.AddXdsResource(resourcev3.ClusterType, emptyRouteCluster); err != nil {
errs = errors.Join(errs, err)
isTLSPassthrough := tcpListener.TLS != nil

clusterName := emptyClusterName
var route *ir.TCPRoute

if isTLSPassthrough {
// TLS passthrough listeners must not share EmptyCluster
clusterName = fmt.Sprintf("%s-%s", emptyClusterName, tcpListener.Name)

if findXdsCluster(tCtx, clusterName) == nil {
if err := tCtx.AddXdsResource(
resourcev3.ClusterType,
&clusterv3.Cluster{
Name: clusterName,
ClusterDiscoveryType: &clusterv3.Cluster_Type{Type: clusterv3.Cluster_STATIC},
},
); err != nil {
errs = errors.Join(errs, err)
}
}
}

emptyRoute := &ir.TCPRoute{
Name: emptyClusterName,
Destination: &ir.RouteDestination{
Name: emptyClusterName,
},
route = &ir.TCPRoute{
Name: clusterName,
Destination: &ir.RouteDestination{
Name: clusterName,
},
}
} else {
// Non-TLS-passthrough: reuse shared EmptyCluster
if findXdsCluster(tCtx, emptyClusterName) == nil {
if err := tCtx.AddXdsResource(resourcev3.ClusterType, emptyRouteCluster); err != nil {
errs = errors.Join(errs, err)
}
}

if sharedEmptyTCPRoute == nil {
sharedEmptyTCPRoute = &ir.TCPRoute{
Name: emptyClusterName,
Destination: &ir.RouteDestination{
Name: emptyClusterName,
},
}
}
route = sharedEmptyTCPRoute
}

if err := t.addXdsTCPFilterChain(
xdsListener,
emptyRoute,
emptyClusterName,
route,
clusterName,
accesslog,
tcpListener.Timeout,
tcpListener.Connection,
); err != nil {
errs = errors.Join(errs, err)
}
}

}

return errs
Expand Down
Loading