summaryrefslogtreecommitdiffstats
path: root/freebsd/sys
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-07 12:12:37 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:36 +0200
commitde261e0404e1fe54544275fc57d5b982df4f42b4 (patch)
tree856cbdf23d6809b99c4d642d066bc45cd67c26e6 /freebsd/sys
parentlibbsd.txt: Use rtems_bsd_ifconfig_lo0() (diff)
downloadrtems-libbsd-de261e0404e1fe54544275fc57d5b982df4f42b4.tar.bz2
Update to FreeBSD head 2017-06-01
Git mirror commit dfb26efac4ce9101dda240e94d9ab53f80a9e131. Update #3472.
Diffstat (limited to 'freebsd/sys')
-rw-r--r--freebsd/sys/bsm/audit.h4
-rw-r--r--freebsd/sys/cam/ata/ata_all.h4
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.c69
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.h12
-rw-r--r--freebsd/sys/crypto/des/des_enc.c20
-rw-r--r--freebsd/sys/crypto/des/des_setkey.c8
-rw-r--r--freebsd/sys/dev/e1000/e1000_ich8lan.c50
-rw-r--r--freebsd/sys/dev/e1000/if_em.c8
-rw-r--r--freebsd/sys/dev/e1000/if_em.h1
-rw-r--r--freebsd/sys/dev/fdt/fdt_common.c2
-rw-r--r--freebsd/sys/dev/ffec/if_ffec.c10
-rw-r--r--freebsd/sys/dev/fxp/if_fxp.c21
-rw-r--r--freebsd/sys/dev/mii/micphy.c28
-rw-r--r--freebsd/sys/dev/pci/pci_pci.c21
-rw-r--r--freebsd/sys/dev/pci/pcib_private.h1
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwn.c8
-rw-r--r--freebsd/sys/dev/rtwn/rtl8188e/r88e_chan.c2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_chan.c8
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c4
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/r12a_chan.c2
-rw-r--r--freebsd/sys/dev/sdhci/sdhci.c26
-rw-r--r--freebsd/sys/dev/sdhci/sdhci.h2
-rw-r--r--freebsd/sys/dev/usb/quirk/usb_quirk.c1
-rw-r--r--freebsd/sys/dev/usb/usb_busdma.c2
-rw-r--r--freebsd/sys/fs/devfs/devfs_vnops.c1
-rw-r--r--freebsd/sys/i386/i386/in_cksum.c6
-rw-r--r--freebsd/sys/kern/kern_intr.c136
-rw-r--r--freebsd/sys/kern/kern_mib.c1
-rw-r--r--freebsd/sys/kern/kern_synch.c2
-rw-r--r--freebsd/sys/kern/kern_timeout.c2
-rw-r--r--freebsd/sys/kern/subr_kobj.c12
-rw-r--r--freebsd/sys/kern/subr_prf.c7
-rw-r--r--freebsd/sys/kern/sys_socket.c29
-rw-r--r--freebsd/sys/kern/tty.c2
-rw-r--r--freebsd/sys/kern/uipc_sockbuf.c14
-rw-r--r--freebsd/sys/kern/uipc_socket.c27
-rw-r--r--freebsd/sys/libkern/crc32.c16
-rw-r--r--freebsd/sys/net/altq/altq_rio.c2
-rw-r--r--freebsd/sys/net/altq/altq_rmclass.h4
-rw-r--r--freebsd/sys/net/bpf_filter.c10
-rw-r--r--freebsd/sys/net/bpf_jitter.c10
-rw-r--r--freebsd/sys/net/bpf_jitter.h8
-rw-r--r--freebsd/sys/net/ethernet.h2
-rw-r--r--freebsd/sys/net/ieee8023ad_lacp.c4
-rw-r--r--freebsd/sys/net/if.c34
-rw-r--r--freebsd/sys/net/if_bridge.c8
-rw-r--r--freebsd/sys/net/if_epair.c4
-rw-r--r--freebsd/sys/net/if_ethersubr.c3
-rw-r--r--freebsd/sys/net/if_gre.c14
-rw-r--r--freebsd/sys/net/if_gre.h1
-rw-r--r--freebsd/sys/net/if_lagg.c608
-rw-r--r--freebsd/sys/net/if_lagg.h36
-rw-r--r--freebsd/sys/net/if_llatbl.c2
-rw-r--r--freebsd/sys/net/if_media.c2
-rw-r--r--freebsd/sys/net/if_media.h12
-rw-r--r--freebsd/sys/net/if_var.h2
-rw-r--r--freebsd/sys/net/if_vlan.c115
-rw-r--r--freebsd/sys/net/iflib.h2
-rw-r--r--freebsd/sys/net/netisr.h1
-rw-r--r--freebsd/sys/net/route.h45
-rw-r--r--freebsd/sys/net/rtsock.c2
-rw-r--r--freebsd/sys/net/slcompress.c64
-rw-r--r--freebsd/sys/net80211/ieee80211_adhoc.c4
-rw-r--r--freebsd/sys/net80211/ieee80211_hostap.c4
-rw-r--r--freebsd/sys/net80211/ieee80211_ht.c142
-rw-r--r--freebsd/sys/net80211/ieee80211_ht.h3
-rw-r--r--freebsd/sys/net80211/ieee80211_input.h2
-rw-r--r--freebsd/sys/net80211/ieee80211_mesh.c2
-rw-r--r--freebsd/sys/net80211/ieee80211_proto.c14
-rw-r--r--freebsd/sys/net80211/ieee80211_proto.h4
-rw-r--r--freebsd/sys/net80211/ieee80211_radiotap.h116
-rw-r--r--freebsd/sys/net80211/ieee80211_sta.c4
-rw-r--r--freebsd/sys/net80211/ieee80211_wds.c4
-rw-r--r--freebsd/sys/netinet/in.c14
-rw-r--r--freebsd/sys/netinet/in_kdtrace.h1
-rw-r--r--freebsd/sys/netinet/in_mcast.c3
-rw-r--r--freebsd/sys/netinet/in_pcb.c20
-rw-r--r--freebsd/sys/netinet/in_pcb.h32
-rw-r--r--freebsd/sys/netinet/ip_divert.c18
-rw-r--r--freebsd/sys/netinet/ip_icmp.c28
-rw-r--r--freebsd/sys/netinet/ip_input.c8
-rw-r--r--freebsd/sys/netinet/libalias/alias.c4
-rw-r--r--freebsd/sys/netinet/raw_ip.c2
-rw-r--r--freebsd/sys/netinet/sctp_input.c19
-rw-r--r--freebsd/sys/netinet/sctp_os_bsd.h6
-rw-r--r--freebsd/sys/netinet/sctp_output.c4
-rw-r--r--freebsd/sys/netinet/sctp_pcb.c28
-rw-r--r--freebsd/sys/netinet/sctp_sysctl.c1
-rw-r--r--freebsd/sys/netinet/sctp_timer.c8
-rw-r--r--freebsd/sys/netinet/sctp_usrreq.c24
-rw-r--r--freebsd/sys/netinet/sctp_var.h2
-rw-r--r--freebsd/sys/netinet/sctputil.c94
-rw-r--r--freebsd/sys/netinet/sctputil.h5
-rw-r--r--freebsd/sys/netinet/tcp_input.c150
-rw-r--r--freebsd/sys/netinet/tcp_lro.c22
-rw-r--r--freebsd/sys/netinet/tcp_output.c10
-rw-r--r--freebsd/sys/netinet/tcp_reass.c2
-rw-r--r--freebsd/sys/netinet/tcp_subr.c2
-rw-r--r--freebsd/sys/netinet/tcp_syncache.c27
-rw-r--r--freebsd/sys/netinet/tcp_syncache.h1
-rw-r--r--freebsd/sys/netinet/tcp_usrreq.c9
-rw-r--r--freebsd/sys/netinet/tcp_var.h2
-rw-r--r--freebsd/sys/netinet/udp_usrreq.c16
-rw-r--r--freebsd/sys/netinet6/icmp6.c5
-rw-r--r--freebsd/sys/netinet6/in6_mcast.c3
-rw-r--r--freebsd/sys/netinet6/in6_pcb.c14
-rw-r--r--freebsd/sys/netinet6/ip6_output.c19
-rw-r--r--freebsd/sys/netinet6/raw_ip6.c4
-rw-r--r--freebsd/sys/netinet6/sctp6_usrreq.c10
-rw-r--r--freebsd/sys/netinet6/sctp6_var.h2
-rw-r--r--freebsd/sys/netinet6/udp6_usrreq.c13
-rw-r--r--freebsd/sys/netipsec/ipsec.h6
-rw-r--r--freebsd/sys/netipsec/ipsec_input.c8
-rw-r--r--freebsd/sys/netipsec/ipsec_mbuf.c4
-rw-r--r--freebsd/sys/netipsec/ipsec_output.c28
-rw-r--r--freebsd/sys/netipsec/ipsec_pcb.c8
-rw-r--r--freebsd/sys/netipsec/key.c6
-rw-r--r--freebsd/sys/netipsec/key_debug.c103
-rw-r--r--freebsd/sys/netipsec/key_debug.h4
-rw-r--r--freebsd/sys/netipsec/xform_ah.c33
-rw-r--r--freebsd/sys/netipsec/xform_esp.c33
-rw-r--r--freebsd/sys/netipsec/xform_ipcomp.c28
-rw-r--r--freebsd/sys/netpfil/pf/pf_if.c36
-rw-r--r--freebsd/sys/netpfil/pf/pf_ioctl.c35
-rw-r--r--freebsd/sys/netpfil/pf/pf_norm.c4
-rw-r--r--freebsd/sys/netpfil/pf/pf_table.c53
-rw-r--r--freebsd/sys/opencrypto/criov.c4
-rw-r--r--freebsd/sys/opencrypto/cryptodev.h24
-rw-r--r--freebsd/sys/opencrypto/cryptosoft.c5
-rw-r--r--freebsd/sys/sys/ata.h2
-rw-r--r--freebsd/sys/sys/conf.h1
-rw-r--r--freebsd/sys/sys/interrupt.h6
-rw-r--r--freebsd/sys/sys/kobj.h6
-rw-r--r--freebsd/sys/sys/libkern.h8
-rw-r--r--freebsd/sys/sys/mbuf.h4
-rw-r--r--freebsd/sys/sys/mount.h35
-rw-r--r--freebsd/sys/sys/pcpu.h5
-rw-r--r--freebsd/sys/sys/proc.h9
-rw-r--r--freebsd/sys/sys/random.h6
-rw-r--r--freebsd/sys/sys/smp.h2
-rw-r--r--freebsd/sys/sys/sysproto.h279
-rw-r--r--freebsd/sys/sys/tty.h2
-rw-r--r--freebsd/sys/sys/user.h79
-rw-r--r--freebsd/sys/sys/vmmeter.h142
-rw-r--r--freebsd/sys/sys/vnode.h12
-rw-r--r--freebsd/sys/vm/uma_core.c3
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;