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

matching: add UDP support for network input types #20116

Merged
merged 8 commits into from
Mar 25, 2022

Conversation

zhxie
Copy link
Contributor

@zhxie zhxie commented Feb 25, 2022

Signed-off-by: Xie Zhihao zhihao.xie@intel.com

Commit Message: matching: add UDP support for network input types
Additional Description: network input types and corresponding matching data introduced by #19493 is for network filters which support stream connections only, and this patch will extent the compatibility for UDP listener filters
Risk Level: Low
Testing: Unit
Docs Changes: N/A
Release Notes: N/A
Platform Specific Features: N/A

@mattklein123 mattklein123 self-assigned this Feb 25, 2022
@zhxie
Copy link
Contributor Author

zhxie commented Feb 28, 2022

It is interesting to find that a registered matcher factory for BaseClass cannot be created from a matcher tree factory of DerivedClass. The CI complains in test of trie matcher, it cannot find DestinationIPInput (whose factory is registered for MatchingDataBase) from match tree factory of MatchingData. I am not sure is it the right behavior? @mattklein123 @snowp

@mattklein123
Copy link
Member

@mattklein123 @snowp

I'm not sure and would need to debug myself unfortunately. @snowp is on vacation and should be back in the next couple of days to help if you want to wait. Thank you.

/wait

@zhxie
Copy link
Contributor Author

zhxie commented Mar 1, 2022

So, maybe we can wait and get some help from snowp. I have done a lot of attempts, but the only solution is to create a UDP matching data, and a lot of UDP inputs and UDP matchers, though these inputs and matchers do the same work with others of TCP, which looks not elegant enough.

@snowp
Copy link
Contributor

snowp commented Mar 7, 2022

The problem is that the factory registrations works via templated factory registrations, which won't honor inheritance. I don' think we have any precedence for this kind of interaction with the existing extension registries, so this will probably require some thinking to come up with a good solution. We do something like this to support "common inputs", where we look for registrations for both the data specific input registrations as well as the common ones.

I think perhaps we'd want some way to declaring a relationship between the more specific and least specific types so that the matcher factory can use this to find all the eligible inputs, but I'm not completely sure on the best way to do this

zhxie added 4 commits March 8, 2022 11:18
Signed-off-by: Xie Zhihao <zhihao.xie@intel.com>
This reverts commit df7971f94524ff15d1719892855e79a1d8331166.

Signed-off-by: Xie Zhihao <zhihao.xie@intel.com>
Signed-off-by: Xie Zhihao <zhihao.xie@intel.com>
Signed-off-by: Xie Zhihao <zhihao.xie@intel.com>
@zhxie zhxie requested a review from mattklein123 as a code owner March 8, 2022 03:18
@zhxie zhxie force-pushed the udp-network-inputs branch from 666de0a to 557b729 Compare March 8, 2022 03:20
@zhxie
Copy link
Contributor Author

zhxie commented Mar 8, 2022

It may be difficult to let these registered base factories support their derivations, so I will make these inputs and factories templated to make the code clean. I choose the simple way since this patch is required by #18791, but I think it is still better to find out some ways making the inheritance work.

@zhxie
Copy link
Contributor Author

zhxie commented Mar 8, 2022

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #20116 (comment) was created by @zhxie.

see: more, trace.

@mattklein123 mattklein123 removed their assignment Mar 8, 2022
Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

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

This seems like an OK solution for now, can you file an issue tracking better ergonomics for shared inputs? I think we generally shy away from template specialization if we can, but I don't have a better solution atm

Could you add a few more tests making sure that all the registration we're doing works as expected?

