Repository: envoyproxy/envoy
Pull request #38945: socket: Add network namespace parameter to SocketAddress proto
Author: login: tonya11en
Created: 2025-03-27T20:07:06Z | Merged: 2025-04-11T03:32:43Z

Extends SocketAddress to allow us to specify the network namespace of the socket. This is an API-only change and it is hidden, since there is no implementation.

Addresses https://github.com/envoyproxy/envoy/issues/38947


Diff:
diff --git a/api/envoy/config/core/v3/address.proto b/api/envoy/config/core/v3/address.proto
index d8d47882655b7..38d74ef280f87 100644
--- a/api/envoy/config/core/v3/address.proto
+++ b/api/envoy/config/core/v3/address.proto
@@ -50,7 +50,7 @@ message EnvoyInternalAddress {
   string endpoint_id = 2;
 }
 
-// [#next-free-field: 7]
+// [#next-free-field: 8]
 message SocketAddress {
   option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.core.SocketAddress";
 
@@ -97,6 +97,11 @@ message SocketAddress {
   // allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into
   // IPv6 space as ``::FFFF:<IPv4-address>``.
   bool ipv4_compat = 6;
+
+  // The Linux network namespace to bind the socket to. If this is set, Envoy will
+  // create the socket in the specified network namespace. Only supported on Linux.
+  // [#not-implemented-hide:]
+  string network_namespace_filepath = 7;
 }
 
 message TcpKeepalive {
diff --git a/test/common/upstream/health_checker_impl_test.cc b/test/common/upstream/health_checker_impl_test.cc
index 1ad63f319821d..50d21e8e52893 100644
--- a/test/common/upstream/health_checker_impl_test.cc
+++ b/test/common/upstream/health_checker_impl_test.cc
@@ -6547,47 +6547,54 @@ TEST(HealthCheckEventLoggerImplTest, All) {
   std::unique_ptr<HealthCheckEventLoggerImpl> event_logger =
       *HealthCheckEventLoggerImpl::create(health_check_config, context);
 
-  EXPECT_CALL(*file, write(absl::string_view{
-                         "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
-                         "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,"
-                         "\"resolver_name\":\"\",\"ipv4_compat\":false}},"
-                         "\"cluster_name\":\"fake_cluster\","
-                         "\"eject_unhealthy_event\":{\"failure_type\":\"ACTIVE\"},"
-                         "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
-                         "\"metadata\":{\"filter_metadata\":{},\"typed_filter_metadata\":{}},"
-                         "\"locality\":{\"region\":\"\",\"zone\":\"\",\"sub_zone\":\"\"}}\n"}));
+  EXPECT_CALL(
+      *file,
+      write(absl::string_view{
+          "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
+          "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,"
+          "\"resolver_name\":\"\",\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},"
+          "\"cluster_name\":\"fake_cluster\","
+          "\"eject_unhealthy_event\":{\"failure_type\":\"ACTIVE\"},"
+          "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
+          "\"metadata\":{\"filter_metadata\":{},\"typed_filter_metadata\":{}},"
+          "\"locality\":{\"region\":\"\",\"zone\":\"\",\"sub_zone\":\"\"}}\n"}));
   event_logger->logEjectUnhealthy(envoy::data::core::v3::HTTP, host, envoy::data::core::v3::ACTIVE);
 
-  EXPECT_CALL(*file, write(absl::string_view{
-                         "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
-                         "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,"
-                         "\"resolver_name\":\"\","
-                         "\"ipv4_compat\":false}},\"cluster_name\":\"fake_"
-                         "cluster\",\"add_healthy_event\":{\"first_check\":false},"
-                         "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
-                         "\"metadata\":"
-                         "{\"filter_metadata\":{},\"typed_filter_metadata\":{}},\"locality\":"
-                         "{\"region\":\"\",\"zone\":\"\",\"sub_zone\":\"\"}}\n"}));
+  EXPECT_CALL(
+      *file,
+      write(absl::string_view{
+          "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
+          "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,"
+          "\"resolver_name\":\"\","
+          "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_name\":\"fake_"
+          "cluster\",\"add_healthy_event\":{\"first_check\":false},"
+          "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
+          "\"metadata\":"
+          "{\"filter_metadata\":{},\"typed_filter_metadata\":{}},\"locality\":"
+          "{\"region\":\"\",\"zone\":\"\",\"sub_zone\":\"\"}}\n"}));
   event_logger->logAddHealthy(envoy::data::core::v3::HTTP, host, false);
 
-  EXPECT_CALL(*file, write(absl::string_view{
-                         "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
-                         "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,"
-                         "\"resolver_name\":\"\","
-                         "\"ipv4_compat\":false}},\"cluster_name\":\"fake_"
-                         "cluster\","
-                         "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
-                         "\"metadata\":"
-                         "{\"filter_metadata\":{},\"typed_filter_metadata\":{}},\"locality\":"
-                         "{\"region\":\"\",\"zone\":\"\",\"sub_zone\":\"\"},"
-                         "\"successful_health_check_event\":{}}\n"}));
+  EXPECT_CALL(
+      *file,
+      write(absl::string_view{
+          "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
+          "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,"
+          "\"resolver_name\":\"\","
+          "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_name\":\"fake_"
+          "cluster\","
+          "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
+          "\"metadata\":"
+          "{\"filter_metadata\":{},\"typed_filter_metadata\":{}},\"locality\":"
+          "{\"region\":\"\",\"zone\":\"\",\"sub_zone\":\"\"},"
+          "\"successful_health_check_event\":{}}\n"}));
   event_logger->logSuccessfulHealthCheck(envoy::data::core::v3::HTTP, host);
 
   EXPECT_CALL(*file, write(absl::string_view{
                          "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
                          "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,"
                          "\"resolver_name\":\"\","
-                         "\"ipv4_compat\":false}},\"cluster_name\":\"fake_cluster\","
+                         "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_"
+                         "name\":\"fake_cluster\","
                          "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
                          "\"health_check_failure_event\":{\"failure_type\":\"ACTIVE\","
                          "\"first_check\":false},"
@@ -6600,7 +6607,8 @@ TEST(HealthCheckEventLoggerImplTest, All) {
                          "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
                          "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,"
                          "\"resolver_name\":\"\","
-                         "\"ipv4_compat\":false}},\"cluster_name\":\"fake_cluster\","
+                         "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_"
+                         "name\":\"fake_cluster\","
                          "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
                          "\"degraded_healthy_host\":{},"
                          "\"metadata\":{\"filter_metadata\":{},\"typed_filter_metadata\":{}},"
@@ -6611,7 +6619,8 @@ TEST(HealthCheckEventLoggerImplTest, All) {
                          "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
                          "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,"
                          "\"resolver_name\":\"\","
-                         "\"ipv4_compat\":false}},\"cluster_name\":\"fake_cluster\","
+                         "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_"
+                         "name\":\"fake_cluster\","
                          "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
                          "\"no_longer_degraded_host\":{},"
                          "\"metadata\":{\"filter_metadata\":{},\"typed_filter_metadata\":{}},"
@@ -6653,7 +6662,8 @@ TEST(HealthCheckEventLoggerImplTest, OneEventLogger) {
       file_log_data.value(),
       "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
       "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,\"resolver_name\":\"\","
-      "\"ipv4_compat\":false}},\"cluster_name\":\"fake_cluster\","
+      "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_name\":\"fake_"
+      "cluster\","
       "\"eject_unhealthy_event\":{\"failure_type\":\"ACTIVE\"},"
       "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
       "\"metadata\":{\"filter_metadata\":{},\"typed_filter_metadata\":{}},"
@@ -6664,7 +6674,7 @@ TEST(HealthCheckEventLoggerImplTest, OneEventLogger) {
       file_log_data.value(),
       "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
       "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,\"resolver_name\":\"\","
-      "\"ipv4_compat\":false}},\"cluster_name\":\"fake_"
+      "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_name\":\"fake_"
       "cluster\",\"add_healthy_event\":{\"first_check\":false},"
       "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
       "\"metadata\":"
@@ -6676,7 +6686,7 @@ TEST(HealthCheckEventLoggerImplTest, OneEventLogger) {
       file_log_data.value(),
       "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
       "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,\"resolver_name\":\"\","
-      "\"ipv4_compat\":false}},\"cluster_name\":\"fake_"
+      "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_name\":\"fake_"
       "cluster\",\"timestamp\":\"2009-02-13T23:31:31.234Z\","
       "\"metadata\":"
       "{\"filter_metadata\":{},\"typed_filter_metadata\":{}},\"locality\":"
@@ -6688,7 +6698,8 @@ TEST(HealthCheckEventLoggerImplTest, OneEventLogger) {
       file_log_data.value(),
       "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
       "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,\"resolver_name\":\"\","
-      "\"ipv4_compat\":false}},\"cluster_name\":\"fake_cluster\","
+      "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_name\":\"fake_"
+      "cluster\","
       "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
       "\"health_check_failure_event\":{\"failure_type\":\"ACTIVE\","
       "\"first_check\":false},"
@@ -6700,7 +6711,8 @@ TEST(HealthCheckEventLoggerImplTest, OneEventLogger) {
       file_log_data.value(),
       "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
       "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,\"resolver_name\":\"\","
-      "\"ipv4_compat\":false}},\"cluster_name\":\"fake_cluster\","
+      "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_name\":\"fake_"
+      "cluster\","
       "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
       "\"degraded_healthy_host\":{},"
       "\"metadata\":{\"filter_metadata\":{},\"typed_filter_metadata\":{}},"
@@ -6711,7 +6723,8 @@ TEST(HealthCheckEventLoggerImplTest, OneEventLogger) {
       file_log_data.value(),
       "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
       "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,\"resolver_name\":\"\","
-      "\"ipv4_compat\":false}},\"cluster_name\":\"fake_cluster\","
+      "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_name\":\"fake_"
+      "cluster\","
       "\"timestamp\":\"2009-02-13T23:31:31.234Z\","
       "\"no_longer_degraded_host\":{},"
       "\"metadata\":{\"filter_metadata\":{},\"typed_filter_metadata\":{}},"
diff --git a/test/extensions/health_check/event_sinks/file/file_sink_impl_test.cc b/test/extensions/health_check/event_sinks/file/file_sink_impl_test.cc
index f6be7bc9c53d8..fc404286c9bfe 100644
--- a/test/extensions/health_check/event_sinks/file/file_sink_impl_test.cc
+++ b/test/extensions/health_check/event_sinks/file/file_sink_impl_test.cc
@@ -75,7 +75,7 @@ TEST(HealthCheckEventFileSink, logTest) {
       file_log_data.value(),
       "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
       "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,\"resolver_name\":\"\","
-      "\"ipv4_compat\":false}},\"cluster_name\":\"fake_"
+      "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_name\":\"fake_"
       "cluster\",\"eject_unhealthy_event\":{\"failure_type\":\"ACTIVE\"},"
       "\"timestamp\":\"2009-02-13T23:31:31.234Z\"}\n");
 
@@ -101,7 +101,7 @@ TEST(HealthCheckEventFileSink, logTest) {
       file_log_data.value(),
       "{\"health_checker_type\":\"HTTP\",\"host\":{\"socket_address\":{"
       "\"protocol\":\"TCP\",\"address\":\"10.0.0.1\",\"port_value\":443,\"resolver_name\":\"\","
-      "\"ipv4_compat\":false}},\"cluster_name\":\"fake_"
+      "\"ipv4_compat\":false,\"network_namespace_filepath\":\"\"}},\"cluster_name\":\"fake_"
       "cluster\",\"add_healthy_event\":{\"first_check\":false},\"timestamp\":"
       "\"2009-02-13T23:31:31.234Z\"}\n");
 }


Reviews:
user: login: abeyad
body: /lgtm api

based on discussion in https://github.com/envoyproxy/envoy/issues/38947
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-03-29T03:12:43Z
user: login: botengyao
body: Thanks for the contribution! This is an API-only change and has been discussed in #38947. The proposal makes sense to me.
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-08T04:37:28Z
user: login: codablock
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-08T07:02:15Z
user: login: tonya11en
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T17:37:49Z

Review comments:
diff_hunk: @@ -97,6 +97,11 @@ message SocketAddress {
   // allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into
   // IPv6 space as ``::FFFF:<IPv4-address>``.
   bool ipv4_compat = 6;
+
+  // The Linux network namespace to bind the socket to. If this is set, Envoy will
+  // create the socket in the specified network namespace. Only supported on Linux.
path: api/envoy/config/core/v3/address.proto
user: login: botengyao
body: Is there any format requirement for the network namespace file path we should follow, e.g., `/proc/<pid>/ns/net`? Maybe add more comments?
created_at: 2025-04-08T04:34:28Z
author_association: MEMBER
diff_hunk: @@ -97,6 +97,11 @@ message SocketAddress {
   // allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into
   // IPv6 space as ``::FFFF:<IPv4-address>``.
   bool ipv4_compat = 6;
+
+  // The Linux network namespace to bind the socket to. If this is set, Envoy will
+  // create the socket in the specified network namespace. Only supported on Linux.
path: api/envoy/config/core/v3/address.proto
user: login: codablock
body: Please also take into account named network namespaces, which are solved via bind mounts to `/var/run/netns/<name>`
created_at: 2025-04-08T07:02:15Z
author_association: NONE
diff_hunk: @@ -97,6 +97,11 @@ message SocketAddress {
   // allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into
   // IPv6 space as ``::FFFF:<IPv4-address>``.
   bool ipv4_compat = 6;
+
+  // The Linux network namespace to bind the socket to. If this is set, Envoy will
+  // create the socket in the specified network namespace. Only supported on Linux.
path: api/envoy/config/core/v3/address.proto
user: login: tonya11en
body: I'll have to follow this PR up with the implementation, so I'll beef up the comments with examples in the next patch.
created_at: 2025-04-08T17:37:49Z
author_association: MEMBER

PR comments:
user: login: repokitteh-read-only[bot]
created_at: 2025-03-27T20:07:11Z
body: 
As a reminder, PRs marked as draft will not be automatically assigned reviewers,
or be handled by maintainer-oncall triage.

Please mark your PR as ready when you want it to be reviewed!



<details>
	<summary>:cat:</summary>

Caused by: https://github.com/envoyproxy/envoy/pull/38945 was opened by tonya11en.

see: [more](https://github.com/envoyproxy/envoy/pull/38945), [trace](https://prod.repokitteh.app/traces/ui/envoyproxy/envoy/0f2ce770-0b47-11f0-922f-c1790a813ca2).
</details>
author_association: NONE
user: login: repokitteh-read-only[bot]
created_at: 2025-03-27T20:07:15Z
body: CC @envoyproxy/api-shepherds: Your approval is needed for changes made to `(api/envoy/|docs/root/api-docs/)`.
envoyproxy/api-shepherds assignee is @abeyad
CC @envoyproxy/api-watchers: FYI only for changes made to `(api/envoy/|docs/root/api-docs/)`.


<details>
	<summary>:cat:</summary>

Caused by: https://github.com/envoyproxy/envoy/pull/38945 was opened by tonya11en.

see: [more](https://github.com/envoyproxy/envoy/pull/38945), [trace](https://prod.repokitteh.app/traces/ui/envoyproxy/envoy/0f2ce770-0b47-11f0-922f-c1790a813ca2).
</details>
author_association: NONE
user: login: tonya11en
created_at: 2025-04-04T20:07:35Z
body: /retest
author_association: MEMBER
user: login: tonya11en
created_at: 2025-04-07T21:27:22Z
body: /retest
author_association: MEMBER
user: login: tonya11en
created_at: 2025-04-07T22:55:56Z
body: @botengyao / @yanavlasov you are required reviewers on this, since you're code owners.
author_association: MEMBER
user: login: botengyao
created_at: 2025-04-08T04:38:56Z
body: Aha, apologies, and we have the Slack notifier for the @assignee not the reviewers.
author_association: MEMBER
user: login: botengyao
created_at: 2025-04-09T15:28:49Z
body: I think this is ok to merge with an api-shepherds approval and the rest.

/assign-from @envoyproxy/senior-maintainers 

since Adi replied in the channel.


author_association: MEMBER
user: login: repokitteh-read-only[bot]
created_at: 2025-04-09T15:28:56Z
body: @envoyproxy/senior-maintainers assignee is @zuercher


<details>
	<summary>:cat:</summary>

Caused by: a https://github.com/envoyproxy/envoy/pull/38945#issuecomment-2790119056 was created by @botengyao.

see: [more](https://github.com/envoyproxy/envoy/pull/38945#issuecomment-2790119056), [trace](https://prod.repokitteh.app/traces/ui/envoyproxy/envoy/56662c40-1557-11f0-9d20-a1bcdb93bd87).
</details>
author_association: NONE