Once change 2342 is in place (running first boot scripts exported from
packages), see https://review.haiku-os.org/c/haiku/+/2342,
remove data/system/boot/post_install/add_catalog_entry_attributes.sh
and related support infrastructure (magic files, launch_roster entries).
The work this script did can in fact be done at image creation time
instead of at first boot.
Change-Id: I485e1a0a87c3e6a6ba3f882e65996f2327134d37
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3751
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
fb3bc59600e25268ed5750fdc351b1e9423a8fb4 Restructure mbuf send tags to provide stronger guarantees.
2b60ecf197e0e187ac028d66d279805e6bece77b Don't use if_maddr_rlock() in 802.11, use epoch(9) directly
998bd62c311425c8cebb4506d7d4a3a9d5ff7f9e [net80211] Print out a bad PN in both hex and decimal.
8bc0d2b8553e012412d03468f84588dc34dea4c4 Fix !DEBUGNET build after r362138
tested with idualwifi7260, iprowifi4965 and atheroswifi
net80211: fix out-of-bounds read in ieee80211_amrr(9).
ieee80211_alloc_node() does not initialize rateset tables; that's not
expected by rate control modules and will result in array access at
index -1 - where ni_essid[] array is located (zeroed at allocation, so
there are no user-visible consequences).
Just delay rate control initialization to the moment, when rateset
tables are initiaziled; nothing will use rates here anyway.
MFC after: 4 days
net80211: fix duplicate sequence number bump for non-AMPDU QoS frames.
This should be a part of r312972.
MFC after: 4 days
net80211: fix panic when device is removed during initialization
if_dead() is called during device detach - check if interface is
still exists before trying to refresh vap MAC address
(IF_LLADDR will trigger page fault otherwise).
MFC after: 5 days
net80211: fix possible panic for some drivers after r342211
Check if rate control structures were allocated before trying to
access them in various places; this was possible before on
allocation failure (unlikely), but was revealed after r342211
where allocation was deferred.
In case if driver uses wlan_amrr(4) and it is loaded it
is possible to reproduce the panic via
sysctl net.wlan.<number>.rate_stats
(for wlan0 the number will be 0).
Tested with: RTL8188EE, AP mode + RTL8188CUS, STA mode.
MFC after: 3 days
net80211: provide rate validation for injected frames.
There may be various side effects (device timeout, firmware and / or
kernel panic) when an invalid (or inapplicable - e.g., an MCS rate
for 11g-only device) is set; check rates before sending the frame to
the driver.
How-to-reproduce:
Set an MCS (real or bogus - with 0x80 bit set) rate in ibp_rate0 field
for any device that uses ieee80211_isratevalid() for rate checks -
rum(4), run(4), ural(4), bwi(4) or ral(4); if kernel is compiled
with INVARIANTS the check will result in "rate %d is basic/mcs?" panic.
Tested with WUSB54GC (rum(4)), AP mode.
MFC after: 1 week
Print more WPS attributes in verbose "list scan" output
- Move WPS related defines to dedicated file
- Add handlers for more WPS attributes
PR: 217317
Submitted by: J.R. Oldroyd <fbsd@opal.com>
MFC after: 3 weeks
net80211: resolve ioctl <-> detach race for ieee80211com structure
Since r287197 ieee80211com is a part of drivers softc; as a result,
after detach all pointers to it (iv_ic, ni_ic) are invalid. Most
possible users (tasks, interrupt handlers) are blocked / removed
when device is stopped; however, ioctl handlers were not tracked
and may crash if ieee80211com structure is accessed.
Since ieee80211com pointer access from ieee80211vap structure is not
protected by lock (constant after interface creation) and used in
many other places just use reference counting for ioctl handlers;
on detach set 'detached' flag and wait until reference counter goes to 0.
For HEAD ieee80211vap size was changed (__FreeBSD_version bumped);
however, in stable branches I'm going to split / reuse the last
iv_spare field for KBI stability.
Tested with:
- rsu(4), SIOCSIFCAP (-rxcsum) ioctl;
- rtwn_pci(4), SIOCG80211 / IEEE80211_IOC_HTPROTMODE ioctl.
MFC after: 1 week
net80211: fix channel list construction for non-auto operating mode.
Change the way how channel list mode <-> desired mode match is done:
- Match channel list mode for next non-auto desired modes:
* 11b: 11g, 11ng, 11acg;
* 11a: 11na, 11ac
- Add pre-defined channels only when one of the next conditions met:
* the desired channel mode is 'auto' or
* the desired channel and selected channel list modes are exactly
the same or
* the previous rule (11g / 11n / 11ac promotion) applies.
Before r275875 construction work properly for all except
11ng / 11na / 11acg / 11ac modes - these were broken at all
(i.e., the scan list was empty); after r275875 all checks were removed,
so scan table was populated by all device-compatible channels
(desired mode was ignored).
For example, if I will set 'ifconfig wlan0 mode 11ng' for RTL8821AU:
- pre-r275875: nothing, scan will not work;
- after r275875: both 11ng and 11na bands were scanned; also, since 11b
channel list was used, 14th channel was scanned too.
- after this change: only 11ng - 1-13 channels - are used for scanning.
Tested with:
* RTL8188EE, STA mode.
* RTL8821AU, STA mode.
MFC after: 5 days
net80211: turn channel mode check into assertion.
There is may be only 11b channel (since chanflags[] table
maps MODE_AUTO to the corresponding 11b channel flags).
Checked with RTL8812AU, STA mode.
MFC after: 5 days
net80211: reuse TICKS_2_MSEC / MSEC_2_TICKS macros from sys/time.h
Replace in-place implementation with system-wide one; since it
guarantees non-zero result drop all less-than-one checks from
drivers and net80211.
MFC after: 2 weeks
Remove 2GHz channel list copies from wireless drivers.
Wrap ieee80211_add_channel_list_2ghz into another function
which supplies default (1-14) channel list to it and drop
its copies from drivers.
Checked with RTL8188EE, country US / JP / KR / UA.
MFC after: 2 weeks
Do not acquire IEEE80211_LOCK twice in cac_timeout(); reuse locked function instead.
It is externally visible since r257065.
MFC after: 5 days
net80211(4): do not setup roaming parameters for unsupported modes.
ifconfig(8) prints per-mode parameters if they are non-zero; since
we have 13 possible modes with 3...5 typically supported this change
should greatly reduce amount of information for 'ifconfig <wlan> list roam'
command.
While here ensure that sta_roam_check() will not use roaming parameters
for unsupported modes (it should not).
This change effectively reverts r188776.
MFC after: 2 weeks
net80211(4): fix rate check when 'roaming' ifconfig(8) option is set to 'auto'
Do not try to clear 'basic rate' bit from roamRate; it cannot be here and,
actually, this operation clears 'MCS rate' bit instead, breaking comparison
for 11n / 11ac modes.
Tested with RTL8188CUS, HOSTAP mode + RTL8821AU, STA mode.
MFC after: 3 days
net80211(4): do not setup Tx parameters for unsupported modes.
That should shorten 'ifconfig <wlan> list txparam' output since
unsupported modes will not be shown.
Checked with RTL8188EE, STA mode.
MFC after: 2 weeks
net80211(4): validate supplied roam:rate values from ifconfig(8)
MFC after: 4 days
net80211(4): hide casts for 'i_seq' field offset calculation inside ieee80211_getqos() and reuse it in various places.
Checked with RTL8188EE, HOSTAP mode + RTL8188CUS, STA mode.
MFC after: 2 weeks
Build fix for Haiku
net80211: correct check for SMPS node flags updates
Update node flags when driver supports SMPS, not when it is disabled or
in dynamic mode ((iv_htcaps & HTCAP_SMPS) != 0).
Checked with RTL8188EE (1T1R), STA mode - 'smps' word should disappear
from 'ifconfig wlan0' output.
MFC after: 2 weeks
Enhance the comment ieee80211_add_channel() to avoid a misunderstanding that the function does not work additive when repeatedly called for diffferent bands.
Reviewed by: avos (a few months ago)
MFC after: 2 weeks
net80211: Move rate printing in amrr_node_stats() to a separate method
This makes amrr_node_stats() cleaner and allows the rate printing to be
reusable.
Submitted by: Neel Chauhan <neel at neelc.org>
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D22318
Mark more nodes as CTLFLAG_MPSAFE or CTLFLAG_NEEDGIANT (7 of many)
r357614 added CTLFLAG_NEEDGIANT to make it easier to find nodes that are
still not MPSAFE (or already are but aren’t properly marked).
Use it in preparation for a general review of all nodes.
This is non-functional change that adds annotations to SYSCTL_NODE and
SYSCTL_PROC nodes using one of the soon-to-be-required flags.
Mark all low hanging fruits as MPSAFE.
Reviewed by: markj
Approved by: kib (mentor, blanket)
Differential Revision: https://reviews.freebsd.org/D23626
Haiku: added CTLFLAG_NEEDGIANT
Fix -Wvoid-pointer-to-enum-cast warnings.
This pattern is used in callbacks with void * data arguments and seems
both relatively uncommon and relatively harmless. Silence the warning
by casting through uintptr_t.
This warning is on by default in Clang 11.
Reviewed by: arichardson
Obtained from: CheriBSD (partial)
MFC after: 1 week
Sponsored by: DARPA
Differential Revision: https://reviews.freebsd.org/D24425
Don't indirect user pointers directly in two 802.11s ioctls.
IEEE80211_MESH_RTCMD_ADD was invoking memcmp() to validate the
supplied address directly on the user pointer rather than first doing
a copyin() and validating the copied value.
IEEE80211_MESH_RTCMD_DELETE was passing the user pointer directly to
ieee80211_mesh_rt_del() rather than copying the user buffer into a
temporary kernel buffer.
Reviewed by: brooks, kib
Obtained from: CheriBSD
MFC after: 2 weeks
Sponsored by: DARPA
Differential Revision: https://reviews.freebsd.org/D24562
Use the unicast key when transmitting DWDS AP multicast frames.
I'm still not sure whether this is the full solution, but here goes.
I have a two node DWDS setup - a main AP with the ethernet bridge uplink
and a satellite AP in the back of the house. They're both AR9344+AR9580
dual band 11n APs.
The problem was that multicast frames was not going from the DWDS AP to
the DWDS STA. Unicast frames are fine, and multicast frames from the
DWDS STA to AP are fine.
Now, multicast and unicast frames from the STA -> AP are just transmitted
using the unicast key. That's fine. However, the AP -> STA multicast
frames by default are transmitted using the current default / multicast
key, the shared one between all STAs in a BSS. Now, the DWDS implementation
ignores non WDS frames - it only allows about 4 address frames outside
of management / EAPOL frames! - so the STA side ignores the normal multicast
frames.
Instead, the AP side uses ieee80211_dwds_mcast() to send multicast frames
to each WDS VAP that was created as part of the "dynamic" part of DWDS.
This should be queuing them individually to each node instead of using
the normal multicast send path; and this is how they should get turned into
4-addr WDS frames.
HOWEVER, ieee80211_encap() was trying to use the default TX key to queue
them rather than the unicast key that's already setup. Since this synthetic
node doesn't have the default TX key setup, transmission fails. Things
would be fine in WEP and in open mode because in both cases you would
have static keys (or no keys) setup. It just fails in WPA mode.
This resolves the issue. AP DWDS multicast is now sent using the unicast
key just like in STA mode and I'm pretty sure the STA mode side will stil
work fine (as it's a STA VAP with a DWDS flag..)
Tested:
* TL-WDR3600/4300 APs
net80211: post RTM_IFINFO notification after toggling IFF_DRV_RUNNING
This is useful when a wireless driver is stopped or started in response
to events like an RF Kill button press. Applications like
wpa_supplicant depend on such events to have a correct view of interface
state.
Reviewed by: adrian, cy, melifaro
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D24925
Fix interrupted scan logic and ticks comparison
The scan task refactoring stuff circa 2014-2016 broke the blocking task
into a taskqueue with some async bits, but it apparently broke scans
being interrupted by traffic.
Notably - the new "field" SCAN_PAUSE sets both SCAN_INTERRUPT and SCAN_CANCEL,
and a bunch of existing code was checking for SCAN_CANCEL only and breaking
the scan. Unfortunately it was then (a) cancelling the scan entirely and
(b) not notifying userland that scan was done.
So:
* Update the calls to scan_end() to only pass in 1 (saying the scan is complete)
if SCAN_CANCEL is set WITHOUT SCAN_INTERRUPT. If both are set then yes,
the scan is interrupted, but it isn't canceled - it's just paused.
* Update the "did the scan flags change whilst the driver was called" logic
to check for canceled scans, not interrupted scans.
* The "scan done" logic now explicitly checks for either interrupted or
completed scans. This accounts for the situation where a scan is being
aborted via traffic but it ALSO happens to have finished (ie the last
channel was checked.)
This doesn't ENTIRELY fix scanning as the resume function is broken
due to incorrect ticks math. Thus, the second half of this patch
changes the ieee80211_ticks_*() macros to use int instead of long,
matching the logic that the TCP code does with ticks and handles
wrapping / negative ticks values. If cast to long then the wrapping
math wouldn't work right (ie, if ticks was actually negative,
ie, after the system has been up for a while.)
This allows contbgscan() to correctly calculate if a scan should
continue based on ticks and ic->ic_lastdata .
Reviewed by: bz
Differential Revision: https://reviews.freebsd.org/D25031
Send a probe request after IBSS node discovery
This sends a probe request after IBSS node discovery through
beacon frames. This allows things like HT and VHT capabilities
to be "negotiated" in adhoc mode.
It is .. kinda fire and pray - this isn't retried after discovery
so it's quite possible that nodes occasionally don't come up with
HT/VHT rate upgrades. At some point it may be a fun side project
to add support for retrying these probe requests/negotiations
after IBSS node discovery.
Tested:
* tested with multiple ath(4) NICs in 11n mode.
Differential Revision: https://reviews.freebsd.org/D24979
Add some more debugging during scanning
I'm trying to chase down more weird "I am not doing an incremental scan
when being asked" issues so these debugging statements help.
Notably, I've added more debugging around reasons why the scan is skipped -
eg because the cache is considered hot.
This should be a no-op unless you care about the debugging output!
Add field definition for A-MSDU inside A-MPDU.
Now that I have A-MSDU and A-MPDU coexisting together, we need to actually
announce if (a) it's permitted and (b) figure out if we should use it
when transmitting.
This just adds the field; it doesn't yet include it in ADDBA exchanges.
Add some TODOs around A-MSDU in A-MPDU negotiation.
net80211 currently doesn't negotiate A-MSDU in A-MPDU during ADDBA.
I've added the field in net80211 and this commit:
* Prints out the ADDBA field value during ADDBA;
* Adds some comments around where I need to follow up with some
negotiation logic.
Right now we don't have a driver flag anywhere which controls
whether A-MSDU in A-MPDU is allowed. I know it works (I have it
manually turned on at home on a couple test APs, heh!) but
I can't flip it on until we can negotiate it.
Tested:
* AR9380, STA/AP mode, printing out ADDBA requests
Migrate short slot time configuration into per-vap and deferred taskqueue updates.
The 11b/11g ERP and slot time update handling are two things which weren't
migrated into the per-VAP state when Sam did the initial VAP work.
That makes sense for a lot of setups where net80211 is driving radio state
and the radio only cares about the shared state.
However, as noted by a now deleted comment, the ERP and slot time updates
aren't EXACTLY correct/accurate - they only take into account the most
RECENTLY created VAP, and the state updates when one creates/destroys
VAPs isn't exactly great.
So:
* track the short slot logic per VAP;
* whenever the slot time configuration changes, just push it into a deferred
task queue update so drivers don't have to serialise it themselves;
* if a driver registers a per-VAP slot time handler then it'll just get the
per VAP one;
* .. if a driver registers a global one then the legacy behaviour is maintained -
a single slot time is calculated and pushed out.
Note that the calculated slot time is better than the existing logic - if ANY
of the VAPs require long slot then it's disabled for all VAPs rather than
whatever the last configured VAP did.
Now, this isn't entirely complete - the rest of ERP tracking around short/long
slot capable station tracking needs to be converted into per-VAP, as well
as the preamble/barker flags. Luckily those also can be done in a similar
fashion - keep per-VAP counters/flags and unify them before doing the driver
update. I'll defer that work until later.
All the existing drivers can keep doing what they're doing with the global
slot time flags as that is maintained. One driver (iwi) used the per-VAP
flags instead of the ic flags, so now that driver will work properly.
This unblocks some ath10k porting work as the firmware takes the slot time
configuration per-VAP rather than globally, and some firmware handles
STA+AP and STA+STA (on same/different channels) configurations where
the firmware will switch slot time as appropriate.
Tested:
* AR9380, STA/AP mode
* AR9880 (ath10k), STA mode
Add initial A-MSDU in A-MPDU negotation support.
This is hopefully a big no-op unless you're running some extra
patches to flip on A-MSDU options in a driver.
802.11n supports sending A-MSDU in A-MPDU. That lets you do things
like pack small frames into an A-MSDU and stuff /those/ into an A-MPDU.
It allows for much more efficient airtime because you're not
wasting time sending small frames - which is still a problem when
doing A-MPDU as there's still per-frame overhead and minimum A-MPDU
density requirements.
It, however, is optional for 802.11n. A lot of stuff doesn't advertise
it (but does it, just wait!); and I know that ath10k does it and my
ath(4) driver work supports it.
Now, 802.11ac makes A-MSDU in A-MPDU something that can happen more
frequently, because even though you can send very large A-MPDUs
(like 1 megabyte and larger) you still have the small frame problem.
So, 802.11ac NICs like ath10k and iwm will support A-MSDU in A-MPDU
out of the box if it's enabled - and you can negotiate it.
So, let's lay down the ground work to enable A-MSDU in A-MPDU.
This will allow hardware like iwn(4) and ath(4) which supports
software A-MSDU but hardware A-MPDU to be more efficient.
Drivers that support A-MSDU in A-MPDU will set TX/RX htcap flags.
Note this is separate from the software A-MSDU encap path; /that/
dictates whether net80211 is doing A-MSDU encapsulation or not.
These HTC flags control negotiation, NOT encapsulation.
Once this negotiation and driver bits are done, hardware like
rtwn(4), run(4), and others will be able to use A-MSDU even without
A-MPDU working; right now FF and A-MSDU aren't even attempted
if you're an 11n node. It's a small hold-over from the initial
A-MPDU work and I know how to fix it, but to flip it on properly
I need to be able to negotiate or ignore A-MSDU in A-MPDU.
Oh and the fun part - some 11ac APs I've tested will quite happily
decap A-MSDU in A-MPDU even though they don't negotiate it when
doing 802.11n. So hey, I know it works - I just want to properly
handle things. :-)
Tested:
* AR9380, STA/AP mode
print out node A-MSDU state.
Now that the node AMSDU TX/RX flags are correctly set in ieee80211_ht.c,
we can print out the AMSDU state here.
Don't call ic_updateslot if it's not set.
Turns out this isn't a required call. I didn't pick it up because my
uncommitted changes involve new updateslot methods for cards I'm working
on.
Dunce hat to: adrian
Fix typo.
Oops!
Fix this typo!
I've just started using this macro in upcoming amsdu/ampdu/ff rework and
yes, too many parens. Oops!
Flip on A-MPDU, A-MSDU, A-MPDU+A-MSDU and Fast frames options.
This updates the logic to allow:
* A-MPDU if available;
* A-MSDU if available and A-MPDU is off/NACKed;
* A-MPDU+A-MSDU if it's available and negotiated;
* Fast frames if the node is 11abg (and not HT/VHT.)
This allows for things to fail back to A-MSDU or fast frames
if A-MPDU isn't available rather than needing to be non-HT/non-VHT.
It also allows A-MPDU+A-MSDU to work if it's negotiated.
Tested:
* AR9380, STA + AP mode (A-MPDU, A-MSDU, FF, A-MPDU+A-MSDU)
* RT5350, STA mode (A-MSDU, FF)
* AR9170, STA mode (A-MSDU, FF)
Add a method to return the vap's ifname.
This removes the requirement to know what's in the ifp.
(If someone wants a quick clean-up task, it'd be nice to convert instances
of ifp dereferencing for if_xname over to this method.)
ok ok if_xname won't ever be NULL.
Somewhere in net80211 if_xname is checked against NULL but it doesn't trigger
a compiler warning, but this does. So DTRT for FreeBSD and the other if_xname
derefences can be converted to this function at a later time.
First part of A-MSDU offload handling - don't bump A-MPDU reordering seqno
When doing A-MSDU offload handling the driver is required to mark
A-MSDUs from the same MPDU with the same sequence number.
It then tags them as AMSDU (if it's a decap'ed A-MSDU) and AMSDU_MORE
(saying there's more AMSDUs decapped in the same MSDU.)
This allows encryption and sequence number offload to work right.
In the A-MSDU path the sequence number check looks at the A-MSDU flags
in the frame to see whether it's part of the same seqno and will pass them
(ie, not increment rx_seq until the last A-MSDU is seen from the driver,
or a new seqno shows up.0
However, I did this work in the A-MSDU path but not the A-MSDU in A-MPDU path.
For the non A-MDSU offload case the A-MPDU receive reordering will do its
thing and then pass up the MPDU up for decap - which then will see it's
an A-MSDU and decap each sub-frame. But this isn't done for offloaded
A-MSDU frames.
This requires two parts:
* Don't bump the RX sequence number, same as above; and
* If frames go into the reordering buffer, they need to be added into the slot
as a set of frames rather than a single frame, so once a new seqno shows up
this slot can be marked as "full" and we can move on.
This patch does the first. The latter requires that I find and commit
work to change rxa_m from an mbuf to an mbufq and the nhandle A-MSDU
there. But, the first is enough to allow the normal case (ie, no or not
a lot of A-MPDU RX reordering) to work.
This allows the athp driver (QCA9880) throughput to go from VERY low
(like 5mbit TCP, 1/3-1/4 expected UDP throughput) to ~ 250mbit TCP
and > 300mbit UDP on a VHT/40 channel. TCP sucks because, well, it
shows up as MASSIVE packet loss when all but one frame in a decap'ed
A-MSDU stream is dropped. Le whoops.
Now, where'd I put that laptop with the patch for rxa_m mbufq that
I wrote like in 2017...
Tested:
* AR9380, STA/AP mode (a big no-op, no A-MSDU hardware decap);
* if_run (RT3593), STA DWDS mode (A-MPDU / A-MSDU receive, but again
no A-MSDU hardware decap);
* QCA9880, STA/AP mode (which is doing hardware A-MPDU/A-MSDU decap,
but no A-MPDU reordering in the firmware.)
net80211: Add framework for debugnet(4) support
Allow net80211 drivers to register a small vtable of debugnet-related
methods.
This is not a functional change. Driver support is needed, similar to
debugnet(4) for wired NICs.
Reviewed by: adrian, markj (earlier version both)
Differential Revision: https://reviews.freebsd.org/D17308
separate out node allocation and node initialisation.
This is a new, optional (for now!) method that drivers can use to separate
node allocation and node initialisation. Right now they're the same, and
drivers that need to do node allocation via firmware commands need to sleep
and thus they need to defer node allocation into an internal taskqueue.
Right now they're just separate but not deferred. Later on if I get the time
we'll start deferring the node and key related operations but that requires
making a bunch of other stuff (notably things that generate frames!) also
async/deferred.
Tested:
* RT3593, STA/DWDS mode
* AR9380, STA/AP modes
* QCA9880 (athp) - STA/AP modes
Handle offloaded AMSDU in AMPDU reordering.
In the 11n world, most NICs did A-MPDU receive/transmit offloading but
not A-MSDU offloading. So, the net80211 A-MPDU receive path would just
receive MPDUs, do the reordering bit, pass it up to the rest of
net80211 for crypto decap and then do A-MSDU decap before throwing ethernet
frames up to the rest of the system.
However 11ac and 11ax NICs are increasingly doing A-MSDU offload (and
newer 11ax stuff does socket offload, but hey I don't want to scare people
JUST yet) - so although A-MPDU reordering may be done in the OS, A-MSDUs
look like a normal MPDU. This means that all the MSDUs are actually
faked into a set of MPDUs with matching 802.11 header - the sequence number,
QoS header and any encryption verification bits (like IV) are just copied.
This shows up as MASSIVE packet loss in net80211, cause after the first MPDU
we just toss the rest.
(And don't get me started about ethernet decap with A-MPDU host reordering;
we'll have to cross that bridge for later 11ac and 11ax bits too.)
Anyway, this work changes each A-MPDU reorder slot into an mbufq.
The mbufq is treated as a whole set of frames to pass up to the stack
and reordered/de-duped as a group. The last frame in the reorder list
is checked to see if it's an A-MSDU final frame so any duplicates are
correctly tossed rather than double-received. Other than that, the
rest of the logic is unchanged.
The previous commit did a small subset of this - if there wasn't any reordering
going on then it'd accept the A-MSDUs. This is the rest of the needed work.
This is a no-op for 11n NICs doing A-MPDU reordering but needing software
A-MSDU decap - they aren't tagged as A-MSDU and so any subsequent
frames added to the reorder slot are tossed.
Tested:
* QCA9880 (ath10k/athp) - STA/AP mode;
* RT3593 (if_rsu) - 11n STA+DWDS mode (I'm committing through it rn);
* QCA9380 (if_ath) - STA/AP mode.
Also convert the ddb path
Whoops - this belonged in my previous commit.
add a concat method.
Reviewed by: gnn, ae, glebius
Approved by: ae, glebius
Differential Revision: https://reviews.freebsd.org/D10158
Treat frames without an rx status as not a decap'ed A-MSDU.
Drivers for NICs which do A-MSDU decap in hardware / driver will need to
set the rx status, so if it's missing then treat it as not a decap'ed
A-MSDU.
Add initial U-APSD negotiation support.
U-APSD (unscheduled automatic power save delivery) is a power save method
that's a bit better than legacy PS-POLL - stations can mark frames with
an extra flag that tells the AP to leak out more frames after it sends
its own frames rather than needing to send a PS-POLL to get another frame
from the AP.
Now, this code just handles the negotiation bits; it doesn't actually
implement U-APSD. That's up to drivers, and nothing in the tree yet
implements this. I /may/ implement this for ath(4) if I eventually care
enough but right now I plan on just implementing it for firmware offload
based NICs that handle this in the NIC.
I'll commit the ifconfig bit after this and I may have some follow-up
commits as this gets used more by me in local testing.
This should be a glorious no-op for everyone else. If things change
for anyone that isn't fixed by a complete recompile then please reach out
to me.
Add missing commit to previous-1 uapsd commit.
Whoops; somehow my big commit line didn't include this.. cue the tree breakage emails.
Migrate HT/legacy protection mode and preamble calculation to per-VAP flags
The later firmware devices (including iwn!) support multiple configuration
contexts for a lot of things, leaving it up to the firmware to decide
which channel and vap is active. This allows for things like off-channel
p2p sta/ap operation and other weird things.
However, net80211 is still focused on a "net80211 drives all" when it comes to driving
the NIC, and as part of this history a lot of these options are global and not per-VAP.
This is fine when net80211 drives things and all VAPs share a single channel - these
parameters importantly really reflect the state of the channel! - but it will increasingly
be not fine when we start supporting more weird configurations and more recent NICs.
Yeah, recent like iwn/iwm.
Anyway - so, migrate all of the HT protection, legacy protection and preamble
stuff to be per-VAP. The global flags are still there; they're now calculated
in a deferred taskqueue that mirrors the old behaviour. Firmware based drivers
which have per-VAP configuration of these parameters can now just listen to the
per-VAP options.
What do I mean by per-channel? Well, the above configuration parameters really
are about interoperation with other devices on the same channel. Eg, HT protection
mode will flip to legacy/mixed if it hears ANY BSS that supports non-HT stations or
indicates it has non-HT stations associated. So, these flags really should be
per-channel rather than per-VAP, and then for things like "do i need short preamble
or long preamble?" turn into a "do I need it for this current operating channel".
Then any VAP using it can query the channel that it's on, reflecting the real
required state.
This patch does none of the above paragraph just yet.
I'm also cheating a bit - I'm currently not using separate taskqueues for
the beacon updates and the per-VAP configuration updates. I can always further
split it later if I need to but I didn't think it was SUPER important here.
So:
* Create vap taskqueue entries for ERP/protection, HT protection and short/long
preamble;
* Migrate the HT station count, short/long slot station count, etc - into per-VAP
variables rather than global;
* Fix a bug with my WME work from a while ago which made it per-VAP - do the WME
beacon update /after/ the WME update taskqueue runs, not before;
* Any time the HT protmode configuration changes or the ERP protection mode
config changes - schedule the task, which will call the driver without the
net80211 lock held and all correctly serialised;
* Use the global flags for beacon IEs and VAP flags for probe responses and
other IE situations.
The primary consumer of this is ath10k. iwn could use it when sending RXON,
but we don't support IBSS or AP modes on it yet, and I'm not yet sure whether
it's required in STA mode (ie whether the firmware parses beacons to change
protection mode or whether we need to.)
Tested:
* AR9280, STA/AP
* AR9380, DWDS STA+STA/AP
* ath10k work, STA/AP
* Intel 6235, STA
* Various rtwn / run NICs, DWDS STA and STA configurations
Commit files missing in the previous commit
These belong to my previous commit, but apparently I typed ieee80211_vhf.[ch]
and forgot ht.h. Le oops.
80211: consistently spell 80P80
The standard uses 80+80 and 80p80 but nowhere 80_80.
Switch the latter to 80P80 for all the macros and comments refering
to #defined flags which I could find.
The only place we leave as 80p80 is the ifconfig command line arguments
as we spell them all in lower case.
Ideally we would use 80+80 for any interactions with the user and
80P80 for anything internal but let us not confuse parsers and
hence avoid the '+' in either case.
Reviewed by: adrian, gnn
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
Differential Revision: https://reviews.freebsd.org/D26001
80211: consistently order 160 and 80+80
For flags and checks the order goes VHT160 and then VHT80P80 unless
checks are in reverse order ("more comes first") in which case we
deal with VHT80P80 first.
The one reverse order to pick out is where we check channel
prefernences. While it may seem that VHT160 is better, finding
two "free" channels (VHT 80+80) is more likely so we do prefer that.
While dealing with VHT160 and VHT80P80 add extra clauses previously
missing or marked TODO in a few places.
Reviewed by: adrian, gnn
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
Differential Revision: https://reviews.freebsd.org/D26002
net80211: remove vertical whitespace
No functional changes.
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
net80211/ifconfig: print hardware device name for wlan interfaces
Add IEEE80211_IOC_IC_NAME to query the ic_name field and in ifconfig
to print the parent interface again. This functionality was lost
around r287197. It helps in case of multiple wlan interfaces and
multiple underlying hardware devices to keep track which wlan
interface belongs to which physical device.
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
Reviewed by: adrian, Idwer Vollering
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D25832
net80211 / ifconfig: cleanup the use of IEEE80211_FVHT_USEVHT*
Rather then using magic numbers duplicate IEEE80211_FVHT_VHT* in
ifconfig (cleanup of these and other flags used and not exposed by
net80211 should happen later) and use those.
In the kernel this simplifies one ioctl path (the other one currently
relies on individual bit flags being passed in).
We also re-order the 80P80 and 160 flag for 160 to come before 80+80
and more clearly leave the flags as TODO in one of the 160/80+80 cases.
Reviewed by: adrian
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
Differential Revision: https://reviews.freebsd.org/D26000
net80211: return 80P80 before 160
In ieee80211_vht_get_chwidth_ie() we need to return 80P80 (3) before
VHT160 (2) as otherwise we'll never use 80P80. Fix the order.
MFC after: 2 weeks
X-MFC with: r364303 (which missed this)
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
net80211: VHT correct NSS Set loop boundary
For the <VHT-MCS, NSS> tuple, NSS is 1..8 (or in our loop case 0..7
but not 0..6). Correct the boundry to check for < 8 and not < 7.
MFC after: 2 weeks
Reviewed by: adrian
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
Differential Revision: https://reviews.freebsd.org/D26087
net80211: replace magic number by define
Rather than coding an array size of [4] replace the number with
WME_NUM_AC.
MFC after: 2 weeks
Reviewed by: adrian
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
Differential Revision: https://reviews.freebsd.org/D26090
net80211: set_vht_extchan() reverse order to always return best
In set_vht_extchan() the checks are performed in the order of VHT20/40/80.
That means if a channel has a lower and higheer VHT flag set we would
return the lower first.
We normally do not set more than one VHT flag so this change is supposed
to be a NOP but follows the logical thinking order of returning the best
first. Also we nowhere assert a single VHT flag so make sure we'll not
be stuck with VHT20 when we could do more.
While here add the debugging printfs for VHT160 and VHT80P80 which still
need doing once we deal with a driver at that level.
Reviewed by: adrian, gnn
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
Differential Revision: https://reviews.freebsd.org/D26088
net80211: improve media information for VHT5GHZ
Improve ieee80211_media_setup(), media2mode(), and
ieee80211_rate2media() for VHT5GHZ at least.
Reviewed by: adrian, gnn
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
Differential Revision: https://reviews.freebsd.org/D26089
net80211: enhance getflags*() and ieee80211_add_channel*()
For ieee80211_add_channel+*() we are passing in an int flag for
ht40 and in some cases another int flag for vht80 where we'd only
need two bits really.
Convert these variables to a bitflag and fold them together into one.
This also allows for VHT160 and VHT80P80 and whatever may come to
be considered. Define the various options currently needed.
Change the drivers (rtwn and rsu) which actually set this bit to non-0.
For convenience the "1" currently used for HT40 is preserved.
Enahnce getflags_5ghz() to handle the full set of VHT flags based
on the input flags from the the driver.
Update the regdomain implementation as well to make use of the new
flags and deal with higher [V]HT bandwidths.
ieee80211_add_channel() specifically did not take flags so it will
not support naything beyond 20Mhz channels.
Note: I am not entirely happy with the "cbw_flag[s]" name, but we
do use chan_flags elsewhere already.
MFC after: 2 weeks
Reviewed by: adrian, gnn
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
Differential revision: https://reviews.freebsd.org/D26091
net: clean up empty lines in .c and .h files
Provide MS() and SM() macros for 80211 and wireless drivers.
We have (two versions) of MS() and SM() macros which we use throughout
the wireless code. Change all but three places (ath_hal, rtwn, and rsu)
to the newly provided _IEEE80211_MASKSHIFT() and _IEEE80211_SHIFTMASK()
macros. Also change one internal case using both _S and _M instead of
just _S away from _M (one of the reasons rtwn and rsu were not changed).
This was done semi-mechanically. No functional changes intended.
Requested by: gnn (D26091)
Reviewed by: adrian (pre line wrap)
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
Differential Revision: https://reviews.freebsd.org/D26539
80211: non-functional changes
Sort a few VHT160 and 80+80 lines, update some comments, and remove
a superfluous ','.
No functional changes intended.
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
net80211: whitespace
Fix indentation for the multi-line copies of
ieee80211_add_channel_list_5ghz() for the 3 bands.
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
net80211: update for (more) VHT160 support
Implement two macros IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ()
and its 80+80 counter part to check in vhtcaps for appropriate
levels of support and use the macros throughout the code.
Add vht160_chan_ranges/is_vht160_valid_freq and handle analogue
to vht80 in various parts of the code.
Add ieee80211_add_channel_cbw() which also takes the CBW flag
fields and make the former ieee80211_add_channel() a wrapper to it.
With the CBW flags we can add HT/VHT channels passing them to
getflags() for the 2/5ghz functions.
In ifconfig(8) add the regdomain_addchans() support for VHT160
and VHT80P80.
With this (+ regdoain.xml updates) VHT160 channels can be
configured, listed, and pass regdomain where appropriate.
Tested with: iwlwifi
Reviewed by: adrian
MFC after: 10 days
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D26712
net80211: fix a typo
Correct a typo referring to the wrong flags in a comment.
No functional changes.
MFC after: 3 days
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
Add new privileges; restrict what can be done in a jail.
Split the MANAGE privilege into MANAGE, SETMAC and CREATE_VAP.
+ VAP_MANAGE is everything but setting the MAC and creating a VAP.
+ VAP_SETMAC is setting the MAC address of the VAP.
Typically you wouldn't want the jail to be able to modify this.
+ CREATE_VAP is to create a new VAP. Again, you don't want to be doing
this in a jail, but this DOES stop being able to run some corner
cases like Dynamic WDS (DWDS) AP in a jail/vnet. We can figure this
bit out later.
This allows me to run wpa_supplicant in a jail after transferring
a STA VAP into it. I unfortunately can't currently set the wlan
debugging inside the jail; that would be super useful!
Reviewed by: bz
Differential Revision: https://reviews.freebsd.org/D25630
net80211: factor out the priv(9) checks into OS specifc code.
Factor out the priv(9) checks into OS specifc code so other OSes can equally
implement them. This sorts out those XXX in the net80211 code.
We provide 3 arguments (cmd, vap, ifp) where available to the functions, in
order to allow other OSes to use that data but also in case we'd add auditing
to these check to have the information available. For now the arguments are
marked __unused.
PR: 249403
Reported by: martin(NetBSD)
Reviewed by: adrian, martin(NetBSD)
MFC after: 10 days
Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate")
Differential Revision: https://reviews.freebsd.org/D26541
sockio.h: add missing ioctl SIOCSIFLLADDR
Change-Id: I68703723ac919b901adb99ca1f7d0319fd0271f5
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3910
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
- Switch to Python3
- Switch to mawk instead of gawk
- Update ffmpeg (there are several new dependencies)
- Update ICU
- Fix various pre-existing problems with packages not being properly
declared for gcc2 (but somehow it ended up working)
- remove curl, subversion, mercurial
Confirmed that both nightly and release images are building fine on both
32 and 64bit. However, non-x86 architecture may require re-bootstrapping
to do a complete nightly or release image build (the minimal profile
should be fine)
Fixes#16751.
Change-Id: Iacac92923c4113b3e0a49a64b0b4cc1b8e2f5e2e
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3871
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
* kMaxOptionSize: TCP header size is 60 bytes. process_options() would have
accepted a longer header as permitted. add_options() would have possibly added
more options or SACK entries as permitted.
* tcp_segment: reserve memory for sack entries.
* _SendQueued(): "fLastAcknowledgeSent <= fReceiveNext": also send SACK entries
for received data when acknowledging a missing segment.
* _SendQueue(): after acknowledging, cancel the delayed acknowledgment timer.
* _Receive(): if calling Acknowledged() already triggered sending a segment
including an acknowledgement (piggy-back), remove "immediate acknowledge"
from the action. This helps to reduce empty ACKs for bidirectional streams.
Change-Id: I32808fbe549be0f5b25bcf4be17cd91a640b8ec4
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3906
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
tested on Wireless 8265 / 8275 [8086:24fd]
iwm: improve rfkill handling
Previously the driver handled the bit within itself, but did not expose
the state change to net80211 and interface layers.
This change uses net80211 KPI for rfkill signaling.
The code is modeled after similar code in iwn and wpi.
Reviewed by: adrian
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D24923
WiFi: fix ieee80211_media_change() callers
In r178354 with the introduction of multi-bss ("vap") support factoring
out started and with r193340 ieee80211_media_change() no longer returned
ENETRESET but only 0 or error.
As ieee80211(9) tells the ieee80211_media_change() function should not
be called directly but is registered with ieee80211_vap_attach() instead.
Some drivers have not been fully converted. After fixing the return
checking some of these functions were simply wrappers between
ieee80211_vap_attach() and ieee80211_media_change(), so remove the extra
function, where possible as well.
PR: 248955
Submitted by: Tong Zhang (ztong0001 gmail.com) (original)
MFC after: 3 days
Sponsored by: The FreeBSD Foundation
iwm: fix regression from r365419 (ieee80211_media_change())
In r365419 ieee80211_media_change() callers were updated to not longer
act on the obselete ENETRESET return code.
While in the old days iwm has done a stop/init cycle in these cases,
this was not executed since r193340.
As a consequence simplify iwm code as well by passing ieee80211_media_change()
right to ieee80211_vap_attach() as there is no more need for a local
implementation.
Reported by: Tomoaki AOKI (junchoon dec.sakura.ne.jp)
Tested by: Tomoaki AOKI (junchoon dec.sakura.ne.jp)
MFC after: 3 days
X-MFC: fix is already in stable/12
PR: 248955
iwm(4): Add support for Intel Killer(R) Wireless-AC 1550i
PR: 252578
Submitted by: shu <ankohuu@outlook.com>
MFC after: 1 week
Change-Id: Ibf9ec28986769bc7532e4c06ea2acafce7a8d86b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3907
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Fix multiple definitions of 'terminaltype' and 'line' when linking.
Pointed out by gcc11.
Change-Id: I85552e2d243bd5db5f80806d92e6fa87bc41eb44
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3903
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
Since nv_globals.h and globals.h are included from several files,
it cause multiple definitions error when linking.
Pointed out by gcc11.
Change-Id: I10e27af062c6f4b49fdb9ef6bb3ba77809ebcba0
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3904
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
Initial rect size doesn't persist to changing text rect sizes and
alignment changes but insets do. Maintains a 3px border around text
on all sides.
Change-Id: I70e855c3b6b17bc576fd5e38cd43fedb6c830aef
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3901
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
* These are pretty much the 10G standards that have
any potential for usage on a desktop system.
Change-Id: I2cb49f41ca61e82e091d042f877ee2f1acb9c4ec
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3900
Reviewed-by: Alex von Gluck IV <kallisti5@unixzen.com>
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
The ioctl call cannot know the expected number of arguments
because it depends on the specific ioctl being used, and the
same value could be used to do different things by different
devices. Without knowing that, it is not safe to use va_arg
(at best a random value will be read from the stack, at worst,
it will just crash).
This changes the implementation of ioctl in two ways:
- For C++ code: a 4 argument function with default values
for arguments 3 and 4.
- For C code: wrap arguments 3 and 4 in a struct with the
help of a macro, providing something that behaves like the
C++ version.
So, with this new code:
- Calling ioctl with only 3 arguments sets the 4th one to 0
- Calling ioctl with only 2 arguments sets the 3rd and 4th to 0
- Calling with 1 or 5+ arguments is a compile time error
The existing ioctl symbol is preserved for ABI compatibility.
Change-Id: I6d4d1d38fccd8cc9bd94203d3e11aeac6da8efc3
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3360
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
gcc2 preprocessor reads `__func__,` as one token, yielding
dprintf("nfs4: %s()" "whatever" "\n", );
and a parse error for the expansion of ERROR with only one parameter.
Separating the comma gives the result we want.
Change-Id: I5d20e2c06a796b7092b9f23162fa7bfb269318be
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3899
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
this is needed for GCC to build after the aligned_alloc introduction
Change-Id: Ieae32a050cc000561107c4a07cf10c912a196152
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3896
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
We now use the same API as BeOS for input devices notification.
Change-Id: I873c7556c039d0628af306bb7d157cc06a5cd652
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3873
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
this adds kernel & libroot stack protector hooks. it uses /dev/random in userspace.
A configure option --enable-stack-protector is added to activate -fstack-protector
on selected system components (ATM apps, kits, servers).
Change-Id: If3a2920ba9aa0a85eaff4ba6778947f8c76ade31
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3895
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
* Thanks to kottan I notices something was of..
* Added uInt16 and uInt64, I was missing UInt16.
Change-Id: Id136dbb5a81392a7a694ac1fbbd9aefbd7f77af3
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3888
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
should help with bug #16929, untested
Change-Id: Ia7b9b6cc8e84e2377d79c0edd1c278cdf74d869b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3891
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
Use B_PRId32 for int32 type fValue.
Pointed out by lgtm.
Change-Id: I751451281ace627e2f3be67d1b860b8ebe675ba5
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3886
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
Fix fBackBitmap and items of fVectorIcons were not released.
Change-Id: I8bf974a9f11852c4b1092490e699b46bd79997eb
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3879
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
There was a bug in the version of this class previously used by MediaPlayer,
and as a result we have settings where uint32 fields are stored as int32.
If the uint32 version is not found, try the int32 version.
Fixes#16922.
Using the CK505 clock source may need some more checks or configuration
we currently don't do, leading to a blank screen in some systems.
Whatever the reason, disabling it makes the driver work on my machine.
Fixes#16357
Change-Id: If207ffdddcf6e6eb73bc69ce5a8bd2842fd2141b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3867
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
Allow for multiple programs to watch for changes in the state
of input devices connected to the system. Previously only one program
at a time could watch input devices. While this functionality was not
implemented in BeOS R5, it was at least documented in the BeBook.
Also added some API documentation where necessary for the function
and related constants.
Change-Id: Icd927998cffcab212bb63bcf10c64c620e9da9a2
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3872
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
Whenever a device is removed, let usb_raw cancel all its pending
transfers. Does not seems to help with the issue I'm getting however.
Change-Id: Ie2856e68ea402c9f1cc352ac47bbca624e17d3dc
Reviewed-on: https://review.haiku-os.org/c/haiku/+/1424
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Reviewed-by: Fredrik Modéen <fredrik@modeen.se>
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>