diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-08-07 12:12:37 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-21 10:29:36 +0200 |
commit | de261e0404e1fe54544275fc57d5b982df4f42b4 (patch) | |
tree | 856cbdf23d6809b99c4d642d066bc45cd67c26e6 /freebsd/sys | |
parent | libbsd.txt: Use rtems_bsd_ifconfig_lo0() (diff) | |
download | rtems-libbsd-de261e0404e1fe54544275fc57d5b982df4f42b4.tar.bz2 |
Update to FreeBSD head 2017-06-01
Git mirror commit dfb26efac4ce9101dda240e94d9ab53f80a9e131.
Update #3472.
Diffstat (limited to 'freebsd/sys')
146 files changed, 2118 insertions, 1400 deletions
diff --git a/freebsd/sys/bsm/audit.h b/freebsd/sys/bsm/audit.h index af9622af..57edb5e4 100644 --- a/freebsd/sys/bsm/audit.h +++ b/freebsd/sys/bsm/audit.h @@ -183,13 +183,13 @@ typedef u_int32_t au_class_t; typedef u_int64_t au_asflgs_t __attribute__ ((aligned (8))); struct au_tid { - dev_t port; + u_int32_t port; /* XXX dev_t compatibility */ u_int32_t machine; }; typedef struct au_tid au_tid_t; struct au_tid_addr { - dev_t at_port; + u_int32_t at_port; /* XXX dev_t compatibility */ u_int32_t at_type; u_int32_t at_addr[4]; }; diff --git a/freebsd/sys/cam/ata/ata_all.h b/freebsd/sys/cam/ata/ata_all.h index ea902d09..a279aa91 100644 --- a/freebsd/sys/cam/ata/ata_all.h +++ b/freebsd/sys/cam/ata/ata_all.h @@ -110,7 +110,9 @@ int ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb); int ata_res_sbuf(struct ata_res *res, struct sbuf *sb); void ata_print_ident(struct ata_params *ident_data); +void ata_print_ident_sbuf(struct ata_params *ident_data, struct sbuf *sb); void ata_print_ident_short(struct ata_params *ident_data); +void ata_print_ident_short_sbuf(struct ata_params *ident_data, struct sbuf *sb); uint32_t ata_logical_sector_size(struct ata_params *ident_data); uint64_t ata_physical_sector_size(struct ata_params *ident_data); @@ -150,7 +152,9 @@ int ata_identify_match(caddr_t identbuffer, caddr_t table_entry); int ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry); void semb_print_ident(struct sep_identify_data *ident_data); +void semb_print_ident_sbuf(struct sep_identify_data *ident_data, struct sbuf *sb); void semb_print_ident_short(struct sep_identify_data *ident_data); +void semb_print_ident_short_sbuf(struct sep_identify_data *ident_data, struct sbuf *sb); void semb_receive_diagnostic_results(struct ccb_ataio *ataio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*), diff --git a/freebsd/sys/cam/scsi/scsi_all.c b/freebsd/sys/cam/scsi/scsi_all.c index 1c3a8c3b..99f6c37d 100644 --- a/freebsd/sys/cam/scsi/scsi_all.c +++ b/freebsd/sys/cam/scsi/scsi_all.c @@ -1621,7 +1621,7 @@ static struct asc_table_entry asc_table[] = { { SST(0x20, 0x01, SS_RDEF, /* XXX TBD */ "Access denied - initiator pending-enrolled") }, /* DT PWROMAEBK */ - { SST(0x20, 0x02, SS_RDEF, /* XXX TBD */ + { SST(0x20, 0x02, SS_FATAL | EPERM, "Access denied - no access rights") }, /* DT PWROMAEBK */ { SST(0x20, 0x03, SS_RDEF, /* XXX TBD */ @@ -5178,7 +5178,7 @@ scsi_sense_print(struct ccb_scsiio *csio) sbuf_finish(&sb); - printf("%s", sbuf_data(&sb)); + sbuf_putbuf(&sb); } #else /* !_KERNEL */ @@ -5373,11 +5373,10 @@ scsi_get_ascq(struct scsi_sense_data *sense_data, u_int sense_len, * for this routine to function properly. */ void -scsi_print_inquiry(struct scsi_inquiry_data *inq_data) +scsi_print_inquiry_sbuf(struct sbuf *sb, struct scsi_inquiry_data *inq_data) { u_int8_t type; char *dtype, *qtype; - char vendor[16], product[48], revision[16], rstr[12]; type = SID_TYPE(inq_data); @@ -5466,41 +5465,55 @@ scsi_print_inquiry(struct scsi_inquiry_data *inq_data) break; } - cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor), - sizeof(vendor)); - cam_strvis(product, inq_data->product, sizeof(inq_data->product), - sizeof(product)); - cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision), - sizeof(revision)); + scsi_print_inquiry_short_sbuf(sb, inq_data); + + sbuf_printf(sb, "%s %s ", SID_IS_REMOVABLE(inq_data) ? "Removable" : "Fixed", dtype); if (SID_ANSI_REV(inq_data) == SCSI_REV_0) - snprintf(rstr, sizeof(rstr), "SCSI"); + sbuf_printf(sb, "SCSI "); else if (SID_ANSI_REV(inq_data) <= SCSI_REV_SPC) { - snprintf(rstr, sizeof(rstr), "SCSI-%d", - SID_ANSI_REV(inq_data)); + sbuf_printf(sb, "SCSI-%d ", SID_ANSI_REV(inq_data)); } else { - snprintf(rstr, sizeof(rstr), "SPC-%d SCSI", - SID_ANSI_REV(inq_data) - 2); + sbuf_printf(sb, "SPC-%d SCSI ", SID_ANSI_REV(inq_data) - 2); } - printf("<%s %s %s> %s %s %s device%s\n", - vendor, product, revision, - SID_IS_REMOVABLE(inq_data) ? "Removable" : "Fixed", - dtype, rstr, qtype); + sbuf_printf(sb, "device%s\n", qtype); } void -scsi_print_inquiry_short(struct scsi_inquiry_data *inq_data) +scsi_print_inquiry(struct scsi_inquiry_data *inq_data) +{ + struct sbuf sb; + char buffer[120]; + + sbuf_new(&sb, buffer, 120, SBUF_FIXEDLEN); + scsi_print_inquiry_sbuf(&sb, inq_data); + sbuf_finish(&sb); + sbuf_putbuf(&sb); +} + +void +scsi_print_inquiry_short_sbuf(struct sbuf *sb, struct scsi_inquiry_data *inq_data) { - char vendor[16], product[48], revision[16]; - cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor), - sizeof(vendor)); - cam_strvis(product, inq_data->product, sizeof(inq_data->product), - sizeof(product)); - cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision), - sizeof(revision)); + sbuf_printf(sb, "<"); + cam_strvis_sbuf(sb, inq_data->vendor, sizeof(inq_data->vendor), 0); + sbuf_printf(sb, " "); + cam_strvis_sbuf(sb, inq_data->product, sizeof(inq_data->product), 0); + sbuf_printf(sb, " "); + cam_strvis_sbuf(sb, inq_data->revision, sizeof(inq_data->revision), 0); + sbuf_printf(sb, "> "); +} + +void +scsi_print_inquiry_short(struct scsi_inquiry_data *inq_data) +{ + struct sbuf sb; + char buffer[84]; - printf("<%s %s %s>", vendor, product, revision); + sbuf_new(&sb, buffer, 84, SBUF_FIXEDLEN); + scsi_print_inquiry_short_sbuf(&sb, inq_data); + sbuf_finish(&sb); + sbuf_putbuf(&sb); } #ifndef __rtems__ diff --git a/freebsd/sys/cam/scsi/scsi_all.h b/freebsd/sys/cam/scsi/scsi_all.h index f85d285e..3a11a15e 100644 --- a/freebsd/sys/cam/scsi/scsi_all.h +++ b/freebsd/sys/cam/scsi/scsi_all.h @@ -565,6 +565,7 @@ struct scsi_log_sense #define SLS_ERROR_LASTN_PAGE 0x07 #define SLS_LOGICAL_BLOCK_PROVISIONING 0x0c #define SLS_SELF_TEST_PAGE 0x10 +#define SLS_SOLID_STATE_MEDIA 0x11 #define SLS_STAT_AND_PERF 0x19 #define SLS_IE_PAGE 0x2f #define SLS_PAGE_CTRL_MASK 0xC0 @@ -624,6 +625,13 @@ struct scsi_log_param_header { u_int8_t param_len; }; +struct scsi_log_media_pct_used { + struct scsi_log_param_header hdr; +#define SLP_SS_MEDIA_PCT_USED 0x0001 + uint8_t reserved[3]; + uint8_t pct_used; +}; + struct scsi_log_stat_and_perf { struct scsi_log_param_header hdr; #define SLP_SAP 0x0001 @@ -3820,7 +3828,11 @@ char * scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string, void scsi_cdb_sbuf(u_int8_t *cdb_ptr, struct sbuf *sb); void scsi_print_inquiry(struct scsi_inquiry_data *inq_data); +void scsi_print_inquiry_sbuf(struct sbuf *sb, + struct scsi_inquiry_data *inq_data); void scsi_print_inquiry_short(struct scsi_inquiry_data *inq_data); +void scsi_print_inquiry_short_sbuf(struct sbuf *sb, + struct scsi_inquiry_data *inq_data); u_int scsi_calc_syncsrate(u_int period_factor); u_int scsi_calc_syncparam(u_int period); diff --git a/freebsd/sys/crypto/des/des_enc.c b/freebsd/sys/crypto/des/des_enc.c index f0ac924d..93fa744c 100644 --- a/freebsd/sys/crypto/des/des_enc.c +++ b/freebsd/sys/crypto/des/des_enc.c @@ -71,14 +71,14 @@ extern const DES_LONG des_SPtrans[8][64]; void des_encrypt1(DES_LONG *data, des_key_schedule ks, int enc) { - register DES_LONG l,r,t,u; + DES_LONG l,r,t,u; #ifdef DES_PTR - register const unsigned char *des_SP=(const unsigned char *)des_SPtrans; + const unsigned char *des_SP=(const unsigned char *)des_SPtrans; #endif #ifndef DES_UNROLL - register int i; + int i; #endif - register DES_LONG *s; + DES_LONG *s; r=data[0]; l=data[1]; @@ -169,14 +169,14 @@ void des_encrypt1(DES_LONG *data, des_key_schedule ks, int enc) void des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc) { - register DES_LONG l,r,t,u; + DES_LONG l,r,t,u; #ifdef DES_PTR - register const unsigned char *des_SP=(const unsigned char *)des_SPtrans; + const unsigned char *des_SP=(const unsigned char *)des_SPtrans; #endif #ifndef DES_UNROLL - register int i; + int i; #endif - register DES_LONG *s; + DES_LONG *s; r=data[0]; l=data[1]; @@ -261,7 +261,7 @@ void des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc) void des_encrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2, des_key_schedule ks3) { - register DES_LONG l,r; + DES_LONG l,r; l=data[0]; r=data[1]; @@ -281,7 +281,7 @@ void des_encrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2, void des_decrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2, des_key_schedule ks3) { - register DES_LONG l,r; + DES_LONG l,r; l=data[0]; r=data[1]; diff --git a/freebsd/sys/crypto/des/des_setkey.c b/freebsd/sys/crypto/des/des_setkey.c index 01adb7d1..966b17d0 100644 --- a/freebsd/sys/crypto/des/des_setkey.c +++ b/freebsd/sys/crypto/des/des_setkey.c @@ -174,10 +174,10 @@ int des_set_key_checked(des_cblock *key, des_key_schedule schedule) void des_set_key_unchecked(des_cblock *key, des_key_schedule schedule) { static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; - register DES_LONG c,d,t,s,t2; - register const unsigned char *in; - register DES_LONG *k; - register int i; + DES_LONG c,d,t,s,t2; + const unsigned char *in; + DES_LONG *k; + int i; k = &schedule->ks.deslong[0]; in = &(*key)[0]; diff --git a/freebsd/sys/dev/e1000/e1000_ich8lan.c b/freebsd/sys/dev/e1000/e1000_ich8lan.c index 6f6cb582..a620d126 100644 --- a/freebsd/sys/dev/e1000/e1000_ich8lan.c +++ b/freebsd/sys/dev/e1000/e1000_ich8lan.c @@ -1498,24 +1498,24 @@ s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg); if (ret_val) goto release; - phy_reg &= ~(I218_ULP_CONFIG1_IND | - I218_ULP_CONFIG1_STICKY_ULP | - I218_ULP_CONFIG1_RESET_TO_SMBUS | - I218_ULP_CONFIG1_WOL_HOST | - I218_ULP_CONFIG1_INBAND_EXIT | - I218_ULP_CONFIG1_EN_ULP_LANPHYPC | - I218_ULP_CONFIG1_DIS_CLR_STICKY_ON_PERST | - I218_ULP_CONFIG1_DISABLE_SMB_PERST); - e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); - - /* Commit ULP changes by starting auto ULP configuration */ - phy_reg |= I218_ULP_CONFIG1_START; - e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); - - /* Clear Disable SMBus Release on PERST# in MAC */ - mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM7); - mac_reg &= ~E1000_FEXTNVM7_DISABLE_SMB_PERST; - E1000_WRITE_REG(hw, E1000_FEXTNVM7, mac_reg); + phy_reg &= ~(I218_ULP_CONFIG1_IND | + I218_ULP_CONFIG1_STICKY_ULP | + I218_ULP_CONFIG1_RESET_TO_SMBUS | + I218_ULP_CONFIG1_WOL_HOST | + I218_ULP_CONFIG1_INBAND_EXIT | + I218_ULP_CONFIG1_EN_ULP_LANPHYPC | + I218_ULP_CONFIG1_DIS_CLR_STICKY_ON_PERST | + I218_ULP_CONFIG1_DISABLE_SMB_PERST); + e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); + + /* Commit ULP changes by starting auto ULP configuration */ + phy_reg |= I218_ULP_CONFIG1_START; + e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); + + /* Clear Disable SMBus Release on PERST# in MAC */ + mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM7); + mac_reg &= ~E1000_FEXTNVM7_DISABLE_SMB_PERST; + E1000_WRITE_REG(hw, E1000_FEXTNVM7, mac_reg); release: hw->phy.ops.release(hw); @@ -1558,13 +1558,13 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) if (!mac->get_link_status) return E1000_SUCCESS; - /* First we want to see if the MII Status Register reports - * link. If so, then we want to get the current speed/duplex - * of the PHY. - */ - ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); - if (ret_val) - return ret_val; + /* First we want to see if the MII Status Register reports + * link. If so, then we want to get the current speed/duplex + * of the PHY. + */ + ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); + if (ret_val) + return ret_val; if (hw->mac.type == e1000_pchlan) { ret_val = e1000_k1_gig_workaround_hv(hw, link); diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c index 2054f994..69381438 100644 --- a/freebsd/sys/dev/e1000/if_em.c +++ b/freebsd/sys/dev/e1000/if_em.c @@ -3707,6 +3707,11 @@ em_update_stats_counters(struct adapter *adapter) adapter->stats.xonrxc += E1000_READ_REG(&adapter->hw, E1000_XONRXC); adapter->stats.xontxc += E1000_READ_REG(&adapter->hw, E1000_XONTXC); adapter->stats.xoffrxc += E1000_READ_REG(&adapter->hw, E1000_XOFFRXC); + /* + ** For watchdog management we need to know if we have been + ** paused during the last interval, so capture that here. + */ + adapter->shared->isc_pause_frames = adapter->stats.xoffrxc; adapter->stats.xofftxc += E1000_READ_REG(&adapter->hw, E1000_XOFFTXC); adapter->stats.fcruc += E1000_READ_REG(&adapter->hw, E1000_FCRUC); adapter->stats.prc64 += E1000_READ_REG(&adapter->hw, E1000_PRC64); @@ -3885,9 +3890,6 @@ em_add_hw_stats(struct adapter *adapter) SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO, "tx_irq", CTLFLAG_RD, &txr->tx_irq, "Queue MSI-X Transmit Interrupts"); - SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO, "no_desc_avail", - CTLFLAG_RD, &txr->no_desc_avail, - "Queue No Descriptor Available"); } for (int j = 0; j < adapter->rx_num_queues; j++, rx_que++) { diff --git a/freebsd/sys/dev/e1000/if_em.h b/freebsd/sys/dev/e1000/if_em.h index cfd1388d..79af551c 100644 --- a/freebsd/sys/dev/e1000/if_em.h +++ b/freebsd/sys/dev/e1000/if_em.h @@ -368,7 +368,6 @@ struct tx_ring { void *tag; struct resource *res; unsigned long tx_irq; - unsigned long no_desc_avail; /* Saved csum offloading context information */ int csum_flags; diff --git a/freebsd/sys/dev/fdt/fdt_common.c b/freebsd/sys/dev/fdt/fdt_common.c index f1f51081..b149695c 100644 --- a/freebsd/sys/dev/fdt/fdt_common.c +++ b/freebsd/sys/dev/fdt/fdt_common.c @@ -424,7 +424,7 @@ fdt_addrsize_cells(phandle_t node, int *addr_cells, int *size_cells) */ cell_size = sizeof(cell); if (OF_getencprop(node, "#address-cells", &cell, cell_size) < cell_size) - *addr_cells = 2; + cell = 2; *addr_cells = (int)cell; if (OF_getencprop(node, "#size-cells", &cell, cell_size) < cell_size) diff --git a/freebsd/sys/dev/ffec/if_ffec.c b/freebsd/sys/dev/ffec/if_ffec.c index 7660e2c7..b9a0d668 100644 --- a/freebsd/sys/dev/ffec/if_ffec.c +++ b/freebsd/sys/dev/ffec/if_ffec.c @@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$"); #include <netinet/in.h> #include <netinet/ip.h> +#include <dev/fdt/fdt_common.h> #include <dev/ffec/if_ffecreg.h> #include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus_subr.h> @@ -121,6 +122,7 @@ static struct ofw_compat_data compat_data[] = { {"fsl,imx51-fec", FECTYPE_GENERIC}, {"fsl,imx53-fec", FECTYPE_IMX53}, {"fsl,imx6q-fec", FECTYPE_IMX6 | FECFLAG_GBE | FECFLAG_RACC}, + {"fsl,imx6ul-fec", FECTYPE_IMX6}, {"fsl,mvf600-fec", FECTYPE_MVF | FECFLAG_RACC}, {"fsl,mvf-fec", FECTYPE_MVF}, {"fsl,imx7d-fec", FECTYPE_IMX6 | FECFLAG_GBE | FECFLAG_AVB | @@ -1702,8 +1704,9 @@ ffec_attach(device_t dev) struct ffec_softc *sc; struct ifnet *ifp = NULL; struct mbuf *m; + void *dummy; phandle_t ofw_node; - int error, rid, irq; + int error, phynum, rid, irq; uint8_t eaddr[ETHER_ADDR_LEN]; char phy_conn_name[32]; uint32_t idx, mscr; @@ -2017,8 +2020,11 @@ ffec_attach(device_t dev) ffec_miigasket_setup(sc); /* Attach the mii driver. */ + if (fdt_get_phyaddr(ofw_node, dev, &phynum, &dummy) != 0) { + phynum = MII_PHY_ANY; + } error = mii_attach(dev, &sc->miibus, ifp, ffec_media_change, - ffec_media_status, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, + ffec_media_status, BMSR_DEFCAPMASK, phynum, MII_OFFSET_ANY, (sc->fectype & FECTYPE_MVF) ? MIIF_FORCEANEG : 0); if (error != 0) { device_printf(dev, "PHY attach failed\n"); diff --git a/freebsd/sys/dev/fxp/if_fxp.c b/freebsd/sys/dev/fxp/if_fxp.c index e4cfc2ac..20bdc988 100644 --- a/freebsd/sys/dev/fxp/if_fxp.c +++ b/freebsd/sys/dev/fxp/if_fxp.c @@ -2214,18 +2214,15 @@ fxp_stop(struct fxp_softc *sc) * Release any xmit buffers. */ txp = sc->fxp_desc.tx_list; - if (txp != NULL) { - for (i = 0; i < FXP_NTXCB; i++) { - if (txp[i].tx_mbuf != NULL) { - bus_dmamap_sync(sc->fxp_txmtag, txp[i].tx_map, - BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->fxp_txmtag, - txp[i].tx_map); - m_freem(txp[i].tx_mbuf); - txp[i].tx_mbuf = NULL; - /* clear this to reset csum offload bits */ - txp[i].tx_cb->tbd[0].tb_addr = 0; - } + for (i = 0; i < FXP_NTXCB; i++) { + if (txp[i].tx_mbuf != NULL) { + bus_dmamap_sync(sc->fxp_txmtag, txp[i].tx_map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->fxp_txmtag, txp[i].tx_map); + m_freem(txp[i].tx_mbuf); + txp[i].tx_mbuf = NULL; + /* clear this to reset csum offload bits */ + txp[i].tx_cb->tbd[0].tb_addr = 0; } } bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, diff --git a/freebsd/sys/dev/mii/micphy.c b/freebsd/sys/dev/mii/micphy.c index a108a9d2..01e75357 100644 --- a/freebsd/sys/dev/mii/micphy.c +++ b/freebsd/sys/dev/mii/micphy.c @@ -78,10 +78,13 @@ __FBSDID("$FreeBSD$"); #define MII_KSZ9031_TX_DATA_PAD_SKEW 0x6 #define MII_KSZ9031_CLOCK_PAD_SKEW 0x8 +#define MII_KSZ8081_PHYCTL2 0x1f + #define PS_TO_REG(p) ((p) / 200) static int micphy_probe(device_t); static int micphy_attach(device_t); +static void micphy_reset(struct mii_softc *); static int micphy_service(struct mii_softc *, struct mii_data *, int); static device_method_t micphy_methods[] = { @@ -104,6 +107,7 @@ static driver_t micphy_driver = { DRIVER_MODULE(micphy, miibus, micphy_driver, micphy_devclass, 0, 0); static const struct mii_phydesc micphys[] = { + MII_PHY_DESC(MICREL, KSZ8081), MII_PHY_DESC(MICREL, KSZ9021), MII_PHY_DESC(MICREL, KSZ9031), MII_PHY_END @@ -112,7 +116,7 @@ static const struct mii_phydesc micphys[] = { static const struct mii_phy_funcs micphy_funcs = { micphy_service, ukphy_status, - mii_phy_reset + micphy_reset }; static uint32_t @@ -259,6 +263,10 @@ micphy_attach(device_t dev) mii_phy_dev_attach(dev, MIIF_NOMANPAUSE, &micphy_funcs, 1); mii_phy_setmedia(sc); + /* Nothing further to configure for 8081 model. */ + if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081) + return (0); + miibus = device_get_parent(dev); parent = device_get_parent(miibus); @@ -273,6 +281,24 @@ micphy_attach(device_t dev) return (0); } +static void +micphy_reset(struct mii_softc *sc) +{ + int reg; + + /* + * The 8081 has no "sticky bits" that survive a soft reset; several bits + * in the Phy Control Register 2 must be preserved across the reset. + * These bits are set up by the bootloader; they control how the phy + * interfaces to the board (such as clock frequency and LED behavior). + */ + if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081) + reg = PHY_READ(sc, MII_KSZ8081_PHYCTL2); + mii_phy_reset(sc); + if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ8081) + PHY_WRITE(sc, MII_KSZ8081_PHYCTL2, reg); +} + static int micphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { diff --git a/freebsd/sys/dev/pci/pci_pci.c b/freebsd/sys/dev/pci/pci_pci.c index c6d07157..ed4c1b50 100644 --- a/freebsd/sys/dev/pci/pci_pci.c +++ b/freebsd/sys/dev/pci/pci_pci.c @@ -78,7 +78,7 @@ static void pcib_pcie_ab_timeout(void *arg); static void pcib_pcie_cc_timeout(void *arg); static void pcib_pcie_dll_timeout(void *arg); #endif -static int pcib_request_feature(device_t pcib, device_t dev, +static int pcib_request_feature_default(device_t pcib, device_t dev, enum pci_feature feature); static device_method_t pcib_methods[] = { @@ -123,7 +123,7 @@ static device_method_t pcib_methods[] = { DEVMETHOD(pcib_try_enable_ari, pcib_try_enable_ari), DEVMETHOD(pcib_ari_enabled, pcib_ari_enabled), DEVMETHOD(pcib_decode_rid, pcib_ari_decode_rid), - DEVMETHOD(pcib_request_feature, pcib_request_feature), + DEVMETHOD(pcib_request_feature, pcib_request_feature_default), DEVMETHOD_END }; @@ -966,8 +966,7 @@ pcib_probe_hotplug(struct pcib_softc *sc) * Now that we're sure we want to do hot plug, ask the * firmware, if any, if that's OK. */ - if (pcib_request_feature(device_get_parent(device_get_parent(dev)), dev, - PCI_FEATURE_HP) != 0) { + if (pcib_request_feature(dev, PCI_FEATURE_HP) != 0) { if (bootverbose) device_printf(dev, "Unable to activate hot plug feature.\n"); return; @@ -2865,6 +2864,17 @@ pcib_request_feature_allow(device_t pcib, device_t dev, return (0); } +int +pcib_request_feature(device_t dev, enum pci_feature feature) +{ + + /* + * Invoke PCIB_REQUEST_FEATURE of this bridge first in case + * the firmware overrides the method of PCI-PCI bridges. + */ + return (PCIB_REQUEST_FEATURE(dev, dev, feature)); +} + /* * Pass the request to use this PCI feature up the tree. Either there's a * firmware like ACPI that's using this feature that will approve (or deny) the @@ -2873,7 +2883,8 @@ pcib_request_feature_allow(device_t pcib, device_t dev, * to make use of the feature or render it harmless. */ static int -pcib_request_feature(device_t pcib, device_t dev, enum pci_feature feature) +pcib_request_feature_default(device_t pcib, device_t dev, + enum pci_feature feature) { device_t bus; diff --git a/freebsd/sys/dev/pci/pcib_private.h b/freebsd/sys/dev/pci/pcib_private.h index 1004e133..5482e12d 100644 --- a/freebsd/sys/dev/pci/pcib_private.h +++ b/freebsd/sys/dev/pci/pcib_private.h @@ -193,6 +193,7 @@ int pcib_get_id(device_t pcib, device_t dev, enum pci_id_type type, uintptr_t *id); void pcib_decode_rid(device_t pcib, uint16_t rid, int *bus, int *slot, int *func); +int pcib_request_feature(device_t dev, enum pci_feature feature); int pcib_request_feature_allow(device_t pcib, device_t dev, enum pci_feature feature); #endif diff --git a/freebsd/sys/dev/rtwn/if_rtwn.c b/freebsd/sys/dev/rtwn/if_rtwn.c index 6adbee68..1f057dad 100644 --- a/freebsd/sys/dev/rtwn/if_rtwn.c +++ b/freebsd/sys/dev/rtwn/if_rtwn.c @@ -93,9 +93,9 @@ static struct ieee80211vap *rtwn_vap_create(struct ieee80211com *, static void rtwn_vap_delete(struct ieee80211vap *); static int rtwn_read_chipid(struct rtwn_softc *); static int rtwn_ioctl_reset(struct ieee80211vap *, u_long); -#ifndef RTWN_WITHOUT_UCODE static void rtwn_set_media_status(struct rtwn_softc *, union sec_param *); +#ifndef RTWN_WITHOUT_UCODE static int rtwn_tx_fwpkt_check(struct rtwn_softc *, struct ieee80211vap *); static int rtwn_construct_nulldata(struct rtwn_softc *, @@ -705,13 +705,13 @@ rtwn_ioctl_reset(struct ieee80211vap *vap, u_long cmd) return (error); } -#ifndef RTWN_WITHOUT_UCODE static void rtwn_set_media_status(struct rtwn_softc *sc, union sec_param *data) { sc->sc_set_media_status(sc, data->macid); } +#ifndef RTWN_WITHOUT_UCODE static int rtwn_tx_fwpkt_check(struct rtwn_softc *sc, struct ieee80211vap *vap) { @@ -1745,11 +1745,9 @@ rtwn_newassoc(struct ieee80211_node *ni, int isnew __unused) return; } -#ifndef RTWN_WITHOUT_UCODE /* Notify firmware. */ id |= RTWN_MACID_VALID; rtwn_cmd_sleepable(sc, &id, sizeof(id), rtwn_set_media_status); -#endif } static void @@ -1761,10 +1759,8 @@ rtwn_node_free(struct ieee80211_node *ni) RTWN_NT_LOCK(sc); if (un->id != RTWN_MACID_UNDEFINED) { sc->node_list[un->id] = NULL; -#ifndef RTWN_WITHOUT_UCODE rtwn_cmd_sleepable(sc, &un->id, sizeof(un->id), rtwn_set_media_status); -#endif } RTWN_NT_UNLOCK(sc); diff --git a/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c b/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c index 8b8ad7a1..fe9d58b7 100644 --- a/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c +++ b/freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c @@ -112,7 +112,7 @@ r88e_get_txpower(struct rtwn_softc *sc, int chain, for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++) power[ridx] = base->pwr[0][ridx]; } - for (ridx = RTWN_RIDX_OFDM6; ridx < RTWN_RIDX_COUNT; ridx++) { + for (ridx = RTWN_RIDX_OFDM6; ridx <= max_mcs; ridx++) { if (rs->regulatory == 3) power[ridx] = base->pwr[0][ridx]; else if (rs->regulatory == 1) { diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c index dc6b3038..c5d72f87 100644 --- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c +++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c @@ -231,13 +231,13 @@ r92c_set_txpower(struct rtwn_softc *sc, struct ieee80211_channel *c) rtwn_r92c_get_txpower(sc, i, c, power); #ifdef RTWN_DEBUG if (sc->sc_debug & RTWN_DEBUG_TXPWR) { - int ridx; + int max_mcs, ridx; + + max_mcs = RTWN_RIDX_MCS(sc->ntxchains * 8 - 1); /* Dump per-rate Tx power values. */ printf("Tx power for chain %d:\n", i); - for (ridx = RTWN_RIDX_CCK1; - ridx < RTWN_RIDX_COUNT; - ridx++) + for (ridx = RTWN_RIDX_CCK1; ridx <= max_mcs; ridx++) printf("Rate %d = %u\n", ridx, power[ridx]); } #endif diff --git a/freebsd/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c b/freebsd/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c index d237731c..ce1e49f4 100644 --- a/freebsd/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c +++ b/freebsd/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c @@ -143,11 +143,13 @@ r92eu_attach(struct rtwn_usb_softc *uc) sc->sc_vap_preattach = rtwn_nop_softc_vap; sc->sc_postattach = rtwn_nop_softc; sc->sc_detach_private = r92e_detach_private; - sc->sc_set_media_status = r92e_set_media_status; #ifndef RTWN_WITHOUT_UCODE + sc->sc_set_media_status = r92e_set_media_status; sc->sc_set_rsvd_page = r88e_set_rsvd_page; sc->sc_set_pwrmode = r92e_set_pwrmode; sc->sc_set_rssi = rtwn_nop_softc; /* XXX TODO? */ +#else + sc->sc_set_media_status = rtwn_nop_softc_int; #endif sc->sc_beacon_init = r12a_beacon_init; sc->sc_beacon_enable = r92c_beacon_enable; diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a_chan.c b/freebsd/sys/dev/rtwn/rtl8812a/r12a_chan.c index 5249c494..27a71bd9 100644 --- a/freebsd/sys/dev/rtwn/rtl8812a/r12a_chan.c +++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a_chan.c @@ -249,7 +249,7 @@ r12a_get_txpower(struct rtwn_softc *sc, int chain, if (sc->sc_debug & RTWN_DEBUG_TXPWR) { /* Dump per-rate Tx power values. */ printf("Tx power for chain %d:\n", chain); - for (ridx = RTWN_RIDX_CCK1; ridx < RTWN_RIDX_COUNT; ridx++) + for (ridx = RTWN_RIDX_CCK1; ridx <= max_mcs; ridx++) printf("Rate %d = %u\n", ridx, power[ridx]); } #endif diff --git a/freebsd/sys/dev/sdhci/sdhci.c b/freebsd/sys/dev/sdhci/sdhci.c index 8c1be21e..c87199a8 100644 --- a/freebsd/sys/dev/sdhci/sdhci.c +++ b/freebsd/sys/dev/sdhci/sdhci.c @@ -733,11 +733,11 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num) MMC_CAP_MMC_DDR52_180 | MMC_CAP_MMC_HS200_180 | MMC_CAP_MMC_HS400_180)) host_caps |= MMC_CAP_SIGNALING_180; - if (caps & SDHCI_CTRL2_DRIVER_TYPE_A) + if (caps2 & SDHCI_CAN_DRIVE_TYPE_A) host_caps |= MMC_CAP_DRIVER_TYPE_A; - if (caps & SDHCI_CTRL2_DRIVER_TYPE_C) + if (caps2 & SDHCI_CAN_DRIVE_TYPE_C) host_caps |= MMC_CAP_DRIVER_TYPE_C; - if (caps & SDHCI_CTRL2_DRIVER_TYPE_D) + if (caps2 & SDHCI_CAN_DRIVE_TYPE_D) host_caps |= MMC_CAP_DRIVER_TYPE_D; slot->host.caps = host_caps; @@ -771,9 +771,9 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num) (caps & SDHCI_CAN_VDD_180) ? " 1.8V" : "", (host_caps & MMC_CAP_SIGNALING_180) ? " 1.8V" : "", (host_caps & MMC_CAP_SIGNALING_120) ? " 1.2V" : "", - (caps & SDHCI_CTRL2_DRIVER_TYPE_A) ? "A" : "", - (caps & SDHCI_CTRL2_DRIVER_TYPE_C) ? "C" : "", - (caps & SDHCI_CTRL2_DRIVER_TYPE_D) ? "D" : "", + (caps2 & SDHCI_CAN_DRIVE_TYPE_A) ? "A" : "", + (caps2 & SDHCI_CAN_DRIVE_TYPE_C) ? "C" : "", + (caps2 & SDHCI_CAN_DRIVE_TYPE_D) ? "D" : "", (slot->opt & SDHCI_HAVE_DMA) ? "DMA" : "PIO"); if (host_caps & (MMC_CAP_MMC_DDR52 | MMC_CAP_MMC_HS200 | MMC_CAP_MMC_HS400 | MMC_CAP_MMC_ENH_STROBE)) @@ -1062,7 +1062,7 @@ sdhci_set_transfer_mode(struct sdhci_slot *slot, struct mmc_data *data) mode |= SDHCI_TRNS_MULTI; if (data->flags & MMC_DATA_READ) mode |= SDHCI_TRNS_READ; - if (slot->req->stop) + if (slot->req->stop && !(slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP)) mode |= SDHCI_TRNS_ACMD12; if (slot->flags & SDHCI_USE_DMA) mode |= SDHCI_TRNS_DMA; @@ -1307,7 +1307,8 @@ sdhci_finish_data(struct sdhci_slot *slot) slot->intmask |= SDHCI_INT_RESPONSE); } /* Unload rest of data from DMA buffer. */ - if (!slot->data_done && (slot->flags & SDHCI_USE_DMA)) { + if (!slot->data_done && (slot->flags & SDHCI_USE_DMA) && + slot->curcmd->data != NULL) { if (data->flags & MMC_DATA_READ) { left = data->len - slot->offset; bus_dmamap_sync(slot->dmatag, slot->dmamap, @@ -1345,17 +1346,18 @@ sdhci_start(struct sdhci_slot *slot) sdhci_start_command(slot, req->cmd); return; } -/* We don't need this until using Auto-CMD12 feature - if (!(slot->flags & STOP_STARTED) && req->stop) { + if ((slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP) && + !(slot->flags & STOP_STARTED) && req->stop) { slot->flags |= STOP_STARTED; sdhci_start_command(slot, req->stop); return; } -*/ if (sdhci_debug > 1) slot_printf(slot, "result: %d\n", req->cmd->error); if (!req->cmd->error && - (slot->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) { + ((slot->curcmd == req->stop && + (slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP)) || + (slot->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) { sdhci_reset(slot, SDHCI_RESET_CMD); sdhci_reset(slot, SDHCI_RESET_DATA); } diff --git a/freebsd/sys/dev/sdhci/sdhci.h b/freebsd/sys/dev/sdhci/sdhci.h index 0b299150..814f81ed 100644 --- a/freebsd/sys/dev/sdhci/sdhci.h +++ b/freebsd/sys/dev/sdhci/sdhci.h @@ -87,6 +87,8 @@ #define SDHCI_QUIRK_CAPS_BIT63_FOR_MMC_HS400 (1 << 26) /* Controller support for SDHCI_CTRL2_PRESET_VALUE is broken. */ #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 registers diff --git a/freebsd/sys/dev/usb/quirk/usb_quirk.c b/freebsd/sys/dev/usb/quirk/usb_quirk.c index ce57f114..a5fac1b3 100644 --- a/freebsd/sys/dev/usb/quirk/usb_quirk.c +++ b/freebsd/sys/dev/usb/quirk/usb_quirk.c @@ -97,7 +97,6 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(SILICONPORTALS, YAPPHONE, 0x100, 0x100, UQ_AU_INP_ASYNC), USB_QUIRK(LOGITECH, UN53B, 0x0000, 0xffff, UQ_NO_STRINGS), USB_QUIRK(REALTEK, RTL8196EU, 0x0000, 0xffff, UQ_CFG_INDEX_1), - USB_QUIRK(REALTEK, RTL8153, 0x0000, 0xffff, UQ_CFG_INDEX_1), USB_QUIRK(ELSA, MODEM1, 0x0000, 0xffff, UQ_CFG_INDEX_1), USB_QUIRK(PLANEX2, MZKUE150N, 0x0000, 0xffff, UQ_CFG_INDEX_1), USB_QUIRK(CISCOLINKSYS, USB3GIGV1, 0x0000, 0xffff, UQ_CFG_INDEX_1), diff --git a/freebsd/sys/dev/usb/usb_busdma.c b/freebsd/sys/dev/usb/usb_busdma.c index c0410d3e..446e36e6 100644 --- a/freebsd/sys/dev/usb/usb_busdma.c +++ b/freebsd/sys/dev/usb/usb_busdma.c @@ -234,7 +234,7 @@ struct usb_m_copy_in_arg { static int usbd_m_copy_in_cb(void *arg, void *src, uint32_t count) { - register struct usb_m_copy_in_arg *ua = arg; + struct usb_m_copy_in_arg *ua = arg; usbd_copy_in(ua->cache, ua->dst_offset, src, count); ua->dst_offset += count; diff --git a/freebsd/sys/fs/devfs/devfs_vnops.c b/freebsd/sys/fs/devfs/devfs_vnops.c index 9725d3fc..85c0af86 100644 --- a/freebsd/sys/fs/devfs/devfs_vnops.c +++ b/freebsd/sys/fs/devfs/devfs_vnops.c @@ -1330,6 +1330,7 @@ devfs_readdir(struct vop_readdir_args *ap) else de = dd; dp = dd->de_dirent; + MPASS(dp->d_reclen == GENERIC_DIRSIZ(dp)); if (dp->d_reclen > uio->uio_resid) break; dp->d_fileno = de->de_inode; diff --git a/freebsd/sys/i386/i386/in_cksum.c b/freebsd/sys/i386/i386/in_cksum.c index 34a7228f..6c8811be 100644 --- a/freebsd/sys/i386/i386/in_cksum.c +++ b/freebsd/sys/i386/i386/in_cksum.c @@ -265,9 +265,9 @@ in_cksum_skip(m, len, skip) int len; int skip; { - register u_short *w; - register unsigned sum = 0; - register int mlen = 0; + u_short *w; + unsigned sum = 0; + int mlen = 0; int byte_swapped = 0; union { char c[2]; u_short s; } su; diff --git a/freebsd/sys/kern/kern_intr.c b/freebsd/sys/kern/kern_intr.c index c3d30c31..fbb5a1e9 100644 --- a/freebsd/sys/kern/kern_intr.c +++ b/freebsd/sys/kern/kern_intr.c @@ -314,13 +314,11 @@ intr_event_create(struct intr_event **event, void *source, int flags, int irq, /* * Bind an interrupt event to the specified CPU. Note that not all * platforms support binding an interrupt to a CPU. For those - * platforms this request will fail. For supported platforms, any - * associated ithreads as well as the primary interrupt context will - * be bound to the specificed CPU. Using a cpu id of NOCPU unbinds + * platforms this request will fail. Using a cpu id of NOCPU unbinds * the interrupt event. */ -int -intr_event_bind(struct intr_event *ie, int cpu) +static int +_intr_event_bind(struct intr_event *ie, int cpu, bool bindirq, bool bindithread) { lwpid_t id; int error; @@ -340,35 +338,75 @@ intr_event_bind(struct intr_event *ie, int cpu) * If we have any ithreads try to set their mask first to verify * permissions, etc. */ - mtx_lock(&ie->ie_lock); - if (ie->ie_thread != NULL) { - id = ie->ie_thread->it_thread->td_tid; - mtx_unlock(&ie->ie_lock); - error = cpuset_setithread(id, cpu); - if (error) - return (error); - } else - mtx_unlock(&ie->ie_lock); - error = ie->ie_assign_cpu(ie->ie_source, cpu); - if (error) { + if (bindithread) { mtx_lock(&ie->ie_lock); if (ie->ie_thread != NULL) { - cpu = ie->ie_cpu; id = ie->ie_thread->it_thread->td_tid; mtx_unlock(&ie->ie_lock); - (void)cpuset_setithread(id, cpu); + error = cpuset_setithread(id, cpu); + if (error) + return (error); } else mtx_unlock(&ie->ie_lock); + } + if (bindirq) + error = ie->ie_assign_cpu(ie->ie_source, cpu); + if (error) { + if (bindithread) { + mtx_lock(&ie->ie_lock); + if (ie->ie_thread != NULL) { + cpu = ie->ie_cpu; + id = ie->ie_thread->it_thread->td_tid; + mtx_unlock(&ie->ie_lock); + (void)cpuset_setithread(id, cpu); + } else + mtx_unlock(&ie->ie_lock); + } return (error); } - mtx_lock(&ie->ie_lock); - ie->ie_cpu = cpu; - mtx_unlock(&ie->ie_lock); + if (bindirq) { + mtx_lock(&ie->ie_lock); + ie->ie_cpu = cpu; + mtx_unlock(&ie->ie_lock); + } return (error); } +/* + * Bind an interrupt event to the specified CPU. For supported platforms, any + * associated ithreads as well as the primary interrupt context will be bound + * to the specificed CPU. + */ +int +intr_event_bind(struct intr_event *ie, int cpu) +{ + + return (_intr_event_bind(ie, cpu, true, true)); +} + +/* + * Bind an interrupt event to the specified CPU, but do not bind associated + * ithreads. + */ +int +intr_event_bind_irqonly(struct intr_event *ie, int cpu) +{ + + return (_intr_event_bind(ie, cpu, true, false)); +} + +/* + * Bind an interrupt event's ithread to the specified CPU. + */ +int +intr_event_bind_ithread(struct intr_event *ie, int cpu) +{ + + return (_intr_event_bind(ie, cpu, false, true)); +} + static struct intr_event * intr_lookup(int irq) { @@ -385,7 +423,7 @@ intr_lookup(int irq) } int -intr_setaffinity(int irq, void *m) +intr_setaffinity(int irq, int mode, void *m) { struct intr_event *ie; cpuset_t *mask; @@ -409,26 +447,62 @@ intr_setaffinity(int irq, void *m) ie = intr_lookup(irq); if (ie == NULL) return (ESRCH); - return (intr_event_bind(ie, cpu)); + switch (mode) { + case CPU_WHICH_IRQ: + return (intr_event_bind(ie, cpu)); + case CPU_WHICH_INTRHANDLER: + return (intr_event_bind_irqonly(ie, cpu)); + case CPU_WHICH_ITHREAD: + return (intr_event_bind_ithread(ie, cpu)); + default: + return (EINVAL); + } } int -intr_getaffinity(int irq, void *m) +intr_getaffinity(int irq, int mode, void *m) { struct intr_event *ie; + struct thread *td; + struct proc *p; cpuset_t *mask; + lwpid_t id; + int error; mask = m; ie = intr_lookup(irq); if (ie == NULL) return (ESRCH); + + error = 0; CPU_ZERO(mask); - mtx_lock(&ie->ie_lock); - if (ie->ie_cpu == NOCPU) - CPU_COPY(cpuset_root, mask); - else - CPU_SET(ie->ie_cpu, mask); - mtx_unlock(&ie->ie_lock); + switch (mode) { + case CPU_WHICH_IRQ: + case CPU_WHICH_INTRHANDLER: + mtx_lock(&ie->ie_lock); + if (ie->ie_cpu == NOCPU) + CPU_COPY(cpuset_root, mask); + else + CPU_SET(ie->ie_cpu, mask); + mtx_unlock(&ie->ie_lock); + break; + case CPU_WHICH_ITHREAD: + mtx_lock(&ie->ie_lock); + if (ie->ie_thread == NULL) { + mtx_unlock(&ie->ie_lock); + CPU_COPY(cpuset_root, mask); + } else { + id = ie->ie_thread->it_thread->td_tid; + mtx_unlock(&ie->ie_lock); + error = cpuset_which(CPU_WHICH_TID, id, &p, &td, NULL); + if (error != 0) + return (error); + CPU_COPY(&td->td_cpuset->cs_mask, mask); + PROC_UNLOCK(p); + } + default: + return (EINVAL); + } return (0); } @@ -1225,7 +1299,7 @@ swi_sched(void *cookie, int flags) if (!(flags & SWI_DELAY)) { #ifndef __rtems__ - PCPU_INC(cnt.v_soft); + VM_CNT_INC(v_soft); #endif /* __rtems__ */ #ifdef INTR_FILTER error = intr_event_schedule_thread(ie, ie->ie_thread); diff --git a/freebsd/sys/kern/kern_mib.c b/freebsd/sys/kern/kern_mib.c index 6dc8a200..1f867dd4 100644 --- a/freebsd/sys/kern/kern_mib.c +++ b/freebsd/sys/kern/kern_mib.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sbuf.h> #include <sys/smp.h> #include <sys/sx.h> +#include <sys/vmmeter.h> #include <sys/sysctl.h> #include <sys/systm.h> #include <rtems/bsd/sys/unistd.h> diff --git a/freebsd/sys/kern/kern_synch.c b/freebsd/sys/kern/kern_synch.c index 8b7b9afa..3dfa4164 100644 --- a/freebsd/sys/kern/kern_synch.c +++ b/freebsd/sys/kern/kern_synch.c @@ -460,7 +460,7 @@ mi_switch(int flags, struct thread *newtd) td->td_incruntime += runtime; PCPU_SET(switchtime, new_switchtime); td->td_generation++; /* bump preempt-detect counter */ - PCPU_INC(cnt.v_swtch); + VM_CNT_INC(v_swtch); PCPU_SET(switchticks, ticks); 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); diff --git a/freebsd/sys/kern/kern_timeout.c b/freebsd/sys/kern/kern_timeout.c index 5427defa..e1f6209d 100644 --- a/freebsd/sys/kern/kern_timeout.c +++ b/freebsd/sys/kern/kern_timeout.c @@ -1670,7 +1670,7 @@ _callout_init_lock(struct callout *c, struct lock_object *lock, int flags) void adjust_timeout_calltodo(struct timeval *time_change) { - register struct callout *p; + struct callout *p; unsigned long delta_ticks; /* diff --git a/freebsd/sys/kern/subr_kobj.c b/freebsd/sys/kern/subr_kobj.c index 519630fb..7436535e 100644 --- a/freebsd/sys/kern/subr_kobj.c +++ b/freebsd/sys/kern/subr_kobj.c @@ -215,19 +215,11 @@ kobj_lookup_method(kobj_class_t cls, { kobj_method_t *ce; -#ifdef KOBJ_STATS - /* - * Correct for the 'hit' assumption in KOBJOPLOOKUP and record - * a 'miss'. - */ - kobj_lookup_hits--; - kobj_lookup_misses++; -#endif - ce = kobj_lookup_method_mi(cls, desc); if (!ce) ce = &desc->deflt; - *cep = ce; + if (cep) + *cep = ce; return ce; } diff --git a/freebsd/sys/kern/subr_prf.c b/freebsd/sys/kern/subr_prf.c index 2f3efe49..39f5826d 100644 --- a/freebsd/sys/kern/subr_prf.c +++ b/freebsd/sys/kern/subr_prf.c @@ -1289,4 +1289,11 @@ sbuf_putbuf(struct sbuf *sb) printf("%s", sbuf_data(sb)); } #endif +#else /* __rtems__ */ +void +sbuf_putbuf(struct sbuf *sb) +{ + + printf("%s", sbuf_data(sb)); +} #endif /* __rtems__ */ diff --git a/freebsd/sys/kern/sys_socket.c b/freebsd/sys/kern/sys_socket.c index 3ffb1839..8d87c51b 100644 --- a/freebsd/sys/kern/sys_socket.c +++ b/freebsd/sys/kern/sys_socket.c @@ -576,18 +576,23 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) kif->kf_type = KF_TYPE_SOCKET; so = fp->f_data; - kif->kf_sock_domain = so->so_proto->pr_domain->dom_family; - kif->kf_sock_type = so->so_type; - kif->kf_sock_protocol = so->so_proto->pr_protocol; + kif->kf_un.kf_sock.kf_sock_domain0 = + so->so_proto->pr_domain->dom_family; + kif->kf_un.kf_sock.kf_sock_type0 = so->so_type; + kif->kf_un.kf_sock.kf_sock_protocol0 = so->so_proto->pr_protocol; kif->kf_un.kf_sock.kf_sock_pcb = (uintptr_t)so->so_pcb; - switch (kif->kf_sock_domain) { + switch (kif->kf_un.kf_sock.kf_sock_domain0) { case AF_INET: case AF_INET6: - if (kif->kf_sock_protocol == IPPROTO_TCP) { + if (kif->kf_un.kf_sock.kf_sock_protocol0 == IPPROTO_TCP) { if (so->so_pcb != NULL) { inpcb = (struct inpcb *)(so->so_pcb); kif->kf_un.kf_sock.kf_sock_inpcb = (uintptr_t)inpcb->inp_ppcb; + kif->kf_un.kf_sock.kf_sock_sendq = + sbused(&so->so_snd); + kif->kf_un.kf_sock.kf_sock_recvq = + sbused(&so->so_rcv); } } break; @@ -601,18 +606,24 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) so->so_rcv.sb_state; kif->kf_un.kf_sock.kf_sock_snd_sb_state = so->so_snd.sb_state; + kif->kf_un.kf_sock.kf_sock_sendq = + sbused(&so->so_snd); + kif->kf_un.kf_sock.kf_sock_recvq = + sbused(&so->so_rcv); } } break; } error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); - if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_local)) { - bcopy(sa, &kif->kf_sa_local, sa->sa_len); + if (error == 0 && + sa->sa_len <= sizeof(kif->kf_un.kf_sock.kf_sa_local)) { + bcopy(sa, &kif->kf_un.kf_sock.kf_sa_local, sa->sa_len); free(sa, M_SONAME); } error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa); - if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) { - bcopy(sa, &kif->kf_sa_peer, sa->sa_len); + if (error == 0 && + sa->sa_len <= sizeof(kif->kf_un.kf_sock.kf_sa_peer)) { + bcopy(sa, &kif->kf_un.kf_sock.kf_sa_peer, sa->sa_len); free(sa, M_SONAME); } strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name, diff --git a/freebsd/sys/kern/tty.c b/freebsd/sys/kern/tty.c index 6e4246b6..7d8400c7 100644 --- a/freebsd/sys/kern/tty.c +++ b/freebsd/sys/kern/tty.c @@ -1220,7 +1220,7 @@ tty_to_xtty(struct tty *tp, struct xtty *xt) xt->xt_pgid = tp->t_pgrp ? tp->t_pgrp->pg_id : 0; xt->xt_sid = tp->t_session ? tp->t_session->s_sid : 0; xt->xt_flags = tp->t_flags; - xt->xt_dev = tp->t_dev ? dev2udev(tp->t_dev) : NODEV; + xt->xt_dev = tp->t_dev ? dev2udev(tp->t_dev) : (uint32_t)NODEV; } static int diff --git a/freebsd/sys/kern/uipc_sockbuf.c b/freebsd/sys/kern/uipc_sockbuf.c index d6c3b04b..04193c29 100644 --- a/freebsd/sys/kern/uipc_sockbuf.c +++ b/freebsd/sys/kern/uipc_sockbuf.c @@ -800,8 +800,20 @@ sbappendaddr_locked_internal(struct sockbuf *sb, const struct sockaddr *asa, return (0); m->m_len = asa->sa_len; bcopy(asa, mtod(m, caddr_t), asa->sa_len); - if (m0) + if (m0) { m_clrprotoflags(m0); + m_tag_delete_chain(m0, NULL); + /* + * Clear some persistent info from pkthdr. + * We don't use m_demote(), because some netgraph consumers + * expect M_PKTHDR presence. + */ + m0->m_pkthdr.rcvif = NULL; + m0->m_pkthdr.flowid = 0; + m0->m_pkthdr.csum_flags = 0; + m0->m_pkthdr.fibnum = 0; + m0->m_pkthdr.rsstype = 0; + } if (ctrl_last) ctrl_last->m_next = m0; /* concatenate data to control */ else diff --git a/freebsd/sys/kern/uipc_socket.c b/freebsd/sys/kern/uipc_socket.c index d64f9ed2..c52a543c 100644 --- a/freebsd/sys/kern/uipc_socket.c +++ b/freebsd/sys/kern/uipc_socket.c @@ -1797,7 +1797,7 @@ dontblock: * requires MT_SONAME mbufs at the head of * each record. */ - if (m && pr->pr_flags & PR_ATOMIC && + if (pr->pr_flags & PR_ATOMIC && ((flags & MSG_PEEK) == 0)) (void)sbdroprecord_locked(&so->so_rcv); SOCKBUF_UNLOCK(&so->so_rcv); @@ -2378,13 +2378,27 @@ int soshutdown(struct socket *so, int how) { struct protosw *pr = so->so_proto; - int error; + int error, soerror_enotconn; if (!(how == SHUT_RD || how == SHUT_WR || how == SHUT_RDWR)) return (EINVAL); + + soerror_enotconn = 0; if ((so->so_state & - (SS_ISCONNECTED | SS_ISCONNECTING | SS_ISDISCONNECTING)) == 0) - return (ENOTCONN); + (SS_ISCONNECTED | SS_ISCONNECTING | SS_ISDISCONNECTING)) == 0) { + /* + * POSIX mandates us to return ENOTCONN when shutdown(2) is + * invoked on a datagram sockets, however historically we would + * actually tear socket down. This is known to be leveraged by + * some applications to unblock process waiting in recvXXX(2) + * by other process that it shares that socket with. Try to meet + * both backward-compatibility and POSIX requirements by forcing + * ENOTCONN but still asking protocol to perform pru_shutdown(). + */ + if (so->so_type != SOCK_DGRAM) + return (ENOTCONN); + soerror_enotconn = 1; + } CURVNET_SET(so->so_vnet); if (pr->pr_usrreqs->pru_flush != NULL) @@ -2395,11 +2409,12 @@ soshutdown(struct socket *so, int how) error = (*pr->pr_usrreqs->pru_shutdown)(so); wakeup(&so->so_timeo); CURVNET_RESTORE(); - return (error); + return ((error == 0 && soerror_enotconn) ? ENOTCONN : error); } wakeup(&so->so_timeo); CURVNET_RESTORE(); - return (0); + + return (soerror_enotconn ? ENOTCONN : 0); } void diff --git a/freebsd/sys/libkern/crc32.c b/freebsd/sys/libkern/crc32.c index f8fc46ea..c987fb4d 100644 --- a/freebsd/sys/libkern/crc32.c +++ b/freebsd/sys/libkern/crc32.c @@ -56,6 +56,10 @@ __FBSDID("$FreeBSD$"); #include <machine/specialreg.h> #endif +#if defined(__aarch64__) +#include <machine/cpu.h> +#endif + const uint32_t crc32_tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, @@ -762,6 +766,18 @@ calculate_crc32c(uint32_t crc32c, return (sse42_crc32c(crc32c, buffer, length)); } else #endif +#if defined(__aarch64__) + uint64_t reg; + + /* + * We only test for CRC32 support on the CPU with index 0 assuming that + * this applies to all CPUs. + */ + reg = READ_SPECIALREG(id_aa64isar0_el1); + if (ID_AA64ISAR0_CRC32(reg) != ID_AA64ISAR0_CRC32_NONE) { + return (armv8_crc32c(crc32c, buffer, length)); + } else +#endif if (length < 4) { return (singletable_crc32c(crc32c, buffer, length)); } else { diff --git a/freebsd/sys/net/altq/altq_rio.c b/freebsd/sys/net/altq/altq_rio.c index 4e8a1158..af9b5835 100644 --- a/freebsd/sys/net/altq/altq_rio.c +++ b/freebsd/sys/net/altq/altq_rio.c @@ -152,7 +152,7 @@ #define RIO_STATS /* collect statistics */ #define TV_DELTA(a, b, delta) { \ - register int xxs; \ + int xxs; \ \ delta = (a)->tv_usec - (b)->tv_usec; \ if ((xxs = (a)->tv_sec - (b)->tv_sec) != 0) { \ diff --git a/freebsd/sys/net/altq/altq_rmclass.h b/freebsd/sys/net/altq/altq_rmclass.h index 6130c4ff..268ed63f 100644 --- a/freebsd/sys/net/altq/altq_rmclass.h +++ b/freebsd/sys/net/altq/altq_rmclass.h @@ -77,7 +77,7 @@ struct red; (((a)->tv_usec < (b)->tv_usec) && ((a)->tv_sec <= (b)->tv_sec))) #define TV_DELTA(a, b, delta) { \ - register int xxs; \ + int xxs; \ \ delta = (a)->tv_usec - (b)->tv_usec; \ if ((xxs = (a)->tv_sec - (b)->tv_sec)) { \ @@ -98,7 +98,7 @@ struct red; } #define TV_ADD_DELTA(a, delta, res) { \ - register int xxus = (a)->tv_usec + (delta); \ + int xxus = (a)->tv_usec + (delta); \ \ (res)->tv_sec = (a)->tv_sec; \ while (xxus >= 1000000) { \ diff --git a/freebsd/sys/net/bpf_filter.c b/freebsd/sys/net/bpf_filter.c index 6eec4b9c..8ca92300 100644 --- a/freebsd/sys/net/bpf_filter.c +++ b/freebsd/sys/net/bpf_filter.c @@ -76,7 +76,7 @@ __FBSDID("$FreeBSD$"); #ifdef _KERNEL #define MINDEX(m, k) \ { \ - register int len = m->m_len; \ + int len = m->m_len; \ \ while (k >= len) { \ k -= len; \ @@ -343,7 +343,7 @@ bpf_filter(const struct bpf_insn *pc, u_char *p, u_int wirelen, u_int buflen) k = pc->k; if (k >= buflen) { #ifdef _KERNEL - register struct mbuf *m; + struct mbuf *m; if (buflen != 0) return (0); @@ -551,8 +551,8 @@ static const u_short bpf_code_map[] = { int bpf_validate(const struct bpf_insn *f, int len) { - register int i; - register const struct bpf_insn *p; + int i; + const struct bpf_insn *p; /* Do not accept negative length filter. */ if (len < 0) @@ -574,7 +574,7 @@ bpf_validate(const struct bpf_insn *f, int len) * the code block. */ if (BPF_CLASS(p->code) == BPF_JMP) { - register u_int offset; + u_int offset; if (p->code == (BPF_JMP|BPF_JA)) offset = p->k; diff --git a/freebsd/sys/net/bpf_jitter.c b/freebsd/sys/net/bpf_jitter.c index a597f626..0369cb72 100644 --- a/freebsd/sys/net/bpf_jitter.c +++ b/freebsd/sys/net/bpf_jitter.c @@ -2,7 +2,7 @@ /*- * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy) - * Copyright (C) 2005-2009 Jung-uk Kim <jkim@FreeBSD.org> + * Copyright (C) 2005-2017 Jung-uk Kim <jkim@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,8 +52,6 @@ __FBSDID("$FreeBSD$"); #include <net/bpf.h> #include <net/bpf_jitter.h> -bpf_filter_func bpf_jit_compile(struct bpf_insn *, u_int, size_t *); - static u_int bpf_jit_accept_all(u_char *, u_int, u_int); #ifdef _KERNEL @@ -103,13 +101,11 @@ void bpf_destroy_jit_filter(bpf_jit_filter *filter) { -#ifdef _KERNEL if (filter->func != bpf_jit_accept_all) - free(filter->func, M_BPFJIT); + bpf_jit_free(filter->func, filter->size); +#ifdef _KERNEL free(filter, M_BPFJIT); #else - if (filter->func != bpf_jit_accept_all) - munmap(filter->func, filter->size); free(filter); #endif } diff --git a/freebsd/sys/net/bpf_jitter.h b/freebsd/sys/net/bpf_jitter.h index 90a1ff5f..479205ea 100644 --- a/freebsd/sys/net/bpf_jitter.h +++ b/freebsd/sys/net/bpf_jitter.h @@ -80,4 +80,12 @@ bpf_jit_filter *bpf_jitter(struct bpf_insn *fp, int nins); */ void bpf_destroy_jit_filter(bpf_jit_filter *filter); +/* + * Declarations for machine-dependent functions. + */ +struct bpf_insn; + +bpf_filter_func bpf_jit_compile(struct bpf_insn *, u_int, size_t *); +void bpf_jit_free(void *, size_t); + #endif /* _NET_BPF_JITTER_H_ */ diff --git a/freebsd/sys/net/ethernet.h b/freebsd/sys/net/ethernet.h index 5ec9d20e..bc5fa9cb 100644 --- a/freebsd/sys/net/ethernet.h +++ b/freebsd/sys/net/ethernet.h @@ -92,7 +92,7 @@ struct ether_vlan_header { #define EVL_PRIOFTAG(tag) (((tag) >> 13) & 7) #define EVL_CFIOFTAG(tag) (((tag) >> 12) & 1) #define EVL_MAKETAG(vlid, pri, cfi) \ - ((((((pri) & 7) << 13) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK)) + ((((((pri) & 7) << 1) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK)) /* * NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields. diff --git a/freebsd/sys/net/ieee8023ad_lacp.c b/freebsd/sys/net/ieee8023ad_lacp.c index 74e68bec..fefe2a1f 100644 --- a/freebsd/sys/net/ieee8023ad_lacp.c +++ b/freebsd/sys/net/ieee8023ad_lacp.c @@ -1123,6 +1123,7 @@ lacp_compose_key(struct lacp_port *lp) case IFM_10G_CR1: case IFM_10G_ER: case IFM_10G_SFI: + case IFM_10G_AOC: key = IFM_10G_LR; break; case IFM_20G_KR2: @@ -1147,6 +1148,9 @@ lacp_compose_key(struct lacp_port *lp) case IFM_25G_CR: case IFM_25G_KR: case IFM_25G_SR: + case IFM_25G_LR: + case IFM_25G_ACC: + case IFM_25G_AOC: key = IFM_25G_PCIE; break; case IFM_40G_CR4: diff --git a/freebsd/sys/net/if.c b/freebsd/sys/net/if.c index b4a29257..ecf9955a 100644 --- a/freebsd/sys/net/if.c +++ b/freebsd/sys/net/if.c @@ -746,6 +746,11 @@ if_attach_internal(struct ifnet *ifp, int vmove, struct if_clone *ifc) /* Reliably crash if used uninitialized. */ ifp->if_broadcastaddr = NULL; + if (ifp->if_type == IFT_ETHER) { + ifp->if_hw_addr = malloc(ifp->if_addrlen, M_IFADDR, + M_WAITOK | M_ZERO); + } + #if defined(INET) || defined(INET6) /* Use defaults for TSO, if nothing is set */ if (ifp->if_hw_tsomax == 0 && @@ -1061,6 +1066,8 @@ if_detach_internal(struct ifnet *ifp, int vmove, struct if_clone **ifcp) * 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. */ @@ -2669,6 +2676,10 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) ifr->ifr_addr.sa_data, ifr->ifr_addr.sa_len); break; + case SIOCGHWADDR: + error = if_gethwaddr(ifp, ifr); + break; + case SIOCAIFGROUP: { struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr; @@ -3602,6 +3613,29 @@ if_requestencap_default(struct ifnet *ifp, struct if_encap_req *req) } /* + * Get the link layer address that was read from the hardware at attach. + * + * This is only set by Ethernet NICs (IFT_ETHER), but laggX interfaces re-type + * their component interfaces as IFT_IEEE8023ADLAG. + */ +int +if_gethwaddr(struct ifnet *ifp, struct ifreq *ifr) +{ + + if (ifp->if_hw_addr == NULL) + return (ENODEV); + + switch (ifp->if_type) { + case IFT_ETHER: + case IFT_IEEE8023ADLAG: + bcopy(ifp->if_hw_addr, ifr->ifr_addr.sa_data, ifp->if_addrlen); + return (0); + default: + return (ENODEV); + } +} + +/* * The name argument must be a pointer to storage which will last as * long as the interface does. For physical devices, the result of * device_get_name(dev) is a good choice and for pseudo-devices a diff --git a/freebsd/sys/net/if_bridge.c b/freebsd/sys/net/if_bridge.c index d0cd7fd7..5d258493 100644 --- a/freebsd/sys/net/if_bridge.c +++ b/freebsd/sys/net/if_bridge.c @@ -942,8 +942,12 @@ bridge_set_ifcap(struct bridge_softc *sc, struct bridge_iflist *bif, int set) error = (*ifp->if_ioctl)(ifp, SIOCSIFCAP, (caddr_t)&ifr); if (error) if_printf(sc->sc_ifp, - "error setting interface capabilities on %s\n", - ifp->if_xname); + "error setting capabilities on %s: %d\n", + ifp->if_xname, error); + if ((ifp->if_capenable & ~set) != 0) + if_printf(sc->sc_ifp, + "can't disable some capabilities on %s: 0x%x\n", + ifp->if_xname, ifp->if_capenable & ~set); } } diff --git a/freebsd/sys/net/if_epair.c b/freebsd/sys/net/if_epair.c index 7d546fcc..2e1911d7 100644 --- a/freebsd/sys/net/if_epair.c +++ b/freebsd/sys/net/if_epair.c @@ -404,8 +404,8 @@ epair_start_locked(struct ifnet *ifp) return; /* - * We get patckets here from ether_output via if_handoff() - * and ned to put them into the input queue of the oifp + * We get packets here from ether_output via if_handoff() + * and need to put them into the input queue of the oifp * and call oifp->if_input() via netisr/epair_sintr(). */ oifp = sc->oifp; diff --git a/freebsd/sys/net/if_ethersubr.c b/freebsd/sys/net/if_ethersubr.c index 7deecb6a..c3c89d24 100644 --- a/freebsd/sys/net/if_ethersubr.c +++ b/freebsd/sys/net/if_ethersubr.c @@ -918,6 +918,9 @@ ether_ifattach(struct ifnet *ifp, const u_int8_t *lla) sdl->sdl_alen = ifp->if_addrlen; bcopy(lla, LLADDR(sdl), ifp->if_addrlen); + if (ifp->if_hw_addr != NULL) + bcopy(lla, ifp->if_hw_addr, ifp->if_addrlen); + bpfattach(ifp, DLT_EN10MB, ETHER_HDR_LEN); if (ng_ether_attach_p != NULL) (*ng_ether_attach_p)(ifp); diff --git a/freebsd/sys/net/if_gre.c b/freebsd/sys/net/if_gre.c index 55931386..a2129eaa 100644 --- a/freebsd/sys/net/if_gre.c +++ b/freebsd/sys/net/if_gre.c @@ -90,7 +90,7 @@ __FBSDID("$FreeBSD$"); #include <machine/in_cksum.h> #include <security/mac/mac_framework.h> -#define GREMTU 1500 +#define GREMTU 1476 static const char grename[] = "gre"; static MALLOC_DEFINE(M_GRE, grename, "Generic Routing Encapsulation"); static VNET_DEFINE(struct mtx, gre_mtx); @@ -179,7 +179,7 @@ gre_clone_create(struct if_clone *ifc, int unit, caddr_t params) GRE2IFP(sc)->if_softc = sc; if_initname(GRE2IFP(sc), grename, unit); - GRE2IFP(sc)->if_mtu = sc->gre_mtu = GREMTU; + GRE2IFP(sc)->if_mtu = GREMTU; GRE2IFP(sc)->if_flags = IFF_POINTOPOINT|IFF_MULTICAST; GRE2IFP(sc)->if_output = gre_output; GRE2IFP(sc)->if_ioctl = gre_ioctl; @@ -237,7 +237,8 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* XXX: */ if (ifr->ifr_mtu < 576) return (EINVAL); - break; + ifp->if_mtu = ifr->ifr_mtu; + return (0); case SIOCSIFADDR: ifp->if_flags |= IFF_UP; case SIOCSIFFLAGS: @@ -261,12 +262,6 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } error = 0; switch (cmd) { - case SIOCSIFMTU: - GRE_WLOCK(sc); - sc->gre_mtu = ifr->ifr_mtu; - gre_updatehdr(sc); - GRE_WUNLOCK(sc); - goto end; case SIOCSIFPHYADDR: #ifdef INET6 case SIOCSIFPHYADDR_IN6: @@ -555,7 +550,6 @@ gre_updatehdr(struct gre_softc *sc) } else sc->gre_oseq = 0; gh->gre_flags = htons(flags); - GRE2IFP(sc)->if_mtu = sc->gre_mtu - sc->gre_hlen; } static void diff --git a/freebsd/sys/net/if_gre.h b/freebsd/sys/net/if_gre.h index 806b0cb8..8fb811cb 100644 --- a/freebsd/sys/net/if_gre.h +++ b/freebsd/sys/net/if_gre.h @@ -69,7 +69,6 @@ struct gre_softc { uint32_t gre_oseq; uint32_t gre_key; uint32_t gre_options; - uint32_t gre_mtu; u_int gre_fibnum; u_int gre_hlen; /* header size */ union { diff --git a/freebsd/sys/net/if_lagg.c b/freebsd/sys/net/if_lagg.c index 78507ffb..4d6e919e 100644 --- a/freebsd/sys/net/if_lagg.c +++ b/freebsd/sys/net/if_lagg.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/lock.h> #include <sys/rmlock.h> +#include <sys/sx.h> #include <sys/taskqueue.h> #include <sys/eventhandler.h> @@ -101,10 +102,7 @@ static VNET_DEFINE(struct if_clone *, lagg_cloner); #define V_lagg_cloner VNET(lagg_cloner) static const char laggname[] = "lagg"; -static void lagg_lladdr(struct lagg_softc *, uint8_t *); static void lagg_capabilities(struct lagg_softc *); -static void lagg_port_lladdr(struct lagg_port *, uint8_t *, lagg_llqtype); -static void lagg_port_setlladdr(void *, int); static int lagg_port_create(struct lagg_softc *, struct ifnet *); static int lagg_port_destroy(struct lagg_port *, int); static struct mbuf *lagg_input(struct ifnet *, struct mbuf *); @@ -126,8 +124,9 @@ static int lagg_snd_tag_alloc(struct ifnet *, union if_snd_tag_alloc_params *, struct m_snd_tag **); #endif -static int lagg_ether_setmulti(struct lagg_softc *); -static int lagg_ether_cmdmulti(struct lagg_port *, int); +static int lagg_setmulti(struct lagg_port *); +static int lagg_clrmulti(struct lagg_port *); +static int lagg_setcaps(struct lagg_port *, int cap); static int lagg_setflag(struct lagg_port *, int, int, int (*func)(struct ifnet *, int)); static int lagg_setflags(struct lagg_port *, int status); @@ -319,6 +318,7 @@ static void lagg_proto_attach(struct lagg_softc *sc, lagg_proto pr) { + LAGG_XLOCK_ASSERT(sc); KASSERT(sc->sc_proto == LAGG_PROTO_NONE, ("%s: sc %p has proto", __func__, sc)); @@ -335,8 +335,8 @@ lagg_proto_detach(struct lagg_softc *sc) { lagg_proto pr; + LAGG_XLOCK_ASSERT(sc); LAGG_WLOCK_ASSERT(sc); - pr = sc->sc_proto; sc->sc_proto = LAGG_PROTO_NONE; @@ -435,17 +435,14 @@ lagg_register_vlan(void *arg, struct ifnet *ifp, u_int16_t vtag) { struct lagg_softc *sc = ifp->if_softc; struct lagg_port *lp; - struct rm_priotracker tracker; if (ifp->if_softc != arg) /* Not our event */ return; - LAGG_RLOCK(sc, &tracker); - if (!SLIST_EMPTY(&sc->sc_ports)) { - SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) - EVENTHANDLER_INVOKE(vlan_config, lp->lp_ifp, vtag); - } - LAGG_RUNLOCK(sc, &tracker); + LAGG_SLOCK(sc); + SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) + EVENTHANDLER_INVOKE(vlan_config, lp->lp_ifp, vtag); + LAGG_SUNLOCK(sc); } /* @@ -457,17 +454,14 @@ lagg_unregister_vlan(void *arg, struct ifnet *ifp, u_int16_t vtag) { struct lagg_softc *sc = ifp->if_softc; struct lagg_port *lp; - struct rm_priotracker tracker; if (ifp->if_softc != arg) /* Not our event */ return; - LAGG_RLOCK(sc, &tracker); - if (!SLIST_EMPTY(&sc->sc_ports)) { - SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) - EVENTHANDLER_INVOKE(vlan_unconfig, lp->lp_ifp, vtag); - } - LAGG_RUNLOCK(sc, &tracker); + LAGG_SLOCK(sc); + SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) + EVENTHANDLER_INVOKE(vlan_unconfig, lp->lp_ifp, vtag); + LAGG_SUNLOCK(sc); } static int @@ -483,7 +477,10 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params) free(sc, M_DEVBUF); return (ENOSPC); } + LAGG_LOCK_INIT(sc); + LAGG_SX_INIT(sc); + LAGG_XLOCK(sc); if (V_def_use_flowid) sc->sc_opts |= LAGG_OPT_USE_FLOWID; sc->flowid_shift = V_def_flowid_shift; @@ -493,9 +490,7 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params) lagg_proto_attach(sc, LAGG_PROTO_DEFAULT); - LAGG_LOCK_INIT(sc); SLIST_INIT(&sc->sc_ports); - TASK_INIT(&sc->sc_lladdr_task, 0, lagg_port_setlladdr, sc); /* Initialise pseudo media types */ ifmedia_init(&sc->sc_media, 0, lagg_media_change, @@ -533,6 +528,7 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params) LAGG_LIST_LOCK(); SLIST_INSERT_HEAD(&V_lagg_list, sc, sc_entries); LAGG_LIST_UNLOCK(); + LAGG_XUNLOCK(sc); return (0); } @@ -543,8 +539,8 @@ lagg_clone_destroy(struct ifnet *ifp) struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; struct lagg_port *lp; - LAGG_WLOCK(sc); - + LAGG_XLOCK(sc); + sc->sc_destroying = 1; lagg_stop(sc); ifp->if_flags &= ~IFF_UP; @@ -552,15 +548,15 @@ lagg_clone_destroy(struct ifnet *ifp) EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach); /* Shutdown and remove lagg ports */ - while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL) { - lp->lp_detaching = LAGG_CLONE_DESTROY; + while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL) lagg_port_destroy(lp, 1); - } + /* Unhook the aggregation protocol */ + LAGG_WLOCK(sc); lagg_proto_detach(sc); LAGG_UNLOCK_ASSERT(sc); + LAGG_XUNLOCK(sc); - taskqueue_drain(taskqueue_swi, &sc->sc_lladdr_task); ifmedia_removeall(&sc->sc_media); ether_ifdetach(ifp); if_free(ifp); @@ -569,69 +565,50 @@ lagg_clone_destroy(struct ifnet *ifp) SLIST_REMOVE(&V_lagg_list, sc, lagg_softc, sc_entries); LAGG_LIST_UNLOCK(); + LAGG_SX_DESTROY(sc); LAGG_LOCK_DESTROY(sc); free(sc, M_DEVBUF); } -/* - * Set link-layer address on the lagg interface itself. - * - * Set noinline to be dtrace-friendly - */ -static __noinline void -lagg_lladdr(struct lagg_softc *sc, uint8_t *lladdr) -{ - struct ifnet *ifp = sc->sc_ifp; - struct lagg_port lp; - - if (memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0) - return; - - LAGG_WLOCK_ASSERT(sc); - /* - * Set the link layer address on the lagg interface. - * lagg_proto_lladdr() notifies the MAC change to - * the aggregation protocol. iflladdr_event handler which - * may trigger gratuitous ARPs for INET will be handled in - * a taskqueue. - */ - bcopy(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN); - lagg_proto_lladdr(sc); - - /* - * Send notification request for lagg interface - * itself. Note that new lladdr is already set. - */ - bzero(&lp, sizeof(lp)); - lp.lp_ifp = sc->sc_ifp; - lp.lp_softc = sc; - - /* Do not request lladdr change */ - lagg_port_lladdr(&lp, lladdr, LAGG_LLQTYPE_VIRT); -} - static void lagg_capabilities(struct lagg_softc *sc) { struct lagg_port *lp; - int cap = ~0, ena = ~0; - u_long hwa = ~0UL; + int cap, ena, pena; + uint64_t hwa; struct ifnet_hw_tsomax hw_tsomax; - LAGG_WLOCK_ASSERT(sc); + LAGG_XLOCK_ASSERT(sc); - memset(&hw_tsomax, 0, sizeof(hw_tsomax)); + /* Get common enabled capabilities for the lagg ports */ + ena = ~0; + SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) + ena &= lp->lp_ifp->if_capenable; + ena = (ena == ~0 ? 0 : ena); + + /* + * Apply common enabled capabilities back to the lagg ports. + * May require several iterations if they are dependent. + */ + do { + pena = ena; + SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { + lagg_setcaps(lp, ena); + ena &= lp->lp_ifp->if_capenable; + } + } while (pena != ena); - /* Get capabilities from the lagg ports */ + /* Get other capabilities from the lagg ports */ + cap = ~0; + hwa = ~(uint64_t)0; + memset(&hw_tsomax, 0, sizeof(hw_tsomax)); SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { cap &= lp->lp_ifp->if_capabilities; - ena &= lp->lp_ifp->if_capenable; hwa &= lp->lp_ifp->if_hwassist; if_hw_tsomax_common(lp->lp_ifp, &hw_tsomax); } cap = (cap == ~0 ? 0 : cap); - ena = (ena == ~0 ? 0 : ena); - hwa = (hwa == ~0 ? 0 : hwa); + hwa = (hwa == ~(uint64_t)0 ? 0 : hwa); if (sc->sc_ifp->if_capabilities != cap || sc->sc_ifp->if_capenable != ena || @@ -648,95 +625,6 @@ lagg_capabilities(struct lagg_softc *sc) } } -/* - * Enqueue interface lladdr notification. - * If request is already queued, it is updated. - * If setting lladdr is also desired, @do_change has to be set to 1. - * - * Set noinline to be dtrace-friendly - */ -static __noinline void -lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr, lagg_llqtype llq_type) -{ - struct lagg_softc *sc = lp->lp_softc; - struct ifnet *ifp = lp->lp_ifp; - struct lagg_llq *llq; - - LAGG_WLOCK_ASSERT(sc); - - /* - * Do not enqueue requests where lladdr is the same for - * "physical" interfaces (e.g. ports in lagg) - */ - if (llq_type == LAGG_LLQTYPE_PHYS && - memcmp(IF_LLADDR(ifp), lladdr, ETHER_ADDR_LEN) == 0) - return; - - /* Check to make sure its not already queued to be changed */ - SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) { - if (llq->llq_ifp == ifp) { - /* Update lladdr, it may have changed */ - bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN); - return; - } - } - - llq = malloc(sizeof(struct lagg_llq), M_DEVBUF, M_NOWAIT | M_ZERO); - if (llq == NULL) /* XXX what to do */ - return; - - llq->llq_ifp = ifp; - llq->llq_type = llq_type; - bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN); - /* XXX: We should insert to tail */ - SLIST_INSERT_HEAD(&sc->sc_llq_head, llq, llq_entries); - - taskqueue_enqueue(taskqueue_swi, &sc->sc_lladdr_task); -} - -/* - * Set the interface MAC address from a taskqueue to avoid a LOR. - * - * Set noinline to be dtrace-friendly - */ -static __noinline void -lagg_port_setlladdr(void *arg, int pending) -{ - struct lagg_softc *sc = (struct lagg_softc *)arg; - struct lagg_llq *llq, *head; - struct ifnet *ifp; - - /* Grab a local reference of the queue and remove it from the softc */ - LAGG_WLOCK(sc); - head = SLIST_FIRST(&sc->sc_llq_head); - SLIST_FIRST(&sc->sc_llq_head) = NULL; - LAGG_WUNLOCK(sc); - - /* - * Traverse the queue and set the lladdr on each ifp. It is safe to do - * unlocked as we have the only reference to it. - */ - for (llq = head; llq != NULL; llq = head) { - ifp = llq->llq_ifp; - - CURVNET_SET(ifp->if_vnet); - - /* - * Set the link layer address on the laggport interface. - * Note that if_setlladdr() or iflladdr_event handler - * may result in arp transmission / lltable updates. - */ - if (llq->llq_type == LAGG_LLQTYPE_PHYS) - if_setlladdr(ifp, llq->llq_lladdr, - ETHER_ADDR_LEN); - else - EVENTHANDLER_INVOKE(iflladdr_event, ifp); - CURVNET_RESTORE(); - head = SLIST_NEXT(llq, llq_entries); - free(llq, M_DEVBUF); - } -} - static int lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp) { @@ -745,7 +633,7 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp) int error, i; uint64_t *pval; - LAGG_WLOCK_ASSERT(sc); + LAGG_XLOCK_ASSERT(sc); /* Limit the maximal number of lagg ports */ if (sc->sc_count >= LAGG_MAX_PORTS) @@ -773,9 +661,8 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp) return (EINVAL); } - if ((lp = malloc(sizeof(struct lagg_port), - M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL) - return (ENOMEM); + lp = malloc(sizeof(struct lagg_port), M_DEVBUF, M_WAITOK|M_ZERO); + lp->lp_softc = sc; /* Check if port is a stacked lagg */ LAGG_LIST_LOCK(); @@ -798,6 +685,26 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp) } LAGG_LIST_UNLOCK(); + if_ref(ifp); + lp->lp_ifp = ifp; + + bcopy(IF_LLADDR(ifp), lp->lp_lladdr, ETHER_ADDR_LEN); + lp->lp_ifcapenable = ifp->if_capenable; + if (SLIST_EMPTY(&sc->sc_ports)) { + LAGG_WLOCK(sc); + bcopy(IF_LLADDR(ifp), IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); + lagg_proto_lladdr(sc); + LAGG_WUNLOCK(sc); + EVENTHANDLER_INVOKE(iflladdr_event, sc->sc_ifp); + } else { + if_setlladdr(ifp, IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); + } + lagg_setflags(lp, 1); + + LAGG_WLOCK(sc); + if (SLIST_EMPTY(&sc->sc_ports)) + sc->sc_primary = lp; + /* Change the interface type */ lp->lp_iftype = ifp->if_type; ifp->if_type = IFT_IEEE8023ADLAG; @@ -807,24 +714,10 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp) lp->lp_output = ifp->if_output; ifp->if_output = lagg_port_output; - lp->lp_ifp = ifp; - lp->lp_softc = sc; - - /* Save port link layer address */ - bcopy(IF_LLADDR(ifp), lp->lp_lladdr, ETHER_ADDR_LEN); - - if (SLIST_EMPTY(&sc->sc_ports)) { - sc->sc_primary = lp; - /* First port in lagg. Update/notify lagg lladdress */ - lagg_lladdr(sc, IF_LLADDR(ifp)); - } else { - - /* - * Update link layer address for this port and - * send notifications to other subsystems. - */ - lagg_port_lladdr(lp, IF_LLADDR(sc->sc_ifp), LAGG_LLQTYPE_PHYS); - } + /* Read port counters */ + pval = lp->port_counters.val; + for (i = 0; i < IFCOUNTERS; i++, pval++) + *pval = ifp->if_get_counter(ifp, i); /* * Insert into the list of ports. @@ -845,24 +738,21 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp) SLIST_INSERT_HEAD(&sc->sc_ports, lp, lp_entries); sc->sc_count++; - /* Update lagg capabilities */ - lagg_capabilities(sc); - lagg_linkstate(sc); - - /* Read port counters */ - pval = lp->port_counters.val; - for (i = 0; i < IFCOUNTERS; i++, pval++) - *pval = ifp->if_get_counter(ifp, i); - /* Add multicast addresses and interface flags to this port */ - lagg_ether_cmdmulti(lp, 1); - lagg_setflags(lp, 1); + lagg_setmulti(lp); if ((error = lagg_proto_addport(sc, lp)) != 0) { /* Remove the port, without calling pr_delport. */ lagg_port_destroy(lp, 0); + LAGG_UNLOCK_ASSERT(sc); return (error); } + LAGG_WUNLOCK(sc); + + /* Update lagg capabilities */ + lagg_capabilities(sc); + lagg_linkstate(sc); + return (0); } @@ -874,8 +764,7 @@ lagg_port_checkstacking(struct lagg_softc *sc) struct lagg_port *lp; int m = 0; - LAGG_WLOCK_ASSERT(sc); - + LAGG_SXLOCK_ASSERT(sc); SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { if (lp->lp_flags & LAGG_PORT_STACK) { sc_ptr = (struct lagg_softc *)lp->lp_ifp->if_softc; @@ -892,25 +781,20 @@ lagg_port_destroy(struct lagg_port *lp, int rundelport) { struct lagg_softc *sc = lp->lp_softc; struct lagg_port *lp_ptr, *lp0; - struct lagg_llq *llq; struct ifnet *ifp = lp->lp_ifp; uint64_t *pval, vdiff; int i; - LAGG_WLOCK_ASSERT(sc); + LAGG_XLOCK_ASSERT(sc); - if (rundelport) + if (rundelport) { + LAGG_WLOCK(sc); lagg_proto_delport(sc, lp); + } else + LAGG_WLOCK_ASSERT(sc); - /* - * Remove multicast addresses and interface flags from this port and - * reset the MAC address, skip if the interface is being detached. - */ - if (lp->lp_detaching == 0) { - lagg_ether_cmdmulti(lp, 0); - lagg_setflags(lp, 0); - lagg_port_lladdr(lp, lp->lp_lladdr, LAGG_LLQTYPE_PHYS); - } + if (lp->lp_detaching == 0) + lagg_clrmulti(lp); /* Restore interface */ ifp->if_type = lp->lp_iftype; @@ -933,42 +817,38 @@ lagg_port_destroy(struct lagg_port *lp, int rundelport) if (lp == sc->sc_primary) { uint8_t lladdr[ETHER_ADDR_LEN]; - if ((lp0 = SLIST_FIRST(&sc->sc_ports)) == NULL) { + if ((lp0 = SLIST_FIRST(&sc->sc_ports)) == NULL) bzero(&lladdr, ETHER_ADDR_LEN); - } else { - bcopy(lp0->lp_lladdr, - lladdr, ETHER_ADDR_LEN); - } - if (lp->lp_detaching != LAGG_CLONE_DESTROY) - lagg_lladdr(sc, lladdr); - - /* Mark lp0 as new primary */ + else + bcopy(lp0->lp_lladdr, lladdr, ETHER_ADDR_LEN); sc->sc_primary = lp0; + if (sc->sc_destroying == 0) { + bcopy(lladdr, IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); + lagg_proto_lladdr(sc); + LAGG_WUNLOCK(sc); + EVENTHANDLER_INVOKE(iflladdr_event, sc->sc_ifp); + } else + LAGG_WUNLOCK(sc); /* - * Enqueue lladdr update/notification for each port - * (new primary needs update as well, to switch from - * old lladdr to its 'real' one). + * Update lladdr for each port (new primary needs update + * as well, to switch from old lladdr to its 'real' one) */ SLIST_FOREACH(lp_ptr, &sc->sc_ports, lp_entries) - lagg_port_lladdr(lp_ptr, lladdr, LAGG_LLQTYPE_PHYS); - } - - /* Remove any pending lladdr changes from the queue */ - if (lp->lp_detaching != 0) { - SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) { - if (llq->llq_ifp == ifp) { - SLIST_REMOVE(&sc->sc_llq_head, llq, lagg_llq, - llq_entries); - free(llq, M_DEVBUF); - break; /* Only appears once */ - } - } - } + if_setlladdr(lp_ptr->lp_ifp, lladdr, ETHER_ADDR_LEN); + } else + LAGG_WUNLOCK(sc); if (lp->lp_ifflags) if_printf(ifp, "%s: lp_ifflags unclean\n", __func__); + if (lp->lp_detaching == 0) { + lagg_setflags(lp, 0); + lagg_setcaps(lp, lp->lp_ifcapenable); + if_setlladdr(ifp, lp->lp_lladdr, ETHER_ADDR_LEN); + } + + if_rele(ifp); free(lp, M_DEVBUF); /* Update lagg capabilities */ @@ -985,7 +865,6 @@ lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct lagg_softc *sc; struct lagg_port *lp = NULL; int error = 0; - struct rm_priotracker tracker; /* Should be checked by the caller */ if (ifp->if_type != IFT_IEEE8023ADLAG || @@ -1000,15 +879,15 @@ lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } - LAGG_RLOCK(sc, &tracker); + LAGG_SLOCK(sc); if ((lp = ifp->if_lagg) == NULL || lp->lp_softc != sc) { error = ENOENT; - LAGG_RUNLOCK(sc, &tracker); + LAGG_SUNLOCK(sc); break; } lagg_port2req(lp, rp); - LAGG_RUNLOCK(sc, &tracker); + LAGG_SUNLOCK(sc); break; case SIOCSIFCAP: @@ -1021,9 +900,10 @@ lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; /* Update lagg interface capabilities */ - LAGG_WLOCK(sc); + LAGG_XLOCK(sc); lagg_capabilities(sc); - LAGG_WUNLOCK(sc); + LAGG_XUNLOCK(sc); + VLAN_CAPABILITIES(sc->sc_ifp); break; case SIOCSIFMTU: @@ -1133,10 +1013,11 @@ lagg_port_ifdetach(void *arg __unused, struct ifnet *ifp) sc = lp->lp_softc; - LAGG_WLOCK(sc); - lp->lp_detaching = LAGG_PORT_DETACH; + LAGG_XLOCK(sc); + lp->lp_detaching = 1; lagg_port_destroy(lp, 1); - LAGG_WUNLOCK(sc); + LAGG_XUNLOCK(sc); + VLAN_CAPABILITIES(sc->sc_ifp); } static void @@ -1186,10 +1067,11 @@ lagg_init(void *xsc) struct ifnet *ifp = sc->sc_ifp; struct lagg_port *lp; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + LAGG_XLOCK(sc); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + LAGG_XUNLOCK(sc); return; - - LAGG_WLOCK(sc); + } ifp->if_drv_flags |= IFF_DRV_RUNNING; @@ -1198,12 +1080,15 @@ lagg_init(void *xsc) * This might be if_setlladdr() notification * that lladdr has been changed. */ - SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) - lagg_port_lladdr(lp, IF_LLADDR(ifp), LAGG_LLQTYPE_PHYS); + SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { + if (memcmp(IF_LLADDR(ifp), IF_LLADDR(lp->lp_ifp), + ETHER_ADDR_LEN) != 0) + if_setlladdr(lp->lp_ifp, IF_LLADDR(ifp), ETHER_ADDR_LEN); + } lagg_proto_init(sc); - LAGG_WUNLOCK(sc); + LAGG_XUNLOCK(sc); } static void @@ -1211,7 +1096,7 @@ lagg_stop(struct lagg_softc *sc) { struct ifnet *ifp = sc->sc_ifp; - LAGG_WLOCK_ASSERT(sc); + LAGG_XLOCK_ASSERT(sc); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; @@ -1235,22 +1120,14 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct thread *td = curthread; char *buf, *outbuf; int count, buflen, len, error = 0; - struct rm_priotracker tracker; bzero(&rpbuf, sizeof(rpbuf)); switch (cmd) { case SIOCGLAGG: - LAGG_RLOCK(sc, &tracker); - count = 0; - SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) - count++; - buflen = count * sizeof(struct lagg_reqport); - LAGG_RUNLOCK(sc, &tracker); - + LAGG_SLOCK(sc); + buflen = sc->sc_count * sizeof(struct lagg_reqport); outbuf = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO); - - LAGG_RLOCK(sc, &tracker); ra->ra_proto = sc->sc_proto; lagg_proto_request(sc, &ra->ra_psc); count = 0; @@ -1266,7 +1143,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) buf += sizeof(rpbuf); len -= sizeof(rpbuf); } - LAGG_RUNLOCK(sc, &tracker); + LAGG_SUNLOCK(sc); ra->ra_ports = count; ra->ra_size = count * sizeof(rpbuf); error = copyout(outbuf, ra->ra_port, ra->ra_size); @@ -1281,12 +1158,15 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } + LAGG_XLOCK(sc); LAGG_WLOCK(sc); lagg_proto_detach(sc); LAGG_UNLOCK_ASSERT(sc); lagg_proto_attach(sc, ra->ra_proto); + LAGG_XUNLOCK(sc); break; case SIOCGLAGGOPTS: + LAGG_SLOCK(sc); ro->ro_opts = sc->sc_opts; if (sc->sc_proto == LAGG_PROTO_LACP) { struct lacp_softc *lsc; @@ -1310,6 +1190,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ro->ro_bkt = sc->sc_bkt; ro->ro_flapping = sc->sc_flapping; ro->ro_flowid_shift = sc->flowid_shift; + LAGG_SUNLOCK(sc); break; case SIOCSLAGGOPTS: if (sc->sc_proto == LAGG_PROTO_ROUNDROBIN) { @@ -1351,13 +1232,13 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } - LAGG_WLOCK(sc); + LAGG_XLOCK(sc); if (valid == 0 || (lacp == 1 && sc->sc_proto != LAGG_PROTO_LACP)) { /* Invalid combination of options specified. */ error = EINVAL; - LAGG_WUNLOCK(sc); + LAGG_XUNLOCK(sc); break; /* Return from SIOCSLAGGOPTS. */ } /* @@ -1412,18 +1293,18 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } } - LAGG_WUNLOCK(sc); + LAGG_XUNLOCK(sc); break; case SIOCGLAGGFLAGS: rf->rf_flags = 0; - LAGG_RLOCK(sc, &tracker); + LAGG_SLOCK(sc); if (sc->sc_flags & MBUF_HASHFLAG_L2) rf->rf_flags |= LAGG_F_HASHL2; if (sc->sc_flags & MBUF_HASHFLAG_L3) rf->rf_flags |= LAGG_F_HASHL3; if (sc->sc_flags & MBUF_HASHFLAG_L4) rf->rf_flags |= LAGG_F_HASHL4; - LAGG_RUNLOCK(sc, &tracker); + LAGG_SUNLOCK(sc); break; case SIOCSLAGGHASH: error = priv_check(td, PRIV_NET_LAGG); @@ -1433,7 +1314,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) error = EINVAL; break; } - LAGG_WLOCK(sc); + LAGG_XLOCK(sc); sc->sc_flags = 0; if (rf->rf_flags & LAGG_F_HASHL2) sc->sc_flags |= MBUF_HASHFLAG_L2; @@ -1441,32 +1322,34 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sc->sc_flags |= MBUF_HASHFLAG_L3; if (rf->rf_flags & LAGG_F_HASHL4) sc->sc_flags |= MBUF_HASHFLAG_L4; - LAGG_WUNLOCK(sc); + LAGG_XUNLOCK(sc); break; case SIOCGLAGGPORT: if (rp->rp_portname[0] == '\0' || - (tpif = ifunit(rp->rp_portname)) == NULL) { + (tpif = ifunit_ref(rp->rp_portname)) == NULL) { error = EINVAL; break; } - LAGG_RLOCK(sc, &tracker); + LAGG_SLOCK(sc); if ((lp = (struct lagg_port *)tpif->if_lagg) == NULL || lp->lp_softc != sc) { error = ENOENT; - LAGG_RUNLOCK(sc, &tracker); + LAGG_SUNLOCK(sc); + if_rele(tpif); break; } lagg_port2req(lp, rp); - LAGG_RUNLOCK(sc, &tracker); + LAGG_SUNLOCK(sc); + if_rele(tpif); break; case SIOCSLAGGPORT: error = priv_check(td, PRIV_NET_LAGG); if (error) break; if (rp->rp_portname[0] == '\0' || - (tpif = ifunit(rp->rp_portname)) == NULL) { + (tpif = ifunit_ref(rp->rp_portname)) == NULL) { error = EINVAL; break; } @@ -1490,38 +1373,42 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) tpif->if_xname); } #endif - LAGG_WLOCK(sc); + LAGG_XLOCK(sc); error = lagg_port_create(sc, tpif); - LAGG_WUNLOCK(sc); + LAGG_XUNLOCK(sc); + if_rele(tpif); + VLAN_CAPABILITIES(ifp); break; case SIOCSLAGGDELPORT: error = priv_check(td, PRIV_NET_LAGG); if (error) break; if (rp->rp_portname[0] == '\0' || - (tpif = ifunit(rp->rp_portname)) == NULL) { + (tpif = ifunit_ref(rp->rp_portname)) == NULL) { error = EINVAL; break; } - LAGG_WLOCK(sc); + LAGG_XLOCK(sc); if ((lp = (struct lagg_port *)tpif->if_lagg) == NULL || lp->lp_softc != sc) { error = ENOENT; - LAGG_WUNLOCK(sc); + LAGG_XUNLOCK(sc); + if_rele(tpif); break; } error = lagg_port_destroy(lp, 1); - LAGG_WUNLOCK(sc); + LAGG_XUNLOCK(sc); + if_rele(tpif); + VLAN_CAPABILITIES(ifp); break; case SIOCSIFFLAGS: /* Set flags on ports too */ - LAGG_WLOCK(sc); + LAGG_XLOCK(sc); SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { lagg_setflags(lp, 1); } - LAGG_WUNLOCK(sc); if (!(ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) { @@ -1529,23 +1416,28 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) * If interface is marked down and it is running, * then stop and disable it. */ - LAGG_WLOCK(sc); lagg_stop(sc); - LAGG_WUNLOCK(sc); + LAGG_XUNLOCK(sc); } else if ((ifp->if_flags & IFF_UP) && !(ifp->if_drv_flags & IFF_DRV_RUNNING)) { /* * If interface is marked up and it is stopped, then * start it. */ + LAGG_XUNLOCK(sc); (*ifp->if_init)(sc); - } + } else + LAGG_XUNLOCK(sc); break; case SIOCADDMULTI: case SIOCDELMULTI: LAGG_WLOCK(sc); - error = lagg_ether_setmulti(sc); + SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { + lagg_clrmulti(lp); + lagg_setmulti(lp); + } LAGG_WUNLOCK(sc); + error = 0; break; case SIOCSIFMEDIA: case SIOCGIFMEDIA: @@ -1553,8 +1445,19 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; case SIOCSIFCAP: + LAGG_XLOCK(sc); + SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { + if (lp->lp_ioctl != NULL) + (*lp->lp_ioctl)(lp->lp_ifp, cmd, data); + } + lagg_capabilities(sc); + LAGG_XUNLOCK(sc); + VLAN_CAPABILITIES(ifp); + error = 0; + break; + case SIOCSIFMTU: - /* Do not allow the MTU or caps to be directly changed */ + /* Do not allow the MTU to be directly changed */ error = EINVAL; break; @@ -1612,67 +1515,69 @@ lagg_snd_tag_alloc(struct ifnet *ifp, #endif static int -lagg_ether_setmulti(struct lagg_softc *sc) +lagg_setmulti(struct lagg_port *lp) { - struct lagg_port *lp; + struct lagg_softc *sc = lp->lp_softc; + struct ifnet *ifp = lp->lp_ifp; + struct ifnet *scifp = sc->sc_ifp; + struct lagg_mc *mc; + struct ifmultiaddr *ifma; + int error; LAGG_WLOCK_ASSERT(sc); - - SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { - /* First, remove any existing filter entries. */ - lagg_ether_cmdmulti(lp, 0); - /* copy all addresses from the lagg interface to the port */ - lagg_ether_cmdmulti(lp, 1); + IF_ADDR_WLOCK(scifp); + TAILQ_FOREACH(ifma, &scifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + mc = malloc(sizeof(struct lagg_mc), M_DEVBUF, M_NOWAIT); + if (mc == NULL) { + IF_ADDR_WUNLOCK(scifp); + return (ENOMEM); + } + bcopy(ifma->ifma_addr, &mc->mc_addr, + ifma->ifma_addr->sa_len); + mc->mc_addr.sdl_index = ifp->if_index; + mc->mc_ifma = NULL; + SLIST_INSERT_HEAD(&lp->lp_mc_head, mc, mc_entries); + } + IF_ADDR_WUNLOCK(scifp); + SLIST_FOREACH (mc, &lp->lp_mc_head, mc_entries) { + error = if_addmulti(ifp, + (struct sockaddr *)&mc->mc_addr, &mc->mc_ifma); + if (error) + return (error); } return (0); } static int -lagg_ether_cmdmulti(struct lagg_port *lp, int set) +lagg_clrmulti(struct lagg_port *lp) { - struct lagg_softc *sc = lp->lp_softc; - struct ifnet *ifp = lp->lp_ifp; - struct ifnet *scifp = sc->sc_ifp; struct lagg_mc *mc; - struct ifmultiaddr *ifma; - int error; - - LAGG_WLOCK_ASSERT(sc); - if (set) { - IF_ADDR_WLOCK(scifp); - TAILQ_FOREACH(ifma, &scifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - mc = malloc(sizeof(struct lagg_mc), M_DEVBUF, M_NOWAIT); - if (mc == NULL) { - IF_ADDR_WUNLOCK(scifp); - return (ENOMEM); - } - bcopy(ifma->ifma_addr, &mc->mc_addr, - ifma->ifma_addr->sa_len); - mc->mc_addr.sdl_index = ifp->if_index; - mc->mc_ifma = NULL; - SLIST_INSERT_HEAD(&lp->lp_mc_head, mc, mc_entries); - } - IF_ADDR_WUNLOCK(scifp); - SLIST_FOREACH (mc, &lp->lp_mc_head, mc_entries) { - error = if_addmulti(ifp, - (struct sockaddr *)&mc->mc_addr, &mc->mc_ifma); - if (error) - return (error); - } - } else { - while ((mc = SLIST_FIRST(&lp->lp_mc_head)) != NULL) { - SLIST_REMOVE(&lp->lp_mc_head, mc, lagg_mc, mc_entries); - if (mc->mc_ifma && lp->lp_detaching == 0) - if_delmulti_ifma(mc->mc_ifma); - free(mc, M_DEVBUF); - } + LAGG_WLOCK_ASSERT(lp->lp_softc); + while ((mc = SLIST_FIRST(&lp->lp_mc_head)) != NULL) { + SLIST_REMOVE(&lp->lp_mc_head, mc, lagg_mc, mc_entries); + if (mc->mc_ifma && lp->lp_detaching == 0) + if_delmulti_ifma(mc->mc_ifma); + free(mc, M_DEVBUF); } return (0); } +static int +lagg_setcaps(struct lagg_port *lp, int cap) +{ + struct ifreq ifr; + + if (lp->lp_ifp->if_capenable == cap) + return (0); + if (lp->lp_ioctl == NULL) + return (ENXIO); + ifr.ifr_reqcap = cap; + return ((*lp->lp_ioctl)(lp->lp_ifp, SIOCSIFCAP, (caddr_t)&ifr)); +} + /* Handle a ref counted flag that should be set on the lagg port as well */ static int lagg_setflag(struct lagg_port *lp, int flag, int status, @@ -1683,7 +1588,7 @@ lagg_setflag(struct lagg_port *lp, int flag, int status, struct ifnet *ifp = lp->lp_ifp; int error; - LAGG_WLOCK_ASSERT(sc); + LAGG_XLOCK_ASSERT(sc); status = status ? (scifp->if_flags & flag) : 0; /* Now "status" contains the flag value or 0 */ @@ -1817,17 +1722,16 @@ lagg_media_status(struct ifnet *ifp, struct ifmediareq *imr) { struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; struct lagg_port *lp; - struct rm_priotracker tracker; imr->ifm_status = IFM_AVALID; imr->ifm_active = IFM_ETHER | IFM_AUTO; - LAGG_RLOCK(sc, &tracker); + LAGG_SLOCK(sc); SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { if (LAGG_PORTACTIVE(lp)) imr->ifm_status |= IFM_ACTIVE; } - LAGG_RUNLOCK(sc, &tracker); + LAGG_SUNLOCK(sc); } static void @@ -1837,6 +1741,8 @@ lagg_linkstate(struct lagg_softc *sc) int new_link = LINK_STATE_DOWN; uint64_t speed; + LAGG_XLOCK_ASSERT(sc); + /* Our link is considered up if at least one of our ports is active */ SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { if (lp->lp_ifp->if_link_state == LINK_STATE_UP) { @@ -1877,19 +1783,17 @@ lagg_port_state(struct ifnet *ifp, int state) if (sc == NULL) return; - LAGG_WLOCK(sc); + LAGG_XLOCK(sc); lagg_linkstate(sc); lagg_proto_linkstate(sc, lp); - LAGG_WUNLOCK(sc); + LAGG_XUNLOCK(sc); } struct lagg_port * lagg_link_active(struct lagg_softc *sc, struct lagg_port *lp) { struct lagg_port *lp_next, *rval = NULL; - // int new_link = LINK_STATE_DOWN; - LAGG_RLOCK_ASSERT(sc); /* * Search a port which reports an active link state. */ @@ -1915,22 +1819,6 @@ search: } found: - if (rval != NULL) { - /* - * The IEEE 802.1D standard assumes that a lagg with - * multiple ports is always full duplex. This is valid - * for load sharing laggs and if at least two links - * are active. Unfortunately, checking the latter would - * be too expensive at this point. - XXX - if ((sc->sc_capabilities & IFCAP_LAGG_FULLDUPLEX) && - (sc->sc_count > 1)) - new_link = LINK_STATE_FULL_DUPLEX; - else - new_link = rval->lp_link_state; - */ - } - return (rval); } @@ -1947,7 +1835,6 @@ lagg_enqueue(struct ifnet *ifp, struct mbuf *m) static void lagg_rr_attach(struct lagg_softc *sc) { - sc->sc_capabilities = IFCAP_LAGG_FULLDUPLEX; sc->sc_seq = 0; sc->sc_bkt_count = sc->sc_bkt; } @@ -2116,9 +2003,6 @@ lagg_lb_attach(struct lagg_softc *sc) struct lagg_lb *lb; lb = malloc(sizeof(struct lagg_lb), M_DEVBUF, M_WAITOK | M_ZERO); - - sc->sc_capabilities = IFCAP_LAGG_FULLDUPLEX; - lb->lb_key = m_ether_tcpip_hash_init(); sc->sc_psc = lb; @@ -2246,6 +2130,8 @@ lagg_lacp_lladdr(struct lagg_softc *sc) { struct lagg_port *lp; + LAGG_SXLOCK_ASSERT(sc); + /* purge all the lacp ports */ SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) lacp_port_destroy(lp); diff --git a/freebsd/sys/net/if_lagg.h b/freebsd/sys/net/if_lagg.h index 81eeeb89..201d909a 100644 --- a/freebsd/sys/net/if_lagg.h +++ b/freebsd/sys/net/if_lagg.h @@ -185,10 +185,6 @@ struct lagg_ifreq { #define sc_ifflags sc_ifp->if_flags /* flags */ #define sc_ifname sc_ifp->if_xname /* name */ -#define sc_capabilities sc_ifp->if_capabilities /* capabilities */ - -#define IFCAP_LAGG_MASK 0xffff0000 /* private capabilities */ -#define IFCAP_LAGG_FULLDUPLEX 0x00010000 /* full duplex with >1 ports */ /* Private data used by the loadbalancing protocol */ struct lagg_lb { @@ -202,19 +198,6 @@ struct lagg_mc { SLIST_ENTRY(lagg_mc) mc_entries; }; -typedef enum { - LAGG_LLQTYPE_PHYS = 0, /* Task related to physical (underlying) port */ - LAGG_LLQTYPE_VIRT, /* Task related to lagg interface itself */ -} lagg_llqtype; - -/* List of interfaces to have the MAC address modified */ -struct lagg_llq { - struct ifnet *llq_ifp; - uint8_t llq_lladdr[ETHER_ADDR_LEN]; - lagg_llqtype llq_type; - SLIST_ENTRY(lagg_llq) llq_entries; -}; - struct lagg_counters { uint64_t val[IFCOUNTERS]; }; @@ -222,6 +205,7 @@ struct lagg_counters { struct lagg_softc { struct ifnet *sc_ifp; /* virtual interface */ struct rmlock sc_mtx; + struct sx sc_sx; int sc_proto; /* lagg protocol */ u_int sc_count; /* number of ports */ u_int sc_active; /* active port count */ @@ -232,13 +216,11 @@ struct lagg_softc { void *sc_psc; /* protocol data */ uint32_t sc_seq; /* sequence counter */ uint32_t sc_flags; + int sc_destroying; /* destroying lagg */ SLIST_HEAD(__tplhd, lagg_port) sc_ports; /* list of interfaces */ SLIST_ENTRY(lagg_softc) sc_entries; - struct task sc_lladdr_task; - SLIST_HEAD(__llqhd, lagg_llq) sc_llq_head; /* interfaces to program - the lladdr on */ eventhandler_tag vlan_attach; eventhandler_tag vlan_detach; struct callout sc_callout; @@ -258,12 +240,10 @@ struct lagg_port { uint32_t lp_prio; /* port priority */ uint32_t lp_flags; /* port flags */ int lp_ifflags; /* saved ifp flags */ + int lp_ifcapenable; /* saved ifp capenable */ void *lh_cookie; /* if state hook */ void *lp_psc; /* protocol data */ int lp_detaching; /* ifnet is detaching */ -#define LAGG_PORT_DETACH 0x01 /* detach lagg port */ -#define LAGG_CLONE_DESTROY 0x02 /* destroy lagg clone */ - SLIST_HEAD(__mclhd, lagg_mc) lp_mc_head; /* multicast addresses */ /* Redirected callbacks */ @@ -285,6 +265,16 @@ struct lagg_port { #define LAGG_WLOCK_ASSERT(_sc) rm_assert(&(_sc)->sc_mtx, RA_WLOCKED) #define LAGG_UNLOCK_ASSERT(_sc) rm_assert(&(_sc)->sc_mtx, RA_UNLOCKED) +#define LAGG_SX_INIT(_sc) sx_init(&(_sc)->sc_sx, "if_lagg sx") +#define LAGG_SX_DESTROY(_sc) sx_destroy(&(_sc)->sc_sx) +#define LAGG_SLOCK(_sc) sx_slock(&(_sc)->sc_sx) +#define LAGG_XLOCK(_sc) sx_xlock(&(_sc)->sc_sx) +#define LAGG_SUNLOCK(_sc) sx_sunlock(&(_sc)->sc_sx) +#define LAGG_XUNLOCK(_sc) sx_xunlock(&(_sc)->sc_sx) +#define LAGG_SXLOCK_ASSERT(_sc) sx_assert(&(_sc)->sc_sx, SA_LOCKED) +#define LAGG_SLOCK_ASSERT(_sc) sx_assert(&(_sc)->sc_sx, SA_SLOCKED) +#define LAGG_XLOCK_ASSERT(_sc) sx_assert(&(_sc)->sc_sx, SA_XLOCKED) + extern struct mbuf *(*lagg_input_p)(struct ifnet *, struct mbuf *); extern void (*lagg_linkstate_p)(struct ifnet *, int ); diff --git a/freebsd/sys/net/if_llatbl.c b/freebsd/sys/net/if_llatbl.c index 7de52a7d..c08218c6 100644 --- a/freebsd/sys/net/if_llatbl.c +++ b/freebsd/sys/net/if_llatbl.c @@ -536,7 +536,7 @@ lltable_drain(int af) { struct lltable *llt; struct llentry *lle; - register int i; + int i; LLTABLE_LIST_RLOCK(); SLIST_FOREACH(llt, &V_lltables, llt_link) { diff --git a/freebsd/sys/net/if_media.c b/freebsd/sys/net/if_media.c index 006afb04..4e39f656 100644 --- a/freebsd/sys/net/if_media.c +++ b/freebsd/sys/net/if_media.c @@ -123,7 +123,7 @@ ifmedia_add(ifm, mword, data, aux) int data; void *aux; { - register struct ifmedia_entry *entry; + struct ifmedia_entry *entry; #ifdef IFMEDIA_DEBUG if (ifmedia_debug) { diff --git a/freebsd/sys/net/if_media.h b/freebsd/sys/net/if_media.h index b6c999d3..d1080dd6 100644 --- a/freebsd/sys/net/if_media.h +++ b/freebsd/sys/net/if_media.h @@ -196,6 +196,10 @@ uint64_t ifmedia_baudrate(int); #define IFM_25G_SR IFM_X(55) /* 25GBase-SR */ #define IFM_50G_CR2 IFM_X(56) /* 50GBase-CR2 */ #define IFM_50G_KR2 IFM_X(57) /* 50GBase-KR2 */ +#define IFM_25G_LR IFM_X(58) /* 25GBase-LR */ +#define IFM_10G_AOC IFM_X(59) /* 10G active optical cable */ +#define IFM_25G_ACC IFM_X(60) /* 25G active copper cable */ +#define IFM_25G_AOC IFM_X(61) /* 25G active optical cable */ /* * Please update ieee8023ad_lacp.c:lacp_compose_key() @@ -450,6 +454,10 @@ struct ifmedia_description { { IFM_25G_SR, "25GBase-SR" }, \ { IFM_50G_CR2, "50GBase-CR2" }, \ { IFM_50G_KR2, "50GBase-KR2" }, \ + { IFM_25G_LR, "25GBase-LR" }, \ + { IFM_10G_AOC, "10GBase-AOC" }, \ + { IFM_25G_ACC, "25GBase-ACC" }, \ + { IFM_25G_AOC, "25GBase-AOC" }, \ { 0, NULL }, \ } @@ -782,6 +790,10 @@ struct ifmedia_baudrate { { IFM_ETHER | IFM_25G_SR, IF_Gbps(25ULL) }, \ { IFM_ETHER | IFM_50G_CR2, IF_Gbps(50ULL) }, \ { IFM_ETHER | IFM_50G_KR2, IF_Gbps(50ULL) }, \ + { IFM_ETHER | IFM_25G_LR, IF_Gbps(25ULL) }, \ + { IFM_ETHER | IFM_10G_AOC, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_25G_ACC, IF_Gbps(25ULL) }, \ + { IFM_ETHER | IFM_25G_AOC, IF_Gbps(25ULL) }, \ \ { IFM_TOKEN | IFM_TOK_STP4, IF_Mbps(4) }, \ { IFM_TOKEN | IFM_TOK_STP16, IF_Mbps(16) }, \ diff --git a/freebsd/sys/net/if_var.h b/freebsd/sys/net/if_var.h index c4601694..b8e5e5b8 100644 --- a/freebsd/sys/net/if_var.h +++ b/freebsd/sys/net/if_var.h @@ -281,6 +281,7 @@ struct ifnet { struct ifmultihead if_multiaddrs; /* multicast addresses configured */ int if_amcount; /* number of all-multicast requests */ struct ifaddr *if_addr; /* pointer to link-level address */ + void *if_hw_addr; /* hardware link-level address */ const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */ struct rwlock if_afdata_lock; void *if_afdata[AF_MAX]; @@ -664,6 +665,7 @@ int if_gethwassist(if_t ifp); int if_setsoftc(if_t ifp, void *softc); void *if_getsoftc(if_t ifp); int if_setflags(if_t ifp, int flags); +int if_gethwaddr(if_t ifp, struct ifreq *); int if_setmtu(if_t ifp, int mtu); int if_getmtu(if_t ifp); int if_getmtu_family(if_t ifp, int family); diff --git a/freebsd/sys/net/if_vlan.c b/freebsd/sys/net/if_vlan.c index 5db11c41..daba2606 100644 --- a/freebsd/sys/net/if_vlan.c +++ b/freebsd/sys/net/if_vlan.c @@ -115,6 +115,7 @@ struct ifvlan { #define PARENT(ifv) ((ifv)->ifv_trunk->parent) void *ifv_cookie; int ifv_pflags; /* special flags we have set on parent */ + int ifv_capenable; struct ifv_linkmib { int ifvm_encaplen; /* encapsulation length */ int ifvm_mtufudge; /* MTU fudged by this much */ @@ -475,6 +476,7 @@ trunk_destroy(struct ifvlantrunk *trunk) trunk->parent->if_vlantrunk = NULL; TRUNK_UNLOCK(trunk); TRUNK_LOCK_DESTROY(trunk); + if_rele(trunk->parent); free(trunk, M_VLAN); } @@ -849,16 +851,20 @@ vlan_clone_match_ethervid(const char *name, int *vidp) if ((cp = strchr(ifname, '.')) == NULL) return (NULL); *cp = '\0'; - if ((ifp = ifunit(ifname)) == NULL) + if ((ifp = ifunit_ref(ifname)) == NULL) return (NULL); /* Parse VID. */ - if (*++cp == '\0') + if (*++cp == '\0') { + if_rele(ifp); return (NULL); + } vid = 0; for(; *cp >= '0' && *cp <= '9'; cp++) vid = (vid * 10) + (*cp - '0'); - if (*cp != '\0') + if (*cp != '\0') { + if_rele(ifp); return (NULL); + } if (vidp != NULL) *vidp = vid; @@ -891,7 +897,6 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) int unit; int error; int vid; - int ethertag; struct ifvlan *ifv; struct ifnet *ifp; struct ifnet *p; @@ -916,23 +921,21 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) error = copyin(params, &vlr, sizeof(vlr)); if (error) return error; - p = ifunit(vlr.vlr_parent); + p = ifunit_ref(vlr.vlr_parent); if (p == NULL) return (ENXIO); error = ifc_name2unit(name, &unit); - if (error != 0) + if (error != 0) { + if_rele(p); return (error); - - ethertag = 1; + } vid = vlr.vlr_tag; wildcard = (unit < 0); } else if ((p = vlan_clone_match_ethervid(name, &vid)) != NULL) { - ethertag = 1; unit = -1; wildcard = 0; } else { - ethertag = 0; - + p = NULL; error = ifc_name2unit(name, &unit); if (error != 0) return (error); @@ -941,8 +944,11 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) } error = ifc_alloc_unit(ifc, &unit); - if (error != 0) + if (error != 0) { + if (p != NULL) + if_rele(p); return (error); + } /* In the wildcard case, we need to update the name. */ if (wildcard) { @@ -958,6 +964,8 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) if (ifp == NULL) { ifc_free_unit(ifc, unit); free(ifv, M_VLAN); + if (p != NULL) + if_rele(p); return (ENOSPC); } SLIST_INIT(&ifv->vlan_mc_listhead); @@ -991,8 +999,9 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) sdl = (struct sockaddr_dl *)ifa->ifa_addr; sdl->sdl_type = IFT_L2VLAN; - if (ethertag) { + if (p != NULL) { error = vlan_config(ifv, p, vid); + if_rele(p); if (error != 0) { /* * Since we've partially failed, we need to back @@ -1279,6 +1288,7 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) TRUNK_LOCK(trunk); p->if_vlantrunk = trunk; trunk->parent = p; + if_ref(trunk->parent); } else { VLAN_LOCK(); exists: @@ -1296,6 +1306,7 @@ exists: ifv->ifv_encaplen = ETHER_VLAN_ENCAP_LEN; ifv->ifv_mintu = ETHERMIN; ifv->ifv_pflags = 0; + ifv->ifv_capenable = -1; /* * If the parent supports the VLAN_MTU capability, @@ -1547,9 +1558,14 @@ vlan_capabilities(struct ifvlan *ifv) struct ifnet *p = PARENT(ifv); struct ifnet *ifp = ifv->ifv_ifp; struct ifnet_hw_tsomax hw_tsomax; + int cap = 0, ena = 0, mena; + u_long hwa = 0; TRUNK_LOCK_ASSERT(TRUNK(ifv)); + /* Mask parent interface enabled capabilities disabled by user. */ + mena = p->if_capenable & ifv->ifv_capenable; + /* * If the parent interface can do checksum offloading * on VLANs, then propagate its hardware-assisted @@ -1557,17 +1573,18 @@ vlan_capabilities(struct ifvlan *ifv) * offloading requires hardware VLAN tagging. */ if (p->if_capabilities & IFCAP_VLAN_HWCSUM) - ifp->if_capabilities = p->if_capabilities & IFCAP_HWCSUM; - + cap |= p->if_capabilities & (IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6); if (p->if_capenable & IFCAP_VLAN_HWCSUM && p->if_capenable & IFCAP_VLAN_HWTAGGING) { - ifp->if_capenable = p->if_capenable & IFCAP_HWCSUM; - ifp->if_hwassist = p->if_hwassist & (CSUM_IP | CSUM_TCP | - CSUM_UDP | CSUM_SCTP); - } else { - ifp->if_capenable = 0; - ifp->if_hwassist = 0; + ena |= mena & (IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6); + if (ena & IFCAP_TXCSUM) + hwa |= p->if_hwassist & (CSUM_IP | CSUM_TCP | + CSUM_UDP | CSUM_SCTP); + if (ena & IFCAP_TXCSUM_IPV6) + hwa |= p->if_hwassist & (CSUM_TCP_IPV6 | + CSUM_UDP_IPV6 | CSUM_SCTP_IPV6); } + /* * If the parent interface can do TSO on VLANs then * propagate the hardware-assisted flag. TSO on VLANs @@ -1577,16 +1594,24 @@ vlan_capabilities(struct ifvlan *ifv) if_hw_tsomax_common(p, &hw_tsomax); if_hw_tsomax_update(ifp, &hw_tsomax); if (p->if_capabilities & IFCAP_VLAN_HWTSO) - ifp->if_capabilities |= p->if_capabilities & IFCAP_TSO; + cap |= p->if_capabilities & IFCAP_TSO; if (p->if_capenable & IFCAP_VLAN_HWTSO) { - ifp->if_capenable |= p->if_capenable & IFCAP_TSO; - ifp->if_hwassist |= p->if_hwassist & CSUM_TSO; - } else { - ifp->if_capenable &= ~(p->if_capenable & IFCAP_TSO); - ifp->if_hwassist &= ~(p->if_hwassist & CSUM_TSO); + ena |= mena & IFCAP_TSO; + if (ena & IFCAP_TSO) + hwa |= p->if_hwassist & CSUM_TSO; } /* + * If the parent interface can do LRO and checksum offloading on + * VLANs, then guess it may do LRO on VLANs. False positive here + * cost nothing, while false negative may lead to some confusions. + */ + if (p->if_capabilities & IFCAP_VLAN_HWCSUM) + cap |= p->if_capabilities & IFCAP_LRO; + if (p->if_capenable & IFCAP_VLAN_HWCSUM) + ena |= p->if_capenable & IFCAP_LRO; + + /* * If the parent interface can offload TCP connections over VLANs then * propagate its TOE capability to the VLAN interface. * @@ -1596,20 +1621,31 @@ vlan_capabilities(struct ifvlan *ifv) */ #define IFCAP_VLAN_TOE IFCAP_TOE if (p->if_capabilities & IFCAP_VLAN_TOE) - ifp->if_capabilities |= p->if_capabilities & IFCAP_TOE; + cap |= p->if_capabilities & IFCAP_TOE; if (p->if_capenable & IFCAP_VLAN_TOE) { TOEDEV(ifp) = TOEDEV(p); - ifp->if_capenable |= p->if_capenable & IFCAP_TOE; + ena |= mena & IFCAP_TOE; } + /* + * If the parent interface supports dynamic link state, so does the + * VLAN interface. + */ + cap |= (p->if_capabilities & IFCAP_LINKSTATE); + ena |= (mena & IFCAP_LINKSTATE); + #ifdef RATELIMIT /* * If the parent interface supports ratelimiting, so does the * VLAN interface. */ - ifp->if_capabilities |= (p->if_capabilities & IFCAP_TXRTLMT); - ifp->if_capenable |= (p->if_capenable & IFCAP_TXRTLMT); + cap |= (p->if_capabilities & IFCAP_TXRTLMT); + ena |= (mena & IFCAP_TXRTLMT); #endif + + ifp->if_capabilities = cap; + ifp->if_capenable = ena; + ifp->if_hwassist = hwa; } static void @@ -1668,8 +1704,10 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) VLAN_LOCK(); if (TRUNK(ifv) != NULL) { p = PARENT(ifv); + if_ref(p); VLAN_UNLOCK(); error = (*p->if_ioctl)(p, SIOCGIFMEDIA, data); + if_rele(p); /* Limit the result to the parent's current config. */ if (error == 0) { struct ifmediareq *ifmr; @@ -1731,12 +1769,13 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) vlan_unconfig(ifp); break; } - p = ifunit(vlr.vlr_parent); + p = ifunit_ref(vlr.vlr_parent); if (p == NULL) { error = ENOENT; break; } error = vlan_config(ifv, p, vlr.vlr_tag); + if_rele(p); if (error) break; @@ -1813,6 +1852,18 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) vlan_tag_recalculate(ifv); break; + case SIOCSIFCAP: + VLAN_LOCK(); + ifv->ifv_capenable = ifr->ifr_reqcap; + trunk = TRUNK(ifv); + if (trunk != NULL) { + TRUNK_LOCK(trunk); + vlan_capabilities(ifv); + TRUNK_UNLOCK(trunk); + } + VLAN_UNLOCK(); + break; + default: error = EINVAL; break; diff --git a/freebsd/sys/net/iflib.h b/freebsd/sys/net/iflib.h index 9af87a2c..8bd20bfc 100644 --- a/freebsd/sys/net/iflib.h +++ b/freebsd/sys/net/iflib.h @@ -215,7 +215,9 @@ typedef struct if_softc_ctx { iflib_intr_mode_t isc_intr; uint16_t isc_max_frame_size; /* set at init time by driver */ + uint32_t isc_pause_frames; /* set by driver for iflib_timer to detect */ pci_vendor_info_t isc_vendor_info; /* set by iflib prior to attach_pre */ + int isc_disable_msix; if_txrx_t isc_txrx; } *if_softc_ctx_t; diff --git a/freebsd/sys/net/netisr.h b/freebsd/sys/net/netisr.h index 63764a74..b0e8e5ab 100644 --- a/freebsd/sys/net/netisr.h +++ b/freebsd/sys/net/netisr.h @@ -55,7 +55,6 @@ #define NETISR_ARP 4 /* same as AF_LINK */ #define NETISR_ETHER 5 /* ethernet input */ #define NETISR_IPV6 6 -#define NETISR_NATM 7 #define NETISR_EPAIR 8 /* if_epair(4) */ #define NETISR_IP_DIRECT 9 /* direct-dispatch IPv4 */ #define NETISR_IPV6_DIRECT 10 /* direct-dispatch IPv6 */ diff --git a/freebsd/sys/net/route.h b/freebsd/sys/net/route.h index 93193b5f..d4bc4056 100644 --- a/freebsd/sys/net/route.h +++ b/freebsd/sys/net/route.h @@ -265,25 +265,35 @@ struct rt_msghdr { /* * Message types. + * + * The format for each message is annotated below using the following + * identifiers: + * + * (1) struct rt_msghdr + * (2) struct ifa_msghdr + * (3) struct if_msghdr + * (4) struct ifma_msghdr + * (5) struct if_announcemsghdr + * */ -#define RTM_ADD 0x1 /* Add Route */ -#define RTM_DELETE 0x2 /* Delete Route */ -#define RTM_CHANGE 0x3 /* Change Metrics or flags */ -#define RTM_GET 0x4 /* Report Metrics */ -#define RTM_LOSING 0x5 /* Kernel Suspects Partitioning */ -#define RTM_REDIRECT 0x6 /* Told to use different route */ -#define RTM_MISS 0x7 /* Lookup failed on this address */ -#define RTM_LOCK 0x8 /* fix specified metrics */ +#define RTM_ADD 0x1 /* (1) Add Route */ +#define RTM_DELETE 0x2 /* (1) Delete Route */ +#define RTM_CHANGE 0x3 /* (1) Change Metrics or flags */ +#define RTM_GET 0x4 /* (1) Report Metrics */ +#define RTM_LOSING 0x5 /* (1) Kernel Suspects Partitioning */ +#define RTM_REDIRECT 0x6 /* (1) Told to use different route */ +#define RTM_MISS 0x7 /* (1) Lookup failed on this address */ +#define RTM_LOCK 0x8 /* (1) fix specified metrics */ /* 0x9 */ /* 0xa */ -#define RTM_RESOLVE 0xb /* req to resolve dst to LL addr */ -#define RTM_NEWADDR 0xc /* address being added to iface */ -#define RTM_DELADDR 0xd /* address being removed from iface */ -#define RTM_IFINFO 0xe /* iface going up/down etc. */ -#define RTM_NEWMADDR 0xf /* mcast group membership being added to if */ -#define RTM_DELMADDR 0x10 /* mcast group membership being deleted */ -#define RTM_IFANNOUNCE 0x11 /* iface arrival/departure */ -#define RTM_IEEE80211 0x12 /* IEEE80211 wireless event */ +#define RTM_RESOLVE 0xb /* (1) req to resolve dst to LL addr */ +#define RTM_NEWADDR 0xc /* (2) address being added to iface */ +#define RTM_DELADDR 0xd /* (2) address being removed from iface */ +#define RTM_IFINFO 0xe /* (3) iface going up/down etc. */ +#define RTM_NEWMADDR 0xf /* (4) mcast group membership being added to if */ +#define RTM_DELMADDR 0x10 /* (4) mcast group membership being deleted */ +#define RTM_IFANNOUNCE 0x11 /* (5) iface arrival/departure */ +#define RTM_IEEE80211 0x12 /* (5) IEEE80211 wireless event */ /* * Bitmask values for rtm_inits and rmx_locks. @@ -342,11 +352,10 @@ struct rt_addrinfo { * This macro returns the size of a struct sockaddr when passed * through a routing socket. Basically we round up sa_len to * a multiple of sizeof(long), with a minimum of sizeof(long). - * The check for a NULL pointer is just a convenience, probably never used. * The case sa_len == 0 should only apply to empty structures. */ #define SA_SIZE(sa) \ - ( (!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? \ + ( (((struct sockaddr *)(sa))->sa_len == 0) ? \ sizeof(long) : \ 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) ) diff --git a/freebsd/sys/net/rtsock.c b/freebsd/sys/net/rtsock.c index d8835e89..1f527cd3 100644 --- a/freebsd/sys/net/rtsock.c +++ b/freebsd/sys/net/rtsock.c @@ -740,7 +740,7 @@ route_output(struct mbuf *m, struct socket *so, ...) if (info.rti_info[RTAX_NETMASK] == NULL && rtm->rtm_type == RTM_GET) { /* - * Provide logest prefix match for + * Provide longest prefix match for * address lookup (no mask). * 'route -n get addr' */ diff --git a/freebsd/sys/net/slcompress.c b/freebsd/sys/net/slcompress.c index 1c850552..7ad705fe 100644 --- a/freebsd/sys/net/slcompress.c +++ b/freebsd/sys/net/slcompress.c @@ -62,12 +62,10 @@ #define BCOPY(p1, p2, n) bcopy((void *)(p1), (void *)(p2), (int)(n)) void -sl_compress_init(comp, max_state) - struct slcompress *comp; - int max_state; +sl_compress_init(struct slcompress *comp, int max_state) { - register u_int i; - register struct cstate *tstate = comp->tstate; + u_int i; + struct cstate *tstate = comp->tstate; if (max_state == -1) { max_state = MAX_STATES - 1; @@ -154,20 +152,17 @@ sl_compress_init(comp, max_state) * if m is an M_PKTHDR mbuf. */ u_int -sl_compress_tcp(m, ip, comp, compress_cid) - struct mbuf *m; - register struct ip *ip; - struct slcompress *comp; - int compress_cid; +sl_compress_tcp(struct mbuf *m, struct ip *ip, struct slcompress *comp, + int compress_cid) { - register struct cstate *cs = comp->last_cs->cs_next; - register u_int hlen = ip->ip_hl; - register struct tcphdr *oth; - register struct tcphdr *th; - register u_int deltaS, deltaA; - register u_int changes = 0; + struct cstate *cs = comp->last_cs->cs_next; + u_int hlen = ip->ip_hl; + struct tcphdr *oth; + struct tcphdr *th; + u_int deltaS, deltaA; + u_int changes = 0; u_char new_seq[16]; - register u_char *cp = new_seq; + u_char *cp = new_seq; /* * Bail if this is an IP fragment or if the TCP packet isn't @@ -204,8 +199,8 @@ sl_compress_tcp(m, ip, comp, compress_cid) * states via linear search. If we don't find a state * for the datagram, the oldest state is (re-)used. */ - register struct cstate *lcs; - register struct cstate *lastcs = comp->last_cs; + struct cstate *lcs; + struct cstate *lastcs = comp->last_cs; do { lcs = cs; cs = cs->cs_next; @@ -414,11 +409,7 @@ uncompressed: int -sl_uncompress_tcp(bufp, len, type, comp) - u_char **bufp; - int len; - u_int type; - struct slcompress *comp; +sl_uncompress_tcp(u_char **bufp, int len, u_int type, struct slcompress *comp) { u_char *hdr, *cp; int hlen, vjlen; @@ -462,21 +453,16 @@ sl_uncompress_tcp(bufp, len, type, comp) * in *hdrp and its length in *hlenp. */ int -sl_uncompress_tcp_core(buf, buflen, total_len, type, comp, hdrp, hlenp) - u_char *buf; - int buflen, total_len; - u_int type; - struct slcompress *comp; - u_char **hdrp; - u_int *hlenp; +sl_uncompress_tcp_core(u_char *buf, int buflen, int total_len, u_int type, + struct slcompress *comp, u_char **hdrp, u_int *hlenp) { - register u_char *cp; - register u_int hlen, changes; - register struct tcphdr *th; - register struct cstate *cs; - register struct ip *ip; - register u_int16_t *bp; - register u_int vjlen; + u_char *cp; + u_int hlen, changes; + struct tcphdr *th; + struct cstate *cs; + struct ip *ip; + u_int16_t *bp; + u_int vjlen; switch (type) { @@ -544,7 +530,7 @@ sl_uncompress_tcp_core(buf, buflen, total_len, type, comp, hdrp, hlenp) switch (changes & SPECIALS_MASK) { case SPECIAL_I: { - register u_int i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen; + u_int i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen; th->th_ack = htonl(ntohl(th->th_ack) + i); th->th_seq = htonl(ntohl(th->th_seq) + i); } diff --git a/freebsd/sys/net80211/ieee80211_adhoc.c b/freebsd/sys/net80211/ieee80211_adhoc.c index 1f3a6207..9372226e 100644 --- a/freebsd/sys/net80211/ieee80211_adhoc.c +++ b/freebsd/sys/net80211/ieee80211_adhoc.c @@ -450,7 +450,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, if (IEEE80211_QOS_HAS_SEQ(wh) && TID_TO_WME_AC(tid) >= WME_AC_VI) ic->ic_wme.wme_hipri_traffic++; - if (! ieee80211_check_rxseq(ni, wh, bssid)) + if (! ieee80211_check_rxseq(ni, wh, bssid, rxs)) goto out; } } @@ -481,7 +481,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, * and we should do nothing more with it. */ if ((m->m_flags & M_AMPDU) && - ieee80211_ampdu_reorder(ni, m) != 0) { + ieee80211_ampdu_reorder(ni, m, rxs) != 0) { m = NULL; goto out; } diff --git a/freebsd/sys/net80211/ieee80211_hostap.c b/freebsd/sys/net80211/ieee80211_hostap.c index 1ac79035..8fd4270a 100644 --- a/freebsd/sys/net80211/ieee80211_hostap.c +++ b/freebsd/sys/net80211/ieee80211_hostap.c @@ -579,7 +579,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, if (IEEE80211_QOS_HAS_SEQ(wh) && TID_TO_WME_AC(tid) >= WME_AC_VI) ic->ic_wme.wme_hipri_traffic++; - if (! ieee80211_check_rxseq(ni, wh, bssid)) + if (! ieee80211_check_rxseq(ni, wh, bssid, rxs)) goto out; } } @@ -667,7 +667,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, * and we should do nothing more with it. */ if ((m->m_flags & M_AMPDU) && - ieee80211_ampdu_reorder(ni, m) != 0) { + ieee80211_ampdu_reorder(ni, m, rxs) != 0) { m = NULL; goto out; } diff --git a/freebsd/sys/net80211/ieee80211_ht.c b/freebsd/sys/net80211/ieee80211_ht.c index 4b2834a1..77e254e6 100644 --- a/freebsd/sys/net80211/ieee80211_ht.c +++ b/freebsd/sys/net80211/ieee80211_ht.c @@ -515,23 +515,67 @@ ieee80211_decap_amsdu(struct ieee80211_node *ni, struct mbuf *m) } /* + * Add the given frame to the current RX reorder slot. + * + * For future offloaded A-MSDU handling where multiple frames with + * the same sequence number show up here, this routine will append + * those frames as long as they're appropriately tagged. + */ +static int +ampdu_rx_add_slot(struct ieee80211_rx_ampdu *rap, int off, int tid, + ieee80211_seq rxseq, + struct ieee80211_node *ni, + struct mbuf *m) +{ + struct ieee80211vap *vap = ni->ni_vap; + + if (rap->rxa_m[off] == NULL) { + rap->rxa_m[off] = m; + rap->rxa_qframes++; + rap->rxa_qbytes += m->m_pkthdr.len; + vap->iv_stats.is_ampdu_rx_reorder++; + return (0); + } else { + IEEE80211_DISCARD_MAC(vap, + IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, + ni->ni_macaddr, "a-mpdu duplicate", + "seqno %u tid %u BA win <%u:%u>", + rxseq, tid, rap->rxa_start, + IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1)); + vap->iv_stats.is_rx_dup++; + IEEE80211_NODE_STAT(ni, rx_dup); + m_freem(m); + return (-1); + } +} + +static void +ampdu_rx_purge_slot(struct ieee80211_rx_ampdu *rap, int i) +{ + struct mbuf *m; + + m = rap->rxa_m[i]; + if (m == NULL) + return; + + rap->rxa_m[i] = NULL; + rap->rxa_qbytes -= m->m_pkthdr.len; + rap->rxa_qframes--; + m_freem(m); +} + +/* * Purge all frames in the A-MPDU re-order queue. */ static void ampdu_rx_purge(struct ieee80211_rx_ampdu *rap) { - struct mbuf *m; int i; for (i = 0; i < rap->rxa_wnd; i++) { - m = rap->rxa_m[i]; - if (m != NULL) { - rap->rxa_m[i] = NULL; - rap->rxa_qbytes -= m->m_pkthdr.len; - m_freem(m); - if (--rap->rxa_qframes == 0) - break; - } + ampdu_rx_purge_slot(rap, i); + if (rap->rxa_qframes == 0) + break; } KASSERT(rap->rxa_qbytes == 0 && rap->rxa_qframes == 0, ("lost %u data, %u frames on ampdu rx q", @@ -646,6 +690,25 @@ ampdu_dispatch(struct ieee80211_node *ni, struct mbuf *m) (void) ieee80211_input(ni, m, 0, 0); } +static int +ampdu_dispatch_slot(struct ieee80211_rx_ampdu *rap, struct ieee80211_node *ni, + int i) +{ + struct mbuf *m; + + if (rap->rxa_m[i] == NULL) + return (0); + + m = rap->rxa_m[i]; + rap->rxa_m[i] = NULL; + rap->rxa_qbytes -= m->m_pkthdr.len; + rap->rxa_qframes--; + + ampdu_dispatch(ni, m); + + return (1); +} + static void ampdu_rx_moveup(struct ieee80211_rx_ampdu *rap, struct ieee80211_node *ni, int i, int winstart) @@ -692,20 +755,14 @@ static void ampdu_rx_dispatch(struct ieee80211_rx_ampdu *rap, struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; - struct mbuf *m; int i; /* flush run of frames */ for (i = 1; i < rap->rxa_wnd; i++) { - m = rap->rxa_m[i]; - if (m == NULL) + if (ampdu_dispatch_slot(rap, ni, i) == 0) break; - rap->rxa_m[i] = NULL; - rap->rxa_qbytes -= m->m_pkthdr.len; - rap->rxa_qframes--; - - ampdu_dispatch(ni, m); } + /* * If frames remain, copy the mbuf pointers down so * they correspond to the offsets in the new window. @@ -727,19 +784,14 @@ static void ampdu_rx_flush(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap) { struct ieee80211vap *vap = ni->ni_vap; - struct mbuf *m; - int i; + int i, r; for (i = 0; i < rap->rxa_wnd; i++) { - m = rap->rxa_m[i]; - if (m == NULL) + r = ampdu_dispatch_slot(rap, ni, i); + if (r == 0) continue; - rap->rxa_m[i] = NULL; - rap->rxa_qbytes -= m->m_pkthdr.len; - rap->rxa_qframes--; - vap->iv_stats.is_ampdu_rx_oor++; + vap->iv_stats.is_ampdu_rx_oor += r; - ampdu_dispatch(ni, m); if (rap->rxa_qframes == 0) break; } @@ -755,9 +807,8 @@ ampdu_rx_flush_upto(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap, ieee80211_seq winstart) { struct ieee80211vap *vap = ni->ni_vap; - struct mbuf *m; ieee80211_seq seqno; - int i; + int i, r; /* * Flush any complete MSDU's with a sequence number lower @@ -768,18 +819,12 @@ ampdu_rx_flush_upto(struct ieee80211_node *ni, */ seqno = rap->rxa_start; for (i = 0; i < rap->rxa_wnd; i++) { - m = rap->rxa_m[i]; - if (m != NULL) { - rap->rxa_m[i] = NULL; - rap->rxa_qbytes -= m->m_pkthdr.len; - rap->rxa_qframes--; - vap->iv_stats.is_ampdu_rx_oor++; - - ampdu_dispatch(ni, m); - } else { + r = ampdu_dispatch_slot(rap, ni, i); + if (r == 0) { if (!IEEE80211_SEQ_BA_BEFORE(seqno, winstart)) break; } + vap->iv_stats.is_ampdu_rx_oor += r; seqno = IEEE80211_SEQ_INC(seqno); } /* @@ -806,7 +851,8 @@ ampdu_rx_flush_upto(struct ieee80211_node *ni, * the frame should be processed normally by the caller. */ int -ieee80211_ampdu_reorder(struct ieee80211_node *ni, struct mbuf *m) +ieee80211_ampdu_reorder(struct ieee80211_node *ni, struct mbuf *m, + const struct ieee80211_rx_stats *rxs) { #define PROCESS 0 /* caller should process frame */ #define CONSUMED 1 /* frame consumed, caller does nothing */ @@ -950,23 +996,9 @@ again: rap->rxa_age = ticks; } - /* save packet */ - if (rap->rxa_m[off] == NULL) { - rap->rxa_m[off] = m; - rap->rxa_qframes++; - rap->rxa_qbytes += m->m_pkthdr.len; - vap->iv_stats.is_ampdu_rx_reorder++; - } else { - IEEE80211_DISCARD_MAC(vap, - IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, - ni->ni_macaddr, "a-mpdu duplicate", - "seqno %u tid %u BA win <%u:%u>", - rxseq, tid, rap->rxa_start, - IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1)); - vap->iv_stats.is_rx_dup++; - IEEE80211_NODE_STAT(ni, rx_dup); - m_freem(m); - } + /* save packet - this consumes, no matter what */ + ampdu_rx_add_slot(rap, off, tid, rxseq, ni, m); + return CONSUMED; } if (off < IEEE80211_SEQ_BA_RANGE) { diff --git a/freebsd/sys/net80211/ieee80211_ht.h b/freebsd/sys/net80211/ieee80211_ht.h index 5b818a28..b85e1c9a 100644 --- a/freebsd/sys/net80211/ieee80211_ht.h +++ b/freebsd/sys/net80211/ieee80211_ht.h @@ -185,7 +185,8 @@ int ieee80211_setup_htrates(struct ieee80211_node *, void ieee80211_setup_basic_htrates(struct ieee80211_node *, const uint8_t *htinfo); struct mbuf *ieee80211_decap_amsdu(struct ieee80211_node *, struct mbuf *); -int ieee80211_ampdu_reorder(struct ieee80211_node *, struct mbuf *); +int ieee80211_ampdu_reorder(struct ieee80211_node *, struct mbuf *, + const struct ieee80211_rx_stats *); void ieee80211_recv_bar(struct ieee80211_node *, struct mbuf *); void ieee80211_ht_node_init(struct ieee80211_node *); void ieee80211_ht_node_cleanup(struct ieee80211_node *); diff --git a/freebsd/sys/net80211/ieee80211_input.h b/freebsd/sys/net80211/ieee80211_input.h index 0ae8dd08..cff07c68 100644 --- a/freebsd/sys/net80211/ieee80211_input.h +++ b/freebsd/sys/net80211/ieee80211_input.h @@ -158,7 +158,7 @@ ishtinfooui(const uint8_t *frm) */ static __inline int ieee80211_check_rxseq(struct ieee80211_node *ni, struct ieee80211_frame *wh, - uint8_t *bssid) + uint8_t *bssid, const struct ieee80211_rx_stats *rxs) { #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) #define SEQ_EQ(a,b) ((int)((a)-(b)) == 0) diff --git a/freebsd/sys/net80211/ieee80211_mesh.c b/freebsd/sys/net80211/ieee80211_mesh.c index ab7291dd..3abe5a26 100644 --- a/freebsd/sys/net80211/ieee80211_mesh.c +++ b/freebsd/sys/net80211/ieee80211_mesh.c @@ -1582,7 +1582,7 @@ mesh_input(struct ieee80211_node *ni, struct mbuf *m, if (IEEE80211_QOS_HAS_SEQ(wh) && TID_TO_WME_AC(tid) >= WME_AC_VI) ic->ic_wme.wme_hipri_traffic++; - if (! ieee80211_check_rxseq(ni, wh, wh->i_addr1)) + if (! ieee80211_check_rxseq(ni, wh, wh->i_addr1, rxs)) goto out; } } diff --git a/freebsd/sys/net80211/ieee80211_proto.c b/freebsd/sys/net80211/ieee80211_proto.c index 5fc764a9..d9cbc3b5 100644 --- a/freebsd/sys/net80211/ieee80211_proto.c +++ b/freebsd/sys/net80211/ieee80211_proto.c @@ -1308,6 +1308,20 @@ ieee80211_wme_updateparams(struct ieee80211vap *vap) } } +void +ieee80211_wme_vap_getparams(struct ieee80211vap *vap, struct chanAccParams *wp) +{ + + memcpy(wp, &vap->iv_ic->ic_wme.wme_chanParams, sizeof(*wp)); +} + +void +ieee80211_wme_ic_getparams(struct ieee80211com *ic, struct chanAccParams *wp) +{ + + memcpy(wp, &ic->ic_wme.wme_chanParams, sizeof(*wp)); +} + static void parent_updown(void *arg, int npending) { diff --git a/freebsd/sys/net80211/ieee80211_proto.h b/freebsd/sys/net80211/ieee80211_proto.h index 784179fd..b9aef7cb 100644 --- a/freebsd/sys/net80211/ieee80211_proto.h +++ b/freebsd/sys/net80211/ieee80211_proto.h @@ -292,6 +292,10 @@ struct ieee80211_wme_state { void ieee80211_wme_initparams(struct ieee80211vap *); void ieee80211_wme_updateparams(struct ieee80211vap *); void ieee80211_wme_updateparams_locked(struct ieee80211vap *); +void ieee80211_wme_vap_getparams(struct ieee80211vap *vap, + struct chanAccParams *); +void ieee80211_wme_ic_getparams(struct ieee80211com *ic, + struct chanAccParams *); /* * Return the WME TID from a QoS frame. If no TID diff --git a/freebsd/sys/net80211/ieee80211_radiotap.h b/freebsd/sys/net80211/ieee80211_radiotap.h index 388d70ed..e42c6664 100644 --- a/freebsd/sys/net80211/ieee80211_radiotap.h +++ b/freebsd/sys/net80211/ieee80211_radiotap.h @@ -178,6 +178,30 @@ struct ieee80211_radiotap_header { * finally the maximum regulatory transmit power cap in .5 dBm * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL * and only one of the two should be present. + * IEEE80211_RADIOTAP_RX_FLAGS guint16 bitmap + * + * Properties of received frames. See flags defined below. + * + * IEEE80211_RADIOTAP_TX_FLAGS guint16 bitmap + * + * Properties of transmitted frames. See flags defined below. + * + * IEEE80211_RADIOTAP_RTS_RETRIES u8 data + * + * Number of rts retries a transmitted frame used. + * + * IEEE80211_RADIOTAP_DATA_RETRIES u8 data + * + * Number of unicast retries a transmitted frame used. + * + * IEEE80211_RADIOTAP_MCS u8, u8, u8 unitless + * + * Contains a bitmap of known fields/flags, the flags, and + * the MCS index. + * + * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitlesss + * + * Contains the AMPDU information for the subframe. */ enum ieee80211_radiotap_type { IEEE80211_RADIOTAP_TSFT = 0, @@ -206,6 +230,7 @@ enum ieee80211_radiotap_type { IEEE80211_RADIOTAP_XCHANNEL = 18, IEEE80211_RADIOTAP_MCS = 19, IEEE80211_RADIOTAP_AMPDU_STATUS = 20, + IEEE80211_RADIOTAP_VHT = 21, IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29, IEEE80211_RADIOTAP_VENDOREXT = 30, @@ -250,4 +275,95 @@ enum ieee80211_radiotap_type { #define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */ #define IEEE80211_RADIOTAP_F_SHORTGI 0x80 /* HT short GI */ +/* For IEEE80211_RADIOTAP_RX_FLAGS */ +#define IEEE80211_RADIOTAP_F_RX_BADPLCP 0x0002 /* bad PLCP */ + +/* For IEEE80211_RADIOTAP_TX_FLAGS */ +#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive + * retries */ +#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */ +#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ + + +/* For IEEE80211_RADIOTAP_MCS */ +#define IEEE80211_RADIOTAP_MCS_HAVE_BW 0x01 +#define IEEE80211_RADIOTAP_MCS_HAVE_MCS 0x02 +#define IEEE80211_RADIOTAP_MCS_HAVE_GI 0x04 +#define IEEE80211_RADIOTAP_MCS_HAVE_FMT 0x08 +#define IEEE80211_RADIOTAP_MCS_HAVE_FEC 0x10 +#define IEEE80211_RADIOTAP_MCS_HAVE_STBC 0x20 +#define IEEE80211_RADIOTAP_MCS_HAVE_NESS 0x40 +#define IEEE80211_RADIOTAP_MCS_NESS_BIT1 0x80 + +#define IEEE80211_RADIOTAP_MCS_BW_MASK 0x03 +#define IEEE80211_RADIOTAP_MCS_BW_20 0 +#define IEEE80211_RADIOTAP_MCS_BW_40 1 +#define IEEE80211_RADIOTAP_MCS_BW_20L 2 +#define IEEE80211_RADIOTAP_MCS_BW_20U 3 +#define IEEE80211_RADIOTAP_MCS_SGI 0x04 +#define IEEE80211_RADIOTAP_MCS_FMT_GF 0x08 +#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 +#define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60 +#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5 +#define IEEE80211_RADIOTAP_MCS_STBC_1 1 +#define IEEE80211_RADIOTAP_MCS_STBC_2 2 +#define IEEE80211_RADIOTAP_MCS_STBC_3 3 +#define IEEE80211_RADIOTAP_MCS_NESS_BIT0 0x80 + +/* For IEEE80211_RADIOTAP_AMPDU_STATUS */ +#define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001 +#define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN 0x0002 +#define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN 0x0004 +#define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008 +#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 +#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 + +/* For IEEE80211_RADIOTAP_VHT */ +#define IEEE80211_RADIOTAP_VHT_HAVE_STBC 0x0001 +#define IEEE80211_RADIOTAP_VHT_HAVE_TXOP_PS 0x0002 +#define IEEE80211_RADIOTAP_VHT_HAVE_GI 0x0004 +#define IEEE80211_RADIOTAP_VHT_HAVE_SGI_NSYM_DA 0x0008 +#define IEEE80211_RADIOTAP_VHT_HAVE_LDPC_EXTRA 0x0010 +#define IEEE80211_RADIOTAP_VHT_HAVE_BF 0x0020 +#define IEEE80211_RADIOTAP_VHT_HAVE_BW 0x0040 +#define IEEE80211_RADIOTAP_VHT_HAVE_GID 0x0080 +#define IEEE80211_RADIOTAP_VHT_HAVE_PAID 0x0100 +#define IEEE80211_RADIOTAP_VHT_STBC 0x01 +#define IEEE80211_RADIOTAP_VHT_TXOP_PS 0x02 +#define IEEE80211_RADIOTAP_VHT_SGI 0x04 +#define IEEE80211_RADIOTAP_VHT_SGI_NSYM_DA 0x08 +#define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA 0x10 +#define IEEE80211_RADIOTAP_VHT_BF 0x20 +#define IEEE80211_RADIOTAP_VHT_NSS 0x0f +#define IEEE80211_RADIOTAP_VHT_MCS 0xf0 +#define IEEE80211_RADIOTAP_VHT_CODING_LDPC 0x01 + +#define IEEE80211_RADIOTAP_VHT_BW_MASK 0x1f +#define IEEE80211_RADIOTAP_VHT_BW_20 IEEE80211_RADIOTAP_MCS_BW_20 +#define IEEE80211_RADIOTAP_VHT_BW_40 IEEE80211_RADIOTAP_MCS_BW_40 +#define IEEE80211_RADIOTAP_VHT_BW_20L IEEE80211_RADIOTAP_MCS_BW_20L +#define IEEE80211_RADIOTAP_VHT_BW_20U IEEE80211_RADIOTAP_MCS_BW_20U +#define IEEE80211_RADIOTAP_VHT_BW_80 4 +#define IEEE80211_RADIOTAP_VHT_BW_40L 5 +#define IEEE80211_RADIOTAP_VHT_BW_40U 6 +#define IEEE80211_RADIOTAP_VHT_BW_20LL 7 +#define IEEE80211_RADIOTAP_VHT_BW_20LU 8 +#define IEEE80211_RADIOTAP_VHT_BW_20UL 9 +#define IEEE80211_RADIOTAP_VHT_BW_20UU 10 +#define IEEE80211_RADIOTAP_VHT_BW_160 11 +#define IEEE80211_RADIOTAP_VHT_BW_80L 12 +#define IEEE80211_RADIOTAP_VHT_BW_80U 13 +#define IEEE80211_RADIOTAP_VHT_BW_40LL 14 +#define IEEE80211_RADIOTAP_VHT_BW_40LU 15 +#define IEEE80211_RADIOTAP_VHT_BW_40UL 16 +#define IEEE80211_RADIOTAP_VHT_BW_40UU 17 +#define IEEE80211_RADIOTAP_VHT_BW_20LLL 18 +#define IEEE80211_RADIOTAP_VHT_BW_20LLU 19 +#define IEEE80211_RADIOTAP_VHT_BW_20LUL 20 +#define IEEE80211_RADIOTAP_VHT_BW_20LUU 21 +#define IEEE80211_RADIOTAP_VHT_BW_20ULL 22 +#define IEEE80211_RADIOTAP_VHT_BW_20ULU 23 +#define IEEE80211_RADIOTAP_VHT_BW_20UUL 24 +#define IEEE80211_RADIOTAP_VHT_BW_20UUU 25 + #endif /* !_NET80211_IEEE80211_RADIOTAP_H_ */ diff --git a/freebsd/sys/net80211/ieee80211_sta.c b/freebsd/sys/net80211/ieee80211_sta.c index 664c3b8f..8e0da623 100644 --- a/freebsd/sys/net80211/ieee80211_sta.c +++ b/freebsd/sys/net80211/ieee80211_sta.c @@ -650,7 +650,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, if (IEEE80211_QOS_HAS_SEQ(wh) && TID_TO_WME_AC(tid) >= WME_AC_VI) ic->ic_wme.wme_hipri_traffic++; - if (! ieee80211_check_rxseq(ni, wh, bssid)) + if (! ieee80211_check_rxseq(ni, wh, bssid, rxs)) goto out; } } @@ -675,7 +675,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, if ((m->m_flags & M_AMPDU) && (dir == IEEE80211_FC1_DIR_FROMDS || dir == IEEE80211_FC1_DIR_DSTODS) && - ieee80211_ampdu_reorder(ni, m) != 0) { + ieee80211_ampdu_reorder(ni, m, rxs) != 0) { m = NULL; goto out; } diff --git a/freebsd/sys/net80211/ieee80211_wds.c b/freebsd/sys/net80211/ieee80211_wds.c index 500d060a..66ee0322 100644 --- a/freebsd/sys/net80211/ieee80211_wds.c +++ b/freebsd/sys/net80211/ieee80211_wds.c @@ -506,7 +506,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, if (IEEE80211_QOS_HAS_SEQ(wh) && TID_TO_WME_AC(tid) >= WME_AC_VI) ic->ic_wme.wme_hipri_traffic++; - if (! ieee80211_check_rxseq(ni, wh, wh->i_addr1)) + if (! ieee80211_check_rxseq(ni, wh, wh->i_addr1, rxs)) goto out; } switch (type) { @@ -542,7 +542,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, * and we should do nothing more with it. */ if ((m->m_flags & M_AMPDU) && - ieee80211_ampdu_reorder(ni, m) != 0) { + ieee80211_ampdu_reorder(ni, m, rxs) != 0) { m = NULL; goto out; } diff --git a/freebsd/sys/netinet/in.c b/freebsd/sys/netinet/in.c index ca902fdc..0b31ff7e 100644 --- a/freebsd/sys/netinet/in.c +++ b/freebsd/sys/netinet/in.c @@ -98,8 +98,8 @@ int in_localaddr(struct in_addr in) { struct rm_priotracker in_ifa_tracker; - register u_long i = ntohl(in.s_addr); - register struct in_ifaddr *ia; + u_long i = ntohl(in.s_addr); + struct in_ifaddr *ia; IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { @@ -189,8 +189,8 @@ in_localip_more(struct in_ifaddr *ia) int in_canforward(struct in_addr in) { - register u_long i = ntohl(in.s_addr); - register u_long net; + u_long i = ntohl(in.s_addr); + u_long net; if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i) || IN_LINKLOCAL(i)) return (0); @@ -208,8 +208,8 @@ in_canforward(struct in_addr in) static void in_socktrim(struct sockaddr_in *ap) { - register char *cplim = (char *) &ap->sin_addr; - register char *cp = (char *) (&ap->sin_addr + 1); + char *cplim = (char *) &ap->sin_addr; + char *cp = (char *) (&ap->sin_addr + 1); ap->sin_len = 0; while (--cp >= cplim) @@ -966,7 +966,7 @@ in_ifaddr_broadcast(struct in_addr in, struct in_ifaddr *ia) int in_broadcast(struct in_addr in, struct ifnet *ifp) { - register struct ifaddr *ifa; + struct ifaddr *ifa; int found; if (in.s_addr == INADDR_BROADCAST || diff --git a/freebsd/sys/netinet/in_kdtrace.h b/freebsd/sys/netinet/in_kdtrace.h index a36991ef..0825c7df 100644 --- a/freebsd/sys/netinet/in_kdtrace.h +++ b/freebsd/sys/netinet/in_kdtrace.h @@ -65,6 +65,7 @@ SDT_PROBE_DECLARE(tcp, , , debug__input); SDT_PROBE_DECLARE(tcp, , , debug__output); SDT_PROBE_DECLARE(tcp, , , debug__user); SDT_PROBE_DECLARE(tcp, , , debug__drop); +SDT_PROBE_DECLARE(tcp, , , receive__autoresize); SDT_PROBE_DECLARE(udp, , , receive); SDT_PROBE_DECLARE(udp, , , send); diff --git a/freebsd/sys/netinet/in_mcast.c b/freebsd/sys/netinet/in_mcast.c index cb92a254..2ba4d9e8 100644 --- a/freebsd/sys/netinet/in_mcast.c +++ b/freebsd/sys/netinet/in_mcast.c @@ -1049,9 +1049,10 @@ inm_merge(struct in_multi *inm, /*const*/ struct in_mfilter *imf) /* Decrement ASM listener count on transition out of ASM mode. */ if (imf->imf_st[0] == MCAST_EXCLUDE && nsrc0 == 0) { if ((imf->imf_st[1] != MCAST_EXCLUDE) || - (imf->imf_st[1] == MCAST_EXCLUDE && nsrc1 > 0)) + (imf->imf_st[1] == MCAST_EXCLUDE && nsrc1 > 0)) { CTR1(KTR_IGMPV3, "%s: --asm on inm at t1", __func__); --inm->inm_st[1].iss_asm; + } } /* Increment ASM listener count on transition to ASM mode. */ diff --git a/freebsd/sys/netinet/in_pcb.c b/freebsd/sys/netinet/in_pcb.c index b61b6e09..3d43ed92 100644 --- a/freebsd/sys/netinet/in_pcb.c +++ b/freebsd/sys/netinet/in_pcb.c @@ -218,14 +218,25 @@ SYSCTL_INT(_net_inet_ip_portrange, OID_AUTO, randomtime, */ /* + * Different protocols initialize their inpcbs differently - giving + * different name to the lock. But they all are disposed the same. + */ +static void +inpcb_fini(void *mem, int size) +{ + struct inpcb *inp = mem; + + INP_LOCK_DESTROY(inp); +} + +/* * Initialize an inpcbinfo -- we should be able to reduce the number of * arguments in time. */ void in_pcbinfo_init(struct inpcbinfo *pcbinfo, const char *name, struct inpcbhead *listhead, int hash_nelements, int porthash_nelements, - char *inpcbzone_name, uma_init inpcbzone_init, uma_fini inpcbzone_fini, - uint32_t inpcbzone_flags, u_int hashfields) + char *inpcbzone_name, uma_init inpcbzone_init, u_int hashfields) { INP_INFO_LOCK_INIT(pcbinfo, name); @@ -245,8 +256,7 @@ in_pcbinfo_init(struct inpcbinfo *pcbinfo, const char *name, in_pcbgroup_init(pcbinfo, hashfields, hash_nelements); #endif pcbinfo->ipi_zone = uma_zcreate(inpcbzone_name, sizeof(struct inpcb), - NULL, NULL, inpcbzone_init, inpcbzone_fini, UMA_ALIGN_PTR, - inpcbzone_flags); + NULL, NULL, inpcbzone_init, inpcb_fini, UMA_ALIGN_PTR, 0); uma_zone_set_max(pcbinfo->ipi_zone, maxsockets); uma_zone_set_warning(pcbinfo->ipi_zone, "kern.ipc.maxsockets limit reached"); @@ -296,7 +306,7 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo) inp = uma_zalloc(pcbinfo->ipi_zone, M_NOWAIT); if (inp == NULL) return (ENOBUFS); - bzero(inp, inp_zero_size); + bzero(&inp->inp_start_zero, inp_zero_size); inp->inp_pcbinfo = pcbinfo; inp->inp_socket = so; inp->inp_cred = crhold(so->so_cred); diff --git a/freebsd/sys/netinet/in_pcb.h b/freebsd/sys/netinet/in_pcb.h index 59de3b0f..42fd23d0 100644 --- a/freebsd/sys/netinet/in_pcb.h +++ b/freebsd/sys/netinet/in_pcb.h @@ -183,26 +183,29 @@ struct icmp6_filter; struct inpcbpolicy; struct m_snd_tag; struct inpcb { + /* Cache line #1 (amd64) */ LIST_ENTRY(inpcb) inp_hash; /* (h/i) hash list */ LIST_ENTRY(inpcb) inp_pcbgrouphash; /* (g/i) hash list */ - LIST_ENTRY(inpcb) inp_list; /* (p/l) list for all PCBs for proto */ - /* (p[w]) for list iteration */ - /* (p[r]/l) for addition/removal */ + struct rwlock inp_lock; + /* Cache line #2 (amd64) */ +#define inp_start_zero inp_refcount +#define inp_zero_size (sizeof(struct inpcb) - \ + offsetof(struct inpcb, inp_start_zero)) + u_int inp_refcount; /* (i) refcount */ + int inp_flags; /* (i) generic IP/datagram flags */ + int inp_flags2; /* (i) generic IP/datagram flags #2*/ void *inp_ppcb; /* (i) pointer to per-protocol pcb */ + struct socket *inp_socket; /* (i) back pointer to socket */ struct inpcbinfo *inp_pcbinfo; /* (c) PCB list info */ struct inpcbgroup *inp_pcbgroup; /* (g/i) PCB group list */ LIST_ENTRY(inpcb) inp_pcbgroup_wild; /* (g/i/h) group wildcard entry */ - struct socket *inp_socket; /* (i) back pointer to socket */ struct ucred *inp_cred; /* (c) cache of socket cred */ u_int32_t inp_flow; /* (i) IPv6 flow information */ - int inp_flags; /* (i) generic IP/datagram flags */ - int inp_flags2; /* (i) generic IP/datagram flags #2*/ u_char inp_vflag; /* (i) IP version flag (v4/v6) */ u_char inp_ip_ttl; /* (i) time to live proto */ u_char inp_ip_p; /* (c) protocol proto */ u_char inp_ip_minttl; /* (i) minimum TTL or drop */ uint32_t inp_flowid; /* (x) flow id / queue id */ - u_int inp_refcount; /* (i) refcount */ struct m_snd_tag *inp_snd_tag; /* (i) send tag for outgoing mbufs */ uint32_t inp_flowtype; /* (x) M_HASHTYPE value */ uint32_t inp_rss_listen_bucket; /* (x) overridden RSS listen bucket */ @@ -235,17 +238,16 @@ struct inpcb { }; LIST_ENTRY(inpcb) inp_portlist; /* (i/h) */ struct inpcbport *inp_phd; /* (i/h) head of this list */ -#define inp_zero_size offsetof(struct inpcb, inp_gencnt) inp_gen_t inp_gencnt; /* (c) generation count */ struct llentry *inp_lle; /* cached L2 information */ - struct rwlock inp_lock; rt_gen_t inp_rt_cookie; /* generation for route entry */ union { /* cached L3 information */ - struct route inpu_route; - struct route_in6 inpu_route6; - } inp_rtu; -#define inp_route inp_rtu.inpu_route -#define inp_route6 inp_rtu.inpu_route6 + struct route inp_route; + struct route_in6 inp_route6; + }; + LIST_ENTRY(inpcb) inp_list; /* (p/l) list for all PCBs for proto */ + /* (p[w]) for list iteration */ + /* (p[r]/l) for addition/removal */ }; #endif /* _KERNEL */ @@ -690,7 +692,7 @@ VNET_DECLARE(int, ipport_tcpallocs); void in_pcbinfo_destroy(struct inpcbinfo *); void in_pcbinfo_init(struct inpcbinfo *, const char *, struct inpcbhead *, - int, int, char *, uma_init, uma_fini, uint32_t, u_int); + int, int, char *, uma_init, u_int); int in_pcbbind_check_bindmulti(const struct inpcb *ni, const struct inpcb *oi); diff --git a/freebsd/sys/netinet/ip_divert.c b/freebsd/sys/netinet/ip_divert.c index 3efae683..5d7b1635 100644 --- a/freebsd/sys/netinet/ip_divert.c +++ b/freebsd/sys/netinet/ip_divert.c @@ -143,14 +143,6 @@ div_inpcb_init(void *mem, int size, int flags) } static void -div_inpcb_fini(void *mem, int size) -{ - struct inpcb *inp = mem; - - INP_LOCK_DESTROY(inp); -} - -static void div_init(void) { @@ -160,7 +152,7 @@ div_init(void) * place for hashbase == NULL. */ in_pcbinfo_init(&V_divcbinfo, "div", &V_divcb, 1, 1, "divcb", - div_inpcb_init, div_inpcb_fini, 0, IPI_HASHFIELDS_NONE); + div_inpcb_init, IPI_HASHFIELDS_NONE); } static void @@ -491,6 +483,14 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin, /* Send packet to input processing via netisr */ switch (ip->ip_v) { case IPVERSION: + /* + * Restore M_BCAST flag when destination address is + * broadcast. It is expected by ip_tryforward(). + */ + if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) + m->m_flags |= M_MCAST; + else if (in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) + m->m_flags |= M_BCAST; netisr_queue_src(NETISR_IP, (uintptr_t)so, m); break; #ifdef INET6 diff --git a/freebsd/sys/netinet/ip_icmp.c b/freebsd/sys/netinet/ip_icmp.c index 1c32b1b8..acc2e6b6 100644 --- a/freebsd/sys/netinet/ip_icmp.c +++ b/freebsd/sys/netinet/ip_icmp.c @@ -187,10 +187,10 @@ kmod_icmpstat_inc(int statnum) void icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu) { - register struct ip *oip = mtod(n, struct ip *), *nip; - register unsigned oiphlen = oip->ip_hl << 2; - register struct icmp *icp; - register struct mbuf *m; + struct ip *oip = mtod(n, struct ip *), *nip; + unsigned oiphlen = oip->ip_hl << 2; + struct icmp *icp; + struct mbuf *m; unsigned icmplen, icmpelen, nlen; KASSERT((u_int)type <= ICMP_MAXTYPE, ("%s: illegal ICMP type", __func__)); @@ -542,11 +542,10 @@ icmp_input(struct mbuf **mp, int *offp, int proto) ICMPSTAT_INC(icps_bmcastecho); break; } - icp->icmp_type = ICMP_ECHOREPLY; if (badport_bandlim(BANDLIM_ICMP_ECHO) < 0) goto freeit; - else - goto reflect; + icp->icmp_type = ICMP_ECHOREPLY; + goto reflect; case ICMP_TSTAMP: if (V_icmptstamprepl == 0) @@ -560,13 +559,12 @@ icmp_input(struct mbuf **mp, int *offp, int proto) ICMPSTAT_INC(icps_badlen); break; } + if (badport_bandlim(BANDLIM_ICMP_TSTAMP) < 0) + goto freeit; icp->icmp_type = ICMP_TSTAMPREPLY; icp->icmp_rtime = iptime(); icp->icmp_ttime = icp->icmp_rtime; /* bogus, do later! */ - if (badport_bandlim(BANDLIM_ICMP_TSTAMP) < 0) - goto freeit; - else - goto reflect; + goto reflect; case ICMP_MASKREQ: if (V_icmpmaskrepl == 0) @@ -816,7 +814,7 @@ match: ip->ip_ttl = V_ip_defttl; if (optlen > 0) { - register u_char *cp; + u_char *cp; int opt, cnt; u_int len; @@ -891,9 +889,9 @@ done: static void icmp_send(struct mbuf *m, struct mbuf *opts) { - register struct ip *ip = mtod(m, struct ip *); - register int hlen; - register struct icmp *icp; + struct ip *ip = mtod(m, struct ip *); + int hlen; + struct icmp *icp; hlen = ip->ip_hl << 2; m->m_data += hlen; diff --git a/freebsd/sys/netinet/ip_input.c b/freebsd/sys/netinet/ip_input.c index a9126d4b..437c281a 100644 --- a/freebsd/sys/netinet/ip_input.c +++ b/freebsd/sys/netinet/ip_input.c @@ -268,9 +268,9 @@ sysctl_netinet_intr_direct_queue_maxlen(SYSCTL_HANDLER_ARGS) return (EINVAL); return (netisr_setqlimit(&ip_direct_nh, qlimit)); } -SYSCTL_PROC(_net_inet_ip, IPCTL_INTRQMAXLEN, intr_direct_queue_maxlen, - CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_netinet_intr_direct_queue_maxlen, "I", - "Maximum size of the IP direct input queue"); +SYSCTL_PROC(_net_inet_ip, IPCTL_INTRDQMAXLEN, intr_direct_queue_maxlen, + CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_netinet_intr_direct_queue_maxlen, + "I", "Maximum size of the IP direct input queue"); static int sysctl_netinet_intr_direct_queue_drops(SYSCTL_HANDLER_ARGS) @@ -289,7 +289,7 @@ sysctl_netinet_intr_direct_queue_drops(SYSCTL_HANDLER_ARGS) return (0); } -SYSCTL_PROC(_net_inet_ip, IPCTL_INTRQDROPS, intr_direct_queue_drops, +SYSCTL_PROC(_net_inet_ip, IPCTL_INTRDQDROPS, intr_direct_queue_drops, CTLTYPE_INT|CTLFLAG_RD, 0, 0, sysctl_netinet_intr_direct_queue_drops, "I", "Number of packets dropped from the IP direct input queue"); #endif /* RSS */ diff --git a/freebsd/sys/netinet/libalias/alias.c b/freebsd/sys/netinet/libalias/alias.c index cd3b5e05..35343c5f 100644 --- a/freebsd/sys/netinet/libalias/alias.c +++ b/freebsd/sys/netinet/libalias/alias.c @@ -701,12 +701,14 @@ ProtoAliasOut(struct libalias *la, struct in_addr *ip_src, struct alias_link *lnk; LIBALIAS_LOCK_ASSERT(la); - (void)create; /* Return if proxy-only mode is enabled */ if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) return (PKT_ALIAS_OK); + if (!create) + return (PKT_ALIAS_IGNORED); + lnk = FindProtoOut(la, *ip_src, ip_dst, ip_p); if (lnk != NULL) { struct in_addr alias_address; diff --git a/freebsd/sys/netinet/raw_ip.c b/freebsd/sys/netinet/raw_ip.c index d67df1ca..689a2bc4 100644 --- a/freebsd/sys/netinet/raw_ip.c +++ b/freebsd/sys/netinet/raw_ip.c @@ -212,7 +212,7 @@ rip_init(void) { in_pcbinfo_init(&V_ripcbinfo, "rip", &V_ripcb, INP_PCBHASH_RAW_SIZE, - 1, "ripcb", rip_inpcb_init, NULL, 0, IPI_HASHFIELDS_NONE); + 1, "ripcb", rip_inpcb_init, IPI_HASHFIELDS_NONE); EVENTHANDLER_REGISTER(maxsockets_change, rip_zone_change, NULL, EVENTHANDLER_PRI_ANY); } diff --git a/freebsd/sys/netinet/sctp_input.c b/freebsd/sys/netinet/sctp_input.c index d363642a..be01c38a 100644 --- a/freebsd/sys/netinet/sctp_input.c +++ b/freebsd/sys/netinet/sctp_input.c @@ -163,13 +163,11 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, *abort_no_unlock = 1; goto outnow; } - /* We are only accepting if we have a socket with positive - * so_qlimit. */ + /* We are only accepting if we have a listening socket. */ if ((stcb == NULL) && ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || - (inp->sctp_socket == NULL) || - (inp->sctp_socket->so_qlimit == 0))) { + (!SCTP_IS_LISTENING(inp)))) { /* * FIX ME ?? What about TCP model and we have a * match/restart case? Actually no fix is needed. the lookup @@ -1607,8 +1605,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, sctp_stop_all_cookie_timers(stcb); if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && - (inp->sctp_socket->so_qlimit == 0) - ) { + (!SCTP_IS_LISTENING(inp))) { #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) struct socket *so; #endif @@ -1808,7 +1805,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && - (inp->sctp_socket->so_qlimit == 0)) { + (!SCTP_IS_LISTENING(inp))) { #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) struct socket *so; #endif @@ -2319,7 +2316,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, *notification = SCTP_NOTIFY_ASSOC_UP; if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && - (inp->sctp_socket->so_qlimit == 0)) { + (!SCTP_IS_LISTENING(inp))) { /* * This is an endpoint that called connect() how it got a * cookie that is NEW is a bit of a mystery. It must be that @@ -2345,7 +2342,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, SCTP_SOCKET_UNLOCK(so, 1); #endif } else if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && - (inp->sctp_socket->so_qlimit)) { + (SCTP_IS_LISTENING(inp))) { /* * We don't want to do anything with this one. Since it is * the listening guy. The timer will get started for @@ -5207,7 +5204,9 @@ process_control_chunks: * longer listening. */ - if ((stcb == NULL) && (inp->sctp_socket->so_qlen >= inp->sctp_socket->so_qlimit)) { + if ((stcb == NULL) && + (!SCTP_IS_LISTENING(inp) || + inp->sctp_socket->so_qlen >= inp->sctp_socket->so_qlimit)) { if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && (SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit))) { op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, ""); diff --git a/freebsd/sys/netinet/sctp_os_bsd.h b/freebsd/sys/netinet/sctp_os_bsd.h index 2da90b69..f2bea00e 100644 --- a/freebsd/sys/netinet/sctp_os_bsd.h +++ b/freebsd/sys/netinet/sctp_os_bsd.h @@ -462,8 +462,6 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, #define SCTP_SHA256_UPDATE SHA256_Update #define SCTP_SHA256_FINAL(x,y) SHA256_Final((caddr_t)x, y) -#endif - #define SCTP_DECREMENT_AND_CHECK_REFCOUNT(addr) (atomic_fetchadd_int(addr, -1) == 1) #if defined(INVARIANTS) #define SCTP_SAVE_ATOMIC_DECREMENT(addr, val) \ @@ -484,3 +482,7 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, } \ } #endif + +#define SCTP_IS_LISTENING(inp) ((inp->sctp_flags & SCTP_PCB_FLAGS_ACCEPTING) != 0) + +#endif diff --git a/freebsd/sys/netinet/sctp_output.c b/freebsd/sys/netinet/sctp_output.c index 2e6eedaf..221d0570 100644 --- a/freebsd/sys/netinet/sctp_output.c +++ b/freebsd/sys/netinet/sctp_output.c @@ -11149,7 +11149,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, ip->ip_v = IPVERSION; ip->ip_hl = (sizeof(struct ip) >> 2); ip->ip_tos = 0; - ip->ip_off = 0; + ip->ip_off = htons(IP_DF); ip_fillid(ip); ip->ip_ttl = MODULE_GLOBAL(ip_defttl); if (port) { @@ -12597,7 +12597,7 @@ sctp_lower_sosend(struct socket *so, (void *)addr, sndlen); if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && - (inp->sctp_socket->so_qlimit)) { + SCTP_IS_LISTENING(inp)) { /* The listener can NOT send */ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOTCONN); error = ENOTCONN; diff --git a/freebsd/sys/netinet/sctp_pcb.c b/freebsd/sys/netinet/sctp_pcb.c index 3608fd5e..e32e63f4 100644 --- a/freebsd/sys/netinet/sctp_pcb.c +++ b/freebsd/sys/netinet/sctp_pcb.c @@ -1313,7 +1313,7 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote, * it is the acceptor, then do the special_lookup to hash * and find the real inp. */ - if ((inp->sctp_socket) && (inp->sctp_socket->so_qlimit)) { + if ((inp->sctp_socket) && SCTP_IS_LISTENING(inp)) { /* to is peer addr, from is my addr */ stcb = sctp_tcb_special_locate(inp_p, remote, local, netp, inp->def_vrf_id); @@ -1886,7 +1886,7 @@ sctp_swap_inpcb_for_listen(struct sctp_inpcb *inp) if (tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { continue; } - if (tinp->sctp_socket->so_qlimit) { + if (SCTP_IS_LISTENING(tinp)) { continue; } SCTP_INP_WLOCK(tinp); @@ -3937,6 +3937,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, stcb->asoc.vrf_id, stcb->sctp_ep->fibnum); + net->src_addr_selected = 0; if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) { /* Get source address */ net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep, @@ -3946,18 +3947,18 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, 0, stcb->asoc.vrf_id); if (net->ro._s_addr != NULL) { + uint32_t imtu, rmtu, hcmtu; + net->src_addr_selected = 1; /* Now get the interface MTU */ if (net->ro._s_addr->ifn_p != NULL) { - net->mtu = SCTP_GATHER_MTU_FROM_INTFC(net->ro._s_addr->ifn_p); + imtu = SCTP_GATHER_MTU_FROM_INTFC(net->ro._s_addr->ifn_p); + } else { + imtu = 0; } - } else { - net->src_addr_selected = 0; - } - if (net->mtu > 0) { - uint32_t rmtu; - rmtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, net->ro.ro_rt); + hcmtu = sctp_hc_get_mtu(&net->ro._l_addr, stcb->sctp_ep->fibnum); + net->mtu = sctp_min_mtu(hcmtu, rmtu, imtu); if (rmtu == 0) { /* * Start things off to match mtu of @@ -3965,17 +3966,8 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, */ SCTP_SET_MTU_OF_ROUTE(&net->ro._l_addr.sa, net->ro.ro_rt, net->mtu); - } else { - /* - * we take the route mtu over the interface, - * since the route may be leading out the - * loopback, or a different interface. - */ - net->mtu = rmtu; } } - } else { - net->src_addr_selected = 0; } if (net->mtu == 0) { switch (newaddr->sa_family) { diff --git a/freebsd/sys/netinet/sctp_sysctl.c b/freebsd/sys/netinet/sctp_sysctl.c index ea3b3d9c..db150112 100644 --- a/freebsd/sys/netinet/sctp_sysctl.c +++ b/freebsd/sys/netinet/sctp_sysctl.c @@ -412,6 +412,7 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS) xinpcb.socket = inp->sctp_socket; so = inp->sctp_socket; if ((so == NULL) || + (!SCTP_IS_LISTENING(inp)) || (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { xinpcb.qlen = 0; xinpcb.maxqlen = 0; diff --git a/freebsd/sys/netinet/sctp_timer.c b/freebsd/sys/netinet/sctp_timer.c index 6ce9fc30..ecadca5b 100644 --- a/freebsd/sys/netinet/sctp_timer.c +++ b/freebsd/sys/netinet/sctp_timer.c @@ -669,6 +669,7 @@ start_again: stcb->asoc.peers_rwnd += SCTP_BASE_SYSCTL(sctp_peer_chunk_oh); } chk->sent = SCTP_DATAGRAM_RESEND; + chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; SCTP_STAT_INCR(sctps_markedretrans); /* reset the TSN for striking and other FR stuff */ @@ -742,6 +743,7 @@ start_again: chk->whoTo = alt; if (chk->sent != SCTP_DATAGRAM_RESEND) { chk->sent = SCTP_DATAGRAM_RESEND; + chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); cnt_mk++; } @@ -1086,6 +1088,7 @@ sctp_cookie_timer(struct sctp_inpcb *inp, sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); } cookie->sent = SCTP_DATAGRAM_RESEND; + cookie->flags |= CHUNK_FLAGS_FRAGMENT_OK; /* * Now call the output routine to kick out the cookie again, Note we * don't mark any chunks for retran so that FR will need to kick in @@ -1132,6 +1135,7 @@ sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, sctp_free_remote_addr(chk->whoTo); if (chk->sent != SCTP_DATAGRAM_RESEND) { chk->sent = SCTP_DATAGRAM_RESEND; + chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); } chk->whoTo = alt; @@ -1149,6 +1153,7 @@ sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, if (strrst->sent != SCTP_DATAGRAM_RESEND) sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); strrst->sent = SCTP_DATAGRAM_RESEND; + strrst->flags |= CHUNK_FLAGS_FRAGMENT_OK; /* restart the timer */ sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, inp, stcb, strrst->whoTo); @@ -1213,6 +1218,7 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, chk->whoTo = alt; if (chk->sent != SCTP_DATAGRAM_RESEND) { chk->sent = SCTP_DATAGRAM_RESEND; + chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); } atomic_add_int(&alt->ref_count, 1); @@ -1227,6 +1233,7 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, if (asconf->sent != SCTP_DATAGRAM_RESEND && chk->sent != SCTP_DATAGRAM_UNSENT) sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); chk->sent = SCTP_DATAGRAM_RESEND; + chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; } if (!(net->dest_state & SCTP_ADDR_REACHABLE)) { /* @@ -1239,6 +1246,7 @@ sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb, if (asconf->sent != SCTP_DATAGRAM_RESEND) sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); asconf->sent = SCTP_DATAGRAM_RESEND; + asconf->flags |= CHUNK_FLAGS_FRAGMENT_OK; /* send another ASCONF if any and we can do */ sctp_send_asconf(stcb, alt, SCTP_ADDR_NOT_LOCKED); diff --git a/freebsd/sys/netinet/sctp_usrreq.c b/freebsd/sys/netinet/sctp_usrreq.c index 550926f3..b65f74d1 100644 --- a/freebsd/sys/netinet/sctp_usrreq.c +++ b/freebsd/sys/netinet/sctp_usrreq.c @@ -154,7 +154,7 @@ sctp_notify(struct sctp_inpcb *inp, uint8_t icmp_type, uint8_t icmp_code, uint16_t ip_len, - uint16_t next_mtu) + uint32_t next_mtu) { #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) struct socket *so; @@ -222,10 +222,15 @@ sctp_notify(struct sctp_inpcb *inp, timer_stopped = 0; } /* Update the path MTU. */ + if (net->port) { + next_mtu -= sizeof(struct udphdr); + } if (net->mtu > next_mtu) { net->mtu = next_mtu; if (net->port) { - net->mtu -= sizeof(struct udphdr); + sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu + sizeof(struct udphdr)); + } else { + sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu); } } /* Update the association MTU */ @@ -330,7 +335,7 @@ sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip) icmp->icmp_type, icmp->icmp_code, ntohs(inner_ip->ip_len), - ntohs(icmp->icmp_nextmtu)); + (uint32_t)ntohs(icmp->icmp_nextmtu)); } else { if ((stcb == NULL) && (inp != NULL)) { /* reduce ref-count */ @@ -7036,7 +7041,7 @@ sctp_listen(struct socket *so, int backlog, struct thread *p) if (tinp && (tinp != inp) && ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && - (tinp->sctp_socket->so_qlimit)) { + (SCTP_IS_LISTENING(tinp))) { /* * we have a listener already and * its not this inp. @@ -7080,7 +7085,7 @@ sctp_listen(struct socket *so, int backlog, struct thread *p) if (tinp && (tinp != inp) && ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && - (tinp->sctp_socket->so_qlimit)) { + (SCTP_IS_LISTENING(tinp))) { /* * we have a listener already and its not * this inp. @@ -7134,6 +7139,7 @@ sctp_listen(struct socket *so, int backlog, struct thread *p) return (error); } } + SCTP_INP_WLOCK(inp); SOCK_LOCK(so); /* It appears for 7.0 and on, we must always call this. */ solisten_proto(so, backlog); @@ -7141,11 +7147,13 @@ sctp_listen(struct socket *so, int backlog, struct thread *p) /* remove the ACCEPTCONN flag for one-to-many sockets */ so->so_options &= ~SO_ACCEPTCONN; } - if (backlog == 0) { - /* turning off listen */ - so->so_options &= ~SO_ACCEPTCONN; + if (backlog > 0) { + inp->sctp_flags |= SCTP_PCB_FLAGS_ACCEPTING; + } else { + inp->sctp_flags &= ~SCTP_PCB_FLAGS_ACCEPTING; } SOCK_UNLOCK(so); + SCTP_INP_WUNLOCK(inp); return (error); } diff --git a/freebsd/sys/netinet/sctp_var.h b/freebsd/sys/netinet/sctp_var.h index 6365dfec..9e149e68 100644 --- a/freebsd/sys/netinet/sctp_var.h +++ b/freebsd/sys/netinet/sctp_var.h @@ -341,7 +341,7 @@ void sctp_drain(void); void sctp_init(void); void sctp_notify(struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *, - uint8_t, uint8_t, uint16_t, uint16_t); + uint8_t, uint8_t, uint16_t, uint32_t); int sctp_flush(struct socket *, int); int sctp_shutdown(struct socket *); int diff --git a/freebsd/sys/netinet/sctputil.c b/freebsd/sys/netinet/sctputil.c index 79bb0620..4c6ba598 100644 --- a/freebsd/sys/netinet/sctputil.c +++ b/freebsd/sys/netinet/sctputil.c @@ -51,6 +51,9 @@ __FBSDID("$FreeBSD$"); #include <netinet/sctp_auth.h> #include <netinet/sctp_asconf.h> #include <netinet/sctp_bsd_addr.h> +#if defined(INET6) || defined(INET) +#include <netinet/tcp_var.h> +#endif #include <netinet/udp.h> #include <netinet/udp_var.h> #include <sys/proc.h> @@ -6973,7 +6976,7 @@ sctp_recv_icmp_tunneled_packet(int cmd, struct sockaddr *sa, void *vip, void *ct } sctp_notify(inp, stcb, net, type, code, ntohs(inner_ip->ip_len), - ntohs(icmp->icmp_nextmtu)); + (uint32_t)ntohs(icmp->icmp_nextmtu)); } else { if ((stcb == NULL) && (inp != NULL)) { /* reduce ref-count */ @@ -7115,7 +7118,7 @@ sctp_recv_icmp6_tunneled_packet(int cmd, struct sockaddr *sa, void *d, void *ctx code = ICMP6_PARAMPROB_NEXTHEADER; } sctp6_notify(inp, stcb, net, type, code, - (uint16_t)ntohl(ip6cp->ip6c_icmp6->icmp6_mtu)); + ntohl(ip6cp->ip6c_icmp6->icmp6_mtu)); } else { if ((stcb == NULL) && (inp != NULL)) { /* reduce inp's ref-count */ @@ -7237,3 +7240,90 @@ sctp_over_udp_start(void) #endif return (0); } + +#if defined(INET6) || defined(INET) + +/* + * sctp_min_mtu ()returns the minimum of all non-zero arguments. + * If all arguments are zero, zero is returned. + */ +uint32_t +sctp_min_mtu(uint32_t mtu1, uint32_t mtu2, uint32_t mtu3) +{ + if (mtu1 > 0) { + if (mtu2 > 0) { + if (mtu3 > 0) { + return (min(mtu1, min(mtu2, mtu3))); + } else { + return (min(mtu1, mtu2)); + } + } else { + if (mtu3 > 0) { + return (min(mtu1, mtu3)); + } else { + return (mtu1); + } + } + } else { + if (mtu2 > 0) { + if (mtu3 > 0) { + return (min(mtu2, mtu3)); + } else { + return (mtu2); + } + } else { + return (mtu3); + } + } +} + +void +sctp_hc_set_mtu(union sctp_sockstore *addr, uint16_t fibnum, uint32_t mtu) +{ + struct in_conninfo inc; + + memset(&inc, 0, sizeof(struct in_conninfo)); + inc.inc_fibnum = fibnum; + switch (addr->sa.sa_family) { +#ifdef INET + case AF_INET: + inc.inc_faddr = addr->sin.sin_addr; + break; +#endif +#ifdef INET6 + case AF_INET6: + inc.inc_flags |= INC_ISIPV6; + inc.inc6_faddr = addr->sin6.sin6_addr; + break; +#endif + default: + return; + } + tcp_hc_updatemtu(&inc, (u_long)mtu); +} + +uint32_t +sctp_hc_get_mtu(union sctp_sockstore *addr, uint16_t fibnum) +{ + struct in_conninfo inc; + + memset(&inc, 0, sizeof(struct in_conninfo)); + inc.inc_fibnum = fibnum; + switch (addr->sa.sa_family) { +#ifdef INET + case AF_INET: + inc.inc_faddr = addr->sin.sin_addr; + break; +#endif +#ifdef INET6 + case AF_INET6: + inc.inc_flags |= INC_ISIPV6; + inc.inc6_faddr = addr->sin6.sin6_addr; + break; +#endif + default: + return (0); + } + return ((uint32_t)tcp_hc_getmtu(&inc)); +} +#endif diff --git a/freebsd/sys/netinet/sctputil.h b/freebsd/sys/netinet/sctputil.h index dd45e49a..50118b7a 100644 --- a/freebsd/sys/netinet/sctputil.h +++ b/freebsd/sys/netinet/sctputil.h @@ -388,5 +388,10 @@ sctp_auditing(int, struct sctp_inpcb *, struct sctp_tcb *, void sctp_audit_log(uint8_t, uint8_t); #endif +#if defined(INET6) || defined(INET) +uint32_t sctp_min_mtu(uint32_t, uint32_t, uint32_t); +void sctp_hc_set_mtu(union sctp_sockstore *, uint16_t, uint32_t); +uint32_t sctp_hc_get_mtu(union sctp_sockstore *, uint16_t); +#endif #endif /* _KERNEL */ #endif diff --git a/freebsd/sys/netinet/tcp_input.c b/freebsd/sys/netinet/tcp_input.c index 89f2bf0c..d7091928 100644 --- a/freebsd/sys/netinet/tcp_input.c +++ b/freebsd/sys/netinet/tcp_input.c @@ -1488,6 +1488,68 @@ drop: return (IPPROTO_DONE); } +/* + * Automatic sizing of receive socket buffer. Often the send + * buffer size is not optimally adjusted to the actual network + * conditions at hand (delay bandwidth product). Setting the + * buffer size too small limits throughput on links with high + * bandwidth and high delay (eg. trans-continental/oceanic links). + * + * On the receive side the socket buffer memory is only rarely + * used to any significant extent. This allows us to be much + * more aggressive in scaling the receive socket buffer. For + * the case that the buffer space is actually used to a large + * extent and we run out of kernel memory we can simply drop + * the new segments; TCP on the sender will just retransmit it + * later. Setting the buffer size too big may only consume too + * much kernel memory if the application doesn't read() from + * the socket or packet loss or reordering makes use of the + * reassembly queue. + * + * The criteria to step up the receive buffer one notch are: + * 1. Application has not set receive buffer size with + * SO_RCVBUF. Setting SO_RCVBUF clears SB_AUTOSIZE. + * 2. the number of bytes received during the time it takes + * one timestamp to be reflected back to us (the RTT); + * 3. received bytes per RTT is within seven eighth of the + * current socket buffer size; + * 4. receive buffer size has not hit maximal automatic size; + * + * This algorithm does one step per RTT at most and only if + * we receive a bulk stream w/o packet losses or reorderings. + * Shrinking the buffer during idle times is not necessary as + * it doesn't consume any memory when idle. + * + * TODO: Only step up if the application is actually serving + * the buffer to better manage the socket buffer resources. + */ +int +tcp_autorcvbuf(struct mbuf *m, struct tcphdr *th, struct socket *so, + struct tcpcb *tp, int tlen) +{ + int newsize = 0; + + if (V_tcp_do_autorcvbuf && (so->so_rcv.sb_flags & SB_AUTOSIZE) && + tp->t_srtt != 0 && tp->rfbuf_ts != 0 && + TCP_TS_TO_TICKS(tcp_ts_getticks() - tp->rfbuf_ts) > + (tp->t_srtt >> TCP_RTT_SHIFT)) { + if (tp->rfbuf_cnt > (so->so_rcv.sb_hiwat / 8 * 7) && + so->so_rcv.sb_hiwat < V_tcp_autorcvbuf_max) { + newsize = min(so->so_rcv.sb_hiwat + + V_tcp_autorcvbuf_inc, V_tcp_autorcvbuf_max); + } + TCP_PROBE6(receive__autoresize, NULL, tp, m, tp, th, newsize); + + /* Start over with next RTT. */ + tp->rfbuf_ts = 0; + tp->rfbuf_cnt = 0; + } else { + tp->rfbuf_cnt += tlen; /* add up */ + } + + return (newsize); +} + void tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int drop_hdrlen, int tlen, uint8_t iptos, @@ -1553,6 +1615,26 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, tcp_pcap_add(th, m, &(tp->t_inpkts)); #endif + if ((thflags & TH_SYN) && (thflags & TH_FIN) && V_drop_synfin) { + if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { + log(LOG_DEBUG, "%s; %s: " + "SYN|FIN segment ignored (based on " + "sysctl setting)\n", s, __func__); + free(s, M_TCPLOG); + } + goto drop; + } + + /* + * If a segment with the ACK-bit set arrives in the SYN-SENT state + * check SEQ.ACK first. + */ + if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) && + (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { + rstreason = BANDLIM_UNLIMITED; + goto dropwithreset; + } + /* * Segment received on connection. * Reset idle time and keep-alive timer. @@ -1851,62 +1933,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, #endif TCP_PROBE3(debug__input, tp, th, m); - /* - * Automatic sizing of receive socket buffer. Often the send - * buffer size is not optimally adjusted to the actual network - * conditions at hand (delay bandwidth product). Setting the - * buffer size too small limits throughput on links with high - * bandwidth and high delay (eg. trans-continental/oceanic links). - * - * On the receive side the socket buffer memory is only rarely - * used to any significant extent. This allows us to be much - * more aggressive in scaling the receive socket buffer. For - * the case that the buffer space is actually used to a large - * extent and we run out of kernel memory we can simply drop - * the new segments; TCP on the sender will just retransmit it - * later. Setting the buffer size too big may only consume too - * much kernel memory if the application doesn't read() from - * the socket or packet loss or reordering makes use of the - * reassembly queue. - * - * The criteria to step up the receive buffer one notch are: - * 1. Application has not set receive buffer size with - * SO_RCVBUF. Setting SO_RCVBUF clears SB_AUTOSIZE. - * 2. the number of bytes received during the time it takes - * one timestamp to be reflected back to us (the RTT); - * 3. received bytes per RTT is within seven eighth of the - * current socket buffer size; - * 4. receive buffer size has not hit maximal automatic size; - * - * This algorithm does one step per RTT at most and only if - * we receive a bulk stream w/o packet losses or reorderings. - * Shrinking the buffer during idle times is not necessary as - * it doesn't consume any memory when idle. - * - * TODO: Only step up if the application is actually serving - * the buffer to better manage the socket buffer resources. - */ - if (V_tcp_do_autorcvbuf && - (to.to_flags & TOF_TS) && - to.to_tsecr && - (so->so_rcv.sb_flags & SB_AUTOSIZE)) { - if (TSTMP_GT(to.to_tsecr, tp->rfbuf_ts) && - to.to_tsecr - tp->rfbuf_ts < hz) { - if (tp->rfbuf_cnt > - (so->so_rcv.sb_hiwat / 8 * 7) && - so->so_rcv.sb_hiwat < - V_tcp_autorcvbuf_max) { - newsize = - min(so->so_rcv.sb_hiwat + - V_tcp_autorcvbuf_inc, - V_tcp_autorcvbuf_max); - } - /* Start over with next RTT. */ - tp->rfbuf_ts = 0; - tp->rfbuf_cnt = 0; - } else - tp->rfbuf_cnt += tlen; /* add up */ - } + newsize = tcp_autorcvbuf(m, th, so, tp, tlen); /* Add data to socket buffer. */ SOCKBUF_LOCK(&so->so_rcv); @@ -1947,10 +1974,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, win = 0; tp->rcv_wnd = imax(win, (int)(tp->rcv_adv - tp->rcv_nxt)); - /* Reset receive buffer auto scaling when not in bulk receive mode. */ - tp->rfbuf_ts = 0; - tp->rfbuf_cnt = 0; - switch (tp->t_state) { /* @@ -1990,7 +2013,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, /* * If the state is SYN_SENT: - * if seg contains an ACK, but not for our SYN, drop the input. * if seg contains a RST, then drop the connection. * if seg does not contain SYN, then drop it. * Otherwise this is an acceptable SYN segment @@ -2003,12 +2025,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * continue processing rest of data/controls, beginning with URG */ case TCPS_SYN_SENT: - if ((thflags & TH_ACK) && - (SEQ_LEQ(th->th_ack, tp->iss) || - SEQ_GT(th->th_ack, tp->snd_max))) { - rstreason = BANDLIM_UNLIMITED; - goto dropwithreset; - } if ((thflags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) { TCP_PROBE5(connect__refused, NULL, tp, m, tp, th); diff --git a/freebsd/sys/netinet/tcp_lro.c b/freebsd/sys/netinet/tcp_lro.c index 13866134..91d534f1 100644 --- a/freebsd/sys/netinet/tcp_lro.c +++ b/freebsd/sys/netinet/tcp_lro.c @@ -117,7 +117,6 @@ tcp_lro_init_args(struct lro_ctrl *lc, struct ifnet *ifp, lc->lro_bad_csum = 0; lc->lro_queued = 0; lc->lro_flushed = 0; - lc->lro_cnt = 0; lc->lro_mbuf_count = 0; lc->lro_mbuf_max = lro_mbufs; lc->lro_cnt = lro_entries; @@ -147,6 +146,7 @@ tcp_lro_init_args(struct lro_ctrl *lc, struct ifnet *ifp, /* check for out of memory */ if (lc->lro_mbuf_data == NULL) { + free(lc->lro_hash, M_LRO); memset(lc, 0, sizeof(*lc)); return (ENOMEM); } @@ -177,17 +177,15 @@ tcp_lro_free(struct lro_ctrl *lc) } /* free hash table */ - if (lc->lro_hash != NULL) { - free(lc->lro_hash, M_LRO); - lc->lro_hash = NULL; - } + free(lc->lro_hash, M_LRO); + lc->lro_hash = NULL; lc->lro_hashsz = 0; /* free mbuf array, if any */ for (x = 0; x != lc->lro_mbuf_count; x++) m_freem(lc->lro_mbuf_data[x].mb); lc->lro_mbuf_count = 0; - + /* free allocated memory, if any */ free(lc->lro_mbuf_data, M_LRO); lc->lro_mbuf_data = NULL; @@ -957,18 +955,12 @@ tcp_lro_queue_mbuf(struct lro_ctrl *lc, struct mbuf *mb) /* check if packet is not LRO capable */ if (__predict_false(mb->m_pkthdr.csum_flags == 0 || (lc->ifp->if_capenable & IFCAP_LRO) == 0)) { - lc->lro_flushed++; - lc->lro_queued++; /* input packet to network layer */ (*lc->ifp->if_input) (lc->ifp, mb); return; } - /* check if array is full */ - if (__predict_false(lc->lro_mbuf_count == lc->lro_mbuf_max)) - tcp_lro_flush_all(lc); - /* create sequence number */ lc->lro_mbuf_data[lc->lro_mbuf_count].seq = (((uint64_t)M_HASHTYPE_GET(mb)) << 56) | @@ -976,7 +968,11 @@ tcp_lro_queue_mbuf(struct lro_ctrl *lc, struct mbuf *mb) ((uint64_t)lc->lro_mbuf_count); /* enter mbuf */ - lc->lro_mbuf_data[lc->lro_mbuf_count++].mb = mb; + lc->lro_mbuf_data[lc->lro_mbuf_count].mb = mb; + + /* flush if array is full */ + if (__predict_false(++lc->lro_mbuf_count == lc->lro_mbuf_max)) + tcp_lro_flush_all(lc); } /* end */ diff --git a/freebsd/sys/netinet/tcp_output.c b/freebsd/sys/netinet/tcp_output.c index 53eccf11..d2606fb6 100644 --- a/freebsd/sys/netinet/tcp_output.c +++ b/freebsd/sys/netinet/tcp_output.c @@ -833,11 +833,13 @@ send: to.to_tsval = tcp_ts_getticks() + tp->ts_offset; to.to_tsecr = tp->ts_recent; to.to_flags |= TOF_TS; - /* Set receive buffer autosizing timestamp. */ - if (tp->rfbuf_ts == 0 && - (so->so_rcv.sb_flags & SB_AUTOSIZE)) - tp->rfbuf_ts = tcp_ts_getticks(); } + + /* Set receive buffer autosizing timestamp. */ + if (tp->rfbuf_ts == 0 && + (so->so_rcv.sb_flags & SB_AUTOSIZE)) + tp->rfbuf_ts = tcp_ts_getticks(); + /* Selective ACK's. */ if (tp->t_flags & TF_SACK_PERMIT) { if (flags & TH_SYN) diff --git a/freebsd/sys/netinet/tcp_reass.c b/freebsd/sys/netinet/tcp_reass.c index 779de5e0..4f944cab 100644 --- a/freebsd/sys/netinet/tcp_reass.c +++ b/freebsd/sys/netinet/tcp_reass.c @@ -110,7 +110,7 @@ tcp_reass_global_init(void) TUNABLE_INT_FETCH("net.inet.tcp.reass.maxsegments", &tcp_reass_maxseg); tcp_reass_zone = uma_zcreate("tcpreass", sizeof (struct tseg_qent), - NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); + NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); /* Set the zone limit and read back the effective value. */ tcp_reass_maxseg = uma_zone_set_max(tcp_reass_zone, tcp_reass_maxseg); diff --git a/freebsd/sys/netinet/tcp_subr.c b/freebsd/sys/netinet/tcp_subr.c index 48f4cfda..30464e1b 100644 --- a/freebsd/sys/netinet/tcp_subr.c +++ b/freebsd/sys/netinet/tcp_subr.c @@ -653,7 +653,7 @@ tcp_init(void) hashsize); } in_pcbinfo_init(&V_tcbinfo, "tcp", &V_tcb, hashsize, hashsize, - "tcp_inpcb", tcp_inpcb_init, NULL, 0, IPI_HASHFIELDS_4TUPLE); + "tcp_inpcb", tcp_inpcb_init, IPI_HASHFIELDS_4TUPLE); /* * These have to be type stable for the benefit of the timers. diff --git a/freebsd/sys/netinet/tcp_syncache.c b/freebsd/sys/netinet/tcp_syncache.c index 84b9d271..13170ae9 100644 --- a/freebsd/sys/netinet/tcp_syncache.c +++ b/freebsd/sys/netinet/tcp_syncache.c @@ -262,6 +262,8 @@ syncache_init(void) &V_tcp_syncache.hashbase[i].sch_mtx, 0); V_tcp_syncache.hashbase[i].sch_length = 0; V_tcp_syncache.hashbase[i].sch_sc = &V_tcp_syncache; + V_tcp_syncache.hashbase[i].sch_last_overflow = + -(SYNCOOKIE_LIFETIME + 1); } /* Create the syncache entry zone. */ @@ -337,6 +339,7 @@ syncache_insert(struct syncache *sc, struct syncache_head *sch) KASSERT(!TAILQ_EMPTY(&sch->sch_bucket), ("sch->sch_length incorrect")); sc2 = TAILQ_LAST(&sch->sch_bucket, sch_head); + sch->sch_last_overflow = time_uptime; syncache_drop(sc2, sch); TCPSTAT_INC(tcps_sc_bucketoverflow); } @@ -984,10 +987,13 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, /* * There is no syncache entry, so see if this ACK is * a returning syncookie. To do this, first: - * A. See if this socket has had a syncache entry dropped in - * the past. We don't want to accept a bogus syncookie - * if we've never received a SYN. - * B. check that the syncookie is valid. If it is, then + * A. Check if syncookies are used in case of syncache + * overflows + * B. See if this socket has had a syncache entry dropped in + * the recent past. We don't want to accept a bogus + * syncookie if we've never received a SYN or accept it + * twice. + * C. check that the syncookie is valid. If it is, then * cobble up a fake syncache entry, and return. */ if (!V_tcp_syncookies) { @@ -998,6 +1004,15 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, s, __func__); goto failed; } + if (!V_tcp_syncookiesonly && + sch->sch_last_overflow < time_uptime - SYNCOOKIE_LIFETIME) { + SCH_UNLOCK(sch); + if ((s = tcp_log_addrs(inc, th, NULL, NULL))) + log(LOG_DEBUG, "%s; %s: Spurious ACK, " + "segment rejected (no syncache entry)\n", + s, __func__); + goto failed; + } bzero(&scs, sizeof(scs)); sc = syncookie_lookup(inc, sch, &scs, th, to, *lsop); SCH_UNLOCK(sch); @@ -1421,8 +1436,10 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, * entry and insert the new one. */ TCPSTAT_INC(tcps_sc_zonefail); - if ((sc = TAILQ_LAST(&sch->sch_bucket, sch_head)) != NULL) + if ((sc = TAILQ_LAST(&sch->sch_bucket, sch_head)) != NULL) { + sch->sch_last_overflow = time_uptime; syncache_drop(sc, sch); + } sc = uma_zalloc(V_tcp_syncache.zone, M_NOWAIT | M_ZERO); if (sc == NULL) { if (V_tcp_syncookies) { diff --git a/freebsd/sys/netinet/tcp_syncache.h b/freebsd/sys/netinet/tcp_syncache.h index 2c8c5b00..ebf9fb84 100644 --- a/freebsd/sys/netinet/tcp_syncache.h +++ b/freebsd/sys/netinet/tcp_syncache.h @@ -99,6 +99,7 @@ struct syncache_head { int sch_nextc; u_int sch_length; struct tcp_syncache *sch_sc; + time_t sch_last_overflow; }; #define SYNCOOKIE_SECRET_SIZE 16 diff --git a/freebsd/sys/netinet/tcp_usrreq.c b/freebsd/sys/netinet/tcp_usrreq.c index 05fed2d5..198291f2 100644 --- a/freebsd/sys/netinet/tcp_usrreq.c +++ b/freebsd/sys/netinet/tcp_usrreq.c @@ -599,6 +599,10 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td) error = EINVAL; goto out; } + if ((inp->inp_vflag & INP_IPV4) == 0) { + error = EAFNOSUPPORT; + goto out; + } in6_sin6_2_sin(&sin, sin6p); inp->inp_vflag |= INP_IPV4; @@ -616,6 +620,11 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td) #endif error = tp->t_fb->tfb_tcp_output(tp); goto out; + } else { + if ((inp->inp_vflag & INP_IPV6) == 0) { + error = EAFNOSUPPORT; + goto out; + } } #endif inp->inp_vflag &= ~INP_IPV4; diff --git a/freebsd/sys/netinet/tcp_var.h b/freebsd/sys/netinet/tcp_var.h index 5705e553..d298c9dd 100644 --- a/freebsd/sys/netinet/tcp_var.h +++ b/freebsd/sys/netinet/tcp_var.h @@ -778,6 +778,8 @@ void hhook_run_tcp_est_in(struct tcpcb *tp, #endif int tcp_input(struct mbuf **, int *, int); +int tcp_autorcvbuf(struct mbuf *, struct tcphdr *, struct socket *, + struct tcpcb *, int); void tcp_do_segment(struct mbuf *, struct tcphdr *, struct socket *, struct tcpcb *, int, int, uint8_t, int); diff --git a/freebsd/sys/netinet/udp_usrreq.c b/freebsd/sys/netinet/udp_usrreq.c index c77439f7..af6b564f 100644 --- a/freebsd/sys/netinet/udp_usrreq.c +++ b/freebsd/sys/netinet/udp_usrreq.c @@ -129,12 +129,6 @@ SYSCTL_INT(_net_inet_udp, OID_AUTO, blackhole, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(udp_blackhole), 0, "Do not send port unreachables for refused connects"); -static VNET_DEFINE(int, udp_require_l2_bcast) = 0; -#define V_udp_require_l2_bcast VNET(udp_require_l2_bcast) -SYSCTL_INT(_net_inet_udp, OID_AUTO, require_l2_bcast, CTLFLAG_VNET | CTLFLAG_RW, - &VNET_NAME(udp_require_l2_bcast), 0, - "Only treat packets sent to an L2 broadcast address as broadcast packets"); - u_long udp_sendspace = 9216; /* really max datagram size */ SYSCTL_ULONG(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram, CTLFLAG_RW, &udp_sendspace, 0, "Maximum outgoing UDP datagram size"); @@ -215,8 +209,7 @@ udp_init(void) * a 4-tuple, flip this to 4-tuple. */ in_pcbinfo_init(&V_udbinfo, "udp", &V_udb, UDBHASHSIZE, UDBHASHSIZE, - "udp_inpcb", udp_inpcb_init, NULL, 0, - IPI_HASHFIELDS_2TUPLE); + "udp_inpcb", udp_inpcb_init, IPI_HASHFIELDS_2TUPLE); V_udpcb_zone = uma_zcreate("udpcb", sizeof(struct udpcb), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); uma_zone_set_max(V_udpcb_zone, maxsockets); @@ -230,8 +223,8 @@ udplite_init(void) { in_pcbinfo_init(&V_ulitecbinfo, "udplite", &V_ulitecb, UDBHASHSIZE, - UDBHASHSIZE, "udplite_inpcb", udplite_inpcb_init, NULL, - 0, IPI_HASHFIELDS_2TUPLE); + UDBHASHSIZE, "udplite_inpcb", udplite_inpcb_init, + IPI_HASHFIELDS_2TUPLE); } /* @@ -535,8 +528,7 @@ udp_input(struct mbuf **mp, int *offp, int proto) pcbinfo = udp_get_inpcbinfo(proto); if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || - ((!V_udp_require_l2_bcast || m->m_flags & M_BCAST) && - in_broadcast(ip->ip_dst, ifp))) { + in_broadcast(ip->ip_dst, ifp)) { struct inpcb *last; struct inpcbhead *pcblist; struct ip_moptions *imo; diff --git a/freebsd/sys/netinet6/icmp6.c b/freebsd/sys/netinet6/icmp6.c index 0b9eeb0a..16b48490 100644 --- a/freebsd/sys/netinet6/icmp6.c +++ b/freebsd/sys/netinet6/icmp6.c @@ -599,9 +599,9 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) sizeof(*nicmp6)); noff = off; } - nicmp6->icmp6_type = ICMP6_ECHO_REPLY; - nicmp6->icmp6_code = 0; if (n) { + nicmp6->icmp6_type = ICMP6_ECHO_REPLY; + nicmp6->icmp6_code = 0; ICMP6STAT_INC(icp6s_reflect); ICMP6STAT_INC(icp6s_outhist[ICMP6_ECHO_REPLY]); icmp6_reflect(n, noff); @@ -691,6 +691,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) */ m_free(n); n = NULL; + break; } maxhlen = M_TRAILINGSPACE(n) - (sizeof(*nip6) + sizeof(*nicmp6) + 4); diff --git a/freebsd/sys/netinet6/in6_mcast.c b/freebsd/sys/netinet6/in6_mcast.c index 33eff90b..5977a6fe 100644 --- a/freebsd/sys/netinet6/in6_mcast.c +++ b/freebsd/sys/netinet6/in6_mcast.c @@ -1001,9 +1001,10 @@ in6m_merge(struct in6_multi *inm, /*const*/ struct in6_mfilter *imf) /* Decrement ASM listener count on transition out of ASM mode. */ if (imf->im6f_st[0] == MCAST_EXCLUDE && nsrc0 == 0) { if ((imf->im6f_st[1] != MCAST_EXCLUDE) || - (imf->im6f_st[1] == MCAST_EXCLUDE && nsrc1 > 0)) + (imf->im6f_st[1] == MCAST_EXCLUDE && nsrc1 > 0)) { CTR1(KTR_MLD, "%s: --asm on inm at t1", __func__); --inm->in6m_st[1].iss_asm; + } } /* Increment ASM listener count on transition to ASM mode. */ diff --git a/freebsd/sys/netinet6/in6_pcb.c b/freebsd/sys/netinet6/in6_pcb.c index 65096c78..56142a1b 100644 --- a/freebsd/sys/netinet6/in6_pcb.c +++ b/freebsd/sys/netinet6/in6_pcb.c @@ -119,7 +119,7 @@ static struct inpcb *in6_pcblookup_hash_locked(struct inpcbinfo *, struct in6_addr *, u_int, struct in6_addr *, u_int, int, struct ifnet *); int -in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, +in6_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred) { struct socket *so = inp->inp_socket; @@ -338,10 +338,10 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, * have forced minor changes in every protocol). */ static int -in6_pcbladdr(register struct inpcb *inp, struct sockaddr *nam, +in6_pcbladdr(struct inpcb *inp, struct sockaddr *nam, struct in6_addr *plocal_addr6) { - register struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam; + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam; int error = 0; int scope_ambiguous = 0; struct in6_addr in6a; @@ -403,11 +403,11 @@ in6_pcbladdr(register struct inpcb *inp, struct sockaddr *nam, * then pick one. */ int -in6_pcbconnect_mbuf(register struct inpcb *inp, struct sockaddr *nam, +in6_pcbconnect_mbuf(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred, struct mbuf *m) { struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; - register struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam; + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam; struct in6_addr addr6; int error; @@ -508,7 +508,7 @@ in6_v4mapsin6_sockaddr(in_port_t port, struct in_addr *addr_p) int in6_getsockaddr(struct socket *so, struct sockaddr **nam) { - register struct inpcb *inp; + struct inpcb *inp; struct in6_addr addr; in_port_t port; @@ -701,7 +701,7 @@ struct inpcb * in6_pcblookup_local(struct inpcbinfo *pcbinfo, struct in6_addr *laddr, u_short lport, int lookupflags, struct ucred *cred) { - register struct inpcb *inp; + struct inpcb *inp; int matchwild = 3, wildcard; KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0, diff --git a/freebsd/sys/netinet6/ip6_output.c b/freebsd/sys/netinet6/ip6_output.c index ac5563c6..48a8c454 100644 --- a/freebsd/sys/netinet6/ip6_output.c +++ b/freebsd/sys/netinet6/ip6_output.c @@ -219,7 +219,7 @@ in6_delayed_cksum(struct mbuf *m, uint32_t plen, u_short offset) int ip6_fragment(struct ifnet *ifp, struct mbuf *m0, int hlen, u_char nextproto, - int mtu, uint32_t id) + int fraglen , uint32_t id) { struct mbuf *m, **mnext, *m_frgpart; struct ip6_hdr *ip6, *mhip6; @@ -228,11 +228,13 @@ ip6_fragment(struct ifnet *ifp, struct mbuf *m0, int hlen, u_char nextproto, int error; int tlen = m0->m_pkthdr.len; + KASSERT((fraglen % 8 == 0), ("Fragment length must be a multiple of 8")); + m = m0; ip6 = mtod(m, struct ip6_hdr *); mnext = &m->m_nextpkt; - for (off = hlen; off < tlen; off += mtu) { + for (off = hlen; off < tlen; off += fraglen) { m = m_gethdr(M_NOWAIT, MT_DATA); if (!m) { IP6STAT_INC(ip6s_odropped); @@ -251,18 +253,18 @@ ip6_fragment(struct ifnet *ifp, struct mbuf *m0, int hlen, u_char nextproto, return (error); } ip6f->ip6f_offlg = htons((u_short)((off - hlen) & ~7)); - if (off + mtu >= tlen) - mtu = tlen - off; + if (off + fraglen >= tlen) + fraglen = tlen - off; else ip6f->ip6f_offlg |= IP6F_MORE_FRAG; - mhip6->ip6_plen = htons((u_short)(mtu + hlen + + mhip6->ip6_plen = htons((u_short)(fraglen + hlen + sizeof(*ip6f) - sizeof(struct ip6_hdr))); - if ((m_frgpart = m_copym(m0, off, mtu, M_NOWAIT)) == NULL) { + if ((m_frgpart = m_copym(m0, off, fraglen, M_NOWAIT)) == NULL) { IP6STAT_INC(ip6s_odropped); return (ENOBUFS); } m_cat(m, m_frgpart); - m->m_pkthdr.len = mtu + hlen + sizeof(*ip6f); + m->m_pkthdr.len = fraglen + hlen + sizeof(*ip6f); m->m_pkthdr.fibnum = m0->m_pkthdr.fibnum; m->m_pkthdr.rcvif = NULL; ip6f->ip6f_reserved = 0; @@ -325,6 +327,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, uint32_t id; if (inp != NULL) { + INP_LOCK_ASSERT(inp); M_SETFIB(m, inp->inp_inc.inc_fibnum); if ((flags & IP_NODEFAULTFLOWID) == 0) { /* unconditionally set flowid */ @@ -2464,7 +2467,7 @@ do {\ if (src->type) {\ int hlen = (((struct ip6_ext *)src->type)->ip6e_len + 1) << 3;\ dst->type = malloc(hlen, M_IP6OPT, canwait);\ - if (dst->type == NULL && canwait == M_NOWAIT)\ + if (dst->type == NULL)\ goto bad;\ bcopy(src->type, dst->type, hlen);\ }\ diff --git a/freebsd/sys/netinet6/raw_ip6.c b/freebsd/sys/netinet6/raw_ip6.c index ed294191..2bbd9864 100644 --- a/freebsd/sys/netinet6/raw_ip6.c +++ b/freebsd/sys/netinet6/raw_ip6.c @@ -160,8 +160,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto) { struct ifnet *ifp; struct mbuf *m = *mp; - register struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); - register struct inpcb *in6p; + struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); + struct inpcb *in6p; struct inpcb *last = NULL; struct mbuf *opts = NULL; struct sockaddr_in6 fromsa; diff --git a/freebsd/sys/netinet6/sctp6_usrreq.c b/freebsd/sys/netinet6/sctp6_usrreq.c index 03e20b18..f94068f9 100644 --- a/freebsd/sys/netinet6/sctp6_usrreq.c +++ b/freebsd/sys/netinet6/sctp6_usrreq.c @@ -185,7 +185,7 @@ sctp6_notify(struct sctp_inpcb *inp, struct sctp_nets *net, uint8_t icmp6_type, uint8_t icmp6_code, - uint16_t next_mtu) + uint32_t next_mtu) { #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) struct socket *so; @@ -239,11 +239,11 @@ sctp6_notify(struct sctp_inpcb *inp, timer_stopped = 0; } /* Update the path MTU. */ + if (net->port) { + next_mtu -= sizeof(struct udphdr); + } if (net->mtu > next_mtu) { net->mtu = next_mtu; - if (net->port) { - net->mtu -= sizeof(struct udphdr); - } } /* Update the association MTU */ if (stcb->asoc.smallest_mtu > next_mtu) { @@ -385,7 +385,7 @@ sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d) sctp6_notify(inp, stcb, net, ip6cp->ip6c_icmp6->icmp6_type, ip6cp->ip6c_icmp6->icmp6_code, - (uint16_t)ntohl(ip6cp->ip6c_icmp6->icmp6_mtu)); + ntohl(ip6cp->ip6c_icmp6->icmp6_mtu)); } else { if ((stcb == NULL) && (inp != NULL)) { /* reduce inp's ref-count */ diff --git a/freebsd/sys/netinet6/sctp6_var.h b/freebsd/sys/netinet6/sctp6_var.h index 232fee15..a24ceba7 100644 --- a/freebsd/sys/netinet6/sctp6_var.h +++ b/freebsd/sys/netinet6/sctp6_var.h @@ -49,6 +49,6 @@ sctp6_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *, void sctp6_ctlinput(int, struct sockaddr *, void *); void sctp6_notify(struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *, - uint8_t, uint8_t, uint16_t); + uint8_t, uint8_t, uint32_t); #endif #endif diff --git a/freebsd/sys/netinet6/udp6_usrreq.c b/freebsd/sys/netinet6/udp6_usrreq.c index bc6596e4..d00584ed 100644 --- a/freebsd/sys/netinet6/udp6_usrreq.c +++ b/freebsd/sys/netinet6/udp6_usrreq.c @@ -106,9 +106,7 @@ __FBSDID("$FreeBSD$"); #include <netinet/in_systm.h> #include <netinet/in_var.h> #include <netinet/ip.h> -#include <netinet/ip_icmp.h> #include <netinet/ip6.h> -#include <netinet/icmp_var.h> #include <netinet/icmp6.h> #include <netinet/ip_var.h> #include <netinet/udp.h> @@ -483,8 +481,6 @@ udp6_input(struct mbuf **mp, int *offp, int proto) } if (V_udp_blackhole) goto badunlocked; - if (badport_bandlim(BANDLIM_ICMP6_UNREACH) < 0) - goto badunlocked; icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0); return (IPPROTO_DONE); } @@ -1121,6 +1117,10 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td) error = EINVAL; goto out; } + if ((inp->inp_vflag & INP_IPV4) == 0) { + error = EAFNOSUPPORT; + goto out; + } if (inp->inp_faddr.s_addr != INADDR_ANY) { error = EISCONN; goto out; @@ -1138,6 +1138,11 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td) if (error == 0) soisconnected(so); goto out; + } else { + if ((inp->inp_vflag & INP_IPV6) == 0) { + error = EAFNOSUPPORT; + goto out; + } } #endif if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) { diff --git a/freebsd/sys/netipsec/ipsec.h b/freebsd/sys/netipsec/ipsec.h index 7653e4d4..0522b7e7 100644 --- a/freebsd/sys/netipsec/ipsec.h +++ b/freebsd/sys/netipsec/ipsec.h @@ -299,7 +299,13 @@ VNET_DECLARE(int, natt_cksum_policy); #define ipseclog(x) do { if (V_ipsec_debug) log x; } while (0) /* for openbsd compatibility */ +#ifdef IPSEC_DEBUG +#define IPSEC_DEBUG_DECLARE(x) x #define DPRINTF(x) do { if (V_ipsec_debug) printf x; } while (0) +#else +#define IPSEC_DEBUG_DECLARE(x) +#define DPRINTF(x) +#endif struct inpcb; struct m_tag; diff --git a/freebsd/sys/netipsec/ipsec_input.c b/freebsd/sys/netipsec/ipsec_input.c index 62143c79..d9dfd254 100644 --- a/freebsd/sys/netipsec/ipsec_input.c +++ b/freebsd/sys/netipsec/ipsec_input.c @@ -119,7 +119,7 @@ __FBSDID("$FreeBSD$"); static int ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto) { - char buf[IPSEC_ADDRSTRLEN]; + IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); union sockaddr_union dst_address; struct secasvar *sav; uint32_t spi; @@ -225,8 +225,6 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto) * everything else. */ error = (*sav->tdb_xform->xf_input)(m, sav, skip, protoff); - if (error != 0) - key_freesav(&sav); return (error); } @@ -281,7 +279,7 @@ int ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int protoff) { - char buf[IPSEC_ADDRSTRLEN]; + IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); struct ipsec_ctx_data ctx; struct xform_history *xh; struct secasindex *saidx; @@ -492,7 +490,7 @@ int ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int protoff) { - char buf[IPSEC_ADDRSTRLEN]; + IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); struct ipsec_ctx_data ctx; struct xform_history *xh; struct secasindex *saidx; diff --git a/freebsd/sys/netipsec/ipsec_mbuf.c b/freebsd/sys/netipsec/ipsec_mbuf.c index ba0321ef..80cb8fbc 100644 --- a/freebsd/sys/netipsec/ipsec_mbuf.c +++ b/freebsd/sys/netipsec/ipsec_mbuf.c @@ -170,8 +170,8 @@ m_makespace(struct mbuf *m0, int skip, int hlen, int *off) caddr_t m_pad(struct mbuf *m, int n) { - register struct mbuf *m0, *m1; - register int len, pad; + struct mbuf *m0, *m1; + int len, pad; caddr_t retval; if (n <= 0) { /* No stupid arguments. */ diff --git a/freebsd/sys/netipsec/ipsec_output.c b/freebsd/sys/netipsec/ipsec_output.c index b68d61a1..b7dd8f30 100644 --- a/freebsd/sys/netipsec/ipsec_output.c +++ b/freebsd/sys/netipsec/ipsec_output.c @@ -185,7 +185,6 @@ next: static int ipsec4_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx) { - char sbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN]; struct ipsec_ctx_data ctx; union sockaddr_union *dst; struct secasvar *sav; @@ -232,12 +231,9 @@ ipsec4_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx) ip->ip_sum = in_cksum(m, ip->ip_hl << 2); error = ipsec_encap(&m, &sav->sah->saidx); if (error != 0) { - DPRINTF(("%s: encapsulation for SA %s->%s " - "SPI 0x%08x failed with error %d\n", __func__, - ipsec_address(&sav->sah->saidx.src, sbuf, - sizeof(sbuf)), - ipsec_address(&sav->sah->saidx.dst, dbuf, - sizeof(dbuf)), ntohl(sav->spi), error)); + DPRINTF(("%s: encapsulation for SPI 0x%08x failed " + "with error %d\n", __func__, ntohl(sav->spi), + error)); /* XXXAE: IPSEC_OSTAT_INC(tunnel); */ goto bad; } @@ -275,10 +271,6 @@ ipsec4_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx) goto bad; } error = (*sav->tdb_xform->xf_output)(m, sp, sav, idx, i, off); - if (error != 0) { - key_freesav(&sav); - key_freesp(&sp); - } return (error); bad: IPSECSTAT_INC(ips_out_inval); @@ -503,7 +495,6 @@ next: static int ipsec6_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx) { - char sbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN]; struct ipsec_ctx_data ctx; union sockaddr_union *dst; struct secasvar *sav; @@ -545,12 +536,9 @@ ipsec6_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx) } error = ipsec_encap(&m, &sav->sah->saidx); if (error != 0) { - DPRINTF(("%s: encapsulation for SA %s->%s " - "SPI 0x%08x failed with error %d\n", __func__, - ipsec_address(&sav->sah->saidx.src, sbuf, - sizeof(sbuf)), - ipsec_address(&sav->sah->saidx.dst, dbuf, - sizeof(dbuf)), ntohl(sav->spi), error)); + DPRINTF(("%s: encapsulation for SPI 0x%08x failed " + "with error %d\n", __func__, ntohl(sav->spi), + error)); /* XXXAE: IPSEC_OSTAT_INC(tunnel); */ goto bad; } @@ -583,10 +571,6 @@ ipsec6_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx) goto bad; } error = (*sav->tdb_xform->xf_output)(m, sp, sav, idx, i, off); - if (error != 0) { - key_freesav(&sav); - key_freesp(&sp); - } return (error); bad: IPSEC6STAT_INC(ips_out_inval); diff --git a/freebsd/sys/netipsec/ipsec_pcb.c b/freebsd/sys/netipsec/ipsec_pcb.c index 8a08e3aa..a8992d56 100644 --- a/freebsd/sys/netipsec/ipsec_pcb.c +++ b/freebsd/sys/netipsec/ipsec_pcb.c @@ -174,10 +174,10 @@ ipsec_delete_pcbpolicy(struct inpcb *inp) if (inp->inp_sp == NULL) return (0); - if (inp->inp_sp->flags & INP_INBOUND_POLICY) + if (inp->inp_sp->sp_in != NULL) key_freesp(&inp->inp_sp->sp_in); - if (inp->inp_sp->flags & INP_OUTBOUND_POLICY) + if (inp->inp_sp->sp_out != NULL) key_freesp(&inp->inp_sp->sp_out); free(inp->inp_sp, M_IPSEC_INPCB); @@ -252,6 +252,8 @@ ipsec_copy_pcbpolicy(struct inpcb *old, struct inpcb *new) if (sp == NULL) return (ENOBUFS); ipsec_setspidx_inpcb(new, &sp->spidx, IPSEC_DIR_INBOUND); + if (new->inp_sp->sp_in != NULL) + key_freesp(&new->inp_sp->sp_in); new->inp_sp->sp_in = sp; new->inp_sp->flags |= INP_INBOUND_POLICY; } @@ -260,6 +262,8 @@ ipsec_copy_pcbpolicy(struct inpcb *old, struct inpcb *new) if (sp == NULL) return (ENOBUFS); ipsec_setspidx_inpcb(new, &sp->spidx, IPSEC_DIR_OUTBOUND); + if (new->inp_sp->sp_out != NULL) + key_freesp(&new->inp_sp->sp_out); new->inp_sp->sp_out = sp; new->inp_sp->flags |= INP_OUTBOUND_POLICY; } diff --git a/freebsd/sys/netipsec/key.c b/freebsd/sys/netipsec/key.c index c0edde4c..0dfab7bd 100644 --- a/freebsd/sys/netipsec/key.c +++ b/freebsd/sys/netipsec/key.c @@ -865,7 +865,8 @@ key_allocsa_tcpmd5(struct secasindex *saidx) kdebug_secash(sah, " ")); if (sah->saidx.proto != IPPROTO_TCP) continue; - if (!key_sockaddrcmp(&saidx->dst.sa, &sah->saidx.dst.sa, 0)) + if (!key_sockaddrcmp(&saidx->dst.sa, &sah->saidx.dst.sa, 0) && + !key_sockaddrcmp(&saidx->src.sa, &sah->saidx.src.sa, 0)) break; } if (sah != NULL) { @@ -4964,7 +4965,8 @@ key_getsav_tcpmd5(struct secasindex *saidx, uint32_t *spi) LIST_FOREACH(sah, SAHADDRHASH_HASH(saidx), addrhash) { if (sah->saidx.proto != IPPROTO_TCP) continue; - if (!key_sockaddrcmp(&saidx->dst.sa, &sah->saidx.dst.sa, 0)) + if (!key_sockaddrcmp(&saidx->dst.sa, &sah->saidx.dst.sa, 0) && + !key_sockaddrcmp(&saidx->src.sa, &sah->saidx.src.sa, 0)) break; } if (sah != NULL) { diff --git a/freebsd/sys/netipsec/key_debug.c b/freebsd/sys/netipsec/key_debug.c index 016ed733..1911af01 100644 --- a/freebsd/sys/netipsec/key_debug.c +++ b/freebsd/sys/netipsec/key_debug.c @@ -65,6 +65,7 @@ #include <ctype.h> #include <stdio.h> #include <stdlib.h> +#include <arpa/inet.h> #endif /* !_KERNEL */ static void kdebug_sadb_prop(struct sadb_ext *); @@ -75,6 +76,8 @@ static void kdebug_sadb_sa(struct sadb_ext *); static void kdebug_sadb_address(struct sadb_ext *); static void kdebug_sadb_key(struct sadb_ext *); static void kdebug_sadb_x_sa2(struct sadb_ext *); +static void kdebug_sadb_x_sa_replay(struct sadb_ext *); +static void kdebug_sadb_x_natt(struct sadb_ext *); #ifdef _KERNEL static void kdebug_secreplay(struct secreplay *); @@ -133,6 +136,10 @@ kdebug_sadb(struct sadb_msg *base) case SADB_EXT_ADDRESS_SRC: case SADB_EXT_ADDRESS_DST: case SADB_EXT_ADDRESS_PROXY: + case SADB_X_EXT_NAT_T_OAI: + case SADB_X_EXT_NAT_T_OAR: + case SADB_X_EXT_NEW_ADDRESS_SRC: + case SADB_X_EXT_NEW_ADDRESS_DST: kdebug_sadb_address(ext); break; case SADB_EXT_KEY_AUTH: @@ -161,6 +168,14 @@ kdebug_sadb(struct sadb_msg *base) case SADB_X_EXT_SA2: kdebug_sadb_x_sa2(ext); break; + case SADB_X_EXT_SA_REPLAY: + kdebug_sadb_x_sa_replay(ext); + break; + case SADB_X_EXT_NAT_T_TYPE: + case SADB_X_EXT_NAT_T_SPORT: + case SADB_X_EXT_NAT_T_DPORT: + kdebug_sadb_x_natt(ext); + break; default: printf("%s: invalid ext_type %u\n", __func__, ext->sadb_ext_type); @@ -344,8 +359,6 @@ kdebug_sadb_address(struct sadb_ext *ext) ((u_char *)&addr->sadb_address_reserved)[1]); kdebug_sockaddr((struct sockaddr *)((caddr_t)ext + sizeof(*addr))); - - return; } static void @@ -394,6 +407,41 @@ kdebug_sadb_x_sa2(struct sadb_ext *ext) return; } +static void +kdebug_sadb_x_sa_replay(struct sadb_ext *ext) +{ + struct sadb_x_sa_replay *replay; + + /* sanity check */ + if (ext == NULL) + panic("%s: NULL pointer was passed.\n", __func__); + + replay = (struct sadb_x_sa_replay *)ext; + printf("sadb_x_sa_replay{ replay=%u }\n", + replay->sadb_x_sa_replay_replay); +} + +static void +kdebug_sadb_x_natt(struct sadb_ext *ext) +{ + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *port; + + /* sanity check */ + if (ext == NULL) + panic("%s: NULL pointer was passed.\n", __func__); + + if (ext->sadb_ext_type == SADB_X_EXT_NAT_T_TYPE) { + type = (struct sadb_x_nat_t_type *)ext; + printf("sadb_x_nat_t_type{ type=%u }\n", + type->sadb_x_nat_t_type_type); + } else { + port = (struct sadb_x_nat_t_port *)ext; + printf("sadb_x_nat_t_port{ port=%u }\n", + ntohs(port->sadb_x_nat_t_port_port)); + } +} + void kdebug_sadb_x_policy(struct sadb_ext *ext) { @@ -404,9 +452,11 @@ kdebug_sadb_x_policy(struct sadb_ext *ext) if (ext == NULL) panic("%s: NULL pointer was passed.\n", __func__); - printf("sadb_x_policy{ type=%u dir=%u id=%x }\n", + printf("sadb_x_policy{ type=%u dir=%u id=%x scope=%u %s=%u }\n", xpl->sadb_x_policy_type, xpl->sadb_x_policy_dir, - xpl->sadb_x_policy_id); + xpl->sadb_x_policy_id, xpl->sadb_x_policy_scope, + xpl->sadb_x_policy_scope == IPSEC_POLICYSCOPE_IFNET ? + "ifindex": "priority", xpl->sadb_x_policy_priority); if (xpl->sadb_x_policy_type == IPSEC_POLICY_IPSEC) { int tlen; @@ -852,39 +902,42 @@ ipsec_sa2str(struct secasvar *sav, char *buf, size_t size) void kdebug_sockaddr(struct sockaddr *addr) { - struct sockaddr_in *sin4; -#ifdef INET6 - struct sockaddr_in6 *sin6; -#endif + char buf[IPSEC_ADDRSTRLEN]; /* sanity check */ if (addr == NULL) panic("%s: NULL pointer was passed.\n", __func__); - /* NOTE: We deal with port number as host byte order. */ - printf("sockaddr{ len=%u family=%u", addr->sa_len, addr->sa_family); - switch (addr->sa_family) { - case AF_INET: - sin4 = (struct sockaddr_in *)addr; - printf(" port=%u\n", ntohs(sin4->sin_port)); - ipsec_hexdump((caddr_t)&sin4->sin_addr, sizeof(sin4->sin_addr)); +#ifdef INET + case AF_INET: { + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *)addr; + inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)); break; + } +#endif #ifdef INET6 - case AF_INET6: + case AF_INET6: { + struct sockaddr_in6 *sin6; + sin6 = (struct sockaddr_in6 *)addr; - printf(" port=%u\n", ntohs(sin6->sin6_port)); - printf(" flowinfo=0x%08x, scope_id=0x%08x\n", - sin6->sin6_flowinfo, sin6->sin6_scope_id); - ipsec_hexdump((caddr_t)&sin6->sin6_addr, - sizeof(sin6->sin6_addr)); + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { + snprintf(buf, sizeof(buf), "%s%%%u", + inet_ntop(AF_INET6, &sin6->sin6_addr, buf, + sizeof(buf)), sin6->sin6_scope_id); + } else + inet_ntop(AF_INET6, &sin6->sin6_addr, buf, + sizeof(buf)); break; + } #endif + default: + sprintf(buf, "unknown"); } - - printf(" }\n"); - - return; + printf("sockaddr{ len=%u family=%u addr=%s }\n", addr->sa_len, + addr->sa_family, buf); } void diff --git a/freebsd/sys/netipsec/key_debug.h b/freebsd/sys/netipsec/key_debug.h index 18150b53..afb11cb1 100644 --- a/freebsd/sys/netipsec/key_debug.h +++ b/freebsd/sys/netipsec/key_debug.h @@ -53,10 +53,14 @@ #define KEYDEBUG_IPSEC_DATA (KEYDEBUG_IPSEC | KEYDEBUG_DATA) #define KEYDEBUG_IPSEC_DUMP (KEYDEBUG_IPSEC | KEYDEBUG_DUMP) +#ifdef IPSEC_DEBUG #define KEYDBG(lev, arg) \ if ((V_key_debug_level & (KEYDEBUG_ ## lev)) == (KEYDEBUG_ ## lev)) { \ arg; \ } +#else +#define KEYDBG(lev, arg) +#endif /* !IPSEC_DEBUG */ VNET_DECLARE(uint32_t, key_debug_level); #define V_key_debug_level VNET(key_debug_level) diff --git a/freebsd/sys/netipsec/xform_ah.c b/freebsd/sys/netipsec/xform_ah.c index f8bbd3c0..9c2620f4 100644 --- a/freebsd/sys/netipsec/xform_ah.c +++ b/freebsd/sys/netipsec/xform_ah.c @@ -546,7 +546,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out) static int ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) { - char buf[128]; + IPSEC_DEBUG_DECLARE(char buf[128]); const struct auth_hash *ahx; struct cryptodesc *crda; struct cryptop *crp; @@ -568,8 +568,8 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) if (ah == NULL) { DPRINTF(("ah_input: cannot pullup header\n")); AHSTAT_INC(ahs_hdrops); /*XXX*/ - m_freem(m); - return ENOBUFS; + error = ENOBUFS; + goto bad; } /* Check replay window, if applicable. */ @@ -580,8 +580,8 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) AHSTAT_INC(ahs_replay); DPRINTF(("%s: packet replay failure: %s\n", __func__, ipsec_sa2str(sav, buf, sizeof(buf)))); - m_freem(m); - return (EACCES); + error = EACCES; + goto bad; } cryptoid = sav->tdb_cryptoid; SECASVAR_UNLOCK(sav); @@ -597,8 +597,8 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), (u_long) ntohl(sav->spi))); AHSTAT_INC(ahs_badauthl); - m_freem(m); - return EACCES; + error = EACCES; + goto bad; } AHSTAT_ADD(ahs_ibytes, m->m_pkthdr.len - skip - hl); @@ -608,8 +608,8 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) DPRINTF(("%s: failed to acquire crypto descriptor\n", __func__)); AHSTAT_INC(ahs_crypto); - m_freem(m); - return ENOBUFS; + error = ENOBUFS; + goto bad; } crda = crp->crp_desc; @@ -631,8 +631,8 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) DPRINTF(("%s: failed to allocate xform_data\n", __func__)); AHSTAT_INC(ahs_crypto); crypto_freereq(crp); - m_freem(m); - return ENOBUFS; + error = ENOBUFS; + goto bad; } /* @@ -652,6 +652,7 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) AHSTAT_INC(ahs_hdrops); free(xd, M_XDATA); crypto_freereq(crp); + key_freesav(&sav); return (error); } @@ -670,6 +671,10 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) xd->skip = skip; xd->cryptoid = cryptoid; return (crypto_dispatch(crp)); +bad: + m_freem(m); + key_freesav(&sav); + return (error); } /* @@ -678,7 +683,7 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) static int ah_input_cb(struct cryptop *crp) { - char buf[IPSEC_ADDRSTRLEN]; + IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); unsigned char calc[AH_ALEN_MAX]; const struct auth_hash *ahx; struct mbuf *m; @@ -828,7 +833,7 @@ static int ah_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, u_int idx, int skip, int protoff) { - char buf[IPSEC_ADDRSTRLEN]; + IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); const struct auth_hash *ahx; struct cryptodesc *crda; struct xform_data *xd; @@ -1046,6 +1051,8 @@ ah_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, bad: if (m) m_freem(m); + key_freesav(&sav); + key_freesp(&sp); return (error); } diff --git a/freebsd/sys/netipsec/xform_esp.c b/freebsd/sys/netipsec/xform_esp.c index 6b79d259..8310b799 100644 --- a/freebsd/sys/netipsec/xform_esp.c +++ b/freebsd/sys/netipsec/xform_esp.c @@ -265,7 +265,7 @@ esp_zeroize(struct secasvar *sav) static int esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) { - char buf[128]; + IPSEC_DEBUG_DECLARE(char buf[128]); const struct auth_hash *esph; const struct enc_xform *espx; struct xform_data *xd; @@ -274,18 +274,18 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) struct newesp *esp; uint8_t *ivp; uint64_t cryptoid; - int plen, alen, hlen; + int alen, error, hlen, plen; IPSEC_ASSERT(sav != NULL, ("null SA")); IPSEC_ASSERT(sav->tdb_encalgxform != NULL, ("null encoding xform")); + error = EINVAL; /* Valid IP Packet length ? */ if ( (skip&3) || (m->m_pkthdr.len&3) ){ DPRINTF(("%s: misaligned packet, skip %u pkt len %u", __func__, skip, m->m_pkthdr.len)); ESPSTAT_INC(esps_badilen); - m_freem(m); - return EINVAL; + goto bad; } /* XXX don't pullup, just copy header */ IP6_EXTHDR_GET(esp, struct newesp *, m, skip, sizeof (struct newesp)); @@ -316,8 +316,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), (u_long)ntohl(sav->spi))); ESPSTAT_INC(esps_badilen); - m_freem(m); - return EINVAL; + goto bad; } /* @@ -330,8 +329,8 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) DPRINTF(("%s: packet replay check for %s\n", __func__, ipsec_sa2str(sav, buf, sizeof(buf)))); ESPSTAT_INC(esps_replay); - m_freem(m); - return (EACCES); + error = EACCES; + goto bad; } } cryptoid = sav->tdb_cryptoid; @@ -346,8 +345,8 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) DPRINTF(("%s: failed to acquire crypto descriptors\n", __func__)); ESPSTAT_INC(esps_crypto); - m_freem(m); - return ENOBUFS; + error = ENOBUFS; + goto bad; } /* Get IPsec-specific opaque pointer */ @@ -356,8 +355,8 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) DPRINTF(("%s: failed to allocate xform_data\n", __func__)); ESPSTAT_INC(esps_crypto); crypto_freereq(crp); - m_freem(m); - return ENOBUFS; + error = ENOBUFS; + goto bad; } if (esph != NULL) { @@ -427,6 +426,10 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) crde->crd_alg = espx->type; return (crypto_dispatch(crp)); +bad: + m_freem(m); + key_freesav(&sav); + return (error); } /* @@ -435,7 +438,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) static int esp_input_cb(struct cryptop *crp) { - char buf[128]; + IPSEC_DEBUG_DECLARE(char buf[128]); u_int8_t lastthree[3], aalg[AH_HMAC_MAXHASHLEN]; const struct auth_hash *esph; const struct enc_xform *espx; @@ -621,7 +624,7 @@ static int esp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, u_int idx, int skip, int protoff) { - char buf[IPSEC_ADDRSTRLEN]; + IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); struct cryptodesc *crde = NULL, *crda = NULL; struct cryptop *crp; const struct auth_hash *esph; @@ -860,6 +863,8 @@ esp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, bad: if (m) m_freem(m); + key_freesav(&sav); + key_freesp(&sp); return (error); } /* diff --git a/freebsd/sys/netipsec/xform_ipcomp.c b/freebsd/sys/netipsec/xform_ipcomp.c index c2327167..e79301b1 100644 --- a/freebsd/sys/netipsec/xform_ipcomp.c +++ b/freebsd/sys/netipsec/xform_ipcomp.c @@ -196,34 +196,35 @@ ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) struct cryptop *crp; struct ipcomp *ipcomp; caddr_t addr; - int hlen = IPCOMP_HLENGTH; + int error, hlen = IPCOMP_HLENGTH; /* * Check that the next header of the IPComp is not IPComp again, before * doing any real work. Given it is not possible to do double * compression it means someone is playing tricks on us. */ + error = ENOBUFS; if (m->m_len < skip + hlen && (m = m_pullup(m, skip + hlen)) == NULL) { IPCOMPSTAT_INC(ipcomps_hdrops); /*XXX*/ DPRINTF(("%s: m_pullup failed\n", __func__)); - return (ENOBUFS); + key_freesav(&sav); + return (error); } addr = (caddr_t) mtod(m, struct ip *) + skip; ipcomp = (struct ipcomp *)addr; if (ipcomp->comp_nxt == IPPROTO_IPCOMP) { - m_freem(m); IPCOMPSTAT_INC(ipcomps_pdrops); /* XXX have our own stats? */ DPRINTF(("%s: recursive compression detected\n", __func__)); - return (EINVAL); + error = EINVAL; + goto bad; } /* Get crypto descriptors */ crp = crypto_getreq(1); if (crp == NULL) { - m_freem(m); DPRINTF(("%s: no crypto descriptors\n", __func__)); IPCOMPSTAT_INC(ipcomps_crypto); - return ENOBUFS; + goto bad; } /* Get IPsec-specific opaque pointer */ xd = malloc(sizeof(*xd), M_XDATA, M_NOWAIT | M_ZERO); @@ -231,8 +232,7 @@ ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) DPRINTF(("%s: cannot allocate xform_data\n", __func__)); IPCOMPSTAT_INC(ipcomps_crypto); crypto_freereq(crp); - m_freem(m); - return ENOBUFS; + goto bad; } crdc = crp->crp_desc; @@ -261,6 +261,10 @@ ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) SECASVAR_UNLOCK(sav); return crypto_dispatch(crp); +bad: + m_freem(m); + key_freesav(&sav); + return (error); } /* @@ -269,7 +273,7 @@ ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) static int ipcomp_input_cb(struct cryptop *crp) { - char buf[IPSEC_ADDRSTRLEN]; + IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); struct cryptodesc *crd; struct xform_data *xd; struct mbuf *m; @@ -385,7 +389,7 @@ static int ipcomp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, u_int idx, int skip, int protoff) { - char buf[IPSEC_ADDRSTRLEN]; + IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); const struct comp_algo *ipcompx; struct cryptodesc *crdc; struct cryptop *crp; @@ -508,6 +512,8 @@ ipcomp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, bad: if (m) m_freem(m); + key_freesav(&sav); + key_freesp(&sp); return (error); } @@ -517,7 +523,7 @@ bad: static int ipcomp_output_cb(struct cryptop *crp) { - char buf[IPSEC_ADDRSTRLEN]; + IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); struct xform_data *xd; struct secpolicy *sp; struct secasvar *sav; diff --git a/freebsd/sys/netpfil/pf/pf_if.c b/freebsd/sys/netpfil/pf/pf_if.c index fbcda5b8..0ca6a019 100644 --- a/freebsd/sys/netpfil/pf/pf_if.c +++ b/freebsd/sys/netpfil/pf/pf_if.c @@ -91,9 +91,9 @@ static int pfi_skip_if(const char *, struct pfi_kif *); static int pfi_unmask(void *); static void pfi_attach_ifnet_event(void * __unused, struct ifnet *); static void pfi_detach_ifnet_event(void * __unused, struct ifnet *); -static void pfi_attach_group_event(void *, struct ifg_group *); -static void pfi_change_group_event(void *, char *); -static void pfi_detach_group_event(void *, struct ifg_group *); +static void pfi_attach_group_event(void * __unused, struct ifg_group *); +static void pfi_change_group_event(void * __unused, char *); +static void pfi_detach_group_event(void * __unused, struct ifg_group *); static void pfi_ifaddr_event(void * __unused, struct ifnet *); RB_HEAD(pfi_ifhead, pfi_kif); @@ -145,11 +145,11 @@ pfi_initialize(void) pfi_detach_cookie = EVENTHANDLER_REGISTER(ifnet_departure_event, pfi_detach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY); pfi_attach_group_cookie = EVENTHANDLER_REGISTER(group_attach_event, - pfi_attach_group_event, curvnet, EVENTHANDLER_PRI_ANY); + pfi_attach_group_event, NULL, EVENTHANDLER_PRI_ANY); pfi_change_group_cookie = EVENTHANDLER_REGISTER(group_change_event, - pfi_change_group_event, curvnet, EVENTHANDLER_PRI_ANY); + pfi_change_group_event, NULL, EVENTHANDLER_PRI_ANY); pfi_detach_group_cookie = EVENTHANDLER_REGISTER(group_detach_event, - pfi_detach_group_event, curvnet, EVENTHANDLER_PRI_ANY); + pfi_detach_group_event, NULL, EVENTHANDLER_PRI_ANY); pfi_ifaddr_event_cookie = EVENTHANDLER_REGISTER(ifaddr_event, pfi_ifaddr_event, NULL, EVENTHANDLER_PRI_ANY); } @@ -802,10 +802,8 @@ static void pfi_attach_ifnet_event(void *arg __unused, struct ifnet *ifp) { - CURVNET_SET(ifp->if_vnet); if (V_pf_vnet_active == 0) { /* Avoid teardown race in the least expensive way. */ - CURVNET_RESTORE(); return; } pfi_attach_ifnet(ifp); @@ -814,7 +812,6 @@ pfi_attach_ifnet_event(void *arg __unused, struct ifnet *ifp) pf_altq_ifnet_event(ifp, 0); PF_RULES_WUNLOCK(); #endif - CURVNET_RESTORE(); } static void @@ -825,10 +822,8 @@ pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp) if (kif == NULL) return; - CURVNET_SET(ifp->if_vnet); if (V_pf_vnet_active == 0) { /* Avoid teardown race in the least expensive way. */ - CURVNET_RESTORE(); return; } PF_RULES_WLOCK(); @@ -841,32 +836,26 @@ pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp) pf_altq_ifnet_event(ifp, 1); #endif PF_RULES_WUNLOCK(); - CURVNET_RESTORE(); } static void -pfi_attach_group_event(void *arg , struct ifg_group *ifg) +pfi_attach_group_event(void *arg __unused, struct ifg_group *ifg) { - CURVNET_SET((struct vnet *)arg); if (V_pf_vnet_active == 0) { /* Avoid teardown race in the least expensive way. */ - CURVNET_RESTORE(); return; } pfi_attach_ifgroup(ifg); - CURVNET_RESTORE(); } static void -pfi_change_group_event(void *arg, char *gname) +pfi_change_group_event(void *arg __unused, char *gname) { struct pfi_kif *kif; - CURVNET_SET((struct vnet *)arg); if (V_pf_vnet_active == 0) { /* Avoid teardown race in the least expensive way. */ - CURVNET_RESTORE(); return; } @@ -876,21 +865,18 @@ pfi_change_group_event(void *arg, char *gname) kif = pfi_kif_attach(kif, gname); pfi_kif_update(kif); PF_RULES_WUNLOCK(); - CURVNET_RESTORE(); } static void -pfi_detach_group_event(void *arg, struct ifg_group *ifg) +pfi_detach_group_event(void *arg __unused, struct ifg_group *ifg) { struct pfi_kif *kif = (struct pfi_kif *)ifg->ifg_pf_kif; if (kif == NULL) return; - CURVNET_SET((struct vnet *)arg); if (V_pf_vnet_active == 0) { /* Avoid teardown race in the least expensive way. */ - CURVNET_RESTORE(); return; } PF_RULES_WLOCK(); @@ -899,7 +885,6 @@ pfi_detach_group_event(void *arg, struct ifg_group *ifg) kif->pfik_group = NULL; ifg->ifg_pf_kif = NULL; PF_RULES_WUNLOCK(); - CURVNET_RESTORE(); } static void @@ -908,10 +893,8 @@ pfi_ifaddr_event(void *arg __unused, struct ifnet *ifp) if (ifp->if_pf_kif == NULL) return; - CURVNET_SET(ifp->if_vnet); if (V_pf_vnet_active == 0) { /* Avoid teardown race in the least expensive way. */ - CURVNET_RESTORE(); return; } PF_RULES_WLOCK(); @@ -920,5 +903,4 @@ pfi_ifaddr_event(void *arg __unused, struct ifnet *ifp) pfi_kif_update(ifp->if_pf_kif); } PF_RULES_WUNLOCK(); - CURVNET_RESTORE(); } diff --git a/freebsd/sys/netpfil/pf/pf_ioctl.c b/freebsd/sys/netpfil/pf/pf_ioctl.c index 4f507081..e9ca8d95 100644 --- a/freebsd/sys/netpfil/pf/pf_ioctl.c +++ b/freebsd/sys/netpfil/pf/pf_ioctl.c @@ -180,7 +180,7 @@ static int hook_pf(void); static int dehook_pf(void); static int shutdown_pf(void); static int pf_load(void); -static int pf_unload(void); +static void pf_unload(void); static struct cdevsw pf_cdevsw = { .d_ioctl = pfioctl, @@ -1864,6 +1864,8 @@ DIOCGETSTATES_full: counter_u64_zero(V_pf_status.fcounters[i]); for (int i = 0; i < SCNT_MAX; i++) counter_u64_zero(V_pf_status.scounters[i]); + for (int i = 0; i < LCNT_MAX; i++) + counter_u64_zero(V_pf_status.lcounters[i]); V_pf_status.since = time_second; if (*V_pf_status.ifname) pfi_update_status(V_pf_status.ifname, NULL); @@ -2440,11 +2442,12 @@ DIOCGETSTATES_full: #undef ERROUT DIOCCHANGEADDR_error: - if (newpa->kif) - pfi_kif_unref(newpa->kif); - PF_RULES_WUNLOCK(); - if (newpa != NULL) + if (newpa != NULL) { + if (newpa->kif) + pfi_kif_unref(newpa->kif); free(newpa, M_PFRULE); + } + PF_RULES_WUNLOCK(); if (kif != NULL) free(kif, PFI_MTYPE); break; @@ -3721,17 +3724,8 @@ dehook_pf(void) static void pf_load_vnet(void) { - VNET_ITERATOR_DECL(vnet_iter); - - VNET_LIST_RLOCK(); - VNET_FOREACH(vnet_iter) { - CURVNET_SET(vnet_iter); - V_pf_pfil_hooked = 0; - TAILQ_INIT(&V_pf_tags); - TAILQ_INIT(&V_pf_qids); - CURVNET_RESTORE(); - } - VNET_LIST_RUNLOCK(); + TAILQ_INIT(&V_pf_tags); + TAILQ_INIT(&V_pf_qids); pfattach_vnet(); V_pf_vnet_active = 1; @@ -3798,10 +3792,9 @@ pf_unload_vnet(void) pf_mtag_cleanup(); } -static int +static void pf_unload(void) { - int error = 0; sx_xlock(&pf_end_lock); pf_end_threads = 1; @@ -3819,8 +3812,6 @@ pf_unload(void) rw_destroy(&pf_rules_lock); sx_destroy(&pf_ioctl_lock); sx_destroy(&pf_end_lock); - - return (error); } static void @@ -3838,6 +3829,7 @@ vnet_pf_uninit(const void *unused __unused) pf_unload_vnet(); } +SYSUNINIT(pf_unload, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND, pf_unload, NULL); VNET_SYSUNINIT(vnet_pf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD, vnet_pf_uninit, NULL); @@ -3858,7 +3850,8 @@ pf_modevent(module_t mod, int type, void *data) error = EBUSY; break; case MOD_UNLOAD: - error = pf_unload(); + /* Handled in SYSUNINIT(pf_unload) to ensure it's done after + * the vnet_pf_uninit()s */ break; default: error = EINVAL; diff --git a/freebsd/sys/netpfil/pf/pf_norm.c b/freebsd/sys/netpfil/pf/pf_norm.c index f4d46378..60733ae8 100644 --- a/freebsd/sys/netpfil/pf/pf_norm.c +++ b/freebsd/sys/netpfil/pf/pf_norm.c @@ -764,6 +764,10 @@ pf_refragment6(struct ifnet *ifp, struct mbuf **m0, struct m_tag *mtag) hdr->ip6_nxt = IPPROTO_FRAGMENT; } + /* The MTU must be a multiple of 8 bytes, or we risk doing the + * fragmentation wrong. */ + maxlen = maxlen & ~7; + /* * Maxlen may be less than 8 if there was only a single * fragment. As it was fragmented before, add a fragment diff --git a/freebsd/sys/netpfil/pf/pf_table.c b/freebsd/sys/netpfil/pf/pf_table.c index 3460046b..c655effa 100644 --- a/freebsd/sys/netpfil/pf/pf_table.c +++ b/freebsd/sys/netpfil/pf/pf_table.c @@ -186,9 +186,14 @@ static struct pfr_kentry static RB_PROTOTYPE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare); static RB_GENERATE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare); -struct pfr_ktablehead pfr_ktables; -struct pfr_table pfr_nulltable; -int pfr_ktable_cnt; +static VNET_DEFINE(struct pfr_ktablehead, pfr_ktables); +#define V_pfr_ktables VNET(pfr_ktables) + +static VNET_DEFINE(struct pfr_table, pfr_nulltable); +#define V_pfr_nulltable VNET(pfr_nulltable) + +static VNET_DEFINE(int, pfr_ktable_cnt); +#define V_pfr_ktable_cnt VNET(pfr_ktable_cnt) void pfr_initialize(void) @@ -258,7 +263,7 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, return (ESRCH); if (kt->pfrkt_flags & PFR_TFLAG_CONST) return (EPERM); - tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0); + tmpkt = pfr_create_ktable(&V_pfr_nulltable, 0, 0); if (tmpkt == NULL) return (ENOMEM); SLIST_INIT(&workq); @@ -410,7 +415,7 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, return (ESRCH); if (kt->pfrkt_flags & PFR_TFLAG_CONST) return (EPERM); - tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0); + tmpkt = pfr_create_ktable(&V_pfr_nulltable, 0, 0); if (tmpkt == NULL) return (ENOMEM); pfr_mark_addrs(kt); @@ -1085,7 +1090,7 @@ pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags) return (ENOENT); SLIST_INIT(&workq); - RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) { + RB_FOREACH(p, pfr_ktablehead, &V_pfr_ktables) { if (pfr_skip_table(filter, p, flags)) continue; if (!strcmp(p->pfrkt_anchor, PF_RESERVED_ANCHOR)) @@ -1120,7 +1125,7 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) flags & PFR_FLAG_USERIOCTL)) senderr(EINVAL); key.pfrkt_flags |= PFR_TFLAG_ACTIVE; - p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key); + p = RB_FIND(pfr_ktablehead, &V_pfr_ktables, &key); if (p == NULL) { p = pfr_create_ktable(&key.pfrkt_t, tzero, 1); if (p == NULL) @@ -1136,7 +1141,7 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) /* find or create root table */ bzero(key.pfrkt_anchor, sizeof(key.pfrkt_anchor)); - r = RB_FIND(pfr_ktablehead, &pfr_ktables, &key); + r = RB_FIND(pfr_ktablehead, &V_pfr_ktables, &key); if (r != NULL) { p->pfrkt_root = r; goto _skip; @@ -1192,7 +1197,7 @@ pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags) if (pfr_validate_table(&key.pfrkt_t, 0, flags & PFR_FLAG_USERIOCTL)) return (EINVAL); - p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key); + p = RB_FIND(pfr_ktablehead, &V_pfr_ktables, &key); if (p != NULL && (p->pfrkt_flags & PFR_TFLAG_ACTIVE)) { SLIST_FOREACH(q, &workq, pfrkt_workq) if (!pfr_ktable_compare(p, q)) @@ -1231,7 +1236,7 @@ pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size, *size = n; return (0); } - RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) { + RB_FOREACH(p, pfr_ktablehead, &V_pfr_ktables) { if (pfr_skip_table(filter, p, flags)) continue; if (n-- <= 0) @@ -1266,7 +1271,7 @@ pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size, return (0); } SLIST_INIT(&workq); - RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) { + RB_FOREACH(p, pfr_ktablehead, &V_pfr_ktables) { if (pfr_skip_table(filter, p, flags)) continue; if (n-- <= 0) @@ -1298,7 +1303,7 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags) bcopy(tbl + i, &key.pfrkt_t, sizeof(key.pfrkt_t)); if (pfr_validate_table(&key.pfrkt_t, 0, 0)) return (EINVAL); - p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key); + p = RB_FIND(pfr_ktablehead, &V_pfr_ktables, &key); if (p != NULL) { SLIST_INSERT_HEAD(&workq, p, pfrkt_workq); xzero++; @@ -1330,7 +1335,7 @@ pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag, if (pfr_validate_table(&key.pfrkt_t, 0, flags & PFR_FLAG_USERIOCTL)) return (EINVAL); - p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key); + p = RB_FIND(pfr_ktablehead, &V_pfr_ktables, &key); if (p != NULL && (p->pfrkt_flags & PFR_TFLAG_ACTIVE)) { p->pfrkt_nflags = (p->pfrkt_flags | setflag) & ~clrflag; @@ -1372,7 +1377,7 @@ pfr_ina_begin(struct pfr_table *trs, u_int32_t *ticket, int *ndel, int flags) if (rs == NULL) return (ENOMEM); SLIST_INIT(&workq); - RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) { + RB_FOREACH(p, pfr_ktablehead, &V_pfr_ktables) { if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) || pfr_skip_table(trs, p, 0)) continue; @@ -1417,7 +1422,7 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size, return (EBUSY); tbl->pfrt_flags |= PFR_TFLAG_INACTIVE; SLIST_INIT(&tableq); - kt = RB_FIND(pfr_ktablehead, &pfr_ktables, (struct pfr_ktable *)tbl); + kt = RB_FIND(pfr_ktablehead, &V_pfr_ktables, (struct pfr_ktable *)tbl); if (kt == NULL) { kt = pfr_create_ktable(tbl, 0, 1); if (kt == NULL) @@ -1430,7 +1435,7 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size, /* find or create root table */ bzero(&key, sizeof(key)); strlcpy(key.pfrkt_name, tbl->pfrt_name, sizeof(key.pfrkt_name)); - rt = RB_FIND(pfr_ktablehead, &pfr_ktables, &key); + rt = RB_FIND(pfr_ktablehead, &V_pfr_ktables, &key); if (rt != NULL) { kt->pfrkt_root = rt; goto _skip; @@ -1507,7 +1512,7 @@ pfr_ina_rollback(struct pfr_table *trs, u_int32_t ticket, int *ndel, int flags) if (rs == NULL || !rs->topen || ticket != rs->tticket) return (0); SLIST_INIT(&workq); - RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) { + RB_FOREACH(p, pfr_ktablehead, &V_pfr_ktables) { if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) || pfr_skip_table(trs, p, 0)) continue; @@ -1543,7 +1548,7 @@ pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd, return (EBUSY); SLIST_INIT(&workq); - RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) { + RB_FOREACH(p, pfr_ktablehead, &V_pfr_ktables) { if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) || pfr_skip_table(trs, p, 0)) continue; @@ -1689,7 +1694,7 @@ pfr_table_count(struct pfr_table *filter, int flags) PF_RULES_ASSERT(); if (flags & PFR_FLAG_ALLRSETS) - return (pfr_ktable_cnt); + return (V_pfr_ktable_cnt); if (filter->pfrt_anchor[0]) { rs = pf_find_ruleset(filter->pfrt_anchor); return ((rs != NULL) ? rs->tables : -1); @@ -1722,8 +1727,8 @@ pfr_insert_ktable(struct pfr_ktable *kt) PF_RULES_WASSERT(); - RB_INSERT(pfr_ktablehead, &pfr_ktables, kt); - pfr_ktable_cnt++; + RB_INSERT(pfr_ktablehead, &V_pfr_ktables, kt); + V_pfr_ktable_cnt++; if (kt->pfrkt_root != NULL) if (!kt->pfrkt_root->pfrkt_refcnt[PFR_REFCNT_ANCHOR]++) pfr_setflags_ktable(kt->pfrkt_root, @@ -1754,14 +1759,14 @@ pfr_setflags_ktable(struct pfr_ktable *kt, int newf) if (!(newf & PFR_TFLAG_ACTIVE)) newf &= ~PFR_TFLAG_USRMASK; if (!(newf & PFR_TFLAG_SETMASK)) { - RB_REMOVE(pfr_ktablehead, &pfr_ktables, kt); + RB_REMOVE(pfr_ktablehead, &V_pfr_ktables, kt); if (kt->pfrkt_root != NULL) if (!--kt->pfrkt_root->pfrkt_refcnt[PFR_REFCNT_ANCHOR]) pfr_setflags_ktable(kt->pfrkt_root, kt->pfrkt_root->pfrkt_flags & ~PFR_TFLAG_REFDANCHOR); pfr_destroy_ktable(kt, 1); - pfr_ktable_cnt--; + V_pfr_ktable_cnt--; return; } if (!(newf & PFR_TFLAG_ACTIVE) && kt->pfrkt_cnt) { @@ -1882,7 +1887,7 @@ static struct pfr_ktable * pfr_lookup_table(struct pfr_table *tbl) { /* struct pfr_ktable start like a struct pfr_table */ - return (RB_FIND(pfr_ktablehead, &pfr_ktables, + return (RB_FIND(pfr_ktablehead, &V_pfr_ktables, (struct pfr_ktable *)tbl)); } diff --git a/freebsd/sys/opencrypto/criov.c b/freebsd/sys/opencrypto/criov.c index f5d64953..7fc7d392 100644 --- a/freebsd/sys/opencrypto/criov.c +++ b/freebsd/sys/opencrypto/criov.c @@ -81,7 +81,7 @@ cuio_copydata(struct uio* uio, int off, int len, caddr_t cp) } void -cuio_copyback(struct uio* uio, int off, int len, caddr_t cp) +cuio_copyback(struct uio* uio, int off, int len, c_caddr_t cp) { struct iovec *iov = uio->uio_iov; int iol = uio->uio_iovcnt; @@ -157,7 +157,7 @@ cuio_apply(struct uio *uio, int off, int len, int (*f)(void *, void *, u_int), } void -crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in) +crypto_copyback(int flags, caddr_t buf, int off, int size, c_caddr_t in) { if ((flags & CRYPTO_F_IMBUF) != 0) diff --git a/freebsd/sys/opencrypto/cryptodev.h b/freebsd/sys/opencrypto/cryptodev.h index d14fb3a8..ca584694 100644 --- a/freebsd/sys/opencrypto/cryptodev.h +++ b/freebsd/sys/opencrypto/cryptodev.h @@ -211,9 +211,9 @@ struct session_op { u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */ u_int32_t keylen; /* cipher key */ - caddr_t key; + c_caddr_t key; int mackeylen; /* mac key */ - caddr_t mackey; + c_caddr_t mackey; u_int32_t ses; /* returns: session # */ }; @@ -223,9 +223,9 @@ struct session2_op { u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */ u_int32_t keylen; /* cipher key */ - caddr_t key; + c_caddr_t key; int mackeylen; /* mac key */ - caddr_t mackey; + c_caddr_t mackey; u_int32_t ses; /* returns: session # */ int crid; /* driver id + flags (rw) */ @@ -240,9 +240,10 @@ struct crypt_op { u_int16_t flags; #define COP_F_BATCH 0x0008 /* Batch op if possible */ u_int len; - caddr_t src, dst; /* become iov[] inside kernel */ + c_caddr_t src; /* become iov[] inside kernel */ + caddr_t dst; caddr_t mac; /* must be big enough for chosen MAC */ - caddr_t iv; + c_caddr_t iv; }; /* op and flags the same as crypt_op */ @@ -253,10 +254,11 @@ struct crypt_aead { u_int len; u_int aadlen; u_int ivlen; - caddr_t src, dst; /* become iov[] inside kernel */ - caddr_t aad; /* additional authenticated data */ + c_caddr_t src; /* become iov[] inside kernel */ + caddr_t dst; + c_caddr_t aad; /* additional authenticated data */ caddr_t tag; /* must fit for chosen TAG length */ - caddr_t iv; + c_caddr_t iv; }; /* @@ -503,7 +505,7 @@ extern int crypto_devallowsoft; /* only use hardware crypto */ */ struct uio; extern void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp); -extern void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp); +extern void cuio_copyback(struct uio* uio, int off, int len, c_caddr_t cp); extern int cuio_getptr(struct uio *uio, int loc, int *off); extern int cuio_apply(struct uio *uio, int off, int len, int (*f)(void *, void *, u_int), void *arg); @@ -514,7 +516,7 @@ extern int crypto_mbuftoiov(struct mbuf *mbuf, struct iovec **iovptr, int *cnt, int *allocated); extern void crypto_copyback(int flags, caddr_t buf, int off, int size, - caddr_t in); + c_caddr_t in); extern void crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out); extern int crypto_apply(int flags, caddr_t buf, int off, int len, diff --git a/freebsd/sys/opencrypto/cryptosoft.c b/freebsd/sys/opencrypto/cryptosoft.c index 11985f58..f0858b3c 100644 --- a/freebsd/sys/opencrypto/cryptosoft.c +++ b/freebsd/sys/opencrypto/cryptosoft.c @@ -932,8 +932,11 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri) axf = &auth_hash_nist_gmac_aes_256; auth4common: len = cri->cri_klen / 8; - if (len != 16 && len != 24 && len != 32) + if (len != 16 && len != 24 && len != 32) { + swcr_freesession_locked(dev, i); + rw_runlock(&swcr_sessions_lock); return EINVAL; + } (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); diff --git a/freebsd/sys/sys/ata.h b/freebsd/sys/sys/ata.h index 9737487d..0ed78ec8 100644 --- a/freebsd/sys/sys/ata.h +++ b/freebsd/sys/sys/ata.h @@ -263,7 +263,7 @@ struct ata_params { u_int16_t reserved170[6]; /*176*/ u_int8_t media_serial[60]; /*206*/ u_int16_t sct; - u_int16_t reserved206[2]; + u_int16_t reserved207[2]; /*209*/ u_int16_t lsalign; /*210*/ u_int16_t wrv_sectors_m3_1; u_int16_t wrv_sectors_m3_2; diff --git a/freebsd/sys/sys/conf.h b/freebsd/sys/sys/conf.h index d5ced5c0..a49b6d60 100644 --- a/freebsd/sys/sys/conf.h +++ b/freebsd/sys/sys/conf.h @@ -343,6 +343,7 @@ void devfs_free_cdp_inode(ino_t ino); #define GID_GAMES 13 #define GID_VIDEO 44 #define GID_DIALER 68 +#define GID_NOGROUP 65533 #define GID_NOBODY 65534 typedef void (*dev_clone_fn)(void *arg, struct ucred *cred, char *name, diff --git a/freebsd/sys/sys/interrupt.h b/freebsd/sys/sys/interrupt.h index c320e5fc..44b769f2 100644 --- a/freebsd/sys/sys/interrupt.h +++ b/freebsd/sys/sys/interrupt.h @@ -162,6 +162,8 @@ int intr_event_add_handler(struct intr_event *ie, const char *name, driver_filter_t filter, driver_intr_t handler, void *arg, u_char pri, enum intr_type flags, void **cookiep); int intr_event_bind(struct intr_event *ie, int cpu); +int intr_event_bind_irqonly(struct intr_event *ie, int cpu); +int intr_event_bind_ithread(struct intr_event *ie, int cpu); int intr_event_create(struct intr_event **event, void *source, int flags, int irq, void (*pre_ithread)(void *), void (*post_ithread)(void *), void (*post_filter)(void *), @@ -173,9 +175,9 @@ int intr_event_destroy(struct intr_event *ie); void intr_event_execute_handlers(struct proc *p, struct intr_event *ie); int intr_event_handle(struct intr_event *ie, struct trapframe *frame); int intr_event_remove_handler(void *cookie); -int intr_getaffinity(int irq, void *mask); +int intr_getaffinity(int irq, int mode, void *mask); void *intr_handler_source(void *cookie); -int intr_setaffinity(int irq, void *mask); +int intr_setaffinity(int irq, int mode, void *mask); void _intr_drain(int irq); /* Linux compat only. */ int swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler, void *arg, int pri, enum intr_type flags, diff --git a/freebsd/sys/sys/kobj.h b/freebsd/sys/sys/kobj.h index 36d8d2a7..862e79f0 100644 --- a/freebsd/sys/sys/kobj.h +++ b/freebsd/sys/sys/kobj.h @@ -226,10 +226,12 @@ extern u_int kobj_lookup_misses; kobj_method_t **_cep = \ &OPS->cache[_desc->id & (KOBJ_CACHE_SIZE-1)]; \ kobj_method_t *_ce = *_cep; \ - kobj_lookup_hits++; /* assume hit */ \ - if (_ce->desc != _desc) \ + if (_ce->desc != _desc) { \ _ce = kobj_lookup_method(OPS->cls, \ _cep, _desc); \ + kobj_lookup_misses++; \ + } else \ + kobj_lookup_hits++; \ _m = _ce->func; \ } while(0) #else diff --git a/freebsd/sys/sys/libkern.h b/freebsd/sys/sys/libkern.h index b7c1d5de..ab47eeaa 100644 --- a/freebsd/sys/sys/libkern.h +++ b/freebsd/sys/sys/libkern.h @@ -123,11 +123,10 @@ extern int arc4rand_iniseed_state; /* Prototypes for non-quad routines. */ struct malloc_type; uint32_t arc4random(void); +void arc4random_buf(void *, size_t); #ifndef __rtems__ -void arc4rand(void *ptr, u_int len, int reseed); +void arc4rand(void *, u_int, int); #else /* __rtems__ */ -void arc4random_buf(void *, size_t); - static inline void arc4rand(void *ptr, u_int len, int reseed) { @@ -277,6 +276,9 @@ calculate_crc32c(uint32_t crc32c, const unsigned char *buffer, #if defined(__amd64__) || defined(__i386__) uint32_t sse42_crc32c(uint32_t, const unsigned char *, unsigned); #endif +#if defined(__aarch64__) +uint32_t armv8_crc32c(uint32_t, const unsigned char *, unsigned int); +#endif #endif diff --git a/freebsd/sys/sys/mbuf.h b/freebsd/sys/sys/mbuf.h index bd62c1cf..60670697 100644 --- a/freebsd/sys/sys/mbuf.h +++ b/freebsd/sys/sys/mbuf.h @@ -488,7 +488,7 @@ void sf_ext_free_nocache(void *, void *); #define CSUM_L4_VALID 0x08000000 /* checksum is correct */ #define CSUM_L5_CALC 0x10000000 /* calculated layer 5 csum */ #define CSUM_L5_VALID 0x20000000 /* checksum is correct */ -#define CSUM_COALESED 0x40000000 /* contains merged segments */ +#define CSUM_COALESCED 0x40000000 /* contains merged segments */ /* * CSUM flag description for use with printf(9) %b identifier. @@ -499,7 +499,7 @@ void sf_ext_free_nocache(void *, void *); "\12CSUM_IP6_UDP\13CSUM_IP6_TCP\14CSUM_IP6_SCTP\15CSUM_IP6_TSO" \ "\16CSUM_IP6_ISCSI" \ "\31CSUM_L3_CALC\32CSUM_L3_VALID\33CSUM_L4_CALC\34CSUM_L4_VALID" \ - "\35CSUM_L5_CALC\36CSUM_L5_VALID\37CSUM_COALESED" + "\35CSUM_L5_CALC\36CSUM_L5_VALID\37CSUM_COALESCED" /* CSUM flags compatibility mappings. */ #define CSUM_IP_CHECKED CSUM_L3_CALC diff --git a/freebsd/sys/sys/mount.h b/freebsd/sys/sys/mount.h index 9800d97d..152b2586 100644 --- a/freebsd/sys/sys/mount.h +++ b/freebsd/sys/sys/mount.h @@ -65,8 +65,8 @@ struct fid { * filesystem statistics */ #define MFSNAMELEN 16 /* length of type name including null */ -#define MNAMELEN 88 /* size of on/from name bufs */ -#define STATFS_VERSION 0x20030518 /* current version number */ +#define MNAMELEN 1024 /* size of on/from name bufs */ +#define STATFS_VERSION 0x20140518 /* current version number */ struct statfs { uint32_t f_version; /* structure version number */ uint32_t f_type; /* type of filesystem */ @@ -92,6 +92,34 @@ struct statfs { char f_mntonname[MNAMELEN]; /* directory on which mounted */ }; +#if defined(_WANT_FREEBSD11_STATFS) || defined(_KERNEL) +#define FREEBSD11_STATFS_VERSION 0x20030518 /* current version number */ +struct freebsd11_statfs { + uint32_t f_version; /* structure version number */ + uint32_t f_type; /* type of filesystem */ + uint64_t f_flags; /* copy of mount exported flags */ + uint64_t f_bsize; /* filesystem fragment size */ + uint64_t f_iosize; /* optimal transfer block size */ + uint64_t f_blocks; /* total data blocks in filesystem */ + uint64_t f_bfree; /* free blocks in filesystem */ + int64_t f_bavail; /* free blocks avail to non-superuser */ + uint64_t f_files; /* total file nodes in filesystem */ + int64_t f_ffree; /* free nodes avail to non-superuser */ + uint64_t f_syncwrites; /* count of sync writes since mount */ + uint64_t f_asyncwrites; /* count of async writes since mount */ + uint64_t f_syncreads; /* count of sync reads since mount */ + uint64_t f_asyncreads; /* count of async reads since mount */ + uint64_t f_spare[10]; /* unused spare */ + uint32_t f_namemax; /* maximum filename length */ + uid_t f_owner; /* user that mounted the filesystem */ + fsid_t f_fsid; /* filesystem id */ + char f_charspare[80]; /* spare string space */ + char f_fstypename[16]; /* filesystem type name */ + char f_mntfromname[88]; /* mounted filesystem */ + char f_mntonname[88]; /* directory on which mounted */ +}; +#endif /* _WANT_FREEBSD11_STATFS || _KERNEL */ + #ifdef _KERNEL #define OMFSNAMELEN 16 /* length of fs type name, including null */ #define OMNAMELEN (88 - 2 * sizeof(long)) /* size of on/from name bufs */ @@ -286,6 +314,7 @@ void __mnt_vnode_markerfree_active(struct vnode **mvp, struct mount *); #define MNT_ROOTFS 0x0000000000004000ULL /* identifies the root fs */ #define MNT_USER 0x0000000000008000ULL /* mounted by a user */ #define MNT_IGNORE 0x0000000000800000ULL /* do not show entry in df */ +#define MNT_VERIFIED 0x0000000400000000ULL /* filesystem is verified */ /* * Mask of flags that are visible to statfs(). @@ -301,7 +330,7 @@ void __mnt_vnode_markerfree_active(struct vnode **mvp, struct mount *); MNT_NOCLUSTERW | MNT_SUIDDIR | MNT_SOFTDEP | \ MNT_IGNORE | MNT_EXPUBLIC | MNT_NOSYMFOLLOW | \ MNT_GJOURNAL | MNT_MULTILABEL | MNT_ACLS | \ - MNT_NFS4ACLS | MNT_AUTOMOUNTED) + MNT_NFS4ACLS | MNT_AUTOMOUNTED | MNT_VERIFIED) /* Mask of flags that can be updated. */ #define MNT_UPDATEMASK (MNT_NOSUID | MNT_NOEXEC | \ diff --git a/freebsd/sys/sys/pcpu.h b/freebsd/sys/sys/pcpu.h index 8e246004..4430cc87 100644 --- a/freebsd/sys/sys/pcpu.h +++ b/freebsd/sys/sys/pcpu.h @@ -43,7 +43,6 @@ #include <sys/_sx.h> #include <sys/queue.h> #include <sys/_rmlock.h> -#include <sys/vmmeter.h> #include <rtems/bsd/sys/resource.h> #include <machine/pcpu.h> @@ -163,9 +162,6 @@ struct pcpu { u_int pc_cpuid; /* This cpu number */ STAILQ_ENTRY(pcpu) pc_allcpu; struct lock_list_entry *pc_spinlocks; -#ifndef __rtems__ - struct vmmeter pc_cnt; /* VM stats counters */ -#endif long pc_cp_time[CPUSTATES]; /* statclock ticks */ struct device *pc_device; void *pc_netisr; /* netisr SWI cookie */ @@ -173,6 +169,7 @@ struct pcpu { int pc_domain; /* Memory domain. */ struct rm_queue pc_rm_queue; /* rmlock list of trackers */ uintptr_t pc_dynamic; /* Dynamic per-cpu data area */ + uint64_t pc_early_dummy_counter; /* Startup time counter(9) */ /* * Keep MD fields last, so that CPU-specific variations on a diff --git a/freebsd/sys/sys/proc.h b/freebsd/sys/sys/proc.h index ea2a8abf..0644d68b 100644 --- a/freebsd/sys/sys/proc.h +++ b/freebsd/sys/sys/proc.h @@ -669,13 +669,13 @@ struct proc { pid_t p_reapsubtree; /* (e) Pid of the direct child of the reaper which spawned our subtree. */ - u_int p_xexit; /* (c) Exit code. */ - u_int p_xsig; /* (c) Stop/kill sig. */ uint16_t p_elf_machine; /* (x) ELF machine type */ uint64_t p_elf_flags; /* (x) ELF flags */ - /* End area that is copied on creation. */ -#define p_endcopy p_elf_flags +#define p_endcopy p_xexit + + u_int p_xexit; /* (c) Exit code. */ + u_int p_xsig; /* (c) Stop/kill sig. */ struct pgrp *p_pgrp; /* (c + e) Pointer to process group. */ struct knlist *p_klist; /* (c) Knotes attached to this proc. */ int p_numthreads; /* (c) Number of threads. */ @@ -1044,6 +1044,7 @@ int cr_canseesocket(struct ucred *cred, struct socket *so); #endif /* __rtems__ */ int cr_canseeothergids(struct ucred *u1, struct ucred *u2); int cr_canseeotheruids(struct ucred *u1, struct ucred *u2); +int cr_canseejailproc(struct ucred *u1, struct ucred *u2); int cr_cansignal(struct ucred *cred, struct proc *proc, int signum); int enterpgrp(struct proc *p, pid_t pgid, struct pgrp *pgrp, struct session *sess); diff --git a/freebsd/sys/sys/random.h b/freebsd/sys/sys/random.h index 996ca5c1..770a2f76 100644 --- a/freebsd/sys/sys/random.h +++ b/freebsd/sys/sys/random.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000-2015 Mark R. V. Murray + * Copyright (c) 2000-2015, 2017 Mark R. V. Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -106,6 +106,10 @@ enum random_entropy_source { #define RANDOM_HARVEST_EVERYTHING_MASK ((1 << (RANDOM_ENVIRONMENTAL_END + 1)) - 1) +#define RANDOM_LEGACY_BOOT_ENTROPY_MODULE "/boot/entropy" +#define RANDOM_CACHED_BOOT_ENTROPY_MODULE "boot_entropy_cache" +#define RANDOM_CACHED_SKIP_START 256 + #if defined(DEV_RANDOM) void random_harvest_queue(const void *, u_int, u_int, enum random_entropy_source); void random_harvest_fast(const void *, u_int, u_int, enum random_entropy_source); diff --git a/freebsd/sys/sys/smp.h b/freebsd/sys/sys/smp.h index d98b7ecf..9101bd76 100644 --- a/freebsd/sys/sys/smp.h +++ b/freebsd/sys/sys/smp.h @@ -251,7 +251,7 @@ extern struct mtx smp_ipi_mtx; int quiesce_all_cpus(const char *, int); int quiesce_cpus(cpuset_t, const char *, int); -void smp_no_rendevous_barrier(void *); +void smp_no_rendezvous_barrier(void *); void smp_rendezvous(void (*)(void *), void (*)(void *), void (*)(void *), diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h index e73e37dd..151b380b 100644 --- a/freebsd/sys/sys/sysproto.h +++ b/freebsd/sys/sys/sysproto.h @@ -80,11 +80,6 @@ struct chdir_args { struct fchdir_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; }; -struct mknod_args { - char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; - char mode_l_[PADL_(int)]; int mode; char mode_r_[PADR_(int)]; - char dev_l_[PADL_(int)]; int dev; char dev_r_[PADR_(int)]; -}; struct chmod_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char mode_l_[PADL_(int)]; int mode; char mode_r_[PADR_(int)]; @@ -583,18 +578,6 @@ struct setegid_args { struct seteuid_args { char euid_l_[PADL_(uid_t)]; uid_t euid; char euid_r_[PADR_(uid_t)]; }; -struct stat_args { - char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; - char ub_l_[PADL_(struct stat *)]; struct stat * ub; char ub_r_[PADR_(struct stat *)]; -}; -struct fstat_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char sb_l_[PADL_(struct stat *)]; struct stat * sb; char sb_r_[PADR_(struct stat *)]; -}; -struct lstat_args { - char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; - char ub_l_[PADL_(struct stat *)]; struct stat * ub; char ub_r_[PADR_(struct stat *)]; -}; struct pathconf_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char name_l_[PADL_(int)]; int name; char name_r_[PADR_(int)]; @@ -611,12 +594,6 @@ struct __setrlimit_args { char which_l_[PADL_(u_int)]; u_int which; char which_r_[PADR_(u_int)]; char rlp_l_[PADL_(struct rlimit *)]; struct rlimit * rlp; char rlp_r_[PADR_(struct rlimit *)]; }; -struct getdirentries_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; - char count_l_[PADL_(u_int)]; u_int count; char count_r_[PADR_(u_int)]; - char basep_l_[PADL_(long *)]; long * basep; char basep_r_[PADR_(long *)]; -}; struct sysctl_args { char name_l_[PADL_(int *)]; int * name; char name_r_[PADR_(int *)]; char namelen_l_[PADL_(u_int)]; u_int namelen; char namelen_r_[PADR_(u_int)]; @@ -778,11 +755,6 @@ struct lio_listio_args { char nent_l_[PADL_(int)]; int nent; char nent_r_[PADR_(int)]; char sig_l_[PADL_(struct sigevent *)]; struct sigevent * sig; char sig_r_[PADR_(struct sigevent *)]; }; -struct getdents_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; - char count_l_[PADL_(size_t)]; size_t count; char count_r_[PADR_(size_t)]; -}; struct lchmod_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char mode_l_[PADL_(mode_t)]; mode_t mode; char mode_r_[PADR_(mode_t)]; @@ -791,18 +763,6 @@ struct lutimes_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char tptr_l_[PADL_(struct timeval *)]; struct timeval * tptr; char tptr_r_[PADR_(struct timeval *)]; }; -struct nstat_args { - char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; - char ub_l_[PADL_(struct nstat *)]; struct nstat * ub; char ub_r_[PADR_(struct nstat *)]; -}; -struct nfstat_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char sb_l_[PADL_(struct nstat *)]; struct nstat * sb; char sb_r_[PADR_(struct nstat *)]; -}; -struct nlstat_args { - char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; - char ub_l_[PADL_(struct nstat *)]; struct nstat * ub; char ub_r_[PADR_(struct nstat *)]; -}; struct preadv_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; char iovp_l_[PADL_(struct iovec *)]; struct iovec * iovp; char iovp_r_[PADR_(struct iovec *)]; @@ -819,10 +779,6 @@ struct fhopen_args { char u_fhp_l_[PADL_(const struct fhandle *)]; const struct fhandle * u_fhp; char u_fhp_r_[PADR_(const struct fhandle *)]; char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; }; -struct fhstat_args { - char u_fhp_l_[PADL_(const struct fhandle *)]; const struct fhandle * u_fhp; char u_fhp_r_[PADR_(const struct fhandle *)]; - char sb_l_[PADL_(struct stat *)]; struct stat * sb; char sb_r_[PADR_(struct stat *)]; -}; struct modnext_args { char modid_l_[PADL_(int)]; int modid; char modid_r_[PADR_(int)]; }; @@ -894,7 +850,7 @@ struct munlockall_args { }; struct __getcwd_args { char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; - char buflen_l_[PADL_(u_int)]; u_int buflen; char buflen_r_[PADR_(u_int)]; + char buflen_l_[PADL_(size_t)]; size_t buflen; char buflen_r_[PADR_(size_t)]; }; struct sched_setparam_args { char pid_l_[PADL_(pid_t)]; pid_t pid; char pid_r_[PADR_(pid_t)]; @@ -1149,23 +1105,6 @@ struct mac_syscall_args { char call_l_[PADL_(int)]; int call; char call_r_[PADR_(int)]; char arg_l_[PADL_(void *)]; void * arg; char arg_r_[PADR_(void *)]; }; -struct getfsstat_args { - char buf_l_[PADL_(struct statfs *)]; struct statfs * buf; char buf_r_[PADR_(struct statfs *)]; - char bufsize_l_[PADL_(long)]; long bufsize; char bufsize_r_[PADR_(long)]; - char mode_l_[PADL_(int)]; int mode; char mode_r_[PADR_(int)]; -}; -struct statfs_args { - char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; - char buf_l_[PADL_(struct statfs *)]; struct statfs * buf; char buf_r_[PADR_(struct statfs *)]; -}; -struct fstatfs_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char buf_l_[PADL_(struct statfs *)]; struct statfs * buf; char buf_r_[PADR_(struct statfs *)]; -}; -struct fhstatfs_args { - char u_fhp_l_[PADL_(const struct fhandle *)]; const struct fhandle * u_fhp; char u_fhp_r_[PADR_(const struct fhandle *)]; - char buf_l_[PADL_(struct statfs *)]; struct statfs * buf; char buf_r_[PADR_(struct statfs *)]; -}; struct ksem_close_args { char id_l_[PADL_(semid_t)]; semid_t id; char id_r_[PADR_(semid_t)]; }; @@ -1557,12 +1496,6 @@ struct fexecve_args { char argv_l_[PADL_(char **)]; char ** argv; char argv_r_[PADR_(char **)]; char envv_l_[PADL_(char **)]; char ** envv; char envv_r_[PADR_(char **)]; }; -struct fstatat_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 buf_l_[PADL_(struct stat *)]; struct stat * buf; char buf_r_[PADR_(struct stat *)]; - char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)]; -}; struct futimesat_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 *)]; @@ -1585,12 +1518,6 @@ struct mkfifoat_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char mode_l_[PADL_(mode_t)]; mode_t mode; char mode_r_[PADR_(mode_t)]; }; -struct mknodat_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 mode_l_[PADL_(mode_t)]; mode_t mode; char mode_r_[PADR_(mode_t)]; - char dev_l_[PADL_(dev_t)]; dev_t dev; char dev_r_[PADR_(dev_t)]; -}; struct openat_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 *)]; @@ -1836,6 +1763,49 @@ struct numa_setaffinity_args { struct fdatasync_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; }; +struct fstat_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char sb_l_[PADL_(struct stat *)]; struct stat * sb; char sb_r_[PADR_(struct stat *)]; +}; +struct fstatat_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 buf_l_[PADL_(struct stat *)]; struct stat * buf; char buf_r_[PADR_(struct stat *)]; + char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)]; +}; +struct fhstat_args { + char u_fhp_l_[PADL_(const struct fhandle *)]; const struct fhandle * u_fhp; char u_fhp_r_[PADR_(const struct fhandle *)]; + char sb_l_[PADL_(struct stat *)]; struct stat * sb; char sb_r_[PADR_(struct stat *)]; +}; +struct getdirentries_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char count_l_[PADL_(size_t)]; size_t count; char count_r_[PADR_(size_t)]; + char basep_l_[PADL_(off_t *)]; off_t * basep; char basep_r_[PADR_(off_t *)]; +}; +struct statfs_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char buf_l_[PADL_(struct statfs *)]; struct statfs * buf; char buf_r_[PADR_(struct statfs *)]; +}; +struct fstatfs_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char buf_l_[PADL_(struct statfs *)]; struct statfs * buf; char buf_r_[PADR_(struct statfs *)]; +}; +struct getfsstat_args { + char buf_l_[PADL_(struct statfs *)]; struct statfs * buf; char buf_r_[PADR_(struct statfs *)]; + char bufsize_l_[PADL_(long)]; long bufsize; char bufsize_r_[PADR_(long)]; + char mode_l_[PADL_(int)]; int mode; char mode_r_[PADR_(int)]; +}; +struct fhstatfs_args { + char u_fhp_l_[PADL_(const struct fhandle *)]; const struct fhandle * u_fhp; char u_fhp_r_[PADR_(const struct fhandle *)]; + char buf_l_[PADL_(struct statfs *)]; struct statfs * buf; char buf_r_[PADR_(struct statfs *)]; +}; +struct mknodat_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 mode_l_[PADL_(mode_t)]; mode_t mode; char mode_r_[PADR_(mode_t)]; + char dev_l_[PADL_(dev_t)]; dev_t dev; char dev_r_[PADR_(dev_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 *); @@ -1848,7 +1818,6 @@ int sys_link(struct thread *, struct link_args *); int sys_unlink(struct thread *, struct unlink_args *); int sys_chdir(struct thread *, struct chdir_args *); int sys_fchdir(struct thread *, struct fchdir_args *); -int sys_mknod(struct thread *, struct mknod_args *); int sys_chmod(struct thread *, struct chmod_args *); int sys_chown(struct thread *, struct chown_args *); int sys_obreak(struct thread *, struct obreak_args *); @@ -1952,14 +1921,10 @@ int sys_ntp_adjtime(struct thread *, struct ntp_adjtime_args *); int sys_setgid(struct thread *, struct setgid_args *); int sys_setegid(struct thread *, struct setegid_args *); int sys_seteuid(struct thread *, struct seteuid_args *); -int sys_stat(struct thread *, struct stat_args *); -int sys_fstat(struct thread *, struct fstat_args *); -int sys_lstat(struct thread *, struct lstat_args *); int sys_pathconf(struct thread *, struct pathconf_args *); int sys_fpathconf(struct thread *, struct fpathconf_args *); int sys_getrlimit(struct thread *, struct __getrlimit_args *); int sys_setrlimit(struct thread *, struct __setrlimit_args *); -int sys_getdirentries(struct thread *, struct getdirentries_args *); int sys___sysctl(struct thread *, struct sysctl_args *); int sys_mlock(struct thread *, struct mlock_args *); int sys_munlock(struct thread *, struct munlock_args *); @@ -1997,16 +1962,11 @@ int sys_lchown(struct thread *, struct lchown_args *); int sys_aio_read(struct thread *, struct aio_read_args *); int sys_aio_write(struct thread *, struct aio_write_args *); int sys_lio_listio(struct thread *, struct lio_listio_args *); -int sys_getdents(struct thread *, struct getdents_args *); int sys_lchmod(struct thread *, struct lchmod_args *); int sys_lutimes(struct thread *, struct lutimes_args *); -int sys_nstat(struct thread *, struct nstat_args *); -int sys_nfstat(struct thread *, struct nfstat_args *); -int sys_nlstat(struct thread *, struct nlstat_args *); int sys_preadv(struct thread *, struct preadv_args *); int sys_pwritev(struct thread *, struct pwritev_args *); int sys_fhopen(struct thread *, struct fhopen_args *); -int sys_fhstat(struct thread *, struct fhstat_args *); int sys_modnext(struct thread *, struct modnext_args *); int sys_modstat(struct thread *, struct modstat_args *); int sys_modfnext(struct thread *, struct modfnext_args *); @@ -2080,10 +2040,6 @@ int sys_lchflags(struct thread *, struct lchflags_args *); int sys_uuidgen(struct thread *, struct uuidgen_args *); int sys_sendfile(struct thread *, struct sendfile_args *); int sys_mac_syscall(struct thread *, struct mac_syscall_args *); -int sys_getfsstat(struct thread *, struct getfsstat_args *); -int sys_statfs(struct thread *, struct statfs_args *); -int sys_fstatfs(struct thread *, struct fstatfs_args *); -int sys_fhstatfs(struct thread *, struct fhstatfs_args *); int sys_ksem_close(struct thread *, struct ksem_close_args *); int sys_ksem_post(struct thread *, struct ksem_post_args *); int sys_ksem_wait(struct thread *, struct ksem_wait_args *); @@ -2167,12 +2123,10 @@ int sys_faccessat(struct thread *, struct faccessat_args *); int sys_fchmodat(struct thread *, struct fchmodat_args *); int sys_fchownat(struct thread *, struct fchownat_args *); int sys_fexecve(struct thread *, struct fexecve_args *); -int sys_fstatat(struct thread *, struct fstatat_args *); int sys_futimesat(struct thread *, struct futimesat_args *); int sys_linkat(struct thread *, struct linkat_args *); int sys_mkdirat(struct thread *, struct mkdirat_args *); int sys_mkfifoat(struct thread *, struct mkfifoat_args *); -int sys_mknodat(struct thread *, struct mknodat_args *); int sys_openat(struct thread *, struct openat_args *); int sys_readlinkat(struct thread *, struct readlinkat_args *); int sys_renameat(struct thread *, struct renameat_args *); @@ -2223,6 +2177,15 @@ int sys_utimensat(struct thread *, struct utimensat_args *); int sys_numa_getaffinity(struct thread *, struct numa_getaffinity_args *); int sys_numa_setaffinity(struct thread *, struct numa_setaffinity_args *); int sys_fdatasync(struct thread *, struct fdatasync_args *); +int sys_fstat(struct thread *, struct fstat_args *); +int sys_fstatat(struct thread *, struct fstatat_args *); +int sys_fhstat(struct thread *, struct fhstat_args *); +int sys_getdirentries(struct thread *, struct getdirentries_args *); +int sys_statfs(struct thread *, struct statfs_args *); +int sys_fstatfs(struct thread *, struct fstatfs_args *); +int sys_getfsstat(struct thread *, struct getfsstat_args *); +int sys_fhstatfs(struct thread *, struct fhstatfs_args *); +int sys_mknodat(struct thread *, struct mknodat_args *); #ifdef COMPAT_43 @@ -2554,6 +2517,101 @@ int freebsd10_pipe(struct thread *, struct freebsd10_pipe_args *); #endif /* COMPAT_FREEBSD10 */ + +#ifdef COMPAT_FREEBSD11 + +struct freebsd11_mknod_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char mode_l_[PADL_(int)]; int mode; char mode_r_[PADR_(int)]; + char dev_l_[PADL_(int)]; int dev; char dev_r_[PADR_(int)]; +}; +struct freebsd11_stat_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char ub_l_[PADL_(struct freebsd11_stat *)]; struct freebsd11_stat * ub; char ub_r_[PADR_(struct freebsd11_stat *)]; +}; +struct freebsd11_fstat_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char sb_l_[PADL_(struct freebsd11_stat *)]; struct freebsd11_stat * sb; char sb_r_[PADR_(struct freebsd11_stat *)]; +}; +struct freebsd11_lstat_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char ub_l_[PADL_(struct freebsd11_stat *)]; struct freebsd11_stat * ub; char ub_r_[PADR_(struct freebsd11_stat *)]; +}; +struct freebsd11_getdirentries_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char count_l_[PADL_(u_int)]; u_int count; char count_r_[PADR_(u_int)]; + char basep_l_[PADL_(long *)]; long * basep; char basep_r_[PADR_(long *)]; +}; +struct freebsd11_getdents_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char count_l_[PADL_(size_t)]; size_t count; char count_r_[PADR_(size_t)]; +}; +struct freebsd11_nstat_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char ub_l_[PADL_(struct nstat *)]; struct nstat * ub; char ub_r_[PADR_(struct nstat *)]; +}; +struct freebsd11_nfstat_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char sb_l_[PADL_(struct nstat *)]; struct nstat * sb; char sb_r_[PADR_(struct nstat *)]; +}; +struct freebsd11_nlstat_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char ub_l_[PADL_(struct nstat *)]; struct nstat * ub; char ub_r_[PADR_(struct nstat *)]; +}; +struct freebsd11_fhstat_args { + char u_fhp_l_[PADL_(const struct fhandle *)]; const struct fhandle * u_fhp; char u_fhp_r_[PADR_(const struct fhandle *)]; + char sb_l_[PADL_(struct freebsd11_stat *)]; struct freebsd11_stat * sb; char sb_r_[PADR_(struct freebsd11_stat *)]; +}; +struct freebsd11_getfsstat_args { + char buf_l_[PADL_(struct freebsd11_statfs *)]; struct freebsd11_statfs * buf; char buf_r_[PADR_(struct freebsd11_statfs *)]; + char bufsize_l_[PADL_(long)]; long bufsize; char bufsize_r_[PADR_(long)]; + char mode_l_[PADL_(int)]; int mode; char mode_r_[PADR_(int)]; +}; +struct freebsd11_statfs_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char buf_l_[PADL_(struct freebsd11_statfs *)]; struct freebsd11_statfs * buf; char buf_r_[PADR_(struct freebsd11_statfs *)]; +}; +struct freebsd11_fstatfs_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char buf_l_[PADL_(struct freebsd11_statfs *)]; struct freebsd11_statfs * buf; char buf_r_[PADR_(struct freebsd11_statfs *)]; +}; +struct freebsd11_fhstatfs_args { + char u_fhp_l_[PADL_(const struct fhandle *)]; const struct fhandle * u_fhp; char u_fhp_r_[PADR_(const struct fhandle *)]; + char buf_l_[PADL_(struct freebsd11_statfs *)]; struct freebsd11_statfs * buf; char buf_r_[PADR_(struct freebsd11_statfs *)]; +}; +struct freebsd11_fstatat_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 buf_l_[PADL_(struct freebsd11_stat *)]; struct freebsd11_stat * buf; char buf_r_[PADR_(struct freebsd11_stat *)]; + char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)]; +}; +struct freebsd11_mknodat_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 mode_l_[PADL_(mode_t)]; mode_t mode; char mode_r_[PADR_(mode_t)]; + char dev_l_[PADL_(uint32_t)]; uint32_t dev; char dev_r_[PADR_(uint32_t)]; +}; +int freebsd11_mknod(struct thread *, struct freebsd11_mknod_args *); +int freebsd11_stat(struct thread *, struct freebsd11_stat_args *); +int freebsd11_fstat(struct thread *, struct freebsd11_fstat_args *); +int freebsd11_lstat(struct thread *, struct freebsd11_lstat_args *); +int freebsd11_getdirentries(struct thread *, struct freebsd11_getdirentries_args *); +int freebsd11_getdents(struct thread *, struct freebsd11_getdents_args *); +int freebsd11_nstat(struct thread *, struct freebsd11_nstat_args *); +int freebsd11_nfstat(struct thread *, struct freebsd11_nfstat_args *); +int freebsd11_nlstat(struct thread *, struct freebsd11_nlstat_args *); +int freebsd11_fhstat(struct thread *, struct freebsd11_fhstat_args *); +int freebsd11_getfsstat(struct thread *, struct freebsd11_getfsstat_args *); +int freebsd11_statfs(struct thread *, struct freebsd11_statfs_args *); +int freebsd11_fstatfs(struct thread *, struct freebsd11_fstatfs_args *); +int freebsd11_fhstatfs(struct thread *, struct freebsd11_fhstatfs_args *); +int freebsd11_fstatat(struct thread *, struct freebsd11_fstatat_args *); +int freebsd11_mknodat(struct thread *, struct freebsd11_mknodat_args *); + +#endif /* COMPAT_FREEBSD11 */ + #define SYS_AUE_syscall AUE_NULL #define SYS_AUE_exit AUE_EXIT #define SYS_AUE_fork AUE_FORK @@ -2567,7 +2625,7 @@ int freebsd10_pipe(struct thread *, struct freebsd10_pipe_args *); #define SYS_AUE_unlink AUE_UNLINK #define SYS_AUE_chdir AUE_CHDIR #define SYS_AUE_fchdir AUE_FCHDIR -#define SYS_AUE_mknod AUE_MKNOD +#define SYS_AUE_freebsd11_mknod AUE_MKNOD #define SYS_AUE_chmod AUE_CHMOD #define SYS_AUE_chown AUE_CHOWN #define SYS_AUE_break AUE_NULL @@ -2716,14 +2774,14 @@ int freebsd10_pipe(struct thread *, struct freebsd10_pipe_args *); #define SYS_AUE_setgid AUE_SETGID #define SYS_AUE_setegid AUE_SETEGID #define SYS_AUE_seteuid AUE_SETEUID -#define SYS_AUE_stat AUE_STAT -#define SYS_AUE_fstat AUE_FSTAT -#define SYS_AUE_lstat AUE_LSTAT +#define SYS_AUE_freebsd11_stat AUE_STAT +#define SYS_AUE_freebsd11_fstat AUE_FSTAT +#define SYS_AUE_freebsd11_lstat AUE_LSTAT #define SYS_AUE_pathconf AUE_PATHCONF #define SYS_AUE_fpathconf AUE_FPATHCONF #define SYS_AUE_getrlimit AUE_GETRLIMIT #define SYS_AUE_setrlimit AUE_SETRLIMIT -#define SYS_AUE_getdirentries AUE_GETDIRENTRIES +#define SYS_AUE_freebsd11_getdirentries AUE_GETDIRENTRIES #define SYS_AUE_freebsd6_mmap AUE_MMAP #define SYS_AUE_freebsd6_lseek AUE_LSEEK #define SYS_AUE_freebsd6_truncate AUE_TRUNCATE @@ -2768,17 +2826,17 @@ int freebsd10_pipe(struct thread *, struct freebsd10_pipe_args *); #define SYS_AUE_aio_read AUE_AIO_READ #define SYS_AUE_aio_write AUE_AIO_WRITE #define SYS_AUE_lio_listio AUE_LIO_LISTIO -#define SYS_AUE_getdents AUE_O_GETDENTS +#define SYS_AUE_freebsd11_getdents AUE_O_GETDENTS #define SYS_AUE_lchmod AUE_LCHMOD #define SYS_AUE_lutimes AUE_LUTIMES -#define SYS_AUE_nstat AUE_STAT -#define SYS_AUE_nfstat AUE_FSTAT -#define SYS_AUE_nlstat AUE_LSTAT +#define SYS_AUE_freebsd11_nstat AUE_STAT +#define SYS_AUE_freebsd11_nfstat AUE_FSTAT +#define SYS_AUE_freebsd11_nlstat AUE_LSTAT #define SYS_AUE_preadv AUE_PREADV #define SYS_AUE_pwritev AUE_PWRITEV #define SYS_AUE_freebsd4_fhstatfs AUE_FHSTATFS #define SYS_AUE_fhopen AUE_FHOPEN -#define SYS_AUE_fhstat AUE_FHSTAT +#define SYS_AUE_freebsd11_fhstat AUE_FHSTAT #define SYS_AUE_modnext AUE_NULL #define SYS_AUE_modstat AUE_NULL #define SYS_AUE_modfnext AUE_NULL @@ -2858,10 +2916,10 @@ int freebsd10_pipe(struct thread *, struct freebsd10_pipe_args *); #define SYS_AUE_uuidgen AUE_NULL #define SYS_AUE_sendfile AUE_SENDFILE #define SYS_AUE_mac_syscall AUE_NULL -#define SYS_AUE_getfsstat AUE_GETFSSTAT -#define SYS_AUE_statfs AUE_STATFS -#define SYS_AUE_fstatfs AUE_FSTATFS -#define SYS_AUE_fhstatfs AUE_FHSTATFS +#define SYS_AUE_freebsd11_getfsstat AUE_GETFSSTAT +#define SYS_AUE_freebsd11_statfs AUE_STATFS +#define SYS_AUE_freebsd11_fstatfs AUE_FSTATFS +#define SYS_AUE_freebsd11_fhstatfs AUE_FHSTATFS #define SYS_AUE_ksem_close AUE_SEMCLOSE #define SYS_AUE_ksem_post AUE_SEMPOST #define SYS_AUE_ksem_wait AUE_SEMWAIT @@ -2945,12 +3003,12 @@ int freebsd10_pipe(struct thread *, struct freebsd10_pipe_args *); #define SYS_AUE_fchmodat AUE_FCHMODAT #define SYS_AUE_fchownat AUE_FCHOWNAT #define SYS_AUE_fexecve AUE_FEXECVE -#define SYS_AUE_fstatat AUE_FSTATAT +#define SYS_AUE_freebsd11_fstatat AUE_FSTATAT #define SYS_AUE_futimesat AUE_FUTIMESAT #define SYS_AUE_linkat AUE_LINKAT #define SYS_AUE_mkdirat AUE_MKDIRAT #define SYS_AUE_mkfifoat AUE_MKFIFOAT -#define SYS_AUE_mknodat AUE_MKNODAT +#define SYS_AUE_freebsd11_mknodat AUE_MKNODAT #define SYS_AUE_openat AUE_OPENAT_RWTC #define SYS_AUE_readlinkat AUE_READLINKAT #define SYS_AUE_renameat AUE_RENAMEAT @@ -3001,6 +3059,15 @@ int freebsd10_pipe(struct thread *, struct freebsd10_pipe_args *); #define SYS_AUE_numa_getaffinity AUE_NULL #define SYS_AUE_numa_setaffinity AUE_NULL #define SYS_AUE_fdatasync AUE_FSYNC +#define SYS_AUE_fstat AUE_FSTAT +#define SYS_AUE_fstatat AUE_FSTATAT +#define SYS_AUE_fhstat AUE_FHSTAT +#define SYS_AUE_getdirentries AUE_GETDIRENTRIES +#define SYS_AUE_statfs AUE_STATFS +#define SYS_AUE_fstatfs AUE_FSTATFS +#define SYS_AUE_getfsstat AUE_GETFSSTAT +#define SYS_AUE_fhstatfs AUE_FHSTATFS +#define SYS_AUE_mknodat AUE_MKNODAT #endif /* __rtems__ */ #undef PAD_ diff --git a/freebsd/sys/sys/tty.h b/freebsd/sys/sys/tty.h index 09e04195..c37d0bf3 100644 --- a/freebsd/sys/sys/tty.h +++ b/freebsd/sys/sys/tty.h @@ -148,7 +148,7 @@ struct xtty { pid_t xt_pgid; /* Foreground process group. */ pid_t xt_sid; /* Session. */ unsigned int xt_flags; /* Terminal option flags. */ - dev_t xt_dev; /* Userland device. */ + uint32_t xt_dev; /* Userland device. XXXKIB truncated */ }; #ifdef _KERNEL diff --git a/freebsd/sys/sys/user.h b/freebsd/sys/sys/user.h index 077baf46..9fdb9dd6 100644 --- a/freebsd/sys/sys/user.h +++ b/freebsd/sys/sys/user.h @@ -84,7 +84,7 @@ * it in two places: function fill_kinfo_proc in sys/kern/kern_proc.c and * function kvm_proclist in lib/libkvm/kvm_proc.c . */ -#define KI_NSPARE_INT 4 +#define KI_NSPARE_INT 2 #define KI_NSPARE_LONG 12 #define KI_NSPARE_PTR 6 @@ -135,7 +135,7 @@ struct kinfo_proc { pid_t ki_tsid; /* Terminal session ID */ short ki_jobc; /* job control counter */ short ki_spare_short1; /* unused (just here for alignment) */ - dev_t ki_tdev; /* controlling tty dev */ + uint32_t ki_tdev_freebsd11; /* controlling tty dev */ sigset_t ki_siglist; /* Signals arrived but not delivered */ sigset_t ki_sigmask; /* Current signal mask */ sigset_t ki_sigignore; /* Signals being ignored */ @@ -188,6 +188,7 @@ struct kinfo_proc { */ char ki_sparestrings[46]; /* spare string space */ int ki_spareints[KI_NSPARE_INT]; /* spare room for growth */ + uint64_t ki_tdev; /* controlling tty dev */ int ki_oncpu; /* Which cpu we are on */ int ki_lastcpu; /* Last cpu we were on */ int ki_tracer; /* Pid of tracing process */ @@ -344,14 +345,20 @@ struct kinfo_file { int kf_flags; /* Flags. */ int kf_pad0; /* Round to 64 bit alignment. */ int64_t kf_offset; /* Seek location. */ - int kf_vnode_type; /* Vnode type. */ - int kf_sock_domain; /* Socket domain. */ - int kf_sock_type; /* Socket type. */ - int kf_sock_protocol; /* Socket protocol. */ - struct sockaddr_storage kf_sa_local; /* Socket address. */ - struct sockaddr_storage kf_sa_peer; /* Peer address. */ union { struct { + /* Sendq size */ + uint32_t kf_sock_sendq; + /* Socket domain. */ + int kf_sock_domain0; + /* Socket type. */ + int kf_sock_type0; + /* Socket protocol. */ + int kf_sock_protocol0; + /* Socket address. */ + struct sockaddr_storage kf_sa_local; + /* Peer address. */ + struct sockaddr_storage kf_sa_peer; /* Address of so_pcb. */ uint64_t kf_sock_pcb; /* Address of inp_ppcb. */ @@ -362,18 +369,27 @@ struct kinfo_file { uint16_t kf_sock_snd_sb_state; /* Receive buffer state. */ uint16_t kf_sock_rcv_sb_state; - /* Round to 64 bit alignment. */ - uint32_t kf_sock_pad0; + /* Recvq size. */ + uint32_t kf_sock_recvq; } kf_sock; struct { + /* Vnode type. */ + int kf_file_type; + /* Space for future use */ + int kf_spareint[3]; + uint64_t kf_spareint64[30]; + /* Vnode filesystem id. */ + uint64_t kf_file_fsid; + /* File device. */ + uint64_t kf_file_rdev; /* Global file id. */ uint64_t kf_file_fileid; /* File size. */ uint64_t kf_file_size; - /* Vnode filesystem id. */ - uint32_t kf_file_fsid; - /* File device. */ - uint32_t kf_file_rdev; + /* Vnode filesystem id, FreeBSD 11 compat. */ + uint32_t kf_file_fsid_freebsd11; + /* File device, FreeBSD 11 compat. */ + uint32_t kf_file_rdev_freebsd11; /* File mode. */ uint16_t kf_file_mode; /* Round to 64 bit alignment. */ @@ -381,10 +397,14 @@ struct kinfo_file { uint32_t kf_file_pad1; } kf_file; struct { + uint32_t kf_spareint[4]; + uint64_t kf_spareint64[32]; uint32_t kf_sem_value; uint16_t kf_sem_mode; } kf_sem; struct { + uint32_t kf_spareint[4]; + uint64_t kf_spareint64[32]; uint64_t kf_pipe_addr; uint64_t kf_pipe_peer; uint32_t kf_pipe_buffer_cnt; @@ -392,11 +412,17 @@ struct kinfo_file { uint32_t kf_pipe_pad0[3]; } kf_pipe; struct { - uint32_t kf_pts_dev; + uint32_t kf_spareint[4]; + uint64_t kf_spareint64[32]; + uint32_t kf_pts_dev_freebsd11; + uint32_t kf_pts_pad0; + uint64_t kf_pts_dev; /* Round to 64 bit alignment. */ - uint32_t kf_pts_pad0[7]; + uint32_t kf_pts_pad1[4]; } kf_pts; struct { + uint32_t kf_spareint[4]; + uint64_t kf_spareint64[32]; pid_t kf_pid; } kf_proc; } kf_un; @@ -411,6 +437,12 @@ struct kinfo_file { int kf_dummy; #endif /* __rtems__ */ }; +#ifndef _KERNEL +#define kf_vnode_type kf_un.kf_file.kf_file_type +#define kf_sock_domain kf_un.kf_sock.kf_sock_domain0 +#define kf_sock_type kf_un.kf_sock.kf_sock_type0 +#define kf_sock_protocol kf_un.kf_sock.kf_sock_protocol0 +#endif /* * The KERN_PROC_VMMAP sysctl allows a process to dump the VM layout of @@ -460,7 +492,7 @@ struct kinfo_ovmentry { void *_kve_pspare[8]; /* Space for more stuff. */ off_t kve_offset; /* Mapping offset in object */ uint64_t kve_fileid; /* inode number if vnode */ - dev_t kve_fsid; /* dev_t of vnode location */ + uint32_t kve_fsid; /* dev_t of vnode location */ int _kve_ispare[3]; /* Space for more stuff. */ }; @@ -475,7 +507,7 @@ struct kinfo_vmentry { uint64_t kve_end; /* Finishing address. */ uint64_t kve_offset; /* Mapping offset in object */ uint64_t kve_vn_fileid; /* inode number if vnode */ - uint32_t kve_vn_fsid; /* dev_t of vnode location */ + uint32_t kve_vn_fsid_freebsd11; /* dev_t of vnode location */ int kve_flags; /* Flags on map entry. */ int kve_resident; /* Number of resident pages. */ int kve_private_resident; /* Number of private pages. */ @@ -484,10 +516,12 @@ struct kinfo_vmentry { int kve_shadow_count; /* VM obj shadow count. */ int kve_vn_type; /* Vnode type. */ uint64_t kve_vn_size; /* File size. */ - uint32_t kve_vn_rdev; /* Device id if device. */ + uint32_t kve_vn_rdev_freebsd11; /* Device id if device. */ uint16_t kve_vn_mode; /* File mode. */ uint16_t kve_status; /* Status flags. */ - int _kve_ispare[12]; /* Space for more stuff. */ + uint64_t kve_vn_fsid; /* dev_t of vnode location */ + uint64_t kve_vn_rdev; /* Device id if device. */ + int _kve_ispare[8]; /* Space for more stuff. */ /* Truncated before copyout in sysctl */ char kve_path[PATH_MAX]; /* Path to VM obj, if any. */ }; @@ -501,14 +535,15 @@ struct kinfo_vmobject { int kvo_type; /* Object type: KVME_TYPE_*. */ uint64_t kvo_size; /* Object size in pages. */ uint64_t kvo_vn_fileid; /* inode number if vnode. */ - uint32_t kvo_vn_fsid; /* dev_t of vnode location. */ + uint32_t kvo_vn_fsid_freebsd11; /* dev_t of vnode location. */ int kvo_ref_count; /* Reference count. */ int kvo_shadow_count; /* Shadow count. */ int kvo_memattr; /* Memory attribute. */ uint64_t kvo_resident; /* Number of resident pages. */ uint64_t kvo_active; /* Number of active pages. */ uint64_t kvo_inactive; /* Number of inactive pages. */ - uint64_t _kvo_qspare[8]; + uint64_t kvo_vn_fsid; + uint64_t _kvo_qspare[7]; uint32_t _kvo_ispare[8]; char kvo_path[PATH_MAX]; /* Pathname, if any. */ }; diff --git a/freebsd/sys/sys/vmmeter.h b/freebsd/sys/sys/vmmeter.h index b5d0ef14..d7692583 100644 --- a/freebsd/sys/sys/vmmeter.h +++ b/freebsd/sys/sys/vmmeter.h @@ -39,50 +39,84 @@ */ #define MAXSLP 20 +/* Systemwide totals computed every five seconds. */ +struct vmtotal { + int16_t t_rq; /* length of the run queue */ + int16_t t_dw; /* jobs in ``disk wait'' (neg priority) */ + int16_t t_pw; /* jobs in page wait */ + int16_t t_sl; /* jobs sleeping in core */ + int16_t t_sw; /* swapped out runnable/short block jobs */ + int32_t t_vm; /* total virtual memory */ + int32_t t_avm; /* active virtual memory */ + int32_t t_rm; /* total real memory in use */ + int32_t t_arm; /* active real memory */ + int32_t t_vmshr; /* shared virtual memory */ + int32_t t_avmshr; /* active shared virtual memory */ + int32_t t_rmshr; /* shared real memory */ + int32_t t_armshr; /* active shared real memory */ + int32_t t_free; /* free memory pages */ +}; + +#if defined(_KERNEL) || defined(_WANT_VMMETER) +#include <sys/counter.h> + /* * System wide statistics counters. * Locking: * a - locked by atomic operations * c - constant after initialization * f - locked by vm_page_queue_free_mtx - * p - locked by being in the PCPU and atomicity respect to interrupts + * p - uses counter(9) * q - changes are synchronized by the corresponding vm_pagequeue lock */ struct vmmeter { /* * General system activity. */ - u_int v_swtch; /* (p) context switches */ - u_int v_trap; /* (p) calls to trap */ - u_int v_syscall; /* (p) calls to syscall() */ - u_int v_intr; /* (p) device interrupts */ - u_int v_soft; /* (p) software interrupts */ + counter_u64_t v_swtch; /* (p) context switches */ + counter_u64_t v_trap; /* (p) calls to trap */ + counter_u64_t v_syscall; /* (p) calls to syscall() */ + counter_u64_t v_intr; /* (p) device interrupts */ + counter_u64_t v_soft; /* (p) software interrupts */ /* * Virtual memory activity. */ - u_int v_vm_faults; /* (p) address memory faults */ - u_int v_io_faults; /* (p) page faults requiring I/O */ - u_int v_cow_faults; /* (p) copy-on-writes faults */ - u_int v_cow_optim; /* (p) optimized copy-on-writes faults */ - u_int v_zfod; /* (p) pages zero filled on demand */ - u_int v_ozfod; /* (p) optimized zero fill pages */ - u_int v_swapin; /* (p) swap pager pageins */ - u_int v_swapout; /* (p) swap pager pageouts */ - u_int v_swappgsin; /* (p) swap pager pages paged in */ - u_int v_swappgsout; /* (p) swap pager pages paged out */ - u_int v_vnodein; /* (p) vnode pager pageins */ - u_int v_vnodeout; /* (p) vnode pager pageouts */ - u_int v_vnodepgsin; /* (p) vnode_pager pages paged in */ - u_int v_vnodepgsout; /* (p) vnode pager pages paged out */ - u_int v_intrans; /* (p) intransit blocking page faults */ - u_int v_reactivated; /* (p) pages reactivated by the pagedaemon */ - u_int v_pdwakeups; /* (p) times daemon has awaken from sleep */ - u_int v_pdpages; /* (p) pages analyzed by daemon */ - u_int v_pdshortfalls; /* (p) page reclamation shortfalls */ - - u_int v_dfree; /* (p) pages freed by daemon */ - u_int v_pfree; /* (p) pages freed by exiting processes */ - u_int v_tfree; /* (p) total pages freed */ + counter_u64_t v_vm_faults; /* (p) address memory faults */ + counter_u64_t v_io_faults; /* (p) page faults requiring I/O */ + counter_u64_t v_cow_faults; /* (p) copy-on-writes faults */ + counter_u64_t v_cow_optim; /* (p) optimized COW faults */ + counter_u64_t v_zfod; /* (p) pages zero filled on demand */ + counter_u64_t v_ozfod; /* (p) optimized zero fill pages */ + counter_u64_t v_swapin; /* (p) swap pager pageins */ + counter_u64_t v_swapout; /* (p) swap pager pageouts */ + counter_u64_t v_swappgsin; /* (p) swap pager pages paged in */ + counter_u64_t v_swappgsout; /* (p) swap pager pages paged out */ + counter_u64_t v_vnodein; /* (p) vnode pager pageins */ + counter_u64_t v_vnodeout; /* (p) vnode pager pageouts */ + counter_u64_t v_vnodepgsin; /* (p) vnode_pager pages paged in */ + counter_u64_t v_vnodepgsout; /* (p) vnode pager pages paged out */ + counter_u64_t v_intrans; /* (p) intransit blocking page faults */ + counter_u64_t v_reactivated; /* (p) reactivated by the pagedaemon */ + counter_u64_t v_pdwakeups; /* (p) times daemon has awaken */ + counter_u64_t v_pdpages; /* (p) pages analyzed by daemon */ + counter_u64_t v_pdshortfalls; /* (p) page reclamation shortfalls */ + + counter_u64_t v_dfree; /* (p) pages freed by daemon */ + counter_u64_t v_pfree; /* (p) pages freed by processes */ + counter_u64_t v_tfree; /* (p) total pages freed */ + /* + * Fork/vfork/rfork activity. + */ + counter_u64_t v_forks; /* (p) fork() calls */ + counter_u64_t v_vforks; /* (p) vfork() calls */ + counter_u64_t v_rforks; /* (p) rfork() calls */ + counter_u64_t v_kthreads; /* (p) fork() calls by kernel */ + counter_u64_t v_forkpages; /* (p) pages affected by fork() */ + counter_u64_t v_vforkpages; /* (p) pages affected by vfork() */ + counter_u64_t v_rforkpages; /* (p) pages affected by rfork() */ + counter_u64_t v_kthreadpages; /* (p) ... and by kernel fork() */ +#define VM_METER_NCOUNTERS \ + (offsetof(struct vmmeter, v_page_size) / sizeof(counter_u64_t)) /* * Distribution of page usages. */ @@ -100,24 +134,18 @@ struct vmmeter { u_int v_pageout_free_min; /* (c) min pages reserved for kernel */ u_int v_interrupt_free_min; /* (c) reserved pages for int code */ u_int v_free_severe; /* (c) severe page depletion point */ - /* - * Fork/vfork/rfork activity. - */ - u_int v_forks; /* (p) fork() calls */ - u_int v_vforks; /* (p) vfork() calls */ - u_int v_rforks; /* (p) rfork() calls */ - u_int v_kthreads; /* (p) fork() calls by kernel */ - u_int v_forkpages; /* (p) VM pages affected by fork() */ - u_int v_vforkpages; /* (p) VM pages affected by vfork() */ - u_int v_rforkpages; /* (p) VM pages affected by rfork() */ - u_int v_kthreadpages; /* (p) VM pages affected by fork() by kernel */ }; +#endif /* _KERNEL || _WANT_VMMETER */ + #ifdef _KERNEL extern struct vmmeter vm_cnt; - extern u_int vm_pageout_wakeup_thresh; +#define VM_CNT_ADD(var, x) counter_u64_add(vm_cnt.var, x) +#define VM_CNT_INC(var) VM_CNT_ADD(var, 1) +#define VM_CNT_FETCH(var) counter_u64_fetch(vm_cnt.var) + /* * Return TRUE if we are under our severe low-free-pages threshold * @@ -189,33 +217,5 @@ vm_laundry_target(void) return (vm_paging_target()); } - -/* - * Obtain the value of a per-CPU counter. - */ -#define VM_METER_PCPU_CNT(member) \ - vm_meter_cnt(__offsetof(struct vmmeter, member)) - -u_int vm_meter_cnt(size_t); - -#endif - -/* systemwide totals computed every five seconds */ -struct vmtotal { - int16_t t_rq; /* length of the run queue */ - int16_t t_dw; /* jobs in ``disk wait'' (neg priority) */ - int16_t t_pw; /* jobs in page wait */ - int16_t t_sl; /* jobs sleeping in core */ - int16_t t_sw; /* swapped out runnable/short block jobs */ - int32_t t_vm; /* total virtual memory */ - int32_t t_avm; /* active virtual memory */ - int32_t t_rm; /* total real memory in use */ - int32_t t_arm; /* active real memory */ - int32_t t_vmshr; /* shared virtual memory */ - int32_t t_avmshr; /* active shared virtual memory */ - int32_t t_rmshr; /* shared real memory */ - int32_t t_armshr; /* active shared real memory */ - int32_t t_free; /* free memory pages */ -}; - -#endif +#endif /* _KERNEL */ +#endif /* _SYS_VMMETER_H_ */ diff --git a/freebsd/sys/sys/vnode.h b/freebsd/sys/sys/vnode.h index 535016ed..8f123d5e 100644 --- a/freebsd/sys/sys/vnode.h +++ b/freebsd/sys/sys/vnode.h @@ -267,11 +267,12 @@ struct xvnode { struct vattr { enum vtype va_type; /* vnode type (for create) */ u_short va_mode; /* files access mode and type */ - short va_nlink; /* number of references to file */ + u_short va_padding0; uid_t va_uid; /* owner user id */ gid_t va_gid; /* owner group id */ + nlink_t va_nlink; /* number of references to file */ dev_t va_fsid; /* filesystem id */ - long va_fileid; /* file id */ + ino_t va_fileid; /* file id */ u_quad_t va_size; /* file size in bytes */ long va_blocksize; /* blocksize preferred for i/o */ struct timespec va_atime; /* time of last access */ @@ -403,6 +404,7 @@ extern int vttoif_tab[]; #define V_ALT 0x0002 /* vinvalbuf: invalidate only alternate bufs */ #define V_NORMAL 0x0004 /* vinvalbuf: invalidate only regular bufs */ #define V_CLEANONLY 0x0008 /* vinvalbuf: invalidate only clean bufs */ +#define V_VMIO 0x0010 /* vinvalbuf: called during pageout */ #define REVOKEALL 0x0001 /* vop_revoke: revoke all aliases */ #define V_WAIT 0x0001 /* vn_start_write: sleep for suspend */ #define V_NOWAIT 0x0002 /* vn_start_write: don't sleep for suspend */ @@ -585,6 +587,7 @@ struct file; struct mount; struct nameidata; struct ostat; +struct freebsd11_stat; struct thread; struct proc; struct stat; @@ -613,7 +616,8 @@ void cache_purge_negative(struct vnode *vp); void cache_purgevfs(struct mount *mp, bool force); int change_dir(struct vnode *vp, struct thread *td); void cvtstat(struct stat *st, struct ostat *ost); -void cvtnstat(struct stat *sb, struct nstat *nsb); +void freebsd11_cvtnstat(struct stat *sb, struct nstat *nsb); +void freebsd11_cvtstat(struct stat *st, struct freebsd11_stat *ost); int getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops, struct vnode **vpp); void getnewvnode_reserve(u_int count); @@ -882,6 +886,8 @@ int vn_chmod(struct file *fp, mode_t mode, struct ucred *active_cred, int vn_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred, struct thread *td); +void vn_fsid(struct vnode *vp, struct vattr *va); + #endif /* _KERNEL */ #endif /* __rtems__ */ diff --git a/freebsd/sys/vm/uma_core.c b/freebsd/sys/vm/uma_core.c index 02f743d2..c69faea9 100644 --- a/freebsd/sys/vm/uma_core.c +++ b/freebsd/sys/vm/uma_core.c @@ -1980,6 +1980,9 @@ uma_zcreate(const char *name, size_t size, uma_ctor ctor, uma_dtor dtor, bool locked; #endif /* __rtems__ */ + KASSERT(powerof2(align + 1), ("invalid zone alignment %d for \"%s\"", + align, name)); + /* This stuff is essential for the zone ctor */ memset(&args, 0, sizeof(args)); args.name = name; |