-
Notifications
You must be signed in to change notification settings - Fork 447
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
Support for multiple interfaces #55
Comments
So... why does smoltcp need to support multiple interfaces? It's not only perfectly doable but also IMO more convenient to build routing on top of it. That is, packets originating in the OS or destined to the OS are routed according to the OS' routing table, and the rest is handled using raw sockets, which also provide buffering, because it's not really possible to do routing without buffering with smoltcp given how ownership works in it. |
That would mean I have to use an instance of |
Once you figure out a design we might lift it into smoltcp, but right now I feel like it's not the right direction for this project to delve into. |
After trying to implement it for some time, I've decided against building on top of smoltcp : coordinating several independent TCP/IP stacks under a single abstraction just doesn't feel right. Instead, I opted for a simple ad-hoc implementation of loopback: redox-os/netstack@b54ead7 . Basically, my Specifically, I'm thinking about changing the While I'm happy with my stop-gap solution for loopback for now (Redox doesn't support multiple NICs yet), I can investigate the described approach once #57 is done if you think it could work for smoltcp. |
I don't think this works. For example, an Ethernet port has an But I just realized something very nice. We don't need to add anything new to smoltcp for it to support multiple interfaces! You can simply use the same |
Why not? If we refactor
I've played with this idea, but decided against it. One of the problems here is egress packets, especially for sockets like DNS server, i.e. UDP bound to 0.0.0.0:53, sending packets potentially to anyone. Even if we had a way for an interface to peek into socket's queue to cherry pick packets it can route, which we don't, it would require |
I'm really not happy with this approach but if I don't come up with anything better, so be it.
Matching against CIDRs is literally a single |
|
Okay, I understand your proposal more clearly now. I will reconsider it. |
I have reconsidered it and, indeed, it makes perfect sense. Also, we can just have a |
That issue is quite old, so I assume people already have working workarounds? What is common approach for having multiple network interfaces? For example Ethernet and IEEE 802.15.4 . |
You can create multiple independent network stacks, each with its own Interface+SocketSet+Device. If you want to speak on Ethernet create a socket on the Ethernet SocketSet, same for ieee802154. With this the two stacks would be 100% independent. This issue is about supporting multiple interfaces in a single network stack, which would allow features like creating one socket and having it routed automatically based on which interface is up or the destination IP, having a single socket listening on all interfaces, routing packets between interfaces. If you don't need any of these, the "multiple stacks" solution should work for you. |
@Dirbaio thank you for your answer, but my question was exactly about things your mentioned, except routing between interfaces:
I just assumed that and did not clarify 😅 |
you can mostly simulate those by looking at what interface is up and creating the socket in that one manually, and for listening on both you can create two sockets. |
That solution does not seem to scale... We may want to contribute this piece in the future. |
As mentioned in #50, I've been looking into support for multiple interfaces/devices. My overall plan is to leave the current
EthernetInterface
structure to represent a network interface with ARP cache, MAC/IP addresses, and aDevice
assigned to it, addInterfaceSet
with aManagedSlice
ofEthernetInterface
s andipv4_gateway
in it, and move all the packet processing logic fromEthernetInterface
toInterfaceSet
.I don't see any point in trying to do it statically, that means we should rely on trait objects a lot and have to accept the inevitable performance hit. The problem is that the current
Device
trait doesn't work well as a trait object because it uses the associated types by value. Since we need to call destructors onRx/TxBuffer
, andBox
is the only way to own a trait object, refactoringDevice::transmit
to return something likeResult<Box<AsMut[u8]>>
looks promising, but usingBox
requiresalloc
, something we can't afford here.All that means the
Device
trait should be redesigned into something more suitable for using as a trait object, maybe something like #49 (comment), but with the functions passed as function pointers directly totransmit
/receive
, if it makes any sense. Maybe we could haveDevice
to own the latest received packet and have a method to return a slice to it, and use a functional argument fortransmit
.I'm not sure if I should go ahead with this approach, so I wonder if you have any ideas.
The text was updated successfully, but these errors were encountered: