Repository: kumahq/kuma
Pull request #11363 (2024-09-09 18:48:03)

chore(deps): bump go to v1.23
Requires https://github.com/kumahq/kuma/pull/11362

### Checklist prior to review

<!--
Each of these sections need to be filled by the author when opening the PR.

If something doesn't apply please check the box and add a justification after the `--`
-->

- [x] [Link to relevant issue][1] as well as docs and UI issues --
- [x] This will not break child repos: it doesn't hardcode values (.e.g "kumahq" as a image registry) and it will work on Windows, system specific functions like `syscall.Mkfifo` have equivalent implementation on the other OS --
- [x] Tests (Unit test, E2E tests, manual test on universal and k8s) --
  - Don't forget `ci/` labels to run additional/fewer tests
- [x] Do you need to update [`UPGRADE.md`](../blob/master/UPGRADE.md)? --
- [x] Does it need to be backported according to the [backporting policy](../blob/master/CONTRIBUTING.md#backporting)? ([this](https://github.com/kumahq/kuma/actions/workflows/auto-backport.yaml) GH action will add "backport" label based on these [file globs](https://github.com/kumahq/kuma/blob/master/.github/workflows/auto-backport.yaml#L6), if you want to prevent it from adding the "backport" label use [no-backport-autolabel](https://github.com/kumahq/kuma/blob/master/.github/workflows/auto-backport.yaml#L8) label) --

<!--
> Changelog: skip
-->
<!--
Uncomment the above section to explicitly set a [`> Changelog:` entry here](https://github.com/kumahq/kuma/blob/master/CONTRIBUTING.md#submitting-a-patch)?
-->

[1]: https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword



Patch:
diff --git a/UPGRADE.md b/UPGRADE.md
index c9af21c3b..73df98251 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -8,6 +8,12 @@ does not have any particular instructions.
 
 ## Upgrade to `2.9.x`
 
+### MeshExternalService
+
+#### Removal of unix sockets support
+
+It's no longer possible to define a unix domain socket on the `address` field.
+
 ### Upgrading Transparent Proxy Configuration
 
 #### Removal of Deprecated IPv6 Redirection Flag and Annotation
diff --git a/deployments/charts/kuma/crds/kuma.io_meshexternalservices.yaml b/deployments/charts/kuma/crds/kuma.io_meshexternalservices.yaml
index 33b3e3b70..4e9e9bd17 100644
--- a/deployments/charts/kuma/crds/kuma.io_meshexternalservices.yaml
+++ b/deployments/charts/kuma/crds/kuma.io_meshexternalservices.yaml
@@ -48,9 +48,8 @@ spec:
                   properties:
                     address:
                       description: Address defines an address to which a user want
-                        to send a request. Is possible to provide `domain`, `ip` and
-                        `unix` sockets.
-                      example: unix:///tmp/example.sock
+                        to send a request. Is possible to provide `domain`, `ip`.
+                      example: example.com
                       minLength: 1
                       type: string
                     port:
diff --git a/docs/generated/openapi.yaml b/docs/generated/openapi.yaml
index da06dc2fd..8e923b400 100644
--- a/docs/generated/openapi.yaml
+++ b/docs/generated/openapi.yaml
@@ -11171,9 +11171,8 @@ components:
                   address:
                     description: >-
                       Address defines an address to which a user want to send a
-                      request. Is possible to provide `domain`, `ip` and `unix`
-                      sockets.
-                    example: unix:///tmp/example.sock
+                      request. Is possible to provide `domain`, `ip`.
+                    example: example.com
                     minLength: 1
                     type: string
                   port:
diff --git a/docs/generated/raw/crds/kuma.io_meshexternalservices.yaml b/docs/generated/raw/crds/kuma.io_meshexternalservices.yaml
index 33b3e3b70..4e9e9bd17 100644
--- a/docs/generated/raw/crds/kuma.io_meshexternalservices.yaml
+++ b/docs/generated/raw/crds/kuma.io_meshexternalservices.yaml
@@ -48,9 +48,8 @@ spec:
                   properties:
                     address:
                       description: Address defines an address to which a user want
-                        to send a request. Is possible to provide `domain`, `ip` and
-                        `unix` sockets.
-                      example: unix:///tmp/example.sock
+                        to send a request. Is possible to provide `domain`, `ip`.
+                      example: example.com
                       minLength: 1
                       type: string
                     port:
diff --git a/go.mod b/go.mod
index fbc607525..6cd09fd7d 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/kumahq/kuma
 
-go 1.22.7
+go 1.23.1
 
 require (
 	cirello.io/pglock v1.14.2
@@ -21,7 +21,7 @@ require (
 	github.com/go-logr/zapr v1.3.0
 	github.com/goburrow/cache v0.1.4
 	github.com/golang-jwt/jwt/v4 v4.5.0
-	github.com/golang-migrate/migrate/v4 v4.17.1
+	github.com/golang-migrate/migrate/v4 v4.18.1
 	github.com/golang/protobuf v1.5.4
 	github.com/google/go-cmp v0.6.0
 	github.com/google/uuid v1.6.0
@@ -42,7 +42,7 @@ require (
 	github.com/pkg/errors v0.9.1
 	github.com/prometheus/client_golang v1.20.3
 	github.com/prometheus/client_model v0.6.1
-	github.com/prometheus/common v0.58.0
+	github.com/prometheus/common v0.59.1
 	github.com/sethvargo/go-retry v0.3.0
 	github.com/shopspring/decimal v1.4.0
 	github.com/slok/go-http-metrics v0.12.0
@@ -105,7 +105,6 @@ require (
 	github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
 	github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b // indirect
-	github.com/containerd/containerd v1.7.18 // indirect
 	github.com/containerd/log v0.1.0 // indirect
 	github.com/containerd/platforms v0.2.1 // indirect
 	github.com/cpuguy83/dockercfg v0.3.1 // indirect
@@ -113,7 +112,7 @@ require (
 	github.com/cyphar/filepath-securejoin v0.2.4 // indirect
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
 	github.com/distribution/reference v0.6.0 // indirect
-	github.com/docker/docker v27.1.1+incompatible // indirect
+	github.com/docker/docker v27.2.0+incompatible // indirect
 	github.com/docker/go-connections v0.5.0 // indirect
 	github.com/docker/go-units v0.5.0 // indirect
 	github.com/fatih/color v1.17.0 // indirect
@@ -177,6 +176,7 @@ require (
 	github.com/moby/spdystream v0.4.0 // indirect
 	github.com/moby/sys/sequential v0.5.0 // indirect
 	github.com/moby/sys/user v0.1.0 // indirect
+	github.com/moby/sys/userns v0.1.0 // indirect
 	github.com/moby/term v0.5.0 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
@@ -207,12 +207,13 @@ require (
 	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
 	github.com/xeipuuv/gojsonschema v1.2.0 // indirect
 	github.com/yusufpapurcu/wmi v1.2.3 // indirect
-	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
+	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
 	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect
 	go.opentelemetry.io/otel/metric v1.29.0 // indirect
 	go.uber.org/atomic v1.10.0 // indirect
 	golang.org/x/crypto v0.27.0 // indirect
-	golang.org/x/mod v0.20.0 // indirect
+	golang.org/x/mod v0.21.0 // indirect
 	golang.org/x/oauth2 v0.22.0 // indirect
 	golang.org/x/sync v0.8.0 // indirect
 	golang.org/x/term v0.24.0 // indirect
diff --git a/go.sum b/go.sum
index 7766ec847..f27a7bf24 100644
--- a/go.sum
+++ b/go.sum
@@ -47,8 +47,6 @@ github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok=
 github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE=
 github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw=
 github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
-github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao=
-github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4=
 github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
 github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
 github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
@@ -71,12 +69,12 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dhui/dktest v0.4.1 h1:/w+IWuDXVymg3IrRJCHHOkMK10m9aNVMOyD0X12YVTg=
-github.com/dhui/dktest v0.4.1/go.mod h1:DdOqcUpL7vgyP4GlF3X3w7HbSlz8cEQzwewPveYEQbA=
+github.com/dhui/dktest v0.4.3 h1:wquqUxAFdcUgabAVLvSCOKOlag5cIZuaOjYIBOWdsR0=
+github.com/dhui/dktest v0.4.3/go.mod h1:zNK8IwktWzQRm6I/l2Wjp7MakiyaFWv4G1hjmodmMTs=
 github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
 github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
-github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
-github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4=
+github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
 github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
 github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@@ -140,8 +138,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
 github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
-github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4=
-github.com/golang-migrate/migrate/v4 v4.17.1/go.mod h1:m8hinFyWBn0SA4QKHuKh175Pm9wjmxj3S2Mia7dbXzM=
+github.com/golang-migrate/migrate/v4 v4.18.1 h1:JML/k+t4tpHCpQTCAD62Nu43NUFzHY4CV3uAuvHGC+Y=
+github.com/golang-migrate/migrate/v4 v4.18.1/go.mod h1:HAX6m3sQgcdO81tdjn5exv20+3Kb13cmGli1hrD6hks=
 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
@@ -295,6 +293,8 @@ github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5
 github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
 github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
 github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
+github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
+github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
 github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
 github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -339,8 +339,8 @@ github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0q
 github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
 github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
 github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
-github.com/prometheus/common v0.58.0 h1:N+N8vY4/23r6iYfD3UQZUoJPnUYAo7v6LG5XZxjZTXo=
-github.com/prometheus/common v0.58.0/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0=
+github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0=
+github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0=
 github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
 github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
 github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
@@ -426,8 +426,8 @@ go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelr
 go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.54.0/go.mod h1:fgH0JNwCMNwGsQOz4nlf6j5OhJwpE/Bv1hpQM6sjYOU=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
 go.opentelemetry.io/contrib/propagators/b3 v1.29.0 h1:hNjyoRsAACnhoOLWupItUjABzeYmX3GTTZLzwJluJlk=
 go.opentelemetry.io/contrib/propagators/b3 v1.29.0/go.mod h1:E76MTitU1Niwo5NSN+mVxkyLu4h4h7Dp/yh38F2WuIU=
 go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
@@ -469,8 +469,8 @@ golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0
 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
-golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
+golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
diff --git a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/meshexternalservice.go b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/meshexternalservice.go
index 593d17e2e..96f445c0f 100644
--- a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/meshexternalservice.go
+++ b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/meshexternalservice.go
@@ -64,10 +64,9 @@ type Extension struct {
 type Port int
 
 type Endpoint struct {
-	// Address defines an address to which a user want to send a request. Is possible to provide `domain`, `ip` and `unix` sockets.
+	// Address defines an address to which a user want to send a request. Is possible to provide `domain`, `ip`.
 	// +kubebuilder:example="127.0.0.1"
 	// +kubebuilder:example="example.com"
-	// +kubebuilder:example="unix:///tmp/example.sock"
 	// +kubebuilder:validation:MinLength=1
 	Address string `json:"address"`
 	// Port of the endpoint
diff --git a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/schema.yaml b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/schema.yaml
index e3fe708ba..d94af615b 100644
--- a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/schema.yaml
+++ b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/schema.yaml
@@ -26,8 +26,8 @@ properties:
         items:
           properties:
             address:
-              description: Address defines an address to which a user want to send a request. Is possible to provide `domain`, `ip` and `unix` sockets.
-              example: unix:///tmp/example.sock
+              description: Address defines an address to which a user want to send a request. Is possible to provide `domain`, `ip`.
+              example: example.com
               minLength: 1
               type: string
             port:
diff --git a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/validator.go b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/validator.go
index 252b56f80..d5df05378 100644
--- a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/validator.go
+++ b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/validator.go
@@ -4,7 +4,6 @@ import (
 	"fmt"
 	"math"
 	"slices"
-	"strings"
 
 	"github.com/asaskevich/govalidator"
 
@@ -106,32 +105,16 @@ func validateEndpoints(endpoints []Endpoint) validators.ValidationError {
 			}
 		}
 
-		if isValidUnixPath(endpoint.Address) {
-			if endpoint.Port != nil {
-				verr.AddViolationAt(validators.Root().Index(i).Field("port"), validators.MustNotBeDefined+" when endpoint is a unix path")
-			}
-		}
-
 		if govalidator.IsDNSName(endpoint.Address) {
 			if endpoint.Port == nil {
 				verr.AddViolationAt(validators.Root().Index(i).Field("port"), validators.MustBeDefined+" when endpoint is a hostname")
 			}
 		}
 
-		if !(govalidator.IsIP(endpoint.Address) || govalidator.IsDNSName(endpoint.Address) || isValidUnixPath(endpoint.Address)) {
-			verr.AddViolationAt(validators.Root().Index(i).Field("address"), "address has to be a valid IP or hostname or a unix path")
+		if !(govalidator.IsIP(endpoint.Address) || govalidator.IsDNSName(endpoint.Address)) {
+			verr.AddViolationAt(validators.Root().Index(i).Field("address"), "address has to be a valid IP or hostname")
 		}
 	}
 
 	return verr
 }
-
-func isValidUnixPath(path string) bool {
-	if strings.HasPrefix(path, "unix://") {
-		parts := strings.Split(path, "unix://")
-		filePath := parts[1]
-		return govalidator.IsUnixFilePath(filePath)
-	} else {
-		return false
-	}
-}
diff --git a/pkg/core/resources/apis/meshexternalservice/k8s/crd/kuma.io_meshexternalservices.yaml b/pkg/core/resources/apis/meshexternalservice/k8s/crd/kuma.io_meshexternalservices.yaml
index 33b3e3b70..4e9e9bd17 100644
--- a/pkg/core/resources/apis/meshexternalservice/k8s/crd/kuma.io_meshexternalservices.yaml
+++ b/pkg/core/resources/apis/meshexternalservice/k8s/crd/kuma.io_meshexternalservices.yaml
@@ -48,9 +48,8 @@ spec:
                   properties:
                     address:
                       description: Address defines an address to which a user want
-                        to send a request. Is possible to provide `domain`, `ip` and
-                        `unix` sockets.
-                      example: unix:///tmp/example.sock
+                        to send a request. Is possible to provide `domain`, `ip`.
+                      example: example.com
                       minLength: 1
                       type: string
                     port:
diff --git a/pkg/plugins/policies/core/xds/meshroute/clusters.go b/pkg/plugins/policies/core/xds/meshroute/clusters.go
index 101302d2d..ba18eae19 100644
--- a/pkg/plugins/policies/core/xds/meshroute/clusters.go
+++ b/pkg/plugins/policies/core/xds/meshroute/clusters.go
@@ -102,8 +102,8 @@ func GenerateClusters(
 							proxy.SecretsTracker,
 							meshCtx.Resource,
 							tlsReady,
-							sniForBackendRef(service.BackendRef(), meshCtx, systemNamespace),
-							serviceTagIdentities(service.BackendRef(), meshCtx),
+							SniForBackendRef(service.BackendRef(), meshCtx, systemNamespace),
+							ServiceTagIdentities(service.BackendRef(), meshCtx),
 						))
 					} else {
 						edsClusterBuilder.Configure(envoy_clusters.ClientSideMTLS(
@@ -157,7 +157,7 @@ func createResourceOrigin(
 	return nil
 }
 
-func sniForBackendRef(
+func SniForBackendRef(
 	backendRef core_model.ResolvedBackendRef,
 	meshCtx xds_context.MeshContext,
 	systemNamespace string,
@@ -186,7 +186,7 @@ func sniForBackendRef(
 	)
 }
 
-func serviceTagIdentities(
+func ServiceTagIdentities(
 	backendRef core_model.ResolvedBackendRef,
 	meshCtx xds_context.MeshContext,
 ) []string {
diff --git a/pkg/plugins/policies/core/xds/meshroute/gateway.go b/pkg/plugins/policies/core/xds/meshroute/gateway/gateway.go
similarity index 99%
rename from pkg/plugins/policies/core/xds/meshroute/gateway.go
rename to pkg/plugins/policies/core/xds/meshroute/gateway/gateway.go
index 0afc305b1..f13a254b8 100644
--- a/pkg/plugins/policies/core/xds/meshroute/gateway.go
+++ b/pkg/plugins/policies/core/xds/meshroute/gateway/gateway.go
@@ -104,6 +104,7 @@ func CollectListenerInfos(
 			listener.listener.GetProtocol(),
 			listener.sublisteners,
 		)
+
 		infos[port] = plugin_gateway.GatewayListenerInfo{
 			Proxy:             proxy,
 			Gateway:           gateway,
diff --git a/pkg/plugins/policies/core/xds/meshroute/listeners.go b/pkg/plugins/policies/core/xds/meshroute/listeners.go
index 530d27cb5..ca9dd88d5 100644
--- a/pkg/plugins/policies/core/xds/meshroute/listeners.go
+++ b/pkg/plugins/policies/core/xds/meshroute/listeners.go
@@ -194,6 +194,51 @@ func collectServiceTagService(
 	}
 }
 
+func GetServiceAndProtocolFromRef(
+	meshCtx xds_context.MeshContext,
+	ref core_model.ResolvedBackendRef,
+) (string, core_mesh.Protocol, bool) {
+	switch {
+	case ref.LegacyBackendRef.Kind == common_api.MeshExternalService:
+		mes, ok := meshCtx.MeshExternalServiceByIdentifier[pointer.Deref(ref.Resource).ResourceIdentifier]
+		if !ok {
+			return "", "", false
+		}
+		port := pointer.Deref(ref.LegacyBackendRef.Port)
+		service := mes.DestinationName(port)
+		protocol := meshCtx.GetServiceProtocol(service)
+		return service, protocol, true
+	case ref.LegacyBackendRef.Kind == common_api.MeshMultiZoneService:
+		ms, ok := meshCtx.MeshMultiZoneServiceByIdentifier[pointer.Deref(ref.Resource).ResourceIdentifier]
+		if !ok {
+			return "", "", false
+		}
+		port, ok := ms.FindPort(*ref.LegacyBackendRef.Port)
+		if !ok {
+			return "", "", false
+		}
+		service := ms.DestinationName(*ref.LegacyBackendRef.Port)
+		protocol := port.AppProtocol
+		return service, protocol, true
+	case ref.LegacyBackendRef.Kind == common_api.MeshService && ref.LegacyBackendRef.ReferencesRealObject():
+		ms, ok := meshCtx.MeshServiceByIdentifier[pointer.Deref(ref.Resource).ResourceIdentifier]
+		if !ok {
+			return "", "", false
+		}
+		port, ok := ms.FindPort(*ref.LegacyBackendRef.Port)
+		if !ok {
+			return "", "", false
+		}
+		service := ms.DestinationName(*ref.LegacyBackendRef.Port)
+		protocol := port.AppProtocol // todo(jakubdyszkiewicz): do we need to default to TCP or will this be done by MeshService defaulter?
+		return service, protocol, true
+	default:
+		service := ref.LegacyBackendRef.Name
+		protocol := meshCtx.GetServiceProtocol(service)
+		return service, protocol, true
+	}
+}
+
 func makeSplit(
 	protocols map[core_mesh.Protocol]struct{},
 	clusterCache map[common_api.BackendRefHash]string,
@@ -215,40 +260,9 @@ func makeSplit(
 		if pointer.DerefOr(ref.LegacyBackendRef.Weight, 1) == 0 {
 			continue
 		}
-		switch {
-		case ref.LegacyBackendRef.Kind == common_api.MeshExternalService:
-			mes, ok := meshCtx.MeshExternalServiceByIdentifier[pointer.Deref(ref.Resource).ResourceIdentifier]
-			if !ok {
-				continue
-			}
-			port := pointer.Deref(ref.LegacyBackendRef.Port)
-			service = mes.DestinationName(port)
-			protocol = meshCtx.GetServiceProtocol(service)
-		case ref.LegacyBackendRef.Kind == common_api.MeshMultiZoneService:
-			ms, ok := meshCtx.MeshMultiZoneServiceByIdentifier[pointer.Deref(ref.Resource).ResourceIdentifier]
-			if !ok {
-				continue
-			}
-			port, ok := ms.FindPort(*ref.LegacyBackendRef.Port)
-			if !ok {
-				continue
-			}
-			service = ms.DestinationName(*ref.LegacyBackendRef.Port)
-			protocol = port.AppProtocol
-		case ref.LegacyBackendRef.Kind == common_api.MeshService && ref.LegacyBackendRef.ReferencesRealObject():
-			ms, ok := meshCtx.MeshServiceByIdentifier[pointer.Deref(ref.Resource).ResourceIdentifier]
-			if !ok {
-				continue
-			}
-			port, ok := ms.FindPort(*ref.LegacyBackendRef.Port)
-			if !ok {
-				continue
-			}
-			service = ms.DestinationName(*ref.LegacyBackendRef.Port)
-			protocol = port.AppProtocol // todo(jakubdyszkiewicz): do we need to default to TCP or will this be done by MeshService defaulter?
-		default:
-			service = ref.LegacyBackendRef.Name
-			protocol = meshCtx.GetServiceProtocol(service)
+		service, protocol, ok := GetServiceAndProtocolFromRef(meshCtx, ref)
+		if !ok {
+			continue
 		}
 		if _, ok := protocols[protocol]; !ok {
 			return nil
diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/gateway_routes.go b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/gateway_routes.go
index 7c6743601..77ddc0d39 100644
--- a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/gateway_routes.go
+++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/gateway_routes.go
@@ -12,7 +12,7 @@ import (
 	core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
 	"github.com/kumahq/kuma/pkg/core/resources/model"
 	"github.com/kumahq/kuma/pkg/plugins/policies/core/rules"
-	"github.com/kumahq/kuma/pkg/plugins/policies/core/xds/meshroute"
+	meshroute_gateway "github.com/kumahq/kuma/pkg/plugins/policies/core/xds/meshroute/gateway"
 	api "github.com/kumahq/kuma/pkg/plugins/policies/meshhttproute/api/v1alpha1"
 	plugin_gateway "github.com/kumahq/kuma/pkg/plugins/runtime/gateway"
 	"github.com/kumahq/kuma/pkg/plugins/runtime/gateway/match"
@@ -33,12 +33,12 @@ func sortRulesToHosts(
 	address string,
 	port uint32,
 	protocol mesh_proto.MeshGateway_Listener_Protocol,
-	sublisteners []meshroute.Sublistener,
+	sublisteners []meshroute_gateway.Sublistener,
 ) []plugin_gateway.GatewayListenerHostname {
 	hostInfosByHostname := map[string]plugin_gateway.GatewayListenerHostname{}
 
 	// Iterate over the listeners in order
-	sublistenersByHostname := map[string]meshroute.Sublistener{}
+	sublistenersByHostname := map[string]meshroute_gateway.Sublistener{}
 	for _, sublistener := range sublisteners {
 		sublistenersByHostname[sublistener.Hostname] = sublistener
 	}
@@ -64,11 +64,19 @@ func sortRulesToHosts(
 		rulesByHostname := map[string][]ruleByHostname{}
 		for _, rawRule := range rawRules {
 			conf := rawRule.Conf.(api.PolicyDefault)
+
+			backendRefOrigin := map[string]model.ResourceMeta{}
+			for hash := range rawRule.BackendRefOriginIndex {
+				if origin, ok := rawRule.GetBackendRefOrigin(hash); ok {
+					backendRefOrigin[string(hash)] = origin
+				}
+			}
 			rule := ToRouteRule{
-				Subset:    rawRule.Subset,
-				Rules:     conf.Rules,
-				Hostnames: conf.Hostnames,
-				Origin:    rawRule.Origin,
+				Subset:           rawRule.Subset,
+				Rules:            conf.Rules,
+				Hostnames:        conf.Hostnames,
+				Origins:          rawRule.Origin,
+				BackendRefOrigin: backendRefOrigin,
 			}
 			hostnames := rule.Hostnames
 			if len(rule.Hostnames) == 0 {
@@ -146,7 +154,7 @@ func sortRulesToHosts(
 			}
 			hostInfo.AppendEntries(generateEnvoyRouteEntries(host, rules))
 
-			meshroute.AddToListenerByHostname(
+			meshroute_gateway.AddToListenerByHostname(
 				hostInfosByHostname,
 				protocol,
 				hostnameTag.Hostname,
@@ -157,7 +165,7 @@ func sortRulesToHosts(
 		observedHostnames = append(observedHostnames, hostname)
 	}
 
-	return meshroute.SortByHostname(hostInfosByHostname)
+	return meshroute_gateway.SortByHostname(hostInfosByHostname)
 }
 
 func generateEnvoyRouteEntries(host plugin_gateway.GatewayHost, toRules []ruleByHostname) []route.Entry {
@@ -173,11 +181,12 @@ func generateEnvoyRouteEntries(host plugin_gateway.GatewayHost, toRules []ruleBy
 	for _, rules := range toRules {
 		for _, rule := range rules.Rule.Rules {
 			var names []string
-			for _, orig := range rules.Rule.Origin {
+			for _, orig := range rules.Rule.Origins {
 				names = append(names, orig.GetName())
 			}
 			slices.Sort(names)
-			entry := makeHttpRouteEntry(strings.Join(names, "_"), rule)
+
+			entry := makeHttpRouteEntry(strings.Join(names, "_"), rule, rules.Rule.BackendRefOrigin)
 
 			hashedMatches := api.HashMatches(rule.Matches)
 			// The rule matches if any of the matches is successful (it has OR
@@ -204,12 +213,16 @@ func generateEnvoyRouteEntries(host plugin_gateway.GatewayHost, toRules []ruleBy
 	return plugin_gateway.HandlePrefixMatchesAndPopulatePolicies(host, exactEntries, prefixEntries, entries)
 }
 
-func makeHttpRouteEntry(name string, rule api.Rule) route.Entry {
+func makeHttpRouteEntry(name string, rule api.Rule, backendRefToOrigin map[string]model.ResourceMeta) route.Entry {
 	entry := route.Entry{
 		Route: name,
 	}
 
 	for _, b := range pointer.Deref(rule.Default.BackendRefs) {
+		var ref *model.ResolvedBackendRef
+		if origin, ok := backendRefToOrigin[api.HashMatches(rule.Matches)]; ok {
+			ref = pointer.To(model.ResolveBackendRef(origin, b))
+		}
 		dest, ok := tags.FromTargetRef(b.TargetRef)
 		if !ok {
 			// This should be caught by validation
@@ -217,6 +230,7 @@ func makeHttpRouteEntry(name string, rule api.Rule) route.Entry {
 		}
 		target := route.Destination{
 			Destination:   dest,
+			BackendRef:    ref,
 			Weight:        uint32(pointer.DerefOr(b.Weight, 1)),
 			Policies:      nil,
 			RouteProtocol: core_mesh.ProtocolHTTP,
diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin.go b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin.go
index cf430fca2..9df91b7e5 100644
--- a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin.go
+++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin.go
@@ -13,6 +13,7 @@ import (
 	"github.com/kumahq/kuma/pkg/plugins/policies/core/matchers"
 	"github.com/kumahq/kuma/pkg/plugins/policies/core/rules"
 	"github.com/kumahq/kuma/pkg/plugins/policies/core/xds/meshroute"
+	meshroute_gateway "github.com/kumahq/kuma/pkg/plugins/policies/core/xds/meshroute/gateway"
 	api "github.com/kumahq/kuma/pkg/plugins/policies/meshhttproute/api/v1alpha1"
 	plugin_gateway "github.com/kumahq/kuma/pkg/plugins/runtime/gateway"
 	xds_context "github.com/kumahq/kuma/pkg/xds/context"
@@ -26,7 +27,9 @@ type ToRouteRule struct {
 	Subset    rules.Subset
 	Rules     []api.Rule
 	Hostnames []string
-	Origin    []core_model.ResourceMeta
+
+	Origins          []core_model.ResourceMeta
+	BackendRefOrigin map[string]core_model.ResourceMeta
 }
 
 type plugin struct{}
@@ -118,7 +121,7 @@ func ApplyToGateway(
 		return nil
 	}
 
-	listeners := meshroute.CollectListenerInfos(
+	listeners := meshroute_gateway.CollectListenerInfos(
 		ctx,
 		xdsCtx.Mesh,
 		gateway,
diff --git a/pkg/plugins/policies/meshtcproute/plugin/v1alpha1/plugin.go b/pkg/plugins/policies/meshtcproute/plugin/v1alpha1/plugin.go
index 810ce07aa..4011edb88 100644
--- a/pkg/plugins/policies/meshtcproute/plugin/v1alpha1/plugin.go
+++ b/pkg/plugins/policies/meshtcproute/plugin/v1alpha1/plugin.go
@@ -13,6 +13,7 @@ import (
 	"github.com/kumahq/kuma/pkg/plugins/policies/core/matchers"
 	"github.com/kumahq/kuma/pkg/plugins/policies/core/rules"
 	"github.com/kumahq/kuma/pkg/plugins/policies/core/xds/meshroute"
+	meshroute_gateway "github.com/kumahq/kuma/pkg/plugins/policies/core/xds/meshroute/gateway"
 	api "github.com/kumahq/kuma/pkg/plugins/policies/meshtcproute/api/v1alpha1"
 	plugin_gateway "github.com/kumahq/kuma/pkg/plugins/runtime/gateway"
 	"github.com/kumahq/kuma/pkg/plugins/runtime/gateway/match"
@@ -120,7 +121,7 @@ func ApplyToGateway(
 		return nil
 	}
 
-	listeners := meshroute.CollectListenerInfos(
+	listeners := meshroute_gateway.CollectListenerInfos(
 		ctx,
 		xdsCtx.Mesh,
 		gateway,
@@ -161,7 +162,7 @@ func sortRulesToHosts(
 	address string,
 	port uint32,
 	protocol mesh_proto.MeshGateway_Listener_Protocol,
-	sublisteners []meshroute.Sublistener,
+	sublisteners []meshroute_gateway.Sublistener,
 ) []plugin_gateway.GatewayListenerHostname {
 	hostInfosByHostname := map[string]plugin_gateway.GatewayListenerHostname{}
 	for _, hostnameTag := range sublisteners {
@@ -184,7 +185,7 @@ func sortRulesToHosts(
 			continue
 		}
 		hostInfo.AppendEntries(generateEnvoyRouteEntries(host, rulesForListener))
-		meshroute.AddToListenerByHostname(
+		meshroute_gateway.AddToListenerByHostname(
 			hostInfosByHostname,
 			protocol,
 			hostnameTag.Hostname,
@@ -193,5 +194,5 @@ func sortRulesToHosts(
 		)
 	}
 
-	return meshroute.SortByHostname(hostInfosByHostname)
+	return meshroute_gateway.SortByHostname(hostInfosByHostname)
 }
diff --git a/pkg/plugins/runtime/gateway/cluster_generator.go b/pkg/plugins/runtime/gateway/cluster_generator.go
index 1406303e4..f4cdb7e8d 100644
--- a/pkg/plugins/runtime/gateway/cluster_generator.go
+++ b/pkg/plugins/runtime/gateway/cluster_generator.go
@@ -8,7 +8,9 @@ import (
 
 	mesh_proto "github.com/kumahq/kuma/api/mesh/v1alpha1"
 	core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
+	"github.com/kumahq/kuma/pkg/core/resources/model"
 	core_xds "github.com/kumahq/kuma/pkg/core/xds"
+	"github.com/kumahq/kuma/pkg/plugins/policies/core/xds/meshroute"
 	"github.com/kumahq/kuma/pkg/plugins/runtime/gateway/match"
 	"github.com/kumahq/kuma/pkg/plugins/runtime/gateway/metadata"
 	"github.com/kumahq/kuma/pkg/plugins/runtime/gateway/route"
@@ -38,48 +40,59 @@ func (c *ClusterGenerator) GenerateClusters(ctx context.Context, xdsCtx xds_cont
 	// an external service. Because the dataplane endpoints happen to be
 	// generated first, the mesh service will have priority.
 	for _, dest := range RouteDestinationsMutable(hostEntries) {
-		service := dest.Destination[mesh_proto.ServiceTag]
+		var isExternalCluster bool
+		var service string
+		var r *core_xds.Resource
+		var err error
 
-		if service == metadata.UnresolvedBackendServiceTag {
-			dest.Name = metadata.UnresolvedBackendServiceTag
-			continue
-		}
+		if dest.BackendRef != nil && dest.BackendRef.Resource != nil {
+			r, service, err = c.generateRealBackendRefCluster(xdsCtx.Mesh, info.Proxy, *dest.BackendRef, dest.RouteProtocol, "kuma-system", hostTags) // TODO
+			if r == nil && err == nil {
+				log.Info("skipping backendRef", "backendRef", dest.BackendRef.LegacyBackendRef)
+				continue
+			}
+			isExternalCluster = dest.BackendRef.LegacyBackendRef.Kind == "MeshExternalService"
+		} else {
+			service = dest.Destination[mesh_proto.ServiceTag]
 
-		isExternalService := xdsCtx.Mesh.IsExternalService(service)
-		if len(xdsCtx.Mesh.Resources.TrafficPermissions().Items) > 0 {
-			isExternalService = route.HasExternalServiceEndpoint(xdsCtx.Mesh.Resource, info.OutboundEndpoints, *dest)
-		}
+			if service == metadata.UnresolvedBackendServiceTag {
+				dest.Name = metadata.UnresolvedBackendServiceTag
+				continue
+			}
 
-		matched := match.ExternalService(info.ExternalServices.Items, mesh_proto.TagSelector(dest.Destination))
+			isExternalService := xdsCtx.Mesh.IsExternalService(service)
+			if len(xdsCtx.Mesh.Resources.TrafficPermissions().Items) > 0 {
+				isExternalService = route.HasExternalServiceEndpoint(xdsCtx.Mesh.Resource, info.OutboundEndpoints, *dest)
+			}
 
-		// If there is Mesh property ZoneEgress enabled we want always to
-		// direct the traffic through them. The condition is, the mesh must
-		// have mTLS enabled and traffic through zoneEgress is enabled.
-		isDirectExternalService := isExternalService && !xdsCtx.Mesh.Resource.ZoneEgressEnabled()
-		isExternalCluster := isDirectExternalService && len(matched) > 0
+			matched := match.ExternalService(info.ExternalServices.Items, mesh_proto.TagSelector(dest.Destination))
 
-		isExternalServiceThroughZoneEgress := isExternalService && xdsCtx.Mesh.Resource.ZoneEgressEnabled()
+			// If there is Mesh property ZoneEgress enabled we want always to
+			// direct the traffic through them. The condition is, the mesh must
+			// have mTLS enabled and traffic through zoneEgress is enabled.
+			isDirectExternalService := isExternalService && !xdsCtx.Mesh.Resource.ZoneEgressEnabled()
+			isExternalCluster = isDirectExternalService && len(matched) > 0
 
-		var r *core_xds.Resource
-		var err error
+			isExternalServiceThroughZoneEgress := isExternalService && xdsCtx.Mesh.Resource.ZoneEgressEnabled()
 
-		if isExternalCluster {
-			log.V(1).Info("generating external service cluster",
-				"service", service,
-			)
+			if isExternalCluster {
+				log.V(1).Info("generating external service cluster",
+					"service", service,
+				)
 
-			r, err = c.generateExternalCluster(ctx, xdsCtx.Mesh, info, matched, dest, hostTags)
-		} else {
-			log.V(1).Info("generating mesh cluster resource",
-				"service", service,
-			)
+				r, err = c.generateExternalCluster(ctx, xdsCtx.Mesh, info, matched, dest, hostTags)
+			} else {
+				log.V(1).Info("generating mesh cluster resource",
+					"service", service,
+				)
 
-			upstreamServiceName := dest.Destination[mesh_proto.ServiceTag]
-			if isExternalServiceThroughZoneEgress {
-				upstreamServiceName = mesh_proto.ZoneEgressServiceName
-			}
+				upstreamServiceName := dest.Destination[mesh_proto.ServiceTag]
+				if isExternalServiceThroughZoneEgress {
+					upstreamServiceName = mesh_proto.ZoneEgressServiceName
+				}
 
-			r, err = c.generateMeshCluster(xdsCtx.Mesh, info, dest, upstreamServiceName, hostTags)
+				r, err = c.generateMeshCluster(xdsCtx.Mesh, info, dest, upstreamServiceName, hostTags)
+			}
 		}
 
 		if err != nil {
@@ -101,7 +114,7 @@ func (c *ClusterGenerator) GenerateClusters(ctx context.Context, xdsCtx xds_cont
 		// at the fields we populate here.
 		cluster := envoy.NewCluster(
 			envoy.WithName(dest.Name),
-			envoy.WithService(dest.Destination[mesh_proto.ServiceTag]),
+			envoy.WithService(service),
 			envoy.WithTags(dest.Destination),
 		)
 
@@ -123,6 +136,49 @@ func (c *ClusterGenerator) GenerateClusters(ctx context.Context, xdsCtx xds_cont
 	return resources, nil
 }
 
+func (c *ClusterGenerator) generateRealBackendRefCluster(
+	meshCtx xds_context.MeshContext,
+	proxy *core_xds.Proxy,
+	backendRef model.ResolvedBackendRef,
+	routeProtocol core_mesh.Protocol,
+	systemNamespace string,
+	identifyingTags map[string]string,
+) (*core_xds.Resource, string, error) {
+	service, destProtocol, ok := meshroute.GetServiceAndProtocolFromRef(meshCtx, backendRef)
+	if !ok {
+		return nil, "", nil
+	}
+	protocol := route.InferServiceProtocol(destProtocol, routeProtocol)
+
+	edsClusterBuilder := clusters.NewClusterBuilder(proxy.APIVersion, service).
+		Configure(
+			clusters.EdsCluster(),
+			clusters.LB(nil /* TODO(jpeach) uses default Round Robin*/),
+			clusters.ClientSideMultiIdentitiesMTLS(
+				proxy.SecretsTracker,
+				meshCtx.Resource,
+				true, // TODO we just assume this atm?...
+				meshroute.SniForBackendRef(backendRef, meshCtx, systemNamespace),
+				meshroute.ServiceTagIdentities(backendRef, meshCtx),
+			),
+			clusters.ConnectionBufferLimit(DefaultConnectionBuffer),
+		)
+
+	switch protocol {
+	case core_mesh.ProtocolHTTP2, core_mesh.ProtocolGRPC:
+		edsClusterBuilder.Configure(clusters.Http2FromEdge())
+	case core_mesh.ProtocolHTTP:
+		edsClusterBuilder.Configure(clusters.Http())
+	default:
+	}
+	// Note: these tags are just used to get a hash!
+	tags := map[string]string{
+		mesh_proto.ServiceTag: service,
+	}
+	cluster, err := buildClusterResource(tags, edsClusterBuilder, identifyingTags)
+	return cluster, service, err
+}
+
 func (c *ClusterGenerator) generateMeshCluster(
 	meshCtx xds_context.MeshContext,
 	info GatewayListenerInfo,
@@ -146,7 +202,7 @@ func (c *ClusterGenerator) generateMeshCluster(
 	// the destination cluster before deciding whether to enable the filter.
 	// It's not clear whether that can be done.
 
-	return buildClusterResource(dest, builder, identifyingTags)
+	return buildClusterResource(dest.Destination, builder, identifyingTags)
 }
 
 func (c *ClusterGenerator) generateExternalCluster(
@@ -171,7 +227,7 @@ func (c *ClusterGenerator) generateExternalCluster(
 	protocol := route.InferServiceProtocol(meshCtx.GetServiceProtocol(serviceName), dest.RouteProtocol)
 
 	return buildClusterResource(
-		dest,
+		dest.Destination,
 		newClusterBuilder(info.Proxy.APIVersion, serviceName, protocol, dest).Configure(
 			clusters.ProvidedEndpointCluster(info.Proxy.Dataplane.IsIPv6(), endpoints...),
 			clusters.ClientSideTLS(endpoints),
@@ -219,7 +275,7 @@ func newClusterBuilder(
 // we can't just build a cluster using the service name and tags, we have to
 // take listener tags into account.
 func buildClusterResource(
-	dest *route.Destination,
+	destinationTags tags.Tags,
 	c *clusters.ClusterBuilder,
 	identifyingTags map[string]string,
 ) (*core_xds.Resource, error) {
@@ -230,7 +286,7 @@ func buildClusterResource(
 
 	cluster := msg.(*envoy_cluster_v3.Cluster)
 
-	name, err := dest.Destination.DestinationClusterName(identifyingTags)
+	name, err := destinationTags.DestinationClusterName(identifyingTags)
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/plugins/runtime/gateway/route/table.go b/pkg/plugins/runtime/gateway/route/table.go
index 71a8882ab..b179a8f7f 100644
--- a/pkg/plugins/runtime/gateway/route/table.go
+++ b/pkg/plugins/runtime/gateway/route/table.go
@@ -108,7 +108,9 @@ type Redirection struct {
 
 // Destination is a forwarding target (aka Cluster).
 type Destination struct {
-	Destination   tags.Tags
+	Destination tags.Tags
+	BackendRef  *model.ResolvedBackendRef
+
 	Weight        uint32
 	RouteProtocol core_mesh.Protocol
 
diff --git a/pkg/xds/topology/outbound.go b/pkg/xds/topology/outbound.go
index 1896b79a3..259b6ea25 100644
--- a/pkg/xds/topology/outbound.go
+++ b/pkg/xds/topology/outbound.go
@@ -5,7 +5,6 @@ import (
 	"maps"
 	"net"
 	"strconv"
-	"strings"
 
 	"github.com/asaskevich/govalidator"
 	"github.com/pkg/errors"
@@ -734,24 +733,13 @@ func createMeshExternalServiceEndpoint(
 		if i == 0 && es.ServerName == "" && govalidator.IsDNSName(endpoint.Address) && tls != nil && tls.Enabled {
 			es.ServerName = endpoint.Address
 		}
-		var outboundEndpoint *core_xds.Endpoint
-		if strings.HasPrefix(endpoint.Address, "unix://") {
-			outboundEndpoint = &core_xds.Endpoint{
-				UnixDomainPath:  endpoint.Address,
-				Weight:          1,
-				ExternalService: es,
-				Tags:            tags,
-				Locality:        GetLocality(zone, getZone(tags), mesh.LocalityAwareLbEnabled()),
-			}
-		} else {
-			outboundEndpoint = &core_xds.Endpoint{
-				Target:          endpoint.Address,
-				Port:            uint32(*endpoint.Port),
-				Weight:          1,
-				ExternalService: es,
-				Tags:            tags,
-				Locality:        GetLocality(zone, getZone(tags), mesh.LocalityAwareLbEnabled()),
-			}
+		outboundEndpoint := &core_xds.Endpoint{
+			Target:          endpoint.Address,
+			Port:            uint32(*endpoint.Port),
+			Weight:          1,
+			ExternalService: es,
+			Tags:            tags,
+			Locality:        GetLocality(zone, getZone(tags), mesh.LocalityAwareLbEnabled()),
 		}
 		outbounds[name] = append(outbounds[name], *outboundEndpoint)
 	}


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 bfff84a38..65d7af055 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
@@ -295,9 +295,8 @@ spec:
                   properties:
                     address:
                       description: Address defines an address to which a user want
-                        to send a request. Is possible to provide `domain`, `ip` and
-                        `unix` sockets.
-                      example: unix:///tmp/example.sock
+                        to send a request. Is possible to provide `domain`, `ip`.
+                      example: example.com
                       minLength: 1
                       type: string
                     port:
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 3c2750439..222b418a3 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
@@ -295,9 +295,8 @@ spec:
                   properties:
                     address:
                       description: Address defines an address to which a user want
-                        to send a request. Is possible to provide `domain`, `ip` and
-                        `unix` sockets.
-                      example: unix:///tmp/example.sock
+                        to send a request. Is possible to provide `domain`, `ip`.
+                      example: example.com
                       minLength: 1
                       type: string
                     port:
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 9bb684a2b..2d3ab8b5e 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
@@ -315,9 +315,8 @@ spec:
                   properties:
                     address:
                       description: Address defines an address to which a user want
-                        to send a request. Is possible to provide `domain`, `ip` and
-                        `unix` sockets.
-                      example: unix:///tmp/example.sock
+                        to send a request. Is possible to provide `domain`, `ip`.
+                      example: example.com
                       minLength: 1
                       type: string
                     port:
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 d8c876565..bc68cce21 100644
--- a/app/kumactl/cmd/install/testdata/install-crds.all.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-crds.all.golden.yaml
@@ -1901,9 +1901,8 @@ spec:
                   properties:
                     address:
                       description: Address defines an address to which a user want
-                        to send a request. Is possible to provide `domain`, `ip` and
-                        `unix` sockets.
-                      example: unix:///tmp/example.sock
+                        to send a request. Is possible to provide `domain`, `ip`.
+                      example: example.com
                       minLength: 1
                       type: string
                     port:
diff --git a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/testdata/full-invalid.input.yaml b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/testdata/full-invalid.input.yaml
index de475b963..4024c5a34 100644
--- a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/testdata/full-invalid.input.yaml
+++ b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/testdata/full-invalid.input.yaml
@@ -7,8 +7,6 @@ endpoints:
   - address: 1.1.1.2
     port: 999999
   - address: example.com
-  - address: unix:///tmp/example.sock
-    port: 80
   - port: 90
 tls:
   version:
diff --git a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/testdata/full-invalid.output.yaml b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/testdata/full-invalid.output.yaml
index 21ed5e71f..32f9081fa 100644
--- a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/testdata/full-invalid.output.yaml
+++ b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/testdata/full-invalid.output.yaml
@@ -11,10 +11,8 @@ violations:
   message: port must be a valid (1-65535)
 - field: spec.endpoints[2].port
   message: must be defined when endpoint is a hostname
-- field: spec.endpoints[3].port
-  message: must not be defined when endpoint is a unix path
-- field: spec.endpoints[4].address
-  message: address has to be a valid IP or hostname or a unix path
+- field: spec.endpoints[3].address
+  message: address has to be a valid IP or hostname
 - field: spec.tls.version.min
   message: '"min" must be one of ["TLSAuto", "TLS10", "TLS11", "TLS12", "TLS13"]'
 - field: spec.tls.version.max
diff --git a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/testdata/full-without-extension-valid.input.yaml b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/testdata/full-without-extension-valid.input.yaml
index 64a605a86..c62f47d40 100644
--- a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/testdata/full-without-extension-valid.input.yaml
+++ b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/testdata/full-without-extension-valid.input.yaml
@@ -7,7 +7,6 @@ endpoints:
     port: 12345
   - address: example.com
     port: 80
-  - address: unix:///tmp/example.sock
 tls:
   version:
     min: TLS12
diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_test.go b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_test.go
index 7bbf4d90b..fedec15d9 100644
--- a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_test.go
+++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_test.go
@@ -1546,6 +1546,118 @@ var _ = Describe("MeshHTTPRoute", func() {
 					Build(),
 			}
 		}()),
+		Entry("gateway-real-mesh-service", func() outboundsTestCase {
+			meshSvc := meshservice_api.MeshServiceResource{
+				Meta: &test_model.ResourceMeta{Name: "backend", Mesh: "default"},
+				Spec: &meshservice_api.MeshService{
+					Selector: meshservice_api.Selector{},
+					Ports: []meshservice_api.Port{{
+						Port:        80,
+						TargetPort:  intstr.FromInt(8080),
+						AppProtocol: core_mesh.ProtocolHTTP,
+						Name:        "test-port",
+					}},
+					Identities: []meshservice_api.MeshServiceIdentity{
+						{
+							Type:  meshservice_api.MeshServiceIdentityServiceTagType,
+							Value: "backend_svc_80",
+						},
+					},
+				},
+				Status: &meshservice_api.MeshServiceStatus{
+					VIPs: []meshservice_api.VIP{{
+						IP: "10.0.0.1",
+					}},
+				},
+			}
+			gateway := &core_mesh.MeshGatewayResource{
+				Meta: &test_model.ResourceMeta{Name: "sample-gateway", Mesh: "default"},
+				Spec: &mesh_proto.MeshGateway{
+					Selectors: []*mesh_proto.Selector{
+						{
+							Match: map[string]string{
+								mesh_proto.ServiceTag: "sample-gateway",
+							},
+						},
+					},
+					Conf: &mesh_proto.MeshGateway_Conf{
+						Listeners: []*mesh_proto.MeshGateway_Listener{
+							{
+								Protocol: mesh_proto.MeshGateway_Listener_HTTP,
+								Port:     8080,
+							},
+						},
+					},
+				},
+			}
+			resources := xds_context.NewResources()
+			resources.MeshLocalResources[core_mesh.MeshGatewayType] = &core_mesh.MeshGatewayResourceList{
+				Items: []*core_mesh.MeshGatewayResource{gateway},
+			}
+			resources.MeshLocalResources[meshservice_api.MeshServiceType] = &meshservice_api.MeshServiceResourceList{
+				Items: []*meshservice_api.MeshServiceResource{&meshSvc},
+			}
+			outboundTargets := xds_builders.EndpointMap().
+				AddEndpoint("backend_msvc_80", xds_builders.Endpoint().
+					WithTarget("192.168.0.4").
+					WithPort(8080).
+					WithWeight(1).
+					WithTags(mesh_proto.ServiceTag, "backend_svc_80"))
+			xdsContext := xds_builders.Context().
+				WithMeshBuilder(samples.MeshDefaultBuilder()).
+				WithResources(resources).
+				WithEndpointMap(outboundTargets).Build()
+
+			commonRules := core_rules.Rules{
+				{
+					Subset: core_rules.MeshSubset(),
+					Origin: []core_model.ResourceMeta{
+						&test_model.ResourceMeta{Mesh: "default", Name: "http-route"},
+					},
+					BackendRefOriginIndex: map[core_rules.MatchesHash]int{
+						core_rules.MatchesHash(api.HashMatches([]api.Match{{Path: &api.PathMatch{Type: api.PathPrefix, Value: "/"}}})): 0,
+					},
+					Conf: api.PolicyDefault{
+						Rules: []api.Rule{{
+							Matches: []api.Match{{
+								Path: &api.PathMatch{
+									Type:  api.PathPrefix,
+									Value: "/",
+								},
+							}},
+							Default: api.RuleConf{
+								BackendRefs: &[]common_api.BackendRef{{
+									TargetRef: common_api.TargetRef{
+										Kind: common_api.MeshService,
+										Name: "backend",
+									},
+									Port:   pointer.To(uint32(80)),
+									Weight: pointer.To(uint(100)),
+								}},
+							},
+						}},
+					},
+				},
+			}
+
+			return outboundsTestCase{
+				xdsContext: *xdsContext,
+				proxy: xds_builders.Proxy().
+					WithDataplane(samples.GatewayDataplaneBuilder()).
+					WithRouting(xds_builders.Routing().WithOutboundTargets(outboundTargets)).
+					WithPolicies(
+						xds_builders.MatchedPolicies().
+							WithGatewayPolicy(api.MeshHTTPRouteType, core_rules.GatewayRules{
+								ToRules: core_rules.GatewayToRules{
+									ByListenerAndHostname: map[rules.InboundListenerHostname]rules.Rules{
+										core_rules.NewInboundListenerHostname("192.168.0.1", 8080, "*"): commonRules,
+									},
+								},
+							}),
+					).
+					Build(),
+			}
+		}()),
 		Entry("gateway-listener-specific", func() outboundsTestCase {
 			gateway := &core_mesh.MeshGatewayResource{
 				Meta: &test_model.ResourceMeta{Name: "sample-gateway", Mesh: "default"},
diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.clusters.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.clusters.golden.yaml
new file mode 100644
index 000000000..961b21fea
--- /dev/null
+++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.clusters.golden.yaml
@@ -0,0 +1,17 @@
+resources:
+- name: backend_msvc_80-6c7282d3d97450ca
+  resource:
+    '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster
+    edsClusterConfig:
+      edsConfig:
+        ads: {}
+        initialFetchTimeout: 0s
+        resourceApiVersion: V3
+    name: backend_msvc_80-6c7282d3d97450ca
+    perConnectionBufferLimitBytes: 32768
+    type: EDS
+    typedExtensionProtocolOptions:
+      envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+        '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+        explicitHttpConfig:
+          httpProtocolOptions: {}
diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.endpoints.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.endpoints.golden.yaml
new file mode 100644
index 000000000..eff575153
--- /dev/null
+++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.endpoints.golden.yaml
@@ -0,0 +1,13 @@
+resources:
+- name: backend_msvc_80-6c7282d3d97450ca
+  resource:
+    '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment
+    clusterName: backend_msvc_80-6c7282d3d97450ca
+    endpoints:
+    - lbEndpoints:
+      - endpoint:
+          address:
+            socketAddress:
+              address: 192.168.0.4
+              portValue: 8080
+        loadBalancingWeight: 1
diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.listeners.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.listeners.golden.yaml
new file mode 100644
index 000000000..d9e3529e6
--- /dev/null
+++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.listeners.golden.yaml
@@ -0,0 +1,60 @@
+resources:
+- name: sample-gateway:HTTP:8080
+  resource:
+    '@type': type.googleapis.com/envoy.config.listener.v3.Listener
+    address:
+      socketAddress:
+        address: 192.168.0.1
+        portValue: 8080
+    enableReusePort: true
+    filterChains:
+    - filters:
+      - name: envoy.filters.network.http_connection_manager
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          commonHttpProtocolOptions:
+            headersWithUnderscoresAction: REJECT_REQUEST
+            idleTimeout: 300s
+          http2ProtocolOptions:
+            allowConnect: true
+            initialConnectionWindowSize: 1048576
+            initialStreamWindowSize: 65536
+            maxConcurrentStreams: 100
+          httpFilters:
+          - name: envoy.filters.http.local_ratelimit
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
+              statPrefix: rate_limit
+          - name: gzip-compress
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.compressor.v3.Compressor
+              compressorLibrary:
+                name: gzip
+                typedConfig:
+                  '@type': type.googleapis.com/envoy.extensions.compression.gzip.compressor.v3.Gzip
+              responseDirectionConfig:
+                disableOnEtagHeader: true
+          - name: envoy.filters.http.router
+            typedConfig:
+              '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+          mergeSlashes: true
+          normalizePath: true
+          pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+          rds:
+            configSource:
+              ads: {}
+              initialFetchTimeout: 0s
+              resourceApiVersion: V3
+            routeConfigName: sample-gateway:HTTP:8080:*
+          requestHeadersTimeout: 0.500s
+          serverName: Kuma Gateway
+          statPrefix: sample-gateway
+          streamIdleTimeout: 5s
+          useRemoteAddress: true
+    listenerFilters:
+    - name: envoy.filters.listener.tls_inspector
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
+    name: sample-gateway:HTTP:8080
+    perConnectionBufferLimitBytes: 32768
+    trafficDirection: INBOUND
diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.routes.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.routes.golden.yaml
new file mode 100644
index 000000000..c23dd9047
--- /dev/null
+++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.routes.golden.yaml
@@ -0,0 +1,42 @@
+resources:
+- name: sample-gateway:HTTP:8080:*
+  resource:
+    '@type': type.googleapis.com/envoy.config.route.v3.RouteConfiguration
+    ignorePortInHostMatching: true
+    name: sample-gateway:HTTP:8080:*
+    requestHeadersToRemove:
+    - x-kuma-tags
+    validateClusters: false
+    virtualHosts:
+    - domains:
+      - '*'
+      name: '*'
+      routes:
+      - match:
+          path: /
+        name: 9Zuf5Tg79OuZcQITwBbQykxAk2u4fRKrwYn3//AL4Yo=
+        route:
+          clusterNotFoundResponseCode: INTERNAL_SERVER_ERROR
+          idleTimeout: 5s
+          weightedClusters:
+            clusters:
+            - name: backend_msvc_80-6c7282d3d97450ca
+              requestHeadersToAdd:
+              - header:
+                  key: x-kuma-tags
+                  value: '&kuma.io/service=sample-gateway&'
+              weight: 100
+      - match:
+          prefix: /
+        name: 9Zuf5Tg79OuZcQITwBbQykxAk2u4fRKrwYn3//AL4Yo=
+        route:
+          clusterNotFoundResponseCode: INTERNAL_SERVER_ERROR
+          idleTimeout: 5s
+          weightedClusters:
+            clusters:
+            - name: backend_msvc_80-6c7282d3d97450ca
+              requestHeadersToAdd:
+              - header:
+                  key: x-kuma-tags
+                  value: '&kuma.io/service=sample-gateway&'
+              weight: 100
diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.secrets.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.secrets.golden.yaml
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/gateway-real-mesh-service.secrets.golden.yaml
@@ -0,0 +1,1 @@
+{}
diff --git a/pkg/xds/topology/outbound_test.go b/pkg/xds/topology/outbound_test.go
index be951a7a3..19f1d820d 100644
--- a/pkg/xds/topology/outbound_test.go
+++ b/pkg/xds/topology/outbound_test.go
@@ -1406,24 +1406,6 @@ var _ = Describe("TrafficRoute", func() {
 							},
 						},
 					},
-					{
-						Meta: &test_model.ResourceMeta{
-							Mesh: "default",
-							Name: "no-tls-mes",
-						},
-						Spec: &meshexternalservice_api.MeshExternalService{
-							Match: meshexternalservice_api.Match{
-								Type:     pointer.To(meshexternalservice_api.HostnameGeneratorType),
-								Port:     10000,
-								Protocol: meshexternalservice_api.GrpcProtocol,
-							},
-							Endpoints: []meshexternalservice_api.Endpoint{
-								{
-									Address: "unix://no-tls-mes",
-								},
-							},
-						},
-					},
 				},
 				zoneEgresses: []*core_mesh.ZoneEgressResource{
 					{
@@ -1456,18 +1438,6 @@ var _ = Describe("TrafficRoute", func() {
 							},
 						},
 					},
-					"no-tls-mes": []core_xds.Endpoint{
-						{
-							Target:   "1.1.1.1",
-							Port:     10002,
-							Locality: nil,
-							Weight:   1,
-							ExternalService: &core_xds.ExternalService{
-								Protocol:   core_mesh.ProtocolGRPC,
-								TLSEnabled: false,
-							},
-						},
-					},
 					"example-mes": []core_xds.Endpoint{
 						{
 							Target:   "1.1.1.1",
diff --git a/test/e2e_env/multizone/meshservice/connectivity.go b/test/e2e_env/multizone/meshservice/connectivity.go
index 3911b7548..c93432aac 100644
--- a/test/e2e_env/multizone/meshservice/connectivity.go
+++ b/test/e2e_env/multizone/meshservice/connectivity.go
@@ -10,6 +10,7 @@ import (
 	kube_meta "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	"github.com/kumahq/kuma/pkg/config/core"
+	"github.com/kumahq/kuma/test/e2e_env/kubernetes/gateway"
 	. "github.com/kumahq/kuma/test/framework"
 	"github.com/kumahq/kuma/test/framework/client"
 	"github.com/kumahq/kuma/test/framework/deployments/democlient"
@@ -19,6 +20,7 @@ import (
 
 func Connectivity() {
 	namespace := "msconnectivity"
+	clientNamespace := "msconnectivity-client"
 	meshName := "msconnectivity"
 	autoGenerateUniversalClusterName := "autogenerate-universal"
 
@@ -78,8 +80,59 @@ spec:
 			Setup(multizone.Global)).To(Succeed())
 		Expect(WaitForMesh(meshName, multizone.Zones())).To(Succeed())
 
+		meshGateway := fmt.Sprintf(`
+apiVersion: kuma.io/v1alpha1
+kind: MeshGateway
+metadata:
+  name: edge-gateway
+  labels:
+    kuma.io/origin: zone
+mesh: %s
+spec:
+  selectors:
+  - match:
+      kuma.io/service: edge-gateway_%s_svc
+  conf:
+    listeners:
+    - port: 8080
+      protocol: HTTP
+`, meshName, namespace)
+		gatewayRoute := fmt.Sprintf(`
+apiVersion: kuma.io/v1alpha1
+kind: MeshHTTPRoute
+metadata:
+  name: route
+  namespace: %s
+  labels:
+    kuma.io/mesh: %s
+    kuma.io/origin: zone
+spec:
+  targetRef:
+    kind: MeshGateway
+    name: edge-gateway
+  to:
+    - targetRef:
+        kind: Mesh
+      rules:
+        - matches:
+            - path:
+                type: PathPrefix
+                value: /local
+          default:
+            backendRefs:
+              - kind: MeshService
+                name: test-server
+                namespace: %s
+                port: 80
+                weight: 1
+`, Config.KumaNamespace, meshName, namespace)
 		err := NewClusterSetup().
 			Install(NamespaceWithSidecarInjection(namespace)).
+			Install(Namespace(clientNamespace)).
+			Install(testserver.Install(
+				testserver.WithName("demo-client"),
+				testserver.WithNamespace(clientNamespace),
+			)).
 			Install(testserver.Install(
 				testserver.WithNamespace(namespace),
 				testserver.WithMesh(meshName),
@@ -93,6 +146,9 @@ spec:
 				testserver.WithHeadlessService(),
 				testserver.WithEchoArgs("echo", "--instance", "kube-statefulset-test-server-1"),
 			)).
+			Install(YamlK8s(meshGateway)).
+			Install(YamlK8s(gatewayRoute)).
+			Install(YamlK8s(gateway.MkGatewayInstance("edge-gateway", namespace, meshName))).
 			Install(democlient.Install(democlient.WithNamespace(namespace), democlient.WithMesh(meshName))).
 			Setup(multizone.KubeZone1)
 		Expect(err).ToNot(HaveOccurred())
@@ -169,6 +225,32 @@ spec:
 		should           types.GomegaMatcher
 	}
 
+	DescribeTable("Gateway in Kubernetes",
+		func(given testCase) {
+			if given.should == nil {
+				given.should = Succeed()
+			}
+			Eventually(func(g Gomega) {
+				response, err := client.CollectEchoResponse(
+					multizone.KubeZone1, "demo-client",
+					fmt.Sprintf("http://edge-gateway.%s:8080/%s", namespace, given.address()),
+					client.FromKubernetesPod(clientNamespace, "demo-client"),
+				)
+
+				g.Expect(err).ToNot(HaveOccurred())
+				g.Expect(response.Instance).To(Equal(given.expectedInstance))
+			}, "30s", "1s").Should(Succeed())
+		},
+		Entry("should access service in the same Kubernetes cluster via a mesh-targeted generator name", testCase{
+			address:          func() string { return "/local" },
+			expectedInstance: "kube-test-server-1",
+		}),
+		XEntry("should access service in the a Universal cluster", testCase{
+			address:          func() string { return "/uni-2" },
+			expectedInstance: "uni-test-server",
+		}),
+	)
+
 	DescribeTable("client from Kubernetes",
 		func(given testCase) {
 			if given.should == nil {