diff --git a/lib/libc/gen/login_cap.3 b/lib/libc/gen/login_cap.3 index f3a43c4c6..2004907db 100644 --- a/lib/libc/gen/login_cap.3 +++ b/lib/libc/gen/login_cap.3 @@ -29,10 +29,10 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: login_cap.3,v 1.23 2022/09/11 06:38:10 jmc Exp $ +.\" $OpenBSD: login_cap.3,v 1.24 2024/03/18 08:50:54 op Exp $ .\" BSDI $From: login_cap.3,v 1.4 1997/11/07 16:22:27 jch Exp $ .\" -.Dd $Mdocdate: September 11 2022 $ +.Dd $Mdocdate: March 18 2024 $ .Dt LOGIN_GETCLASS 3 .Os .Sh NAME @@ -245,7 +245,7 @@ Sets the environment variable to the value of the .Li path keyword if specified, or to the value of -.Li _PATH_DEFPATH +.Dv _PATH_DEFPATH in .In paths.h if not. diff --git a/sys/arch/arm64/arm64/cpu.c b/sys/arch/arm64/arm64/cpu.c index a14e1f229..f1edd5bca 100644 --- a/sys/arch/arm64/arm64/cpu.c +++ b/sys/arch/arm64/arm64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.111 2024/03/17 13:05:40 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.113 2024/03/18 21:57:22 kettenis Exp $ */ /* * Copyright (c) 2016 Dale Rahn @@ -278,6 +278,43 @@ void cpu_kstat_attach(struct cpu_info *ci); void cpu_opp_kstat_attach(struct cpu_info *ci); #endif +/* + * Enable mitigation for Spectre-V4 speculative store bypass + * vulnerabilities (CVE-2018-3639). + */ +void +cpu_mitigate_spectre_v4(struct cpu_info *ci) +{ + uint64_t id; + + switch (CPU_IMPL(ci->ci_midr)) { + case CPU_IMPL_ARM: + switch (CPU_PART(ci->ci_midr)) { + case CPU_PART_CORTEX_A35: + case CPU_PART_CORTEX_A53: + case CPU_PART_CORTEX_A55: + /* Not vulnerable. */ + return; + } + break; + case CPU_IMPL_QCOM: + switch (CPU_PART(ci->ci_midr)) { + case CPU_PART_KRYO400_SILVER: + /* Not vulnerable. */ + return; + } + break; + } + + /* SSBS tells us Spectre-V4 is mitigated. */ + id = READ_SPECIALREG(id_aa64pfr1_el1); + if (ID_AA64PFR1_SSBS(id) >= ID_AA64PFR1_SSBS_PSTATE) + return; + + /* Enable firmware workaround if required. */ + smccc_enable_arch_workaround_2(); +} + void cpu_identify(struct cpu_info *ci) { @@ -289,13 +326,14 @@ cpu_identify(struct cpu_info *ci) static uint64_t prev_id_aa64pfr0; static uint64_t prev_id_aa64pfr1; uint64_t midr, impl, part; - uint64_t clidr, id; - uint32_t ctr, ccsidr, sets, ways, line; + uint64_t clidr, ccsidr, id; + uint32_t ctr, sets, ways, line; const char *impl_name = NULL; const char *part_name = NULL; const char *il1p_name = NULL; const char *sep; struct cpu_cores *coreselecter = cpu_cores_none; + int ccidx; int i; midr = READ_SPECIALREG(midr_el1); @@ -348,7 +386,18 @@ cpu_identify(struct cpu_info *ci) break; } + id = READ_SPECIALREG(id_aa64mmfr2_el1); clidr = READ_SPECIALREG(clidr_el1); + if (ID_AA64MMFR2_CCIDX(id) > ID_AA64MMFR2_CCIDX_IMPL) { + /* Reserved value. Don't print cache information. */ + clidr = 0; + } else if (ID_AA64MMFR2_CCIDX(id) == ID_AA64MMFR2_CCIDX_IMPL) { + /* CCSIDR_EL1 uses the new 64-bit format. */ + ccidx = 1; + } else { + /* CCSIDR_EL1 uses the old 32-bit format. */ + ccidx = 0; + } for (i = 0; i < 7; i++) { if ((clidr & CLIDR_CTYPE_MASK) == 0) break; @@ -359,9 +408,15 @@ cpu_identify(struct cpu_info *ci) i << CSSELR_LEVEL_SHIFT | CSSELR_IND); __asm volatile("isb"); ccsidr = READ_SPECIALREG(ccsidr_el1); - sets = CCSIDR_SETS(ccsidr); - ways = CCSIDR_WAYS(ccsidr); - line = CCSIDR_LINE_SIZE(ccsidr); + if (ccidx) { + sets = CCSIDR_CCIDX_SETS(ccsidr); + ways = CCSIDR_CCIDX_WAYS(ccsidr); + line = CCSIDR_CCIDX_LINE_SIZE(ccsidr); + } else { + sets = CCSIDR_SETS(ccsidr); + ways = CCSIDR_WAYS(ccsidr); + line = CCSIDR_LINE_SIZE(ccsidr); + } printf("%s %dKB %db/line %d-way L%d %sI-cache", sep, (sets * ways * line) / 1024, line, ways, (i + 1), il1p_name); @@ -372,9 +427,15 @@ cpu_identify(struct cpu_info *ci) WRITE_SPECIALREG(csselr_el1, i << CSSELR_LEVEL_SHIFT); __asm volatile("isb"); ccsidr = READ_SPECIALREG(ccsidr_el1); - sets = CCSIDR_SETS(ccsidr); - ways = CCSIDR_WAYS(ccsidr); - line = CCSIDR_LINE_SIZE(ccsidr); + if (ccidx) { + sets = CCSIDR_CCIDX_SETS(ccsidr); + ways = CCSIDR_CCIDX_WAYS(ccsidr); + line = CCSIDR_CCIDX_LINE_SIZE(ccsidr); + } else { + sets = CCSIDR_SETS(ccsidr); + ways = CCSIDR_WAYS(ccsidr); + line = CCSIDR_LINE_SIZE(ccsidr); + } printf("%s %dKB %db/line %d-way L%d D-cache", sep, (sets * ways * line) / 1024, line, ways, (i + 1)); sep = ","; @@ -383,9 +444,15 @@ cpu_identify(struct cpu_info *ci) WRITE_SPECIALREG(csselr_el1, i << CSSELR_LEVEL_SHIFT); __asm volatile("isb"); ccsidr = READ_SPECIALREG(ccsidr_el1); - sets = CCSIDR_SETS(ccsidr); - ways = CCSIDR_WAYS(ccsidr); - line = CCSIDR_LINE_SIZE(ccsidr); + if (ccidx) { + sets = CCSIDR_CCIDX_SETS(ccsidr); + ways = CCSIDR_CCIDX_WAYS(ccsidr); + line = CCSIDR_CCIDX_LINE_SIZE(ccsidr); + } else { + sets = CCSIDR_SETS(ccsidr); + ways = CCSIDR_WAYS(ccsidr); + line = CCSIDR_LINE_SIZE(ccsidr); + } printf("%s %dKB %db/line %d-way L%d cache", sep, (sets * ways * line) / 1024, line, ways, (i + 1)); } @@ -478,7 +545,7 @@ cpu_identify(struct cpu_info *ci) */ #if NPSCI > 0 if (ci->ci_trampoline_vectors == (vaddr_t)trampoline_vectors_none && - psci_flush_bp_has_bhb()) { + smccc_needs_arch_workaround_3()) { ci->ci_flush_bp = cpu_flush_bp_noop; if (psci_method() == PSCI_METHOD_HVC) ci->ci_trampoline_vectors = @@ -509,6 +576,8 @@ cpu_identify(struct cpu_info *ci) ci->ci_trampoline_vectors = (vaddr_t)trampoline_vectors_none; } + cpu_mitigate_spectre_v4(ci); + /* * Apple CPUs provide detailed information for SError. */ diff --git a/sys/arch/arm64/include/armreg.h b/sys/arch/arm64/include/armreg.h index 5d0081587..445c07ac2 100644 --- a/sys/arch/arm64/include/armreg.h +++ b/sys/arch/arm64/include/armreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: armreg.h,v 1.32 2024/03/17 13:05:40 kettenis Exp $ */ +/* $OpenBSD: armreg.h,v 1.33 2024/03/18 18:35:21 kettenis Exp $ */ /*- * Copyright (c) 2013, 2014 Andrew Turner * Copyright (c) 2015 The FreeBSD Foundation @@ -56,6 +56,18 @@ #define CCSIDR_LINE_MASK 0x00000007 #define CCSIDR_LINE_SIZE(reg) (1 << (((reg) & CCSIDR_LINE_MASK) + 4)) +#define CCSIDR_CCIDX_SETS_MASK 0x00ffffff00000000ULL +#define CCSIDR_CCIDX_SETS_SHIFT 32 +#define CCSIDR_CCIDX_SETS(reg) \ + ((((reg) & CCSIDR_CCIDX_SETS_MASK) >> CCSIDR_CCIDX_SETS_SHIFT) + 1) +#define CCSIDR_CCIDX_WAYS_MASK 0x0000000000fffff8ULL +#define CCSIDR_CCIDX_WAYS_SHIFT 3 +#define CCSIDR_CCIDX_WAYS(reg) \ + ((((reg) & CCSIDR_CCIDX_WAYS_MASK) >> CCSIDR_CCIDX_WAYS_SHIFT) + 1) +#define CCSIDR_CCIDX_LINE_MASK 0x0000000000000007ULL +#define CCSIDR_CCIDX_LINE_SIZE(reg) \ + (1 << (((reg) & CCSIDR_CCIDX_LINE_MASK) + 4)) + /* CLIDR_EL1 - Cache Level ID Register */ #define CLIDR_CTYPE_MASK 0x7 #define CLIDR_CTYPE_INSN 0x1 @@ -491,6 +503,13 @@ #define ID_AA64MMFR1_ECBHB_NONE (0x0ULL << ID_AA64MMFR1_ECBHB_SHIFT) #define ID_AA64MMFR1_ECBHB_IMPL (0x1ULL << ID_AA64MMFR1_ECBHB_SHIFT) +/* ID_AA64MMFR2_EL1 */ +#define ID_AA64MMFR2_MASK 0xffff0fffffffffffULL +#define ID_AA64MMFR2_CCIDX_SHIFT 20 +#define ID_AA64MMFR2_CCIDX_MASK (0xfULL << ID_AA64MMFR2_CCIDX_SHIFT) +#define ID_AA64MMFR2_CCIDX(x) ((x) & ID_AA64MMFR2_CCIDX_MASK) +#define ID_AA64MMFR2_CCIDX_IMPL (0x1ULL << ID_AA64MMFR2_CCIDX_SHIFT) + /* ID_AA64PFR0_EL1 */ #define ID_AA64PFR0_MASK 0xff0fffffffffffffULL #define ID_AA64PFR0_EL0_SHIFT 0 diff --git a/sys/dev/fdt/if_mvpp.c b/sys/dev/fdt/if_mvpp.c index c2881861b..f3347fa38 100644 --- a/sys/dev/fdt/if_mvpp.c +++ b/sys/dev/fdt/if_mvpp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mvpp.c,v 1.51 2023/11/10 15:51:19 bluhm Exp $ */ +/* $OpenBSD: if_mvpp.c,v 1.52 2024/03/18 21:37:44 patrick Exp $ */ /* * Copyright (c) 2008, 2019 Mark Kettenis * Copyright (c) 2017, 2020 Patrick Wildt @@ -1388,6 +1388,7 @@ mvpp2_port_attach(struct device *parent, struct device *self, void *aux) sc->sc_mdio = mii_byphandle(phy); sc->sc_phyloc = OF_getpropint(node, "reg", MII_PHY_ANY); sc->sc_sfp = OF_getpropint(node, "sfp", sc->sc_sfp); + sc->sc_mii.mii_node = node; } if (sc->sc_sfp) diff --git a/sys/dev/fdt/psci.c b/sys/dev/fdt/psci.c index 675a97d5c..c064823cc 100644 --- a/sys/dev/fdt/psci.c +++ b/sys/dev/fdt/psci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: psci.c,v 1.14 2023/02/19 17:16:13 kettenis Exp $ */ +/* $OpenBSD: psci.c,v 1.15 2024/03/18 21:57:22 kettenis Exp $ */ /* * Copyright (c) 2016 Jonathan Gray @@ -34,6 +34,7 @@ extern void (*powerdownfn)(void); #define SMCCC_VERSION 0x80000000 #define SMCCC_ARCH_FEATURES 0x80000001 #define SMCCC_ARCH_WORKAROUND_1 0x80008000 +#define SMCCC_ARCH_WORKAROUND_2 0x80007fff #define SMCCC_ARCH_WORKAROUND_3 0x80003fff #define PSCI_VERSION 0x84000000 @@ -240,8 +241,24 @@ psci_flush_bp(void) } } +void +smccc_enable_arch_workaround_2(void) +{ + struct psci_softc *sc = psci_sc; + + /* + * SMCCC 1.1 allows us to detect if the workaround is + * implemented and needed. + */ + if (sc && sc->sc_smccc_version >= 0x10001 && + smccc_arch_features(SMCCC_ARCH_WORKAROUND_2) == 0) { + /* Workaround implemented and needed. */ + (*sc->sc_callfn)(SMCCC_ARCH_WORKAROUND_2, 1, 0, 0); + } +} + int -psci_flush_bp_has_bhb(void) +smccc_needs_arch_workaround_3(void) { struct psci_softc *sc = psci_sc; diff --git a/sys/dev/fdt/pscivar.h b/sys/dev/fdt/pscivar.h index 04e418f31..f13a757d7 100644 --- a/sys/dev/fdt/pscivar.h +++ b/sys/dev/fdt/pscivar.h @@ -22,4 +22,7 @@ int psci_method(void); int32_t smccc(uint32_t, register_t, register_t, register_t); +void smccc_enable_arch_workaround_2(void); +int smccc_needs_arch_workaround_3(void); + #endif /* _SYS_DEV_FDT_PSCIVAR_H_ */ diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 69dc8751e..eaa3da9c5 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci.c,v 1.127 2023/04/13 15:36:28 miod Exp $ */ +/* $OpenBSD: pci.c,v 1.128 2024/03/18 21:20:46 kettenis Exp $ */ /* $NetBSD: pci.c,v 1.31 1997/06/06 23:48:04 thorpej Exp $ */ /* @@ -875,8 +875,8 @@ pci_reserve_resources(struct pci_attach_args *pa) { pci_chipset_tag_t pc = pa->pa_pc; pcitag_t tag = pa->pa_tag; - pcireg_t bhlc, blr, type, bir; - pcireg_t addr, mask; + pcireg_t bhlc, blr, bir, csr; + pcireg_t addr, mask, type; bus_addr_t base, limit; bus_size_t size; int reg, reg_start, reg_end, reg_rom; @@ -908,6 +908,7 @@ pci_reserve_resources(struct pci_attach_args *pa) return (0); } + csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); for (reg = reg_start; reg < reg_end; reg += 4) { if (!pci_mapreg_probe(pc, tag, reg, &type)) continue; @@ -945,8 +946,11 @@ pci_reserve_resources(struct pci_attach_args *pa) #endif if (pa->pa_memex && extent_alloc_region(pa->pa_memex, base, size, EX_NOWAIT)) { - printf("%d:%d:%d: mem address conflict 0x%lx/0x%lx\n", - bus, dev, func, base, size); + if (csr & PCI_COMMAND_MEM_ENABLE) { + printf("%d:%d:%d: mem address conflict" + " 0x%lx/0x%lx\n", bus, dev, func, + base, size); + } pci_conf_write(pc, tag, reg, 0); if (type & PCI_MAPREG_MEM_TYPE_64BIT) pci_conf_write(pc, tag, reg + 4, 0); @@ -955,8 +959,11 @@ pci_reserve_resources(struct pci_attach_args *pa) case PCI_MAPREG_TYPE_IO: if (pa->pa_ioex && extent_alloc_region(pa->pa_ioex, base, size, EX_NOWAIT)) { - printf("%d:%d:%d: io address conflict 0x%lx/0x%lx\n", - bus, dev, func, base, size); + if (csr & PCI_COMMAND_IO_ENABLE) { + printf("%d:%d:%d: io address conflict" + " 0x%lx/0x%lx\n", bus, dev, func, + base, size); + } pci_conf_write(pc, tag, reg, 0); } break; @@ -981,8 +988,11 @@ pci_reserve_resources(struct pci_attach_args *pa) base, size, EX_NOWAIT) && pa->pa_memex && extent_alloc_region(pa->pa_memex, base, size, EX_NOWAIT)) { - printf("%d:%d:%d: rom address conflict 0x%lx/0x%lx\n", - bus, dev, func, base, size); + if (addr & PCI_ROM_ENABLE) { + printf("%d:%d:%d: rom address conflict" + " 0x%lx/0x%lx\n", bus, dev, func, + base, size); + } pci_conf_write(pc, tag, PCI_ROM_REG, 0); } } diff --git a/sys/net/if_aggr.c b/sys/net/if_aggr.c index 748b3c922..3780d82df 100644 --- a/sys/net/if_aggr.c +++ b/sys/net/if_aggr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_aggr.c,v 1.43 2024/03/04 04:44:12 dlg Exp $ */ +/* $OpenBSD: if_aggr.c,v 1.45 2024/03/18 06:14:50 dlg Exp $ */ /* * Copyright (c) 2019 The University of Queensland @@ -53,6 +53,7 @@ */ #include "bpfilter.h" +#include "kstat.h" #include #include @@ -67,6 +68,7 @@ #include #include #include +#include #include #include @@ -299,8 +301,11 @@ static const char *lacp_mux_event_names[] = { * aggr interface */ -#define AGGR_MAX_PORTS 32 -#define AGGR_MAX_SLOW_PKTS (AGGR_MAX_PORTS * 3) +#define AGGR_PORT_BITS 5 +#define AGGR_FLOWID_SHIFT (16 - AGGR_PORT_BITS) + +#define AGGR_MAX_PORTS (1 << AGGR_PORT_BITS) +#define AGGR_MAX_SLOW_PKTS 3 struct aggr_multiaddr { TAILQ_ENTRY(aggr_multiaddr) @@ -326,8 +331,22 @@ static const char *aggr_port_selected_names[] = { "STANDBY", }; +struct aggr_proto_count { + uint64_t c_pkts; + uint64_t c_bytes; +}; + +#define AGGR_PROTO_TX_LACP 0 +#define AGGR_PROTO_TX_MARKER 1 +#define AGGR_PROTO_RX_LACP 2 +#define AGGR_PROTO_RX_MARKER 3 + +#define AGGR_PROTO_COUNT 4 + struct aggr_port { struct ifnet *p_ifp0; + struct kstat *p_kstat; + struct mutex p_mtx; uint8_t p_lladdr[ETHER_ADDR_LEN]; uint32_t p_mtu; @@ -362,7 +381,7 @@ struct aggr_port { /* Receive machine */ enum lacp_rxm_state p_rxm_state; - struct mbuf_queue p_rxm_mq; + struct mbuf_list p_rxm_ml; struct task p_rxm_task; /* Periodic Transmission machine */ @@ -375,6 +394,11 @@ struct aggr_port { int p_txm_log[LACP_TX_MACHINE_RATE]; unsigned int p_txm_slot; struct timeout p_txm_ntt; + + /* Counters */ + struct aggr_proto_count p_proto_counts[AGGR_PROTO_COUNT]; + uint64_t p_rx_drops; + uint32_t p_nselectch; }; TAILQ_HEAD(aggr_port_list, aggr_port); @@ -506,6 +530,11 @@ static void aggr_unselected(struct aggr_port *); static void aggr_selection_logic(struct aggr_softc *, struct aggr_port *); +#if NKSTAT > 0 +static void aggr_port_kstat_attach(struct aggr_port *); +static void aggr_port_kstat_detach(struct aggr_port *); +#endif + static struct if_clone aggr_cloner = IF_CLONE_INITIALIZER("aggr", aggr_clone_create, aggr_clone_destroy); @@ -660,7 +689,7 @@ aggr_transmit(struct aggr_softc *sc, const struct aggr_map *map, struct mbuf *m) #endif if (ISSET(m->m_pkthdr.csum_flags, M_FLOWID)) - flow = m->m_pkthdr.ph_flowid; + flow = m->m_pkthdr.ph_flowid >> AGGR_FLOWID_SHIFT; ifp0 = map->m_ifp0s[flow % AGGR_MAX_PORTS]; @@ -743,7 +772,9 @@ aggr_input(struct ifnet *ifp0, struct mbuf *m) eh = mtod(m, struct ether_header *); if (!ISSET(m->m_flags, M_VLANTAG) && __predict_false(aggr_eh_is_slow(eh))) { + unsigned int rx_proto = AGGR_PROTO_RX_LACP; struct ether_slowproto_hdr *sph; + int drop = 0; hlen += sizeof(*sph); if (m->m_len < hlen) { @@ -757,9 +788,25 @@ aggr_input(struct ifnet *ifp0, struct mbuf *m) sph = (struct ether_slowproto_hdr *)(eh + 1); switch (sph->sph_subtype) { - case SLOWPROTOCOLS_SUBTYPE_LACP: case SLOWPROTOCOLS_SUBTYPE_LACP_MARKER: - if (mq_enqueue(&p->p_rxm_mq, m) == 0) + rx_proto = AGGR_PROTO_RX_MARKER; + /* FALLTHROUGH */ + case SLOWPROTOCOLS_SUBTYPE_LACP: + mtx_enter(&p->p_mtx); + p->p_proto_counts[rx_proto].c_pkts++; + p->p_proto_counts[rx_proto].c_bytes += m->m_pkthdr.len; + + if (ml_len(&p->p_rxm_ml) < AGGR_MAX_SLOW_PKTS) + ml_enqueue(&p->p_rxm_ml, m); + else { + p->p_rx_drops++; + drop = 1; + } + mtx_leave(&p->p_mtx); + + if (drop) + goto drop; + else task_add(systq, &p->p_rxm_task); return; default: @@ -1112,6 +1159,7 @@ aggr_add_port(struct aggr_softc *sc, const struct trunk_reqport *rp) p->p_ifp0 = ifp0; p->p_aggr = sc; p->p_mtu = ifp0->if_mtu; + mtx_init(&p->p_mtx, IPL_SOFTNET); CTASSERT(sizeof(p->p_lladdr) == sizeof(ac0->ac_enaddr)); memcpy(p->p_lladdr, ac0->ac_enaddr, sizeof(p->p_lladdr)); @@ -1152,7 +1200,7 @@ aggr_add_port(struct aggr_softc *sc, const struct trunk_reqport *rp) if_detachhook_add(ifp0, &p->p_dhook); task_set(&p->p_rxm_task, aggr_rx, p); - mq_init(&p->p_rxm_mq, 3, IPL_NET); + ml_init(&p->p_rxm_ml); timeout_set_proc(&p->p_ptm_tx, aggr_ptm_tx, p); timeout_set_proc(&p->p_txm_ntt, aggr_transmit_machine, p); @@ -1170,6 +1218,10 @@ aggr_add_port(struct aggr_softc *sc, const struct trunk_reqport *rp) DPRINTF(sc, "%s %s trunkport: creating port\n", ifp->if_xname, ifp0->if_xname); +#if NKSTAT > 0 + aggr_port_kstat_attach(p); /* this prints warnings itself */ +#endif + TAILQ_INSERT_TAIL(&sc->sc_ports, p, p_entry); sc->sc_nports++; @@ -1415,6 +1467,10 @@ aggr_p_dtor(struct aggr_softc *sc, struct aggr_port *p, const char *op) ifp0->if_ioctl = p->p_ioctl; ifp0->if_output = p->p_output; +#if NKSTAT > 0 + aggr_port_kstat_detach(p); +#endif + TAILQ_REMOVE(&sc->sc_ports, p, p_entry); sc->sc_nports--; @@ -1457,7 +1513,6 @@ aggr_p_dtor(struct aggr_softc *sc, struct aggr_port *p, const char *op) if_detachhook_del(ifp0, &p->p_dhook); if_linkstatehook_del(ifp0, &p->p_lhook); - if_put(ifp0); free(p, M_DEVBUF, sizeof(*p)); @@ -1754,6 +1809,11 @@ aggr_marker_response(struct aggr_port *p, struct mbuf *m) memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(eh->ether_shost)); eh->ether_type = htons(ETHERTYPE_SLOW); + mtx_enter(&p->p_mtx); + p->p_proto_counts[AGGR_PROTO_TX_MARKER].c_pkts++; + p->p_proto_counts[AGGR_PROTO_TX_MARKER].c_bytes += m->m_pkthdr.len; + mtx_leave(&p->p_mtx); + (void)if_enqueue(ifp0, m); } @@ -1786,7 +1846,10 @@ aggr_rx(void *arg) struct mbuf_list ml; struct mbuf *m; - mq_delist(&p->p_rxm_mq, &ml); + mtx_enter(&p->p_mtx); + ml = p->p_rxm_ml; + ml_init(&p->p_rxm_ml); + mtx_leave(&p->p_mtx); while ((m = ml_dequeue(&ml)) != NULL) { struct ether_slowproto_hdr *sph; @@ -1820,7 +1883,16 @@ aggr_set_selected(struct aggr_port *p, enum aggr_port_selected s, sc->sc_if.if_xname, p->p_ifp0->if_xname, aggr_port_selected_names[p->p_selected], aggr_port_selected_names[s]); + + /* + * setting p_selected doesnt need the mtx except to + * coordinate with a kstat read. + */ + + mtx_enter(&p->p_mtx); p->p_selected = s; + p->p_nselectch++; + mtx_leave(&p->p_mtx); } aggr_mux(sc, p, ev); } @@ -2736,6 +2808,11 @@ aggr_ntt_transmit(struct aggr_port *p) lacpdu->lacp_terminator.lacp_tlv_type = LACP_T_TERMINATOR; lacpdu->lacp_terminator.lacp_tlv_length = 0; + mtx_enter(&p->p_mtx); + p->p_proto_counts[AGGR_PROTO_TX_LACP].c_pkts++; + p->p_proto_counts[AGGR_PROTO_TX_LACP].c_bytes += m->m_pkthdr.len; + mtx_leave(&p->p_mtx); + (void)if_enqueue(ifp0, m); } @@ -2919,3 +2996,129 @@ aggr_multi_del(struct aggr_softc *sc, struct ifreq *ifr) return (0); } + +#if NKSTAT > 0 +static const char *aggr_proto_names[AGGR_PROTO_COUNT] = { + [AGGR_PROTO_TX_LACP] = "tx-lacp", + [AGGR_PROTO_TX_MARKER] = "tx-marker", + [AGGR_PROTO_RX_LACP] = "rx-lacp", + [AGGR_PROTO_RX_MARKER] = "rx-marker", +}; + +struct aggr_port_kstat { + struct kstat_kv interface; + + struct { + struct kstat_kv pkts; + struct kstat_kv bytes; + } protos[AGGR_PROTO_COUNT]; + + struct kstat_kv rx_drops; + + struct kstat_kv selected; + struct kstat_kv nselectch; +}; + +static int +aggr_port_kstat_read(struct kstat *ks) +{ + struct aggr_port *p = ks->ks_softc; + struct aggr_port_kstat *pk = ks->ks_data; + unsigned int proto; + + mtx_enter(&p->p_mtx); + for (proto = 0; proto < AGGR_PROTO_COUNT; proto++) { + kstat_kv_u64(&pk->protos[proto].pkts) = + p->p_proto_counts[proto].c_pkts; + kstat_kv_u64(&pk->protos[proto].bytes) = + p->p_proto_counts[proto].c_bytes; + } + kstat_kv_u64(&pk->rx_drops) = p->p_rx_drops; + + kstat_kv_bool(&pk->selected) = p->p_selected == AGGR_PORT_SELECTED; + kstat_kv_u32(&pk->nselectch) = p->p_nselectch; + mtx_leave(&p->p_mtx); + + nanouptime(&ks->ks_updated); + + return (0); +} + +static void +aggr_port_kstat_attach(struct aggr_port *p) +{ + struct aggr_softc *sc = p->p_aggr; + struct ifnet *ifp = &sc->sc_if; + struct ifnet *ifp0 = p->p_ifp0; + struct kstat *ks; + struct aggr_port_kstat *pk; + unsigned int proto; + + pk = malloc(sizeof(*pk), M_DEVBUF, M_WAITOK|M_CANFAIL|M_ZERO); + if (pk == NULL) { + log(LOG_WARNING, "%s %s: unable to allocate aggr-port kstat\n", + ifp->if_xname, ifp0->if_xname); + return; + } + + ks = kstat_create(ifp->if_xname, 0, "aggr-port", ifp0->if_index, + KSTAT_T_KV, 0); + if (ks == NULL) { + log(LOG_WARNING, "%s %s: unable to create aggr-port kstat\n", + ifp->if_xname, ifp0->if_xname); + free(pk, M_DEVBUF, sizeof(*pk)); + return; + } + + kstat_kv_init(&pk->interface, "interface", KSTAT_KV_T_ISTR); + strlcpy(kstat_kv_istr(&pk->interface), ifp0->if_xname, + sizeof(kstat_kv_istr(&pk->interface))); + + for (proto = 0; proto < AGGR_PROTO_COUNT; proto++) { + char kvname[KSTAT_KV_NAMELEN]; + + snprintf(kvname, sizeof(kvname), + "%s-pkts", aggr_proto_names[proto]); + kstat_kv_unit_init(&pk->protos[proto].pkts, + kvname, KSTAT_KV_T_COUNTER64, KSTAT_KV_U_PACKETS); + + snprintf(kvname, sizeof(kvname), + "%s-bytes", aggr_proto_names[proto]); + kstat_kv_unit_init(&pk->protos[proto].bytes, + kvname, KSTAT_KV_T_COUNTER64, KSTAT_KV_U_BYTES); + } + + kstat_kv_unit_init(&pk->rx_drops, "rx-drops", + KSTAT_KV_T_COUNTER64, KSTAT_KV_U_PACKETS); + + kstat_kv_init(&pk->selected, "selected", KSTAT_KV_T_BOOL); + kstat_kv_init(&pk->nselectch, "select-changes", KSTAT_KV_T_COUNTER32); + + ks->ks_softc = p; + ks->ks_data = pk; + ks->ks_datalen = sizeof(*pk); + ks->ks_read = aggr_port_kstat_read; + + kstat_install(ks); + + p->p_kstat = ks; +} + +static void +aggr_port_kstat_detach(struct aggr_port *p) +{ + struct kstat *ks = p->p_kstat; + struct aggr_port_kstat *pk; + + if (ks == NULL) + return; + + p->p_kstat = NULL; + + kstat_remove(ks); + pk = ks->ks_data; + kstat_destroy(ks); + + free(pk, M_DEVBUF, sizeof(*pk)); +} +#endif diff --git a/usr.sbin/bgpd/bgpd.conf.5 b/usr.sbin/bgpd/bgpd.conf.5 index 6dc0fba5d..a52227b8e 100644 --- a/usr.sbin/bgpd/bgpd.conf.5 +++ b/usr.sbin/bgpd/bgpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bgpd.conf.5,v 1.237 2023/10/13 07:37:35 claudio Exp $ +.\" $OpenBSD: bgpd.conf.5,v 1.238 2024/03/18 10:16:50 claudio Exp $ .\" .\" Copyright (c) 2004 Claudio Jeker .\" Copyright (c) 2003, 2004 Henning Brauer @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: October 13 2023 $ +.Dd $Mdocdate: March 18 2024 $ .Dt BGPD.CONF 5 .Os .Sh NAME @@ -473,7 +473,9 @@ aspa-set { .Pp .It Xo .Ic origin-set Ar name -.Ic { Ar address Ns Li / Ns Ar len Ic maxlen Ar mlen Ic source-as Ar asn ... Ic } +.Ic { Ar address Ns Li / Ns Ar len +.Op Ic maxlen Ar mlen +.Ic source-as Ar asn ... Ic } .Xc An .Ic origin-set diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 8fe49ac07..6e72746cd 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.486 2024/02/19 10:15:35 job Exp $ */ +/* $OpenBSD: bgpd.h,v 1.487 2024/03/18 10:49:24 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -37,7 +37,7 @@ #define RTR_PORT 323 #define CONFFILE "/etc/bgpd.conf" #define BGPD_USER "_bgpd" -#define PEER_DESCR_LEN 32 +#define PEER_DESCR_LEN 64 #define REASON_LEN 256 /* includes NUL terminator */ #define PFTABLE_LEN 32 #define ROUTELABEL_LEN 32 diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index 235eedf30..ea47a659b 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.455 2023/08/16 08:26:35 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.456 2024/03/18 14:54:52 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer @@ -4989,7 +4989,7 @@ expand_rule(struct filter_rule *rule, struct filter_rib_l *rib, int str2key(char *s, char *dest, size_t max_len) { - unsigned i; + unsigned int i; char t[3]; if (strlen(s) / 2 > max_len) { @@ -5006,7 +5006,8 @@ str2key(char *s, char *dest, size_t max_len) t[0] = s[2*i]; t[1] = s[2*i + 1]; t[2] = 0; - if (!isxdigit(t[0]) || !isxdigit(t[1])) { + if (!isxdigit((unsigned char)t[0]) || + !isxdigit((unsigned char)t[1])) { yyerror("key must be specified in hex"); return (-1); } diff --git a/usr.sbin/smtpd/smtpd.conf.5 b/usr.sbin/smtpd/smtpd.conf.5 index 161650059..24fa6daba 100644 --- a/usr.sbin/smtpd/smtpd.conf.5 +++ b/usr.sbin/smtpd/smtpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: smtpd.conf.5,v 1.269 2024/03/15 21:56:22 op Exp $ +.\" $OpenBSD: smtpd.conf.5,v 1.270 2024/03/18 08:48:50 op Exp $ .\" .\" Copyright (c) 2008 Janne Johansson .\" Copyright (c) 2009 Jacek Masiulaniec @@ -17,7 +17,7 @@ .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .\" -.Dd $Mdocdate: March 15 2024 $ +.Dd $Mdocdate: March 18 2024 $ .Dt SMTPD.CONF 5 .Os .Sh NAME @@ -155,7 +155,8 @@ Deliver the message to the user's mbox with .It Cm mda Ar command Delegate the delivery to a .Ar command -that receives the message on its standard input. +that receives the message on its standard input +.Pq see Sx MDA COMMANDS . .Pp The .Ar command @@ -1113,34 +1114,65 @@ For example, with recipient .It %{rcpt} Ta expands to Dq user+t:g@example.org .It %{rcpt:raw} Ta expands to Dq user+t?g@example.org .El -.Ss MDA ENVIRONMENT -When a MDA is invoked, +.Ss MDA COMMANDS +When an action delivery method is +.Cm mda , .Xr smtpd 8 -will create a new process. -Only the uid and gid of the destination user is set. -The following environment variables will be set: -.Bl -tag -width "ORIGINAL_RECIPIENT" +runs the associated command for the delivery with the mail content +provided via standard input. +The command is expected to read all the mail content. +.Pp +The exit code of the command reports the outcome of the delivery: +status 0 +.Pq Dv EX_OK +is a successful delivery; status 71 +.Pq Dv EX_OSERR +and 75 +.Pq Dv EX_TEMPFAIL +are temporary failures; and all other exit status are considered +permament failures. +.Pp +The following environment variables are set: +.Pp +.Bl -tag -width ORIGINAL_RECIPIENT -compact .It Ev DOMAIN The recipient domain. +.It Ev EXTENSION +The sub address of the recipient (may be unset). .It Ev HOME -The home directory of the destination user. -.It Ev RECIPIENT -The address of the final recipient. +The delivery user's login directory. +.It Ev LOCAL +The local part of the recipient user address. +.It Ev LOGNAME +The login name of the user. .It Ev ORIGINAL_RECIPIENT The address of the original recipient. -.It Ev EXTENSION -The sub address of the recipient, only set when there is a sub address. +.It Ev PATH +Set to +.Ev _PATH_DEFPATH . +Traditionally +.Pa /usr/bin:/bin , +but expanded to include +.Pa /usr/sbin , +.Pa /sbin , +.Pa /usr/X11R6/bin , +.Pa /usr/local/bin , +and +.Pa /usr/local/sbin +in +.Ox . +.It Ev RECIPIENT +The address of the final recipient. .It Ev SENDER The address of the sender (might be empty). +.It Ev SHELL +Set to +.Pa /bin/sh . +.It Ev USER +Synonym of +.Ev LOGNAME +for backwards compatibility. .El -.Pp -This process gets the mail piped to -.Xr stdin 3 . -A mail is considered as delivered when the mda exit with -.Dv EX_OK -and -.Xr stdin 3 -is completely read. .Sh FILES .Bl -tag -width "/etc/mail/smtpd.confXXX" -compact .It Pa /etc/mail/smtpd.conf