Comments (10)
Looks like this is from wireguard interfaces that don't currently have an endpoint. It's strange I'm not seeing this on any of my other routers since this is fairly common in my deployment because I always have two wg devices per destination host so things work over both v4 and v6 underlay networks, but often only one will actually be working.
The router that started printing the errors has recently been updated to Debian 12 whereas the others aren't yet so it's probably related to a kernel change.
from babeld.
Interesting. Do you think you could capture a trace with strace?
from babeld.
This error is returned by Wireguard, it makes "interesting" usage of existing error codes and that can sometimes make it hard to understand the error.
It indeed happens if you have Wireguard peers without an endpoint, here is what Wireguard does:
family = READ_ONCE(peer->endpoint.addr.sa_family);
if (unlikely(family != AF_INET && family != AF_INET6)) {
ret = -EDESTADDRREQ;
net_dbg_ratelimited("%s: No valid endpoint has been configured or discovered for peer %llu\n",
dev->name, peer->internal_id);
goto err_peer;
}
from babeld.
Could you please explain what it means for a wireguard peer to not have an endpoint? Is it something that happens in normal usage, or is it an erroneous configuration?
from babeld.
It's a perfectly valid configuration. Setting the endpoint on startup is optional. Wireguard sets the endpoint based on incoming encapsulated packets automatically, so not having an endpoint set (yet) just means this interface is standing by waiting to get traffic from this peer.
It certainly isn't worth printing a log line on every attempted send(). I've been thinking about how to handle this and I think we have two options 1) special case type wireguard
interfaces and ignore this error completely or 2) rate-limit this error to once per startup or once every couple of minutes.
from babeld.
We could of course avoid logging this specific error, or at least rate-limit the logging. But I'd much rather somebody implemented good support for Wireguard in Babel.
Some ideas:
interface wg0 unicast-only true
. All packets are send to unicast addresses. Hellos are either converted to multi-unicast, or sent as unicast Hellos (not sure which one is better). This is stronger thanunicast true
, which send Hellos as multicast.neighbour fe80::1234 if wg0
: statically defines a unicast neighbour, to which it will send Hellos even ifunicast-only
is true.- Have some form of communication between Wireguard and babeld so that babeld can learn unicast-only peer addresses. (Probably not needed.)
from babeld.
I've started copying the embeddable-wg-library into the babeld tree more than once but it always defeats me in the end ;)
-
I'm not sure what a multi-unicast here?
-
I don't think statically configuring the neighbours is very nice.. I'd much rather babeld just sent it's adverts to every peer that has an fe80::/64 addresses automatically (or at least does this optionally).
The main blocker for wg support is it's internal routing based on allowedips.
We pretty much have to dynamically install allowedips to select which peer traffic should go to but wireguard doesn't have an efficient API for doing this like we have for kernel routes which is disappointing.
Makes me think perhaps there should be a route attribute we can set that wireguard picks up. Not sure how well received that would be by Jason though. Certainly would be more efficient (and easier code wise) for the dynamic routing use-case though. Hmm.
from babeld.
I'm not sure what a multi-unicast here?
A multi-unicast is when instead of sending a multicast packet, you send the equivalent unicast packet to every neighbour. Of course, this requires that you already know the addresses of the neighbours, but it is my understanding that wireguard is able to provide this information.
Makes me think perhaps there should be a route attribute we can set that wireguard picks up. Not sure how well received that would be by Jason though.
Could that not be done in userspace? A daemon that monitor's Babel's routing table and pushes all routes into Wireguard?
from babeld.
FYI, I wrote a small daemon that does almost this, although it's the other way around: it monitors Wireguard peers and pushes routes to the kernel. It's at https://github.com/zorun/wg-autoroute . I didn't use netlink to ease deployment. Also, we don't have resources constraints, so forking regularly is fine for us.
from babeld.
I'm not sure what a multi-unicast here?
A multi-unicast is when instead of sending a multicast packet, you send the equivalent unicast packet to every neighbour. Of course, this requires that you already know the addresses of the neighbours, but it is my understanding that wireguard is able to provide this information.
Right, we can enumerate all wireguard peers and find their allowed-ips, sure. The user would have to ensure every peer has a unique fe80::/64 link-local address though but that's not really a problem either.
Makes me think perhaps there should be a route attribute we can set that wireguard picks up. Not sure how well received that would be by Jason though.
Could that not be done in userspace? A daemon that monitor's Babel's routing table and pushes all routes into Wireguard?
I mean in my mind babeld is exactly that daemon.
It's not that we can't do it, but it's inefficient. AFAICT from the kernel source wireguard's netlink interface only lets us replace all peers and all their allowedips at once. So that's going to be a big scaling bottleneck.
My idea would be to have something like ip route add 2001:db8::/64 dev wg0 wg-peer <base64-pubkey>
to bypass wireguard's internal allowedip based routing and select the peer directly in the routing table, but that's probably too much hassle to support in the kernel. I'd settle for just a more efficient wg netlink api to add/remove allowedips instead :)
FYI, I wrote a small daemon that does almost this, although it's the other way around: it monitors Wireguard peers and pushes routes to the kernel. It's at https://github.com/zorun/wg-autoroute . I didn't use netlink to ease deployment. Also, we don't have resources constraints, so forking regularly is fine for us.
Thanks! I was pretty much about to implement this myself as I want to play with redundant wg endpoints :)
I had one additional idea I was going to try out: what if the (babel) metric of a peer's route was dependent on the time since the last wg handshake? That way failover could be much faster than just picking a cutoff for when a peer is "active" like you (seem) to do. Alas, again, there is no efficient netlink API for getting notified of handshake events so it would amount to polling every wg device and every peer once a second (or however fast/slow the failover should be) which is not efficient at all.
Anyway this is orthogonal to the issue of supporting dynamic(!) allowedips with babel. The problem with setting AllowedIPs=::/0 statically is that you loose the ability to have more than one peer per wg device and having a static list of prefixes as is the "normal" wireguard deployment kind of defeats the purpose of dynamic routing.
--Daniel
from babeld.
Related Issues (20)
- kernel_route: Invalid argument HOT 2
- bugs in parse_hello_subtlv, parse_ihu_subtlv, parse_request_subtlv, parse_seqno_request_subtlv, and parse_other_subtlv HOT 2
- Babeld does not function properly HOT 1
- Feature request: exchange arbitrary strings HOT 4
- incorrect checkings in babel HOT 1
- babeld replaces routes non-atomically HOT 1
- routing loop due to ignoring linkdown HOT 3
- Need help with redistribute default routes HOT 4
- Interface Regex? HOT 1
- Inject routes with different mtu? HOT 3
- Is there intention to support IPv4 multicast group as well? HOT 1
- Error : Generating IPV6 Address HOT 1
- Same route announced twice? HOT 2
- Upper Bound on Interface Count? HOT 4
- Denying routes in install filter doesn't work HOT 6
- Release tag missing for 1.11 HOT 1
- 1.12 tag missing HOT 1
- Check Interfaces in add_interface HOT 2
- babeld 1.12.1 build failure HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from babeld.