Teach net module how to query an IPv6 address.#1239
Conversation
patrick96
left a comment
There was a problem hiding this comment.
Don't worry about FreeBSD, the network module doesn't work there anyway.
I think throwing an exception would cause the module to be disabled when there is no ipv6 address. What I would propose is to log a warning when the ipv6 address cannot be queried and setting the ipv6 address to "N/A".
Always warning the user would spam the console for non-ipv6 users, so maybe we should have a flag in the network adapter so that only a single warning is generated. We should probably also reset the flag once we successfully query the ipv6 address, so the user gets a warning every time they lose their ipv6 connectivity.
If we lose the ipv6 address and the interface is still up, query_ip6 should automatically fail, so if we implement it as I described above, the ipv6 address should be reset automatically (unlike the ipv4 address).
I wonder if the AF_PACKET case in the query method also counts the data sent via the ipv6 address or if we need extra logic to capture the up and down speeds for ipv6
|
Thank you very much for contributing, I've added my comments above. EDIT: Also the failed travis is not your fault |
I'm pretty sure those statistics include everything on that link regardless of the protocol. It increases accordingly if I do a speed test over IPv6. You can send raw ethernet frames full of null bytes with something like, |
|
Alright, so we don't need extra logic for this, I'm relieved. This makes this really only about finding the ipv6 address |
|
It seems like the message deduplication should be a logging feature, rather than live in the network module adapter thing where I put it. What I imagine is a new Anyway, I think my last changeset addressed your concerns, let me know if I missed something or there's anything else. |
patrick96
left a comment
There was a problem hiding this comment.
Code looks solid. The think with the logger, I think it's overkill to add an extra subclass for that, I was also not necessarily thinking about actual deduplication though, just a boolean whether or not to print a warning right now. But you're way is fine too.
From testing this, on my machine, I get ::1 for the ipv6 address, if I turn of ipv6 connectivity in connman. I don't know how that would work for other network managers though. But I think both N/A and ::1 would be fine in this case.
| freeifaddrs(ifaddr); | ||
|
|
||
| try { | ||
| this->query_ip6(); |
There was a problem hiding this comment.
Please reset the m_ip6_last_error after every successful ipv6 query so that we get warnings message after we lose the ipv6 address again
There was a problem hiding this comment.
Forgot about that basic part while I was busy overthinking this. :)
on my machine, I get ::1 for the ipv6 address
That seems weird. That's loopback and should only be on your lo interface. These changes don't do anything interface specific (although they probably ought to). But it sounds like Linux is saying your IPv6 address is going to be sourced from your loopback address, which is weird.
There was a problem hiding this comment.
Yeah I'm not entirely sure what to do about the IPv6 address information showing up for all interfaces. It's almost better if the IPv6 thing is a separate module to do with routing or something that shows you what source address and interface it would use to get somewhere.
There was a problem hiding this comment.
Oh man! Totally didn't occur to me that this will give the same ipv6 address independent of the interface
So this could only be used for generic ipv6 connectivity (without specifying the interface)
From what I've seen, to open a socket bound to a specific interface you need to have root and so I think the only option is to just use getifaddrs as we already do for ipv4 and use any of the ipv6 addresses on that interface. Technically that's what we do for ipv4 as well, because an interface can also have multiple ipv4 addresses.
There was a problem hiding this comment.
The problem with getifaddrs is that I kept getting several addresses and picking the wrong one. Even if I filtered out link local and filtered by their scope. But curl seems to use getifaddrs successfully. They're probably doing something right that I missed. So I'll look at that later and if I figure it out I'll rewrite this.
There was a problem hiding this comment.
If an interface has multiple ipv6 addresses (with global scope), how can any of them be the right one?
From looking at curl lib/if2ip.c, it filters addresses out by scope, but depending on the destination address (which we don't have).
How many ipv6 addresses does your interface have, that you are getting so many different addresses?
I would have said that it is a safe heuristic it to always use an address with global scope (if available) and otherwise choose any of the other addresses, because most of our users will have an ipv6 address with global scope (if they have an ipv6 address). But if you still pick the "wrong" address after that, then maybe it's not such a good heuristic.
There was a problem hiding this comment.
how can any of them be the right one
The one I use to talk to the internet. :)
My interface has five IPv6 addresses, two are supposed to be there, a global unicast address and a link local address.
The other three appear to be from avahi-daemon I guess. I don't know why it was running, but it seems like a configuration issue with my machine. One of the three address is a global unicast address that I can use on the internet. However, it's not important enough in my routing table--so Linux won't use it--but polybar doesn't know that when it sees the addresses.
While I was searching for this, I found several folks who had received extra addressing from SLAAC. So it seems like something that could come up.
There was a problem hiding this comment.
Turns out maybe avahi-daemon wasn't responsible for the extra addresses, maybe it was just logging about them innocently, because I stopped the service and rebooted and still have these extra weird addresses. I'm thinking that NetworkManager is doing something. But I'm not sure why. As far as I can tell, SLAAC shouldn't be enabled. With the previous change, polybar displays the wrong address. Something I might look at is what ip route get to 2001:7fd::1 dev eno1 does, but netlink can be a bit gross to deal with.
There was a problem hiding this comment.
The one I use to talk to the internet. :)
Yeah obviously, but isn't it possible that a single interface has multiple IPs with which it can reach the internet? On my Raspberry PI, I have three global ipv6 addresses on the same interface.
Something I might look at is what
ip route get to 2001:7fd::1 dev eno1does, but netlink can be a bit gross to deal with.
Yeah, or ping -6 -I eno1 2001:7fd::1 will also give you an ipv6 address that can reach the internet.
There was a problem hiding this comment.
Just checked and I can ping 2001:7fd::1 with two of the three addressed. It seems we might have to inspect some routing tables in order to determine which IPv6 can reach the internet. Worst case, we can call ip route get to 2001:7fd::1 dev eno1 and inspect the output
No longer trying to get the address from a socket.
| label->reset_tokens(); | ||
| label->replace_token("%ifname%", m_interface); | ||
| label->replace_token("%local_ip%", network->ip()); | ||
| label->replace_token("%local_ip6%", network->ip6()); |
There was a problem hiding this comment.
Since we are now trying to display globally routable ipv6 addresses, do you think calling it local_ip6 could be a little misleading?
There was a problem hiding this comment.
Maybe if you treat "local" here is being used to mean "private". I believe the compliment of "local" is "remote" not "global". And technically you can have a public/globally routable ipv4 address on the interface and it would show up in polybar. So "local_ip" really does mean local, as opposed to meaning "private". So I kinda think local is technically correct.
patrick96
left a comment
There was a problem hiding this comment.
Everything looks good to me. Are you satisfied with this? Or do you still want to do some work to get the right ipv6 address?
|
Sorry for the delay. On my machine, it doesn't yet display how I'd like it to, but I don't know if I'll have much time to work on this in the near future. It's also possible that my machine's configuration is a little bananas and this will work for most everyone who cares. So I'd be happy if it were merged it in. If I revisit it in the future I can open a new pull request or something. |
|
Alright, going to merge this then. I think the solution is good enough. Thank you! |
Breaking Changes: * `0 < label-NAME-maxlen < 3` will now throw an exception and disable the containing module, if ellipsis is enabled for that label. (#1198) Changelog: Deprecations: * `internal/volume` is now called `internal/alsa` (#967) * temperature: The `%temperature%` is deprecated in favor of `%temperature-c%`(#897) * mpd: `icon-repeatone` is deprecated in favor of `icon-single` (#1295), see #1279 Features: * feat(mpd): Add support for icon-consume (#861) * feat(bspwm): Add workspace separator (#942) * feat(i3): Add workspace separator (#938), see #929 * feat(build): Make polybar build on FreeBSD (#931, polybar/xpp#8), see #239 * feat(volume): Add pulseaudio backend (#779) * feat(script): Add %pid% token for tail commands (#934) * feat(temp): Add temperature tokens without unit (#897) * feat(memory): Add memory used/free ramp (#1038), see #1037 * feat(memory): Add swap tokens (#1018) * feat(net): Add unknown-as-up option (#1077), see #457 * feat(config): Support fractional size and offset (#972), see #953 * feat(xwindow): Add label-empty (#1136) * feat(battery): Add animation-discharging (analog to animation-charging) (#1190) * feat(config): Support pixel offset for bar size and offset values (#1224) * feat(mpd): Add `%album-artist%` token (#1263) * feat(net): Add local_ip6 token (#1239), see #1234 * feat(net): Add nl80211 support (#1009), see #277 Fixes: * fix(mpd): Wrong elapsed time when after standby (#921), see #915 * fix(config): Wrong min, maxlen when using the same token multiple times (#974), see #971 * fix(battery): use power_now correctly (#958), see #928 * fix(mpd): Crash when mpd isn't running (#983), see #979 * fix(xworkspaces): Respect 'enable-scroll' (#1002) * fix(xbacklight): Respect 'enable-scroll' (#1014) * fix(build): support xcb-proto >=1.13 (polybar/xpp#11), see #973 * fix(mpd): Respect MPD_HOST env variable (#1025), see #1007 * fix(i3): Reconnect i3 IPC socket on restart/error (#1099), see #762 * fix(cursor): Occasional crash on mouseover (#1124), see #1117 * fix(net): Mark 'not connected' on querying failure (#1171), see #1163 * fix(gcc): Fix -Wstringop-truncation warning (#1216, polybar/i3ipcpp#7), see #1215 * fix(builder): Don't truncate colors with same channels (#1217), see #1183 * fix(bspwm): Consistent behavior when scrolling through multiple desktops (#986), see #981 * fix(builder): Respect label-ellipsis option (#1198), see #1194
This should probably throw network_error instead of call
perror()maybe?Also, I think if you lose addressing but the interface is still up, the value on m_status isn't unset so the address is still displayed. I think the IPv4 thingy does that too.
I'm also not sure if this works on FreeBSD.
EDIT: Fixes #1234