In bridge messages (family = AF_BRIDGE), the commands are the same, but the
contents are different, and this can confuse netifd into thinking that devices
are down, while they are actually up.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Add RTM_DELLINK handling to properly track device lifecycle. When a
device is deleted, update its state with flags=0 to mark it as not
present. This improves synchronization compared to only relying on
the hotplug handler.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Maintainer: @nbd, @robimarko
I was missing the ip rules for `sport` and `dport` in netifd and although I have a working C knowledge, I have little netlink knowledge and it is the first time I looked into netifd but after some research I could come up with a working patch to implement `option sport` and `option dport`.
I hope you can have a look and implement these useful options.
Run tested: Dynalink DL-WRX36 (ipq8074) running Main Snapshot r29276-963d320086 20-apr-2025
Example 1 sport:
```
config rule
option src '192.168.9.23/32'
option sport '1194'
option lookup 'main'
```
Result:
```
root@DL-WRX36:~# ip ru
0: from all lookup local
1: from 192.168.9.23 sport 1194 lookup main
```
Example 2 sport range:
```
config rule
option src '192.168.9.23/32'
option sport '1194-1195'
option lookup 'main'
```
Result:
```
root@DL-WRX36:~# ip ru
0: from all lookup local
1: from 192.168.9.23 sport 1194-1195 lookup main
```
Example 3 dport:
```
config rule
option src '192.168.9.23/32'
option dport '1294'
option lookup 'main'
```
Result:
```
root@DL-WRX36:~# ip ru
0: from all lookup local
1: from 192.168.9.23 dport 1294 lookup main
```
Example 4 dport range:
```
config rule
option src '192.168.9.23/32'
option dport '1294-1295'
option lookup 'main'
```
Result:
```
root@DL-WRX36:~# ip ru
0: from all lookup local
1: from 192.168.9.23 dport 1294-1295 lookup main
```
Example 5 sport dport:
```
config rule
option src '192.168.9.23/32'
option sport '1194-1195'
option dport '1294-1295'
option lookup 'main'
```
Result:
```
root@DL-WRX36:~# ip ru
0: from all lookup local
1: from 192.168.9.23 sport 1194-1195 dport 1294-1295 lookup main
```
Signed-off-by: Erik Conijn <egc112@msn.com>
Link: https://github.com/openwrt/netifd/pull/47
Signed-off-by: Robert Marko <robimarko@gmail.com>
Right now system-linux writes to the wrong file (not existing)
to configure the "all_ports_active" flag for bonding devices.
Write to the correct "bonding/all_slaves_active" path.
Signed-off-by: Nicolò Veronese <nicveronese@gmail.com>
Link: https://github.com/openwrt/netifd/pull/49
Signed-off-by: Robert Marko <robimarko@gmail.com>
Config example:
...
config device
option type 'vrf'
option name 'dcn'
option table '20'
option mtu '1500'
option ipv6 '0'
list ports 'l2tp-wanvpn'
list ports 'lan3'
config interface 'dcn'
option proto 'none'
option device 'dcn'
...
Note: using "ports" in config simplifies luci integration
Tested-by: Paul Donald <newtwen+github@gmail.com>
Signed-off-by: Maxim Anisimov <maxim.anisimov.ua@gmail.com>
Link: https://github.com/openwrt/netifd/pull/38
Signed-off-by: Robert Marko <robimarko@gmail.com>
FRA_IP_PROTO expects an 8 bit value.
Follow-up fix for d29cf70747.
uint8 prevents the kernel log message:
netlink: 'netifd': attribute type 22 has an invalid length.
The message is otherwise harmless; ip rules using ipproto are created
successfully.
Tested on 24.10-snapshot
Signed-off-by: Paul Donald <newtwen+github@gmail.com>
Link: https://github.com/openwrt/netifd/pull/42
Signed-off-by: Robert Marko <robimarko@gmail.com>
The SIOCGIFFLAGS ioctl truncates returned flags to u16, and the IFF_LOWER_UP
flag exceeds that size. Because of that, the carrier status needs to be pulled
from the netlink message.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
```
config rule
option ...
option ipproto '17'
```
This allows handling rules which anchor to protocol number like:
`ip ru add from all ipproto udp table udp_table prior 10`
Handle ipproto as an unsigned integer.
https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
Example:
config rule
option in 'lan'
option src '10.48.0.0/16'
option out 'lan'
option dest '192.168.1.144/32'
option lookup 'main'
option ipproto '17'
Results in
~# ip rule
0: from all lookup local
1: from 10.48.0.0/16 to 192.168.1.144 iif br-lan oif br-lan ipproto udp lookup main
Tested on 23.05.5 x86_64
Signed-off-by: Paul Donald <newtwen+github@gmail.com>
rtnl event processing might be delayed due to other calls / state changes.
That can lead to devices toggled up/down unnecessarily.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This reverts commit 68c8a4f94c.
Matching on flags IFF_UP AND NOT IFF_LOWER_UP and then reapply ethtool
settings freaks out some PHY drivers. While a better method is being
worked on, revert the problematic solution.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
ethtool settings applied before the interface is in IFF_UP state
are going to be lost when phylink is being used.
This is the case with many modern NICs as well as when using SFP
modules, resulting in the speed, duplex, *pause and autoneg
settings not having any effect.
Reapply ethtool settings once the PHY is attached.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
The error handling needed for the buffer growth logic relies on
uloop_fd's error flag, which is set based on epoll events. Doing so
without handling recvmsg's error codes is racy, as an error state may be
set between receiving epoll events and the next recvmsg, but calling
recvmsg clears the error state.
To fix this, add handling for errors returned by nl_recvmsgs_default()
and nl_recv(); checking for u->error and retrieving the error status
using getsockopt() becomes redundant.
We have observed this issue on Gluon (recent OpenWrt 23.05); on some
devices with DSA switches, the bridge interface's carrier-on event would
consistenly get lost during boot due to insufficient buffer space
(see [1]).
We have bisected the issue to netifd commit 516ab774cc ("system-linux:
fix race condition on bringing up wireless devices"), but that commit only
uncovered the preexisting bug by switching from getting the carrier state
from sysfs to using the netlink messages in cb_rtnl_event().
I suspect that other recent issues about netifd missing a carrier state
change like [2] may have the same underlying cause.
[1] https://github.com/freifunk-gluon/gluon/issues/3130
[2] https://github.com/openwrt/openwrt/issues/13863
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
This reverts commit 66a7652176.
Users reported that netifd hangs after this commit. I suspect that the added
optimization which sets data->pending to false early might be the cause.
It might leave unprocessed netlink messages in the socket, which could mess up
the next netlink call.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Fix Coverity Defect 1559194 reporting an Infinite loop when
data->pending is not set to 0 on finishing the callback.
While this is a false-positive report as ACK is always called, this is a
good time to optimize the code and make the callback exit early if we
find the ifindex for the DSA conduit.
Correctly set pending to 0 on ifindex found or error for if_get_master
valid netlink callback.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
If custom MAC or a default MAC needs to be applied, skip refreshing MAC
after master change to correctly apply the custom MAC.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
On changing the conduit for a DSA port, the conduit may have different
a MAC address. In the scenario where a port is part of a bridge and
is the primary port, some inconsistency may arise where the bridge have
the MAC address of the previous conduit and is never updated.
This inconsistency cause problem with packet forwarding with FDB and
other related problems.
To fix this, refresh the original MAC address after the conduit for the
DSA port is changed by polling the new MAC address for the device using
ioctl API.
Fixes: 2dc7f450f3 ("system-linux: add option to configure DSA conduit device")
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
When a device is added that isn't up, status toggles can sometimes lead to a
DEV_EVENT_REMOVE event, which causes the device to be removed from an interface
or a bridge.
Fix this by toggling the dev->disabled status instead based on IFF_UP, and
adding a check to bridge/interface code to only permanently remove devices that
are actually gone.
Fixes: 516ab774cc ("system-linux: fix race condition on bringing up wireless devices")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Add support for configurable EEE option i.e. energy efficient ethernet.
The option can be configured by adding the config for the device in the
network uci config. Example:
config device
option name 'eth0'
option eee '1'
Signed-off-by: Rahul Thakur <rahul.thakur@iopsys.eu>
Changing DSA port conduit was introduced only with kernel 6.1. Fix
compilation error by disabling support for this on unsupported kernels.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Make system_if_get_master_ifindex static as it was wrongly exposed and
is only used in system-linux.c.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Device might have multiple CPU port with DSA based switch and OEM
firmware might set specific port to one CPU port (for example WAN) to
sustain full gigabit traffic with the kernel.
To set them iproute2 tool is currently required.
Add support to set the DSA port conduit directly from network config
using netlink. Example:
config device
option name 'lan1'
option conduit 'eth1'
Conduit option refer to the CPU port interface. Invalid option will
simply be ignored and won't be applied similar to what iproute2 does.
Option can also be set in board.json by setting the conduit option.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Add support for configurable GRO option. Some device doesn't have HW
Checksum support and may suffer from performance regression by using
GRO. Disabling GRO restore the original performance and make the device
usable again.
The option can be configured by adding the config for the device in the
network config. Example:
config device
option name 'eth0'
option gro '0'
The option can also be configured by adding the config to the
board.json.
Notice that a new "kind" of settings are introduced
"system_if_apply_settings_after_up". Option set in this function will be
executed AFTER the interface is UP. This is needed as some option
(example GRO) needs to be applied after the interface is UP and applying
them before results in error in ioctl.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Support the configuration of network routes not bound to any specific
interface. In case such a route is configured, it will be internally
owned by the loopback interface and have a new DEVROUTE_NODEV flag
set to inhibit the RTA_OIF attribute when installing the kernel route.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
When wireless devices are added via hotplug before their state is set to up,
adding routes to the device can fail in the kernel.
Since the up state is managed externally, use it as input for netifd's device
present state, so that they are only brought up when ready.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
ETHTOOL_GSET / ETHTOOL_SSET API is deprecated since Linux v5.2
released in 2016, see torvalds/linux@3f1ac7a700 ("net: ethtool: add
new ETHTOOL_xLINKSETTINGS API"). All still maintained OpenWrt versions
use kernel versions new enough to support the new API.
Hence migrate to ETHTOOL_xLINKSETTINGS API API to handle
auto-negotiation for flow-control as well as higher bandwidth like
2.5G, 5G and 10G.
Use ethtool API to switch on or off auto-negotiation of Ethernet
interfaces, and set speed and duplex accordingly in case auto-
negotiation is switched off.
Add support for flow-control settings, both manual/force mode for
RX and TX pause frames as well as advertising Pause and Asym_Pause
bits.
Instead of hard-coding the supported modes, generate a header file
describing them from <linux/ethtool.h>.
Signed-off-by: Ruiwei Chen <crwbak@gmail.com>
[generate list of link modes from toolchain headers, select by speed
and duplex, also use new API for dump function, add support for flow-
control settings]
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This can be used to allow trunking dynamically allocated VLANs into a specific
member port. In order to use this, add a device section for the member port with
the 'vlan' array option, which can contain vlan numbers or ranges.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
The message passed to nl_send_auto_complete still needs to be freed
even in the normal path
Fixes: https://github.com/openwrt/netifd/issues/4
Fixes: 85f01c44a9 ("bridge: check bridge port vlan membership on link-up events")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Fixes bunch of clang-15/gcc-10 compiler warnings, mostly related to
blobmsg_for_each_attr() usage:
error: comparison of integers of different signs: 'int' and 'unsigned long' [-Werror,-Wsign-compare]
error: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Werror,-Wsign-compare]
error: format string is not a string literal [-Werror,-Wformat-nonliteral]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
The -pedantic option was complaining about the old initialization and
prefers if it is explicitly initialized to zero.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This fixes warnings like this:
warning: comparison of integer expressions of different signedness: 'int' and 'long unsigned int' [-Wsign-compare]
Mostly this was an int compared to a size_t returned by ARRAY_SIZE().
The easiest fix is to count on the size_t type.
The ifindex is sometimes an unsigned int and sometimes a signed int in
the kernel interfaces. I think it normally fits into an unsigned 16 bit
value, so this should be fine. Do the one comparison where the
compiler complains as a long.
Casting the result of sizeof() to int should be safe. These values are
never out of range of int.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The `IFNAMSIZ` macro defines the required buffer size to hold a Linux
interface name including the terminating zero byte while netifd currently
uses an `IFNAMSIZ + 1` limit for interface name buffers.
This causes netifd to use overlong names (16 instead of 15 bytes) in
netlink communication with the kernel, leading to netlink failure replies
due to policy violations.
Fix this issue by applying the correct length, that is `IFNAMSIZ` directly,
to the corresponding buffers.
Ref: https://github.com/openwrt/openwrt/issues/11259
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Allow for per-user routing policies via the uidrange iprule option.
Option allows for a single UID or range of UIDs.
Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
Every network device has a type but there is no standard interface here.
The type can be determined either from the file
'/sys/class/net/<device>/uevent' or, if no information is found
there, from the file '/sys/class/net/<device>/type'.
This new function first checks whether there is a DEVTYPE=<type> string
in the 'uevent' file and uses it. If it does not find this information,
the 'type' is used as a fallback and mapped the number to a character
sequence.
This new 'devtype' information can be found in the network.device ubus
call.
Command:
ubus call network.device status
Output:
{
"eth0": {
"devtype": "ethernet",
Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com> [commit rewording]
The deletion of IP tunnels via the ioctl interface is broken; instead of
fixing the ioctl interface switch to the netlink based interface to delete
IP tunnel devices as this simplifies and unifies the code
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
Supported options:
- ports: member devices
- policy: bonding policy
supported values:
- balance-rr
- active-backup
- balance-xor
- broadcast
- 802.3ad
- balance-tlb
- balance-alb
- xmit_hash_policy: slave selection tx hash policy
supported values:
- layer2
- layer2+3
- layer3+4
- encap2+3
- encap3+4
- all_ports_active: allow receiving on inactive ports
- min_links: minimum number of active links
- ad_actor_system: LACPDU exchange MAC address
- ad_actor_sys_prio: LACPDU priority value
- ad_select: 802.3ad aggregation logic
supported values:
- stable
- bandwidth
- count
- lacp_rate: 802.3ad LACPDU packet rate
supported values:
- slow (every 30 seconds)
- fast (every second)
- packets_per_port: number of packets before switching
ports (balance-rr mode).
- lp_interval: number of seconds between sent learning packets
- dynamic_lb: distribute traffic according to port load
- resend_igmp: number if IGMP membership updates after failover event
- num_peer_notif: number of tx unsolicited ARP/NA after failover event
- primary: name of the primary port
- primary_reselect: primary port reselection policy
supported values:
- always
- better
- failure
- failover_mac: MAC address selection policy
supported values:
- none
- active
- follow
- monitor_mode: select ARP or MII link monitor:
supported values:
- arp
- mii
- monitor_interval: link monitor update interval (msec)
- arp_target: ARP monitor target IP address (list)
- arp_all_targets: all targets must be reachable to consider the link valid
- arp_validate: ARP validation policy
supported values:
- none
- active
- backup
- all
- filter
- filter_active
- filter_backup
- use_carrier: use carrier status instead of MII ioctl result
- updelay: delay before enabling port after MII link up event (msec)
- downdelay: delay before disabling port after MII link down event (msec)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
instead of relying on hostapd to manipulate bridge attributes (which can race
against netifd adding/removing of member ports), set the proxyarp related
attributes in netifd directly when bringing up the member port
Signed-off-by: Felix Fietkau <nbd@nbd.name>