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

net/vnstat: Handle multiple interfaces better #4443

Open
wants to merge 15 commits into
base: master
Choose a base branch
from

Conversation

bensmithurst
Copy link

@bensmithurst bensmithurst commented Jan 4, 2025

I tried using vnstat to report on multiple interfaces (to see how much traffic is going over a backup LTE connection I'm experimenting with) and it didn't really work. (update: some of this was due to user error)

  • Selecting two interfaces was allowed but resulted in Interface foo+bar in vnstat.conf which appears to be a config directive only supporting one interface. (this works fine, my problem was due to the point below)
  • vnstat was not configured to pick up new interfaces added after it was first installed.
  • The stat in the UI only show the interface configured on the general tab, and as noted, configuring more than one there doesn't work. (also not a problem)

Putting my user error aside, it does work mostly, but doesn't pick up new interfaces, and can't show interface stats individually.

To improve this I have:

  • Restricted the interface option to one interface only, and renamed it to Default interface
  • I've added a second 'Interfaces to display' option, which allows more than one to be selected
  • The stats pages in the UI now show stats for all interfaces specified under 'Interfaces to display'
  • The vnstat config contains AlwaysAddNewInterfaces to make it notice new interfaces added.
  • Added a new config option to show stats separately, instead of a sum.

@@ -9,7 +9,11 @@
</enabled>
<interface type="InterfaceField">
<Required>N</Required>
<multiple>Y</multiple>
<multiple>N</multiple>
Copy link
Member

Choose a reason for hiding this comment

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

Allegedly this worked in the past with multiple interfaces given as a single interface, but only up to a limit of 16/32 characters which may be the reason it doesn’t work for you. This is an upstream issue. Breaking this here for people who use it ok is not an option, however.

Copy link
Author

Choose a reason for hiding this comment

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

Interesting. My interface string was just igb0+ue0 (possibly reversed) so well within that limit. I'll dig into exactly how vnstat handles that config option later hopefully.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, yes, pretty sure this used to work.

Copy link
Author

Choose a reason for hiding this comment

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

Ok, some of this may have been caused by me trying to fix it before understanding that the missing AlwaysAddNewInterfaces was part of the problem, so that's my bad. Sorry for the noise. If the Interface directive contains an interface that doesn't exist in vnstat's DB, retrieving stats returns an error. So just adding AlwaysAddNewInterfaces would be enough to fix that.

However what I was hoping for (and what my change does) is to show stats for different interfaces separately. Getting a combined total for WAN+LTE isn't useful for my use case.

Would a PR which just adds AlwaysAddNewInterfaces and adds a new option called something like 'Separate interface stats' - implemented along the lines as I have done here, and defaulting off of course - and otherwise leaving the interface options alone, be acceptable?

Copy link
Member

Choose a reason for hiding this comment

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

Yes that sounds like a plan 😊

Copy link
Author

Choose a reason for hiding this comment

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

I'll get right on it. :)

Copy link
Author

Choose a reason for hiding this comment

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

I've updated the PR. I've removed the stats.sh wrapper I added, that was only needed because I'd misunderstood how the Interface option worked, so I've binned it.

@bensmithurst bensmithurst marked this pull request as draft January 5, 2025 10:58
@bensmithurst bensmithurst marked this pull request as ready for review January 5, 2025 11:28
@@ -9,6 +9,13 @@
<id>general.interface</id>
<label>Interface</label>
<type>select_multiple</type>
<help>Set the interface to listen on.</help>
<help>Set the interface(s) to display stats for.</help>
Copy link
Author

Choose a reason for hiding this comment

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

Open to suggestions on this but I think the previous text was misleading, vnstat always gathers stats for all known interfaces as far as I can tell, this config option just controls the default for command line queries, and therefore what OPNsense shows in the UI pages.

Copy link
Member

Choose a reason for hiding this comment

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

If this is true it might be better to flip the default to the new behaviour.

wouldn’t that also mean querying stats works using “dev1+dev2”?

Copy link
Author

Choose a reason for hiding this comment

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

I'm not sure what you mean by 'new behaviour' - do you mean the separation of interface stats? That seems a bad default change for people used to the current behaviour.

Querying for dev1+dev2 does work (other than my problems due to a 'missing' interface earlier) but just provides the total, not separate stats per interface as I'm trying to achieve - perhaps I've misunderstood what you're asking though.

Copy link
Member

Choose a reason for hiding this comment

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

If this merely pertains to stats fetch and you can fetch all interfaces using your code… changing the default to separate interface stats for multi select is not a bad thing. People can flip back to the old behaviour of the summarized query?

Copy link
Author

Choose a reason for hiding this comment

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

I've changed the default now.

$result = '';
foreach (explode(',', $config['OPNsense']['vnstat']['general']['interface']) as $interface) {
// Map the OPNsense interface name to the kernel interface name that vnstat uses.
if (isset($config['interfaces'][$interface]['if'])) {
Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately this is only correct for IPv4 or the easy interface cases. Ping me on Monday for how to gather complete stats across split IPv4/6 interface assignments.

Copy link
Author

Choose a reason for hiding this comment

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

@fichtner so, about this, what's a better way to do it? I checked the logic for how the vnstat.conf is generated and it seems to use similar logic to this, but using a macro

{%     for interface in OPNsense.vnstat.general.interface.split(',') %}
{%       do interfaces.append(physical_interface(interface)) %}
{%     endfor %}

where the macro is doing:

{% if helpers.exists('interfaces.'+name+'.if')
%}{{
      helpers.getNodeByTag('interfaces.'+name+'.if')
}}{%
else %}{{name}}{%
endif

.. which is largely the same as I'm doing, I think? If my logic in this PR is wrong, is this config logic also wrong? (I find it odd that the config logic falls back to the input value for unknown interfaces, rather than just ignoring them? Or is that needed for.. reasons?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants