diff options
36 files changed, 611 insertions, 529 deletions
diff --git a/lib/libnvmf/nvmf_tcp.c b/lib/libnvmf/nvmf_tcp.c index 6f41ca7ff502..48ddabaf506a 100644 --- a/lib/libnvmf/nvmf_tcp.c +++ b/lib/libnvmf/nvmf_tcp.c @@ -728,7 +728,7 @@ nvmf_tcp_handle_r2t(struct nvmf_tcp_qpair *qp, struct nvmf_tcp_rxpdu *pdu) } /* - * XXX: The spec does not specify how to handle R2T tranfers + * XXX: The spec does not specify how to handle R2T transfers * out of range of the original command. */ data_len = le32toh(r2t->r2tl); diff --git a/sys/amd64/vmm/intel/vmx_support.S b/sys/amd64/vmm/intel/vmx_support.S index 130130b64541..877e377f892d 100644 --- a/sys/amd64/vmm/intel/vmx_support.S +++ b/sys/amd64/vmm/intel/vmx_support.S @@ -171,13 +171,11 @@ do_launch: */ movq %rsp, %rdi /* point %rdi back to 'vmxctx' */ movl $VMX_VMLAUNCH_ERROR, %eax - jmp decode_inst_error - + /* FALLTHROUGH */ decode_inst_error: movl $VM_FAIL_VALID, %r11d - jz inst_error - movl $VM_FAIL_INVALID, %r11d -inst_error: + movl $VM_FAIL_INVALID, %esi + cmovnzl %esi, %r11d movl %r11d, VMXCTX_INST_FAIL_STATUS(%rdi) /* diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index f9a2b86f0c06..7cd768a9811a 100644 --- a/sys/cam/ata/ata_all.c +++ b/sys/cam/ata/ata_all.c @@ -1151,7 +1151,7 @@ ata_zac_mgmt_out(struct ccb_ataio *ataio, uint32_t retries, /* * For SEND FPDMA QUEUED, the transfer length is * encoded in the FEATURE register, and 0 means - * that 65536 512 byte blocks are to be tranferred. + * that 65536 512 byte blocks are to be transferred. * In practice, it seems unlikely that we'll see * a transfer that large. */ @@ -1220,7 +1220,7 @@ ata_zac_mgmt_in(struct ccb_ataio *ataio, uint32_t retries, /* * For RECEIVE FPDMA QUEUED, the transfer length is * encoded in the FEATURE register, and 0 means - * that 65536 512 byte blocks are to be tranferred. + * that 65536 512 byte blocks are to be transferred. * In practice, it is unlikely we will see a transfer that * large. */ diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index d02750aaacaf..fc8c0413448d 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -6830,7 +6830,7 @@ scsi_ata_zac_mgmt_out(struct ccb_scsiio *csio, uint32_t retries, /* * For SEND FPDMA QUEUED, the transfer length is * encoded in the FEATURE register, and 0 means - * that 65536 512 byte blocks are to be tranferred. + * that 65536 512 byte blocks are to be transferred. * In practice, it seems unlikely that we'll see * a transfer that large, and it may confuse the * the SAT layer, because generally that means that @@ -6916,7 +6916,7 @@ scsi_ata_zac_mgmt_in(struct ccb_scsiio *csio, uint32_t retries, /* * For RECEIVE FPDMA QUEUED, the transfer length is * encoded in the FEATURE register, and 0 means - * that 65536 512 byte blocks are to be tranferred. + * that 65536 512 byte blocks are to be transferred. * In practice, it seems unlikely that we'll see * a transfer that large, and it may confuse the * the SAT layer, because generally that means that diff --git a/sys/compat/linuxkpi/common/include/linux/netdevice.h b/sys/compat/linuxkpi/common/include/linux/netdevice.h index cd7d23077a62..3b808a4a1749 100644 --- a/sys/compat/linuxkpi/common/include/linux/netdevice.h +++ b/sys/compat/linuxkpi/common/include/linux/netdevice.h @@ -4,7 +4,7 @@ * Copyright (c) 2010 Panasas, Inc. * Copyright (c) 2013-2019 Mellanox Technologies, Ltd. * All rights reserved. - * Copyright (c) 2020-2021 The FreeBSD Foundation + * Copyright (c) 2020-2025 The FreeBSD Foundation * Copyright (c) 2020-2022 Bjoern A. Zeeb * * Portions of this software were developed by Björn Zeeb @@ -302,6 +302,13 @@ netdev_rss_key_fill(uint32_t *buf, size_t len) get_random_bytes(buf, len); } +static inline void +__hw_addr_init(struct netdev_hw_addr_list *list) +{ + list->count = 0; + INIT_LIST_HEAD(&list->addr_list); +} + static inline int netdev_hw_addr_list_count(struct netdev_hw_addr_list *list) { diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h index 19f7bcff29dc..0106e6648bd4 100644 --- a/sys/compat/linuxkpi/common/include/net/mac80211.h +++ b/sys/compat/linuxkpi/common/include/net/mac80211.h @@ -87,6 +87,9 @@ enum mcast_filter_flags { FIF_PSPOLL = BIT(5), FIF_CONTROL = BIT(6), FIF_MCAST_ACTION = BIT(7), + + /* Must stay last. */ + FIF_FLAGS_MASK = BIT(8)-1, }; enum ieee80211_bss_changed { diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index 91836b857727..e248588dd275 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -274,48 +274,40 @@ lkpi_nl80211_sta_info_to_str(struct sbuf *s, const char *prefix, sbuf_printf(s, "\n"); } -static int -lkpi_80211_dump_stas(SYSCTL_HANDLER_ARGS) +static void +lkpi_80211_dump_lvif_stas(struct lkpi_vif *lvif, struct sbuf *s) { struct lkpi_hw *lhw; struct ieee80211_hw *hw; struct ieee80211vap *vap; - struct lkpi_vif *lvif; struct ieee80211_vif *vif; struct lkpi_sta *lsta; struct ieee80211_sta *sta; struct station_info sinfo; - struct sbuf s; int error; - if (req->newptr) - return (EPERM); - - lvif = (struct lkpi_vif *)arg1; vif = LVIF_TO_VIF(lvif); vap = LVIF_TO_VAP(lvif); lhw = vap->iv_ic->ic_softc; hw = LHW_TO_HW(lhw); - sbuf_new_for_sysctl(&s, NULL, 1024, req); - wiphy_lock(hw->wiphy); list_for_each_entry(lsta, &lvif->lsta_list, lsta_list) { sta = LSTA_TO_STA(lsta); - sbuf_putc(&s, '\n'); - sbuf_printf(&s, "lsta %p sta %p added_to_drv %d\n", lsta, sta, lsta->added_to_drv); + sbuf_putc(s, '\n'); + sbuf_printf(s, "lsta %p sta %p added_to_drv %d\n", lsta, sta, lsta->added_to_drv); memset(&sinfo, 0, sizeof(sinfo)); error = lkpi_80211_mo_sta_statistics(hw, vif, sta, &sinfo); if (error == EEXIST) /* Not added to driver. */ continue; if (error == ENOTSUPP) { - sbuf_printf(&s, " sta_statistics not supported\n"); + sbuf_printf(s, " sta_statistics not supported\n"); continue; } if (error != 0) { - sbuf_printf(&s, " sta_statistics failed: %d\n", error); + sbuf_printf(s, " sta_statistics failed: %d\n", error); continue; } @@ -334,51 +326,67 @@ lkpi_80211_dump_stas(SYSCTL_HANDLER_ARGS) sinfo.filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); } - lkpi_nl80211_sta_info_to_str(&s, " nl80211_sta_info (valid fields)", sinfo.filled); - sbuf_printf(&s, " connected_time %u inactive_time %u\n", + lkpi_nl80211_sta_info_to_str(s, " nl80211_sta_info (valid fields)", sinfo.filled); + sbuf_printf(s, " connected_time %u inactive_time %u\n", sinfo.connected_time, sinfo.inactive_time); - sbuf_printf(&s, " rx_bytes %ju rx_packets %u rx_dropped_misc %u\n", + sbuf_printf(s, " rx_bytes %ju rx_packets %u rx_dropped_misc %u\n", (uintmax_t)sinfo.rx_bytes, sinfo.rx_packets, sinfo.rx_dropped_misc); - sbuf_printf(&s, " rx_duration %ju rx_beacon %u rx_beacon_signal_avg %d\n", + sbuf_printf(s, " rx_duration %ju rx_beacon %u rx_beacon_signal_avg %d\n", (uintmax_t)sinfo.rx_duration, sinfo.rx_beacon, (int8_t)sinfo.rx_beacon_signal_avg); - sbuf_printf(&s, " tx_bytes %ju tx_packets %u tx_failed %u\n", + sbuf_printf(s, " tx_bytes %ju tx_packets %u tx_failed %u\n", (uintmax_t)sinfo.tx_bytes, sinfo.tx_packets, sinfo.tx_failed); - sbuf_printf(&s, " tx_duration %ju tx_retries %u\n", + sbuf_printf(s, " tx_duration %ju tx_retries %u\n", (uintmax_t)sinfo.tx_duration, sinfo.tx_retries); - sbuf_printf(&s, " signal %d signal_avg %d ack_signal %d avg_ack_signal %d\n", + sbuf_printf(s, " signal %d signal_avg %d ack_signal %d avg_ack_signal %d\n", sinfo.signal, sinfo.signal_avg, sinfo.ack_signal, sinfo.avg_ack_signal); - sbuf_printf(&s, " generation %d assoc_req_ies_len %zu chains %#04x\n", + sbuf_printf(s, " generation %d assoc_req_ies_len %zu chains %#04x\n", sinfo.generation, sinfo.assoc_req_ies_len, sinfo.chains); for (int i = 0; i < nitems(sinfo.chain_signal) && i < IEEE80211_MAX_CHAINS; i++) { if (!(sinfo.chains & BIT(i))) continue; - sbuf_printf(&s, " chain[%d] signal %d signal_avg %d\n", + sbuf_printf(s, " chain[%d] signal %d signal_avg %d\n", i, (int8_t)sinfo.chain_signal[i], (int8_t)sinfo.chain_signal_avg[i]); } /* assoc_req_ies, bss_param, sta_flags */ - sbuf_printf(&s, " rxrate: flags %b bw %u(%s) legacy %u kbit/s mcs %u nss %u\n", + sbuf_printf(s, " rxrate: flags %b bw %u(%s) legacy %u kbit/s mcs %u nss %u\n", sinfo.rxrate.flags, CFG80211_RATE_INFO_FLAGS_BITS, sinfo.rxrate.bw, lkpi_rate_info_bw_to_str(sinfo.rxrate.bw), sinfo.rxrate.legacy * 100, sinfo.rxrate.mcs, sinfo.rxrate.nss); - sbuf_printf(&s, " he_dcm %u he_gi %u he_ru_alloc %u eht_gi %u\n", + sbuf_printf(s, " he_dcm %u he_gi %u he_ru_alloc %u eht_gi %u\n", sinfo.rxrate.he_dcm, sinfo.rxrate.he_gi, sinfo.rxrate.he_ru_alloc, sinfo.rxrate.eht_gi); - sbuf_printf(&s, " txrate: flags %b bw %u(%s) legacy %u kbit/s mcs %u nss %u\n", + sbuf_printf(s, " txrate: flags %b bw %u(%s) legacy %u kbit/s mcs %u nss %u\n", sinfo.txrate.flags, CFG80211_RATE_INFO_FLAGS_BITS, sinfo.txrate.bw, lkpi_rate_info_bw_to_str(sinfo.txrate.bw), sinfo.txrate.legacy * 100, sinfo.txrate.mcs, sinfo.txrate.nss); - sbuf_printf(&s, " he_dcm %u he_gi %u he_ru_alloc %u eht_gi %u\n", + sbuf_printf(s, " he_dcm %u he_gi %u he_ru_alloc %u eht_gi %u\n", sinfo.txrate.he_dcm, sinfo.txrate.he_gi, sinfo.txrate.he_ru_alloc, sinfo.txrate.eht_gi); } wiphy_unlock(hw->wiphy); +} + +static int +lkpi_80211_dump_stas(SYSCTL_HANDLER_ARGS) +{ + struct lkpi_vif *lvif; + struct sbuf s; + + if (req->newptr) + return (EPERM); + + lvif = (struct lkpi_vif *)arg1; + + sbuf_new_for_sysctl(&s, NULL, 1024, req); + + lkpi_80211_dump_lvif_stas(lvif, &s); sbuf_finish(&s); sbuf_delete(&s); @@ -1171,7 +1179,7 @@ lkpi_find_lkpi80211_chan(struct lkpi_hw *lhw, channels = hw->wiphy->bands[band]->channels; for (i = 0; i < nchans; i++) { - if (channels[i].hw_value == c->ic_ieee) + if (channels[i].center_freq == c->ic_freq) return (&channels[i]); } @@ -1709,6 +1717,24 @@ lkpi_iv_key_update_end(struct ieee80211vap *vap) } #endif +static void +lkpi_cleanup_mcast_list_locked(struct lkpi_hw *lhw) +{ + struct list_head *le, *next; + struct netdev_hw_addr *addr; + + if (lhw->mc_list.count != 0) { + list_for_each_safe(le, next, &lhw->mc_list.addr_list) { + addr = list_entry(le, struct netdev_hw_addr, addr_list); + list_del(le); + lhw->mc_list.count--; + free(addr, M_LKPI80211); + } + } + KASSERT(lhw->mc_list.count == 0, ("%s: mc_list %p count %d != 0\n", + __func__, &lhw->mc_list, lhw->mc_list.count)); +} + static u_int lkpi_ic_update_mcast_copy(void *arg, struct sockaddr_dl *sdl, u_int cnt) { @@ -1745,16 +1771,13 @@ lkpi_ic_update_mcast_copy(void *arg, struct sockaddr_dl *sdl, u_int cnt) } static void -lkpi_update_mcast_filter(struct ieee80211com *ic, bool force) +lkpi_update_mcast_filter(struct ieee80211com *ic) { struct lkpi_hw *lhw; struct ieee80211_hw *hw; - struct netdev_hw_addr_list mc_list; - struct list_head *le, *next; - struct netdev_hw_addr *addr; - struct ieee80211vap *vap; u64 mc; - unsigned int changed_flags, total_flags; + unsigned int changed_flags, flags; + bool scanning; lhw = ic->ic_softc; @@ -1762,44 +1785,32 @@ lkpi_update_mcast_filter(struct ieee80211com *ic, bool force) lhw->ops->configure_filter == NULL) return; - if (!lhw->update_mc && !force) - return; + LKPI_80211_LHW_SCAN_LOCK(lhw); + scanning = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0; + LKPI_80211_LHW_SCAN_UNLOCK(lhw); - changed_flags = total_flags = 0; - mc_list.count = 0; - INIT_LIST_HEAD(&mc_list.addr_list); - if (ic->ic_allmulti == 0) { - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if_foreach_llmaddr(vap->iv_ifp, - lkpi_ic_update_mcast_copy, &mc_list); - } else { - changed_flags |= FIF_ALLMULTI; - } + LKPI_80211_LHW_MC_LOCK(lhw); + + flags = 0; + if (scanning) + flags |= FIF_BCN_PRBRESP_PROMISC; + if (lhw->mc_all_multi) + flags |= FIF_ALLMULTI; hw = LHW_TO_HW(lhw); - mc = lkpi_80211_mo_prepare_multicast(hw, &mc_list); - /* - * XXX-BZ make sure to get this sorted what is a change, - * what gets all set; what was already set? - */ - total_flags = changed_flags; - lkpi_80211_mo_configure_filter(hw, changed_flags, &total_flags, mc); + mc = lkpi_80211_mo_prepare_multicast(hw, &lhw->mc_list); + + changed_flags = (lhw->mc_flags ^ flags) & FIF_FLAGS_MASK; + lkpi_80211_mo_configure_filter(hw, changed_flags, &flags, mc); + lhw->mc_flags = flags; #ifdef LINUXKPI_DEBUG_80211 if (linuxkpi_debug_80211 & D80211_TRACE) - printf("%s: changed_flags %#06x count %d total_flags %#010x\n", - __func__, changed_flags, mc_list.count, total_flags); + printf("%s: changed_flags %#06x count %d mc_flags %#010x\n", + __func__, changed_flags, lhw->mc_list.count, lhw->mc_flags); #endif - if (mc_list.count != 0) { - list_for_each_safe(le, next, &mc_list.addr_list) { - addr = list_entry(le, struct netdev_hw_addr, addr_list); - free(addr, M_LKPI80211); - mc_list.count--; - } - } - KASSERT(mc_list.count == 0, ("%s: mc_list %p count %d != 0\n", - __func__, &mc_list, mc_list.count)); + LKPI_80211_LHW_MC_UNLOCK(lhw); } static enum ieee80211_bss_changed @@ -1918,19 +1929,19 @@ lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif, struct lkpi_hw *lhw) { enum ieee80211_bss_changed changed; + struct lkpi_vif *lvif; changed = 0; sta->aid = 0; if (vif->cfg.assoc) { - lhw->update_mc = true; - lkpi_update_mcast_filter(lhw->ic, true); - vif->cfg.assoc = false; vif->cfg.aid = 0; changed |= BSS_CHANGED_ASSOC; IMPROVE(); + lkpi_update_mcast_filter(lhw->ic); + /* * Executing the bss_info_changed(BSS_CHANGED_ASSOC) with * assoc = false right away here will remove the sta from @@ -1941,6 +1952,9 @@ lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif, * bss_info_changed() update. * See lkpi_sta_run_to_init() for more detailed comment. */ + + lvif = VIF_TO_LVIF(vif); + lvif->beacons = 0; } return (changed); @@ -2211,6 +2225,7 @@ lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int /* vif->bss_conf.basic_rates ? Where exactly? */ + lvif->beacons = 0; /* Should almost assert it is this. */ vif->cfg.assoc = false; vif->cfg.aid = 0; @@ -2400,6 +2415,7 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int struct lkpi_sta *lsta; struct ieee80211_sta *sta; struct ieee80211_prep_tx_info prep_tx_info; + enum ieee80211_bss_changed bss_changed; int error; lhw = vap->iv_ic->ic_softc; @@ -2471,6 +2487,11 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int lsta->added_to_drv = false; /* mo manages. */ #endif + bss_changed = 0; + vif->bss_conf.dtim_period = 0; /* go back to 0. */ + bss_changed |= BSS_CHANGED_BEACON_INFO; + lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); + lkpi_lsta_dump(lsta, ni, __func__, __LINE__); LKPI_80211_LVIF_LOCK(lvif); @@ -2799,6 +2820,8 @@ _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum ieee80211_state nstate, i vif->cfg.ssid_len = 0; memset(vif->cfg.ssid, '\0', sizeof(vif->cfg.ssid)); bss_changed |= BSS_CHANGED_BSSID; + vif->bss_conf.dtim_period = 0; /* go back to 0. */ + bss_changed |= BSS_CHANGED_BEACON_INFO; lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); LKPI_80211_LVIF_LOCK(lvif); @@ -2931,6 +2954,7 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int bss_changed |= lkpi_wme_update(lhw, vap, true); #endif if (!vif->cfg.assoc || vif->cfg.aid != IEEE80211_NODE_AID(ni)) { + lvif->beacons = 0; vif->cfg.assoc = true; vif->cfg.aid = IEEE80211_NODE_AID(ni); bss_changed |= BSS_CHANGED_ASSOC; @@ -2979,9 +3003,6 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int * - set_key (?) * - ipv6_addr_change (?) */ - /* Prepare_multicast && configure_filter. */ - lhw->update_mc = true; - lkpi_update_mcast_filter(vap->iv_ic, true); if (!ieee80211_node_is_authorized(ni)) { IMPROVE("net80211 does not consider node authorized"); @@ -3020,6 +3041,9 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__); lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); + /* Prepare_multicast && configure_filter. */ + lkpi_update_mcast_filter(vap->iv_ic); + out: wiphy_unlock(hw->wiphy); IEEE80211_LOCK(vap->iv_ic); @@ -3400,6 +3424,8 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int vif->bss_conf.use_short_preamble = false; vif->bss_conf.qos = false; /* XXX BSS_CHANGED_???? */ + vif->bss_conf.dtim_period = 0; /* go back to 0. */ + bss_changed |= BSS_CHANGED_BEACON_INFO; lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); LKPI_80211_LVIF_LOCK(lvif); @@ -3702,6 +3728,42 @@ lkpi_ic_wme_update(struct ieee80211com *ic) return (0); /* unused */ } +static void +lkpi_iv_sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, + int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf) +{ + struct lkpi_hw *lhw; + struct ieee80211_hw *hw; + struct lkpi_vif *lvif; + struct ieee80211_vif *vif; + enum ieee80211_bss_changed bss_changed; + + lvif = VAP_TO_LVIF(ni->ni_vap); + + lvif->iv_recv_mgmt(ni, m0, subtype, rxs, rssi, nf); + + switch (subtype) { + case IEEE80211_FC0_SUBTYPE_PROBE_RESP: + break; + case IEEE80211_FC0_SUBTYPE_BEACON: + lvif->beacons++; + break; + default: + return; + } + + vif = LVIF_TO_VIF(lvif); + lhw = ni->ni_ic->ic_softc; + hw = LHW_TO_HW(lhw); + + /* + * If this direct call to mo_bss_info_changed will not work due to + * locking, see if queue_work() is fast enough. + */ + bss_changed = lkpi_update_dtim_tsf(vif, ni, ni->ni_vap, __func__, __LINE__); + lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed); +} + /* * Change link-layer address on the vif (if the vap is not started/"UP"). * This can happen if a user changes 'ether' using ifconfig. @@ -3884,7 +3946,7 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed); /* Force MC init. */ - lkpi_update_mcast_filter(ic, true); + lkpi_update_mcast_filter(ic); ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); @@ -3897,6 +3959,8 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], vap->iv_newstate = lkpi_iv_newstate; lvif->iv_update_bss = vap->iv_update_bss; vap->iv_update_bss = lkpi_iv_update_bss; + lvif->iv_recv_mgmt = vap->iv_recv_mgmt; + vap->iv_recv_mgmt = lkpi_iv_sta_recv_mgmt; #ifdef LKPI_80211_HW_CRYPTO /* Key management. */ @@ -4019,8 +4083,30 @@ lkpi_ic_vap_delete(struct ieee80211vap *vap) static void lkpi_ic_update_mcast(struct ieee80211com *ic) { + struct ieee80211vap *vap; + struct lkpi_hw *lhw; - lkpi_update_mcast_filter(ic, false); + lhw = ic->ic_softc; + if (lhw->ops->prepare_multicast == NULL || + lhw->ops->configure_filter == NULL) + return; + + LKPI_80211_LHW_MC_LOCK(lhw); + /* Cleanup anything on the current list. */ + lkpi_cleanup_mcast_list_locked(lhw); + + /* Build up the new list (or allmulti). */ + if (ic->ic_allmulti == 0) { + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) + if_foreach_llmaddr(vap->iv_ifp, + lkpi_ic_update_mcast_copy, &lhw->mc_list); + lhw->mc_all_multi = false; + } else { + lhw->mc_all_multi = true; + } + LKPI_80211_LHW_MC_UNLOCK(lhw); + + lkpi_update_mcast_filter(ic); TRACEOK(); } @@ -4256,6 +4342,8 @@ sw_scan: if (vap->iv_state == IEEE80211_S_SCAN) lkpi_hw_conf_idle(hw, false); + lkpi_update_mcast_filter(ic); + lkpi_80211_mo_sw_scan_start(hw, vif, vif->addr); /* net80211::scan_start() handled PS for us. */ IMPROVE(); @@ -4363,7 +4451,6 @@ sw_scan: struct ieee80211_channel *c; c = ss->ss_chans[ss->ss_next + i]; - lc->hw_value = c->ic_ieee; lc->center_freq = c->ic_freq; /* XXX */ /* lc->flags */ lc->band = lkpi_net80211_chan_to_nl80211_band(c); @@ -4392,7 +4479,6 @@ sw_scan: } } #endif - hw_req->req.n_ssids = ssid_count; if (hw_req->req.n_ssids > 0) { ssids = (struct cfg80211_ssid *)lc; @@ -4439,6 +4525,8 @@ sw_scan: return; } + lkpi_update_mcast_filter(ic); + error = lkpi_80211_mo_hw_scan(hw, vif, hw_req); if (error != 0) { ieee80211_cancel_scan(vap); @@ -4464,6 +4552,7 @@ sw_scan: lhw->scan_flags &= ~LKPI_LHW_SCAN_RUNNING; } LKPI_80211_LHW_SCAN_UNLOCK(lhw); + lkpi_update_mcast_filter(ic); /* * XXX-SIGH magic number. @@ -5831,8 +5920,9 @@ lkpi_ic_getradiocaps(struct ieee80211com *ic, int maxchan, cflags &= ~NET80211_CBW_FLAG_HT40; error = ieee80211_add_channel_cbw(c, maxchan, n, - channels[i].hw_value, channels[i].center_freq, - channels[i].max_power, + ieee80211_mhz2ieee(channels[i].center_freq, + lkpi_nl80211_band_to_net80211_band(channels[i].band)), + channels[i].center_freq, channels[i].max_power, nflags, bands, cflags); /* net80211::ENOBUFS: *n >= maxchans */ if (error != 0 && error != ENOBUFS) @@ -5903,8 +5993,9 @@ lkpi_ic_getradiocaps(struct ieee80211com *ic, int maxchan, cflags &= ~NET80211_CBW_FLAG_HT40; error = ieee80211_add_channel_cbw(c, maxchan, n, - channels[i].hw_value, channels[i].center_freq, - channels[i].max_power, + ieee80211_mhz2ieee(channels[i].center_freq, + lkpi_nl80211_band_to_net80211_band(channels[i].band)), + channels[i].center_freq, channels[i].max_power, nflags, bands, cflags); /* net80211::ENOBUFS: *n >= maxchans */ if (error != 0 && error != ENOBUFS) @@ -5952,7 +6043,9 @@ linuxkpi_ieee80211_alloc_hw(size_t priv_len, const struct ieee80211_ops *ops) LKPI_80211_LHW_SCAN_LOCK_INIT(lhw); LKPI_80211_LHW_TXQ_LOCK_INIT(lhw); sx_init_flags(&lhw->lvif_sx, "lhw-lvif", SX_RECURSE | SX_DUPOK); + LKPI_80211_LHW_MC_LOCK_INIT(lhw); TAILQ_INIT(&lhw->lvif_head); + __hw_addr_init(&lhw->mc_list); for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { lhw->txq_generation[ac] = 1; TAILQ_INIT(&lhw->scheduled_txqs[ac]); @@ -6049,10 +6142,15 @@ linuxkpi_ieee80211_iffree(struct ieee80211_hw *hw) } } + LKPI_80211_LHW_MC_LOCK(lhw); + lkpi_cleanup_mcast_list_locked(lhw); + LKPI_80211_LHW_MC_UNLOCK(lhw); + /* Cleanup more of lhw here or in wiphy_free()? */ LKPI_80211_LHW_TXQ_LOCK_DESTROY(lhw); LKPI_80211_LHW_SCAN_LOCK_DESTROY(lhw); sx_destroy(&lhw->lvif_sx); + LKPI_80211_LHW_MC_LOCK_DESTROY(lhw) IMPROVE(); } @@ -7857,8 +7955,11 @@ linuxkpi_ieee80211_connection_loss(struct ieee80211_vif *vif) nstate = IEEE80211_S_INIT; arg = 0; /* Not a valid reason. */ - ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s\n", __func__, - vif, vap, ieee80211_state_name[vap->iv_state]); + ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s (synched %d, assoc %d " + "beacons %d dtim_period %d)\n", __func__, vif, vap, + ieee80211_state_name[vap->iv_state], + lvif->lvif_bss_synched, vif->cfg.assoc, lvif->beacons, + vif->bss_conf.dtim_period); ieee80211_new_state(vap, nstate, arg); } @@ -7871,8 +7972,11 @@ linuxkpi_ieee80211_beacon_loss(struct ieee80211_vif *vif) lvif = VIF_TO_LVIF(vif); vap = LVIF_TO_VAP(lvif); - ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s\n", __func__, - vif, vap, ieee80211_state_name[vap->iv_state]); + ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s (synched %d, assoc %d " + "beacons %d dtim_period %d)\n", __func__, vif, vap, + ieee80211_state_name[vap->iv_state], + lvif->lvif_bss_synched, vif->cfg.assoc, lvif->beacons, + vif->bss_conf.dtim_period); ieee80211_beacon_miss(vap->iv_ic); } diff --git a/sys/compat/linuxkpi/common/src/linux_80211.h b/sys/compat/linuxkpi/common/src/linux_80211.h index 89afec1235bd..eaf6d804af4c 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.h +++ b/sys/compat/linuxkpi/common/src/linux_80211.h @@ -187,6 +187,11 @@ struct lkpi_vif { enum ieee80211_state, int); struct ieee80211_node * (*iv_update_bss)(struct ieee80211vap *, struct ieee80211_node *); + void (*iv_recv_mgmt)(struct ieee80211_node *, + struct mbuf *, int, + const struct ieee80211_rx_stats *, + int, int); + struct list_head lsta_list; struct lkpi_sta *lvif_bss; @@ -194,6 +199,7 @@ struct lkpi_vif { struct ieee80211_node *key_update_iv_bss; int ic_unlocked; /* Count of ic unlocks pending (*mo_set_key) */ int nt_unlocked; /* Count of nt unlocks pending (*mo_set_key) */ + int beacons; /* # of beacons since assoc */ bool lvif_bss_synched; bool added_to_drv; /* Driver knows; i.e. we called add_interface(). */ @@ -223,6 +229,9 @@ struct lkpi_hw { /* name it mac80211_sc? */ struct sx lvif_sx; struct list_head lchanctx_list; + struct netdev_hw_addr_list mc_list; + unsigned int mc_flags; + struct sx mc_sx; struct mtx txq_mtx; uint32_t txq_generation[IEEE80211_NUM_ACS]; @@ -279,7 +288,7 @@ struct lkpi_hw { /* name it mac80211_sc? */ int max_rates; /* Maximum number of bitrates supported in any channel. */ int scan_ie_len; /* Length of common per-band scan IEs. */ - bool update_mc; + bool mc_all_multi; bool update_wme; bool rxq_stopped; @@ -369,6 +378,13 @@ struct lkpi_wiphy { #define LKPI_80211_LHW_LVIF_LOCK(_lhw) sx_xlock(&(_lhw)->lvif_sx) #define LKPI_80211_LHW_LVIF_UNLOCK(_lhw) sx_xunlock(&(_lhw)->lvif_sx) +#define LKPI_80211_LHW_MC_LOCK_INIT(_lhw) \ + sx_init_flags(&lhw->mc_sx, "lhw-mc", 0); +#define LKPI_80211_LHW_MC_LOCK_DESTROY(_lhw) \ + sx_destroy(&lhw->mc_sx); +#define LKPI_80211_LHW_MC_LOCK(_lhw) sx_xlock(&(_lhw)->mc_sx) +#define LKPI_80211_LHW_MC_UNLOCK(_lhw) sx_xunlock(&(_lhw)->mc_sx) + #define LKPI_80211_LVIF_LOCK(_lvif) mtx_lock(&(_lvif)->mtx) #define LKPI_80211_LVIF_UNLOCK(_lvif) mtx_unlock(&(_lvif)->mtx) diff --git a/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh b/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh index 70a2364f1fc6..62e06926e268 100755 --- a/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh +++ b/sys/contrib/openzfs/.github/workflows/scripts/qemu-2-start.sh @@ -25,6 +25,10 @@ UBMIRROR="https://cloud-images.ubuntu.com" # default nic model for vm's NIC="virtio" +# additional options for virt-install +OPTS[0]="" +OPTS[1]="" + case "$OS" in almalinux8) OSNAME="AlmaLinux 8" @@ -61,6 +65,14 @@ case "$OS" in OSNAME="Debian 12" URL="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2" ;; + debian13) + OSNAME="Debian 13" + # TODO: Overwrite OSv to debian13 for virt-install until it's added to osinfo + OSv="debian12" + URL="https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2" + OPTS[0]="--boot" + OPTS[1]="uefi=on" + ;; fedora41) OSNAME="Fedora 41" OSv="fedora-unknown" @@ -242,7 +254,7 @@ sudo virt-install \ --network bridge=virbr0,model=$NIC,mac='52:54:00:83:79:00' \ --cloud-init user-data=/tmp/user-data \ --disk $DISK,bus=virtio,cache=none,format=raw,driver.discard=unmap \ - --import --noautoconsole >/dev/null + --import --noautoconsole ${OPTS[0]} ${OPTS[1]} >/dev/null # Give the VMs hostnames so we don't have to refer to them with # hardcoded IP addresses. diff --git a/sys/contrib/openzfs/.github/workflows/scripts/qemu-3-deps-vm.sh b/sys/contrib/openzfs/.github/workflows/scripts/qemu-3-deps-vm.sh index c41ecd09d52e..ee058b488088 100755 --- a/sys/contrib/openzfs/.github/workflows/scripts/qemu-3-deps-vm.sh +++ b/sys/contrib/openzfs/.github/workflows/scripts/qemu-3-deps-vm.sh @@ -41,7 +41,7 @@ function debian() { libelf-dev libffi-dev libmount-dev libpam0g-dev libselinux-dev libssl-dev \ libtool libtool-bin libudev-dev libunwind-dev linux-headers-$(uname -r) \ lsscsi nfs-kernel-server pamtester parted python3 python3-all-dev \ - python3-cffi python3-dev python3-distlib python3-packaging \ + python3-cffi python3-dev python3-distlib python3-packaging libtirpc-dev \ python3-setuptools python3-sphinx qemu-guest-agent rng-tools rpm2cpio \ rsync samba sysstat uuid-dev watchdog wget xfslibs-dev xxhash zlib1g-dev echo "##[endgroup]" diff --git a/sys/contrib/openzfs/.github/workflows/scripts/qemu-5-setup.sh b/sys/contrib/openzfs/.github/workflows/scripts/qemu-5-setup.sh index 6bf10024a1a6..0adcad2a99bc 100755 --- a/sys/contrib/openzfs/.github/workflows/scripts/qemu-5-setup.sh +++ b/sys/contrib/openzfs/.github/workflows/scripts/qemu-5-setup.sh @@ -12,16 +12,26 @@ source /var/tmp/env.txt # wait for poweroff to succeed PID=$(pidof /usr/bin/qemu-system-x86_64) tail --pid=$PID -f /dev/null -sudo virsh undefine openzfs +sudo virsh undefine --nvram openzfs # cpu pinning CPUSET=("0,1" "2,3") +# additional options for virt-install +OPTS[0]="" +OPTS[1]="" + case "$OS" in freebsd*) # FreeBSD needs only 6GiB RAM=6 ;; + debian13) + RAM=8 + # Boot Debian 13 with uefi=on and secureboot=off (ZFS Kernel Module not signed) + OPTS[0]="--boot" + OPTS[1]="firmware=efi,firmware.feature0.name=secure-boot,firmware.feature0.enabled=no" + ;; *) # Linux needs more memory, but can be optimized to share it via KSM RAM=8 @@ -79,7 +89,7 @@ EOF --network bridge=virbr0,model=$NIC,mac="52:54:00:83:79:0$i" \ --disk $DISK-system,bus=virtio,cache=none,format=$FORMAT,driver.discard=unmap \ --disk $DISK-tests,bus=virtio,cache=none,format=$FORMAT,driver.discard=unmap \ - --import --noautoconsole >/dev/null + --import --noautoconsole ${OPTS[0]} ${OPTS[1]} done # generate some memory stats diff --git a/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml b/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml index cda620313189..4ebb80af1f03 100644 --- a/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml +++ b/sys/contrib/openzfs/.github/workflows/zfs-qemu.yml @@ -29,7 +29,7 @@ jobs: - name: Generate OS config and CI type id: os run: | - FULL_OS='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian11", "debian12", "fedora41", "fedora42", "freebsd13-5r", "freebsd14-3s", "freebsd15-0c", "ubuntu22", "ubuntu24"]' + FULL_OS='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian12", "debian13", "fedora41", "fedora42", "freebsd13-5r", "freebsd14-3s", "freebsd15-0c", "ubuntu22", "ubuntu24"]' QUICK_OS='["almalinux8", "almalinux9", "almalinux10", "debian12", "fedora42", "freebsd14-3s", "ubuntu24"]' # determine CI type when running on PR ci_type="full" @@ -63,8 +63,8 @@ jobs: strategy: fail-fast: false matrix: - # rhl: almalinux8, almalinux9, centos-stream9, fedora41 - # debian: debian11, debian12, ubuntu22, ubuntu24 + # rhl: almalinux8, almalinux9, centos-stream9, fedora4x + # debian: debian12, debian13, ubuntu22, ubuntu24 # misc: archlinux, tumbleweed # FreeBSD variants of 2025-06: # FreeBSD Release: freebsd13-5r, freebsd14-2r, freebsd14-3r diff --git a/sys/contrib/openzfs/META b/sys/contrib/openzfs/META index 1a9c671feac6..42f65290e4e3 100644 --- a/sys/contrib/openzfs/META +++ b/sys/contrib/openzfs/META @@ -1,8 +1,8 @@ Meta: 1 Name: zfs Branch: 1.0 -Version: 2.3.99 -Release: 1 +Version: 2.4.0 +Release: rc1 Release-Tags: relext License: CDDL Author: OpenZFS diff --git a/sys/contrib/openzfs/cmd/zdb/zdb.c b/sys/contrib/openzfs/cmd/zdb/zdb.c index a5f23be2aaaf..adaa5cd10961 100644 --- a/sys/contrib/openzfs/cmd/zdb/zdb.c +++ b/sys/contrib/openzfs/cmd/zdb/zdb.c @@ -1586,9 +1586,8 @@ dump_spacemap(objset_t *os, space_map_t *sm) continue; } - uint8_t words; char entry_type; - uint64_t entry_off, entry_run, entry_vdev = SM_NO_VDEVID; + uint64_t entry_off, entry_run, entry_vdev; if (sm_entry_is_single_word(word)) { entry_type = (SM_TYPE_DECODE(word) == SM_ALLOC) ? @@ -1596,35 +1595,43 @@ dump_spacemap(objset_t *os, space_map_t *sm) entry_off = (SM_OFFSET_DECODE(word) << mapshift) + sm->sm_start; entry_run = SM_RUN_DECODE(word) << mapshift; - words = 1; + + (void) printf("\t [%6llu] %c " + "range: %012llx-%012llx size: %08llx\n", + (u_longlong_t)entry_id, entry_type, + (u_longlong_t)entry_off, + (u_longlong_t)(entry_off + entry_run - 1), + (u_longlong_t)entry_run); } else { /* it is a two-word entry so we read another word */ ASSERT(sm_entry_is_double_word(word)); uint64_t extra_word; offset += sizeof (extra_word); + ASSERT3U(offset, <, space_map_length(sm)); VERIFY0(dmu_read(os, space_map_object(sm), offset, sizeof (extra_word), &extra_word, DMU_READ_PREFETCH)); - ASSERT3U(offset, <=, space_map_length(sm)); - entry_run = SM2_RUN_DECODE(word) << mapshift; entry_vdev = SM2_VDEV_DECODE(word); entry_type = (SM2_TYPE_DECODE(extra_word) == SM_ALLOC) ? 'A' : 'F'; entry_off = (SM2_OFFSET_DECODE(extra_word) << mapshift) + sm->sm_start; - words = 2; - } - (void) printf("\t [%6llu] %c range:" - " %010llx-%010llx size: %06llx vdev: %06llu words: %u\n", - (u_longlong_t)entry_id, - entry_type, (u_longlong_t)entry_off, - (u_longlong_t)(entry_off + entry_run), - (u_longlong_t)entry_run, - (u_longlong_t)entry_vdev, words); + if (zopt_metaslab_args == 0 || + zopt_metaslab[0] == entry_vdev) { + (void) printf("\t [%6llu] %c " + "range: %012llx-%012llx size: %08llx " + "vdev: %llu\n", + (u_longlong_t)entry_id, entry_type, + (u_longlong_t)entry_off, + (u_longlong_t)(entry_off + entry_run - 1), + (u_longlong_t)entry_run, + (u_longlong_t)entry_vdev); + } + } if (entry_type == 'A') alloc += entry_run; @@ -1873,7 +1880,7 @@ dump_metaslabs(spa_t *spa) (void) printf("\nMetaslabs:\n"); - if (!dump_opt['d'] && zopt_metaslab_args > 0) { + if (zopt_metaslab_args > 0) { c = zopt_metaslab[0]; if (c >= children) diff --git a/sys/contrib/openzfs/contrib/debian/rules.in b/sys/contrib/openzfs/contrib/debian/rules.in index 3226d604546c..2b0568938b25 100755 --- a/sys/contrib/openzfs/contrib/debian/rules.in +++ b/sys/contrib/openzfs/contrib/debian/rules.in @@ -93,7 +93,7 @@ override_dh_auto_install: @# Install the DKMS source. @# We only want the files needed to build the modules install -D -t '$(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/scripts' \ - '$(CURDIR)/scripts/dkms.postbuild' + '$(CURDIR)/scripts/dkms.postbuild' '$(CURDIR)/scripts/objtool-wrapper.in' $(foreach file,$(DKMSFILES),mv '$(CURDIR)/$(NAME)-$(DEB_VERSION_UPSTREAM)/$(file)' '$(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)' || exit 1;) @# Only ever build Linux modules @@ -108,8 +108,8 @@ override_dh_auto_install: @# - zfs.release$ @# * Takes care of spaces and tabs @# * Remove reference to ZFS_AC_PACKAGE - awk '/^AC_CONFIG_FILES\(\[/,/^\]\)/ {\ - if ($$0 !~ /^(AC_CONFIG_FILES\(\[([ \t]+)?$$|\]\)([ \t]+)?$$|([ \t]+)?(include\/(Makefile|sys|os\/(Makefile|linux))|module\/|Makefile([ \t]+)?$$|zfs\.release([ \t]+)?$$))/) \ + awk '/^AC_CONFIG_FILES\(\[/,/\]\)/ {\ + if ($$0 !~ /^(AC_CONFIG_FILES\(\[([ \t]+)?$$|\]\)([ \t]+)?$$|([ \t]+)?(include\/(Makefile|sys|os\/(Makefile|linux))|module\/|Makefile([ \t]+)?$$|zfs\.release([ \t]+)?$$))|scripts\/objtool-wrapper.*\]\)$$/) \ {next} } {print}' \ '$(CURDIR)/$(NAME)-$(DEB_VERSION_UPSTREAM)/configure.ac' | sed '/ZFS_AC_PACKAGE/d' > '$(CURDIR)/debian/tmp/usr/src/$(NAME)-$(DEB_VERSION_UPSTREAM)/configure.ac' @# Set "SUBDIRS = module include" for CONFIG_KERNEL and remove SUBDIRS for all other configs. diff --git a/sys/contrib/openzfs/include/sys/dmu_impl.h b/sys/contrib/openzfs/include/sys/dmu_impl.h index 21a8b16a3ee6..bae872bd1907 100644 --- a/sys/contrib/openzfs/include/sys/dmu_impl.h +++ b/sys/contrib/openzfs/include/sys/dmu_impl.h @@ -168,12 +168,10 @@ extern "C" { * dn_allocated_txg * dn_free_txg * dn_assigned_txg - * dn_dirty_txg + * dn_dirtycnt * dd_assigned_tx * dn_notxholds * dn_nodnholds - * dn_dirtyctx - * dn_dirtyctx_firstset * (dn_phys copy fields?) * (dn_phys contents?) * held from: diff --git a/sys/contrib/openzfs/include/sys/dnode.h b/sys/contrib/openzfs/include/sys/dnode.h index 76218c8b09ca..8bd1db5b7165 100644 --- a/sys/contrib/openzfs/include/sys/dnode.h +++ b/sys/contrib/openzfs/include/sys/dnode.h @@ -141,12 +141,6 @@ struct dmu_buf_impl; struct objset; struct zio; -enum dnode_dirtycontext { - DN_UNDIRTIED, - DN_DIRTY_OPEN, - DN_DIRTY_SYNC -}; - /* Is dn_used in bytes? if not, it's in multiples of SPA_MINBLOCKSIZE */ #define DNODE_FLAG_USED_BYTES (1 << 0) #define DNODE_FLAG_USERUSED_ACCOUNTED (1 << 1) @@ -340,11 +334,9 @@ struct dnode { uint64_t dn_allocated_txg; uint64_t dn_free_txg; uint64_t dn_assigned_txg; - uint64_t dn_dirty_txg; /* txg dnode was last dirtied */ + uint8_t dn_dirtycnt; kcondvar_t dn_notxholds; kcondvar_t dn_nodnholds; - enum dnode_dirtycontext dn_dirtyctx; - const void *dn_dirtyctx_firstset; /* dbg: contents meaningless */ /* protected by own devices */ zfs_refcount_t dn_tx_holds; @@ -440,7 +432,6 @@ void dnode_rele_and_unlock(dnode_t *dn, const void *tag, boolean_t evicting); int dnode_try_claim(objset_t *os, uint64_t object, int slots); boolean_t dnode_is_dirty(dnode_t *dn); void dnode_setdirty(dnode_t *dn, dmu_tx_t *tx); -void dnode_set_dirtyctx(dnode_t *dn, dmu_tx_t *tx, const void *tag); void dnode_sync(dnode_t *dn, dmu_tx_t *tx); void dnode_allocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int ibs, dmu_object_type_t bonustype, int bonuslen, int dn_slots, dmu_tx_t *tx); @@ -468,9 +459,6 @@ void dnode_free_interior_slots(dnode_t *dn); void dnode_set_storage_type(dnode_t *dn, dmu_object_type_t type); -#define DNODE_IS_DIRTY(_dn) \ - ((_dn)->dn_dirty_txg >= spa_syncing_txg((_dn)->dn_objset->os_spa)) - #define DNODE_LEVEL_IS_CACHEABLE(_dn, _level) \ ((_dn)->dn_objset->os_primary_cache == ZFS_CACHE_ALL || \ (((_level) > 0 || DMU_OT_IS_METADATA((_dn)->dn_type)) && \ diff --git a/sys/contrib/openzfs/module/zfs/dbuf.c b/sys/contrib/openzfs/module/zfs/dbuf.c index 7403f10d91b7..fccc4c5b5b94 100644 --- a/sys/contrib/openzfs/module/zfs/dbuf.c +++ b/sys/contrib/openzfs/module/zfs/dbuf.c @@ -2270,14 +2270,6 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) if (dn->dn_objset->os_dsl_dataset != NULL) rrw_exit(&dn->dn_objset->os_dsl_dataset->ds_bp_rwlock, FTAG); #endif - /* - * We make this assert for private objects as well, but after we - * check if we're already dirty. They are allowed to re-dirty - * in syncing context. - */ - ASSERT(dn->dn_object == DMU_META_DNODE_OBJECT || - dn->dn_dirtyctx == DN_UNDIRTIED || dn->dn_dirtyctx == - (dmu_tx_is_syncing(tx) ? DN_DIRTY_SYNC : DN_DIRTY_OPEN)); mutex_enter(&db->db_mtx); /* @@ -2289,12 +2281,6 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) db->db_state == DB_CACHED || db->db_state == DB_FILL || db->db_state == DB_NOFILL); - mutex_enter(&dn->dn_mtx); - dnode_set_dirtyctx(dn, tx, db); - if (tx->tx_txg > dn->dn_dirty_txg) - dn->dn_dirty_txg = tx->tx_txg; - mutex_exit(&dn->dn_mtx); - if (db->db_blkid == DMU_SPILL_BLKID) dn->dn_have_spill = B_TRUE; @@ -2313,13 +2299,6 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) return (dr_next); } - /* - * Only valid if not already dirty. - */ - ASSERT(dn->dn_object == 0 || - dn->dn_dirtyctx == DN_UNDIRTIED || dn->dn_dirtyctx == - (dmu_tx_is_syncing(tx) ? DN_DIRTY_SYNC : DN_DIRTY_OPEN)); - ASSERT3U(dn->dn_nlevels, >, db->db_level); /* diff --git a/sys/contrib/openzfs/module/zfs/dmu_objset.c b/sys/contrib/openzfs/module/zfs/dmu_objset.c index a77f338bdfd3..8e6b569c2100 100644 --- a/sys/contrib/openzfs/module/zfs/dmu_objset.c +++ b/sys/contrib/openzfs/module/zfs/dmu_objset.c @@ -2037,6 +2037,8 @@ userquota_updates_task(void *arg) dn->dn_id_flags |= DN_ID_CHKED_BONUS; } dn->dn_id_flags &= ~(DN_ID_NEW_EXIST); + ASSERT3U(dn->dn_dirtycnt, >, 0); + dn->dn_dirtycnt--; mutex_exit(&dn->dn_mtx); multilist_sublist_remove(list, dn); @@ -2070,6 +2072,10 @@ dnode_rele_task(void *arg) dnode_t *dn; while ((dn = multilist_sublist_head(list)) != NULL) { + mutex_enter(&dn->dn_mtx); + ASSERT3U(dn->dn_dirtycnt, >, 0); + dn->dn_dirtycnt--; + mutex_exit(&dn->dn_mtx); multilist_sublist_remove(list, dn); dnode_rele(dn, &os->os_synced_dnodes); } diff --git a/sys/contrib/openzfs/module/zfs/dnode.c b/sys/contrib/openzfs/module/zfs/dnode.c index 963ff41232a3..6c150d31c669 100644 --- a/sys/contrib/openzfs/module/zfs/dnode.c +++ b/sys/contrib/openzfs/module/zfs/dnode.c @@ -173,9 +173,7 @@ dnode_cons(void *arg, void *unused, int kmflag) dn->dn_allocated_txg = 0; dn->dn_free_txg = 0; dn->dn_assigned_txg = 0; - dn->dn_dirty_txg = 0; - dn->dn_dirtyctx = 0; - dn->dn_dirtyctx_firstset = NULL; + dn->dn_dirtycnt = 0; dn->dn_bonus = NULL; dn->dn_have_spill = B_FALSE; dn->dn_zio = NULL; @@ -229,9 +227,7 @@ dnode_dest(void *arg, void *unused) ASSERT0(dn->dn_allocated_txg); ASSERT0(dn->dn_free_txg); ASSERT0(dn->dn_assigned_txg); - ASSERT0(dn->dn_dirty_txg); - ASSERT0(dn->dn_dirtyctx); - ASSERT0P(dn->dn_dirtyctx_firstset); + ASSERT0(dn->dn_dirtycnt); ASSERT0P(dn->dn_bonus); ASSERT(!dn->dn_have_spill); ASSERT0P(dn->dn_zio); @@ -692,10 +688,8 @@ dnode_destroy(dnode_t *dn) dn->dn_allocated_txg = 0; dn->dn_free_txg = 0; dn->dn_assigned_txg = 0; - dn->dn_dirty_txg = 0; + dn->dn_dirtycnt = 0; - dn->dn_dirtyctx = 0; - dn->dn_dirtyctx_firstset = NULL; if (dn->dn_bonus != NULL) { mutex_enter(&dn->dn_bonus->db_mtx); dbuf_destroy(dn->dn_bonus); @@ -800,11 +794,9 @@ dnode_allocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int ibs, dn->dn_bonuslen = bonuslen; dn->dn_checksum = ZIO_CHECKSUM_INHERIT; dn->dn_compress = ZIO_COMPRESS_INHERIT; - dn->dn_dirtyctx = 0; dn->dn_free_txg = 0; - dn->dn_dirtyctx_firstset = NULL; - dn->dn_dirty_txg = 0; + dn->dn_dirtycnt = 0; dn->dn_allocated_txg = tx->tx_txg; dn->dn_id_flags = 0; @@ -955,9 +947,7 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn) ndn->dn_allocated_txg = odn->dn_allocated_txg; ndn->dn_free_txg = odn->dn_free_txg; ndn->dn_assigned_txg = odn->dn_assigned_txg; - ndn->dn_dirty_txg = odn->dn_dirty_txg; - ndn->dn_dirtyctx = odn->dn_dirtyctx; - ndn->dn_dirtyctx_firstset = odn->dn_dirtyctx_firstset; + ndn->dn_dirtycnt = odn->dn_dirtycnt; ASSERT0(zfs_refcount_count(&odn->dn_tx_holds)); zfs_refcount_transfer(&ndn->dn_holds, &odn->dn_holds); ASSERT(avl_is_empty(&ndn->dn_dbufs)); @@ -1020,9 +1010,7 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn) odn->dn_allocated_txg = 0; odn->dn_free_txg = 0; odn->dn_assigned_txg = 0; - odn->dn_dirty_txg = 0; - odn->dn_dirtyctx = 0; - odn->dn_dirtyctx_firstset = NULL; + odn->dn_dirtycnt = 0; odn->dn_have_spill = B_FALSE; odn->dn_zio = NULL; odn->dn_oldused = 0; @@ -1273,8 +1261,8 @@ dnode_check_slots_free(dnode_children_t *children, int idx, int slots) } else if (DN_SLOT_IS_PTR(dn)) { mutex_enter(&dn->dn_mtx); boolean_t can_free = (dn->dn_type == DMU_OT_NONE && - zfs_refcount_is_zero(&dn->dn_holds) && - !DNODE_IS_DIRTY(dn)); + dn->dn_dirtycnt == 0 && + zfs_refcount_is_zero(&dn->dn_holds)); mutex_exit(&dn->dn_mtx); if (!can_free) @@ -1757,17 +1745,23 @@ dnode_hold(objset_t *os, uint64_t object, const void *tag, dnode_t **dnp) * reference on the dnode. Returns FALSE if unable to add a * new reference. */ +static boolean_t +dnode_add_ref_locked(dnode_t *dn, const void *tag) +{ + ASSERT(MUTEX_HELD(&dn->dn_mtx)); + if (zfs_refcount_is_zero(&dn->dn_holds)) + return (FALSE); + VERIFY(1 < zfs_refcount_add(&dn->dn_holds, tag)); + return (TRUE); +} + boolean_t dnode_add_ref(dnode_t *dn, const void *tag) { mutex_enter(&dn->dn_mtx); - if (zfs_refcount_is_zero(&dn->dn_holds)) { - mutex_exit(&dn->dn_mtx); - return (FALSE); - } - VERIFY(1 < zfs_refcount_add(&dn->dn_holds, tag)); + boolean_t r = dnode_add_ref_locked(dn, tag); mutex_exit(&dn->dn_mtx); - return (TRUE); + return (r); } void @@ -1830,31 +1824,20 @@ dnode_try_claim(objset_t *os, uint64_t object, int slots) } /* - * Checks if the dnode itself is dirty, or is carrying any uncommitted records. - * It is important to check both conditions, as some operations (eg appending - * to a file) can dirty both as a single logical unit, but they are not synced - * out atomically, so checking one and not the other can result in an object - * appearing to be clean mid-way through a commit. + * Test if the dnode is dirty, or carrying uncommitted records. * - * Do not change this lightly! If you get it wrong, dmu_offset_next() can - * detect a hole where there is really data, leading to silent corruption. + * dn_dirtycnt is the number of txgs this dnode is dirty on. It's incremented + * in dnode_setdirty() the first time the dnode is dirtied on a txg, and + * decremented in either dnode_rele_task() or userquota_updates_task() when the + * txg is synced out. */ boolean_t dnode_is_dirty(dnode_t *dn) { mutex_enter(&dn->dn_mtx); - - for (int i = 0; i < TXG_SIZE; i++) { - if (multilist_link_active(&dn->dn_dirty_link[i]) || - !list_is_empty(&dn->dn_dirty_records[i])) { - mutex_exit(&dn->dn_mtx); - return (B_TRUE); - } - } - + boolean_t dirty = (dn->dn_dirtycnt != 0); mutex_exit(&dn->dn_mtx); - - return (B_FALSE); + return (dirty); } void @@ -1916,7 +1899,11 @@ dnode_setdirty(dnode_t *dn, dmu_tx_t *tx) * dnode will hang around after we finish processing its * children. */ - VERIFY(dnode_add_ref(dn, (void *)(uintptr_t)tx->tx_txg)); + mutex_enter(&dn->dn_mtx); + VERIFY(dnode_add_ref_locked(dn, (void *)(uintptr_t)tx->tx_txg)); + dn->dn_dirtycnt++; + ASSERT3U(dn->dn_dirtycnt, <=, 3); + mutex_exit(&dn->dn_mtx); (void) dbuf_dirty(dn->dn_dbuf, tx); @@ -2221,32 +2208,6 @@ dnode_dirty_l1range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid, mutex_exit(&dn->dn_dbufs_mtx); } -void -dnode_set_dirtyctx(dnode_t *dn, dmu_tx_t *tx, const void *tag) -{ - /* - * Don't set dirtyctx to SYNC if we're just modifying this as we - * initialize the objset. - */ - if (dn->dn_dirtyctx == DN_UNDIRTIED) { - dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset; - - if (ds != NULL) { - rrw_enter(&ds->ds_bp_rwlock, RW_READER, tag); - } - if (!BP_IS_HOLE(dn->dn_objset->os_rootbp)) { - if (dmu_tx_is_syncing(tx)) - dn->dn_dirtyctx = DN_DIRTY_SYNC; - else - dn->dn_dirtyctx = DN_DIRTY_OPEN; - dn->dn_dirtyctx_firstset = tag; - } - if (ds != NULL) { - rrw_exit(&ds->ds_bp_rwlock, tag); - } - } -} - static void dnode_partial_zero(dnode_t *dn, uint64_t off, uint64_t blkoff, uint64_t len, dmu_tx_t *tx) diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c index 16bfce5338a7..6cf39e035ea6 100644 --- a/sys/dev/bce/if_bce.c +++ b/sys/dev/bce/if_bce.c @@ -1221,7 +1221,7 @@ bce_attach(device_t dev) sc->bce_bc_ver[j++] = '.'; } - /* Check if any management firwmare is enabled. */ + /* Check if any management firmware is enabled. */ val = bce_shmem_rd(sc, BCE_PORT_FEATURE); if (val & BCE_PORT_FEATURE_ASF_ENABLED) { sc->bce_flags |= BCE_MFW_ENABLE_FLAG; diff --git a/sys/dev/hpt27xx/hptintf.h b/sys/dev/hpt27xx/hptintf.h index 558b479ec2ee..eb8105ec5666 100644 --- a/sys/dev/hpt27xx/hptintf.h +++ b/sys/dev/hpt27xx/hptintf.h @@ -155,8 +155,8 @@ typedef HPT_U32 DEVICEID; #define ARRAY_FLAG_NEED_AUTOREBUILD 0x00000080 /* auto-rebuild should start */ #define ARRAY_FLAG_VERIFYING 0x00000100 /* is being verified */ #define ARRAY_FLAG_INITIALIZING 0x00000200 /* is being initialized */ -#define ARRAY_FLAG_TRANSFORMING 0x00000400 /* tranform in progress */ -#define ARRAY_FLAG_NEEDTRANSFORM 0x00000800 /* array need tranform */ +#define ARRAY_FLAG_TRANSFORMING 0x00000400 /* transform in progress */ +#define ARRAY_FLAG_NEEDTRANSFORM 0x00000800 /* array need transform */ #define ARRAY_FLAG_NEEDINITIALIZING 0x00001000 /* the array's initialization hasn't finished*/ #define ARRAY_FLAG_BROKEN_REDUNDANT 0x00002000 /* broken but redundant (raid6) */ #define ARRAY_FLAG_RAID15PLUS 0x80000000 /* display this RAID 1 as RAID 1.5 */ @@ -2018,7 +2018,7 @@ DEVICEID hpt_create_transform_v2(DEVICEID idArray, PCREATE_ARRAY_PARAMS_V3 destI #endif /* hpt_step_transform - * move a block in a tranform progress. + * move a block in a transform progress. * This function is called by mid-layer, not GUI (which uses set_array_state instead). * Version compatibility: v2.0.0.0 or later * Parameters: diff --git a/sys/dev/ice/ice_fw_logging.c b/sys/dev/ice/ice_fw_logging.c index 0025a65d73fc..16a9ab6823bf 100644 --- a/sys/dev/ice/ice_fw_logging.c +++ b/sys/dev/ice/ice_fw_logging.c @@ -48,7 +48,7 @@ SDT_PROVIDER_DEFINE(ice_fwlog); /* * SDT DTrace probe fired when a firmware log message is received over the - * AdminQ. It passes the buffer of the firwmare log message along with its + * AdminQ. It passes the buffer of the firmware log message along with its * length in bytes to the DTrace framework. */ SDT_PROBE_DEFINE2(ice_fwlog, , , message, "uint8_t *", "int"); diff --git a/sys/dev/iwx/if_iwx.c b/sys/dev/iwx/if_iwx.c index d60ef1874a6c..1fe531d69933 100644 --- a/sys/dev/iwx/if_iwx.c +++ b/sys/dev/iwx/if_iwx.c @@ -5673,6 +5673,10 @@ iwx_tx(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni) if (rinfo == NULL) return EINVAL; + /* Offloaded sequence number assignment */ + /* Note: Should be done in firmware on all supported devices */ + + /* Radiotap */ if (ieee80211_radiotap_active_vap(vap)) { struct iwx_tx_radiotap_header *tap = &sc->sc_txtap; @@ -5685,6 +5689,7 @@ iwx_tx(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni) ieee80211_radiotap_tx(vap, m); } + /* Encrypt - CCMP via direct HW path, TKIP/WEP indirected openbsd-style for now */ if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { k = ieee80211_crypto_get_txkey(ni, m); if (k == NULL) { @@ -10467,6 +10472,8 @@ iwx_attach(device_t dev) IEEE80211_C_BGSCAN /* capable of bg scanning */ ; ic->ic_flags_ext = IEEE80211_FEXT_SCAN_OFFLOAD; + /* Enable seqno offload */ + ic->ic_flags_ext |= IEEE80211_FEXT_SEQNO_OFFLOAD; ic->ic_txstream = 2; ic->ic_rxstream = 2; diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c index 2570cbce525b..0e2eb0b2d8fe 100644 --- a/sys/dev/mwl/if_mwl.c +++ b/sys/dev/mwl/if_mwl.c @@ -1797,7 +1797,7 @@ mwl_updateslot(struct ieee80211com *ic) return; /* - * Calculate the ERP flags. The firwmare will use + * Calculate the ERP flags. The firmware will use * this to carry out the appropriate measures. */ prot = 0; diff --git a/sys/dev/nvmf/nvmf_tcp.c b/sys/dev/nvmf/nvmf_tcp.c index 6ad5229f6043..e50d7ff48d2b 100644 --- a/sys/dev/nvmf/nvmf_tcp.c +++ b/sys/dev/nvmf/nvmf_tcp.c @@ -970,7 +970,7 @@ nvmf_tcp_handle_r2t(struct nvmf_tcp_qpair *qp, struct nvmf_tcp_rxpdu *pdu) } /* - * XXX: The spec does not specify how to handle R2T tranfers + * XXX: The spec does not specify how to handle R2T transfers * out of range of the original command. */ data_len = le32toh(r2t->r2tl); diff --git a/sys/dev/usb/net/if_umb.c b/sys/dev/usb/net/if_umb.c index 5703bc03dd39..f640b4224aad 100644 --- a/sys/dev/usb/net/if_umb.c +++ b/sys/dev/usb/net/if_umb.c @@ -666,7 +666,7 @@ umb_ncm_setup(struct umb_softc *sc, struct usb_config * config) struct ncm_ntb_parameters np; usb_error_t error; - /* Query NTB tranfers sizes */ + /* Query NTB transfers sizes */ req.bmRequestType = UT_READ_CLASS_INTERFACE; req.bRequest = NCM_GET_NTB_PARAMETERS; USETW(req.wValue, 0); diff --git a/sys/fs/msdosfs/bootsect.h b/sys/fs/msdosfs/bootsect.h index 170d94cb9512..94b1137a153e 100644 --- a/sys/fs/msdosfs/bootsect.h +++ b/sys/fs/msdosfs/bootsect.h @@ -20,7 +20,7 @@ /* * Format of a boot sector. This is the first sector on a DOS floppy disk - * or the fist sector of a partition on a hard disk. But, it is not the + * or the first sector of a partition on a hard disk. But, it is not the * first sector of a partitioned hard disk. */ struct bootsector33 { diff --git a/sys/modules/zfs/zfs_config.h b/sys/modules/zfs/zfs_config.h index 12274bcceea1..72167b752e53 100644 --- a/sys/modules/zfs/zfs_config.h +++ b/sys/modules/zfs/zfs_config.h @@ -840,7 +840,7 @@ /* #undef ZFS_DEVICE_MINOR */ /* Define the project alias string. */ -#define ZFS_META_ALIAS "zfs-2.3.99-571-FreeBSD_ga9410ccbd" +#define ZFS_META_ALIAS "zfs-2.4.0-rc1-FreeBSD_g00dfa094a" /* Define the project author. */ #define ZFS_META_AUTHOR "OpenZFS" @@ -870,10 +870,10 @@ #define ZFS_META_NAME "zfs" /* Define the project release. */ -#define ZFS_META_RELEASE "571-FreeBSD_ga9410ccbd" +#define ZFS_META_RELEASE "zfs-2.4.0-rc1-FreeBSD_g00dfa094a" /* Define the project version. */ -#define ZFS_META_VERSION "2.3.99" +#define ZFS_META_VERSION "2.4.0" /* count is located in percpu_ref.data */ /* #undef ZFS_PERCPU_REF_COUNT_IN_DATA */ diff --git a/sys/modules/zfs/zfs_gitrev.h b/sys/modules/zfs/zfs_gitrev.h index 5c265cf5b08e..2b5d717da216 100644 --- a/sys/modules/zfs/zfs_gitrev.h +++ b/sys/modules/zfs/zfs_gitrev.h @@ -1 +1 @@ -#define ZFS_META_GITREV "zfs-2.3.99-571-ga9410ccbd" +#define ZFS_META_GITREV "zfs-2.4.0-rc1-0-g00dfa094a" diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h index 141b13f9f740..3684fba52c5c 100644 --- a/sys/net80211/ieee80211_freebsd.h +++ b/sys/net80211/ieee80211_freebsd.h @@ -93,12 +93,22 @@ typedef struct { } while (0) #define IEEE80211_TX_LOCK_OBJ(_ic) (&(_ic)->ic_txlock.mtx) #define IEEE80211_TX_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_TX_LOCK_OBJ(_ic)) -#define IEEE80211_TX_LOCK(_ic) mtx_lock(IEEE80211_TX_LOCK_OBJ(_ic)) -#define IEEE80211_TX_UNLOCK(_ic) mtx_unlock(IEEE80211_TX_LOCK_OBJ(_ic)) -#define IEEE80211_TX_LOCK_ASSERT(_ic) \ - mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_OWNED) -#define IEEE80211_TX_UNLOCK_ASSERT(_ic) \ - mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_NOTOWNED) +#define IEEE80211_TX_LOCK(_ic) do { \ + if (!IEEE80211_CONF_SEQNO_OFFLOAD(_ic)) \ + mtx_lock(IEEE80211_TX_LOCK_OBJ(_ic)); \ + } while (0); +#define IEEE80211_TX_UNLOCK(_ic) do { \ + if (!IEEE80211_CONF_SEQNO_OFFLOAD(_ic)) \ + mtx_unlock(IEEE80211_TX_LOCK_OBJ(_ic)); \ + } while (0); +#define IEEE80211_TX_LOCK_ASSERT(_ic) do { \ + if (!IEEE80211_CONF_SEQNO_OFFLOAD(_ic)) \ + mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_OWNED); \ + } while (0) +#define IEEE80211_TX_UNLOCK_ASSERT(_ic) { \ + if (!IEEE80211_CONF_SEQNO_OFFLOAD(_ic)) \ + mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_NOTOWNED); \ + } while (0) /* * Stageq / ni_tx_superg lock diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index afe83ea0805c..57fe687adffe 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -974,7 +974,7 @@ ieee80211_send_setup( /* NB: zero out i_seq field (for s/w encryption etc) */ *(uint16_t *)&wh->i_seq[0] = 0; - } else + } else if (!IEEE80211_CONF_SEQNO_OFFLOAD(ni->ni_ic)) ieee80211_output_seqno_assign(ni, tid, m); if (IEEE80211_IS_MULTICAST(wh->i_addr1)) @@ -1810,7 +1810,8 @@ ieee80211_encap(struct ieee80211vap *vap, struct ieee80211_node *ni, * and we don't need the TX lock held. */ if ((m->m_flags & M_AMPDU_MPDU) == 0) { - ieee80211_output_seqno_assign(ni, tid, m); + if (!IEEE80211_CONF_SEQNO_OFFLOAD(ic)) + ieee80211_output_seqno_assign(ni, tid, m); } else { /* * NB: don't assign a sequence # to potential @@ -1828,7 +1829,9 @@ ieee80211_encap(struct ieee80211vap *vap, struct ieee80211_node *ni, *(uint16_t *)wh->i_seq = 0; } } else { - ieee80211_output_seqno_assign(ni, IEEE80211_NONQOS_TID, m); + if (!IEEE80211_CONF_SEQNO_OFFLOAD(ic)) + ieee80211_output_seqno_assign(ni, IEEE80211_NONQOS_TID, + m); /* * XXX TODO: we shouldn't allow EAPOL, etc that would * be forced to be non-QoS traffic to be A-MSDU encapsulated. @@ -3856,6 +3859,8 @@ ieee80211_beacon_update(struct ieee80211_node *ni, struct mbuf *m, int mcast) * If the driver identifies it does its own TX seqno management then * we can skip this (and still not do the TX seqno.) */ + + /* TODO: IEEE80211_CONF_SEQNO_OFFLOAD() */ ieee80211_output_beacon_seqno_assign(ni, m); /* XXX faster to recalculate entirely or just changes? */ diff --git a/sys/netinet/cc/cc.c b/sys/netinet/cc/cc.c index d85ad4e9f4fd..c20a20cd983d 100644 --- a/sys/netinet/cc/cc.c +++ b/sys/netinet/cc/cc.c @@ -659,7 +659,7 @@ cc_modevent(module_t mod, int event_type, void *data) case MOD_SHUTDOWN: break; case MOD_QUIESCE: - /* Stop any new assigments */ + /* Stop any new assignments */ err = cc_stop_new_assignments(algo); break; case MOD_UNLOAD: diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 6492495dc583..d5dc516c28aa 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -2562,299 +2562,270 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, hhook_run_tcp_est_in(tp, th, &to); #endif - if (SEQ_LEQ(th->th_ack, tp->snd_una)) { - maxseg = tcp_maxseg(tp); - if (no_data && - (tiwin == tp->snd_wnd || - (tp->t_flags & TF_SACK_PERMIT))) { + if (SEQ_LT(th->th_ack, tp->snd_una)) { + /* This is old ACK information, don't process it. */ + break; + } + if (th->th_ack == tp->snd_una) { + /* Check if this is a duplicate ACK. */ + if ((tp->t_flags & TF_SACK_PERMIT) && + V_tcp_do_newsack) { /* - * If this is the first time we've seen a - * FIN from the remote, this is not a - * duplicate and it needs to be processed - * normally. This happens during a - * simultaneous close. + * If SEG.ACK == SND.UNA, RFC 6675 requires a + * duplicate ACK to selectively acknowledge + * at least one byte, which was not selectively + * acknowledged before. */ - if ((thflags & TH_FIN) && - (TCPS_HAVERCVDFIN(tp->t_state) == 0)) { - tp->t_dupacks = 0; + if (sack_changed == SACK_NOCHANGE) { break; } - TCPSTAT_INC(tcps_rcvdupack); - /* - * If we have outstanding data (other than - * a window probe), this is a completely - * duplicate ack (ie, window info didn't - * change and FIN isn't set), - * the ack is the biggest we've - * seen and we've seen exactly our rexmt - * threshold of them, assume a packet - * has been dropped and retransmit it. - * Kludge snd_nxt & the congestion - * window so we send only this one - * packet. - * - * We know we're losing at the current - * window size so do congestion avoidance - * (set ssthresh to half the current window - * and pull our congestion window back to - * the new ssthresh). - * - * Dup acks mean that packets have left the - * network (they're now cached at the receiver) - * so bump cwnd by the amount in the receiver - * to keep a constant cwnd packets in the - * network. - * - * When using TCP ECN, notify the peer that - * we reduced the cwnd. - */ + } else { /* - * Following 2 kinds of acks should not affect - * dupack counting: - * 1) Old acks - * 2) Acks with SACK but without any new SACK - * information in them. These could result from - * any anomaly in the network like a switch - * duplicating packets or a possible DoS attack. + * If SEG.ACK == SND.UNA, RFC 5681 requires a + * duplicate ACK to have no data on it and to + * not be a window update. */ - if (th->th_ack != tp->snd_una || - (tcp_is_sack_recovery(tp, &to) && - (sack_changed == SACK_NOCHANGE))) { + if (!no_data || tiwin != tp->snd_wnd) { break; - } else if (!tcp_timer_active(tp, TT_REXMT)) { - tp->t_dupacks = 0; - } else if (++tp->t_dupacks > tcprexmtthresh || - IN_FASTRECOVERY(tp->t_flags)) { - cc_ack_received(tp, th, nsegs, - CC_DUPACK); - if (V_tcp_do_prr && + } + } + /* + * If this is the first time we've seen a + * FIN from the remote, this is not a + * duplicate ACK and it needs to be processed + * normally. + * This happens during a simultaneous close. + */ + if ((thflags & TH_FIN) && + (TCPS_HAVERCVDFIN(tp->t_state) == 0)) { + tp->t_dupacks = 0; + break; + } + /* Perform duplicate ACK processing. */ + TCPSTAT_INC(tcps_rcvdupack); + maxseg = tcp_maxseg(tp); + if (!tcp_timer_active(tp, TT_REXMT)) { + tp->t_dupacks = 0; + } else if (++tp->t_dupacks > tcprexmtthresh || + IN_FASTRECOVERY(tp->t_flags)) { + cc_ack_received(tp, th, nsegs, CC_DUPACK); + if (V_tcp_do_prr && + IN_FASTRECOVERY(tp->t_flags) && + (tp->t_flags & TF_SACK_PERMIT)) { + tcp_do_prr_ack(tp, th, &to, + sack_changed, &maxseg); + } else if (tcp_is_sack_recovery(tp, &to) && IN_FASTRECOVERY(tp->t_flags) && - (tp->t_flags & TF_SACK_PERMIT)) { - tcp_do_prr_ack(tp, th, &to, - sack_changed, &maxseg); - } else if (tcp_is_sack_recovery(tp, &to) && - IN_FASTRECOVERY(tp->t_flags) && - (tp->snd_nxt == tp->snd_max)) { - int awnd; + (tp->snd_nxt == tp->snd_max)) { + int awnd; - /* - * Compute the amount of data in flight first. - * We can inject new data into the pipe iff - * we have less than ssthresh - * worth of data in flight. - */ - awnd = tcp_compute_pipe(tp); - if (awnd < tp->snd_ssthresh) { - tp->snd_cwnd += imax(maxseg, - imin(2 * maxseg, - tp->sackhint.delivered_data)); - if (tp->snd_cwnd > tp->snd_ssthresh) - tp->snd_cwnd = tp->snd_ssthresh; - } - } else if (tcp_is_sack_recovery(tp, &to) && - IN_FASTRECOVERY(tp->t_flags) && - SEQ_LT(tp->snd_nxt, tp->snd_max)) { + /* + * Compute the amount of data in flight first. + * We can inject new data into the pipe iff + * we have less than ssthresh + * worth of data in flight. + */ + awnd = tcp_compute_pipe(tp); + if (awnd < tp->snd_ssthresh) { tp->snd_cwnd += imax(maxseg, imin(2 * maxseg, tp->sackhint.delivered_data)); - } else { - tp->snd_cwnd += maxseg; + if (tp->snd_cwnd > tp->snd_ssthresh) + tp->snd_cwnd = tp->snd_ssthresh; } - (void) tcp_output(tp); - goto drop; - } else if (tp->t_dupacks == tcprexmtthresh || - (tp->t_flags & TF_SACK_PERMIT && - V_tcp_do_newsack && - tp->sackhint.sacked_bytes > - (tcprexmtthresh - 1) * maxseg)) { + } else if (tcp_is_sack_recovery(tp, &to) && + IN_FASTRECOVERY(tp->t_flags) && + SEQ_LT(tp->snd_nxt, tp->snd_max)) { + tp->snd_cwnd += imax(maxseg, + imin(2 * maxseg, + tp->sackhint.delivered_data)); + } else { + tp->snd_cwnd += maxseg; + } + (void) tcp_output(tp); + goto drop; + } else if (tp->t_dupacks == tcprexmtthresh || + (tp->t_flags & TF_SACK_PERMIT && + V_tcp_do_newsack && + tp->sackhint.sacked_bytes > + (tcprexmtthresh - 1) * maxseg)) { enter_recovery: - /* - * Above is the RFC6675 trigger condition of - * more than (dupthresh-1)*maxseg sacked data. - * If the count of holes in the - * scoreboard is >= dupthresh, we could - * also enter loss recovery, but don't - * have that value readily available. - */ - tp->t_dupacks = tcprexmtthresh; - tcp_seq onxt = tp->snd_nxt; + /* + * Above is the RFC6675 trigger condition of + * more than (dupthresh-1)*maxseg sacked data. + * If the count of holes in the + * scoreboard is >= dupthresh, we could + * also enter loss recovery, but don't + * have that value readily available. + */ + tp->t_dupacks = tcprexmtthresh; + tcp_seq onxt = tp->snd_nxt; - /* - * If we're doing sack, check to - * see if we're already in sack - * recovery. If we're not doing sack, - * check to see if we're in newreno - * recovery. - */ - if (tcp_is_sack_recovery(tp, &to)) { - if (IN_FASTRECOVERY(tp->t_flags)) { - tp->t_dupacks = 0; - break; - } - } else { - if (SEQ_LEQ(th->th_ack, - tp->snd_recover)) { - tp->t_dupacks = 0; - break; - } + /* + * If we're doing sack, check to + * see if we're already in sack + * recovery. If we're not doing sack, + * check to see if we're in newreno + * recovery. + */ + if (tcp_is_sack_recovery(tp, &to)) { + if (IN_FASTRECOVERY(tp->t_flags)) { + tp->t_dupacks = 0; + break; } - /* Congestion signal before ack. */ - cc_cong_signal(tp, th, CC_NDUPACK); - cc_ack_received(tp, th, nsegs, - CC_DUPACK); - tcp_timer_activate(tp, TT_REXMT, 0); - tp->t_rtttime = 0; - if (V_tcp_do_prr) { - /* - * snd_ssthresh and snd_recover are - * already updated by cc_cong_signal. - */ - if (tcp_is_sack_recovery(tp, &to)) { - /* - * Include Limited Transmit - * segments here - */ - tp->sackhint.prr_delivered = - imin(tp->snd_max - th->th_ack, - (tp->snd_limited + 1) * maxseg); - } else { - tp->sackhint.prr_delivered = - maxseg; - } - tp->sackhint.recover_fs = max(1, - tp->snd_nxt - tp->snd_una); + } else { + if (SEQ_LEQ(th->th_ack, + tp->snd_recover)) { + tp->t_dupacks = 0; + break; } - tp->snd_limited = 0; + } + /* Congestion signal before ack. */ + cc_cong_signal(tp, th, CC_NDUPACK); + cc_ack_received(tp, th, nsegs, CC_DUPACK); + tcp_timer_activate(tp, TT_REXMT, 0); + tp->t_rtttime = 0; + if (V_tcp_do_prr) { + /* + * snd_ssthresh and snd_recover are + * already updated by cc_cong_signal. + */ if (tcp_is_sack_recovery(tp, &to)) { - TCPSTAT_INC(tcps_sack_recovery_episode); /* - * When entering LR after RTO due to - * Duplicate ACKs, retransmit existing - * holes from the scoreboard. + * Include Limited Transmit + * segments here */ - tcp_resend_sackholes(tp); - /* Avoid inflating cwnd in tcp_output */ - tp->snd_nxt = tp->snd_max; - tp->snd_cwnd = tcp_compute_pipe(tp) + + tp->sackhint.prr_delivered = + imin(tp->snd_max - th->th_ack, + (tp->snd_limited + 1) * maxseg); + } else { + tp->sackhint.prr_delivered = maxseg; - (void) tcp_output(tp); - /* Set cwnd to the expected flightsize */ - tp->snd_cwnd = tp->snd_ssthresh; - if (SEQ_GT(th->th_ack, tp->snd_una)) { - goto resume_partialack; - } - goto drop; } - tp->snd_nxt = th->th_ack; - tp->snd_cwnd = maxseg; - (void) tcp_output(tp); - KASSERT(tp->snd_limited <= 2, - ("%s: tp->snd_limited too big", - __func__)); - tp->snd_cwnd = tp->snd_ssthresh + - maxseg * - (tp->t_dupacks - tp->snd_limited); - if (SEQ_GT(onxt, tp->snd_nxt)) - tp->snd_nxt = onxt; - goto drop; - } else if (V_tcp_do_rfc3042) { - /* - * Process first and second duplicate - * ACKs. Each indicates a segment - * leaving the network, creating room - * for more. Make sure we can send a - * packet on reception of each duplicate - * ACK by increasing snd_cwnd by one - * segment. Restore the original - * snd_cwnd after packet transmission. - */ - cc_ack_received(tp, th, nsegs, CC_DUPACK); - uint32_t oldcwnd = tp->snd_cwnd; - tcp_seq oldsndmax = tp->snd_max; - u_int sent; - int avail; - - KASSERT(tp->t_dupacks == 1 || - tp->t_dupacks == 2, - ("%s: dupacks not 1 or 2", - __func__)); - if (tp->t_dupacks == 1) - tp->snd_limited = 0; - if ((tp->snd_nxt == tp->snd_max) && - (tp->t_rxtshift == 0)) - tp->snd_cwnd = - SEQ_SUB(tp->snd_nxt, - tp->snd_una) - - tcp_sack_adjust(tp); - tp->snd_cwnd += - (tp->t_dupacks - tp->snd_limited) * - maxseg - tcp_sack_adjust(tp); + tp->sackhint.recover_fs = max(1, + tp->snd_nxt - tp->snd_una); + } + tp->snd_limited = 0; + if (tcp_is_sack_recovery(tp, &to)) { + TCPSTAT_INC(tcps_sack_recovery_episode); /* - * Only call tcp_output when there - * is new data available to be sent - * or we need to send an ACK. + * When entering LR after RTO due to + * Duplicate ACKs, retransmit existing + * holes from the scoreboard. */ - SOCK_SENDBUF_LOCK(so); - avail = sbavail(&so->so_snd); - SOCK_SENDBUF_UNLOCK(so); - if (tp->t_flags & TF_ACKNOW || - (avail >= - SEQ_SUB(tp->snd_nxt, tp->snd_una))) { - (void) tcp_output(tp); - } - sent = SEQ_SUB(tp->snd_max, oldsndmax); - if (sent > maxseg) { - KASSERT((tp->t_dupacks == 2 && - tp->snd_limited == 0) || - (sent == maxseg + 1 && - tp->t_flags & TF_SENTFIN) || - (sent < 2 * maxseg && - tp->t_flags & TF_NODELAY), - ("%s: sent too much: %u>%u", - __func__, sent, maxseg)); - tp->snd_limited = 2; - } else if (sent > 0) { - ++tp->snd_limited; - } - tp->snd_cwnd = oldcwnd; + tcp_resend_sackholes(tp); + /* Avoid inflating cwnd in tcp_output */ + tp->snd_nxt = tp->snd_max; + tp->snd_cwnd = tcp_compute_pipe(tp) + + maxseg; + (void) tcp_output(tp); + /* Set cwnd to the expected flightsize */ + tp->snd_cwnd = tp->snd_ssthresh; goto drop; } - } - break; - } else { - /* - * This ack is advancing the left edge, reset the - * counter. - */ - tp->t_dupacks = 0; - /* - * If this ack also has new SACK info, increment the - * counter as per rfc6675. The variable - * sack_changed tracks all changes to the SACK - * scoreboard, including when partial ACKs without - * SACK options are received, and clear the scoreboard - * from the left side. Such partial ACKs should not be - * counted as dupacks here. - */ - if (tcp_is_sack_recovery(tp, &to) && - (((tp->t_rxtshift == 0) && (sack_changed != SACK_NOCHANGE)) || - ((tp->t_rxtshift > 0) && (sack_changed == SACK_NEWLOSS))) && - (tp->snd_nxt == tp->snd_max)) { - tp->t_dupacks++; - /* limit overhead by setting maxseg last */ - if (!IN_FASTRECOVERY(tp->t_flags) && - (tp->sackhint.sacked_bytes > - ((tcprexmtthresh - 1) * - (maxseg = tcp_maxseg(tp))))) { - goto enter_recovery; + tp->snd_nxt = th->th_ack; + tp->snd_cwnd = maxseg; + (void) tcp_output(tp); + KASSERT(tp->snd_limited <= 2, + ("%s: tp->snd_limited too big", + __func__)); + tp->snd_cwnd = tp->snd_ssthresh + + maxseg * + (tp->t_dupacks - tp->snd_limited); + if (SEQ_GT(onxt, tp->snd_nxt)) + tp->snd_nxt = onxt; + goto drop; + } else if (V_tcp_do_rfc3042) { + /* + * Process first and second duplicate + * ACKs. Each indicates a segment + * leaving the network, creating room + * for more. Make sure we can send a + * packet on reception of each duplicate + * ACK by increasing snd_cwnd by one + * segment. Restore the original + * snd_cwnd after packet transmission. + */ + cc_ack_received(tp, th, nsegs, CC_DUPACK); + uint32_t oldcwnd = tp->snd_cwnd; + tcp_seq oldsndmax = tp->snd_max; + u_int sent; + int avail; + + KASSERT(tp->t_dupacks == 1 || + tp->t_dupacks == 2, + ("%s: dupacks not 1 or 2", + __func__)); + if (tp->t_dupacks == 1) + tp->snd_limited = 0; + if ((tp->snd_nxt == tp->snd_max) && + (tp->t_rxtshift == 0)) + tp->snd_cwnd = + SEQ_SUB(tp->snd_nxt, tp->snd_una); + tp->snd_cwnd += + (tp->t_dupacks - tp->snd_limited) * maxseg; + tp->snd_cwnd -= tcp_sack_adjust(tp); + /* + * Only call tcp_output when there + * is new data available to be sent + * or we need to send an ACK. + */ + SOCK_SENDBUF_LOCK(so); + avail = sbavail(&so->so_snd); + SOCK_SENDBUF_UNLOCK(so); + if (tp->t_flags & TF_ACKNOW || + (avail >= + SEQ_SUB(tp->snd_nxt, tp->snd_una))) { + (void) tcp_output(tp); + } + sent = SEQ_SUB(tp->snd_max, oldsndmax); + if (sent > maxseg) { + KASSERT((tp->t_dupacks == 2 && + tp->snd_limited == 0) || + (sent == maxseg + 1 && + tp->t_flags & TF_SENTFIN) || + (sent < 2 * maxseg && + tp->t_flags & TF_NODELAY), + ("%s: sent too much: %u>%u", + __func__, sent, maxseg)); + tp->snd_limited = 2; + } else if (sent > 0) { + ++tp->snd_limited; } + tp->snd_cwnd = oldcwnd; + goto drop; } + break; } - -resume_partialack: KASSERT(SEQ_GT(th->th_ack, tp->snd_una), - ("%s: th_ack <= snd_una", __func__)); - + ("%s: SEQ_LEQ(th_ack, snd_una)", __func__)); + /* + * This ack is advancing the left edge, reset the + * counter. + */ + tp->t_dupacks = 0; + /* + * If this ack also has new SACK info, increment the + * t_dupacks as per RFC 6675. The variable + * sack_changed tracks all changes to the SACK + * scoreboard, including when partial ACKs without + * SACK options are received, and clear the scoreboard + * from the left side. Such partial ACKs should not be + * counted as dupacks here. + */ + if (V_tcp_do_newsack && + tcp_is_sack_recovery(tp, &to) && + (((tp->t_rxtshift == 0) && (sack_changed != SACK_NOCHANGE)) || + ((tp->t_rxtshift > 0) && (sack_changed == SACK_NEWLOSS))) && + (tp->snd_nxt == tp->snd_max)) { + tp->t_dupacks++; + /* limit overhead by setting maxseg last */ + if (!IN_FASTRECOVERY(tp->t_flags) && + (tp->sackhint.sacked_bytes > + (tcprexmtthresh - 1) * (maxseg = tcp_maxseg(tp)))) { + goto enter_recovery; + } + } /* * If the congestion window was inflated to account * for the other side's cached packets, retract it. diff --git a/sys/ufs/ffs/ffs_rawread.c b/sys/ufs/ffs/ffs_rawread.c index 9db0bee0d66d..ef0b2ff4f788 100644 --- a/sys/ufs/ffs/ffs_rawread.c +++ b/sys/ufs/ffs/ffs_rawread.c @@ -281,7 +281,7 @@ ffs_rawread_main(struct vnode *vp, if (error != 0) break; - if (resid > bp->b_bufsize) { /* Setup fist readahead */ + if (resid > bp->b_bufsize) { /* Setup first readahead */ if (rawreadahead != 0) nbp = uma_zalloc(ffsraw_pbuf_zone, M_NOWAIT); diff --git a/tests/sys/netpfil/pf/mbuf.sh b/tests/sys/netpfil/pf/mbuf.sh index e3f138bb73b9..3abae65203cd 100644 --- a/tests/sys/netpfil/pf/mbuf.sh +++ b/tests/sys/netpfil/pf/mbuf.sh @@ -69,22 +69,22 @@ inet_in_mbuf_len_body() # Should still work for m_len=0 jexec alcatraz pfilctl link -i dummymbuf:inet inet jexec alcatraz sysctl net.dummymbuf.rules="inet in ${epair}b pull-head 0;" - atf_check_equal "0" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '0' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=1 jexec alcatraz sysctl net.dummymbuf.rules="inet in ${epair}b pull-head 1;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=19 # provided IPv4 basic header is 20 bytes long, it should impact the dst addr jexec alcatraz sysctl net.dummymbuf.rules="inet in ${epair}b pull-head 19;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' } inet_in_mbuf_len_cleanup() { @@ -140,22 +140,22 @@ inet6_in_mbuf_len_body() # Should still work for m_len=0 jexec alcatraz pfilctl link -i dummymbuf:inet6 inet6 jexec alcatraz sysctl net.dummymbuf.rules="inet6 in ${epair}b pull-head 0;" - atf_check_equal "0" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '0' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' atf_check -s exit:0 -o ignore ping -c1 2001:db8::2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=1 jexec alcatraz sysctl net.dummymbuf.rules="inet6 in ${epair}b pull-head 1;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 2001:db8::2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=39 # provided IPv6 basic header is 40 bytes long, it should impact the dst addr jexec alcatraz sysctl net.dummymbuf.rules="inet6 in ${epair}b pull-head 39;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 2001:db8::2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' } inet6_in_mbuf_len_cleanup() { @@ -205,29 +205,29 @@ ethernet_in_mbuf_len_body() # Should still work for m_len=0 jexec alcatraz pfilctl link -i dummymbuf:ethernet ethernet jexec alcatraz sysctl net.dummymbuf.rules="ethernet in ${epair}b pull-head 0;" - atf_check_equal "0" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '0' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=1 jexec alcatraz sysctl net.dummymbuf.rules="ethernet in ${epair}b pull-head 1;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=11 # for the simplest L2 Ethernet frame it should impact src field jexec alcatraz sysctl net.dummymbuf.rules="ethernet in ${epair}b pull-head 11;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' # m_len=13 # provided L2 Ethernet simplest header is 14 bytes long, it should impact ethertype field jexec alcatraz sysctl net.dummymbuf.rules="ethernet in ${epair}b pull-head 13;" jexec alcatraz sysctl net.dummymbuf.hits=0 atf_check -s exit:0 -o ignore ping -c1 192.0.2.2 - atf_check_equal "1" "$(jexec alcatraz sysctl -n net.dummymbuf.hits)" + atf_check_equal '1' '$(jexec alcatraz sysctl -n net.dummymbuf.hits)' } ethernet_in_mbuf_len_cleanup() { |