<feed xmlns='http://www.w3.org/2005/Atom'>
<title>netifd, branch master</title>
<subtitle>OpenWrt Network interface configuration daemon</subtitle>
<id>https://git-03.infra.openwrt.org/project/netifd/atom?h=master</id>
<link rel='self' href='https://git-03.infra.openwrt.org/project/netifd/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/netifd/'/>
<updated>2026-07-04T17:11:21Z</updated>
<entry>
<title>iprule: keep unchanged rules installed on reload</title>
<updated>2026-07-04T17:11:21Z</updated>
<author>
<name>Felix Fietkau</name>
</author>
<published>2026-07-02T16:20:34Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/netifd/commit/?id=fb456b5e65dffb57ef9ef68ec5b56516c2cdec81'/>
<id>urn:sha1:fb456b5e65dffb57ef9ef68ec5b56516c2cdec81</id>
<content type='text'>
iprule_update_rule() unconditionally deleted and re-added every rule
on config reload, opening a window in which policy rules are absent
and in-flight traffic on multi-table setups is misrouted. When the
vlist matched an identical rule (the comparator covers all rule
parameters) and the kernel priority is unchanged, keep the installed
rule. Rules bound to interfaces keep the existing event-driven cycle,
since re-registering the interface user would re-add the rule and
create a duplicate.

Signed-off-by: Felix Fietkau &lt;nbd@nbd.name&gt;
</content>
</entry>
<entry>
<title>system-linux: initialise FMR prefix lengths before parsing</title>
<updated>2026-07-04T17:04:45Z</updated>
<author>
<name>Felix Fietkau</name>
</author>
<published>2026-07-02T15:57:38Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/netifd/commit/?id=dbdf0d0e58302f5b16eb5a8fbd32c4c54f1a18f7'/>
<id>urn:sha1:dbdf0d0e58302f5b16eb5a8fbd32c4c54f1a18f7</id>
<content type='text'>
split_netmask() leaves the prefix length untouched when the value has
no '/' suffix, so a map FMR entry with a bare address passed
uninitialised stack values through the range check and on to the
kernel as prefix lengths. Default to the host prefix length.

Signed-off-by: Felix Fietkau &lt;nbd@nbd.name&gt;
</content>
</entry>
<entry>
<title>device: remove unused __devlock counter</title>
<updated>2026-07-04T17:02:16Z</updated>
<author>
<name>Felix Fietkau</name>
</author>
<published>2026-07-04T12:36:56Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/netifd/commit/?id=844c0fe78eed5674aad8cde73a9b71e28e43a239'/>
<id>urn:sha1:844c0fe78eed5674aad8cde73a9b71e28e43a239</id>
<content type='text'>
The __devlock counter was a recursion guard for deferring device frees.
Since the free-unused path was reworked to defer via a uloop timeout, the
counter is no longer read anywhere, only incremented and decremented.
Remove the dead variable and its remaining write sites.

Signed-off-by: Felix Fietkau &lt;nbd@nbd.name&gt;
</content>
</entry>
<entry>
<title>system-linux: include the priority when deleting ip rules</title>
<updated>2026-07-04T17:00:21Z</updated>
<author>
<name>Felix Fietkau</name>
</author>
<published>2026-07-04T17:00:21Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/netifd/commit/?id=8a38aecd84de644f8a78705922b2af7c68b36819'/>
<id>urn:sha1:8a38aecd84de644f8a78705922b2af7c68b36819</id>
<content type='text'>
Rules are always installed with a priority, either explicit or derived
from their config order, but RTM_DELRULE requests omitted the derived
priority and matched on selectors alone. With two rules sharing
selectors the kernel deletes the first match, so removing one rule
could delete a different one, leaving the removed rule installed.

Signed-off-by: Felix Fietkau &lt;nbd@nbd.name&gt;
</content>
</entry>
<entry>
<title>proto-ext: clear the proto task kill flag when starting a new task</title>
<updated>2026-07-04T16:58:48Z</updated>
<author>
<name>Felix Fietkau</name>
</author>
<published>2026-07-02T16:08:12Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/netifd/commit/?id=4c7b3f7caf881bf4fdfeb022c4681b91ffc9d7f6'/>
<id>urn:sha1:4c7b3f7caf881bf4fdfeb022c4681b91ffc9d7f6</id>
<content type='text'>
proto_task_killed was set when a proto script killed its own client
via proto_kill_command but never cleared, so teardown of any later
proto task instance skipped the SIGTERM and stalled until the 5 s
teardown timeout killed the client with SIGKILL, without a graceful
shutdown (no DHCP release, no PPP terminate). The flag describes the
current task instance, so reset it whenever a new task is started.

Signed-off-by: Felix Fietkau &lt;nbd@nbd.name&gt;
</content>
</entry>
<entry>
<title>bridge: fix memory leak of hotplug member vlan ranges</title>
<updated>2026-07-04T16:56:57Z</updated>
<author>
<name>Felix Fietkau</name>
</author>
<published>2026-07-02T15:53:30Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/netifd/commit/?id=a562a8eca41d80b52092d6404eb5f3d3f6dca676'/>
<id>urn:sha1:a562a8eca41d80b52092d6404eb5f3d3f6dca676</id>
<content type='text'>
bridge_free_member() never freed bm-&gt;extra_vlan, allocated by
bridge_hotplug_set_member_vlans(), leaking the array every time a
hotplug member with extra vlans (e.g. a wireless interface) was
removed.