*/
class UdpMatchingDataImpl : public UdpMatchingData {
public:
explicit UdpMatchingDataImpl(const Address::InstanceConstSharedPtr& local_address,
Copy link
Contributor

Choose a reason for hiding this comment

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

No need for explicit unless it's a 1-arg ctor

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, fixed.

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 have added some tests integrating matcher with network inputs.

And I have opened #20324 to track issues about templated factory registrations inheritance.

zhxie added 2 commits March 14, 2022 13:09
Signed-off-by: Xie Zhihao <zhihao.xie@intel.com>
Signed-off-by: Xie Zhihao <zhihao.xie@intel.com>
@zhxie
Copy link
Contributor Author

zhxie commented Mar 15, 2022

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #20116 (comment) was created by @zhxie.

see: more, trace.

@kyessenov
Copy link
Contributor

@snowp I think templating based on TCP/UDP matching data will also cause the issue occur in the usage in listener matcher (https://github.com/envoyproxy/envoy/pull/20110/files#diff-33e2c942f20e7830dfae2aac2b4f5851e096028e94f29451ffff7b57487caa26R397). We'd have to create either a matcher for UdpMatchingData or TcpMatchingData as DataType unless we solve the base class factory lookup.

/**
* UDP listener filter matching context data for unified matchers.
*/
class UdpMatchingData {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be simpler if we merged this into MatchingData and made socket optional. We can modify the inputs to avoid using socket whenever possible, so they apply to both TCP and UDP.

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 am not sure if it works, since MatchingData currently have inputs like ServerNameInput which only works on TCP now.

Copy link
Contributor

Choose a reason for hiding this comment

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

But you can have SNI in DTLS, no? So in theory, the input could work for datagrams. I'm not certain it's a good idea to combine TCP/UDP datatype, just thinking through.

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 get your idea. Do you think it would be better if we provide interfaces like onSocket, onDestinationIp which is similar to HttpMatchingDataImpl? @snowp

Copy link
Contributor

Choose a reason for hiding this comment

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

The issue is not the callback but the way we get the local address is different between TCP, HTTP, UDP. So I guess it's fine to have separate UDPMatchingData since we have to implement Input functions three times anyways. It's unfortunate that we can't reuse code as much as we'd like.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I mean we can make Socket, DestinationIp in MatchingData as OptRefs and use certain methods to assign their value. It is also a feasible way, but I vote for separating MatchingData since the way to construct a MatchingData with socket looks more natural. And I wish some day we can have template inheritance, so their will be no waste of codes.

Copy link
Contributor

@snowp snowp Mar 18, 2022

Choose a reason for hiding this comment

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

Given how icky the situation is without, can we take a stab at getting something generic working? I can imagine something like

struct Empty {};
struct A {
    using BaseClass = Empty;
    constexpr static std::string_view name = "a";
};

struct B : A {
    using BaseClass = A;
    constexpr static std::string_view name = "b";
};

template<class T>
void traverseInheritanceChain() {
    std::cout << T::name << std::endl;

    if constexpr (!std::is_same_v<typename T::BaseClass, Empty>) {
        traverseInheritanceChain<typename T::BaseClass>();
    }
}

which would require all the data impls to specify either their "base class" or a singleton type. We could probably come up with something clever to avoid having to specify terminal type but might not be worth the complexity

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We are going to register Factory<BaseMatchingData> for Factory<DerivedMatchingData>, and the method we make factories to find their base class may not work, since their is no direct inheritance between Factory<Base> and Factory<Derived>.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for digging into this, seems like it will require some more work so let's get this merged

@zhxie zhxie requested a review from snowp March 18, 2022 06:20
@zhxie
Copy link
Contributor Author

zhxie commented Mar 24, 2022

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #20116 (comment) was created by @zhxie.

see: more, trace.

@snowp
Copy link
Contributor

snowp commented Mar 24, 2022

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #20116 (comment) was created by @snowp.

see: more, trace.

snowp
snowp previously approved these changes Mar 24, 2022
@snowp
Copy link
Contributor

snowp commented Mar 24, 2022

Maybe @mattklein123 can give this a second set of maintainer eyes?

@mattklein123 mattklein123 self-assigned this Mar 24, 2022
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Thanks this makes sense to me. I just want to understand 1 thing: this is not adding new APIs, it's just implementing existing matchers for UDP, is that right? Either way, do we need any documentation updates here? It seems like there should be documentation in release notes, some examples in the UDP proxy filter docs, and I'm not sure if any of the docs that @kyessenov has been working on should be altered to talk about UDP?

@kyessenov do you mind weighing in here since you have done so much work recently on the docs around this? Thank you.

/wait

@zhxie
Copy link
Contributor Author

zhxie commented Mar 25, 2022

Merge conflicts.

Yes, this patch just implements existing network inputs supports for UDP. And as far as I am concerned, documentation of network inputs is protocol agnostic, so there will be no doc changes. And for release notes, this patch does not bring new features or update current filters, it is just a prerequisite for #18791. I would like to add docs for UDP proxy filter, but it is sad that the filter has not supported router yet.

@kyessenov
Copy link
Contributor

@zhxie Documentation-wise, the only thing that is important is to state which inputs work for UDP. This is done explicitly here https://github.com/envoyproxy/envoy/blob/main/docs/root/intro/arch_overview/advanced/matching/matching_api.rst#network-input-functions. We'll probably automate this table later, but for now it's manual.

Signed-off-by: Xie Zhihao <zhihao.xie@intel.com>
@zhxie
Copy link
Contributor Author

zhxie commented Mar 25, 2022

Ok, docs updated. Could you please take a look? @kyessenov

@kyessenov
Copy link
Contributor

Docs LGTM, thanks.

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Great thanks, we can add full docs in the UDP router feature PR. Thank you!

@mattklein123 mattklein123 merged commit 5ccd686 into envoyproxy:main Mar 25, 2022
ravenblackx pushed a commit to ravenblackx/envoy that referenced this pull request Jun 8, 2022
Signed-off-by: Xie Zhihao <zhihao.xie@intel.com>
@zhxie zhxie deleted the udp-network-inputs branch September 7, 2022 08:28
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.

4 participants