ironsheep / RPi-Reporter-MQTT2HA-Daemon

Linux service to collect and transfer Raspberry Pi data via MQTT to Home Assistant (for RPi Monitoring)
GNU General Public License v3.0
442 stars 62 forks source link

Suggestion to replace "eth|wlan" with "en|eth|wl" for improved compatibility with network naming conventions #79

Open BoW2EviL opened 1 year ago

BoW2EviL commented 1 year ago

Description: The following line of code is used to show links in a network interface:

cmd_str = '{} link show | /bin/egrep -v "link" | /bin/egrep " eth| wlan"'.format(

However, this command may not be compatible with all network naming conventions. For example, some systems use interface names starting with "eno" instead of "eth" , which would not be included in the command's search pattern.

To improve compatibility with a wider range of network naming conventions, I suggest replacing "eth|wlan" with "eno|eth|wl". The updated line of code would look like this:

cmd_str = '{} link show | /bin/egrep -v "link" | /bin/egrep " eno| eth| wl"'.format(

This way, the command will search for interface names starting with "eno", "eth", "wl*", which should cover a wider range of naming conventions.

Let me know if you have any questions or concerns about this suggestion.

ironsheep commented 1 year ago

I would like to hear about which OS's these names do not work so I can document what's being done to support each of them. As you suggest it should be pretty easy to add this support (or to add config.ini options to change how they're being recognized for a given os - which strings are being used...)

bsimmo commented 1 year ago

This is part of the Predictable Naming Scheme. Ubuntu uses this style, at least on the one I was helping with yesterday. No doubt Debian does by default (I don't actually know).

RaspberryPi OS, for a short time, had it enabled some years back, either with the move to Jessie or Stretch. It was quickly disabled for compatibility and ease with the education side. You can enable it again in raspi-config. (basically eth0 may turn up as eth1 and wlan's in USB can move around from wlan0 to wlan1 depending on luck during boot up because of the way they are assigned, the move to predictable allows someone to know where it is. Likely useful for CM4 style setup or servers and AP routers). @BoW2EviL will confirm if that is what it is for?

Webguyatwork commented 1 year ago

I have a slightly different but related situation with an Ubuntu container running in Proxmox:

DISTRIB_ID=Ubuntu DISTRIB_RELEASE=22.04 DISTRIB_CODENAME=jammy DISTRIB_DESCRIPTION="Ubuntu 22.04.1 LTS"

# ip address
2: eth0@if29: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
# /sbin/ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

getSingleInterfaceDetails() uses /sbin/ifconfig on the provided interface names, which in my case it throws an error. As a result, I get no mac address returned, and all my container VMs stomp over each other because the unique_id values are all the same.

I fixed this with a one-line update:

    #lines = getSingleInterfaceDetails(interface)
    lines = getSingleInterfaceDetails(interface.split('@')[0])

It seems this 'eth0@if##' convention is common when using VLAN interfaces, which is exactly what I'm doing with my Proxmox containers.

BoW2EviL commented 1 year ago

(basically eth0 may turn up as eth1 and wlan's in USB can move around from wlan0 to wlan1 depending on luck during boot up because of the way they are assigned, the move to predictable allows someone to know where it is. Likely useful for CM4 style setup or servers and AP routers). @BoW2EviL will confirm if that is what it is for?

your mainly correct but some like debian use a different naming structure here's a example of mine: eno1: ethernet wlp3s0b1: wifi

thus "eno| eth| wl" should pick up most iface's but according to the following maybe it should be "en| eth| wl"

according to https://superuser.com/questions/1053003/what-is-the-difference-between-eth1-and-eno1

The difference between eth0 and eno1 is the method/scheme the Linux kernel used to assign a name the Ethernet interface in question.

In the 1990s, Linux assigned the names of the form ethX (where X is a numeral) to Ethernet network interfaces.

However, on a machine with multiple network interfaces, an interface would not receive the same name consistently across reboots due to boot-time race conditions.

Consequently, a new naming scheme was introduced. Most commonly (at least in my experience), these names were of the form enpXsY, where X and Y are numerals. These interface names were consistent across boots (provided no hardware was added, removed, or moved to a different slot between boots).

I suspect (but have not been able to confirm) that interface names of the form enoX or ensY are more likely to appear when the machine boots via UEFI (as opposed to booting via legacy BIOS).

Freedesktop.org says that as of Systemd v197:

The following different naming schemes for network interfaces are now supported by udev natively:

    Names incorporating Firmware/BIOS provided index numbers for on-board devices (example: eno1)
    Names incorporating Firmware/BIOS provided PCI Express hotplug slot index numbers (example: ens1)
    Names incorporating physical/geographical location of the connector of the hardware (example: enp2s0)
    Names incorporating the interfaces's MAC address (example: enx78e7d1ea46da)
    Classic, unpredictable kernel-native ethX naming (example: eth0)
bsimmo commented 1 year ago

Yes that is the difference between Predictable Naming and old style.

eth0/eth1 etc are old method and eth =ethernet, number is the assignment.

eto1/ets1 are Predictable and should be read as et o1 / et s1 meaning ethernet onboard1 and ethernet slot1

So yes just et, will pick up all four et predictable names. It would also pick up eth ;-) Iirc when it was enabled by default on the Pi it would use the etx(mac address) form.

I've not tried it on Pi4s and Bullseye predictable names to see if it give mac address with the built in WiFi, but CM4s may well have it on the PCIe or ZeroW plug in on the USB...

BoW2EviL commented 1 year ago

Yes that is the difference between Predictable Naming and old style.

eth0/eth1 etc are old method and eth =ethernet, number is the assignment.

eto1/ets1 are Predictable and should be read as et o1 / et s1 meaning ethernet onboard1 and ethernet slot1

So yes just et, will pick up all four et predictable names. It would also pick up eth ;-)

no not really "et" will only pick the old varents like eth1 etc ... i have not personally ran into "eto\ets" but i run into "eno\ens\enp" all the time. not sure where you got eto\ets from what distro did you see using it?

The following different naming schemes for network interfaces are now supported by udev natively:

thus it should be "en| eth| wl" to collect all common interface names. not "et| wl" if thats what you were suggesting?

bsimmo commented 1 year ago

et in my post should be en. It seems it autocorrected and then I ran with it :-) , apologies* So just en/et/wl

The point was supposed to be, I think, not eno but en as you pondered in your post before.

And I also don't see the point in the extra h on eth, not that it really matters.

Thanks for checking and correcting me.

*Typing on phones can be a right pain, yet I still do it.

On Thu, 18 May 2023, 1:47 am BoW2EviL, @.***> wrote:

Yes that is the difference between Predictable Naming and old style.

eth0/eth1 etc are old method and eth =ethernet, number is the assignment.

eto1/ets1 are Predictable and should be read as et o1 / et s1 meaning ethernet onboard1 and ethernet slot1

So yes just et, will pick up all four et predictable names. It would also pick up eth ;-)

no not really "et" will only pick the old varents like eth1 etc ... i have not personally ran into "eto\ets" but i run into "eno\ens\enp" all the time. not sure where you got eto\ets from what distro did you see using it?

The following different naming schemes for network interfaces are now supported by udev natively:

-

   Names incorporating Firmware/BIOS provided index numbers for on-board devices (example: eno1)

-

   Names incorporating Firmware/BIOS provided PCI Express hotplug slot index numbers (example: ens1)

-

   Names incorporating physical/geographical location of the connector of the hardware (example: enp2s0)

-

   Names incorporating the interfaces's MAC address (example: enx78e7d1ea46da)

-

   Classic, unpredictable kernel-native ethX naming (example: eth0)

thus it should be "en| eth| wl" to collect all common interface names. not "et| wl" if thats what you were suggesting?

— Reply to this email directly, view it on GitHub https://github.com/ironsheep/RPi-Reporter-MQTT2HA-Daemon/issues/79#issuecomment-1552258385, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACYAXN422U6KKB4ITL5LFGLXGVWTVANCNFSM6AAAAAAVASHAXM . You are receiving this because you commented.Message ID: @.***>

BoW2EviL commented 1 year ago

no prob i figured it was a spell check issue but then i figured there might be a eno enp ens somewhere? so i figured i better comment on it.

BoW2EviL commented 1 year ago

Okay, after testing and experimentation, I believe I have come up with a better solution. From my understanding, the /bin/egrep -v "link" part of the code is meant to remove extra lines.

During my testing, when I changed it to " en| eth| wl", I noticed that it resulted in a duplicate interface with the additional string "altname enpXX". To address this issue, I tried various approaches, and the one that worked best for me was searching for ": en|: eth|: wl" without using the /bin/egrep -v "link" portion at all.

This revised code appears to produce the same results but with minimal speed. I have already forked the library and I am preparing to submit a pull request.

Keep up the great work and happy coding!

https://github.com/ironsheep/RPi-Reporter-MQTT2HA-Daemon/pull/100#issue-1716748297

amd64$ time ip link show | /bin/egrep ": en|: eth|: wl"
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
3: wlp3s0b1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000
real    0m0.005s
user    0m0.000s
sys 0m0.009s

RPI4# time ip link show | /bin/egrep ": en|: eth|: wl"
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
3: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN mode DORMANT group default qlen 1000
real    0m0.007s
user    0m0.003s
sys 0m0.010s

RPI4# time /bin/ip link show | /bin/egrep -v "link" | /bin/egrep " eth| wlan"
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
3: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN mode DORMANT group default qlen 1000
real    0m0.008s
user    0m0.001s
sys 0m0.018s

##This works for both of my OS's but maybe not everyones?
amd64$ time /bin/ip link show | /bin/egrep -v "link" | /bin/egrep " eno| eth| wl"
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
3: wlp3s0b1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000
real    0m0.007s
user    0m0.005s
sys 0m0.011s

##this one Results in an duplicate interface because it scraped the altname line.
amd64$ time /bin/ip link show | /bin/egrep -v "link" | /bin/egrep " en| eth| wl"
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    altname enp0s25
3: wlp3s0b1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000
real    0m0.007s
user    0m0.005s
sys 0m0.011s