Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

original_dst listener filter: implement internal listener support #29655

Merged
merged 9 commits into from
Sep 21, 2023

Conversation

kyessenov
Copy link
Contributor

@kyessenov kyessenov commented Sep 15, 2023

Commit Message: Adds support for recovery of the local and the remote addresses in the internal connections using the original_dst listener filter. This supports two use cases:

  • cluster endpoint tunneling: an endpoint host metadata is passed through to the internal listener to set the IP destination, example:
name: internal_outbound
load_assignment:
  cluster_name: internal_outbound
  endpoints:
  - lb_endpoints:
    - endpoint:
        address:
          envoy_internal_address:
            server_listener_name: internal_outbound
      metadata:
        filter_metadata:
          envoy.filters.listener.original_dst:
            local: 127.0.0.1:8080 # Actual network destination
transport_socket:
  name: envoy.transport_sockets.internal_upstream
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.transport_sockets.internal_upstream.v3.InternalUpstreamTransport
    passthrough_metadata:
    - name: envoy.filters.listener.original_dst
      kind: { host: {}}
    transport_socket:
      name: envoy.transport_sockets.raw_buffer
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer

Additional Description:
Risk Level: low, new feature
Testing: added
Docs Changes: yes
Release Notes: yes
Issue: #29652
issue: #29681

Signed-off-by: Kuat Yessenov <kuat@google.com>
Signed-off-by: Kuat Yessenov <kuat@google.com>
@kyessenov
Copy link
Contributor Author

/assign-from @envoyproxy/envoy-maintainers

@repokitteh-read-only
Copy link

@envoyproxy/envoy-maintainers assignee is @snowp

🐱

Caused by: a #29655 (comment) was created by @kyessenov.

see: more, trace.

@kyessenov
Copy link
Contributor Author

/retest

@kyessenov
Copy link
Contributor Author

/assign-from @envoyproxy/envoy-maintainers

@repokitteh-read-only
Copy link

@envoyproxy/envoy-maintainers assignee is @snowp

🐱

Caused by: a #29655 (comment) was created by @kyessenov.

see: more, trace.

@envoyproxy envoyproxy deleted a comment from repokitteh-read-only bot Sep 18, 2023
@envoyproxy envoyproxy deleted a comment from repokitteh-read-only bot Sep 18, 2023
@kyessenov
Copy link
Contributor Author

/assign-from @envoyproxy/envoy-maintainers

@repokitteh-read-only
Copy link

@envoyproxy/envoy-maintainers assignee is @snowp

🐱

Caused by: a #29655 (comment) was created by @kyessenov.

see: more, trace.

@kyessenov
Copy link
Contributor Author

/assign-from @envoyproxy/envoy-maintainers

@repokitteh-read-only
Copy link

@envoyproxy/envoy-maintainers assignee is @htuch

🐱

Caused by: a #29655 (comment) was created by @kyessenov.

see: more, trace.


Dynamic metadata for the destination address is expected to be placed into the
key `envoy.filters.listener.original_dst` under the field `local` and should
contain a string with an IP and a port address.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the existing use of original_dst and this form, it seems the contract with the rest of Envoy is different. This new use case is about populating filter state, rather than original_dst cluster. Feels a bit overloaded, should there be some plans to separate source of information in some consistent metadata from consumption?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you thinking of a "common" metadata for the destination? This change is about consuming a filter state and metadata, so the typical chain is the following:

  1. Some listener/cluster that produces filter state and/or metadata to an internal address.
  2. Internal listener with original_dst listener filter.
  3. Any cluster, common to have original_dst cluster here.

I was thinking that original_dst listener filter updates the addresses, we no longer need to modify original_dst cluster. But it already has a filter state defined for the same purpose, so we could reuse the same object. This approach might interfere with normal original_dst cluster behavior because filter state takes priority and there is no way to delete a filter state object.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you saying we're using the same filter state as the existing original_dst cluster? If so, I suggest refactoring the docs to make this explicit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we're using different filter states. ORIGINAL_DST cluster uses envoy.network.transport_socket.original_dst_address. original_dst listener filter uses envoy.filters.listener.original_dst.local_ip. I thought you suggested to share them? I think it's safer not to share.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a bit of refactoring to make it clear that ORIGINAL_DST cluster and filter share the object but have different keys.

EXPECT_TRUE(socket_.connectionInfoProvider().localAddressRestored());
EXPECT_EQ(local->asString(), socket_.connectionInfoProvider().localAddress()->asString());
EXPECT_EQ(remote->asString(), socket_.connectionInfoProvider().remoteAddress()->asString());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does an integration test make sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's strictly necessary - the override doesn't affect the data path of original_dst, only where the data comes from. But if you feel like we need it, I can add it. It would need 4 extensions (original_dst filter and cluster, internal listener and upstream).

Signed-off-by: Kuat Yessenov <kuat@google.com>
Signed-off-by: Kuat Yessenov <kuat@google.com>
htuch
htuch previously approved these changes Sep 21, 2023
Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, feel free to merge if you think this is done.

Signed-off-by: Kuat Yessenov <kuat@google.com>
Signed-off-by: Kuat Yessenov <kuat@google.com>
@kyessenov
Copy link
Contributor Author

This should be ready now, @htuch PTAL again.

@htuch htuch merged commit 287a42f into envoyproxy:main Sep 21, 2023
116 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants