istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/networking/core/gateway_test.go (about)

     1  // Copyright Istio 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 core
    16  
    17  import (
    18  	"reflect"
    19  	"sort"
    20  	"testing"
    21  	"time"
    22  
    23  	core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
    24  	route "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
    25  	hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
    26  	auth "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
    27  	"github.com/google/go-cmp/cmp"
    28  	"github.com/google/uuid"
    29  	"google.golang.org/protobuf/testing/protocmp"
    30  	"google.golang.org/protobuf/types/known/durationpb"
    31  	wrappers "google.golang.org/protobuf/types/known/wrapperspb"
    32  
    33  	extensions "istio.io/api/extensions/v1alpha1"
    34  	meshconfig "istio.io/api/mesh/v1alpha1"
    35  	networking "istio.io/api/networking/v1alpha3"
    36  	security "istio.io/api/security/v1beta1"
    37  	telemetry "istio.io/api/telemetry/v1alpha1"
    38  	"istio.io/istio/pilot/pkg/features"
    39  	pilot_model "istio.io/istio/pilot/pkg/model"
    40  	istionetworking "istio.io/istio/pilot/pkg/networking"
    41  	"istio.io/istio/pilot/pkg/networking/core/listenertest"
    42  	istio_route "istio.io/istio/pilot/pkg/networking/core/route"
    43  	"istio.io/istio/pilot/pkg/networking/util"
    44  	"istio.io/istio/pilot/pkg/security/model"
    45  	xdsfilters "istio.io/istio/pilot/pkg/xds/filters"
    46  	"istio.io/istio/pilot/test/xdstest"
    47  	config "istio.io/istio/pkg/config"
    48  	"istio.io/istio/pkg/config/host"
    49  	"istio.io/istio/pkg/config/mesh"
    50  	"istio.io/istio/pkg/config/protocol"
    51  	"istio.io/istio/pkg/config/schema/gvk"
    52  	"istio.io/istio/pkg/config/visibility"
    53  	"istio.io/istio/pkg/config/xds"
    54  	"istio.io/istio/pkg/maps"
    55  	"istio.io/istio/pkg/proto"
    56  	"istio.io/istio/pkg/slices"
    57  	"istio.io/istio/pkg/test"
    58  	"istio.io/istio/pkg/util/sets"
    59  	"istio.io/istio/pkg/wellknown"
    60  )
    61  
    62  func TestBuildGatewayListenerTlsContext(t *testing.T) {
    63  	testCases := []struct {
    64  		name              string
    65  		server            *networking.Server
    66  		result            *auth.DownstreamTlsContext
    67  		transportProtocol istionetworking.TransportProtocol
    68  		mesh              *meshconfig.MeshConfig
    69  	}{
    70  		{
    71  			name: "mesh SDS enabled, tls mode ISTIO_MUTUAL",
    72  			server: &networking.Server{
    73  				Hosts: []string{"httpbin.example.com"},
    74  				Port: &networking.Port{
    75  					Protocol: string(protocol.HTTPS),
    76  				},
    77  				Tls: &networking.ServerTLSSettings{
    78  					Mode: networking.ServerTLSSettings_ISTIO_MUTUAL,
    79  				},
    80  			},
    81  			result: &auth.DownstreamTlsContext{
    82  				CommonTlsContext: &auth.CommonTlsContext{
    83  					AlpnProtocols: util.ALPNHttp,
    84  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
    85  						{
    86  							Name: "default",
    87  							SdsConfig: &core.ConfigSource{
    88  								InitialFetchTimeout: durationpb.New(time.Second * 0),
    89  								ResourceApiVersion:  core.ApiVersion_V3,
    90  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
    91  									ApiConfigSource: &core.ApiConfigSource{
    92  										ApiType:                   core.ApiConfigSource_GRPC,
    93  										SetNodeOnFirstMessageOnly: true,
    94  										TransportApiVersion:       core.ApiVersion_V3,
    95  										GrpcServices: []*core.GrpcService{
    96  											{
    97  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
    98  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
    99  												},
   100  											},
   101  										},
   102  									},
   103  								},
   104  							},
   105  						},
   106  					},
   107  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
   108  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
   109  							DefaultValidationContext: &auth.CertificateValidationContext{},
   110  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
   111  								Name: "ROOTCA",
   112  								SdsConfig: &core.ConfigSource{
   113  									InitialFetchTimeout: durationpb.New(time.Second * 0),
   114  									ResourceApiVersion:  core.ApiVersion_V3,
   115  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   116  										ApiConfigSource: &core.ApiConfigSource{
   117  											ApiType:                   core.ApiConfigSource_GRPC,
   118  											SetNodeOnFirstMessageOnly: true,
   119  											TransportApiVersion:       core.ApiVersion_V3,
   120  											GrpcServices: []*core.GrpcService{
   121  												{
   122  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   123  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   124  													},
   125  												},
   126  											},
   127  										},
   128  									},
   129  								},
   130  							},
   131  						},
   132  					},
   133  				},
   134  				RequireClientCertificate: proto.BoolTrue,
   135  			},
   136  		},
   137  		{
   138  			name: "mesh SDS enabled, tls mode ISTIO_MUTUAL, CRL specified",
   139  			server: &networking.Server{
   140  				Hosts: []string{"httpbin.example.com"},
   141  				Port: &networking.Port{
   142  					Protocol: string(protocol.HTTPS),
   143  				},
   144  				Tls: &networking.ServerTLSSettings{
   145  					Mode:  networking.ServerTLSSettings_ISTIO_MUTUAL,
   146  					CaCrl: "/custom/path/to/crl.pem",
   147  				},
   148  			},
   149  			result: &auth.DownstreamTlsContext{
   150  				CommonTlsContext: &auth.CommonTlsContext{
   151  					AlpnProtocols: util.ALPNHttp,
   152  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   153  						{
   154  							Name: "default",
   155  							SdsConfig: &core.ConfigSource{
   156  								InitialFetchTimeout: durationpb.New(time.Second * 0),
   157  								ResourceApiVersion:  core.ApiVersion_V3,
   158  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   159  									ApiConfigSource: &core.ApiConfigSource{
   160  										ApiType:                   core.ApiConfigSource_GRPC,
   161  										SetNodeOnFirstMessageOnly: true,
   162  										TransportApiVersion:       core.ApiVersion_V3,
   163  										GrpcServices: []*core.GrpcService{
   164  											{
   165  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   166  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   167  												},
   168  											},
   169  										},
   170  									},
   171  								},
   172  							},
   173  						},
   174  					},
   175  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
   176  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
   177  							DefaultValidationContext: &auth.CertificateValidationContext{
   178  								Crl: &core.DataSource{
   179  									Specifier: &core.DataSource_Filename{
   180  										Filename: "/custom/path/to/crl.pem",
   181  									},
   182  								},
   183  							},
   184  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
   185  								Name: "ROOTCA",
   186  								SdsConfig: &core.ConfigSource{
   187  									InitialFetchTimeout: durationpb.New(time.Second * 0),
   188  									ResourceApiVersion:  core.ApiVersion_V3,
   189  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   190  										ApiConfigSource: &core.ApiConfigSource{
   191  											ApiType:                   core.ApiConfigSource_GRPC,
   192  											SetNodeOnFirstMessageOnly: true,
   193  											TransportApiVersion:       core.ApiVersion_V3,
   194  											GrpcServices: []*core.GrpcService{
   195  												{
   196  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   197  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   198  													},
   199  												},
   200  											},
   201  										},
   202  									},
   203  								},
   204  							},
   205  						},
   206  					},
   207  				},
   208  				RequireClientCertificate: proto.BoolTrue,
   209  			},
   210  		},
   211  		{
   212  			// regression test for having both fields set. This is rejected in validation.
   213  			name: "tls mode ISTIO_MUTUAL, with credentialName",
   214  			server: &networking.Server{
   215  				Hosts: []string{"httpbin.example.com"},
   216  				Port: &networking.Port{
   217  					Protocol: string(protocol.HTTPS),
   218  				},
   219  				Tls: &networking.ServerTLSSettings{
   220  					Mode:           networking.ServerTLSSettings_ISTIO_MUTUAL,
   221  					CredentialName: "ignored",
   222  				},
   223  			},
   224  			result: &auth.DownstreamTlsContext{
   225  				CommonTlsContext: &auth.CommonTlsContext{
   226  					AlpnProtocols: util.ALPNHttp,
   227  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   228  						{
   229  							Name: "default",
   230  							SdsConfig: &core.ConfigSource{
   231  								InitialFetchTimeout: durationpb.New(time.Second * 0),
   232  								ResourceApiVersion:  core.ApiVersion_V3,
   233  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   234  									ApiConfigSource: &core.ApiConfigSource{
   235  										ApiType:                   core.ApiConfigSource_GRPC,
   236  										SetNodeOnFirstMessageOnly: true,
   237  										TransportApiVersion:       core.ApiVersion_V3,
   238  										GrpcServices: []*core.GrpcService{
   239  											{
   240  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   241  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   242  												},
   243  											},
   244  										},
   245  									},
   246  								},
   247  							},
   248  						},
   249  					},
   250  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
   251  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
   252  							DefaultValidationContext: &auth.CertificateValidationContext{},
   253  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
   254  								Name: "ROOTCA",
   255  								SdsConfig: &core.ConfigSource{
   256  									InitialFetchTimeout: durationpb.New(time.Second * 0),
   257  									ResourceApiVersion:  core.ApiVersion_V3,
   258  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   259  										ApiConfigSource: &core.ApiConfigSource{
   260  											ApiType:                   core.ApiConfigSource_GRPC,
   261  											SetNodeOnFirstMessageOnly: true,
   262  											TransportApiVersion:       core.ApiVersion_V3,
   263  											GrpcServices: []*core.GrpcService{
   264  												{
   265  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   266  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   267  													},
   268  												},
   269  											},
   270  										},
   271  									},
   272  								},
   273  							},
   274  						},
   275  					},
   276  				},
   277  				RequireClientCertificate: proto.BoolTrue,
   278  			},
   279  		},
   280  		{ // No credential name is specified, generate file paths for key/cert.
   281  			name: "no credential name no key no cert tls SIMPLE",
   282  			server: &networking.Server{
   283  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   284  				Port: &networking.Port{
   285  					Protocol: string(protocol.HTTPS),
   286  				},
   287  				Tls: &networking.ServerTLSSettings{
   288  					Mode: networking.ServerTLSSettings_SIMPLE,
   289  				},
   290  			},
   291  			result: &auth.DownstreamTlsContext{
   292  				CommonTlsContext: &auth.CommonTlsContext{
   293  					AlpnProtocols: util.ALPNHttp,
   294  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   295  						{
   296  							Name: "default",
   297  							SdsConfig: &core.ConfigSource{
   298  								InitialFetchTimeout: durationpb.New(time.Second * 0),
   299  								ResourceApiVersion:  core.ApiVersion_V3,
   300  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   301  									ApiConfigSource: &core.ApiConfigSource{
   302  										ApiType:                   core.ApiConfigSource_GRPC,
   303  										SetNodeOnFirstMessageOnly: true,
   304  										TransportApiVersion:       core.ApiVersion_V3,
   305  										GrpcServices: []*core.GrpcService{
   306  											{
   307  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   308  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   309  												},
   310  											},
   311  										},
   312  									},
   313  								},
   314  							},
   315  						},
   316  					},
   317  				},
   318  				RequireClientCertificate: proto.BoolFalse,
   319  			},
   320  		},
   321  		{ // Credential name is specified, SDS config is generated for fetching key/cert.
   322  			name: "credential name no key no cert tls SIMPLE",
   323  			server: &networking.Server{
   324  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   325  				Port: &networking.Port{
   326  					Protocol: string(protocol.HTTPS),
   327  				},
   328  				Tls: &networking.ServerTLSSettings{
   329  					Mode:           networking.ServerTLSSettings_SIMPLE,
   330  					CredentialName: "ingress-sds-resource-name",
   331  				},
   332  			},
   333  			result: &auth.DownstreamTlsContext{
   334  				CommonTlsContext: &auth.CommonTlsContext{
   335  					AlpnProtocols: util.ALPNHttp,
   336  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   337  						{
   338  							Name:      "kubernetes://ingress-sds-resource-name",
   339  							SdsConfig: model.SDSAdsConfig,
   340  						},
   341  					},
   342  				},
   343  				RequireClientCertificate: proto.BoolFalse,
   344  			},
   345  		},
   346  		{ // Credential name and subject alternative names are specified, generate SDS configs for
   347  			// key/cert and static validation context config.
   348  			name: "credential name subject alternative name no key no cert tls SIMPLE",
   349  			server: &networking.Server{
   350  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   351  				Port: &networking.Port{
   352  					Protocol: string(protocol.HTTPS),
   353  				},
   354  				Tls: &networking.ServerTLSSettings{
   355  					Mode:            networking.ServerTLSSettings_SIMPLE,
   356  					CredentialName:  "ingress-sds-resource-name",
   357  					SubjectAltNames: []string{"subject.name.a.com", "subject.name.b.com"},
   358  				},
   359  			},
   360  			result: &auth.DownstreamTlsContext{
   361  				CommonTlsContext: &auth.CommonTlsContext{
   362  					AlpnProtocols: util.ALPNHttp,
   363  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   364  						{
   365  							Name:      "kubernetes://ingress-sds-resource-name",
   366  							SdsConfig: model.SDSAdsConfig,
   367  						},
   368  					},
   369  					ValidationContextType: &auth.CommonTlsContext_ValidationContext{
   370  						ValidationContext: &auth.CertificateValidationContext{
   371  							MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}),
   372  						},
   373  					},
   374  				},
   375  				RequireClientCertificate: proto.BoolFalse,
   376  			},
   377  		},
   378  		{
   379  			name: "no credential name key and cert tls SIMPLE",
   380  			server: &networking.Server{
   381  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   382  				Port: &networking.Port{
   383  					Protocol: string(protocol.HTTPS),
   384  				},
   385  				Tls: &networking.ServerTLSSettings{
   386  					Mode:              networking.ServerTLSSettings_SIMPLE,
   387  					ServerCertificate: "server-cert.crt",
   388  					PrivateKey:        "private-key.key",
   389  				},
   390  			},
   391  			result: &auth.DownstreamTlsContext{
   392  				CommonTlsContext: &auth.CommonTlsContext{
   393  					AlpnProtocols: util.ALPNHttp,
   394  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   395  						{
   396  							Name: "file-cert:server-cert.crt~private-key.key",
   397  							SdsConfig: &core.ConfigSource{
   398  								ResourceApiVersion: core.ApiVersion_V3,
   399  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   400  									ApiConfigSource: &core.ApiConfigSource{
   401  										ApiType:                   core.ApiConfigSource_GRPC,
   402  										SetNodeOnFirstMessageOnly: true,
   403  										TransportApiVersion:       core.ApiVersion_V3,
   404  										GrpcServices: []*core.GrpcService{
   405  											{
   406  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   407  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   408  												},
   409  											},
   410  										},
   411  									},
   412  								},
   413  							},
   414  						},
   415  					},
   416  				},
   417  				RequireClientCertificate: proto.BoolFalse,
   418  			},
   419  		},
   420  		{
   421  			name: "no credential name key and cert tls MUTUAL",
   422  			server: &networking.Server{
   423  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   424  				Port: &networking.Port{
   425  					Protocol: string(protocol.HTTPS),
   426  				},
   427  				Tls: &networking.ServerTLSSettings{
   428  					Mode:              networking.ServerTLSSettings_MUTUAL,
   429  					ServerCertificate: "server-cert.crt",
   430  					PrivateKey:        "private-key.key",
   431  					CaCertificates:    "ca-cert.crt",
   432  				},
   433  			},
   434  			result: &auth.DownstreamTlsContext{
   435  				CommonTlsContext: &auth.CommonTlsContext{
   436  					AlpnProtocols: util.ALPNHttp,
   437  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   438  						{
   439  							Name: "file-cert:server-cert.crt~private-key.key",
   440  							SdsConfig: &core.ConfigSource{
   441  								ResourceApiVersion: core.ApiVersion_V3,
   442  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   443  									ApiConfigSource: &core.ApiConfigSource{
   444  										ApiType:                   core.ApiConfigSource_GRPC,
   445  										SetNodeOnFirstMessageOnly: true,
   446  										TransportApiVersion:       core.ApiVersion_V3,
   447  										GrpcServices: []*core.GrpcService{
   448  											{
   449  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   450  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   451  												},
   452  											},
   453  										},
   454  									},
   455  								},
   456  							},
   457  						},
   458  					},
   459  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
   460  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
   461  							DefaultValidationContext: &auth.CertificateValidationContext{},
   462  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
   463  								Name: "file-root:ca-cert.crt",
   464  								SdsConfig: &core.ConfigSource{
   465  									ResourceApiVersion: core.ApiVersion_V3,
   466  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   467  										ApiConfigSource: &core.ApiConfigSource{
   468  											ApiType:                   core.ApiConfigSource_GRPC,
   469  											SetNodeOnFirstMessageOnly: true,
   470  											TransportApiVersion:       core.ApiVersion_V3,
   471  											GrpcServices: []*core.GrpcService{
   472  												{
   473  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   474  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   475  													},
   476  												},
   477  											},
   478  										},
   479  									},
   480  								},
   481  							},
   482  						},
   483  					},
   484  				},
   485  				RequireClientCertificate: proto.BoolTrue,
   486  			},
   487  		},
   488  		{
   489  			name: "no credential name key and cert subject alt names tls MUTUAL",
   490  			server: &networking.Server{
   491  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   492  				Port: &networking.Port{
   493  					Protocol: string(protocol.HTTPS),
   494  				},
   495  				Tls: &networking.ServerTLSSettings{
   496  					Mode:              networking.ServerTLSSettings_MUTUAL,
   497  					ServerCertificate: "server-cert.crt",
   498  					PrivateKey:        "private-key.key",
   499  					CaCertificates:    "ca-cert.crt",
   500  					SubjectAltNames:   []string{"subject.name.a.com", "subject.name.b.com"},
   501  				},
   502  			},
   503  			result: &auth.DownstreamTlsContext{
   504  				CommonTlsContext: &auth.CommonTlsContext{
   505  					AlpnProtocols: util.ALPNHttp,
   506  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   507  						{
   508  							Name: "file-cert:server-cert.crt~private-key.key",
   509  							SdsConfig: &core.ConfigSource{
   510  								ResourceApiVersion: core.ApiVersion_V3,
   511  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   512  									ApiConfigSource: &core.ApiConfigSource{
   513  										ApiType:                   core.ApiConfigSource_GRPC,
   514  										SetNodeOnFirstMessageOnly: true,
   515  										TransportApiVersion:       core.ApiVersion_V3,
   516  										GrpcServices: []*core.GrpcService{
   517  											{
   518  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   519  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   520  												},
   521  											},
   522  										},
   523  									},
   524  								},
   525  							},
   526  						},
   527  					},
   528  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
   529  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
   530  							DefaultValidationContext: &auth.CertificateValidationContext{
   531  								MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}),
   532  							},
   533  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
   534  								Name: "file-root:ca-cert.crt",
   535  								SdsConfig: &core.ConfigSource{
   536  									ResourceApiVersion: core.ApiVersion_V3,
   537  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   538  										ApiConfigSource: &core.ApiConfigSource{
   539  											ApiType:                   core.ApiConfigSource_GRPC,
   540  											SetNodeOnFirstMessageOnly: true,
   541  											TransportApiVersion:       core.ApiVersion_V3,
   542  											GrpcServices: []*core.GrpcService{
   543  												{
   544  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   545  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   546  													},
   547  												},
   548  											},
   549  										},
   550  									},
   551  								},
   552  							},
   553  						},
   554  					},
   555  				},
   556  				RequireClientCertificate: proto.BoolTrue,
   557  			},
   558  		},
   559  		{
   560  			name: "no credential name key and cert subject alt names tls MUTUAL",
   561  			server: &networking.Server{
   562  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   563  				Port: &networking.Port{
   564  					Protocol: string(protocol.HTTPS),
   565  				},
   566  				Tls: &networking.ServerTLSSettings{
   567  					Mode:              networking.ServerTLSSettings_MUTUAL,
   568  					ServerCertificate: "server-cert.crt",
   569  					PrivateKey:        "private-key.key",
   570  					CaCertificates:    "ca-cert.crt",
   571  					SubjectAltNames:   []string{"subject.name.a.com", "subject.name.b.com"},
   572  					CaCrl:             "/custom/path/to/crl.pem",
   573  				},
   574  			},
   575  			result: &auth.DownstreamTlsContext{
   576  				CommonTlsContext: &auth.CommonTlsContext{
   577  					AlpnProtocols: util.ALPNHttp,
   578  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   579  						{
   580  							Name: "file-cert:server-cert.crt~private-key.key",
   581  							SdsConfig: &core.ConfigSource{
   582  								ResourceApiVersion: core.ApiVersion_V3,
   583  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   584  									ApiConfigSource: &core.ApiConfigSource{
   585  										ApiType:                   core.ApiConfigSource_GRPC,
   586  										SetNodeOnFirstMessageOnly: true,
   587  										TransportApiVersion:       core.ApiVersion_V3,
   588  										GrpcServices: []*core.GrpcService{
   589  											{
   590  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   591  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   592  												},
   593  											},
   594  										},
   595  									},
   596  								},
   597  							},
   598  						},
   599  					},
   600  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
   601  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
   602  							DefaultValidationContext: &auth.CertificateValidationContext{
   603  								MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}),
   604  								Crl: &core.DataSource{
   605  									Specifier: &core.DataSource_Filename{
   606  										Filename: "/custom/path/to/crl.pem",
   607  									},
   608  								},
   609  							},
   610  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
   611  								Name: "file-root:ca-cert.crt",
   612  								SdsConfig: &core.ConfigSource{
   613  									ResourceApiVersion: core.ApiVersion_V3,
   614  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   615  										ApiConfigSource: &core.ApiConfigSource{
   616  											ApiType:                   core.ApiConfigSource_GRPC,
   617  											SetNodeOnFirstMessageOnly: true,
   618  											TransportApiVersion:       core.ApiVersion_V3,
   619  											GrpcServices: []*core.GrpcService{
   620  												{
   621  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   622  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   623  													},
   624  												},
   625  											},
   626  										},
   627  									},
   628  								},
   629  							},
   630  						},
   631  					},
   632  				},
   633  				RequireClientCertificate: proto.BoolTrue,
   634  			},
   635  		},
   636  		{
   637  			name: "no credential name key and cert subject alt names tls OPTIONAL_MUTUAL",
   638  			server: &networking.Server{
   639  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   640  				Port: &networking.Port{
   641  					Protocol: string(protocol.HTTPS),
   642  				},
   643  				Tls: &networking.ServerTLSSettings{
   644  					Mode:              networking.ServerTLSSettings_OPTIONAL_MUTUAL,
   645  					ServerCertificate: "server-cert.crt",
   646  					PrivateKey:        "private-key.key",
   647  					CaCertificates:    "ca-cert.crt",
   648  					SubjectAltNames:   []string{"subject.name.a.com", "subject.name.b.com"},
   649  				},
   650  			},
   651  			result: &auth.DownstreamTlsContext{
   652  				CommonTlsContext: &auth.CommonTlsContext{
   653  					AlpnProtocols: util.ALPNHttp,
   654  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   655  						{
   656  							Name: "file-cert:server-cert.crt~private-key.key",
   657  							SdsConfig: &core.ConfigSource{
   658  								ResourceApiVersion: core.ApiVersion_V3,
   659  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   660  									ApiConfigSource: &core.ApiConfigSource{
   661  										ApiType:                   core.ApiConfigSource_GRPC,
   662  										SetNodeOnFirstMessageOnly: true,
   663  										TransportApiVersion:       core.ApiVersion_V3,
   664  										GrpcServices: []*core.GrpcService{
   665  											{
   666  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   667  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   668  												},
   669  											},
   670  										},
   671  									},
   672  								},
   673  							},
   674  						},
   675  					},
   676  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
   677  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
   678  							DefaultValidationContext: &auth.CertificateValidationContext{
   679  								MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}),
   680  							},
   681  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
   682  								Name: "file-root:ca-cert.crt",
   683  								SdsConfig: &core.ConfigSource{
   684  									ResourceApiVersion: core.ApiVersion_V3,
   685  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   686  										ApiConfigSource: &core.ApiConfigSource{
   687  											ApiType:                   core.ApiConfigSource_GRPC,
   688  											SetNodeOnFirstMessageOnly: true,
   689  											TransportApiVersion:       core.ApiVersion_V3,
   690  											GrpcServices: []*core.GrpcService{
   691  												{
   692  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   693  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   694  													},
   695  												},
   696  											},
   697  										},
   698  									},
   699  								},
   700  							},
   701  						},
   702  					},
   703  				},
   704  				RequireClientCertificate: proto.BoolFalse,
   705  			},
   706  		},
   707  		{
   708  			name: "no credential name key and cert subject alt names tls OPTIONAL_MUTUAL",
   709  			server: &networking.Server{
   710  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   711  				Port: &networking.Port{
   712  					Protocol: string(protocol.HTTPS),
   713  				},
   714  				Tls: &networking.ServerTLSSettings{
   715  					Mode:              networking.ServerTLSSettings_OPTIONAL_MUTUAL,
   716  					ServerCertificate: "server-cert.crt",
   717  					PrivateKey:        "private-key.key",
   718  					CaCertificates:    "ca-cert.crt",
   719  					CaCrl:             "/custom/path/to/crl.pem",
   720  					SubjectAltNames:   []string{"subject.name.a.com", "subject.name.b.com"},
   721  				},
   722  			},
   723  			result: &auth.DownstreamTlsContext{
   724  				CommonTlsContext: &auth.CommonTlsContext{
   725  					AlpnProtocols: util.ALPNHttp,
   726  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   727  						{
   728  							Name: "file-cert:server-cert.crt~private-key.key",
   729  							SdsConfig: &core.ConfigSource{
   730  								ResourceApiVersion: core.ApiVersion_V3,
   731  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   732  									ApiConfigSource: &core.ApiConfigSource{
   733  										ApiType:                   core.ApiConfigSource_GRPC,
   734  										SetNodeOnFirstMessageOnly: true,
   735  										TransportApiVersion:       core.ApiVersion_V3,
   736  										GrpcServices: []*core.GrpcService{
   737  											{
   738  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   739  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   740  												},
   741  											},
   742  										},
   743  									},
   744  								},
   745  							},
   746  						},
   747  					},
   748  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
   749  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
   750  							DefaultValidationContext: &auth.CertificateValidationContext{
   751  								MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}),
   752  								Crl: &core.DataSource{
   753  									Specifier: &core.DataSource_Filename{
   754  										Filename: "/custom/path/to/crl.pem",
   755  									},
   756  								},
   757  							},
   758  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
   759  								Name: "file-root:ca-cert.crt",
   760  								SdsConfig: &core.ConfigSource{
   761  									ResourceApiVersion: core.ApiVersion_V3,
   762  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
   763  										ApiConfigSource: &core.ApiConfigSource{
   764  											ApiType:                   core.ApiConfigSource_GRPC,
   765  											SetNodeOnFirstMessageOnly: true,
   766  											TransportApiVersion:       core.ApiVersion_V3,
   767  											GrpcServices: []*core.GrpcService{
   768  												{
   769  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
   770  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
   771  													},
   772  												},
   773  											},
   774  										},
   775  									},
   776  								},
   777  							},
   778  						},
   779  					},
   780  				},
   781  				RequireClientCertificate: proto.BoolFalse,
   782  			},
   783  		},
   784  		{
   785  			// Credential name and subject names are specified, SDS configs are generated for fetching
   786  			// key/cert and root cert.
   787  			name: "credential name subject alternative name key and cert tls MUTUAL",
   788  			server: &networking.Server{
   789  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   790  				Port: &networking.Port{
   791  					Protocol: string(protocol.HTTPS),
   792  				},
   793  				Tls: &networking.ServerTLSSettings{
   794  					Mode:              networking.ServerTLSSettings_MUTUAL,
   795  					CredentialName:    "ingress-sds-resource-name",
   796  					ServerCertificate: "server-cert.crt",
   797  					PrivateKey:        "private-key.key",
   798  					SubjectAltNames:   []string{"subject.name.a.com", "subject.name.b.com"},
   799  				},
   800  			},
   801  			result: &auth.DownstreamTlsContext{
   802  				CommonTlsContext: &auth.CommonTlsContext{
   803  					AlpnProtocols: util.ALPNHttp,
   804  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   805  						{
   806  							Name:      "kubernetes://ingress-sds-resource-name",
   807  							SdsConfig: model.SDSAdsConfig,
   808  						},
   809  					},
   810  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
   811  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
   812  							DefaultValidationContext: &auth.CertificateValidationContext{
   813  								MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}),
   814  							},
   815  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
   816  								Name:      "kubernetes://ingress-sds-resource-name-cacert",
   817  								SdsConfig: model.SDSAdsConfig,
   818  							},
   819  						},
   820  					},
   821  				},
   822  				RequireClientCertificate: proto.BoolTrue,
   823  			},
   824  		},
   825  		{
   826  			// Credential name and subject names are specified, SDS configs are generated for fetching
   827  			// key/cert and root cert.
   828  			name: "credential name subject alternative name key and cert tls OPTIONAL_MUTUAL",
   829  			server: &networking.Server{
   830  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   831  				Port: &networking.Port{
   832  					Protocol: string(protocol.HTTPS),
   833  				},
   834  				Tls: &networking.ServerTLSSettings{
   835  					Mode:              networking.ServerTLSSettings_OPTIONAL_MUTUAL,
   836  					CredentialName:    "ingress-sds-resource-name",
   837  					ServerCertificate: "server-cert.crt",
   838  					PrivateKey:        "private-key.key",
   839  					SubjectAltNames:   []string{"subject.name.a.com", "subject.name.b.com"},
   840  				},
   841  			},
   842  			result: &auth.DownstreamTlsContext{
   843  				CommonTlsContext: &auth.CommonTlsContext{
   844  					AlpnProtocols: util.ALPNHttp,
   845  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   846  						{
   847  							Name:      "kubernetes://ingress-sds-resource-name",
   848  							SdsConfig: model.SDSAdsConfig,
   849  						},
   850  					},
   851  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
   852  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
   853  							DefaultValidationContext: &auth.CertificateValidationContext{
   854  								MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}),
   855  							},
   856  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
   857  								Name:      "kubernetes://ingress-sds-resource-name-cacert",
   858  								SdsConfig: model.SDSAdsConfig,
   859  							},
   860  						},
   861  					},
   862  				},
   863  				RequireClientCertificate: proto.BoolFalse,
   864  			},
   865  		},
   866  		{
   867  			// Credential name and VerifyCertificateSpki options are specified, SDS configs are generated for fetching
   868  			// key/cert and root cert
   869  			name: "credential name verify spki key and cert tls MUTUAL",
   870  			server: &networking.Server{
   871  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   872  				Port: &networking.Port{
   873  					Protocol: string(protocol.HTTPS),
   874  				},
   875  				Tls: &networking.ServerTLSSettings{
   876  					Mode:                  networking.ServerTLSSettings_MUTUAL,
   877  					CredentialName:        "ingress-sds-resource-name",
   878  					VerifyCertificateSpki: []string{"abcdef"},
   879  				},
   880  			},
   881  			result: &auth.DownstreamTlsContext{
   882  				CommonTlsContext: &auth.CommonTlsContext{
   883  					AlpnProtocols: util.ALPNHttp,
   884  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   885  						{
   886  							Name:      "kubernetes://ingress-sds-resource-name",
   887  							SdsConfig: model.SDSAdsConfig,
   888  						},
   889  					},
   890  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
   891  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
   892  							DefaultValidationContext: &auth.CertificateValidationContext{
   893  								VerifyCertificateSpki: []string{"abcdef"},
   894  							},
   895  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
   896  								Name:      "kubernetes://ingress-sds-resource-name-cacert",
   897  								SdsConfig: model.SDSAdsConfig,
   898  							},
   899  						},
   900  					},
   901  				},
   902  				RequireClientCertificate: proto.BoolTrue,
   903  			},
   904  		},
   905  		{
   906  			// Credential name and VerifyCertificateHash options are specified, SDS configs are generated for fetching
   907  			// key/cert and root cert
   908  			name: "credential name verify hash key and cert tls MUTUAL",
   909  			server: &networking.Server{
   910  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   911  				Port: &networking.Port{
   912  					Protocol: string(protocol.HTTPS),
   913  				},
   914  				Tls: &networking.ServerTLSSettings{
   915  					Mode:                  networking.ServerTLSSettings_MUTUAL,
   916  					CredentialName:        "ingress-sds-resource-name",
   917  					VerifyCertificateHash: []string{"fedcba"},
   918  				},
   919  			},
   920  			result: &auth.DownstreamTlsContext{
   921  				CommonTlsContext: &auth.CommonTlsContext{
   922  					AlpnProtocols: util.ALPNHttp,
   923  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   924  						{
   925  							Name:      "kubernetes://ingress-sds-resource-name",
   926  							SdsConfig: model.SDSAdsConfig,
   927  						},
   928  					},
   929  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
   930  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
   931  							DefaultValidationContext: &auth.CertificateValidationContext{
   932  								VerifyCertificateHash: []string{"fedcba"},
   933  							},
   934  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
   935  								Name:      "kubernetes://ingress-sds-resource-name-cacert",
   936  								SdsConfig: model.SDSAdsConfig,
   937  							},
   938  						},
   939  					},
   940  				},
   941  				RequireClientCertificate: proto.BoolTrue,
   942  			},
   943  		},
   944  		{
   945  			name: "no credential name key and cert tls PASSTHROUGH",
   946  			server: &networking.Server{
   947  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   948  				Port: &networking.Port{
   949  					Protocol: string(protocol.HTTPS),
   950  				},
   951  				Tls: &networking.ServerTLSSettings{
   952  					Mode:              networking.ServerTLSSettings_PASSTHROUGH,
   953  					ServerCertificate: "server-cert.crt",
   954  					PrivateKey:        "private-key.key",
   955  				},
   956  			},
   957  			result: nil,
   958  		},
   959  		{
   960  			name: "Downstream TLS settings for QUIC transport",
   961  			server: &networking.Server{
   962  				Hosts: []string{"httpbin.example.com"},
   963  				Port: &networking.Port{
   964  					Protocol: string(protocol.HTTPS),
   965  				},
   966  				Tls: &networking.ServerTLSSettings{
   967  					Mode:           networking.ServerTLSSettings_SIMPLE,
   968  					CredentialName: "httpbin-cred",
   969  				},
   970  			},
   971  			transportProtocol: istionetworking.TransportProtocolQUIC,
   972  			result: &auth.DownstreamTlsContext{
   973  				CommonTlsContext: &auth.CommonTlsContext{
   974  					AlpnProtocols: util.ALPNHttp3OverQUIC,
   975  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
   976  						{
   977  							Name:      "kubernetes://httpbin-cred",
   978  							SdsConfig: model.SDSAdsConfig,
   979  						},
   980  					},
   981  				},
   982  				RequireClientCertificate: proto.BoolFalse,
   983  			},
   984  		},
   985  		{
   986  			name: "duplicated cipher suites with tls SIMPLE",
   987  			server: &networking.Server{
   988  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
   989  				Port: &networking.Port{
   990  					Protocol: string(protocol.HTTPS),
   991  				},
   992  				Tls: &networking.ServerTLSSettings{
   993  					Mode:              networking.ServerTLSSettings_SIMPLE,
   994  					ServerCertificate: "server-cert.crt",
   995  					PrivateKey:        "private-key.key",
   996  					CipherSuites:      []string{"ECDHE-ECDSA-AES128-SHA", "ECDHE-ECDSA-AES128-SHA"},
   997  				},
   998  			},
   999  			result: &auth.DownstreamTlsContext{
  1000  				CommonTlsContext: &auth.CommonTlsContext{
  1001  					AlpnProtocols: util.ALPNHttp,
  1002  					TlsParams: &auth.TlsParameters{
  1003  						CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA"},
  1004  					},
  1005  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1006  						{
  1007  							Name: "file-cert:server-cert.crt~private-key.key",
  1008  							SdsConfig: &core.ConfigSource{
  1009  								ResourceApiVersion: core.ApiVersion_V3,
  1010  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1011  									ApiConfigSource: &core.ApiConfigSource{
  1012  										ApiType:                   core.ApiConfigSource_GRPC,
  1013  										SetNodeOnFirstMessageOnly: true,
  1014  										TransportApiVersion:       core.ApiVersion_V3,
  1015  										GrpcServices: []*core.GrpcService{
  1016  											{
  1017  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1018  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1019  												},
  1020  											},
  1021  										},
  1022  									},
  1023  								},
  1024  							},
  1025  						},
  1026  					},
  1027  				},
  1028  				RequireClientCertificate: proto.BoolFalse,
  1029  			},
  1030  		},
  1031  		{
  1032  			name: "ecdh curves and cipher suites specified in mesh config with tls SIMPLE",
  1033  			server: &networking.Server{
  1034  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
  1035  				Port: &networking.Port{
  1036  					Protocol: string(protocol.HTTPS),
  1037  				},
  1038  				Tls: &networking.ServerTLSSettings{
  1039  					Mode:              networking.ServerTLSSettings_SIMPLE,
  1040  					ServerCertificate: "server-cert.crt",
  1041  					PrivateKey:        "private-key.key",
  1042  				},
  1043  			},
  1044  			mesh: &meshconfig.MeshConfig{
  1045  				TlsDefaults: &meshconfig.MeshConfig_TLSConfig{
  1046  					EcdhCurves:   []string{"P-256"},
  1047  					CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA"},
  1048  				},
  1049  			},
  1050  			result: &auth.DownstreamTlsContext{
  1051  				CommonTlsContext: &auth.CommonTlsContext{
  1052  					AlpnProtocols: util.ALPNHttp,
  1053  					TlsParams: &auth.TlsParameters{
  1054  						EcdhCurves:   []string{"P-256"},
  1055  						CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA"},
  1056  					},
  1057  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1058  						{
  1059  							Name: "file-cert:server-cert.crt~private-key.key",
  1060  							SdsConfig: &core.ConfigSource{
  1061  								ResourceApiVersion: core.ApiVersion_V3,
  1062  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1063  									ApiConfigSource: &core.ApiConfigSource{
  1064  										ApiType:                   core.ApiConfigSource_GRPC,
  1065  										SetNodeOnFirstMessageOnly: true,
  1066  										TransportApiVersion:       core.ApiVersion_V3,
  1067  										GrpcServices: []*core.GrpcService{
  1068  											{
  1069  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1070  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1071  												},
  1072  											},
  1073  										},
  1074  									},
  1075  								},
  1076  							},
  1077  						},
  1078  					},
  1079  				},
  1080  				RequireClientCertificate: proto.BoolFalse,
  1081  			},
  1082  		},
  1083  		{
  1084  			name: "ecdh curves and cipher suites specified in mesh config with, tls mode ISTIO_MUTUAL",
  1085  			server: &networking.Server{
  1086  				Hosts: []string{"httpbin.example.com"},
  1087  				Port: &networking.Port{
  1088  					Protocol: string(protocol.HTTPS),
  1089  				},
  1090  				Tls: &networking.ServerTLSSettings{
  1091  					Mode: networking.ServerTLSSettings_ISTIO_MUTUAL,
  1092  				},
  1093  			},
  1094  			mesh: &meshconfig.MeshConfig{
  1095  				TlsDefaults: &meshconfig.MeshConfig_TLSConfig{
  1096  					EcdhCurves:   []string{"P-256"},
  1097  					CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES256-GCM-SHA384"},
  1098  				},
  1099  			},
  1100  			result: &auth.DownstreamTlsContext{
  1101  				CommonTlsContext: &auth.CommonTlsContext{
  1102  					AlpnProtocols: util.ALPNHttp,
  1103  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1104  						{
  1105  							Name: "default",
  1106  							SdsConfig: &core.ConfigSource{
  1107  								InitialFetchTimeout: durationpb.New(time.Second * 0),
  1108  								ResourceApiVersion:  core.ApiVersion_V3,
  1109  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1110  									ApiConfigSource: &core.ApiConfigSource{
  1111  										ApiType:                   core.ApiConfigSource_GRPC,
  1112  										SetNodeOnFirstMessageOnly: true,
  1113  										TransportApiVersion:       core.ApiVersion_V3,
  1114  										GrpcServices: []*core.GrpcService{
  1115  											{
  1116  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1117  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1118  												},
  1119  											},
  1120  										},
  1121  									},
  1122  								},
  1123  							},
  1124  						},
  1125  					},
  1126  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
  1127  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
  1128  							DefaultValidationContext: &auth.CertificateValidationContext{},
  1129  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
  1130  								Name: "ROOTCA",
  1131  								SdsConfig: &core.ConfigSource{
  1132  									InitialFetchTimeout: durationpb.New(time.Second * 0),
  1133  									ResourceApiVersion:  core.ApiVersion_V3,
  1134  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1135  										ApiConfigSource: &core.ApiConfigSource{
  1136  											ApiType:                   core.ApiConfigSource_GRPC,
  1137  											SetNodeOnFirstMessageOnly: true,
  1138  											TransportApiVersion:       core.ApiVersion_V3,
  1139  											GrpcServices: []*core.GrpcService{
  1140  												{
  1141  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1142  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1143  													},
  1144  												},
  1145  											},
  1146  										},
  1147  									},
  1148  								},
  1149  							},
  1150  						},
  1151  					},
  1152  				},
  1153  				RequireClientCertificate: proto.BoolTrue,
  1154  			},
  1155  		},
  1156  		{
  1157  			name: "ecdh curves and cipher suites specified in mesh config with tls MUTUAL",
  1158  			server: &networking.Server{
  1159  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
  1160  				Port: &networking.Port{
  1161  					Protocol: string(protocol.HTTPS),
  1162  				},
  1163  				Tls: &networking.ServerTLSSettings{
  1164  					Mode:              networking.ServerTLSSettings_MUTUAL,
  1165  					CredentialName:    "ingress-sds-resource-name",
  1166  					ServerCertificate: "server-cert.crt",
  1167  					PrivateKey:        "private-key.key",
  1168  					SubjectAltNames:   []string{"subject.name.a.com", "subject.name.b.com"},
  1169  				},
  1170  			},
  1171  			mesh: &meshconfig.MeshConfig{
  1172  				TlsDefaults: &meshconfig.MeshConfig_TLSConfig{
  1173  					EcdhCurves:   []string{"P-256", "P-384"},
  1174  					CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES256-GCM-SHA384"},
  1175  				},
  1176  			},
  1177  			result: &auth.DownstreamTlsContext{
  1178  				CommonTlsContext: &auth.CommonTlsContext{
  1179  					TlsParams: &auth.TlsParameters{
  1180  						EcdhCurves:   []string{"P-256", "P-384"},
  1181  						CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES256-GCM-SHA384"},
  1182  					},
  1183  					AlpnProtocols: util.ALPNHttp,
  1184  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1185  						{
  1186  							Name:      "kubernetes://ingress-sds-resource-name",
  1187  							SdsConfig: model.SDSAdsConfig,
  1188  						},
  1189  					},
  1190  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
  1191  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
  1192  							DefaultValidationContext: &auth.CertificateValidationContext{
  1193  								MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}),
  1194  							},
  1195  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
  1196  								Name:      "kubernetes://ingress-sds-resource-name-cacert",
  1197  								SdsConfig: model.SDSAdsConfig,
  1198  							},
  1199  						},
  1200  					},
  1201  				},
  1202  				RequireClientCertificate: proto.BoolTrue,
  1203  			},
  1204  		},
  1205  		{
  1206  			name: "ecdh curves and cipher suites specified in mesh config with tls OPTIONAL MUTUAL",
  1207  			server: &networking.Server{
  1208  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
  1209  				Port: &networking.Port{
  1210  					Protocol: string(protocol.HTTPS),
  1211  				},
  1212  				Tls: &networking.ServerTLSSettings{
  1213  					Mode:              networking.ServerTLSSettings_OPTIONAL_MUTUAL,
  1214  					CredentialName:    "ingress-sds-resource-name",
  1215  					ServerCertificate: "server-cert.crt",
  1216  					PrivateKey:        "private-key.key",
  1217  					SubjectAltNames:   []string{"subject.name.a.com", "subject.name.b.com"},
  1218  				},
  1219  			},
  1220  			mesh: &meshconfig.MeshConfig{
  1221  				TlsDefaults: &meshconfig.MeshConfig_TLSConfig{
  1222  					EcdhCurves:   []string{"P-256", "P-384"},
  1223  					CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES256-GCM-SHA384"},
  1224  				},
  1225  			},
  1226  			result: &auth.DownstreamTlsContext{
  1227  				CommonTlsContext: &auth.CommonTlsContext{
  1228  					TlsParams: &auth.TlsParameters{
  1229  						EcdhCurves:   []string{"P-256", "P-384"},
  1230  						CipherSuites: []string{"ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES256-GCM-SHA384"},
  1231  					},
  1232  					AlpnProtocols: util.ALPNHttp,
  1233  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1234  						{
  1235  							Name:      "kubernetes://ingress-sds-resource-name",
  1236  							SdsConfig: model.SDSAdsConfig,
  1237  						},
  1238  					},
  1239  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
  1240  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
  1241  							DefaultValidationContext: &auth.CertificateValidationContext{
  1242  								MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}),
  1243  							},
  1244  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
  1245  								Name:      "kubernetes://ingress-sds-resource-name-cacert",
  1246  								SdsConfig: model.SDSAdsConfig,
  1247  							},
  1248  						},
  1249  					},
  1250  				},
  1251  				RequireClientCertificate: proto.BoolFalse,
  1252  			},
  1253  		},
  1254  		{
  1255  			// tcp server is non-istio mtls, no istio-peer-exchange in the alpns
  1256  			name: "tcp server with terminating (non-istio)mutual tls",
  1257  			server: &networking.Server{
  1258  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
  1259  				Port: &networking.Port{
  1260  					Protocol: string(protocol.TLS),
  1261  				},
  1262  				Tls: &networking.ServerTLSSettings{
  1263  					Mode:              networking.ServerTLSSettings_MUTUAL,
  1264  					ServerCertificate: "server-cert.crt",
  1265  					PrivateKey:        "private-key.key",
  1266  					CaCertificates:    "ca-cert.crt",
  1267  					SubjectAltNames:   []string{"subject.name.a.com", "subject.name.b.com"},
  1268  				},
  1269  			},
  1270  			result: &auth.DownstreamTlsContext{
  1271  				CommonTlsContext: &auth.CommonTlsContext{
  1272  					AlpnProtocols: util.ALPNHttp,
  1273  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1274  						{
  1275  							Name: "file-cert:server-cert.crt~private-key.key",
  1276  							SdsConfig: &core.ConfigSource{
  1277  								ResourceApiVersion: core.ApiVersion_V3,
  1278  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1279  									ApiConfigSource: &core.ApiConfigSource{
  1280  										ApiType:                   core.ApiConfigSource_GRPC,
  1281  										SetNodeOnFirstMessageOnly: true,
  1282  										TransportApiVersion:       core.ApiVersion_V3,
  1283  										GrpcServices: []*core.GrpcService{
  1284  											{
  1285  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1286  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1287  												},
  1288  											},
  1289  										},
  1290  									},
  1291  								},
  1292  							},
  1293  						},
  1294  					},
  1295  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
  1296  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
  1297  							DefaultValidationContext: &auth.CertificateValidationContext{
  1298  								MatchSubjectAltNames: util.StringToExactMatch([]string{"subject.name.a.com", "subject.name.b.com"}),
  1299  							},
  1300  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
  1301  								Name: "file-root:ca-cert.crt",
  1302  								SdsConfig: &core.ConfigSource{
  1303  									ResourceApiVersion: core.ApiVersion_V3,
  1304  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1305  										ApiConfigSource: &core.ApiConfigSource{
  1306  											ApiType:                   core.ApiConfigSource_GRPC,
  1307  											SetNodeOnFirstMessageOnly: true,
  1308  											TransportApiVersion:       core.ApiVersion_V3,
  1309  											GrpcServices: []*core.GrpcService{
  1310  												{
  1311  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1312  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1313  													},
  1314  												},
  1315  											},
  1316  										},
  1317  									},
  1318  								},
  1319  							},
  1320  						},
  1321  					},
  1322  				},
  1323  				RequireClientCertificate: proto.BoolTrue,
  1324  			},
  1325  		},
  1326  		{
  1327  			// tcp server is istio mtls, istio-peer-exchange in the alpns
  1328  			name: "mesh SDS enabled, tcp server, tls mode ISTIO_MUTUAL",
  1329  			server: &networking.Server{
  1330  				Hosts: []string{"httpbin.example.com"},
  1331  				Port: &networking.Port{
  1332  					Protocol: string(protocol.TLS),
  1333  				},
  1334  				Tls: &networking.ServerTLSSettings{
  1335  					Mode: networking.ServerTLSSettings_ISTIO_MUTUAL,
  1336  				},
  1337  			},
  1338  			result: &auth.DownstreamTlsContext{
  1339  				CommonTlsContext: &auth.CommonTlsContext{
  1340  					AlpnProtocols: util.ALPNDownstreamWithMxc,
  1341  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1342  						{
  1343  							Name: "default",
  1344  							SdsConfig: &core.ConfigSource{
  1345  								InitialFetchTimeout: durationpb.New(time.Second * 0),
  1346  								ResourceApiVersion:  core.ApiVersion_V3,
  1347  								ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1348  									ApiConfigSource: &core.ApiConfigSource{
  1349  										ApiType:                   core.ApiConfigSource_GRPC,
  1350  										SetNodeOnFirstMessageOnly: true,
  1351  										TransportApiVersion:       core.ApiVersion_V3,
  1352  										GrpcServices: []*core.GrpcService{
  1353  											{
  1354  												TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1355  													EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1356  												},
  1357  											},
  1358  										},
  1359  									},
  1360  								},
  1361  							},
  1362  						},
  1363  					},
  1364  					ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
  1365  						CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
  1366  							DefaultValidationContext: &auth.CertificateValidationContext{},
  1367  							ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
  1368  								Name: "ROOTCA",
  1369  								SdsConfig: &core.ConfigSource{
  1370  									InitialFetchTimeout: durationpb.New(time.Second * 0),
  1371  									ResourceApiVersion:  core.ApiVersion_V3,
  1372  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1373  										ApiConfigSource: &core.ApiConfigSource{
  1374  											ApiType:                   core.ApiConfigSource_GRPC,
  1375  											SetNodeOnFirstMessageOnly: true,
  1376  											TransportApiVersion:       core.ApiVersion_V3,
  1377  											GrpcServices: []*core.GrpcService{
  1378  												{
  1379  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1380  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1381  													},
  1382  												},
  1383  											},
  1384  										},
  1385  									},
  1386  								},
  1387  							},
  1388  						},
  1389  					},
  1390  				},
  1391  				RequireClientCertificate: proto.BoolTrue,
  1392  			},
  1393  		},
  1394  		{
  1395  			// tcp server is simple tls, no istio-peer-exchange in the alpns
  1396  			name: "tcp server, tls SIMPLE",
  1397  			server: &networking.Server{
  1398  				Hosts: []string{"httpbin.example.com", "bookinfo.example.com"},
  1399  				Port: &networking.Port{
  1400  					Protocol: string(protocol.TLS),
  1401  				},
  1402  				Tls: &networking.ServerTLSSettings{
  1403  					Mode:           networking.ServerTLSSettings_SIMPLE,
  1404  					CredentialName: "ingress-sds-resource-name",
  1405  				},
  1406  			},
  1407  			result: &auth.DownstreamTlsContext{
  1408  				CommonTlsContext: &auth.CommonTlsContext{
  1409  					AlpnProtocols: util.ALPNHttp,
  1410  					TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1411  						{
  1412  							Name:      "kubernetes://ingress-sds-resource-name",
  1413  							SdsConfig: model.SDSAdsConfig,
  1414  						},
  1415  					},
  1416  				},
  1417  				RequireClientCertificate: proto.BoolFalse,
  1418  			},
  1419  		},
  1420  	}
  1421  
  1422  	for _, tc := range testCases {
  1423  		t.Run(tc.name, func(t *testing.T) {
  1424  			ret := buildGatewayListenerTLSContext(tc.mesh, tc.server, &pilot_model.Proxy{
  1425  				Metadata: &pilot_model.NodeMetadata{},
  1426  			}, tc.transportProtocol)
  1427  			if diff := cmp.Diff(tc.result, ret, protocmp.Transform()); diff != "" {
  1428  				t.Errorf("got diff: %v", diff)
  1429  			}
  1430  		})
  1431  	}
  1432  }
  1433  
  1434  func TestCreateGatewayHTTPFilterChainOpts(t *testing.T) {
  1435  	cg := NewConfigGenTest(t, TestOptions{})
  1436  	testCases := []struct {
  1437  		name              string
  1438  		node              *pilot_model.Proxy
  1439  		server            *networking.Server
  1440  		routeName         string
  1441  		proxyConfig       *meshconfig.ProxyConfig
  1442  		result            *filterChainOpts
  1443  		transportProtocol istionetworking.TransportProtocol
  1444  	}{
  1445  		{
  1446  			name: "HTTP1.0 mode enabled",
  1447  			node: &pilot_model.Proxy{
  1448  				Metadata: &pilot_model.NodeMetadata{HTTP10: "1"},
  1449  			},
  1450  			server: &networking.Server{
  1451  				Port: &networking.Port{
  1452  					Protocol: protocol.HTTP.String(),
  1453  				},
  1454  			},
  1455  			routeName:   "some-route",
  1456  			proxyConfig: nil,
  1457  			result: &filterChainOpts{
  1458  				sniHosts:   nil,
  1459  				tlsContext: nil,
  1460  				httpOpts: &httpListenerOpts{
  1461  					rds:              "some-route",
  1462  					useRemoteAddress: true,
  1463  					connectionManager: &hcm.HttpConnectionManager{
  1464  						XffNumTrustedHops:        0,
  1465  						ForwardClientCertDetails: hcm.HttpConnectionManager_SANITIZE_SET,
  1466  						SetCurrentClientCertDetails: &hcm.HttpConnectionManager_SetCurrentClientCertDetails{
  1467  							Subject: proto.BoolTrue,
  1468  							Cert:    true,
  1469  							Uri:     true,
  1470  							Dns:     true,
  1471  						},
  1472  						ServerName: EnvoyServerName,
  1473  						HttpProtocolOptions: &core.Http1ProtocolOptions{
  1474  							AcceptHttp_10: true,
  1475  						},
  1476  						Proxy_100Continue: true,
  1477  					},
  1478  					class:    istionetworking.ListenerClassGateway,
  1479  					protocol: protocol.HTTP,
  1480  				},
  1481  			},
  1482  		},
  1483  		{
  1484  			name: "Duplicate hosts in TLS filterChain",
  1485  			node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}},
  1486  			server: &networking.Server{
  1487  				Port: &networking.Port{
  1488  					Protocol: "HTTPS",
  1489  				},
  1490  				Hosts: []string{"example.org", "example.org"},
  1491  				Tls: &networking.ServerTLSSettings{
  1492  					Mode: networking.ServerTLSSettings_ISTIO_MUTUAL,
  1493  				},
  1494  			},
  1495  			routeName:   "some-route",
  1496  			proxyConfig: nil,
  1497  			result: &filterChainOpts{
  1498  				sniHosts: []string{"example.org"},
  1499  				tlsContext: &auth.DownstreamTlsContext{
  1500  					CommonTlsContext: &auth.CommonTlsContext{
  1501  						AlpnProtocols: util.ALPNHttp,
  1502  						TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1503  							{
  1504  								Name: "default",
  1505  								SdsConfig: &core.ConfigSource{
  1506  									ResourceApiVersion:  core.ApiVersion_V3,
  1507  									InitialFetchTimeout: durationpb.New(time.Second * 0),
  1508  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1509  										ApiConfigSource: &core.ApiConfigSource{
  1510  											ApiType:                   core.ApiConfigSource_GRPC,
  1511  											SetNodeOnFirstMessageOnly: true,
  1512  											TransportApiVersion:       core.ApiVersion_V3,
  1513  											GrpcServices: []*core.GrpcService{
  1514  												{
  1515  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1516  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1517  													},
  1518  												},
  1519  											},
  1520  										},
  1521  									},
  1522  								},
  1523  							},
  1524  						},
  1525  						ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
  1526  							CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
  1527  								DefaultValidationContext: &auth.CertificateValidationContext{},
  1528  								ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
  1529  									Name: "ROOTCA",
  1530  									SdsConfig: &core.ConfigSource{
  1531  										ResourceApiVersion:  core.ApiVersion_V3,
  1532  										InitialFetchTimeout: durationpb.New(time.Second * 0),
  1533  										ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1534  											ApiConfigSource: &core.ApiConfigSource{
  1535  												ApiType:                   core.ApiConfigSource_GRPC,
  1536  												SetNodeOnFirstMessageOnly: true,
  1537  												TransportApiVersion:       core.ApiVersion_V3,
  1538  												GrpcServices: []*core.GrpcService{
  1539  													{
  1540  														TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1541  															EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1542  														},
  1543  													},
  1544  												},
  1545  											},
  1546  										},
  1547  									},
  1548  								},
  1549  							},
  1550  						},
  1551  					},
  1552  					RequireClientCertificate: proto.BoolTrue,
  1553  				},
  1554  				httpOpts: &httpListenerOpts{
  1555  					rds:              "some-route",
  1556  					useRemoteAddress: true,
  1557  					connectionManager: &hcm.HttpConnectionManager{
  1558  						XffNumTrustedHops:        0,
  1559  						ForwardClientCertDetails: hcm.HttpConnectionManager_SANITIZE_SET,
  1560  						SetCurrentClientCertDetails: &hcm.HttpConnectionManager_SetCurrentClientCertDetails{
  1561  							Subject: proto.BoolTrue,
  1562  							Cert:    true,
  1563  							Uri:     true,
  1564  							Dns:     true,
  1565  						},
  1566  						ServerName:          EnvoyServerName,
  1567  						HttpProtocolOptions: &core.Http1ProtocolOptions{},
  1568  						Proxy_100Continue:   true,
  1569  					},
  1570  					class:    istionetworking.ListenerClassGateway,
  1571  					protocol: protocol.HTTPS,
  1572  				},
  1573  			},
  1574  		},
  1575  		{
  1576  			name: "Unique hosts in TLS filterChain",
  1577  			node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}},
  1578  			server: &networking.Server{
  1579  				Port: &networking.Port{
  1580  					Protocol: "HTTPS",
  1581  				},
  1582  				Hosts: []string{"example.org", "test.org"},
  1583  				Tls: &networking.ServerTLSSettings{
  1584  					Mode: networking.ServerTLSSettings_ISTIO_MUTUAL,
  1585  				},
  1586  			},
  1587  			routeName:   "some-route",
  1588  			proxyConfig: nil,
  1589  			result: &filterChainOpts{
  1590  				sniHosts: []string{"example.org", "test.org"},
  1591  				tlsContext: &auth.DownstreamTlsContext{
  1592  					CommonTlsContext: &auth.CommonTlsContext{
  1593  						AlpnProtocols: util.ALPNHttp,
  1594  						TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1595  							{
  1596  								Name: "default",
  1597  								SdsConfig: &core.ConfigSource{
  1598  									ResourceApiVersion:  core.ApiVersion_V3,
  1599  									InitialFetchTimeout: durationpb.New(time.Second * 0),
  1600  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1601  										ApiConfigSource: &core.ApiConfigSource{
  1602  											ApiType:                   core.ApiConfigSource_GRPC,
  1603  											SetNodeOnFirstMessageOnly: true,
  1604  											TransportApiVersion:       core.ApiVersion_V3,
  1605  											GrpcServices: []*core.GrpcService{
  1606  												{
  1607  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1608  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1609  													},
  1610  												},
  1611  											},
  1612  										},
  1613  									},
  1614  								},
  1615  							},
  1616  						},
  1617  						ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
  1618  							CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
  1619  								DefaultValidationContext: &auth.CertificateValidationContext{},
  1620  								ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
  1621  									Name: "ROOTCA",
  1622  									SdsConfig: &core.ConfigSource{
  1623  										ResourceApiVersion:  core.ApiVersion_V3,
  1624  										InitialFetchTimeout: durationpb.New(time.Second * 0),
  1625  										ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1626  											ApiConfigSource: &core.ApiConfigSource{
  1627  												ApiType:                   core.ApiConfigSource_GRPC,
  1628  												SetNodeOnFirstMessageOnly: true,
  1629  												TransportApiVersion:       core.ApiVersion_V3,
  1630  												GrpcServices: []*core.GrpcService{
  1631  													{
  1632  														TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1633  															EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1634  														},
  1635  													},
  1636  												},
  1637  											},
  1638  										},
  1639  									},
  1640  								},
  1641  							},
  1642  						},
  1643  					},
  1644  					RequireClientCertificate: proto.BoolTrue,
  1645  				},
  1646  				httpOpts: &httpListenerOpts{
  1647  					rds:              "some-route",
  1648  					useRemoteAddress: true,
  1649  					connectionManager: &hcm.HttpConnectionManager{
  1650  						XffNumTrustedHops:        0,
  1651  						ForwardClientCertDetails: hcm.HttpConnectionManager_SANITIZE_SET,
  1652  						SetCurrentClientCertDetails: &hcm.HttpConnectionManager_SetCurrentClientCertDetails{
  1653  							Subject: proto.BoolTrue,
  1654  							Cert:    true,
  1655  							Uri:     true,
  1656  							Dns:     true,
  1657  						},
  1658  						ServerName:          EnvoyServerName,
  1659  						HttpProtocolOptions: &core.Http1ProtocolOptions{},
  1660  						Proxy_100Continue:   true,
  1661  					},
  1662  					class:    istionetworking.ListenerClassGateway,
  1663  					protocol: protocol.HTTPS,
  1664  				},
  1665  			},
  1666  		},
  1667  		{
  1668  			name: "Wildcard hosts in TLS filterChain are not duplicates",
  1669  			node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}},
  1670  			server: &networking.Server{
  1671  				Port: &networking.Port{
  1672  					Protocol: "HTTPS",
  1673  				},
  1674  				Hosts: []string{"*.example.org", "example.org"},
  1675  				Tls: &networking.ServerTLSSettings{
  1676  					Mode: networking.ServerTLSSettings_ISTIO_MUTUAL,
  1677  				},
  1678  			},
  1679  			routeName:   "some-route",
  1680  			proxyConfig: nil,
  1681  			result: &filterChainOpts{
  1682  				sniHosts: []string{"*.example.org", "example.org"},
  1683  				tlsContext: &auth.DownstreamTlsContext{
  1684  					CommonTlsContext: &auth.CommonTlsContext{
  1685  						AlpnProtocols: util.ALPNHttp,
  1686  						TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1687  							{
  1688  								Name: "default",
  1689  								SdsConfig: &core.ConfigSource{
  1690  									ResourceApiVersion:  core.ApiVersion_V3,
  1691  									InitialFetchTimeout: durationpb.New(time.Second * 0),
  1692  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1693  										ApiConfigSource: &core.ApiConfigSource{
  1694  											ApiType:                   core.ApiConfigSource_GRPC,
  1695  											SetNodeOnFirstMessageOnly: true,
  1696  											TransportApiVersion:       core.ApiVersion_V3,
  1697  											GrpcServices: []*core.GrpcService{
  1698  												{
  1699  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1700  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1701  													},
  1702  												},
  1703  											},
  1704  										},
  1705  									},
  1706  								},
  1707  							},
  1708  						},
  1709  						ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
  1710  							CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
  1711  								DefaultValidationContext: &auth.CertificateValidationContext{},
  1712  								ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
  1713  									Name: "ROOTCA",
  1714  									SdsConfig: &core.ConfigSource{
  1715  										ResourceApiVersion:  core.ApiVersion_V3,
  1716  										InitialFetchTimeout: durationpb.New(time.Second * 0),
  1717  										ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1718  											ApiConfigSource: &core.ApiConfigSource{
  1719  												ApiType:                   core.ApiConfigSource_GRPC,
  1720  												SetNodeOnFirstMessageOnly: true,
  1721  												TransportApiVersion:       core.ApiVersion_V3,
  1722  												GrpcServices: []*core.GrpcService{
  1723  													{
  1724  														TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1725  															EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1726  														},
  1727  													},
  1728  												},
  1729  											},
  1730  										},
  1731  									},
  1732  								},
  1733  							},
  1734  						},
  1735  					},
  1736  					RequireClientCertificate: proto.BoolTrue,
  1737  				},
  1738  				httpOpts: &httpListenerOpts{
  1739  					rds:              "some-route",
  1740  					useRemoteAddress: true,
  1741  					connectionManager: &hcm.HttpConnectionManager{
  1742  						XffNumTrustedHops:        0,
  1743  						ForwardClientCertDetails: hcm.HttpConnectionManager_SANITIZE_SET,
  1744  						SetCurrentClientCertDetails: &hcm.HttpConnectionManager_SetCurrentClientCertDetails{
  1745  							Subject: proto.BoolTrue,
  1746  							Cert:    true,
  1747  							Uri:     true,
  1748  							Dns:     true,
  1749  						},
  1750  						ServerName:          EnvoyServerName,
  1751  						HttpProtocolOptions: &core.Http1ProtocolOptions{},
  1752  						Proxy_100Continue:   true,
  1753  					},
  1754  					class:    istionetworking.ListenerClassGateway,
  1755  					protocol: protocol.HTTPS,
  1756  				},
  1757  			},
  1758  		},
  1759  		{
  1760  			name: "Topology HTTP Protocol",
  1761  			node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}},
  1762  			server: &networking.Server{
  1763  				Port: &networking.Port{
  1764  					Protocol: protocol.HTTP.String(),
  1765  				},
  1766  			},
  1767  			routeName: "some-route",
  1768  			proxyConfig: &meshconfig.ProxyConfig{
  1769  				GatewayTopology: &meshconfig.Topology{
  1770  					NumTrustedProxies:        2,
  1771  					ForwardClientCertDetails: meshconfig.ForwardClientCertDetails_APPEND_FORWARD,
  1772  				},
  1773  			},
  1774  			result: &filterChainOpts{
  1775  				sniHosts:   nil,
  1776  				tlsContext: nil,
  1777  				httpOpts: &httpListenerOpts{
  1778  					rds:              "some-route",
  1779  					useRemoteAddress: true,
  1780  					connectionManager: &hcm.HttpConnectionManager{
  1781  						XffNumTrustedHops:        2,
  1782  						ForwardClientCertDetails: hcm.HttpConnectionManager_APPEND_FORWARD,
  1783  						SetCurrentClientCertDetails: &hcm.HttpConnectionManager_SetCurrentClientCertDetails{
  1784  							Subject: proto.BoolTrue,
  1785  							Cert:    true,
  1786  							Uri:     true,
  1787  							Dns:     true,
  1788  						},
  1789  						ServerName:          EnvoyServerName,
  1790  						HttpProtocolOptions: &core.Http1ProtocolOptions{},
  1791  						Proxy_100Continue:   true,
  1792  					},
  1793  					class:    istionetworking.ListenerClassGateway,
  1794  					protocol: protocol.HTTP,
  1795  				},
  1796  			},
  1797  		},
  1798  		{
  1799  			name: "Topology HTTPS Protocol",
  1800  			node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}},
  1801  			server: &networking.Server{
  1802  				Port: &networking.Port{
  1803  					Protocol: "HTTPS",
  1804  				},
  1805  				Hosts: []string{"example.org"},
  1806  				Tls: &networking.ServerTLSSettings{
  1807  					Mode: networking.ServerTLSSettings_ISTIO_MUTUAL,
  1808  				},
  1809  			},
  1810  			routeName: "some-route",
  1811  			proxyConfig: &meshconfig.ProxyConfig{
  1812  				GatewayTopology: &meshconfig.Topology{
  1813  					NumTrustedProxies:        3,
  1814  					ForwardClientCertDetails: meshconfig.ForwardClientCertDetails_FORWARD_ONLY,
  1815  				},
  1816  			},
  1817  			result: &filterChainOpts{
  1818  				sniHosts: []string{"example.org"},
  1819  				tlsContext: &auth.DownstreamTlsContext{
  1820  					CommonTlsContext: &auth.CommonTlsContext{
  1821  						AlpnProtocols: util.ALPNHttp,
  1822  						TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1823  							{
  1824  								Name: "default",
  1825  								SdsConfig: &core.ConfigSource{
  1826  									ResourceApiVersion:  core.ApiVersion_V3,
  1827  									InitialFetchTimeout: durationpb.New(time.Second * 0),
  1828  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1829  										ApiConfigSource: &core.ApiConfigSource{
  1830  											ApiType:                   core.ApiConfigSource_GRPC,
  1831  											SetNodeOnFirstMessageOnly: true,
  1832  											TransportApiVersion:       core.ApiVersion_V3,
  1833  											GrpcServices: []*core.GrpcService{
  1834  												{
  1835  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1836  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1837  													},
  1838  												},
  1839  											},
  1840  										},
  1841  									},
  1842  								},
  1843  							},
  1844  						},
  1845  						ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
  1846  							CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
  1847  								DefaultValidationContext: &auth.CertificateValidationContext{},
  1848  								ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
  1849  									Name: "ROOTCA",
  1850  									SdsConfig: &core.ConfigSource{
  1851  										ResourceApiVersion:  core.ApiVersion_V3,
  1852  										InitialFetchTimeout: durationpb.New(time.Second * 0),
  1853  										ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1854  											ApiConfigSource: &core.ApiConfigSource{
  1855  												ApiType:                   core.ApiConfigSource_GRPC,
  1856  												SetNodeOnFirstMessageOnly: true,
  1857  												TransportApiVersion:       core.ApiVersion_V3,
  1858  												GrpcServices: []*core.GrpcService{
  1859  													{
  1860  														TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1861  															EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1862  														},
  1863  													},
  1864  												},
  1865  											},
  1866  										},
  1867  									},
  1868  								},
  1869  							},
  1870  						},
  1871  					},
  1872  					RequireClientCertificate: proto.BoolTrue,
  1873  				},
  1874  				httpOpts: &httpListenerOpts{
  1875  					rds:              "some-route",
  1876  					useRemoteAddress: true,
  1877  					connectionManager: &hcm.HttpConnectionManager{
  1878  						XffNumTrustedHops:        3,
  1879  						ForwardClientCertDetails: hcm.HttpConnectionManager_FORWARD_ONLY,
  1880  						ServerName:               EnvoyServerName,
  1881  						HttpProtocolOptions:      &core.Http1ProtocolOptions{},
  1882  						Proxy_100Continue:        true,
  1883  					},
  1884  					class:    istionetworking.ListenerClassGateway,
  1885  					protocol: protocol.HTTPS,
  1886  				},
  1887  			},
  1888  		},
  1889  		{
  1890  			name: "HTTPS Protocol with server name",
  1891  			node: &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}},
  1892  			server: &networking.Server{
  1893  				Name: "server1",
  1894  				Port: &networking.Port{
  1895  					Protocol: "HTTPS",
  1896  				},
  1897  				Hosts: []string{"example.org"},
  1898  				Tls: &networking.ServerTLSSettings{
  1899  					Mode: networking.ServerTLSSettings_ISTIO_MUTUAL,
  1900  				},
  1901  			},
  1902  			routeName: "some-route",
  1903  			proxyConfig: &meshconfig.ProxyConfig{
  1904  				GatewayTopology: &meshconfig.Topology{
  1905  					NumTrustedProxies:        3,
  1906  					ForwardClientCertDetails: meshconfig.ForwardClientCertDetails_FORWARD_ONLY,
  1907  				},
  1908  			},
  1909  			result: &filterChainOpts{
  1910  				sniHosts: []string{"example.org"},
  1911  				tlsContext: &auth.DownstreamTlsContext{
  1912  					RequireClientCertificate: proto.BoolTrue,
  1913  					CommonTlsContext: &auth.CommonTlsContext{
  1914  						AlpnProtocols: util.ALPNHttp,
  1915  						TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  1916  							{
  1917  								Name: "default",
  1918  								SdsConfig: &core.ConfigSource{
  1919  									ResourceApiVersion:  core.ApiVersion_V3,
  1920  									InitialFetchTimeout: durationpb.New(time.Second * 0),
  1921  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1922  										ApiConfigSource: &core.ApiConfigSource{
  1923  											ApiType:                   core.ApiConfigSource_GRPC,
  1924  											SetNodeOnFirstMessageOnly: true,
  1925  											TransportApiVersion:       core.ApiVersion_V3,
  1926  											GrpcServices: []*core.GrpcService{
  1927  												{
  1928  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1929  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1930  													},
  1931  												},
  1932  											},
  1933  										},
  1934  									},
  1935  								},
  1936  							},
  1937  						},
  1938  						ValidationContextType: &auth.CommonTlsContext_CombinedValidationContext{
  1939  							CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
  1940  								DefaultValidationContext: &auth.CertificateValidationContext{},
  1941  								ValidationContextSdsSecretConfig: &auth.SdsSecretConfig{
  1942  									Name: "ROOTCA",
  1943  									SdsConfig: &core.ConfigSource{
  1944  										ResourceApiVersion:  core.ApiVersion_V3,
  1945  										InitialFetchTimeout: durationpb.New(time.Second * 0),
  1946  										ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  1947  											ApiConfigSource: &core.ApiConfigSource{
  1948  												ApiType:                   core.ApiConfigSource_GRPC,
  1949  												SetNodeOnFirstMessageOnly: true,
  1950  												TransportApiVersion:       core.ApiVersion_V3,
  1951  												GrpcServices: []*core.GrpcService{
  1952  													{
  1953  														TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1954  															EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: model.SDSClusterName},
  1955  														},
  1956  													},
  1957  												},
  1958  											},
  1959  										},
  1960  									},
  1961  								},
  1962  							},
  1963  						},
  1964  					},
  1965  				},
  1966  				httpOpts: &httpListenerOpts{
  1967  					rds:              "some-route",
  1968  					useRemoteAddress: true,
  1969  					connectionManager: &hcm.HttpConnectionManager{
  1970  						XffNumTrustedHops:        3,
  1971  						ForwardClientCertDetails: hcm.HttpConnectionManager_FORWARD_ONLY,
  1972  						ServerName:               EnvoyServerName,
  1973  						HttpProtocolOptions:      &core.Http1ProtocolOptions{},
  1974  						Proxy_100Continue:        true,
  1975  					},
  1976  					statPrefix: "server1",
  1977  					class:      istionetworking.ListenerClassGateway,
  1978  					protocol:   protocol.HTTPS,
  1979  				},
  1980  			},
  1981  		},
  1982  		{
  1983  			name:              "QUIC protocol with server name",
  1984  			node:              &pilot_model.Proxy{Metadata: &pilot_model.NodeMetadata{}},
  1985  			transportProtocol: istionetworking.TransportProtocolQUIC,
  1986  			server: &networking.Server{
  1987  				Name: "server1",
  1988  				Port: &networking.Port{
  1989  					Name:     "https-app",
  1990  					Number:   443,
  1991  					Protocol: "HTTPS",
  1992  				},
  1993  				Hosts: []string{"example.org"},
  1994  				Tls: &networking.ServerTLSSettings{
  1995  					Mode:              networking.ServerTLSSettings_SIMPLE,
  1996  					ServerCertificate: "/etc/cert/example.crt",
  1997  					PrivateKey:        "/etc/cert/example.key",
  1998  				},
  1999  			},
  2000  			routeName: "some-route",
  2001  			proxyConfig: &meshconfig.ProxyConfig{
  2002  				GatewayTopology: &meshconfig.Topology{
  2003  					NumTrustedProxies:        3,
  2004  					ForwardClientCertDetails: meshconfig.ForwardClientCertDetails_FORWARD_ONLY,
  2005  				},
  2006  			},
  2007  			result: &filterChainOpts{
  2008  				sniHosts: []string{"example.org"},
  2009  				tlsContext: &auth.DownstreamTlsContext{
  2010  					RequireClientCertificate: proto.BoolFalse,
  2011  					CommonTlsContext: &auth.CommonTlsContext{
  2012  						AlpnProtocols: util.ALPNHttp3OverQUIC,
  2013  						TlsCertificateSdsSecretConfigs: []*auth.SdsSecretConfig{
  2014  							{
  2015  								Name: "file-cert:/etc/cert/example.crt~/etc/cert/example.key",
  2016  								SdsConfig: &core.ConfigSource{
  2017  									ResourceApiVersion: core.ApiVersion_V3,
  2018  									ConfigSourceSpecifier: &core.ConfigSource_ApiConfigSource{
  2019  										ApiConfigSource: &core.ApiConfigSource{
  2020  											ApiType: core.ApiConfigSource_GRPC,
  2021  											GrpcServices: []*core.GrpcService{
  2022  												{
  2023  													TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  2024  														EnvoyGrpc: &core.GrpcService_EnvoyGrpc{
  2025  															ClusterName: "sds-grpc",
  2026  														},
  2027  													},
  2028  												},
  2029  											},
  2030  											SetNodeOnFirstMessageOnly: true,
  2031  											TransportApiVersion:       core.ApiVersion_V3,
  2032  										},
  2033  									},
  2034  								},
  2035  							},
  2036  						},
  2037  					},
  2038  				},
  2039  				httpOpts: &httpListenerOpts{
  2040  					rds:       "some-route",
  2041  					http3Only: true,
  2042  					connectionManager: &hcm.HttpConnectionManager{
  2043  						XffNumTrustedHops:        3,
  2044  						ForwardClientCertDetails: hcm.HttpConnectionManager_FORWARD_ONLY,
  2045  						ServerName:               EnvoyServerName,
  2046  						HttpProtocolOptions:      &core.Http1ProtocolOptions{},
  2047  						Http3ProtocolOptions:     &core.Http3ProtocolOptions{},
  2048  						CodecType:                hcm.HttpConnectionManager_HTTP3,
  2049  						Proxy_100Continue:        true,
  2050  					},
  2051  					useRemoteAddress: true,
  2052  					statPrefix:       "server1",
  2053  					class:            istionetworking.ListenerClassGateway,
  2054  					protocol:         protocol.HTTPS,
  2055  				},
  2056  			},
  2057  		},
  2058  	}
  2059  
  2060  	for _, tc := range testCases {
  2061  		t.Run(tc.name, func(t *testing.T) {
  2062  			cgi := NewConfigGenerator(&pilot_model.DisabledCache{})
  2063  			tc.node.MergedGateway = &pilot_model.MergedGateway{TLSServerInfo: map[*networking.Server]*pilot_model.TLSServerInfo{
  2064  				tc.server: {SNIHosts: pilot_model.GetSNIHostsForServer(tc.server)},
  2065  			}}
  2066  			ret := cgi.createGatewayHTTPFilterChainOpts(tc.node, tc.server.Port, tc.server,
  2067  				tc.routeName, tc.proxyConfig, tc.transportProtocol, cg.PushContext())
  2068  			if diff := cmp.Diff(tc.result.tlsContext, ret.tlsContext, protocmp.Transform()); diff != "" {
  2069  				t.Errorf("got diff in tls context: %v", diff)
  2070  			}
  2071  			if !reflect.DeepEqual(tc.result.httpOpts, ret.httpOpts) {
  2072  				t.Errorf("expecting httpopts:\n %+v \nbut got:\n %+v", tc.result.httpOpts, ret.httpOpts)
  2073  			}
  2074  			if !reflect.DeepEqual(tc.result.sniHosts, ret.sniHosts) {
  2075  				t.Errorf("expecting snihosts %+v but got %+v", tc.result.sniHosts, ret.sniHosts)
  2076  			}
  2077  		})
  2078  	}
  2079  }
  2080  
  2081  func TestGatewayHTTPRouteConfig(t *testing.T) {
  2082  	httpRedirectGateway := config.Config{
  2083  		Meta: config.Meta{
  2084  			Name:             "gateway-redirect",
  2085  			Namespace:        "default",
  2086  			GroupVersionKind: gvk.Gateway,
  2087  		},
  2088  		Spec: &networking.Gateway{
  2089  			Selector: map[string]string{"istio": "ingressgateway"},
  2090  			Servers: []*networking.Server{
  2091  				{
  2092  					Hosts: []string{"example.org"},
  2093  					Port:  &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2094  					Tls:   &networking.ServerTLSSettings{HttpsRedirect: true},
  2095  				},
  2096  			},
  2097  		},
  2098  	}
  2099  	httpRedirectGatewayWithoutVS := config.Config{
  2100  		Meta: config.Meta{
  2101  			Name:             "gateway-redirect-noroutes",
  2102  			Namespace:        "default",
  2103  			GroupVersionKind: gvk.Gateway,
  2104  		},
  2105  		Spec: &networking.Gateway{
  2106  			Selector: map[string]string{"istio": "ingressgateway"},
  2107  			Servers: []*networking.Server{
  2108  				{
  2109  					Hosts: []string{"example.org"},
  2110  					Port:  &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2111  					Tls:   &networking.ServerTLSSettings{HttpsRedirect: true},
  2112  				},
  2113  			},
  2114  		},
  2115  	}
  2116  	httpGateway := config.Config{
  2117  		Meta: config.Meta{
  2118  			Name:             "gateway",
  2119  			Namespace:        "default",
  2120  			GroupVersionKind: gvk.Gateway,
  2121  		},
  2122  		Spec: &networking.Gateway{
  2123  			Selector: map[string]string{"istio": "ingressgateway"},
  2124  			Servers: []*networking.Server{
  2125  				{
  2126  					Hosts: []string{"example.org"},
  2127  					Port:  &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2128  				},
  2129  			},
  2130  		},
  2131  	}
  2132  	httpCaseInSensitiveGateway := config.Config{
  2133  		Meta: config.Meta{
  2134  			Name:             "case-insensitive-gateway",
  2135  			Namespace:        "default",
  2136  			GroupVersionKind: gvk.Gateway,
  2137  		},
  2138  		Spec: &networking.Gateway{
  2139  			Selector: map[string]string{"istio": "ingressgateway"},
  2140  			Servers: []*networking.Server{
  2141  				{
  2142  					Hosts: []string{"Example.org"},
  2143  					Port:  &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2144  				},
  2145  			},
  2146  		},
  2147  	}
  2148  	httpsGateway := config.Config{
  2149  		Meta: config.Meta{
  2150  			Name:             "gateway-https",
  2151  			Namespace:        "default",
  2152  			GroupVersionKind: gvk.Gateway,
  2153  		},
  2154  		Spec: &networking.Gateway{
  2155  			Selector: map[string]string{"istio": "ingressgateway"},
  2156  			Servers: []*networking.Server{
  2157  				{
  2158  					Hosts: []string{"example.org"},
  2159  					Port:  &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2160  					Tls:   &networking.ServerTLSSettings{HttpsRedirect: true},
  2161  				},
  2162  				{
  2163  					Hosts: []string{"example.org"},
  2164  					Port:  &networking.Port{Name: "https", Number: 443, Protocol: "HTTPS"},
  2165  					Tls:   &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_TLSmode(networking.ClientTLSSettings_SIMPLE)},
  2166  				},
  2167  			},
  2168  		},
  2169  	}
  2170  	httpsGatewayRedirect := config.Config{
  2171  		Meta: config.Meta{
  2172  			Name:             "gateway-https",
  2173  			Namespace:        "default",
  2174  			GroupVersionKind: gvk.Gateway,
  2175  		},
  2176  		Spec: &networking.Gateway{
  2177  			Selector: map[string]string{"istio": "ingressgateway"},
  2178  			Servers: []*networking.Server{
  2179  				{
  2180  					Hosts: []string{"example.org"},
  2181  					Port:  &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2182  					Tls:   &networking.ServerTLSSettings{HttpsRedirect: true},
  2183  				},
  2184  				{
  2185  					Hosts: []string{"example.org"},
  2186  					Port:  &networking.Port{Name: "https", Number: 443, Protocol: "HTTPS"},
  2187  					Tls:   &networking.ServerTLSSettings{HttpsRedirect: true, Mode: networking.ServerTLSSettings_TLSmode(networking.ClientTLSSettings_SIMPLE)},
  2188  				},
  2189  			},
  2190  		},
  2191  	}
  2192  	httpGatewayWildcard := config.Config{
  2193  		Meta: config.Meta{
  2194  			Name:             "gateway",
  2195  			Namespace:        "default",
  2196  			GroupVersionKind: gvk.Gateway,
  2197  		},
  2198  		Spec: &networking.Gateway{
  2199  			Selector: map[string]string{"istio": "ingressgateway"},
  2200  			Servers: []*networking.Server{
  2201  				{
  2202  					Hosts: []string{"*"},
  2203  					Port:  &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2204  				},
  2205  			},
  2206  		},
  2207  	}
  2208  	virtualServiceSpec := &networking.VirtualService{
  2209  		Hosts:    []string{"example.org"},
  2210  		Gateways: []string{"gateway", "gateway-redirect"},
  2211  		Http: []*networking.HTTPRoute{
  2212  			{
  2213  				Route: []*networking.HTTPRouteDestination{
  2214  					{
  2215  						Destination: &networking.Destination{
  2216  							Host: "example.org",
  2217  							Port: &networking.PortSelector{
  2218  								Number: 80,
  2219  							},
  2220  						},
  2221  					},
  2222  				},
  2223  			},
  2224  		},
  2225  	}
  2226  	virtualServiceCaseInsensitiveSpec := &networking.VirtualService{
  2227  		Hosts:    []string{"Example.org"},
  2228  		Gateways: []string{"case-insensitive-gateway", "gateway-redirect"},
  2229  		Http: []*networking.HTTPRoute{
  2230  			{
  2231  				Route: []*networking.HTTPRouteDestination{
  2232  					{
  2233  						Destination: &networking.Destination{
  2234  							Host: "example.org",
  2235  							Port: &networking.PortSelector{
  2236  								Number: 80,
  2237  							},
  2238  						},
  2239  					},
  2240  				},
  2241  			},
  2242  		},
  2243  	}
  2244  	virtualServiceHTTPSMatchSpec := &networking.VirtualService{
  2245  		Hosts:    []string{"example.org"},
  2246  		Gateways: []string{"gateway-https"},
  2247  		Http: []*networking.HTTPRoute{
  2248  			{
  2249  				Match: []*networking.HTTPMatchRequest{
  2250  					{
  2251  						Port: 443,
  2252  					},
  2253  				},
  2254  				Route: []*networking.HTTPRouteDestination{
  2255  					{
  2256  						Destination: &networking.Destination{
  2257  							Host: "example.default.svc.cluster.local",
  2258  							Port: &networking.PortSelector{
  2259  								Number: 8080,
  2260  							},
  2261  						},
  2262  					},
  2263  				},
  2264  			},
  2265  		},
  2266  	}
  2267  	virtualService := config.Config{
  2268  		Meta: config.Meta{
  2269  			GroupVersionKind: gvk.VirtualService,
  2270  			Name:             "virtual-service",
  2271  			Namespace:        "default",
  2272  		},
  2273  		Spec: virtualServiceSpec,
  2274  	}
  2275  	virtualServiceCaseInsensitive := config.Config{
  2276  		Meta: config.Meta{
  2277  			GroupVersionKind: gvk.VirtualService,
  2278  			Name:             "virtual-service-case-insensitive",
  2279  			Namespace:        "default",
  2280  		},
  2281  		Spec: virtualServiceCaseInsensitiveSpec,
  2282  	}
  2283  	virtualServiceHTTPS := config.Config{
  2284  		Meta: config.Meta{
  2285  			GroupVersionKind: gvk.VirtualService,
  2286  			Name:             "virtual-service-https",
  2287  			Namespace:        "default",
  2288  		},
  2289  		Spec: virtualServiceHTTPSMatchSpec,
  2290  	}
  2291  	virtualServiceCopy := config.Config{
  2292  		Meta: config.Meta{
  2293  			GroupVersionKind: gvk.VirtualService,
  2294  			Name:             "virtual-service-copy",
  2295  			Namespace:        "default",
  2296  		},
  2297  		Spec: virtualServiceSpec,
  2298  	}
  2299  	virtualServiceWildcard := config.Config{
  2300  		Meta: config.Meta{
  2301  			GroupVersionKind: gvk.VirtualService,
  2302  			Name:             "virtual-service-wildcard",
  2303  			Namespace:        "default",
  2304  		},
  2305  		Spec: &networking.VirtualService{
  2306  			Hosts:    []string{"*.org"},
  2307  			Gateways: []string{"gateway", "gateway-redirect"},
  2308  			Http: []*networking.HTTPRoute{
  2309  				{
  2310  					Route: []*networking.HTTPRouteDestination{
  2311  						{
  2312  							Destination: &networking.Destination{
  2313  								Host: "example.org",
  2314  								Port: &networking.PortSelector{
  2315  									Number: 80,
  2316  								},
  2317  							},
  2318  						},
  2319  					},
  2320  				},
  2321  			},
  2322  		},
  2323  	}
  2324  	cases := []struct {
  2325  		name                              string
  2326  		virtualServices                   []config.Config
  2327  		gateways                          []config.Config
  2328  		routeName                         string
  2329  		expectedVirtualHosts              map[string][]string
  2330  		expectedVirtualHostsHostPortStrip map[string][]string
  2331  		expectedHTTPRoutes                map[string]int
  2332  		redirect                          bool
  2333  		expectStatefulSession             bool
  2334  	}{
  2335  		{
  2336  			name:            "404 when no services",
  2337  			virtualServices: []config.Config{},
  2338  			gateways:        []config.Config{httpGateway},
  2339  			routeName:       "http.80",
  2340  			expectedVirtualHosts: map[string][]string{
  2341  				"blackhole:80": {
  2342  					"*",
  2343  				},
  2344  			},
  2345  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2346  				"blackhole:80": {
  2347  					"*",
  2348  				},
  2349  			},
  2350  			expectedHTTPRoutes:    map[string]int{"blackhole:80": 0},
  2351  			expectStatefulSession: false,
  2352  		},
  2353  		{
  2354  			name:            "tls redirect without virtual services",
  2355  			virtualServices: []config.Config{virtualService},
  2356  			gateways:        []config.Config{httpRedirectGatewayWithoutVS},
  2357  			routeName:       "http.80",
  2358  			expectedVirtualHosts: map[string][]string{
  2359  				"example.org:80": {
  2360  					"example.org",
  2361  				},
  2362  			},
  2363  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2364  				"example.org:80": {"example.org"},
  2365  			},
  2366  			// We will setup a VHost which just redirects; no routes
  2367  			expectedHTTPRoutes:    map[string]int{"example.org:80": 0},
  2368  			redirect:              true,
  2369  			expectStatefulSession: false,
  2370  		},
  2371  		{
  2372  			name:            "virtual services with tls redirect",
  2373  			virtualServices: []config.Config{virtualService},
  2374  			gateways:        []config.Config{httpRedirectGateway},
  2375  			routeName:       "http.80",
  2376  			expectedVirtualHosts: map[string][]string{
  2377  				"example.org:80": {
  2378  					"example.org",
  2379  				},
  2380  			},
  2381  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2382  				"example.org:80": {"example.org"},
  2383  			},
  2384  			expectedHTTPRoutes:    map[string]int{"example.org:80": 1},
  2385  			redirect:              true,
  2386  			expectStatefulSession: true,
  2387  		},
  2388  		{
  2389  			name:            "merging of virtual services when tls redirect is set",
  2390  			virtualServices: []config.Config{virtualService, virtualServiceCopy},
  2391  			gateways:        []config.Config{httpRedirectGateway, httpGateway},
  2392  			routeName:       "http.80",
  2393  			expectedVirtualHosts: map[string][]string{
  2394  				"example.org:80": {
  2395  					"example.org",
  2396  				},
  2397  			},
  2398  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2399  				"example.org:80": {"example.org"},
  2400  			},
  2401  			expectedHTTPRoutes:    map[string]int{"example.org:80": 4},
  2402  			redirect:              true,
  2403  			expectStatefulSession: true,
  2404  		},
  2405  		{
  2406  			name:            "reverse merging of virtual services when tls redirect is set",
  2407  			virtualServices: []config.Config{virtualService, virtualServiceCopy},
  2408  			gateways:        []config.Config{httpGateway, httpRedirectGateway},
  2409  			routeName:       "http.80",
  2410  			expectedVirtualHosts: map[string][]string{
  2411  				"example.org:80": {
  2412  					"example.org",
  2413  				},
  2414  			},
  2415  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2416  				"example.org:80": {"example.org"},
  2417  			},
  2418  			expectedHTTPRoutes:    map[string]int{"example.org:80": 4},
  2419  			redirect:              true,
  2420  			expectStatefulSession: true,
  2421  		},
  2422  		{
  2423  			name:            "merging of virtual services when tls redirect is set without VS",
  2424  			virtualServices: []config.Config{virtualService, virtualServiceCopy},
  2425  			gateways:        []config.Config{httpGateway, httpRedirectGatewayWithoutVS},
  2426  			routeName:       "http.80",
  2427  			expectedVirtualHosts: map[string][]string{
  2428  				"example.org:80": {
  2429  					"example.org",
  2430  				},
  2431  			},
  2432  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2433  				"example.org:80": {"example.org"},
  2434  			},
  2435  			expectedHTTPRoutes:    map[string]int{"example.org:80": 2},
  2436  			redirect:              true,
  2437  			expectStatefulSession: true,
  2438  		},
  2439  		{
  2440  			name:            "reverse merging of virtual services when tls redirect is set without VS",
  2441  			virtualServices: []config.Config{virtualService, virtualServiceCopy},
  2442  			gateways:        []config.Config{httpRedirectGatewayWithoutVS, httpGateway},
  2443  			routeName:       "http.80",
  2444  			expectedVirtualHosts: map[string][]string{
  2445  				"example.org:80": {
  2446  					"example.org",
  2447  				},
  2448  			},
  2449  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2450  				"example.org:80": {"example.org"},
  2451  			},
  2452  			expectedHTTPRoutes:    map[string]int{"example.org:80": 2},
  2453  			redirect:              true,
  2454  			expectStatefulSession: false,
  2455  		},
  2456  		{
  2457  			name:            "add a route for a virtual service",
  2458  			virtualServices: []config.Config{virtualService},
  2459  			gateways:        []config.Config{httpGateway},
  2460  			routeName:       "http.80",
  2461  			expectedVirtualHosts: map[string][]string{
  2462  				"example.org:80": {
  2463  					"example.org",
  2464  				},
  2465  			},
  2466  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2467  				"example.org:80": {"example.org"},
  2468  			},
  2469  			expectedHTTPRoutes: map[string]int{"example.org:80": 1},
  2470  		},
  2471  		{
  2472  			name:            "duplicate virtual service should merge",
  2473  			virtualServices: []config.Config{virtualService, virtualServiceCopy},
  2474  			gateways:        []config.Config{httpGateway},
  2475  			routeName:       "http.80",
  2476  			expectedVirtualHosts: map[string][]string{
  2477  				"example.org:80": {
  2478  					"example.org",
  2479  				},
  2480  			},
  2481  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2482  				"example.org:80": {"example.org"},
  2483  			},
  2484  			expectedHTTPRoutes: map[string]int{"example.org:80": 2},
  2485  		},
  2486  		{
  2487  			name:            "duplicate virtual service case insensitive",
  2488  			virtualServices: []config.Config{virtualService, virtualServiceCaseInsensitive},
  2489  			gateways:        []config.Config{httpGateway, httpCaseInSensitiveGateway},
  2490  			routeName:       "http.80",
  2491  			expectedVirtualHosts: map[string][]string{
  2492  				"example.org:80": {
  2493  					"example.org",
  2494  				},
  2495  			},
  2496  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2497  				"example.org:80": {"example.org"},
  2498  			},
  2499  			expectedHTTPRoutes: map[string]int{"example.org:80": 2},
  2500  		},
  2501  		{
  2502  			name:            "duplicate by wildcard should merge",
  2503  			virtualServices: []config.Config{virtualService, virtualServiceWildcard},
  2504  			gateways:        []config.Config{httpGateway},
  2505  			routeName:       "http.80",
  2506  			expectedVirtualHosts: map[string][]string{
  2507  				"example.org:80": {
  2508  					"example.org",
  2509  				},
  2510  			},
  2511  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2512  				"example.org:80": {"example.org"},
  2513  			},
  2514  			expectedHTTPRoutes: map[string]int{"example.org:80": 2},
  2515  		},
  2516  		{
  2517  			name:            "wildcard virtual service",
  2518  			virtualServices: []config.Config{virtualServiceWildcard},
  2519  			gateways:        []config.Config{httpGatewayWildcard},
  2520  			routeName:       "http.80",
  2521  			expectedVirtualHosts: map[string][]string{
  2522  				"*.org:80": {"*.org"},
  2523  			},
  2524  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2525  				"*.org:80": {"*.org"},
  2526  			},
  2527  			expectedHTTPRoutes:    map[string]int{"*.org:80": 1},
  2528  			expectStatefulSession: false,
  2529  		},
  2530  		{
  2531  			name:            "http redirection not working when virtualservice not match http port",
  2532  			virtualServices: []config.Config{virtualServiceHTTPS},
  2533  			gateways:        []config.Config{httpsGateway},
  2534  			routeName:       "https.443.https.gateway-https.default",
  2535  			expectedVirtualHosts: map[string][]string{
  2536  				"example.org:443": {"example.org"},
  2537  			},
  2538  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2539  				"example.org:443": {"example.org"},
  2540  			},
  2541  			expectedHTTPRoutes:    map[string]int{"example.org:443": 1},
  2542  			expectStatefulSession: false,
  2543  		},
  2544  		{
  2545  			name:            "http redirection not working when virtualservice not match http port",
  2546  			virtualServices: []config.Config{virtualServiceHTTPS},
  2547  			gateways:        []config.Config{httpsGateway},
  2548  			routeName:       "http.80",
  2549  			expectedVirtualHosts: map[string][]string{
  2550  				"example.org:80": {"example.org"},
  2551  			},
  2552  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2553  				"example.org:80": {"example.org"},
  2554  			},
  2555  			// We will setup a VHost which just redirects; no routes
  2556  			expectedHTTPRoutes:    map[string]int{"example.org:80": 0},
  2557  			redirect:              true,
  2558  			expectStatefulSession: false,
  2559  		},
  2560  		{
  2561  			name:            "http & https redirection not working when virtualservice not match http port",
  2562  			virtualServices: []config.Config{virtualServiceHTTPS},
  2563  			gateways:        []config.Config{httpsGatewayRedirect},
  2564  			routeName:       "https.443.https.gateway-https.default",
  2565  			expectedVirtualHosts: map[string][]string{
  2566  				"example.org:443": {"example.org"},
  2567  			},
  2568  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2569  				"example.org:443": {"example.org"},
  2570  			},
  2571  			expectedHTTPRoutes:    map[string]int{"example.org:443": 1},
  2572  			redirect:              true,
  2573  			expectStatefulSession: false,
  2574  		},
  2575  		{
  2576  			name:            "http & https redirection not working when virtualservice not match http port",
  2577  			virtualServices: []config.Config{virtualServiceHTTPS},
  2578  			gateways:        []config.Config{httpsGatewayRedirect},
  2579  			routeName:       "http.80",
  2580  			expectedVirtualHosts: map[string][]string{
  2581  				"example.org:80": {"example.org"},
  2582  			},
  2583  			expectedVirtualHostsHostPortStrip: map[string][]string{
  2584  				"example.org:80": {"example.org"},
  2585  			},
  2586  			// We will setup a VHost which just redirects; no routes
  2587  			expectedHTTPRoutes:    map[string]int{"example.org:80": 0},
  2588  			redirect:              true,
  2589  			expectStatefulSession: false,
  2590  		},
  2591  	}
  2592  	exampleService := &pilot_model.Service{
  2593  		Hostname: host.Name("example.org"),
  2594  		Ports: []*pilot_model.Port{{
  2595  			Name:     "http",
  2596  			Protocol: "HTTP",
  2597  			Port:     80,
  2598  		}},
  2599  		Attributes: pilot_model.ServiceAttributes{
  2600  			Namespace: "default",
  2601  			Labels:    map[string]string{"istio.io/persistent-session": "session-cookie"},
  2602  		},
  2603  	}
  2604  
  2605  	for _, tt := range cases {
  2606  		t.Run(tt.name, func(t *testing.T) {
  2607  			cfgs := tt.gateways
  2608  			cfgs = append(cfgs, tt.virtualServices...)
  2609  			cg := NewConfigGenTest(t, TestOptions{
  2610  				Configs: cfgs,
  2611  				Services: []*pilot_model.Service{
  2612  					exampleService,
  2613  				},
  2614  			})
  2615  			r := cg.ConfigGen.buildGatewayHTTPRouteConfig(cg.SetupProxy(&proxyGateway), cg.PushContext(), tt.routeName)
  2616  			if r == nil {
  2617  				t.Fatal("got an empty route configuration")
  2618  			}
  2619  			if r.MaxDirectResponseBodySizeBytes != istio_route.DefaultMaxDirectResponseBodySizeBytes {
  2620  				t.Errorf("expected MaxDirectResponseBodySizeBytes %v, got %v",
  2621  					istio_route.DefaultMaxDirectResponseBodySizeBytes, r.MaxDirectResponseBodySizeBytes)
  2622  			}
  2623  			vh := make(map[string][]string)
  2624  			hr := make(map[string]int)
  2625  			for _, h := range r.VirtualHosts {
  2626  				vh[h.Name] = h.Domains
  2627  				hr[h.Name] = len(h.Routes)
  2628  				if h.Name != "blackhole:80" && !h.IncludeRequestAttemptCount {
  2629  					t.Errorf("expected attempt count to be set in virtual host, but not found")
  2630  				}
  2631  				if tt.redirect != (h.RequireTls == route.VirtualHost_ALL) {
  2632  					t.Errorf("expected redirect %v, got %v", tt.redirect, h.RequireTls)
  2633  				}
  2634  				if tt.expectStatefulSession && h.TypedPerFilterConfig[util.StatefulSessionFilter] == nil {
  2635  					t.Errorf("expected per filter config for stateful session filter, but not found")
  2636  				}
  2637  			}
  2638  
  2639  			if !maps.EqualFunc(tt.expectedVirtualHosts, vh, slices.Equal) {
  2640  				t.Errorf("got unexpected virtual hosts. Expected: %v, Got: %v", tt.expectedVirtualHosts, vh)
  2641  			}
  2642  			if !maps.Equal(tt.expectedHTTPRoutes, hr) {
  2643  				t.Errorf("got unexpected number of http routes. Expected: %v, Got: %v", tt.expectedHTTPRoutes, hr)
  2644  			}
  2645  		})
  2646  	}
  2647  }
  2648  
  2649  func TestBuildGatewayListeners(t *testing.T) {
  2650  	cases := []struct {
  2651  		name              string
  2652  		node              *pilot_model.Proxy
  2653  		gateways          []config.Config
  2654  		virtualServices   []config.Config
  2655  		expectedListeners []string
  2656  	}{
  2657  		{
  2658  			"targetPort overrides service port",
  2659  			&pilot_model.Proxy{
  2660  				ServiceTargets: []pilot_model.ServiceTarget{
  2661  					{
  2662  						Service: &pilot_model.Service{
  2663  							Hostname: "test",
  2664  						},
  2665  						Port: pilot_model.ServiceInstancePort{
  2666  							ServicePort: &pilot_model.Port{
  2667  								Port: 80,
  2668  							},
  2669  							TargetPort: 8080,
  2670  						},
  2671  					},
  2672  				},
  2673  			},
  2674  			[]config.Config{
  2675  				{
  2676  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway},
  2677  					Spec: &networking.Gateway{
  2678  						Servers: []*networking.Server{
  2679  							{
  2680  								Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2681  							},
  2682  						},
  2683  					},
  2684  				},
  2685  			},
  2686  			nil,
  2687  			[]string{"0.0.0.0_8080"},
  2688  		},
  2689  		{
  2690  			"multiple ports",
  2691  			&pilot_model.Proxy{},
  2692  			[]config.Config{
  2693  				{
  2694  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway},
  2695  					Spec: &networking.Gateway{
  2696  						Servers: []*networking.Server{
  2697  							{
  2698  								Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2699  							},
  2700  							{
  2701  								Port: &networking.Port{Name: "http", Number: 801, Protocol: "HTTP"},
  2702  							},
  2703  						},
  2704  					},
  2705  				},
  2706  			},
  2707  			nil,
  2708  			[]string{"0.0.0.0_80", "0.0.0.0_801"},
  2709  		},
  2710  		{
  2711  			"privileged port on unprivileged pod",
  2712  			&pilot_model.Proxy{
  2713  				Metadata: &pilot_model.NodeMetadata{
  2714  					UnprivilegedPod: "true",
  2715  				},
  2716  			},
  2717  			[]config.Config{
  2718  				{
  2719  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway},
  2720  					Spec: &networking.Gateway{
  2721  						Servers: []*networking.Server{
  2722  							{
  2723  								Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2724  							},
  2725  							{
  2726  								Port: &networking.Port{Name: "http", Number: 8080, Protocol: "HTTP"},
  2727  							},
  2728  						},
  2729  					},
  2730  				},
  2731  			},
  2732  			nil,
  2733  			[]string{"0.0.0.0_8080"},
  2734  		},
  2735  		{
  2736  			"privileged port on privileged pod when empty env var is set",
  2737  			&pilot_model.Proxy{
  2738  				Metadata: &pilot_model.NodeMetadata{
  2739  					UnprivilegedPod: "",
  2740  				},
  2741  			},
  2742  			[]config.Config{
  2743  				{
  2744  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway},
  2745  					Spec: &networking.Gateway{
  2746  						Servers: []*networking.Server{
  2747  							{
  2748  								Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2749  							},
  2750  							{
  2751  								Port: &networking.Port{Name: "http", Number: 8080, Protocol: "HTTP"},
  2752  							},
  2753  						},
  2754  					},
  2755  				},
  2756  			},
  2757  			nil,
  2758  			[]string{"0.0.0.0_80", "0.0.0.0_8080"},
  2759  		},
  2760  		{
  2761  			"privileged port on privileged pod",
  2762  			&pilot_model.Proxy{},
  2763  			[]config.Config{
  2764  				{
  2765  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway},
  2766  					Spec: &networking.Gateway{
  2767  						Servers: []*networking.Server{
  2768  							{
  2769  								Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2770  							},
  2771  							{
  2772  								Port: &networking.Port{Name: "http", Number: 8080, Protocol: "HTTP"},
  2773  							},
  2774  						},
  2775  					},
  2776  				},
  2777  			},
  2778  			nil,
  2779  			[]string{"0.0.0.0_80", "0.0.0.0_8080"},
  2780  		},
  2781  		{
  2782  			"gateway with bind",
  2783  			&pilot_model.Proxy{},
  2784  			[]config.Config{
  2785  				{
  2786  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway},
  2787  					Spec: &networking.Gateway{
  2788  						Servers: []*networking.Server{
  2789  							{
  2790  								Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2791  							},
  2792  							{
  2793  								Port:  &networking.Port{Name: "http", Number: 8080, Protocol: "HTTP"},
  2794  								Hosts: []string{"externalgatewayclient.com"},
  2795  							},
  2796  							{
  2797  								Port:  &networking.Port{Name: "http", Number: 8080, Protocol: "HTTP"},
  2798  								Bind:  "127.0.0.1",
  2799  								Hosts: []string{"internalmesh.svc.cluster.local"},
  2800  							},
  2801  						},
  2802  					},
  2803  				},
  2804  			},
  2805  			nil,
  2806  			[]string{"0.0.0.0_80", "0.0.0.0_8080", "127.0.0.1_8080"},
  2807  		},
  2808  		{
  2809  			"gateway with simple and passthrough",
  2810  			&pilot_model.Proxy{},
  2811  			[]config.Config{
  2812  				{
  2813  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.Gateway},
  2814  					Spec: &networking.Gateway{
  2815  						Servers: []*networking.Server{
  2816  							{
  2817  								Port:  &networking.Port{Name: "http", Number: 443, Protocol: "HTTPS"},
  2818  								Hosts: []string{"*.example.com"},
  2819  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  2820  							},
  2821  							{
  2822  								Port:  &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2823  								Hosts: []string{"foo.example.com"},
  2824  							},
  2825  						},
  2826  					},
  2827  				},
  2828  				{
  2829  					Meta: config.Meta{Name: "passthrough-gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  2830  					Spec: &networking.Gateway{
  2831  						Servers: []*networking.Server{
  2832  							{
  2833  								Port:  &networking.Port{Name: "http", Number: 443, Protocol: "HTTPS"},
  2834  								Hosts: []string{"*.example.com"},
  2835  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  2836  							},
  2837  							{
  2838  								Port:  &networking.Port{Name: "tcp", Number: 9443, Protocol: "TLS"},
  2839  								Hosts: []string{"barone.example.com"},
  2840  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_PASSTHROUGH},
  2841  							},
  2842  							{
  2843  								Port:  &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2844  								Hosts: []string{"bar.example.com"},
  2845  							},
  2846  						},
  2847  					},
  2848  				},
  2849  			},
  2850  			[]config.Config{
  2851  				{
  2852  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  2853  					Spec: &networking.VirtualService{
  2854  						Gateways: []string{"testns/passthrough-gateway"},
  2855  						Hosts:    []string{"barone.example.com"},
  2856  						Tls: []*networking.TLSRoute{
  2857  							{
  2858  								Match: []*networking.TLSMatchAttributes{
  2859  									{
  2860  										Port:     9443,
  2861  										SniHosts: []string{"barone.example.com"},
  2862  									},
  2863  								},
  2864  								Route: []*networking.RouteDestination{
  2865  									{
  2866  										Destination: &networking.Destination{
  2867  											Host: "foo.com",
  2868  										},
  2869  									},
  2870  								},
  2871  							},
  2872  						},
  2873  					},
  2874  				},
  2875  			},
  2876  			[]string{"0.0.0.0_443", "0.0.0.0_80", "0.0.0.0_9443"},
  2877  		},
  2878  		{
  2879  			"gateway with multiple http servers",
  2880  			&pilot_model.Proxy{},
  2881  			[]config.Config{
  2882  				{
  2883  					Meta: config.Meta{Name: "gateway1", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  2884  					Spec: &networking.Gateway{
  2885  						Servers: []*networking.Server{
  2886  							{
  2887  								Port:  &networking.Port{Name: "http", Number: 443, Protocol: "HTTPS"},
  2888  								Hosts: []string{"*.example.com"},
  2889  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  2890  							},
  2891  							{
  2892  								Port:  &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2893  								Hosts: []string{"foo.example.com"},
  2894  							},
  2895  						},
  2896  					},
  2897  				},
  2898  				{
  2899  					Meta: config.Meta{Name: "gateway2", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  2900  					Spec: &networking.Gateway{
  2901  						Servers: []*networking.Server{
  2902  							{
  2903  								Port:  &networking.Port{Name: "http", Number: 443, Protocol: "HTTPS"},
  2904  								Hosts: []string{"*.exampleone.com"},
  2905  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  2906  							},
  2907  							{
  2908  								Port:  &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  2909  								Hosts: []string{"bar.example.com"},
  2910  							},
  2911  						},
  2912  					},
  2913  				},
  2914  			},
  2915  			nil,
  2916  			[]string{"0.0.0.0_443", "0.0.0.0_80"},
  2917  		},
  2918  		{
  2919  			"gateway with multiple TLS HTTPS TCP servers",
  2920  			&pilot_model.Proxy{},
  2921  			[]config.Config{
  2922  				{
  2923  					Meta: config.Meta{Name: "gateway1", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  2924  					Spec: &networking.Gateway{
  2925  						Servers: []*networking.Server{
  2926  							{
  2927  								Port:  &networking.Port{Name: "tcp", Number: 443, Protocol: "TLS"},
  2928  								Hosts: []string{"*.example.com"},
  2929  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  2930  							},
  2931  							{
  2932  								Port:  &networking.Port{Name: "tcp", Number: 443, Protocol: "HTTPS"},
  2933  								Hosts: []string{"https.example.com"},
  2934  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  2935  							},
  2936  							{
  2937  								Port:  &networking.Port{Name: "tcp", Number: 9443, Protocol: "TCP"},
  2938  								Hosts: []string{"tcp.example.com"},
  2939  							},
  2940  						},
  2941  					},
  2942  				},
  2943  				{
  2944  					Meta: config.Meta{Name: "gateway2", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  2945  					Spec: &networking.Gateway{
  2946  						Servers: []*networking.Server{
  2947  							{
  2948  								Port:  &networking.Port{Name: "http", Number: 443, Protocol: "HTTPS"},
  2949  								Hosts: []string{"*.exampleone.com"},
  2950  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  2951  							},
  2952  							{
  2953  								Port:  &networking.Port{Name: "tcp", Number: 443, Protocol: "TLS"},
  2954  								Hosts: []string{"*.exampleone.com"},
  2955  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  2956  							},
  2957  						},
  2958  					},
  2959  				},
  2960  			},
  2961  			[]config.Config{
  2962  				{
  2963  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  2964  					Spec: &networking.VirtualService{
  2965  						Gateways: []string{"testns/gateway1"},
  2966  						Hosts:    []string{"tcp.example.com"},
  2967  						Tcp: []*networking.TCPRoute{
  2968  							{
  2969  								Match: []*networking.L4MatchAttributes{
  2970  									{
  2971  										Port: 9443,
  2972  									},
  2973  								},
  2974  								Route: []*networking.RouteDestination{
  2975  									{
  2976  										Destination: &networking.Destination{
  2977  											Host: "foo.com",
  2978  										},
  2979  									},
  2980  								},
  2981  							},
  2982  						},
  2983  					},
  2984  				},
  2985  			},
  2986  			[]string{"0.0.0.0_443", "0.0.0.0_9443"},
  2987  		},
  2988  		{
  2989  			"gateway with multiple TCP/HTTPS servers with bind",
  2990  			&pilot_model.Proxy{},
  2991  			[]config.Config{
  2992  				{
  2993  					Meta: config.Meta{Name: "gateway1", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  2994  					Spec: &networking.Gateway{
  2995  						Servers: []*networking.Server{
  2996  							{
  2997  								Port:  &networking.Port{Name: "tcp", Number: 8000, Protocol: "TCP"},
  2998  								Hosts: []string{"*"},
  2999  								Bind:  "10.0.0.1",
  3000  							},
  3001  						},
  3002  					},
  3003  				},
  3004  				{
  3005  					Meta: config.Meta{Name: "gateway2", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3006  					Spec: &networking.Gateway{
  3007  						Servers: []*networking.Server{
  3008  							{
  3009  								Port:  &networking.Port{Name: "tcp", Number: 8000, Protocol: "TCP"},
  3010  								Hosts: []string{"*"},
  3011  								Bind:  "10.0.0.2",
  3012  							},
  3013  						},
  3014  					},
  3015  				},
  3016  				{
  3017  					Meta: config.Meta{Name: "gateway3", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3018  					Spec: &networking.Gateway{
  3019  						Servers: []*networking.Server{
  3020  							{
  3021  								Port:  &networking.Port{Name: "https", Number: 8000, Protocol: "HTTPS"},
  3022  								Hosts: []string{"*"},
  3023  								Bind:  "10.0.0.3",
  3024  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  3025  							},
  3026  						},
  3027  					},
  3028  				},
  3029  			},
  3030  			[]config.Config{
  3031  				{
  3032  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3033  					Spec: &networking.VirtualService{
  3034  						Gateways: []string{"testns/gateway1"},
  3035  						Hosts:    []string{"*"},
  3036  						Tcp: []*networking.TCPRoute{
  3037  							{
  3038  								Match: []*networking.L4MatchAttributes{
  3039  									{
  3040  										Port: 8000,
  3041  									},
  3042  								},
  3043  								Route: []*networking.RouteDestination{
  3044  									{
  3045  										Destination: &networking.Destination{
  3046  											Host: "foo.com",
  3047  										},
  3048  									},
  3049  								},
  3050  							},
  3051  						},
  3052  					},
  3053  				},
  3054  				{
  3055  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3056  					Spec: &networking.VirtualService{
  3057  						Gateways: []string{"testns/gateway2"},
  3058  						Hosts:    []string{"*"},
  3059  						Tcp: []*networking.TCPRoute{
  3060  							{
  3061  								Match: []*networking.L4MatchAttributes{
  3062  									{
  3063  										Port: 8000,
  3064  									},
  3065  								},
  3066  								Route: []*networking.RouteDestination{
  3067  									{
  3068  										Destination: &networking.Destination{
  3069  											Host: "foo.com",
  3070  										},
  3071  									},
  3072  								},
  3073  							},
  3074  						},
  3075  					},
  3076  				},
  3077  				{
  3078  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3079  					Spec: &networking.VirtualService{
  3080  						Gateways: []string{"testns/gateway3"},
  3081  						Hosts:    []string{"*"},
  3082  						Http: []*networking.HTTPRoute{
  3083  							{
  3084  								Route: []*networking.HTTPRouteDestination{
  3085  									{
  3086  										Destination: &networking.Destination{
  3087  											Host: "grpc.example.org",
  3088  											Port: &networking.PortSelector{
  3089  												Number: 80,
  3090  											},
  3091  										},
  3092  									},
  3093  								},
  3094  							},
  3095  						},
  3096  					},
  3097  				},
  3098  			},
  3099  			[]string{"10.0.0.1_8000", "10.0.0.2_8000", "10.0.0.3_8000"},
  3100  		},
  3101  		{
  3102  			"gateway with HTTPS/GRPC servers with bind",
  3103  			&pilot_model.Proxy{},
  3104  			[]config.Config{
  3105  				{
  3106  					Meta: config.Meta{Name: "gateway1", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3107  					Spec: &networking.Gateway{
  3108  						Servers: []*networking.Server{
  3109  							{
  3110  								Port:  &networking.Port{Name: "https", Number: 443, Protocol: "HTTPS"},
  3111  								Hosts: []string{"*"},
  3112  								Bind:  "10.0.0.1",
  3113  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  3114  							},
  3115  						},
  3116  					},
  3117  				},
  3118  				{
  3119  					Meta: config.Meta{Name: "gateway2", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3120  					Spec: &networking.Gateway{
  3121  						Servers: []*networking.Server{
  3122  							{
  3123  								Port:  &networking.Port{Name: "grpc", Number: 443, Protocol: "GRPC"},
  3124  								Bind:  "10.0.0.2",
  3125  								Hosts: []string{"*"},
  3126  							},
  3127  						},
  3128  					},
  3129  				},
  3130  				{
  3131  					Meta: config.Meta{Name: "gateway3", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3132  					Spec: &networking.Gateway{
  3133  						Servers: []*networking.Server{
  3134  							{
  3135  								Port:  &networking.Port{Name: "grpc", Number: 443, Protocol: "GRPC"},
  3136  								Hosts: []string{"grpc.example.org"},
  3137  							},
  3138  						},
  3139  					},
  3140  				},
  3141  			},
  3142  			[]config.Config{
  3143  				{
  3144  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3145  					Spec: &networking.VirtualService{
  3146  						Gateways: []string{"testns/gateway1"},
  3147  						Hosts:    []string{"*"},
  3148  						Http: []*networking.HTTPRoute{
  3149  							{
  3150  								Route: []*networking.HTTPRouteDestination{
  3151  									{
  3152  										Destination: &networking.Destination{
  3153  											Host: "example.org",
  3154  											Port: &networking.PortSelector{
  3155  												Number: 80,
  3156  											},
  3157  										},
  3158  									},
  3159  								},
  3160  							},
  3161  						},
  3162  					},
  3163  				},
  3164  				{
  3165  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3166  					Spec: &networking.VirtualService{
  3167  						Gateways: []string{"testns/gateway2"},
  3168  						Hosts:    []string{"*"},
  3169  						Http: []*networking.HTTPRoute{
  3170  							{
  3171  								Route: []*networking.HTTPRouteDestination{
  3172  									{
  3173  										Destination: &networking.Destination{
  3174  											Host: "grpc.example.org",
  3175  											Port: &networking.PortSelector{
  3176  												Number: 80,
  3177  											},
  3178  										},
  3179  									},
  3180  								},
  3181  							},
  3182  						},
  3183  					},
  3184  				},
  3185  				{
  3186  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3187  					Spec: &networking.VirtualService{
  3188  						Gateways: []string{"testns/gateway3"},
  3189  						Hosts:    []string{"grpc.example.org"},
  3190  						Http: []*networking.HTTPRoute{
  3191  							{
  3192  								Route: []*networking.HTTPRouteDestination{
  3193  									{
  3194  										Destination: &networking.Destination{
  3195  											Host: "grpc.example.org",
  3196  											Port: &networking.PortSelector{
  3197  												Number: 80,
  3198  											},
  3199  										},
  3200  									},
  3201  								},
  3202  							},
  3203  						},
  3204  					},
  3205  				},
  3206  			},
  3207  			[]string{"10.0.0.1_443", "10.0.0.2_443", "0.0.0.0_443"},
  3208  		},
  3209  		{
  3210  			"gateway with HTTPS/TCP invalid configuration",
  3211  			&pilot_model.Proxy{},
  3212  			[]config.Config{
  3213  				{
  3214  					Meta: config.Meta{Name: "gateway1", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3215  					Spec: &networking.Gateway{
  3216  						Servers: []*networking.Server{
  3217  							{
  3218  								Port:  &networking.Port{Name: "https", Number: 443, Protocol: "HTTPS"},
  3219  								Hosts: []string{"*.1.example.com"},
  3220  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  3221  							},
  3222  							{
  3223  								Port:  &networking.Port{Name: "tcp", Number: 443, Protocol: "TCP"},
  3224  								Hosts: []string{"*.1.example.com"},
  3225  							},
  3226  						},
  3227  					},
  3228  				},
  3229  				{
  3230  					Meta: config.Meta{Name: "gateway2", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3231  					Spec: &networking.Gateway{
  3232  						Servers: []*networking.Server{
  3233  							{
  3234  								Port:  &networking.Port{Name: "https", Number: 443, Protocol: "HTTPS"},
  3235  								Hosts: []string{"*.2.example.com"},
  3236  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  3237  							},
  3238  							{
  3239  								Port:  &networking.Port{Name: "tcp", Number: 443, Protocol: "TCP"},
  3240  								Hosts: []string{"*.2.example.com"},
  3241  							},
  3242  						},
  3243  					},
  3244  				},
  3245  			},
  3246  			[]config.Config{
  3247  				{
  3248  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3249  					Spec: &networking.VirtualService{
  3250  						Gateways: []string{"testns/gateway1"},
  3251  						Hosts:    []string{"*"},
  3252  						Tcp: []*networking.TCPRoute{{
  3253  							Route: []*networking.RouteDestination{{Destination: &networking.Destination{Host: "example.com"}}},
  3254  						}},
  3255  					},
  3256  				},
  3257  				{
  3258  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3259  					Spec: &networking.VirtualService{
  3260  						Gateways: []string{"testns/gateway2"},
  3261  						Hosts:    []string{"*"},
  3262  						Tcp: []*networking.TCPRoute{{
  3263  							Route: []*networking.RouteDestination{{Destination: &networking.Destination{Host: "example.com"}}},
  3264  						}},
  3265  					},
  3266  				},
  3267  			},
  3268  			[]string{"0.0.0.0_443"},
  3269  		},
  3270  		{
  3271  			"gateway with multiple HTTPS servers with bind and same host",
  3272  			&pilot_model.Proxy{},
  3273  			[]config.Config{
  3274  				{
  3275  					Meta: config.Meta{Name: "gateway1", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3276  					Spec: &networking.Gateway{
  3277  						Servers: []*networking.Server{
  3278  							{
  3279  								Port:  &networking.Port{Name: "tcp", Number: 443, Protocol: "HTTPS"},
  3280  								Hosts: []string{"*"},
  3281  								Bind:  "10.0.0.1",
  3282  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  3283  							},
  3284  						},
  3285  					},
  3286  				},
  3287  				{
  3288  					Meta: config.Meta{Name: "gateway2", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3289  					Spec: &networking.Gateway{
  3290  						Servers: []*networking.Server{
  3291  							{
  3292  								Port:  &networking.Port{Name: "tcp", Number: 443, Protocol: "HTTPS"},
  3293  								Hosts: []string{"*"},
  3294  								Bind:  "10.0.0.2",
  3295  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  3296  							},
  3297  						},
  3298  					},
  3299  				},
  3300  			},
  3301  			[]config.Config{
  3302  				{
  3303  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3304  					Spec: &networking.VirtualService{
  3305  						Gateways: []string{"testns/gateway1"},
  3306  						Hosts:    []string{"*"},
  3307  						Tcp: []*networking.TCPRoute{
  3308  							{
  3309  								Match: []*networking.L4MatchAttributes{
  3310  									{
  3311  										Port: 9443,
  3312  									},
  3313  								},
  3314  								Route: []*networking.RouteDestination{
  3315  									{
  3316  										Destination: &networking.Destination{
  3317  											Host: "foo.com",
  3318  										},
  3319  									},
  3320  								},
  3321  							},
  3322  						},
  3323  					},
  3324  				},
  3325  				{
  3326  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3327  					Spec: &networking.VirtualService{
  3328  						Gateways: []string{"testns/gateway2"},
  3329  						Hosts:    []string{"*"},
  3330  						Tcp: []*networking.TCPRoute{
  3331  							{
  3332  								Match: []*networking.L4MatchAttributes{
  3333  									{
  3334  										Port: 9443,
  3335  									},
  3336  								},
  3337  								Route: []*networking.RouteDestination{
  3338  									{
  3339  										Destination: &networking.Destination{
  3340  											Host: "foo.com",
  3341  										},
  3342  									},
  3343  								},
  3344  							},
  3345  						},
  3346  					},
  3347  				},
  3348  			},
  3349  			[]string{"10.0.0.1_443", "10.0.0.2_443"},
  3350  		},
  3351  	}
  3352  
  3353  	for _, tt := range cases {
  3354  		t.Run(tt.name, func(t *testing.T) {
  3355  			Configs := make([]config.Config, 0)
  3356  			Configs = append(Configs, tt.gateways...)
  3357  			Configs = append(Configs, tt.virtualServices...)
  3358  			cg := NewConfigGenTest(t, TestOptions{
  3359  				Configs: Configs,
  3360  			})
  3361  			cg.MemRegistry.WantGetProxyServiceTargets = tt.node.ServiceTargets
  3362  			proxy := cg.SetupProxy(&proxyGateway)
  3363  			if tt.node.Metadata != nil {
  3364  				proxy.Metadata = tt.node.Metadata
  3365  			} else {
  3366  				proxy.Metadata = &proxyGatewayMetadata
  3367  			}
  3368  
  3369  			builder := cg.ConfigGen.buildGatewayListeners(NewListenerBuilder(proxy, cg.PushContext()))
  3370  			listeners := xdstest.ExtractListenerNames(builder.gatewayListeners)
  3371  			sort.Strings(listeners)
  3372  			sort.Strings(tt.expectedListeners)
  3373  			if !reflect.DeepEqual(listeners, tt.expectedListeners) {
  3374  				t.Fatalf("Expected listeners: %v, got: %v\n%v", tt.expectedListeners, listeners, proxyGateway.MergedGateway.MergedServers)
  3375  			}
  3376  			xdstest.ValidateListeners(t, builder.gatewayListeners)
  3377  
  3378  			// gateways bind to port, but exact_balance can still be used
  3379  			for _, l := range builder.gatewayListeners {
  3380  				if l.ConnectionBalanceConfig != nil {
  3381  					t.Fatalf("expected connection balance config to be empty, found %v", l.ConnectionBalanceConfig)
  3382  				}
  3383  			}
  3384  		})
  3385  	}
  3386  }
  3387  
  3388  func TestBuildNameToServiceMapForHttpRoutes(t *testing.T) {
  3389  	virtualServiceSpec := &networking.VirtualService{
  3390  		Hosts: []string{"*"},
  3391  		Http: []*networking.HTTPRoute{
  3392  			{
  3393  				Route: []*networking.HTTPRouteDestination{
  3394  					{
  3395  						Destination: &networking.Destination{
  3396  							Host: "foo.example.org",
  3397  						},
  3398  					},
  3399  					{
  3400  						Destination: &networking.Destination{
  3401  							Host: "bar.example.org",
  3402  						},
  3403  					},
  3404  				},
  3405  				Mirror: &networking.Destination{
  3406  					Host: "baz.example.org",
  3407  				},
  3408  				Mirrors: []*networking.HTTPMirrorPolicy{
  3409  					{
  3410  						Destination: &networking.Destination{
  3411  							Host: "bazs.example.org",
  3412  						},
  3413  					},
  3414  					{
  3415  						Destination: &networking.Destination{
  3416  							Host: "bazs2.example.org",
  3417  						},
  3418  					},
  3419  				},
  3420  			},
  3421  		},
  3422  	}
  3423  	virtualService := config.Config{
  3424  		Meta: config.Meta{
  3425  			GroupVersionKind: gvk.VirtualService,
  3426  			Name:             "virtual-service",
  3427  			Namespace:        "test",
  3428  		},
  3429  		Spec: virtualServiceSpec,
  3430  	}
  3431  
  3432  	fooHostName := host.Name("foo.example.org")
  3433  	fooServiceInTestNamespace := &pilot_model.Service{
  3434  		Hostname: fooHostName,
  3435  		Ports: []*pilot_model.Port{{
  3436  			Name:     "http",
  3437  			Protocol: "HTTP",
  3438  			Port:     80,
  3439  		}},
  3440  		Attributes: pilot_model.ServiceAttributes{
  3441  			Namespace: "test",
  3442  			ExportTo:  sets.New(visibility.Private),
  3443  		},
  3444  	}
  3445  
  3446  	barHostName := host.Name("bar.example.org")
  3447  	barServiceInDefaultNamespace := &pilot_model.Service{
  3448  		Hostname: barHostName,
  3449  		Ports: []*pilot_model.Port{{
  3450  			Name:     "http",
  3451  			Protocol: "HTTP",
  3452  			Port:     8080,
  3453  		}},
  3454  		Attributes: pilot_model.ServiceAttributes{
  3455  			Namespace: "default",
  3456  			ExportTo:  sets.New(visibility.Public),
  3457  		},
  3458  	}
  3459  
  3460  	bazHostName := host.Name("baz.example.org")
  3461  	bazServiceInDefaultNamespace := &pilot_model.Service{
  3462  		Hostname: bazHostName,
  3463  		Ports: []*pilot_model.Port{{
  3464  			Name:     "http",
  3465  			Protocol: "HTTP",
  3466  			Port:     8090,
  3467  		}},
  3468  		Attributes: pilot_model.ServiceAttributes{
  3469  			Namespace: "default",
  3470  			ExportTo:  sets.New(visibility.Private),
  3471  		},
  3472  	}
  3473  
  3474  	bazsHostName := host.Name("bazs.example.org")
  3475  	bazsServiceInDefaultNamespace := &pilot_model.Service{
  3476  		Hostname: bazsHostName,
  3477  		Ports: []*pilot_model.Port{{
  3478  			Name:     "http",
  3479  			Protocol: "HTTP",
  3480  			Port:     8091,
  3481  		}},
  3482  		Attributes: pilot_model.ServiceAttributes{
  3483  			Namespace: "default",
  3484  			ExportTo:  sets.New(visibility.Private),
  3485  		},
  3486  	}
  3487  	bazs2HostName := host.Name("bazs2.example.org")
  3488  	bazs2ServiceInDefaultNamespace := &pilot_model.Service{
  3489  		Hostname: bazs2HostName,
  3490  		Ports: []*pilot_model.Port{{
  3491  			Name:     "http",
  3492  			Protocol: "HTTP",
  3493  			Port:     8092,
  3494  		}},
  3495  		Attributes: pilot_model.ServiceAttributes{
  3496  			Namespace: "default",
  3497  			ExportTo:  sets.New(visibility.Private),
  3498  		},
  3499  	}
  3500  
  3501  	cg := NewConfigGenTest(t, TestOptions{
  3502  		Configs: []config.Config{virtualService},
  3503  		Services: []*pilot_model.Service{
  3504  			fooServiceInTestNamespace, barServiceInDefaultNamespace, bazServiceInDefaultNamespace, bazsServiceInDefaultNamespace, bazs2ServiceInDefaultNamespace,
  3505  		},
  3506  	})
  3507  	proxy := &pilot_model.Proxy{
  3508  		Type:            pilot_model.Router,
  3509  		ConfigNamespace: "test",
  3510  	}
  3511  	proxy = cg.SetupProxy(proxy)
  3512  
  3513  	nameToServiceMap := buildNameToServiceMapForHTTPRoutes(proxy, cg.env.PushContext(), virtualService)
  3514  
  3515  	if len(nameToServiceMap) != 5 {
  3516  		t.Errorf("The length of nameToServiceMap is wrong.")
  3517  	}
  3518  
  3519  	if service, exist := nameToServiceMap[fooHostName]; !exist || service == nil {
  3520  		t.Errorf("The service of %s not found or should be not nil.", fooHostName)
  3521  	} else {
  3522  		if service.Ports[0].Port != 80 {
  3523  			t.Errorf("The port of %s is wrong.", fooHostName)
  3524  		}
  3525  
  3526  		if service.Attributes.Namespace != "test" {
  3527  			t.Errorf("The namespace of %s is wrong.", fooHostName)
  3528  		}
  3529  	}
  3530  
  3531  	if service, exist := nameToServiceMap[barHostName]; !exist || service == nil {
  3532  		t.Errorf("The service of %s not found or should be not nil", barHostName)
  3533  	} else {
  3534  		if service.Ports[0].Port != 8080 {
  3535  			t.Errorf("The port of %s is wrong.", barHostName)
  3536  		}
  3537  
  3538  		if service.Attributes.Namespace != "default" {
  3539  			t.Errorf("The namespace of %s is wrong.", barHostName)
  3540  		}
  3541  	}
  3542  
  3543  	if service, exist := nameToServiceMap[bazHostName]; !exist || service != nil {
  3544  		t.Errorf("The value of hostname %s mapping must be exist and it should be nil.", bazHostName)
  3545  	}
  3546  }
  3547  
  3548  func TestBuildGatewayListenersFilters(t *testing.T) {
  3549  	cases := []struct {
  3550  		name             string
  3551  		configs          []config.Config
  3552  		proxyConfig      *pilot_model.NodeMetaProxyConfig
  3553  		expectedListener listenertest.ListenerTest
  3554  	}{
  3555  		{
  3556  			name: "http server",
  3557  			configs: []config.Config{
  3558  				{
  3559  					Meta: config.Meta{Name: "http-server", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3560  					Spec: &networking.Gateway{
  3561  						Servers: []*networking.Server{
  3562  							{
  3563  								Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  3564  							},
  3565  						},
  3566  					},
  3567  				},
  3568  			},
  3569  			expectedListener: listenertest.ListenerTest{FilterChains: []listenertest.FilterChainTest{
  3570  				{
  3571  					NetworkFilters: []string{
  3572  						wellknown.HTTPConnectionManager,
  3573  					},
  3574  					HTTPFilters: []string{
  3575  						xdsfilters.MxFilterName,
  3576  						xdsfilters.Alpn.GetName(),
  3577  						xdsfilters.Fault.GetName(), xdsfilters.Cors.GetName(), wellknown.Router,
  3578  					},
  3579  				},
  3580  			}},
  3581  		},
  3582  		{
  3583  			name: "passthrough server",
  3584  			configs: []config.Config{
  3585  				{
  3586  					Meta: config.Meta{Name: "passthrough-gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3587  					Spec: &networking.Gateway{
  3588  						Servers: []*networking.Server{
  3589  							{
  3590  								Port:  &networking.Port{Name: "tls", Number: 9443, Protocol: "TLS"},
  3591  								Hosts: []string{"barone.example.com"},
  3592  								Tls:   &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_PASSTHROUGH},
  3593  							},
  3594  						},
  3595  					},
  3596  				},
  3597  				{
  3598  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3599  					Spec: &networking.VirtualService{
  3600  						Gateways: []string{"testns/passthrough-gateway"},
  3601  						Hosts:    []string{"barone.example.com"},
  3602  						Tls: []*networking.TLSRoute{
  3603  							{
  3604  								Match: []*networking.TLSMatchAttributes{
  3605  									{
  3606  										Port:     9443,
  3607  										SniHosts: []string{"barone.example.com"},
  3608  									},
  3609  								},
  3610  								Route: []*networking.RouteDestination{
  3611  									{
  3612  										Destination: &networking.Destination{
  3613  											Host: "foo.com",
  3614  										},
  3615  									},
  3616  								},
  3617  							},
  3618  						},
  3619  					},
  3620  				},
  3621  			},
  3622  			expectedListener: listenertest.ListenerTest{FilterChains: []listenertest.FilterChainTest{
  3623  				{
  3624  					NetworkFilters: []string{
  3625  						wellknown.TCPProxy,
  3626  					},
  3627  					HTTPFilters: []string{},
  3628  					TotalMatch:  true,
  3629  				},
  3630  			}},
  3631  		},
  3632  		{
  3633  			name: "terminated-tls server",
  3634  			configs: []config.Config{
  3635  				{
  3636  					Meta: config.Meta{Name: "terminated-tls-gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3637  					Spec: &networking.Gateway{
  3638  						Servers: []*networking.Server{
  3639  							{
  3640  								Port:  &networking.Port{Name: "tls", Number: 5678, Protocol: "TLS"},
  3641  								Hosts: []string{"barone.example.com"},
  3642  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  3643  							},
  3644  						},
  3645  					},
  3646  				},
  3647  				{
  3648  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3649  					Spec: &networking.VirtualService{
  3650  						Gateways: []string{"testns/terminated-tls-gateway"},
  3651  						Hosts:    []string{"barone.example.com"},
  3652  						Tcp: []*networking.TCPRoute{
  3653  							{
  3654  								Match: []*networking.L4MatchAttributes{
  3655  									{
  3656  										Port: 5678,
  3657  									},
  3658  								},
  3659  								Route: []*networking.RouteDestination{
  3660  									{
  3661  										Destination: &networking.Destination{
  3662  											Host: "foo.com",
  3663  										},
  3664  									},
  3665  								},
  3666  							},
  3667  						},
  3668  					},
  3669  				},
  3670  			},
  3671  			expectedListener: listenertest.ListenerTest{FilterChains: []listenertest.FilterChainTest{
  3672  				{
  3673  					NetworkFilters: []string{
  3674  						wellknown.TCPProxy,
  3675  					},
  3676  					HTTPFilters: []string{},
  3677  					TotalMatch:  true,
  3678  				},
  3679  			}},
  3680  		},
  3681  		{
  3682  			name: "non-http istio-mtls server",
  3683  			configs: []config.Config{
  3684  				{
  3685  					Meta: config.Meta{Name: "non-http-gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3686  					Spec: &networking.Gateway{
  3687  						Servers: []*networking.Server{
  3688  							{
  3689  								Port:  &networking.Port{Name: "mtls", Number: 15443, Protocol: "TLS"},
  3690  								Hosts: []string{"barone.example.com"},
  3691  								Tls:   &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_ISTIO_MUTUAL},
  3692  							},
  3693  						},
  3694  					},
  3695  				},
  3696  				{
  3697  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3698  					Spec: &networking.VirtualService{
  3699  						Gateways: []string{"testns/non-http-gateway"},
  3700  						Hosts:    []string{"barone.example.com"},
  3701  						Tcp: []*networking.TCPRoute{
  3702  							{
  3703  								Match: []*networking.L4MatchAttributes{
  3704  									{
  3705  										Port: 15443,
  3706  									},
  3707  								},
  3708  								Route: []*networking.RouteDestination{
  3709  									{
  3710  										Destination: &networking.Destination{
  3711  											Host: "foo.com",
  3712  										},
  3713  									},
  3714  								},
  3715  							},
  3716  						},
  3717  					},
  3718  				},
  3719  			},
  3720  			expectedListener: listenertest.ListenerTest{FilterChains: []listenertest.FilterChainTest{
  3721  				{
  3722  					NetworkFilters: []string{
  3723  						xdsfilters.TCPListenerMx.GetName(),
  3724  						wellknown.TCPProxy,
  3725  					},
  3726  					HTTPFilters: []string{},
  3727  					TotalMatch:  true,
  3728  				},
  3729  			}},
  3730  		},
  3731  		{
  3732  			name: "http and tcp istio-mtls server",
  3733  			configs: []config.Config{
  3734  				{
  3735  					Meta: config.Meta{Name: "gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3736  					Spec: &networking.Gateway{
  3737  						Servers: []*networking.Server{
  3738  							{
  3739  								Port:  &networking.Port{Name: "mtls", Number: 15443, Protocol: "HTTPS"},
  3740  								Hosts: []string{"www.example.com"},
  3741  								Tls:   &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_ISTIO_MUTUAL},
  3742  							},
  3743  							{
  3744  								Port:  &networking.Port{Name: "mtls", Number: 15443, Protocol: "TLS"},
  3745  								Hosts: []string{"tcp.example.com"},
  3746  								Tls:   &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_ISTIO_MUTUAL},
  3747  							},
  3748  						},
  3749  					},
  3750  				},
  3751  				{
  3752  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3753  					Spec: &networking.VirtualService{
  3754  						Gateways: []string{"testns/gateway"},
  3755  						Hosts:    []string{"www.example.com"},
  3756  						Http: []*networking.HTTPRoute{
  3757  							{
  3758  								Match: []*networking.HTTPMatchRequest{
  3759  									{
  3760  										Port: 15443,
  3761  									},
  3762  								},
  3763  								Route: []*networking.HTTPRouteDestination{
  3764  									{
  3765  										Destination: &networking.Destination{
  3766  											Host: "http.com",
  3767  										},
  3768  									},
  3769  								},
  3770  							},
  3771  						},
  3772  					},
  3773  				},
  3774  				{
  3775  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3776  					Spec: &networking.VirtualService{
  3777  						Gateways: []string{"testns/gateway"},
  3778  						Hosts:    []string{"tcp.example.com"},
  3779  						Tcp: []*networking.TCPRoute{
  3780  							{
  3781  								Match: []*networking.L4MatchAttributes{
  3782  									{
  3783  										Port: 15443,
  3784  									},
  3785  								},
  3786  								Route: []*networking.RouteDestination{
  3787  									{
  3788  										Destination: &networking.Destination{
  3789  											Host: "tcp.com",
  3790  										},
  3791  									},
  3792  								},
  3793  							},
  3794  						},
  3795  					},
  3796  				},
  3797  			},
  3798  			expectedListener: listenertest.ListenerTest{
  3799  				TotalMatch: true,
  3800  				FilterChains: []listenertest.FilterChainTest{
  3801  					{
  3802  						TotalMatch: true, // there must be only 1 `istio_authn` network filter
  3803  						NetworkFilters: []string{
  3804  							wellknown.HTTPConnectionManager,
  3805  						},
  3806  						HTTPFilters: []string{
  3807  							xdsfilters.MxFilterName,
  3808  							xdsfilters.GrpcStats.GetName(),
  3809  							xdsfilters.Alpn.GetName(),
  3810  							xdsfilters.Fault.GetName(), xdsfilters.Cors.GetName(), wellknown.Router,
  3811  						},
  3812  					},
  3813  					{
  3814  						TotalMatch: true, // there must be only 1 `istio_authn` network filter
  3815  						NetworkFilters: []string{
  3816  							xdsfilters.TCPListenerMx.GetName(),
  3817  							wellknown.TCPProxy,
  3818  						},
  3819  						HTTPFilters: []string{},
  3820  					},
  3821  				},
  3822  			},
  3823  		},
  3824  		{
  3825  			name: "http server with proxy proto",
  3826  			configs: []config.Config{
  3827  				{
  3828  					Meta: config.Meta{Name: "http-server", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3829  					Spec: &networking.Gateway{
  3830  						Servers: []*networking.Server{
  3831  							{
  3832  								Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"},
  3833  							},
  3834  						},
  3835  					},
  3836  				},
  3837  			},
  3838  			proxyConfig: &pilot_model.NodeMetaProxyConfig{
  3839  				GatewayTopology: &meshconfig.Topology{ProxyProtocol: &meshconfig.Topology_ProxyProtocolConfiguration{}},
  3840  			},
  3841  			expectedListener: listenertest.ListenerTest{
  3842  				FilterChains: []listenertest.FilterChainTest{
  3843  					{
  3844  						NetworkFilters: []string{
  3845  							wellknown.HTTPConnectionManager,
  3846  						},
  3847  						HTTPFilters: []string{
  3848  							xdsfilters.MxFilterName,
  3849  							wellknown.HTTPGRPCStats,
  3850  							xdsfilters.Alpn.GetName(),
  3851  							xdsfilters.Fault.GetName(), xdsfilters.Cors.GetName(), wellknown.Router,
  3852  						},
  3853  						TotalMatch: true,
  3854  					},
  3855  				},
  3856  				Filters: []string{wellknown.ProxyProtocol},
  3857  			},
  3858  		},
  3859  		{
  3860  			name: "terminated-tls server with proxy proto",
  3861  			configs: []config.Config{
  3862  				{
  3863  					Meta: config.Meta{Name: "terminated-tls-gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3864  					Spec: &networking.Gateway{
  3865  						Servers: []*networking.Server{
  3866  							{
  3867  								Port:  &networking.Port{Name: "tls", Number: 5678, Protocol: "TLS"},
  3868  								Hosts: []string{"barone.example.com"},
  3869  								Tls:   &networking.ServerTLSSettings{CredentialName: "test", Mode: networking.ServerTLSSettings_SIMPLE},
  3870  							},
  3871  						},
  3872  					},
  3873  				},
  3874  				{
  3875  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3876  					Spec: &networking.VirtualService{
  3877  						Gateways: []string{"testns/terminated-tls-gateway"},
  3878  						Hosts:    []string{"barone.example.com"},
  3879  						Tcp: []*networking.TCPRoute{
  3880  							{
  3881  								Match: []*networking.L4MatchAttributes{
  3882  									{
  3883  										Port: 5678,
  3884  									},
  3885  								},
  3886  								Route: []*networking.RouteDestination{
  3887  									{
  3888  										Destination: &networking.Destination{
  3889  											Host: "foo.com",
  3890  										},
  3891  									},
  3892  								},
  3893  							},
  3894  						},
  3895  					},
  3896  				},
  3897  			},
  3898  			proxyConfig: &pilot_model.NodeMetaProxyConfig{
  3899  				GatewayTopology: &meshconfig.Topology{ProxyProtocol: &meshconfig.Topology_ProxyProtocolConfiguration{}},
  3900  			},
  3901  			expectedListener: listenertest.ListenerTest{
  3902  				FilterChains: []listenertest.FilterChainTest{
  3903  					{
  3904  						NetworkFilters: []string{
  3905  							wellknown.TCPProxy,
  3906  						},
  3907  						HTTPFilters: []string{},
  3908  						TotalMatch:  true,
  3909  					},
  3910  				},
  3911  				Filters: []string{wellknown.ProxyProtocol},
  3912  			},
  3913  		},
  3914  		{
  3915  			name: "TCP RBAC and Stats",
  3916  			configs: []config.Config{
  3917  				{
  3918  					Meta: config.Meta{Name: "gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3919  					Spec: &networking.Gateway{
  3920  						Servers: []*networking.Server{
  3921  							{
  3922  								Port:  &networking.Port{Name: "tcp", Number: 100, Protocol: "TCP"},
  3923  								Hosts: []string{"www.example.com"},
  3924  							},
  3925  						},
  3926  					},
  3927  				},
  3928  				{
  3929  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3930  					Spec: &networking.VirtualService{
  3931  						Gateways: []string{"testns/gateway"},
  3932  						Hosts:    []string{"www.example.com"},
  3933  						Tcp: []*networking.TCPRoute{
  3934  							{
  3935  								Route: []*networking.RouteDestination{
  3936  									{
  3937  										Destination: &networking.Destination{
  3938  											Host: "http.com",
  3939  										},
  3940  									},
  3941  								},
  3942  							},
  3943  						},
  3944  					},
  3945  				},
  3946  				{
  3947  					Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.AuthorizationPolicy},
  3948  					Spec: &security.AuthorizationPolicy{},
  3949  				},
  3950  				{
  3951  					Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.Telemetry},
  3952  					Spec: &telemetry.Telemetry{
  3953  						Metrics: []*telemetry.Metrics{{Providers: []*telemetry.ProviderRef{{Name: "prometheus"}}}},
  3954  					},
  3955  				},
  3956  			},
  3957  			expectedListener: listenertest.ListenerTest{
  3958  				TotalMatch: true,
  3959  				FilterChains: []listenertest.FilterChainTest{
  3960  					{
  3961  						TotalMatch: true,
  3962  						NetworkFilters: []string{
  3963  							wellknown.RoleBasedAccessControl,
  3964  							xds.StatsFilterName,
  3965  							wellknown.TCPProxy,
  3966  						},
  3967  					},
  3968  				},
  3969  			},
  3970  		},
  3971  		{
  3972  			name: "mTLS, RBAC, WASM, and Stats",
  3973  			configs: []config.Config{
  3974  				{
  3975  					Meta: config.Meta{Name: "gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  3976  					Spec: &networking.Gateway{
  3977  						Servers: []*networking.Server{
  3978  							{
  3979  								Port:  &networking.Port{Name: "tcp", Number: 100, Protocol: "TCP"},
  3980  								Tls:   &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_ISTIO_MUTUAL},
  3981  								Hosts: []string{"www.example.com"},
  3982  							},
  3983  						},
  3984  					},
  3985  				},
  3986  				{
  3987  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  3988  					Spec: &networking.VirtualService{
  3989  						Gateways: []string{"testns/gateway"},
  3990  						Hosts:    []string{"www.example.com"},
  3991  						Tcp: []*networking.TCPRoute{
  3992  							{
  3993  								Route: []*networking.RouteDestination{
  3994  									{
  3995  										Destination: &networking.Destination{
  3996  											Host: "http.com",
  3997  										},
  3998  									},
  3999  								},
  4000  							},
  4001  						},
  4002  					},
  4003  				},
  4004  				{
  4005  					Meta: config.Meta{Name: "wasm-authz", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin},
  4006  					Spec: &extensions.WasmPlugin{
  4007  						Phase: extensions.PluginPhase_AUTHZ,
  4008  						Type:  extensions.PluginType_NETWORK,
  4009  					},
  4010  				},
  4011  				{
  4012  					Meta: config.Meta{Name: "wasm-authn", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin},
  4013  					Spec: &extensions.WasmPlugin{
  4014  						Phase: extensions.PluginPhase_AUTHN,
  4015  						Type:  extensions.PluginType_NETWORK,
  4016  					},
  4017  				},
  4018  				{
  4019  					Meta: config.Meta{Name: "wasm-stats", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin},
  4020  					Spec: &extensions.WasmPlugin{
  4021  						Phase: extensions.PluginPhase_STATS,
  4022  						Type:  extensions.PluginType_NETWORK,
  4023  					},
  4024  				},
  4025  				{
  4026  					Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.AuthorizationPolicy},
  4027  					Spec: &security.AuthorizationPolicy{},
  4028  				},
  4029  				{
  4030  					Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.AuthorizationPolicy},
  4031  					Spec: &security.AuthorizationPolicy{
  4032  						Action:       security.AuthorizationPolicy_CUSTOM,
  4033  						ActionDetail: &security.AuthorizationPolicy_Provider{Provider: &security.AuthorizationPolicy_ExtensionProvider{Name: "extauthz"}},
  4034  					},
  4035  				},
  4036  				{
  4037  					Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.Telemetry},
  4038  					Spec: &telemetry.Telemetry{
  4039  						Metrics: []*telemetry.Metrics{{Providers: []*telemetry.ProviderRef{{Name: "prometheus"}}}},
  4040  					},
  4041  				},
  4042  			},
  4043  			expectedListener: listenertest.ListenerTest{
  4044  				TotalMatch: true,
  4045  				FilterChains: []listenertest.FilterChainTest{
  4046  					{
  4047  						TotalMatch: true,
  4048  						NetworkFilters: []string{
  4049  							xdsfilters.MxFilterName,
  4050  							// Ext auth makes 2 filters
  4051  							wellknown.RoleBasedAccessControl,
  4052  							wellknown.ExternalAuthorization,
  4053  							"extenstions.istio.io/wasmplugin/istio-system.wasm-authn",
  4054  							"extenstions.istio.io/wasmplugin/istio-system.wasm-authz",
  4055  							wellknown.RoleBasedAccessControl,
  4056  							"extenstions.istio.io/wasmplugin/istio-system.wasm-stats",
  4057  							xds.StatsFilterName,
  4058  							wellknown.TCPProxy,
  4059  						},
  4060  					},
  4061  				},
  4062  			},
  4063  		},
  4064  		{
  4065  			name: "HTTP RBAC, WASM, and Stats",
  4066  			configs: []config.Config{
  4067  				{
  4068  					Meta: config.Meta{Name: "gateway", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  4069  					Spec: &networking.Gateway{
  4070  						Servers: []*networking.Server{
  4071  							{
  4072  								Port:  &networking.Port{Name: "http", Number: 200, Protocol: "HTTP"},
  4073  								Hosts: []string{"www.example.com"},
  4074  							},
  4075  						},
  4076  					},
  4077  				},
  4078  				{
  4079  					Meta: config.Meta{Name: "wasm-network-authz", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin},
  4080  					Spec: &extensions.WasmPlugin{
  4081  						Phase: extensions.PluginPhase_AUTHZ,
  4082  						Type:  extensions.PluginType_NETWORK,
  4083  					},
  4084  				},
  4085  				{
  4086  					Meta: config.Meta{Name: "wasm-network-authn", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin},
  4087  					Spec: &extensions.WasmPlugin{
  4088  						Phase: extensions.PluginPhase_AUTHN,
  4089  						Type:  extensions.PluginType_NETWORK,
  4090  					},
  4091  				},
  4092  				{
  4093  					Meta: config.Meta{Name: "wasm-network-stats", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin},
  4094  					Spec: &extensions.WasmPlugin{
  4095  						Phase: extensions.PluginPhase_STATS,
  4096  						Type:  extensions.PluginType_NETWORK,
  4097  					},
  4098  				},
  4099  				{
  4100  					Meta: config.Meta{Name: "wasm-authz", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin},
  4101  					Spec: &extensions.WasmPlugin{
  4102  						Phase: extensions.PluginPhase_AUTHZ,
  4103  					},
  4104  				},
  4105  				{
  4106  					Meta: config.Meta{Name: "wasm-authn", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin},
  4107  					Spec: &extensions.WasmPlugin{
  4108  						Phase: extensions.PluginPhase_AUTHN,
  4109  					},
  4110  				},
  4111  				{
  4112  					Meta: config.Meta{Name: "wasm-stats", Namespace: "istio-system", GroupVersionKind: gvk.WasmPlugin},
  4113  					Spec: &extensions.WasmPlugin{
  4114  						Phase: extensions.PluginPhase_STATS,
  4115  					},
  4116  				},
  4117  				{
  4118  					Meta: config.Meta{Name: uuid.NewString(), Namespace: uuid.NewString(), GroupVersionKind: gvk.VirtualService},
  4119  					Spec: &networking.VirtualService{
  4120  						Gateways: []string{"testns/gateway"},
  4121  						Hosts:    []string{"www.example.com"},
  4122  						Http: []*networking.HTTPRoute{
  4123  							{
  4124  								Route: []*networking.HTTPRouteDestination{
  4125  									{
  4126  										Destination: &networking.Destination{
  4127  											Host: "http.com",
  4128  										},
  4129  									},
  4130  								},
  4131  							},
  4132  						},
  4133  					},
  4134  				},
  4135  				{
  4136  					Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.AuthorizationPolicy},
  4137  					Spec: &security.AuthorizationPolicy{
  4138  						Action:       security.AuthorizationPolicy_CUSTOM,
  4139  						ActionDetail: &security.AuthorizationPolicy_Provider{Provider: &security.AuthorizationPolicy_ExtensionProvider{Name: "extauthz"}},
  4140  					},
  4141  				},
  4142  				{
  4143  					Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.AuthorizationPolicy},
  4144  					Spec: &security.AuthorizationPolicy{},
  4145  				},
  4146  				{
  4147  					Meta: config.Meta{Name: uuid.NewString(), Namespace: "istio-system", GroupVersionKind: gvk.Telemetry},
  4148  					Spec: &telemetry.Telemetry{
  4149  						Metrics: []*telemetry.Metrics{{Providers: []*telemetry.ProviderRef{{Name: "prometheus"}}}},
  4150  					},
  4151  				},
  4152  			},
  4153  			expectedListener: listenertest.ListenerTest{
  4154  				TotalMatch: true,
  4155  				FilterChains: []listenertest.FilterChainTest{
  4156  					{
  4157  						TotalMatch: true,
  4158  						NetworkFilters: []string{
  4159  							"extenstions.istio.io/wasmplugin/istio-system.wasm-network-authn",
  4160  							"extenstions.istio.io/wasmplugin/istio-system.wasm-network-authz",
  4161  							"extenstions.istio.io/wasmplugin/istio-system.wasm-network-stats",
  4162  							wellknown.HTTPConnectionManager,
  4163  						},
  4164  						HTTPFilters: []string{
  4165  							xdsfilters.MxFilterName,
  4166  							// Ext auth makes 2 filters
  4167  							wellknown.HTTPRoleBasedAccessControl,
  4168  							wellknown.HTTPExternalAuthorization,
  4169  							"extenstions.istio.io/wasmplugin/istio-system.wasm-authn",
  4170  							"extenstions.istio.io/wasmplugin/istio-system.wasm-authz",
  4171  							wellknown.HTTPRoleBasedAccessControl,
  4172  							"extenstions.istio.io/wasmplugin/istio-system.wasm-stats",
  4173  							wellknown.HTTPGRPCStats,
  4174  							xdsfilters.Alpn.Name,
  4175  							xdsfilters.Fault.Name,
  4176  							xdsfilters.Cors.Name,
  4177  							xds.StatsFilterName,
  4178  							wellknown.Router,
  4179  						},
  4180  					},
  4181  				},
  4182  			},
  4183  		},
  4184  	}
  4185  	for _, tt := range cases {
  4186  		t.Run(tt.name, func(t *testing.T) {
  4187  			mc := mesh.DefaultMeshConfig()
  4188  			mc.ExtensionProviders = append(mc.ExtensionProviders, &meshconfig.MeshConfig_ExtensionProvider{
  4189  				Name: "extauthz",
  4190  				Provider: &meshconfig.MeshConfig_ExtensionProvider_EnvoyExtAuthzGrpc{
  4191  					EnvoyExtAuthzGrpc: &meshconfig.MeshConfig_ExtensionProvider_EnvoyExternalAuthorizationGrpcProvider{
  4192  						Service: "foo/example.local",
  4193  						Port:    1234,
  4194  					},
  4195  				},
  4196  			})
  4197  
  4198  			cg := NewConfigGenTest(t, TestOptions{
  4199  				Configs:    tt.configs,
  4200  				MeshConfig: mc,
  4201  			})
  4202  			cg.PushContext().ServiceIndex.HostnameAndNamespace = map[host.Name]map[string]*pilot_model.Service{
  4203  				"example.local": {
  4204  					"foo": &pilot_model.Service{
  4205  						Hostname: "example.local",
  4206  					},
  4207  				},
  4208  			}
  4209  			proxy := cg.SetupProxy(&proxyGateway)
  4210  			metadata := proxyGatewayMetadata
  4211  			metadata.ProxyConfig = tt.proxyConfig
  4212  			proxy.Metadata = &metadata
  4213  
  4214  			lb := NewListenerBuilder(proxy, cg.PushContext())
  4215  			builder := cg.ConfigGen.buildGatewayListeners(lb)
  4216  			listenertest.VerifyListeners(t, builder.gatewayListeners, listenertest.ListenersTest{
  4217  				Listener: tt.expectedListener,
  4218  			})
  4219  		})
  4220  	}
  4221  }
  4222  
  4223  func TestGatewayFilterChainSNIOverlap(t *testing.T) {
  4224  	cases := []struct {
  4225  		name            string
  4226  		gateways        []config.Config
  4227  		virtualServices []config.Config
  4228  	}{
  4229  		{
  4230  			name: "no sni overlap",
  4231  			gateways: []config.Config{
  4232  				{
  4233  					Meta: config.Meta{Name: "gw", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  4234  					Spec: &networking.Gateway{
  4235  						Servers: []*networking.Server{
  4236  							{
  4237  								Port:  &networking.Port{Name: "example", Number: 443, Protocol: "TLS"},
  4238  								Hosts: []string{"example.com"},
  4239  								Tls:   &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_PASSTHROUGH},
  4240  							},
  4241  						},
  4242  					},
  4243  				},
  4244  			},
  4245  			virtualServices: []config.Config{
  4246  				{
  4247  					Meta: config.Meta{Name: "example", Namespace: "testns", GroupVersionKind: gvk.VirtualService},
  4248  					Spec: &networking.VirtualService{
  4249  						Gateways: []string{"testns/gw"},
  4250  						Hosts:    []string{"example.com"},
  4251  						Tls: []*networking.TLSRoute{
  4252  							{
  4253  								Match: []*networking.TLSMatchAttributes{
  4254  									{
  4255  										SniHosts: []string{"example.com"},
  4256  									},
  4257  								},
  4258  								Route: []*networking.RouteDestination{
  4259  									{
  4260  										Destination: &networking.Destination{
  4261  											Host: "example",
  4262  										},
  4263  									},
  4264  								},
  4265  							},
  4266  						},
  4267  					},
  4268  				},
  4269  			},
  4270  		},
  4271  		{
  4272  			name: "sni overlap in one gateway",
  4273  			gateways: []config.Config{
  4274  				{
  4275  					Meta: config.Meta{Name: "gw", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  4276  					Spec: &networking.Gateway{
  4277  						Servers: []*networking.Server{
  4278  							{
  4279  								Port:  &networking.Port{Name: "example", Number: 443, Protocol: "TLS"},
  4280  								Hosts: []string{"example.com"},
  4281  								Tls:   &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_PASSTHROUGH},
  4282  							},
  4283  							{
  4284  								Port:  &networking.Port{Name: "wildcard-tls", Number: 443, Protocol: "HTTPS"},
  4285  								Hosts: []string{"*"},
  4286  								Tls:   &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_PASSTHROUGH},
  4287  							},
  4288  						},
  4289  					},
  4290  				},
  4291  			},
  4292  			virtualServices: []config.Config{
  4293  				{
  4294  					Meta: config.Meta{Name: "example", Namespace: "testns", GroupVersionKind: gvk.VirtualService},
  4295  					Spec: &networking.VirtualService{
  4296  						Gateways: []string{"testns/gw"},
  4297  						Hosts:    []string{"example.com"},
  4298  						Tls: []*networking.TLSRoute{
  4299  							{
  4300  								Match: []*networking.TLSMatchAttributes{
  4301  									{
  4302  										SniHosts: []string{"example.com"},
  4303  									},
  4304  								},
  4305  								Route: []*networking.RouteDestination{
  4306  									{
  4307  										Destination: &networking.Destination{
  4308  											Host: "example",
  4309  										},
  4310  									},
  4311  								},
  4312  							},
  4313  						},
  4314  					},
  4315  				},
  4316  			},
  4317  		},
  4318  		{
  4319  			name: "sni overlap in two gateways",
  4320  			gateways: []config.Config{
  4321  				{
  4322  					Meta: config.Meta{Name: "gw1", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  4323  					Spec: &networking.Gateway{
  4324  						Servers: []*networking.Server{
  4325  							{
  4326  								Port:  &networking.Port{Name: "example", Number: 443, Protocol: "TLS"},
  4327  								Hosts: []string{"example.com"},
  4328  								Tls:   &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_PASSTHROUGH},
  4329  							},
  4330  						},
  4331  					},
  4332  				},
  4333  				{
  4334  					Meta: config.Meta{Name: "gw2", Namespace: "testns", GroupVersionKind: gvk.Gateway},
  4335  					Spec: &networking.Gateway{
  4336  						Servers: []*networking.Server{
  4337  							{
  4338  								Port:  &networking.Port{Name: "wildcard-tls", Number: 443, Protocol: "HTTPS"},
  4339  								Hosts: []string{"*"},
  4340  								Tls:   &networking.ServerTLSSettings{Mode: networking.ServerTLSSettings_PASSTHROUGH},
  4341  							},
  4342  						},
  4343  					},
  4344  				},
  4345  			},
  4346  			virtualServices: []config.Config{
  4347  				{
  4348  					Meta: config.Meta{Name: "example", Namespace: "testns", GroupVersionKind: gvk.VirtualService},
  4349  					Spec: &networking.VirtualService{
  4350  						Gateways: []string{"testns/gw2"},
  4351  						Hosts:    []string{"example.com"},
  4352  						Tls: []*networking.TLSRoute{
  4353  							{
  4354  								Match: []*networking.TLSMatchAttributes{
  4355  									{
  4356  										SniHosts: []string{"example.com"},
  4357  									},
  4358  								},
  4359  								Route: []*networking.RouteDestination{
  4360  									{
  4361  										Destination: &networking.Destination{
  4362  											Host: "example",
  4363  										},
  4364  									},
  4365  								},
  4366  							},
  4367  						},
  4368  					},
  4369  				},
  4370  			},
  4371  		},
  4372  	}
  4373  
  4374  	for _, tt := range cases {
  4375  		t.Run(tt.name, func(t *testing.T) {
  4376  			configs := make([]config.Config, 0)
  4377  			configs = append(configs, tt.gateways...)
  4378  			configs = append(configs, tt.virtualServices...)
  4379  			cg := NewConfigGenTest(t, TestOptions{
  4380  				Configs: configs,
  4381  			})
  4382  			proxy := cg.SetupProxy(&proxyGateway)
  4383  			proxy.Metadata = &proxyGatewayMetadata
  4384  
  4385  			builder := cg.ConfigGen.buildGatewayListeners(NewListenerBuilder(proxy, cg.PushContext()))
  4386  			xdstest.ValidateListeners(t, builder.gatewayListeners)
  4387  		})
  4388  	}
  4389  }
  4390  
  4391  func TestGatewayHCMInternalAddressConfig(t *testing.T) {
  4392  	cg := NewConfigGenTest(t, TestOptions{})
  4393  	proxy := &pilot_model.Proxy{
  4394  		Type:            pilot_model.Router,
  4395  		ConfigNamespace: "test",
  4396  	}
  4397  	proxy = cg.SetupProxy(proxy)
  4398  	test.SetForTest(t, &features.EnableHCMInternalNetworks, true)
  4399  	push := cg.PushContext()
  4400  	cases := []struct {
  4401  		name           string
  4402  		networks       *meshconfig.MeshNetworks
  4403  		expectedconfig *hcm.HttpConnectionManager_InternalAddressConfig
  4404  	}{
  4405  		{
  4406  			name:           "nil networks",
  4407  			expectedconfig: nil,
  4408  		},
  4409  		{
  4410  			name:           "empty networks",
  4411  			networks:       &meshconfig.MeshNetworks{},
  4412  			expectedconfig: nil,
  4413  		},
  4414  		{
  4415  			name: "networks populated",
  4416  			networks: &meshconfig.MeshNetworks{
  4417  				Networks: map[string]*meshconfig.Network{
  4418  					"default": {
  4419  						Endpoints: []*meshconfig.Network_NetworkEndpoints{
  4420  							{
  4421  								Ne: &meshconfig.Network_NetworkEndpoints_FromCidr{
  4422  									FromCidr: "192.168.0.0/16",
  4423  								},
  4424  							},
  4425  							{
  4426  								Ne: &meshconfig.Network_NetworkEndpoints_FromCidr{
  4427  									FromCidr: "172.16.0.0/12",
  4428  								},
  4429  							},
  4430  						},
  4431  					},
  4432  				},
  4433  			},
  4434  			expectedconfig: &hcm.HttpConnectionManager_InternalAddressConfig{
  4435  				CidrRanges: []*core.CidrRange{
  4436  					{
  4437  						AddressPrefix: "192.168.0.0",
  4438  						PrefixLen:     &wrappers.UInt32Value{Value: 16},
  4439  					},
  4440  					{
  4441  						AddressPrefix: "172.16.0.0",
  4442  						PrefixLen:     &wrappers.UInt32Value{Value: 12},
  4443  					},
  4444  				},
  4445  			},
  4446  		},
  4447  	}
  4448  	for _, tt := range cases {
  4449  		t.Run(tt.name, func(t *testing.T) {
  4450  			push.Networks = tt.networks
  4451  			httpConnManager := buildGatewayConnectionManager(&meshconfig.ProxyConfig{}, proxy, false, push)
  4452  			if !reflect.DeepEqual(tt.expectedconfig, httpConnManager.InternalAddressConfig) {
  4453  				t.Errorf("unexpected internal address config, expected: %v, got :%v", tt.expectedconfig, httpConnManager.InternalAddressConfig)
  4454  			}
  4455  		})
  4456  	}
  4457  }