Signed-off-by: Felix Fietkau &lt;nbd@nbd.name&gt;
</content>
</entry>
<entry>
<title>bridge: cancel the member retry timer on teardown and free</title>
<updated>2026-07-04T16:55:18Z</updated>
<author>
<name>Felix Fietkau</name>
</author>
<published>2026-07-02T15:47:46Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/netifd/commit/?id=0bab70f052967d597ada57299c13690edf7c681f'/>
<id>urn:sha1:0bab70f052967d597ada57299c13690edf7c681f</id>
<content type='text'>
The retry timer armed by bridge_check_retry() was never cancelled.
When the bridge device was freed with a retry pending (member enslave
failure followed by a config reload removing the bridge), the timer
fired into freed memory. A pending retry could also re-create the
kernel bridge via bridge_enable_interface() after bridge_set_down().

Signed-off-by: Felix Fietkau &lt;nbd@nbd.name&gt;
</content>
</entry>
<entry>
<title>interface: fix alias handling when the parent interface does not exist</title>
<updated>2026-07-04T16:52:24Z</updated>
<author>
<name>Felix Fietkau</name>
</author>
<published>2026-07-02T15:46:34Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/netifd/commit/?id=34760f2aec34ba206b5e3048fc6d75617743a577'/>
<id>urn:sha1:34760f2aec34ba206b5e3048fc6d75617743a577</id>
<content type='text'>
When interface_claim_device() could not resolve parent_ifname,
interface_add_user() linked the parent_iface dep into the global
iface_all_users list without setting dep-&gt;iface. interface_alias_cb()
then received events from every interface and bound the alias to
whichever interface came up first, applying its configuration to the
wrong device. On the next reload, interface_claim_device() skipped the
removal (it only checked dep-&gt;iface) and called list_add() on the
still-linked node, corrupting the list.

Make the wait-for-parent registration work as intended: while on the
global list, ignore events from other interfaces and re-register on
the parent once it appears. Replace the dep-&gt;iface guards with a
helper that removes the dep whenever it is linked, regardless of which
list it is on.

Signed-off-by: Felix Fietkau &lt;nbd@nbd.name&gt;
</content>
</entry>
<entry>
<title>interface: defer interface removal to avoid use-after-free</title>
<updated>2026-07-04T16:52:24Z</updated>
<author>
<name>Felix Fietkau</name>
</author>
<published>2026-07-02T15:44:29Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/netifd/commit/?id=e2f28e5ec0a83d00c8586e2fc7fd52740773388b'/>
<id>urn:sha1:e2f28e5ec0a83d00c8586e2fc7fd52740773388b</id>
<content type='text'>
interface_handle_config_change() called interface_do_remove()
synchronously, freeing the interface while callers further up the
stack still dereference it. For a dynamic interface with an immediate
proto (static, none), __interface_set_down() sets IFC_REMOVE and the
PROTO_CMD_TEARDOWN event delivers IFPEV_DOWN inline, so the interface
was freed before __interface_set_down() ran interface_flush_state() on
it. The same synchronous free corrupted the vlist walks in
interface_set_down(NULL) and interface_stop_jail(), the caller
interface_main_dev_cb(), and interface_do_remove() itself when
removing a dynamic interface that is still up (recursive removal
through the forced teardown in interface_cleanup()).

Defer the removal through the existing remove_timer. Keep config_state
at IFC_REMOVE during the deferral so the timer callback can re-check
it, and guard against re-arming while a removal is already pending.
Since interfaces pending removal now stay in the tree until the timer
fires, cancel the removal when the interface config is updated
(interface_change_config() only rewrites config_state when it decides
to reload, so a re-add with identical config would otherwise still be
freed) and refuse to bring up an interface whose removal is pending,
so interface_start_pending() does not bounce a config-deleted
autostart interface after the flush.

Signed-off-by: Felix Fietkau &lt;nbd@nbd.name&gt;
</content>
</entry>
<entry>
<title>device: migrate alias users when replacing a device</title>
<updated>2026-07-04T16:52:24Z</updated>
<author>
<name>Felix Fietkau</name>
</author>
<published>2026-07-02T15:39:08Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/netifd/commit/?id=4a19d2568c0be6754cb5d5a9563c0ff0ece18af7'/>
<id>urn:sha1:4a19d2568c0be6754cb5d5a9563c0ff0ece18af7</id>
<content type='text'>
device_replace() moved only the entries of the users list over to the
new device before freeing the old one. Alias device_users live on the
separate aliases list, and neither device_cleanup_cb() nor the alias
DEV_EVENT_REMOVE handler unlinks them or clears dep-&gt;dev, so any alias
attached to the replaced device was left pointing into freed memory.
The next alias_set_device() then ran safe_list_del() on the freed
device, corrupting the heap.

Reachable via config reload whenever a device section is recreated
(type change or removal) while an interface still references the
device through an @alias.

Signed-off-by: Felix Fietkau &lt;nbd@nbd.name&gt;
</content>
</entry>
</feed>
