summaryrefslogtreecommitdiffstats
path: root/freebsd/sys
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-12-20 11:12:40 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-12-20 13:36:34 +0100
commit2b2563da953978f63e3e707f758fd600dcd19a32 (patch)
treea207b096c10788192b56025e8187f14d1b5a978d /freebsd/sys
parentfreebsd/if_cpsw: Port. (diff)
downloadrtems-libbsd-2b2563da953978f63e3e707f758fd600dcd19a32.tar.bz2
Update to FreeBSD head 2018-12-20
Git mirror commit 19a6ceb89dbacf74697d493e48c388767126d418. It includes an update of wpa_supplicant to version 2.7. It includes an update of the OpenSSL baseline to version 1.1.1a. Update #3472.
Diffstat (limited to 'freebsd/sys')
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.c34
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.h6
-rw-r--r--freebsd/sys/contrib/ck/include/gcc/sparcv9/ck_pr.h30
-rw-r--r--freebsd/sys/dev/evdev/evdev_utils.c7
-rw-r--r--freebsd/sys/dev/fdt/simplebus.c9
-rw-r--r--freebsd/sys/dev/fdt/simplebus.h2
-rw-r--r--freebsd/sys/dev/fxp/if_fxp.c2
-rw-r--r--freebsd/sys/dev/fxp/if_fxpreg.h13
-rw-r--r--freebsd/sys/dev/mmc/mmc.c22
-rw-r--r--freebsd/sys/dev/nvme/nvme.h7
-rw-r--r--freebsd/sys/dev/pci/pci.c40
-rw-r--r--freebsd/sys/dev/pci/pci_pci.c3
-rw-r--r--freebsd/sys/dev/pci/pci_user.c6
-rw-r--r--freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h2
-rw-r--r--freebsd/sys/dev/sdhci/sdhci.c3
-rw-r--r--freebsd/sys/dev/sdhci/sdhci.h2
-rw-r--r--freebsd/sys/dev/usb/wlan/if_rsu.c1
-rw-r--r--freebsd/sys/kern/init_main.c99
-rw-r--r--freebsd/sys/kern/kern_event.c110
-rw-r--r--freebsd/sys/kern/kern_intr.c104
-rw-r--r--freebsd/sys/kern/kern_synch.c2
-rw-r--r--freebsd/sys/kern/kern_sysctl.c24
-rw-r--r--freebsd/sys/kern/subr_blist.c55
-rw-r--r--freebsd/sys/kern/subr_bus.c68
-rw-r--r--freebsd/sys/kern/subr_rman.c15
-rw-r--r--freebsd/sys/kern/subr_taskqueue.c28
-rw-r--r--freebsd/sys/kern/subr_unit.c13
-rwxr-xr-xfreebsd/sys/kern/sys_pipe.c27
-rw-r--r--freebsd/sys/kern/uipc_sockbuf.c47
-rw-r--r--freebsd/sys/kern/uipc_socket.c3
-rw-r--r--freebsd/sys/kern/uipc_syscalls.c4
-rw-r--r--freebsd/sys/kern/uipc_usrreq.c7
-rw-r--r--freebsd/sys/net/altq/altq.h122
-rw-r--r--freebsd/sys/net/altq/altq_cbq.c606
-rw-r--r--freebsd/sys/net/altq/altq_cbq.h105
-rw-r--r--freebsd/sys/net/altq/altq_cdnr.c1384
-rw-r--r--freebsd/sys/net/altq/altq_hfsc.c580
-rw-r--r--freebsd/sys/net/altq/altq_hfsc.h68
-rw-r--r--freebsd/sys/net/altq/altq_priq.c427
-rw-r--r--freebsd/sys/net/altq/altq_priq.h63
-rw-r--r--freebsd/sys/net/altq/altq_red.c859
-rw-r--r--freebsd/sys/net/altq/altq_red.h70
-rw-r--r--freebsd/sys/net/altq/altq_rio.c393
-rw-r--r--freebsd/sys/net/altq/altq_rio.h48
-rw-r--r--freebsd/sys/net/altq/altq_rmclass.c8
-rw-r--r--freebsd/sys/net/altq/altq_rmclass.h4
-rw-r--r--freebsd/sys/net/altq/altq_subr.c29
-rw-r--r--freebsd/sys/net/if.c12
-rw-r--r--freebsd/sys/net/if_ipsec.c14
-rw-r--r--freebsd/sys/net/if_tap.c2
-rw-r--r--freebsd/sys/net/if_tun.c2
-rw-r--r--freebsd/sys/net/if_vlan.c6
-rw-r--r--freebsd/sys/net/route.h1
-rw-r--r--freebsd/sys/net/rtsock.c22
-rw-r--r--freebsd/sys/net80211/ieee80211_node.c2
-rw-r--r--freebsd/sys/netinet/cc/cc.h4
-rw-r--r--freebsd/sys/netinet/cc/cc_newreno.c18
-rw-r--r--freebsd/sys/netinet/if_ether.c21
-rw-r--r--freebsd/sys/netinet/if_ether.h3
-rw-r--r--freebsd/sys/netinet/in_pcb.c26
-rw-r--r--freebsd/sys/netinet/in_pcb.h2
-rw-r--r--freebsd/sys/netinet/ip_divert.c1
-rw-r--r--freebsd/sys/netinet/ip_fw.h9
-rw-r--r--freebsd/sys/netinet/ip_reass.c45
-rw-r--r--freebsd/sys/netinet/ip_var.h1
-rw-r--r--freebsd/sys/netinet/raw_ip.c1
-rw-r--r--freebsd/sys/netinet/sctp_sysctl.c3
-rw-r--r--freebsd/sys/netinet/tcp_output.c16
-rw-r--r--freebsd/sys/netinet/tcp_subr.c5
-rw-r--r--freebsd/sys/netinet/tcp_usrreq.c2
-rw-r--r--freebsd/sys/netinet/udp_usrreq.c1
-rw-r--r--freebsd/sys/netinet6/in6_pcb.c10
-rw-r--r--freebsd/sys/netinet6/ip6_mroute.c3
-rw-r--r--freebsd/sys/netinet6/ip6_output.c9
-rw-r--r--freebsd/sys/netipsec/ipsec_pcb.c2
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_private.h33
-rw-r--r--freebsd/sys/netpfil/pf/if_pfsync.c566
-rw-r--r--freebsd/sys/netpfil/pf/pf.c12
-rw-r--r--freebsd/sys/netpfil/pf/pf_if.c3
-rw-r--r--freebsd/sys/netpfil/pf/pf_lb.c10
-rw-r--r--freebsd/sys/opencrypto/criov.c54
-rw-r--r--freebsd/sys/opencrypto/cryptodev.h2
-rw-r--r--freebsd/sys/opencrypto/cryptosoft.c3
-rw-r--r--freebsd/sys/security/audit/audit.h8
-rw-r--r--freebsd/sys/sys/bus.h7
-rw-r--r--freebsd/sys/sys/filedesc.h14
-rw-r--r--freebsd/sys/sys/interrupt.h4
-rw-r--r--freebsd/sys/sys/jail.h9
-rw-r--r--freebsd/sys/sys/mount.h4
-rw-r--r--freebsd/sys/sys/mutex.h4
-rw-r--r--freebsd/sys/sys/priv.h4
-rw-r--r--freebsd/sys/sys/proc.h24
-rw-r--r--freebsd/sys/sys/racct.h10
-rw-r--r--freebsd/sys/sys/refcount.h2
-rw-r--r--freebsd/sys/sys/resourcevar.h13
-rw-r--r--freebsd/sys/sys/rman.h2
-rw-r--r--freebsd/sys/sys/sdt.h5
-rw-r--r--freebsd/sys/sys/sockbuf.h2
-rw-r--r--freebsd/sys/sys/sx.h1
-rw-r--r--freebsd/sys/sys/sysctl.h12
-rw-r--r--freebsd/sys/sys/sysproto.h51
-rw-r--r--freebsd/sys/sys/systm.h26
-rw-r--r--freebsd/sys/sys/taskqueue.h1
-rw-r--r--freebsd/sys/sys/user.h1
-rw-r--r--freebsd/sys/vm/uma_core.c72
-rw-r--r--freebsd/sys/vm/uma_int.h12
106 files changed, 1286 insertions, 5489 deletions
diff --git a/freebsd/sys/cam/scsi/scsi_all.c b/freebsd/sys/cam/scsi/scsi_all.c
index 1a469f32..0be7e692 100644
--- a/freebsd/sys/cam/scsi/scsi_all.c
+++ b/freebsd/sys/cam/scsi/scsi_all.c
@@ -1168,7 +1168,7 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x04, 0x1B, SS_RDEF, /* XXX TBD */
"Logical unit not ready, sanitize in progress") },
/* DT MAEB */
- { SST(0x04, 0x1C, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x1C, SS_START | SSQ_DECREMENT_COUNT | ENXIO,
"Logical unit not ready, additional power use not yet granted") },
/* D */
{ SST(0x04, 0x1D, SS_RDEF, /* XXX TBD */
@@ -8414,6 +8414,38 @@ scsi_ata_read_log(struct ccb_scsiio *csio, uint32_t retries,
return (retval);
}
+int scsi_ata_setfeatures(struct ccb_scsiio *csio, uint32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, uint8_t feature,
+ uint64_t lba, uint32_t count,
+ uint8_t sense_len, uint32_t timeout)
+{
+ return (scsi_ata_pass(csio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_NONE,
+ tag_action,
+ /*protocol*/AP_PROTO_PIO_IN,
+ /*ata_flags*/AP_FLAG_TDIR_FROM_DEV |
+ AP_FLAG_BYT_BLOK_BYTES |
+ AP_FLAG_TLEN_SECT_CNT,
+ /*features*/feature,
+ /*sector_count*/count,
+ /*lba*/lba,
+ /*command*/ATA_SETFEATURES,
+ /*device*/ 0,
+ /*icc*/ 0,
+ /*auxiliary*/0,
+ /*control*/0,
+ /*data_ptr*/NULL,
+ /*dxfer_len*/0,
+ /*cdb_storage*/NULL,
+ /*cdb_storage_len*/0,
+ /*minimum_cmd_size*/0,
+ sense_len,
+ timeout));
+}
+
/*
* Note! This is an unusual CDB building function because it can return
* an error in the event that the command in question requires a variable
diff --git a/freebsd/sys/cam/scsi/scsi_all.h b/freebsd/sys/cam/scsi/scsi_all.h
index 80f8a221..b5c45bc0 100644
--- a/freebsd/sys/cam/scsi/scsi_all.h
+++ b/freebsd/sys/cam/scsi/scsi_all.h
@@ -4176,6 +4176,12 @@ int scsi_ata_read_log(struct ccb_scsiio *csio, uint32_t retries,
uint8_t protocol, uint8_t *data_ptr, uint32_t dxfer_len,
uint8_t sense_len, uint32_t timeout);
+int scsi_ata_setfeatures(struct ccb_scsiio *csio, uint32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, uint8_t feature,
+ uint64_t lba, uint32_t count,
+ uint8_t sense_len, uint32_t timeout);
+
int scsi_ata_pass(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
uint32_t flags, uint8_t tag_action,
diff --git a/freebsd/sys/contrib/ck/include/gcc/sparcv9/ck_pr.h b/freebsd/sys/contrib/ck/include/gcc/sparcv9/ck_pr.h
index 7dc71725..b60e199d 100644
--- a/freebsd/sys/contrib/ck/include/gcc/sparcv9/ck_pr.h
+++ b/freebsd/sys/contrib/ck/include/gcc/sparcv9/ck_pr.h
@@ -136,11 +136,26 @@ CK_PR_STORE_S(int, int, "stsw")
#undef CK_PR_STORE_S
#undef CK_PR_STORE
+/* Use the appropriate address space for atomics within the FreeBSD kernel. */
+#if defined(__FreeBSD__) && defined(_KERNEL)
+#include <sys/cdefs.h>
+#include <machine/atomic.h>
+#define CK_PR_INS_CAS "casa"
+#define CK_PR_INS_CASX "casxa"
+#define CK_PR_INS_SWAP "swapa"
+#define CK_PR_ASI_ATOMIC __XSTRING(__ASI_ATOMIC)
+#else
+#define CK_PR_INS_CAS "cas"
+#define CK_PR_INS_CASX "casx"
+#define CK_PR_INS_SWAP "swap"
+#define CK_PR_ASI_ATOMIC ""
+#endif
+
CK_CC_INLINE static bool
ck_pr_cas_64_value(uint64_t *target, uint64_t compare, uint64_t set, uint64_t *value)
{
- __asm__ __volatile__("casx [%1], %2, %0"
+ __asm__ __volatile__(CK_PR_INS_CASX " [%1] " CK_PR_ASI_ATOMIC ", %2, %0"
: "+&r" (set)
: "r" (target),
"r" (compare)
@@ -154,7 +169,7 @@ CK_CC_INLINE static bool
ck_pr_cas_64(uint64_t *target, uint64_t compare, uint64_t set)
{
- __asm__ __volatile__("casx [%1], %2, %0"
+ __asm__ __volatile__(CK_PR_INS_CASX " [%1] " CK_PR_ASI_ATOMIC ", %2, %0"
: "+&r" (set)
: "r" (target),
"r" (compare)
@@ -181,7 +196,7 @@ ck_pr_cas_ptr_value(void *target, void *compare, void *set, void *previous)
CK_CC_INLINE static bool \
ck_pr_cas_##N##_value(T *target, T compare, T set, T *value) \
{ \
- __asm__ __volatile__("cas [%1], %2, %0" \
+ __asm__ __volatile__(CK_PR_INS_CAS " [%1] " CK_PR_ASI_ATOMIC ", %2, %0" \
: "+&r" (set) \
: "r" (target), \
"r" (compare) \
@@ -192,7 +207,7 @@ ck_pr_cas_ptr_value(void *target, void *compare, void *set, void *previous)
CK_CC_INLINE static bool \
ck_pr_cas_##N(T *target, T compare, T set) \
{ \
- __asm__ __volatile__("cas [%1], %2, %0" \
+ __asm__ __volatile__(CK_PR_INS_CAS " [%1] " CK_PR_ASI_ATOMIC ", %2, %0" \
: "+&r" (set) \
: "r" (target), \
"r" (compare) \
@@ -211,7 +226,7 @@ CK_PR_CAS(int, int)
ck_pr_fas_##N(T *target, T update) \
{ \
\
- __asm__ __volatile__("swap [%1], %0" \
+ __asm__ __volatile__(CK_PR_INS_SWAP " [%1] " CK_PR_ASI_ATOMIC ", %0" \
: "+&r" (update) \
: "r" (target) \
: "memory"); \
@@ -224,5 +239,10 @@ CK_PR_FAS(32, uint32_t)
#undef CK_PR_FAS
+#undef CK_PR_INS_CAS
+#undef CK_PR_INS_CASX
+#undef CK_PR_INS_SWAP
+#undef CK_PR_ASI_ATOMIC
+
#endif /* CK_PR_SPARCV9_H */
diff --git a/freebsd/sys/dev/evdev/evdev_utils.c b/freebsd/sys/dev/evdev/evdev_utils.c
index 17a815fb..9bdc5a23 100644
--- a/freebsd/sys/dev/evdev/evdev_utils.c
+++ b/freebsd/sys/dev/evdev/evdev_utils.c
@@ -252,12 +252,15 @@ evdev_scancode2key(int *state, int scancode)
*/
*state = 0;
if ((scancode & 0x7f) == 0x1D)
- *state = 0x1D;
+ *state = scancode;
return (NONE);
/* NOT REACHED */
case 0x1D: /* pause / break */
+ case 0x9D:
+ if ((*state ^ scancode) & 0x80)
+ return (NONE);
*state = 0;
- if (scancode != 0x45)
+ if ((scancode & 0x7f) != 0x45)
return (NONE);
keycode = KEY_PAUSE;
break;
diff --git a/freebsd/sys/dev/fdt/simplebus.c b/freebsd/sys/dev/fdt/simplebus.c
index 54b17074..583590d4 100644
--- a/freebsd/sys/dev/fdt/simplebus.c
+++ b/freebsd/sys/dev/fdt/simplebus.c
@@ -64,13 +64,6 @@ static const struct ofw_bus_devinfo *simplebus_get_devinfo(device_t bus,
device_t child);
/*
- * local methods
- */
-
-static int simplebus_fill_ranges(phandle_t node,
- struct simplebus_softc *sc);
-
-/*
* Driver methods.
*/
static device_method_t simplebus_methods[] = {
@@ -186,7 +179,7 @@ simplebus_init(device_t dev, phandle_t node)
OF_getencprop(node, "#size-cells", &sc->scells, sizeof(sc->scells));
}
-static int
+int
simplebus_fill_ranges(phandle_t node, struct simplebus_softc *sc)
{
int host_address_cells;
diff --git a/freebsd/sys/dev/fdt/simplebus.h b/freebsd/sys/dev/fdt/simplebus.h
index caccf162..bc695578 100644
--- a/freebsd/sys/dev/fdt/simplebus.h
+++ b/freebsd/sys/dev/fdt/simplebus.h
@@ -61,4 +61,6 @@ device_t simplebus_add_device(device_t dev, phandle_t node, u_int order,
const char *name, int unit, struct simplebus_devinfo *di);
struct simplebus_devinfo *simplebus_setup_dinfo(device_t dev, phandle_t node,
struct simplebus_devinfo *di);
+int simplebus_fill_ranges(phandle_t node,
+ struct simplebus_softc *sc);
#endif /* _FDT_SIMPLEBUS_H */
diff --git a/freebsd/sys/dev/fxp/if_fxp.c b/freebsd/sys/dev/fxp/if_fxp.c
index e9c8721e..b781905b 100644
--- a/freebsd/sys/dev/fxp/if_fxp.c
+++ b/freebsd/sys/dev/fxp/if_fxp.c
@@ -1629,7 +1629,7 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
cbp->tbd_number = nseg;
/* Configure TSO. */
if (m->m_pkthdr.csum_flags & CSUM_TSO) {
- cbp->tbd[-1].tb_size = htole32(m->m_pkthdr.tso_segsz << 16);
+ cbp->tbdtso.tb_size = htole32(m->m_pkthdr.tso_segsz << 16);
cbp->tbd[1].tb_size |= htole32(tcp_payload << 16);
cbp->ipcb_ip_schedule |= FXP_IPCB_LARGESEND_ENABLE |
FXP_IPCB_IP_CHECKSUM_ENABLE |
diff --git a/freebsd/sys/dev/fxp/if_fxpreg.h b/freebsd/sys/dev/fxp/if_fxpreg.h
index d1e6a45a..6b5f3d8b 100644
--- a/freebsd/sys/dev/fxp/if_fxpreg.h
+++ b/freebsd/sys/dev/fxp/if_fxpreg.h
@@ -281,10 +281,15 @@ struct fxp_cb_tx {
uint16_t cb_status;
uint16_t cb_command;
uint32_t link_addr;
- uint32_t tbd_array_addr;
- uint16_t byte_count;
- uint8_t tx_threshold;
- uint8_t tbd_number;
+ union {
+ struct {
+ uint32_t tbd_array_addr;
+ uint16_t byte_count;
+ uint8_t tx_threshold;
+ uint8_t tbd_number;
+ };
+ struct fxp_tbd tbdtso;
+ };
/*
* The following structure isn't actually part of the TxCB,
diff --git a/freebsd/sys/dev/mmc/mmc.c b/freebsd/sys/dev/mmc/mmc.c
index cfbce2a5..4c8aefcf 100644
--- a/freebsd/sys/dev/mmc/mmc.c
+++ b/freebsd/sys/dev/mmc/mmc.c
@@ -844,9 +844,14 @@ mmc_set_power_class(struct mmc_softc *sc, struct mmc_ivars *ivar)
const uint8_t *ext_csd;
uint32_t clock;
uint8_t value;
+ enum mmc_bus_timing timing;
+ enum mmc_bus_width bus_width;
dev = sc->dev;
- if (mmcbr_get_mode(dev) != mode_mmc || ivar->csd.spec_vers < 4)
+ timing = mmcbr_get_timing(dev);
+ bus_width = ivar->bus_width;
+ if (mmcbr_get_mode(dev) != mode_mmc || ivar->csd.spec_vers < 4 ||
+ timing == bus_timing_normal || bus_width == bus_width_1)
return (MMC_ERR_NONE);
value = 0;
@@ -857,8 +862,8 @@ mmc_set_power_class(struct mmc_softc *sc, struct mmc_ivars *ivar)
if (clock <= MMC_TYPE_HS_26_MAX)
value = ext_csd[EXT_CSD_PWR_CL_26_195];
else if (clock <= MMC_TYPE_HS_52_MAX) {
- if (mmcbr_get_timing(dev) >= bus_timing_mmc_ddr52 &&
- ivar->bus_width >= bus_width_4)
+ if (timing >= bus_timing_mmc_ddr52 &&
+ bus_width >= bus_width_4)
value = ext_csd[EXT_CSD_PWR_CL_52_195_DDR];
else
value = ext_csd[EXT_CSD_PWR_CL_52_195];
@@ -877,13 +882,13 @@ mmc_set_power_class(struct mmc_softc *sc, struct mmc_ivars *ivar)
if (clock <= MMC_TYPE_HS_26_MAX)
value = ext_csd[EXT_CSD_PWR_CL_26_360];
else if (clock <= MMC_TYPE_HS_52_MAX) {
- if (mmcbr_get_timing(dev) == bus_timing_mmc_ddr52 &&
- ivar->bus_width >= bus_width_4)
+ if (timing == bus_timing_mmc_ddr52 &&
+ bus_width >= bus_width_4)
value = ext_csd[EXT_CSD_PWR_CL_52_360_DDR];
else
value = ext_csd[EXT_CSD_PWR_CL_52_360];
} else if (clock <= MMC_TYPE_HS200_HS400ES_MAX) {
- if (ivar->bus_width == bus_width_8)
+ if (bus_width == bus_width_8)
value = ext_csd[EXT_CSD_PWR_CL_200_360_DDR];
else
value = ext_csd[EXT_CSD_PWR_CL_200_360];
@@ -895,7 +900,7 @@ mmc_set_power_class(struct mmc_softc *sc, struct mmc_ivars *ivar)
return (MMC_ERR_INVALID);
}
- if (ivar->bus_width == bus_width_8)
+ if (bus_width == bus_width_8)
value = (value & EXT_CSD_POWER_CLASS_8BIT_MASK) >>
EXT_CSD_POWER_CLASS_8BIT_SHIFT;
else
@@ -2178,7 +2183,7 @@ mmc_calculate_clock(struct mmc_softc *sc)
for (i = 0; i < sc->child_count; i++) {
ivar = device_get_ivars(sc->child_list[i]);
if ((ivar->timings & ~(1 << bus_timing_normal)) == 0)
- continue;
+ goto clock;
rca = ivar->rca;
if (mmc_select_card(sc, rca) != MMC_ERR_NONE) {
@@ -2244,6 +2249,7 @@ mmc_calculate_clock(struct mmc_softc *sc)
}
}
+clock:
/* Set clock (must be done before initial tuning). */
mmcbr_set_clock(dev, max_dtr);
mmcbr_update_ios(dev);
diff --git a/freebsd/sys/dev/nvme/nvme.h b/freebsd/sys/dev/nvme/nvme.h
index 747767ce..845ba75b 100644
--- a/freebsd/sys/dev/nvme/nvme.h
+++ b/freebsd/sys/dev/nvme/nvme.h
@@ -1259,6 +1259,13 @@ void nvme_unregister_consumer(struct nvme_consumer *consumer);
device_t nvme_ctrlr_get_device(struct nvme_controller *ctrlr);
const struct nvme_controller_data *
nvme_ctrlr_get_data(struct nvme_controller *ctrlr);
+static inline bool
+nvme_ctrlr_has_dataset_mgmt(const struct nvme_controller_data *cd)
+{
+ /* Assumes cd was byte swapped by nvme_controller_data_swapbytes() */
+ return ((cd->oncs >> NVME_CTRLR_DATA_ONCS_DSM_SHIFT) &
+ NVME_CTRLR_DATA_ONCS_DSM_MASK);
+}
/* Namespace helper functions */
uint32_t nvme_ns_get_max_io_xfer_size(struct nvme_namespace *ns);
diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c
index 512e8636..2c977b85 100644
--- a/freebsd/sys/dev/pci/pci.c
+++ b/freebsd/sys/dev/pci/pci.c
@@ -216,7 +216,8 @@ static device_method_t pci_methods[] = {
DEFINE_CLASS_0(pci, pci_driver, pci_methods, sizeof(struct pci_softc));
static devclass_t pci_devclass;
-DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, NULL);
+EARLY_DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, NULL,
+ BUS_PASS_BUS);
MODULE_VERSION(pci, 1);
static char *pci_vendordata;
@@ -231,6 +232,7 @@ struct pci_quirk {
#define PCI_QUIRK_UNMAP_REG 4 /* Ignore PCI map register */
#define PCI_QUIRK_DISABLE_MSIX 5 /* MSI-X doesn't work */
#define PCI_QUIRK_MSI_INTX_BUG 6 /* PCIM_CMD_INTxDIS disables MSI */
+#define PCI_QUIRK_REALLOC_BAR 7 /* Can't allocate memory at the default address */
int arg1;
int arg2;
};
@@ -312,6 +314,12 @@ static const struct pci_quirk pci_quirks[] = {
{ 0x167814e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5715 */
{ 0x167914e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5715S */
+ /*
+ * HPE Gen 10 VGA has a memory range that can't be allocated in the
+ * expected place.
+ */
+ { 0x98741002, PCI_QUIRK_REALLOC_BAR, 0, 0 },
+
{ 0 }
};
@@ -3286,7 +3294,9 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl,
*/
res = resource_list_reserve(rl, bus, dev, type, &reg, start, end, count,
flags);
- if (pci_do_realloc_bars && res == NULL && (start != 0 || end != ~0)) {
+ if ((pci_do_realloc_bars
+ || pci_has_quirk(pci_get_devid(dev), PCI_QUIRK_REALLOC_BAR))
+ && res == NULL && (start != 0 || end != ~0)) {
/*
* If the allocation fails, try to allocate a resource for
* this BAR using any available range. The firmware felt
@@ -4467,6 +4477,7 @@ int
pci_suspend_child(device_t dev, device_t child)
{
struct pci_devinfo *dinfo;
+ struct resource_list_entry *rle;
int error;
dinfo = device_get_ivars(child);
@@ -4483,8 +4494,20 @@ pci_suspend_child(device_t dev, device_t child)
if (error)
return (error);
- if (pci_do_power_suspend)
+ if (pci_do_power_suspend) {
+ /*
+ * Make sure this device's interrupt handler is not invoked
+ * in the case the device uses a shared interrupt that can
+ * be raised by some other device.
+ * This is applicable only to regular (legacy) PCI interrupts
+ * as MSI/MSI-X interrupts are never shared.
+ */
+ rle = resource_list_find(&dinfo->resources,
+ SYS_RES_IRQ, 0);
+ if (rle != NULL && rle->res != NULL)
+ (void)bus_suspend_intr(child, rle->res);
pci_set_power_child(dev, child, PCI_POWERSTATE_D3);
+ }
return (0);
}
@@ -4493,6 +4516,7 @@ int
pci_resume_child(device_t dev, device_t child)
{
struct pci_devinfo *dinfo;
+ struct resource_list_entry *rle;
if (pci_do_power_resume)
pci_set_power_child(dev, child, PCI_POWERSTATE_D0);
@@ -4504,6 +4528,16 @@ pci_resume_child(device_t dev, device_t child)
bus_generic_resume_child(dev, child);
+ /*
+ * Allow interrupts only after fully resuming the driver and hardware.
+ */
+ if (pci_do_power_suspend) {
+ /* See pci_suspend_child for details. */
+ rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, 0);
+ if (rle != NULL && rle->res != NULL)
+ (void)bus_resume_intr(child, rle->res);
+ }
+
return (0);
}
diff --git a/freebsd/sys/dev/pci/pci_pci.c b/freebsd/sys/dev/pci/pci_pci.c
index ec52e1fb..607a0614 100644
--- a/freebsd/sys/dev/pci/pci_pci.c
+++ b/freebsd/sys/dev/pci/pci_pci.c
@@ -133,7 +133,8 @@ static device_method_t pcib_methods[] = {
static devclass_t pcib_devclass;
DEFINE_CLASS_0(pcib, pcib_driver, pcib_methods, sizeof(struct pcib_softc));
-DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, NULL, NULL);
+EARLY_DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, NULL, NULL,
+ BUS_PASS_BUS);
#if defined(NEW_PCIB) || defined(PCI_HP)
SYSCTL_DECL(_hw_pci);
diff --git a/freebsd/sys/dev/pci/pci_user.c b/freebsd/sys/dev/pci/pci_user.c
index 27fb3475..3e2c3c7e 100644
--- a/freebsd/sys/dev/pci/pci_user.c
+++ b/freebsd/sys/dev/pci/pci_user.c
@@ -951,6 +951,9 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
if (!(flag & FWRITE)) {
switch (cmd) {
case PCIOCGETCONF:
+#ifdef COMPAT_FREEBSD32
+ case PCIOCGETCONF32:
+#endif
#ifdef PRE7_COMPAT
case PCIOCGETCONF_OLD:
#ifdef COMPAT_FREEBSD32
@@ -968,6 +971,9 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
switch (cmd) {
case PCIOCGETCONF:
+#ifdef COMPAT_FREEBSD32
+ case PCIOCGETCONF32:
+#endif
#ifdef PRE7_COMPAT
case PCIOCGETCONF_OLD:
#ifdef COMPAT_FREEBSD32
diff --git a/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h b/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h
index e30ae6be..432d7e97 100644
--- a/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h
+++ b/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h
@@ -118,6 +118,7 @@ static const STRUCT_USB_HOST_ID rtwn_devs[] = {
RTWN_RTL8188EU_DEV(DLINK, DWA123D1),
RTWN_RTL8188EU_DEV(DLINK, DWA125D1),
RTWN_RTL8188EU_DEV(ELECOM, WDC150SU2M),
+ RTWN_RTL8188EU_DEV(TPLINK, WN722NV2),
RTWN_RTL8188EU_DEV(REALTEK, RTL8188ETV),
RTWN_RTL8188EU_DEV(REALTEK, RTL8188EU),
#undef RTWN_RTL8188EU_DEV
@@ -139,6 +140,7 @@ static const STRUCT_USB_HOST_ID rtwn_devs[] = {
RTWN_RTL8812AU_DEV(SITECOMEU, WLA7100),
RTWN_RTL8812AU_DEV(TPLINK, T4U),
RTWN_RTL8812AU_DEV(TPLINK, T4UV2),
+ RTWN_RTL8812AU_DEV(TPLINK, T4UHV1),
RTWN_RTL8812AU_DEV(TPLINK, T4UHV2),
RTWN_RTL8812AU_DEV(TRENDNET, TEW805UB),
RTWN_RTL8812AU_DEV(ZYXEL, NWD6605),
diff --git a/freebsd/sys/dev/sdhci/sdhci.c b/freebsd/sys/dev/sdhci/sdhci.c
index ccbf5d85..0bb9edc7 100644
--- a/freebsd/sys/dev/sdhci/sdhci.c
+++ b/freebsd/sys/dev/sdhci/sdhci.c
@@ -900,6 +900,9 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num)
if (slot->quirks & SDHCI_QUIRK_CAPS_BIT63_FOR_MMC_HS400 &&
caps2 & SDHCI_CAN_MMC_HS400)
host_caps |= MMC_CAP_MMC_HS400;
+ if (slot->quirks & SDHCI_QUIRK_MMC_HS400_IF_CAN_SDR104 &&
+ caps2 & SDHCI_CAN_SDR104)
+ host_caps |= MMC_CAP_MMC_HS400;
/*
* Disable UHS-I and eMMC modes if the set_uhs_timing method is the
diff --git a/freebsd/sys/dev/sdhci/sdhci.h b/freebsd/sys/dev/sdhci/sdhci.h
index f2a7a9b1..a22e0235 100644
--- a/freebsd/sys/dev/sdhci/sdhci.h
+++ b/freebsd/sys/dev/sdhci/sdhci.h
@@ -93,6 +93,8 @@
#define SDHCI_QUIRK_PRESET_VALUE_BROKEN (1 << 27)
/* Controller does not support or the support for ACMD12 is broken. */
#define SDHCI_QUIRK_BROKEN_AUTO_STOP (1 << 28)
+/* Controller supports eMMC HS400 mode if SDHCI_CAN_SDR104 is set. */
+#define SDHCI_QUIRK_MMC_HS400_IF_CAN_SDR104 (1 << 29)
/*
* Controller registers
diff --git a/freebsd/sys/dev/usb/wlan/if_rsu.c b/freebsd/sys/dev/usb/wlan/if_rsu.c
index 1cb504cc..b730ce59 100644
--- a/freebsd/sys/dev/usb/wlan/if_rsu.c
+++ b/freebsd/sys/dev/usb/wlan/if_rsu.c
@@ -119,6 +119,7 @@ static const STRUCT_USB_HOST_ID rsu_devs[] = {
RSU_HT_NOT_SUPPORTED) }
RSU_DEV(ASUS, RTL8192SU),
RSU_DEV(AZUREWAVE, RTL8192SU_4),
+ RSU_DEV(SITECOMEU, WLA1000),
RSU_DEV_HT(ACCTON, RTL8192SU),
RSU_DEV_HT(ASUS, USBN10),
RSU_DEV_HT(AZUREWAVE, RTL8192SU_1),
diff --git a/freebsd/sys/kern/init_main.c b/freebsd/sys/kern/init_main.c
index 8fcc314b..c6a9e310 100644
--- a/freebsd/sys/kern/init_main.c
+++ b/freebsd/sys/kern/init_main.c
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
#include <sys/exec.h>
#include <sys/file.h>
#include <sys/filedesc.h>
+#include <sys/imgact.h>
#include <sys/jail.h>
#include <sys/ktr.h>
#include <sys/lock.h>
@@ -428,7 +429,6 @@ null_set_syscall_retval(struct thread *td __unused, int error __unused)
struct sysentvec null_sysvec = {
.sv_size = 0,
.sv_table = NULL,
- .sv_mask = 0,
.sv_errsize = 0,
.sv_errtbl = NULL,
.sv_transtrap = NULL,
@@ -744,15 +744,13 @@ SYSCTL_INT(_kern, OID_AUTO, init_shutdown_timeout,
static void
start_init(void *dummy)
{
- vm_offset_t addr;
- struct execve_args args;
- int options, error;
- size_t pathlen;
+ struct image_args args;
+ int error;
char *var, *path;
char *free_init_path, *tmp_init_path;
- char *ucp, **uap, *arg0, *arg1;
struct thread *td;
struct proc *p;
+ struct vmspace *oldvmspace;
TSENTER(); /* Here so we don't overlap with mi_startup. */
@@ -764,16 +762,6 @@ start_init(void *dummy)
/* Wipe GELI passphrase from the environment. */
kern_unsetenv("kern.geom.eli.passphrase");
- /*
- * Need just enough stack to hold the faked-up "execve()" arguments.
- */
- addr = p->p_sysent->sv_usrstack - PAGE_SIZE;
- if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, 0,
- VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
- panic("init: couldn't allocate argument space");
- p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
- p->p_vmspace->vm_ssize = 1;
-
if ((var = kern_getenv("init_path")) != NULL) {
strlcpy(init_path, var, sizeof(init_path));
freeenv(var);
@@ -781,58 +769,25 @@ start_init(void *dummy)
free_init_path = tmp_init_path = strdup(init_path, M_TEMP);
while ((path = strsep(&tmp_init_path, ":")) != NULL) {
- pathlen = strlen(path) + 1;
if (bootverbose)
printf("start_init: trying %s\n", path);
- /*
- * Move out the boot flag argument.
- */
- options = 0;
- ucp = (char *)p->p_sysent->sv_usrstack;
- (void)subyte(--ucp, 0); /* trailing zero */
- if (boothowto & RB_SINGLE) {
- (void)subyte(--ucp, 's');
- options = 1;
- }
-#ifdef notyet
- if (boothowto & RB_FASTBOOT) {
- (void)subyte(--ucp, 'f');
- options = 1;
- }
-#endif
-
-#ifdef BOOTCDROM
- (void)subyte(--ucp, 'C');
- options = 1;
-#endif
-
- if (options == 0)
- (void)subyte(--ucp, '-');
- (void)subyte(--ucp, '-'); /* leading hyphen */
- arg1 = ucp;
-
- /*
- * Move out the file name (also arg 0).
- */
- ucp -= pathlen;
- copyout(path, ucp, pathlen);
- arg0 = ucp;
-
- /*
- * Move out the arg pointers.
- */
- uap = (char **)rounddown2((intptr_t)ucp, sizeof(intptr_t));
- (void)suword((caddr_t)--uap, (long)0); /* terminator */
- (void)suword((caddr_t)--uap, (long)(intptr_t)arg1);
- (void)suword((caddr_t)--uap, (long)(intptr_t)arg0);
-
- /*
- * Point at the arguments.
- */
- args.fname = arg0;
- args.argv = uap;
- args.envv = NULL;
+ memset(&args, 0, sizeof(args));
+ error = exec_alloc_args(&args);
+ if (error != 0)
+ panic("%s: Can't allocate space for init arguments %d",
+ __func__, error);
+
+ error = exec_args_add_fname(&args, path, UIO_SYSSPACE);
+ if (error != 0)
+ panic("%s: Can't add fname %d", __func__, error);
+ error = exec_args_add_arg(&args, path, UIO_SYSSPACE);
+ if (error != 0)
+ panic("%s: Can't add argv[0] %d", __func__, error);
+ if (boothowto & RB_SINGLE)
+ error = exec_args_add_arg(&args, "-s", UIO_SYSSPACE);
+ if (error != 0)
+ panic("%s: Can't add argv[0] %d", __func__, error);
/*
* Now try to exec the program. If can't for any reason
@@ -841,7 +796,19 @@ start_init(void *dummy)
* Otherwise, return via fork_trampoline() all the way
* to user mode as init!
*/
- if ((error = sys_execve(td, &args)) == EJUSTRETURN) {
+ KASSERT((td->td_pflags & TDP_EXECVMSPC) == 0,
+ ("nested execve"));
+ oldvmspace = td->td_proc->p_vmspace;
+ error = kern_execve(td, &args, NULL);
+ KASSERT(error != 0,
+ ("kern_execve returned success, not EJUSTRETURN"));
+ if (error == EJUSTRETURN) {
+ if ((td->td_pflags & TDP_EXECVMSPC) != 0) {
+ KASSERT(p->p_vmspace != oldvmspace,
+ ("oldvmspace still used"));
+ vmspace_free(oldvmspace);
+ td->td_pflags &= ~TDP_EXECVMSPC;
+ }
free(free_init_path, M_TEMP);
TSEXIT();
return;
diff --git a/freebsd/sys/kern/kern_event.c b/freebsd/sys/kern/kern_event.c
index 2fae2d89..5c75c657 100644
--- a/freebsd/sys/kern/kern_event.c
+++ b/freebsd/sys/kern/kern_event.c
@@ -110,13 +110,13 @@ TASKQUEUE_DEFINE_THREAD(kqueue_ctx);
static int kevent_copyout(void *arg, struct kevent *kevp, int count);
static int kevent_copyin(void *arg, struct kevent *kevp, int count);
static int kqueue_register(struct kqueue *kq, struct kevent *kev,
- struct thread *td, int waitok);
+ struct thread *td, int mflag);
static int kqueue_acquire(struct file *fp, struct kqueue **kqp);
static void kqueue_release(struct kqueue *kq, int locked);
static void kqueue_destroy(struct kqueue *kq);
static void kqueue_drain(struct kqueue *kq, struct thread *td);
static int kqueue_expand(struct kqueue *kq, struct filterops *fops,
- uintptr_t ident, int waitok);
+ uintptr_t ident, int mflag);
static void kqueue_task(void *arg, int pending);
static int kqueue_scan(struct kqueue *kq, int maxevents,
struct kevent_copyops *k_ops,
@@ -165,7 +165,7 @@ static void knote_drop_detached(struct knote *kn, struct thread *td);
static void knote_enqueue(struct knote *kn);
static void knote_dequeue(struct knote *kn);
static void knote_init(void);
-static struct knote *knote_alloc(int waitok);
+static struct knote *knote_alloc(int mflag);
static void knote_free(struct knote *kn);
static void filt_kqdetach(struct knote *kn);
@@ -571,10 +571,12 @@ knote_fork(struct knlist *list, int pid)
struct kevent kev;
int error;
- if (list == NULL)
+ MPASS(list != NULL);
+ KNL_ASSERT_LOCKED(list);
+ if (SLIST_EMPTY(&list->kl_list))
return;
- list->kl_lock(list->kl_lockarg);
+ memset(&kev, 0, sizeof(kev));
SLIST_FOREACH(kn, &list->kl_list, kn_selnext) {
kq = kn->kn_kq;
KQ_LOCK(kq);
@@ -587,10 +589,8 @@ knote_fork(struct knlist *list, int pid)
* The same as knote(), activate the event.
*/
if ((kn->kn_sfflags & NOTE_TRACK) == 0) {
- kn->kn_status |= KN_HASKQLOCK;
if (kn->kn_fop->f_event(kn, NOTE_FORK))
KNOTE_ACTIVATE(kn, 1);
- kn->kn_status &= ~KN_HASKQLOCK;
KQ_UNLOCK(kq);
continue;
}
@@ -621,7 +621,7 @@ knote_fork(struct knlist *list, int pid)
kev.fflags = kn->kn_sfflags;
kev.data = kn->kn_id; /* parent */
kev.udata = kn->kn_kevent.udata;/* preserve udata */
- error = kqueue_register(kq, &kev, NULL, 0);
+ error = kqueue_register(kq, &kev, NULL, M_NOWAIT);
if (error)
kn->kn_fflags |= NOTE_TRACKERR;
@@ -635,17 +635,16 @@ knote_fork(struct knlist *list, int pid)
kev.fflags = kn->kn_sfflags;
kev.data = kn->kn_id; /* parent */
kev.udata = kn->kn_kevent.udata;/* preserve udata */
- error = kqueue_register(kq, &kev, NULL, 0);
+ error = kqueue_register(kq, &kev, NULL, M_NOWAIT);
if (error)
kn->kn_fflags |= NOTE_TRACKERR;
if (kn->kn_fop->f_event(kn, NOTE_FORK))
KNOTE_ACTIVATE(kn, 0);
+ list->kl_lock(list->kl_lockarg);
KQ_LOCK(kq);
kn_leave_flux(kn);
KQ_UNLOCK_FLUX(kq);
- list->kl_lock(list->kl_lockarg);
}
- list->kl_unlock(list->kl_lockarg);
}
#endif /* __rtems__ */
@@ -1352,7 +1351,7 @@ kqueue_kevent(struct kqueue *kq, struct thread *td, int nchanges, int nevents,
if (!kevp->filter)
continue;
kevp->flags &= ~EV_SYSFLAGS;
- error = kqueue_register(kq, kevp, td, 1);
+ error = kqueue_register(kq, kevp, td, M_WAITOK);
if (error || (kevp->flags & EV_RECEIPT)) {
if (nevents == 0)
return (error);
@@ -1495,12 +1494,11 @@ kqueue_fo_release(int filt)
}
/*
- * A ref to kq (obtained via kqueue_acquire) must be held. waitok will
- * influence if memory allocation should wait. Make sure it is 0 if you
- * hold any mutexes.
+ * A ref to kq (obtained via kqueue_acquire) must be held.
*/
static int
-kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int waitok)
+kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td,
+ int mflag)
{
struct filterops *fops;
struct file *fp;
@@ -1530,7 +1528,7 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int wa
* allocation failures are handled in the loop, only
* if the spare knote appears to be actually required.
*/
- tkn = knote_alloc(waitok);
+ tkn = knote_alloc(mflag);
} else {
tkn = NULL;
}
@@ -1546,11 +1544,11 @@ findkn:
goto done;
if ((kev->flags & EV_ADD) == EV_ADD && kqueue_expand(kq, fops,
- kev->ident, 0) != 0) {
+ kev->ident, M_NOWAIT) != 0) {
/* try again */
fdrop(fp, td);
fp = NULL;
- error = kqueue_expand(kq, fops, kev->ident, waitok);
+ error = kqueue_expand(kq, fops, kev->ident, mflag);
if (error)
goto done;
goto findkn;
@@ -1590,8 +1588,11 @@ findkn:
break;
}
} else {
- if ((kev->flags & EV_ADD) == EV_ADD)
- kqueue_expand(kq, fops, kev->ident, waitok);
+ if ((kev->flags & EV_ADD) == EV_ADD) {
+ error = kqueue_expand(kq, fops, kev->ident, mflag);
+ if (error != 0)
+ goto done;
+ }
KQ_LOCK(kq);
@@ -1663,6 +1664,8 @@ findkn:
kn->kn_kevent.flags &= ~(EV_ADD | EV_DELETE |
EV_ENABLE | EV_DISABLE | EV_FORCEONESHOT);
kn->kn_status = KN_DETACHED;
+ if ((kev->flags & EV_DISABLE) != 0)
+ kn->kn_status |= KN_DISABLED;
kn_enter_flux(kn);
error = knote_attach(kn, kq);
@@ -1698,6 +1701,11 @@ findkn:
KNOTE_ACTIVATE(kn, 1);
}
+ if ((kev->flags & EV_ENABLE) != 0)
+ kn->kn_status &= ~KN_DISABLED;
+ else if ((kev->flags & EV_DISABLE) != 0)
+ kn->kn_status |= KN_DISABLED;
+
/*
* The user may change some filter values after the initial EV_ADD,
* but doing so will not reset any filter which has already been
@@ -1715,19 +1723,17 @@ findkn:
kn->kn_sdata = kev->data;
}
+done_ev_add:
/*
* We can get here with kn->kn_knlist == NULL. This can happen when
* the initial attach event decides that the event is "completed"
- * already. i.e. filt_procattach is called on a zombie process. It
- * will call filt_proc which will remove it from the list, and NULL
+ * already, e.g., filt_procattach() is called on a zombie process. It
+ * will call filt_proc() which will remove it from the list, and NULL
* kn_knlist.
+ *
+ * KN_DISABLED will be stable while the knote is in flux, so the
+ * unlocked read will not race with an update.
*/
-done_ev_add:
- if ((kev->flags & EV_ENABLE) != 0)
- kn->kn_status &= ~KN_DISABLED;
- else if ((kev->flags & EV_DISABLE) != 0)
- kn->kn_status |= KN_DISABLED;
-
if ((kn->kn_status & KN_DISABLED) == 0)
event = kn->kn_fop->f_event(kn, 0);
else
@@ -1815,23 +1821,18 @@ kqueue_schedtask(struct kqueue *kq)
* Expand the kq to make sure we have storage for fops/ident pair.
*
* Return 0 on success (or no work necessary), return errno on failure.
- *
- * Not calling hashinit w/ waitok (proper malloc flag) should be safe.
- * If kqueue_register is called from a non-fd context, there usually/should
- * be no locks held.
*/
static int
kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
- int waitok)
+ int mflag)
{
struct klist *list, *tmp_knhash, *to_free;
u_long tmp_knhashmask;
- int size;
- int fd;
- int mflag = waitok ? M_WAITOK : M_NOWAIT;
+ int error, fd, size;
KQ_NOTOWNED(kq);
+ error = 0;
to_free = NULL;
if (fops->f_isfd) {
fd = ident;
@@ -1843,9 +1844,11 @@ kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
if (list == NULL)
return ENOMEM;
KQ_LOCK(kq);
- if (kq->kq_knlistsize > fd) {
+ if ((kq->kq_state & KQ_CLOSING) != 0) {
+ to_free = list;
+ error = EBADF;
+ } else if (kq->kq_knlistsize > fd) {
to_free = list;
- list = NULL;
} else {
if (kq->kq_knlist != NULL) {
bcopy(kq->kq_knlist, list,
@@ -1863,12 +1866,16 @@ kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
}
} else {
if (kq->kq_knhashmask == 0) {
- tmp_knhash = hashinit(KN_HASHSIZE, M_KQUEUE,
- &tmp_knhashmask);
+ tmp_knhash = hashinit_flags(KN_HASHSIZE, M_KQUEUE,
+ &tmp_knhashmask, (mflag & M_WAITOK) != 0 ?
+ HASH_WAITOK : HASH_NOWAIT);
if (tmp_knhash == NULL)
- return ENOMEM;
+ return (ENOMEM);
KQ_LOCK(kq);
- if (kq->kq_knhashmask == 0) {
+ if ((kq->kq_state & KQ_CLOSING) != 0) {
+ to_free = tmp_knhash;
+ error = EBADF;
+ } else if (kq->kq_knhashmask == 0) {
kq->kq_knhash = tmp_knhash;
kq->kq_knhashmask = tmp_knhashmask;
} else {
@@ -1880,7 +1887,7 @@ kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
free(to_free, M_KQUEUE);
KQ_NOTOWNED(kq);
- return 0;
+ return (error);
}
static void
@@ -1950,7 +1957,7 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent_copyops *k_ops,
asbt = -1;
} else
asbt = 0;
- marker = knote_alloc(1);
+ marker = knote_alloc(M_WAITOK);
marker->kn_status = KN_MARKER;
KQ_LOCK(kq);
@@ -2463,10 +2470,8 @@ knote(struct knlist *list, long hint, int lockflags)
KNOTE_ACTIVATE(kn, 1);
KQ_UNLOCK_FLUX(kq);
} else {
- kn->kn_status |= KN_HASKQLOCK;
if (kn->kn_fop->f_event(kn, hint))
KNOTE_ACTIVATE(kn, 1);
- kn->kn_status &= ~KN_HASKQLOCK;
KQ_UNLOCK(kq);
}
}
@@ -2807,6 +2812,8 @@ knote_attach(struct knote *kn, struct kqueue *kq)
KASSERT(kn_in_flux(kn), ("knote %p not marked influx", kn));
KQ_OWNED(kq);
+ if ((kq->kq_state & KQ_CLOSING) != 0)
+ return (EBADF);
if (kn->kn_fop->f_isfd) {
if (kn->kn_id >= kq->kq_knlistsize)
return (ENOMEM);
@@ -2902,11 +2909,10 @@ knote_init(void)
SYSINIT(knote, SI_SUB_PSEUDO, SI_ORDER_ANY, knote_init, NULL);
static struct knote *
-knote_alloc(int waitok)
+knote_alloc(int mflag)
{
- return (uma_zalloc(knote_zone, (waitok ? M_WAITOK : M_NOWAIT) |
- M_ZERO));
+ return (uma_zalloc(knote_zone, mflag | M_ZERO));
}
static void
@@ -2920,7 +2926,7 @@ knote_free(struct knote *kn)
* Register the kev w/ the kq specified by fd.
*/
int
-kqfd_register(int fd, struct kevent *kev, struct thread *td, int waitok)
+kqfd_register(int fd, struct kevent *kev, struct thread *td, int mflag)
{
struct kqueue *kq;
struct file *fp;
@@ -2933,7 +2939,7 @@ kqfd_register(int fd, struct kevent *kev, struct thread *td, int waitok)
if ((error = kqueue_acquire(fp, &kq)) != 0)
goto noacquire;
- error = kqueue_register(kq, kev, td, waitok);
+ error = kqueue_register(kq, kev, td, mflag);
kqueue_release(kq, 0);
noacquire:
diff --git a/freebsd/sys/kern/kern_intr.c b/freebsd/sys/kern/kern_intr.c
index 04914e93..4e311cb8 100644
--- a/freebsd/sys/kern/kern_intr.c
+++ b/freebsd/sys/kern/kern_intr.c
@@ -756,6 +756,28 @@ intr_event_barrier(struct intr_event *ie)
atomic_thread_fence_acq();
}
+static void
+intr_handler_barrier(struct intr_handler *handler)
+{
+ struct intr_event *ie;
+
+ ie = handler->ih_event;
+ mtx_assert(&ie->ie_lock, MA_OWNED);
+ KASSERT((handler->ih_flags & IH_DEAD) == 0,
+ ("update for a removed handler"));
+
+ if (ie->ie_thread == NULL) {
+ intr_event_barrier(ie);
+ return;
+ }
+ if ((handler->ih_flags & IH_CHANGED) == 0) {
+ handler->ih_flags |= IH_CHANGED;
+ intr_event_schedule_thread(ie);
+ }
+ while ((handler->ih_flags & IH_CHANGED) != 0)
+ msleep(handler, &ie->ie_lock, 0, "ih_barr", 0);
+}
+
/*
* Sleep until an ithread finishes executing an interrupt handler.
*
@@ -879,7 +901,50 @@ intr_event_remove_handler(void *cookie)
return (0);
}
+int
+intr_event_suspend_handler(void *cookie)
+{
+ struct intr_handler *handler = (struct intr_handler *)cookie;
+ struct intr_event *ie;
+
+ if (handler == NULL)
+ return (EINVAL);
+ ie = handler->ih_event;
+ KASSERT(ie != NULL,
+ ("interrupt handler \"%s\" has a NULL interrupt event",
+ handler->ih_name));
+ mtx_lock(&ie->ie_lock);
+ handler->ih_flags |= IH_SUSP;
+ intr_handler_barrier(handler);
+ mtx_unlock(&ie->ie_lock);
+ return (0);
+}
+
+int
+intr_event_resume_handler(void *cookie)
+{
+ struct intr_handler *handler = (struct intr_handler *)cookie;
+ struct intr_event *ie;
+
+ if (handler == NULL)
+ return (EINVAL);
+ ie = handler->ih_event;
+ KASSERT(ie != NULL,
+ ("interrupt handler \"%s\" has a NULL interrupt event",
+ handler->ih_name));
+
+ /*
+ * intr_handler_barrier() acts not only as a barrier,
+ * it also allows to check for any pending interrupts.
+ */
+ mtx_lock(&ie->ie_lock);
+ handler->ih_flags &= ~IH_SUSP;
+ intr_handler_barrier(handler);
+ mtx_unlock(&ie->ie_lock);
+ return (0);
+}
#endif /* __rtems__ */
+
static int
intr_event_schedule_thread(struct intr_event *ie)
{
@@ -1068,10 +1133,21 @@ intr_event_execute_handlers(struct proc *p, struct intr_event *ie)
*/
ihp = ih;
+ if ((ih->ih_flags & IH_CHANGED) != 0) {
+ mtx_lock(&ie->ie_lock);
+ ih->ih_flags &= ~IH_CHANGED;
+ wakeup(ih);
+ mtx_unlock(&ie->ie_lock);
+ }
+
/* Skip filter only handlers */
if (ih->ih_handler == NULL)
continue;
+ /* Skip suspended handlers */
+ if ((ih->ih_flags & IH_SUSP) != 0)
+ continue;
+
/*
* For software interrupt threads, we only execute
* handlers that have their need flag set. Hardware
@@ -1255,8 +1331,9 @@ intr_event_handle(struct intr_event *ie, struct trapframe *frame)
struct intr_handler *ih;
struct trapframe *oldframe;
struct thread *td;
- int ret, thread;
int phase;
+ int ret;
+ bool filter, thread;
td = curthread;
@@ -1275,7 +1352,8 @@ intr_event_handle(struct intr_event *ie, struct trapframe *frame)
* a trapframe as its argument.
*/
td->td_intr_nesting_level++;
- thread = 0;
+ filter = false;
+ thread = false;
ret = 0;
critical_enter();
oldframe = td->td_intr_frame;
@@ -1291,8 +1369,10 @@ intr_event_handle(struct intr_event *ie, struct trapframe *frame)
atomic_thread_fence_seq_cst();
CK_SLIST_FOREACH(ih, &ie->ie_handlers, ih_next) {
+ if ((ih->ih_flags & IH_SUSP) != 0)
+ continue;
if (ih->ih_filter == NULL) {
- thread = 1;
+ thread = true;
continue;
}
CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__,
@@ -1307,24 +1387,25 @@ intr_event_handle(struct intr_event *ie, struct trapframe *frame)
(ret & ~(FILTER_SCHEDULE_THREAD | FILTER_HANDLED)) == 0),
("%s: incorrect return value %#x from %s", __func__, ret,
ih->ih_name));
+ filter = filter || ret == FILTER_HANDLED;
- /*
+ /*
* Wrapper handler special handling:
*
- * in some particular cases (like pccard and pccbb),
+ * in some particular cases (like pccard and pccbb),
* the _real_ device handler is wrapped in a couple of
* functions - a filter wrapper and an ithread wrapper.
- * In this case (and just in this case), the filter wrapper
+ * In this case (and just in this case), the filter wrapper
* could ask the system to schedule the ithread and mask
* the interrupt source if the wrapped handler is composed
* of just an ithread handler.
*
- * TODO: write a generic wrapper to avoid people rolling
- * their own
+ * TODO: write a generic wrapper to avoid people rolling
+ * their own.
*/
if (!thread) {
if (ret == FILTER_SCHEDULE_THREAD)
- thread = 1;
+ thread = true;
}
}
atomic_add_rel_int(&ie->ie_active[phase], -1);
@@ -1348,6 +1429,11 @@ intr_event_handle(struct intr_event *ie, struct trapframe *frame)
}
critical_exit();
td->td_intr_nesting_level--;
+#ifdef notyet
+ /* The interrupt is not aknowledged by any filter and has no ithread. */
+ if (!thread && !filter)
+ return (EINVAL);
+#endif
return (0);
}
diff --git a/freebsd/sys/kern/kern_synch.c b/freebsd/sys/kern/kern_synch.c
index 9c0d1206..2597f91d 100644
--- a/freebsd/sys/kern/kern_synch.c
+++ b/freebsd/sys/kern/kern_synch.c
@@ -466,7 +466,7 @@ mi_switch(int flags, struct thread *newtd)
CTR4(KTR_PROC, "mi_switch: old thread %ld (td_sched %p, pid %ld, %s)",
td->td_tid, td_get_sched(td), td->td_proc->p_pid, td->td_name);
#ifdef KDTRACE_HOOKS
- if (__predict_false(sdt_probes_enabled) &&
+ if (SDT_PROBES_ENABLED() &&
((flags & SW_PREEMPT) != 0 || ((flags & SW_INVOL) != 0 &&
(flags & SW_TYPE_MASK) == SWT_NEEDRESCHED)))
SDT_PROBE0(sched, , , preempt);
diff --git a/freebsd/sys/kern/kern_sysctl.c b/freebsd/sys/kern/kern_sysctl.c
index ea9c1821..dc7c4c72 100644
--- a/freebsd/sys/kern/kern_sysctl.c
+++ b/freebsd/sys/kern/kern_sysctl.c
@@ -552,10 +552,10 @@ sysctl_unregister_oid(struct sysctl_oid *oidp)
int error;
SYSCTL_ASSERT_WLOCKED();
- error = ENOENT;
if (oidp->oid_number == OID_AUTO) {
error = EINVAL;
} else {
+ error = ENOENT;
SLIST_FOREACH(p, oidp->oid_parent, oid_link) {
if (p == oidp) {
SLIST_REMOVE(oidp->oid_parent, oidp,
@@ -571,8 +571,10 @@ sysctl_unregister_oid(struct sysctl_oid *oidp)
* being unloaded afterwards. It should not be a panic()
* for normal use.
*/
- if (error)
- printf("%s: failed to unregister sysctl\n", __func__);
+ if (error) {
+ printf("%s: failed(%d) to unregister sysctl(%s)\n",
+ __func__, error, oidp->oid_name);
+ }
}
/* Initialize a new context to keep track of dynamically added sysctls. */
@@ -1714,13 +1716,13 @@ sysctl_usec_to_sbintime(SYSCTL_HANDLER_ARGS)
sbintime_t sb;
tt = *(int64_t *)arg1;
- sb = ustosbt(tt);
+ sb = sbttous(tt);
error = sysctl_handle_64(oidp, &sb, 0, req);
if (error || !req->newptr)
return (error);
- tt = sbttous(sb);
+ tt = ustosbt(sb);
*(int64_t *)arg1 = tt;
return (0);
@@ -1737,13 +1739,13 @@ sysctl_msec_to_sbintime(SYSCTL_HANDLER_ARGS)
sbintime_t sb;
tt = *(int64_t *)arg1;
- sb = mstosbt(tt);
+ sb = sbttoms(tt);
error = sysctl_handle_64(oidp, &sb, 0, req);
if (error || !req->newptr)
return (error);
- tt = sbttoms(sb);
+ tt = mstosbt(sb);
*(int64_t *)arg1 = tt;
return (0);
@@ -1782,7 +1784,7 @@ sysctl_new_kernel(struct sysctl_req *req, void *p, size_t l)
return (0);
if (req->newlen - req->newidx < l)
return (EINVAL);
- bcopy((char *)req->newptr + req->newidx, p, l);
+ bcopy((const char *)req->newptr + req->newidx, p, l);
req->newidx += l;
return (0);
}
@@ -1919,7 +1921,7 @@ sysctl_new_user(struct sysctl_req *req, void *p, size_t l)
return (EINVAL);
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
"sysctl_new_user()");
- error = copyin((char *)req->newptr + req->newidx, p, l);
+ error = copyin((const char *)req->newptr + req->newidx, p, l);
req->newidx += l;
return (error);
}
@@ -2153,8 +2155,8 @@ sys___sysctl(struct thread *td, struct sysctl_args *uap)
*/
int
userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
- size_t *oldlenp, int inkernel, void *new, size_t newlen, size_t *retval,
- int flags)
+ size_t *oldlenp, int inkernel, const void *new, size_t newlen,
+ size_t *retval, int flags)
{
int error = 0, memlocked;
struct sysctl_req req;
diff --git a/freebsd/sys/kern/subr_blist.c b/freebsd/sys/kern/subr_blist.c
index 79a5a7b4..807a7f3c 100644
--- a/freebsd/sys/kern/subr_blist.c
+++ b/freebsd/sys/kern/subr_blist.c
@@ -297,9 +297,9 @@ blist_alloc(blist_t bl, daddr_t count)
* This loop iterates at most twice. An allocation failure in the
* first iteration leads to a second iteration only if the cursor was
* non-zero. When the cursor is zero, an allocation failure will
- * reduce the hint, stopping further iterations.
+ * stop further iterations.
*/
- while (count <= bl->bl_root->bm_bighint) {
+ for (;;) {
blk = blst_meta_alloc(bl->bl_root, bl->bl_cursor, count,
bl->bl_radix);
if (blk != SWAPBLK_NONE) {
@@ -308,10 +308,10 @@ blist_alloc(blist_t bl, daddr_t count)
if (bl->bl_cursor == bl->bl_blocks)
bl->bl_cursor = 0;
return (blk);
- }
+ } else if (bl->bl_cursor == 0)
+ return (SWAPBLK_NONE);
bl->bl_cursor = 0;
}
- return (SWAPBLK_NONE);
}
/*
@@ -646,14 +646,14 @@ blst_next_leaf_alloc(blmeta_t *scan, daddr_t blk, int count)
/*
* BLST_LEAF_ALLOC() - allocate at a leaf in the radix tree (a bitmap).
*
- * This is the core of the allocator and is optimized for the
- * BLIST_BMAP_RADIX block allocation case. Otherwise, execution
- * time is proportional to log2(count) + bitpos time.
+ * This function is the core of the allocator. Its execution time is
+ * proportional to log(count), plus height of the tree if the allocation
+ * crosses a leaf boundary.
*/
static daddr_t
blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count)
{
- u_daddr_t mask;
+ u_daddr_t cursor_mask, mask;
int count1, hi, lo, num_shifts, range1, range_ext;
range1 = 0;
@@ -663,14 +663,14 @@ blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count)
while ((-mask & ~mask) != 0 && num_shifts > 0) {
/*
* If bit i is set in mask, then bits in [i, i+range1] are set
- * in scan->bm_bitmap. The value of range1 is equal to
- * count1 >> num_shifts. Grow range and reduce num_shifts to 0,
- * while preserving these invariants. The updates to mask leave
- * fewer bits set, but each bit that remains set represents a
- * longer string of consecutive bits set in scan->bm_bitmap.
- * If more updates to mask cannot clear more bits, because mask
- * is partitioned with all 0 bits preceding all 1 bits, the loop
- * terminates immediately.
+ * in scan->bm_bitmap. The value of range1 is equal to count1
+ * >> num_shifts. Grow range1 and reduce num_shifts to 0,
+ * while preserving these invariants. The updates to mask
+ * leave fewer bits set, but each bit that remains set
+ * represents a longer string of consecutive bits set in
+ * scan->bm_bitmap. If more updates to mask cannot clear more
+ * bits, because mask is partitioned with all 0 bits preceding
+ * all 1 bits, the loop terminates immediately.
*/
num_shifts--;
range_ext = range1 + ((count1 >> num_shifts) & 1);
@@ -693,9 +693,22 @@ blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count)
}
/* Discard any candidates that appear before blk. */
- mask &= (u_daddr_t)-1 << (blk & BLIST_BMAP_MASK);
- if (mask == 0)
- return (SWAPBLK_NONE);
+ if ((blk & BLIST_BMAP_MASK) != 0) {
+ cursor_mask = mask & bitrange(0, blk & BLIST_BMAP_MASK);
+ if (cursor_mask != 0) {
+ mask ^= cursor_mask;
+ if (mask == 0)
+ return (SWAPBLK_NONE);
+
+ /*
+ * Bighint change for last block allocation cannot
+ * assume that any other blocks are allocated, so the
+ * bighint cannot be reduced much.
+ */
+ range1 = BLIST_MAX_ALLOC - 1;
+ }
+ blk &= ~BLIST_BMAP_MASK;
+ }
/*
* The least significant set bit in mask marks the start of the first
@@ -736,7 +749,7 @@ blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count)
}
/* Clear the allocated bits from this leaf. */
scan->bm_bitmap &= ~mask;
- return ((blk & ~BLIST_BMAP_MASK) + lo);
+ return (blk + lo);
}
/*
@@ -766,6 +779,8 @@ blst_meta_alloc(blmeta_t *scan, daddr_t cursor, daddr_t count, u_daddr_t radix)
/* Discard any candidates that appear before cursor. */
digit = (cursor / radix) & BLIST_META_MASK;
mask &= (u_daddr_t)-1 << digit;
+ if (mask == 0)
+ return (SWAPBLK_NONE);
/*
* If the first try is for a block that includes the cursor, pre-undo
diff --git a/freebsd/sys/kern/subr_bus.c b/freebsd/sys/kern/subr_bus.c
index 391b2ed6..a87c02a5 100644
--- a/freebsd/sys/kern/subr_bus.c
+++ b/freebsd/sys/kern/subr_bus.c
@@ -2821,6 +2821,16 @@ device_set_devclass_fixed(device_t dev, const char *classname)
}
/**
+ * @brief Query the device to determine if it's of a fixed devclass
+ * @see device_set_devclass_fixed()
+ */
+bool
+device_is_devclass_fixed(device_t dev)
+{
+ return ((dev->flags & DF_FIXEDCLASS) != 0);
+}
+
+/**
* @brief Set the driver of a device
*
* @retval 0 success
@@ -4101,6 +4111,36 @@ bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq,
}
/**
+ * @brief Helper function for implementing BUS_SUSPEND_INTR().
+ *
+ * This simple implementation of BUS_SUSPEND_INTR() simply calls the
+ * BUS_SUSPEND_INTR() method of the parent of @p dev.
+ */
+int
+bus_generic_suspend_intr(device_t dev, device_t child, struct resource *irq)
+{
+ /* Propagate up the bus hierarchy until someone handles it. */
+ if (dev->parent)
+ return (BUS_SUSPEND_INTR(dev->parent, child, irq));
+ return (EINVAL);
+}
+
+/**
+ * @brief Helper function for implementing BUS_RESUME_INTR().
+ *
+ * This simple implementation of BUS_RESUME_INTR() simply calls the
+ * BUS_RESUME_INTR() method of the parent of @p dev.
+ */
+int
+bus_generic_resume_intr(device_t dev, device_t child, struct resource *irq)
+{
+ /* Propagate up the bus hierarchy until someone handles it. */
+ if (dev->parent)
+ return (BUS_RESUME_INTR(dev->parent, child, irq));
+ return (EINVAL);
+}
+
+/**
* @brief Helper function for implementing BUS_ADJUST_RESOURCE().
*
* This simple implementation of BUS_ADJUST_RESOURCE() simply calls the
@@ -4668,6 +4708,34 @@ bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
}
/**
+ * @brief Wrapper function for BUS_SUSPEND_INTR().
+ *
+ * This function simply calls the BUS_SUSPEND_INTR() method of the
+ * parent of @p dev.
+ */
+int
+bus_suspend_intr(device_t dev, struct resource *r)
+{
+ if (dev->parent == NULL)
+ return (EINVAL);
+ return (BUS_SUSPEND_INTR(dev->parent, dev, r));
+}
+
+/**
+ * @brief Wrapper function for BUS_RESUME_INTR().
+ *
+ * This function simply calls the BUS_RESUME_INTR() method of the
+ * parent of @p dev.
+ */
+int
+bus_resume_intr(device_t dev, struct resource *r)
+{
+ if (dev->parent == NULL)
+ return (EINVAL);
+ return (BUS_RESUME_INTR(dev->parent, dev, r));
+}
+
+/**
* @brief Wrapper function for BUS_BIND_INTR().
*
* This function simply calls the BUS_BIND_INTR() method of the
diff --git a/freebsd/sys/kern/subr_rman.c b/freebsd/sys/kern/subr_rman.c
index 75f22dd5..e307df46 100644
--- a/freebsd/sys/kern/subr_rman.c
+++ b/freebsd/sys/kern/subr_rman.c
@@ -96,6 +96,7 @@ struct resource_i {
rman_res_t r_end; /* index of the last entry (inclusive) */
u_int r_flags;
void *r_virtual; /* virtual address of this resource */
+ void *r_irq_cookie; /* interrupt cookie for this (interrupt) resource */
device_t r_dev; /* device which has allocated this resource */
struct rman *r_rm; /* resource manager from whence this came */
int r_rid; /* optional rid for this resource. */
@@ -871,6 +872,20 @@ rman_get_virtual(struct resource *r)
}
void
+rman_set_irq_cookie(struct resource *r, void *c)
+{
+
+ r->__r_i->r_irq_cookie = c;
+}
+
+void *
+rman_get_irq_cookie(struct resource *r)
+{
+
+ return (r->__r_i->r_irq_cookie);
+}
+
+void
rman_set_bustag(struct resource *r, bus_space_tag_t t)
{
diff --git a/freebsd/sys/kern/subr_taskqueue.c b/freebsd/sys/kern/subr_taskqueue.c
index 60057f78..39d9f939 100644
--- a/freebsd/sys/kern/subr_taskqueue.c
+++ b/freebsd/sys/kern/subr_taskqueue.c
@@ -375,13 +375,13 @@ taskqueue_task_nop_fn(void *context, int pending)
* have begun execution. Tasks queued during execution of
* this function are ignored.
*/
-static void
+static int
taskqueue_drain_tq_queue(struct taskqueue *queue)
{
struct task t_barrier;
if (STAILQ_EMPTY(&queue->tq_queue))
- return;
+ return (0);
/*
* Enqueue our barrier after all current tasks, but with
@@ -401,6 +401,7 @@ taskqueue_drain_tq_queue(struct taskqueue *queue)
*/
while (t_barrier.ta_pending != 0)
TQ_SLEEP(queue, &t_barrier, &queue->tq_mutex, PWAIT, "-", 0);
+ return (1);
}
/*
@@ -408,13 +409,13 @@ taskqueue_drain_tq_queue(struct taskqueue *queue)
* complete. Tasks that begin execution during the execution
* of this function are ignored.
*/
-static void
+static int
taskqueue_drain_tq_active(struct taskqueue *queue)
{
struct taskqueue_busy tb_marker, *tb_first;
if (TAILQ_EMPTY(&queue->tq_active))
- return;
+ return (0);
/* Block taskq_terminate().*/
queue->tq_callouts++;
@@ -441,6 +442,7 @@ taskqueue_drain_tq_active(struct taskqueue *queue)
queue->tq_callouts--;
if ((queue->tq_flags & TQ_FLAGS_ACTIVE) == 0)
wakeup_one(queue->tq_threads);
+ return (1);
}
void
@@ -615,8 +617,8 @@ taskqueue_drain_all(struct taskqueue *queue)
#endif /* __rtems__ */
TQ_LOCK(queue);
- taskqueue_drain_tq_queue(queue);
- taskqueue_drain_tq_active(queue);
+ (void)taskqueue_drain_tq_queue(queue);
+ (void)taskqueue_drain_tq_active(queue);
TQ_UNLOCK(queue);
}
@@ -645,6 +647,20 @@ taskqueue_drain_timeout(struct taskqueue *queue,
TQ_UNLOCK(queue);
}
+void
+taskqueue_quiesce(struct taskqueue *queue)
+{
+ int ret;
+
+ TQ_LOCK(queue);
+ do {
+ ret = taskqueue_drain_tq_queue(queue);
+ if (ret == 0)
+ ret = taskqueue_drain_tq_active(queue);
+ } while (ret != 0);
+ TQ_UNLOCK(queue);
+}
+
static void
taskqueue_swi_enqueue(void *context)
{
diff --git a/freebsd/sys/kern/subr_unit.c b/freebsd/sys/kern/subr_unit.c
index 426253dc..c4bdea34 100644
--- a/freebsd/sys/kern/subr_unit.c
+++ b/freebsd/sys/kern/subr_unit.c
@@ -100,6 +100,19 @@ static struct mtx unitmtx;
MTX_SYSINIT(unit, &unitmtx, "unit# allocation", MTX_DEF);
+#ifdef UNR64_LOCKED
+uint64_t
+alloc_unr64(struct unrhdr64 *unr64)
+{
+ uint64_t item;
+
+ mtx_lock(&unitmtx);
+ item = unr64->counter++;
+ mtx_unlock(&unitmtx);
+ return (item);
+}
+#endif
+
#else /* ...USERLAND */
#include <bitstring.h>
diff --git a/freebsd/sys/kern/sys_pipe.c b/freebsd/sys/kern/sys_pipe.c
index b6616271..050d63a4 100755
--- a/freebsd/sys/kern/sys_pipe.c
+++ b/freebsd/sys/kern/sys_pipe.c
@@ -294,7 +294,7 @@ static int pipe_zone_init(void *mem, int size, int flags);
static void pipe_zone_fini(void *mem, int size);
static uma_zone_t pipe_zone;
-static struct unrhdr *pipeino_unr;
+static struct unrhdr64 pipeino_unr;
static dev_t pipedev_ino;
SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_ANY, pipeinit, NULL);
@@ -307,8 +307,7 @@ pipeinit(void *dummy __unused)
pipe_zone_ctor, NULL, pipe_zone_init, pipe_zone_fini,
UMA_ALIGN_PTR, 0);
KASSERT(pipe_zone != NULL, ("pipe_zone not initialized"));
- pipeino_unr = new_unrhdr(1, INT32_MAX, NULL);
- KASSERT(pipeino_unr != NULL, ("pipe fake inodes not initialized"));
+ new_unrhdr64(&pipeino_unr, 1);
pipedev_ino = devfs_alloc_cdp_inode();
KASSERT(pipedev_ino > 0, ("pipe dev inode not initialized"));
}
@@ -444,8 +443,6 @@ pipe_dtor(struct pipe *dpipe)
funsetown(&peer->pipe_sigio);
pipeclose(peer);
}
- if (ino != 0 && ino != (ino_t)-1)
- free_unr(pipeino_unr, ino);
}
/*
@@ -730,7 +727,7 @@ pipe_create(struct pipe *pipe, int backing)
(void)pipespace_new(pipe, PIPE_SIZE);
}
- pipe->pipe_ino = -1;
+ pipe->pipe_ino = alloc_unr64(&pipeino_unr);
}
/* ARGSUSED */
@@ -1762,7 +1759,6 @@ static int
pipe_stat(struct pipe *pipe, struct stat *ub)
{
#endif /* __rtems__ */
- int new_unr;
#ifdef MAC
int error;
#endif
@@ -1789,23 +1785,6 @@ pipe_stat(struct pipe *pipe, struct stat *ub)
#endif /* __rtems__ */
}
- /*
- * Lazily allocate an inode number for the pipe. Most pipe
- * users do not call fstat(2) on the pipe, which means that
- * postponing the inode allocation until it is must be
- * returned to userland is useful. If alloc_unr failed,
- * assign st_ino zero instead of returning an error.
- * Special pipe_ino values:
- * -1 - not yet initialized;
- * 0 - alloc_unr failed, return 0 as st_ino forever.
- */
- if (pipe->pipe_ino == (ino_t)-1) {
- new_unr = alloc_unr(pipeino_unr);
- if (new_unr != -1)
- pipe->pipe_ino = new_unr;
- else
- pipe->pipe_ino = 0;
- }
PIPE_UNLOCK(pipe);
#ifndef __rtems__
diff --git a/freebsd/sys/kern/uipc_sockbuf.c b/freebsd/sys/kern/uipc_sockbuf.c
index cf99c615..0830206a 100644
--- a/freebsd/sys/kern/uipc_sockbuf.c
+++ b/freebsd/sys/kern/uipc_sockbuf.c
@@ -1230,53 +1230,6 @@ sbdrop(struct sockbuf *sb, int len)
m_freem(mfree);
}
-/*
- * Maintain a pointer and offset pair into the socket buffer mbuf chain to
- * avoid traversal of the entire socket buffer for larger offsets.
- */
-struct mbuf *
-sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff)
-{
- struct mbuf *m, *ret;
-
- KASSERT(sb->sb_mb != NULL, ("%s: sb_mb is NULL", __func__));
- KASSERT(off + len <= sb->sb_acc, ("%s: beyond sb", __func__));
- KASSERT(sb->sb_sndptroff <= sb->sb_acc, ("%s: sndptroff broken", __func__));
-
- /*
- * Is off below stored offset? Happens on retransmits.
- * Just return, we can't help here.
- */
- if (sb->sb_sndptroff > off) {
- *moff = off;
- return (sb->sb_mb);
- }
-
- /* Return closest mbuf in chain for current offset. */
- *moff = off - sb->sb_sndptroff;
- m = ret = sb->sb_sndptr ? sb->sb_sndptr : sb->sb_mb;
- if (*moff == m->m_len) {
- *moff = 0;
- sb->sb_sndptroff += m->m_len;
- m = ret = m->m_next;
- KASSERT(ret->m_len > 0,
- ("mbuf %p in sockbuf %p chain has no valid data", ret, sb));
- }
-
- /* Advance by len to be as close as possible for the next transmit. */
- for (off = off - sb->sb_sndptroff + len - 1;
- off > 0 && m != NULL && off >= m->m_len;
- m = m->m_next) {
- sb->sb_sndptroff += m->m_len;
- off -= m->m_len;
- }
- if (off > 0 && m == NULL)
- panic("%s: sockbuf %p and mbuf %p clashing", __func__, sb, ret);
- sb->sb_sndptr = m;
-
- return (ret);
-}
-
struct mbuf *
#ifndef __rtems__
sbsndptr_noadv(struct sockbuf *sb, uint32_t off, uint32_t *moff)
diff --git a/freebsd/sys/kern/uipc_socket.c b/freebsd/sys/kern/uipc_socket.c
index aa045cd9..380c97dd 100644
--- a/freebsd/sys/kern/uipc_socket.c
+++ b/freebsd/sys/kern/uipc_socket.c
@@ -4063,6 +4063,7 @@ void
sotoxsocket(struct socket *so, struct xsocket *xso)
{
+ bzero(xso, sizeof(*xso));
xso->xso_len = sizeof *xso;
xso->xso_so = (uintptr_t)so;
xso->so_type = so->so_type;
@@ -4085,8 +4086,6 @@ sotoxsocket(struct socket *so, struct xsocket *xso)
xso->so_incqlen = so->sol_incqlen;
xso->so_qlimit = so->sol_qlimit;
xso->so_oobmark = 0;
- bzero(&xso->so_snd, sizeof(xso->so_snd));
- bzero(&xso->so_rcv, sizeof(xso->so_rcv));
} else {
xso->so_state |= so->so_qstate;
xso->so_qlen = xso->so_incqlen = xso->so_qlimit = 0;
diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c
index f338629e..529268a9 100644
--- a/freebsd/sys/kern/uipc_syscalls.c
+++ b/freebsd/sys/kern/uipc_syscalls.c
@@ -643,9 +643,7 @@ sys_accept4(td, uap)
#ifdef COMPAT_OLDSOCK
int
-oaccept(td, uap)
- struct thread *td;
- struct accept_args *uap;
+oaccept(struct thread *td, struct oaccept_args *uap)
{
return (accept1(td, uap->s, uap->name, uap->anamelen,
diff --git a/freebsd/sys/kern/uipc_usrreq.c b/freebsd/sys/kern/uipc_usrreq.c
index c1885ed6..6b34dcb8 100644
--- a/freebsd/sys/kern/uipc_usrreq.c
+++ b/freebsd/sys/kern/uipc_usrreq.c
@@ -551,6 +551,7 @@ uipc_attach(struct socket *so, int proto, struct thread *td)
UNP_LINK_WLOCK();
unp->unp_gencnt = ++unp_gencnt;
+ unp->unp_ino = ++unp_ino;
unp_count++;
switch (so->so_type) {
case SOCK_STREAM:
@@ -1434,12 +1435,8 @@ uipc_sense(struct socket *so, struct stat *sb)
KASSERT(unp != NULL, ("uipc_sense: unp == NULL"));
sb->st_blksize = so->so_snd.sb_hiwat;
- UNP_PCB_LOCK(unp);
sb->st_dev = NODEV;
- if (unp->unp_ino == 0)
- unp->unp_ino = (++unp_ino == 0) ? ++unp_ino : unp_ino;
sb->st_ino = unp->unp_ino;
- UNP_PCB_UNLOCK(unp);
return (0);
}
@@ -1993,7 +1990,7 @@ unp_pcblist(SYSCTL_HANDLER_ARGS)
/*
* OK, now we're committed to doing something.
*/
- xug = malloc(sizeof(*xug), M_TEMP, M_WAITOK);
+ xug = malloc(sizeof(*xug), M_TEMP, M_WAITOK | M_ZERO);
UNP_LINK_RLOCK();
gencnt = unp_gencnt;
n = unp_count;
diff --git a/freebsd/sys/net/altq/altq.h b/freebsd/sys/net/altq/altq.h
index 35024461..731fead4 100644
--- a/freebsd/sys/net/altq/altq.h
+++ b/freebsd/sys/net/altq/altq.h
@@ -38,16 +38,6 @@
#define ALTQ3_CLFIER_COMPAT /* for compatibility with altq-3 classifier */
#endif
-#ifdef ALTQ3_COMPAT
-#include <sys/param.h>
-#include <sys/ioccom.h>
-#include <sys/queue.h>
-#include <netinet/in.h>
-
-#ifndef IFNAMSIZ
-#define IFNAMSIZ 16
-#endif
-#endif /* ALTQ3_COMPAT */
/* altq discipline type */
#define ALTQT_NONE 0 /* reserved */
@@ -67,12 +57,6 @@
#define ALTQT_CODEL 14 /* CoDel */
#define ALTQT_MAX 15 /* should be max discipline type + 1 */
-#ifdef ALTQ3_COMPAT
-struct altqreq {
- char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
- u_long arg; /* request-specific argument */
-};
-#endif
/* simple token backet meter profile */
struct tb_profile {
@@ -80,85 +64,6 @@ struct tb_profile {
u_int32_t depth; /* depth in bytes */
};
-#ifdef ALTQ3_COMPAT
-struct tbrreq {
- char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
- struct tb_profile tb_prof; /* token bucket profile */
-};
-
-#ifdef ALTQ3_CLFIER_COMPAT
-/*
- * common network flow info structure
- */
-struct flowinfo {
- u_char fi_len; /* total length */
- u_char fi_family; /* address family */
- u_int8_t fi_data[46]; /* actually longer; address family
- specific flow info. */
-};
-
-/*
- * flow info structure for internet protocol family.
- * (currently this is the only protocol family supported)
- */
-struct flowinfo_in {
- u_char fi_len; /* sizeof(struct flowinfo_in) */
- u_char fi_family; /* AF_INET */
- u_int8_t fi_proto; /* IPPROTO_XXX */
- u_int8_t fi_tos; /* type-of-service */
- struct in_addr fi_dst; /* dest address */
- struct in_addr fi_src; /* src address */
- u_int16_t fi_dport; /* dest port */
- u_int16_t fi_sport; /* src port */
- u_int32_t fi_gpi; /* generalized port id for ipsec */
- u_int8_t _pad[28]; /* make the size equal to
- flowinfo_in6 */
-};
-
-#ifdef SIN6_LEN
-struct flowinfo_in6 {
- u_char fi6_len; /* sizeof(struct flowinfo_in6) */
- u_char fi6_family; /* AF_INET6 */
- u_int8_t fi6_proto; /* IPPROTO_XXX */
- u_int8_t fi6_tclass; /* traffic class */
- u_int32_t fi6_flowlabel; /* ipv6 flowlabel */
- u_int16_t fi6_dport; /* dest port */
- u_int16_t fi6_sport; /* src port */
- u_int32_t fi6_gpi; /* generalized port id */
- struct in6_addr fi6_dst; /* dest address */
- struct in6_addr fi6_src; /* src address */
-};
-#endif /* INET6 */
-
-/*
- * flow filters for AF_INET and AF_INET6
- */
-struct flow_filter {
- int ff_ruleno;
- struct flowinfo_in ff_flow;
- struct {
- struct in_addr mask_dst;
- struct in_addr mask_src;
- u_int8_t mask_tos;
- u_int8_t _pad[3];
- } ff_mask;
- u_int8_t _pad2[24]; /* make the size equal to flow_filter6 */
-};
-
-#ifdef SIN6_LEN
-struct flow_filter6 {
- int ff_ruleno;
- struct flowinfo_in6 ff_flow6;
- struct {
- struct in6_addr mask6_dst;
- struct in6_addr mask6_src;
- u_int8_t mask6_tclass;
- u_int8_t _pad[3];
- } ff_mask6;
-};
-#endif /* INET6 */
-#endif /* ALTQ3_CLFIER_COMPAT */
-#endif /* ALTQ3_COMPAT */
/*
* generic packet counter
@@ -171,33 +76,6 @@ struct pktcntr {
#define PKTCNTR_ADD(cntr, len) \
do { (cntr)->packets++; (cntr)->bytes += len; } while (/*CONSTCOND*/ 0)
-#ifdef ALTQ3_COMPAT
-/*
- * altq related ioctls
- */
-#define ALTQGTYPE _IOWR('q', 0, struct altqreq) /* get queue type */
-#if 0
-/*
- * these ioctls are currently discipline-specific but could be shared
- * in the future.
- */
-#define ALTQATTACH _IOW('q', 1, struct altqreq) /* attach discipline */
-#define ALTQDETACH _IOW('q', 2, struct altqreq) /* detach discipline */
-#define ALTQENABLE _IOW('q', 3, struct altqreq) /* enable discipline */
-#define ALTQDISABLE _IOW('q', 4, struct altqreq) /* disable discipline*/
-#define ALTQCLEAR _IOW('q', 5, struct altqreq) /* (re)initialize */
-#define ALTQCONFIG _IOWR('q', 6, struct altqreq) /* set config params */
-#define ALTQADDCLASS _IOWR('q', 7, struct altqreq) /* add a class */
-#define ALTQMODCLASS _IOWR('q', 8, struct altqreq) /* modify a class */
-#define ALTQDELCLASS _IOWR('q', 9, struct altqreq) /* delete a class */
-#define ALTQADDFILTER _IOWR('q', 10, struct altqreq) /* add a filter */
-#define ALTQDELFILTER _IOWR('q', 11, struct altqreq) /* delete a filter */
-#define ALTQGETSTATS _IOWR('q', 12, struct altqreq) /* get statistics */
-#define ALTQGETCNTR _IOWR('q', 13, struct altqreq) /* get a pkt counter */
-#endif /* 0 */
-#define ALTQTBRSET _IOW('q', 14, struct tbrreq) /* set tb regulator */
-#define ALTQTBRGET _IOWR('q', 15, struct tbrreq) /* get tb regulator */
-#endif /* ALTQ3_COMPAT */
#ifdef _KERNEL
#include <net/altq/altq_var.h>
diff --git a/freebsd/sys/net/altq/altq_cbq.c b/freebsd/sys/net/altq/altq_cbq.c
index ac108bd1..015e35bf 100644
--- a/freebsd/sys/net/altq/altq_cbq.c
+++ b/freebsd/sys/net/altq/altq_cbq.c
@@ -46,10 +46,6 @@
#include <sys/proc.h>
#include <sys/errno.h>
#include <sys/time.h>
-#ifdef ALTQ3_COMPAT
-#include <sys/uio.h>
-#include <sys/kernel.h>
-#endif
#include <net/if.h>
#include <net/if_var.h>
@@ -60,16 +56,7 @@
#include <netpfil/pf/pf_mtag.h>
#include <net/altq/altq.h>
#include <net/altq/altq_cbq.h>
-#ifdef ALTQ3_COMPAT
-#include <net/altq/altq_conf.h>
-#endif
-#ifdef ALTQ3_COMPAT
-/*
- * Local Data structures.
- */
-static cbq_state_t *cbq_list = NULL;
-#endif
/*
* Forward Declarations.
@@ -84,21 +71,6 @@ static struct mbuf *cbq_dequeue(struct ifaltq *, int);
static void cbqrestart(struct ifaltq *);
static void get_class_stats(class_stats_t *, struct rm_class *);
static void cbq_purge(cbq_state_t *);
-#ifdef ALTQ3_COMPAT
-static int cbq_add_class(struct cbq_add_class *);
-static int cbq_delete_class(struct cbq_delete_class *);
-static int cbq_modify_class(struct cbq_modify_class *);
-static int cbq_class_create(cbq_state_t *, struct cbq_add_class *,
- struct rm_class *, struct rm_class *);
-static int cbq_clear_hierarchy(struct cbq_interface *);
-static int cbq_set_enable(struct cbq_interface *, int);
-static int cbq_ifattach(struct cbq_interface *);
-static int cbq_ifdetach(struct cbq_interface *);
-static int cbq_getstats(struct cbq_getstats *);
-
-static int cbq_add_filter(struct cbq_add_filter *);
-static int cbq_delete_filter(struct cbq_delete_filter *);
-#endif /* ALTQ3_COMPAT */
/*
* int
@@ -125,10 +97,6 @@ cbq_class_destroy(cbq_state_t *cbqp, struct rm_class *cl)
cbqp->ifnp.root_ = NULL;
if (cl == cbqp->ifnp.default_)
cbqp->ifnp.default_ = NULL;
-#ifdef ALTQ3_COMPAT
- if (cl == cbqp->ifnp.ctl_)
- cbqp->ifnp.ctl_ = NULL;
-#endif
return (0);
}
@@ -181,10 +149,6 @@ cbq_clear_interface(cbq_state_t *cbqp)
cbqp->ifnp.root_ = NULL;
if (cl == cbqp->ifnp.default_)
cbqp->ifnp.default_ = NULL;
-#ifdef ALTQ3_COMPAT
- if (cl == cbqp->ifnp.ctl_)
- cbqp->ifnp.ctl_ = NULL;
-#endif
}
}
}
@@ -514,10 +478,6 @@ cbq_enqueue(struct ifaltq *ifq, struct mbuf *m, struct altq_pktattr *pktattr)
cl = NULL;
if ((t = pf_find_mtag(m)) != NULL)
cl = clh_to_clp(cbqp, t->qid);
-#ifdef ALTQ3_COMPAT
- else if ((ifq->altq_flags & ALTQF_CLASSIFY) && pktattr != NULL)
- cl = pktattr->pattr_class;
-#endif
if (cl == NULL) {
cl = cbqp->ifnp.default_;
if (cl == NULL) {
@@ -525,12 +485,7 @@ cbq_enqueue(struct ifaltq *ifq, struct mbuf *m, struct altq_pktattr *pktattr)
return (ENOBUFS);
}
}
-#ifdef ALTQ3_COMPAT
- if (pktattr != NULL)
- cl->pktattr_ = pktattr; /* save proto hdr used by ECN */
- else
-#endif
- cl->pktattr_ = NULL;
+ cl->pktattr_ = NULL;
len = m_pktlen(m);
if (rmc_queue_packet(cl, m) != 0) {
/* drop occurred. some mbuf was freed in rmc_queue_packet. */
@@ -608,564 +563,5 @@ static void cbq_purge(cbq_state_t *cbqp)
if (ALTQ_IS_ENABLED(cbqp->ifnp.ifq_))
cbqp->ifnp.ifq_->ifq_len = 0;
}
-#ifdef ALTQ3_COMPAT
-
-static int
-cbq_add_class(acp)
- struct cbq_add_class *acp;
-{
- char *ifacename;
- struct rm_class *borrow, *parent;
- cbq_state_t *cbqp;
-
- ifacename = acp->cbq_iface.cbq_ifacename;
- if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL)
- return (EBADF);
-
- /* check parameters */
- if (acp->cbq_class.priority >= CBQ_MAXPRI ||
- acp->cbq_class.maxq > CBQ_MAXQSIZE)
- return (EINVAL);
-
- /* Get pointers to parent and borrow classes. */
- parent = clh_to_clp(cbqp, acp->cbq_class.parent_class_handle);
- borrow = clh_to_clp(cbqp, acp->cbq_class.borrow_class_handle);
-
- /*
- * A class must borrow from it's parent or it can not
- * borrow at all. Hence, borrow can be null.
- */
- if (parent == NULL && (acp->cbq_class.flags & CBQCLF_ROOTCLASS) == 0) {
- printf("cbq_add_class: no parent class!\n");
- return (EINVAL);
- }
-
- if ((borrow != parent) && (borrow != NULL)) {
- printf("cbq_add_class: borrow class != parent\n");
- return (EINVAL);
- }
-
- return cbq_class_create(cbqp, acp, parent, borrow);
-}
-
-static int
-cbq_delete_class(dcp)
- struct cbq_delete_class *dcp;
-{
- char *ifacename;
- struct rm_class *cl;
- cbq_state_t *cbqp;
-
- ifacename = dcp->cbq_iface.cbq_ifacename;
- if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL)
- return (EBADF);
-
- if ((cl = clh_to_clp(cbqp, dcp->cbq_class_handle)) == NULL)
- return (EINVAL);
-
- /* if we are a parent class, then return an error. */
- if (is_a_parent_class(cl))
- return (EINVAL);
-
- /* if a filter has a reference to this class delete the filter */
- acc_discard_filters(&cbqp->cbq_classifier, cl, 0);
-
- return cbq_class_destroy(cbqp, cl);
-}
-
-static int
-cbq_modify_class(acp)
- struct cbq_modify_class *acp;
-{
- char *ifacename;
- struct rm_class *cl;
- cbq_state_t *cbqp;
-
- ifacename = acp->cbq_iface.cbq_ifacename;
- if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL)
- return (EBADF);
-
- /* Get pointer to this class */
- if ((cl = clh_to_clp(cbqp, acp->cbq_class_handle)) == NULL)
- return (EINVAL);
-
- if (rmc_modclass(cl, acp->cbq_class.nano_sec_per_byte,
- acp->cbq_class.maxq, acp->cbq_class.maxidle,
- acp->cbq_class.minidle, acp->cbq_class.offtime,
- acp->cbq_class.pktsize) < 0)
- return (EINVAL);
- return (0);
-}
-
-/*
- * struct rm_class *
- * cbq_class_create(cbq_mod_state_t *cbqp, struct cbq_add_class *acp,
- * struct rm_class *parent, struct rm_class *borrow)
- *
- * This function create a new traffic class in the CBQ class hierarchy of
- * given parameters. The class that created is either the root, default,
- * or a new dynamic class. If CBQ is not initilaized, the root class
- * will be created.
- */
-static int
-cbq_class_create(cbqp, acp, parent, borrow)
- cbq_state_t *cbqp;
- struct cbq_add_class *acp;
- struct rm_class *parent, *borrow;
-{
- struct rm_class *cl;
- cbq_class_spec_t *spec = &acp->cbq_class;
- u_int32_t chandle;
- int i;
-
- /*
- * allocate class handle
- */
- for (i = 1; i < CBQ_MAX_CLASSES; i++)
- if (cbqp->cbq_class_tbl[i] == NULL)
- break;
- if (i == CBQ_MAX_CLASSES)
- return (EINVAL);
- chandle = i; /* use the slot number as class handle */
-
- /*
- * create a class. if this is a root class, initialize the
- * interface.
- */
- if ((spec->flags & CBQCLF_CLASSMASK) == CBQCLF_ROOTCLASS) {
- rmc_init(cbqp->ifnp.ifq_, &cbqp->ifnp, spec->nano_sec_per_byte,
- cbqrestart, spec->maxq, RM_MAXQUEUED,
- spec->maxidle, spec->minidle, spec->offtime,
- spec->flags);
- cl = cbqp->ifnp.root_;
- } else {
- cl = rmc_newclass(spec->priority,
- &cbqp->ifnp, spec->nano_sec_per_byte,
- rmc_delay_action, spec->maxq, parent, borrow,
- spec->maxidle, spec->minidle, spec->offtime,
- spec->pktsize, spec->flags);
- }
- if (cl == NULL)
- return (ENOMEM);
-
- /* return handle to user space. */
- acp->cbq_class_handle = chandle;
-
- cl->stats_.handle = chandle;
- cl->stats_.depth = cl->depth_;
-
- /* save the allocated class */
- cbqp->cbq_class_tbl[i] = cl;
-
- if ((spec->flags & CBQCLF_CLASSMASK) == CBQCLF_DEFCLASS)
- cbqp->ifnp.default_ = cl;
- if ((spec->flags & CBQCLF_CLASSMASK) == CBQCLF_CTLCLASS)
- cbqp->ifnp.ctl_ = cl;
-
- return (0);
-}
-
-static int
-cbq_add_filter(afp)
- struct cbq_add_filter *afp;
-{
- char *ifacename;
- cbq_state_t *cbqp;
- struct rm_class *cl;
-
- ifacename = afp->cbq_iface.cbq_ifacename;
- if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL)
- return (EBADF);
-
- /* Get the pointer to class. */
- if ((cl = clh_to_clp(cbqp, afp->cbq_class_handle)) == NULL)
- return (EINVAL);
-
- return acc_add_filter(&cbqp->cbq_classifier, &afp->cbq_filter,
- cl, &afp->cbq_filter_handle);
-}
-
-static int
-cbq_delete_filter(dfp)
- struct cbq_delete_filter *dfp;
-{
- char *ifacename;
- cbq_state_t *cbqp;
-
- ifacename = dfp->cbq_iface.cbq_ifacename;
- if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL)
- return (EBADF);
-
- return acc_delete_filter(&cbqp->cbq_classifier,
- dfp->cbq_filter_handle);
-}
-
-/*
- * cbq_clear_hierarchy deletes all classes and their filters on the
- * given interface.
- */
-static int
-cbq_clear_hierarchy(ifacep)
- struct cbq_interface *ifacep;
-{
- char *ifacename;
- cbq_state_t *cbqp;
-
- ifacename = ifacep->cbq_ifacename;
- if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL)
- return (EBADF);
-
- return cbq_clear_interface(cbqp);
-}
-
-/*
- * static int
- * cbq_set_enable(struct cbq_enable *ep) - this function processed the
- * ioctl request to enable class based queueing. It searches the list
- * of interfaces for the specified interface and then enables CBQ on
- * that interface.
- *
- * Returns: 0, for no error.
- * EBADF, for specified inteface not found.
- */
-
-static int
-cbq_set_enable(ep, enable)
- struct cbq_interface *ep;
- int enable;
-{
- int error = 0;
- cbq_state_t *cbqp;
- char *ifacename;
-
- ifacename = ep->cbq_ifacename;
- if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL)
- return (EBADF);
-
- switch (enable) {
- case ENABLE:
- if (cbqp->ifnp.root_ == NULL || cbqp->ifnp.default_ == NULL ||
- cbqp->ifnp.ctl_ == NULL) {
- if (cbqp->ifnp.root_ == NULL)
- printf("No Root Class for %s\n", ifacename);
- if (cbqp->ifnp.default_ == NULL)
- printf("No Default Class for %s\n", ifacename);
- if (cbqp->ifnp.ctl_ == NULL)
- printf("No Control Class for %s\n", ifacename);
- error = EINVAL;
- } else if ((error = altq_enable(cbqp->ifnp.ifq_)) == 0) {
- cbqp->cbq_qlen = 0;
- }
- break;
-
- case DISABLE:
- error = altq_disable(cbqp->ifnp.ifq_);
- break;
- }
- return (error);
-}
-
-static int
-cbq_getstats(gsp)
- struct cbq_getstats *gsp;
-{
- char *ifacename;
- int i, n, nclasses;
- cbq_state_t *cbqp;
- struct rm_class *cl;
- class_stats_t stats, *usp;
- int error = 0;
-
- ifacename = gsp->iface.cbq_ifacename;
- nclasses = gsp->nclasses;
- usp = gsp->stats;
-
- if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL)
- return (EBADF);
- if (nclasses <= 0)
- return (EINVAL);
-
- for (n = 0, i = 0; n < nclasses && i < CBQ_MAX_CLASSES; n++, i++) {
- while ((cl = cbqp->cbq_class_tbl[i]) == NULL)
- if (++i >= CBQ_MAX_CLASSES)
- goto out;
-
- get_class_stats(&stats, cl);
- stats.handle = cl->stats_.handle;
-
- if ((error = copyout((caddr_t)&stats, (caddr_t)usp++,
- sizeof(stats))) != 0)
- return (error);
- }
-
- out:
- gsp->nclasses = n;
- return (error);
-}
-
-static int
-cbq_ifattach(ifacep)
- struct cbq_interface *ifacep;
-{
- int error = 0;
- char *ifacename;
- cbq_state_t *new_cbqp;
- struct ifnet *ifp;
-
- ifacename = ifacep->cbq_ifacename;
- if ((ifp = ifunit(ifacename)) == NULL)
- return (ENXIO);
- if (!ALTQ_IS_READY(&ifp->if_snd))
- return (ENXIO);
-
- /* allocate and initialize cbq_state_t */
- new_cbqp = malloc(sizeof(cbq_state_t), M_DEVBUF, M_WAITOK);
- if (new_cbqp == NULL)
- return (ENOMEM);
- bzero(new_cbqp, sizeof(cbq_state_t));
- CALLOUT_INIT(&new_cbqp->cbq_callout);
-
- new_cbqp->cbq_qlen = 0;
- new_cbqp->ifnp.ifq_ = &ifp->if_snd; /* keep the ifq */
-
- /*
- * set CBQ to this ifnet structure.
- */
- error = altq_attach(&ifp->if_snd, ALTQT_CBQ, new_cbqp,
- cbq_enqueue, cbq_dequeue, cbq_request,
- &new_cbqp->cbq_classifier, acc_classify);
- if (error) {
- free(new_cbqp, M_DEVBUF);
- return (error);
- }
-
- /* prepend to the list of cbq_state_t's. */
- new_cbqp->cbq_next = cbq_list;
- cbq_list = new_cbqp;
-
- return (0);
-}
-
-static int
-cbq_ifdetach(ifacep)
- struct cbq_interface *ifacep;
-{
- char *ifacename;
- cbq_state_t *cbqp;
-
- ifacename = ifacep->cbq_ifacename;
- if ((cbqp = altq_lookup(ifacename, ALTQT_CBQ)) == NULL)
- return (EBADF);
-
- (void)cbq_set_enable(ifacep, DISABLE);
-
- cbq_clear_interface(cbqp);
-
- /* remove CBQ from the ifnet structure. */
- (void)altq_detach(cbqp->ifnp.ifq_);
-
- /* remove from the list of cbq_state_t's. */
- if (cbq_list == cbqp)
- cbq_list = cbqp->cbq_next;
- else {
- cbq_state_t *cp;
-
- for (cp = cbq_list; cp != NULL; cp = cp->cbq_next)
- if (cp->cbq_next == cbqp) {
- cp->cbq_next = cbqp->cbq_next;
- break;
- }
- ASSERT(cp != NULL);
- }
-
- /* deallocate cbq_state_t */
- free(cbqp, M_DEVBUF);
-
- return (0);
-}
-
-/*
- * cbq device interface
- */
-
-altqdev_decl(cbq);
-
-int
-cbqopen(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- return (0);
-}
-
-int
-cbqclose(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- struct ifnet *ifp;
- struct cbq_interface iface;
- int err, error = 0;
-
- while (cbq_list) {
- ifp = cbq_list->ifnp.ifq_->altq_ifp;
- sprintf(iface.cbq_ifacename, "%s", ifp->if_xname);
- err = cbq_ifdetach(&iface);
- if (err != 0 && error == 0)
- error = err;
- }
-
- return (error);
-}
-
-int
-cbqioctl(dev, cmd, addr, flag, p)
- dev_t dev;
- ioctlcmd_t cmd;
- caddr_t addr;
- int flag;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- int error = 0;
-
- /* check cmd for superuser only */
- switch (cmd) {
- case CBQ_GETSTATS:
- /* currently only command that an ordinary user can call */
- break;
- default:
-#if (__FreeBSD_version > 700000)
- error = priv_check(p, PRIV_ALTQ_MANAGE);
-#elsif (__FreeBSD_version > 400000)
- error = suser(p);
-#else
- error = suser(p->p_ucred, &p->p_acflag);
-#endif
- if (error)
- return (error);
- break;
- }
-
- switch (cmd) {
-
- case CBQ_ENABLE:
- error = cbq_set_enable((struct cbq_interface *)addr, ENABLE);
- break;
-
- case CBQ_DISABLE:
- error = cbq_set_enable((struct cbq_interface *)addr, DISABLE);
- break;
-
- case CBQ_ADD_FILTER:
- error = cbq_add_filter((struct cbq_add_filter *)addr);
- break;
-
- case CBQ_DEL_FILTER:
- error = cbq_delete_filter((struct cbq_delete_filter *)addr);
- break;
-
- case CBQ_ADD_CLASS:
- error = cbq_add_class((struct cbq_add_class *)addr);
- break;
-
- case CBQ_DEL_CLASS:
- error = cbq_delete_class((struct cbq_delete_class *)addr);
- break;
-
- case CBQ_MODIFY_CLASS:
- error = cbq_modify_class((struct cbq_modify_class *)addr);
- break;
-
- case CBQ_CLEAR_HIERARCHY:
- error = cbq_clear_hierarchy((struct cbq_interface *)addr);
- break;
-
- case CBQ_IF_ATTACH:
- error = cbq_ifattach((struct cbq_interface *)addr);
- break;
-
- case CBQ_IF_DETACH:
- error = cbq_ifdetach((struct cbq_interface *)addr);
- break;
-
- case CBQ_GETSTATS:
- error = cbq_getstats((struct cbq_getstats *)addr);
- break;
-
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-#if 0
-/* for debug */
-static void cbq_class_dump(int);
-
-static void cbq_class_dump(i)
- int i;
-{
- struct rm_class *cl;
- rm_class_stats_t *s;
- struct _class_queue_ *q;
-
- if (cbq_list == NULL) {
- printf("cbq_class_dump: no cbq_state found\n");
- return;
- }
- cl = cbq_list->cbq_class_tbl[i];
-
- printf("class %d cl=%p\n", i, cl);
- if (cl != NULL) {
- s = &cl->stats_;
- q = cl->q_;
-
- printf("pri=%d, depth=%d, maxrate=%d, allotment=%d\n",
- cl->pri_, cl->depth_, cl->maxrate_, cl->allotment_);
- printf("w_allotment=%d, bytes_alloc=%d, avgidle=%d, maxidle=%d\n",
- cl->w_allotment_, cl->bytes_alloc_, cl->avgidle_,
- cl->maxidle_);
- printf("minidle=%d, offtime=%d, sleeping=%d, leaf=%d\n",
- cl->minidle_, cl->offtime_, cl->sleeping_, cl->leaf_);
- printf("handle=%d, depth=%d, packets=%d, bytes=%d\n",
- s->handle, s->depth,
- (int)s->xmit_cnt.packets, (int)s->xmit_cnt.bytes);
- printf("over=%d\n, borrows=%d, drops=%d, overactions=%d, delays=%d\n",
- s->over, s->borrows, (int)s->drop_cnt.packets,
- s->overactions, s->delays);
- printf("tail=%p, head=%p, qlen=%d, qlim=%d, qthresh=%d,qtype=%d\n",
- q->tail_, q->head_, q->qlen_, q->qlim_,
- q->qthresh_, q->qtype_);
- }
-}
-#endif /* 0 */
-
-#ifdef KLD_MODULE
-
-static struct altqsw cbq_sw =
- {"cbq", cbqopen, cbqclose, cbqioctl};
-
-ALTQ_MODULE(altq_cbq, ALTQT_CBQ, &cbq_sw);
-MODULE_DEPEND(altq_cbq, altq_red, 1, 1, 1);
-MODULE_DEPEND(altq_cbq, altq_rio, 1, 1, 1);
-
-#endif /* KLD_MODULE */
-#endif /* ALTQ3_COMPAT */
#endif /* ALTQ_CBQ */
diff --git a/freebsd/sys/net/altq/altq_cbq.h b/freebsd/sys/net/altq/altq_cbq.h
index 04bcab1a..70974715 100644
--- a/freebsd/sys/net/altq/altq_cbq.h
+++ b/freebsd/sys/net/altq/altq_cbq.h
@@ -46,7 +46,7 @@ extern "C" {
#define NULL_CLASS_HANDLE 0
-/* class flags should be same as class flags in rm_class.h */
+/* class flags must be same as class flags in altq_rmclass.h */
#define CBQCLF_RED 0x0001 /* use RED */
#define CBQCLF_ECN 0x0002 /* use RED/ECN */
#define CBQCLF_RIO 0x0004 /* use RIO */
@@ -55,6 +55,15 @@ extern "C" {
#define CBQCLF_BORROW 0x0020 /* borrow from parent */
#define CBQCLF_CODEL 0x0040 /* use CoDel */
+#ifdef _KERNEL
+CTASSERT(CBQCLF_RED == RMCF_RED);
+CTASSERT(CBQCLF_ECN == RMCF_ECN);
+CTASSERT(CBQCLF_RIO == RMCF_RIO);
+CTASSERT(CBQCLF_FLOWVALVE == RMCF_FLOWVALVE);
+CTASSERT(CBQCLF_CLEARDSCP == RMCF_CLEARDSCP);
+CTASSERT(CBQCLF_CODEL == RMCF_CODEL);
+#endif
+
/* class flags only for root class */
#define CBQCLF_WRR 0x0100 /* weighted-round robin */
#define CBQCLF_EFFICIENT 0x0200 /* work-conserving */
@@ -62,9 +71,6 @@ extern "C" {
/* class flags for special classes */
#define CBQCLF_ROOTCLASS 0x1000 /* root class */
#define CBQCLF_DEFCLASS 0x2000 /* default class */
-#ifdef ALTQ3_COMPAT
-#define CBQCLF_CTLCLASS 0x4000 /* control class */
-#endif
#define CBQCLF_CLASSMASK 0xf000 /* class mask */
#define CBQ_MAXQSIZE 200
@@ -105,88 +111,6 @@ typedef struct _cbq_class_stats_ {
* header.
*/
-#ifdef ALTQ3_COMPAT
-/*
- * Define structures associated with IOCTLS for cbq.
- */
-
-/*
- * Define the CBQ interface structure. This must be included in all
- * IOCTL's such that the CBQ driver may find the appropriate CBQ module
- * associated with the network interface to be affected.
- */
-struct cbq_interface {
- char cbq_ifacename[IFNAMSIZ];
-};
-
-typedef struct cbq_class_spec {
- u_int priority;
- u_int nano_sec_per_byte;
- u_int maxq;
- u_int maxidle;
- int minidle;
- u_int offtime;
- u_int32_t parent_class_handle;
- u_int32_t borrow_class_handle;
-
- u_int pktsize;
- int flags;
-} cbq_class_spec_t;
-
-struct cbq_add_class {
- struct cbq_interface cbq_iface;
-
- cbq_class_spec_t cbq_class;
- u_int32_t cbq_class_handle;
-};
-
-struct cbq_delete_class {
- struct cbq_interface cbq_iface;
- u_int32_t cbq_class_handle;
-};
-
-struct cbq_modify_class {
- struct cbq_interface cbq_iface;
-
- cbq_class_spec_t cbq_class;
- u_int32_t cbq_class_handle;
-};
-
-struct cbq_add_filter {
- struct cbq_interface cbq_iface;
- u_int32_t cbq_class_handle;
- struct flow_filter cbq_filter;
-
- u_long cbq_filter_handle;
-};
-
-struct cbq_delete_filter {
- struct cbq_interface cbq_iface;
- u_long cbq_filter_handle;
-};
-
-/* number of classes are returned in nclasses field */
-struct cbq_getstats {
- struct cbq_interface iface;
- int nclasses;
- class_stats_t *stats;
-};
-
-/*
- * Define IOCTLs for CBQ.
- */
-#define CBQ_IF_ATTACH _IOW('Q', 1, struct cbq_interface)
-#define CBQ_IF_DETACH _IOW('Q', 2, struct cbq_interface)
-#define CBQ_ENABLE _IOW('Q', 3, struct cbq_interface)
-#define CBQ_DISABLE _IOW('Q', 4, struct cbq_interface)
-#define CBQ_CLEAR_HIERARCHY _IOW('Q', 5, struct cbq_interface)
-#define CBQ_ADD_CLASS _IOWR('Q', 7, struct cbq_add_class)
-#define CBQ_DEL_CLASS _IOW('Q', 8, struct cbq_delete_class)
-#define CBQ_MODIFY_CLASS _IOWR('Q', 9, struct cbq_modify_class)
-#define CBQ_ADD_FILTER _IOWR('Q', 10, struct cbq_add_filter)
-#define CBQ_DEL_FILTER _IOW('Q', 11, struct cbq_delete_filter)
-#define CBQ_GETSTATS _IOWR('Q', 12, struct cbq_getstats)
-#endif /* ALTQ3_COMPAT */
#ifdef _KERNEL
/*
@@ -198,20 +122,11 @@ struct cbq_getstats {
#define CBQ_MAX_CLASSES 256
-#ifdef ALTQ3_COMPAT
-#define CBQ_MAX_FILTERS 256
-
-#define DISABLE 0x00
-#define ENABLE 0x01
-#endif /* ALTQ3_COMPAT */
/*
* Define State structures.
*/
typedef struct cbqstate {
-#ifdef ALTQ3_COMPAT
- struct cbqstate *cbq_next;
-#endif
int cbq_qlen; /* # of packets in cbq */
struct rm_class *cbq_class_tbl[CBQ_MAX_CLASSES];
diff --git a/freebsd/sys/net/altq/altq_cdnr.c b/freebsd/sys/net/altq/altq_cdnr.c
deleted file mode 100644
index 0f4eeec1..00000000
--- a/freebsd/sys/net/altq/altq_cdnr.c
+++ /dev/null
@@ -1,1384 +0,0 @@
-#include <machine/rtems-bsd-kernel-space.h>
-
-/*-
- * Copyright (C) 1999-2002
- * Sony Computer Science Laboratories Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $KAME: altq_cdnr.c,v 1.15 2005/04/13 03:44:24 suz Exp $
- * $FreeBSD$
- */
-
-#include <rtems/bsd/local/opt_altq.h>
-#include <rtems/bsd/local/opt_inet.h>
-#include <rtems/bsd/local/opt_inet6.h>
-
-#include <sys/param.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/errno.h>
-#include <sys/kernel.h>
-#include <sys/queue.h>
-
-#include <net/if.h>
-#include <net/if_types.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#ifdef INET6
-#include <netinet/ip6.h>
-#endif
-
-#include <net/altq/if_altq.h>
-#include <net/altq/altq.h>
-#ifdef ALTQ3_COMPAT
-#include <net/altq/altq_conf.h>
-#endif
-#include <net/altq/altq_cdnr.h>
-
-#ifdef ALTQ3_COMPAT
-/*
- * diffserv traffic conditioning module
- */
-
-int altq_cdnr_enabled = 0;
-
-/* traffic conditioner is enabled by ALTQ_CDNR option in opt_altq.h */
-#ifdef ALTQ_CDNR
-
-/* cdnr_list keeps all cdnr's allocated. */
-static LIST_HEAD(, top_cdnr) tcb_list;
-
-static int altq_cdnr_input(struct mbuf *, int);
-static struct top_cdnr *tcb_lookup(char *ifname);
-static struct cdnr_block *cdnr_handle2cb(u_long);
-static u_long cdnr_cb2handle(struct cdnr_block *);
-static void *cdnr_cballoc(struct top_cdnr *, int,
- struct tc_action *(*)(struct cdnr_block *, struct cdnr_pktinfo *));
-static void cdnr_cbdestroy(void *);
-static int tca_verify_action(struct tc_action *);
-static void tca_import_action(struct tc_action *, struct tc_action *);
-static void tca_invalidate_action(struct tc_action *);
-
-static int generic_element_destroy(struct cdnr_block *);
-static struct top_cdnr *top_create(struct ifaltq *);
-static int top_destroy(struct top_cdnr *);
-static struct cdnr_block *element_create(struct top_cdnr *, struct tc_action *);
-static int element_destroy(struct cdnr_block *);
-static void tb_import_profile(struct tbe *, struct tb_profile *);
-static struct tbmeter *tbm_create(struct top_cdnr *, struct tb_profile *,
- struct tc_action *, struct tc_action *);
-static int tbm_destroy(struct tbmeter *);
-static struct tc_action *tbm_input(struct cdnr_block *, struct cdnr_pktinfo *);
-static struct trtcm *trtcm_create(struct top_cdnr *,
- struct tb_profile *, struct tb_profile *,
- struct tc_action *, struct tc_action *, struct tc_action *,
- int);
-static int trtcm_destroy(struct trtcm *);
-static struct tc_action *trtcm_input(struct cdnr_block *, struct cdnr_pktinfo *);
-static struct tswtcm *tswtcm_create(struct top_cdnr *,
- u_int32_t, u_int32_t, u_int32_t,
- struct tc_action *, struct tc_action *, struct tc_action *);
-static int tswtcm_destroy(struct tswtcm *);
-static struct tc_action *tswtcm_input(struct cdnr_block *, struct cdnr_pktinfo *);
-
-static int cdnrcmd_if_attach(char *);
-static int cdnrcmd_if_detach(char *);
-static int cdnrcmd_add_element(struct cdnr_add_element *);
-static int cdnrcmd_delete_element(struct cdnr_delete_element *);
-static int cdnrcmd_add_filter(struct cdnr_add_filter *);
-static int cdnrcmd_delete_filter(struct cdnr_delete_filter *);
-static int cdnrcmd_add_tbm(struct cdnr_add_tbmeter *);
-static int cdnrcmd_modify_tbm(struct cdnr_modify_tbmeter *);
-static int cdnrcmd_tbm_stats(struct cdnr_tbmeter_stats *);
-static int cdnrcmd_add_trtcm(struct cdnr_add_trtcm *);
-static int cdnrcmd_modify_trtcm(struct cdnr_modify_trtcm *);
-static int cdnrcmd_tcm_stats(struct cdnr_tcm_stats *);
-static int cdnrcmd_add_tswtcm(struct cdnr_add_tswtcm *);
-static int cdnrcmd_modify_tswtcm(struct cdnr_modify_tswtcm *);
-static int cdnrcmd_get_stats(struct cdnr_get_stats *);
-
-altqdev_decl(cdnr);
-
-/*
- * top level input function called from ip_input.
- * should be called before converting header fields to host-byte-order.
- */
-int
-altq_cdnr_input(m, af)
- struct mbuf *m;
- int af; /* address family */
-{
- struct ifnet *ifp;
- struct ip *ip;
- struct top_cdnr *top;
- struct tc_action *tca;
- struct cdnr_block *cb;
- struct cdnr_pktinfo pktinfo;
-
- ifp = m->m_pkthdr.rcvif;
- if (!ALTQ_IS_CNDTNING(&ifp->if_snd))
- /* traffic conditioner is not enabled on this interface */
- return (1);
-
- top = ifp->if_snd.altq_cdnr;
-
- ip = mtod(m, struct ip *);
-#ifdef INET6
- if (af == AF_INET6) {
- u_int32_t flowlabel;
-
- flowlabel = ((struct ip6_hdr *)ip)->ip6_flow;
- pktinfo.pkt_dscp = (ntohl(flowlabel) >> 20) & DSCP_MASK;
- } else
-#endif
- pktinfo.pkt_dscp = ip->ip_tos & DSCP_MASK;
- pktinfo.pkt_len = m_pktlen(m);
-
- tca = NULL;
-
- cb = acc_classify(&top->tc_classifier, m, af);
- if (cb != NULL)
- tca = &cb->cb_action;
-
- if (tca == NULL)
- tca = &top->tc_block.cb_action;
-
- while (1) {
- PKTCNTR_ADD(&top->tc_cnts[tca->tca_code], pktinfo.pkt_len);
-
- switch (tca->tca_code) {
- case TCACODE_PASS:
- return (1);
- case TCACODE_DROP:
- m_freem(m);
- return (0);
- case TCACODE_RETURN:
- return (0);
- case TCACODE_MARK:
-#ifdef INET6
- if (af == AF_INET6) {
- struct ip6_hdr *ip6 = (struct ip6_hdr *)ip;
- u_int32_t flowlabel;
-
- flowlabel = ntohl(ip6->ip6_flow);
- flowlabel = (tca->tca_dscp << 20) |
- (flowlabel & ~(DSCP_MASK << 20));
- ip6->ip6_flow = htonl(flowlabel);
- } else
-#endif
- ip->ip_tos = tca->tca_dscp |
- (ip->ip_tos & DSCP_CUMASK);
- return (1);
- case TCACODE_NEXT:
- cb = tca->tca_next;
- tca = (*cb->cb_input)(cb, &pktinfo);
- break;
- case TCACODE_NONE:
- default:
- return (1);
- }
- }
-}
-
-static struct top_cdnr *
-tcb_lookup(ifname)
- char *ifname;
-{
- struct top_cdnr *top;
- struct ifnet *ifp;
-
- if ((ifp = ifunit(ifname)) != NULL)
- LIST_FOREACH(top, &tcb_list, tc_next)
- if (top->tc_ifq->altq_ifp == ifp)
- return (top);
- return (NULL);
-}
-
-static struct cdnr_block *
-cdnr_handle2cb(handle)
- u_long handle;
-{
- struct cdnr_block *cb;
-
- cb = (struct cdnr_block *)handle;
- if (handle != ALIGN(cb))
- return (NULL);
-
- if (cb == NULL || cb->cb_handle != handle)
- return (NULL);
- return (cb);
-}
-
-static u_long
-cdnr_cb2handle(cb)
- struct cdnr_block *cb;
-{
- return (cb->cb_handle);
-}
-
-static void *
-cdnr_cballoc(top, type, input_func)
- struct top_cdnr *top;
- int type;
- struct tc_action *(*input_func)(struct cdnr_block *,
- struct cdnr_pktinfo *);
-{
- struct cdnr_block *cb;
- int size;
-
- switch (type) {
- case TCETYPE_TOP:
- size = sizeof(struct top_cdnr);
- break;
- case TCETYPE_ELEMENT:
- size = sizeof(struct cdnr_block);
- break;
- case TCETYPE_TBMETER:
- size = sizeof(struct tbmeter);
- break;
- case TCETYPE_TRTCM:
- size = sizeof(struct trtcm);
- break;
- case TCETYPE_TSWTCM:
- size = sizeof(struct tswtcm);
- break;
- default:
- return (NULL);
- }
-
- cb = malloc(size, M_DEVBUF, M_WAITOK);
- if (cb == NULL)
- return (NULL);
- bzero(cb, size);
-
- cb->cb_len = size;
- cb->cb_type = type;
- cb->cb_ref = 0;
- cb->cb_handle = (u_long)cb;
- if (top == NULL)
- cb->cb_top = (struct top_cdnr *)cb;
- else
- cb->cb_top = top;
-
- if (input_func != NULL) {
- /*
- * if this cdnr has an action function,
- * make tc_action to call itself.
- */
- cb->cb_action.tca_code = TCACODE_NEXT;
- cb->cb_action.tca_next = cb;
- cb->cb_input = input_func;
- } else
- cb->cb_action.tca_code = TCACODE_NONE;
-
- /* if this isn't top, register the element to the top level cdnr */
- if (top != NULL)
- LIST_INSERT_HEAD(&top->tc_elements, cb, cb_next);
-
- return ((void *)cb);
-}
-
-static void
-cdnr_cbdestroy(cblock)
- void *cblock;
-{
- struct cdnr_block *cb = cblock;
-
- /* delete filters belonging to this cdnr */
- acc_discard_filters(&cb->cb_top->tc_classifier, cb, 0);
-
- /* remove from the top level cdnr */
- if (cb->cb_top != cblock)
- LIST_REMOVE(cb, cb_next);
-
- free(cb, M_DEVBUF);
-}
-
-/*
- * conditioner common destroy routine
- */
-static int
-generic_element_destroy(cb)
- struct cdnr_block *cb;
-{
- int error = 0;
-
- switch (cb->cb_type) {
- case TCETYPE_TOP:
- error = top_destroy((struct top_cdnr *)cb);
- break;
- case TCETYPE_ELEMENT:
- error = element_destroy(cb);
- break;
- case TCETYPE_TBMETER:
- error = tbm_destroy((struct tbmeter *)cb);
- break;
- case TCETYPE_TRTCM:
- error = trtcm_destroy((struct trtcm *)cb);
- break;
- case TCETYPE_TSWTCM:
- error = tswtcm_destroy((struct tswtcm *)cb);
- break;
- default:
- error = EINVAL;
- }
- return (error);
-}
-
-static int
-tca_verify_action(utca)
- struct tc_action *utca;
-{
- switch (utca->tca_code) {
- case TCACODE_PASS:
- case TCACODE_DROP:
- case TCACODE_MARK:
- /* these are ok */
- break;
-
- case TCACODE_HANDLE:
- /* verify handle value */
- if (cdnr_handle2cb(utca->tca_handle) == NULL)
- return (-1);
- break;
-
- case TCACODE_NONE:
- case TCACODE_RETURN:
- case TCACODE_NEXT:
- default:
- /* should not be passed from a user */
- return (-1);
- }
- return (0);
-}
-
-static void
-tca_import_action(ktca, utca)
- struct tc_action *ktca, *utca;
-{
- struct cdnr_block *cb;
-
- *ktca = *utca;
- if (ktca->tca_code == TCACODE_HANDLE) {
- cb = cdnr_handle2cb(ktca->tca_handle);
- if (cb == NULL) {
- ktca->tca_code = TCACODE_NONE;
- return;
- }
- ktca->tca_code = TCACODE_NEXT;
- ktca->tca_next = cb;
- cb->cb_ref++;
- } else if (ktca->tca_code == TCACODE_MARK) {
- ktca->tca_dscp &= DSCP_MASK;
- }
- return;
-}
-
-static void
-tca_invalidate_action(tca)
- struct tc_action *tca;
-{
- struct cdnr_block *cb;
-
- if (tca->tca_code == TCACODE_NEXT) {
- cb = tca->tca_next;
- if (cb == NULL)
- return;
- cb->cb_ref--;
- }
- tca->tca_code = TCACODE_NONE;
-}
-
-/*
- * top level traffic conditioner
- */
-static struct top_cdnr *
-top_create(ifq)
- struct ifaltq *ifq;
-{
- struct top_cdnr *top;
-
- if ((top = cdnr_cballoc(NULL, TCETYPE_TOP, NULL)) == NULL)
- return (NULL);
-
- top->tc_ifq = ifq;
- /* set default action for the top level conditioner */
- top->tc_block.cb_action.tca_code = TCACODE_PASS;
-
- LIST_INSERT_HEAD(&tcb_list, top, tc_next);
-
- ifq->altq_cdnr = top;
-
- return (top);
-}
-
-static int
-top_destroy(top)
- struct top_cdnr *top;
-{
- struct cdnr_block *cb;
-
- if (ALTQ_IS_CNDTNING(top->tc_ifq))
- ALTQ_CLEAR_CNDTNING(top->tc_ifq);
- top->tc_ifq->altq_cdnr = NULL;
-
- /*
- * destroy all the conditioner elements belonging to this interface
- */
- while ((cb = LIST_FIRST(&top->tc_elements)) != NULL) {
- while (cb != NULL && cb->cb_ref > 0)
- cb = LIST_NEXT(cb, cb_next);
- if (cb != NULL)
- generic_element_destroy(cb);
- }
-
- LIST_REMOVE(top, tc_next);
-
- cdnr_cbdestroy(top);
-
- /* if there is no active conditioner, remove the input hook */
- if (altq_input != NULL) {
- LIST_FOREACH(top, &tcb_list, tc_next)
- if (ALTQ_IS_CNDTNING(top->tc_ifq))
- break;
- if (top == NULL)
- altq_input = NULL;
- }
-
- return (0);
-}
-
-/*
- * simple tc elements without input function (e.g., dropper and makers).
- */
-static struct cdnr_block *
-element_create(top, action)
- struct top_cdnr *top;
- struct tc_action *action;
-{
- struct cdnr_block *cb;
-
- if (tca_verify_action(action) < 0)
- return (NULL);
-
- if ((cb = cdnr_cballoc(top, TCETYPE_ELEMENT, NULL)) == NULL)
- return (NULL);
-
- tca_import_action(&cb->cb_action, action);
-
- return (cb);
-}
-
-static int
-element_destroy(cb)
- struct cdnr_block *cb;
-{
- if (cb->cb_ref > 0)
- return (EBUSY);
-
- tca_invalidate_action(&cb->cb_action);
-
- cdnr_cbdestroy(cb);
- return (0);
-}
-
-/*
- * internal representation of token bucket parameters
- * rate: byte_per_unittime << 32
- * (((bits_per_sec) / 8) << 32) / machclk_freq
- * depth: byte << 32
- *
- */
-#define TB_SHIFT 32
-#define TB_SCALE(x) ((u_int64_t)(x) << TB_SHIFT)
-#define TB_UNSCALE(x) ((x) >> TB_SHIFT)
-
-static void
-tb_import_profile(tb, profile)
- struct tbe *tb;
- struct tb_profile *profile;
-{
- tb->rate = TB_SCALE(profile->rate / 8) / machclk_freq;
- tb->depth = TB_SCALE(profile->depth);
- if (tb->rate > 0)
- tb->filluptime = tb->depth / tb->rate;
- else
- tb->filluptime = 0xffffffffffffffffLL;
- tb->token = tb->depth;
- tb->last = read_machclk();
-}
-
-/*
- * simple token bucket meter
- */
-static struct tbmeter *
-tbm_create(top, profile, in_action, out_action)
- struct top_cdnr *top;
- struct tb_profile *profile;
- struct tc_action *in_action, *out_action;
-{
- struct tbmeter *tbm = NULL;
-
- if (tca_verify_action(in_action) < 0
- || tca_verify_action(out_action) < 0)
- return (NULL);
-
- if ((tbm = cdnr_cballoc(top, TCETYPE_TBMETER,
- tbm_input)) == NULL)
- return (NULL);
-
- tb_import_profile(&tbm->tb, profile);
-
- tca_import_action(&tbm->in_action, in_action);
- tca_import_action(&tbm->out_action, out_action);
-
- return (tbm);
-}
-
-static int
-tbm_destroy(tbm)
- struct tbmeter *tbm;
-{
- if (tbm->cdnrblk.cb_ref > 0)
- return (EBUSY);
-
- tca_invalidate_action(&tbm->in_action);
- tca_invalidate_action(&tbm->out_action);
-
- cdnr_cbdestroy(tbm);
- return (0);
-}
-
-static struct tc_action *
-tbm_input(cb, pktinfo)
- struct cdnr_block *cb;
- struct cdnr_pktinfo *pktinfo;
-{
- struct tbmeter *tbm = (struct tbmeter *)cb;
- u_int64_t len;
- u_int64_t interval, now;
-
- len = TB_SCALE(pktinfo->pkt_len);
-
- if (tbm->tb.token < len) {
- now = read_machclk();
- interval = now - tbm->tb.last;
- if (interval >= tbm->tb.filluptime)
- tbm->tb.token = tbm->tb.depth;
- else {
- tbm->tb.token += interval * tbm->tb.rate;
- if (tbm->tb.token > tbm->tb.depth)
- tbm->tb.token = tbm->tb.depth;
- }
- tbm->tb.last = now;
- }
-
- if (tbm->tb.token < len) {
- PKTCNTR_ADD(&tbm->out_cnt, pktinfo->pkt_len);
- return (&tbm->out_action);
- }
-
- tbm->tb.token -= len;
- PKTCNTR_ADD(&tbm->in_cnt, pktinfo->pkt_len);
- return (&tbm->in_action);
-}
-
-/*
- * two rate three color marker
- * as described in draft-heinanen-diffserv-trtcm-01.txt
- */
-static struct trtcm *
-trtcm_create(top, cmtd_profile, peak_profile,
- green_action, yellow_action, red_action, coloraware)
- struct top_cdnr *top;
- struct tb_profile *cmtd_profile, *peak_profile;
- struct tc_action *green_action, *yellow_action, *red_action;
- int coloraware;
-{
- struct trtcm *tcm = NULL;
-
- if (tca_verify_action(green_action) < 0
- || tca_verify_action(yellow_action) < 0
- || tca_verify_action(red_action) < 0)
- return (NULL);
-
- if ((tcm = cdnr_cballoc(top, TCETYPE_TRTCM,
- trtcm_input)) == NULL)
- return (NULL);
-
- tb_import_profile(&tcm->cmtd_tb, cmtd_profile);
- tb_import_profile(&tcm->peak_tb, peak_profile);
-
- tca_import_action(&tcm->green_action, green_action);
- tca_import_action(&tcm->yellow_action, yellow_action);
- tca_import_action(&tcm->red_action, red_action);
-
- /* set dscps to use */
- if (tcm->green_action.tca_code == TCACODE_MARK)
- tcm->green_dscp = tcm->green_action.tca_dscp & DSCP_MASK;
- else
- tcm->green_dscp = DSCP_AF11;
- if (tcm->yellow_action.tca_code == TCACODE_MARK)
- tcm->yellow_dscp = tcm->yellow_action.tca_dscp & DSCP_MASK;
- else
- tcm->yellow_dscp = DSCP_AF12;
- if (tcm->red_action.tca_code == TCACODE_MARK)
- tcm->red_dscp = tcm->red_action.tca_dscp & DSCP_MASK;
- else
- tcm->red_dscp = DSCP_AF13;
-
- tcm->coloraware = coloraware;
-
- return (tcm);
-}
-
-static int
-trtcm_destroy(tcm)
- struct trtcm *tcm;
-{
- if (tcm->cdnrblk.cb_ref > 0)
- return (EBUSY);
-
- tca_invalidate_action(&tcm->green_action);
- tca_invalidate_action(&tcm->yellow_action);
- tca_invalidate_action(&tcm->red_action);
-
- cdnr_cbdestroy(tcm);
- return (0);
-}
-
-static struct tc_action *
-trtcm_input(cb, pktinfo)
- struct cdnr_block *cb;
- struct cdnr_pktinfo *pktinfo;
-{
- struct trtcm *tcm = (struct trtcm *)cb;
- u_int64_t len;
- u_int64_t interval, now;
- u_int8_t color;
-
- len = TB_SCALE(pktinfo->pkt_len);
- if (tcm->coloraware) {
- color = pktinfo->pkt_dscp;
- if (color != tcm->yellow_dscp && color != tcm->red_dscp)
- color = tcm->green_dscp;
- } else {
- /* if color-blind, precolor it as green */
- color = tcm->green_dscp;
- }
-
- now = read_machclk();
- if (tcm->cmtd_tb.token < len) {
- interval = now - tcm->cmtd_tb.last;
- if (interval >= tcm->cmtd_tb.filluptime)
- tcm->cmtd_tb.token = tcm->cmtd_tb.depth;
- else {
- tcm->cmtd_tb.token += interval * tcm->cmtd_tb.rate;
- if (tcm->cmtd_tb.token > tcm->cmtd_tb.depth)
- tcm->cmtd_tb.token = tcm->cmtd_tb.depth;
- }
- tcm->cmtd_tb.last = now;
- }
- if (tcm->peak_tb.token < len) {
- interval = now - tcm->peak_tb.last;
- if (interval >= tcm->peak_tb.filluptime)
- tcm->peak_tb.token = tcm->peak_tb.depth;
- else {
- tcm->peak_tb.token += interval * tcm->peak_tb.rate;
- if (tcm->peak_tb.token > tcm->peak_tb.depth)
- tcm->peak_tb.token = tcm->peak_tb.depth;
- }
- tcm->peak_tb.last = now;
- }
-
- if (color == tcm->red_dscp || tcm->peak_tb.token < len) {
- pktinfo->pkt_dscp = tcm->red_dscp;
- PKTCNTR_ADD(&tcm->red_cnt, pktinfo->pkt_len);
- return (&tcm->red_action);
- }
-
- if (color == tcm->yellow_dscp || tcm->cmtd_tb.token < len) {
- pktinfo->pkt_dscp = tcm->yellow_dscp;
- tcm->peak_tb.token -= len;
- PKTCNTR_ADD(&tcm->yellow_cnt, pktinfo->pkt_len);
- return (&tcm->yellow_action);
- }
-
- pktinfo->pkt_dscp = tcm->green_dscp;
- tcm->cmtd_tb.token -= len;
- tcm->peak_tb.token -= len;
- PKTCNTR_ADD(&tcm->green_cnt, pktinfo->pkt_len);
- return (&tcm->green_action);
-}
-
-/*
- * time sliding window three color marker
- * as described in draft-fang-diffserv-tc-tswtcm-00.txt
- */
-static struct tswtcm *
-tswtcm_create(top, cmtd_rate, peak_rate, avg_interval,
- green_action, yellow_action, red_action)
- struct top_cdnr *top;
- u_int32_t cmtd_rate, peak_rate, avg_interval;
- struct tc_action *green_action, *yellow_action, *red_action;
-{
- struct tswtcm *tsw;
-
- if (tca_verify_action(green_action) < 0
- || tca_verify_action(yellow_action) < 0
- || tca_verify_action(red_action) < 0)
- return (NULL);
-
- if ((tsw = cdnr_cballoc(top, TCETYPE_TSWTCM,
- tswtcm_input)) == NULL)
- return (NULL);
-
- tca_import_action(&tsw->green_action, green_action);
- tca_import_action(&tsw->yellow_action, yellow_action);
- tca_import_action(&tsw->red_action, red_action);
-
- /* set dscps to use */
- if (tsw->green_action.tca_code == TCACODE_MARK)
- tsw->green_dscp = tsw->green_action.tca_dscp & DSCP_MASK;
- else
- tsw->green_dscp = DSCP_AF11;
- if (tsw->yellow_action.tca_code == TCACODE_MARK)
- tsw->yellow_dscp = tsw->yellow_action.tca_dscp & DSCP_MASK;
- else
- tsw->yellow_dscp = DSCP_AF12;
- if (tsw->red_action.tca_code == TCACODE_MARK)
- tsw->red_dscp = tsw->red_action.tca_dscp & DSCP_MASK;
- else
- tsw->red_dscp = DSCP_AF13;
-
- /* convert rates from bits/sec to bytes/sec */
- tsw->cmtd_rate = cmtd_rate / 8;
- tsw->peak_rate = peak_rate / 8;
- tsw->avg_rate = 0;
-
- /* timewin is converted from msec to machine clock unit */
- tsw->timewin = (u_int64_t)machclk_freq * avg_interval / 1000;
-
- return (tsw);
-}
-
-static int
-tswtcm_destroy(tsw)
- struct tswtcm *tsw;
-{
- if (tsw->cdnrblk.cb_ref > 0)
- return (EBUSY);
-
- tca_invalidate_action(&tsw->green_action);
- tca_invalidate_action(&tsw->yellow_action);
- tca_invalidate_action(&tsw->red_action);
-
- cdnr_cbdestroy(tsw);
- return (0);
-}
-
-static struct tc_action *
-tswtcm_input(cb, pktinfo)
- struct cdnr_block *cb;
- struct cdnr_pktinfo *pktinfo;
-{
- struct tswtcm *tsw = (struct tswtcm *)cb;
- int len;
- u_int32_t avg_rate;
- u_int64_t interval, now, tmp;
-
- /*
- * rate estimator
- */
- len = pktinfo->pkt_len;
- now = read_machclk();
-
- interval = now - tsw->t_front;
- /*
- * calculate average rate:
- * avg = (avg * timewin + pkt_len)/(timewin + interval)
- * pkt_len needs to be multiplied by machclk_freq in order to
- * get (bytes/sec).
- * note: when avg_rate (bytes/sec) and timewin (machclk unit) are
- * less than 32 bits, the following 64-bit operation has enough
- * precision.
- */
- tmp = ((u_int64_t)tsw->avg_rate * tsw->timewin
- + (u_int64_t)len * machclk_freq) / (tsw->timewin + interval);
- tsw->avg_rate = avg_rate = (u_int32_t)tmp;
- tsw->t_front = now;
-
- /*
- * marker
- */
- if (avg_rate > tsw->cmtd_rate) {
- u_int32_t randval = arc4random() % avg_rate;
-
- if (avg_rate > tsw->peak_rate) {
- if (randval < avg_rate - tsw->peak_rate) {
- /* mark red */
- pktinfo->pkt_dscp = tsw->red_dscp;
- PKTCNTR_ADD(&tsw->red_cnt, len);
- return (&tsw->red_action);
- } else if (randval < avg_rate - tsw->cmtd_rate)
- goto mark_yellow;
- } else {
- /* peak_rate >= avg_rate > cmtd_rate */
- if (randval < avg_rate - tsw->cmtd_rate) {
- mark_yellow:
- pktinfo->pkt_dscp = tsw->yellow_dscp;
- PKTCNTR_ADD(&tsw->yellow_cnt, len);
- return (&tsw->yellow_action);
- }
- }
- }
-
- /* mark green */
- pktinfo->pkt_dscp = tsw->green_dscp;
- PKTCNTR_ADD(&tsw->green_cnt, len);
- return (&tsw->green_action);
-}
-
-/*
- * ioctl requests
- */
-static int
-cdnrcmd_if_attach(ifname)
- char *ifname;
-{
- struct ifnet *ifp;
- struct top_cdnr *top;
-
- if ((ifp = ifunit(ifname)) == NULL)
- return (EBADF);
-
- if (ifp->if_snd.altq_cdnr != NULL)
- return (EBUSY);
-
- if ((top = top_create(&ifp->if_snd)) == NULL)
- return (ENOMEM);
- return (0);
-}
-
-static int
-cdnrcmd_if_detach(ifname)
- char *ifname;
-{
- struct top_cdnr *top;
-
- if ((top = tcb_lookup(ifname)) == NULL)
- return (EBADF);
-
- return top_destroy(top);
-}
-
-static int
-cdnrcmd_add_element(ap)
- struct cdnr_add_element *ap;
-{
- struct top_cdnr *top;
- struct cdnr_block *cb;
-
- if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
- return (EBADF);
-
- cb = element_create(top, &ap->action);
- if (cb == NULL)
- return (EINVAL);
- /* return a class handle to the user */
- ap->cdnr_handle = cdnr_cb2handle(cb);
- return (0);
-}
-
-static int
-cdnrcmd_delete_element(ap)
- struct cdnr_delete_element *ap;
-{
- struct top_cdnr *top;
- struct cdnr_block *cb;
-
- if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
- return (EBADF);
-
- if ((cb = cdnr_handle2cb(ap->cdnr_handle)) == NULL)
- return (EINVAL);
-
- if (cb->cb_type != TCETYPE_ELEMENT)
- return generic_element_destroy(cb);
-
- return element_destroy(cb);
-}
-
-static int
-cdnrcmd_add_filter(ap)
- struct cdnr_add_filter *ap;
-{
- struct top_cdnr *top;
- struct cdnr_block *cb;
-
- if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
- return (EBADF);
-
- if ((cb = cdnr_handle2cb(ap->cdnr_handle)) == NULL)
- return (EINVAL);
-
- return acc_add_filter(&top->tc_classifier, &ap->filter,
- cb, &ap->filter_handle);
-}
-
-static int
-cdnrcmd_delete_filter(ap)
- struct cdnr_delete_filter *ap;
-{
- struct top_cdnr *top;
-
- if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
- return (EBADF);
-
- return acc_delete_filter(&top->tc_classifier, ap->filter_handle);
-}
-
-static int
-cdnrcmd_add_tbm(ap)
- struct cdnr_add_tbmeter *ap;
-{
- struct top_cdnr *top;
- struct tbmeter *tbm;
-
- if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
- return (EBADF);
-
- tbm = tbm_create(top, &ap->profile, &ap->in_action, &ap->out_action);
- if (tbm == NULL)
- return (EINVAL);
- /* return a class handle to the user */
- ap->cdnr_handle = cdnr_cb2handle(&tbm->cdnrblk);
- return (0);
-}
-
-static int
-cdnrcmd_modify_tbm(ap)
- struct cdnr_modify_tbmeter *ap;
-{
- struct tbmeter *tbm;
-
- if ((tbm = (struct tbmeter *)cdnr_handle2cb(ap->cdnr_handle)) == NULL)
- return (EINVAL);
-
- tb_import_profile(&tbm->tb, &ap->profile);
-
- return (0);
-}
-
-static int
-cdnrcmd_tbm_stats(ap)
- struct cdnr_tbmeter_stats *ap;
-{
- struct tbmeter *tbm;
-
- if ((tbm = (struct tbmeter *)cdnr_handle2cb(ap->cdnr_handle)) == NULL)
- return (EINVAL);
-
- ap->in_cnt = tbm->in_cnt;
- ap->out_cnt = tbm->out_cnt;
-
- return (0);
-}
-
-static int
-cdnrcmd_add_trtcm(ap)
- struct cdnr_add_trtcm *ap;
-{
- struct top_cdnr *top;
- struct trtcm *tcm;
-
- if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
- return (EBADF);
-
- tcm = trtcm_create(top, &ap->cmtd_profile, &ap->peak_profile,
- &ap->green_action, &ap->yellow_action,
- &ap->red_action, ap->coloraware);
- if (tcm == NULL)
- return (EINVAL);
-
- /* return a class handle to the user */
- ap->cdnr_handle = cdnr_cb2handle(&tcm->cdnrblk);
- return (0);
-}
-
-static int
-cdnrcmd_modify_trtcm(ap)
- struct cdnr_modify_trtcm *ap;
-{
- struct trtcm *tcm;
-
- if ((tcm = (struct trtcm *)cdnr_handle2cb(ap->cdnr_handle)) == NULL)
- return (EINVAL);
-
- tb_import_profile(&tcm->cmtd_tb, &ap->cmtd_profile);
- tb_import_profile(&tcm->peak_tb, &ap->peak_profile);
-
- return (0);
-}
-
-static int
-cdnrcmd_tcm_stats(ap)
- struct cdnr_tcm_stats *ap;
-{
- struct cdnr_block *cb;
-
- if ((cb = cdnr_handle2cb(ap->cdnr_handle)) == NULL)
- return (EINVAL);
-
- if (cb->cb_type == TCETYPE_TRTCM) {
- struct trtcm *tcm = (struct trtcm *)cb;
-
- ap->green_cnt = tcm->green_cnt;
- ap->yellow_cnt = tcm->yellow_cnt;
- ap->red_cnt = tcm->red_cnt;
- } else if (cb->cb_type == TCETYPE_TSWTCM) {
- struct tswtcm *tsw = (struct tswtcm *)cb;
-
- ap->green_cnt = tsw->green_cnt;
- ap->yellow_cnt = tsw->yellow_cnt;
- ap->red_cnt = tsw->red_cnt;
- } else
- return (EINVAL);
-
- return (0);
-}
-
-static int
-cdnrcmd_add_tswtcm(ap)
- struct cdnr_add_tswtcm *ap;
-{
- struct top_cdnr *top;
- struct tswtcm *tsw;
-
- if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
- return (EBADF);
-
- if (ap->cmtd_rate > ap->peak_rate)
- return (EINVAL);
-
- tsw = tswtcm_create(top, ap->cmtd_rate, ap->peak_rate,
- ap->avg_interval, &ap->green_action,
- &ap->yellow_action, &ap->red_action);
- if (tsw == NULL)
- return (EINVAL);
-
- /* return a class handle to the user */
- ap->cdnr_handle = cdnr_cb2handle(&tsw->cdnrblk);
- return (0);
-}
-
-static int
-cdnrcmd_modify_tswtcm(ap)
- struct cdnr_modify_tswtcm *ap;
-{
- struct tswtcm *tsw;
-
- if ((tsw = (struct tswtcm *)cdnr_handle2cb(ap->cdnr_handle)) == NULL)
- return (EINVAL);
-
- if (ap->cmtd_rate > ap->peak_rate)
- return (EINVAL);
-
- /* convert rates from bits/sec to bytes/sec */
- tsw->cmtd_rate = ap->cmtd_rate / 8;
- tsw->peak_rate = ap->peak_rate / 8;
- tsw->avg_rate = 0;
-
- /* timewin is converted from msec to machine clock unit */
- tsw->timewin = (u_int64_t)machclk_freq * ap->avg_interval / 1000;
-
- return (0);
-}
-
-static int
-cdnrcmd_get_stats(ap)
- struct cdnr_get_stats *ap;
-{
- struct top_cdnr *top;
- struct cdnr_block *cb;
- struct tbmeter *tbm;
- struct trtcm *tcm;
- struct tswtcm *tsw;
- struct tce_stats tce, *usp;
- int error, n, nskip, nelements;
-
- if ((top = tcb_lookup(ap->iface.cdnr_ifname)) == NULL)
- return (EBADF);
-
- /* copy action stats */
- bcopy(top->tc_cnts, ap->cnts, sizeof(ap->cnts));
-
- /* stats for each element */
- nelements = ap->nelements;
- usp = ap->tce_stats;
- if (nelements <= 0 || usp == NULL)
- return (0);
-
- nskip = ap->nskip;
- n = 0;
- LIST_FOREACH(cb, &top->tc_elements, cb_next) {
- if (nskip > 0) {
- nskip--;
- continue;
- }
-
- bzero(&tce, sizeof(tce));
- tce.tce_handle = cb->cb_handle;
- tce.tce_type = cb->cb_type;
- switch (cb->cb_type) {
- case TCETYPE_TBMETER:
- tbm = (struct tbmeter *)cb;
- tce.tce_cnts[0] = tbm->in_cnt;
- tce.tce_cnts[1] = tbm->out_cnt;
- break;
- case TCETYPE_TRTCM:
- tcm = (struct trtcm *)cb;
- tce.tce_cnts[0] = tcm->green_cnt;
- tce.tce_cnts[1] = tcm->yellow_cnt;
- tce.tce_cnts[2] = tcm->red_cnt;
- break;
- case TCETYPE_TSWTCM:
- tsw = (struct tswtcm *)cb;
- tce.tce_cnts[0] = tsw->green_cnt;
- tce.tce_cnts[1] = tsw->yellow_cnt;
- tce.tce_cnts[2] = tsw->red_cnt;
- break;
- default:
- continue;
- }
-
- if ((error = copyout((caddr_t)&tce, (caddr_t)usp++,
- sizeof(tce))) != 0)
- return (error);
-
- if (++n == nelements)
- break;
- }
- ap->nelements = n;
-
- return (0);
-}
-
-/*
- * conditioner device interface
- */
-int
-cdnropen(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- if (machclk_freq == 0)
- init_machclk();
-
- if (machclk_freq == 0) {
- printf("cdnr: no cpu clock available!\n");
- return (ENXIO);
- }
-
- /* everything will be done when the queueing scheme is attached. */
- return 0;
-}
-
-int
-cdnrclose(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- struct top_cdnr *top;
- int err, error = 0;
-
- while ((top = LIST_FIRST(&tcb_list)) != NULL) {
- /* destroy all */
- err = top_destroy(top);
- if (err != 0 && error == 0)
- error = err;
- }
- altq_input = NULL;
-
- return (error);
-}
-
-int
-cdnrioctl(dev, cmd, addr, flag, p)
- dev_t dev;
- ioctlcmd_t cmd;
- caddr_t addr;
- int flag;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- struct top_cdnr *top;
- struct cdnr_interface *ifacep;
- int s, error = 0;
-
- /* check super-user privilege */
- switch (cmd) {
- case CDNR_GETSTATS:
- break;
- default:
-#if (__FreeBSD_version > 700000)
- if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0)
-#elsif (__FreeBSD_version > 400000)
- if ((error = suser(p)) != 0)
-#else
- if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
-#endif
- return (error);
- break;
- }
-
- s = splnet();
- switch (cmd) {
-
- case CDNR_IF_ATTACH:
- ifacep = (struct cdnr_interface *)addr;
- error = cdnrcmd_if_attach(ifacep->cdnr_ifname);
- break;
-
- case CDNR_IF_DETACH:
- ifacep = (struct cdnr_interface *)addr;
- error = cdnrcmd_if_detach(ifacep->cdnr_ifname);
- break;
-
- case CDNR_ENABLE:
- case CDNR_DISABLE:
- ifacep = (struct cdnr_interface *)addr;
- if ((top = tcb_lookup(ifacep->cdnr_ifname)) == NULL) {
- error = EBADF;
- break;
- }
-
- switch (cmd) {
-
- case CDNR_ENABLE:
- ALTQ_SET_CNDTNING(top->tc_ifq);
- if (altq_input == NULL)
- altq_input = altq_cdnr_input;
- break;
-
- case CDNR_DISABLE:
- ALTQ_CLEAR_CNDTNING(top->tc_ifq);
- LIST_FOREACH(top, &tcb_list, tc_next)
- if (ALTQ_IS_CNDTNING(top->tc_ifq))
- break;
- if (top == NULL)
- altq_input = NULL;
- break;
- }
- break;
-
- case CDNR_ADD_ELEM:
- error = cdnrcmd_add_element((struct cdnr_add_element *)addr);
- break;
-
- case CDNR_DEL_ELEM:
- error = cdnrcmd_delete_element((struct cdnr_delete_element *)addr);
- break;
-
- case CDNR_ADD_TBM:
- error = cdnrcmd_add_tbm((struct cdnr_add_tbmeter *)addr);
- break;
-
- case CDNR_MOD_TBM:
- error = cdnrcmd_modify_tbm((struct cdnr_modify_tbmeter *)addr);
- break;
-
- case CDNR_TBM_STATS:
- error = cdnrcmd_tbm_stats((struct cdnr_tbmeter_stats *)addr);
- break;
-
- case CDNR_ADD_TCM:
- error = cdnrcmd_add_trtcm((struct cdnr_add_trtcm *)addr);
- break;
-
- case CDNR_MOD_TCM:
- error = cdnrcmd_modify_trtcm((struct cdnr_modify_trtcm *)addr);
- break;
-
- case CDNR_TCM_STATS:
- error = cdnrcmd_tcm_stats((struct cdnr_tcm_stats *)addr);
- break;
-
- case CDNR_ADD_FILTER:
- error = cdnrcmd_add_filter((struct cdnr_add_filter *)addr);
- break;
-
- case CDNR_DEL_FILTER:
- error = cdnrcmd_delete_filter((struct cdnr_delete_filter *)addr);
- break;
-
- case CDNR_GETSTATS:
- error = cdnrcmd_get_stats((struct cdnr_get_stats *)addr);
- break;
-
- case CDNR_ADD_TSW:
- error = cdnrcmd_add_tswtcm((struct cdnr_add_tswtcm *)addr);
- break;
-
- case CDNR_MOD_TSW:
- error = cdnrcmd_modify_tswtcm((struct cdnr_modify_tswtcm *)addr);
- break;
-
- default:
- error = EINVAL;
- break;
- }
- splx(s);
-
- return error;
-}
-
-#ifdef KLD_MODULE
-
-static struct altqsw cdnr_sw =
- {"cdnr", cdnropen, cdnrclose, cdnrioctl};
-
-ALTQ_MODULE(altq_cdnr, ALTQT_CDNR, &cdnr_sw);
-
-#endif /* KLD_MODULE */
-
-#endif /* ALTQ3_COMPAT */
-#endif /* ALTQ_CDNR */
diff --git a/freebsd/sys/net/altq/altq_hfsc.c b/freebsd/sys/net/altq/altq_hfsc.c
index 8d8fdfdc..202915a8 100644
--- a/freebsd/sys/net/altq/altq_hfsc.c
+++ b/freebsd/sys/net/altq/altq_hfsc.c
@@ -72,9 +72,6 @@
#include <netpfil/pf/pf_mtag.h>
#include <net/altq/altq.h>
#include <net/altq/altq_hfsc.h>
-#ifdef ALTQ3_COMPAT
-#include <net/altq/altq_conf.h>
-#endif
/*
* function prototypes
@@ -139,23 +136,6 @@ static void get_class_stats_v1(struct hfsc_classstats_v1 *,
static struct hfsc_class *clh_to_clp(struct hfsc_if *, u_int32_t);
-#ifdef ALTQ3_COMPAT
-static struct hfsc_if *hfsc_attach(struct ifaltq *, u_int);
-static int hfsc_detach(struct hfsc_if *);
-static int hfsc_class_modify(struct hfsc_class *, struct service_curve *,
- struct service_curve *, struct service_curve *);
-
-static int hfsccmd_if_attach(struct hfsc_attach *);
-static int hfsccmd_if_detach(struct hfsc_interface *);
-static int hfsccmd_add_class(struct hfsc_add_class *);
-static int hfsccmd_delete_class(struct hfsc_delete_class *);
-static int hfsccmd_modify_class(struct hfsc_modify_class *);
-static int hfsccmd_add_filter(struct hfsc_add_filter *);
-static int hfsccmd_delete_filter(struct hfsc_delete_filter *);
-static int hfsccmd_class_stats(struct hfsc_class_stats *);
-
-altqdev_decl(hfsc);
-#endif /* ALTQ3_COMPAT */
/*
* macros
@@ -164,10 +144,6 @@ altqdev_decl(hfsc);
#define HT_INFINITY 0xffffffffffffffffULL /* infinite time value */
-#ifdef ALTQ3_COMPAT
-/* hif_list keeps all hfsc_if's allocated. */
-static struct hfsc_if *hif_list = NULL;
-#endif /* ALTQ3_COMPAT */
int
hfsc_pfattach(struct pf_altq *a)
@@ -334,10 +310,6 @@ hfsc_clear_interface(struct hfsc_if *hif)
{
struct hfsc_class *cl;
-#ifdef ALTQ3_COMPAT
- /* free the filters for this interface */
- acc_discard_filters(&hif->hif_classifier, NULL, 1);
-#endif
/* clear out the classes */
while (hif->hif_rootclass != NULL &&
@@ -599,10 +571,6 @@ hfsc_class_destroy(struct hfsc_class *cl)
s = splnet();
IFQ_LOCK(cl->cl_hif->hif_ifq);
-#ifdef ALTQ3_COMPAT
- /* delete filters referencing to this class */
- acc_discard_filters(&cl->cl_hif->hif_classifier, cl, 0);
-#endif /* ALTQ3_COMPAT */
if (!qempty(cl->cl_q))
hfsc_purgeq(cl);
@@ -716,10 +684,6 @@ hfsc_enqueue(struct ifaltq *ifq, struct mbuf *m, struct altq_pktattr *pktattr)
cl = NULL;
if ((t = pf_find_mtag(m)) != NULL)
cl = clh_to_clp(hif, t->qid);
-#ifdef ALTQ3_COMPAT
- else if ((ifq->altq_flags & ALTQF_CLASSIFY) && pktattr != NULL)
- cl = pktattr->pattr_class;
-#endif
if (cl == NULL || is_a_parent_class(cl)) {
cl = hif->hif_defaultclass;
if (cl == NULL) {
@@ -727,12 +691,7 @@ hfsc_enqueue(struct ifaltq *ifq, struct mbuf *m, struct altq_pktattr *pktattr)
return (ENOBUFS);
}
}
-#ifdef ALTQ3_COMPAT
- if (pktattr != NULL)
- cl->cl_pktattr = pktattr; /* save proto hdr used by ECN */
- else
-#endif
- cl->cl_pktattr = NULL;
+ cl->cl_pktattr = NULL;
len = m_pktlen(m);
if (hfsc_addq(cl, m) != 0) {
/* drop occurred. mbuf was freed in hfsc_addq. */
@@ -1790,542 +1749,5 @@ clh_to_clp(struct hfsc_if *hif, u_int32_t chandle)
return (NULL);
}
-#ifdef ALTQ3_COMPAT
-static struct hfsc_if *
-hfsc_attach(ifq, bandwidth)
- struct ifaltq *ifq;
- u_int bandwidth;
-{
- struct hfsc_if *hif;
-
- hif = malloc(sizeof(struct hfsc_if), M_DEVBUF, M_WAITOK);
- if (hif == NULL)
- return (NULL);
- bzero(hif, sizeof(struct hfsc_if));
-
- hif->hif_eligible = ellist_alloc();
- if (hif->hif_eligible == NULL) {
- free(hif, M_DEVBUF);
- return NULL;
- }
-
- hif->hif_ifq = ifq;
-
- /* add this state to the hfsc list */
- hif->hif_next = hif_list;
- hif_list = hif;
-
- return (hif);
-}
-
-static int
-hfsc_detach(hif)
- struct hfsc_if *hif;
-{
- (void)hfsc_clear_interface(hif);
- (void)hfsc_class_destroy(hif->hif_rootclass);
-
- /* remove this interface from the hif list */
- if (hif_list == hif)
- hif_list = hif->hif_next;
- else {
- struct hfsc_if *h;
-
- for (h = hif_list; h != NULL; h = h->hif_next)
- if (h->hif_next == hif) {
- h->hif_next = hif->hif_next;
- break;
- }
- ASSERT(h != NULL);
- }
-
- ellist_destroy(hif->hif_eligible);
-
- free(hif, M_DEVBUF);
-
- return (0);
-}
-
-static int
-hfsc_class_modify(cl, rsc, fsc, usc)
- struct hfsc_class *cl;
- struct service_curve *rsc, *fsc, *usc;
-{
- struct internal_sc *rsc_tmp, *fsc_tmp, *usc_tmp;
- u_int64_t cur_time;
- int s;
-
- rsc_tmp = fsc_tmp = usc_tmp = NULL;
- if (rsc != NULL && (rsc->m1 != 0 || rsc->m2 != 0) &&
- cl->cl_rsc == NULL) {
- rsc_tmp = malloc(sizeof(struct internal_sc),
- M_DEVBUF, M_WAITOK);
- if (rsc_tmp == NULL)
- return (ENOMEM);
- }
- if (fsc != NULL && (fsc->m1 != 0 || fsc->m2 != 0) &&
- cl->cl_fsc == NULL) {
- fsc_tmp = malloc(sizeof(struct internal_sc),
- M_DEVBUF, M_WAITOK);
- if (fsc_tmp == NULL) {
- free(rsc_tmp);
- return (ENOMEM);
- }
- }
- if (usc != NULL && (usc->m1 != 0 || usc->m2 != 0) &&
- cl->cl_usc == NULL) {
- usc_tmp = malloc(sizeof(struct internal_sc),
- M_DEVBUF, M_WAITOK);
- if (usc_tmp == NULL) {
- free(rsc_tmp);
- free(fsc_tmp);
- return (ENOMEM);
- }
- }
-
- cur_time = read_machclk();
- s = splnet();
- IFQ_LOCK(cl->cl_hif->hif_ifq);
-
- if (rsc != NULL) {
- if (rsc->m1 == 0 && rsc->m2 == 0) {
- if (cl->cl_rsc != NULL) {
- if (!qempty(cl->cl_q))
- hfsc_purgeq(cl);
- free(cl->cl_rsc, M_DEVBUF);
- cl->cl_rsc = NULL;
- }
- } else {
- if (cl->cl_rsc == NULL)
- cl->cl_rsc = rsc_tmp;
- sc2isc(rsc, cl->cl_rsc);
- rtsc_init(&cl->cl_deadline, cl->cl_rsc, cur_time,
- cl->cl_cumul);
- cl->cl_eligible = cl->cl_deadline;
- if (cl->cl_rsc->sm1 <= cl->cl_rsc->sm2) {
- cl->cl_eligible.dx = 0;
- cl->cl_eligible.dy = 0;
- }
- }
- }
-
- if (fsc != NULL) {
- if (fsc->m1 == 0 && fsc->m2 == 0) {
- if (cl->cl_fsc != NULL) {
- if (!qempty(cl->cl_q))
- hfsc_purgeq(cl);
- free(cl->cl_fsc, M_DEVBUF);
- cl->cl_fsc = NULL;
- }
- } else {
- if (cl->cl_fsc == NULL)
- cl->cl_fsc = fsc_tmp;
- sc2isc(fsc, cl->cl_fsc);
- rtsc_init(&cl->cl_virtual, cl->cl_fsc, cl->cl_vt,
- cl->cl_total);
- }
- }
-
- if (usc != NULL) {
- if (usc->m1 == 0 && usc->m2 == 0) {
- if (cl->cl_usc != NULL) {
- free(cl->cl_usc, M_DEVBUF);
- cl->cl_usc = NULL;
- cl->cl_myf = 0;
- }
- } else {
- if (cl->cl_usc == NULL)
- cl->cl_usc = usc_tmp;
- sc2isc(usc, cl->cl_usc);
- rtsc_init(&cl->cl_ulimit, cl->cl_usc, cur_time,
- cl->cl_total);
- }
- }
-
- if (!qempty(cl->cl_q)) {
- if (cl->cl_rsc != NULL)
- update_ed(cl, m_pktlen(qhead(cl->cl_q)));
- if (cl->cl_fsc != NULL)
- update_vf(cl, 0, cur_time);
- /* is this enough? */
- }
-
- IFQ_UNLOCK(cl->cl_hif->hif_ifq);
- splx(s);
-
- return (0);
-}
-
-/*
- * hfsc device interface
- */
-int
-hfscopen(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- if (machclk_freq == 0)
- init_machclk();
-
- if (machclk_freq == 0) {
- printf("hfsc: no cpu clock available!\n");
- return (ENXIO);
- }
-
- /* everything will be done when the queueing scheme is attached. */
- return 0;
-}
-
-int
-hfscclose(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- struct hfsc_if *hif;
- int err, error = 0;
-
- while ((hif = hif_list) != NULL) {
- /* destroy all */
- if (ALTQ_IS_ENABLED(hif->hif_ifq))
- altq_disable(hif->hif_ifq);
-
- err = altq_detach(hif->hif_ifq);
- if (err == 0)
- err = hfsc_detach(hif);
- if (err != 0 && error == 0)
- error = err;
- }
-
- return error;
-}
-
-int
-hfscioctl(dev, cmd, addr, flag, p)
- dev_t dev;
- ioctlcmd_t cmd;
- caddr_t addr;
- int flag;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- struct hfsc_if *hif;
- struct hfsc_interface *ifacep;
- int error = 0;
-
- /* check super-user privilege */
- switch (cmd) {
- case HFSC_GETSTATS:
- break;
- default:
-#if (__FreeBSD_version > 700000)
- if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0)
- return (error);
-#elsif (__FreeBSD_version > 400000)
- if ((error = suser(p)) != 0)
- return (error);
-#else
- if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
- return (error);
-#endif
- break;
- }
-
- switch (cmd) {
-
- case HFSC_IF_ATTACH:
- error = hfsccmd_if_attach((struct hfsc_attach *)addr);
- break;
-
- case HFSC_IF_DETACH:
- error = hfsccmd_if_detach((struct hfsc_interface *)addr);
- break;
-
- case HFSC_ENABLE:
- case HFSC_DISABLE:
- case HFSC_CLEAR_HIERARCHY:
- ifacep = (struct hfsc_interface *)addr;
- if ((hif = altq_lookup(ifacep->hfsc_ifname,
- ALTQT_HFSC)) == NULL) {
- error = EBADF;
- break;
- }
-
- switch (cmd) {
-
- case HFSC_ENABLE:
- if (hif->hif_defaultclass == NULL) {
-#ifdef ALTQ_DEBUG
- printf("hfsc: no default class\n");
-#endif
- error = EINVAL;
- break;
- }
- error = altq_enable(hif->hif_ifq);
- break;
-
- case HFSC_DISABLE:
- error = altq_disable(hif->hif_ifq);
- break;
-
- case HFSC_CLEAR_HIERARCHY:
- hfsc_clear_interface(hif);
- break;
- }
- break;
-
- case HFSC_ADD_CLASS:
- error = hfsccmd_add_class((struct hfsc_add_class *)addr);
- break;
-
- case HFSC_DEL_CLASS:
- error = hfsccmd_delete_class((struct hfsc_delete_class *)addr);
- break;
-
- case HFSC_MOD_CLASS:
- error = hfsccmd_modify_class((struct hfsc_modify_class *)addr);
- break;
-
- case HFSC_ADD_FILTER:
- error = hfsccmd_add_filter((struct hfsc_add_filter *)addr);
- break;
-
- case HFSC_DEL_FILTER:
- error = hfsccmd_delete_filter((struct hfsc_delete_filter *)addr);
- break;
-
- case HFSC_GETSTATS:
- error = hfsccmd_class_stats((struct hfsc_class_stats *)addr);
- break;
-
- default:
- error = EINVAL;
- break;
- }
- return error;
-}
-
-static int
-hfsccmd_if_attach(ap)
- struct hfsc_attach *ap;
-{
- struct hfsc_if *hif;
- struct ifnet *ifp;
- int error;
-
- if ((ifp = ifunit(ap->iface.hfsc_ifname)) == NULL)
- return (ENXIO);
-
- if ((hif = hfsc_attach(&ifp->if_snd, ap->bandwidth)) == NULL)
- return (ENOMEM);
-
- /*
- * set HFSC to this ifnet structure.
- */
- if ((error = altq_attach(&ifp->if_snd, ALTQT_HFSC, hif,
- hfsc_enqueue, hfsc_dequeue, hfsc_request,
- &hif->hif_classifier, acc_classify)) != 0)
- (void)hfsc_detach(hif);
-
- return (error);
-}
-
-static int
-hfsccmd_if_detach(ap)
- struct hfsc_interface *ap;
-{
- struct hfsc_if *hif;
- int error;
-
- if ((hif = altq_lookup(ap->hfsc_ifname, ALTQT_HFSC)) == NULL)
- return (EBADF);
-
- if (ALTQ_IS_ENABLED(hif->hif_ifq))
- altq_disable(hif->hif_ifq);
-
- if ((error = altq_detach(hif->hif_ifq)))
- return (error);
-
- return hfsc_detach(hif);
-}
-
-static int
-hfsccmd_add_class(ap)
- struct hfsc_add_class *ap;
-{
- struct hfsc_if *hif;
- struct hfsc_class *cl, *parent;
- int i;
-
- if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL)
- return (EBADF);
-
- if (ap->parent_handle == HFSC_NULLCLASS_HANDLE &&
- hif->hif_rootclass == NULL)
- parent = NULL;
- else if ((parent = clh_to_clp(hif, ap->parent_handle)) == NULL)
- return (EINVAL);
-
- /* assign a class handle (use a free slot number for now) */
- for (i = 1; i < HFSC_MAX_CLASSES; i++)
- if (hif->hif_class_tbl[i] == NULL)
- break;
- if (i == HFSC_MAX_CLASSES)
- return (EBUSY);
-
- if ((cl = hfsc_class_create(hif, &ap->service_curve, NULL, NULL,
- parent, ap->qlimit, ap->flags, i)) == NULL)
- return (ENOMEM);
-
- /* return a class handle to the user */
- ap->class_handle = i;
-
- return (0);
-}
-
-static int
-hfsccmd_delete_class(ap)
- struct hfsc_delete_class *ap;
-{
- struct hfsc_if *hif;
- struct hfsc_class *cl;
-
- if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL)
- return (EBADF);
-
- if ((cl = clh_to_clp(hif, ap->class_handle)) == NULL)
- return (EINVAL);
-
- return hfsc_class_destroy(cl);
-}
-
-static int
-hfsccmd_modify_class(ap)
- struct hfsc_modify_class *ap;
-{
- struct hfsc_if *hif;
- struct hfsc_class *cl;
- struct service_curve *rsc = NULL;
- struct service_curve *fsc = NULL;
- struct service_curve *usc = NULL;
-
- if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL)
- return (EBADF);
-
- if ((cl = clh_to_clp(hif, ap->class_handle)) == NULL)
- return (EINVAL);
-
- if (ap->sctype & HFSC_REALTIMESC)
- rsc = &ap->service_curve;
- if (ap->sctype & HFSC_LINKSHARINGSC)
- fsc = &ap->service_curve;
- if (ap->sctype & HFSC_UPPERLIMITSC)
- usc = &ap->service_curve;
-
- return hfsc_class_modify(cl, rsc, fsc, usc);
-}
-
-static int
-hfsccmd_add_filter(ap)
- struct hfsc_add_filter *ap;
-{
- struct hfsc_if *hif;
- struct hfsc_class *cl;
-
- if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL)
- return (EBADF);
-
- if ((cl = clh_to_clp(hif, ap->class_handle)) == NULL)
- return (EINVAL);
-
- if (is_a_parent_class(cl)) {
-#ifdef ALTQ_DEBUG
- printf("hfsccmd_add_filter: not a leaf class!\n");
-#endif
- return (EINVAL);
- }
-
- return acc_add_filter(&hif->hif_classifier, &ap->filter,
- cl, &ap->filter_handle);
-}
-
-static int
-hfsccmd_delete_filter(ap)
- struct hfsc_delete_filter *ap;
-{
- struct hfsc_if *hif;
-
- if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL)
- return (EBADF);
-
- return acc_delete_filter(&hif->hif_classifier,
- ap->filter_handle);
-}
-
-static int
-hfsccmd_class_stats(ap)
- struct hfsc_class_stats *ap;
-{
- struct hfsc_if *hif;
- struct hfsc_class *cl;
- struct hfsc_classstats stats, *usp;
- int n, nclasses, error;
-
- if ((hif = altq_lookup(ap->iface.hfsc_ifname, ALTQT_HFSC)) == NULL)
- return (EBADF);
-
- ap->cur_time = read_machclk();
- ap->machclk_freq = machclk_freq;
- ap->hif_classes = hif->hif_classes;
- ap->hif_packets = hif->hif_packets;
-
- /* skip the first N classes in the tree */
- nclasses = ap->nskip;
- for (cl = hif->hif_rootclass, n = 0; cl != NULL && n < nclasses;
- cl = hfsc_nextclass(cl), n++)
- ;
- if (n != nclasses)
- return (EINVAL);
-
- /* then, read the next N classes in the tree */
- nclasses = ap->nclasses;
- usp = ap->stats;
- for (n = 0; cl != NULL && n < nclasses; cl = hfsc_nextclass(cl), n++) {
-
- get_class_stats(&stats, cl);
-
- if ((error = copyout((caddr_t)&stats, (caddr_t)usp++,
- sizeof(stats))) != 0)
- return (error);
- }
-
- ap->nclasses = n;
-
- return (0);
-}
-
-#ifdef KLD_MODULE
-
-static struct altqsw hfsc_sw =
- {"hfsc", hfscopen, hfscclose, hfscioctl};
-
-ALTQ_MODULE(altq_hfsc, ALTQT_HFSC, &hfsc_sw);
-MODULE_DEPEND(altq_hfsc, altq_red, 1, 1, 1);
-MODULE_DEPEND(altq_hfsc, altq_rio, 1, 1, 1);
-
-#endif /* KLD_MODULE */
-#endif /* ALTQ3_COMPAT */
#endif /* ALTQ_HFSC */
diff --git a/freebsd/sys/net/altq/altq_hfsc.h b/freebsd/sys/net/altq/altq_hfsc.h
index 67ec0036..fa4aa811 100644
--- a/freebsd/sys/net/altq/altq_hfsc.h
+++ b/freebsd/sys/net/altq/altq_hfsc.h
@@ -168,74 +168,6 @@ struct hfsc_classstats_v1 {
* header.
*/
-#ifdef ALTQ3_COMPAT
-struct hfsc_interface {
- char hfsc_ifname[IFNAMSIZ]; /* interface name (e.g., fxp0) */
-};
-
-struct hfsc_attach {
- struct hfsc_interface iface;
- u_int bandwidth; /* link bandwidth in bits/sec */
-};
-
-struct hfsc_add_class {
- struct hfsc_interface iface;
- u_int32_t parent_handle;
- struct service_curve service_curve;
- int qlimit;
- int flags;
-
- u_int32_t class_handle; /* return value */
-};
-
-struct hfsc_delete_class {
- struct hfsc_interface iface;
- u_int32_t class_handle;
-};
-
-struct hfsc_modify_class {
- struct hfsc_interface iface;
- u_int32_t class_handle;
- struct service_curve service_curve;
- int sctype;
-};
-
-struct hfsc_add_filter {
- struct hfsc_interface iface;
- u_int32_t class_handle;
- struct flow_filter filter;
-
- u_long filter_handle; /* return value */
-};
-
-struct hfsc_delete_filter {
- struct hfsc_interface iface;
- u_long filter_handle;
-};
-
-struct hfsc_class_stats {
- struct hfsc_interface iface;
- int nskip; /* skip # of classes */
- int nclasses; /* # of class stats (WR) */
- u_int64_t cur_time; /* current time */
- u_int32_t machclk_freq; /* machine clock frequency */
- u_int hif_classes; /* # of classes in the tree */
- u_int hif_packets; /* # of packets in the tree */
- struct hfsc_classstats *stats; /* pointer to stats array */
-};
-
-#define HFSC_IF_ATTACH _IOW('Q', 1, struct hfsc_attach)
-#define HFSC_IF_DETACH _IOW('Q', 2, struct hfsc_interface)
-#define HFSC_ENABLE _IOW('Q', 3, struct hfsc_interface)
-#define HFSC_DISABLE _IOW('Q', 4, struct hfsc_interface)
-#define HFSC_CLEAR_HIERARCHY _IOW('Q', 5, struct hfsc_interface)
-#define HFSC_ADD_CLASS _IOWR('Q', 7, struct hfsc_add_class)
-#define HFSC_DEL_CLASS _IOW('Q', 8, struct hfsc_delete_class)
-#define HFSC_MOD_CLASS _IOW('Q', 9, struct hfsc_modify_class)
-#define HFSC_ADD_FILTER _IOWR('Q', 10, struct hfsc_add_filter)
-#define HFSC_DEL_FILTER _IOW('Q', 11, struct hfsc_delete_filter)
-#define HFSC_GETSTATS _IOWR('Q', 12, struct hfsc_class_stats)
-#endif /* ALTQ3_COMPAT */
#ifdef _KERNEL
/*
diff --git a/freebsd/sys/net/altq/altq_priq.c b/freebsd/sys/net/altq/altq_priq.c
index ce0830eb..5e77aef2 100644
--- a/freebsd/sys/net/altq/altq_priq.c
+++ b/freebsd/sys/net/altq/altq_priq.c
@@ -57,18 +57,11 @@
#include <netpfil/pf/pf_altq.h>
#include <netpfil/pf/pf_mtag.h>
#include <net/altq/altq.h>
-#ifdef ALTQ3_COMPAT
-#include <net/altq/altq_conf.h>
-#endif
#include <net/altq/altq_priq.h>
/*
* function prototypes
*/
-#ifdef ALTQ3_COMPAT
-static struct priq_if *priq_attach(struct ifaltq *, u_int);
-static int priq_detach(struct priq_if *);
-#endif
static int priq_clear_interface(struct priq_if *);
static int priq_request(struct ifaltq *, int, void *);
static void priq_purge(struct priq_if *);
@@ -83,26 +76,10 @@ static struct mbuf *priq_getq(struct priq_class *);
static struct mbuf *priq_pollq(struct priq_class *);
static void priq_purgeq(struct priq_class *);
-#ifdef ALTQ3_COMPAT
-static int priqcmd_if_attach(struct priq_interface *);
-static int priqcmd_if_detach(struct priq_interface *);
-static int priqcmd_add_class(struct priq_add_class *);
-static int priqcmd_delete_class(struct priq_delete_class *);
-static int priqcmd_modify_class(struct priq_modify_class *);
-static int priqcmd_add_filter(struct priq_add_filter *);
-static int priqcmd_delete_filter(struct priq_delete_filter *);
-static int priqcmd_class_stats(struct priq_class_stats *);
-#endif /* ALTQ3_COMPAT */
static void get_class_stats(struct priq_classstats *, struct priq_class *);
static struct priq_class *clh_to_clp(struct priq_if *, u_int32_t);
-#ifdef ALTQ3_COMPAT
-altqdev_decl(priq);
-
-/* pif_list keeps all priq_if's allocated. */
-static struct priq_if *pif_list = NULL;
-#endif /* ALTQ3_COMPAT */
int
priq_pfattach(struct pf_altq *a)
@@ -491,10 +468,6 @@ priq_enqueue(struct ifaltq *ifq, struct mbuf *m, struct altq_pktattr *pktattr)
cl = NULL;
if ((t = pf_find_mtag(m)) != NULL)
cl = clh_to_clp(pif, t->qid);
-#ifdef ALTQ3_COMPAT
- else if ((ifq->altq_flags & ALTQF_CLASSIFY) && pktattr != NULL)
- cl = pktattr->pattr_class;
-#endif
if (cl == NULL) {
cl = pif->pif_default;
if (cl == NULL) {
@@ -502,12 +475,7 @@ priq_enqueue(struct ifaltq *ifq, struct mbuf *m, struct altq_pktattr *pktattr)
return (ENOBUFS);
}
}
-#ifdef ALTQ3_COMPAT
- if (pktattr != NULL)
- cl->cl_pktattr = pktattr; /* save proto hdr used by ECN */
- else
-#endif
- cl->cl_pktattr = NULL;
+ cl->cl_pktattr = NULL;
len = m_pktlen(m);
if (priq_addq(cl, m) != 0) {
/* drop occurred. mbuf was freed in priq_addq. */
@@ -676,397 +644,4 @@ clh_to_clp(struct priq_if *pif, u_int32_t chandle)
}
-#ifdef ALTQ3_COMPAT
-
-static struct priq_if *
-priq_attach(ifq, bandwidth)
- struct ifaltq *ifq;
- u_int bandwidth;
-{
- struct priq_if *pif;
-
- pif = malloc(sizeof(struct priq_if),
- M_DEVBUF, M_WAITOK);
- if (pif == NULL)
- return (NULL);
- bzero(pif, sizeof(struct priq_if));
- pif->pif_bandwidth = bandwidth;
- pif->pif_maxpri = -1;
- pif->pif_ifq = ifq;
-
- /* add this state to the priq list */
- pif->pif_next = pif_list;
- pif_list = pif;
-
- return (pif);
-}
-
-static int
-priq_detach(pif)
- struct priq_if *pif;
-{
- (void)priq_clear_interface(pif);
-
- /* remove this interface from the pif list */
- if (pif_list == pif)
- pif_list = pif->pif_next;
- else {
- struct priq_if *p;
-
- for (p = pif_list; p != NULL; p = p->pif_next)
- if (p->pif_next == pif) {
- p->pif_next = pif->pif_next;
- break;
- }
- ASSERT(p != NULL);
- }
-
- free(pif, M_DEVBUF);
- return (0);
-}
-
-/*
- * priq device interface
- */
-int
-priqopen(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- /* everything will be done when the queueing scheme is attached. */
- return 0;
-}
-
-int
-priqclose(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- struct priq_if *pif;
- int err, error = 0;
-
- while ((pif = pif_list) != NULL) {
- /* destroy all */
- if (ALTQ_IS_ENABLED(pif->pif_ifq))
- altq_disable(pif->pif_ifq);
-
- err = altq_detach(pif->pif_ifq);
- if (err == 0)
- err = priq_detach(pif);
- if (err != 0 && error == 0)
- error = err;
- }
-
- return error;
-}
-
-int
-priqioctl(dev, cmd, addr, flag, p)
- dev_t dev;
- ioctlcmd_t cmd;
- caddr_t addr;
- int flag;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- struct priq_if *pif;
- struct priq_interface *ifacep;
- int error = 0;
-
- /* check super-user privilege */
- switch (cmd) {
- case PRIQ_GETSTATS:
- break;
- default:
-#if (__FreeBSD_version > 700000)
- if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0)
- return (error);
-#elsif (__FreeBSD_version > 400000)
- if ((error = suser(p)) != 0)
- return (error);
-#else
- if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
- return (error);
-#endif
- break;
- }
-
- switch (cmd) {
-
- case PRIQ_IF_ATTACH:
- error = priqcmd_if_attach((struct priq_interface *)addr);
- break;
-
- case PRIQ_IF_DETACH:
- error = priqcmd_if_detach((struct priq_interface *)addr);
- break;
-
- case PRIQ_ENABLE:
- case PRIQ_DISABLE:
- case PRIQ_CLEAR:
- ifacep = (struct priq_interface *)addr;
- if ((pif = altq_lookup(ifacep->ifname,
- ALTQT_PRIQ)) == NULL) {
- error = EBADF;
- break;
- }
-
- switch (cmd) {
- case PRIQ_ENABLE:
- if (pif->pif_default == NULL) {
-#ifdef ALTQ_DEBUG
- printf("priq: no default class\n");
-#endif
- error = EINVAL;
- break;
- }
- error = altq_enable(pif->pif_ifq);
- break;
-
- case PRIQ_DISABLE:
- error = altq_disable(pif->pif_ifq);
- break;
-
- case PRIQ_CLEAR:
- priq_clear_interface(pif);
- break;
- }
- break;
-
- case PRIQ_ADD_CLASS:
- error = priqcmd_add_class((struct priq_add_class *)addr);
- break;
-
- case PRIQ_DEL_CLASS:
- error = priqcmd_delete_class((struct priq_delete_class *)addr);
- break;
-
- case PRIQ_MOD_CLASS:
- error = priqcmd_modify_class((struct priq_modify_class *)addr);
- break;
-
- case PRIQ_ADD_FILTER:
- error = priqcmd_add_filter((struct priq_add_filter *)addr);
- break;
-
- case PRIQ_DEL_FILTER:
- error = priqcmd_delete_filter((struct priq_delete_filter *)addr);
- break;
-
- case PRIQ_GETSTATS:
- error = priqcmd_class_stats((struct priq_class_stats *)addr);
- break;
-
- default:
- error = EINVAL;
- break;
- }
- return error;
-}
-
-static int
-priqcmd_if_attach(ap)
- struct priq_interface *ap;
-{
- struct priq_if *pif;
- struct ifnet *ifp;
- int error;
-
- if ((ifp = ifunit(ap->ifname)) == NULL)
- return (ENXIO);
-
- if ((pif = priq_attach(&ifp->if_snd, ap->arg)) == NULL)
- return (ENOMEM);
-
- /*
- * set PRIQ to this ifnet structure.
- */
- if ((error = altq_attach(&ifp->if_snd, ALTQT_PRIQ, pif,
- priq_enqueue, priq_dequeue, priq_request,
- &pif->pif_classifier, acc_classify)) != 0)
- (void)priq_detach(pif);
-
- return (error);
-}
-
-static int
-priqcmd_if_detach(ap)
- struct priq_interface *ap;
-{
- struct priq_if *pif;
- int error;
-
- if ((pif = altq_lookup(ap->ifname, ALTQT_PRIQ)) == NULL)
- return (EBADF);
-
- if (ALTQ_IS_ENABLED(pif->pif_ifq))
- altq_disable(pif->pif_ifq);
-
- if ((error = altq_detach(pif->pif_ifq)))
- return (error);
-
- return priq_detach(pif);
-}
-
-static int
-priqcmd_add_class(ap)
- struct priq_add_class *ap;
-{
- struct priq_if *pif;
- struct priq_class *cl;
- int qid;
-
- if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL)
- return (EBADF);
-
- if (ap->pri < 0 || ap->pri >= PRIQ_MAXPRI)
- return (EINVAL);
- if (pif->pif_classes[ap->pri] != NULL)
- return (EBUSY);
-
- qid = ap->pri + 1;
- if ((cl = priq_class_create(pif, ap->pri,
- ap->qlimit, ap->flags, qid)) == NULL)
- return (ENOMEM);
-
- /* return a class handle to the user */
- ap->class_handle = cl->cl_handle;
-
- return (0);
-}
-
-static int
-priqcmd_delete_class(ap)
- struct priq_delete_class *ap;
-{
- struct priq_if *pif;
- struct priq_class *cl;
-
- if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL)
- return (EBADF);
-
- if ((cl = clh_to_clp(pif, ap->class_handle)) == NULL)
- return (EINVAL);
-
- return priq_class_destroy(cl);
-}
-
-static int
-priqcmd_modify_class(ap)
- struct priq_modify_class *ap;
-{
- struct priq_if *pif;
- struct priq_class *cl;
-
- if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL)
- return (EBADF);
-
- if (ap->pri < 0 || ap->pri >= PRIQ_MAXPRI)
- return (EINVAL);
-
- if ((cl = clh_to_clp(pif, ap->class_handle)) == NULL)
- return (EINVAL);
-
- /*
- * if priority is changed, move the class to the new priority
- */
- if (pif->pif_classes[ap->pri] != cl) {
- if (pif->pif_classes[ap->pri] != NULL)
- return (EEXIST);
- pif->pif_classes[cl->cl_pri] = NULL;
- pif->pif_classes[ap->pri] = cl;
- cl->cl_pri = ap->pri;
- }
-
- /* call priq_class_create to change class parameters */
- if ((cl = priq_class_create(pif, ap->pri,
- ap->qlimit, ap->flags, ap->class_handle)) == NULL)
- return (ENOMEM);
- return 0;
-}
-
-static int
-priqcmd_add_filter(ap)
- struct priq_add_filter *ap;
-{
- struct priq_if *pif;
- struct priq_class *cl;
-
- if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL)
- return (EBADF);
-
- if ((cl = clh_to_clp(pif, ap->class_handle)) == NULL)
- return (EINVAL);
-
- return acc_add_filter(&pif->pif_classifier, &ap->filter,
- cl, &ap->filter_handle);
-}
-
-static int
-priqcmd_delete_filter(ap)
- struct priq_delete_filter *ap;
-{
- struct priq_if *pif;
-
- if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL)
- return (EBADF);
-
- return acc_delete_filter(&pif->pif_classifier,
- ap->filter_handle);
-}
-
-static int
-priqcmd_class_stats(ap)
- struct priq_class_stats *ap;
-{
- struct priq_if *pif;
- struct priq_class *cl;
- struct priq_classstats stats, *usp;
- int pri, error;
-
- if ((pif = altq_lookup(ap->iface.ifname, ALTQT_PRIQ)) == NULL)
- return (EBADF);
-
- ap->maxpri = pif->pif_maxpri;
-
- /* then, read the next N classes in the tree */
- usp = ap->stats;
- for (pri = 0; pri <= pif->pif_maxpri; pri++) {
- cl = pif->pif_classes[pri];
- if (cl != NULL)
- get_class_stats(&stats, cl);
- else
- bzero(&stats, sizeof(stats));
- if ((error = copyout((caddr_t)&stats, (caddr_t)usp++,
- sizeof(stats))) != 0)
- return (error);
- }
- return (0);
-}
-
-#ifdef KLD_MODULE
-
-static struct altqsw priq_sw =
- {"priq", priqopen, priqclose, priqioctl};
-
-ALTQ_MODULE(altq_priq, ALTQT_PRIQ, &priq_sw);
-MODULE_DEPEND(altq_priq, altq_red, 1, 1, 1);
-MODULE_DEPEND(altq_priq, altq_rio, 1, 1, 1);
-
-#endif /* KLD_MODULE */
-
-#endif /* ALTQ3_COMPAT */
#endif /* ALTQ_PRIQ */
diff --git a/freebsd/sys/net/altq/altq_priq.h b/freebsd/sys/net/altq/altq_priq.h
index 1a824d60..a5ee3289 100644
--- a/freebsd/sys/net/altq/altq_priq.h
+++ b/freebsd/sys/net/altq/altq_priq.h
@@ -42,21 +42,6 @@ extern "C" {
#define PRIQ_MAXPRI 16 /* upper limit of the number of priorities */
-#ifdef ALTQ3_COMPAT
-struct priq_interface {
- char ifname[IFNAMSIZ]; /* interface name (e.g., fxp0) */
- u_long arg; /* request-specific argument */
-};
-
-struct priq_add_class {
- struct priq_interface iface;
- int pri; /* priority (0 is the lowest) */
- int qlimit; /* queue size limit */
- int flags; /* misc flags (see below) */
-
- u_int32_t class_handle; /* return value */
-};
-#endif /* ALTQ3_COMPAT */
/* priq class flags */
#define PRCF_RED 0x0001 /* use RED */
@@ -69,33 +54,6 @@ struct priq_add_class {
/* special class handles */
#define PRIQ_NULLCLASS_HANDLE 0
-#ifdef ALTQ3_COMPAT
-struct priq_delete_class {
- struct priq_interface iface;
- u_int32_t class_handle;
-};
-
-struct priq_modify_class {
- struct priq_interface iface;
- u_int32_t class_handle;
- int pri;
- int qlimit;
- int flags;
-};
-
-struct priq_add_filter {
- struct priq_interface iface;
- u_int32_t class_handle;
- struct flow_filter filter;
-
- u_long filter_handle; /* return value */
-};
-
-struct priq_delete_filter {
- struct priq_interface iface;
- u_long filter_handle;
-};
-#endif /* ALTQ3_COMPAT */
struct priq_classstats {
u_int32_t class_handle;
@@ -118,27 +76,6 @@ struct priq_classstats {
* header.
*/
-#ifdef ALTQ3_COMPAT
-struct priq_class_stats {
- struct priq_interface iface;
- int maxpri; /* in/out */
-
- struct priq_classstats *stats; /* pointer to stats array */
-};
-
-#define PRIQ_IF_ATTACH _IOW('Q', 1, struct priq_interface)
-#define PRIQ_IF_DETACH _IOW('Q', 2, struct priq_interface)
-#define PRIQ_ENABLE _IOW('Q', 3, struct priq_interface)
-#define PRIQ_DISABLE _IOW('Q', 4, struct priq_interface)
-#define PRIQ_CLEAR _IOW('Q', 5, struct priq_interface)
-#define PRIQ_ADD_CLASS _IOWR('Q', 7, struct priq_add_class)
-#define PRIQ_DEL_CLASS _IOW('Q', 8, struct priq_delete_class)
-#define PRIQ_MOD_CLASS _IOW('Q', 9, struct priq_modify_class)
-#define PRIQ_ADD_FILTER _IOWR('Q', 10, struct priq_add_filter)
-#define PRIQ_DEL_FILTER _IOW('Q', 11, struct priq_delete_filter)
-#define PRIQ_GETSTATS _IOWR('Q', 12, struct priq_class_stats)
-
-#endif /* ALTQ3_COMPAT */
#ifdef _KERNEL
diff --git a/freebsd/sys/net/altq/altq_red.c b/freebsd/sys/net/altq/altq_red.c
index 3ac0e0ec..f6ba0da8 100644
--- a/freebsd/sys/net/altq/altq_red.c
+++ b/freebsd/sys/net/altq/altq_red.c
@@ -98,12 +98,6 @@
#include <netpfil/pf/pf_mtag.h>
#include <net/altq/altq.h>
#include <net/altq/altq_red.h>
-#ifdef ALTQ3_COMPAT
-#include <net/altq/altq_conf.h>
-#ifdef ALTQ_FLOWVALVE
-#include <net/altq/altq_flowvalve.h>
-#endif
-#endif
/*
* ALTQ/RED (Random Early Detection) implementation using 32-bit
@@ -170,56 +164,12 @@
* to switch to the random-drop policy, define "RED_RANDOM_DROP".
*/
-#ifdef ALTQ3_COMPAT
-#ifdef ALTQ_FLOWVALVE
-/*
- * flow-valve is an extension to protect red from unresponsive flows
- * and to promote end-to-end congestion control.
- * flow-valve observes the average drop rates of the flows that have
- * experienced packet drops in the recent past.
- * when the average drop rate exceeds the threshold, the flow is
- * blocked by the flow-valve. the trapped flow should back off
- * exponentially to escape from the flow-valve.
- */
-#ifdef RED_RANDOM_DROP
-#error "random-drop can't be used with flow-valve!"
-#endif
-#endif /* ALTQ_FLOWVALVE */
-
-/* red_list keeps all red_queue_t's allocated. */
-static red_queue_t *red_list = NULL;
-
-#endif /* ALTQ3_COMPAT */
/* default red parameter values */
static int default_th_min = TH_MIN;
static int default_th_max = TH_MAX;
static int default_inv_pmax = INV_P_MAX;
-#ifdef ALTQ3_COMPAT
-/* internal function prototypes */
-static int red_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *);
-static struct mbuf *red_dequeue(struct ifaltq *, int);
-static int red_request(struct ifaltq *, int, void *);
-static void red_purgeq(red_queue_t *);
-static int red_detach(red_queue_t *);
-#ifdef ALTQ_FLOWVALVE
-static __inline struct fve *flowlist_lookup(struct flowvalve *,
- struct altq_pktattr *, struct timeval *);
-static __inline struct fve *flowlist_reclaim(struct flowvalve *,
- struct altq_pktattr *);
-static __inline void flowlist_move_to_head(struct flowvalve *, struct fve *);
-static __inline int fv_p2f(struct flowvalve *, int);
-#if 0 /* XXX: make the compiler happy (fv_alloc unused) */
-static struct flowvalve *fv_alloc(struct red *);
-#endif
-static void fv_destroy(struct flowvalve *);
-static int fv_checkflow(struct flowvalve *, struct altq_pktattr *,
- struct fve **);
-static void fv_dropbyred(struct flowvalve *fv, struct altq_pktattr *,
- struct fve *);
-#endif
-#endif /* ALTQ3_COMPAT */
/*
* red support routines
@@ -317,12 +267,6 @@ red_alloc(int weight, int inv_pmax, int th_min, int th_max, int flags,
void
red_destroy(red_t *rp)
{
-#ifdef ALTQ3_COMPAT
-#ifdef ALTQ_FLOWVALVE
- if (rp->red_flowvalve != NULL)
- fv_destroy(rp->red_flowvalve);
-#endif
-#endif /* ALTQ3_COMPAT */
wtab_destroy(rp->red_wtab);
free(rp, M_DEVBUF);
}
@@ -344,17 +288,6 @@ red_addq(red_t *rp, class_queue_t *q, struct mbuf *m,
{
int avg, droptype;
int n;
-#ifdef ALTQ3_COMPAT
-#ifdef ALTQ_FLOWVALVE
- struct fve *fve = NULL;
-
- if (rp->red_flowvalve != NULL && rp->red_flowvalve->fv_flows > 0)
- if (fv_checkflow(rp->red_flowvalve, pktattr, &fve)) {
- m_freem(m);
- return (-1);
- }
-#endif
-#endif /* ALTQ3_COMPAT */
avg = rp->red_avg;
@@ -460,12 +393,6 @@ red_addq(red_t *rp, class_queue_t *q, struct mbuf *m,
PKTCNTR_ADD(&rp->red_stats.drop_cnt, m_pktlen(m));
#endif
rp->red_count = 0;
-#ifdef ALTQ3_COMPAT
-#ifdef ALTQ_FLOWVALVE
- if (rp->red_flowvalve != NULL)
- fv_dropbyred(rp->red_flowvalve, pktattr, fve);
-#endif
-#endif /* ALTQ3_COMPAT */
m_freem(m);
return (-1);
}
@@ -523,11 +450,6 @@ mark_ecn(struct mbuf *m, struct altq_pktattr *pktattr, int flags)
at = pf_find_mtag(m);
if (at != NULL) {
hdr = at->hdr;
-#ifdef ALTQ3_COMPAT
- } else if (pktattr != NULL) {
- af = pktattr->pattr_af;
- hdr = pktattr->pattr_hdr;
-#endif /* ALTQ3_COMPAT */
} else
return (0);
@@ -709,786 +631,5 @@ pow_w(struct wtab *w, int n)
return (val);
}
-#ifdef ALTQ3_COMPAT
-/*
- * red device interface
- */
-altqdev_decl(red);
-
-int
-redopen(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- /* everything will be done when the queueing scheme is attached. */
- return 0;
-}
-
-int
-redclose(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- red_queue_t *rqp;
- int err, error = 0;
-
- while ((rqp = red_list) != NULL) {
- /* destroy all */
- err = red_detach(rqp);
- if (err != 0 && error == 0)
- error = err;
- }
-
- return error;
-}
-
-int
-redioctl(dev, cmd, addr, flag, p)
- dev_t dev;
- ioctlcmd_t cmd;
- caddr_t addr;
- int flag;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- red_queue_t *rqp;
- struct red_interface *ifacep;
- struct ifnet *ifp;
- int error = 0;
-
- /* check super-user privilege */
- switch (cmd) {
- case RED_GETSTATS:
- break;
- default:
-#if (__FreeBSD_version > 700000)
- if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0)
-#elsif (__FreeBSD_version > 400000)
- if ((error = suser(p)) != 0)
-#else
- if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
-#endif
- return (error);
- break;
- }
-
- switch (cmd) {
-
- case RED_ENABLE:
- ifacep = (struct red_interface *)addr;
- if ((rqp = altq_lookup(ifacep->red_ifname, ALTQT_RED)) == NULL) {
- error = EBADF;
- break;
- }
- error = altq_enable(rqp->rq_ifq);
- break;
-
- case RED_DISABLE:
- ifacep = (struct red_interface *)addr;
- if ((rqp = altq_lookup(ifacep->red_ifname, ALTQT_RED)) == NULL) {
- error = EBADF;
- break;
- }
- error = altq_disable(rqp->rq_ifq);
- break;
-
- case RED_IF_ATTACH:
- ifp = ifunit(((struct red_interface *)addr)->red_ifname);
- if (ifp == NULL) {
- error = ENXIO;
- break;
- }
-
- /* allocate and initialize red_queue_t */
- rqp = malloc(sizeof(red_queue_t), M_DEVBUF, M_WAITOK);
- if (rqp == NULL) {
- error = ENOMEM;
- break;
- }
- bzero(rqp, sizeof(red_queue_t));
-
- rqp->rq_q = malloc(sizeof(class_queue_t),
- M_DEVBUF, M_WAITOK);
- if (rqp->rq_q == NULL) {
- free(rqp, M_DEVBUF);
- error = ENOMEM;
- break;
- }
- bzero(rqp->rq_q, sizeof(class_queue_t));
-
- rqp->rq_red = red_alloc(0, 0, 0, 0, 0, 0);
- if (rqp->rq_red == NULL) {
- free(rqp->rq_q, M_DEVBUF);
- free(rqp, M_DEVBUF);
- error = ENOMEM;
- break;
- }
-
- rqp->rq_ifq = &ifp->if_snd;
- qtail(rqp->rq_q) = NULL;
- qlen(rqp->rq_q) = 0;
- qlimit(rqp->rq_q) = RED_LIMIT;
- qtype(rqp->rq_q) = Q_RED;
-
- /*
- * set RED to this ifnet structure.
- */
- error = altq_attach(rqp->rq_ifq, ALTQT_RED, rqp,
- red_enqueue, red_dequeue, red_request,
- NULL, NULL);
- if (error) {
- red_destroy(rqp->rq_red);
- free(rqp->rq_q, M_DEVBUF);
- free(rqp, M_DEVBUF);
- break;
- }
-
- /* add this state to the red list */
- rqp->rq_next = red_list;
- red_list = rqp;
- break;
-
- case RED_IF_DETACH:
- ifacep = (struct red_interface *)addr;
- if ((rqp = altq_lookup(ifacep->red_ifname, ALTQT_RED)) == NULL) {
- error = EBADF;
- break;
- }
- error = red_detach(rqp);
- break;
-
- case RED_GETSTATS:
- do {
- struct red_stats *q_stats;
- red_t *rp;
-
- q_stats = (struct red_stats *)addr;
- if ((rqp = altq_lookup(q_stats->iface.red_ifname,
- ALTQT_RED)) == NULL) {
- error = EBADF;
- break;
- }
-
- q_stats->q_len = qlen(rqp->rq_q);
- q_stats->q_limit = qlimit(rqp->rq_q);
-
- rp = rqp->rq_red;
- q_stats->q_avg = rp->red_avg >> rp->red_wshift;
- q_stats->xmit_cnt = rp->red_stats.xmit_cnt;
- q_stats->drop_cnt = rp->red_stats.drop_cnt;
- q_stats->drop_forced = rp->red_stats.drop_forced;
- q_stats->drop_unforced = rp->red_stats.drop_unforced;
- q_stats->marked_packets = rp->red_stats.marked_packets;
-
- q_stats->weight = rp->red_weight;
- q_stats->inv_pmax = rp->red_inv_pmax;
- q_stats->th_min = rp->red_thmin;
- q_stats->th_max = rp->red_thmax;
-
-#ifdef ALTQ_FLOWVALVE
- if (rp->red_flowvalve != NULL) {
- struct flowvalve *fv = rp->red_flowvalve;
- q_stats->fv_flows = fv->fv_flows;
- q_stats->fv_pass = fv->fv_stats.pass;
- q_stats->fv_predrop = fv->fv_stats.predrop;
- q_stats->fv_alloc = fv->fv_stats.alloc;
- q_stats->fv_escape = fv->fv_stats.escape;
- } else {
-#endif /* ALTQ_FLOWVALVE */
- q_stats->fv_flows = 0;
- q_stats->fv_pass = 0;
- q_stats->fv_predrop = 0;
- q_stats->fv_alloc = 0;
- q_stats->fv_escape = 0;
-#ifdef ALTQ_FLOWVALVE
- }
-#endif /* ALTQ_FLOWVALVE */
- } while (/*CONSTCOND*/ 0);
- break;
-
- case RED_CONFIG:
- do {
- struct red_conf *fc;
- red_t *new;
- int s, limit;
-
- fc = (struct red_conf *)addr;
- if ((rqp = altq_lookup(fc->iface.red_ifname,
- ALTQT_RED)) == NULL) {
- error = EBADF;
- break;
- }
- new = red_alloc(fc->red_weight,
- fc->red_inv_pmax,
- fc->red_thmin,
- fc->red_thmax,
- fc->red_flags,
- fc->red_pkttime);
- if (new == NULL) {
- error = ENOMEM;
- break;
- }
-
- s = splnet();
- red_purgeq(rqp);
- limit = fc->red_limit;
- if (limit < fc->red_thmax)
- limit = fc->red_thmax;
- qlimit(rqp->rq_q) = limit;
- fc->red_limit = limit; /* write back the new value */
-
- red_destroy(rqp->rq_red);
- rqp->rq_red = new;
-
- splx(s);
-
- /* write back new values */
- fc->red_limit = limit;
- fc->red_inv_pmax = rqp->rq_red->red_inv_pmax;
- fc->red_thmin = rqp->rq_red->red_thmin;
- fc->red_thmax = rqp->rq_red->red_thmax;
-
- } while (/*CONSTCOND*/ 0);
- break;
-
- case RED_SETDEFAULTS:
- do {
- struct redparams *rp;
-
- rp = (struct redparams *)addr;
-
- default_th_min = rp->th_min;
- default_th_max = rp->th_max;
- default_inv_pmax = rp->inv_pmax;
- } while (/*CONSTCOND*/ 0);
- break;
-
- default:
- error = EINVAL;
- break;
- }
- return error;
-}
-
-static int
-red_detach(rqp)
- red_queue_t *rqp;
-{
- red_queue_t *tmp;
- int error = 0;
-
- if (ALTQ_IS_ENABLED(rqp->rq_ifq))
- altq_disable(rqp->rq_ifq);
-
- if ((error = altq_detach(rqp->rq_ifq)))
- return (error);
-
- if (red_list == rqp)
- red_list = rqp->rq_next;
- else {
- for (tmp = red_list; tmp != NULL; tmp = tmp->rq_next)
- if (tmp->rq_next == rqp) {
- tmp->rq_next = rqp->rq_next;
- break;
- }
- if (tmp == NULL)
- printf("red_detach: no state found in red_list!\n");
- }
-
- red_destroy(rqp->rq_red);
- free(rqp->rq_q, M_DEVBUF);
- free(rqp, M_DEVBUF);
- return (error);
-}
-
-/*
- * enqueue routine:
- *
- * returns: 0 when successfully queued.
- * ENOBUFS when drop occurs.
- */
-static int
-red_enqueue(ifq, m, pktattr)
- struct ifaltq *ifq;
- struct mbuf *m;
- struct altq_pktattr *pktattr;
-{
- red_queue_t *rqp = (red_queue_t *)ifq->altq_disc;
-
- IFQ_LOCK_ASSERT(ifq);
-
- if (red_addq(rqp->rq_red, rqp->rq_q, m, pktattr) < 0)
- return ENOBUFS;
- ifq->ifq_len++;
- return 0;
-}
-
-/*
- * dequeue routine:
- * must be called in splimp.
- *
- * returns: mbuf dequeued.
- * NULL when no packet is available in the queue.
- */
-
-static struct mbuf *
-red_dequeue(ifq, op)
- struct ifaltq *ifq;
- int op;
-{
- red_queue_t *rqp = (red_queue_t *)ifq->altq_disc;
- struct mbuf *m;
-
- IFQ_LOCK_ASSERT(ifq);
-
- if (op == ALTDQ_POLL)
- return qhead(rqp->rq_q);
-
- /* op == ALTDQ_REMOVE */
- m = red_getq(rqp->rq_red, rqp->rq_q);
- if (m != NULL)
- ifq->ifq_len--;
- return (m);
-}
-
-static int
-red_request(ifq, req, arg)
- struct ifaltq *ifq;
- int req;
- void *arg;
-{
- red_queue_t *rqp = (red_queue_t *)ifq->altq_disc;
-
- IFQ_LOCK_ASSERT(ifq);
-
- switch (req) {
- case ALTRQ_PURGE:
- red_purgeq(rqp);
- break;
- }
- return (0);
-}
-
-static void
-red_purgeq(rqp)
- red_queue_t *rqp;
-{
- _flushq(rqp->rq_q);
- if (ALTQ_IS_ENABLED(rqp->rq_ifq))
- rqp->rq_ifq->ifq_len = 0;
-}
-
-#ifdef ALTQ_FLOWVALVE
-
-#define FV_PSHIFT 7 /* weight of average drop rate -- 1/128 */
-#define FV_PSCALE(x) ((x) << FV_PSHIFT)
-#define FV_PUNSCALE(x) ((x) >> FV_PSHIFT)
-#define FV_FSHIFT 5 /* weight of average fraction -- 1/32 */
-#define FV_FSCALE(x) ((x) << FV_FSHIFT)
-#define FV_FUNSCALE(x) ((x) >> FV_FSHIFT)
-
-#define FV_TIMER (3 * hz) /* timer value for garbage collector */
-#define FV_FLOWLISTSIZE 64 /* how many flows in flowlist */
-
-#define FV_N 10 /* update fve_f every FV_N packets */
-
-#define FV_BACKOFFTHRESH 1 /* backoff threshold interval in second */
-#define FV_TTHRESH 3 /* time threshold to delete fve */
-#define FV_ALPHA 5 /* extra packet count */
-
-#define FV_STATS
-
-#if (__FreeBSD_version > 300000)
-#define FV_TIMESTAMP(tp) getmicrotime(tp)
-#else
-#define FV_TIMESTAMP(tp) { (*(tp)) = time; }
-#endif
-
-/*
- * Brtt table: 127 entry table to convert drop rate (p) to
- * the corresponding bandwidth fraction (f)
- * the following equation is implemented to use scaled values,
- * fve_p and fve_f, in the fixed point format.
- *
- * Brtt(p) = 1 /(sqrt(4*p/3) + min(1,3*sqrt(p*6/8)) * p * (1+32 * p*p))
- * f = Brtt(p) / (max_th + alpha)
- */
-#define BRTT_SIZE 128
-#define BRTT_SHIFT 12
-#define BRTT_MASK 0x0007f000
-#define BRTT_PMAX (1 << (FV_PSHIFT + FP_SHIFT))
-
-const int brtt_tab[BRTT_SIZE] = {
- 0, 1262010, 877019, 703694, 598706, 525854, 471107, 427728,
- 392026, 361788, 335598, 312506, 291850, 273158, 256081, 240361,
- 225800, 212247, 199585, 187788, 178388, 169544, 161207, 153333,
- 145888, 138841, 132165, 125836, 119834, 114141, 108739, 103612,
- 98747, 94129, 89746, 85585, 81637, 77889, 74333, 70957,
- 67752, 64711, 61824, 59084, 56482, 54013, 51667, 49440,
- 47325, 45315, 43406, 41591, 39866, 38227, 36667, 35184,
- 33773, 32430, 31151, 29933, 28774, 27668, 26615, 25611,
- 24653, 23740, 22868, 22035, 21240, 20481, 19755, 19062,
- 18399, 17764, 17157, 16576, 16020, 15487, 14976, 14487,
- 14017, 13567, 13136, 12721, 12323, 11941, 11574, 11222,
- 10883, 10557, 10243, 9942, 9652, 9372, 9103, 8844,
- 8594, 8354, 8122, 7898, 7682, 7474, 7273, 7079,
- 6892, 6711, 6536, 6367, 6204, 6046, 5893, 5746,
- 5603, 5464, 5330, 5201, 5075, 4954, 4836, 4722,
- 4611, 4504, 4400, 4299, 4201, 4106, 4014, 3924
-};
-
-static __inline struct fve *
-flowlist_lookup(fv, pktattr, now)
- struct flowvalve *fv;
- struct altq_pktattr *pktattr;
- struct timeval *now;
-{
- struct fve *fve;
- int flows;
- struct ip *ip;
-#ifdef INET6
- struct ip6_hdr *ip6;
-#endif
- struct timeval tthresh;
-
- if (pktattr == NULL)
- return (NULL);
-
- tthresh.tv_sec = now->tv_sec - FV_TTHRESH;
- flows = 0;
- /*
- * search the flow list
- */
- switch (pktattr->pattr_af) {
- case AF_INET:
- ip = (struct ip *)pktattr->pattr_hdr;
- TAILQ_FOREACH(fve, &fv->fv_flowlist, fve_lru){
- if (fve->fve_lastdrop.tv_sec == 0)
- break;
- if (fve->fve_lastdrop.tv_sec < tthresh.tv_sec) {
- fve->fve_lastdrop.tv_sec = 0;
- break;
- }
- if (fve->fve_flow.flow_af == AF_INET &&
- fve->fve_flow.flow_ip.ip_src.s_addr ==
- ip->ip_src.s_addr &&
- fve->fve_flow.flow_ip.ip_dst.s_addr ==
- ip->ip_dst.s_addr)
- return (fve);
- flows++;
- }
- break;
-#ifdef INET6
- case AF_INET6:
- ip6 = (struct ip6_hdr *)pktattr->pattr_hdr;
- TAILQ_FOREACH(fve, &fv->fv_flowlist, fve_lru){
- if (fve->fve_lastdrop.tv_sec == 0)
- break;
- if (fve->fve_lastdrop.tv_sec < tthresh.tv_sec) {
- fve->fve_lastdrop.tv_sec = 0;
- break;
- }
- if (fve->fve_flow.flow_af == AF_INET6 &&
- IN6_ARE_ADDR_EQUAL(&fve->fve_flow.flow_ip6.ip6_src,
- &ip6->ip6_src) &&
- IN6_ARE_ADDR_EQUAL(&fve->fve_flow.flow_ip6.ip6_dst,
- &ip6->ip6_dst))
- return (fve);
- flows++;
- }
- break;
-#endif /* INET6 */
-
- default:
- /* unknown protocol. no drop. */
- return (NULL);
- }
- fv->fv_flows = flows; /* save the number of active fve's */
- return (NULL);
-}
-
-static __inline struct fve *
-flowlist_reclaim(fv, pktattr)
- struct flowvalve *fv;
- struct altq_pktattr *pktattr;
-{
- struct fve *fve;
- struct ip *ip;
-#ifdef INET6
- struct ip6_hdr *ip6;
-#endif
-
- /*
- * get an entry from the tail of the LRU list.
- */
- fve = TAILQ_LAST(&fv->fv_flowlist, fv_flowhead);
-
- switch (pktattr->pattr_af) {
- case AF_INET:
- ip = (struct ip *)pktattr->pattr_hdr;
- fve->fve_flow.flow_af = AF_INET;
- fve->fve_flow.flow_ip.ip_src = ip->ip_src;
- fve->fve_flow.flow_ip.ip_dst = ip->ip_dst;
- break;
-#ifdef INET6
- case AF_INET6:
- ip6 = (struct ip6_hdr *)pktattr->pattr_hdr;
- fve->fve_flow.flow_af = AF_INET6;
- fve->fve_flow.flow_ip6.ip6_src = ip6->ip6_src;
- fve->fve_flow.flow_ip6.ip6_dst = ip6->ip6_dst;
- break;
-#endif
- }
-
- fve->fve_state = Green;
- fve->fve_p = 0.0;
- fve->fve_f = 0.0;
- fve->fve_ifseq = fv->fv_ifseq - 1;
- fve->fve_count = 0;
-
- fv->fv_flows++;
-#ifdef FV_STATS
- fv->fv_stats.alloc++;
-#endif
- return (fve);
-}
-
-static __inline void
-flowlist_move_to_head(fv, fve)
- struct flowvalve *fv;
- struct fve *fve;
-{
- if (TAILQ_FIRST(&fv->fv_flowlist) != fve) {
- TAILQ_REMOVE(&fv->fv_flowlist, fve, fve_lru);
- TAILQ_INSERT_HEAD(&fv->fv_flowlist, fve, fve_lru);
- }
-}
-
-#if 0 /* XXX: make the compiler happy (fv_alloc unused) */
-/*
- * allocate flowvalve structure
- */
-static struct flowvalve *
-fv_alloc(rp)
- struct red *rp;
-{
- struct flowvalve *fv;
- struct fve *fve;
- int i, num;
-
- num = FV_FLOWLISTSIZE;
- fv = malloc(sizeof(struct flowvalve),
- M_DEVBUF, M_WAITOK);
- if (fv == NULL)
- return (NULL);
- bzero(fv, sizeof(struct flowvalve));
-
- fv->fv_fves = malloc(sizeof(struct fve) * num,
- M_DEVBUF, M_WAITOK);
- if (fv->fv_fves == NULL) {
- free(fv, M_DEVBUF);
- return (NULL);
- }
- bzero(fv->fv_fves, sizeof(struct fve) * num);
-
- fv->fv_flows = 0;
- TAILQ_INIT(&fv->fv_flowlist);
- for (i = 0; i < num; i++) {
- fve = &fv->fv_fves[i];
- fve->fve_lastdrop.tv_sec = 0;
- TAILQ_INSERT_TAIL(&fv->fv_flowlist, fve, fve_lru);
- }
-
- /* initialize drop rate threshold in scaled fixed-point */
- fv->fv_pthresh = (FV_PSCALE(1) << FP_SHIFT) / rp->red_inv_pmax;
-
- /* initialize drop rate to fraction table */
- fv->fv_p2ftab = malloc(sizeof(int) * BRTT_SIZE,
- M_DEVBUF, M_WAITOK);
- if (fv->fv_p2ftab == NULL) {
- free(fv->fv_fves, M_DEVBUF);
- free(fv, M_DEVBUF);
- return (NULL);
- }
- /*
- * create the p2f table.
- * (shift is used to keep the precision)
- */
- for (i = 1; i < BRTT_SIZE; i++) {
- int f;
-
- f = brtt_tab[i] << 8;
- fv->fv_p2ftab[i] = (f / (rp->red_thmax + FV_ALPHA)) >> 8;
- }
-
- return (fv);
-}
-#endif
-
-static void fv_destroy(fv)
- struct flowvalve *fv;
-{
- free(fv->fv_p2ftab, M_DEVBUF);
- free(fv->fv_fves, M_DEVBUF);
- free(fv, M_DEVBUF);
-}
-
-static __inline int
-fv_p2f(fv, p)
- struct flowvalve *fv;
- int p;
-{
- int val, f;
-
- if (p >= BRTT_PMAX)
- f = fv->fv_p2ftab[BRTT_SIZE-1];
- else if ((val = (p & BRTT_MASK)))
- f = fv->fv_p2ftab[(val >> BRTT_SHIFT)];
- else
- f = fv->fv_p2ftab[1];
- return (f);
-}
-
-/*
- * check if an arriving packet should be pre-dropped.
- * called from red_addq() when a packet arrives.
- * returns 1 when the packet should be pre-dropped.
- * should be called in splimp.
- */
-static int
-fv_checkflow(fv, pktattr, fcache)
- struct flowvalve *fv;
- struct altq_pktattr *pktattr;
- struct fve **fcache;
-{
- struct fve *fve;
- struct timeval now;
-
- fv->fv_ifseq++;
- FV_TIMESTAMP(&now);
-
- if ((fve = flowlist_lookup(fv, pktattr, &now)) == NULL)
- /* no matching entry in the flowlist */
- return (0);
-
- *fcache = fve;
-
- /* update fraction f for every FV_N packets */
- if (++fve->fve_count == FV_N) {
- /*
- * f = Wf * N / (fv_ifseq - fve_ifseq) + (1 - Wf) * f
- */
- fve->fve_f =
- (FV_N << FP_SHIFT) / (fv->fv_ifseq - fve->fve_ifseq)
- + fve->fve_f - FV_FUNSCALE(fve->fve_f);
- fve->fve_ifseq = fv->fv_ifseq;
- fve->fve_count = 0;
- }
-
- /*
- * overpumping test
- */
- if (fve->fve_state == Green && fve->fve_p > fv->fv_pthresh) {
- int fthresh;
-
- /* calculate a threshold */
- fthresh = fv_p2f(fv, fve->fve_p);
- if (fve->fve_f > fthresh)
- fve->fve_state = Red;
- }
-
- if (fve->fve_state == Red) {
- /*
- * backoff test
- */
- if (now.tv_sec - fve->fve_lastdrop.tv_sec > FV_BACKOFFTHRESH) {
- /* no drop for at least FV_BACKOFFTHRESH sec */
- fve->fve_p = 0;
- fve->fve_state = Green;
-#ifdef FV_STATS
- fv->fv_stats.escape++;
-#endif
- } else {
- /* block this flow */
- flowlist_move_to_head(fv, fve);
- fve->fve_lastdrop = now;
-#ifdef FV_STATS
- fv->fv_stats.predrop++;
-#endif
- return (1);
- }
- }
-
- /*
- * p = (1 - Wp) * p
- */
- fve->fve_p -= FV_PUNSCALE(fve->fve_p);
- if (fve->fve_p < 0)
- fve->fve_p = 0;
-#ifdef FV_STATS
- fv->fv_stats.pass++;
-#endif
- return (0);
-}
-
-/*
- * called from red_addq when a packet is dropped by red.
- * should be called in splimp.
- */
-static void fv_dropbyred(fv, pktattr, fcache)
- struct flowvalve *fv;
- struct altq_pktattr *pktattr;
- struct fve *fcache;
-{
- struct fve *fve;
- struct timeval now;
-
- if (pktattr == NULL)
- return;
- FV_TIMESTAMP(&now);
-
- if (fcache != NULL)
- /* the fve of this packet is already cached */
- fve = fcache;
- else if ((fve = flowlist_lookup(fv, pktattr, &now)) == NULL)
- fve = flowlist_reclaim(fv, pktattr);
-
- flowlist_move_to_head(fv, fve);
-
- /*
- * update p: the following line cancels the update
- * in fv_checkflow() and calculate
- * p = Wp + (1 - Wp) * p
- */
- fve->fve_p = (1 << FP_SHIFT) + fve->fve_p;
-
- fve->fve_lastdrop = now;
-}
-
-#endif /* ALTQ_FLOWVALVE */
-
-#ifdef KLD_MODULE
-
-static struct altqsw red_sw =
- {"red", redopen, redclose, redioctl};
-
-ALTQ_MODULE(altq_red, ALTQT_RED, &red_sw);
-MODULE_VERSION(altq_red, 1);
-
-#endif /* KLD_MODULE */
-#endif /* ALTQ3_COMPAT */
#endif /* ALTQ_RED */
diff --git a/freebsd/sys/net/altq/altq_red.h b/freebsd/sys/net/altq/altq_red.h
index 8ae8d291..d4cd3d8b 100644
--- a/freebsd/sys/net/altq/altq_red.h
+++ b/freebsd/sys/net/altq/altq_red.h
@@ -32,48 +32,6 @@
#include <net/altq/altq_classq.h>
-#ifdef ALTQ3_COMPAT
-struct red_interface {
- char red_ifname[IFNAMSIZ];
-};
-
-struct red_stats {
- struct red_interface iface;
- int q_len;
- int q_avg;
-
- struct pktcntr xmit_cnt;
- struct pktcntr drop_cnt;
- u_int drop_forced;
- u_int drop_unforced;
- u_int marked_packets;
-
- /* static red parameters */
- int q_limit;
- int weight;
- int inv_pmax;
- int th_min;
- int th_max;
-
- /* flowvalve related stuff */
- u_int fv_flows;
- u_int fv_pass;
- u_int fv_predrop;
- u_int fv_alloc;
- u_int fv_escape;
-};
-
-struct red_conf {
- struct red_interface iface;
- int red_weight; /* weight for EWMA */
- int red_inv_pmax; /* inverse of max drop probability */
- int red_thmin; /* red min threshold */
- int red_thmax; /* red max threshold */
- int red_limit; /* max queue length */
- int red_pkttime; /* average packet time in usec */
- int red_flags; /* see below */
-};
-#endif /* ALTQ3_COMPAT */
/* red flags */
#define REDF_ECN4 0x01 /* use packet marking for IPv4 packets */
@@ -100,24 +58,9 @@ struct redstats {
u_int marked_packets;
};
-#ifdef ALTQ3_COMPAT
-/*
- * IOCTLs for RED
- */
-#define RED_IF_ATTACH _IOW('Q', 1, struct red_interface)
-#define RED_IF_DETACH _IOW('Q', 2, struct red_interface)
-#define RED_ENABLE _IOW('Q', 3, struct red_interface)
-#define RED_DISABLE _IOW('Q', 4, struct red_interface)
-#define RED_CONFIG _IOWR('Q', 6, struct red_conf)
-#define RED_GETSTATS _IOWR('Q', 12, struct red_stats)
-#define RED_SETDEFAULTS _IOW('Q', 30, struct redparams)
-#endif /* ALTQ3_COMPAT */
#ifdef _KERNEL
-#ifdef ALTQ3_COMPAT
-struct flowvalve;
-#endif
/* weight table structure for idle time calibration */
struct wtab {
@@ -153,9 +96,6 @@ typedef struct red {
struct wtab *red_wtab; /* weight table */
struct timeval red_last; /* time when the queue becomes idle */
-#ifdef ALTQ3_COMPAT
- struct flowvalve *red_flowvalve; /* flowvalve state */
-#endif
struct {
struct pktcntr xmit_cnt;
@@ -166,16 +106,6 @@ typedef struct red {
} red_stats;
} red_t;
-#ifdef ALTQ3_COMPAT
-typedef struct red_queue {
- struct red_queue *rq_next; /* next red_state in the list */
- struct ifaltq *rq_ifq; /* backpointer to ifaltq */
-
- class_queue_t *rq_q;
-
- red_t *rq_red;
-} red_queue_t;
-#endif /* ALTQ3_COMPAT */
/* red drop types */
#define DTYPE_NODROP 0 /* no drop */
diff --git a/freebsd/sys/net/altq/altq_rio.c b/freebsd/sys/net/altq/altq_rio.c
index af9b5835..f75660ad 100644
--- a/freebsd/sys/net/altq/altq_rio.c
+++ b/freebsd/sys/net/altq/altq_rio.c
@@ -94,9 +94,6 @@
#include <net/altq/altq_cdnr.h>
#include <net/altq/altq_red.h>
#include <net/altq/altq_rio.h>
-#ifdef ALTQ3_COMPAT
-#include <net/altq/altq_conf.h>
-#endif
/*
* RIO: RED with IN/OUT bit
@@ -170,10 +167,6 @@
} \
}
-#ifdef ALTQ3_COMPAT
-/* rio_list keeps all rio_queue_t's allocated. */
-static rio_queue_t *rio_list = NULL;
-#endif
/* default rio parameter values */
static struct redparams default_rio_params[RIO_NDROPPREC] = {
/* th_min, th_max, inv_pmax */
@@ -184,18 +177,6 @@ static struct redparams default_rio_params[RIO_NDROPPREC] = {
/* internal function prototypes */
static int dscp2index(u_int8_t);
-#ifdef ALTQ3_COMPAT
-static int rio_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *);
-static struct mbuf *rio_dequeue(struct ifaltq *, int);
-static int rio_request(struct ifaltq *, int, void *);
-static int rio_detach(rio_queue_t *);
-
-/*
- * rio device interface
- */
-altqdev_decl(rio);
-
-#endif /* ALTQ3_COMPAT */
rio_t *
rio_alloc(int weight, struct redparams *params, int flags, int pkttime)
@@ -468,379 +449,5 @@ rio_getq(rio_t *rp, class_queue_t *q)
return (m);
}
-#ifdef ALTQ3_COMPAT
-int
-rioopen(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- /* everything will be done when the queueing scheme is attached. */
- return 0;
-}
-
-int
-rioclose(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- rio_queue_t *rqp;
- int err, error = 0;
-
- while ((rqp = rio_list) != NULL) {
- /* destroy all */
- err = rio_detach(rqp);
- if (err != 0 && error == 0)
- error = err;
- }
-
- return error;
-}
-
-int
-rioioctl(dev, cmd, addr, flag, p)
- dev_t dev;
- ioctlcmd_t cmd;
- caddr_t addr;
- int flag;
-#if (__FreeBSD_version > 500000)
- struct thread *p;
-#else
- struct proc *p;
-#endif
-{
- rio_queue_t *rqp;
- struct rio_interface *ifacep;
- struct ifnet *ifp;
- int error = 0;
-
- /* check super-user privilege */
- switch (cmd) {
- case RIO_GETSTATS:
- break;
- default:
-#if (__FreeBSD_version > 700000)
- if ((error = priv_check(p, PRIV_ALTQ_MANAGE)) != 0)
- return (error);
-#elsif (__FreeBSD_version > 400000)
- if ((error = suser(p)) != 0)
- return (error);
-#else
- if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
- return (error);
-#endif
- break;
- }
-
- switch (cmd) {
-
- case RIO_ENABLE:
- ifacep = (struct rio_interface *)addr;
- if ((rqp = altq_lookup(ifacep->rio_ifname, ALTQT_RIO)) == NULL) {
- error = EBADF;
- break;
- }
- error = altq_enable(rqp->rq_ifq);
- break;
-
- case RIO_DISABLE:
- ifacep = (struct rio_interface *)addr;
- if ((rqp = altq_lookup(ifacep->rio_ifname, ALTQT_RIO)) == NULL) {
- error = EBADF;
- break;
- }
- error = altq_disable(rqp->rq_ifq);
- break;
-
- case RIO_IF_ATTACH:
- ifp = ifunit(((struct rio_interface *)addr)->rio_ifname);
- if (ifp == NULL) {
- error = ENXIO;
- break;
- }
-
- /* allocate and initialize rio_queue_t */
- rqp = malloc(sizeof(rio_queue_t), M_DEVBUF, M_WAITOK);
- if (rqp == NULL) {
- error = ENOMEM;
- break;
- }
- bzero(rqp, sizeof(rio_queue_t));
-
- rqp->rq_q = malloc(sizeof(class_queue_t),
- M_DEVBUF, M_WAITOK);
- if (rqp->rq_q == NULL) {
- free(rqp, M_DEVBUF);
- error = ENOMEM;
- break;
- }
- bzero(rqp->rq_q, sizeof(class_queue_t));
-
- rqp->rq_rio = rio_alloc(0, NULL, 0, 0);
- if (rqp->rq_rio == NULL) {
- free(rqp->rq_q, M_DEVBUF);
- free(rqp, M_DEVBUF);
- error = ENOMEM;
- break;
- }
-
- rqp->rq_ifq = &ifp->if_snd;
- qtail(rqp->rq_q) = NULL;
- qlen(rqp->rq_q) = 0;
- qlimit(rqp->rq_q) = RIO_LIMIT;
- qtype(rqp->rq_q) = Q_RIO;
-
- /*
- * set RIO to this ifnet structure.
- */
- error = altq_attach(rqp->rq_ifq, ALTQT_RIO, rqp,
- rio_enqueue, rio_dequeue, rio_request,
- NULL, NULL);
- if (error) {
- rio_destroy(rqp->rq_rio);
- free(rqp->rq_q, M_DEVBUF);
- free(rqp, M_DEVBUF);
- break;
- }
-
- /* add this state to the rio list */
- rqp->rq_next = rio_list;
- rio_list = rqp;
- break;
-
- case RIO_IF_DETACH:
- ifacep = (struct rio_interface *)addr;
- if ((rqp = altq_lookup(ifacep->rio_ifname, ALTQT_RIO)) == NULL) {
- error = EBADF;
- break;
- }
- error = rio_detach(rqp);
- break;
-
- case RIO_GETSTATS:
- do {
- struct rio_stats *q_stats;
- rio_t *rp;
- int i;
-
- q_stats = (struct rio_stats *)addr;
- if ((rqp = altq_lookup(q_stats->iface.rio_ifname,
- ALTQT_RIO)) == NULL) {
- error = EBADF;
- break;
- }
-
- rp = rqp->rq_rio;
-
- q_stats->q_limit = qlimit(rqp->rq_q);
- q_stats->weight = rp->rio_weight;
- q_stats->flags = rp->rio_flags;
-
- for (i = 0; i < RIO_NDROPPREC; i++) {
- q_stats->q_len[i] = rp->rio_precstate[i].qlen;
- bcopy(&rp->q_stats[i], &q_stats->q_stats[i],
- sizeof(struct redstats));
- q_stats->q_stats[i].q_avg =
- rp->rio_precstate[i].avg >> rp->rio_wshift;
-
- q_stats->q_params[i].inv_pmax
- = rp->rio_precstate[i].inv_pmax;
- q_stats->q_params[i].th_min
- = rp->rio_precstate[i].th_min;
- q_stats->q_params[i].th_max
- = rp->rio_precstate[i].th_max;
- }
- } while (/*CONSTCOND*/ 0);
- break;
-
- case RIO_CONFIG:
- do {
- struct rio_conf *fc;
- rio_t *new;
- int s, limit, i;
-
- fc = (struct rio_conf *)addr;
- if ((rqp = altq_lookup(fc->iface.rio_ifname,
- ALTQT_RIO)) == NULL) {
- error = EBADF;
- break;
- }
-
- new = rio_alloc(fc->rio_weight, &fc->q_params[0],
- fc->rio_flags, fc->rio_pkttime);
- if (new == NULL) {
- error = ENOMEM;
- break;
- }
-
- s = splnet();
- _flushq(rqp->rq_q);
- limit = fc->rio_limit;
- if (limit < fc->q_params[RIO_NDROPPREC-1].th_max)
- limit = fc->q_params[RIO_NDROPPREC-1].th_max;
- qlimit(rqp->rq_q) = limit;
-
- rio_destroy(rqp->rq_rio);
- rqp->rq_rio = new;
-
- splx(s);
-
- /* write back new values */
- fc->rio_limit = limit;
- for (i = 0; i < RIO_NDROPPREC; i++) {
- fc->q_params[i].inv_pmax =
- rqp->rq_rio->rio_precstate[i].inv_pmax;
- fc->q_params[i].th_min =
- rqp->rq_rio->rio_precstate[i].th_min;
- fc->q_params[i].th_max =
- rqp->rq_rio->rio_precstate[i].th_max;
- }
- } while (/*CONSTCOND*/ 0);
- break;
-
- case RIO_SETDEFAULTS:
- do {
- struct redparams *rp;
- int i;
-
- rp = (struct redparams *)addr;
- for (i = 0; i < RIO_NDROPPREC; i++)
- default_rio_params[i] = rp[i];
- } while (/*CONSTCOND*/ 0);
- break;
-
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-static int
-rio_detach(rqp)
- rio_queue_t *rqp;
-{
- rio_queue_t *tmp;
- int error = 0;
-
- if (ALTQ_IS_ENABLED(rqp->rq_ifq))
- altq_disable(rqp->rq_ifq);
-
- if ((error = altq_detach(rqp->rq_ifq)))
- return (error);
-
- if (rio_list == rqp)
- rio_list = rqp->rq_next;
- else {
- for (tmp = rio_list; tmp != NULL; tmp = tmp->rq_next)
- if (tmp->rq_next == rqp) {
- tmp->rq_next = rqp->rq_next;
- break;
- }
- if (tmp == NULL)
- printf("rio_detach: no state found in rio_list!\n");
- }
-
- rio_destroy(rqp->rq_rio);
- free(rqp->rq_q, M_DEVBUF);
- free(rqp, M_DEVBUF);
- return (error);
-}
-
-/*
- * rio support routines
- */
-static int
-rio_request(ifq, req, arg)
- struct ifaltq *ifq;
- int req;
- void *arg;
-{
- rio_queue_t *rqp = (rio_queue_t *)ifq->altq_disc;
-
- IFQ_LOCK_ASSERT(ifq);
-
- switch (req) {
- case ALTRQ_PURGE:
- _flushq(rqp->rq_q);
- if (ALTQ_IS_ENABLED(ifq))
- ifq->ifq_len = 0;
- break;
- }
- return (0);
-}
-
-/*
- * enqueue routine:
- *
- * returns: 0 when successfully queued.
- * ENOBUFS when drop occurs.
- */
-static int
-rio_enqueue(ifq, m, pktattr)
- struct ifaltq *ifq;
- struct mbuf *m;
- struct altq_pktattr *pktattr;
-{
- rio_queue_t *rqp = (rio_queue_t *)ifq->altq_disc;
- int error = 0;
-
- IFQ_LOCK_ASSERT(ifq);
-
- if (rio_addq(rqp->rq_rio, rqp->rq_q, m, pktattr) == 0)
- ifq->ifq_len++;
- else
- error = ENOBUFS;
- return error;
-}
-
-/*
- * dequeue routine:
- * must be called in splimp.
- *
- * returns: mbuf dequeued.
- * NULL when no packet is available in the queue.
- */
-
-static struct mbuf *
-rio_dequeue(ifq, op)
- struct ifaltq *ifq;
- int op;
-{
- rio_queue_t *rqp = (rio_queue_t *)ifq->altq_disc;
- struct mbuf *m = NULL;
-
- IFQ_LOCK_ASSERT(ifq);
-
- if (op == ALTDQ_POLL)
- return qhead(rqp->rq_q);
-
- m = rio_getq(rqp->rq_rio, rqp->rq_q);
- if (m != NULL)
- ifq->ifq_len--;
- return m;
-}
-
-#ifdef KLD_MODULE
-
-static struct altqsw rio_sw =
- {"rio", rioopen, rioclose, rioioctl};
-
-ALTQ_MODULE(altq_rio, ALTQT_RIO, &rio_sw);
-MODULE_VERSION(altq_rio, 1);
-MODULE_DEPEND(altq_rio, altq_red, 1, 1, 1);
-
-#endif /* KLD_MODULE */
-#endif /* ALTQ3_COMPAT */
#endif /* ALTQ_RIO */
diff --git a/freebsd/sys/net/altq/altq_rio.h b/freebsd/sys/net/altq/altq_rio.h
index ce9dc0e0..2ae71394 100644
--- a/freebsd/sys/net/altq/altq_rio.h
+++ b/freebsd/sys/net/altq/altq_rio.h
@@ -38,32 +38,6 @@
*/
#define RIO_NDROPPREC 3 /* number of drop precedence values */
-#ifdef ALTQ3_COMPAT
-struct rio_interface {
- char rio_ifname[IFNAMSIZ];
-};
-
-struct rio_stats {
- struct rio_interface iface;
- int q_len[RIO_NDROPPREC];
- struct redstats q_stats[RIO_NDROPPREC];
-
- /* static red parameters */
- int q_limit;
- int weight;
- int flags;
- struct redparams q_params[RIO_NDROPPREC];
-};
-
-struct rio_conf {
- struct rio_interface iface;
- struct redparams q_params[RIO_NDROPPREC];
- int rio_weight; /* weight for EWMA */
- int rio_limit; /* max queue length */
- int rio_pkttime; /* average packet time in usec */
- int rio_flags; /* see below */
-};
-#endif /* ALTQ3_COMPAT */
/* rio flags */
#define RIOF_ECN4 0x01 /* use packet marking for IPv4 packets */
@@ -71,18 +45,6 @@ struct rio_conf {
#define RIOF_ECN (RIOF_ECN4 | RIOF_ECN6)
#define RIOF_CLEARDSCP 0x200 /* clear diffserv codepoint */
-#ifdef ALTQ3_COMPAT
-/*
- * IOCTLs for RIO
- */
-#define RIO_IF_ATTACH _IOW('Q', 1, struct rio_interface)
-#define RIO_IF_DETACH _IOW('Q', 2, struct rio_interface)
-#define RIO_ENABLE _IOW('Q', 3, struct rio_interface)
-#define RIO_DISABLE _IOW('Q', 4, struct rio_interface)
-#define RIO_CONFIG _IOWR('Q', 6, struct rio_conf)
-#define RIO_GETSTATS _IOWR('Q', 12, struct rio_stats)
-#define RIO_SETDEFAULTS _IOW('Q', 30, struct redparams[RIO_NDROPPREC])
-#endif /* ALTQ3_COMPAT */
#ifdef _KERNEL
@@ -122,16 +84,6 @@ typedef struct rio {
struct redstats q_stats[RIO_NDROPPREC]; /* statistics */
} rio_t;
-#ifdef ALTQ3_COMPAT
-typedef struct rio_queue {
- struct rio_queue *rq_next; /* next red_state in the list */
- struct ifaltq *rq_ifq; /* backpointer to ifaltq */
-
- class_queue_t *rq_q;
-
- rio_t *rq_rio;
-} rio_queue_t;
-#endif /* ALTQ3_COMPAT */
extern rio_t *rio_alloc(int, struct redparams *, int, int);
extern void rio_destroy(rio_t *);
diff --git a/freebsd/sys/net/altq/altq_rmclass.c b/freebsd/sys/net/altq/altq_rmclass.c
index 9ba3eb25..0f4a4899 100644
--- a/freebsd/sys/net/altq/altq_rmclass.c
+++ b/freebsd/sys/net/altq/altq_rmclass.c
@@ -51,17 +51,9 @@
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/time.h>
-#ifdef ALTQ3_COMPAT
-#include <sys/kernel.h>
-#endif
#include <net/if.h>
#include <net/if_var.h>
-#ifdef ALTQ3_COMPAT
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#endif
#include <net/altq/if_altq.h>
#include <net/altq/altq.h>
diff --git a/freebsd/sys/net/altq/altq_rmclass.h b/freebsd/sys/net/altq/altq_rmclass.h
index 268ed63f..7e58ec49 100644
--- a/freebsd/sys/net/altq/altq_rmclass.h
+++ b/freebsd/sys/net/altq/altq_rmclass.h
@@ -233,13 +233,13 @@ struct rm_ifdat {
};
/* flags for rmc_init and rmc_newclass */
-/* class flags */
+/* class flags; must be the same as class flags in altq_cbq.h */
#define RMCF_RED 0x0001
#define RMCF_ECN 0x0002
#define RMCF_RIO 0x0004
#define RMCF_FLOWVALVE 0x0008 /* use flowvalve (aka penalty-box) */
#define RMCF_CLEARDSCP 0x0010 /* clear diffserv codepoint */
-#define RMCF_CODEL 0x0020
+#define RMCF_CODEL 0x0040
/* flags for rmc_init */
#define RMCF_WRR 0x0100
diff --git a/freebsd/sys/net/altq/altq_subr.c b/freebsd/sys/net/altq/altq_subr.c
index 6da36129..61aaec59 100644
--- a/freebsd/sys/net/altq/altq_subr.c
+++ b/freebsd/sys/net/altq/altq_subr.c
@@ -64,9 +64,6 @@
#include <netpfil/pf/pf.h>
#include <netpfil/pf/pf_altq.h>
#include <net/altq/altq.h>
-#ifdef ALTQ3_COMPAT
-#include <net/altq/altq_conf.h>
-#endif
/* machine dependent clock related includes */
#include <sys/bus.h>
@@ -157,22 +154,6 @@ altq_attach(ifq, type, discipline, enqueue, dequeue, request, clfier, classify)
return ENXIO;
}
-#ifdef ALTQ3_COMPAT
- /*
- * pfaltq can override the existing discipline, but altq3 cannot.
- * check these if clfier is not NULL (which implies altq3).
- */
- if (clfier != NULL) {
- if (ALTQ_IS_ENABLED(ifq)) {
- IFQ_UNLOCK(ifq);
- return EBUSY;
- }
- if (ALTQ_IS_ATTACHED(ifq)) {
- IFQ_UNLOCK(ifq);
- return EEXIST;
- }
- }
-#endif
ifq->altq_type = type;
ifq->altq_disc = discipline;
ifq->altq_enqueue = enqueue;
@@ -181,11 +162,6 @@ altq_attach(ifq, type, discipline, enqueue, dequeue, request, clfier, classify)
ifq->altq_clfier = clfier;
ifq->altq_classify = classify;
ifq->altq_flags &= (ALTQF_CANTCHANGE|ALTQF_ENABLED);
-#ifdef ALTQ3_COMPAT
-#ifdef ALTQ_KLD
- altq_module_incref(type);
-#endif
-#endif
IFQ_UNLOCK(ifq);
return 0;
}
@@ -208,11 +184,6 @@ altq_detach(ifq)
IFQ_UNLOCK(ifq);
return (0);
}
-#ifdef ALTQ3_COMPAT
-#ifdef ALTQ_KLD
- altq_module_declref(ifq->altq_type);
-#endif
-#endif
ifq->altq_type = ALTQT_NONE;
ifq->altq_disc = NULL;
diff --git a/freebsd/sys/net/if.c b/freebsd/sys/net/if.c
index d846482e..9d233444 100644
--- a/freebsd/sys/net/if.c
+++ b/freebsd/sys/net/if.c
@@ -604,8 +604,6 @@ if_free_internal(struct ifnet *ifp)
#ifdef MAC
mac_ifnet_destroy(ifp);
#endif /* MAC */
- if (ifp->if_description != NULL)
- free(ifp->if_description, M_IFDESCR);
IF_AFDATA_DESTROY(ifp);
IF_ADDR_LOCK_DESTROY(ifp);
ifq_delete(&ifp->if_snd);
@@ -613,6 +611,8 @@ if_free_internal(struct ifnet *ifp)
for (int i = 0; i < IFCOUNTERS; i++)
counter_u64_free(ifp->if_counters[i]);
+ free(ifp->if_description, M_IFDESCR);
+ free(ifp->if_hw_addr, M_IFADDR);
free(ifp, M_IFNET);
}
@@ -1077,6 +1077,8 @@ if_detach_internal(struct ifnet *ifp, int vmove, struct if_clone **ifcp)
CK_STAILQ_FOREACH(iter, &V_ifnet, if_link)
if (iter == ifp) {
CK_STAILQ_REMOVE(&V_ifnet, ifp, ifnet, if_link);
+ if (!vmove)
+ ifp->if_flags |= IFF_DYING;
found = 1;
break;
}
@@ -1191,14 +1193,8 @@ if_detach_internal(struct ifnet *ifp, int vmove, struct if_clone **ifcp)
if_dead(ifp);
/*
- * Remove link ifaddr pointer and maybe decrement if_index.
* Clean up all addresses.
*/
- free(ifp->if_hw_addr, M_IFADDR);
- ifp->if_hw_addr = NULL;
- ifp->if_addr = NULL;
-
- /* We can now free link ifaddr. */
IF_ADDR_WLOCK(ifp);
if (!CK_STAILQ_EMPTY(&ifp->if_addrhead)) {
ifa = CK_STAILQ_FIRST(&ifp->if_addrhead);
diff --git a/freebsd/sys/net/if_ipsec.c b/freebsd/sys/net/if_ipsec.c
index 7cc2c961..4b4d9ec5 100644
--- a/freebsd/sys/net/if_ipsec.c
+++ b/freebsd/sys/net/if_ipsec.c
@@ -974,7 +974,7 @@ static int
ipsec_set_addresses(struct ifnet *ifp, struct sockaddr *src,
struct sockaddr *dst)
{
- struct ipsec_softc *sc, *tsc;
+ struct ipsec_softc *sc;
struct secasindex *saidx;
sx_assert(&ipsec_ioctl_sx, SA_XLOCKED);
@@ -989,18 +989,6 @@ ipsec_set_addresses(struct ifnet *ifp, struct sockaddr *src,
return (0); /* Nothing has been changed. */
}
- /* Check that given addresses aren't already configured */
- CK_LIST_FOREACH(tsc, ipsec_srchash(src), srchash) {
- if (tsc == sc)
- continue;
- MPASS(tsc->family == src->sa_family);
- saidx = ipsec_getsaidx(tsc, IPSEC_DIR_OUTBOUND, tsc->family);
- if (key_sockaddrcmp(&saidx->src.sa, src, 0) == 0 &&
- key_sockaddrcmp(&saidx->dst.sa, dst, 0) == 0) {
- /* We already have tunnel with such addresses */
- return (EADDRNOTAVAIL);
- }
- }
/* If reqid is not set, generate new one. */
if (ipsec_init_reqid(sc) != 0)
return (EEXIST);
diff --git a/freebsd/sys/net/if_tap.c b/freebsd/sys/net/if_tap.c
index a540a59a..dbf3e599 100644
--- a/freebsd/sys/net/if_tap.c
+++ b/freebsd/sys/net/if_tap.c
@@ -348,7 +348,7 @@ tapclone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **d
return;
if (!tapdclone ||
- (!tapuopen && priv_check_cred(cred, PRIV_NET_IFCREATE, 0) != 0))
+ (!tapuopen && priv_check_cred(cred, PRIV_NET_IFCREATE) != 0))
return;
unit = 0;
diff --git a/freebsd/sys/net/if_tun.c b/freebsd/sys/net/if_tun.c
index 328b1963..44441773 100644
--- a/freebsd/sys/net/if_tun.c
+++ b/freebsd/sys/net/if_tun.c
@@ -206,7 +206,7 @@ tunclone(void *arg, struct ucred *cred, char *name, int namelen,
* If tun cloning is enabled, only the superuser can create an
* interface.
*/
- if (!tundclone || priv_check_cred(cred, PRIV_NET_IFCREATE, 0) != 0)
+ if (!tundclone || priv_check_cred(cred, PRIV_NET_IFCREATE) != 0)
return;
if (strcmp(name, tunname) == 0) {
diff --git a/freebsd/sys/net/if_vlan.c b/freebsd/sys/net/if_vlan.c
index 6f07b4b4..893bb2cf 100644
--- a/freebsd/sys/net/if_vlan.c
+++ b/freebsd/sys/net/if_vlan.c
@@ -316,9 +316,6 @@ VNET_DEFINE_STATIC(struct if_clone *, vlan_cloner);
#define V_vlan_cloner VNET(vlan_cloner)
#endif
-#ifndef VLAN_ARRAY
-#define HASH(n, m) ((((n) >> 8) ^ ((n) >> 4) ^ (n)) & (m))
-
static void
vlan_mc_free(struct epoch_context *ctx)
{
@@ -326,6 +323,9 @@ vlan_mc_free(struct epoch_context *ctx)
free(mc, M_VLAN);
}
+#ifndef VLAN_ARRAY
+#define HASH(n, m) ((((n) >> 8) ^ ((n) >> 4) ^ (n)) & (m))
+
static void
vlan_inithash(struct ifvlantrunk *trunk)
{
diff --git a/freebsd/sys/net/route.h b/freebsd/sys/net/route.h
index 15ec1b3e..c4333838 100644
--- a/freebsd/sys/net/route.h
+++ b/freebsd/sys/net/route.h
@@ -251,6 +251,7 @@ struct rt_msghdr {
u_char rtm_version; /* future binary compatibility */
u_char rtm_type; /* message type */
u_short rtm_index; /* index for associated ifp */
+ u_short _rtm_spare1;
int rtm_flags; /* flags, incl. kern & message, e.g. DONE */
int rtm_addrs; /* bitmask identifying sockaddrs in msg */
pid_t rtm_pid; /* identify sender */
diff --git a/freebsd/sys/net/rtsock.c b/freebsd/sys/net/rtsock.c
index 84afd627..e1b87095 100644
--- a/freebsd/sys/net/rtsock.c
+++ b/freebsd/sys/net/rtsock.c
@@ -85,6 +85,7 @@ struct if_msghdr32 {
int32_t ifm_addrs;
int32_t ifm_flags;
uint16_t ifm_index;
+ uint16_t _ifm_spare1;
struct if_data ifm_data;
};
@@ -98,6 +99,7 @@ struct if_msghdrl32 {
uint16_t _ifm_spare1;
uint16_t ifm_len;
uint16_t ifm_data_off;
+ uint32_t _ifm_spare2;
struct if_data ifm_data;
};
@@ -1231,8 +1233,11 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int *
dlen = ALIGN(len) - len;
if (buflen < dlen)
cp = NULL;
- else
+ else {
+ bzero(cp, dlen);
+ cp += dlen;
buflen -= dlen;
+ }
}
len = ALIGN(len);
@@ -1566,6 +1571,8 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
struct rt_addrinfo info;
struct sockaddr_storage ss;
+ IFNET_RLOCK_NOSLEEP_ASSERT();
+
if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg))
return 0;
if ((rt->rt_flags & RTF_HOST) == 0
@@ -1578,7 +1585,7 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
info.rti_info[RTAX_NETMASK] = rtsock_fix_netmask(rt_key(rt),
rt_mask(rt), &ss);
info.rti_info[RTAX_GENMASK] = 0;
- if (rt->rt_ifp) {
+ if (rt->rt_ifp && !(rt->rt_ifp->if_flags & IFF_DYING)) {
info.rti_info[RTAX_IFP] = rt->rt_ifp->if_addr->ifa_addr;
info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
if (rt->rt_ifp->if_flags & IFF_POINTOPOINT)
@@ -1589,6 +1596,8 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
if (w->w_req && w->w_tmem) {
struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem;
+ bzero(&rtm->rtm_index,
+ sizeof(*rtm) - offsetof(struct rt_msghdr, rtm_index));
if (rt->rt_flags & RTF_GWFLAG_COMPAT)
rtm->rtm_flags = RTF_GATEWAY |
(rt->rt_flags & ~RTF_GWFLAG_COMPAT);
@@ -1596,7 +1605,6 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
rtm->rtm_flags = rt->rt_flags;
rt_getmetrics(rt, &rtm->rtm_rmx);
rtm->rtm_index = rt->rt_ifp->if_index;
- rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0;
rtm->rtm_addrs = info.rti_addrs;
error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size);
return (error);
@@ -1624,6 +1632,7 @@ sysctl_iflist_ifml(struct ifnet *ifp, const struct if_data *src_ifd,
ifm32->_ifm_spare1 = 0;
ifm32->ifm_len = sizeof(*ifm32);
ifm32->ifm_data_off = offsetof(struct if_msghdrl32, ifm_data);
+ ifm32->_ifm_spare2 = 0;
ifd = &ifm32->ifm_data;
} else
#endif
@@ -1634,6 +1643,7 @@ sysctl_iflist_ifml(struct ifnet *ifp, const struct if_data *src_ifd,
ifm->_ifm_spare1 = 0;
ifm->ifm_len = sizeof(*ifm);
ifm->ifm_data_off = offsetof(struct if_msghdrl, ifm_data);
+ ifm->_ifm_spare2 = 0;
ifd = &ifm->ifm_data;
}
@@ -1659,6 +1669,7 @@ sysctl_iflist_ifm(struct ifnet *ifp, const struct if_data *src_ifd,
ifm32->ifm_addrs = info->rti_addrs;
ifm32->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
ifm32->ifm_index = ifp->if_index;
+ ifm32->_ifm_spare1 = 0;
ifd = &ifm32->ifm_data;
} else
#endif
@@ -1666,6 +1677,7 @@ sysctl_iflist_ifm(struct ifnet *ifp, const struct if_data *src_ifd,
ifm->ifm_addrs = info->rti_addrs;
ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
ifm->ifm_index = ifp->if_index;
+ ifm->_ifm_spare1 = 0;
ifd = &ifm->ifm_data;
}
@@ -1734,6 +1746,7 @@ sysctl_iflist_ifam(struct ifaddr *ifa, struct rt_addrinfo *info,
ifam->ifam_addrs = info->rti_addrs;
ifam->ifam_flags = ifa->ifa_flags;
ifam->ifam_index = ifa->ifa_ifp->if_index;
+ ifam->_ifam_spare1 = 0;
ifam->ifam_metric = ifa->ifa_ifp->if_metric;
return (SYSCTL_OUT(w->w_req, w->w_tmem, len));
@@ -1845,6 +1858,7 @@ sysctl_ifmalist(int af, struct walkarg *w)
ifmam->ifmam_index = ifma->ifma_ifp->if_index;
ifmam->ifmam_flags = 0;
ifmam->ifmam_addrs = info.rti_addrs;
+ ifmam->_ifmam_spare1 = 0;
error = SYSCTL_OUT(w->w_req, w->w_tmem, len);
if (error != 0)
break;
@@ -1942,8 +1956,10 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
rnh = rt_tables_get_rnh(fib, i);
if (rnh != NULL) {
RIB_RLOCK(rnh);
+ IFNET_RLOCK_NOSLEEP();
error = rnh->rnh_walktree(&rnh->head,
sysctl_dumpentry, &w);
+ IFNET_RUNLOCK_NOSLEEP();
RIB_RUNLOCK(rnh);
} else if (af != 0)
error = EAFNOSUPPORT;
diff --git a/freebsd/sys/net80211/ieee80211_node.c b/freebsd/sys/net80211/ieee80211_node.c
index 55e51299..ec726880 100644
--- a/freebsd/sys/net80211/ieee80211_node.c
+++ b/freebsd/sys/net80211/ieee80211_node.c
@@ -1419,8 +1419,6 @@ ieee80211_alloc_node(struct ieee80211_node_table *nt,
IEEE80211_NOTE(vap, IEEE80211_MSG_INACT, ni,
"%s: inact_reload %u", __func__, ni->ni_inact_reload);
- ieee80211_ratectl_node_init(ni);
-
return ni;
}
diff --git a/freebsd/sys/netinet/cc/cc.h b/freebsd/sys/netinet/cc/cc.h
index 1389b27a..b1a69ca1 100644
--- a/freebsd/sys/netinet/cc/cc.h
+++ b/freebsd/sys/netinet/cc/cc.h
@@ -102,8 +102,6 @@ struct cc_var {
#define CCF_ACKNOW 0x0008 /* Will this ack be sent now? */
#define CCF_IPHDR_CE 0x0010 /* Does this packet set CE bit? */
#define CCF_TCPHDR_CWR 0x0020 /* Does this packet set CWR bit? */
-#define CCF_MAX_CWND 0x0040 /* Have we reached maximum cwnd? */
-#define CCF_CHG_MAX_CWND 0x0080 /* Cubic max_cwnd changed, for K */
/* ACK types passed to the ack_received() hook. */
#define CC_ACK 0x0001 /* Regular in sequence ACK. */
@@ -184,4 +182,6 @@ extern struct rwlock cc_list_lock;
#define CC_LIST_WUNLOCK() rw_wunlock(&cc_list_lock)
#define CC_LIST_LOCK_ASSERT() rw_assert(&cc_list_lock, RA_LOCKED)
+#define CC_ALGOOPT_LIMIT 2048
+
#endif /* _NETINET_CC_CC_H_ */
diff --git a/freebsd/sys/netinet/cc/cc_newreno.c b/freebsd/sys/netinet/cc/cc_newreno.c
index 2450f08e..b1307c92 100644
--- a/freebsd/sys/netinet/cc/cc_newreno.c
+++ b/freebsd/sys/netinet/cc/cc_newreno.c
@@ -81,8 +81,6 @@ __FBSDID("$FreeBSD$");
static MALLOC_DEFINE(M_NEWRENO, "newreno data",
"newreno beta values");
-#define CAST_PTR_INT(X) (*((int*)(X)))
-
static void newreno_cb_destroy(struct cc_var *ccv);
static void newreno_ack_received(struct cc_var *ccv, uint16_t type);
static void newreno_after_idle(struct cc_var *ccv);
@@ -366,15 +364,21 @@ newreno_ctl_output(struct cc_var *ccv, struct sockopt *sopt, void *buf)
static int
newreno_beta_handler(SYSCTL_HANDLER_ARGS)
{
+ int error;
+ uint32_t new;
- if (req->newptr != NULL ) {
+ new = *(uint32_t *)arg1;
+ error = sysctl_handle_int(oidp, &new, 0, req);
+ if (error == 0 && req->newptr != NULL ) {
if (arg1 == &VNET_NAME(newreno_beta_ecn) && !V_cc_do_abe)
- return (EACCES);
- if (CAST_PTR_INT(req->newptr) <= 0 || CAST_PTR_INT(req->newptr) > 100)
- return (EINVAL);
+ error = EACCES;
+ else if (new == 0 || new > 100)
+ error = EINVAL;
+ else
+ *(uint32_t *)arg1 = new;
}
- return (sysctl_handle_int(oidp, arg1, arg2, req));
+ return (error);
}
SYSCTL_DECL(_net_inet_tcp_cc_newreno);
diff --git a/freebsd/sys/netinet/if_ether.c b/freebsd/sys/netinet/if_ether.c
index 6ee6b71c..e9efd89e 100644
--- a/freebsd/sys/netinet/if_ether.c
+++ b/freebsd/sys/netinet/if_ether.c
@@ -435,10 +435,10 @@ arprequest(struct ifnet *ifp, const struct in_addr *sip,
/*
* Resolve an IP address into an ethernet address - heavy version.
* Used internally by arpresolve().
- * We have already checked than we can't use existing lle without
- * modification so we have to acquire LLE_EXCLUSIVE lle lock.
+ * We have already checked that we can't use an existing lle without
+ * modification so we have to acquire an LLE_EXCLUSIVE lle lock.
*
- * On success, desten and flags are filled in and the function returns 0;
+ * On success, desten and pflags are filled in and the function returns 0;
* If the packet must be held pending resolution, we return EWOULDBLOCK
* On other errors, we return the corresponding error code.
* Note that m_freem() handles NULL.
@@ -575,21 +575,6 @@ arpresolve_full(struct ifnet *ifp, int is_gw, int flags, struct mbuf *m,
}
/*
- * Resolve an IP address into an ethernet address.
- */
-int
-arpresolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst,
- char *desten, uint32_t *pflags, struct llentry **plle)
-{
- int error;
-
- flags |= LLE_ADDRONLY;
- error = arpresolve_full(ifp, 0, flags, NULL, dst, desten, pflags, plle);
- return (error);
-}
-
-
-/*
* Lookups link header based on an IP address.
* On input:
* ifp is the interface we use
diff --git a/freebsd/sys/netinet/if_ether.h b/freebsd/sys/netinet/if_ether.h
index 028e45a7..2f56e7a9 100644
--- a/freebsd/sys/netinet/if_ether.h
+++ b/freebsd/sys/netinet/if_ether.h
@@ -117,9 +117,6 @@ extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN];
struct ifaddr;
struct llentry;
-int arpresolve_addr(struct ifnet *ifp, int flags,
- const struct sockaddr *dst, char *desten, uint32_t *pflags,
- struct llentry **plle);
int arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
const struct sockaddr *dst, u_char *desten, uint32_t *pflags,
struct llentry **plle);
diff --git a/freebsd/sys/netinet/in_pcb.c b/freebsd/sys/netinet/in_pcb.c
index 6bf43464..c00593e5 100644
--- a/freebsd/sys/netinet/in_pcb.c
+++ b/freebsd/sys/netinet/in_pcb.c
@@ -345,8 +345,7 @@ in_pcbinslbgrouphash(struct inpcb *inp)
}
#endif
- idx = INP_PCBLBGROUP_PORTHASH(inp->inp_lport,
- pcbinfo->ipi_lbgrouphashmask);
+ idx = INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_lbgrouphashmask);
hdr = &pcbinfo->ipi_lbgrouphashbase[idx];
CK_LIST_FOREACH(grp, hdr, il_list) {
if (grp->il_vflag == inp->inp_vflag &&
@@ -403,9 +402,7 @@ in_pcbremlbgrouphash(struct inpcb *inp)
INP_HASH_WLOCK_ASSERT(pcbinfo);
hdr = &pcbinfo->ipi_lbgrouphashbase[
- INP_PCBLBGROUP_PORTHASH(inp->inp_lport,
- pcbinfo->ipi_lbgrouphashmask)];
-
+ INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_lbgrouphashmask)];
CK_LIST_FOREACH(grp, hdr, il_list) {
for (i = 0; i < grp->il_inpcnt; ++i) {
if (grp->il_inp[i] != inp)
@@ -445,6 +442,8 @@ in_pcbinfo_init(struct inpcbinfo *pcbinfo, const char *name,
char *inpcbzone_name, uma_init inpcbzone_init, u_int hashfields)
{
+ porthash_nelements = imin(porthash_nelements, IPPORT_MAX + 1);
+
INP_INFO_LOCK_INIT(pcbinfo, name);
INP_HASH_LOCK_INIT(pcbinfo, "pcbinfohash"); /* XXXRW: argument? */
INP_LIST_LOCK_INIT(pcbinfo, "pcbinfolist");
@@ -458,7 +457,7 @@ in_pcbinfo_init(struct inpcbinfo *pcbinfo, const char *name,
&pcbinfo->ipi_hashmask);
pcbinfo->ipi_porthashbase = hashinit(porthash_nelements, M_PCB,
&pcbinfo->ipi_porthashmask);
- pcbinfo->ipi_lbgrouphashbase = hashinit(hash_nelements, M_PCB,
+ pcbinfo->ipi_lbgrouphashbase = hashinit(porthash_nelements, M_PCB,
&pcbinfo->ipi_lbgrouphashmask);
#ifdef PCBGROUP
in_pcbgroup_init(pcbinfo, hashfields, hash_nelements);
@@ -629,7 +628,7 @@ in_pcb_lport(struct inpcb *inp, struct in_addr *laddrp, u_short *lportp,
last = V_ipport_hilastauto;
lastport = &pcbinfo->ipi_lasthi;
} else if (inp->inp_flags & INP_LOWPORT) {
- error = priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT, 0);
+ error = priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT);
if (error)
return (error);
first = V_ipport_lowfirstauto; /* 1023 */
@@ -875,12 +874,10 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
/* GROSS */
if (ntohs(lport) <= V_ipport_reservedhigh &&
ntohs(lport) >= V_ipport_reservedlow &&
- priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT,
- 0))
+ priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT))
return (EACCES);
if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) &&
- priv_check_cred(inp->inp_cred,
- PRIV_NETINET_REUSEPORT, 0) != 0) {
+ priv_check_cred(inp->inp_cred, PRIV_NETINET_REUSEPORT) != 0) {
t = in_pcblookup_local(pcbinfo, sin->sin_addr,
lport, INPLOOKUP_WILDCARD, cred);
/*
@@ -1962,8 +1959,8 @@ in_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo,
INP_HASH_LOCK_ASSERT(pcbinfo);
- hdr = &pcbinfo->ipi_lbgrouphashbase[INP_PCBLBGROUP_PORTHASH(lport,
- pcbinfo->ipi_lbgrouphashmask)];
+ hdr = &pcbinfo->ipi_lbgrouphashbase[
+ INP_PCBPORTHASH(lport, pcbinfo->ipi_lbgrouphashmask)];
/*
* Order of socket selection:
@@ -2895,11 +2892,10 @@ void
in_pcbtoxinpcb(const struct inpcb *inp, struct xinpcb *xi)
{
+ bzero(xi, sizeof(*xi));
xi->xi_len = sizeof(struct xinpcb);
if (inp->inp_socket)
sotoxsocket(inp->inp_socket, &xi->xi_socket);
- else
- bzero(&xi->xi_socket, sizeof(struct xsocket));
bcopy(&inp->inp_inc, &xi->inp_inc, sizeof(struct in_conninfo));
xi->inp_gencnt = inp->inp_gencnt;
xi->inp_ppcb = (uintptr_t)inp->inp_ppcb;
diff --git a/freebsd/sys/netinet/in_pcb.h b/freebsd/sys/netinet/in_pcb.h
index 6d2c86d5..ecbd7a22 100644
--- a/freebsd/sys/netinet/in_pcb.h
+++ b/freebsd/sys/netinet/in_pcb.h
@@ -688,8 +688,6 @@ int inp_so_options(const struct inpcb *inp);
(((faddr) ^ ((faddr) >> 16) ^ ntohs((lport) ^ (fport))) & (mask))
#define INP_PCBPORTHASH(lport, mask) \
(ntohs((lport)) & (mask))
-#define INP_PCBLBGROUP_PORTHASH(lport, mask) \
- (ntohs((lport)) & (mask))
#define INP_PCBLBGROUP_PKTHASH(faddr, lport, fport) \
((faddr) ^ ((faddr) >> 16) ^ ntohs((lport) ^ (fport)))
#define INP6_PCBHASHKEY(faddr) ((faddr)->s6_addr32[3])
diff --git a/freebsd/sys/netinet/ip_divert.c b/freebsd/sys/netinet/ip_divert.c
index fbf74ca1..6a99645e 100644
--- a/freebsd/sys/netinet/ip_divert.c
+++ b/freebsd/sys/netinet/ip_divert.c
@@ -666,6 +666,7 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
if (error != 0)
return (error);
+ bzero(&xig, sizeof(xig));
xig.xig_len = sizeof xig;
xig.xig_count = n;
xig.xig_gen = gencnt;
diff --git a/freebsd/sys/netinet/ip_fw.h b/freebsd/sys/netinet/ip_fw.h
index cfcdaa29..41351215 100644
--- a/freebsd/sys/netinet/ip_fw.h
+++ b/freebsd/sys/netinet/ip_fw.h
@@ -551,11 +551,12 @@ typedef struct _ipfw_insn_nat {
} ipfw_insn_nat;
/* Apply ipv6 mask on ipv6 addr */
-#define APPLY_MASK(addr,mask) \
+#define APPLY_MASK(addr,mask) do { \
(addr)->__u6_addr.__u6_addr32[0] &= (mask)->__u6_addr.__u6_addr32[0]; \
(addr)->__u6_addr.__u6_addr32[1] &= (mask)->__u6_addr.__u6_addr32[1]; \
(addr)->__u6_addr.__u6_addr32[2] &= (mask)->__u6_addr.__u6_addr32[2]; \
- (addr)->__u6_addr.__u6_addr32[3] &= (mask)->__u6_addr.__u6_addr32[3];
+ (addr)->__u6_addr.__u6_addr32[3] &= (mask)->__u6_addr.__u6_addr32[3]; \
+} while (0)
/* Structure for ipv6 */
typedef struct _ipfw_insn_ip6 {
@@ -707,6 +708,7 @@ struct _ipfw_dyn_rule {
u_int32_t state; /* state of this rule (typically a
* combination of TCP flags)
*/
+#define IPFW_DYN_ORPHANED 0x40000 /* state's parent rule was deleted */
u_int32_t ack_fwd; /* most recent ACKs in forward */
u_int32_t ack_rev; /* and reverse directions (used */
/* to generate keepalives) */
@@ -937,9 +939,10 @@ typedef struct _ipfw_range_tlv {
#define IPFW_RCFLAG_RANGE 0x01 /* rule range is set */
#define IPFW_RCFLAG_ALL 0x02 /* match ALL rules */
#define IPFW_RCFLAG_SET 0x04 /* match rules in given set */
+#define IPFW_RCFLAG_DYNAMIC 0x08 /* match only dynamic states */
/* User-settable flags */
#define IPFW_RCFLAG_USER (IPFW_RCFLAG_RANGE | IPFW_RCFLAG_ALL | \
- IPFW_RCFLAG_SET)
+ IPFW_RCFLAG_SET | IPFW_RCFLAG_DYNAMIC)
/* Internally used flags */
#define IPFW_RCFLAG_DEFAULT 0x0100 /* Do not skip defaul rule */
diff --git a/freebsd/sys/netinet/ip_reass.c b/freebsd/sys/netinet/ip_reass.c
index 8bc5b53b..70a6edae 100644
--- a/freebsd/sys/netinet/ip_reass.c
+++ b/freebsd/sys/netinet/ip_reass.c
@@ -213,19 +213,21 @@ ip_reass(struct mbuf *m)
* convert offset of this to bytes.
*/
ip->ip_len = htons(ntohs(ip->ip_len) - hlen);
- if (ip->ip_off & htons(IP_MF)) {
- /*
- * Make sure that fragments have a data length
- * that's a non-zero multiple of 8 bytes.
- */
- if (ip->ip_len == htons(0) || (ntohs(ip->ip_len) & 0x7) != 0) {
- IPSTAT_INC(ips_toosmall); /* XXX */
- IPSTAT_INC(ips_fragdropped);
- m_freem(m);
- return (NULL);
- }
+ /*
+ * Make sure that fragments have a data length
+ * that's a non-zero multiple of 8 bytes, unless
+ * this is the last fragment.
+ */
+ if (ip->ip_len == htons(0) ||
+ ((ip->ip_off & htons(IP_MF)) && (ntohs(ip->ip_len) & 0x7) != 0)) {
+ IPSTAT_INC(ips_toosmall); /* XXX */
+ IPSTAT_INC(ips_fragdropped);
+ m_freem(m);
+ return (NULL);
+ }
+ if (ip->ip_off & htons(IP_MF))
m->m_flags |= M_IP_FRAG;
- } else
+ else
m->m_flags &= ~M_IP_FRAG;
ip->ip_off = htons(ntohs(ip->ip_off) << 3);
@@ -303,9 +305,28 @@ ip_reass(struct mbuf *m)
fp->ipq_src = ip->ip_src;
fp->ipq_dst = ip->ip_dst;
fp->ipq_frags = m;
+ if (m->m_flags & M_IP_FRAG)
+ fp->ipq_maxoff = -1;
+ else
+ fp->ipq_maxoff = ntohs(ip->ip_off) + ntohs(ip->ip_len);
m->m_nextpkt = NULL;
goto done;
} else {
+ /*
+ * If we already saw the last fragment, make sure
+ * this fragment's offset looks sane. Otherwise, if
+ * this is the last fragment, record its endpoint.
+ */
+ if (fp->ipq_maxoff > 0) {
+ i = ntohs(ip->ip_off) + ntohs(ip->ip_len);
+ if (((m->m_flags & M_IP_FRAG) && i >= fp->ipq_maxoff) ||
+ ((m->m_flags & M_IP_FRAG) == 0 &&
+ i != fp->ipq_maxoff)) {
+ fp = NULL;
+ goto dropfrag;
+ }
+ } else if ((m->m_flags & M_IP_FRAG) == 0)
+ fp->ipq_maxoff = ntohs(ip->ip_off) + ntohs(ip->ip_len);
fp->ipq_nfrags++;
atomic_add_int(&nfrags, 1);
#ifdef MAC
diff --git a/freebsd/sys/netinet/ip_var.h b/freebsd/sys/netinet/ip_var.h
index f874628a..86615a15 100644
--- a/freebsd/sys/netinet/ip_var.h
+++ b/freebsd/sys/netinet/ip_var.h
@@ -61,6 +61,7 @@ struct ipq {
u_char ipq_ttl; /* time for reass q to live */
u_char ipq_p; /* protocol of this fragment */
u_short ipq_id; /* sequence id for reassembly */
+ int ipq_maxoff; /* total length of packet */
struct mbuf *ipq_frags; /* to ip headers of fragments */
struct in_addr ipq_src,ipq_dst;
u_char ipq_nfrags; /* # frags in this packet */
diff --git a/freebsd/sys/netinet/raw_ip.c b/freebsd/sys/netinet/raw_ip.c
index a97eadae..1cac8d12 100644
--- a/freebsd/sys/netinet/raw_ip.c
+++ b/freebsd/sys/netinet/raw_ip.c
@@ -1062,6 +1062,7 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
n = V_ripcbinfo.ipi_count;
INP_INFO_WUNLOCK(&V_ripcbinfo);
+ bzero(&xig, sizeof(xig));
xig.xig_len = sizeof xig;
xig.xig_count = n;
xig.xig_gen = gencnt;
diff --git a/freebsd/sys/netinet/sctp_sysctl.c b/freebsd/sys/netinet/sctp_sysctl.c
index a4343cbe..1ba7e261 100644
--- a/freebsd/sys/netinet/sctp_sysctl.c
+++ b/freebsd/sys/netinet/sctp_sysctl.c
@@ -397,6 +397,9 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_SYSCTL, EPERM);
return (EPERM);
}
+ memset(&xinpcb, 0, sizeof(xinpcb));
+ memset(&xstcb, 0, sizeof(xstcb));
+ memset(&xraddr, 0, sizeof(xraddr));
LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
SCTP_INP_RLOCK(inp);
if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
diff --git a/freebsd/sys/netinet/tcp_output.c b/freebsd/sys/netinet/tcp_output.c
index 60276348..b641f04c 100644
--- a/freebsd/sys/netinet/tcp_output.c
+++ b/freebsd/sys/netinet/tcp_output.c
@@ -1174,14 +1174,18 @@ send:
/*
* Calculate receive window. Don't shrink window,
* but avoid silly window syndrome.
+ * If a RST segment is sent, advertise a window of zero.
*/
- if (recwin < (so->so_rcv.sb_hiwat / 4) &&
- recwin < tp->t_maxseg)
+ if (flags & TH_RST) {
recwin = 0;
- if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt) &&
- recwin < (tp->rcv_adv - tp->rcv_nxt))
- recwin = (tp->rcv_adv - tp->rcv_nxt);
-
+ } else {
+ if (recwin < (so->so_rcv.sb_hiwat / 4) &&
+ recwin < tp->t_maxseg)
+ recwin = 0;
+ if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt) &&
+ recwin < (tp->rcv_adv - tp->rcv_nxt))
+ recwin = (tp->rcv_adv - tp->rcv_nxt);
+ }
/*
* According to RFC1323 the window field in a SYN (i.e., a <SYN>
* or <SYN,ACK>) segment itself is never scaled. The <SYN,ACK>
diff --git a/freebsd/sys/netinet/tcp_subr.c b/freebsd/sys/netinet/tcp_subr.c
index 4852ffaf..52d2ca2a 100644
--- a/freebsd/sys/netinet/tcp_subr.c
+++ b/freebsd/sys/netinet/tcp_subr.c
@@ -562,6 +562,7 @@ sysctl_net_inet_list_func_info(SYSCTL_HANDLER_ARGS)
cnt++;
#endif
if (req->oldptr != NULL) {
+ bzero(&tfi, sizeof(tfi));
tfi.tfi_refcnt = f->tf_fb->tfb_refcnt;
tfi.tfi_id = f->tf_fb->tfb_id;
(void)strncpy(tfi.tfi_alias, f->tf_name,
@@ -2160,6 +2161,7 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
if (error != 0)
return (error);
+ bzero(&xig, sizeof(xig));
xig.xig_len = sizeof xig;
xig.xig_count = n + m;
xig.xig_gen = gencnt;
@@ -3221,8 +3223,8 @@ tcp_inptoxtp(const struct inpcb *inp, struct xtcpcb *xt)
struct tcpcb *tp = intotcpcb(inp);
sbintime_t now;
+ bzero(xt, sizeof(*xt));
if (inp->inp_flags & INP_TIMEWAIT) {
- bzero(xt, sizeof(struct xtcpcb));
xt->t_state = TCPS_TIME_WAIT;
} else {
xt->t_state = tp->t_state;
@@ -3250,7 +3252,6 @@ tcp_inptoxtp(const struct inpcb *inp, struct xtcpcb *xt)
bcopy(tp->t_fb->tfb_tcp_block_name, xt->xt_stack,
TCP_FUNCTION_NAME_LEN_MAX);
- bzero(xt->xt_logid, TCP_LOG_ID_LEN);
#ifdef TCP_BLACKBOX
(void)tcp_log_get_id(tp, xt->xt_logid);
#endif
diff --git a/freebsd/sys/netinet/tcp_usrreq.c b/freebsd/sys/netinet/tcp_usrreq.c
index 617f60d0..27ab745b 100644
--- a/freebsd/sys/netinet/tcp_usrreq.c
+++ b/freebsd/sys/netinet/tcp_usrreq.c
@@ -1771,6 +1771,8 @@ tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp
switch (sopt->sopt_name) {
case TCP_CCALGOOPT:
INP_WUNLOCK(inp);
+ if (sopt->sopt_valsize > CC_ALGOOPT_LIMIT)
+ return (EINVAL);
pbuf = malloc(sopt->sopt_valsize, M_TEMP, M_WAITOK | M_ZERO);
error = sooptcopyin(sopt, pbuf, sopt->sopt_valsize,
sopt->sopt_valsize);
diff --git a/freebsd/sys/netinet/udp_usrreq.c b/freebsd/sys/netinet/udp_usrreq.c
index ca4fecc0..33b89c21 100644
--- a/freebsd/sys/netinet/udp_usrreq.c
+++ b/freebsd/sys/netinet/udp_usrreq.c
@@ -893,6 +893,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
if (error != 0)
return (error);
+ bzero(&xig, sizeof(xig));
xig.xig_len = sizeof xig;
xig.xig_count = n;
xig.xig_gen = gencnt;
diff --git a/freebsd/sys/netinet6/in6_pcb.c b/freebsd/sys/netinet6/in6_pcb.c
index f5b22db7..a6beba43 100644
--- a/freebsd/sys/netinet6/in6_pcb.c
+++ b/freebsd/sys/netinet6/in6_pcb.c
@@ -218,12 +218,10 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr *nam,
/* GROSS */
if (ntohs(lport) <= V_ipport_reservedhigh &&
ntohs(lport) >= V_ipport_reservedlow &&
- priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT,
- 0))
+ priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT))
return (EACCES);
if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) &&
- priv_check_cred(inp->inp_cred,
- PRIV_NETINET_REUSEPORT, 0) != 0) {
+ priv_check_cred(inp->inp_cred, PRIV_NETINET_REUSEPORT) != 0) {
t = in6_pcblookup_local(pcbinfo,
&sin6->sin6_addr, lport,
INPLOOKUP_WILDCARD, cred);
@@ -894,8 +892,8 @@ in6_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo,
INP_HASH_LOCK_ASSERT(pcbinfo);
- hdr = &pcbinfo->ipi_lbgrouphashbase[INP_PCBLBGROUP_PORTHASH(
- lport, pcbinfo->ipi_lbgrouphashmask)];
+ hdr = &pcbinfo->ipi_lbgrouphashbase[
+ INP_PCBPORTHASH(lport, pcbinfo->ipi_lbgrouphashmask)];
/*
* Order of socket selection:
diff --git a/freebsd/sys/netinet6/ip6_mroute.c b/freebsd/sys/netinet6/ip6_mroute.c
index c1f66028..9dee53b0 100644
--- a/freebsd/sys/netinet6/ip6_mroute.c
+++ b/freebsd/sys/netinet6/ip6_mroute.c
@@ -205,7 +205,8 @@ sysctl_mif6table(SYSCTL_HANDLER_ARGS)
struct mif6_sctl *out;
int error;
- out = malloc(sizeof(struct mif6_sctl) * MAXMIFS, M_TEMP, M_WAITOK);
+ out = malloc(sizeof(struct mif6_sctl) * MAXMIFS, M_TEMP,
+ M_WAITOK | M_ZERO);
for (int i = 0; i < MAXMIFS; i++) {
out[i].m6_flags = mif6table[i].m6_flags;
out[i].m6_rate_limit = mif6table[i].m6_rate_limit;
diff --git a/freebsd/sys/netinet6/ip6_output.c b/freebsd/sys/netinet6/ip6_output.c
index d3e530a6..0851bef8 100644
--- a/freebsd/sys/netinet6/ip6_output.c
+++ b/freebsd/sys/netinet6/ip6_output.c
@@ -2783,8 +2783,7 @@ ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt,
case IPV6_2292NEXTHOP:
case IPV6_NEXTHOP:
if (cred != NULL) {
- error = priv_check_cred(cred,
- PRIV_NETINET_SETHDROPTS, 0);
+ error = priv_check_cred(cred, PRIV_NETINET_SETHDROPTS);
if (error)
return (error);
}
@@ -2842,8 +2841,7 @@ ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt,
* overhead.
*/
if (cred != NULL) {
- error = priv_check_cred(cred,
- PRIV_NETINET_SETHDROPTS, 0);
+ error = priv_check_cred(cred, PRIV_NETINET_SETHDROPTS);
if (error)
return (error);
}
@@ -2879,8 +2877,7 @@ ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt,
int destlen;
if (cred != NULL) { /* XXX: see the comment for IPV6_HOPOPTS */
- error = priv_check_cred(cred,
- PRIV_NETINET_SETHDROPTS, 0);
+ error = priv_check_cred(cred, PRIV_NETINET_SETHDROPTS);
if (error)
return (error);
}
diff --git a/freebsd/sys/netipsec/ipsec_pcb.c b/freebsd/sys/netipsec/ipsec_pcb.c
index a8992d56..3b98ab65 100644
--- a/freebsd/sys/netipsec/ipsec_pcb.c
+++ b/freebsd/sys/netipsec/ipsec_pcb.c
@@ -298,7 +298,7 @@ ipsec_set_pcbpolicy(struct inpcb *inp, struct ucred *cred,
case IPSEC_POLICY_IPSEC:
case IPSEC_POLICY_BYPASS:
if (cred != NULL &&
- priv_check_cred(cred, PRIV_NETINET_IPSEC, 0) != 0)
+ priv_check_cred(cred, PRIV_NETINET_IPSEC) != 0)
return (EACCES);
/* Allocate new SP entry. */
newsp = key_msg2sp(xpl, len, &error);
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_private.h b/freebsd/sys/netpfil/ipfw/ip_fw_private.h
index c389e01a..7e966d0a 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_private.h
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_private.h
@@ -146,6 +146,9 @@ enum {
/*
* Function definitions.
*/
+int ipfw_chk(struct ip_fw_args *args);
+struct mbuf *ipfw_send_pkt(struct mbuf *, struct ipfw_flow_id *,
+ u_int32_t, u_int32_t, int);
/* attach (arg = 1) or detach (arg = 0) hooks */
int ipfw_attach_hooks(int);
@@ -156,6 +159,7 @@ void ipfw_nat_destroy(void);
/* In ip_fw_log.c */
struct ip;
struct ip_fw_chain;
+
void ipfw_bpf_init(int);
void ipfw_bpf_uninit(int);
void ipfw_bpf_mtap2(void *, u_int, struct mbuf *);
@@ -168,6 +172,7 @@ VNET_DECLARE(int, verbose_limit);
#define V_verbose_limit VNET(verbose_limit)
/* In ip_fw_dynamic.c */
+struct sockopt_data;
enum { /* result for matching dynamic rules */
MATCH_REVERSE = 0,
@@ -177,19 +182,6 @@ enum { /* result for matching dynamic rules */
};
/*
- * The lock for dynamic rules is only used once outside the file,
- * and only to release the result of lookup_dyn_rule().
- * Eventually we may implement it with a callback on the function.
- */
-struct ip_fw_chain;
-struct sockopt_data;
-int ipfw_is_dyn_rule(struct ip_fw *rule);
-void ipfw_expire_dyn_states(struct ip_fw_chain *, ipfw_range_tlv *);
-
-struct tcphdr;
-struct mbuf *ipfw_send_pkt(struct mbuf *, struct ipfw_flow_id *,
- u_int32_t, u_int32_t, int);
-/*
* Macro to determine that we need to do or redo dynamic state lookup.
* direction == MATCH_UNKNOWN means that this is first lookup, then we need
* to do lookup.
@@ -219,13 +211,17 @@ struct ip_fw *ipfw_dyn_lookup_state(const struct ip_fw_args *args,
const void *ulp, int pktlen, const ipfw_insn *cmd,
struct ipfw_dyn_info *info);
+int ipfw_is_dyn_rule(struct ip_fw *rule);
+void ipfw_expire_dyn_states(struct ip_fw_chain *, ipfw_range_tlv *);
void ipfw_get_dynamic(struct ip_fw_chain *chain, char **bp, const char *ep);
int ipfw_dump_states(struct ip_fw_chain *chain, struct sockopt_data *sd);
void ipfw_dyn_init(struct ip_fw_chain *); /* per-vnet initialization */
void ipfw_dyn_uninit(int); /* per-vnet deinitialization */
int ipfw_dyn_len(void);
-uint32_t ipfw_dyn_get_count(void);
+uint32_t ipfw_dyn_get_count(uint32_t *, int *);
+void ipfw_dyn_reset_eaction(struct ip_fw_chain *ch, uint16_t eaction_id,
+ uint16_t default_id, uint16_t instance_id);
/* common variables */
VNET_DECLARE(int, fw_one_pass);
@@ -280,7 +276,9 @@ struct ip_fw {
uint32_t id; /* rule id */
uint32_t cached_id; /* used by jump_fast */
uint32_t cached_pos; /* used by jump_fast */
+ uint32_t refcnt; /* number of references */
+ struct ip_fw *next; /* linked list of deleted rules */
ipfw_insn cmd[1]; /* storage for commands */
};
@@ -650,7 +648,6 @@ void ipfw_init_skipto_cache(struct ip_fw_chain *chain);
void ipfw_destroy_skipto_cache(struct ip_fw_chain *chain);
int ipfw_find_rule(struct ip_fw_chain *chain, uint32_t key, uint32_t id);
int ipfw_ctl3(struct sockopt *sopt);
-int ipfw_chk(struct ip_fw_args *args);
int ipfw_add_protected_rule(struct ip_fw_chain *chain, struct ip_fw *rule,
int locked);
void ipfw_reap_add(struct ip_fw_chain *chain, struct ip_fw **head,
@@ -659,7 +656,9 @@ void ipfw_reap_rules(struct ip_fw *head);
void ipfw_init_counters(void);
void ipfw_destroy_counters(void);
struct ip_fw *ipfw_alloc_rule(struct ip_fw_chain *chain, size_t rulesize);
+void ipfw_free_rule(struct ip_fw *rule);
int ipfw_match_range(struct ip_fw *rule, ipfw_range_tlv *rt);
+int ipfw_mark_object_kidx(uint32_t *bmask, uint16_t etlv, uint16_t kidx);
typedef int (sopt_handler_f)(struct ip_fw_chain *ch,
ip_fw3_opheader *op3, struct sockopt_data *sd);
@@ -758,6 +757,10 @@ uint16_t ipfw_add_eaction(struct ip_fw_chain *ch, ipfw_eaction_t handler,
int ipfw_del_eaction(struct ip_fw_chain *ch, uint16_t eaction_id);
int ipfw_run_eaction(struct ip_fw_chain *ch, struct ip_fw_args *args,
ipfw_insn *cmd, int *done);
+int ipfw_reset_eaction(struct ip_fw_chain *ch, struct ip_fw *rule,
+ uint16_t eaction_id, uint16_t default_id, uint16_t instance_id);
+int ipfw_reset_eaction_instance(struct ip_fw_chain *ch, uint16_t eaction_id,
+ uint16_t instance_id);
/* In ip_fw_table.c */
struct table_info;
diff --git a/freebsd/sys/netpfil/pf/if_pfsync.c b/freebsd/sys/netpfil/pf/if_pfsync.c
index 9612ac99..026d19a3 100644
--- a/freebsd/sys/netpfil/pf/if_pfsync.c
+++ b/freebsd/sys/netpfil/pf/if_pfsync.c
@@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/priv.h>
#include <sys/protosw.h>
+#include <sys/smp.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
@@ -108,6 +109,8 @@ __FBSDID("$FreeBSD$");
sizeof(struct pfsync_header) + \
sizeof(struct pfsync_subheader) )
+struct pfsync_bucket;
+
struct pfsync_pkt {
struct ip *ip;
struct in_addr src;
@@ -166,7 +169,7 @@ static struct pfsync_q pfsync_qs[] = {
};
static void pfsync_q_ins(struct pf_state *, int, bool);
-static void pfsync_q_del(struct pf_state *, bool);
+static void pfsync_q_del(struct pf_state *, bool, struct pfsync_bucket *);
static void pfsync_update_state(struct pf_state *);
@@ -185,6 +188,28 @@ struct pfsync_deferral {
struct mbuf *pd_m;
};
+struct pfsync_sofct;
+
+struct pfsync_bucket
+{
+ int b_id;
+ struct pfsync_softc *b_sc;
+ struct mtx b_mtx;
+ struct callout b_tmo;
+ int b_flags;
+#define PFSYNCF_BUCKET_PUSH 0x00000001
+
+ size_t b_len;
+ TAILQ_HEAD(, pf_state) b_qs[PFSYNC_S_COUNT];
+ TAILQ_HEAD(, pfsync_upd_req_item) b_upd_req_list;
+ TAILQ_HEAD(, pfsync_deferral) b_deferrals;
+ u_int b_deferred;
+ void *b_plus;
+ size_t b_pluslen;
+
+ struct ifaltq b_snd;
+};
+
struct pfsync_softc {
/* Configuration */
struct ifnet *sc_ifp;
@@ -194,20 +219,12 @@ struct pfsync_softc {
uint32_t sc_flags;
#define PFSYNCF_OK 0x00000001
#define PFSYNCF_DEFER 0x00000002
-#define PFSYNCF_PUSH 0x00000004
uint8_t sc_maxupdates;
struct ip sc_template;
- struct callout sc_tmo;
struct mtx sc_mtx;
/* Queued data */
- size_t sc_len;
- TAILQ_HEAD(, pf_state) sc_qs[PFSYNC_S_COUNT];
- TAILQ_HEAD(, pfsync_upd_req_item) sc_upd_req_list;
- TAILQ_HEAD(, pfsync_deferral) sc_deferrals;
- u_int sc_deferred;
- void *sc_plus;
- size_t sc_pluslen;
+ struct pfsync_bucket *sc_buckets;
/* Bulk update info */
struct mtx sc_bulk_mtx;
@@ -225,6 +242,10 @@ struct pfsync_softc {
#define PFSYNC_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
#define PFSYNC_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
+#define PFSYNC_BUCKET_LOCK(b) mtx_lock(&(b)->b_mtx)
+#define PFSYNC_BUCKET_UNLOCK(b) mtx_unlock(&(b)->b_mtx)
+#define PFSYNC_BUCKET_LOCK_ASSERT(b) mtx_assert(&(b)->b_mtx, MA_OWNED)
+
#define PFSYNC_BLOCK(sc) mtx_lock(&(sc)->sc_bulk_mtx)
#define PFSYNC_BUNLOCK(sc) mtx_unlock(&(sc)->sc_bulk_mtx)
#define PFSYNC_BLOCK_ASSERT(sc) mtx_assert(&(sc)->sc_bulk_mtx, MA_OWNED)
@@ -241,7 +262,8 @@ VNET_DEFINE_STATIC(int, pfsync_carp_adj) = CARP_MAXSKEW;
#define V_pfsync_carp_adj VNET(pfsync_carp_adj)
static void pfsync_timeout(void *);
-static void pfsync_push(struct pfsync_softc *);
+static void pfsync_push(struct pfsync_bucket *);
+static void pfsync_push_all(struct pfsync_softc *);
static void pfsyncintr(void *);
static int pfsync_multicast_setup(struct pfsync_softc *, struct ifnet *,
void *);
@@ -251,12 +273,16 @@ static void pfsync_pointers_uninit(void);
static int pfsync_init(void);
static void pfsync_uninit(void);
+static unsigned long pfsync_buckets;
+
SYSCTL_NODE(_net, OID_AUTO, pfsync, CTLFLAG_RW, 0, "PFSYNC");
SYSCTL_STRUCT(_net_pfsync, OID_AUTO, stats, CTLFLAG_VNET | CTLFLAG_RW,
&VNET_NAME(pfsyncstats), pfsyncstats,
"PFSYNC statistics (struct pfsyncstats, net/if_pfsync.h)");
SYSCTL_INT(_net_pfsync, OID_AUTO, carp_demotion_factor, CTLFLAG_RW,
&VNET_NAME(pfsync_carp_adj), 0, "pfsync's CARP demotion factor adjustment");
+SYSCTL_ULONG(_net_pfsync, OID_AUTO, pfsync_buckets, CTLFLAG_RDTUN,
+ &pfsync_buckets, 0, "Number of pfsync hash buckets");
static int pfsync_clone_create(struct if_clone *, int, caddr_t);
static void pfsync_clone_destroy(struct ifnet *);
@@ -272,10 +298,10 @@ static void pfsync_undefer_state(struct pf_state *, int);
static void pfsync_defer_tmo(void *);
static void pfsync_request_update(u_int32_t, u_int64_t);
-static void pfsync_update_state_req(struct pf_state *);
+static bool pfsync_update_state_req(struct pf_state *);
static void pfsync_drop(struct pfsync_softc *);
-static void pfsync_sendout(int);
+static void pfsync_sendout(int, int);
static void pfsync_send_plus(void *, size_t);
static void pfsync_bulk_start(void);
@@ -287,6 +313,9 @@ static void pfsync_detach_ifnet(struct ifnet *);
#ifdef IPSEC
static void pfsync_update_net_tdb(struct pfsync_tdb *);
#endif
+static struct pfsync_bucket *pfsync_get_bucket(struct pfsync_softc *,
+ struct pf_state *);
+
#define PFSYNC_MAX_BULKTRIES 12
@@ -298,21 +327,16 @@ pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param)
{
struct pfsync_softc *sc;
struct ifnet *ifp;
- int q;
+ struct pfsync_bucket *b;
+ int c, q;
if (unit != 0)
return (EINVAL);
- sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO);
- sc->sc_flags |= PFSYNCF_OK;
-
- for (q = 0; q < PFSYNC_S_COUNT; q++)
- TAILQ_INIT(&sc->sc_qs[q]);
-
- TAILQ_INIT(&sc->sc_upd_req_list);
- TAILQ_INIT(&sc->sc_deferrals);
+ if (! pfsync_buckets)
+ pfsync_buckets = mp_ncpus * 2;
- sc->sc_len = PFSYNC_MINPKT;
+ sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO);
sc->sc_maxupdates = 128;
ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC);
@@ -325,12 +349,10 @@ pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param)
ifp->if_ioctl = pfsyncioctl;
ifp->if_output = pfsyncoutput;
ifp->if_type = IFT_PFSYNC;
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
ifp->if_hdrlen = sizeof(struct pfsync_header);
ifp->if_mtu = ETHERMTU;
mtx_init(&sc->sc_mtx, pfsyncname, NULL, MTX_DEF);
mtx_init(&sc->sc_bulk_mtx, "pfsync bulk", NULL, MTX_DEF);
- callout_init(&sc->sc_tmo, 1);
callout_init_mtx(&sc->sc_bulk_tmo, &sc->sc_bulk_mtx, 0);
callout_init_mtx(&sc->sc_bulkfail_tmo, &sc->sc_bulk_mtx, 0);
@@ -338,6 +360,27 @@ pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param)
bpfattach(ifp, DLT_PFSYNC, PFSYNC_HDRLEN);
+ sc->sc_buckets = mallocarray(pfsync_buckets, sizeof(*sc->sc_buckets),
+ M_PFSYNC, M_ZERO | M_WAITOK);
+ for (c = 0; c < pfsync_buckets; c++) {
+ b = &sc->sc_buckets[c];
+ mtx_init(&b->b_mtx, pfsyncname, NULL, MTX_DEF);
+
+ b->b_id = c;
+ b->b_sc = sc;
+ b->b_len = PFSYNC_MINPKT;
+
+ for (q = 0; q < PFSYNC_S_COUNT; q++)
+ TAILQ_INIT(&b->b_qs[q]);
+
+ TAILQ_INIT(&b->b_upd_req_list);
+ TAILQ_INIT(&b->b_deferrals);
+
+ callout_init(&b->b_tmo, 1);
+
+ b->b_snd.ifq_maxlen = ifqmaxlen;
+ }
+
V_pfsyncif = sc;
return (0);
@@ -347,29 +390,36 @@ static void
pfsync_clone_destroy(struct ifnet *ifp)
{
struct pfsync_softc *sc = ifp->if_softc;
+ struct pfsync_bucket *b;
+ int c;
- /*
- * At this stage, everything should have already been
- * cleared by pfsync_uninit(), and we have only to
- * drain callouts.
- */
- while (sc->sc_deferred > 0) {
- struct pfsync_deferral *pd = TAILQ_FIRST(&sc->sc_deferrals);
-
- TAILQ_REMOVE(&sc->sc_deferrals, pd, pd_entry);
- sc->sc_deferred--;
- if (callout_stop(&pd->pd_tmo) > 0) {
- pf_release_state(pd->pd_st);
- m_freem(pd->pd_m);
- free(pd, M_PFSYNC);
- } else {
- pd->pd_refs++;
- callout_drain(&pd->pd_tmo);
- free(pd, M_PFSYNC);
+ for (c = 0; c < pfsync_buckets; c++) {
+ b = &sc->sc_buckets[c];
+ /*
+ * At this stage, everything should have already been
+ * cleared by pfsync_uninit(), and we have only to
+ * drain callouts.
+ */
+ while (b->b_deferred > 0) {
+ struct pfsync_deferral *pd =
+ TAILQ_FIRST(&b->b_deferrals);
+
+ TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry);
+ b->b_deferred--;
+ if (callout_stop(&pd->pd_tmo) > 0) {
+ pf_release_state(pd->pd_st);
+ m_freem(pd->pd_m);
+ free(pd, M_PFSYNC);
+ } else {
+ pd->pd_refs++;
+ callout_drain(&pd->pd_tmo);
+ free(pd, M_PFSYNC);
+ }
}
+
+ callout_drain(&b->b_tmo);
}
- callout_drain(&sc->sc_tmo);
callout_drain(&sc->sc_bulkfail_tmo);
callout_drain(&sc->sc_bulk_tmo);
@@ -385,6 +435,8 @@ pfsync_clone_destroy(struct ifnet *ifp)
pfsync_multicast_cleanup(sc);
mtx_destroy(&sc->sc_mtx);
mtx_destroy(&sc->sc_bulk_mtx);
+
+ free(sc->sc_buckets, M_PFSYNC);
free(sc, M_PFSYNC);
V_pfsyncif = NULL;
@@ -548,7 +600,7 @@ pfsync_state_import(struct pfsync_state *sp, u_int8_t flags)
st->state_flags &= ~PFSTATE_NOSYNC;
if (st->state_flags & PFSTATE_ACK) {
pfsync_q_ins(st, PFSYNC_S_IACK, true);
- pfsync_push(sc);
+ pfsync_push_all(sc);
}
}
st->state_flags &= ~PFSTATE_ACK;
@@ -787,9 +839,7 @@ pfsync_in_iack(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
continue;
if (st->state_flags & PFSTATE_ACK) {
- PFSYNC_LOCK(V_pfsyncif);
pfsync_undefer_state(st, 0);
- PFSYNC_UNLOCK(V_pfsyncif);
}
PF_STATE_UNLOCK(st);
}
@@ -878,9 +928,7 @@ pfsync_in_upd(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
}
if (st->state_flags & PFSTATE_ACK) {
- PFSYNC_LOCK(sc);
pfsync_undefer_state(st, 1);
- PFSYNC_UNLOCK(sc);
}
if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP)
@@ -914,9 +962,7 @@ pfsync_in_upd(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
pfsync_update_state(st);
PF_STATE_UNLOCK(st);
- PFSYNC_LOCK(sc);
- pfsync_push(sc);
- PFSYNC_UNLOCK(sc);
+ pfsync_push_all(sc);
continue;
}
PF_STATE_UNLOCK(st);
@@ -962,16 +1008,14 @@ pfsync_in_upd_c(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
st = pf_find_state_byid(up->id, up->creatorid);
if (st == NULL) {
/* We don't have this state. Ask for it. */
- PFSYNC_LOCK(sc);
+ PFSYNC_BUCKET_LOCK(&sc->sc_buckets[0]);
pfsync_request_update(up->creatorid, up->id);
- PFSYNC_UNLOCK(sc);
+ PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[0]);
continue;
}
if (st->state_flags & PFSTATE_ACK) {
- PFSYNC_LOCK(sc);
pfsync_undefer_state(st, 1);
- PFSYNC_UNLOCK(sc);
}
if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP)
@@ -1005,9 +1049,7 @@ pfsync_in_upd_c(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
pfsync_update_state(st);
PF_STATE_UNLOCK(st);
- PFSYNC_LOCK(sc);
- pfsync_push(sc);
- PFSYNC_UNLOCK(sc);
+ pfsync_push_all(sc);
continue;
}
PF_STATE_UNLOCK(st);
@@ -1285,6 +1327,7 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
struct ifreq *ifr = (struct ifreq *)data;
struct pfsyncreq pfsyncr;
int error;
+ int c;
switch (cmd) {
case SIOCSIFFLAGS:
@@ -1305,10 +1348,12 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ifr->ifr_mtu > sc->sc_sync_if->if_mtu)
return (EINVAL);
if (ifr->ifr_mtu < ifp->if_mtu) {
- PFSYNC_LOCK(sc);
- if (sc->sc_len > PFSYNC_MINPKT)
- pfsync_sendout(1);
- PFSYNC_UNLOCK(sc);
+ for (c = 0; c < pfsync_buckets; c++) {
+ PFSYNC_BUCKET_LOCK(&sc->sc_buckets[c]);
+ if (sc->sc_buckets[c].b_len > PFSYNC_MINPKT)
+ pfsync_sendout(1, c);
+ PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[c]);
+ }
}
ifp->if_mtu = ifr->ifr_mtu;
break;
@@ -1381,12 +1426,16 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
}
- if (sc->sc_len > PFSYNC_MINPKT &&
- (sifp->if_mtu < sc->sc_ifp->if_mtu ||
- (sc->sc_sync_if != NULL &&
- sifp->if_mtu < sc->sc_sync_if->if_mtu) ||
- sifp->if_mtu < MCLBYTES - sizeof(struct ip)))
- pfsync_sendout(1);
+ for (c = 0; c < pfsync_buckets; c++) {
+ PFSYNC_BUCKET_LOCK(&sc->sc_buckets[c]);
+ if (sc->sc_buckets[c].b_len > PFSYNC_MINPKT &&
+ (sifp->if_mtu < sc->sc_ifp->if_mtu ||
+ (sc->sc_sync_if != NULL &&
+ sifp->if_mtu < sc->sc_sync_if->if_mtu) ||
+ sifp->if_mtu < MCLBYTES - sizeof(struct ip)))
+ pfsync_sendout(1, c);
+ PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[c]);
+ }
if (imo->imo_membership)
pfsync_multicast_cleanup(sc);
@@ -1423,8 +1472,10 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
sc->sc_flags &= ~PFSYNCF_OK;
if (V_pf_status.debug >= PF_DEBUG_MISC)
printf("pfsync: requesting bulk update\n");
- pfsync_request_update(0, 0);
PFSYNC_UNLOCK(sc);
+ PFSYNC_BUCKET_LOCK(&sc->sc_buckets[0]);
+ pfsync_request_update(0, 0);
+ PFSYNC_BUCKET_UNLOCK(&sc->sc_buckets[0]);
PFSYNC_BLOCK(sc);
sc->sc_ureq_sent = time_uptime;
callout_reset(&sc->sc_bulkfail_tmo, 5 * hz, pfsync_bulk_fail,
@@ -1485,33 +1536,37 @@ pfsync_drop(struct pfsync_softc *sc)
{
struct pf_state *st, *next;
struct pfsync_upd_req_item *ur;
- int q;
+ struct pfsync_bucket *b;
+ int c, q;
- for (q = 0; q < PFSYNC_S_COUNT; q++) {
- if (TAILQ_EMPTY(&sc->sc_qs[q]))
- continue;
+ for (c = 0; c < pfsync_buckets; c++) {
+ b = &sc->sc_buckets[c];
+ for (q = 0; q < PFSYNC_S_COUNT; q++) {
+ if (TAILQ_EMPTY(&b->b_qs[q]))
+ continue;
- TAILQ_FOREACH_SAFE(st, &sc->sc_qs[q], sync_list, next) {
- KASSERT(st->sync_state == q,
- ("%s: st->sync_state == q",
- __func__));
- st->sync_state = PFSYNC_S_NONE;
- pf_release_state(st);
+ TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, next) {
+ KASSERT(st->sync_state == q,
+ ("%s: st->sync_state == q",
+ __func__));
+ st->sync_state = PFSYNC_S_NONE;
+ pf_release_state(st);
+ }
+ TAILQ_INIT(&b->b_qs[q]);
}
- TAILQ_INIT(&sc->sc_qs[q]);
- }
- while ((ur = TAILQ_FIRST(&sc->sc_upd_req_list)) != NULL) {
- TAILQ_REMOVE(&sc->sc_upd_req_list, ur, ur_entry);
- free(ur, M_PFSYNC);
- }
+ while ((ur = TAILQ_FIRST(&b->b_upd_req_list)) != NULL) {
+ TAILQ_REMOVE(&b->b_upd_req_list, ur, ur_entry);
+ free(ur, M_PFSYNC);
+ }
- sc->sc_plus = NULL;
- sc->sc_len = PFSYNC_MINPKT;
+ b->b_len = PFSYNC_MINPKT;
+ b->b_plus = NULL;
+ }
}
static void
-pfsync_sendout(int schedswi)
+pfsync_sendout(int schedswi, int c)
{
struct pfsync_softc *sc = V_pfsyncif;
struct ifnet *ifp = sc->sc_ifp;
@@ -1521,27 +1576,28 @@ pfsync_sendout(int schedswi)
struct pfsync_subheader *subh;
struct pf_state *st, *st_next;
struct pfsync_upd_req_item *ur;
+ struct pfsync_bucket *b = &sc->sc_buckets[c];
int offset;
int q, count = 0;
KASSERT(sc != NULL, ("%s: null sc", __func__));
- KASSERT(sc->sc_len > PFSYNC_MINPKT,
- ("%s: sc_len %zu", __func__, sc->sc_len));
- PFSYNC_LOCK_ASSERT(sc);
+ KASSERT(b->b_len > PFSYNC_MINPKT,
+ ("%s: sc_len %zu", __func__, b->b_len));
+ PFSYNC_BUCKET_LOCK_ASSERT(b);
if (ifp->if_bpf == NULL && sc->sc_sync_if == NULL) {
pfsync_drop(sc);
return;
}
- m = m_get2(max_linkhdr + sc->sc_len, M_NOWAIT, MT_DATA, M_PKTHDR);
+ m = m_get2(max_linkhdr + b->b_len, M_NOWAIT, MT_DATA, M_PKTHDR);
if (m == NULL) {
if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1);
V_pfsyncstats.pfsyncs_onomem++;
return;
}
m->m_data += max_linkhdr;
- m->m_len = m->m_pkthdr.len = sc->sc_len;
+ m->m_len = m->m_pkthdr.len = b->b_len;
/* build the ip header */
ip = (struct ip *)m->m_data;
@@ -1557,19 +1613,19 @@ pfsync_sendout(int schedswi)
offset += sizeof(*ph);
ph->version = PFSYNC_VERSION;
- ph->len = htons(sc->sc_len - sizeof(*ip));
+ ph->len = htons(b->b_len - sizeof(*ip));
bcopy(V_pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH);
/* walk the queues */
for (q = 0; q < PFSYNC_S_COUNT; q++) {
- if (TAILQ_EMPTY(&sc->sc_qs[q]))
+ if (TAILQ_EMPTY(&b->b_qs[q]))
continue;
subh = (struct pfsync_subheader *)(m->m_data + offset);
offset += sizeof(*subh);
count = 0;
- TAILQ_FOREACH_SAFE(st, &sc->sc_qs[q], sync_list, st_next) {
+ TAILQ_FOREACH_SAFE(st, &b->b_qs[q], sync_list, st_next) {
KASSERT(st->sync_state == q,
("%s: st->sync_state == q",
__func__));
@@ -1583,7 +1639,7 @@ pfsync_sendout(int schedswi)
pf_release_state(st);
count++;
}
- TAILQ_INIT(&sc->sc_qs[q]);
+ TAILQ_INIT(&b->b_qs[q]);
bzero(subh, sizeof(*subh));
subh->action = pfsync_qs[q].action;
@@ -1591,13 +1647,13 @@ pfsync_sendout(int schedswi)
V_pfsyncstats.pfsyncs_oacts[pfsync_qs[q].action] += count;
}
- if (!TAILQ_EMPTY(&sc->sc_upd_req_list)) {
+ if (!TAILQ_EMPTY(&b->b_upd_req_list)) {
subh = (struct pfsync_subheader *)(m->m_data + offset);
offset += sizeof(*subh);
count = 0;
- while ((ur = TAILQ_FIRST(&sc->sc_upd_req_list)) != NULL) {
- TAILQ_REMOVE(&sc->sc_upd_req_list, ur, ur_entry);
+ while ((ur = TAILQ_FIRST(&b->b_upd_req_list)) != NULL) {
+ TAILQ_REMOVE(&b->b_upd_req_list, ur, ur_entry);
bcopy(&ur->ur_msg, m->m_data + offset,
sizeof(ur->ur_msg));
@@ -1613,11 +1669,11 @@ pfsync_sendout(int schedswi)
}
/* has someone built a custom region for us to add? */
- if (sc->sc_plus != NULL) {
- bcopy(sc->sc_plus, m->m_data + offset, sc->sc_pluslen);
- offset += sc->sc_pluslen;
+ if (b->b_plus != NULL) {
+ bcopy(b->b_plus, m->m_data + offset, b->b_pluslen);
+ offset += b->b_pluslen;
- sc->sc_plus = NULL;
+ b->b_plus = NULL;
}
subh = (struct pfsync_subheader *)(m->m_data + offset);
@@ -1631,24 +1687,24 @@ pfsync_sendout(int schedswi)
/* we're done, let's put it on the wire */
if (ifp->if_bpf) {
m->m_data += sizeof(*ip);
- m->m_len = m->m_pkthdr.len = sc->sc_len - sizeof(*ip);
+ m->m_len = m->m_pkthdr.len = b->b_len - sizeof(*ip);
BPF_MTAP(ifp, m);
m->m_data -= sizeof(*ip);
- m->m_len = m->m_pkthdr.len = sc->sc_len;
+ m->m_len = m->m_pkthdr.len = b->b_len;
}
if (sc->sc_sync_if == NULL) {
- sc->sc_len = PFSYNC_MINPKT;
+ b->b_len = PFSYNC_MINPKT;
m_freem(m);
return;
}
if_inc_counter(sc->sc_ifp, IFCOUNTER_OPACKETS, 1);
if_inc_counter(sc->sc_ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);
- sc->sc_len = PFSYNC_MINPKT;
+ b->b_len = PFSYNC_MINPKT;
- if (!_IF_QFULL(&sc->sc_ifp->if_snd))
- _IF_ENQUEUE(&sc->sc_ifp->if_snd, m);
+ if (!_IF_QFULL(&b->b_snd))
+ _IF_ENQUEUE(&b->b_snd, m);
else {
m_freem(m);
if_inc_counter(sc->sc_ifp, IFCOUNTER_OQDROPS, 1);
@@ -1661,6 +1717,7 @@ static void
pfsync_insert_state(struct pf_state *st)
{
struct pfsync_softc *sc = V_pfsyncif;
+ struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
if (st->state_flags & PFSTATE_NOSYNC)
return;
@@ -1674,12 +1731,12 @@ pfsync_insert_state(struct pf_state *st)
KASSERT(st->sync_state == PFSYNC_S_NONE,
("%s: st->sync_state %u", __func__, st->sync_state));
- PFSYNC_LOCK(sc);
- if (sc->sc_len == PFSYNC_MINPKT)
- callout_reset(&sc->sc_tmo, 1 * hz, pfsync_timeout, V_pfsyncif);
+ PFSYNC_BUCKET_LOCK(b);
+ if (b->b_len == PFSYNC_MINPKT)
+ callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b);
pfsync_q_ins(st, PFSYNC_S_INS, true);
- PFSYNC_UNLOCK(sc);
+ PFSYNC_BUCKET_UNLOCK(b);
st->sync_updates = 0;
}
@@ -1689,6 +1746,7 @@ pfsync_defer(struct pf_state *st, struct mbuf *m)
{
struct pfsync_softc *sc = V_pfsyncif;
struct pfsync_deferral *pd;
+ struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
if (m->m_flags & (M_BCAST|M_MCAST))
return (0);
@@ -1701,13 +1759,13 @@ pfsync_defer(struct pf_state *st, struct mbuf *m)
return (0);
}
- if (sc->sc_deferred >= 128)
- pfsync_undefer(TAILQ_FIRST(&sc->sc_deferrals), 0);
+ if (b->b_deferred >= 128)
+ pfsync_undefer(TAILQ_FIRST(&b->b_deferrals), 0);
pd = malloc(sizeof(*pd), M_PFSYNC, M_NOWAIT);
if (pd == NULL)
return (0);
- sc->sc_deferred++;
+ b->b_deferred++;
m->m_flags |= M_SKIP_FIREWALL;
st->state_flags |= PFSTATE_ACK;
@@ -1718,11 +1776,11 @@ pfsync_defer(struct pf_state *st, struct mbuf *m)
pf_ref_state(st);
pd->pd_m = m;
- TAILQ_INSERT_TAIL(&sc->sc_deferrals, pd, pd_entry);
- callout_init_mtx(&pd->pd_tmo, &sc->sc_mtx, CALLOUT_RETURNUNLOCKED);
+ TAILQ_INSERT_TAIL(&b->b_deferrals, pd, pd_entry);
+ callout_init_mtx(&pd->pd_tmo, &b->b_mtx, CALLOUT_RETURNUNLOCKED);
callout_reset(&pd->pd_tmo, 10, pfsync_defer_tmo, pd);
- pfsync_push(sc);
+ pfsync_push(b);
return (1);
}
@@ -1733,11 +1791,12 @@ pfsync_undefer(struct pfsync_deferral *pd, int drop)
struct pfsync_softc *sc = pd->pd_sc;
struct mbuf *m = pd->pd_m;
struct pf_state *st = pd->pd_st;
+ struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
- PFSYNC_LOCK_ASSERT(sc);
+ PFSYNC_BUCKET_LOCK_ASSERT(b);
- TAILQ_REMOVE(&sc->sc_deferrals, pd, pd_entry);
- sc->sc_deferred--;
+ TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry);
+ b->b_deferred--;
pd->pd_st->state_flags &= ~PFSTATE_ACK; /* XXX: locking! */
free(pd, M_PFSYNC);
pf_release_state(st);
@@ -1745,8 +1804,8 @@ pfsync_undefer(struct pfsync_deferral *pd, int drop)
if (drop)
m_freem(m);
else {
- _IF_ENQUEUE(&sc->sc_ifp->if_snd, m);
- pfsync_push(sc);
+ _IF_ENQUEUE(&b->b_snd, m);
+ pfsync_push(b);
}
}
@@ -1757,13 +1816,14 @@ pfsync_defer_tmo(void *arg)
struct pfsync_softc *sc = pd->pd_sc;
struct mbuf *m = pd->pd_m;
struct pf_state *st = pd->pd_st;
+ struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
- PFSYNC_LOCK_ASSERT(sc);
+ PFSYNC_BUCKET_LOCK_ASSERT(b);
CURVNET_SET(m->m_pkthdr.rcvif->if_vnet);
- TAILQ_REMOVE(&sc->sc_deferrals, pd, pd_entry);
- sc->sc_deferred--;
+ TAILQ_REMOVE(&b->b_deferrals, pd, pd_entry);
+ b->b_deferred--;
pd->pd_st->state_flags &= ~PFSTATE_ACK; /* XXX: locking! */
if (pd->pd_refs == 0)
free(pd, M_PFSYNC);
@@ -1781,40 +1841,52 @@ pfsync_undefer_state(struct pf_state *st, int drop)
{
struct pfsync_softc *sc = V_pfsyncif;
struct pfsync_deferral *pd;
+ struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
- PFSYNC_LOCK_ASSERT(sc);
+ PFSYNC_BUCKET_LOCK(b);
- TAILQ_FOREACH(pd, &sc->sc_deferrals, pd_entry) {
+ TAILQ_FOREACH(pd, &b->b_deferrals, pd_entry) {
if (pd->pd_st == st) {
if (callout_stop(&pd->pd_tmo) > 0)
pfsync_undefer(pd, drop);
+
+ PFSYNC_BUCKET_UNLOCK(b);
return;
}
}
+ PFSYNC_BUCKET_UNLOCK(b);
panic("%s: unable to find deferred state", __func__);
}
+static struct pfsync_bucket*
+pfsync_get_bucket(struct pfsync_softc *sc, struct pf_state *st)
+{
+ int c = PF_IDHASH(st) % pfsync_buckets;
+ return &sc->sc_buckets[c];
+}
+
static void
pfsync_update_state(struct pf_state *st)
{
struct pfsync_softc *sc = V_pfsyncif;
bool sync = false, ref = true;
+ struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
PF_STATE_LOCK_ASSERT(st);
- PFSYNC_LOCK(sc);
+ PFSYNC_BUCKET_LOCK(b);
if (st->state_flags & PFSTATE_ACK)
pfsync_undefer_state(st, 0);
if (st->state_flags & PFSTATE_NOSYNC) {
if (st->sync_state != PFSYNC_S_NONE)
- pfsync_q_del(st, true);
- PFSYNC_UNLOCK(sc);
+ pfsync_q_del(st, true, b);
+ PFSYNC_BUCKET_UNLOCK(b);
return;
}
- if (sc->sc_len == PFSYNC_MINPKT)
- callout_reset(&sc->sc_tmo, 1 * hz, pfsync_timeout, V_pfsyncif);
+ if (b->b_len == PFSYNC_MINPKT)
+ callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b);
switch (st->sync_state) {
case PFSYNC_S_UPD_C:
@@ -1830,7 +1902,7 @@ pfsync_update_state(struct pf_state *st)
break;
case PFSYNC_S_IACK:
- pfsync_q_del(st, false);
+ pfsync_q_del(st, false, b);
ref = false;
/* FALLTHROUGH */
@@ -1844,26 +1916,27 @@ pfsync_update_state(struct pf_state *st)
}
if (sync || (time_uptime - st->pfsync_time) < 2)
- pfsync_push(sc);
+ pfsync_push(b);
- PFSYNC_UNLOCK(sc);
+ PFSYNC_BUCKET_UNLOCK(b);
}
static void
pfsync_request_update(u_int32_t creatorid, u_int64_t id)
{
struct pfsync_softc *sc = V_pfsyncif;
+ struct pfsync_bucket *b = &sc->sc_buckets[0];
struct pfsync_upd_req_item *item;
size_t nlen = sizeof(struct pfsync_upd_req);
- PFSYNC_LOCK_ASSERT(sc);
+ PFSYNC_BUCKET_LOCK_ASSERT(b);
/*
* This code does a bit to prevent multiple update requests for the
* same state being generated. It searches current subheader queue,
* but it doesn't lookup into queue of already packed datagrams.
*/
- TAILQ_FOREACH(item, &sc->sc_upd_req_list, ur_entry)
+ TAILQ_FOREACH(item, &b->b_upd_req_list, ur_entry)
if (item->ur_msg.id == id &&
item->ur_msg.creatorid == creatorid)
return;
@@ -1875,46 +1948,47 @@ pfsync_request_update(u_int32_t creatorid, u_int64_t id)
item->ur_msg.id = id;
item->ur_msg.creatorid = creatorid;
- if (TAILQ_EMPTY(&sc->sc_upd_req_list))
+ if (TAILQ_EMPTY(&b->b_upd_req_list))
nlen += sizeof(struct pfsync_subheader);
- if (sc->sc_len + nlen > sc->sc_ifp->if_mtu) {
- pfsync_sendout(1);
+ if (b->b_len + nlen > sc->sc_ifp->if_mtu) {
+ pfsync_sendout(1, 0);
nlen = sizeof(struct pfsync_subheader) +
sizeof(struct pfsync_upd_req);
}
- TAILQ_INSERT_TAIL(&sc->sc_upd_req_list, item, ur_entry);
- sc->sc_len += nlen;
+ TAILQ_INSERT_TAIL(&b->b_upd_req_list, item, ur_entry);
+ b->b_len += nlen;
}
-static void
+static bool
pfsync_update_state_req(struct pf_state *st)
{
struct pfsync_softc *sc = V_pfsyncif;
- bool ref = true;
+ bool ref = true, full = false;
+ struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
PF_STATE_LOCK_ASSERT(st);
- PFSYNC_LOCK(sc);
+ PFSYNC_BUCKET_LOCK(b);
if (st->state_flags & PFSTATE_NOSYNC) {
if (st->sync_state != PFSYNC_S_NONE)
- pfsync_q_del(st, true);
- PFSYNC_UNLOCK(sc);
- return;
+ pfsync_q_del(st, true, b);
+ PFSYNC_BUCKET_UNLOCK(b);
+ return (full);
}
switch (st->sync_state) {
case PFSYNC_S_UPD_C:
case PFSYNC_S_IACK:
- pfsync_q_del(st, false);
+ pfsync_q_del(st, false, b);
ref = false;
/* FALLTHROUGH */
case PFSYNC_S_NONE:
pfsync_q_ins(st, PFSYNC_S_UPD, ref);
- pfsync_push(sc);
+ pfsync_push(b);
break;
case PFSYNC_S_INS:
@@ -1927,38 +2001,44 @@ pfsync_update_state_req(struct pf_state *st)
panic("%s: unexpected sync state %d", __func__, st->sync_state);
}
- PFSYNC_UNLOCK(sc);
+ if ((sc->sc_ifp->if_mtu - b->b_len) < sizeof(struct pfsync_state))
+ full = true;
+
+ PFSYNC_BUCKET_UNLOCK(b);
+
+ return (full);
}
static void
pfsync_delete_state(struct pf_state *st)
{
struct pfsync_softc *sc = V_pfsyncif;
+ struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
bool ref = true;
- PFSYNC_LOCK(sc);
+ PFSYNC_BUCKET_LOCK(b);
if (st->state_flags & PFSTATE_ACK)
pfsync_undefer_state(st, 1);
if (st->state_flags & PFSTATE_NOSYNC) {
if (st->sync_state != PFSYNC_S_NONE)
- pfsync_q_del(st, true);
- PFSYNC_UNLOCK(sc);
+ pfsync_q_del(st, true, b);
+ PFSYNC_BUCKET_UNLOCK(b);
return;
}
- if (sc->sc_len == PFSYNC_MINPKT)
- callout_reset(&sc->sc_tmo, 1 * hz, pfsync_timeout, V_pfsyncif);
+ if (b->b_len == PFSYNC_MINPKT)
+ callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b);
switch (st->sync_state) {
case PFSYNC_S_INS:
/* We never got to tell the world so just forget about it. */
- pfsync_q_del(st, true);
+ pfsync_q_del(st, true, b);
break;
case PFSYNC_S_UPD_C:
case PFSYNC_S_UPD:
case PFSYNC_S_IACK:
- pfsync_q_del(st, false);
+ pfsync_q_del(st, false, b);
ref = false;
/* FALLTHROUGH */
@@ -1970,13 +2050,12 @@ pfsync_delete_state(struct pf_state *st)
panic("%s: unexpected sync state %d", __func__, st->sync_state);
}
- PFSYNC_UNLOCK(sc);
+ PFSYNC_BUCKET_UNLOCK(b);
}
static void
pfsync_clear_states(u_int32_t creatorid, const char *ifname)
{
- struct pfsync_softc *sc = V_pfsyncif;
struct {
struct pfsync_subheader subh;
struct pfsync_clr clr;
@@ -1991,9 +2070,7 @@ pfsync_clear_states(u_int32_t creatorid, const char *ifname)
strlcpy(r.clr.ifname, ifname, sizeof(r.clr.ifname));
r.clr.creatorid = creatorid;
- PFSYNC_LOCK(sc);
pfsync_send_plus(&r, sizeof(r));
- PFSYNC_UNLOCK(sc);
}
static void
@@ -2001,48 +2078,48 @@ pfsync_q_ins(struct pf_state *st, int q, bool ref)
{
struct pfsync_softc *sc = V_pfsyncif;
size_t nlen = pfsync_qs[q].len;
+ struct pfsync_bucket *b = pfsync_get_bucket(sc, st);
- PFSYNC_LOCK_ASSERT(sc);
+ PFSYNC_BUCKET_LOCK_ASSERT(b);
KASSERT(st->sync_state == PFSYNC_S_NONE,
("%s: st->sync_state %u", __func__, st->sync_state));
- KASSERT(sc->sc_len >= PFSYNC_MINPKT, ("pfsync pkt len is too low %zu",
- sc->sc_len));
+ KASSERT(b->b_len >= PFSYNC_MINPKT, ("pfsync pkt len is too low %zu",
+ b->b_len));
- if (TAILQ_EMPTY(&sc->sc_qs[q]))
+ if (TAILQ_EMPTY(&b->b_qs[q]))
nlen += sizeof(struct pfsync_subheader);
- if (sc->sc_len + nlen > sc->sc_ifp->if_mtu) {
- pfsync_sendout(1);
+ if (b->b_len + nlen > sc->sc_ifp->if_mtu) {
+ pfsync_sendout(1, b->b_id);
nlen = sizeof(struct pfsync_subheader) + pfsync_qs[q].len;
}
- sc->sc_len += nlen;
- TAILQ_INSERT_TAIL(&sc->sc_qs[q], st, sync_list);
+ b->b_len += nlen;
+ TAILQ_INSERT_TAIL(&b->b_qs[q], st, sync_list);
st->sync_state = q;
if (ref)
pf_ref_state(st);
}
static void
-pfsync_q_del(struct pf_state *st, bool unref)
+pfsync_q_del(struct pf_state *st, bool unref, struct pfsync_bucket *b)
{
- struct pfsync_softc *sc = V_pfsyncif;
int q = st->sync_state;
- PFSYNC_LOCK_ASSERT(sc);
+ PFSYNC_BUCKET_LOCK_ASSERT(b);
KASSERT(st->sync_state != PFSYNC_S_NONE,
("%s: st->sync_state != PFSYNC_S_NONE", __func__));
- sc->sc_len -= pfsync_qs[q].len;
- TAILQ_REMOVE(&sc->sc_qs[q], st, sync_list);
+ b->b_len -= pfsync_qs[q].len;
+ TAILQ_REMOVE(&b->b_qs[q], st, sync_list);
st->sync_state = PFSYNC_S_NONE;
if (unref)
pf_release_state(st);
- if (TAILQ_EMPTY(&sc->sc_qs[q]))
- sc->sc_len -= sizeof(struct pfsync_subheader);
+ if (TAILQ_EMPTY(&b->b_qs[q]))
+ b->b_len -= sizeof(struct pfsync_subheader);
}
static void
@@ -2096,23 +2173,19 @@ pfsync_bulk_update(void *arg)
}
for (; s; s = LIST_NEXT(s, entry)) {
-
- if (sent > 1 && (sc->sc_ifp->if_mtu - sc->sc_len) <
- sizeof(struct pfsync_state)) {
- /* We've filled a packet. */
- sc->sc_bulk_hashid = i;
- sc->sc_bulk_stateid = s->id;
- sc->sc_bulk_creatorid = s->creatorid;
- PF_HASHROW_UNLOCK(ih);
- callout_reset(&sc->sc_bulk_tmo, 1,
- pfsync_bulk_update, sc);
- goto full;
- }
-
if (s->sync_state == PFSYNC_S_NONE &&
s->timeout < PFTM_MAX &&
s->pfsync_time <= sc->sc_ureq_received) {
- pfsync_update_state_req(s);
+ if (pfsync_update_state_req(s)) {
+ /* We've filled a packet. */
+ sc->sc_bulk_hashid = i;
+ sc->sc_bulk_stateid = s->id;
+ sc->sc_bulk_creatorid = s->creatorid;
+ PF_HASHROW_UNLOCK(ih);
+ callout_reset(&sc->sc_bulk_tmo, 1,
+ pfsync_bulk_update, sc);
+ goto full;
+ }
sent++;
}
}
@@ -2121,7 +2194,6 @@ pfsync_bulk_update(void *arg)
/* We're done. */
pfsync_bulk_status(PFSYNC_BUS_END);
-
full:
CURVNET_RESTORE();
}
@@ -2146,15 +2218,14 @@ pfsync_bulk_status(u_int8_t status)
r.bus.endtime = htonl(time_uptime - sc->sc_ureq_received);
r.bus.status = status;
- PFSYNC_LOCK(sc);
pfsync_send_plus(&r, sizeof(r));
- PFSYNC_UNLOCK(sc);
}
static void
pfsync_bulk_fail(void *arg)
{
struct pfsync_softc *sc = arg;
+ struct pfsync_bucket *b = &sc->sc_buckets[0];
CURVNET_SET(sc->sc_ifp->if_vnet);
@@ -2164,9 +2235,9 @@ pfsync_bulk_fail(void *arg)
/* Try again */
callout_reset(&sc->sc_bulkfail_tmo, 5 * hz,
pfsync_bulk_fail, V_pfsyncif);
- PFSYNC_LOCK(sc);
+ PFSYNC_BUCKET_LOCK(b);
pfsync_request_update(0, 0);
- PFSYNC_UNLOCK(sc);
+ PFSYNC_BUCKET_UNLOCK(b);
} else {
/* Pretend like the transfer was ok. */
sc->sc_ureq_sent = 0;
@@ -2188,73 +2259,96 @@ static void
pfsync_send_plus(void *plus, size_t pluslen)
{
struct pfsync_softc *sc = V_pfsyncif;
+ struct pfsync_bucket *b = &sc->sc_buckets[0];
- PFSYNC_LOCK_ASSERT(sc);
+ PFSYNC_BUCKET_LOCK(b);
- if (sc->sc_len + pluslen > sc->sc_ifp->if_mtu)
- pfsync_sendout(1);
+ if (b->b_len + pluslen > sc->sc_ifp->if_mtu)
+ pfsync_sendout(1, b->b_id);
- sc->sc_plus = plus;
- sc->sc_len += (sc->sc_pluslen = pluslen);
+ b->b_plus = plus;
+ b->b_len += (b->b_pluslen = pluslen);
- pfsync_sendout(1);
+ pfsync_sendout(1, b->b_id);
+ PFSYNC_BUCKET_UNLOCK(b);
}
static void
pfsync_timeout(void *arg)
{
- struct pfsync_softc *sc = arg;
+ struct pfsync_bucket *b = arg;
- CURVNET_SET(sc->sc_ifp->if_vnet);
- PFSYNC_LOCK(sc);
- pfsync_push(sc);
- PFSYNC_UNLOCK(sc);
+ CURVNET_SET(b->b_sc->sc_ifp->if_vnet);
+ PFSYNC_BUCKET_LOCK(b);
+ pfsync_push(b);
+ PFSYNC_BUCKET_UNLOCK(b);
CURVNET_RESTORE();
}
static void
-pfsync_push(struct pfsync_softc *sc)
+pfsync_push(struct pfsync_bucket *b)
{
- PFSYNC_LOCK_ASSERT(sc);
+ PFSYNC_BUCKET_LOCK_ASSERT(b);
- sc->sc_flags |= PFSYNCF_PUSH;
+ b->b_flags |= PFSYNCF_BUCKET_PUSH;
swi_sched(V_pfsync_swi_cookie, 0);
}
static void
+pfsync_push_all(struct pfsync_softc *sc)
+{
+ int c;
+ struct pfsync_bucket *b;
+
+ for (c = 0; c < pfsync_buckets; c++) {
+ b = &sc->sc_buckets[c];
+
+ PFSYNC_BUCKET_LOCK(b);
+ pfsync_push(b);
+ PFSYNC_BUCKET_UNLOCK(b);
+ }
+}
+
+static void
pfsyncintr(void *arg)
{
struct pfsync_softc *sc = arg;
+ struct pfsync_bucket *b;
struct mbuf *m, *n;
+ int c;
CURVNET_SET(sc->sc_ifp->if_vnet);
- PFSYNC_LOCK(sc);
- if ((sc->sc_flags & PFSYNCF_PUSH) && sc->sc_len > PFSYNC_MINPKT) {
- pfsync_sendout(0);
- sc->sc_flags &= ~PFSYNCF_PUSH;
- }
- _IF_DEQUEUE_ALL(&sc->sc_ifp->if_snd, m);
- PFSYNC_UNLOCK(sc);
+ for (c = 0; c < pfsync_buckets; c++) {
+ b = &sc->sc_buckets[c];
- for (; m != NULL; m = n) {
+ PFSYNC_BUCKET_LOCK(b);
+ if ((b->b_flags & PFSYNCF_BUCKET_PUSH) && b->b_len > PFSYNC_MINPKT) {
+ pfsync_sendout(0, b->b_id);
+ b->b_flags &= ~PFSYNCF_BUCKET_PUSH;
+ }
+ _IF_DEQUEUE_ALL(&b->b_snd, m);
+ PFSYNC_BUCKET_UNLOCK(b);
- n = m->m_nextpkt;
- m->m_nextpkt = NULL;
+ for (; m != NULL; m = n) {
- /*
- * We distinguish between a deferral packet and our
- * own pfsync packet based on M_SKIP_FIREWALL
- * flag. This is XXX.
- */
- if (m->m_flags & M_SKIP_FIREWALL)
- ip_output(m, NULL, NULL, 0, NULL, NULL);
- else if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo,
- NULL) == 0)
- V_pfsyncstats.pfsyncs_opackets++;
- else
- V_pfsyncstats.pfsyncs_oerrors++;
+ n = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+
+ /*
+ * We distinguish between a deferral packet and our
+ * own pfsync packet based on M_SKIP_FIREWALL
+ * flag. This is XXX.
+ */
+ if (m->m_flags & M_SKIP_FIREWALL)
+ ip_output(m, NULL, NULL, 0, NULL, NULL);
+ else if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo,
+ NULL) == 0)
+ V_pfsyncstats.pfsyncs_opackets++;
+ else
+ V_pfsyncstats.pfsyncs_oerrors++;
+ }
}
CURVNET_RESTORE();
}
diff --git a/freebsd/sys/netpfil/pf/pf.c b/freebsd/sys/netpfil/pf/pf.c
index e115061a..9b4653e2 100644
--- a/freebsd/sys/netpfil/pf/pf.c
+++ b/freebsd/sys/netpfil/pf/pf.c
@@ -1569,9 +1569,11 @@ pf_state_expires(const struct pf_state *state)
states = V_pf_status.states;
}
if (end && states > start && start < end) {
- if (states < end)
- return (state->expire + timeout * (end - states) /
- (end - start));
+ if (states < end) {
+ timeout = (u_int64_t)timeout * (end - states) /
+ (end - start);
+ return (state->expire + timeout);
+ }
else
return (time_uptime);
}
@@ -5523,6 +5525,8 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
dst.sin_len = sizeof(dst);
dst.sin_addr = ip->ip_dst;
+ bzero(&naddr, sizeof(naddr));
+
if (TAILQ_EMPTY(&r->rpool.list)) {
DPFPRINTF(PF_DEBUG_URGENT,
("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__));
@@ -5682,6 +5686,8 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
dst.sin6_len = sizeof(dst);
dst.sin6_addr = ip6->ip6_dst;
+ bzero(&naddr, sizeof(naddr));
+
if (TAILQ_EMPTY(&r->rpool.list)) {
DPFPRINTF(PF_DEBUG_URGENT,
("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__));
diff --git a/freebsd/sys/netpfil/pf/pf_if.c b/freebsd/sys/netpfil/pf/pf_if.c
index ed69acad..4314bbce 100644
--- a/freebsd/sys/netpfil/pf/pf_if.c
+++ b/freebsd/sys/netpfil/pf/pf_if.c
@@ -855,7 +855,8 @@ pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp)
V_pfi_update++;
pfi_kif_update(kif);
- if_rele(kif->pfik_ifp);
+ if (kif->pfik_ifp)
+ if_rele(kif->pfik_ifp);
kif->pfik_ifp = NULL;
ifp->if_pf_kif = NULL;
diff --git a/freebsd/sys/netpfil/pf/pf_lb.c b/freebsd/sys/netpfil/pf/pf_lb.c
index 1fd02a0b..4e2bbbee 100644
--- a/freebsd/sys/netpfil/pf/pf_lb.c
+++ b/freebsd/sys/netpfil/pf/pf_lb.c
@@ -295,6 +295,10 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
switch (r->rpool.opts & PF_POOL_TYPEMASK) {
case PF_POOL_RANDOM:
case PF_POOL_ROUNDROBIN:
+ /*
+ * pick a different source address since we're out
+ * of free port choices for the current one.
+ */
if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
return (1);
break;
@@ -326,6 +330,12 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
src node was created just a moment ago in pf_create_state and it
needs to be filled in with routing decision calculated here. */
if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
+ /* If the supplied address is the same as the current one we've
+ * been asked before, so tell the caller that there's no other
+ * address to be had. */
+ if (PF_AEQ(naddr, &(*sn)->raddr, af))
+ return (1);
+
PF_ACPY(naddr, &(*sn)->raddr, af);
if (V_pf_status.debug >= PF_DEBUG_MISC) {
printf("pf_map_addr: src tracking maps ");
diff --git a/freebsd/sys/opencrypto/criov.c b/freebsd/sys/opencrypto/criov.c
index 7fc7d392..a1893691 100644
--- a/freebsd/sys/opencrypto/criov.c
+++ b/freebsd/sys/opencrypto/criov.c
@@ -40,6 +40,8 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/uio.h>
+#include <sys/limits.h>
+#include <sys/lock.h>
#include <opencrypto/cryptodev.h>
@@ -241,3 +243,55 @@ crypto_mbuftoiov(struct mbuf *mbuf, struct iovec **iovptr, int *cnt,
*cnt = i;
return 0;
}
+
+static inline void *
+m_contiguous_subsegment(struct mbuf *m, size_t skip, size_t len)
+{
+ int rel_off;
+
+ MPASS(skip <= INT_MAX);
+
+ m = m_getptr(m, (int)skip, &rel_off);
+ if (m == NULL)
+ return (NULL);
+
+ MPASS(rel_off >= 0);
+ skip = rel_off;
+ if (skip + len > m->m_len)
+ return (NULL);
+
+ return (mtod(m, char*) + skip);
+}
+
+static inline void *
+cuio_contiguous_segment(struct uio *uio, size_t skip, size_t len)
+{
+ int rel_off, idx;
+
+ MPASS(skip <= INT_MAX);
+ idx = cuio_getptr(uio, (int)skip, &rel_off);
+ if (idx < 0)
+ return (NULL);
+
+ MPASS(rel_off >= 0);
+ skip = rel_off;
+ if (skip + len > uio->uio_iov[idx].iov_len)
+ return (NULL);
+ return ((char *)uio->uio_iov[idx].iov_base + skip);
+}
+
+void *
+crypto_contiguous_subsegment(int crp_flags, void *crpbuf,
+ size_t skip, size_t len)
+{
+ if ((crp_flags & CRYPTO_F_IMBUF) != 0)
+ return (m_contiguous_subsegment(crpbuf, skip, len));
+ else if ((crp_flags & CRYPTO_F_IOV) != 0)
+ return (cuio_contiguous_segment(crpbuf, skip, len));
+ else {
+ MPASS((crp_flags & (CRYPTO_F_IMBUF | CRYPTO_F_IOV)) !=
+ (CRYPTO_F_IMBUF | CRYPTO_F_IOV));
+ return ((char*)crpbuf + skip);
+ }
+}
+
diff --git a/freebsd/sys/opencrypto/cryptodev.h b/freebsd/sys/opencrypto/cryptodev.h
index b3f81563..6431e6d8 100644
--- a/freebsd/sys/opencrypto/cryptodev.h
+++ b/freebsd/sys/opencrypto/cryptodev.h
@@ -564,5 +564,7 @@ extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
extern int crypto_apply(int flags, caddr_t buf, int off, int len,
int (*f)(void *, void *, u_int), void *arg);
+extern void *crypto_contiguous_subsegment(int, void *, size_t, size_t);
+
#endif /* _KERNEL */
#endif /* _CRYPTO_CRYPTO_H_ */
diff --git a/freebsd/sys/opencrypto/cryptosoft.c b/freebsd/sys/opencrypto/cryptosoft.c
index 81c5bde8..43455b48 100644
--- a/freebsd/sys/opencrypto/cryptosoft.c
+++ b/freebsd/sys/opencrypto/cryptosoft.c
@@ -1093,6 +1093,9 @@ swcr_freesession(device_t dev, crypto_session_t cses)
case CRYPTO_SHA2_256:
case CRYPTO_SHA2_384:
case CRYPTO_SHA2_512:
+ case CRYPTO_AES_128_NIST_GMAC:
+ case CRYPTO_AES_192_NIST_GMAC:
+ case CRYPTO_AES_256_NIST_GMAC:
axf = swd->sw_axf;
if (swd->sw_ictx) {
diff --git a/freebsd/sys/security/audit/audit.h b/freebsd/sys/security/audit/audit.h
index 2e47b8c4..2aeb5329 100644
--- a/freebsd/sys/security/audit/audit.h
+++ b/freebsd/sys/security/audit/audit.h
@@ -71,7 +71,7 @@
extern u_int audit_dtrace_enabled;
extern int audit_trail_enabled;
extern int audit_trail_suspended;
-extern int audit_syscalls_enabled;
+extern bool audit_syscalls_enabled;
void audit_syscall_enter(unsigned short code, struct thread *td);
void audit_syscall_exit(int error, struct thread *td);
@@ -150,7 +150,7 @@ void audit_thread_free(struct thread *td);
* Define macros to wrap the audit_arg_* calls by checking the global
* audit_syscalls_enabled flag before performing the actual call.
*/
-#define AUDITING_TD(td) ((td)->td_pflags & TDP_AUDITREC)
+#define AUDITING_TD(td) (__predict_false((td)->td_pflags & TDP_AUDITREC))
#define AUDIT_ARG_ADDR(addr) do { \
if (AUDITING_TD(curthread)) \
@@ -389,7 +389,7 @@ void audit_thread_free(struct thread *td);
* auditing is disabled, so we don't just check audit_syscalls_enabled here.
*/
#define AUDIT_SYSCALL_EXIT(error, td) do { \
- if (td->td_pflags & TDP_AUDITREC) \
+ if (AUDITING_TD(td)) \
audit_syscall_exit(error, td); \
} while (0)
@@ -397,7 +397,7 @@ void audit_thread_free(struct thread *td);
* A Macro to wrap the audit_sysclose() function.
*/
#define AUDIT_SYSCLOSE(td, fd) do { \
- if (td->td_pflags & TDP_AUDITREC) \
+ if (AUDITING_TD(td)) \
audit_sysclose(td, fd); \
} while (0)
diff --git a/freebsd/sys/sys/bus.h b/freebsd/sys/sys/bus.h
index 74a48f81..8e1ba763 100644
--- a/freebsd/sys/sys/bus.h
+++ b/freebsd/sys/sys/bus.h
@@ -485,6 +485,10 @@ int bus_generic_suspend(device_t dev);
int bus_generic_suspend_child(device_t dev, device_t child);
int bus_generic_teardown_intr(device_t dev, device_t child,
struct resource *irq, void *cookie);
+int bus_generic_suspend_intr(device_t dev, device_t child,
+ struct resource *irq);
+int bus_generic_resume_intr(device_t dev, device_t child,
+ struct resource *irq);
int bus_generic_unmap_resource(device_t dev, device_t child, int type,
struct resource *r,
struct resource_map *map);
@@ -535,6 +539,8 @@ int bus_setup_intr(device_t dev, struct resource *r, int flags,
driver_filter_t filter, driver_intr_t handler,
void *arg, void **cookiep);
int bus_teardown_intr(device_t dev, struct resource *r, void *cookie);
+int bus_suspend_intr(device_t dev, struct resource *r);
+int bus_resume_intr(device_t dev, struct resource *r);
int bus_bind_intr(device_t dev, struct resource *r, int cpu);
int bus_describe_intr(device_t dev, struct resource *irq, void *cookie,
const char *fmt, ...) __printflike(4, 5);
@@ -612,6 +618,7 @@ void device_set_desc(device_t dev, const char* desc);
void device_set_desc_copy(device_t dev, const char* desc);
int device_set_devclass(device_t dev, const char *classname);
int device_set_devclass_fixed(device_t dev, const char *classname);
+bool device_is_devclass_fixed(device_t dev);
int device_set_driver(device_t dev, driver_t *driver);
void device_set_flags(device_t dev, u_int32_t flags);
void device_set_softc(device_t dev, void *softc);
diff --git a/freebsd/sys/sys/filedesc.h b/freebsd/sys/sys/filedesc.h
index a3224f42..857d1fc9 100644
--- a/freebsd/sys/sys/filedesc.h
+++ b/freebsd/sys/sys/filedesc.h
@@ -173,7 +173,13 @@ enum {
struct thread;
-void filecaps_init(struct filecaps *fcaps);
+static __inline void
+filecaps_init(struct filecaps *fcaps)
+{
+
+ bzero(fcaps, sizeof(*fcaps));
+ fcaps->fc_nioctls = -1;
+}
bool filecaps_copy(const struct filecaps *src, struct filecaps *dst,
bool locked);
void filecaps_move(struct filecaps *src, struct filecaps *dst);
@@ -289,7 +295,7 @@ fget_locked(struct filedesc *fdp, int fd)
FILEDESC_LOCK_ASSERT(fdp);
- if (fd < 0 || fd > fdp->fd_lastfile)
+ if (__predict_false((u_int)fd >= fdp->fd_nfiles))
return (NULL);
return (fdp->fd_ofiles[fd].fde_file);
@@ -302,11 +308,11 @@ fdeget_locked(struct filedesc *fdp, int fd)
FILEDESC_LOCK_ASSERT(fdp);
- if (fd < 0 || fd > fdp->fd_lastfile)
+ if (__predict_false((u_int)fd >= fdp->fd_nfiles))
return (NULL);
fde = &fdp->fd_ofiles[fd];
- if (fde->fde_file == NULL)
+ if (__predict_false(fde->fde_file == NULL))
return (NULL);
return (fde);
diff --git a/freebsd/sys/sys/interrupt.h b/freebsd/sys/sys/interrupt.h
index 105bb968..5c634054 100644
--- a/freebsd/sys/sys/interrupt.h
+++ b/freebsd/sys/sys/interrupt.h
@@ -62,6 +62,8 @@ struct intr_handler {
#define IH_EXCLUSIVE 0x00000002 /* Exclusive interrupt. */
#define IH_ENTROPY 0x00000004 /* Device is a good entropy source. */
#define IH_DEAD 0x00000008 /* Handler should be removed. */
+#define IH_SUSP 0x00000010 /* Device is powered down. */
+#define IH_CHANGED 0x40000000 /* Handler state is changed. */
#define IH_MPSAFE 0x80000000 /* Handler does not need Giant. */
/*
@@ -184,6 +186,8 @@ int intr_event_describe_handler(struct intr_event *ie, void *cookie,
int intr_event_destroy(struct intr_event *ie);
int intr_event_handle(struct intr_event *ie, struct trapframe *frame);
int intr_event_remove_handler(void *cookie);
+int intr_event_suspend_handler(void *cookie);
+int intr_event_resume_handler(void *cookie);
int intr_getaffinity(int irq, int mode, void *mask);
void *intr_handler_source(void *cookie);
int intr_setaffinity(int irq, int mode, void *mask);
diff --git a/freebsd/sys/sys/jail.h b/freebsd/sys/sys/jail.h
index c9f24bdd..ccd9f57f 100644
--- a/freebsd/sys/sys/jail.h
+++ b/freebsd/sys/sys/jail.h
@@ -229,9 +229,16 @@ struct prison_racct {
#define PR_ALLOW_SOCKET_AF 0x00000040
#define PR_ALLOW_MLOCK 0x00000080
#define PR_ALLOW_READ_MSGBUF 0x00000100
+#define PR_ALLOW_UNPRIV_DEBUG 0x00000200
#define PR_ALLOW_RESERVED_PORTS 0x00008000
#define PR_ALLOW_KMEM_ACCESS 0x00010000 /* reserved, not used yet */
-#define PR_ALLOW_ALL_STATIC 0x000181ff
+#define PR_ALLOW_ALL_STATIC 0x000183ff
+
+/*
+ * PR_ALLOW_DIFFERENCES determines which flags are able to be
+ * different between the parent and child jail upon creation.
+ */
+#define PR_ALLOW_DIFFERENCES (PR_ALLOW_UNPRIV_DEBUG)
/*
* OSD methods
diff --git a/freebsd/sys/sys/mount.h b/freebsd/sys/sys/mount.h
index ac1c215b..2a5d4cff 100644
--- a/freebsd/sys/sys/mount.h
+++ b/freebsd/sys/sys/mount.h
@@ -932,11 +932,15 @@ void syncer_resume(void);
struct stat;
__BEGIN_DECLS
+int fhlink(struct fhandle *, const char *);
+int fhlinkat(struct fhandle *, int, const char *);
int fhopen(const struct fhandle *, int);
+int fhreadlink(struct fhandle *, char *, size_t);
int fhstat(const struct fhandle *, struct stat *);
int fhstatfs(const struct fhandle *, struct statfs *);
int fstatfs(int, struct statfs *);
int getfh(const char *, fhandle_t *);
+int getfhat(int, char *, struct fhandle *, int);
int getfsstat(struct statfs *, long, int);
int getmntinfo(struct statfs **, int);
int lgetfh(const char *, fhandle_t *);
diff --git a/freebsd/sys/sys/mutex.h b/freebsd/sys/sys/mutex.h
index e9c91f80..8d2f01ba 100644
--- a/freebsd/sys/sys/mutex.h
+++ b/freebsd/sys/sys/mutex.h
@@ -531,7 +531,7 @@ do { \
int _giantcnt = 0; \
WITNESS_SAVE_DECL(Giant); \
\
- if (mtx_owned(&Giant)) { \
+ if (__predict_false(mtx_owned(&Giant))) { \
WITNESS_SAVE(&Giant.lock_object, Giant); \
for (_giantcnt = 0; mtx_owned(&Giant) && \
!SCHEDULER_STOPPED(); _giantcnt++) \
@@ -544,7 +544,7 @@ do { \
#define PARTIAL_PICKUP_GIANT() \
mtx_assert(&Giant, MA_NOTOWNED); \
- if (_giantcnt > 0) { \
+ if (__predict_false(_giantcnt > 0)) { \
while (_giantcnt--) \
mtx_lock(&Giant); \
WITNESS_RESTORE(&Giant.lock_object, Giant); \
diff --git a/freebsd/sys/sys/priv.h b/freebsd/sys/sys/priv.h
index 55453f5a..3027cbf5 100644
--- a/freebsd/sys/sys/priv.h
+++ b/freebsd/sys/sys/priv.h
@@ -533,10 +533,10 @@ struct thread;
struct ucred;
#ifndef __rtems__
int priv_check(struct thread *td, int priv);
-int priv_check_cred(struct ucred *cred, int priv, int flags);
+int priv_check_cred(struct ucred *cred, int priv);
#else /* __rtems__ */
#define priv_check(td, priv) 0
-#define priv_check_cred(cred, priv, flags) 0
+#define priv_check_cred(cred, priv) 0
#endif /* __rtems__ */
#endif
diff --git a/freebsd/sys/sys/proc.h b/freebsd/sys/sys/proc.h
index 9868f9cf..6c352059 100644
--- a/freebsd/sys/sys/proc.h
+++ b/freebsd/sys/sys/proc.h
@@ -643,10 +643,10 @@ struct proc {
struct ksiginfo *p_ksi; /* Locked by parent proc lock */
sigqueue_t p_sigqueue; /* (c) Sigs not delivered to a td. */
#define p_siglist p_sigqueue.sq_signals
+ pid_t p_oppid; /* (c + e) Real parent pid. */
/* The following fields are all zeroed upon creation in fork. */
-#define p_startzero p_oppid
- pid_t p_oppid; /* (c + e) Save ppid in ptrace. XXX */
+#define p_startzero p_vmspace
struct vmspace *p_vmspace; /* (b) Address space. */
u_int p_swtick; /* (c) Tick when swapped in or out. */
u_int p_cowgen; /* (c) Generation of COW pointers. */
@@ -691,6 +691,7 @@ struct proc {
u_int p_magic; /* (b) Magic number. */
int p_osrel; /* (x) osreldate for the
binary (from ELF note, if any) */
+ uint32_t p_fctl0; /* (x) ABI feature control, ELF note */
char p_comm[MAXCOMLEN + 1]; /* (x) Process name. */
struct sysentvec *p_sysent; /* (b) Syscall dispatch info. */
struct pargs *p_args; /* (c) Process arguments. */
@@ -997,8 +998,11 @@ extern pid_t pid_max;
#define THREAD_CAN_SLEEP() ((curthread)->td_no_sleeping == 0)
#define PIDHASH(pid) (&pidhashtbl[(pid) & pidhash])
+#define PIDHASHLOCK(pid) (&pidhashtbl_lock[((pid) & pidhashlock)])
extern LIST_HEAD(pidhashhead, proc) *pidhashtbl;
+extern struct sx *pidhashtbl_lock;
extern u_long pidhash;
+extern u_long pidhashlock;
#define TIDHASH(tid) (&tidhashtbl[(tid) & tidhash])
extern LIST_HEAD(tidhashhead, thread) *tidhashtbl;
extern u_long tidhash;
@@ -1010,8 +1014,10 @@ extern u_long pgrphash;
extern struct sx allproc_lock;
extern int allproc_gen;
+extern struct sx zombproc_lock;
extern struct sx proctree_lock;
extern struct mtx ppeers_lock;
+extern struct mtx procid_lock;
extern struct proc proc0; /* Process slot for swapper. */
extern struct thread0_storage thread0_st; /* Primary thread in proc0. */
#define thread0 (thread0_st.t0st_thread)
@@ -1033,7 +1039,6 @@ extern struct uma_zone *proc_zone;
struct proc *pfind(pid_t); /* Find process by id. */
struct proc *pfind_any(pid_t); /* Find (zombie) process by id. */
-struct proc *pfind_locked(pid_t pid);
struct pgrp *pgfind(pid_t); /* Find process group by id. */
struct proc *zpfind(pid_t); /* Find zombie process by id. */
@@ -1081,6 +1086,7 @@ int enterthispgrp(struct proc *p, struct pgrp *pgrp);
void faultin(struct proc *p);
void fixjobc(struct proc *p, struct pgrp *pgrp, int entering);
int fork1(struct thread *, struct fork_req *);
+void fork_rfppwait(struct thread *);
void fork_exit(void (*)(void *, struct trapframe *), void *,
struct trapframe *);
void fork_return(struct thread *, struct trapframe *);
@@ -1111,11 +1117,12 @@ int proc_getargv(struct thread *td, struct proc *p, struct sbuf *sb);
int proc_getauxv(struct thread *td, struct proc *p, struct sbuf *sb);
int proc_getenvv(struct thread *td, struct proc *p, struct sbuf *sb);
void procinit(void);
+int proc_iterate(int (*cb)(struct proc *, void *), void *cbarg);
void proc_linkup0(struct proc *p, struct thread *td);
void proc_linkup(struct proc *p, struct thread *td);
struct proc *proc_realparent(struct proc *child);
void proc_reap(struct thread *td, struct proc *p, int *status, int options);
-void proc_reparent(struct proc *child, struct proc *newparent);
+void proc_reparent(struct proc *child, struct proc *newparent, bool set_oppid);
void proc_set_traced(struct proc *p, bool stop);
void proc_wkilled(struct proc *p);
struct pstats *pstats_alloc(void);
@@ -1234,6 +1241,15 @@ td_softdep_cleanup(struct thread *td)
}
#endif /* __rtems__ */
+#define PROC_ID_PID 0
+#define PROC_ID_GROUP 1
+#define PROC_ID_SESSION 2
+#define PROC_ID_REAP 3
+
+void proc_id_set(int type, pid_t id);
+void proc_id_set_cond(int type, pid_t id);
+void proc_id_clear(int type, pid_t id);
+
#endif /* _KERNEL */
#endif /* !_SYS_PROC_H_ */
diff --git a/freebsd/sys/sys/racct.h b/freebsd/sys/sys/racct.h
index 84de705f..17af3276 100644
--- a/freebsd/sys/sys/racct.h
+++ b/freebsd/sys/sys/racct.h
@@ -91,7 +91,7 @@ struct ucred;
#define RACCT_DECAYING 0x20
extern int racct_types[];
-extern int racct_enable;
+extern bool racct_enable;
#define ASSERT_RACCT_ENABLED() KASSERT(racct_enable, \
("%s called with !racct_enable", __func__))
@@ -164,12 +164,14 @@ extern struct mtx racct_lock;
#define RACCT_UNLOCK() mtx_unlock(&racct_lock)
#define RACCT_LOCK_ASSERT() mtx_assert(&racct_lock, MA_OWNED)
+#define RACCT_ENABLED() __predict_false(racct_enable)
+
#define RACCT_PROC_LOCK(p) do { \
- if (__predict_false(racct_enable)) \
+ if (RACCT_ENABLED()) \
PROC_LOCK(p); \
} while (0)
#define RACCT_PROC_UNLOCK(p) do { \
- if (__predict_false(racct_enable)) \
+ if (RACCT_ENABLED()) \
PROC_UNLOCK(p); \
} while (0)
@@ -178,6 +180,7 @@ void racct_add_cred(struct ucred *cred, int resource, uint64_t amount);
void racct_add_force(struct proc *p, int resource, uint64_t amount);
void racct_add_buf(struct proc *p, const struct buf *bufp, int is_write);
int racct_set(struct proc *p, int resource, uint64_t amount);
+int racct_set_unlocked(struct proc *p, int resource, uint64_t amount);
void racct_set_force(struct proc *p, int resource, uint64_t amount);
void racct_sub(struct proc *p, int resource, uint64_t amount);
void racct_sub_cred(struct ucred *cred, int resource, uint64_t amount);
@@ -194,6 +197,7 @@ void racct_proc_exit(struct proc *p);
void racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred,
struct ucred *newcred);
void racct_move(struct racct *dest, struct racct *src);
+void racct_proc_throttled(struct proc *p);
void racct_proc_throttle(struct proc *p, int timeout);
#else
diff --git a/freebsd/sys/sys/refcount.h b/freebsd/sys/sys/refcount.h
index 41713147..0cc4eb41 100644
--- a/freebsd/sys/sys/refcount.h
+++ b/freebsd/sys/sys/refcount.h
@@ -79,8 +79,6 @@ refcount_release(volatile u_int *count)
/*
* This functions returns non-zero if the refcount was
* incremented. Else zero is returned.
- *
- * A temporary hack until refcount_* APIs are sorted out.
*/
static __inline __result_use_check int
refcount_acquire_if_not_zero(volatile u_int *count)
diff --git a/freebsd/sys/sys/resourcevar.h b/freebsd/sys/sys/resourcevar.h
index 7c7e8458..c7576d2d 100644
--- a/freebsd/sys/sys/resourcevar.h
+++ b/freebsd/sys/sys/resourcevar.h
@@ -147,6 +147,19 @@ struct plimit
*lim_alloc(void);
void lim_copy(struct plimit *dst, struct plimit *src);
rlim_t lim_cur(struct thread *td, int which);
+#define lim_cur(td, which) ({ \
+ rlim_t _rlim; \
+ struct thread *_td = (td); \
+ int _which = (which); \
+ if (__builtin_constant_p(which) && which != RLIMIT_DATA && \
+ which != RLIMIT_STACK && which != RLIMIT_VMEM) { \
+ _rlim = td->td_limit->pl_rlimit[which].rlim_cur; \
+ } else { \
+ _rlim = lim_cur(_td, _which); \
+ } \
+ _rlim; \
+})
+
rlim_t lim_cur_proc(struct proc *p, int which);
void lim_fork(struct proc *p1, struct proc *p2);
void lim_free(struct plimit *limp);
diff --git a/freebsd/sys/sys/rman.h b/freebsd/sys/sys/rman.h
index 9c2f4653..e955cd58 100644
--- a/freebsd/sys/sys/rman.h
+++ b/freebsd/sys/sys/rman.h
@@ -131,6 +131,7 @@ bus_space_tag_t rman_get_bustag(struct resource *);
rman_res_t rman_get_end(struct resource *);
device_t rman_get_device(struct resource *);
u_int rman_get_flags(struct resource *);
+void *rman_get_irq_cookie(struct resource *);
void rman_get_mapping(struct resource *, struct resource_map *);
int rman_get_rid(struct resource *);
rman_res_t rman_get_size(struct resource *);
@@ -155,6 +156,7 @@ void rman_set_bushandle(struct resource *_r, bus_space_handle_t _h);
void rman_set_bustag(struct resource *_r, bus_space_tag_t _t);
void rman_set_device(struct resource *_r, device_t _dev);
void rman_set_end(struct resource *_r, rman_res_t _end);
+void rman_set_irq_cookie(struct resource *_r, void *_c);
void rman_set_mapping(struct resource *, struct resource_map *);
void rman_set_rid(struct resource *_r, int _rid);
void rman_set_start(struct resource *_r, rman_res_t _start);
diff --git a/freebsd/sys/sys/sdt.h b/freebsd/sys/sys/sdt.h
index 424a0e3a..fb5c3d67 100644
--- a/freebsd/sys/sys/sdt.h
+++ b/freebsd/sys/sys/sdt.h
@@ -90,6 +90,7 @@ extern volatile bool sdt_probes_enabled;
#define SDT_PROVIDER_DECLARE(prov)
#define SDT_PROBE_DEFINE(prov, mod, func, name)
#define SDT_PROBE_DECLARE(prov, mod, func, name)
+#define SDT_PROBES_ENABLED() 0
#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4)
#define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type, xtype)
@@ -164,8 +165,10 @@ SET_DECLARE(sdt_argtypes_set, struct sdt_argtype);
#define SDT_PROBE_DECLARE(prov, mod, func, name) \
extern struct sdt_probe sdt_##prov##_##mod##_##func##_##name[1]
+#define SDT_PROBES_ENABLED() __predict_false(sdt_probes_enabled)
+
#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) do { \
- if (__predict_false(sdt_probes_enabled)) { \
+ if (SDT_PROBES_ENABLED()) { \
if (__predict_false(sdt_##prov##_##mod##_##func##_##name->id)) \
(*sdt_probe_func)(sdt_##prov##_##mod##_##func##_##name->id, \
(uintptr_t) arg0, (uintptr_t) arg1, (uintptr_t) arg2, \
diff --git a/freebsd/sys/sys/sockbuf.h b/freebsd/sys/sys/sockbuf.h
index fc287023..3b716283 100644
--- a/freebsd/sys/sys/sockbuf.h
+++ b/freebsd/sys/sys/sockbuf.h
@@ -165,8 +165,6 @@ void sbrelease_locked(struct sockbuf *sb, struct socket *so);
int sbsetopt(struct socket *so, int cmd, u_long cc);
int sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
struct thread *td);
-struct mbuf *
- sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff);
void sbsndptr_adv(struct sockbuf *sb, struct mbuf *mb, u_int len);
struct mbuf *
sbsndptr_noadv(struct sockbuf *sb, u_int off, u_int *moff);
diff --git a/freebsd/sys/sys/sx.h b/freebsd/sys/sys/sx.h
index 10cfb10a..9e0da83a 100644
--- a/freebsd/sys/sys/sx.h
+++ b/freebsd/sys/sys/sx.h
@@ -313,7 +313,6 @@ int sx_xlocked(struct sx *sx);
#define SX_NOPROFILE 0x02
#define SX_NOWITNESS 0x04
#define SX_QUIET 0x08
-#define SX_NOADAPTIVE 0x10
#define SX_RECURSE 0x20
#define SX_NEW 0x40
diff --git a/freebsd/sys/sys/sysctl.h b/freebsd/sys/sys/sysctl.h
index e270a4b2..cf5a5581 100644
--- a/freebsd/sys/sys/sysctl.h
+++ b/freebsd/sys/sys/sysctl.h
@@ -165,11 +165,7 @@ struct sysctl_req {
size_t oldlen;
size_t oldidx;
int (*oldfunc)(struct sysctl_req *, const void *, size_t);
-#ifndef __rtems__
- void *newptr;
-#else /* __rtems__ */
- const void *newptr;
-#endif /* __rtems__ */
+ const void *newptr;
size_t newlen;
size_t newidx;
int (*newfunc)(struct sysctl_req *, void *, size_t);
@@ -1135,11 +1131,7 @@ int kernel_sysctlbyname(struct thread *td, char *name, void *old,
#endif /* __rtems__ */
int flags);
int userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
-#ifndef __rtems__
- size_t *oldlenp, int inkernel, void *new, size_t newlen,
-#else /* __rtems__ */
- size_t *oldlenp, int inkernel, const void *newp, size_t newlen,
-#endif /* __rtems__ */
+ size_t *oldlenp, int inkernel, const void *new, size_t newlen,
size_t *retval, int flags);
int sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid,
int *nindx, struct sysctl_req *req);
diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h
index a39f5cd3..faa5a62f 100644
--- a/freebsd/sys/sys/sysproto.h
+++ b/freebsd/sys/sys/sysproto.h
@@ -254,7 +254,7 @@ struct umask_args {
struct chroot_args {
char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
};
-struct getpagesize_args {
+struct ogetpagesize_args {
register_t dummy;
};
struct msync_args {
@@ -1817,6 +1817,26 @@ struct getrandom_args {
char buflen_l_[PADL_(size_t)]; size_t buflen; char buflen_r_[PADR_(size_t)];
char flags_l_[PADL_(unsigned int)]; unsigned int flags; char flags_r_[PADR_(unsigned int)];
};
+struct getfhat_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char fhp_l_[PADL_(struct fhandle *)]; struct fhandle * fhp; char fhp_r_[PADR_(struct fhandle *)];
+ char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+};
+struct fhlink_args {
+ char fhp_l_[PADL_(struct fhandle *)]; struct fhandle * fhp; char fhp_r_[PADR_(struct fhandle *)];
+ char to_l_[PADL_(const char *)]; const char * to; char to_r_[PADR_(const char *)];
+};
+struct fhlinkat_args {
+ char fhp_l_[PADL_(struct fhandle *)]; struct fhandle * fhp; char fhp_r_[PADR_(struct fhandle *)];
+ char tofd_l_[PADL_(int)]; int tofd; char tofd_r_[PADR_(int)];
+ char to_l_[PADL_(const char *)]; const char * to; char to_r_[PADR_(const char *)];
+};
+struct fhreadlink_args {
+ char fhp_l_[PADL_(struct fhandle *)]; struct fhandle * fhp; char fhp_r_[PADR_(struct fhandle *)];
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char bufsize_l_[PADL_(size_t)]; size_t bufsize; char bufsize_r_[PADR_(size_t)];
+};
int nosys(struct thread *, struct nosys_args *);
void sys_sys_exit(struct thread *, struct sys_exit_args *);
int sys_fork(struct thread *, struct fork_args *);
@@ -2197,6 +2217,10 @@ int sys_kevent(struct thread *, struct kevent_args *);
int sys_cpuset_getdomain(struct thread *, struct cpuset_getdomain_args *);
int sys_cpuset_setdomain(struct thread *, struct cpuset_setdomain_args *);
int sys_getrandom(struct thread *, struct getrandom_args *);
+int sys_getfhat(struct thread *, struct getfhat_args *);
+int sys_fhlink(struct thread *, struct fhlink_args *);
+int sys_fhlinkat(struct thread *, struct fhlinkat_args *);
+int sys_fhreadlink(struct thread *, struct fhreadlink_args *);
#ifdef COMPAT_43
@@ -2230,7 +2254,7 @@ struct ofstat_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char sb_l_[PADL_(struct ostat *)]; struct ostat * sb; char sb_r_[PADR_(struct ostat *)];
};
-struct getkerninfo_args {
+struct ogetkerninfo_args {
char op_l_[PADL_(int)]; int op; char op_r_[PADR_(int)];
char where_l_[PADL_(char *)]; char * where; char where_r_[PADR_(char *)];
char size_l_[PADL_(size_t *)]; size_t * size; char size_r_[PADR_(size_t *)];
@@ -2244,14 +2268,19 @@ struct ommap_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char pos_l_[PADL_(long)]; long pos; char pos_r_[PADR_(long)];
};
-struct gethostname_args {
+struct ogethostname_args {
char hostname_l_[PADL_(char *)]; char * hostname; char hostname_r_[PADR_(char *)];
char len_l_[PADL_(u_int)]; u_int len; char len_r_[PADR_(u_int)];
};
-struct sethostname_args {
+struct osethostname_args {
char hostname_l_[PADL_(char *)]; char * hostname; char hostname_r_[PADR_(char *)];
char len_l_[PADL_(u_int)]; u_int len; char len_r_[PADR_(u_int)];
};
+struct oaccept_args {
+ char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
+ char name_l_[PADL_(struct sockaddr *)]; struct sockaddr * name; char name_r_[PADR_(struct sockaddr *)];
+ char anamelen_l_[PADL_(int *)]; int * anamelen; char anamelen_r_[PADR_(int *)];
+};
struct osend_args {
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
char buf_l_[PADL_(const void *)]; const void * buf; char buf_r_[PADR_(const void *)];
@@ -2337,13 +2366,13 @@ int osigaction(struct thread *, struct osigaction_args *);
int osigprocmask(struct thread *, struct osigprocmask_args *);
int osigpending(struct thread *, struct osigpending_args *);
int ofstat(struct thread *, struct ofstat_args *);
-int ogetkerninfo(struct thread *, struct getkerninfo_args *);
-int ogetpagesize(struct thread *, struct getpagesize_args *);
+int ogetkerninfo(struct thread *, struct ogetkerninfo_args *);
+int ogetpagesize(struct thread *, struct ogetpagesize_args *);
int ommap(struct thread *, struct ommap_args *);
int owait(struct thread *, struct owait_args *);
-int ogethostname(struct thread *, struct gethostname_args *);
-int osethostname(struct thread *, struct sethostname_args *);
-int oaccept(struct thread *, struct accept_args *);
+int ogethostname(struct thread *, struct ogethostname_args *);
+int osethostname(struct thread *, struct osethostname_args *);
+int oaccept(struct thread *, struct oaccept_args *);
int osend(struct thread *, struct osend_args *);
int orecv(struct thread *, struct orecv_args *);
int osigreturn(struct thread *, struct osigreturn_args *);
@@ -3094,6 +3123,10 @@ int freebsd11_mknodat(struct thread *, struct freebsd11_mknodat_args *);
#define SYS_AUE_cpuset_getdomain AUE_NULL
#define SYS_AUE_cpuset_setdomain AUE_NULL
#define SYS_AUE_getrandom AUE_NULL
+#define SYS_AUE_getfhat AUE_NULL
+#define SYS_AUE_fhlink AUE_NULL
+#define SYS_AUE_fhlinkat AUE_NULL
+#define SYS_AUE_fhreadlink AUE_NULL
#endif /* __rtems__ */
#undef PAD_
diff --git a/freebsd/sys/sys/systm.h b/freebsd/sys/sys/systm.h
index d74a1e4b..1aa57670 100644
--- a/freebsd/sys/sys/systm.h
+++ b/freebsd/sys/sys/systm.h
@@ -654,6 +654,32 @@ int alloc_unr_specific(struct unrhdr *uh, u_int item);
int alloc_unrl(struct unrhdr *uh);
void free_unr(struct unrhdr *uh, u_int item);
+#ifndef __LP64__
+#define UNR64_LOCKED
+#endif
+
+struct unrhdr64 {
+ uint64_t counter;
+};
+
+static __inline void
+new_unrhdr64(struct unrhdr64 *unr64, uint64_t low)
+{
+
+ unr64->counter = low;
+}
+
+#ifdef UNR64_LOCKED
+uint64_t alloc_unr64(struct unrhdr64 *);
+#else
+static __inline uint64_t
+alloc_unr64(struct unrhdr64 *unr64)
+{
+
+ return (atomic_fetchadd_64(&unr64->counter, 1));
+}
+#endif
+
void intr_prof_stack_use(struct thread *td, struct trapframe *frame);
void counted_warning(unsigned *counter, const char *msg);
diff --git a/freebsd/sys/sys/taskqueue.h b/freebsd/sys/sys/taskqueue.h
index 7ba9e268..4af1e0a3 100644
--- a/freebsd/sys/sys/taskqueue.h
+++ b/freebsd/sys/sys/taskqueue.h
@@ -93,6 +93,7 @@ void taskqueue_drain(struct taskqueue *queue, struct task *task);
void taskqueue_drain_timeout(struct taskqueue *queue,
struct timeout_task *timeout_task);
void taskqueue_drain_all(struct taskqueue *queue);
+void taskqueue_quiesce(struct taskqueue *queue);
void taskqueue_free(struct taskqueue *queue);
void taskqueue_run(struct taskqueue *queue);
void taskqueue_block(struct taskqueue *queue);
diff --git a/freebsd/sys/sys/user.h b/freebsd/sys/sys/user.h
index 1218deec..80716460 100644
--- a/freebsd/sys/sys/user.h
+++ b/freebsd/sys/sys/user.h
@@ -264,6 +264,7 @@ struct user {
#define KF_TYPE_SEM 9
#define KF_TYPE_PTS 10
#define KF_TYPE_PROCDESC 11
+#define KF_TYPE_DEV 12
#define KF_TYPE_UNKNOWN 255
#define KF_VTYPE_VNON 0
diff --git a/freebsd/sys/vm/uma_core.c b/freebsd/sys/vm/uma_core.c
index db624654..ade3328a 100644
--- a/freebsd/sys/vm/uma_core.c
+++ b/freebsd/sys/vm/uma_core.c
@@ -1537,7 +1537,7 @@ keg_small_init(uma_keg_t keg)
if (keg->uk_flags & UMA_ZONE_OFFPAGE)
shsize = 0;
else
- shsize = sizeof(struct uma_slab);
+ shsize = SIZEOF_UMA_SLAB;
if (rsize <= slabsize - shsize)
keg->uk_ipers = (slabsize - shsize) / rsize;
@@ -1607,7 +1607,6 @@ keg_small_init(uma_keg_t keg)
static void
keg_large_init(uma_keg_t keg)
{
- u_int shsize;
KASSERT(keg != NULL, ("Keg is null in keg_large_init"));
KASSERT((keg->uk_flags & UMA_ZFLAG_CACHEONLY) == 0,
@@ -1620,23 +1619,17 @@ keg_large_init(uma_keg_t keg)
keg->uk_rsize = keg->uk_size;
/* Check whether we have enough space to not do OFFPAGE. */
- if ((keg->uk_flags & UMA_ZONE_OFFPAGE) == 0) {
- shsize = sizeof(struct uma_slab);
- if (shsize & UMA_ALIGN_PTR)
- shsize = (shsize & ~UMA_ALIGN_PTR) +
- (UMA_ALIGN_PTR + 1);
-
- if (PAGE_SIZE * keg->uk_ppera - keg->uk_rsize < shsize) {
- /*
- * We can't do OFFPAGE if we're internal, in which case
- * we need an extra page per allocation to contain the
- * slab header.
- */
- if ((keg->uk_flags & UMA_ZFLAG_INTERNAL) == 0)
- keg->uk_flags |= UMA_ZONE_OFFPAGE;
- else
- keg->uk_ppera++;
- }
+ if ((keg->uk_flags & UMA_ZONE_OFFPAGE) == 0 &&
+ PAGE_SIZE * keg->uk_ppera - keg->uk_rsize < SIZEOF_UMA_SLAB) {
+ /*
+ * We can't do OFFPAGE if we're internal, in which case
+ * we need an extra page per allocation to contain the
+ * slab header.
+ */
+ if ((keg->uk_flags & UMA_ZFLAG_INTERNAL) == 0)
+ keg->uk_flags |= UMA_ZONE_OFFPAGE;
+ else
+ keg->uk_ppera++;
}
if ((keg->uk_flags & UMA_ZONE_OFFPAGE) &&
@@ -1783,20 +1776,11 @@ keg_ctor(void *mem, int size, void *udata, int flags)
/*
* If we're putting the slab header in the actual page we need to
- * figure out where in each page it goes. This calculates a right
- * justified offset into the memory on an ALIGN_PTR boundary.
+ * figure out where in each page it goes. See SIZEOF_UMA_SLAB
+ * macro definition.
*/
if (!(keg->uk_flags & UMA_ZONE_OFFPAGE)) {
- u_int totsize;
-
- /* Size of the slab struct and free list */
- totsize = sizeof(struct uma_slab);
-
- if (totsize & UMA_ALIGN_PTR)
- totsize = (totsize & ~UMA_ALIGN_PTR) +
- (UMA_ALIGN_PTR + 1);
- keg->uk_pgoff = (PAGE_SIZE * keg->uk_ppera) - totsize;
-
+ keg->uk_pgoff = (PAGE_SIZE * keg->uk_ppera) - SIZEOF_UMA_SLAB;
/*
* The only way the following is possible is if with our
* UMA_ALIGN_PTR adjustments we are now bigger than
@@ -1804,13 +1788,10 @@ keg_ctor(void *mem, int size, void *udata, int flags)
* mathematically possible for all cases, so we make
* sure here anyway.
*/
- totsize = keg->uk_pgoff + sizeof(struct uma_slab);
- if (totsize > PAGE_SIZE * keg->uk_ppera) {
- printf("zone %s ipers %d rsize %d size %d\n",
- zone->uz_name, keg->uk_ipers, keg->uk_rsize,
- keg->uk_size);
- panic("UMA slab won't fit.");
- }
+ KASSERT(keg->uk_pgoff + sizeof(struct uma_slab) <=
+ PAGE_SIZE * keg->uk_ppera,
+ ("zone %s ipers %d rsize %d size %d slab won't fit",
+ zone->uz_name, keg->uk_ipers, keg->uk_rsize, keg->uk_size));
}
if (keg->uk_flags & UMA_ZONE_HASH)
@@ -2105,10 +2086,17 @@ uma_startup_count(int vm_zones)
#endif
/* Memory for the rest of startup zones, UMA and VM, ... */
- if (zsize > UMA_SLAB_SPACE)
- pages += (zones + vm_zones) *
- howmany(roundup2(zsize, UMA_BOOT_ALIGN), UMA_SLAB_SIZE);
- else if (roundup2(zsize, UMA_BOOT_ALIGN) > UMA_SLAB_SPACE)
+ if (zsize > UMA_SLAB_SPACE) {
+ /* See keg_large_init(). */
+ u_int ppera;
+
+ ppera = howmany(roundup2(zsize, UMA_BOOT_ALIGN), PAGE_SIZE);
+ if (PAGE_SIZE * ppera - roundup2(zsize, UMA_BOOT_ALIGN) <
+ SIZEOF_UMA_SLAB)
+ ppera++;
+ pages += (zones + vm_zones) * ppera;
+ } else if (roundup2(zsize, UMA_BOOT_ALIGN) > UMA_SLAB_SPACE)
+ /* See keg_small_init() special case for uk_ppera = 1. */
pages += zones;
else
pages += howmany(zones,
diff --git a/freebsd/sys/vm/uma_int.h b/freebsd/sys/vm/uma_int.h
index 0fbc0512..0429bac6 100644
--- a/freebsd/sys/vm/uma_int.h
+++ b/freebsd/sys/vm/uma_int.h
@@ -139,9 +139,17 @@
#define UMA_MAX_WASTE 10
/*
- * Size of memory in a not offpage slab available for actual items.
+ * Actual size of uma_slab when it is placed at an end of a page
+ * with pointer sized alignment requirement.
*/
-#define UMA_SLAB_SPACE (UMA_SLAB_SIZE - sizeof(struct uma_slab))
+#define SIZEOF_UMA_SLAB ((sizeof(struct uma_slab) & UMA_ALIGN_PTR) ? \
+ (sizeof(struct uma_slab) & ~UMA_ALIGN_PTR) + \
+ (UMA_ALIGN_PTR + 1) : sizeof(struct uma_slab))
+
+/*
+ * Size of memory in a not offpage single page slab available for actual items.
+ */
+#define UMA_SLAB_SPACE (PAGE_SIZE - SIZEOF_UMA_SLAB)
/*
* I doubt there will be many cases where this is exceeded. This is the initial