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

Add raweth transport (implementation) #283

Merged
merged 38 commits into from
Dec 4, 2023

Conversation

jean-roland
Copy link
Contributor

@jean-roland jean-roland commented Nov 27, 2023

We had a request to send data on an Ethernet link with VLAN support on multicast addresses. This should have been a multicast transport with Ethernet link but we needed to map each keyexpr to a multicast address, from a specific configuration file.

This is not possible to do from the link layer since links don't deal with keyexpr, so we went the route of an ad hoc multicast transport that only deal with raw Ethernet frames and VLAN.

This PR only include the transport implementation, not the code binding the transport to the rest of Zenoh to focus the review on the transport itself.

Here is what's included:

  • system: open, write and send on raw sockets (UNIX only)
  • link: check the locator which is only the root reth, everything else is given by the config
  • config: ad hoc config file with the keyexpr mapping information
  • transport: a multicast transport that encodes Ethernet and VLAN headers from the config data.

Copy link
Member

@cguimaraes cguimaraes left a comment

Choose a reason for hiding this comment

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

Why not to consider each raweth as a new Zenoh link, and each keyexpr mapping to a multicast ethernet address to be the instantiation of a new link?

It seems to me that it would imply less code replication and less cross-layer dependencies between code components.

@jean-roland
Copy link
Contributor Author

Can't reply directly to your comment @cguimaraes, so answering here.

Truly, the major offender of this PR is breaking the transport/link separation but at the same time it's completely isolated from the rest of Zenoh and can be easily removed, which alleviates the code replication.

Currently a session can only have one transport and one link 1:1:1, changing that to 1:1:n has a heap cost and impacts every transport. Also, I'm unsure where the keyexpr mapping would be handled in this case.

@cguimaraes
Copy link
Member

@jean-roland that in indeed a current limitation. But, eventually, we need to extend it to support 1:1:n or even 1:n(2):n. The overhead will happen but only if more than one link or transport is used. But well, there are no free meals :-)

It seems that now would be the time to support multiple links given the constraints you are having. I would like to avoid shortcuts now that could become headaches in the future.

Also, in Zenoh there are only two types of transports: unicast and multicast. It seems that you are implicitly adding a new type, and I am not sure how these changes are planned to be propagated to the rest of Zenoh suite.

@Mallets
Copy link
Member

Mallets commented Nov 28, 2023

@jean-roland that in indeed a current limitation. But, eventually, we need to extend it to support 1:1:n or even 1:n(2):n. The overhead will happen but only if more than one link or transport is used. But well, there are no free meals :-)

It seems that now would be the time to support multiple links given the constraints you are having. I would like to avoid shortcuts now that could become headaches in the future.

Also, in Zenoh there are only two types of transports: unicast and multicast. It seems that you are implicitly adding a new type, and I am not sure how these changes are planned to be propagated to the rest of Zenoh suite.

The main goals of the raweth transport are:

  • working directly on raw ethernet sockets
  • mapping different key expressions to different destination MAC addresses and VLAN IDs for transmission
  • being able to receive different key expressions from different destination MAC addresses and VLAN IDs
  • the sets of MAC addresses used for transmission and reception may be disjoint
  • one single thread for receiving data

Based on the above, I believe in this particular case moving to 1:1:n support will make things more complex:

  • there might be links used only for TX and some others only for RX
  • thread management may become more complex since we might need to handle different links separately
  • since we only have one raw socket, we might need to do some internal dispatching to preserve the link abstraction
  • mapping and ensuring correct src/dst MAC address would be an issue since the sets of MAC addresses used for TX and RX may be disjoint (we need to break somehow the abstraction here)
  • memory footprint would increase since several links objects would need to be created runtime while with a single transport/link a static configuration could be used

@jean-roland
Copy link
Contributor Author

@Mallets: Some update on the PR:

  • Use a configurable ethertype for the frame header
  • Remove the vlan struct as we don't need it
  • Remove code duplication, especially the multicast rx fsm

const _zp_raweth_cfg_entry _ZP_RAWETH_CFG_ARRAY[] = {
{{0, {0}, ""}, 0x00, {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, false}, // Default mac addr
{{0, {0}, "some/key/expr"}, 0x8c, {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}, true}, // entry1
{{0, {0}, "another/keyexpr"}, 0x43, {0x01, 0x23, 0x45, 0x67, 0x89, 0xab}, true}, // entry2
Copy link
Member

Choose a reason for hiding this comment

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

The config should also include a list of allowed MAC addresses in RX.

@@ -0,0 +1,208 @@
//
Copy link
Member

Choose a reason for hiding this comment

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

Is this file really needed? From what I see there is nothing really specific to raweth but rather a code duplication from a generic multicast transport.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For lease/read/join the only differences is the send_t function if I'm not mistaken, so there certainly is a way to mutualize the code.

Copy link
Member

@Mallets Mallets Nov 29, 2023

Choose a reason for hiding this comment

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

I see. In the meanwhile I'd like to the raweth being validated. My proposal is the following:

  • We keep this PR open (and not merging it yet)
  • You can work on an additional PR (based on this one - or directly on this one) that implements the actual logic and code glue
  • Once raweth is validated, we can think about merging into master
    Does it sound like a plan?

@jean-roland jean-roland changed the title Add raweth transport Add raweth transport (implementation) Nov 29, 2023
@jean-roland
Copy link
Contributor Author

jean-roland commented Nov 30, 2023

Alright so moving from the draft to testing phase some modifications needed to be made:

  • Added an interface string in the config to bind the socket, uses a linux specific structure
  • Throw an error if activating the feature not on linux (should revisit this later to support more OS)
  • Added missing vlan ether type in the header
  • Fix some issues with the config parsing
  • Fix some write buffer issues
  • Fix some mutex issues
  • Fix rx task not having a valid path

@p-avital p-avital merged commit 4b8b0a0 into eclipse-zenoh:master Dec 4, 2023
45 of 46 checks passed
@jean-roland jean-roland deleted the ft_raweth_transport branch December 4, 2023 09:00
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