Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Teach net module how to query an IPv6 address.#1239

Merged
patrick96 merged 5 commits into
polybar:masterfrom
sqwishy:local_ip6
Jun 10, 2018
Merged

Teach net module how to query an IPv6 address.#1239
patrick96 merged 5 commits into
polybar:masterfrom
sqwishy:local_ip6

Conversation

@sqwishy

@sqwishy sqwishy commented May 17, 2018

Copy link
Copy Markdown
Contributor

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

@patrick96 patrick96 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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

@patrick96

patrick96 commented May 17, 2018

Copy link
Copy Markdown
Member

Thank you very much for contributing, I've added my comments above.

EDIT: Also the failed travis is not your fault

@sqwishy

sqwishy commented May 18, 2018

Copy link
Copy Markdown
Contributor Author

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

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, seq 3000 | xargs -n1 -P12 -i socat -u OPEN:/dev/zero,readbytes=1234 INTERFACE:eno1. Even though those packets don't mean anything, they appear to be included in the link statistics and bump up the reported send rate a little bit in polybar.

@patrick96

Copy link
Copy Markdown
Member

Alright, so we don't need extra logic for this, I'm relieved. This makes this really only about finding the ipv6 address

@sqwishy

sqwishy commented May 19, 2018

Copy link
Copy Markdown
Contributor Author

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 logger subclass where output tests the message against the previous, exits if they match, otherwise saves that messages the last and either calls the base class output() or calls output() on a "parent" logger in order to go through filtering (such as log level) of the singleton logger. But I didn't try this because I didn't want to get carried away.

Anyway, I think my last changeset addressed your concerns, let me know if I missed something or there's anything else.

@patrick96 patrick96 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Comment thread src/adapters/net.cpp Outdated
freeifaddrs(ifaddr);

try {
this->query_ip6();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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

@sqwishy sqwishy May 21, 2018

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

@sqwishy sqwishy May 24, 2018

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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 eno1 does, 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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

sqwishy added 2 commits May 21, 2018 12:53
No longer trying to get the address from a socket.
Comment thread src/modules/network.cpp
label->reset_tokens();
label->replace_token("%ifname%", m_interface);
label->replace_token("%local_ip%", network->ip());
label->replace_token("%local_ip6%", network->ip6());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since we are now trying to display globally routable ipv6 addresses, do you think calling it local_ip6 could be a little misleading?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Fair enough :)

@patrick96 patrick96 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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?

@sqwishy

sqwishy commented Jun 10, 2018

Copy link
Copy Markdown
Contributor Author

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.

@patrick96

Copy link
Copy Markdown
Member

Alright, going to merge this then. I think the solution is good enough. Thank you!

@patrick96 patrick96 merged commit d1d307d into polybar:master Jun 10, 2018
patrick96 added a commit that referenced this pull request Jul 23, 2018
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
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.

2 participants