Repository: kumahq/kuma
Pull request #12157 (2024-12-03 15:43:00)

fix(meshpassthrough): generate separate filter chain  when ip/cidr fo… (backport of #12054)
Automatic cherry-pick of #12054 for branch release-2.9

Generated by [action](https://github.com/kumahq/kuma/actions/runs/12143142100)

cherry-picked commit a5d4745e6dbc1fbc2db00ba119617dddbb294ca2


Patch:
diff --git a/deployments/charts/kuma/crds/kuma.io_meshpassthroughs.yaml b/deployments/charts/kuma/crds/kuma.io_meshpassthroughs.yaml
index 9f5822b55..4c2d96eac 100644
--- a/deployments/charts/kuma/crds/kuma.io_meshpassthroughs.yaml
+++ b/deployments/charts/kuma/crds/kuma.io_meshpassthroughs.yaml
@@ -58,6 +58,7 @@ spec:
                         port:
                           description: Port defines the port to which a user makes
                             a request.
+                          format: int32
                           type: integer
                         protocol:
                           default: tcp
diff --git a/docs/generated/openapi.yaml b/docs/generated/openapi.yaml
index 8fdbcf1a0..0391de25b 100644
--- a/docs/generated/openapi.yaml
+++ b/docs/generated/openapi.yaml
@@ -7387,6 +7387,7 @@ components:
                     properties:
                       port:
                         description: Port defines the port to which a user makes a request.
+                        format: int32
                         type: integer
                       protocol:
                         default: tcp
diff --git a/docs/generated/raw/crds/kuma.io_meshpassthroughs.yaml b/docs/generated/raw/crds/kuma.io_meshpassthroughs.yaml
index 9f5822b55..4c2d96eac 100644
--- a/docs/generated/raw/crds/kuma.io_meshpassthroughs.yaml
+++ b/docs/generated/raw/crds/kuma.io_meshpassthroughs.yaml
@@ -58,6 +58,7 @@ spec:
                         port:
                           description: Port defines the port to which a user makes
                             a request.
+                          format: int32
                           type: integer
                         protocol:
                           default: tcp
diff --git a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/meshpassthrough.go b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/meshpassthrough.go
index 518fc9ebd..640b6b3ce 100644
--- a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/meshpassthrough.go
+++ b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/meshpassthrough.go
@@ -47,7 +47,7 @@ type Match struct {
 	// Value for the specified Type.
 	Value string `json:"value,omitempty"`
 	// Port defines the port to which a user makes a request.
-	Port *int `json:"port,omitempty"`
+	Port *uint32 `json:"port,omitempty"`
 	// Protocol defines the communication protocol. Possible values: `tcp`, `tls`, `grpc`, `http`, `http2`.
 	// +kubebuilder:default=tcp
 	Protocol ProtocolType `json:"protocol,omitempty"`
diff --git a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/schema.yaml b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/schema.yaml
index fb94ec022..f7d132c1e 100644
--- a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/schema.yaml
+++ b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/schema.yaml
@@ -30,6 +30,7 @@ properties:
               properties:
                 port:
                   description: Port defines the port to which a user makes a request.
+                  format: int32
                   type: integer
                 protocol:
                   default: tcp
diff --git a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/validator.go b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/validator.go
index 232fbe82f..65df4b243 100644
--- a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/validator.go
+++ b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/validator.go
@@ -44,21 +44,21 @@ func validateTop(targetRef *common_api.TargetRef) validators.ValidationError {
 
 func validateDefault(conf Conf) validators.ValidationError {
 	var verr validators.ValidationError
-	portAndProtocol := map[int]ProtocolType{}
+	portAndProtocol := map[uint32]ProtocolType{}
 	type portProtocol struct {
-		port     int
+		port     uint32
 		protocol ProtocolType
 	}
 	uniqueDomains := map[portProtocol]map[string]bool{}
 	for i, match := range conf.AppendMatch {
-		if match.Port != nil && pointer.Deref[int](match.Port) == 0 || pointer.Deref[int](match.Port) > math.MaxUint16 {
+		if match.Port != nil && pointer.Deref[uint32](match.Port) == 0 || pointer.Deref[uint32](match.Port) > math.MaxUint16 {
 			verr.AddViolationAt(validators.RootedAt("appendMatch").Index(i).Field("port"), "port must be a valid (1-65535)")
 		}
 		if match.Port != nil {
-			if value, found := portAndProtocol[pointer.Deref[int](match.Port)]; found && value != match.Protocol && slices.Contains(notAllowedProtocolsOnTheSamePort, match.Protocol) {
+			if value, found := portAndProtocol[pointer.Deref[uint32](match.Port)]; found && value != match.Protocol && slices.Contains(notAllowedProtocolsOnTheSamePort, match.Protocol) {
 				verr.AddViolationAt(validators.RootedAt("appendMatch").Index(i).Field("port"), fmt.Sprintf("using the same port in multiple matches requires the same protocol for the following protocols: %v", notAllowedProtocolsOnTheSamePort))
 			} else {
-				portAndProtocol[pointer.Deref[int](match.Port)] = match.Protocol
+				portAndProtocol[pointer.Deref[uint32](match.Port)] = match.Protocol
 			}
 			key := portProtocol{
 				port:     *match.Port,
@@ -95,6 +95,9 @@ func validateDefault(conf Conf) validators.ValidationError {
 			if wildcardPartialPrefixPattern.MatchString(match.Value) {
 				verr.AddViolationAt(validators.RootedAt("appendMatch").Index(i).Field("value"), "provided DNS has incorrect value, partial wildcard is currently not supported")
 			}
+			if match.Port == nil && strings.HasPrefix(match.Value, "*") && slices.Contains(notAllowedProtocolsOnTheSamePort, match.Protocol) {
+				verr.AddViolationAt(validators.RootedAt("appendMatch").Index(i).Field("port"), "wildcard domains doesn't work for all ports and layer 7 protocol")
+			}
 			if !strings.HasPrefix(match.Value, "*") {
 				isValid := govalidator.IsDNSName(match.Value)
 				if !isValid {
diff --git a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/zz_generated.deepcopy.go b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/zz_generated.deepcopy.go
index c2d7994a3..bf22526f8 100644
--- a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/zz_generated.deepcopy.go
@@ -40,7 +40,7 @@ func (in *Match) DeepCopyInto(out *Match) {
 	*out = *in
 	if in.Port != nil {
 		in, out := &in.Port, &out.Port
-		*out = new(int)
+		*out = new(uint32)
 		**out = **in
 	}
 }
diff --git a/pkg/plugins/policies/meshpassthrough/k8s/crd/kuma.io_meshpassthroughs.yaml b/pkg/plugins/policies/meshpassthrough/k8s/crd/kuma.io_meshpassthroughs.yaml
index 9f5822b55..4c2d96eac 100644
--- a/pkg/plugins/policies/meshpassthrough/k8s/crd/kuma.io_meshpassthroughs.yaml
+++ b/pkg/plugins/policies/meshpassthrough/k8s/crd/kuma.io_meshpassthroughs.yaml
@@ -58,6 +58,7 @@ spec:
                         port:
                           description: Port defines the port to which a user makes
                             a request.
+                          format: int32
                           type: integer
                         protocol:
                           default: tcp
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/xds/configurer.go b/pkg/plugins/policies/meshpassthrough/plugin/xds/configurer.go
index 84c7ddf80..573c6f3fa 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/xds/configurer.go
+++ b/pkg/plugins/policies/meshpassthrough/plugin/xds/configurer.go
@@ -1,6 +1,8 @@
 package xds
 
 import (
+	"slices"
+
 	envoy_listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
 
 	core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
@@ -20,18 +22,18 @@ type Configurer struct {
 
 func (c Configurer) Configure(ipv4 *envoy_listener.Listener, ipv6 *envoy_listener.Listener, rs *core_xds.ResourceSet) error {
 	clustersAccumulator := map[string]core_mesh.Protocol{}
-	orderedMatchers, err := GetOrderedMatchers(c.Conf)
+	filterChainMatches, err := GetOrderedMatchers(c.Conf)
 	if err != nil {
 		return err
 	}
 
-	if hasIPv4Matches(orderedMatchers) {
-		if err := c.configureListener(orderedMatchers, ipv4, clustersAccumulator, false); err != nil {
+	if hasIPv4Matches(filterChainMatches) {
+		if err := c.configureListener(filterChainMatches, ipv4, clustersAccumulator, false); err != nil {
 			return err
 		}
 	}
-	if hasIPv6Matches(orderedMatchers) {
-		if err := c.configureListener(orderedMatchers, ipv6, clustersAccumulator, true); err != nil {
+	if hasIPv6Matches(filterChainMatches) {
+		if err := c.configureListener(filterChainMatches, ipv6, clustersAccumulator, true); err != nil {
 			return err
 		}
 	}
@@ -51,7 +53,7 @@ func (c Configurer) Configure(ipv4 *envoy_listener.Listener, ipv6 *envoy_listene
 }
 
 func (c Configurer) configureListener(
-	orderedMatchers []FilterChainMatcher,
+	orderedFilterChainMatches []FilterChainMatch,
 	listener *envoy_listener.Listener,
 	clustersAccumulator map[string]core_mesh.Protocol,
 	isIPv6 bool,
@@ -61,11 +63,13 @@ func (c Configurer) configureListener(
 	}
 	// remove default filter chain provided by `transparent_proxy_generator`
 	listener.FilterChains = []*envoy_listener.FilterChain{}
-	for _, matcher := range orderedMatchers {
+	for _, matcher := range orderedFilterChainMatches {
 		configurer := FilterChainConfigurer{
 			APIVersion: c.APIVersion,
 			Protocol:   matcher.Protocol,
 			Port:       matcher.Port,
+			MatchType:  matcher.MatchType,
+			MatchValue: matcher.Value,
 			Routes:     matcher.Routes,
 			IsIPv6:     isIPv6,
 		}
@@ -106,29 +110,19 @@ func (c Configurer) configureListenerFilter(listener *envoy_listener.Listener) e
 	return err
 }
 
-func hasIPv4Matches(orderedMatchers []FilterChainMatcher) bool {
+func hasIPv4Matches(orderedMatchers []FilterChainMatch) bool {
 	for _, matcher := range orderedMatchers {
-		for _, route := range matcher.Routes {
-			if route.MatchType == Domain ||
-				route.MatchType == WildcardDomain ||
-				route.MatchType == CIDR ||
-				route.MatchType == IP {
-				return true
-			}
+		if slices.Contains([]MatchType{Domain, WildcardDomain, CIDR, IP}, matcher.MatchType) {
+			return true
 		}
 	}
 	return false
 }
 
-func hasIPv6Matches(orderedMatchers []FilterChainMatcher) bool {
+func hasIPv6Matches(orderedMatchers []FilterChainMatch) bool {
 	for _, matcher := range orderedMatchers {
-		for _, route := range matcher.Routes {
-			if route.MatchType == Domain ||
-				route.MatchType == WildcardDomain ||
-				route.MatchType == CIDRV6 ||
-				route.MatchType == IPV6 {
-				return true
-			}
+		if slices.Contains([]MatchType{Domain, WildcardDomain, CIDRV6, IPV6}, matcher.MatchType) {
+			return true
 		}
 	}
 	return false
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/xds/listeners_filter_chain.go b/pkg/plugins/policies/meshpassthrough/plugin/xds/listeners_filter_chain.go
index cee191e2c..9deaaf1c4 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/xds/listeners_filter_chain.go
+++ b/pkg/plugins/policies/meshpassthrough/plugin/xds/listeners_filter_chain.go
@@ -20,7 +20,9 @@ type FilterChainConfigurer struct {
 	APIVersion core_xds.APIVersion
 	Protocol   core_mesh.Protocol
 	Port       uint32
-	Routes     []Route
+	MatchType  MatchType
+	MatchValue string
+	Routes     []Route // should be set only for http and domains/wildcard
 	IsIPv6     bool
 }
 
@@ -37,92 +39,125 @@ func (c FilterChainConfigurer) Configure(listener *envoy_listener.Listener, clus
 func (c FilterChainConfigurer) addFilterChainConfiguration(listener *envoy_listener.Listener, clustersAccumulator map[string]core_mesh.Protocol) error {
 	switch c.Protocol {
 	case core_mesh.ProtocolTCP:
-		for _, route := range c.Routes {
-			if err := c.configureTcpFilterChain(listener, route, clustersAccumulator); err != nil {
-				return err
-			}
+		if err := c.configureTcpFilterChain(listener, clustersAccumulator); err != nil {
+			return err
 		}
 	case core_mesh.ProtocolTLS:
-		for _, route := range c.Routes {
-			if err := c.configureTlsFilterChain(listener, route, clustersAccumulator); err != nil {
-				return err
-			}
+		if err := c.configureTlsFilterChain(listener, clustersAccumulator); err != nil {
+			return err
 		}
 	default:
-		chainName := FilterChainName(
-			string(c.Protocol),
-			c.Protocol,
-			c.Port,
-		)
-		routeBuilder := xds_routes.NewRouteConfigurationBuilder(c.APIVersion, chainName)
-		for _, route := range c.Routes {
-			if c.IsIPv6 && route.MatchType == IP {
-				continue
+		switch c.MatchType {
+		case Domain, WildcardDomain:
+			routeFn := func(routeBuilder *xds_routes.RouteConfigurationBuilder, clustersAccumulator map[string]core_mesh.Protocol) {
+				for _, route := range c.Routes {
+					if c.IsIPv6 && route.MatchType == IP {
+						continue
+					}
+					if !c.IsIPv6 && route.MatchType == IPV6 {
+						continue
+					}
+					switch route.MatchType {
+					case Domain, WildcardDomain, IP, IPV6:
+						domains := []string{route.Value}
+						// based on the RFC, the host header might include a port, so we add another entry with the port defined
+						if c.Port != 0 && (route.MatchType == IP || route.MatchType == Domain || route.MatchType == WildcardDomain) {
+							domains = append(domains, fmt.Sprintf("%s:%d", route.Value, c.Port))
+						}
+						if c.Port != 0 && route.MatchType == IPV6 {
+							domains = append(domains, fmt.Sprintf("[%s]", route.Value), fmt.Sprintf("[%s]:%d", route.Value, c.Port))
+						}
+						if c.Port == 0 && route.MatchType == Domain {
+							// we want to match all domains
+							domains = append(domains, fmt.Sprintf("%s:*", route.Value))
+						}
+
+						clusterName := ClusterName(route.Value, c.Protocol, c.Port)
+						routeBuilder.Configure(xds_routes.VirtualHost(xds_virtual_hosts.NewVirtualHostBuilder(c.APIVersion, route.Value).
+							Configure(
+								xds_virtual_hosts.BasicRoute(clusterName),
+								xds_virtual_hosts.DomainNames(domains...),
+							)))
+						clustersAccumulator[clusterName] = c.Protocol
+					}
+				}
+				routeBuilder.Configure(xds_routes.VirtualHost(xds_virtual_hosts.NewVirtualHostBuilder(c.APIVersion, "no_match").
+					Configure(
+						xds_virtual_hosts.DirectResponseRoute(http.StatusServiceUnavailable, NoMatchMsg),
+					)))
 			}
-			if !c.IsIPv6 && route.MatchType == IPV6 {
-				continue
+			filterChainName := FilterChainName(string(c.Protocol), c.Protocol, c.Port)
+			if err := c.configureHttpFilterChain(listener, routeFn, clustersAccumulator, filterChainName); err != nil {
+				return err
 			}
-			switch route.MatchType {
-			case Domain, WildcardDomain, IP, IPV6:
-				domains := []string{route.Value}
-				// based on the RFC, the host header might include a port, so we add another entry with the port defined
-				if route.MatchType == IP {
-					domains = append(domains, fmt.Sprintf("%s:%d", route.Value, c.Port))
-				}
-				if route.MatchType == IPV6 {
-					domains = append(domains, fmt.Sprintf("[%s]", route.Value), fmt.Sprintf("[%s]:%d", route.Value, c.Port))
-				}
-				clusterName := ClusterName(route, c.Protocol, c.Port)
-				routeBuilder.Configure(xds_routes.VirtualHost(xds_virtual_hosts.NewVirtualHostBuilder(c.APIVersion, route.Value).
+		default:
+			routeFn := func(routeBuilder *xds_routes.RouteConfigurationBuilder, clustersAccumulator map[string]core_mesh.Protocol) {
+				clusterName := ClusterName(c.MatchValue, c.Protocol, c.Port)
+				routeBuilder.Configure(xds_routes.VirtualHost(xds_virtual_hosts.NewVirtualHostBuilder(c.APIVersion, c.MatchValue).
 					Configure(
-						xds_virtual_hosts.BasicRoute(ClusterName(route, c.Protocol, c.Port)),
-						xds_virtual_hosts.DomainNames(domains...),
+						xds_virtual_hosts.BasicRoute(clusterName),
+						xds_virtual_hosts.DomainNames("*"),
 					)))
 				clustersAccumulator[clusterName] = c.Protocol
 			}
+			filterChainName := FilterChainName(c.MatchValue, c.Protocol, c.Port)
+			if err := c.configureHttpFilterChain(listener, routeFn, clustersAccumulator, filterChainName); err != nil {
+				return err
+			}
 		}
+	}
+	return nil
+}
 
-		routeBuilder.Configure(xds_routes.VirtualHost(xds_virtual_hosts.NewVirtualHostBuilder(c.APIVersion, "no_match").
-			Configure(
-				xds_virtual_hosts.DirectResponseRoute(http.StatusServiceUnavailable, NoMatchMsg),
-			)))
-
-		filterChainBuilder := xds_listeners.NewFilterChainBuilder(c.APIVersion, chainName).
-			Configure(xds_listeners.MatchApplicationProtocols("http/1.1", "h2c")).
-			Configure(xds_listeners.MatchTransportProtocol("raw_buffer")).
-			Configure(xds_listeners.HttpConnectionManager(chainName, false)).
-			Configure(xds_listeners.HttpStaticRoute(routeBuilder))
-
-		switch c.Protocol {
-		case core_mesh.ProtocolGRPC:
-			filterChainBuilder.Configure(xds_listeners.GrpcStats())
-		}
+func (c FilterChainConfigurer) configureHttpFilterChain(
+	listener *envoy_listener.Listener,
+	routeFn func(routeBuilder *xds_routes.RouteConfigurationBuilder, clustersAccumulator map[string]core_mesh.Protocol),
+	clustersAccumulator map[string]core_mesh.Protocol,
+	filterChainName string,
+) error {
+	if c.IsIPv6 && (c.MatchType == IP || c.MatchType == CIDR) {
+		return nil
+	}
+	if !c.IsIPv6 && (c.MatchType == IPV6 || c.MatchType == CIDRV6) {
+		return nil
+	}
+	routeBuilder := xds_routes.NewRouteConfigurationBuilder(c.APIVersion, filterChainName)
+	routeFn(routeBuilder, clustersAccumulator)
+	filterChainBuilder := xds_listeners.NewFilterChainBuilder(c.APIVersion, filterChainName).
+		Configure(xds_listeners.MatchApplicationProtocols("http/1.1", "h2c")).
+		Configure(xds_listeners.MatchTransportProtocol("raw_buffer")).
+		Configure(xds_listeners.HttpConnectionManager(filterChainName, false)).
+		Configure(xds_listeners.HttpStaticRoute(routeBuilder))
+	c.configureAddressMatch(filterChainBuilder)
+	if c.Port != 0 {
+		filterChainBuilder.
+			Configure(xds_listeners.MatchDestiantionPort(c.Port))
+	}
 
-		filterChain, err := filterChainBuilder.Build()
-		if err != nil {
-			return err
-		}
-		listener.FilterChains = append(listener.FilterChains, filterChain.(*envoy_listener.FilterChain))
+	filterChain, err := filterChainBuilder.Build()
+	if err != nil {
+		return err
 	}
+	listener.FilterChains = append(listener.FilterChains, filterChain.(*envoy_listener.FilterChain))
 	return nil
 }
 
-func (c FilterChainConfigurer) configureTcpFilterChain(listener *envoy_listener.Listener, route Route, clustersAccumulator map[string]core_mesh.Protocol) error {
-	if c.IsIPv6 && (route.MatchType == IP || route.MatchType == CIDR) {
+func (c FilterChainConfigurer) configureTcpFilterChain(listener *envoy_listener.Listener, clustersAccumulator map[string]core_mesh.Protocol) error {
+	if c.IsIPv6 && (c.MatchType == IP || c.MatchType == CIDR) {
 		return nil
 	}
-	if !c.IsIPv6 && (route.MatchType == IPV6 || route.MatchType == CIDRV6) {
+	if !c.IsIPv6 && (c.MatchType == IPV6 || c.MatchType == CIDRV6) {
 		return nil
 	}
-	chainName := FilterChainName(route.Value, core_mesh.ProtocolTCP, c.Port)
-	clusterName := ClusterName(route, core_mesh.ProtocolTCP, c.Port)
+	chainName := FilterChainName(c.MatchValue, core_mesh.ProtocolTCP, c.Port)
+	clusterName := ClusterName(c.MatchValue, core_mesh.ProtocolTCP, c.Port)
 	split := plugins_xds.NewSplitBuilder().
 		WithClusterName(clusterName).
 		Build()
 	filterChainBuilder := xds_listeners.NewFilterChainBuilder(c.APIVersion, chainName).
 		Configure(xds_listeners.TCPProxy(clusterName, split)).
 		Configure(xds_listeners.MatchTransportProtocol("raw_buffer"))
-	c.configureAddressMatch(route, filterChainBuilder)
+	c.configureAddressMatch(filterChainBuilder)
 	if c.Port != 0 {
 		filterChainBuilder.
 			Configure(xds_listeners.MatchDestiantionPort(c.Port))
@@ -137,26 +172,26 @@ func (c FilterChainConfigurer) configureTcpFilterChain(listener *envoy_listener.
 	return nil
 }
 
-func (c FilterChainConfigurer) configureTlsFilterChain(listener *envoy_listener.Listener, route Route, clustersAccumulator map[string]core_mesh.Protocol) error {
-	if c.IsIPv6 && (route.MatchType == IP || route.MatchType == CIDR) {
+func (c FilterChainConfigurer) configureTlsFilterChain(listener *envoy_listener.Listener, clustersAccumulator map[string]core_mesh.Protocol) error {
+	if c.IsIPv6 && (c.MatchType == IP || c.MatchType == CIDR) {
 		return nil
 	}
-	if !c.IsIPv6 && (route.MatchType == IPV6 || route.MatchType == CIDRV6) {
+	if !c.IsIPv6 && (c.MatchType == IPV6 || c.MatchType == CIDRV6) {
 		return nil
 	}
-	chainName := FilterChainName(route.Value, core_mesh.ProtocolTLS, c.Port)
-	clusterName := ClusterName(route, core_mesh.ProtocolTLS, c.Port)
+	chainName := FilterChainName(c.MatchValue, core_mesh.ProtocolTLS, c.Port)
+	clusterName := ClusterName(c.MatchValue, core_mesh.ProtocolTLS, c.Port)
 	split := plugins_xds.NewSplitBuilder().
 		WithClusterName(clusterName).
 		Build()
 	filterChainBuilder := xds_listeners.NewFilterChainBuilder(c.APIVersion, chainName).
 		Configure(xds_listeners.TCPProxy(clusterName, split)).
 		Configure(xds_listeners.MatchTransportProtocol("tls"))
-	c.configureAddressMatch(route, filterChainBuilder)
-	switch route.MatchType {
+	c.configureAddressMatch(filterChainBuilder)
+	switch c.MatchType {
 	case WildcardDomain, Domain:
 		filterChainBuilder.
-			Configure(xds_listeners.MatchServerNames(route.Value))
+			Configure(xds_listeners.MatchServerNames(c.MatchValue))
 	}
 	if c.Port != 0 {
 		filterChainBuilder.
@@ -172,21 +207,21 @@ func (c FilterChainConfigurer) configureTlsFilterChain(listener *envoy_listener.
 	return nil
 }
 
-func (c FilterChainConfigurer) configureAddressMatch(route Route, builder *xds_listeners.FilterChainBuilder) {
-	switch route.MatchType {
+func (c FilterChainConfigurer) configureAddressMatch(builder *xds_listeners.FilterChainBuilder) {
+	switch c.MatchType {
 	case CIDR, CIDRV6:
-		ip, mask := getIpAndMask(route.Value)
+		ip, mask := getIpAndMask(c.MatchValue)
 		builder.Configure(xds_listeners.MatchDestiantionAddressesRange(ip, mask))
 	case IP, IPV6:
-		builder.Configure(xds_listeners.MatchDestiantionAddress(route.Value, c.IsIPv6))
+		builder.Configure(xds_listeners.MatchDestiantionAddress(c.MatchValue, c.IsIPv6))
 	}
 }
 
-func ClusterName(route Route, protocol core_mesh.Protocol, port uint32) string {
+func ClusterName(matchValue string, protocol core_mesh.Protocol, port uint32) string {
 	if port == 0 {
-		return fmt.Sprintf("meshpassthrough_%s_*", route.Value)
+		return fmt.Sprintf("meshpassthrough_%s_%s_*", protocol, matchValue)
 	}
-	return fmt.Sprintf("meshpassthrough_%s_%d", route.Value, port)
+	return fmt.Sprintf("meshpassthrough_%s_%s_%d", protocol, matchValue, port)
 }
 
 func FilterChainName(name string, protocol core_mesh.Protocol, port uint32) string {
@@ -194,8 +229,8 @@ func FilterChainName(name string, protocol core_mesh.Protocol, port uint32) stri
 	if port != 0 {
 		displayPort = fmt.Sprintf("%d", port)
 	}
-	if protocol == core_mesh.ProtocolTCP || protocol == core_mesh.ProtocolTLS {
+	if name == string(protocol) {
 		return fmt.Sprintf("meshpassthrough_%s_%s", name, displayPort)
 	}
-	return fmt.Sprintf("meshpassthrough_http_%s", displayPort)
+	return fmt.Sprintf("meshpassthrough_%s_%s_%s", protocol, name, displayPort)
 }
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/xds/order.go b/pkg/plugins/policies/meshpassthrough/plugin/xds/order.go
index b78137c9f..8dfea41c1 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/xds/order.go
+++ b/pkg/plugins/policies/meshpassthrough/plugin/xds/order.go
@@ -1,7 +1,9 @@
 package xds
 
 import (
+	"maps"
 	"net"
+	"slices"
 	"sort"
 	"strings"
 
@@ -11,109 +13,183 @@ import (
 
 	core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
 	api "github.com/kumahq/kuma/pkg/plugins/policies/meshpassthrough/api/v1alpha1"
+	"github.com/kumahq/kuma/pkg/util/pointer"
 )
 
 type MatchType int
 
 const (
-	Domain MatchType = iota + 1
-	WildcardDomain
-	IP
-	IPV6
+	WildcardDomain MatchType = iota + 1
+	Domain
 	CIDR
 	CIDRV6
+	IP
+	IPV6
 )
 
+var protocolOrder = map[core_mesh.Protocol]int{
+	core_mesh.ProtocolTLS:   0,
+	core_mesh.ProtocolTCP:   1,
+	core_mesh.ProtocolHTTP:  2,
+	core_mesh.ProtocolHTTP2: 3,
+	core_mesh.ProtocolGRPC:  4,
+}
+
 type Route struct {
 	Value     string
 	MatchType MatchType
 }
 
 type Matcher struct {
-	Protocol core_mesh.Protocol
-	Port     uint32
+	Protocol  core_mesh.Protocol
+	Port      uint32
+	MatchType MatchType
+	Value     string
 }
 
-type FilterChainMatcher struct {
-	Protocol core_mesh.Protocol
-	Port     uint32
-	Routes   []Route
+type FilterChainMatch struct {
+	Protocol  core_mesh.Protocol
+	Port      uint32
+	MatchType MatchType
+	Value     string
+	Routes    []Route
 }
 
-func GetOrderedMatchers(conf api.Conf) ([]FilterChainMatcher, error) {
-	matchers := map[Matcher]map[Route]bool{}
-	portProtocols := map[int]map[core_mesh.Protocol]bool{}
+func GetOrderedMatchers(conf api.Conf) ([]FilterChainMatch, error) {
+	matcherWithRoutes := map[Matcher]map[Route]bool{}
+	portProtocols := map[uint32]map[core_mesh.Protocol]bool{}
 	for _, match := range conf.AppendMatch {
-		var matchType MatchType
-		switch match.Type {
-		case api.MatchType("Domain"):
-			if strings.HasPrefix(match.Value, "*") {
-				matchType = WildcardDomain
-			} else {
-				matchType = Domain
-			}
-		case api.MatchType("IP"):
-			if govalidator.IsIPv6(match.Value) {
-				matchType = IPV6
-			} else {
-				matchType = IP
-			}
-		case api.MatchType("CIDR"):
-			split := strings.Split(match.Value, "/")
-			if govalidator.IsIPv6(split[0]) {
-				matchType = CIDRV6
-			} else {
-				matchType = CIDR
-			}
-		}
-		port := 0
-		if match.Port != nil {
-			port = *match.Port
-		}
+		port := pointer.DerefOr[uint32](match.Port, 0)
 		protocol := core_mesh.ParseProtocol(string(match.Protocol))
+		matchType, isWildcardDomain := getMatchType(match, protocol)
+		matcher := Matcher{
+			Protocol:  protocol,
+			Port:      port,
+			MatchType: matchType,
+		}
 		if _, found := portProtocols[port]; !found {
 			portProtocols[port] = map[core_mesh.Protocol]bool{protocol: true}
 		} else {
 			portProtocols[port][protocol] = true
 		}
-		matcher := Matcher{
-			Protocol: protocol,
-			Port:     uint32(port),
-		}
-		route := Route{
-			Value:     match.Value,
-			MatchType: matchType,
-		}
-		if _, found := matchers[matcher]; found {
-			matchers[matcher][route] = true
-		} else {
-			matchers[matcher] = map[Route]bool{
-				route: true,
+		switch protocol {
+		case core_mesh.ProtocolHTTP, core_mesh.ProtocolHTTP2, core_mesh.ProtocolGRPC:
+			// when there are domains we want to create VirtualHosts with Domain match
+			if matchType == Domain {
+				if isWildcardDomain {
+					matchType = WildcardDomain
+				}
+				route := Route{
+					Value:     match.Value,
+					MatchType: matchType,
+				}
+				if _, found := matcherWithRoutes[matcher]; found {
+					matcherWithRoutes[matcher][route] = true
+				} else {
+					matcherWithRoutes[matcher] = map[Route]bool{
+						route: true,
+					}
+				}
+			} else {
+				matcher.Value = match.Value
+				// there should be no existing matcher if there is ip/cidr
+				matcherWithRoutes[matcher] = map[Route]bool{}
 			}
+		default:
+			matcher.Value = match.Value
+			matcherWithRoutes[matcher] = map[Route]bool{}
 		}
 	}
-	filterChainMatchers := []FilterChainMatcher{}
-	for matcher, routesMap := range matchers {
-		routes := []Route{}
-		for route := range routesMap {
-			routes = append(routes, route)
-		}
-		orderRoutes(routes)
-		filterChainMatcher := FilterChainMatcher{
-			Protocol: matcher.Protocol,
-			Port:     matcher.Port,
-			Routes:   routes,
-		}
-		filterChainMatchers = append(filterChainMatchers, filterChainMatcher)
-	}
+	// we cannot differentiate between HTTP, HTTP/2, and gRPC on the same port.
 	if err := validatePortAndProtocol(portProtocols); err != nil {
 		return nil, err
 	}
-	orderValues(filterChainMatchers)
+	// Envoy first checks the port when performing matching. If there is a matcher for a specific port
+	// and one rule to match all ports alongside another for a specific port,
+	// it might select the matcher for the specific port but fail to find a corresponding filter chain.
+	// To avoid this issue, we also generate specific port matchers for rules intended to match all ports.
+	matcherWithRoutesAndAdditionalPorts := map[Matcher]map[Route]bool{}
+	for matcher, routes := range matcherWithRoutes {
+		if _, found := matcherWithRoutesAndAdditionalPorts[matcher]; found {
+			for route := range routes {
+				matcherWithRoutesAndAdditionalPorts[matcher][Route{
+					Value:     route.Value,
+					MatchType: route.MatchType,
+				}] = true
+			}
+		} else {
+			matcherWithRoutesAndAdditionalPorts[matcher] = maps.Clone(routes)
+		}
+		if matcher.Port == 0 {
+			for port := range portProtocols {
+				if port == 0 {
+					continue
+				}
+				additionalMatcher := Matcher{
+					Protocol:  matcher.Protocol,
+					Port:      port,
+					MatchType: matcher.MatchType,
+					Value:     matcher.Value,
+				}
+				if _, found := matcherWithRoutesAndAdditionalPorts[additionalMatcher]; found {
+					for route := range routes {
+						matcherWithRoutesAndAdditionalPorts[additionalMatcher][Route{
+							Value:     route.Value,
+							MatchType: route.MatchType,
+						}] = true
+					}
+				} else {
+					matcherWithRoutesAndAdditionalPorts[additionalMatcher] = maps.Clone(routes)
+				}
+			}
+		}
+	}
+	filterChainMatchers := []FilterChainMatch{}
+	for matcher, routes := range matcherWithRoutesAndAdditionalPorts {
+		filterChainMatchers = append(filterChainMatchers,
+			FilterChainMatch{
+				Protocol:  matcher.Protocol,
+				Port:      matcher.Port,
+				MatchType: matcher.MatchType,
+				Value:     matcher.Value,
+				Routes:    getOrderedRoutes(routes),
+			})
+	}
+	orderMatchers(filterChainMatchers)
 	return filterChainMatchers, nil
 }
 
-func validatePortAndProtocol(portProtocols map[int]map[core_mesh.Protocol]bool) error {
+func getMatchType(match api.Match, protocol core_mesh.Protocol) (MatchType, bool) {
+	var matchType MatchType
+	isWildcardDomain := false
+	switch match.Type {
+	case api.MatchType("Domain"):
+		matchType = Domain
+		// for L7 protocol we want to aggregate routes
+		if strings.HasPrefix(match.Value, "*") && slices.Contains([]core_mesh.Protocol{core_mesh.ProtocolGRPC, core_mesh.ProtocolHTTP, core_mesh.ProtocolHTTP2}, protocol) {
+			matchType = Domain
+			isWildcardDomain = true
+		} else if strings.HasPrefix(match.Value, "*") {
+			matchType = WildcardDomain
+		}
+	case api.MatchType("IP"):
+		if govalidator.IsIPv6(match.Value) {
+			matchType = IPV6
+		} else {
+			matchType = IP
+		}
+	case api.MatchType("CIDR"):
+		split := strings.Split(match.Value, "/")
+		if govalidator.IsIPv6(split[0]) {
+			matchType = CIDRV6
+		} else {
+			matchType = CIDR
+		}
+	}
+	return matchType, isWildcardDomain
+}
+
+func validatePortAndProtocol(portProtocols map[uint32]map[core_mesh.Protocol]bool) error {
 	var errs error
 	for port, protocols := range portProtocols {
 		var counter int
@@ -133,30 +209,45 @@ func validatePortAndProtocol(portProtocols map[int]map[core_mesh.Protocol]bool)
 	return errs
 }
 
-func orderRoutes(routes []Route) {
+func getOrderedRoutes(routesMap map[Route]bool) []Route {
+	routes := []Route{}
+	for route := range routesMap {
+		routes = append(routes, route)
+	}
 	sort.SliceStable(routes, func(i, j int) bool {
 		if routes[i].MatchType != routes[j].MatchType {
-			return routes[i].MatchType < routes[j].MatchType
+			return routes[i].MatchType > routes[j].MatchType
 		}
 		if routes[i].MatchType == Domain || routes[i].MatchType == WildcardDomain {
 			return sortDomains(routes[i].Value, routes[j].Value)
 		}
-		if routes[i].MatchType == CIDR || routes[i].MatchType == CIDRV6 {
-			_, prefixI := getIpAndMask(routes[i].Value)
-			_, prefixJ := getIpAndMask(routes[j].Value)
-			return prefixI > prefixJ
-		}
 
 		return routes[i].MatchType < routes[j].MatchType
 	})
+	return routes
 }
 
-func orderValues(matchers []FilterChainMatcher) {
+func orderMatchers(matchers []FilterChainMatch) {
 	sort.SliceStable(matchers, func(i, j int) bool {
-		if matchers[i].Protocol != matchers[j].Protocol {
-			return matchers[i].Protocol > matchers[j].Protocol
+		if protocolOrder[matchers[i].Protocol] != protocolOrder[matchers[j].Protocol] {
+			return protocolOrder[matchers[i].Protocol] < protocolOrder[matchers[j].Protocol]
 		}
-		return matchers[i].Port > matchers[j].Port
+		if matchers[i].MatchType != matchers[j].MatchType {
+			return matchers[i].MatchType > matchers[j].MatchType
+		}
+		if matchers[i].Port != matchers[j].Port {
+			return matchers[i].Port > matchers[j].Port
+		}
+		if matchers[i].MatchType == Domain || matchers[i].MatchType == WildcardDomain {
+			return sortDomains(matchers[i].Value, matchers[j].Value)
+		}
+		if matchers[i].MatchType == CIDR || matchers[i].MatchType == CIDRV6 {
+			_, prefixI := getIpAndMask(matchers[i].Value)
+			_, prefixJ := getIpAndMask(matchers[j].Value)
+			return prefixI > prefixJ
+		}
+
+		return len(matchers[i].Routes) > len(matchers[j].Routes)
 	})
 }
 


Test patch:
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml
index c348e28df..142d22885 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml
@@ -3952,6 +3952,7 @@ spec:
                         port:
                           description: Port defines the port to which a user makes
                             a request.
+                          format: int32
                           type: integer
                         protocol:
                           default: tcp
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.gateway-api-present.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.gateway-api-present.yaml
index 05fe9d1ed..b4b1b9a81 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.gateway-api-present.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.gateway-api-present.yaml
@@ -3952,6 +3952,7 @@ spec:
                         port:
                           description: Port defines the port to which a user makes
                             a request.
+                          format: int32
                           type: integer
                         protocol:
                           default: tcp
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-set.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-set.yaml
index 2071b32e8..b8cbf7d3b 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-set.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-set.yaml
@@ -3972,6 +3972,7 @@ spec:
                         port:
                           description: Port defines the port to which a user makes
                             a request.
+                          format: int32
                           type: integer
                         protocol:
                           default: tcp
diff --git a/app/kumactl/cmd/install/testdata/install-crds.all.golden.yaml b/app/kumactl/cmd/install/testdata/install-crds.all.golden.yaml
index 43739bcc2..0aa2176ea 100644
--- a/app/kumactl/cmd/install/testdata/install-crds.all.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-crds.all.golden.yaml
@@ -5508,6 +5508,7 @@ spec:
                         port:
                           description: Port defines the port to which a user makes
                             a request.
+                          format: int32
                           type: integer
                         protocol:
                           default: tcp
diff --git a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/testdata/full-invalid.input.yaml b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/testdata/full-invalid.input.yaml
index 6573a9a5a..e055916ba 100644
--- a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/testdata/full-invalid.input.yaml
+++ b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/testdata/full-invalid.input.yaml
@@ -42,3 +42,6 @@ default:
     value: google.com
     port: 10000
     protocol: http
+  - type: Domain
+    value: "*.example.com"
+    protocol: http
diff --git a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/testdata/full-invalid.output.yaml b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/testdata/full-invalid.output.yaml
index f2a6db224..7e93e72d7 100644
--- a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/testdata/full-invalid.output.yaml
+++ b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/testdata/full-invalid.output.yaml
@@ -22,3 +22,5 @@ violations:
   message: provided DNS has incorrect value, partial wildcard is currently not supported
 - field: spec.default.appendMatch[9].value
   message: value google.com is already defiend for this port and protocol
+- field: spec.default.appendMatch[10].port
+  message: wildcard domains doesn't work for all ports and layer 7 protocol
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/plugin_test.go b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/plugin_test.go
index 5b69db0f3..82415234e 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/plugin_test.go
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/plugin_test.go
@@ -123,113 +123,289 @@ var _ = Describe("MeshPassthrough", func() {
 								{
 									Type:     api.MatchType("Domain"),
 									Value:    "api.example.com",
-									Port:     pointer.To[int](443),
+									Port:     pointer.To[uint32](443),
 									Protocol: api.ProtocolType("tls"),
 								},
 								{
 									Type:     api.MatchType("Domain"),
 									Value:    "example.com",
-									Port:     pointer.To[int](443),
+									Port:     pointer.To[uint32](443),
 									Protocol: api.ProtocolType("tls"),
 								},
 								{
 									Type:     api.MatchType("Domain"),
 									Value:    "*.example.com",
-									Port:     pointer.To[int](443),
+									Port:     pointer.To[uint32](443),
 									Protocol: api.ProtocolType("tls"),
 								},
 								{
 									Type:     api.MatchType("Domain"),
 									Value:    "example.com",
-									Port:     pointer.To[int](8080),
+									Port:     pointer.To[uint32](8080),
 									Protocol: api.ProtocolType("http"),
 								},
 								{
 									Type:     api.MatchType("Domain"),
 									Value:    "other.com",
-									Port:     pointer.To[int](8080),
+									Port:     pointer.To[uint32](8080),
 									Protocol: api.ProtocolType("http"),
 								},
 								{
-									Type:     api.MatchType("Domain"),
-									Value:    "grpcdomain.com",
-									Port:     pointer.To[int](19000),
-									Protocol: api.ProtocolType("grpc"),
+									Type:     api.MatchType("CIDR"),
+									Value:    "192.168.0.0/16",
+									Protocol: api.ProtocolType("http"),
+									Port:     pointer.To[uint32](8126),
 								},
 								{
-									Type:     api.MatchType("Domain"),
-									Value:    "http2.com",
-									Port:     pointer.To[int](8080),
+									Type:     api.MatchType("CIDR"),
+									Value:    "240.0.0.0/4",
 									Protocol: api.ProtocolType("http"),
+									Port:     pointer.To[uint32](8126),
 								},
 								{
 									Type:     api.MatchType("Domain"),
-									Value:    "http2.com",
-									Port:     pointer.To[int](8080),
+									Value:    "www.google.com",
 									Protocol: api.ProtocolType("http"),
+									Port:     pointer.To[uint32](80),
 								},
 								{
-									Type:     api.MatchType("Domain"),
-									Value:    "*.example.com",
-									Protocol: api.ProtocolType("tls"),
+									Type:     api.MatchType("IP"),
+									Value:    "10.42.0.8",
+									Protocol: api.ProtocolType("http"),
 								},
 								{
 									Type:     api.MatchType("IP"),
-									Value:    "192.168.19.1",
+									Value:    "b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6",
 									Protocol: api.ProtocolType("tls"),
 								},
 								{
 									Type:     api.MatchType("IP"),
-									Value:    "192.168.19.1",
-									Port:     pointer.To[int](10000),
+									Value:    "9942:9abf:d0e0:f2da:2290:333b:e590:f497",
+									Port:     pointer.To[uint32](9091),
+									Protocol: api.ProtocolType("tcp"),
+								},
+							},
+						},
+					},
+				},
+			},
+			listenersGolden: "basic.listener.golden.yaml",
+			clustersGolden:  "basic.clusters.golden.yaml",
+		}),
+		Entry("only ipv4 rules", testCase{
+			resources: []*core_xds.Resource{
+				{
+					Name:   "outbound:passthrough:ipv4",
+					Origin: generator.OriginTransparent,
+					Resource: NewListenerBuilder(envoy_common.APIV3, "outbound:passthrough:ipv4").
+						Configure(OutboundListener("0.0.0.0", 15001, core_xds.SocketAddressProtocolTCP)).
+						Configure(FilterChain(NewFilterChainBuilder(envoy_common.APIV3, envoy_common.AnonymousResource).
+							Configure(TCPProxy("outbound_passthrough_ipv4", []envoy_common.Split{
+								plugins_xds.NewSplitBuilder().WithClusterName("outbound:passthrough:ipv4").WithWeight(100).Build(),
+							}...)),
+						)).MustBuild(),
+				},
+				{
+					Name:   "outbound:passthrough:ipv6",
+					Origin: generator.OriginTransparent,
+					Resource: NewListenerBuilder(envoy_common.APIV3, "outbound:passthrough:ipv6").
+						Configure(OutboundListener("::", 15001, core_xds.SocketAddressProtocolTCP)).
+						Configure(FilterChain(NewFilterChainBuilder(envoy_common.APIV3, envoy_common.AnonymousResource).
+							Configure(TCPProxy("outbound_passthrough_ipv6", []envoy_common.Split{
+								plugins_xds.NewSplitBuilder().WithClusterName("outbound:passthrough:ipv6").WithWeight(100).Build(),
+							}...)),
+						)).MustBuild(),
+				},
+			},
+			singleItemRules: core_rules.SingleItemRules{
+				Rules: []*core_rules.Rule{
+					{
+						Subset: []core_rules.Tag{},
+						Conf: api.Conf{
+							AppendMatch: []api.Match{
+								{
+									Type:     api.MatchType("IP"),
+									Value:    "192.168.0.0",
+									Port:     pointer.To[uint32](80),
+									Protocol: api.ProtocolType("tcp"),
+								},
+							},
+						},
+					},
+				},
+			},
+			listenersGolden: "only-ipv4-rules.listener.golden.yaml",
+			clustersGolden:  "only-ipv4-rules.clusters.golden.yaml",
+		}),
+		Entry("simple policy", testCase{
+			resources: []*core_xds.Resource{
+				{
+					Name:   "outbound:passthrough:ipv4",
+					Origin: generator.OriginTransparent,
+					Resource: NewListenerBuilder(envoy_common.APIV3, "outbound:passthrough:ipv4").
+						Configure(OutboundListener("0.0.0.0", 15001, core_xds.SocketAddressProtocolTCP)).
+						Configure(FilterChain(NewFilterChainBuilder(envoy_common.APIV3, envoy_common.AnonymousResource).
+							Configure(TCPProxy("outbound_passthrough_ipv4", []envoy_common.Split{
+								plugins_xds.NewSplitBuilder().WithClusterName("outbound:passthrough:ipv4").WithWeight(100).Build(),
+							}...)),
+						)).MustBuild(),
+				},
+				{
+					Name:   "outbound:passthrough:ipv6",
+					Origin: generator.OriginTransparent,
+					Resource: NewListenerBuilder(envoy_common.APIV3, "outbound:passthrough:ipv6").
+						Configure(OutboundListener("::", 15001, core_xds.SocketAddressProtocolTCP)).
+						Configure(FilterChain(NewFilterChainBuilder(envoy_common.APIV3, envoy_common.AnonymousResource).
+							Configure(TCPProxy("outbound_passthrough_ipv6", []envoy_common.Split{
+								plugins_xds.NewSplitBuilder().WithClusterName("outbound:passthrough:ipv6").WithWeight(100).Build(),
+							}...)),
+						)).MustBuild(),
+				},
+			},
+			singleItemRules: core_rules.SingleItemRules{
+				Rules: []*core_rules.Rule{
+					{
+						Subset: []core_rules.Tag{},
+						Conf: api.Conf{
+							AppendMatch: []api.Match{
+								{
+									Type:     api.MatchType("Domain"),
+									Value:    "api.example.com",
+									Port:     pointer.To[uint32](80),
 									Protocol: api.ProtocolType("http"),
 								},
 								{
 									Type:     api.MatchType("IP"),
-									Value:    "192.168.0.1",
-									Port:     pointer.To[int](9091),
+									Value:    "192.168.0.0",
+									Port:     pointer.To[uint32](80),
 									Protocol: api.ProtocolType("tcp"),
 								},
+							},
+						},
+					},
+				},
+			},
+			listenersGolden: "simple.listener.golden.yaml",
+			clustersGolden:  "simple.clusters.golden.yaml",
+		}),
+		Entry("cidr and http policy", testCase{
+			resources: []*core_xds.Resource{
+				{
+					Name:   "outbound:passthrough:ipv4",
+					Origin: generator.OriginTransparent,
+					Resource: NewListenerBuilder(envoy_common.APIV3, "outbound:passthrough:ipv4").
+						Configure(OutboundListener("0.0.0.0", 15001, core_xds.SocketAddressProtocolTCP)).
+						Configure(FilterChain(NewFilterChainBuilder(envoy_common.APIV3, envoy_common.AnonymousResource).
+							Configure(TCPProxy("outbound_passthrough_ipv4", []envoy_common.Split{
+								plugins_xds.NewSplitBuilder().WithClusterName("outbound:passthrough:ipv4").WithWeight(100).Build(),
+							}...)),
+						)).MustBuild(),
+				},
+				{
+					Name:   "outbound:passthrough:ipv6",
+					Origin: generator.OriginTransparent,
+					Resource: NewListenerBuilder(envoy_common.APIV3, "outbound:passthrough:ipv6").
+						Configure(OutboundListener("::", 15001, core_xds.SocketAddressProtocolTCP)).
+						Configure(FilterChain(NewFilterChainBuilder(envoy_common.APIV3, envoy_common.AnonymousResource).
+							Configure(TCPProxy("outbound_passthrough_ipv6", []envoy_common.Split{
+								plugins_xds.NewSplitBuilder().WithClusterName("outbound:passthrough:ipv6").WithWeight(100).Build(),
+							}...)),
+						)).MustBuild(),
+				},
+			},
+			singleItemRules: core_rules.SingleItemRules{
+				Rules: []*core_rules.Rule{
+					{
+						Subset: []core_rules.Tag{},
+						Conf: api.Conf{
+							AppendMatch: []api.Match{
 								{
 									Type:     api.MatchType("CIDR"),
-									Value:    "192.168.0.1/24",
-									Protocol: api.ProtocolType("tcp"),
+									Value:    "10.10.0.0/16",
+									Port:     pointer.To[uint32](80),
+									Protocol: api.ProtocolType("http"),
 								},
 								{
 									Type:     api.MatchType("CIDR"),
-									Value:    "192.168.0.1/30",
-									Protocol: api.ProtocolType("tcp"),
+									Value:    "192.168.0.0/24",
+									Port:     pointer.To[uint32](80),
+									Protocol: api.ProtocolType("http"),
 								},
 								{
 									Type:     api.MatchType("IP"),
-									Value:    "b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6",
-									Protocol: api.ProtocolType("tls"),
+									Value:    "192.168.0.0",
+									Protocol: api.ProtocolType("http"),
 								},
+							},
+						},
+					},
+				},
+			},
+			listenersGolden: "cidr-http.listener.golden.yaml",
+			clustersGolden:  "cidr-http.clusters.golden.yaml",
+		}),
+		Entry("http domain aggregated policy", testCase{
+			resources: []*core_xds.Resource{
+				{
+					Name:   "outbound:passthrough:ipv4",
+					Origin: generator.OriginTransparent,
+					Resource: NewListenerBuilder(envoy_common.APIV3, "outbound:passthrough:ipv4").
+						Configure(OutboundListener("0.0.0.0", 15001, core_xds.SocketAddressProtocolTCP)).
+						Configure(FilterChain(NewFilterChainBuilder(envoy_common.APIV3, envoy_common.AnonymousResource).
+							Configure(TCPProxy("outbound_passthrough_ipv4", []envoy_common.Split{
+								plugins_xds.NewSplitBuilder().WithClusterName("outbound:passthrough:ipv4").WithWeight(100).Build(),
+							}...)),
+						)).MustBuild(),
+				},
+				{
+					Name:   "outbound:passthrough:ipv6",
+					Origin: generator.OriginTransparent,
+					Resource: NewListenerBuilder(envoy_common.APIV3, "outbound:passthrough:ipv6").
+						Configure(OutboundListener("::", 15001, core_xds.SocketAddressProtocolTCP)).
+						Configure(FilterChain(NewFilterChainBuilder(envoy_common.APIV3, envoy_common.AnonymousResource).
+							Configure(TCPProxy("outbound_passthrough_ipv6", []envoy_common.Split{
+								plugins_xds.NewSplitBuilder().WithClusterName("outbound:passthrough:ipv6").WithWeight(100).Build(),
+							}...)),
+						)).MustBuild(),
+				},
+			},
+			singleItemRules: core_rules.SingleItemRules{
+				Rules: []*core_rules.Rule{
+					{
+						Subset: []core_rules.Tag{},
+						Conf: api.Conf{
+							AppendMatch: []api.Match{
 								{
-									Type:     api.MatchType("IP"),
-									Value:    "9942:9abf:d0e0:f2da:2290:333b:e590:f497",
-									Port:     pointer.To[int](9091),
-									Protocol: api.ProtocolType("tcp"),
+									Type:     api.MatchType("Domain"),
+									Value:    "example1.com",
+									Port:     pointer.To[uint32](80),
+									Protocol: api.ProtocolType("http"),
 								},
 								{
-									Type:     api.MatchType("CIDR"),
-									Value:    "b0ce:f616:4e74:28f7:427c:b969:8016:6344/64",
-									Protocol: api.ProtocolType("tcp"),
+									Type:     api.MatchType("Domain"),
+									Value:    "anotherexample.com",
+									Protocol: api.ProtocolType("http"),
 								},
 								{
-									Type:     api.MatchType("CIDR"),
-									Value:    "b0ce:f616:4e74:28f7:427c:b969:8016:6344/96",
-									Protocol: api.ProtocolType("tcp"),
+									Type:     api.MatchType("Domain"),
+									Value:    "example2.com",
+									Port:     pointer.To[uint32](80),
+									Protocol: api.ProtocolType("http"),
+								},
+								{
+									Type:     api.MatchType("Domain"),
+									Value:    "*.example.com",
+									Protocol: api.ProtocolType("http"),
 								},
 							},
 						},
 					},
 				},
 			},
-			listenersGolden: "basic.listener.golden.yaml",
-			clustersGolden:  "basic.clusters.golden.yaml",
+			listenersGolden: "http-domains-aggregated.listener.golden.yaml",
+			clustersGolden:  "http-domains-aggregated.clusters.golden.yaml",
 		}),
-		Entry("only ipv4 rules", testCase{
+		Entry("http domains", testCase{
 			resources: []*core_xds.Resource{
 				{
 					Name:   "outbound:passthrough:ipv4",
@@ -261,20 +437,25 @@ var _ = Describe("MeshPassthrough", func() {
 						Conf: api.Conf{
 							AppendMatch: []api.Match{
 								{
-									Type:     api.MatchType("IP"),
-									Value:    "192.168.0.0",
-									Port:     pointer.To[int](80),
-									Protocol: api.ProtocolType("tcp"),
+									Type:     api.MatchType("Domain"),
+									Value:    "www.example.com",
+									Port:     pointer.To[uint32](80),
+									Protocol: api.ProtocolType("http"),
+								},
+								{
+									Type:     api.MatchType("Domain"),
+									Value:    "www.anotherexample.com",
+									Protocol: api.ProtocolType("http"),
 								},
 							},
 						},
 					},
 				},
 			},
-			listenersGolden: "only-ipv4-rules.listener.golden.yaml",
-			clustersGolden:  "only-ipv4-rules.clusters.golden.yaml",
+			listenersGolden: "http-domains.listener.golden.yaml",
+			clustersGolden:  "http-domains.clusters.golden.yaml",
 		}),
-		Entry("simple policy", testCase{
+		Entry("the same protocol but different type match", testCase{
 			resources: []*core_xds.Resource{
 				{
 					Name:   "outbound:passthrough:ipv4",
@@ -307,23 +488,22 @@ var _ = Describe("MeshPassthrough", func() {
 							AppendMatch: []api.Match{
 								{
 									Type:     api.MatchType("Domain"),
-									Value:    "api.example.com",
-									Port:     pointer.To[int](80),
+									Value:    "www.gmail.com",
+									Port:     pointer.To[uint32](80),
 									Protocol: api.ProtocolType("http"),
 								},
 								{
 									Type:     api.MatchType("IP"),
-									Value:    "192.168.0.0",
-									Port:     pointer.To[int](80),
-									Protocol: api.ProtocolType("tcp"),
+									Value:    "10.42.0.8",
+									Protocol: api.ProtocolType("http"),
 								},
 							},
 						},
 					},
 				},
 			},
-			listenersGolden: "simple.listener.golden.yaml",
-			clustersGolden:  "simple.clusters.golden.yaml",
+			listenersGolden: "same-protocol.listener.golden.yaml",
+			clustersGolden:  "same-protocol.clusters.golden.yaml",
 		}),
 		Entry("disabled on policy but enabled on mesh", testCase{
 			resources: []*core_xds.Resource{
@@ -381,7 +561,7 @@ var _ = Describe("MeshPassthrough", func() {
 								{
 									Type:     api.MatchType("Domain"),
 									Value:    "api.example.com",
-									Port:     pointer.To[int](443),
+									Port:     pointer.To[uint32](443),
 									Protocol: api.ProtocolType("tls"),
 								},
 							},
@@ -422,7 +602,7 @@ var _ = Describe("MeshPassthrough", func() {
 								{
 									Type:     api.MatchType("Domain"),
 									Value:    "api.example.com",
-									Port:     pointer.To[int](443),
+									Port:     pointer.To[uint32](443),
 									Protocol: api.ProtocolType("tls"),
 								},
 							},
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/basic.clusters.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/basic.clusters.golden.yaml
index f4f986b05..d6cde5ef8 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/basic.clusters.golden.yaml
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/basic.clusters.golden.yaml
@@ -1,142 +1,169 @@
 resources:
-- name: meshpassthrough_*.example.com_*
+- name: meshpassthrough_http_10.42.0.8_*
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough___example_com__
+    altStatName: meshpassthrough_http_10_42_0_8__
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_*.example.com_*
+    name: meshpassthrough_http_10.42.0.8_*
     type: ORIGINAL_DST
-- name: meshpassthrough_*.example.com_443
+- name: meshpassthrough_http_10.42.0.8_443
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough___example_com_443
+    altStatName: meshpassthrough_http_10_42_0_8_443
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_*.example.com_443
+    name: meshpassthrough_http_10.42.0.8_443
     type: ORIGINAL_DST
-- name: meshpassthrough_192.168.0.1/24_*
+- name: meshpassthrough_http_10.42.0.8_80
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_192_168_0_1_24__
+    altStatName: meshpassthrough_http_10_42_0_8_80
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_192.168.0.1/24_*
+    name: meshpassthrough_http_10.42.0.8_80
     type: ORIGINAL_DST
-- name: meshpassthrough_192.168.0.1/30_*
+- name: meshpassthrough_http_10.42.0.8_8080
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_192_168_0_1_30__
+    altStatName: meshpassthrough_http_10_42_0_8_8080
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_192.168.0.1/30_*
+    name: meshpassthrough_http_10.42.0.8_8080
     type: ORIGINAL_DST
-- name: meshpassthrough_192.168.0.1_9091
+- name: meshpassthrough_http_10.42.0.8_8126
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_192_168_0_1_9091
+    altStatName: meshpassthrough_http_10_42_0_8_8126
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_192.168.0.1_9091
+    name: meshpassthrough_http_10.42.0.8_8126
     type: ORIGINAL_DST
-- name: meshpassthrough_192.168.19.1_*
+- name: meshpassthrough_http_10.42.0.8_9091
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_192_168_19_1__
+    altStatName: meshpassthrough_http_10_42_0_8_9091
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_192.168.19.1_*
+    name: meshpassthrough_http_10.42.0.8_9091
     type: ORIGINAL_DST
-- name: meshpassthrough_192.168.19.1_10000
+- name: meshpassthrough_http_192.168.0.0/16_8126
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_192_168_19_1_10000
+    altStatName: meshpassthrough_http_192_168_0_0_16_8126
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_192.168.19.1_10000
+    name: meshpassthrough_http_192.168.0.0/16_8126
     type: ORIGINAL_DST
-- name: meshpassthrough_9942:9abf:d0e0:f2da:2290:333b:e590:f497_9091
+- name: meshpassthrough_http_240.0.0.0/4_8126
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_9942_9abf_d0e0_f2da_2290_333b_e590_f497_9091
+    altStatName: meshpassthrough_http_240_0_0_0_4_8126
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_9942:9abf:d0e0:f2da:2290:333b:e590:f497_9091
+    name: meshpassthrough_http_240.0.0.0/4_8126
     type: ORIGINAL_DST
-- name: meshpassthrough_api.example.com_443
+- name: meshpassthrough_http_example.com_8080
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_api_example_com_443
+    altStatName: meshpassthrough_http_example_com_8080
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_api.example.com_443
+    name: meshpassthrough_http_example.com_8080
     type: ORIGINAL_DST
-- name: meshpassthrough_b0ce:f616:4e74:28f7:427c:b969:8016:6344/64_*
+- name: meshpassthrough_http_other.com_8080
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_b0ce_f616_4e74_28f7_427c_b969_8016_6344_64__
+    altStatName: meshpassthrough_http_other_com_8080
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_b0ce:f616:4e74:28f7:427c:b969:8016:6344/64_*
+    name: meshpassthrough_http_other.com_8080
     type: ORIGINAL_DST
-- name: meshpassthrough_b0ce:f616:4e74:28f7:427c:b969:8016:6344/96_*
+- name: meshpassthrough_http_www.google.com_80
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_b0ce_f616_4e74_28f7_427c_b969_8016_6344_96__
+    altStatName: meshpassthrough_http_www_google_com_80
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_b0ce:f616:4e74:28f7:427c:b969:8016:6344/96_*
+    name: meshpassthrough_http_www.google.com_80
     type: ORIGINAL_DST
-- name: meshpassthrough_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_*
+- name: meshpassthrough_tcp_9942:9abf:d0e0:f2da:2290:333b:e590:f497_9091
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6__
+    altStatName: meshpassthrough_tcp_9942_9abf_d0e0_f2da_2290_333b_e590_f497_9091
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_*
+    name: meshpassthrough_tcp_9942:9abf:d0e0:f2da:2290:333b:e590:f497_9091
     type: ORIGINAL_DST
-- name: meshpassthrough_example.com_443
+- name: meshpassthrough_tls_*.example.com_443
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_example_com_443
+    altStatName: meshpassthrough_tls___example_com_443
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_example.com_443
+    name: meshpassthrough_tls_*.example.com_443
     type: ORIGINAL_DST
-- name: meshpassthrough_example.com_8080
+- name: meshpassthrough_tls_api.example.com_443
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_example_com_8080
+    altStatName: meshpassthrough_tls_api_example_com_443
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_example.com_8080
+    name: meshpassthrough_tls_api.example.com_443
     type: ORIGINAL_DST
-- name: meshpassthrough_grpcdomain.com_19000
+- name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_*
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_grpcdomain_com_19000
+    altStatName: meshpassthrough_tls_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6__
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_grpcdomain.com_19000
+    name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_*
     type: ORIGINAL_DST
-    typedExtensionProtocolOptions:
-      envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
-        '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
-        explicitHttpConfig:
-          http2ProtocolOptions: {}
-- name: meshpassthrough_http2.com_8080
+- name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_443
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_http2_com_8080
+    altStatName: meshpassthrough_tls_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6_443
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_http2.com_8080
+    name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_443
     type: ORIGINAL_DST
-- name: meshpassthrough_other.com_8080
+- name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_80
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_other_com_8080
+    altStatName: meshpassthrough_tls_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6_80
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_other.com_8080
+    name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_80
+    type: ORIGINAL_DST
+- name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_8080
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_tls_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6_8080
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_8080
+    type: ORIGINAL_DST
+- name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_8126
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_tls_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6_8126
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_8126
+    type: ORIGINAL_DST
+- name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_9091
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_tls_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6_9091
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_9091
+    type: ORIGINAL_DST
+- name: meshpassthrough_tls_example.com_443
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_tls_example_com_443
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_tls_example.com_443
     type: ORIGINAL_DST
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/basic.listener.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/basic.listener.golden.yaml
index 74499aa22..1d3913fe8 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/basic.listener.golden.yaml
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/basic.listener.golden.yaml
@@ -16,9 +16,9 @@ resources:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_api.example.com_443
-          statPrefix: meshpassthrough_api_example_com_443
-      name: meshpassthrough_api.example.com_443
+          cluster: meshpassthrough_tls_api.example.com_443
+          statPrefix: meshpassthrough_tls_api_example_com_443
+      name: meshpassthrough_tls_api.example.com_443
     - filterChainMatch:
         destinationPort: 443
         serverNames:
@@ -28,9 +28,9 @@ resources:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_example.com_443
-          statPrefix: meshpassthrough_example_com_443
-      name: meshpassthrough_example.com_443
+          cluster: meshpassthrough_tls_example.com_443
+          statPrefix: meshpassthrough_tls_example_com_443
+      name: meshpassthrough_tls_example.com_443
     - filterChainMatch:
         destinationPort: 443
         serverNames:
@@ -40,73 +40,166 @@ resources:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_*.example.com_443
-          statPrefix: meshpassthrough___example_com_443
-      name: meshpassthrough_*.example.com_443
+          cluster: meshpassthrough_tls_*.example.com_443
+          statPrefix: meshpassthrough_tls___example_com_443
+      name: meshpassthrough_tls_*.example.com_443
     - filterChainMatch:
-        serverNames:
-        - '*.example.com'
-        transportProtocol: tls
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 9091
+        prefixRanges:
+        - addressPrefix: 10.42.0.8
+          prefixLen: 32
+        transportProtocol: raw_buffer
       filters:
-      - name: envoy.filters.network.tcp_proxy
+      - name: envoy.filters.network.http_connection_manager
         typedConfig:
-          '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_*.example.com_*
-          statPrefix: meshpassthrough___example_com__
-      name: meshpassthrough_*.example.com_*
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_10.42.0.8_9091
+            virtualHosts:
+            - domains:
+              - '*'
+              name: 10.42.0.8
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_10.42.0.8_9091
+          statPrefix: meshpassthrough_http_10_42_0_8_9091
+      name: meshpassthrough_http_10.42.0.8_9091
     - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 8126
         prefixRanges:
-        - addressPrefix: 192.168.19.1
+        - addressPrefix: 10.42.0.8
           prefixLen: 32
-        transportProtocol: tls
+        transportProtocol: raw_buffer
       filters:
-      - name: envoy.filters.network.tcp_proxy
+      - name: envoy.filters.network.http_connection_manager
         typedConfig:
-          '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_192.168.19.1_*
-          statPrefix: meshpassthrough_192_168_19_1__
-      name: meshpassthrough_192.168.19.1_*
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_10.42.0.8_8126
+            virtualHosts:
+            - domains:
+              - '*'
+              name: 10.42.0.8
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_10.42.0.8_8126
+          statPrefix: meshpassthrough_http_10_42_0_8_8126
+      name: meshpassthrough_http_10.42.0.8_8126
     - filterChainMatch:
-        destinationPort: 9091
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 8080
         prefixRanges:
-        - addressPrefix: 192.168.0.1
+        - addressPrefix: 10.42.0.8
           prefixLen: 32
         transportProtocol: raw_buffer
       filters:
-      - name: envoy.filters.network.tcp_proxy
+      - name: envoy.filters.network.http_connection_manager
         typedConfig:
-          '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_192.168.0.1_9091
-          statPrefix: meshpassthrough_192_168_0_1_9091
-      name: meshpassthrough_192.168.0.1_9091
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_10.42.0.8_8080
+            virtualHosts:
+            - domains:
+              - '*'
+              name: 10.42.0.8
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_10.42.0.8_8080
+          statPrefix: meshpassthrough_http_10_42_0_8_8080
+      name: meshpassthrough_http_10.42.0.8_8080
     - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 443
         prefixRanges:
-        - addressPrefix: 192.168.0.0
-          prefixLen: 30
+        - addressPrefix: 10.42.0.8
+          prefixLen: 32
         transportProtocol: raw_buffer
       filters:
-      - name: envoy.filters.network.tcp_proxy
+      - name: envoy.filters.network.http_connection_manager
         typedConfig:
-          '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_192.168.0.1/30_*
-          statPrefix: meshpassthrough_192_168_0_1_30__
-      name: meshpassthrough_192.168.0.1/30_*
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_10.42.0.8_443
+            virtualHosts:
+            - domains:
+              - '*'
+              name: 10.42.0.8
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_10.42.0.8_443
+          statPrefix: meshpassthrough_http_10_42_0_8_443
+      name: meshpassthrough_http_10.42.0.8_443
     - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 80
         prefixRanges:
-        - addressPrefix: 192.168.0.0
-          prefixLen: 24
+        - addressPrefix: 10.42.0.8
+          prefixLen: 32
         transportProtocol: raw_buffer
       filters:
-      - name: envoy.filters.network.tcp_proxy
+      - name: envoy.filters.network.http_connection_manager
         typedConfig:
-          '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_192.168.0.1/24_*
-          statPrefix: meshpassthrough_192_168_0_1_24__
-      name: meshpassthrough_192.168.0.1/24_*
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_10.42.0.8_80
+            virtualHosts:
+            - domains:
+              - '*'
+              name: 10.42.0.8
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_10.42.0.8_80
+          statPrefix: meshpassthrough_http_10_42_0_8_80
+      name: meshpassthrough_http_10.42.0.8_80
     - filterChainMatch:
         applicationProtocols:
         - http/1.1
         - h2c
+        prefixRanges:
+        - addressPrefix: 10.42.0.8
+          prefixLen: 32
         transportProtocol: raw_buffer
       filters:
       - name: envoy.filters.network.http_connection_manager
@@ -117,34 +210,56 @@ resources:
             typedConfig:
               '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
           routeConfig:
-            name: meshpassthrough_http_10000
+            name: meshpassthrough_http_10.42.0.8_*
             virtualHosts:
             - domains:
-              - 192.168.19.1
-              - 192.168.19.1:10000
-              name: 192.168.19.1
+              - '*'
+              name: 10.42.0.8
               routes:
               - match:
                   prefix: /
                 route:
-                  cluster: meshpassthrough_192.168.19.1_10000
+                  cluster: meshpassthrough_http_10.42.0.8_*
+          statPrefix: meshpassthrough_http_10_42_0_8__
+      name: meshpassthrough_http_10.42.0.8_*
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 8126
+        prefixRanges:
+        - addressPrefix: 192.168.0.0
+          prefixLen: 16
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_192.168.0.0/16_8126
+            virtualHosts:
             - domains:
               - '*'
-              name: no_match
+              name: 192.168.0.0/16
               routes:
-              - directResponse:
-                  body:
-                    inlineString: |
-                      This response comes from Kuma Sidecar. No routes matched this domain - check configuration of your MeshPassthrough policy.
-                  status: 503
-                match:
+              - match:
                   prefix: /
-          statPrefix: meshpassthrough_http_10000
-      name: meshpassthrough_http_10000
+                route:
+                  cluster: meshpassthrough_http_192.168.0.0/16_8126
+          statPrefix: meshpassthrough_http_192_168_0_0_16_8126
+      name: meshpassthrough_http_192.168.0.0/16_8126
     - filterChainMatch:
         applicationProtocols:
         - http/1.1
         - h2c
+        destinationPort: 8126
+        prefixRanges:
+        - addressPrefix: 240.0.0.0
+          prefixLen: 4
         transportProtocol: raw_buffer
       filters:
       - name: envoy.filters.network.http_connection_manager
@@ -155,32 +270,53 @@ resources:
             typedConfig:
               '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
           routeConfig:
-            name: meshpassthrough_http_8080
+            name: meshpassthrough_http_240.0.0.0/4_8126
             virtualHosts:
             - domains:
-              - example.com
-              name: example.com
+              - '*'
+              name: 240.0.0.0/4
               routes:
               - match:
                   prefix: /
                 route:
-                  cluster: meshpassthrough_example.com_8080
+                  cluster: meshpassthrough_http_240.0.0.0/4_8126
+          statPrefix: meshpassthrough_http_240_0_0_0_4_8126
+      name: meshpassthrough_http_240.0.0.0/4_8126
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 8080
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_8080
+            virtualHosts:
             - domains:
-              - http2.com
-              name: http2.com
+              - example.com
+              - example.com:8080
+              name: example.com
               routes:
               - match:
                   prefix: /
                 route:
-                  cluster: meshpassthrough_http2.com_8080
+                  cluster: meshpassthrough_http_example.com_8080
             - domains:
               - other.com
+              - other.com:8080
               name: other.com
               routes:
               - match:
                   prefix: /
                 route:
-                  cluster: meshpassthrough_other.com_8080
+                  cluster: meshpassthrough_http_other.com_8080
             - domains:
               - '*'
               name: no_match
@@ -198,30 +334,28 @@ resources:
         applicationProtocols:
         - http/1.1
         - h2c
+        destinationPort: 80
         transportProtocol: raw_buffer
       filters:
       - name: envoy.filters.network.http_connection_manager
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
           httpFilters:
-          - name: envoy.filters.http.grpc_stats
-            typedConfig:
-              '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig
-              emitFilterState: true
           - name: envoy.filters.http.router
             typedConfig:
               '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
           routeConfig:
-            name: meshpassthrough_http_19000
+            name: meshpassthrough_http_80
             virtualHosts:
             - domains:
-              - grpcdomain.com
-              name: grpcdomain.com
+              - www.google.com
+              - www.google.com:80
+              name: www.google.com
               routes:
               - match:
                   prefix: /
                 route:
-                  cluster: meshpassthrough_grpcdomain.com_19000
+                  cluster: meshpassthrough_http_www.google.com_80
             - domains:
               - '*'
               name: no_match
@@ -233,8 +367,8 @@ resources:
                   status: 503
                 match:
                   prefix: /
-          statPrefix: meshpassthrough_http_19000
-      name: meshpassthrough_http_19000
+          statPrefix: meshpassthrough_http_80
+      name: meshpassthrough_http_80
     listenerFilters:
     - name: envoy.filters.listener.tls_inspector
       typedConfig:
@@ -253,53 +387,59 @@ resources:
         portValue: 15001
     filterChains:
     - filterChainMatch:
-        destinationPort: 443
-        serverNames:
-        - api.example.com
+        destinationPort: 9091
+        prefixRanges:
+        - addressPrefix: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
+          prefixLen: 128
         transportProtocol: tls
       filters:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_api.example.com_443
-          statPrefix: meshpassthrough_api_example_com_443
-      name: meshpassthrough_api.example.com_443
+          cluster: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_9091
+          statPrefix: meshpassthrough_tls_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6_9091
+      name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_9091
     - filterChainMatch:
-        destinationPort: 443
-        serverNames:
-        - example.com
+        destinationPort: 8126
+        prefixRanges:
+        - addressPrefix: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
+          prefixLen: 128
         transportProtocol: tls
       filters:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_example.com_443
-          statPrefix: meshpassthrough_example_com_443
-      name: meshpassthrough_example.com_443
+          cluster: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_8126
+          statPrefix: meshpassthrough_tls_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6_8126
+      name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_8126
     - filterChainMatch:
-        destinationPort: 443
-        serverNames:
-        - '*.example.com'
+        destinationPort: 8080
+        prefixRanges:
+        - addressPrefix: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
+          prefixLen: 128
         transportProtocol: tls
       filters:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_*.example.com_443
-          statPrefix: meshpassthrough___example_com_443
-      name: meshpassthrough_*.example.com_443
+          cluster: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_8080
+          statPrefix: meshpassthrough_tls_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6_8080
+      name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_8080
     - filterChainMatch:
-        serverNames:
-        - '*.example.com'
+        destinationPort: 443
+        prefixRanges:
+        - addressPrefix: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
+          prefixLen: 128
         transportProtocol: tls
       filters:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_*.example.com_*
-          statPrefix: meshpassthrough___example_com__
-      name: meshpassthrough_*.example.com_*
+          cluster: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_443
+          statPrefix: meshpassthrough_tls_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6_443
+      name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_443
     - filterChainMatch:
+        destinationPort: 80
         prefixRanges:
         - addressPrefix: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
           prefixLen: 128
@@ -308,79 +448,75 @@ resources:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_*
-          statPrefix: meshpassthrough_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6__
-      name: meshpassthrough_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_*
+          cluster: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_80
+          statPrefix: meshpassthrough_tls_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6_80
+      name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_80
     - filterChainMatch:
-        destinationPort: 9091
         prefixRanges:
-        - addressPrefix: 9942:9abf:d0e0:f2da:2290:333b:e590:f497
+        - addressPrefix: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
           prefixLen: 128
-        transportProtocol: raw_buffer
+        transportProtocol: tls
       filters:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_9942:9abf:d0e0:f2da:2290:333b:e590:f497_9091
-          statPrefix: meshpassthrough_9942_9abf_d0e0_f2da_2290_333b_e590_f497_9091
-      name: meshpassthrough_9942:9abf:d0e0:f2da:2290:333b:e590:f497_9091
+          cluster: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_*
+          statPrefix: meshpassthrough_tls_b6e5_a45e_70ae_e77f_d24e_5023_375d_20a6__
+      name: meshpassthrough_tls_b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6_*
     - filterChainMatch:
-        prefixRanges:
-        - addressPrefix: 'b0ce:f616:4e74:28f7:427c:b969::'
-          prefixLen: 96
-        transportProtocol: raw_buffer
+        destinationPort: 443
+        serverNames:
+        - api.example.com
+        transportProtocol: tls
       filters:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_b0ce:f616:4e74:28f7:427c:b969:8016:6344/96_*
-          statPrefix: meshpassthrough_b0ce_f616_4e74_28f7_427c_b969_8016_6344_96__
-      name: meshpassthrough_b0ce:f616:4e74:28f7:427c:b969:8016:6344/96_*
+          cluster: meshpassthrough_tls_api.example.com_443
+          statPrefix: meshpassthrough_tls_api_example_com_443
+      name: meshpassthrough_tls_api.example.com_443
     - filterChainMatch:
-        prefixRanges:
-        - addressPrefix: 'b0ce:f616:4e74:28f7::'
-          prefixLen: 64
-        transportProtocol: raw_buffer
+        destinationPort: 443
+        serverNames:
+        - example.com
+        transportProtocol: tls
       filters:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_b0ce:f616:4e74:28f7:427c:b969:8016:6344/64_*
-          statPrefix: meshpassthrough_b0ce_f616_4e74_28f7_427c_b969_8016_6344_64__
-      name: meshpassthrough_b0ce:f616:4e74:28f7:427c:b969:8016:6344/64_*
+          cluster: meshpassthrough_tls_example.com_443
+          statPrefix: meshpassthrough_tls_example_com_443
+      name: meshpassthrough_tls_example.com_443
     - filterChainMatch:
-        applicationProtocols:
-        - http/1.1
-        - h2c
+        destinationPort: 443
+        serverNames:
+        - '*.example.com'
+        transportProtocol: tls
+      filters:
+      - name: envoy.filters.network.tcp_proxy
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+          cluster: meshpassthrough_tls_*.example.com_443
+          statPrefix: meshpassthrough_tls___example_com_443
+      name: meshpassthrough_tls_*.example.com_443
+    - filterChainMatch:
+        destinationPort: 9091
+        prefixRanges:
+        - addressPrefix: 9942:9abf:d0e0:f2da:2290:333b:e590:f497
+          prefixLen: 128
         transportProtocol: raw_buffer
       filters:
-      - name: envoy.filters.network.http_connection_manager
+      - name: envoy.filters.network.tcp_proxy
         typedConfig:
-          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
-          httpFilters:
-          - name: envoy.filters.http.router
-            typedConfig:
-              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
-          routeConfig:
-            name: meshpassthrough_http_10000
-            virtualHosts:
-            - domains:
-              - '*'
-              name: no_match
-              routes:
-              - directResponse:
-                  body:
-                    inlineString: |
-                      This response comes from Kuma Sidecar. No routes matched this domain - check configuration of your MeshPassthrough policy.
-                  status: 503
-                match:
-                  prefix: /
-          statPrefix: meshpassthrough_http_10000
-      name: meshpassthrough_http_10000
+          '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+          cluster: meshpassthrough_tcp_9942:9abf:d0e0:f2da:2290:333b:e590:f497_9091
+          statPrefix: meshpassthrough_tcp_9942_9abf_d0e0_f2da_2290_333b_e590_f497_9091
+      name: meshpassthrough_tcp_9942:9abf:d0e0:f2da:2290:333b:e590:f497_9091
     - filterChainMatch:
         applicationProtocols:
         - http/1.1
         - h2c
+        destinationPort: 8080
         transportProtocol: raw_buffer
       filters:
       - name: envoy.filters.network.http_connection_manager
@@ -395,28 +531,22 @@ resources:
             virtualHosts:
             - domains:
               - example.com
+              - example.com:8080
               name: example.com
               routes:
               - match:
                   prefix: /
                 route:
-                  cluster: meshpassthrough_example.com_8080
-            - domains:
-              - http2.com
-              name: http2.com
-              routes:
-              - match:
-                  prefix: /
-                route:
-                  cluster: meshpassthrough_http2.com_8080
+                  cluster: meshpassthrough_http_example.com_8080
             - domains:
               - other.com
+              - other.com:8080
               name: other.com
               routes:
               - match:
                   prefix: /
                 route:
-                  cluster: meshpassthrough_other.com_8080
+                  cluster: meshpassthrough_http_other.com_8080
             - domains:
               - '*'
               name: no_match
@@ -434,30 +564,28 @@ resources:
         applicationProtocols:
         - http/1.1
         - h2c
+        destinationPort: 80
         transportProtocol: raw_buffer
       filters:
       - name: envoy.filters.network.http_connection_manager
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
           httpFilters:
-          - name: envoy.filters.http.grpc_stats
-            typedConfig:
-              '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig
-              emitFilterState: true
           - name: envoy.filters.http.router
             typedConfig:
               '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
           routeConfig:
-            name: meshpassthrough_http_19000
+            name: meshpassthrough_http_80
             virtualHosts:
             - domains:
-              - grpcdomain.com
-              name: grpcdomain.com
+              - www.google.com
+              - www.google.com:80
+              name: www.google.com
               routes:
               - match:
                   prefix: /
                 route:
-                  cluster: meshpassthrough_grpcdomain.com_19000
+                  cluster: meshpassthrough_http_www.google.com_80
             - domains:
               - '*'
               name: no_match
@@ -469,8 +597,8 @@ resources:
                   status: 503
                 match:
                   prefix: /
-          statPrefix: meshpassthrough_http_19000
-      name: meshpassthrough_http_19000
+          statPrefix: meshpassthrough_http_80
+      name: meshpassthrough_http_80
     listenerFilters:
     - name: envoy.filters.listener.tls_inspector
       typedConfig:
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/cidr-http.clusters.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/cidr-http.clusters.golden.yaml
new file mode 100644
index 000000000..4e405b64d
--- /dev/null
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/cidr-http.clusters.golden.yaml
@@ -0,0 +1,33 @@
+resources:
+- name: meshpassthrough_http_10.10.0.0/16_80
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_10_10_0_0_16_80
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_10.10.0.0/16_80
+    type: ORIGINAL_DST
+- name: meshpassthrough_http_192.168.0.0/24_80
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_192_168_0_0_24_80
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_192.168.0.0/24_80
+    type: ORIGINAL_DST
+- name: meshpassthrough_http_192.168.0.0_*
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_192_168_0_0__
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_192.168.0.0_*
+    type: ORIGINAL_DST
+- name: meshpassthrough_http_192.168.0.0_80
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_192_168_0_0_80
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_192.168.0.0_80
+    type: ORIGINAL_DST
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/cidr-http.listener.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/cidr-http.listener.golden.yaml
new file mode 100644
index 000000000..ea8cedfd6
--- /dev/null
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/cidr-http.listener.golden.yaml
@@ -0,0 +1,153 @@
+resources:
+- name: outbound:passthrough:ipv4
+  resource:
+    '@type': type.googleapis.com/envoy.config.listener.v3.Listener
+    address:
+      socketAddress:
+        address: 0.0.0.0
+        portValue: 15001
+    filterChains:
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 80
+        prefixRanges:
+        - addressPrefix: 192.168.0.0
+          prefixLen: 32
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_192.168.0.0_80
+            virtualHosts:
+            - domains:
+              - '*'
+              name: 192.168.0.0
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_192.168.0.0_80
+          statPrefix: meshpassthrough_http_192_168_0_0_80
+      name: meshpassthrough_http_192.168.0.0_80
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        prefixRanges:
+        - addressPrefix: 192.168.0.0
+          prefixLen: 32
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_192.168.0.0_*
+            virtualHosts:
+            - domains:
+              - '*'
+              name: 192.168.0.0
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_192.168.0.0_*
+          statPrefix: meshpassthrough_http_192_168_0_0__
+      name: meshpassthrough_http_192.168.0.0_*
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 80
+        prefixRanges:
+        - addressPrefix: 192.168.0.0
+          prefixLen: 24
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_192.168.0.0/24_80
+            virtualHosts:
+            - domains:
+              - '*'
+              name: 192.168.0.0/24
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_192.168.0.0/24_80
+          statPrefix: meshpassthrough_http_192_168_0_0_24_80
+      name: meshpassthrough_http_192.168.0.0/24_80
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 80
+        prefixRanges:
+        - addressPrefix: 10.10.0.0
+          prefixLen: 16
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_10.10.0.0/16_80
+            virtualHosts:
+            - domains:
+              - '*'
+              name: 10.10.0.0/16
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_10.10.0.0/16_80
+          statPrefix: meshpassthrough_http_10_10_0_0_16_80
+      name: meshpassthrough_http_10.10.0.0/16_80
+    listenerFilters:
+    - name: envoy.filters.listener.tls_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
+    - name: envoy.filters.listener.http_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.http_inspector.v3.HttpInspector
+    name: outbound:passthrough:ipv4
+    trafficDirection: OUTBOUND
+- name: outbound:passthrough:ipv6
+  resource:
+    '@type': type.googleapis.com/envoy.config.listener.v3.Listener
+    address:
+      socketAddress:
+        address: '::'
+        portValue: 15001
+    filterChains:
+    - filters:
+      - name: envoy.filters.network.tcp_proxy
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+          cluster: outbound:passthrough:ipv6
+          statPrefix: outbound_passthrough_ipv6
+    name: outbound:passthrough:ipv6
+    trafficDirection: OUTBOUND
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/http-domains-aggregated.clusters.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/http-domains-aggregated.clusters.golden.yaml
new file mode 100644
index 000000000..a4810ac41
--- /dev/null
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/http-domains-aggregated.clusters.golden.yaml
@@ -0,0 +1,49 @@
+resources:
+- name: meshpassthrough_http_*.example.com_*
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http___example_com__
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_*.example.com_*
+    type: ORIGINAL_DST
+- name: meshpassthrough_http_*.example.com_80
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http___example_com_80
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_*.example.com_80
+    type: ORIGINAL_DST
+- name: meshpassthrough_http_anotherexample.com_*
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_anotherexample_com__
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_anotherexample.com_*
+    type: ORIGINAL_DST
+- name: meshpassthrough_http_anotherexample.com_80
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_anotherexample_com_80
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_anotherexample.com_80
+    type: ORIGINAL_DST
+- name: meshpassthrough_http_example1.com_80
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_example1_com_80
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_example1.com_80
+    type: ORIGINAL_DST
+- name: meshpassthrough_http_example2.com_80
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_example2_com_80
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_example2.com_80
+    type: ORIGINAL_DST
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/http-domains-aggregated.listener.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/http-domains-aggregated.listener.golden.yaml
new file mode 100644
index 000000000..1d1a73fc7
--- /dev/null
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/http-domains-aggregated.listener.golden.yaml
@@ -0,0 +1,259 @@
+resources:
+- name: outbound:passthrough:ipv4
+  resource:
+    '@type': type.googleapis.com/envoy.config.listener.v3.Listener
+    address:
+      socketAddress:
+        address: 0.0.0.0
+        portValue: 15001
+    filterChains:
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 80
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_80
+            virtualHosts:
+            - domains:
+              - anotherexample.com
+              - anotherexample.com:80
+              name: anotherexample.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_anotherexample.com_80
+            - domains:
+              - example1.com
+              - example1.com:80
+              name: example1.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_example1.com_80
+            - domains:
+              - example2.com
+              - example2.com:80
+              name: example2.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_example2.com_80
+            - domains:
+              - '*.example.com'
+              - '*.example.com:80'
+              name: '*.example.com'
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_*.example.com_80
+            - domains:
+              - '*'
+              name: no_match
+              routes:
+              - directResponse:
+                  body:
+                    inlineString: |
+                      This response comes from Kuma Sidecar. No routes matched this domain - check configuration of your MeshPassthrough policy.
+                  status: 503
+                match:
+                  prefix: /
+          statPrefix: meshpassthrough_http_80
+      name: meshpassthrough_http_80
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_*
+            virtualHosts:
+            - domains:
+              - anotherexample.com
+              - anotherexample.com:*
+              name: anotherexample.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_anotherexample.com_*
+            - domains:
+              - '*.example.com'
+              name: '*.example.com'
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_*.example.com_*
+            - domains:
+              - '*'
+              name: no_match
+              routes:
+              - directResponse:
+                  body:
+                    inlineString: |
+                      This response comes from Kuma Sidecar. No routes matched this domain - check configuration of your MeshPassthrough policy.
+                  status: 503
+                match:
+                  prefix: /
+          statPrefix: meshpassthrough_http__
+      name: meshpassthrough_http_*
+    listenerFilters:
+    - name: envoy.filters.listener.tls_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
+    - name: envoy.filters.listener.http_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.http_inspector.v3.HttpInspector
+    name: outbound:passthrough:ipv4
+    trafficDirection: OUTBOUND
+- name: outbound:passthrough:ipv6
+  resource:
+    '@type': type.googleapis.com/envoy.config.listener.v3.Listener
+    address:
+      socketAddress:
+        address: '::'
+        portValue: 15001
+    filterChains:
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 80
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_80
+            virtualHosts:
+            - domains:
+              - anotherexample.com
+              - anotherexample.com:80
+              name: anotherexample.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_anotherexample.com_80
+            - domains:
+              - example1.com
+              - example1.com:80
+              name: example1.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_example1.com_80
+            - domains:
+              - example2.com
+              - example2.com:80
+              name: example2.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_example2.com_80
+            - domains:
+              - '*.example.com'
+              - '*.example.com:80'
+              name: '*.example.com'
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_*.example.com_80
+            - domains:
+              - '*'
+              name: no_match
+              routes:
+              - directResponse:
+                  body:
+                    inlineString: |
+                      This response comes from Kuma Sidecar. No routes matched this domain - check configuration of your MeshPassthrough policy.
+                  status: 503
+                match:
+                  prefix: /
+          statPrefix: meshpassthrough_http_80
+      name: meshpassthrough_http_80
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_*
+            virtualHosts:
+            - domains:
+              - anotherexample.com
+              - anotherexample.com:*
+              name: anotherexample.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_anotherexample.com_*
+            - domains:
+              - '*.example.com'
+              name: '*.example.com'
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_*.example.com_*
+            - domains:
+              - '*'
+              name: no_match
+              routes:
+              - directResponse:
+                  body:
+                    inlineString: |
+                      This response comes from Kuma Sidecar. No routes matched this domain - check configuration of your MeshPassthrough policy.
+                  status: 503
+                match:
+                  prefix: /
+          statPrefix: meshpassthrough_http__
+      name: meshpassthrough_http_*
+    listenerFilters:
+    - name: envoy.filters.listener.tls_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
+    - name: envoy.filters.listener.http_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.http_inspector.v3.HttpInspector
+    name: outbound:passthrough:ipv6
+    trafficDirection: OUTBOUND
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/http-domains.clusters.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/http-domains.clusters.golden.yaml
new file mode 100644
index 000000000..db01f5257
--- /dev/null
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/http-domains.clusters.golden.yaml
@@ -0,0 +1,25 @@
+resources:
+- name: meshpassthrough_http_www.anotherexample.com_*
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_www_anotherexample_com__
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_www.anotherexample.com_*
+    type: ORIGINAL_DST
+- name: meshpassthrough_http_www.anotherexample.com_80
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_www_anotherexample_com_80
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_www.anotherexample.com_80
+    type: ORIGINAL_DST
+- name: meshpassthrough_http_www.example.com_80
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_www_example_com_80
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_www.example.com_80
+    type: ORIGINAL_DST
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/http-domains.listener.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/http-domains.listener.golden.yaml
new file mode 100644
index 000000000..4c65f7df3
--- /dev/null
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/http-domains.listener.golden.yaml
@@ -0,0 +1,207 @@
+resources:
+- name: outbound:passthrough:ipv4
+  resource:
+    '@type': type.googleapis.com/envoy.config.listener.v3.Listener
+    address:
+      socketAddress:
+        address: 0.0.0.0
+        portValue: 15001
+    filterChains:
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 80
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_80
+            virtualHosts:
+            - domains:
+              - www.anotherexample.com
+              - www.anotherexample.com:80
+              name: www.anotherexample.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_www.anotherexample.com_80
+            - domains:
+              - www.example.com
+              - www.example.com:80
+              name: www.example.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_www.example.com_80
+            - domains:
+              - '*'
+              name: no_match
+              routes:
+              - directResponse:
+                  body:
+                    inlineString: |
+                      This response comes from Kuma Sidecar. No routes matched this domain - check configuration of your MeshPassthrough policy.
+                  status: 503
+                match:
+                  prefix: /
+          statPrefix: meshpassthrough_http_80
+      name: meshpassthrough_http_80
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_*
+            virtualHosts:
+            - domains:
+              - www.anotherexample.com
+              - www.anotherexample.com:*
+              name: www.anotherexample.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_www.anotherexample.com_*
+            - domains:
+              - '*'
+              name: no_match
+              routes:
+              - directResponse:
+                  body:
+                    inlineString: |
+                      This response comes from Kuma Sidecar. No routes matched this domain - check configuration of your MeshPassthrough policy.
+                  status: 503
+                match:
+                  prefix: /
+          statPrefix: meshpassthrough_http__
+      name: meshpassthrough_http_*
+    listenerFilters:
+    - name: envoy.filters.listener.tls_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
+    - name: envoy.filters.listener.http_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.http_inspector.v3.HttpInspector
+    name: outbound:passthrough:ipv4
+    trafficDirection: OUTBOUND
+- name: outbound:passthrough:ipv6
+  resource:
+    '@type': type.googleapis.com/envoy.config.listener.v3.Listener
+    address:
+      socketAddress:
+        address: '::'
+        portValue: 15001
+    filterChains:
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 80
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_80
+            virtualHosts:
+            - domains:
+              - www.anotherexample.com
+              - www.anotherexample.com:80
+              name: www.anotherexample.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_www.anotherexample.com_80
+            - domains:
+              - www.example.com
+              - www.example.com:80
+              name: www.example.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_www.example.com_80
+            - domains:
+              - '*'
+              name: no_match
+              routes:
+              - directResponse:
+                  body:
+                    inlineString: |
+                      This response comes from Kuma Sidecar. No routes matched this domain - check configuration of your MeshPassthrough policy.
+                  status: 503
+                match:
+                  prefix: /
+          statPrefix: meshpassthrough_http_80
+      name: meshpassthrough_http_80
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_*
+            virtualHosts:
+            - domains:
+              - www.anotherexample.com
+              - www.anotherexample.com:*
+              name: www.anotherexample.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_www.anotherexample.com_*
+            - domains:
+              - '*'
+              name: no_match
+              routes:
+              - directResponse:
+                  body:
+                    inlineString: |
+                      This response comes from Kuma Sidecar. No routes matched this domain - check configuration of your MeshPassthrough policy.
+                  status: 503
+                match:
+                  prefix: /
+          statPrefix: meshpassthrough_http__
+      name: meshpassthrough_http_*
+    listenerFilters:
+    - name: envoy.filters.listener.tls_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
+    - name: envoy.filters.listener.http_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.http_inspector.v3.HttpInspector
+    name: outbound:passthrough:ipv6
+    trafficDirection: OUTBOUND
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/only-ipv4-rules.clusters.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/only-ipv4-rules.clusters.golden.yaml
index 4e732e0d7..d92305be8 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/only-ipv4-rules.clusters.golden.yaml
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/only-ipv4-rules.clusters.golden.yaml
@@ -1,9 +1,9 @@
 resources:
-- name: meshpassthrough_192.168.0.0_80
+- name: meshpassthrough_tcp_192.168.0.0_80
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_192_168_0_0_80
+    altStatName: meshpassthrough_tcp_192_168_0_0_80
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_192.168.0.0_80
+    name: meshpassthrough_tcp_192.168.0.0_80
     type: ORIGINAL_DST
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/only-ipv4-rules.listener.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/only-ipv4-rules.listener.golden.yaml
index c5f046106..2d2cb409f 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/only-ipv4-rules.listener.golden.yaml
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/only-ipv4-rules.listener.golden.yaml
@@ -17,9 +17,9 @@ resources:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_192.168.0.0_80
-          statPrefix: meshpassthrough_192_168_0_0_80
-      name: meshpassthrough_192.168.0.0_80
+          cluster: meshpassthrough_tcp_192.168.0.0_80
+          statPrefix: meshpassthrough_tcp_192_168_0_0_80
+      name: meshpassthrough_tcp_192.168.0.0_80
     listenerFilters:
     - name: envoy.filters.listener.tls_inspector
       typedConfig:
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/same-protocol.clusters.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/same-protocol.clusters.golden.yaml
new file mode 100644
index 000000000..83f640342
--- /dev/null
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/same-protocol.clusters.golden.yaml
@@ -0,0 +1,25 @@
+resources:
+- name: meshpassthrough_http_10.42.0.8_*
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_10_42_0_8__
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_10.42.0.8_*
+    type: ORIGINAL_DST
+- name: meshpassthrough_http_10.42.0.8_80
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_10_42_0_8_80
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_10.42.0.8_80
+    type: ORIGINAL_DST
+- name: meshpassthrough_http_www.gmail.com_80
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    altStatName: meshpassthrough_http_www_gmail_com_80
+    connectTimeout: 5s
+    lbPolicy: CLUSTER_PROVIDED
+    name: meshpassthrough_http_www.gmail.com_80
+    type: ORIGINAL_DST
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/same-protocol.listener.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/same-protocol.listener.golden.yaml
new file mode 100644
index 000000000..a842db83e
--- /dev/null
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/same-protocol.listener.golden.yaml
@@ -0,0 +1,172 @@
+resources:
+- name: outbound:passthrough:ipv4
+  resource:
+    '@type': type.googleapis.com/envoy.config.listener.v3.Listener
+    address:
+      socketAddress:
+        address: 0.0.0.0
+        portValue: 15001
+    filterChains:
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 80
+        prefixRanges:
+        - addressPrefix: 10.42.0.8
+          prefixLen: 32
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_10.42.0.8_80
+            virtualHosts:
+            - domains:
+              - '*'
+              name: 10.42.0.8
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_10.42.0.8_80
+          statPrefix: meshpassthrough_http_10_42_0_8_80
+      name: meshpassthrough_http_10.42.0.8_80
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        prefixRanges:
+        - addressPrefix: 10.42.0.8
+          prefixLen: 32
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_10.42.0.8_*
+            virtualHosts:
+            - domains:
+              - '*'
+              name: 10.42.0.8
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_10.42.0.8_*
+          statPrefix: meshpassthrough_http_10_42_0_8__
+      name: meshpassthrough_http_10.42.0.8_*
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 80
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_80
+            virtualHosts:
+            - domains:
+              - www.gmail.com
+              - www.gmail.com:80
+              name: www.gmail.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_www.gmail.com_80
+            - domains:
+              - '*'
+              name: no_match
+              routes:
+              - directResponse:
+                  body:
+                    inlineString: |
+                      This response comes from Kuma Sidecar. No routes matched this domain - check configuration of your MeshPassthrough policy.
+                  status: 503
+                match:
+                  prefix: /
+          statPrefix: meshpassthrough_http_80
+      name: meshpassthrough_http_80
+    listenerFilters:
+    - name: envoy.filters.listener.tls_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
+    - name: envoy.filters.listener.http_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.http_inspector.v3.HttpInspector
+    name: outbound:passthrough:ipv4
+    trafficDirection: OUTBOUND
+- name: outbound:passthrough:ipv6
+  resource:
+    '@type': type.googleapis.com/envoy.config.listener.v3.Listener
+    address:
+      socketAddress:
+        address: '::'
+        portValue: 15001
+    filterChains:
+    - filterChainMatch:
+        applicationProtocols:
+        - http/1.1
+        - h2c
+        destinationPort: 80
+        transportProtocol: raw_buffer
+      filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          httpFilters:
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          routeConfig:
+            name: meshpassthrough_http_80
+            virtualHosts:
+            - domains:
+              - www.gmail.com
+              - www.gmail.com:80
+              name: www.gmail.com
+              routes:
+              - match:
+                  prefix: /
+                route:
+                  cluster: meshpassthrough_http_www.gmail.com_80
+            - domains:
+              - '*'
+              name: no_match
+              routes:
+              - directResponse:
+                  body:
+                    inlineString: |
+                      This response comes from Kuma Sidecar. No routes matched this domain - check configuration of your MeshPassthrough policy.
+                  status: 503
+                match:
+                  prefix: /
+          statPrefix: meshpassthrough_http_80
+      name: meshpassthrough_http_80
+    listenerFilters:
+    - name: envoy.filters.listener.tls_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
+    - name: envoy.filters.listener.http_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.http_inspector.v3.HttpInspector
+    name: outbound:passthrough:ipv6
+    trafficDirection: OUTBOUND
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/simple.clusters.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/simple.clusters.golden.yaml
index acfd6b8c4..6e10d3aec 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/simple.clusters.golden.yaml
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/simple.clusters.golden.yaml
@@ -1,17 +1,17 @@
 resources:
-- name: meshpassthrough_192.168.0.0_80
+- name: meshpassthrough_http_api.example.com_80
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_192_168_0_0_80
+    altStatName: meshpassthrough_http_api_example_com_80
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_192.168.0.0_80
+    name: meshpassthrough_http_api.example.com_80
     type: ORIGINAL_DST
-- name: meshpassthrough_api.example.com_80
+- name: meshpassthrough_tcp_192.168.0.0_80
   resource:
     '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
-    altStatName: meshpassthrough_api_example_com_80
+    altStatName: meshpassthrough_tcp_192_168_0_0_80
     connectTimeout: 5s
     lbPolicy: CLUSTER_PROVIDED
-    name: meshpassthrough_api.example.com_80
+    name: meshpassthrough_tcp_192.168.0.0_80
     type: ORIGINAL_DST
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/simple.listener.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/simple.listener.golden.yaml
index b0b8f1cc3..2b4e4a5a7 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/simple.listener.golden.yaml
+++ b/pkg/plugins/policies/meshpassthrough/plugin/v1alpha1/testdata/simple.listener.golden.yaml
@@ -17,13 +17,14 @@ resources:
       - name: envoy.filters.network.tcp_proxy
         typedConfig:
           '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-          cluster: meshpassthrough_192.168.0.0_80
-          statPrefix: meshpassthrough_192_168_0_0_80
-      name: meshpassthrough_192.168.0.0_80
+          cluster: meshpassthrough_tcp_192.168.0.0_80
+          statPrefix: meshpassthrough_tcp_192_168_0_0_80
+      name: meshpassthrough_tcp_192.168.0.0_80
     - filterChainMatch:
         applicationProtocols:
         - http/1.1
         - h2c
+        destinationPort: 80
         transportProtocol: raw_buffer
       filters:
       - name: envoy.filters.network.http_connection_manager
@@ -38,12 +39,13 @@ resources:
             virtualHosts:
             - domains:
               - api.example.com
+              - api.example.com:80
               name: api.example.com
               routes:
               - match:
                   prefix: /
                 route:
-                  cluster: meshpassthrough_api.example.com_80
+                  cluster: meshpassthrough_http_api.example.com_80
             - domains:
               - '*'
               name: no_match
@@ -78,6 +80,7 @@ resources:
         applicationProtocols:
         - http/1.1
         - h2c
+        destinationPort: 80
         transportProtocol: raw_buffer
       filters:
       - name: envoy.filters.network.http_connection_manager
@@ -92,12 +95,13 @@ resources:
             virtualHosts:
             - domains:
               - api.example.com
+              - api.example.com:80
               name: api.example.com
               routes:
               - match:
                   prefix: /
                 route:
-                  cluster: meshpassthrough_api.example.com_80
+                  cluster: meshpassthrough_http_api.example.com_80
             - domains:
               - '*'
               name: no_match
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/xds/order_test.go b/pkg/plugins/policies/meshpassthrough/plugin/xds/order_test.go
index 191988196..a28090fa8 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/xds/order_test.go
+++ b/pkg/plugins/policies/meshpassthrough/plugin/xds/order_test.go
@@ -22,9 +22,9 @@ var _ = Describe("Match order", func() {
 	DescribeTable("should generate proper order",
 		func(given validTestCase) {
 			// when
-			ordered, _ := plugin_xds.GetOrderedMatchers(given.conf)
+			orderedFilterChainMatches, _ := plugin_xds.GetOrderedMatchers(given.conf)
 
-			yaml, err := yaml.Marshal(ordered)
+			yaml, err := yaml.Marshal(orderedFilterChainMatches)
 			// then
 			Expect(err).ToNot(HaveOccurred())
 			Expect(yaml).To(matchers.MatchGoldenYAML(fmt.Sprintf("testdata/%s", given.orderedGolden)))
@@ -35,7 +35,7 @@ var _ = Describe("Match order", func() {
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "api.example.com",
-						Port:     pointer.To[int](443),
+						Port:     pointer.To[uint32](443),
 						Protocol: api.ProtocolType("tls"),
 					},
 					{
@@ -46,50 +46,60 @@ var _ = Describe("Match order", func() {
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "example.com",
-						Port:     pointer.To[int](443),
+						Port:     pointer.To[uint32](443),
 						Protocol: api.ProtocolType("tls"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "*.example.com",
-						Port:     pointer.To[int](443),
+						Port:     pointer.To[uint32](443),
 						Protocol: api.ProtocolType("tls"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "example.com",
-						Port:     pointer.To[int](8080),
+						Port:     pointer.To[uint32](8080),
 						Protocol: api.ProtocolType("http"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "other.com",
-						Port:     pointer.To[int](8080),
+						Port:     pointer.To[uint32](8080),
 						Protocol: api.ProtocolType("http"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "anotherhttp.com",
-						Port:     pointer.To[int](8080),
+						Port:     pointer.To[uint32](8080),
 						Protocol: api.ProtocolType("http"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "http2.com",
-						Port:     pointer.To[int](9000),
+						Port:     pointer.To[uint32](9000),
 						Protocol: api.ProtocolType("http2"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "grpc.com",
-						Port:     pointer.To[int](9001),
+						Port:     pointer.To[uint32](9001),
 						Protocol: api.ProtocolType("grpc"),
 					},
+					{
+						Type:     api.MatchType("Domain"),
+						Value:    "*.example.com",
+						Protocol: api.ProtocolType("http"),
+					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "*.example.com",
 						Protocol: api.ProtocolType("tls"),
 					},
+					{
+						Type:     api.MatchType("IP"),
+						Value:    "10.42.0.8",
+						Protocol: api.ProtocolType("http"),
+					},
 					{
 						Type:     api.MatchType("IP"),
 						Value:    "192.168.19.1",
@@ -98,7 +108,7 @@ var _ = Describe("Match order", func() {
 					{
 						Type:     api.MatchType("IP"),
 						Value:    "192.168.0.1",
-						Port:     pointer.To[int](9091),
+						Port:     pointer.To[uint32](9091),
 						Protocol: api.ProtocolType("tcp"),
 					},
 					{
@@ -116,6 +126,16 @@ var _ = Describe("Match order", func() {
 						Value:    "192.168.0.1/30",
 						Protocol: api.ProtocolType("tcp"),
 					},
+					{
+						Type:     api.MatchType("CIDR"),
+						Value:    "240.0.0.0/4",
+						Protocol: api.ProtocolType("http"),
+					},
+					{
+						Type:     api.MatchType("CIDR"),
+						Value:    "172.18.0.0/16",
+						Protocol: api.ProtocolType("http"),
+					},
 					{
 						Type:     api.MatchType("IP"),
 						Value:    "b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6",
@@ -124,7 +144,7 @@ var _ = Describe("Match order", func() {
 					{
 						Type:     api.MatchType("IP"),
 						Value:    "9942:9abf:d0e0:f2da:2290:333b:e590:f497",
-						Port:     pointer.To[int](9091),
+						Port:     pointer.To[uint32](9091),
 						Protocol: api.ProtocolType("tcp"),
 					},
 					{
@@ -147,57 +167,73 @@ var _ = Describe("Match order", func() {
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "api.example.com",
-						Port:     pointer.To[int](443),
+						Port:     pointer.To[uint32](443),
 						Protocol: api.ProtocolType("tls"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "api.example.com",
-						Port:     pointer.To[int](443),
+						Port:     pointer.To[uint32](443),
 						Protocol: api.ProtocolType("http"),
 					},
 					{
 						Type:     api.MatchType("IP"),
 						Value:    "127.0.0.1",
-						Port:     pointer.To[int](443),
+						Port:     pointer.To[uint32](443),
 						Protocol: api.ProtocolType("tcp"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "api.example.com",
-						Port:     pointer.To[int](9090),
+						Port:     pointer.To[uint32](9090),
 						Protocol: api.ProtocolType("tls"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "api.example.com",
-						Port:     pointer.To[int](9090),
+						Port:     pointer.To[uint32](9090),
 						Protocol: api.ProtocolType("http2"),
 					},
 					{
 						Type:     api.MatchType("IP"),
 						Value:    "127.0.0.1",
-						Port:     pointer.To[int](9090),
+						Port:     pointer.To[uint32](9090),
 						Protocol: api.ProtocolType("tcp"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "api.example.com",
-						Port:     pointer.To[int](9091),
+						Port:     pointer.To[uint32](9091),
 						Protocol: api.ProtocolType("tls"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "api.example.com",
-						Port:     pointer.To[int](9091),
+						Port:     pointer.To[uint32](9091),
 						Protocol: api.ProtocolType("grpc"),
 					},
 					{
 						Type:     api.MatchType("IP"),
 						Value:    "127.0.0.1",
-						Port:     pointer.To[int](9091),
+						Port:     pointer.To[uint32](9091),
+						Protocol: api.ProtocolType("tcp"),
+					},
+					{
+						Type:     api.MatchType("IP"),
+						Value:    "127.0.0.1",
 						Protocol: api.ProtocolType("tcp"),
 					},
+					{
+						Type:     api.MatchType("Domain"),
+						Value:    "httpbin.com",
+						Port:     pointer.To[uint32](80),
+						Protocol: api.ProtocolType("http"),
+					},
+					{
+						Type:     api.MatchType("IP"),
+						Value:    "10.22.22.1",
+						Protocol: api.ProtocolType("http"),
+					},
 				},
 			},
 			orderedGolden: "ordered-diff-protocols.golden.yaml",
@@ -225,37 +261,37 @@ var _ = Describe("Match order", func() {
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "example.com",
-						Port:     pointer.To[int](8080),
+						Port:     pointer.To[uint32](8080),
 						Protocol: api.ProtocolType("http"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "another.com",
-						Port:     pointer.To[int](8080),
+						Port:     pointer.To[uint32](8080),
 						Protocol: api.ProtocolType("http2"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "other.com",
-						Port:     pointer.To[int](8080),
+						Port:     pointer.To[uint32](8080),
 						Protocol: api.ProtocolType("tcp"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "anotherhttp.com",
-						Port:     pointer.To[int](9001),
+						Port:     pointer.To[uint32](9001),
 						Protocol: api.ProtocolType("http"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "http2.com",
-						Port:     pointer.To[int](9001),
+						Port:     pointer.To[uint32](9001),
 						Protocol: api.ProtocolType("http2"),
 					},
 					{
 						Type:     api.MatchType("Domain"),
 						Value:    "grpc.com",
-						Port:     pointer.To[int](9001),
+						Port:     pointer.To[uint32](9001),
 						Protocol: api.ProtocolType("grpc"),
 					},
 				},
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/xds/testdata/ordered-diff-protocols.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/xds/testdata/ordered-diff-protocols.golden.yaml
index bedb2515e..90d914cd7 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/xds/testdata/ordered-diff-protocols.golden.yaml
+++ b/pkg/plugins/policies/meshpassthrough/plugin/xds/testdata/ordered-diff-protocols.golden.yaml
@@ -1,45 +1,93 @@
-- Port: 9091
+- MatchType: 2
+  Port: 9091
   Protocol: tls
-  Routes:
-  - MatchType: 1
-    Value: api.example.com
-- Port: 9090
+  Routes: []
+  Value: api.example.com
+- MatchType: 2
+  Port: 9090
   Protocol: tls
-  Routes:
-  - MatchType: 1
-    Value: api.example.com
-- Port: 443
+  Routes: []
+  Value: api.example.com
+- MatchType: 2
+  Port: 443
   Protocol: tls
-  Routes:
-  - MatchType: 1
-    Value: api.example.com
-- Port: 9091
+  Routes: []
+  Value: api.example.com
+- MatchType: 5
+  Port: 9091
   Protocol: tcp
-  Routes:
-  - MatchType: 3
-    Value: 127.0.0.1
-- Port: 9090
+  Routes: []
+  Value: 127.0.0.1
+- MatchType: 5
+  Port: 9090
   Protocol: tcp
-  Routes:
-  - MatchType: 3
-    Value: 127.0.0.1
-- Port: 443
+  Routes: []
+  Value: 127.0.0.1
+- MatchType: 5
+  Port: 443
   Protocol: tcp
+  Routes: []
+  Value: 127.0.0.1
+- MatchType: 5
+  Port: 80
+  Protocol: tcp
+  Routes: []
+  Value: 127.0.0.1
+- MatchType: 5
+  Port: 0
+  Protocol: tcp
+  Routes: []
+  Value: 127.0.0.1
+- MatchType: 5
+  Port: 9091
+  Protocol: http
+  Routes: []
+  Value: 10.22.22.1
+- MatchType: 5
+  Port: 9090
+  Protocol: http
+  Routes: []
+  Value: 10.22.22.1
+- MatchType: 5
+  Port: 443
+  Protocol: http
+  Routes: []
+  Value: 10.22.22.1
+- MatchType: 5
+  Port: 80
+  Protocol: http
+  Routes: []
+  Value: 10.22.22.1
+- MatchType: 5
+  Port: 0
+  Protocol: http
+  Routes: []
+  Value: 10.22.22.1
+- MatchType: 2
+  Port: 443
+  Protocol: http
   Routes:
-  - MatchType: 3
-    Value: 127.0.0.1
-- Port: 9090
-  Protocol: http2
-  Routes:
-  - MatchType: 1
+  - MatchType: 2
     Value: api.example.com
-- Port: 443
+  Value: ""
+- MatchType: 2
+  Port: 80
   Protocol: http
   Routes:
-  - MatchType: 1
+  - MatchType: 2
+    Value: httpbin.com
+  Value: ""
+- MatchType: 2
+  Port: 9090
+  Protocol: http2
+  Routes:
+  - MatchType: 2
     Value: api.example.com
-- Port: 9091
+  Value: ""
+- MatchType: 2
+  Port: 9091
   Protocol: grpc
   Routes:
-  - MatchType: 1
+  - MatchType: 2
     Value: api.example.com
+  Value: ""
diff --git a/pkg/plugins/policies/meshpassthrough/plugin/xds/testdata/ordered.golden.yaml b/pkg/plugins/policies/meshpassthrough/plugin/xds/testdata/ordered.golden.yaml
index 3111afba4..bf71e0205 100644
--- a/pkg/plugins/policies/meshpassthrough/plugin/xds/testdata/ordered.golden.yaml
+++ b/pkg/plugins/policies/meshpassthrough/plugin/xds/testdata/ordered.golden.yaml
@@ -1,62 +1,419 @@
-- Port: 443
+- MatchType: 6
+  Port: 9091
   Protocol: tls
+  Routes: []
+  Value: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
+- MatchType: 6
+  Port: 9001
+  Protocol: tls
+  Routes: []
+  Value: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
+- MatchType: 6
+  Port: 9000
+  Protocol: tls
+  Routes: []
+  Value: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
+- MatchType: 6
+  Port: 8080
+  Protocol: tls
+  Routes: []
+  Value: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
+- MatchType: 6
+  Port: 443
+  Protocol: tls
+  Routes: []
+  Value: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
+- MatchType: 6
+  Port: 0
+  Protocol: tls
+  Routes: []
+  Value: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
+- MatchType: 5
+  Port: 9091
+  Protocol: tls
+  Routes: []
+  Value: 192.168.19.1
+- MatchType: 5
+  Port: 9001
+  Protocol: tls
+  Routes: []
+  Value: 192.168.19.1
+- MatchType: 5
+  Port: 9000
+  Protocol: tls
+  Routes: []
+  Value: 192.168.19.1
+- MatchType: 5
+  Port: 8080
+  Protocol: tls
+  Routes: []
+  Value: 192.168.19.1
+- MatchType: 5
+  Port: 443
+  Protocol: tls
+  Routes: []
+  Value: 192.168.19.1
+- MatchType: 5
+  Port: 0
+  Protocol: tls
+  Routes: []
+  Value: 192.168.19.1
+- MatchType: 2
+  Port: 9091
+  Protocol: tls
+  Routes: []
+  Value: api.example.com
+- MatchType: 2
+  Port: 9001
+  Protocol: tls
+  Routes: []
+  Value: api.example.com
+- MatchType: 2
+  Port: 9000
+  Protocol: tls
+  Routes: []
+  Value: api.example.com
+- MatchType: 2
+  Port: 8080
+  Protocol: tls
+  Routes: []
+  Value: api.example.com
+- MatchType: 2
+  Port: 443
+  Protocol: tls
+  Routes: []
+  Value: api.example.com
+- MatchType: 2
+  Port: 443
+  Protocol: tls
+  Routes: []
+  Value: example.com
+- MatchType: 2
+  Port: 0
+  Protocol: tls
+  Routes: []
+  Value: api.example.com
+- MatchType: 1
+  Port: 9091
+  Protocol: tls
+  Routes: []
+  Value: '*.example.com'
+- MatchType: 1
+  Port: 9001
+  Protocol: tls
+  Routes: []
+  Value: '*.example.com'
+- MatchType: 1
+  Port: 9000
+  Protocol: tls
+  Routes: []
+  Value: '*.example.com'
+- MatchType: 1
+  Port: 8080
+  Protocol: tls
+  Routes: []
+  Value: '*.example.com'
+- MatchType: 1
+  Port: 443
+  Protocol: tls
+  Routes: []
+  Value: '*.example.com'
+- MatchType: 1
+  Port: 0
+  Protocol: tls
+  Routes: []
+  Value: '*.example.com'
+- MatchType: 6
+  Port: 9091
+  Protocol: tcp
+  Routes: []
+  Value: 9942:9abf:d0e0:f2da:2290:333b:e590:f497
+- MatchType: 5
+  Port: 9091
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1
+- MatchType: 4
+  Port: 9091
+  Protocol: tcp
+  Routes: []
+  Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/96
+- MatchType: 4
+  Port: 9091
+  Protocol: tcp
+  Routes: []
+  Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/64
+- MatchType: 4
+  Port: 9001
+  Protocol: tcp
+  Routes: []
+  Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/96
+- MatchType: 4
+  Port: 9001
+  Protocol: tcp
+  Routes: []
+  Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/64
+- MatchType: 4
+  Port: 9000
+  Protocol: tcp
+  Routes: []
+  Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/96
+- MatchType: 4
+  Port: 9000
+  Protocol: tcp
+  Routes: []
+  Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/64
+- MatchType: 4
+  Port: 8080
+  Protocol: tcp
+  Routes: []
+  Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/96
+- MatchType: 4
+  Port: 8080
+  Protocol: tcp
+  Routes: []
+  Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/64
+- MatchType: 4
+  Port: 443
+  Protocol: tcp
+  Routes: []
+  Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/96
+- MatchType: 4
+  Port: 443
+  Protocol: tcp
+  Routes: []
+  Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/64
+- MatchType: 4
+  Port: 0
+  Protocol: tcp
+  Routes: []
+  Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/96
+- MatchType: 4
+  Port: 0
+  Protocol: tcp
+  Routes: []
+  Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/64
+- MatchType: 3
+  Port: 9091
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1/30
+- MatchType: 3
+  Port: 9091
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1/24
+- MatchType: 3
+  Port: 9001
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1/30
+- MatchType: 3
+  Port: 9001
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1/24
+- MatchType: 3
+  Port: 9000
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1/30
+- MatchType: 3
+  Port: 9000
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1/24
+- MatchType: 3
+  Port: 8080
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1/30
+- MatchType: 3
+  Port: 8080
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1/24
+- MatchType: 3
+  Port: 443
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1/30
+- MatchType: 3
+  Port: 443
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1/24
+- MatchType: 3
+  Port: 0
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1/30
+- MatchType: 3
+  Port: 0
+  Protocol: tcp
+  Routes: []
+  Value: 192.168.0.1/24
+- MatchType: 5
+  Port: 9091
+  Protocol: http
+  Routes: []
+  Value: 10.42.0.8
+- MatchType: 5
+  Port: 9001
+  Protocol: http
+  Routes: []
+  Value: 10.42.0.8
+- MatchType: 5
+  Port: 9000
+  Protocol: http
+  Routes: []
+  Value: 10.42.0.8
+- MatchType: 5
+  Port: 8080
+  Protocol: http
+  Routes: []
+  Value: 10.42.0.8
+- MatchType: 5
+  Port: 443
+  Protocol: http
+  Routes: []
+  Value: 10.42.0.8
+- MatchType: 5
+  Port: 0
+  Protocol: http
+  Routes: []
+  Value: 10.42.0.8
+- MatchType: 3
+  Port: 9091
+  Protocol: http
+  Routes: []
+  Value: 172.18.0.0/16
+- MatchType: 3
+  Port: 9091
+  Protocol: http
+  Routes: []
+  Value: 240.0.0.0/4
+- MatchType: 3
+  Port: 9001
+  Protocol: http
+  Routes: []
+  Value: 172.18.0.0/16
+- MatchType: 3
+  Port: 9001
+  Protocol: http
+  Routes: []
+  Value: 240.0.0.0/4
+- MatchType: 3
+  Port: 9000
+  Protocol: http
+  Routes: []
+  Value: 172.18.0.0/16
+- MatchType: 3
+  Port: 9000
+  Protocol: http
+  Routes: []
+  Value: 240.0.0.0/4
+- MatchType: 3
+  Port: 8080
+  Protocol: http
+  Routes: []
+  Value: 172.18.0.0/16
+- MatchType: 3
+  Port: 8080
+  Protocol: http
+  Routes: []
+  Value: 240.0.0.0/4
+- MatchType: 3
+  Port: 443
+  Protocol: http
+  Routes: []
+  Value: 172.18.0.0/16
+- MatchType: 3
+  Port: 443
+  Protocol: http
+  Routes: []
+  Value: 240.0.0.0/4
+- MatchType: 3
+  Port: 0
+  Protocol: http
+  Routes: []
+  Value: 172.18.0.0/16
+- MatchType: 3
+  Port: 0
+  Protocol: http
+  Routes: []
+  Value: 240.0.0.0/4
+- MatchType: 2
+  Port: 9091
+  Protocol: http
   Routes:
-  - MatchType: 1
-    Value: api.example.com
-  - MatchType: 1
-    Value: example.com
   - MatchType: 2
+    Value: otherexample.com
+  - MatchType: 1
     Value: '*.example.com'
-- Port: 0
-  Protocol: tls
+  Value: ""
+- MatchType: 2
+  Port: 9001
+  Protocol: http
   Routes:
-  - MatchType: 1
-    Value: api.example.com
   - MatchType: 2
+    Value: otherexample.com
+  - MatchType: 1
     Value: '*.example.com'
-  - MatchType: 3
-    Value: 192.168.19.1
-  - MatchType: 4
-    Value: b6e5:a45e:70ae:e77f:d24e:5023:375d:20a6
-- Port: 9091
-  Protocol: tcp
-  Routes:
-  - MatchType: 3
-    Value: 192.168.0.1
-  - MatchType: 4
-    Value: 9942:9abf:d0e0:f2da:2290:333b:e590:f497
-- Port: 0
-  Protocol: tcp
-  Routes:
-  - MatchType: 5
-    Value: 192.168.0.1/30
-  - MatchType: 5
-    Value: 192.168.0.1/24
-  - MatchType: 6
-    Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/96
-  - MatchType: 6
-    Value: b0ce:f616:4e74:28f7:427c:b969:8016:6344/64
-- Port: 9000
-  Protocol: http2
+  Value: ""
+- MatchType: 2
+  Port: 9000
+  Protocol: http
   Routes:
+  - MatchType: 2
+    Value: otherexample.com
   - MatchType: 1
-    Value: http2.com
-- Port: 8080
+    Value: '*.example.com'
+  Value: ""
+- MatchType: 2
+  Port: 8080
   Protocol: http
   Routes:
-  - MatchType: 1
+  - MatchType: 2
     Value: anotherhttp.com
-  - MatchType: 1
+  - MatchType: 2
     Value: example.com
-  - MatchType: 1
+  - MatchType: 2
     Value: other.com
-- Port: 0
+  - MatchType: 2
+    Value: otherexample.com
+  - MatchType: 1
+    Value: '*.example.com'
+  Value: ""
+- MatchType: 2
+  Port: 443
   Protocol: http
   Routes:
+  - MatchType: 2
+    Value: otherexample.com
   - MatchType: 1
+    Value: '*.example.com'
+  Value: ""
+- MatchType: 2
+  Port: 0
+  Protocol: http
+  Routes:
+  - MatchType: 2
     Value: otherexample.com
-- Port: 9001
+  - MatchType: 1
+    Value: '*.example.com'
+  Value: ""
+- MatchType: 2
+  Port: 9000
+  Protocol: http2
+  Routes:
+  - MatchType: 2
+    Value: http2.com
+  Value: ""
+- MatchType: 2
+  Port: 9001
   Protocol: grpc
   Routes:
-  - MatchType: 1
+  - MatchType: 2
     Value: grpc.com
+  Value: ""