netinet: Maintain RTF_LOCAL in the kernel
* Expose in_rtlocalize() for using in route_output_change_callback() to
correctly set RTF_LOCAL, taking into account of the IFA/IFP changes.
* Add RTF_LOCAL to PRESERVED_RTF and ignore the RTF_LOCAL flag from
userspace, making this flag be maintained by the kernel.
* Clean up arp_rtrequest() to directly check the RTF_LOCAL flag instead
of comparing the IP addresses.
net: Normalize IPv4 /32 route to a host route (RTF_HOST)
An IPv4 /32 route denotes a host route (RTF_HOST). Add the
rt_hostroute_normalize() helper to normalize such routes by setting the
RTF_HOST flag. Use the helper in both rtrequest1() and
rtsearch_msghandler() so that this normalization applies to RTM_ADD,
RTM_GET, RTM_CHANGE and RTM_LOCK.
netinet: Move loopback route maintain functions to in.c
The ifa_{add,del}_loopback_route() functions are only used in
netinet/in.c, so just move them to there and make them static.
Meanwhile, rename them to in_{add,del}_loopback_route() for consistency.
gmp: Clean up makefile
* Use per-target flags "FLAGS.<target>" to replace the FLAGS_GROUPS,
expressing the intention/requirement more clearly.
* Introduce helper varaibles to clean up the loop code.
* Remove the unused "mpn/generic" directory.
netinet: Clean up interface routes handling in arp_rtrequest()
in_addroute() gives every non-host, non-multicast IPv4 route either
RTF_CLONING or RTF_PRCLONING, so manually added interface routes would
have RTF_PRCLONING. As a result, we can clean up arp_rtrequest() to
check either RTF_CLONING or RTF_PRCLONING in handling a cloned route,
without hacking the RTF_CLONING flag.
An edge case is a non-host route with a "/32" mask. However, that case
doesn't make practical sense and should be normalized to a host route.
That will be addressed in the coming commits.
net: Handle R_Malloc() failure in rt_setshims()
Introduce the rt_freeshims() helper to free the memory allocated by
rt_setshims(), and also call it in rtrequest1() to avoid potential
memory leak.
This only applies MPLS.
netinet: Improve local routes handling in in_addroute()
* Extract the in_rtlocalize() helper function to improve the handling of
local routes, including explicit loopback routes added by
ifa_add_loopback_route().
* Skip modifying IFA/IFP for the explicit loopback routes, and thus
remove the pre-setting RTF_LOCAL from ifa_maintain_loopback_route().
No functional changes.
nd6: keep foreign-CPU neighbors off the timer and purge list
Route requests create neighbor entries on each network CPU, but timers
and purge run on CPU 0. Purging a foreign-CPU entry deletes the matching
local route and can follow its freed neighbor entry. Link only CPU 0
entries into the list and unlink only linked entries; keep other CPUs
route-local neighbor data.
Bug: https://bugs.dragonflybsd.org/issues/3439
pf.conf.5: describe IPv6 fragment filtering without reassembly
IPv6 fragments are filtered as the Fragment header protocol, not blocked
unconditionally. State that port/type rules cannot pass them and that a
broad pass rule does not enforce those restrictions.
Bug: https://bugs.dragonflybsd.org/issues/3438
netinet: fix ARP resolution during the first second of uptime
A cloned route created while time_uptime is zero passes a zero expiry
to its neighbors. Zero denotes a permanent entry, so unresolved dynamic
neighbors never send ARP requests.
Add the arp_expire_unresolved (= time_uptime + 1) to keep dynamic expiry
nonzero and track the last request time separately, using la_asked to
indicate whether that time is valid. This preserves same-second rate
limiting and permanent-entry semantics without changing the routing ABI.
While there, fix the code to add arpt_down to rt_expire only when it's a
cloned route.
Co-authored-by: Aaron LI <aly at aaronly.me>
GitHub-PR: https://github.com/DragonFlyBSD/DragonFlyBSD/pull/58
dsynth - Do not cross mount boundaries when making template's /etc
* When making the template's /etc, do not cross mount boundaries.
* This is a bit of a hack but /etc/namedb sometimes has a "dev"
subdirectory for its chroot area that mounts devfs. This kinda
implodes when we later try to tmpfs it.
dsynth - Apply the "debug" directive to ports-mgmt/pkg
The debug directive was not being applied to ports-mgmt/pkg,
so we couldn't retain the mounts for debugging purposes when
explicitly building that target.
Adjust the (s4) string to recognize multiple flags, since fixing
this requires two flags to be passed in.
Reported-by: aly
kernel - Fix I/O stalls caused by TRIM ops
* I/O can stall out in physstr when TRIM ops are delpoyed. The
cause is that the da_softc->outstanding_cmds_rd tracker used by
the I/O balancer was decrementing the field on TRIM completions.
* Fix by ensuring that the tracker only applies to READ commands.
* Refactor scheduling checks in dastart(). The checks were a bit broken
but worked due to a catch-all in dadone(). Refactor so they work properly.
* Refactor conditional/block syntax a bit for readability.
Reported-by: myself and numerous others
kern: avoid reading a disk label while dumping
Checking an unlabelled dump slice can trigger a disk-label read through
normal buffered I/O. During a crash dump, that read can wait indefinitely
before the dump writer reaches its polled I/O path.
Skip the label read while dumping and use the slice bounds already held
in memory, keeping the normal label probe outside the dump path.
Bug: https://bugs.dragonflybsd.org/issues/3441
kern: skip module shutdown handlers on panic
module_shutdown() is a shutdown_post_sync handler, so it also runs on the
panic path after the panicking CPU has stopped the other CPUs. Some
MOD_SHUTDOWN handlers block on kernel threads that cannot run once their
CPU is stopped: vn calls disk_destroy(), and disk_msg_send_sync() then
waits forever for the disk_msg_core thread. The machine hangs after
"Dump complete" and never reboots.
Skip the module shutdown handlers on a panic, as resettodr_on_shutdown()
and shutdown_kproc() already do. The dump is already written when this
handler runs.
Reproduced in a QEMU/NVMM guest: panic + dump with
hw.acpi.handle_reboot=1 hangs at "Dump complete" on SMP and reboots on a
single CPU. With this change the guest reboots with
hw.acpi.handle_reboot 1 and 0, with and without a dump.
Bug: https://bugs.dragonflybsd.org/issues/3450
dsynth - Fix improper deletions with "prepare-system"
* Don't delete "obsolete" packages for "prepare-system"
* Obsolete packages can only be properly deleted when
a full scan is done. "prepare-system" only does a
partial scan so it winds up deleting stuff it
should not delete.
pf: fix IPv6 fragment length checks
ip6_plen excludes the IPv6 header, but off includes it. Check packet and
fragment-header bounds, use matching length units, and reject misaligned
non-final fragments. Include pre-fragment extension headers in the
reassembled payload limit.
Bug: https://bugs.dragonflybsd.org/issues/3437
ndp(8): avoid deleting covering routes and report socket errors
RTM_GET can return a covering route for an absent neighbor. Require the
requested address and an NDP route before deletion. Return failure for
routing-socket write, read and reply errors, and pass deletion failure
to the exit status.
Bug: https://bugs.dragonflybsd.org/issues/3436
libkvm(3): clear failed lookups and report lookup errors
Clear requested symbol results before lookup. Keep the live failure
count and continue looking up later entries. Report lookup errors
without relying on the last errno, and preserve table errors in internal
callers.
Bug: https://bugs.dragonflybsd.org/issues/3444
asr(4): Fix bug of DPT_4_BYTES being wrongly defined as long (8 bytes)
Caught by GCC 12.5 with the following '-Warray-bounds' warnings:
```
In file included from /usr/src/sys/dev/raid/asr/asr.c:148:
/usr/src/sys/dev/raid/asr/asr.c: In function 'ASR_getStatus':
/usr/src/sys/dev/raid/asr/dptalign.h:277:26: warning: array subscript 'long unsigned int[4]' is partly outside array bounds of 'I2O_EXEC_STATUS_GET_MESSAGE[1]' {aka 'struct _I2O_EXEC_STATUS_GET_MESSAGE[1]'} [-Warray-bounds]
277 | *((unsigned DPT_4_BYTES __FAR__ *)getUP1(x,y)) \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/src/sys/dev/raid/asr/i2odep.h:492:17: note: in expansion of macro 'setLU4'
492 | setLU4((&(x)->ReplyBufferLength),0,y)
| ^~~~~~
/usr/src/sys/dev/raid/asr/asr.c:614:9: note: in expansion of macro 'I2O_EXEC_STATUS_GET_MESSAGE_setReplyBufferLength'
614 | I2O_EXEC_STATUS_GET_MESSAGE_setReplyBufferLength(Message_Ptr,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/src/sys/dev/raid/asr/asr.c:599:41: note: at offset 32 into object 'Message' of size 36
599 | I2O_EXEC_STATUS_GET_MESSAGE Message;
| ^~~~~~~
[17 lines not shown]
ena(4): Fix possible NULL deref in ena_com_create_and_store_tx_meta_desc()
get_sq_desc() may return NULL, so passing the return value to memset()
would cause a NULL deref. GCC 12.5 caught this and gave a
-Warray-bounds warning:
```
In file included from /usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_plat.h:40,
from /usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_com.h:38,
from /usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_eth_com.h:40,
from /usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_eth_com.c:34:
In function 'ena_com_create_and_store_tx_meta_desc',
inlined from 'ena_com_prepare_tx' at /usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_eth_com.c:409:3:
dragonfly/sys/systm.h:268:9: warning: '__builtin_memset' offset [0, 11] is out of the bounds [0, 0] [-Warray-bounds]
268 | __builtin_memset(__DEQUALIFY(void *, (ptr)), (c), (len))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_eth_com.c:295:9: note: in expansion of macro 'memset'
295 | memset(meta_desc, 0x0, sizeof(struct ena_eth_io_tx_meta_desc));
| ^~~~~~
[3 lines not shown]
wlan: Fix NULL deref bug in hwmp_discover()
The 'ni' is explicitly NULL, but IEEE80211_NOTE() expands to
ieee80211_note_mac() that would access 'ni->ni_macaddr', causing a NULL
deref. Fix it by porting the FreeBSD's fix: replacing IEEE80211_NOTE()
with IEEE80211_DPRINTF() without accessing 'ni'.
Caught by GCC 12.5 warning:
```
In file included from /usr/src/sys/netproto/802_11/wlan/ieee80211_hwmp.c:63:
/usr/src/sys/netproto/802_11/wlan/ieee80211_hwmp.c: In function 'hwmp_discover':
dragonfly/netproto/802_11/ieee80211_var.h:963:17: warning: 'ieee80211_note_mac' reading 6 bytes from a region of size 0 [-Wstringop-overread]
963 | ieee80211_note_mac(_vap, (_ni)->ni_macaddr, _fmt, __VA_ARGS__);\
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/src/sys/netproto/802_11/wlan/ieee80211_hwmp.c:2137:33: note: in expansion of macro 'IEEE80211_NOTE'
2137 | IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP,
| ^~~~~~~~~~~~~~
dragonfly/netproto/802_11/ieee80211_var.h:963:17: note: referencing argument 2 of type 'const uint8_t[6]' {aka 'const unsigned char[6]'}
[9 lines not shown]
hammer2: Fix a NULL deref in hammer2_chain_lastdrop()
That is the no-parent case, i.e., parent is NULL, so it was an error
to access 'parent->core.spin'. Simply remove the hammer2_spin_unex()
call to fix the bug.
This bug was caught by the GCC 12.5 warning:
```
In file included from include/machine/atomic.h:7,
from /usr/src/sys/sys/systm.h:49,
from /usr/src/sys/vfs/hammer2/hammer2_chain.c:57:
In function 'atomic_add_int',
inlined from 'spin_unlock_quick' at /usr/src/sys/sys/spinlock2.h:170:2,
inlined from 'spin_unlock' at /usr/src/sys/sys/spinlock2.h:183:2,
inlined from 'hammer2_chain_lastdrop' at /usr/src/sys/vfs/hammer2/hammer2_chain.c:654:4,
inlined from 'hammer2_chain_drop' at /usr/src/sys/vfs/hammer2/hammer2_chain.c:359:13,
inlined from 'hammer2_chain_drop' at /usr/src/sys/vfs/hammer2/hammer2_chain.c:346:1:
./cpu/atomic.h:91:9: warning: array subscript 0 is outside array bounds of 'int[0]' [-Warray-bounds]
[12 lines not shown]