Detect if current connection is metered with NetworkManager
Asked Answered
A

3

16

How can I detect whether the current connection is marked as metered on a system with NetworkManager?

This is from a shell script, but I can easily call any C functions via Python.

Armillary answered 5/4, 2017 at 10:47 Comment(0)
I
20

With the nmcli utility, the necessary steps are:

  1. verify NetworkManager is version 1.0.6+:

    $ nmcli -v nmcli tool, version 1.9.0

  2. check GENERAL.METERED on an interface:

    $ nmcli -t -f GENERAL.METERED dev show eth1 GENERAL.METERED:unknown

  3. values are: unknown, yes, no, yes (guessed), no (guessed)

  4. Forcing the value is done like this:

    $ nmcli dev modify wlan1 connection.METERED yes Connection successfully reapplied to device 'wlan1' $ nmcli -t -f GENERAL.METERED dev show wlan1 GENERAL.METERED:yes

And, to get a list grouped by device:

  $ nmcli -t -f GENERAL.DEVICE,GENERAL.METERED dev show

  GENERAL.DEVICE:wlan1
  GENERAL.METERED:yes

  GENERAL.DEVICE:eth1
  GENERAL.METERED:unknown

  GENERAL.DEVICE:lo
  GENERAL.METERED:unknown

Trying to cut this down to info on just the default route would still require a call to another command as NetworkManager doesn't try to distinguish between multiple devices in a connected state:

  $ nmcli -t -f GENERAL.DEVICE,GENERAL.METERED dev show `ip route list 0/0 | sed -r 's/.*dev (\S*).*/\1/g'`
Intoxication answered 7/4, 2017 at 21:17 Comment(5)
Excellent! Is there a way to only show the information for the network the first default route is going over? With many VPNs and otherwise virtual networks, the output of nmcli -t -f GENERAL.METERED dev show (without a device) is a mixture of all possible values for me.Armillary
I've added a way to see the device names, but I think you may need to ask ip route and ideally ip monitor to reliably track the interface of the default route or relevant server then do/redo the nmcli query.Intoxication
Thanks! I'll award the bounty in a couple of hours.Armillary
See also unix.stackexchange.com/questions/364927/…, which describes how to set the connection (i.e. SSID) rather than the interface. This makes sense when you may have more than wifi connection, one to a mobile hotspot.Rival
You can test the output with [[ "$(nmcli -t -f GENERAL.METERED dev show `ip route list 0/0 | sed -r 's/.*dev (\S*).*/\1/g'` | cut -d':' -f2)" == yes* ]]Northampton
N
14

You can also get the metered status of the current connection via D-Bus. From a shell, you can use busctl:

busctl get-property org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager Metered

which is only one command, in contrast to the nmcli solution, and in other programming languages it can be more efficient to use D-Bus directly instead of having to call nmcli.

The result is an enum with the following values (documentation):

Name Value Description
NM_METERED_UNKNOWN 0 The metered status is unknown
NM_METERED_YES 1 Metered, the value was explicitly configured
NM_METERED_NO 2 Not metered, the value was explicitly configured
NM_METERED_GUESS_YES 3 Metered, the value was guessed
NM_METERED_GUESS_NO 4 Not metered, the value was guessed
Nelda answered 1/2, 2019 at 14:39 Comment(3)
The result is an enum with the following valuesNorthampton
The output is something like: u 1 . If you prefer JSON, then pass the -j flag, and you will get output like { "type": "u", "data": 1 }Louisiana
For future explorers, you can use Gnome's D-Spy app to explore and get the service, object, interface, and property names passed to busctl. It even tells you the datatype and lets you query the property in real-time. Invaluable!Platonic
E
0

For some reason the solution from lossleader always returns no on my system, while using the metered parameter from the connection works fine:

nmcli -f connection.metered connection show `nmcli -t -f GENERAL.CONNECTION --mode tabular device show $DEVICE | head -n1`

Edlin answered 11/6, 2022 at 15:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.