From 7eeb079d84bc4abe9897be0047fc28a754e46ecd Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 2 Feb 2015 14:27:13 +0100 Subject: Update to FreeBSD 9.3 --- freebsd-org | 2 +- freebsd/include/rpc/auth.h | 49 +- freebsd/include/rpc/auth_des.h | 53 +- freebsd/include/rpc/auth_unix.h | 49 +- freebsd/include/rpc/clnt.h | 69 +- freebsd/include/rpc/clnt_soc.h | 53 +- freebsd/include/rpc/pmap_clnt.h | 49 +- freebsd/include/rpc/pmap_prot.h | 49 +- freebsd/include/rpc/rpc.h | 49 +- freebsd/include/rpc/rpc_msg.h | 49 +- freebsd/include/rpc/rpcb_clnt.h | 53 +- freebsd/include/rpc/rpcb_prot.x | 49 +- freebsd/include/rpc/rpcent.h | 53 +- freebsd/include/rpc/svc.h | 49 +- freebsd/include/rpc/svc_auth.h | 49 +- freebsd/include/rpc/svc_soc.h | 53 +- freebsd/include/rpc/xdr.h | 49 +- freebsd/lib/libc/net/getaddrinfo.c | 111 +- freebsd/lib/libipsec/ipsec_dump_policy.c | 1 + freebsd/sbin/ifconfig/af_inet.c | 4 +- freebsd/sbin/ifconfig/ifgroup.c | 4 +- freebsd/sbin/route/keywords | 2 + freebsd/sbin/route/route.c | 24 +- freebsd/sys/cam/ata/ata_all.h | 2 + freebsd/sys/cam/cam.h | 4 +- freebsd/sys/cam/cam_ccb.h | 17 +- freebsd/sys/cam/cam_debug.h | 17 +- freebsd/sys/cam/cam_periph.h | 3 +- freebsd/sys/cam/cam_xpt.h | 4 + freebsd/sys/cam/cam_xpt_sim.h | 4 - freebsd/sys/cam/scsi/scsi_all.c | 32 +- freebsd/sys/cam/scsi/scsi_all.h | 4 + freebsd/sys/cam/scsi/scsi_da.h | 32 + freebsd/sys/contrib/pf/net/pf_lb.c | 53 +- freebsd/sys/dev/bce/if_bce.c | 28 +- freebsd/sys/dev/bce/if_bcefw.h | 8 +- freebsd/sys/dev/bce/if_bcereg.h | 10 +- freebsd/sys/dev/bge/if_bge.c | 217 +++- freebsd/sys/dev/bge/if_bgereg.h | 25 +- freebsd/sys/dev/e1000/e1000_defines.h | 2 +- freebsd/sys/dev/e1000/if_em.c | 9 +- freebsd/sys/dev/e1000/if_igb.c | 14 +- freebsd/sys/dev/e1000/if_lem.c | 10 +- freebsd/sys/dev/fxp/if_fxpreg.h | 2 +- freebsd/sys/dev/mii/brgphy.c | 3 + freebsd/sys/dev/pci/pci.c | 283 +++-- freebsd/sys/dev/pci/pci_pci.c | 508 +++++++-- freebsd/sys/dev/pci/pci_private.h | 2 + freebsd/sys/dev/pci/pci_user.c | 128 ++- freebsd/sys/dev/pci/pcib_private.h | 3 +- freebsd/sys/dev/pci/pcireg.h | 9 + freebsd/sys/dev/pci/pcivar.h | 9 + freebsd/sys/dev/re/if_re.c | 84 +- freebsd/sys/dev/usb/controller/ehci.c | 112 +- freebsd/sys/dev/usb/controller/ohci.c | 5 +- freebsd/sys/dev/usb/controller/usb_controller.c | 67 +- freebsd/sys/dev/usb/controller/xhcireg.h | 3 +- freebsd/sys/dev/usb/quirk/usb_quirk.c | 11 + freebsd/sys/dev/usb/storage/umass.c | 4 +- freebsd/sys/dev/usb/usb.h | 3 + freebsd/sys/dev/usb/usb_bus.h | 1 + freebsd/sys/dev/usb/usb_busdma.c | 27 +- freebsd/sys/dev/usb/usb_controller.h | 1 + freebsd/sys/dev/usb/usb_core.h | 2 + freebsd/sys/dev/usb/usb_dev.c | 254 ++++- freebsd/sys/dev/usb/usb_device.c | 116 ++- freebsd/sys/dev/usb/usb_device.h | 17 +- freebsd/sys/dev/usb/usb_freebsd.h | 3 + freebsd/sys/dev/usb/usb_generic.c | 84 +- freebsd/sys/dev/usb/usb_hub.c | 395 ++++++- freebsd/sys/dev/usb/usb_hub.h | 7 + freebsd/sys/dev/usb/usb_ioctl.h | 64 +- freebsd/sys/dev/usb/usb_msctest.c | 74 +- freebsd/sys/dev/usb/usb_process.c | 12 + freebsd/sys/dev/usb/usb_process.h | 1 + freebsd/sys/dev/usb/usb_request.c | 80 +- freebsd/sys/dev/usb/usb_transfer.c | 59 +- freebsd/sys/dev/usb/usbdi.h | 3 + freebsd/sys/i386/include/machine/specialreg.h | 6 + freebsd/sys/kern/init_main.c | 16 +- freebsd/sys/kern/kern_event.c | 131 ++- freebsd/sys/kern/kern_linker.c | 197 ++-- freebsd/sys/kern/kern_mbuf.c | 137 ++- freebsd/sys/kern/kern_mib.c | 7 + freebsd/sys/kern/kern_time.c | 242 ++++- freebsd/sys/kern/kern_timeout.c | 16 +- freebsd/sys/kern/subr_lock.c | 4 +- freebsd/sys/kern/subr_rman.c | 31 +- freebsd/sys/kern/subr_sbuf.c | 5 +- freebsd/sys/kern/subr_taskqueue.c | 36 +- freebsd/sys/kern/sys_generic.c | 4 + freebsd/sys/kern/uipc_sockbuf.c | 78 +- freebsd/sys/kern/uipc_socket.c | 59 +- freebsd/sys/kern/uipc_syscalls.c | 61 +- freebsd/sys/kern/uipc_usrreq.c | 19 +- freebsd/sys/mips/include/machine/cpufunc.h | 2 +- freebsd/sys/net/ieee8023ad_lacp.c | 41 +- freebsd/sys/net/if.c | 4 +- freebsd/sys/net/if_lagg.c | 19 +- freebsd/sys/net/if_media.h | 5 +- freebsd/sys/net/if_spppsubr.c | 2 +- freebsd/sys/net/if_tap.c | 6 +- freebsd/sys/net/if_tun.c | 1 + freebsd/sys/net/if_vlan.c | 2 + freebsd/sys/net/radix.c | 415 ++++---- freebsd/sys/net/radix.h | 6 +- freebsd/sys/net/radix_mpath.c | 86 +- freebsd/sys/net/route.c | 167 ++- freebsd/sys/net/route.h | 9 +- freebsd/sys/net/rtsock.c | 198 ++-- freebsd/sys/net80211/ieee80211.h | 1 + freebsd/sys/net80211/ieee80211_proto.h | 3 + freebsd/sys/netinet/if_ether.c | 8 +- freebsd/sys/netinet/in.c | 52 +- freebsd/sys/netinet/in_mcast.c | 30 +- freebsd/sys/netinet/in_pcb.c | 2 +- freebsd/sys/netinet/ip_icmp.c | 1 + freebsd/sys/netinet/ip_input.c | 5 +- freebsd/sys/netinet/ip_mroute.c | 20 +- freebsd/sys/netinet/ip_output.c | 16 +- freebsd/sys/netinet/sctp.h | 79 +- freebsd/sys/netinet/sctp_asconf.c | 92 +- freebsd/sys/netinet/sctp_auth.c | 137 +-- freebsd/sys/netinet/sctp_auth.h | 15 +- freebsd/sys/netinet/sctp_bsd_addr.c | 13 +- freebsd/sys/netinet/sctp_constants.h | 16 +- freebsd/sys/netinet/sctp_dtrace_define.h | 261 ++--- freebsd/sys/netinet/sctp_indata.c | 725 ++++--------- freebsd/sys/netinet/sctp_input.c | 128 ++- freebsd/sys/netinet/sctp_os_bsd.h | 26 +- freebsd/sys/netinet/sctp_output.c | 302 ++++-- freebsd/sys/netinet/sctp_pcb.c | 229 ++-- freebsd/sys/netinet/sctp_pcb.h | 2 +- freebsd/sys/netinet/sctp_structs.h | 4 +- freebsd/sys/netinet/sctp_sysctl.c | 17 +- freebsd/sys/netinet/sctp_sysctl.h | 8 +- freebsd/sys/netinet/sctp_timer.c | 48 +- freebsd/sys/netinet/sctp_uio.h | 4 - freebsd/sys/netinet/sctp_usrreq.c | 176 ++-- freebsd/sys/netinet/sctputil.c | 138 ++- freebsd/sys/netinet/sctputil.h | 4 +- freebsd/sys/netinet/tcp_input.c | 6 +- freebsd/sys/netinet/tcp_reass.c | 7 +- freebsd/sys/netinet/tcp_subr.c | 6 +- freebsd/sys/netinet6/frag6.c | 5 +- freebsd/sys/netinet6/icmp6.c | 1 + freebsd/sys/netinet6/in6.c | 1 + freebsd/sys/netinet6/in6_mcast.c | 69 +- freebsd/sys/netinet6/in6_pcb.c | 2 +- freebsd/sys/netinet6/ip6_forward.c | 7 +- freebsd/sys/netinet6/ip6_input.c | 16 +- freebsd/sys/netinet6/ip6_mroute.c | 596 +++++------ freebsd/sys/netinet6/ip6_mroute.h | 5 - freebsd/sys/netinet6/nd6.c | 17 +- freebsd/sys/netinet6/nd6_nbr.c | 4 +- freebsd/sys/netinet6/sctp6_usrreq.c | 4 +- freebsd/sys/netpfil/ipfw/ip_dummynet.c | 2 +- freebsd/sys/netpfil/ipfw/ip_fw2.c | 39 +- freebsd/sys/netpfil/ipfw/ip_fw_log.c | 11 +- freebsd/sys/netpfil/ipfw/ip_fw_nat.c | 76 +- freebsd/sys/netpfil/ipfw/ip_fw_private.h | 24 +- freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c | 14 +- freebsd/sys/netpfil/ipfw/ip_fw_table.c | 8 +- freebsd/sys/opencrypto/deflate.c | 8 +- freebsd/sys/pci/if_rlreg.h | 29 +- freebsd/sys/rpc/types.h | 51 +- freebsd/sys/sys/_rmlock.h | 5 +- freebsd/sys/sys/_rwlock.h | 3 - freebsd/sys/sys/ata.h | 7 + freebsd/sys/sys/bus_dma.h | 7 - freebsd/sys/sys/conf.h | 1 + freebsd/sys/sys/eventhandler.h | 18 + freebsd/sys/sys/eventvar.h | 2 +- freebsd/sys/sys/kernel.h | 4 +- freebsd/sys/sys/linker.h | 4 - freebsd/sys/sys/lockmgr.h | 1 + freebsd/sys/sys/mbuf.h | 23 +- freebsd/sys/sys/mman.h | 11 + freebsd/sys/sys/pciio.h | 21 + freebsd/sys/sys/proc.h | 10 +- freebsd/sys/sys/refcount.h | 3 - freebsd/sys/sys/rmlock.h | 22 + freebsd/sys/sys/rwlock.h | 3 - freebsd/sys/sys/sdt.h | 420 +++++--- freebsd/sys/sys/sockbuf.h | 2 + freebsd/sys/sys/sysctl.h | 1 + freebsd/sys/sys/sysproto.h | 20 +- freebsd/sys/sys/systm.h | 2 + freebsd/sys/sys/taskqueue.h | 1 + freebsd/sys/sys/tty.h | 2 + freebsd/sys/sys/user.h | 11 +- freebsd/sys/vm/uma_core.c | 11 +- freebsd/sys/vm/vm.h | 1 + freebsd/sys/vm/vm_extern.h | 4 +- freebsd/usr.bin/netstat/main.c | 32 +- rtemsbsd/include/rtems/bsd/local/miidevs.h | 5 + rtemsbsd/include/rtems/bsd/local/usbdevs.h | 247 ++++- rtemsbsd/include/rtems/bsd/local/usbdevs_data.h | 1268 ++++++++++++++++++++++- rtemsbsd/include/rtems/bsd/sys/param.h | 2 +- rtemsbsd/rtems/rtems-bsd-mutex.c | 1 + rtemsbsd/rtems/rtems-bsd-thread.c | 2 +- 201 files changed, 7721 insertions(+), 3941 deletions(-) diff --git a/freebsd-org b/freebsd-org index 74d8320d..a5feb686 160000 --- a/freebsd-org +++ b/freebsd-org @@ -1 +1 @@ -Subproject commit 74d8320d56de778817fa39bc074b177c93945481 +Subproject commit a5feb686027eafe7ae45360846ff5ae4cd64fed7 diff --git a/freebsd/include/rpc/auth.h b/freebsd/include/rpc/auth.h index b19addc8..5503762b 100644 --- a/freebsd/include/rpc/auth.h +++ b/freebsd/include/rpc/auth.h @@ -1,32 +1,31 @@ /* $NetBSD: auth.h,v 1.15 2000/06/02 22:57:55 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * from: @(#)auth.h 1.17 88/02/08 SMI * from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC diff --git a/freebsd/include/rpc/auth_des.h b/freebsd/include/rpc/auth_des.h index fff4ebfe..58b34d77 100644 --- a/freebsd/include/rpc/auth_des.h +++ b/freebsd/include/rpc/auth_des.h @@ -1,32 +1,31 @@ /* @(#)auth_des.h 2.2 88/07/29 4.0 RPCSRC; from 1.3 88/02/08 SMI */ /* $FreeBSD$ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * from: @(#)auth_des.h 2.2 88/07/29 4.0 RPCSRC * from: @(#)auth_des.h 1.14 94/04/25 SMI diff --git a/freebsd/include/rpc/auth_unix.h b/freebsd/include/rpc/auth_unix.h index b005bac8..fa47e8ba 100644 --- a/freebsd/include/rpc/auth_unix.h +++ b/freebsd/include/rpc/auth_unix.h @@ -1,30 +1,29 @@ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * from: @(#)auth_unix.h 1.8 88/02/08 SMI * from: @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC diff --git a/freebsd/include/rpc/clnt.h b/freebsd/include/rpc/clnt.h index 1c85a4a7..66533e24 100644 --- a/freebsd/include/rpc/clnt.h +++ b/freebsd/include/rpc/clnt.h @@ -1,49 +1,31 @@ /* $NetBSD: clnt.h,v 1.14 2000/06/02 22:57:55 fvdl Exp $ */ -/* - * The contents of this file are subject to the Sun Standards - * License Version 1.0 the (the "License";) You may not use - * this file except in compliance with the License. You may - * obtain a copy of the License at lib/libc/rpc/LICENSE - * - * Software distributed under the License is distributed on - * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either - * express or implied. See the License for the specific - * language governing rights and limitations under the License. - * - * The Original Code is Copyright 1998 by Sun Microsystems, Inc - * - * The Initial Developer of the Original Code is: Sun - * Microsystems, Inc. - * - * All Rights Reserved. - * - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. +/*- + * Copyright (c) 2010, Oracle America, Inc. + * All rights reserved. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the "Oracle America, Inc." nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * from: @(#)clnt.h 1.31 94/04/29 SMI * from: @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC @@ -52,9 +34,6 @@ /* * clnt.h - Client side remote procedure call interface. - * - * Copyright (c) 1986-1991,1994-1999 by Sun Microsystems, Inc. - * All rights reserved. */ #ifndef _RPC_CLNT_H_ diff --git a/freebsd/include/rpc/clnt_soc.h b/freebsd/include/rpc/clnt_soc.h index 1e7a0dea..6536a4bb 100644 --- a/freebsd/include/rpc/clnt_soc.h +++ b/freebsd/include/rpc/clnt_soc.h @@ -1,33 +1,32 @@ /* $NetBSD: clnt_soc.h,v 1.1 2000/06/02 22:57:55 fvdl Exp $ */ /* $FreeBSD$ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /* * Copyright (c) 1984 - 1991 by Sun Microsystems, Inc. diff --git a/freebsd/include/rpc/pmap_clnt.h b/freebsd/include/rpc/pmap_clnt.h index 89f1614a..e8314f60 100644 --- a/freebsd/include/rpc/pmap_clnt.h +++ b/freebsd/include/rpc/pmap_clnt.h @@ -1,32 +1,31 @@ /* $NetBSD: pmap_clnt.h,v 1.9 2000/06/02 22:57:55 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * from: @(#)pmap_clnt.h 1.11 88/02/08 SMI * from: @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC diff --git a/freebsd/include/rpc/pmap_prot.h b/freebsd/include/rpc/pmap_prot.h index 366832a7..d880c40d 100644 --- a/freebsd/include/rpc/pmap_prot.h +++ b/freebsd/include/rpc/pmap_prot.h @@ -1,32 +1,31 @@ /* $NetBSD: pmap_prot.h,v 1.8 2000/06/02 22:57:55 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * from: @(#)pmap_prot.h 1.14 88/02/08 SMI * from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC diff --git a/freebsd/include/rpc/rpc.h b/freebsd/include/rpc/rpc.h index 725b542a..e7a3dc8d 100644 --- a/freebsd/include/rpc/rpc.h +++ b/freebsd/include/rpc/rpc.h @@ -1,32 +1,31 @@ /* $NetBSD: rpc.h,v 1.13 2000/06/02 22:57:56 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * from: @(#)rpc.h 1.9 88/02/08 SMI * from: @(#)rpc.h 2.4 89/07/11 4.0 RPCSRC diff --git a/freebsd/include/rpc/rpc_msg.h b/freebsd/include/rpc/rpc_msg.h index 354b3414..6e8d0745 100644 --- a/freebsd/include/rpc/rpc_msg.h +++ b/freebsd/include/rpc/rpc_msg.h @@ -1,32 +1,31 @@ /* $NetBSD: rpc_msg.h,v 1.11 2000/06/02 22:57:56 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * from: @(#)rpc_msg.h 1.7 86/07/16 SMI * from: @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC diff --git a/freebsd/include/rpc/rpcb_clnt.h b/freebsd/include/rpc/rpcb_clnt.h index fa64a853..45527872 100644 --- a/freebsd/include/rpc/rpcb_clnt.h +++ b/freebsd/include/rpc/rpcb_clnt.h @@ -1,33 +1,32 @@ /* $NetBSD: rpcb_clnt.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $ */ /* $FreeBSD$ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /* * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. diff --git a/freebsd/include/rpc/rpcb_prot.x b/freebsd/include/rpc/rpcb_prot.x index c5748413..a34bcc12 100644 --- a/freebsd/include/rpc/rpcb_prot.x +++ b/freebsd/include/rpc/rpcb_prot.x @@ -1,32 +1,31 @@ -%/* +%/*- % * $FreeBSD$ % * -% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for -% * unrestricted use provided that this legend is included on all tape -% * media and as a part of the software program in whole or part. Users -% * may copy or modify Sun RPC without charge, but are not authorized -% * to license or distribute it to anyone else except as part of a product or -% * program developed by the user. -% * -% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE -% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR -% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. -% * -% * Sun RPC is provided with no support and without any obligation on the -% * part of Sun Microsystems, Inc. to assist in its use, correction, -% * modification or enhancement. -% * -% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE -% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC -% * OR ANY PART THEREOF. +% * Copyright (c) 2009, Sun Microsystems, Inc. +% * All rights reserved. % * -% * In no event will Sun Microsystems, Inc. be liable for any lost revenue -% * or profits or other special, indirect and consequential damages, even if -% * Sun has been advised of the possibility of such damages. +% * Redistribution and use in source and binary forms, with or without +% * modification, are permitted provided that the following conditions are met: +% * - Redistributions of source code must retain the above copyright notice, +% * this list of conditions and the following disclaimer. +% * - Redistributions in binary form must reproduce the above copyright notice, +% * this list of conditions and the following disclaimer in the documentation +% * and/or other materials provided with the distribution. +% * - Neither the name of Sun Microsystems, Inc. nor the names of its +% * contributors may be used to endorse or promote products derived +% * from this software without specific prior written permission. % * -% * Sun Microsystems, Inc. -% * 2550 Garcia Avenue -% * Mountain View, California 94043 +% * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +% * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +% * POSSIBILITY OF SUCH DAMAGE. % */ %/* % * Copyright (c) 1988 by Sun Microsystems, Inc. diff --git a/freebsd/include/rpc/rpcent.h b/freebsd/include/rpc/rpcent.h index 876b488b..405ba678 100644 --- a/freebsd/include/rpc/rpcent.h +++ b/freebsd/include/rpc/rpcent.h @@ -1,33 +1,32 @@ /* $NetBSD: rpcent.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $ */ /* $FreeBSD$ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /* * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. diff --git a/freebsd/include/rpc/svc.h b/freebsd/include/rpc/svc.h index 8466ef8b..2af5550f 100644 --- a/freebsd/include/rpc/svc.h +++ b/freebsd/include/rpc/svc.h @@ -1,32 +1,31 @@ /* $NetBSD: svc.h,v 1.17 2000/06/02 22:57:56 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * from: @(#)svc.h 1.35 88/12/17 SMI * from: @(#)svc.h 1.27 94/04/25 SMI diff --git a/freebsd/include/rpc/svc_auth.h b/freebsd/include/rpc/svc_auth.h index 41fc82b0..87b8efe7 100644 --- a/freebsd/include/rpc/svc_auth.h +++ b/freebsd/include/rpc/svc_auth.h @@ -1,32 +1,31 @@ /* $NetBSD: svc_auth.h,v 1.8 2000/06/02 22:57:57 fvdl Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * from: @(#)svc_auth.h 1.6 86/07/16 SMI * @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC diff --git a/freebsd/include/rpc/svc_soc.h b/freebsd/include/rpc/svc_soc.h index 6c528dbc..311c8322 100644 --- a/freebsd/include/rpc/svc_soc.h +++ b/freebsd/include/rpc/svc_soc.h @@ -1,33 +1,32 @@ /* $NetBSD: svc_soc.h,v 1.1 2000/06/02 22:57:57 fvdl Exp $ */ /* $FreeBSD$ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /* * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. diff --git a/freebsd/include/rpc/xdr.h b/freebsd/include/rpc/xdr.h index ada5c5bd..9456f70c 100644 --- a/freebsd/include/rpc/xdr.h +++ b/freebsd/include/rpc/xdr.h @@ -1,32 +1,31 @@ /* $NetBSD: xdr.h,v 1.19 2000/07/17 05:00:45 matt Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * from: @(#)xdr.h 1.19 87/04/22 SMI * from: @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC diff --git a/freebsd/lib/libc/net/getaddrinfo.c b/freebsd/lib/libc/net/getaddrinfo.c index 5c1965b6..fbffd6b0 100644 --- a/freebsd/lib/libc/net/getaddrinfo.c +++ b/freebsd/lib/libc/net/getaddrinfo.c @@ -64,12 +64,15 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #ifdef INET6 #include #include #include -#include /* XXX */ +#include +#include #endif #include #include @@ -246,6 +249,9 @@ static int get_portmatch(const struct addrinfo *, const char *); static int get_port(struct addrinfo *, const char *, int); static const struct afd *find_afd(int); static int addrconfig(struct addrinfo *); +#ifdef INET6 +static int is_ifdisabled(char *); +#endif static void set_source(struct ai_order *, struct policyhead *); static int comp_dst(const void *, const void *); #ifdef INET6 @@ -1003,7 +1009,8 @@ comp_dst(const void *arg1, const void *arg2) * We compare the match length in a same AF only. */ if (dst1->aio_ai->ai_addr->sa_family == - dst2->aio_ai->ai_addr->sa_family) { + dst2->aio_ai->ai_addr->sa_family && + dst1->aio_ai->ai_addr->sa_family != AF_INET) { if (dst1->aio_matchlen > dst2->aio_matchlen) { return(-1); } @@ -1522,10 +1529,11 @@ find_afd(int af) } /* - * post-2553: AI_ADDRCONFIG check. if we use getipnodeby* as backend, backend - * will take care of it. - * the semantics of AI_ADDRCONFIG is not defined well. we are not sure - * if the code is right or not. + * RFC 3493: AI_ADDRCONFIG check. Determines which address families are + * configured on the local system and correlates with pai->ai_family value. + * If an address family is not configured on the system, it will not be + * queried for. For this purpose, loopback addresses are not considered + * configured addresses. * * XXX PF_UNSPEC -> PF_INET6 + PF_INET mapping needs to be in sync with * _dns_getaddrinfo. @@ -1533,37 +1541,80 @@ find_afd(int af) static int addrconfig(struct addrinfo *pai) { - int s, af; + struct ifaddrs *ifaddrs, *ifa; + struct sockaddr_in *sin; +#ifdef INET6 + struct sockaddr_in6 *sin6; +#endif + int seen_inet = 0, seen_inet6 = 0; - /* - * TODO: - * Note that implementation dependent test for address - * configuration should be done everytime called - * (or apropriate interval), - * because addresses will be dynamically assigned or deleted. - */ - af = pai->ai_family; - if (af == AF_UNSPEC) { - if ((s = _socket(AF_INET6, SOCK_DGRAM, 0)) < 0) - af = AF_INET; - else { - _close(s); - if ((s = _socket(AF_INET, SOCK_DGRAM, 0)) < 0) - af = AF_INET6; - else - _close(s); + if (getifaddrs(&ifaddrs) != 0) + return (0); + + for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL || (ifa->ifa_flags & IFF_UP) == 0) + continue; + switch (ifa->ifa_addr->sa_family) { + case AF_INET: + if (seen_inet) + continue; + sin = (struct sockaddr_in *)(ifa->ifa_addr); + if (IN_LOOPBACK(htonl(sin->sin_addr.s_addr))) + continue; + seen_inet = 1; + break; +#ifdef INET6 + case AF_INET6: + if (seen_inet6) + continue; + sin6 = (struct sockaddr_in6 *)(ifa->ifa_addr); + if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) + continue; + if ((ifa->ifa_flags & IFT_LOOP) != 0 && + IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + continue; + if (is_ifdisabled(ifa->ifa_name)) + continue; + seen_inet6 = 1; + break; +#endif } } - if (af != AF_UNSPEC) { - if ((s = _socket(af, SOCK_DGRAM, 0)) < 0) - return 0; - _close(s); + freeifaddrs(ifaddrs); + + switch(pai->ai_family) { + case AF_INET6: + return (seen_inet6); + case AF_INET: + return (seen_inet); + case AF_UNSPEC: + if (seen_inet == seen_inet6) + return (seen_inet); + pai->ai_family = seen_inet ? AF_INET : AF_INET6; + return (1); } - pai->ai_family = af; - return 1; + return (1); } #ifdef INET6 +static int +is_ifdisabled(char *name) +{ + struct in6_ndireq nd; + int fd; + + if ((fd = _socket(AF_INET6, SOCK_DGRAM, 0)) < 0) + return (-1); + memset(&nd, 0, sizeof(nd)); + strlcpy(nd.ifname, name, sizeof(nd.ifname)); + if (_ioctl(fd, SIOCGIFINFO_IN6, &nd) < 0) { + _close(fd); + return (-1); + } + _close(fd); + return ((nd.ndi.flags & ND6_IFF_IFDISABLED) != 0); +} + /* convert a string to a scope identifier. XXX: IPv6 specific */ static int ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid) diff --git a/freebsd/lib/libipsec/ipsec_dump_policy.c b/freebsd/lib/libipsec/ipsec_dump_policy.c index 33d4bb13..a12727bc 100644 --- a/freebsd/lib/libipsec/ipsec_dump_policy.c +++ b/freebsd/lib/libipsec/ipsec_dump_policy.c @@ -201,6 +201,7 @@ ipsec_dump_ipsecrequest(buf, len, xisr, bound) break; case IPPROTO_TCP: proto = "tcp"; + break; default: __ipsec_errcode = EIPSEC_INVAL_PROTO; return NULL; diff --git a/freebsd/sbin/ifconfig/af_inet.c b/freebsd/sbin/ifconfig/af_inet.c index 0e6ace11..3e9ac8ea 100644 --- a/freebsd/sbin/ifconfig/af_inet.c +++ b/freebsd/sbin/ifconfig/af_inet.c @@ -106,8 +106,7 @@ in_getaddr(const char *s, int which) struct netent *np; sin->sin_len = sizeof(*sin); - if (which != MASK) - sin->sin_family = AF_INET; + sin->sin_family = AF_INET; if (which == ADDR) { char *p = NULL; @@ -126,6 +125,7 @@ in_getaddr(const char *s, int which) *p = '/'; errx(1, "%s: bad value (width %s)", s, errstr); } + min->sin_family = AF_INET; min->sin_len = sizeof(*min); min->sin_addr.s_addr = htonl(~((1LL << (32 - masklen)) - 1) & 0xffffffff); diff --git a/freebsd/sbin/ifconfig/ifgroup.c b/freebsd/sbin/ifconfig/ifgroup.c index daffb3b0..c8dae3b9 100644 --- a/freebsd/sbin/ifconfig/ifgroup.c +++ b/freebsd/sbin/ifconfig/ifgroup.c @@ -62,7 +62,7 @@ setifgroup(const char *group_name, int d, int s, const struct afswtch *rafp) if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ) errx(1, "setifgroup: group name too long"); - if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) == -1) + if (ioctl(s, SIOCAIFGROUP, (caddr_t)&ifgr) == -1 && errno != EEXIST) err(1," SIOCAIFGROUP"); } @@ -80,7 +80,7 @@ unsetifgroup(const char *group_name, int d, int s, const struct afswtch *rafp) if (strlcpy(ifgr.ifgr_group, group_name, IFNAMSIZ) >= IFNAMSIZ) errx(1, "unsetifgroup: group name too long"); - if (ioctl(s, SIOCDIFGROUP, (caddr_t)&ifgr) == -1) + if (ioctl(s, SIOCDIFGROUP, (caddr_t)&ifgr) == -1 && errno != ENOENT) err(1, "SIOCDIFGROUP"); } diff --git a/freebsd/sbin/route/keywords b/freebsd/sbin/route/keywords index adfba7cf..676f781d 100644 --- a/freebsd/sbin/route/keywords +++ b/freebsd/sbin/route/keywords @@ -1,6 +1,8 @@ # @(#)keywords 8.2 (Berkeley) 3/19/94 # $FreeBSD$ +4 +6 add atalk blackhole diff --git a/freebsd/sbin/route/route.c b/freebsd/sbin/route/route.c index 158445d8..05b4f5a3 100644 --- a/freebsd/sbin/route/route.c +++ b/freebsd/sbin/route/route.c @@ -177,7 +177,7 @@ usage(const char *cp) if (cp != NULL) warnx("bad keyword: %s", cp); (void) fprintf(stderr, - "usage: route [-dnqtv] command [[modifiers] args]\n"); + "usage: route [-46dnqtv] command [[modifiers] args]\n"); exit(EX_USAGE); /* NOTREACHED */ } @@ -263,8 +263,24 @@ main(int argc, char **argv) if (argc < 2) usage(NULL); - while ((ch = getopt(argc, argv, "nqdtv")) != -1) + while ((ch = getopt(argc, argv, "46nqdtv")) != -1) switch(ch) { + case '4': +#ifdef INET + c->af = AF_INET; + c->aflen = sizeof(struct sockaddr_in); +#else + errx(1, "IPv4 support is not compiled in"); +#endif + break; + case '6': +#ifdef INET6 + c->af = AF_INET6; + c->aflen = sizeof(struct sockaddr_in6); +#else + errx(1, "IPv6 support is not compiled in"); +#endif + break; case 'n': c->nflag = 1; break; @@ -485,10 +501,12 @@ flushroutes(struct rt_ctx *c, int argc, char *argv[]) if (**argv != '-') usage(*argv); switch (keyword(*argv + 1)) { + case K_4: case K_INET: c->af = AF_INET; break; #ifdef INET6 + case K_6: case K_INET6: c->af = AF_INET6; break; @@ -903,11 +921,13 @@ newroute(struct rt_ctx *c, int argc, char **argv) c->af = AF_LINK; c->aflen = sizeof(struct sockaddr_dl); break; + case K_4: case K_INET: c->af = AF_INET; c->aflen = sizeof(struct sockaddr_in); break; #ifdef INET6 + case K_6: case K_INET6: c->af = AF_INET6; c->aflen = sizeof(struct sockaddr_in6); diff --git a/freebsd/sys/cam/ata/ata_all.h b/freebsd/sys/cam/ata/ata_all.h index 25732b60..91e941c8 100644 --- a/freebsd/sys/cam/ata/ata_all.h +++ b/freebsd/sys/cam/ata/ata_all.h @@ -109,6 +109,7 @@ int ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb); int ata_res_sbuf(struct ccb_ataio *ataio, struct sbuf *sb); void ata_print_ident(struct ata_params *ident_data); +void ata_print_ident_short(struct ata_params *ident_data); uint32_t ata_logical_sector_size(struct ata_params *ident_data); uint64_t ata_physical_sector_size(struct ata_params *ident_data); @@ -143,6 +144,7 @@ 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_short(struct sep_identify_data *ident_data); 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/cam.h b/freebsd/sys/cam/cam.h index af57f1a6..499fffa3 100644 --- a/freebsd/sys/cam/cam.h +++ b/freebsd/sys/cam/cam.h @@ -84,15 +84,15 @@ typedef struct { #define CAM_PRIORITY_BUS ((CAM_RL_BUS << 8) + 0x80) #define CAM_PRIORITY_XPT ((CAM_RL_XPT << 8) + 0x80) #define CAM_PRIORITY_DEV ((CAM_RL_DEV << 8) + 0x80) +#define CAM_PRIORITY_OOB (CAM_RL_DEV << 8) #define CAM_PRIORITY_NORMAL ((CAM_RL_NORMAL << 8) + 0x80) #define CAM_PRIORITY_NONE (u_int32_t)-1 -#define CAM_PRIORITY_TO_RL(x) ((x) >> 8) -#define CAM_RL_TO_PRIORITY(x) ((x) << 8) u_int32_t generation; int index; #define CAM_UNQUEUED_INDEX -1 #define CAM_ACTIVE_INDEX -2 #define CAM_DONEQ_INDEX -3 +#define CAM_EXTRAQ_INDEX INT_MAX } cam_pinfo; /* diff --git a/freebsd/sys/cam/cam_ccb.h b/freebsd/sys/cam/cam_ccb.h index 893c6469..4222de9d 100644 --- a/freebsd/sys/cam/cam_ccb.h +++ b/freebsd/sys/cam/cam_ccb.h @@ -154,8 +154,6 @@ typedef enum { /* Path statistics (error counts, etc.) */ XPT_GDEV_STATS = 0x0c, /* Device statistics (error counts, etc.) */ - XPT_FREEZE_QUEUE = 0x0d, - /* Freeze device queue */ XPT_DEV_ADVINFO = 0x0e, /* Get/Set Device advanced information */ /* SCSI Control Functions: 0x10->0x1F */ @@ -592,6 +590,7 @@ typedef enum { PIM_NO_6_BYTE = 0x08, /* Do not send 6-byte commands */ PIM_SEQSCAN = 0x04, /* Do bus scans sequentially, not in parallel */ PIM_UNMAPPED = 0x02, + PIM_NOSCAN = 0x01 /* SIM does its own scanning */ } pi_miscflag; /* Path Inquiry CCB */ @@ -774,7 +773,6 @@ struct ccb_relsim { #define RELSIM_RELEASE_AFTER_TIMEOUT 0x02 #define RELSIM_RELEASE_AFTER_CMDCMPLT 0x04 #define RELSIM_RELEASE_AFTER_QEMPTY 0x08 -#define RELSIM_RELEASE_RUNLEVEL 0x10 u_int32_t openings; u_int32_t release_timeout; /* Abstract argument. */ u_int32_t qfrozen_cnt; @@ -1328,6 +1326,19 @@ cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retries, smpio->smp_response_len = smp_response_len; } +static __inline void +cam_set_ccbstatus(union ccb *ccb, cam_status status) +{ + ccb->ccb_h.status &= ~CAM_STATUS_MASK; + ccb->ccb_h.status |= status; +} + +static __inline cam_status +cam_ccb_status(union ccb *ccb) +{ + return ((cam_status)(ccb->ccb_h.status & CAM_STATUS_MASK)); +} + void cam_calc_geometry(struct ccb_calc_geometry *ccg, int extended); __END_DECLS diff --git a/freebsd/sys/cam/cam_debug.h b/freebsd/sys/cam/cam_debug.h index 37acd7dc..7b619a29 100644 --- a/freebsd/sys/cam/cam_debug.h +++ b/freebsd/sys/cam/cam_debug.h @@ -61,13 +61,13 @@ typedef enum { #endif #ifndef CAM_DEBUG_BUS -#define CAM_DEBUG_BUS (-1) +#define CAM_DEBUG_BUS CAM_BUS_WILDCARD #endif #ifndef CAM_DEBUG_TARGET -#define CAM_DEBUG_TARGET (-1) +#define CAM_DEBUG_TARGET CAM_TARGET_WILDCARD #endif #ifndef CAM_DEBUG_LUN -#define CAM_DEBUG_LUN (-1) +#define CAM_DEBUG_LUN CAM_LUN_WILDCARD #endif #ifndef CAM_DEBUG_DELAY @@ -99,6 +99,17 @@ extern u_int32_t cam_debug_delay; DELAY(cam_debug_delay); \ } +#define CAM_DEBUG_DEV(dev, flag, printfargs) \ + if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags) \ + && (cam_dpath != NULL) \ + && (xpt_path_comp_dev(cam_dpath, dev) >= 0) \ + && (xpt_path_comp_dev(cam_dpath, dev) < 2)) { \ + xpt_print_device(dev); \ + printf printfargs; \ + if (cam_debug_delay != 0) \ + DELAY(cam_debug_delay); \ + } + #define CAM_DEBUG_PRINT(flag, printfargs) \ if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags)) { \ printf("cam_debug: "); \ diff --git a/freebsd/sys/cam/cam_periph.h b/freebsd/sys/cam/cam_periph.h index 102dc3c3..a58ec947 100644 --- a/freebsd/sys/cam/cam_periph.h +++ b/freebsd/sys/cam/cam_periph.h @@ -121,6 +121,7 @@ struct cam_periph { #define CAM_PERIPH_NEW_DEV_FOUND 0x10 #define CAM_PERIPH_RECOVERY_INPROG 0x20 #define CAM_PERIPH_FREE 0x80 +#define CAM_PERIPH_ANNOUNCED 0x100 u_int32_t immediate_priority; u_int32_t refcount; SLIST_HEAD(, ccb_hdr) ccb_list; /* For "immediate" requests */ @@ -171,8 +172,6 @@ int cam_periph_ioctl(struct cam_periph *periph, u_long cmd, cam_flags camflags, u_int32_t sense_flags)); void cam_freeze_devq(struct cam_path *path); -void cam_freeze_devq_arg(struct cam_path *path, u_int32_t flags, - uint32_t arg); u_int32_t cam_release_devq(struct cam_path *path, u_int32_t relsim_flags, u_int32_t opening_reduction, u_int32_t arg, int getcount_only); diff --git a/freebsd/sys/cam/cam_xpt.h b/freebsd/sys/cam/cam_xpt.h index 492fa3a4..97933b98 100644 --- a/freebsd/sys/cam/cam_xpt.h +++ b/freebsd/sys/cam/cam_xpt.h @@ -35,6 +35,7 @@ /* Forward Declarations */ union ccb; struct cam_periph; +struct cam_ed; struct cam_sim; /* @@ -89,7 +90,10 @@ void xpt_path_counts(struct cam_path *path, uint32_t *bus_ref, uint32_t *device_ref); int xpt_path_comp(struct cam_path *path1, struct cam_path *path2); +int xpt_path_comp_dev(struct cam_path *path, + struct cam_ed *dev); void xpt_print_path(struct cam_path *path); +void xpt_print_device(struct cam_ed *device); void xpt_print(struct cam_path *path, const char *fmt, ...); int xpt_path_string(struct cam_path *path, char *str, size_t str_len); diff --git a/freebsd/sys/cam/cam_xpt_sim.h b/freebsd/sys/cam/cam_xpt_sim.h index d32eea71..62ded090 100644 --- a/freebsd/sys/cam/cam_xpt_sim.h +++ b/freebsd/sys/cam/cam_xpt_sim.h @@ -47,12 +47,8 @@ u_int32_t xpt_freeze_devq(struct cam_path *path, u_int count); #else /* __rtems__ */ #define xpt_freeze_devq(path, count) do { } while (0) #endif /* __rtems__ */ -u_int32_t xpt_freeze_devq_rl(struct cam_path *path, cam_rl rl, - u_int count); void xpt_release_devq(struct cam_path *path, u_int count, int run_queue); -void xpt_release_devq_rl(struct cam_path *path, cam_rl rl, - u_int count, int run_queue); int xpt_sim_opened(struct cam_sim *sim); void xpt_done(union ccb *done_ccb); void xpt_batch_start(struct cam_sim *sim); diff --git a/freebsd/sys/cam/scsi/scsi_all.c b/freebsd/sys/cam/scsi/scsi_all.c index 5b504010..4cad972d 100644 --- a/freebsd/sys/cam/scsi/scsi_all.c +++ b/freebsd/sys/cam/scsi/scsi_all.c @@ -672,6 +672,10 @@ scsi_op_desc(u_int16_t opcode, struct scsi_inquiry_data *inq_data) if (pd_type == T_RBC) pd_type = T_DIRECT; + /* Map NODEVICE to Direct Access Device to handle REPORT LUNS, etc. */ + if (pd_type == T_NODEVICE) + pd_type = T_DIRECT; + opmask = 1 << pd_type; for (j = 0; j < num_tables; j++) { @@ -1121,7 +1125,7 @@ static struct asc_table_entry asc_table[] = { { SST(0x04, 0x10, SS_RDEF, /* XXX TBD */ "Logical unit not ready, auxiliary memory not accessible") }, /* DT WRO AEB VF */ - { SST(0x04, 0x11, SS_RDEF, /* XXX TBD */ + { SST(0x04, 0x11, SS_TUR | SSQ_MANY | SSQ_DECREMENT_COUNT | EBUSY, "Logical unit not ready, notify (enable spinup) required") }, /* M V */ { SST(0x04, 0x12, SS_RDEF, /* XXX TBD */ @@ -1652,7 +1656,7 @@ static struct asc_table_entry asc_table[] = { { SST(0x24, 0x08, SS_RDEF, /* XXX TBD */ "Invalid XCDB") }, /* DTLPWROMAEBKVF */ - { SST(0x25, 0x00, SS_FATAL | ENXIO, + { SST(0x25, 0x00, SS_FATAL | ENXIO | SSQ_LOST, "Logical unit not supported") }, /* DTLPWROMAEBKVF */ { SST(0x26, 0x00, SS_FATAL | EINVAL, @@ -2170,7 +2174,7 @@ static struct asc_table_entry asc_table[] = { { SST(0x3F, 0x0D, SS_RDEF, "Volume set reassigned") }, /* DTLPWROMAE */ - { SST(0x3F, 0x0E, SS_RDEF, /* XXX TBD */ + { SST(0x3F, 0x0E, SS_RDEF | SSQ_RESCAN , "Reported LUNs data has changed") }, /* DTLPWROMAEBKVF */ { SST(0x3F, 0x0F, SS_RDEF, /* XXX TBD */ @@ -3270,6 +3274,7 @@ scsi_error_action(struct ccb_scsiio *csio, struct scsi_inquiry_data *inq_data, action |= SS_RETRY|SSQ_DECREMENT_COUNT| SSQ_PRINT_SENSE; } + action |= SSQ_UA; } } if ((action & SS_MASK) >= SS_START && @@ -5256,6 +5261,21 @@ scsi_print_inquiry(struct scsi_inquiry_data *inq_data) dtype, rstr, qtype); } +void +scsi_print_inquiry_short(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)); + + printf("<%s %s %s>", vendor, product, revision); +} + #ifndef __rtems__ /* * Table of syncrates that don't follow the "divisible by 4" @@ -6510,7 +6530,11 @@ scsi_devid_match(uint8_t *lhs, size_t lhs_len, uint8_t *rhs, size_t rhs_len) while (rhs_id <= rhs_last && (rhs_id->identifier + rhs_id->length) <= rhs_end) { - if (rhs_id->length == lhs_id->length + if ((rhs_id->id_type & + (SVPD_ID_ASSOC_MASK | SVPD_ID_TYPE_MASK)) == + (lhs_id->id_type & + (SVPD_ID_ASSOC_MASK | SVPD_ID_TYPE_MASK)) + && rhs_id->length == lhs_id->length && memcmp(rhs_id->identifier, lhs_id->identifier, rhs_id->length) == 0) return (0); diff --git a/freebsd/sys/cam/scsi/scsi_all.h b/freebsd/sys/cam/scsi/scsi_all.h index 4fe0b1dd..cf84d396 100644 --- a/freebsd/sys/cam/scsi/scsi_all.h +++ b/freebsd/sys/cam/scsi/scsi_all.h @@ -88,6 +88,9 @@ typedef enum { * and text. */ SSQ_PRINT_SENSE = 0x0800, + SSQ_UA = 0x1000, /* Broadcast UA. */ + SSQ_RESCAN = 0x2000, /* Rescan target for LUNs. */ + SSQ_LOST = 0x4000, /* Destroy the LUNs. */ SSQ_MASK = 0xff00 } scsi_sense_action_qualifier; @@ -2309,6 +2312,7 @@ char * scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string, size_t len); void scsi_print_inquiry(struct scsi_inquiry_data *inq_data); +void scsi_print_inquiry_short(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/cam/scsi/scsi_da.h b/freebsd/sys/cam/scsi/scsi_da.h index 57992381..4fbd7256 100644 --- a/freebsd/sys/cam/scsi/scsi_da.h +++ b/freebsd/sys/cam/scsi/scsi_da.h @@ -116,6 +116,31 @@ struct scsi_read_defect_data_10 u_int8_t control; }; +struct scsi_sanitize +{ + u_int8_t opcode; + u_int8_t byte2; +#define SSZ_SERVICE_ACTION_OVERWRITE 0x01 +#define SSZ_SERVICE_ACTION_BLOCK_ERASE 0x02 +#define SSZ_SERVICE_ACTION_CRYPTO_ERASE 0x03 +#define SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE 0x1F +#define SSZ_UNRESTRICTED_EXIT 0x20 +#define SSZ_IMMED 0x80 + u_int8_t reserved[5]; + u_int8_t length[2]; + u_int8_t control; +}; + +struct scsi_sanitize_parameter_list +{ + u_int8_t byte1; +#define SSZPL_INVERT 0x80 + u_int8_t reserved; + u_int8_t length[2]; + /* Variable length initialization pattern. */ +#define SSZPL_MAX_PATTERN_LENGTH 65535 +}; + struct scsi_read_defect_data_12 { u_int8_t opcode; @@ -156,6 +181,7 @@ struct scsi_read_defect_data_12 #define WRITE_AND_VERIFY 0x2e #define VERIFY 0x2f #define READ_DEFECT_DATA_10 0x37 +#define SANITIZE 0x48 #define READ_DEFECT_DATA_12 0xb7 struct format_defect_list_header @@ -508,6 +534,12 @@ void scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries, u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout); +void scsi_sanitize(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + u_int8_t tag_action, u_int8_t byte2, u_int16_t control, + u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, + u_int32_t timeout); + #endif /* !_KERNEL */ __END_DECLS diff --git a/freebsd/sys/contrib/pf/net/pf_lb.c b/freebsd/sys/contrib/pf/net/pf_lb.c index 0c2046c2..16faac02 100644 --- a/freebsd/sys/contrib/pf/net/pf_lb.c +++ b/freebsd/sys/contrib/pf/net/pf_lb.c @@ -167,8 +167,8 @@ struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *, struct pf_addr *, u_int16_t, struct pf_addr *, u_int16_t, int); int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *, - struct pf_addr *, struct pf_addr *, u_int16_t, - struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t, + struct pf_addr *, uint16_t, struct pf_addr *, uint16_t, + struct pf_addr *, uint16_t*, uint16_t, uint16_t, struct pf_src_node **); #define mix(a,b,c) \ @@ -320,13 +320,13 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, - struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport, - struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high, - struct pf_src_node **sn) + struct pf_addr *saddr, uint16_t sport, struct pf_addr *daddr, + uint16_t dport, struct pf_addr *naddr, uint16_t *nport, uint16_t low, + uint16_t high, struct pf_src_node **sn) { struct pf_state_key_cmp key; struct pf_addr init_addr; - u_int16_t cut; + uint16_t cut; bzero(&init_addr, sizeof(init_addr)); if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) @@ -337,34 +337,38 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, high = 65535; } + bzero(&key,sizeof(key)); + key.af = af; + key.proto = proto; + key.port[0] = dport; + PF_ACPY(&key.addr[0], daddr, key.af); + do { - key.af = af; - key.proto = proto; - PF_ACPY(&key.addr[1], daddr, key.af); - PF_ACPY(&key.addr[0], naddr, key.af); - key.port[1] = dport; + PF_ACPY(&key.addr[1], naddr, key.af); /* * port search; start random, step; * similar 2 portloop in in_pcbbind */ if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP || - proto == IPPROTO_ICMP)) { - key.port[0] = dport; - if (pf_find_state_all(&key, PF_IN, NULL) == NULL) - return (0); - } else if (low == 0 && high == 0) { - key.port[0] = *nport; - if (pf_find_state_all(&key, PF_IN, NULL) == NULL) + proto == IPPROTO_ICMP) || (low == 0 && high == 0)) { + /* + * XXX bug: icmp state don't use the id on both sides. + * (traceroute -l through nat) + */ + key.port[1] = sport; + if (pf_find_state_all(&key, PF_IN, NULL) == NULL) { + *nport = sport; return (0); + } } else if (low == high) { - key.port[0] = htons(low); + key.port[1] = htons(low); if (pf_find_state_all(&key, PF_IN, NULL) == NULL) { *nport = htons(low); return (0); } } else { - u_int16_t tmp; + uint16_t tmp; if (low > high) { tmp = low; @@ -379,7 +383,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, #endif /* low <= cut <= high */ for (tmp = cut; tmp <= high; ++(tmp)) { - key.port[0] = htons(tmp); + key.port[1] = htons(tmp); if (pf_find_state_all(&key, PF_IN, NULL) == #ifdef __FreeBSD__ NULL) { @@ -391,7 +395,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, } } for (tmp = cut - 1; tmp >= low; --(tmp)) { - key.port[0] = htons(tmp); + key.port[1] = htons(tmp); if (pf_find_state_all(&key, PF_IN, NULL) == #ifdef __FreeBSD__ NULL) { @@ -657,8 +661,8 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, case PF_NORDR: return (NULL); case PF_NAT: - if (pf_get_sport(pd->af, pd->proto, r, saddr, - daddr, dport, naddr, nport, r->rpool.proxy_port[0], + if (pf_get_sport(pd->af, pd->proto, r, saddr, sport, daddr, + dport, naddr, nport, r->rpool.proxy_port[0], r->rpool.proxy_port[1], sn)) { DPFPRINTF(PF_DEBUG_MISC, ("pf: NAT proxy port allocation " @@ -786,6 +790,7 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, pool_put(&pf_state_key_pl, *skp); #endif *skw = *sks = *nkp = *skp = NULL; + *sn = NULL; return (NULL); } } diff --git a/freebsd/sys/dev/bce/if_bce.c b/freebsd/sys/dev/bce/if_bce.c index dfae5dcc..e186590f 100644 --- a/freebsd/sys/dev/bce/if_bce.c +++ b/freebsd/sys/dev/bce/if_bce.c @@ -1,8 +1,7 @@ #include /*- - * Copyright (c) 2006-2010 Broadcom Corporation - * David Christensen . All rights reserved. + * Copyright (c) 2006-2014 QLogic Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -13,9 +12,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Broadcom Corporation nor the name of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written consent. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -108,13 +104,13 @@ static const struct bce_type bce_devs[] = { { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x1709, "HP NC371i Multifunction Gigabit Server Adapter" }, { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, PCI_ANY_ID, PCI_ANY_ID, - "Broadcom NetXtreme II BCM5706 1000Base-T" }, + "QLogic NetXtreme II BCM5706 1000Base-T" }, /* BCM5706S controllers and OEM boards. */ { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102, "HP NC370F Multifunction Gigabit Server Adapter" }, { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID, PCI_ANY_ID, - "Broadcom NetXtreme II BCM5706 1000Base-SX" }, + "QLogic NetXtreme II BCM5706 1000Base-SX" }, /* BCM5708C controllers and OEM boards. */ { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7037, @@ -124,7 +120,7 @@ static const struct bce_type bce_devs[] = { { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7045, "HP NC374m PCIe Multifunction Adapter" }, { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, PCI_ANY_ID, PCI_ANY_ID, - "Broadcom NetXtreme II BCM5708 1000Base-T" }, + "QLogic NetXtreme II BCM5708 1000Base-T" }, /* BCM5708S controllers and OEM boards. */ { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x1706, @@ -134,7 +130,7 @@ static const struct bce_type bce_devs[] = { { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x703d, "HP NC373F PCIe Multifunc Giga Server Adapter" }, { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, PCI_ANY_ID, PCI_ANY_ID, - "Broadcom NetXtreme II BCM5708 1000Base-SX" }, + "QLogic NetXtreme II BCM5708 1000Base-SX" }, /* BCM5709C controllers and OEM boards. */ { BRCM_VENDORID, BRCM_DEVICEID_BCM5709, HP_VENDORID, 0x7055, @@ -142,7 +138,7 @@ static const struct bce_type bce_devs[] = { { BRCM_VENDORID, BRCM_DEVICEID_BCM5709, HP_VENDORID, 0x7059, "HP NC382T PCIe DP Multifunction Gigabit Server Adapter" }, { BRCM_VENDORID, BRCM_DEVICEID_BCM5709, PCI_ANY_ID, PCI_ANY_ID, - "Broadcom NetXtreme II BCM5709 1000Base-T" }, + "QLogic NetXtreme II BCM5709 1000Base-T" }, /* BCM5709S controllers and OEM boards. */ { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, HP_VENDORID, 0x171d, @@ -150,11 +146,11 @@ static const struct bce_type bce_devs[] = { { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, HP_VENDORID, 0x7056, "HP NC382i DP Multifunction Gigabit Server Adapter" }, { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, PCI_ANY_ID, PCI_ANY_ID, - "Broadcom NetXtreme II BCM5709 1000Base-SX" }, + "QLogic NetXtreme II BCM5709 1000Base-SX" }, /* BCM5716 controllers and OEM boards. */ { BRCM_VENDORID, BRCM_DEVICEID_BCM5716, PCI_ANY_ID, PCI_ANY_ID, - "Broadcom NetXtreme II BCM5716 1000Base-T" }, + "QLogic NetXtreme II BCM5716 1000Base-T" }, { 0, 0, 0, 0, NULL } }; @@ -5066,9 +5062,11 @@ bce_reset(struct bce_softc *sc, u32 reset_code) bce_reset_exit: /* Restore EMAC Mode bits needed to keep ASF/IPMI running. */ - val = REG_RD(sc, BCE_EMAC_MODE); - val = (val & ~emac_mode_mask) | emac_mode_save; - REG_WR(sc, BCE_EMAC_MODE, val); + if (reset_code == BCE_DRV_MSG_CODE_RESET) { + val = REG_RD(sc, BCE_EMAC_MODE); + val = (val & ~emac_mode_mask) | emac_mode_save; + REG_WR(sc, BCE_EMAC_MODE, val); + } DBEXIT(BCE_VERBOSE_RESET); return (rc); diff --git a/freebsd/sys/dev/bce/if_bcefw.h b/freebsd/sys/dev/bce/if_bcefw.h index 8d97b31c..fa0d528a 100644 --- a/freebsd/sys/dev/bce/if_bcefw.h +++ b/freebsd/sys/dev/bce/if_bcefw.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2006-2011 Broadcom Corporation - * David Christensen . All rights reserved. + * Copyright (c) 2006-2014 QLogic Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,9 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Broadcom Corporation nor the name of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written consent. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -31,7 +27,7 @@ /* * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004-2011 Broadcom Corporation. + * source code, Copyright (c) 2004-2014 QLogic Corporation. * * Permission is hereby granted for the distribution of this firmware data * in hexadecimal or equivalent format, provided this copyright notice also diff --git a/freebsd/sys/dev/bce/if_bcereg.h b/freebsd/sys/dev/bce/if_bcereg.h index 450180bd..00903562 100644 --- a/freebsd/sys/dev/bce/if_bcereg.h +++ b/freebsd/sys/dev/bce/if_bcereg.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2006-2010 Broadcom Corporation - * David Christensen . All rights reserved. + * Copyright (c) 2006-2014 QLogic Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,9 +9,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Broadcom Corporation nor the name of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written consent. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -6355,8 +6351,8 @@ struct fw_info { #define BCE_TX_TIMEOUT 5 -#define BCE_MAX_SEGMENTS 32 -#define BCE_TSO_MAX_SIZE 65536 +#define BCE_MAX_SEGMENTS 35 +#define BCE_TSO_MAX_SIZE (65535 + sizeof(struct ether_vlan_header)) #define BCE_TSO_MAX_SEG_SIZE 4096 #define BCE_DMA_ALIGN 8 diff --git a/freebsd/sys/dev/bge/if_bge.c b/freebsd/sys/dev/bge/if_bge.c index f9010aa1..c0f78a78 100644 --- a/freebsd/sys/dev/bge/if_bge.c +++ b/freebsd/sys/dev/bge/if_bge.c @@ -178,6 +178,8 @@ static const struct bge_type { { BCOM_VENDORID, BCOM_DEVICEID_BCM5721 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5722 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5723 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5725 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5727 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5750 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5750M }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5751 }, @@ -197,6 +199,7 @@ static const struct bge_type { { BCOM_VENDORID, BCOM_DEVICEID_BCM5761E }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5761S }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5761SE }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM5762 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5764 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5780 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM5780S }, @@ -219,11 +222,16 @@ static const struct bge_type { { BCOM_VENDORID, BCOM_DEVICEID_BCM57760 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM57761 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM57762 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM57764 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM57765 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM57766 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM57767 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM57780 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM57781 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM57782 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM57785 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM57786 }, + { BCOM_VENDORID, BCOM_DEVICEID_BCM57787 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM57788 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM57790 }, { BCOM_VENDORID, BCOM_DEVICEID_BCM57791 }, @@ -312,6 +320,7 @@ static const struct bge_revision { { BGE_CHIPID_BCM5722_A0, "BCM5722 A0" }, { BGE_CHIPID_BCM5761_A0, "BCM5761 A0" }, { BGE_CHIPID_BCM5761_A1, "BCM5761 A1" }, + { BGE_CHIPID_BCM5762_A0, "BCM5762 A0" }, { BGE_CHIPID_BCM5784_A0, "BCM5784 A0" }, { BGE_CHIPID_BCM5784_A1, "BCM5784 A1" }, /* 5754 and 5787 share the same ASIC ID */ @@ -356,6 +365,7 @@ static const struct bge_revision bge_majorrevs[] = { { BGE_ASICREV_BCM5717, "unknown BCM5717" }, { BGE_ASICREV_BCM5719, "unknown BCM5719" }, { BGE_ASICREV_BCM5720, "unknown BCM5720" }, + { BGE_ASICREV_BCM5762, "unknown BCM5762" }, { 0, NULL } }; @@ -1798,6 +1808,20 @@ bge_chipinit(struct bge_softc *sc) pci_write_config(sc->bge_dev, BGE_PCI_MSI_DATA + 2, val, 2); } + if (sc->bge_asicrev == BGE_ASICREV_BCM57765 || + sc->bge_asicrev == BGE_ASICREV_BCM57766) { + /* + * For the 57766 and non Ax versions of 57765, bootcode + * needs to setup the PCIE Fast Training Sequence (FTS) + * value to prevent transmit hangs. + */ + if (sc->bge_chiprev != BGE_CHIPREV_57765_AX) { + CSR_WRITE_4(sc, BGE_CPMU_PADRNG_CTL, + CSR_READ_4(sc, BGE_CPMU_PADRNG_CTL) | + BGE_CPMU_PADRNG_CTL_RDIV2); + } + } + /* * Set up the PCI DMA control register. */ @@ -1873,8 +1897,9 @@ bge_chipinit(struct bge_softc *sc) * a status tag update and leave interrupts permanently * disabled. */ - if (sc->bge_asicrev != BGE_ASICREV_BCM5717 && - sc->bge_asicrev != BGE_ASICREV_BCM57765) + if (!BGE_IS_57765_PLUS(sc) && + sc->bge_asicrev != BGE_ASICREV_BCM5717 && + sc->bge_asicrev != BGE_ASICREV_BCM5762) dma_rw_ctl |= BGE_PCIDMARWCTL_TAGGED_STATUS_WA; } pci_write_config(sc->bge_dev, BGE_PCI_DMA_RW_CTL, dma_rw_ctl, 4); @@ -1883,7 +1908,8 @@ bge_chipinit(struct bge_softc *sc) * Set up general mode register. */ mode_ctl = bge_dma_swap_options(sc); - if (sc->bge_asicrev == BGE_ASICREV_BCM5720) { + if (sc->bge_asicrev == BGE_ASICREV_BCM5720 || + sc->bge_asicrev == BGE_ASICREV_BCM5762) { /* Retain Host-2-BMC settings written by APE firmware. */ mode_ctl |= CSR_READ_4(sc, BGE_MODE_CTL) & (BGE_MODECTL_BYTESWAP_B2HRX_DATA | @@ -1941,7 +1967,7 @@ bge_blockinit(struct bge_softc *sc) struct bge_rcb *rcb; bus_size_t vrcb; bge_hostaddr taddr; - uint32_t dmactl, val; + uint32_t dmactl, rdmareg, val; int i, limit; /* @@ -2212,6 +2238,11 @@ bge_blockinit(struct bge_softc *sc) if (!BGE_IS_5705_PLUS(sc)) /* 5700 to 5704 had 16 send rings. */ limit = BGE_TX_RINGS_EXTSSRAM_MAX; + else if (BGE_IS_57765_PLUS(sc) || + sc->bge_asicrev == BGE_ASICREV_BCM5762) + limit = 2; + else if (BGE_IS_5717_PLUS(sc)) + limit = 4; else limit = 1; vrcb = BGE_MEMWIN_START + BGE_SEND_RING_RCB; @@ -2250,6 +2281,7 @@ bge_blockinit(struct bge_softc *sc) } else if (!BGE_IS_5705_PLUS(sc)) limit = BGE_RX_RINGS_MAX; else if (sc->bge_asicrev == BGE_ASICREV_BCM5755 || + sc->bge_asicrev == BGE_ASICREV_BCM5762 || BGE_IS_57765_PLUS(sc)) limit = 4; else @@ -2289,7 +2321,8 @@ bge_blockinit(struct bge_softc *sc) /* Set inter-packet gap */ val = 0x2620; - if (sc->bge_asicrev == BGE_ASICREV_BCM5720) + if (sc->bge_asicrev == BGE_ASICREV_BCM5720 || + sc->bge_asicrev == BGE_ASICREV_BCM5762) val |= CSR_READ_4(sc, BGE_TX_LENGTHS) & (BGE_TXLEN_JMB_FRM_LEN_MSK | BGE_TXLEN_CNT_DN_VAL_MSK); CSR_WRITE_4(sc, BGE_TX_LENGTHS, val); @@ -2453,7 +2486,8 @@ bge_blockinit(struct bge_softc *sc) val |= BGE_RDMAMODE_TSO6_ENABLE; } - if (sc->bge_asicrev == BGE_ASICREV_BCM5720) { + if (sc->bge_asicrev == BGE_ASICREV_BCM5720 || + sc->bge_asicrev == BGE_ASICREV_BCM5762) { val |= CSR_READ_4(sc, BGE_RDMA_MODE) & BGE_RDMAMODE_H2BNC_VLAN_DET; /* @@ -2467,14 +2501,18 @@ bge_blockinit(struct bge_softc *sc) sc->bge_asicrev == BGE_ASICREV_BCM5784 || sc->bge_asicrev == BGE_ASICREV_BCM5785 || sc->bge_asicrev == BGE_ASICREV_BCM57780 || - BGE_IS_5717_PLUS(sc)) { - dmactl = CSR_READ_4(sc, BGE_RDMA_RSRVCTRL); + BGE_IS_5717_PLUS(sc) || BGE_IS_57765_PLUS(sc)) { + if (sc->bge_asicrev == BGE_ASICREV_BCM5762) + rdmareg = BGE_RDMA_RSRVCTRL_REG2; + else + rdmareg = BGE_RDMA_RSRVCTRL; + dmactl = CSR_READ_4(sc, rdmareg); /* * Adjust tx margin to prevent TX data corruption and * fix internal FIFO overflow. */ - if (sc->bge_asicrev == BGE_ASICREV_BCM5719 && - sc->bge_chipid == BGE_CHIPID_BCM5719_A0) { + if (sc->bge_chipid == BGE_CHIPID_BCM5719_A0 || + sc->bge_asicrev == BGE_ASICREV_BCM5762) { dmactl &= ~(BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK | BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK | BGE_RDMA_RSRVCTRL_TXMRGN_MASK); @@ -2487,7 +2525,7 @@ bge_blockinit(struct bge_softc *sc) * The fix is to limit the number of RX BDs * the hardware would fetch at a fime. */ - CSR_WRITE_4(sc, BGE_RDMA_RSRVCTRL, dmactl | + CSR_WRITE_4(sc, rdmareg, dmactl | BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX); } @@ -2505,11 +2543,34 @@ bge_blockinit(struct bge_softc *sc) CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) | BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512 | BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K); + } else if (sc->bge_asicrev == BGE_ASICREV_BCM5762) { + CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL_REG2, + CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL_REG2) | + BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K | + BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K); } CSR_WRITE_4(sc, BGE_RDMA_MODE, val); DELAY(40); + if (sc->bge_flags & BGE_FLAG_RDMA_BUG) { + for (i = 0; i < BGE_NUM_RDMA_CHANNELS / 2; i++) { + val = CSR_READ_4(sc, BGE_RDMA_LENGTH + i * 4); + if ((val & 0xFFFF) > BGE_FRAMELEN) + break; + if (((val >> 16) & 0xFFFF) > BGE_FRAMELEN) + break; + } + if (i != BGE_NUM_RDMA_CHANNELS / 2) { + val = CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL); + if (sc->bge_asicrev == BGE_ASICREV_BCM5719) + val |= BGE_RDMA_TX_LENGTH_WA_5719; + else + val |= BGE_RDMA_TX_LENGTH_WA_5720; + CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL, val); + } + } + /* Turn on RX data completion state machine */ CSR_WRITE_4(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE); @@ -2636,6 +2697,12 @@ bge_chipid(device_t dev) case BCOM_DEVICEID_BCM5718: case BCOM_DEVICEID_BCM5719: case BCOM_DEVICEID_BCM5720: + case BCOM_DEVICEID_BCM5725: + case BCOM_DEVICEID_BCM5727: + case BCOM_DEVICEID_BCM5762: + case BCOM_DEVICEID_BCM57764: + case BCOM_DEVICEID_BCM57767: + case BCOM_DEVICEID_BCM57787: id = pci_read_config(dev, BGE_PCI_GEN2_PRODID_ASICREV, 4); break; @@ -2644,7 +2711,9 @@ bge_chipid(device_t dev) case BCOM_DEVICEID_BCM57765: case BCOM_DEVICEID_BCM57766: case BCOM_DEVICEID_BCM57781: + case BCOM_DEVICEID_BCM57782: case BCOM_DEVICEID_BCM57785: + case BCOM_DEVICEID_BCM57786: case BCOM_DEVICEID_BCM57791: case BCOM_DEVICEID_BCM57795: id = pci_read_config(dev, @@ -3259,7 +3328,7 @@ bge_attach(device_t dev) struct bge_softc *sc; uint32_t hwcfg = 0, misccfg, pcistate; u_char eaddr[ETHER_ADDR_LEN]; - int capmask, error, msicount, reg, rid, trys; + int capmask, error, reg, rid, trys; sc = device_get_softc(dev); sc->bge_dev = dev; @@ -3268,11 +3337,11 @@ bge_attach(device_t dev) TASK_INIT(&sc->bge_intr_task, 0, bge_intr_task, sc); callout_init_mtx(&sc->bge_stat_ch, &sc->bge_mtx, 0); - /* - * Map control/status registers. - */ pci_enable_busmaster(dev); + /* + * Allocate control/status registers. + */ rid = PCIR_BAR(0); sc->bge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); @@ -3336,6 +3405,7 @@ bge_attach(device_t dev) /* Save chipset family. */ switch (sc->bge_asicrev) { + case BGE_ASICREV_BCM5762: case BGE_ASICREV_BCM57765: case BGE_ASICREV_BCM57766: sc->bge_flags |= BGE_FLAG_57765_PLUS; @@ -3346,10 +3416,18 @@ bge_attach(device_t dev) sc->bge_flags |= BGE_FLAG_5717_PLUS | BGE_FLAG_5755_PLUS | BGE_FLAG_575X_PLUS | BGE_FLAG_5705_PLUS | BGE_FLAG_JUMBO | BGE_FLAG_JUMBO_FRAME; - if (sc->bge_asicrev == BGE_ASICREV_BCM5719 && - sc->bge_chipid == BGE_CHIPID_BCM5719_A0) { - /* Jumbo frame on BCM5719 A0 does not work. */ - sc->bge_flags &= ~BGE_FLAG_JUMBO; + if (sc->bge_asicrev == BGE_ASICREV_BCM5719 || + sc->bge_asicrev == BGE_ASICREV_BCM5720) { + /* + * Enable work around for DMA engine miscalculation + * of TXMBUF available space. + */ + sc->bge_flags |= BGE_FLAG_RDMA_BUG; + if (sc->bge_asicrev == BGE_ASICREV_BCM5719 && + sc->bge_chipid == BGE_CHIPID_BCM5719_A0) { + /* Jumbo frame on BCM5719 A0 does not work. */ + sc->bge_flags &= ~BGE_FLAG_JUMBO; + } } break; case BGE_ASICREV_BCM5755: @@ -3388,6 +3466,7 @@ bge_attach(device_t dev) case BGE_ASICREV_BCM5719: case BGE_ASICREV_BCM5720: case BGE_ASICREV_BCM5761: + case BGE_ASICREV_BCM5762: sc->bge_flags |= BGE_FLAG_APE; break; } @@ -3572,13 +3651,8 @@ bge_attach(device_t dev) rid = 0; if (pci_find_cap(sc->bge_dev, PCIY_MSI, ®) == 0) { sc->bge_msicap = reg; - if (bge_can_use_msi(sc)) { - msicount = pci_msi_count(dev); - if (msicount > 1) - msicount = 1; - } else - msicount = 0; - if (msicount == 1 && pci_alloc_msi(dev, &msicount) == 0) { + reg = 1; + if (bge_can_use_msi(sc) && pci_alloc_msi(dev, ®) == 0) { rid = 1; sc->bge_flags |= BGE_FLAG_MSI; } @@ -3595,7 +3669,7 @@ bge_attach(device_t dev) #endif sc->bge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_SHAREABLE | RF_ACTIVE); + RF_ACTIVE | (rid != 0 ? 0 : RF_SHAREABLE)); if (sc->bge_irq == NULL) { device_printf(sc->bge_dev, "couldn't map interrupt\n"); @@ -3938,20 +4012,19 @@ bge_release_resources(struct bge_softc *sc) if (sc->bge_intrhand != NULL) bus_teardown_intr(dev, sc->bge_irq, sc->bge_intrhand); - if (sc->bge_irq != NULL) + if (sc->bge_irq != NULL) { bus_release_resource(dev, SYS_RES_IRQ, - sc->bge_flags & BGE_FLAG_MSI ? 1 : 0, sc->bge_irq); - - if (sc->bge_flags & BGE_FLAG_MSI) + rman_get_rid(sc->bge_irq), sc->bge_irq); pci_release_msi(dev); + } if (sc->bge_res != NULL) bus_release_resource(dev, SYS_RES_MEMORY, - PCIR_BAR(0), sc->bge_res); + rman_get_rid(sc->bge_res), sc->bge_res); if (sc->bge_res2 != NULL) bus_release_resource(dev, SYS_RES_MEMORY, - PCIR_BAR(2), sc->bge_res2); + rman_get_rid(sc->bge_res2), sc->bge_res2); if (sc->bge_ifp != NULL) if_free(sc->bge_ifp); @@ -4767,6 +4840,7 @@ bge_stats_update_regs(struct bge_softc *sc) { struct ifnet *ifp; struct bge_mac_stats *stats; + uint32_t val; ifp = sc->bge_ifp; stats = &sc->bge_mac_stats; @@ -4867,6 +4941,24 @@ bge_stats_update_regs(struct bge_softc *sc) ifp->if_collisions = (u_long)stats->etherStatsCollisions; ifp->if_ierrors = (u_long)(stats->NoMoreRxBDs + stats->InputDiscards + stats->InputErrors); + + if (sc->bge_flags & BGE_FLAG_RDMA_BUG) { + /* + * If controller transmitted more than BGE_NUM_RDMA_CHANNELS + * frames, it's safe to disable workaround for DMA engine's + * miscalculation of TXMBUF space. + */ + if (stats->ifHCOutUcastPkts + stats->ifHCOutMulticastPkts + + stats->ifHCOutBroadcastPkts > BGE_NUM_RDMA_CHANNELS) { + val = CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL); + if (sc->bge_asicrev == BGE_ASICREV_BCM5719) + val &= ~BGE_RDMA_TX_LENGTH_WA_5719; + else + val &= ~BGE_RDMA_TX_LENGTH_WA_5720; + CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL, val); + sc->bge_flags &= ~BGE_FLAG_RDMA_BUG; + } + } } static void @@ -5196,17 +5288,51 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx) csum_flags |= BGE_TXBDFLAG_VLAN_TAG; vlan_tag = m->m_pkthdr.ether_vtag; } - for (i = 0; ; i++) { - d = &sc->bge_ldata.bge_tx_ring[idx]; - d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr); - d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr); - d->bge_len = segs[i].ds_len; - d->bge_flags = csum_flags; - d->bge_vlan_tag = vlan_tag; - d->bge_mss = mss; - if (i == nsegs - 1) - break; - BGE_INC(idx, BGE_TX_RING_CNT); + + if (sc->bge_asicrev == BGE_ASICREV_BCM5762 && + (m->m_pkthdr.csum_flags & CSUM_TSO) != 0) { + /* + * 5725 family of devices corrupts TSO packets when TSO DMA + * buffers cross into regions which are within MSS bytes of + * a 4GB boundary. If we encounter the condition, drop the + * packet. + */ + for (i = 0; ; i++) { + d = &sc->bge_ldata.bge_tx_ring[idx]; + d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr); + d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr); + d->bge_len = segs[i].ds_len; + if (d->bge_addr.bge_addr_lo + segs[i].ds_len + mss < + d->bge_addr.bge_addr_lo) + break; + d->bge_flags = csum_flags; + d->bge_vlan_tag = vlan_tag; + d->bge_mss = mss; + if (i == nsegs - 1) + break; + BGE_INC(idx, BGE_TX_RING_CNT); + } + if (i != nsegs - 1) { + bus_dmamap_sync(sc->bge_cdata.bge_tx_mtag, map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->bge_cdata.bge_tx_mtag, map); + m_freem(*m_head); + *m_head = NULL; + return (EIO); + } + } else { + for (i = 0; ; i++) { + d = &sc->bge_ldata.bge_tx_ring[idx]; + d->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[i].ds_addr); + d->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[i].ds_addr); + d->bge_len = segs[i].ds_len; + d->bge_flags = csum_flags; + d->bge_vlan_tag = vlan_tag; + d->bge_mss = mss; + if (i == nsegs - 1) + break; + BGE_INC(idx, BGE_TX_RING_CNT); + } } /* Mark the last segment as end of packet... */ @@ -5433,7 +5559,8 @@ bge_init_locked(struct bge_softc *sc) mode = CSR_READ_4(sc, BGE_TX_MODE); if (BGE_IS_5755_PLUS(sc) || sc->bge_asicrev == BGE_ASICREV_BCM5906) mode |= BGE_TXMODE_MBUF_LOCKUP_FIX; - if (sc->bge_asicrev == BGE_ASICREV_BCM5720) { + if (sc->bge_asicrev == BGE_ASICREV_BCM5720 || + sc->bge_asicrev == BGE_ASICREV_BCM5762) { mode &= ~(BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE); mode |= CSR_READ_4(sc, BGE_TX_MODE) & (BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE); diff --git a/freebsd/sys/dev/bge/if_bgereg.h b/freebsd/sys/dev/bge/if_bgereg.h index 09ced543..acac8b28 100644 --- a/freebsd/sys/dev/bge/if_bgereg.h +++ b/freebsd/sys/dev/bge/if_bgereg.h @@ -331,6 +331,7 @@ #define BGE_CHIPID_BCM5717_B0 0x05717100 #define BGE_CHIPID_BCM5719_A0 0x05719000 #define BGE_CHIPID_BCM5720_A0 0x05720000 +#define BGE_CHIPID_BCM5762_A0 0x05762000 #define BGE_CHIPID_BCM57765_A0 0x57785000 #define BGE_CHIPID_BCM57765_B0 0x57785100 @@ -357,6 +358,7 @@ #define BGE_ASICREV_BCM5719 0x5719 #define BGE_ASICREV_BCM5720 0x5720 #define BGE_ASICREV_BCM5761 0x5761 +#define BGE_ASICREV_BCM5762 0x5762 #define BGE_ASICREV_BCM5784 0x5784 #define BGE_ASICREV_BCM5785 0x5785 #define BGE_ASICREV_BCM57765 0x57785 @@ -378,6 +380,7 @@ #define BGE_CHIPREV_5717_AX 0x57170 #define BGE_CHIPREV_5717_BX 0x57171 #define BGE_CHIPREV_5761_AX 0x57611 +#define BGE_CHIPREV_57765_AX 0x577850 #define BGE_CHIPREV_5784_AX 0x57841 /* PCI DMA Read/Write Control register */ @@ -1289,6 +1292,7 @@ #define BGE_CPMU_MUTEX_REQ 0x365C #define BGE_CPMU_MUTEX_GNT 0x3660 #define BGE_CPMU_PHY_STRAP 0x3664 +#define BGE_CPMU_PADRNG_CTL 0x3668 /* Central Power Management Unit (CPMU) register */ #define BGE_CPMU_CTRL_LINK_IDLE_MODE 0x00000200 @@ -1328,6 +1332,9 @@ /* CPMU GPHY Strap register */ #define BGE_CPMU_PHY_STRAP_IS_SERDES 0x00000020 +/* CPMU Padring Control register */ +#define BGE_CPMU_PADRNG_CTL_RDIV2 0x00040000 + /* * Mbuf Cluster Free registers (has nothing to do with BSD mbufs) */ @@ -1539,6 +1546,8 @@ */ #define BGE_RDMA_MODE 0x4800 #define BGE_RDMA_STATUS 0x4804 +#define BGE_RDMA_RSRVCTRL_REG2 0x4890 +#define BGE_RDMA_LSO_CRPTEN_CTRL_REG2 0x48A0 #define BGE_RDMA_RSRVCTRL 0x4900 #define BGE_RDMA_LSO_CRPTEN_CTRL 0x4910 @@ -1586,6 +1595,8 @@ #define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512 0x00020000 #define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K 0x00030000 #define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K 0x000C0000 +#define BGE_RDMA_TX_LENGTH_WA_5719 0x02000000 +#define BGE_RDMA_TX_LENGTH_WA_5720 0x00200000 /* BD Read DMA Mode register */ #define BGE_RDMA_BD_MODE 0x4A00 @@ -1603,6 +1614,9 @@ #define BGE_RDMA_NON_LSO_MODE_RESET 0x00000001 #define BGE_RDMA_NON_LSO_MODE_ENABLE 0x00000002 +#define BGE_RDMA_LENGTH 0x4BE0 +#define BGE_NUM_RDMA_CHANNELS 4 + /* * Write DMA control registers */ @@ -2444,6 +2458,8 @@ struct bge_status_block { #define BCOM_DEVICEID_BCM5721 0x1659 #define BCOM_DEVICEID_BCM5722 0x165A #define BCOM_DEVICEID_BCM5723 0x165B +#define BCOM_DEVICEID_BCM5725 0x1643 +#define BCOM_DEVICEID_BCM5727 0x16F3 #define BCOM_DEVICEID_BCM5750 0x1676 #define BCOM_DEVICEID_BCM5750M 0x167C #define BCOM_DEVICEID_BCM5751 0x1677 @@ -2463,6 +2479,7 @@ struct bge_status_block { #define BCOM_DEVICEID_BCM5761E 0x1680 #define BCOM_DEVICEID_BCM5761S 0x1688 #define BCOM_DEVICEID_BCM5761SE 0x1689 +#define BCOM_DEVICEID_BCM5762 0x1687 #define BCOM_DEVICEID_BCM5764 0x1684 #define BCOM_DEVICEID_BCM5780 0x166A #define BCOM_DEVICEID_BCM5780S 0x166B @@ -2485,11 +2502,16 @@ struct bge_status_block { #define BCOM_DEVICEID_BCM57760 0x1690 #define BCOM_DEVICEID_BCM57761 0x16B0 #define BCOM_DEVICEID_BCM57762 0x1682 +#define BCOM_DEVICEID_BCM57764 0x1642 #define BCOM_DEVICEID_BCM57765 0x16B4 #define BCOM_DEVICEID_BCM57766 0x1686 +#define BCOM_DEVICEID_BCM57767 0x1683 #define BCOM_DEVICEID_BCM57780 0x1692 #define BCOM_DEVICEID_BCM57781 0x16B1 +#define BCOM_DEVICEID_BCM57782 0x16B7 #define BCOM_DEVICEID_BCM57785 0x16B5 +#define BCOM_DEVICEID_BCM57786 0x16B3 +#define BCOM_DEVICEID_BCM57787 0x1641 #define BCOM_DEVICEID_BCM57788 0x1691 #define BCOM_DEVICEID_BCM57790 0x1694 #define BCOM_DEVICEID_BCM57791 0x16B2 @@ -2829,7 +2851,7 @@ struct bge_gib { */ #define BGE_NSEG_JUMBO 4 -#define BGE_NSEG_NEW 32 +#define BGE_NSEG_NEW 35 #define BGE_TSOSEG_SZ 4096 /* Maximum DMA address for controllers that have 40bit DMA address bug. */ @@ -2982,6 +3004,7 @@ struct bge_softc { #define BGE_FLAG_SHORT_DMA_BUG 0x08000000 #define BGE_FLAG_4K_RDMA_BUG 0x10000000 #define BGE_FLAG_MBOX_REORDER 0x20000000 +#define BGE_FLAG_RDMA_BUG 0x40000000 uint32_t bge_mfw_flags; /* Management F/W flags */ #define BGE_MFW_ON_RXCPU 0x00000001 #define BGE_MFW_ON_APE 0x00000002 diff --git a/freebsd/sys/dev/e1000/e1000_defines.h b/freebsd/sys/dev/e1000/e1000_defines.h index 48c04b01..0815ea8e 100644 --- a/freebsd/sys/dev/e1000/e1000_defines.h +++ b/freebsd/sys/dev/e1000/e1000_defines.h @@ -129,7 +129,7 @@ #define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ #define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ -#define E1000_RXDEXT_STATERR_TST 0x00000100 /* Time Stamp taken */ +#define E1000_RXDEXT_STATERR_TST 0x00010000 /* Time Stamp taken */ #define E1000_RXDEXT_STATERR_LB 0x00040000 #define E1000_RXDEXT_STATERR_CE 0x01000000 #define E1000_RXDEXT_STATERR_SE 0x02000000 diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c index 4c1d3469..2a3fe54a 100644 --- a/freebsd/sys/dev/e1000/if_em.c +++ b/freebsd/sys/dev/e1000/if_em.c @@ -3837,8 +3837,7 @@ em_txeof(struct tx_ring *txr) EM_TX_LOCK_ASSERT(txr); #ifdef DEV_NETMAP - if (netmap_tx_irq(ifp, txr->me | - (NETMAP_LOCKED_ENTER | NETMAP_LOCKED_EXIT))) + if (netmap_tx_irq(ifp, txr->me)) return; #endif /* DEV_NETMAP */ @@ -4355,7 +4354,7 @@ em_initialize_receive_unit(struct adapter *adapter) * preserve the rx buffers passed to userspace. */ if (ifp->if_capenable & IFCAP_NETMAP) - rdt -= NA(adapter->ifp)->rx_rings[i].nr_hwavail; + rdt -= nm_kr_rxspace(&NA(adapter->ifp)->rx_rings[i]); #endif /* DEV_NETMAP */ E1000_WRITE_REG(hw, E1000_RDT(i), rdt); } @@ -4434,8 +4433,10 @@ em_rxeof(struct rx_ring *rxr, int count, int *done) EM_RX_LOCK(rxr); #ifdef DEV_NETMAP - if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed)) + if (netmap_rx_irq(ifp, rxr->me, &processed)) { + EM_RX_UNLOCK(rxr); return (FALSE); + } #endif /* DEV_NETMAP */ for (i = rxr->next_to_check, processed = 0; count != 0;) { diff --git a/freebsd/sys/dev/e1000/if_igb.c b/freebsd/sys/dev/e1000/if_igb.c index e26a867c..09da15ca 100644 --- a/freebsd/sys/dev/e1000/if_igb.c +++ b/freebsd/sys/dev/e1000/if_igb.c @@ -2885,6 +2885,9 @@ igb_setup_msix(struct adapter *adapter) if (queues > maxqueues) queues = maxqueues; + /* reflect correct sysctl value */ + igb_num_queues = queues; + /* ** One vector (RX/TX pair) per queue ** plus an additional for Link interrupt @@ -3909,8 +3912,7 @@ igb_txeof(struct tx_ring *txr) IGB_TX_LOCK_ASSERT(txr); #ifdef DEV_NETMAP - if (netmap_tx_irq(ifp, txr->me | - (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT))) + if (netmap_tx_irq(ifp, txr->me )) return (FALSE); #endif /* DEV_NETMAP */ if (txr->tx_avail == adapter->num_tx_desc) { @@ -4571,13 +4573,13 @@ igb_initialize_receive_units(struct adapter *adapter) * an init() while a netmap client is active must * preserve the rx buffers passed to userspace. * In this driver it means we adjust RDT to - * somthing different from next_to_refresh + * something different from next_to_refresh * (which is not used in netmap mode). */ if (ifp->if_capenable & IFCAP_NETMAP) { struct netmap_adapter *na = NA(adapter->ifp); struct netmap_kring *kring = &na->rx_rings[i]; - int t = rxr->next_to_refresh - kring->nr_hwavail; + int t = rxr->next_to_refresh - nm_kr_rxspace(kring); if (t >= adapter->num_rx_desc) t -= adapter->num_rx_desc; @@ -4765,8 +4767,10 @@ igb_rxeof(struct igb_queue *que, int count, int *done) BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); #ifdef DEV_NETMAP - if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed)) + if (netmap_rx_irq(ifp, rxr->me, &processed)) { + IGB_RX_UNLOCK(rxr); return (FALSE); + } #endif /* DEV_NETMAP */ /* Main clean loop */ diff --git a/freebsd/sys/dev/e1000/if_lem.c b/freebsd/sys/dev/e1000/if_lem.c index 5127445c..64a1bcc0 100644 --- a/freebsd/sys/dev/e1000/if_lem.c +++ b/freebsd/sys/dev/e1000/if_lem.c @@ -2680,7 +2680,7 @@ lem_setup_transmit_structures(struct adapter *adapter) void *addr; addr = PNMB(slot + si, &paddr); - adapter->tx_desc_base[si].buffer_addr = htole64(paddr); + adapter->tx_desc_base[i].buffer_addr = htole64(paddr); /* reload the map for netmap mode */ netmap_load_map(adapter->txtag, tx_buffer->map, addr); } @@ -2987,7 +2987,7 @@ lem_txeof(struct adapter *adapter) EM_TX_LOCK_ASSERT(adapter); #ifdef DEV_NETMAP - if (netmap_tx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT))) + if (netmap_tx_irq(ifp, 0)) return; #endif /* DEV_NETMAP */ if (adapter->num_tx_desc_avail == adapter->num_tx_desc) @@ -3370,7 +3370,7 @@ lem_initialize_receive_unit(struct adapter *adapter) #ifdef DEV_NETMAP /* preserve buffers already made available to clients */ if (ifp->if_capenable & IFCAP_NETMAP) - rctl -= NA(adapter->ifp)->rx_rings[0].nr_hwavail; + rctl -= nm_kr_rxspace(&NA(adapter->ifp)->rx_rings[0]); #endif /* DEV_NETMAP */ E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), rctl); @@ -3456,8 +3456,10 @@ lem_rxeof(struct adapter *adapter, int count, int *done) BUS_DMASYNC_POSTREAD); #ifdef DEV_NETMAP - if (netmap_rx_irq(ifp, 0 | NETMAP_LOCKED_ENTER, &rx_sent)) + if (netmap_rx_irq(ifp, 0, &rx_sent)) { + EM_RX_UNLOCK(adapter); return (FALSE); + } #endif /* DEV_NETMAP */ if (!((current_desc->status) & E1000_RXD_STAT_DD)) { diff --git a/freebsd/sys/dev/fxp/if_fxpreg.h b/freebsd/sys/dev/fxp/if_fxpreg.h index cc764b54..7fd60afd 100644 --- a/freebsd/sys/dev/fxp/if_fxpreg.h +++ b/freebsd/sys/dev/fxp/if_fxpreg.h @@ -250,7 +250,7 @@ struct fxp_cb_ucode { /* * Number of DMA segments in a TxCB. */ -#define FXP_NTXSEG 32 +#define FXP_NTXSEG 35 struct fxp_tbd { uint32_t tb_addr; diff --git a/freebsd/sys/dev/mii/brgphy.c b/freebsd/sys/dev/mii/brgphy.c index de1249c3..75c15774 100644 --- a/freebsd/sys/dev/mii/brgphy.c +++ b/freebsd/sys/dev/mii/brgphy.c @@ -149,6 +149,7 @@ static const struct mii_phydesc brgphys[] = { MII_PHY_DESC(BROADCOM3, BCM5720C), MII_PHY_DESC(BROADCOM3, BCM57765), MII_PHY_DESC(BROADCOM3, BCM57780), + MII_PHY_DESC(BROADCOM4, BCM5725C), MII_PHY_DESC(xxBROADCOM_ALT1, BCM5906), MII_PHY_END }; @@ -934,6 +935,8 @@ brgphy_reset(struct mii_softc *sc) return; } break; + case MII_OUI_BROADCOM4: + return; } ifp = sc->mii_pdata->mii_ifp; diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c index 94eeb844..7dcaa0d5 100644 --- a/freebsd/sys/dev/pci/pci.c +++ b/freebsd/sys/dev/pci/pci.c @@ -164,7 +164,7 @@ static device_method_t pci_methods[] = { DEVMETHOD(bus_delete_resource, pci_delete_resource), DEVMETHOD(bus_alloc_resource, pci_alloc_resource), DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), - DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), + DEVMETHOD(bus_release_resource, pci_release_resource), DEVMETHOD(bus_activate_resource, pci_activate_resource), DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource), DEVMETHOD(bus_child_pnpinfo_str, pci_child_pnpinfo_str_method), @@ -347,6 +347,11 @@ SYSCTL_INT(_hw_pci, OID_AUTO, usb_early_takeover, CTLFLAG_RDTUN, Disable this if you depend on BIOS emulation of USB devices, that is\n\ you use USB devices (like keyboard or mouse) but do not load USB drivers"); +static int pci_clear_bars; +TUNABLE_INT("hw.pci.clear_bars", &pci_clear_bars); +SYSCTL_INT(_hw_pci, OID_AUTO, clear_bars, CTLFLAG_RDTUN, &pci_clear_bars, 0, + "Ignore firmware-assigned resources for BARs."); + static int pci_has_quirk(uint32_t devid, int quirk) { @@ -999,7 +1004,7 @@ pci_read_vpd(device_t pcib, pcicfgregs *cfg) state = -2; break; } - dflen = byte2; + cfg->vpd.vpd_ros[off].len = dflen = byte2; if (dflen == 0 && strncmp(cfg->vpd.vpd_ros[off].keyword, "RV", 2) == 0) { @@ -1200,6 +1205,17 @@ pci_get_vpd_readonly_method(device_t dev, device_t child, const char *kw, return (ENXIO); } +struct pcicfg_vpd * +pci_fetch_vpd_list(device_t dev) +{ + struct pci_devinfo *dinfo = device_get_ivars(dev); + pcicfgregs *cfg = &dinfo->cfg; + + if (!cfg->vpd.vpd_cached && cfg->vpd.vpd_reg != 0) + pci_read_vpd(device_get_parent(device_get_parent(dev)), cfg); + return (&cfg->vpd); +} + /* * Find the requested extended capability and return the offset in * configuration space via the pointer provided. The function returns @@ -2668,7 +2684,7 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl, struct pci_map *pm; pci_addr_t base, map, testval; pci_addr_t start, end, count; - int barlen, basezero, maprange, mapsize, type; + int barlen, basezero, flags, maprange, mapsize, type; uint16_t cmd; struct resource *res; @@ -2774,7 +2790,10 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl, } count = (pci_addr_t)1 << mapsize; - if (basezero || base == pci_mapbase(testval)) { + flags = RF_ALIGNMENT_LOG2(mapsize); + if (prefetch) + flags |= RF_PREFETCHABLE; + if (basezero || base == pci_mapbase(testval) || pci_clear_bars) { start = 0; /* Let the parent decide. */ end = ~0ul; } else { @@ -2790,7 +2809,7 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl, * pci_alloc_resource(). */ res = resource_list_reserve(rl, bus, dev, type, ®, start, end, count, - prefetch ? RF_PREFETCHABLE : 0); + flags); if (pci_do_realloc_bars && res == NULL && (start != 0 || end != ~0ul)) { /* * If the allocation fails, try to allocate a resource for @@ -2801,7 +2820,7 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl, resource_list_delete(rl, type, reg); resource_list_add(rl, type, reg, 0, ~0ul, count); res = resource_list_reserve(rl, bus, dev, type, ®, 0, ~0ul, - count, prefetch ? RF_PREFETCHABLE : 0); + count, flags); } if (res == NULL) { /* @@ -3650,105 +3669,107 @@ static const struct { int class; int subclass; + int report; /* 0 = bootverbose, 1 = always */ const char *desc; } pci_nomatch_tab[] = { - {PCIC_OLD, -1, "old"}, - {PCIC_OLD, PCIS_OLD_NONVGA, "non-VGA display device"}, - {PCIC_OLD, PCIS_OLD_VGA, "VGA-compatible display device"}, - {PCIC_STORAGE, -1, "mass storage"}, - {PCIC_STORAGE, PCIS_STORAGE_SCSI, "SCSI"}, - {PCIC_STORAGE, PCIS_STORAGE_IDE, "ATA"}, - {PCIC_STORAGE, PCIS_STORAGE_FLOPPY, "floppy disk"}, - {PCIC_STORAGE, PCIS_STORAGE_IPI, "IPI"}, - {PCIC_STORAGE, PCIS_STORAGE_RAID, "RAID"}, - {PCIC_STORAGE, PCIS_STORAGE_ATA_ADMA, "ATA (ADMA)"}, - {PCIC_STORAGE, PCIS_STORAGE_SATA, "SATA"}, - {PCIC_STORAGE, PCIS_STORAGE_SAS, "SAS"}, - {PCIC_STORAGE, PCIS_STORAGE_NVM, "NVM"}, - {PCIC_NETWORK, -1, "network"}, - {PCIC_NETWORK, PCIS_NETWORK_ETHERNET, "ethernet"}, - {PCIC_NETWORK, PCIS_NETWORK_TOKENRING, "token ring"}, - {PCIC_NETWORK, PCIS_NETWORK_FDDI, "fddi"}, - {PCIC_NETWORK, PCIS_NETWORK_ATM, "ATM"}, - {PCIC_NETWORK, PCIS_NETWORK_ISDN, "ISDN"}, - {PCIC_DISPLAY, -1, "display"}, - {PCIC_DISPLAY, PCIS_DISPLAY_VGA, "VGA"}, - {PCIC_DISPLAY, PCIS_DISPLAY_XGA, "XGA"}, - {PCIC_DISPLAY, PCIS_DISPLAY_3D, "3D"}, - {PCIC_MULTIMEDIA, -1, "multimedia"}, - {PCIC_MULTIMEDIA, PCIS_MULTIMEDIA_VIDEO, "video"}, - {PCIC_MULTIMEDIA, PCIS_MULTIMEDIA_AUDIO, "audio"}, - {PCIC_MULTIMEDIA, PCIS_MULTIMEDIA_TELE, "telephony"}, - {PCIC_MULTIMEDIA, PCIS_MULTIMEDIA_HDA, "HDA"}, - {PCIC_MEMORY, -1, "memory"}, - {PCIC_MEMORY, PCIS_MEMORY_RAM, "RAM"}, - {PCIC_MEMORY, PCIS_MEMORY_FLASH, "flash"}, - {PCIC_BRIDGE, -1, "bridge"}, - {PCIC_BRIDGE, PCIS_BRIDGE_HOST, "HOST-PCI"}, - {PCIC_BRIDGE, PCIS_BRIDGE_ISA, "PCI-ISA"}, - {PCIC_BRIDGE, PCIS_BRIDGE_EISA, "PCI-EISA"}, - {PCIC_BRIDGE, PCIS_BRIDGE_MCA, "PCI-MCA"}, - {PCIC_BRIDGE, PCIS_BRIDGE_PCI, "PCI-PCI"}, - {PCIC_BRIDGE, PCIS_BRIDGE_PCMCIA, "PCI-PCMCIA"}, - {PCIC_BRIDGE, PCIS_BRIDGE_NUBUS, "PCI-NuBus"}, - {PCIC_BRIDGE, PCIS_BRIDGE_CARDBUS, "PCI-CardBus"}, - {PCIC_BRIDGE, PCIS_BRIDGE_RACEWAY, "PCI-RACEway"}, - {PCIC_SIMPLECOMM, -1, "simple comms"}, - {PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_UART, "UART"}, /* could detect 16550 */ - {PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_PAR, "parallel port"}, - {PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_MULSER, "multiport serial"}, - {PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_MODEM, "generic modem"}, - {PCIC_BASEPERIPH, -1, "base peripheral"}, - {PCIC_BASEPERIPH, PCIS_BASEPERIPH_PIC, "interrupt controller"}, - {PCIC_BASEPERIPH, PCIS_BASEPERIPH_DMA, "DMA controller"}, - {PCIC_BASEPERIPH, PCIS_BASEPERIPH_TIMER, "timer"}, - {PCIC_BASEPERIPH, PCIS_BASEPERIPH_RTC, "realtime clock"}, - {PCIC_BASEPERIPH, PCIS_BASEPERIPH_PCIHOT, "PCI hot-plug controller"}, - {PCIC_BASEPERIPH, PCIS_BASEPERIPH_SDHC, "SD host controller"}, - {PCIC_INPUTDEV, -1, "input device"}, - {PCIC_INPUTDEV, PCIS_INPUTDEV_KEYBOARD, "keyboard"}, - {PCIC_INPUTDEV, PCIS_INPUTDEV_DIGITIZER,"digitizer"}, - {PCIC_INPUTDEV, PCIS_INPUTDEV_MOUSE, "mouse"}, - {PCIC_INPUTDEV, PCIS_INPUTDEV_SCANNER, "scanner"}, - {PCIC_INPUTDEV, PCIS_INPUTDEV_GAMEPORT, "gameport"}, - {PCIC_DOCKING, -1, "docking station"}, - {PCIC_PROCESSOR, -1, "processor"}, - {PCIC_SERIALBUS, -1, "serial bus"}, - {PCIC_SERIALBUS, PCIS_SERIALBUS_FW, "FireWire"}, - {PCIC_SERIALBUS, PCIS_SERIALBUS_ACCESS, "AccessBus"}, - {PCIC_SERIALBUS, PCIS_SERIALBUS_SSA, "SSA"}, - {PCIC_SERIALBUS, PCIS_SERIALBUS_USB, "USB"}, - {PCIC_SERIALBUS, PCIS_SERIALBUS_FC, "Fibre Channel"}, - {PCIC_SERIALBUS, PCIS_SERIALBUS_SMBUS, "SMBus"}, - {PCIC_WIRELESS, -1, "wireless controller"}, - {PCIC_WIRELESS, PCIS_WIRELESS_IRDA, "iRDA"}, - {PCIC_WIRELESS, PCIS_WIRELESS_IR, "IR"}, - {PCIC_WIRELESS, PCIS_WIRELESS_RF, "RF"}, - {PCIC_INTELLIIO, -1, "intelligent I/O controller"}, - {PCIC_INTELLIIO, PCIS_INTELLIIO_I2O, "I2O"}, - {PCIC_SATCOM, -1, "satellite communication"}, - {PCIC_SATCOM, PCIS_SATCOM_TV, "sat TV"}, - {PCIC_SATCOM, PCIS_SATCOM_AUDIO, "sat audio"}, - {PCIC_SATCOM, PCIS_SATCOM_VOICE, "sat voice"}, - {PCIC_SATCOM, PCIS_SATCOM_DATA, "sat data"}, - {PCIC_CRYPTO, -1, "encrypt/decrypt"}, - {PCIC_CRYPTO, PCIS_CRYPTO_NETCOMP, "network/computer crypto"}, - {PCIC_CRYPTO, PCIS_CRYPTO_ENTERTAIN, "entertainment crypto"}, - {PCIC_DASP, -1, "dasp"}, - {PCIC_DASP, PCIS_DASP_DPIO, "DPIO module"}, - {0, 0, NULL} + {PCIC_OLD, -1, 1, "old"}, + {PCIC_OLD, PCIS_OLD_NONVGA, 1, "non-VGA display device"}, + {PCIC_OLD, PCIS_OLD_VGA, 1, "VGA-compatible display device"}, + {PCIC_STORAGE, -1, 1, "mass storage"}, + {PCIC_STORAGE, PCIS_STORAGE_SCSI, 1, "SCSI"}, + {PCIC_STORAGE, PCIS_STORAGE_IDE, 1, "ATA"}, + {PCIC_STORAGE, PCIS_STORAGE_FLOPPY, 1, "floppy disk"}, + {PCIC_STORAGE, PCIS_STORAGE_IPI, 1, "IPI"}, + {PCIC_STORAGE, PCIS_STORAGE_RAID, 1, "RAID"}, + {PCIC_STORAGE, PCIS_STORAGE_ATA_ADMA, 1, "ATA (ADMA)"}, + {PCIC_STORAGE, PCIS_STORAGE_SATA, 1, "SATA"}, + {PCIC_STORAGE, PCIS_STORAGE_SAS, 1, "SAS"}, + {PCIC_STORAGE, PCIS_STORAGE_NVM, 1, "NVM"}, + {PCIC_NETWORK, -1, 1, "network"}, + {PCIC_NETWORK, PCIS_NETWORK_ETHERNET, 1, "ethernet"}, + {PCIC_NETWORK, PCIS_NETWORK_TOKENRING, 1, "token ring"}, + {PCIC_NETWORK, PCIS_NETWORK_FDDI, 1, "fddi"}, + {PCIC_NETWORK, PCIS_NETWORK_ATM, 1, "ATM"}, + {PCIC_NETWORK, PCIS_NETWORK_ISDN, 1, "ISDN"}, + {PCIC_DISPLAY, -1, 1, "display"}, + {PCIC_DISPLAY, PCIS_DISPLAY_VGA, 1, "VGA"}, + {PCIC_DISPLAY, PCIS_DISPLAY_XGA, 1, "XGA"}, + {PCIC_DISPLAY, PCIS_DISPLAY_3D, 1, "3D"}, + {PCIC_MULTIMEDIA, -1, 1, "multimedia"}, + {PCIC_MULTIMEDIA, PCIS_MULTIMEDIA_VIDEO, 1, "video"}, + {PCIC_MULTIMEDIA, PCIS_MULTIMEDIA_AUDIO, 1, "audio"}, + {PCIC_MULTIMEDIA, PCIS_MULTIMEDIA_TELE, 1, "telephony"}, + {PCIC_MULTIMEDIA, PCIS_MULTIMEDIA_HDA, 1, "HDA"}, + {PCIC_MEMORY, -1, 1, "memory"}, + {PCIC_MEMORY, PCIS_MEMORY_RAM, 1, "RAM"}, + {PCIC_MEMORY, PCIS_MEMORY_FLASH, 1, "flash"}, + {PCIC_BRIDGE, -1, 1, "bridge"}, + {PCIC_BRIDGE, PCIS_BRIDGE_HOST, 1, "HOST-PCI"}, + {PCIC_BRIDGE, PCIS_BRIDGE_ISA, 1, "PCI-ISA"}, + {PCIC_BRIDGE, PCIS_BRIDGE_EISA, 1, "PCI-EISA"}, + {PCIC_BRIDGE, PCIS_BRIDGE_MCA, 1, "PCI-MCA"}, + {PCIC_BRIDGE, PCIS_BRIDGE_PCI, 1, "PCI-PCI"}, + {PCIC_BRIDGE, PCIS_BRIDGE_PCMCIA, 1, "PCI-PCMCIA"}, + {PCIC_BRIDGE, PCIS_BRIDGE_NUBUS, 1, "PCI-NuBus"}, + {PCIC_BRIDGE, PCIS_BRIDGE_CARDBUS, 1, "PCI-CardBus"}, + {PCIC_BRIDGE, PCIS_BRIDGE_RACEWAY, 1, "PCI-RACEway"}, + {PCIC_SIMPLECOMM, -1, 1, "simple comms"}, + {PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_UART, 1, "UART"}, /* could detect 16550 */ + {PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_PAR, 1, "parallel port"}, + {PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_MULSER, 1, "multiport serial"}, + {PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_MODEM, 1, "generic modem"}, + {PCIC_BASEPERIPH, -1, 0, "base peripheral"}, + {PCIC_BASEPERIPH, PCIS_BASEPERIPH_PIC, 1, "interrupt controller"}, + {PCIC_BASEPERIPH, PCIS_BASEPERIPH_DMA, 1, "DMA controller"}, + {PCIC_BASEPERIPH, PCIS_BASEPERIPH_TIMER, 1, "timer"}, + {PCIC_BASEPERIPH, PCIS_BASEPERIPH_RTC, 1, "realtime clock"}, + {PCIC_BASEPERIPH, PCIS_BASEPERIPH_PCIHOT, 1, "PCI hot-plug controller"}, + {PCIC_BASEPERIPH, PCIS_BASEPERIPH_SDHC, 1, "SD host controller"}, + {PCIC_INPUTDEV, -1, 1, "input device"}, + {PCIC_INPUTDEV, PCIS_INPUTDEV_KEYBOARD, 1, "keyboard"}, + {PCIC_INPUTDEV, PCIS_INPUTDEV_DIGITIZER,1, "digitizer"}, + {PCIC_INPUTDEV, PCIS_INPUTDEV_MOUSE, 1, "mouse"}, + {PCIC_INPUTDEV, PCIS_INPUTDEV_SCANNER, 1, "scanner"}, + {PCIC_INPUTDEV, PCIS_INPUTDEV_GAMEPORT, 1, "gameport"}, + {PCIC_DOCKING, -1, 1, "docking station"}, + {PCIC_PROCESSOR, -1, 1, "processor"}, + {PCIC_SERIALBUS, -1, 1, "serial bus"}, + {PCIC_SERIALBUS, PCIS_SERIALBUS_FW, 1, "FireWire"}, + {PCIC_SERIALBUS, PCIS_SERIALBUS_ACCESS, 1, "AccessBus"}, + {PCIC_SERIALBUS, PCIS_SERIALBUS_SSA, 1, "SSA"}, + {PCIC_SERIALBUS, PCIS_SERIALBUS_USB, 1, "USB"}, + {PCIC_SERIALBUS, PCIS_SERIALBUS_FC, 1, "Fibre Channel"}, + {PCIC_SERIALBUS, PCIS_SERIALBUS_SMBUS, 0, "SMBus"}, + {PCIC_WIRELESS, -1, 1, "wireless controller"}, + {PCIC_WIRELESS, PCIS_WIRELESS_IRDA, 1, "iRDA"}, + {PCIC_WIRELESS, PCIS_WIRELESS_IR, 1, "IR"}, + {PCIC_WIRELESS, PCIS_WIRELESS_RF, 1, "RF"}, + {PCIC_INTELLIIO, -1, 1, "intelligent I/O controller"}, + {PCIC_INTELLIIO, PCIS_INTELLIIO_I2O, 1, "I2O"}, + {PCIC_SATCOM, -1, 1, "satellite communication"}, + {PCIC_SATCOM, PCIS_SATCOM_TV, 1, "sat TV"}, + {PCIC_SATCOM, PCIS_SATCOM_AUDIO, 1, "sat audio"}, + {PCIC_SATCOM, PCIS_SATCOM_VOICE, 1, "sat voice"}, + {PCIC_SATCOM, PCIS_SATCOM_DATA, 1, "sat data"}, + {PCIC_CRYPTO, -1, 1, "encrypt/decrypt"}, + {PCIC_CRYPTO, PCIS_CRYPTO_NETCOMP, 1, "network/computer crypto"}, + {PCIC_CRYPTO, PCIS_CRYPTO_ENTERTAIN, 1, "entertainment crypto"}, + {PCIC_DASP, -1, 0, "dasp"}, + {PCIC_DASP, PCIS_DASP_DPIO, 1, "DPIO module"}, + {0, 0, 0, NULL} }; void pci_probe_nomatch(device_t dev, device_t child) { - int i; + int i, report; const char *cp, *scp; char *device; /* * Look for a listing for this device in a loaded device database. */ + report = 1; if ((device = pci_describe_device(child)) != NULL) { device_printf(dev, "<%s>", device); free(device, M_DEVBUF); @@ -3763,19 +3784,25 @@ pci_probe_nomatch(device_t dev, device_t child) if (pci_nomatch_tab[i].class == pci_get_class(child)) { if (pci_nomatch_tab[i].subclass == -1) { cp = pci_nomatch_tab[i].desc; + report = pci_nomatch_tab[i].report; } else if (pci_nomatch_tab[i].subclass == pci_get_subclass(child)) { scp = pci_nomatch_tab[i].desc; + report = pci_nomatch_tab[i].report; } } } - device_printf(dev, "<%s%s%s>", - cp ? cp : "", - ((cp != NULL) && (scp != NULL)) ? ", " : "", - scp ? scp : ""); + if (report || bootverbose) { + device_printf(dev, "<%s%s%s>", + cp ? cp : "", + ((cp != NULL) && (scp != NULL)) ? ", " : "", + scp ? scp : ""); + } + } + if (report || bootverbose) { + printf(" at device %d.%d (no driver attached)\n", + pci_get_slot(child), pci_get_function(child)); } - printf(" at device %d.%d (no driver attached)\n", - pci_get_slot(child), pci_get_function(child)); pci_cfg_save(child, device_get_ivars(child), 1); } @@ -4078,7 +4105,6 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid, { struct pci_devinfo *dinfo = device_get_ivars(child); struct resource_list *rl = &dinfo->resources; - struct resource_list_entry *rle; struct resource *res; struct pci_map *pm; pci_addr_t map, testval; @@ -4151,23 +4177,16 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid, * Allocate enough resource, and then write back the * appropriate BAR for that resource. */ - res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, - start, end, count, flags & ~RF_ACTIVE); + resource_list_add(rl, type, *rid, start, end, count); + res = resource_list_reserve(rl, dev, child, type, rid, start, end, + count, flags & ~RF_ACTIVE); if (res == NULL) { + resource_list_delete(rl, type, *rid); device_printf(child, "%#lx bytes of rid %#x res %d failed (%#lx, %#lx).\n", count, *rid, type, start, end); goto out; } - resource_list_add(rl, type, *rid, start, end, count); - rle = resource_list_find(rl, type, *rid); - if (rle == NULL) - panic("pci_reserve_map: unexpectedly can't find resource."); - rle->res = res; - rle->start = rman_get_start(res); - rle->end = rman_get_end(res); - rle->count = count; - rle->flags = RLE_RESERVED; if (bootverbose) device_printf(child, "Lazy allocation of %#lx bytes rid %#x type %d at %#lx\n", @@ -4182,11 +4201,11 @@ struct resource * pci_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { - struct pci_devinfo *dinfo = device_get_ivars(child); - struct resource_list *rl = &dinfo->resources; + struct pci_devinfo *dinfo; + struct resource_list *rl; struct resource_list_entry *rle; struct resource *res; - pcicfgregs *cfg = &dinfo->cfg; + pcicfgregs *cfg; if (device_get_parent(child) != dev) return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, @@ -4195,6 +4214,9 @@ pci_alloc_resource(device_t dev, device_t child, int type, int *rid, /* * Perform lazy resource allocation */ + dinfo = device_get_ivars(child); + rl = &dinfo->resources; + cfg = &dinfo->cfg; switch (type) { case SYS_RES_IRQ: /* @@ -4249,6 +4271,41 @@ pci_alloc_resource(device_t dev, device_t child, int type, int *rid, start, end, count, flags)); } +int +pci_release_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + struct pci_devinfo *dinfo; + struct resource_list *rl; + pcicfgregs *cfg; + + if (device_get_parent(child) != dev) + return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, + type, rid, r)); + + dinfo = device_get_ivars(child); + cfg = &dinfo->cfg; +#ifdef NEW_PCIB + /* + * PCI-PCI bridge I/O window resources are not BARs. For + * those allocations just pass the request up the tree. + */ + if (cfg->hdrtype == PCIM_HDRTYPE_BRIDGE && + (type == SYS_RES_IOPORT || type == SYS_RES_MEMORY)) { + switch (rid) { + case PCIR_IOBASEL_1: + case PCIR_MEMBASE_1: + case PCIR_PMBASEL_1: + return (bus_generic_release_resource(dev, child, type, + rid, r)); + } + } +#endif + + rl = &dinfo->resources; + return (resource_list_release(rl, dev, child, type, rid, r)); +} + int pci_activate_resource(device_t dev, device_t child, int type, int rid, struct resource *r) diff --git a/freebsd/sys/dev/pci/pci_pci.c b/freebsd/sys/dev/pci/pci_pci.c index bfaabf35..6c159aec 100644 --- a/freebsd/sys/dev/pci/pci_pci.c +++ b/freebsd/sys/dev/pci/pci_pci.c @@ -105,13 +105,12 @@ DEFINE_CLASS_0(pcib, pcib_driver, pcib_methods, sizeof(struct pcib_softc)); DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, NULL, NULL); #ifdef NEW_PCIB -/* - * XXX Todo: - * - properly handle the ISA enable bit. If it is set, we should change - * the behavior of the I/O window resource and rman to not allocate the - * blocked ranges (upper 768 bytes of each 1K in the first 64k of the - * I/O port address space). - */ +SYSCTL_DECL(_hw_pci); + +static int pci_clear_pcib; +TUNABLE_INT("hw.pci.clear_pcib", &pci_clear_pcib); +SYSCTL_INT(_hw_pci, OID_AUTO, clear_pcib, CTLFLAG_RDTUN, &pci_clear_pcib, 0, + "Clear firmware-assigned resources for PCI-PCI bridge I/O windows."); /* * Is a resource from a child device sub-allocated from one of our @@ -191,10 +190,183 @@ pcib_write_windows(struct pcib_softc *sc, int mask) } } +/* + * This is used to reject I/O port allocations that conflict with an + * ISA alias range. + */ +static int +pcib_is_isa_range(struct pcib_softc *sc, u_long start, u_long end, u_long count) +{ + u_long next_alias; + + if (!(sc->bridgectl & PCIB_BCR_ISA_ENABLE)) + return (0); + + /* Only check fixed ranges for overlap. */ + if (start + count - 1 != end) + return (0); + + /* ISA aliases are only in the lower 64KB of I/O space. */ + if (start >= 65536) + return (0); + + /* Check for overlap with 0x000 - 0x0ff as a special case. */ + if (start < 0x100) + goto alias; + + /* + * If the start address is an alias, the range is an alias. + * Otherwise, compute the start of the next alias range and + * check if it is before the end of the candidate range. + */ + if ((start & 0x300) != 0) + goto alias; + next_alias = (start & ~0x3fful) | 0x100; + if (next_alias <= end) + goto alias; + return (0); + +alias: + if (bootverbose) + device_printf(sc->dev, + "I/O range %#lx-%#lx overlaps with an ISA alias\n", start, + end); + return (1); +} + +static void +pcib_add_window_resources(struct pcib_window *w, struct resource **res, + int count) +{ + struct resource **newarray; + int error, i; + + newarray = malloc(sizeof(struct resource *) * (w->count + count), + M_DEVBUF, M_WAITOK); + if (w->res != NULL) + bcopy(w->res, newarray, sizeof(struct resource *) * w->count); + bcopy(res, newarray + w->count, sizeof(struct resource *) * count); + free(w->res, M_DEVBUF); + w->res = newarray; + w->count += count; + + for (i = 0; i < count; i++) { + error = rman_manage_region(&w->rman, rman_get_start(res[i]), + rman_get_end(res[i])); + if (error) + panic("Failed to add resource to rman"); + } +} + +typedef void (nonisa_callback)(u_long start, u_long end, void *arg); + +static void +pcib_walk_nonisa_ranges(u_long start, u_long end, nonisa_callback *cb, + void *arg) +{ + u_long next_end; + + /* + * If start is within an ISA alias range, move up to the start + * of the next non-alias range. As a special case, addresses + * in the range 0x000 - 0x0ff should also be skipped since + * those are used for various system I/O devices in ISA + * systems. + */ + if (start <= 65535) { + if (start < 0x100 || (start & 0x300) != 0) { + start &= ~0x3ff; + start += 0x400; + } + } + + /* ISA aliases are only in the lower 64KB of I/O space. */ + while (start <= MIN(end, 65535)) { + next_end = MIN(start | 0xff, end); + cb(start, next_end, arg); + start += 0x400; + } + + if (start <= end) + cb(start, end, arg); +} + +static void +count_ranges(u_long start, u_long end, void *arg) +{ + int *countp; + + countp = arg; + (*countp)++; +} + +struct alloc_state { + struct resource **res; + struct pcib_softc *sc; + int count, error; +}; + +static void +alloc_ranges(u_long start, u_long end, void *arg) +{ + struct alloc_state *as; + struct pcib_window *w; + int rid; + + as = arg; + if (as->error != 0) + return; + + w = &as->sc->io; + rid = w->reg; + if (bootverbose) + device_printf(as->sc->dev, + "allocating non-ISA range %#lx-%#lx\n", start, end); + as->res[as->count] = bus_alloc_resource(as->sc->dev, SYS_RES_IOPORT, + &rid, start, end, end - start + 1, 0); + if (as->res[as->count] == NULL) + as->error = ENXIO; + else + as->count++; +} + +static int +pcib_alloc_nonisa_ranges(struct pcib_softc *sc, u_long start, u_long end) +{ + struct alloc_state as; + int i, new_count; + + /* First, see how many ranges we need. */ + new_count = 0; + pcib_walk_nonisa_ranges(start, end, count_ranges, &new_count); + + /* Second, allocate the ranges. */ + as.res = malloc(sizeof(struct resource *) * new_count, M_DEVBUF, + M_WAITOK); + as.sc = sc; + as.count = 0; + as.error = 0; + pcib_walk_nonisa_ranges(start, end, alloc_ranges, &as); + if (as.error != 0) { + for (i = 0; i < as.count; i++) + bus_release_resource(sc->dev, SYS_RES_IOPORT, + sc->io.reg, as.res[i]); + free(as.res, M_DEVBUF); + return (as.error); + } + KASSERT(as.count == new_count, ("%s: count mismatch", __func__)); + + /* Third, add the ranges to the window. */ + pcib_add_window_resources(&sc->io, as.res, as.count); + free(as.res, M_DEVBUF); + return (0); +} + static void pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type, int flags, pci_addr_t max_address) { + struct resource *res; char buf[64]; int error, rid; @@ -219,9 +391,15 @@ pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type, "initial %s window has too many bits, ignoring\n", w->name); return; } - rid = w->reg; - w->res = bus_alloc_resource(sc->dev, type, &rid, w->base, w->limit, - w->limit - w->base + 1, flags); + if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE) + (void)pcib_alloc_nonisa_ranges(sc, w->base, w->limit); + else { + rid = w->reg; + res = bus_alloc_resource(sc->dev, type, &rid, w->base, w->limit, + w->limit - w->base + 1, flags); + if (res != NULL) + pcib_add_window_resources(w, &res, 1); + } if (w->res == NULL) { device_printf(sc->dev, "failed to allocate initial %s window: %#jx-%#jx\n", @@ -232,11 +410,6 @@ pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type, return; } pcib_activate_window(sc, type); - - error = rman_manage_region(&w->rman, rman_get_start(w->res), - rman_get_end(w->res)); - if (error) - panic("Failed to initialize rman with resource"); } /* @@ -251,6 +424,19 @@ pcib_probe_windows(struct pcib_softc *sc) dev = sc->dev; + if (pci_clear_pcib) { + pci_write_config(dev, PCIR_IOBASEL_1, 0xff, 1); + pci_write_config(dev, PCIR_IOBASEH_1, 0xffff, 2); + pci_write_config(dev, PCIR_IOLIMITL_1, 0, 1); + pci_write_config(dev, PCIR_IOLIMITH_1, 0, 2); + pci_write_config(dev, PCIR_MEMBASE_1, 0xffff, 2); + pci_write_config(dev, PCIR_MEMLIMIT_1, 0, 2); + pci_write_config(dev, PCIR_PMBASEL_1, 0xffff, 2); + pci_write_config(dev, PCIR_PMBASEH_1, 0xffffffff, 4); + pci_write_config(dev, PCIR_PMLIMITL_1, 0, 2); + pci_write_config(dev, PCIR_PMLIMITH_1, 0, 4); + } + /* Determine if the I/O port window is implemented. */ val = pci_read_config(dev, PCIR_IOBASEL_1, 1); if (val == 0) { @@ -543,6 +729,7 @@ pcib_attach_common(device_t dev) struct pcib_softc *sc; struct sysctl_ctx_list *sctx; struct sysctl_oid *soid; + int comma; sc = device_get_softc(dev); sc->dev = dev; @@ -671,10 +858,22 @@ pcib_attach_common(device_t dev) device_printf(dev, " prefetched decode 0x%jx-0x%jx\n", (uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit); #endif - else - device_printf(dev, " no prefetched decode\n"); - if (sc->flags & PCIB_SUBTRACTIVE) - device_printf(dev, " Subtractively decoded bridge.\n"); + if (sc->bridgectl & (PCIB_BCR_ISA_ENABLE | PCIB_BCR_VGA_ENABLE) || + sc->flags & PCIB_SUBTRACTIVE) { + device_printf(dev, " special decode "); + comma = 0; + if (sc->bridgectl & PCIB_BCR_ISA_ENABLE) { + printf("ISA"); + comma = 1; + } + if (sc->bridgectl & PCIB_BCR_VGA_ENABLE) { + printf("%sVGA", comma ? ", " : ""); + comma = 1; + } + if (sc->flags & PCIB_SUBTRACTIVE) + printf("%ssubtractive", comma ? ", " : ""); + printf("\n"); + } } /* @@ -821,23 +1020,197 @@ pcib_suballoc_resource(struct pcib_softc *sc, struct pcib_window *w, return (res); } +/* Allocate a fresh resource range for an unconfigured window. */ +static int +pcib_alloc_new_window(struct pcib_softc *sc, struct pcib_window *w, int type, + u_long start, u_long end, u_long count, u_int flags) +{ + struct resource *res; + u_long base, limit, wmask; + int rid; + + /* + * If this is an I/O window on a bridge with ISA enable set + * and the start address is below 64k, then try to allocate an + * initial window of 0x1000 bytes long starting at address + * 0xf000 and walking down. Note that if the original request + * was larger than the non-aliased range size of 0x100 our + * caller would have raised the start address up to 64k + * already. + */ + if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE && + start < 65536) { + for (base = 0xf000; (long)base >= 0; base -= 0x1000) { + limit = base + 0xfff; + + /* + * Skip ranges that wouldn't work for the + * original request. Note that the actual + * window that overlaps are the non-alias + * ranges within [base, limit], so this isn't + * quite a simple comparison. + */ + if (start + count > limit - 0x400) + continue; + if (base == 0) { + /* + * The first open region for the window at + * 0 is 0x400-0x4ff. + */ + if (end - count + 1 < 0x400) + continue; + } else { + if (end - count + 1 < base) + continue; + } + + if (pcib_alloc_nonisa_ranges(sc, base, limit) == 0) { + w->base = base; + w->limit = limit; + return (0); + } + } + return (ENOSPC); + } + + wmask = (1ul << w->step) - 1; + if (RF_ALIGNMENT(flags) < w->step) { + flags &= ~RF_ALIGNMENT_MASK; + flags |= RF_ALIGNMENT_LOG2(w->step); + } + start &= ~wmask; + end |= wmask; + count = roundup2(count, 1ul << w->step); + rid = w->reg; + res = bus_alloc_resource(sc->dev, type, &rid, start, end, count, + flags & ~RF_ACTIVE); + if (res == NULL) + return (ENOSPC); + pcib_add_window_resources(w, &res, 1); + pcib_activate_window(sc, type); + w->base = rman_get_start(res); + w->limit = rman_get_end(res); + return (0); +} + +/* Try to expand an existing window to the requested base and limit. */ +static int +pcib_expand_window(struct pcib_softc *sc, struct pcib_window *w, int type, + u_long base, u_long limit) +{ + struct resource *res; + int error, i, force_64k_base; + + KASSERT(base <= w->base && limit >= w->limit, + ("attempting to shrink window")); + + /* + * XXX: pcib_grow_window() doesn't try to do this anyway and + * the error handling for all the edge cases would be tedious. + */ + KASSERT(limit == w->limit || base == w->base, + ("attempting to grow both ends of a window")); + + /* + * Yet more special handling for requests to expand an I/O + * window behind an ISA-enabled bridge. Since I/O windows + * have to grow in 0x1000 increments and the end of the 0xffff + * range is an alias, growing a window below 64k will always + * result in allocating new resources and never adjusting an + * existing resource. + */ + if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE && + (limit <= 65535 || (base <= 65535 && base != w->base))) { + KASSERT(limit == w->limit || limit <= 65535, + ("attempting to grow both ends across 64k ISA alias")); + + if (base != w->base) + error = pcib_alloc_nonisa_ranges(sc, base, w->base - 1); + else + error = pcib_alloc_nonisa_ranges(sc, w->limit + 1, + limit); + if (error == 0) { + w->base = base; + w->limit = limit; + } + return (error); + } + + /* + * Find the existing resource to adjust. Usually there is only one, + * but for an ISA-enabled bridge we might be growing the I/O window + * above 64k and need to find the existing resource that maps all + * of the area above 64k. + */ + for (i = 0; i < w->count; i++) { + if (rman_get_end(w->res[i]) == w->limit) + break; + } + KASSERT(i != w->count, ("did not find existing resource")); + res = w->res[i]; + + /* + * Usually the resource we found should match the window's + * existing range. The one exception is the ISA-enabled case + * mentioned above in which case the resource should start at + * 64k. + */ + if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE && + w->base <= 65535) { + KASSERT(rman_get_start(res) == 65536, + ("existing resource mismatch")); + force_64k_base = 1; + } else { + KASSERT(w->base == rman_get_start(res), + ("existing resource mismatch")); + force_64k_base = 0; + } + + error = bus_adjust_resource(sc->dev, type, res, force_64k_base ? + rman_get_start(res) : base, limit); + if (error) + return (error); + + /* Add the newly allocated region to the resource manager. */ + if (w->base != base) { + error = rman_manage_region(&w->rman, base, w->base - 1); + w->base = base; + } else { + error = rman_manage_region(&w->rman, w->limit + 1, limit); + w->limit = limit; + } + if (error) { + if (bootverbose) + device_printf(sc->dev, + "failed to expand %s resource manager\n", w->name); + (void)bus_adjust_resource(sc->dev, type, res, force_64k_base ? + rman_get_start(res) : w->base, w->limit); + } + return (error); +} + /* * Attempt to grow a window to make room for a given resource request. - * The 'step' parameter is log_2 of the desired I/O window's alignment. */ static int pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type, u_long start, u_long end, u_long count, u_int flags) { u_long align, start_free, end_free, front, back, wmask; - int error, rid; + int error; /* * Clamp the desired resource range to the maximum address * this window supports. Reject impossible requests. + * + * For I/O port requests behind a bridge with the ISA enable + * bit set, force large allocations to start above 64k. */ if (!w->valid) return (EINVAL); + if (sc->bridgectl & PCIB_BCR_ISA_ENABLE && count > 0x100 && + start < 65536) + start = 65536; if (end > w->rman.rm_end) end = w->rman.rm_end; if (start + count - 1 > end || start + count < start) @@ -849,40 +1222,19 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type, * aligned space for this resource. */ if (w->res == NULL) { - if (RF_ALIGNMENT(flags) < w->step) { - flags &= ~RF_ALIGNMENT_MASK; - flags |= RF_ALIGNMENT_LOG2(w->step); - } - start &= ~wmask; - end |= wmask; - count = roundup2(count, 1ul << w->step); - rid = w->reg; - w->res = bus_alloc_resource(sc->dev, type, &rid, start, end, - count, flags & ~RF_ACTIVE); - if (w->res == NULL) { + error = pcib_alloc_new_window(sc, w, type, start, end, count, + flags); + if (error) { if (bootverbose) device_printf(sc->dev, "failed to allocate initial %s window (%#lx-%#lx,%#lx)\n", w->name, start, end, count); - return (ENXIO); + return (error); } if (bootverbose) device_printf(sc->dev, - "allocated initial %s window of %#lx-%#lx\n", - w->name, rman_get_start(w->res), - rman_get_end(w->res)); - error = rman_manage_region(&w->rman, rman_get_start(w->res), - rman_get_end(w->res)); - if (error) { - if (bootverbose) - device_printf(sc->dev, - "failed to add initial %s window to rman\n", - w->name); - bus_release_resource(sc->dev, type, w->reg, w->res); - w->res = NULL; - return (error); - } - pcib_activate_window(sc, type); + "allocated initial %s window of %#jx-%#jx\n", + w->name, (uintmax_t)w->base, (uintmax_t)w->limit); goto updatewin; } @@ -896,6 +1248,11 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type, * edge of the window, grow from the inner edge of the free * region. Otherwise grow from the window boundary. * + * Growing an I/O window below 64k for a bridge with the ISA + * enable bit doesn't require any special magic as the step + * size of an I/O window (1k) always includes multiple + * non-alias ranges when it is grown in either direction. + * * XXX: Special case: if w->res is completely empty and the * request size is larger than w->res, we should find the * optimal aligned buffer containing w->res and allocate that. @@ -905,10 +1262,10 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type, "attempting to grow %s window for (%#lx-%#lx,%#lx)\n", w->name, start, end, count); align = 1ul << RF_ALIGNMENT(flags); - if (start < rman_get_start(w->res)) { + if (start < w->base) { if (rman_first_free_region(&w->rman, &start_free, &end_free) != - 0 || start_free != rman_get_start(w->res)) - end_free = rman_get_start(w->res); + 0 || start_free != w->base) + end_free = w->base; if (end_free > end) end_free = end + 1; @@ -929,15 +1286,15 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type, printf("\tfront candidate range: %#lx-%#lx\n", front, end_free); front &= ~wmask; - front = rman_get_start(w->res) - front; + front = w->base - front; } else front = 0; } else front = 0; - if (end > rman_get_end(w->res)) { + if (end > w->limit) { if (rman_last_free_region(&w->rman, &start_free, &end_free) != - 0 || end_free != rman_get_end(w->res)) - start_free = rman_get_end(w->res) + 1; + 0 || end_free != w->limit) + start_free = w->limit + 1; if (start_free < start) start_free = start; @@ -957,7 +1314,7 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type, printf("\tback candidate range: %#lx-%#lx\n", start_free, back); back |= wmask; - back -= rman_get_end(w->res); + back -= w->limit; } else back = 0; } else @@ -970,16 +1327,14 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type, error = ENOSPC; while (front != 0 || back != 0) { if (front != 0 && (front <= back || back == 0)) { - error = bus_adjust_resource(sc->dev, type, w->res, - rman_get_start(w->res) - front, - rman_get_end(w->res)); + error = pcib_expand_window(sc, w, type, w->base - front, + w->limit); if (error == 0) break; front = 0; } else { - error = bus_adjust_resource(sc->dev, type, w->res, - rman_get_start(w->res), - rman_get_end(w->res) + back); + error = pcib_expand_window(sc, w, type, w->base, + w->limit + back); if (error == 0) break; back = 0; @@ -989,32 +1344,11 @@ pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type, if (error) return (error); if (bootverbose) - device_printf(sc->dev, "grew %s window to %#lx-%#lx\n", - w->name, rman_get_start(w->res), rman_get_end(w->res)); - - /* Add the newly allocated region to the resource manager. */ - if (w->base != rman_get_start(w->res)) { - KASSERT(w->limit == rman_get_end(w->res), ("both ends moved")); - error = rman_manage_region(&w->rman, rman_get_start(w->res), - w->base - 1); - } else { - KASSERT(w->limit != rman_get_end(w->res), - ("neither end moved")); - error = rman_manage_region(&w->rman, w->limit + 1, - rman_get_end(w->res)); - } - if (error) { - if (bootverbose) - device_printf(sc->dev, - "failed to expand %s resource manager\n", w->name); - bus_adjust_resource(sc->dev, type, w->res, w->base, w->limit); - return (error); - } + device_printf(sc->dev, "grew %s window to %#jx-%#jx\n", + w->name, (uintmax_t)w->base, (uintmax_t)w->limit); updatewin: - /* Save the new window. */ - w->base = rman_get_start(w->res); - w->limit = rman_get_end(w->res); + /* Write the new window. */ KASSERT((w->base & wmask) == 0, ("start address is not aligned")); KASSERT((w->limit & wmask) == wmask, ("end address is not aligned")); pcib_write_windows(sc, w->mask); @@ -1050,6 +1384,8 @@ pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, switch (type) { case SYS_RES_IOPORT: + if (pcib_is_isa_range(sc, start, end, count)) + return (NULL); r = pcib_suballoc_resource(sc, &sc->io, child, type, rid, start, end, count, flags); if (r != NULL || (sc->flags & PCIB_SUBTRACTIVE) != 0) diff --git a/freebsd/sys/dev/pci/pci_private.h b/freebsd/sys/dev/pci/pci_private.h index b8e446ea..92f36d5c 100644 --- a/freebsd/sys/dev/pci/pci_private.h +++ b/freebsd/sys/dev/pci/pci_private.h @@ -91,6 +91,8 @@ int pci_msix_count_method(device_t dev, device_t child); struct resource *pci_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags); +int pci_release_resource(device_t dev, device_t child, int type, + int rid, struct resource *r); int pci_activate_resource(device_t dev, device_t child, int type, int rid, struct resource *r); int pci_deactivate_resource(device_t dev, device_t child, int type, diff --git a/freebsd/sys/dev/pci/pci_user.c b/freebsd/sys/dev/pci/pci_user.c index 63d64c39..dc22106c 100644 --- a/freebsd/sys/dev/pci/pci_user.c +++ b/freebsd/sys/dev/pci/pci_user.c @@ -408,6 +408,89 @@ pci_conf_match_old32(struct pci_match_conf_old32 *matches, int num_matches, #endif /* COMPAT_FREEBSD32 */ #endif /* PRE7_COMPAT */ +static int +pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio) +{ + struct pci_vpd_element vpd_element, *vpd_user; + struct pcicfg_vpd *vpd; + size_t len; + int error, i; + + vpd = pci_fetch_vpd_list(dev); + if (vpd->vpd_reg == 0 || vpd->vpd_ident == NULL) + return (ENXIO); + + /* + * Calculate the amount of space needed in the data buffer. An + * identifier element is always present followed by the read-only + * and read-write keywords. + */ + len = sizeof(struct pci_vpd_element) + strlen(vpd->vpd_ident); + for (i = 0; i < vpd->vpd_rocnt; i++) + len += sizeof(struct pci_vpd_element) + vpd->vpd_ros[i].len; + for (i = 0; i < vpd->vpd_wcnt; i++) + len += sizeof(struct pci_vpd_element) + vpd->vpd_w[i].len; + + if (lvio->plvi_len == 0) { + lvio->plvi_len = len; + return (0); + } + if (lvio->plvi_len < len) { + lvio->plvi_len = len; + return (ENOMEM); + } + + /* + * Copyout the identifier string followed by each keyword and + * value. + */ + vpd_user = lvio->plvi_data; + vpd_element.pve_keyword[0] = '\0'; + vpd_element.pve_keyword[1] = '\0'; + vpd_element.pve_flags = PVE_FLAG_IDENT; + vpd_element.pve_datalen = strlen(vpd->vpd_ident); + error = copyout(&vpd_element, vpd_user, sizeof(vpd_element)); + if (error) + return (error); + error = copyout(vpd->vpd_ident, vpd_user->pve_data, + strlen(vpd->vpd_ident)); + if (error) + return (error); + vpd_user = PVE_NEXT(vpd_user); + vpd_element.pve_flags = 0; + for (i = 0; i < vpd->vpd_rocnt; i++) { + vpd_element.pve_keyword[0] = vpd->vpd_ros[i].keyword[0]; + vpd_element.pve_keyword[1] = vpd->vpd_ros[i].keyword[1]; + vpd_element.pve_datalen = vpd->vpd_ros[i].len; + error = copyout(&vpd_element, vpd_user, sizeof(vpd_element)); + if (error) + return (error); + error = copyout(vpd->vpd_ros[i].value, vpd_user->pve_data, + vpd->vpd_ros[i].len); + if (error) + return (error); + vpd_user = PVE_NEXT(vpd_user); + } + vpd_element.pve_flags = PVE_FLAG_RW; + for (i = 0; i < vpd->vpd_wcnt; i++) { + vpd_element.pve_keyword[0] = vpd->vpd_w[i].keyword[0]; + vpd_element.pve_keyword[1] = vpd->vpd_w[i].keyword[1]; + vpd_element.pve_datalen = vpd->vpd_w[i].len; + error = copyout(&vpd_element, vpd_user, sizeof(vpd_element)); + if (error) + return (error); + error = copyout(vpd->vpd_w[i].value, vpd_user->pve_data, + vpd->vpd_w[i].len); + if (error) + return (error); + vpd_user = PVE_NEXT(vpd_user); + } + KASSERT((char *)vpd_user - (char *)lvio->plvi_data == len, + ("length mismatch")); + lvio->plvi_len = len; + return (0); +} + static int pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) { @@ -419,6 +502,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t struct pci_devinfo *dinfo; struct pci_io *io; struct pci_bar_io *bio; + struct pci_list_vpd_io *lvio; struct pci_match_conf *pattern_buf; struct pci_map *pm; size_t confsz, iolen, pbufsz; @@ -435,19 +519,29 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t struct pci_match_conf_old *pattern_buf_old = NULL; io_old = NULL; +#endif - if (!(flag & FWRITE) && cmd != PCIOCGETBAR && - cmd != PCIOCGETCONF && cmd != PCIOCGETCONF_OLD) - return EPERM; -#else - if (!(flag & FWRITE) && cmd != PCIOCGETBAR && cmd != PCIOCGETCONF) - return EPERM; + if (!(flag & FWRITE)) { + switch (cmd) { +#ifdef PRE7_COMPAT +#ifdef COMPAT_FREEBSD32 + case PCIOCGETCONF_OLD32: #endif + case PCIOCGETCONF_OLD: +#endif + case PCIOCGETCONF: + case PCIOCGETBAR: + case PCIOCLISTVPD: + break; + default: + return (EPERM); + } + } - switch(cmd) { + switch (cmd) { #ifdef PRE7_COMPAT #ifdef COMPAT_FREEBSD32 - case PCIOCGETCONF_OLD32: + case PCIOCGETCONF_OLD32: cio32 = (struct pci_conf_io32 *)data; cio = malloc(sizeof(struct pci_conf_io), M_TEMP, M_WAITOK); cio->pat_buf_len = cio32->pat_buf_len; @@ -468,7 +562,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t cio = (struct pci_conf_io *)data; } - switch(cmd) { + switch (cmd) { #ifdef PRE7_COMPAT #ifdef COMPAT_FREEBSD32 case PCIOCGETCONF_OLD32: @@ -914,6 +1008,22 @@ getconfexit: else error = ENODEV; break; + case PCIOCLISTVPD: + lvio = (struct pci_list_vpd_io *)data; + + /* + * Assume that the user-level bus number is + * in fact the physical PCI bus number. + */ + pcidev = pci_find_dbsf(lvio->plvi_sel.pc_domain, + lvio->plvi_sel.pc_bus, lvio->plvi_sel.pc_dev, + lvio->plvi_sel.pc_func); + if (pcidev == NULL) { + error = ENODEV; + break; + } + error = pci_list_vpd(pcidev, lvio); + break; default: error = ENOTTY; break; diff --git a/freebsd/sys/dev/pci/pcib_private.h b/freebsd/sys/dev/pci/pcib_private.h index 79135afa..e9d4c4bf 100644 --- a/freebsd/sys/dev/pci/pcib_private.h +++ b/freebsd/sys/dev/pci/pcib_private.h @@ -73,7 +73,8 @@ struct pcib_window { pci_addr_t base; /* base address */ pci_addr_t limit; /* topmost address */ struct rman rman; - struct resource *res; + struct resource **res; + int count; /* size of 'res' array */ int reg; /* resource id from parent */ int valid; int mask; /* WIN_* bitmask of this window */ diff --git a/freebsd/sys/dev/pci/pcireg.h b/freebsd/sys/dev/pci/pcireg.h index ef351356..f2d1ccbe 100644 --- a/freebsd/sys/dev/pci/pcireg.h +++ b/freebsd/sys/dev/pci/pcireg.h @@ -752,8 +752,17 @@ #define PCIEM_SLOT_STA_EIS 0x0080 #define PCIEM_SLOT_STA_DLLSC 0x0100 #define PCIER_ROOT_CTL 0x1c +#define PCIEM_ROOT_CTL_SERR_CORR 0x0001 +#define PCIEM_ROOT_CTL_SERR_NONFATAL 0x0002 +#define PCIEM_ROOT_CTL_SERR_FATAL 0x0004 +#define PCIEM_ROOT_CTL_PME 0x0008 +#define PCIEM_ROOT_CTL_CRS_VIS 0x0010 #define PCIER_ROOT_CAP 0x1e +#define PCIEM_ROOT_CAP_CRS_VIS 0x0001 #define PCIER_ROOT_STA 0x20 +#define PCIEM_ROOT_STA_PME_REQID_MASK 0x0000ffff +#define PCIEM_ROOT_STA_PME_STATUS 0x00010000 +#define PCIEM_ROOT_STA_PME_PEND 0x00020000 #define PCIER_DEVICE_CAP2 0x24 #define PCIER_DEVICE_CTL2 0x28 #define PCIEM_CTL2_COMP_TIMEOUT_VAL 0x000f diff --git a/freebsd/sys/dev/pci/pcivar.h b/freebsd/sys/dev/pci/pcivar.h index 84e7c871..a951ca66 100644 --- a/freebsd/sys/dev/pci/pcivar.h +++ b/freebsd/sys/dev/pci/pcivar.h @@ -57,6 +57,7 @@ struct pci_map { struct vpd_readonly { char keyword[2]; char *value; + int len; }; struct vpd_write { @@ -491,5 +492,13 @@ extern uint32_t pci_generation; struct pci_map *pci_find_bar(device_t dev, int reg); int pci_bar_enabled(device_t dev, struct pci_map *pm); +struct pcicfg_vpd *pci_fetch_vpd_list(device_t dev); + +#define VGA_PCI_BIOS_SHADOW_ADDR 0xC0000 +#define VGA_PCI_BIOS_SHADOW_SIZE 131072 + +int vga_pci_is_boot_display(device_t dev); +void * vga_pci_map_bios(device_t dev, size_t *size); +void vga_pci_unmap_bios(device_t dev, void *bios); #endif /* _PCIVAR_H_ */ diff --git a/freebsd/sys/dev/re/if_re.c b/freebsd/sys/dev/re/if_re.c index cde6bcee..99751374 100644 --- a/freebsd/sys/dev/re/if_re.c +++ b/freebsd/sys/dev/re/if_re.c @@ -183,7 +183,7 @@ static const struct rl_type re_devs[] = { { RT_VENDORID, RT_DEVICEID_8101E, 0, "RealTek 810xE PCIe 10/100baseTX" }, { RT_VENDORID, RT_DEVICEID_8168, 0, - "RealTek 8168/8111 B/C/CP/D/DP/E/F PCIe Gigabit Ethernet" }, + "RealTek 8168/8111 B/C/CP/D/DP/E/F/G PCIe Gigabit Ethernet" }, { RT_VENDORID, RT_DEVICEID_8169, 0, "RealTek 8169/8169S/8169SB(L)/8110S/8110SB(L) Gigabit Ethernet" }, { RT_VENDORID, RT_DEVICEID_8169SC, 0, @@ -225,6 +225,7 @@ static const struct rl_hwrev re_hwrevs[] = { { RL_HWREV_8402, RL_8169, "8402", RL_MTU }, { RL_HWREV_8105E, RL_8169, "8105E", RL_MTU }, { RL_HWREV_8105E_SPIN1, RL_8169, "8105E", RL_MTU }, + { RL_HWREV_8106E, RL_8169, "8106E", RL_MTU }, { RL_HWREV_8168B_SPIN2, RL_8169, "8168", RL_JUMBO_MTU }, { RL_HWREV_8168B_SPIN3, RL_8169, "8168", RL_JUMBO_MTU }, { RL_HWREV_8168C, RL_8169, "8168C/8111C", RL_JUMBO_MTU_6K }, @@ -234,8 +235,12 @@ static const struct rl_hwrev re_hwrevs[] = { { RL_HWREV_8168DP, RL_8169, "8168DP/8111DP", RL_JUMBO_MTU_9K }, { RL_HWREV_8168E, RL_8169, "8168E/8111E", RL_JUMBO_MTU_9K}, { RL_HWREV_8168E_VL, RL_8169, "8168E/8111E-VL", RL_JUMBO_MTU_6K}, + { RL_HWREV_8168EP, RL_8169, "8168EP/8111EP", RL_JUMBO_MTU_9K}, { RL_HWREV_8168F, RL_8169, "8168F/8111F", RL_JUMBO_MTU_9K}, + { RL_HWREV_8168G, RL_8169, "8168G/8111G", RL_JUMBO_MTU_9K}, + { RL_HWREV_8168GU, RL_8169, "8168GU/8111GU", RL_JUMBO_MTU_9K}, { RL_HWREV_8411, RL_8169, "8411", RL_JUMBO_MTU_9K}, + { RL_HWREV_8411B, RL_8169, "8411B", RL_JUMBO_MTU_9K}, { 0, 0, NULL, 0 } }; @@ -652,6 +657,10 @@ re_set_rxmode(struct rl_softc *sc) ifp = sc->rl_ifp; rxfilt = RL_RXCFG_CONFIG | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_BROAD; + if ((sc->rl_flags & RL_FLAG_EARLYOFF) != 0) + rxfilt |= RL_RXCFG_EARLYOFF; + else if ((sc->rl_flags & RL_FLAG_EARLYOFFV2) != 0) + rxfilt |= RL_RXCFG_EARLYOFFV2; if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) { if (ifp->if_flags & IFF_PROMISC) @@ -1261,7 +1270,7 @@ re_attach(device_t dev) msic = 0; /* Prefer MSI-X to MSI. */ if (msixc > 0) { - msixc = 1; + msixc = RL_MSI_MESSAGES; rid = PCIR_BAR(4); sc->rl_res_pba = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); @@ -1271,7 +1280,7 @@ re_attach(device_t dev) } if (sc->rl_res_pba != NULL && pci_alloc_msix(dev, &msixc) == 0) { - if (msixc == 1) { + if (msixc == RL_MSI_MESSAGES) { device_printf(dev, "Using %d MSI-X message\n", msixc); sc->rl_flags |= RL_FLAG_MSIX; @@ -1288,7 +1297,7 @@ re_attach(device_t dev) } /* Prefer MSI to INTx. */ if (msixc == 0 && msic > 0) { - msic = 1; + msic = RL_MSI_MESSAGES; if (pci_alloc_msi(dev, &msic) == 0) { if (msic == RL_MSI_MESSAGES) { device_printf(dev, "Using %d MSI message\n", @@ -1369,10 +1378,11 @@ re_attach(device_t dev) break; default: device_printf(dev, "Chip rev. 0x%08x\n", hwrev & 0x7c800000); + sc->rl_macrev = hwrev & 0x00700000; hwrev &= RL_TXCFG_HWREV; break; } - device_printf(dev, "MAC rev. 0x%08x\n", hwrev & 0x00700000); + device_printf(dev, "MAC rev. 0x%08x\n", sc->rl_macrev); while (hw_rev->rl_desc != NULL) { if (hw_rev->rl_rev == hwrev) { sc->rl_type = hw_rev->rl_type; @@ -1410,6 +1420,7 @@ re_attach(device_t dev) case RL_HWREV_8401E: case RL_HWREV_8105E: case RL_HWREV_8105E_SPIN1: + case RL_HWREV_8106E: sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHYWAKE_PM | RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_FASTETHER | RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD; @@ -1431,7 +1442,7 @@ re_attach(device_t dev) sc->rl_flags |= RL_FLAG_MACSLEEP; /* FALLTHROUGH */ case RL_HWREV_8168C: - if ((hwrev & 0x00700000) == 0x00200000) + if (sc->rl_macrev == 0x00200000) sc->rl_flags |= RL_FLAG_MACSLEEP; /* FALLTHROUGH */ case RL_HWREV_8168CP: @@ -1458,12 +1469,35 @@ re_attach(device_t dev) break; case RL_HWREV_8168E_VL: case RL_HWREV_8168F: + sc->rl_flags |= RL_FLAG_EARLYOFF; + /* FALLTHROUGH */ case RL_HWREV_8411: sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 | RL_FLAG_CMDSTOP_WAIT_TXQ | RL_FLAG_WOL_MANLINK; break; + case RL_HWREV_8168EP: + case RL_HWREV_8168G: + case RL_HWREV_8411B: + sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR | + RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP | + RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 | + RL_FLAG_CMDSTOP_WAIT_TXQ | RL_FLAG_WOL_MANLINK | + RL_FLAG_EARLYOFFV2 | RL_FLAG_RXDV_GATED; + break; + case RL_HWREV_8168GU: + if (pci_get_device(dev) == RT_DEVICEID_8101E) { + /* RTL8106EUS */ + sc->rl_flags |= RL_FLAG_FASTETHER; + } else + sc->rl_flags |= RL_FLAG_JUMBOV2 | RL_FLAG_WOL_MANLINK; + + sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR | + RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP | + RL_FLAG_AUTOPAD | RL_FLAG_CMDSTOP_WAIT_TXQ | + RL_FLAG_EARLYOFFV2 | RL_FLAG_RXDV_GATED; + break; case RL_HWREV_8169_8110SB: case RL_HWREV_8169_8110SBL: case RL_HWREV_8169_8110SC: @@ -1586,16 +1620,18 @@ re_attach(device_t dev) ifp->if_start = re_start; /* * RTL8168/8111C generates wrong IP checksummed frame if the - * packet has IP options so disable TX IP checksum offloading. + * packet has IP options so disable TX checksum offloading. */ if (sc->rl_hwrev->rl_rev == RL_HWREV_8168C || sc->rl_hwrev->rl_rev == RL_HWREV_8168C_SPIN2 || - sc->rl_hwrev->rl_rev == RL_HWREV_8168CP) - ifp->if_hwassist = CSUM_TCP | CSUM_UDP; - else + sc->rl_hwrev->rl_rev == RL_HWREV_8168CP) { + ifp->if_hwassist = 0; + ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_TSO4; + } else { ifp->if_hwassist = CSUM_IP | CSUM_TCP | CSUM_UDP; + ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4; + } ifp->if_hwassist |= CSUM_TSO; - ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4; ifp->if_capenable = ifp->if_capabilities; ifp->if_init = re_init; IFQ_SET_MAXLEN(&ifp->if_snd, RL_IFQ_MAXLEN); @@ -2114,8 +2150,7 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp) ifp = sc->rl_ifp; #ifdef DEV_NETMAP - if (netmap_rx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT), - &rx_npkts)) + if (netmap_rx_irq(ifp, 0, &rx_npkts)) return 0; #endif /* DEV_NETMAP */ if (ifp->if_mtu > RL_MTU && (sc->rl_flags & RL_FLAG_JUMBOV2) != 0) @@ -2360,7 +2395,7 @@ re_txeof(struct rl_softc *sc) ifp = sc->rl_ifp; #ifdef DEV_NETMAP - if (netmap_tx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT))) + if (netmap_tx_irq(ifp, 0)) return; #endif /* DEV_NETMAP */ /* Invalidate the TX descriptor list */ @@ -3151,6 +3186,10 @@ re_init_locked(struct rl_softc *sc) CSR_WRITE_4(sc, RL_TXLIST_ADDR_LO, RL_ADDR_LO(sc->rl_ldata.rl_tx_list_addr)); + if ((sc->rl_flags & RL_FLAG_RXDV_GATED) != 0) + CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) & + ~0x00080000); + /* * Enable transmit and receive. */ @@ -3328,13 +3367,14 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data) struct rl_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; - uint32_t rev; int error = 0; switch (command) { case SIOCSIFMTU: if (ifr->ifr_mtu < ETHERMIN || - ifr->ifr_mtu > sc->rl_hwrev->rl_max_mtu) { + ifr->ifr_mtu > sc->rl_hwrev->rl_max_mtu || + ((sc->rl_flags & RL_FLAG_FASTETHER) != 0 && + ifr->ifr_mtu > RL_MTU)) { error = EINVAL; break; } @@ -3415,15 +3455,9 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if ((mask & IFCAP_TXCSUM) != 0 && (ifp->if_capabilities & IFCAP_TXCSUM) != 0) { ifp->if_capenable ^= IFCAP_TXCSUM; - if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) { - rev = sc->rl_hwrev->rl_rev; - if (rev == RL_HWREV_8168C || - rev == RL_HWREV_8168C_SPIN2 || - rev == RL_HWREV_8168CP) - ifp->if_hwassist |= CSUM_TCP | CSUM_UDP; - else - ifp->if_hwassist |= RE_CSUM_FEATURES; - } else + if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) + ifp->if_hwassist |= RE_CSUM_FEATURES; + else ifp->if_hwassist &= ~RE_CSUM_FEATURES; reinit = 1; } diff --git a/freebsd/sys/dev/usb/controller/ehci.c b/freebsd/sys/dev/usb/controller/ehci.c index 456aff61..528e4a02 100644 --- a/freebsd/sys/dev/usb/controller/ehci.c +++ b/freebsd/sys/dev/usb/controller/ehci.c @@ -258,7 +258,7 @@ ehci_init_sub(struct ehci_softc *sc) DPRINTF("HCC uses 64-bit structures\n"); /* MUST clear segment register if 64 bit capable */ - EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0); + EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0); } usbd_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res); @@ -1197,9 +1197,16 @@ ehci_non_isoc_done_sub(struct usb_xfer *xfer) (status & EHCI_QTD_PINGSTATE) ? "[PING]" : ""); } #endif - - return ((status & EHCI_QTD_HALTED) ? - USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION); + if (status & EHCI_QTD_HALTED) { + if ((xfer->xroot->udev->parent_hs_hub != NULL) || + (xfer->xroot->udev->address != 0)) { + /* try to separate I/O errors from STALL */ + if (EHCI_QTD_GET_CERR(status) == 0) + return (USB_ERR_IOERROR); + } + return (USB_ERR_STALLED); + } + return (USB_ERR_NORMAL_COMPLETION); } static void @@ -1653,12 +1660,17 @@ restart: } td->len = 0; + /* properly reset reserved fields */ td->qtd_buffer[0] = 0; - td->qtd_buffer_hi[0] = 0; - td->qtd_buffer[1] = 0; + td->qtd_buffer[2] = 0; + td->qtd_buffer[3] = 0; + td->qtd_buffer[4] = 0; + td->qtd_buffer_hi[0] = 0; td->qtd_buffer_hi[1] = 0; - + td->qtd_buffer_hi[2] = 0; + td->qtd_buffer_hi[3] = 0; + td->qtd_buffer_hi[4] = 0; } else { uint8_t x; @@ -1713,6 +1725,12 @@ restart: htohc32(temp->sc, buf_res.physaddr & (~0xFFF)); td->qtd_buffer_hi[x] = 0; + + /* properly reset reserved fields */ + while (++x < EHCI_QTD_NBUFFERS) { + td->qtd_buffer[x] = 0; + td->qtd_buffer_hi[x] = 0; + } } if (td_next) { @@ -2000,6 +2018,18 @@ ehci_setup_standard_chain(struct usb_xfer *xfer, ehci_qh_t **qh_last) qh->qh_qtd.qtd_altnext = htohc32(temp.sc, EHCI_LINK_TERMINATE); + /* properly reset reserved fields */ + qh->qh_qtd.qtd_buffer[0] = 0; + qh->qh_qtd.qtd_buffer[1] = 0; + qh->qh_qtd.qtd_buffer[2] = 0; + qh->qh_qtd.qtd_buffer[3] = 0; + qh->qh_qtd.qtd_buffer[4] = 0; + qh->qh_qtd.qtd_buffer_hi[0] = 0; + qh->qh_qtd.qtd_buffer_hi[1] = 0; + qh->qh_qtd.qtd_buffer_hi[2] = 0; + qh->qh_qtd.qtd_buffer_hi[3] = 0; + qh->qh_qtd.qtd_buffer_hi[4] = 0; + usb_pc_cpu_flush(qh->page_cache); if (xfer->xroot->udev->flags.self_suspended == 0) { @@ -2229,11 +2259,27 @@ ehci_device_bulk_enter(struct usb_xfer *xfer) return; } +static void +ehci_doorbell_async(struct ehci_softc *sc) +{ + uint32_t temp; + + /* + * XXX Performance quirk: Some Host Controllers have a too low + * interrupt rate. Issue an IAAD to stimulate the Host + * Controller after queueing the BULK transfer. + * + * XXX Force the host controller to refresh any QH caches. + */ + temp = EOREAD4(sc, EHCI_USBCMD); + if (!(temp & EHCI_CMD_IAAD)) + EOWRITE4(sc, EHCI_USBCMD, temp | EHCI_CMD_IAAD); +} + static void ehci_device_bulk_start(struct usb_xfer *xfer) { ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); - uint32_t temp; /* setup TD's and QH */ ehci_setup_standard_chain(xfer, &sc->sc_async_p_last); @@ -2248,13 +2294,7 @@ ehci_device_bulk_start(struct usb_xfer *xfer) if (sc->sc_flags & EHCI_SCFLG_IAADBUG) return; - /* XXX Performance quirk: Some Host Controllers have a too low - * interrupt rate. Issue an IAAD to stimulate the Host - * Controller after queueing the BULK transfer. - */ - temp = EOREAD4(sc, EHCI_USBCMD); - if (!(temp & EHCI_CMD_IAAD)) - EOWRITE4(sc, EHCI_USBCMD, temp | EHCI_CMD_IAAD); + ehci_doorbell_async(sc); } struct usb_pipe_methods ehci_device_bulk_methods = @@ -3707,10 +3747,6 @@ ehci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc, edesc->bEndpointAddress, udev->flags.usb_mode, sc->sc_addr); - if (udev->flags.usb_mode != USB_MODE_HOST) { - /* not supported */ - return; - } if (udev->device_index != sc->sc_addr) { if ((udev->speed != USB_SPEED_HIGH) && @@ -3754,7 +3790,7 @@ ehci_get_dma_delay(struct usb_device *udev, uint32_t *pus) * Wait until the hardware has finished any possible use of * the transfer descriptor(s) and QH */ - *pus = (188); /* microseconds */ + *pus = (1125); /* microseconds */ } static void @@ -3875,6 +3911,41 @@ ehci_set_hw_power(struct usb_bus *bus) return; } +static void +ehci_start_dma_delay_second(struct usb_xfer *xfer) +{ + struct ehci_softc *sc = EHCI_BUS2SC(xfer->xroot->bus); + + DPRINTF("\n"); + + /* trigger doorbell */ + ehci_doorbell_async(sc); + + /* give the doorbell 4ms */ + usbd_transfer_timeout_ms(xfer, + (void (*)(void *))&usb_dma_delay_done_cb, 4); +} + +/* + * Ring the doorbell twice before freeing any DMA descriptors. Some host + * controllers apparently cache the QH descriptors and need a message + * that the cache needs to be discarded. + */ +static void +ehci_start_dma_delay(struct usb_xfer *xfer) +{ + struct ehci_softc *sc = EHCI_BUS2SC(xfer->xroot->bus); + + DPRINTF("\n"); + + /* trigger doorbell */ + ehci_doorbell_async(sc); + + /* give the doorbell 4ms */ + usbd_transfer_timeout_ms(xfer, + (void (*)(void *))&ehci_start_dma_delay_second, 4); +} + struct usb_bus_methods ehci_bus_methods = { .endpoint_init = ehci_ep_init, @@ -3887,4 +3958,5 @@ struct usb_bus_methods ehci_bus_methods = .set_hw_power_sleep = ehci_set_hw_power_sleep, .roothub_exec = ehci_roothub_exec, .xfer_poll = ehci_do_poll, + .start_dma_delay = ehci_start_dma_delay, }; diff --git a/freebsd/sys/dev/usb/controller/ohci.c b/freebsd/sys/dev/usb/controller/ohci.c index 42129a8e..05c5e19b 100644 --- a/freebsd/sys/dev/usb/controller/ohci.c +++ b/freebsd/sys/dev/usb/controller/ohci.c @@ -2316,6 +2316,7 @@ ohci_roothub_exec(struct usb_device *udev, } v = OREAD4(sc, OHCI_RH_PORT_STATUS(index)); DPRINTFN(9, "port status=0x%04x\n", v); + v &= ~UPS_PORT_MODE_DEVICE; /* force host mode */ USETW(sc->sc_hub_desc.ps.wPortStatus, v); USETW(sc->sc_hub_desc.ps.wPortChange, v >> 16); len = sizeof(sc->sc_hub_desc.ps); @@ -2552,10 +2553,6 @@ ohci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc, edesc->bEndpointAddress, udev->flags.usb_mode, sc->sc_addr); - if (udev->flags.usb_mode != USB_MODE_HOST) { - /* not supported */ - return; - } if (udev->device_index != sc->sc_addr) { switch (edesc->bmAttributes & UE_XFERTYPE) { case UE_CONTROL: diff --git a/freebsd/sys/dev/usb/controller/usb_controller.c b/freebsd/sys/dev/usb/controller/usb_controller.c index 37f79364..c0fda652 100644 --- a/freebsd/sys/dev/usb/controller/usb_controller.c +++ b/freebsd/sys/dev/usb/controller/usb_controller.c @@ -287,6 +287,28 @@ usb_resume(device_t dev) return (0); } +/*------------------------------------------------------------------------* + * usb_bus_reset_async_locked + *------------------------------------------------------------------------*/ +void +usb_bus_reset_async_locked(struct usb_bus *bus) +{ + USB_BUS_LOCK_ASSERT(bus, MA_OWNED); + + DPRINTF("\n"); + + if (bus->reset_msg[0].hdr.pm_qentry.tqe_prev != NULL || + bus->reset_msg[1].hdr.pm_qentry.tqe_prev != NULL) { + DPRINTF("Reset already pending\n"); + return; + } + + device_printf(bus->parent, "Resetting controller\n"); + + usb_proc_msignal(&bus->explore_proc, + &bus->reset_msg[0], &bus->reset_msg[1]); +} + /*------------------------------------------------------------------------* * usb_shutdown *------------------------------------------------------------------------*/ @@ -338,7 +360,13 @@ usb_bus_explore(struct usb_proc_msg *pm) if (bus->no_explore != 0) return; - if (udev && udev->hub) { + if (udev != NULL) { + USB_BUS_UNLOCK(bus); + uhub_explore_handle_re_enumerate(udev); + USB_BUS_LOCK(bus); + } + + if (udev != NULL && udev->hub != NULL) { if (bus->do_probe) { bus->do_probe = 0; @@ -411,7 +439,7 @@ usb_bus_detach(struct usb_proc_msg *pm) /*------------------------------------------------------------------------* * usb_bus_suspend * - * This function is used to suspend the USB contoller. + * This function is used to suspend the USB controller. *------------------------------------------------------------------------*/ static void usb_bus_suspend(struct usb_proc_msg *pm) @@ -421,6 +449,8 @@ usb_bus_suspend(struct usb_proc_msg *pm) usb_error_t err; uint8_t do_unlock; + DPRINTF("\n"); + bus = ((struct usb_bus_msg *)pm)->bus; udev = bus->devices[USB_ROOT_HUB_ADDR]; @@ -466,7 +496,7 @@ usb_bus_suspend(struct usb_proc_msg *pm) /*------------------------------------------------------------------------* * usb_bus_resume * - * This function is used to resume the USB contoller. + * This function is used to resume the USB controller. *------------------------------------------------------------------------*/ static void usb_bus_resume(struct usb_proc_msg *pm) @@ -476,6 +506,8 @@ usb_bus_resume(struct usb_proc_msg *pm) usb_error_t err; uint8_t do_unlock; + DPRINTF("\n"); + bus = ((struct usb_bus_msg *)pm)->bus; udev = bus->devices[USB_ROOT_HUB_ADDR]; @@ -524,10 +556,32 @@ usb_bus_resume(struct usb_proc_msg *pm) USB_BUS_LOCK(bus); } +/*------------------------------------------------------------------------* + * usb_bus_reset + * + * This function is used to reset the USB controller. + *------------------------------------------------------------------------*/ +static void +usb_bus_reset(struct usb_proc_msg *pm) +{ + struct usb_bus *bus; + + DPRINTF("\n"); + + bus = ((struct usb_bus_msg *)pm)->bus; + + if (bus->bdev == NULL || bus->no_explore != 0) + return; + + /* a suspend and resume will reset the USB controller */ + usb_bus_suspend(pm); + usb_bus_resume(pm); +} + /*------------------------------------------------------------------------* * usb_bus_shutdown * - * This function is used to shutdown the USB contoller. + * This function is used to shutdown the USB controller. *------------------------------------------------------------------------*/ static void usb_bus_shutdown(struct usb_proc_msg *pm) @@ -740,6 +794,11 @@ usb_attach_sub(device_t dev, struct usb_bus *bus) bus->resume_msg[1].hdr.pm_callback = &usb_bus_resume; bus->resume_msg[1].bus = bus; + bus->reset_msg[0].hdr.pm_callback = &usb_bus_reset; + bus->reset_msg[0].bus = bus; + bus->reset_msg[1].hdr.pm_callback = &usb_bus_reset; + bus->reset_msg[1].bus = bus; + bus->shutdown_msg[0].hdr.pm_callback = &usb_bus_shutdown; bus->shutdown_msg[0].bus = bus; bus->shutdown_msg[1].hdr.pm_callback = &usb_bus_shutdown; diff --git a/freebsd/sys/dev/usb/controller/xhcireg.h b/freebsd/sys/dev/usb/controller/xhcireg.h index 85d989a6..bd1d635c 100644 --- a/freebsd/sys/dev/usb/controller/xhcireg.h +++ b/freebsd/sys/dev/usb/controller/xhcireg.h @@ -166,7 +166,8 @@ #define XHCI_IMOD_IVAL_SET(x) (((x) & 0xFFFF) << 0) /* 250ns unit */ #define XHCI_IMOD_ICNT_GET(x) (((x) >> 16) & 0xFFFF) /* 250ns unit */ #define XHCI_IMOD_ICNT_SET(x) (((x) & 0xFFFF) << 16) /* 250ns unit */ -#define XHCI_IMOD_DEFAULT 0x000003E8U /* 8000 IRQ/second */ +#define XHCI_IMOD_DEFAULT 0x000001F4U /* 8000 IRQs/second */ +#define XHCI_IMOD_DEFAULT_LP 0x000003F8U /* 4000 IRQs/second - LynxPoint */ #define XHCI_ERSTSZ(n) (0x0028 + (0x20 * (n))) /* XHCI event ring segment table size */ #define XHCI_ERSTS_GET(x) ((x) & 0xFFFF) #define XHCI_ERSTS_SET(x) ((x) & 0xFFFF) diff --git a/freebsd/sys/dev/usb/quirk/usb_quirk.c b/freebsd/sys/dev/usb/quirk/usb_quirk.c index 9042c166..2f7ea792 100644 --- a/freebsd/sys/dev/usb/quirk/usb_quirk.c +++ b/freebsd/sys/dev/usb/quirk/usb_quirk.c @@ -95,6 +95,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(TELEX, MIC1, 0x009, 0x009, UQ_AU_NO_FRAC), 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(ELSA, MODEM1, 0x0000, 0xffff, UQ_CFG_INDEX_1), USB_QUIRK(PLANEX2, MZKUE150N, 0x0000, 0xffff, UQ_CFG_INDEX_1), /* Quirks for printer devices */ @@ -114,6 +115,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(ITUNERNET, USBLCD2X20, 0x0000, 0xffff, UQ_HID_IGNORE), USB_QUIRK(ITUNERNET, USBLCD4X20, 0x0000, 0xffff, UQ_HID_IGNORE), USB_QUIRK(LIEBERT, POWERSURE_PXT, 0x0000, 0xffff, UQ_HID_IGNORE), + USB_QUIRK(LIEBERT2, PSI1000, 0x0000, 0xffff, UQ_HID_IGNORE), USB_QUIRK(MGE, UPS1, 0x0000, 0xffff, UQ_HID_IGNORE), USB_QUIRK(MGE, UPS2, 0x0000, 0xffff, UQ_HID_IGNORE), USB_QUIRK(APPLE, IPHONE, 0x0000, 0xffff, UQ_HID_IGNORE), @@ -165,6 +167,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), USB_QUIRK(ASAHIOPTICAL, OPTIO330, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), + USB_QUIRK(ATP, EUSB, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), USB_QUIRK(BELKIN, USB2SCSI, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI), USB_QUIRK(CASIO, QV_DIGICAM, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, @@ -235,6 +238,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(JMICRON, JM20337, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(KINGSTON, HYPERX3_0, 0x0000, 0xffff, UQ_MSC_NO_INQUIRY), USB_QUIRK(KYOCERA, FINECAM_L3, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), USB_QUIRK(KYOCERA, FINECAM_S3X, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, @@ -287,6 +291,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE), USB_QUIRK(NETCHIP, CLIK_40, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_ATAPI, UQ_MSC_NO_INQUIRY), + USB_QUIRK(NETCHIP, POCKETBOOK, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), USB_QUIRK(NIKON, D300, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI), USB_QUIRK(OLYMPUS, C1, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, @@ -333,6 +338,9 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(SANDISK, SDDR12, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_READ_CAP_OFFBY1, UQ_MSC_NO_GETMAXLUN), + USB_QUIRK(SANDISK, SDCZ2_128, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, + UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE, + UQ_MSC_NO_SYNC_CACHE), USB_QUIRK(SANDISK, SDCZ2_256, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_IGNORE_RESIDUE), USB_QUIRK(SANDISK, SDCZ4_128, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, @@ -398,6 +406,8 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(STMICRO, ST72682, 0x0000, 0xffff, UQ_MSC_NO_PREVENT_ALLOW), USB_QUIRK(SUPERTOP, IDE, 0x0000, 0xffff, UQ_MSC_IGNORE_RESIDUE, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(SUPERTOP, FLASHDRIVE, 0x0000, 0xffff, UQ_MSC_NO_TEST_UNIT_READY, + UQ_MSC_NO_SYNC_CACHE), USB_QUIRK(TAUGA, CAMERAMATE, 0x0000, 0xffff, UQ_MSC_FORCE_PROTO_SCSI), USB_QUIRK(TEAC, FD05PUB, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_CBI, UQ_MSC_FORCE_PROTO_UFI), @@ -427,6 +437,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY_EVPD, UQ_MSC_NO_SYNC_CACHE), USB_QUIRK(WESTERN, MYPASSWORD, 0x0000, 0xffff, UQ_MSC_FORCE_SHORT_INQ), + USB_QUIRK(WESTERN, MYPASSPORT, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), USB_QUIRK(WINMAXGROUP, FLASH64MC, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_INQUIRY), USB_QUIRK(YANO, FW800HD, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB, diff --git a/freebsd/sys/dev/usb/storage/umass.c b/freebsd/sys/dev/usb/storage/umass.c index 76a1fcb6..39d32698 100644 --- a/freebsd/sys/dev/usb/storage/umass.c +++ b/freebsd/sys/dev/usb/storage/umass.c @@ -1326,10 +1326,12 @@ umass_t_bbb_command_callback(struct usb_xfer *xfer, usb_error_t error) } sc->cbw.bCDBLength = sc->sc_transfer.cmd_len; + /* copy SCSI command data */ memcpy(sc->cbw.CBWCDB, sc->sc_transfer.cmd_data, sc->sc_transfer.cmd_len); - memset(sc->sc_transfer.cmd_data + + /* clear remaining command area */ + memset(sc->cbw.CBWCDB + sc->sc_transfer.cmd_len, 0, sizeof(sc->cbw.CBWCDB) - sc->sc_transfer.cmd_len); diff --git a/freebsd/sys/dev/usb/usb.h b/freebsd/sys/dev/usb/usb.h index 9492d491..bb5a60cd 100644 --- a/freebsd/sys/dev/usb/usb.h +++ b/freebsd/sys/dev/usb/usb.h @@ -493,8 +493,11 @@ typedef struct usb_interface_assoc_descriptor usb_interface_assoc_descriptor_t; #define UICLASS_WIRELESS 0xe0 #define UISUBCLASS_RF 0x01 #define UIPROTO_BLUETOOTH 0x01 +#define UIPROTO_RNDIS 0x03 #define UICLASS_IAD 0xEF /* Interface Association Descriptor */ +#define UISUBCLASS_SYNC 0x01 +#define UIPROTO_ACTIVESYNC 0x01 #define UICLASS_APPL_SPEC 0xfe #define UISUBCLASS_FIRMWARE_DOWNLOAD 1 diff --git a/freebsd/sys/dev/usb/usb_bus.h b/freebsd/sys/dev/usb/usb_bus.h index 459219bd..702f623d 100644 --- a/freebsd/sys/dev/usb/usb_bus.h +++ b/freebsd/sys/dev/usb/usb_bus.h @@ -73,6 +73,7 @@ struct usb_bus { struct usb_bus_msg attach_msg[2]; struct usb_bus_msg suspend_msg[2]; struct usb_bus_msg resume_msg[2]; + struct usb_bus_msg reset_msg[2]; struct usb_bus_msg shutdown_msg[2]; /* * This mutex protects the USB hardware: diff --git a/freebsd/sys/dev/usb/usb_busdma.c b/freebsd/sys/dev/usb/usb_busdma.c index 80cd8c37..7d98155c 100644 --- a/freebsd/sys/dev/usb/usb_busdma.c +++ b/freebsd/sys/dev/usb/usb_busdma.c @@ -213,9 +213,7 @@ usbd_m_copy_in(struct usb_page_cache *cache, usb_frlength_t dst_offset, struct mbuf *m, usb_size_t src_offset, usb_frlength_t src_len) { struct usb_m_copy_in_arg arg = {cache, dst_offset}; - int error; - - error = m_apply(m, src_offset, src_len, &usbd_m_copy_in_cb, &arg); + (void) m_apply(m, src_offset, src_len, &usbd_m_copy_in_cb, &arg); } #endif @@ -360,8 +358,7 @@ usb_dma_tag_create(struct usb_dma_tag *udt, if (bus_dma_tag_create ( /* parent */ udt->tag_parent->tag, /* alignment */ align, - /* boundary */ (align == 1) ? - USB_PAGE_SIZE : 0, + /* boundary */ 0, /* lowaddr */ (2ULL << (udt->tag_parent->dma_bits - 1)) - 1, /* highaddr */ BUS_SPACE_MAXADDR, /* filter */ NULL, @@ -420,6 +417,7 @@ usb_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs, struct usb_page_cache *pc; struct usb_page *pg; usb_size_t rem; + bus_size_t off; uint8_t owned; pc = arg; @@ -435,12 +433,13 @@ usb_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs, if (error) { goto done; } + + off = 0; pg = pc->page_start; pg->physaddr = segs->ds_addr & ~(USB_PAGE_SIZE - 1); rem = segs->ds_addr & (USB_PAGE_SIZE - 1); pc->page_offset_buf = rem; pc->page_offset_end += rem; - nseg--; #ifdef USB_DEBUG if (rem != (USB_P2U(pc->buffer) & (USB_PAGE_SIZE - 1))) { /* @@ -451,11 +450,19 @@ usb_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs, goto done; } #endif - while (nseg > 0) { - nseg--; - segs++; + while (pc->ismultiseg) { + off += USB_PAGE_SIZE; + if (off >= (segs->ds_len + rem)) { + /* page crossing */ + nseg--; + segs++; + off = 0; + rem = 0; + if (nseg == 0) + break; + } pg++; - pg->physaddr = segs->ds_addr & ~(USB_PAGE_SIZE - 1); + pg->physaddr = (segs->ds_addr + off) & ~(USB_PAGE_SIZE - 1); } done: diff --git a/freebsd/sys/dev/usb/usb_controller.h b/freebsd/sys/dev/usb/usb_controller.h index ad871913..f23ade21 100644 --- a/freebsd/sys/dev/usb/usb_controller.h +++ b/freebsd/sys/dev/usb/usb_controller.h @@ -186,6 +186,7 @@ void usb_bus_mem_flush_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb); uint8_t usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat, usb_bus_mem_cb_t *cb); void usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb); uint16_t usb_isoc_time_expand(struct usb_bus *bus, uint16_t isoc_time_curr); +void usb_bus_reset_async_locked(struct usb_bus *bus); #if USB_HAVE_TT_SUPPORT uint8_t usbd_fs_isoc_schedule_alloc_slot(struct usb_xfer *isoc_xfer, uint16_t isoc_time); #endif diff --git a/freebsd/sys/dev/usb/usb_core.h b/freebsd/sys/dev/usb/usb_core.h index 3dfd0d1a..48e5ee83 100644 --- a/freebsd/sys/dev/usb/usb_core.h +++ b/freebsd/sys/dev/usb/usb_core.h @@ -113,6 +113,8 @@ struct usb_xfer_flags_int { uint8_t can_cancel_immed:1; /* set if USB transfer can be * cancelled immediately */ uint8_t doing_callback:1; /* set if executing the callback */ + uint8_t maxp_was_clamped:1; /* set if the max packet size + * was outside its allowed range */ }; /* diff --git a/freebsd/sys/dev/usb/usb_dev.c b/freebsd/sys/dev/usb/usb_dev.c index 7697b64c..3ff064ee 100644 --- a/freebsd/sys/dev/usb/usb_dev.c +++ b/freebsd/sys/dev/usb/usb_dev.c @@ -107,7 +107,7 @@ static void usb_dev_uninit(void *); static int usb_fifo_uiomove(struct usb_fifo *, void *, int, struct uio *); static void usb_fifo_check_methods(struct usb_fifo_methods *); -static struct usb_fifo *usb_fifo_alloc(void); +static struct usb_fifo *usb_fifo_alloc(struct mtx *); static struct usb_endpoint *usb_dev_get_ep(struct usb_device *, uint8_t, uint8_t); static void usb_loc_fill(struct usb_fs_privdata *, @@ -122,6 +122,7 @@ static d_ioctl_t usb_ioctl; static d_read_t usb_read; static d_write_t usb_write; static d_poll_t usb_poll; +static d_kqfilter_t usb_kqfilter; static d_ioctl_t usb_static_ioctl; @@ -139,7 +140,8 @@ struct cdevsw usb_devsw = { .d_flags = D_TRACKCLOSE, .d_read = usb_read, .d_write = usb_write, - .d_poll = usb_poll + .d_poll = usb_poll, + .d_kqfilter = usb_kqfilter, }; static struct cdev* usb_dev = NULL; @@ -205,12 +207,18 @@ usb_ref_device(struct usb_cdev_privdata *cpd, DPRINTFN(2, "no device at %u\n", cpd->dev_index); goto error; } - if (cpd->udev->refcount == USB_DEV_REF_MAX) { - DPRINTFN(2, "no dev ref\n"); + if (cpd->udev->state == USB_STATE_DETACHED && + (need_uref != 2)) { + DPRINTFN(2, "device is detached\n"); goto error; } if (need_uref) { DPRINTFN(2, "ref udev - needed\n"); + + if (cpd->udev->refcount == USB_DEV_REF_MAX) { + DPRINTFN(2, "no dev ref\n"); + goto error; + } cpd->udev->refcount++; mtx_unlock(&usb_ref_lock); @@ -284,9 +292,8 @@ error: usbd_enum_unlock(cpd->udev); if (crd->is_uref) { - if (--(cpd->udev->refcount) == 0) { - cv_signal(&cpd->udev->ref_cv); - } + cpd->udev->refcount--; + cv_broadcast(&cpd->udev->ref_cv); } mtx_unlock(&usb_ref_lock); DPRINTFN(2, "fail\n"); @@ -352,24 +359,25 @@ usb_unref_device(struct usb_cdev_privdata *cpd, crd->is_write = 0; } if (crd->is_uref) { - if (--(cpd->udev->refcount) == 0) { - cv_signal(&cpd->udev->ref_cv); - } crd->is_uref = 0; + cpd->udev->refcount--; + cv_broadcast(&cpd->udev->ref_cv); } mtx_unlock(&usb_ref_lock); } static struct usb_fifo * -usb_fifo_alloc(void) +usb_fifo_alloc(struct mtx *mtx) { struct usb_fifo *f; f = malloc(sizeof(*f), M_USBDEV, M_WAITOK | M_ZERO); - if (f) { + if (f != NULL) { cv_init(&f->cv_io, "FIFO-IO"); cv_init(&f->cv_drain, "FIFO-DRAIN"); + f->priv_mtx = mtx; f->refcount = 1; + knlist_init_mtx(&f->selinfo.si_note, mtx); } return (f); } @@ -493,7 +501,7 @@ usb_fifo_create(struct usb_cdev_privdata *cpd, DPRINTFN(5, "dev_get_endpoint returned NULL\n"); return (EINVAL); } - f = usb_fifo_alloc(); + f = usb_fifo_alloc(&udev->device_mtx); if (f == NULL) { DPRINTFN(5, "could not alloc tx fifo\n"); return (ENOMEM); @@ -501,7 +509,6 @@ usb_fifo_create(struct usb_cdev_privdata *cpd, /* update some fields */ f->fifo_index = n + USB_FIFO_TX; f->dev_ep_index = e; - f->priv_mtx = &udev->device_mtx; f->priv_sc0 = ep; f->methods = &usb_ugen_methods; f->iface_index = ep->iface_index; @@ -520,7 +527,7 @@ usb_fifo_create(struct usb_cdev_privdata *cpd, DPRINTFN(5, "dev_get_endpoint returned NULL\n"); return (EINVAL); } - f = usb_fifo_alloc(); + f = usb_fifo_alloc(&udev->device_mtx); if (f == NULL) { DPRINTFN(5, "could not alloc rx fifo\n"); return (ENOMEM); @@ -528,7 +535,6 @@ usb_fifo_create(struct usb_cdev_privdata *cpd, /* update some fields */ f->fifo_index = n + USB_FIFO_RX; f->dev_ep_index = e; - f->priv_mtx = &udev->device_mtx; f->priv_sc0 = ep; f->methods = &usb_ugen_methods; f->iface_index = ep->iface_index; @@ -595,6 +601,13 @@ usb_fifo_free(struct usb_fifo *f) mtx_unlock(f->priv_mtx); mtx_lock(&usb_ref_lock); + /* + * Check if the "f->refcount" variable reached zero + * during the unlocked time before entering wait: + */ + if (f->refcount == 0) + break; + /* wait for sync */ cv_wait(&f->cv_drain, &usb_ref_lock); } @@ -606,6 +619,10 @@ usb_fifo_free(struct usb_fifo *f) cv_destroy(&f->cv_io); cv_destroy(&f->cv_drain); + knlist_clear(&f->selinfo.si_note, 0); + seldrain(&f->selinfo); + knlist_destroy(&f->selinfo.si_note); + free(f, M_USBDEV); } @@ -760,7 +777,12 @@ usb_fifo_close(struct usb_fifo *f, int fflags) mtx_lock(f->priv_mtx); /* clear current cdev private data pointer */ + mtx_lock(&usb_ref_lock); f->curr_cpd = NULL; + mtx_unlock(&usb_ref_lock); + + /* check if we are watched by kevent */ + KNOTE_LOCKED(&f->selinfo.si_note, 0); /* check if we are selected */ if (f->flag_isselect) { @@ -913,23 +935,12 @@ usb_close(void *arg) DPRINTFN(2, "cpd=%p\n", cpd); - err = usb_ref_device(cpd, &refs, 0); - if (err) + err = usb_ref_device(cpd, &refs, + 2 /* uref and allow detached state */); + if (err) { + DPRINTFN(2, "Cannot grab USB reference when " + "closing USB file handle\n"); goto done; - - /* - * If this function is not called directly from the root HUB - * thread, there is usually a need to lock the enumeration - * lock. Check this. - */ - if (!usbd_enum_is_locked(cpd->udev)) { - - DPRINTFN(2, "Locking enumeration\n"); - - /* reference device */ - err = usb_usb_ref_device(cpd, &refs); - if (err) - goto done; } if (cpd->fflags & FREAD) { usb_fifo_close(refs.rxfifo, cpd->fflags); @@ -1097,15 +1108,20 @@ usb_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread* /* Wait for re-enumeration, if any */ - while (f->udev->re_enumerate_wait != 0) { + while (f->udev->re_enumerate_wait != USB_RE_ENUM_DONE) { usb_unref_device(cpd, &refs); usb_pause_mtx(NULL, hz / 128); - if (usb_ref_device(cpd, &refs, 1 /* need uref */)) { - err = ENXIO; - goto done; + while (usb_ref_device(cpd, &refs, 1 /* need uref */)) { + if (usb_ref_device(cpd, &refs, 0)) { + /* device no longer exits */ + err = ENXIO; + goto done; + } + usb_unref_device(cpd, &refs); + usb_pause_mtx(NULL, hz / 128); } } @@ -1114,6 +1130,162 @@ done: return (err); } +static void +usb_filter_detach(struct knote *kn) +{ + struct usb_fifo *f = kn->kn_hook; + knlist_remove(&f->selinfo.si_note, kn, 0); +} + +static int +usb_filter_write(struct knote *kn, long hint) +{ + struct usb_cdev_privdata* cpd; + struct usb_fifo *f; + struct usb_mbuf *m; + + DPRINTFN(2, "\n"); + + f = kn->kn_hook; + + mtx_assert(f->priv_mtx, MA_OWNED); + + cpd = f->curr_cpd; + if (cpd == NULL) { + m = (void *)1; + } else if (f->fs_ep_max == 0) { + if (f->flag_iserror) { + /* we got an error */ + m = (void *)1; + } else { + if (f->queue_data == NULL) { + /* + * start write transfer, if not + * already started + */ + (f->methods->f_start_write) (f); + } + /* check if any packets are available */ + USB_IF_POLL(&f->free_q, m); + } + } else { + if (f->flag_iscomplete) { + m = (void *)1; + } else { + m = NULL; + } + } + return (m ? 1 : 0); +} + +static int +usb_filter_read(struct knote *kn, long hint) +{ + struct usb_cdev_privdata* cpd; + struct usb_fifo *f; + struct usb_mbuf *m; + + DPRINTFN(2, "\n"); + + f = kn->kn_hook; + + mtx_assert(f->priv_mtx, MA_OWNED); + + cpd = f->curr_cpd; + if (cpd == NULL) { + m = (void *)1; + } else if (f->fs_ep_max == 0) { + if (f->flag_iserror) { + /* we have an error */ + m = (void *)1; + } else { + if (f->queue_data == NULL) { + /* + * start read transfer, if not + * already started + */ + (f->methods->f_start_read) (f); + } + /* check if any packets are available */ + USB_IF_POLL(&f->used_q, m); + + /* start reading data, if any */ + if (m == NULL) + (f->methods->f_start_read) (f); + } + } else { + if (f->flag_iscomplete) { + m = (void *)1; + } else { + m = NULL; + } + } + return (m ? 1 : 0); +} + +static struct filterops usb_filtops_write = { + .f_isfd = 1, + .f_detach = usb_filter_detach, + .f_event = usb_filter_write, +}; + +static struct filterops usb_filtops_read = { + .f_isfd = 1, + .f_detach = usb_filter_detach, + .f_event = usb_filter_read, +}; + + +/* ARGSUSED */ +static int +usb_kqfilter(struct cdev* dev, struct knote *kn) +{ + struct usb_cdev_refdata refs; + struct usb_cdev_privdata* cpd; + struct usb_fifo *f; + int fflags; + int err = EINVAL; + + DPRINTFN(2, "\n"); + + if (devfs_get_cdevpriv((void **)&cpd) != 0 || + usb_ref_device(cpd, &refs, 0) != 0) + return (ENXIO); + + fflags = cpd->fflags; + + /* Figure out who needs service */ + switch (kn->kn_filter) { + case EVFILT_WRITE: + if (fflags & FWRITE) { + f = refs.txfifo; + kn->kn_fop = &usb_filtops_write; + err = 0; + } + break; + case EVFILT_READ: + if (fflags & FREAD) { + f = refs.rxfifo; + kn->kn_fop = &usb_filtops_read; + err = 0; + } + break; + default: + err = EOPNOTSUPP; + break; + } + + if (err == 0) { + kn->kn_hook = f; + mtx_lock(f->priv_mtx); + knlist_add(&f->selinfo.si_note, kn, 1); + mtx_unlock(f->priv_mtx); + } + + usb_unref_device(cpd, &refs); + return (err); +} + /* ARGSUSED */ static int usb_poll(struct cdev* dev, int events, struct thread* td) @@ -1181,7 +1353,7 @@ usb_poll(struct cdev* dev, int events, struct thread* td) if (!refs.is_usbfs) { if (f->flag_iserror) { - /* we have and error */ + /* we have an error */ m = (void *)1; } else { if (f->queue_data == NULL) { @@ -1578,6 +1750,8 @@ usb_fifo_wakeup(struct usb_fifo *f) { usb_fifo_signal(f); + KNOTE_LOCKED(&f->selinfo.si_note, 0); + if (f->flag_isselect) { selwakeup(&f->selinfo); f->flag_isselect = 0; @@ -1693,8 +1867,8 @@ usb_fifo_attach(struct usb_device *udev, void *priv_sc, break; } - f_tx = usb_fifo_alloc(); - f_rx = usb_fifo_alloc(); + f_tx = usb_fifo_alloc(priv_mtx); + f_rx = usb_fifo_alloc(priv_mtx); if ((f_tx == NULL) || (f_rx == NULL)) { usb_fifo_free(f_tx); @@ -1705,7 +1879,6 @@ usb_fifo_attach(struct usb_device *udev, void *priv_sc, f_tx->fifo_index = n + USB_FIFO_TX; f_tx->dev_ep_index = -1; - f_tx->priv_mtx = priv_mtx; f_tx->priv_sc0 = priv_sc; f_tx->methods = pm; f_tx->iface_index = iface_index; @@ -1713,7 +1886,6 @@ usb_fifo_attach(struct usb_device *udev, void *priv_sc, f_rx->fifo_index = n + USB_FIFO_RX; f_rx->dev_ep_index = -1; - f_rx->priv_mtx = priv_mtx; f_rx->priv_sc0 = priv_sc; f_rx->methods = pm; f_rx->iface_index = iface_index; diff --git a/freebsd/sys/dev/usb/usb_device.c b/freebsd/sys/dev/usb/usb_device.c index 78ae3d8c..e18c32df 100644 --- a/freebsd/sys/dev/usb/usb_device.c +++ b/freebsd/sys/dev/usb/usb_device.c @@ -96,7 +96,7 @@ static void usb_init_attach_arg(struct usb_device *, struct usb_attach_arg *); static void usb_suspend_resume_sub(struct usb_device *, device_t, uint8_t); -static void usbd_clear_stall_proc(struct usb_proc_msg *_pm); +static usb_proc_callback_t usbd_clear_stall_proc; static usb_error_t usb_config_parse(struct usb_device *, uint8_t, uint8_t); static void usbd_set_device_strings(struct usb_device *); #if USB_HAVE_DEVCTL @@ -436,6 +436,65 @@ usb_endpoint_foreach(struct usb_device *udev, struct usb_endpoint *ep) return (NULL); } +/*------------------------------------------------------------------------* + * usb_wait_pending_ref_locked + * + * This function will wait for any USB references to go away before + * returning and disable further USB device refcounting on the + * specified USB device. This function is used when detaching a USB + * device. + *------------------------------------------------------------------------*/ +static void +usb_wait_pending_ref_locked(struct usb_device *udev) +{ +#if USB_HAVE_UGEN + const uint16_t refcount = + usb_proc_is_called_from( + &udev->bus->explore_proc) ? 1 : 2; + + DPRINTF("Refcount = %d\n", (int)refcount); + + while (1) { + /* wait for any pending references to go away */ + mtx_lock(&usb_ref_lock); + if (udev->refcount == refcount) { + /* prevent further refs being taken */ + udev->refcount = USB_DEV_REF_MAX; + mtx_unlock(&usb_ref_lock); + break; + } + usbd_enum_unlock(udev); + cv_wait(&udev->ref_cv, &usb_ref_lock); + mtx_unlock(&usb_ref_lock); + (void) usbd_enum_lock(udev); + } +#endif +} + +/*------------------------------------------------------------------------* + * usb_ref_restore_locked + * + * This function will restore the reference count value after a call + * to "usb_wait_pending_ref_locked()". + *------------------------------------------------------------------------*/ +static void +usb_ref_restore_locked(struct usb_device *udev) +{ +#if USB_HAVE_UGEN + const uint16_t refcount = + usb_proc_is_called_from( + &udev->bus->explore_proc) ? 1 : 2; + + DPRINTF("Refcount = %d\n", (int)refcount); + + /* restore reference count and wakeup waiters, if any */ + mtx_lock(&usb_ref_lock); + udev->refcount = refcount; + cv_broadcast(&udev->ref_cv); + mtx_unlock(&usb_ref_lock); +#endif +} + /*------------------------------------------------------------------------* * usb_unconfigure * @@ -1097,6 +1156,9 @@ usb_detach_device(struct usb_device *udev, uint8_t iface_index, sx_assert(&udev->enum_sx, SA_LOCKED); + /* wait for pending refs to go away */ + usb_wait_pending_ref_locked(udev); + /* * First detach the child to give the child's detach routine a * chance to detach the sub-devices in the correct order. @@ -1123,6 +1185,8 @@ usb_detach_device(struct usb_device *udev, uint8_t iface_index, usb_detach_device_sub(udev, &iface->subdev, &iface->pnpinfo, flag); } + + usb_ref_restore_locked(udev); } /*------------------------------------------------------------------------* @@ -1450,7 +1514,7 @@ usb_suspend_resume(struct usb_device *udev, uint8_t do_suspend) static void usbd_clear_stall_proc(struct usb_proc_msg *_pm) { - struct usb_clear_stall_msg *pm = (void *)_pm; + struct usb_udev_msg *pm = (void *)_pm; struct usb_device *udev = pm->udev; /* Change lock */ @@ -1679,10 +1743,14 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus, err = usbd_setup_device_desc(udev, NULL); if (err != 0) { - /* XXX try to re-enumerate the device */ + /* try to enumerate two more times */ err = usbd_req_re_enumerate(udev, NULL); - if (err) - goto done; + if (err != 0) { + err = usbd_req_re_enumerate(udev, NULL); + if (err != 0) { + goto done; + } + } } /* @@ -2038,6 +2106,8 @@ usb_free_device(struct usb_device *udev, uint8_t flag) DPRINTFN(4, "udev=%p port=%d\n", udev, udev->port_no); bus = udev->bus; + + /* set DETACHED state to prevent any further references */ usb_set_device_state(udev, USB_STATE_DETACHED); #if USB_HAVE_DEVCTL @@ -2053,23 +2123,6 @@ usb_free_device(struct usb_device *udev, uint8_t flag) usb_free_symlink(udev->ugen_symlink); udev->ugen_symlink = NULL; } -#endif - /* - * Unregister our device first which will prevent any further - * references: - */ - usb_bus_port_set_device(bus, udev->parent_hub ? - udev->parent_hub->hub->ports + udev->port_index : NULL, - NULL, USB_ROOT_HUB_ADDR); - -#if USB_HAVE_UGEN - /* wait for all pending references to go away: */ - mtx_lock(&usb_ref_lock); - udev->refcount--; - while (udev->refcount != 0) { - cv_wait(&udev->ref_cv, &usb_ref_lock); - } - mtx_unlock(&usb_ref_lock); usb_destroy_dev(udev->ctrl_dev); #endif @@ -2082,6 +2135,11 @@ usb_free_device(struct usb_device *udev, uint8_t flag) /* the following will get the device unconfigured in software */ usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_EP0); + /* final device unregister after all character devices are closed */ + usb_bus_port_set_device(bus, udev->parent_hub ? + udev->parent_hub->hub->ports + udev->port_index : NULL, + NULL, USB_ROOT_HUB_ADDR); + /* unsetup any leftover default USB transfers */ usbd_transfer_unsetup(udev->ctrl_xfer, USB_CTRL_XFER_MAX); @@ -2582,8 +2640,14 @@ usb_fifo_free_wrap(struct usb_device *udev, /* no need to free this FIFO */ continue; } + /* wait for pending refs to go away */ + usb_wait_pending_ref_locked(udev); + /* free this FIFO */ usb_fifo_free(f); + + /* restore refcount */ + usb_ref_restore_locked(udev); } } #endif @@ -2615,8 +2679,14 @@ usb_set_device_state(struct usb_device *udev, enum usb_dev_state state) DPRINTF("udev %p state %s -> %s\n", udev, usb_statestr(udev->state), usb_statestr(state)); - udev->state = state; +#if USB_HAVE_UGEN + mtx_lock(&usb_ref_lock); +#endif + udev->state = state; +#if USB_HAVE_UGEN + mtx_unlock(&usb_ref_lock); +#endif if (udev->bus->methods->device_state_change != NULL) (udev->bus->methods->device_state_change) (udev); } diff --git a/freebsd/sys/dev/usb/usb_device.h b/freebsd/sys/dev/usb/usb_device.h index 8e13e3de..361f5c3c 100644 --- a/freebsd/sys/dev/usb/usb_device.h +++ b/freebsd/sys/dev/usb/usb_device.h @@ -53,7 +53,7 @@ struct usb_symlink; /* UGEN */ #define USB_UNCFG_FLAG_NONE 0x00 #define USB_UNCFG_FLAG_FREE_EP0 0x02 /* endpoint zero is freed */ -struct usb_clear_stall_msg { +struct usb_udev_msg { struct usb_proc_msg hdr; struct usb_device *udev; }; @@ -179,8 +179,8 @@ union usb_device_scratch { * these structures for every USB device. */ struct usb_device { - struct usb_clear_stall_msg cs_msg[2]; /* generic clear stall - * messages */ + /* generic clear stall message */ + struct usb_udev_msg cs_msg[2]; struct sx enum_sx; struct sx sr_sx; struct mtx device_mtx; @@ -220,6 +220,7 @@ struct usb_device { uint8_t address; /* device addess */ uint8_t device_index; /* device index in "bus->devices" */ uint8_t controller_slot_id; /* controller specific value */ + uint8_t next_config_index; /* used by USB_RE_ENUM_SET_CONFIG */ uint8_t curr_config_index; /* current configuration index */ uint8_t curr_config_no; /* current configuration number */ uint8_t depth; /* distance from root HUB */ @@ -230,6 +231,10 @@ struct usb_device { uint8_t driver_added_refcount; /* our driver added generation count */ uint8_t power_mode; /* see USB_POWER_XXX */ uint8_t re_enumerate_wait; /* set if re-enum. is in progress */ +#define USB_RE_ENUM_DONE 0 +#define USB_RE_ENUM_START 1 +#define USB_RE_ENUM_PWR_OFF 2 +#define USB_RE_ENUM_SET_CONFIG 3 uint8_t ifaces_max; /* number of interfaces present */ uint8_t endpoints_max; /* number of endpoints present */ @@ -301,4 +306,10 @@ void usbd_sr_lock(struct usb_device *); void usbd_sr_unlock(struct usb_device *); uint8_t usbd_enum_is_locked(struct usb_device *); +#if USB_HAVE_TT_SUPPORT +void uhub_tt_buffer_reset_async_locked(struct usb_device *, struct usb_endpoint *); +#endif + +uint8_t uhub_count_active_host_ports(struct usb_device *, enum usb_dev_speed); + #endif /* _USB_DEVICE_H_ */ diff --git a/freebsd/sys/dev/usb/usb_freebsd.h b/freebsd/sys/dev/usb/usb_freebsd.h index 06369a25..4cd1758a 100644 --- a/freebsd/sys/dev/usb/usb_freebsd.h +++ b/freebsd/sys/dev/usb/usb_freebsd.h @@ -45,6 +45,9 @@ #define USB_HAVE_PF 1 #endif /* __rtems__ */ +/* define zero ticks callout value */ +#define USB_CALLOUT_ZERO_TICKS 1 + #define USB_TD_GET_PROC(td) (td)->td_proc #define USB_PROC_GET_GID(td) (td)->p_pgid diff --git a/freebsd/sys/dev/usb/usb_generic.c b/freebsd/sys/dev/usb/usb_generic.c index a0b7f007..e1fc141f 100644 --- a/freebsd/sys/dev/usb/usb_generic.c +++ b/freebsd/sys/dev/usb/usb_generic.c @@ -612,24 +612,17 @@ ugen_set_config(struct usb_fifo *f, uint8_t index) /* not possible in device side mode */ return (ENOTTY); } - if (f->udev->curr_config_index == index) { - /* no change needed */ - return (0); - } + /* make sure all FIFO's are gone */ /* else there can be a deadlock */ if (ugen_fs_uninit(f)) { /* ignore any errors */ DPRINTFN(6, "no FIFOs\n"); } - /* change setting - will free generic FIFOs, if any */ - if (usbd_set_config_index(f->udev, index)) { - return (EIO); - } - /* probe and attach */ - if (usb_probe_and_attach(f->udev, USB_IFACE_INDEX_ANY)) { + + if (usbd_start_set_config(f->udev, index) != 0) return (EIO); - } + return (0); } @@ -963,11 +956,6 @@ ugen_re_enumerate(struct usb_fifo *f) DPRINTFN(6, "device mode\n"); return (ENOTTY); } - if (udev->parent_hub == NULL) { - /* the root HUB cannot be re-enumerated */ - DPRINTFN(6, "cannot reset root HUB\n"); - return (EINVAL); - } /* make sure all FIFO's are gone */ /* else there can be a deadlock */ if (ugen_fs_uninit(f)) { @@ -1751,16 +1739,11 @@ ugen_set_power_mode(struct usb_fifo *f, int mode) switch (mode) { case USB_POWER_MODE_OFF: - /* get the device unconfigured */ - err = ugen_set_config(f, USB_UNCONFIG_INDEX); - if (err) { - DPRINTFN(0, "Could not unconfigure " - "device (ignored)\n"); + if (udev->flags.usb_mode == USB_MODE_HOST && + udev->re_enumerate_wait == USB_RE_ENUM_DONE) { + udev->re_enumerate_wait = USB_RE_ENUM_PWR_OFF; } - - /* clear port enable */ - err = usbd_req_clear_port_feature(udev->parent_hub, - NULL, udev->port_no, UHF_PORT_ENABLE); + /* set power mode will wake up the explore thread */ break; case USB_POWER_MODE_ON: @@ -1808,9 +1791,9 @@ ugen_set_power_mode(struct usb_fifo *f, int mode) /* if we are powered off we need to re-enumerate first */ if (old_mode == USB_POWER_MODE_OFF) { - if (udev->flags.usb_mode == USB_MODE_HOST) { - if (udev->re_enumerate_wait == 0) - udev->re_enumerate_wait = 1; + if (udev->flags.usb_mode == USB_MODE_HOST && + udev->re_enumerate_wait == USB_RE_ENUM_DONE) { + udev->re_enumerate_wait = USB_RE_ENUM_START; } /* set power mode will wake up the explore thread */ } @@ -1832,6 +1815,46 @@ ugen_get_power_mode(struct usb_fifo *f) return (udev->power_mode); } +static int +ugen_get_port_path(struct usb_fifo *f, struct usb_device_port_path *dpp) +{ + struct usb_device *udev = f->udev; + struct usb_device *next; + unsigned int nlevel = 0; + + if (udev == NULL) + goto error; + + dpp->udp_bus = device_get_unit(udev->bus->bdev); + dpp->udp_index = udev->device_index; + + /* count port levels */ + next = udev; + while (next->parent_hub != NULL) { + nlevel++; + next = next->parent_hub; + } + + /* check if too many levels */ + if (nlevel > USB_DEVICE_PORT_PATH_MAX) + goto error; + + /* store port index array */ + next = udev; + while (next->parent_hub != NULL) { + nlevel--; + + dpp->udp_port_no[nlevel] = next->port_no; + dpp->udp_port_level = nlevel; + + next = next->parent_hub; + } + return (0); /* success */ + +error: + return (EINVAL); /* failure */ +} + static int ugen_get_power_usage(struct usb_fifo *f) { @@ -2033,6 +2056,7 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags) struct usb_device_stats *stat; struct usb_fs_init *pinit; struct usb_fs_uninit *puninit; + struct usb_device_port_path *dpp; uint32_t *ptime; void *addr; int *pint; @@ -2205,6 +2229,10 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags) *u.pint = ugen_get_power_mode(f); break; + case USB_GET_DEV_PORT_PATH: + error = ugen_get_port_path(f, u.dpp); + break; + case USB_GET_POWER_USAGE: *u.pint = ugen_get_power_usage(f); break; diff --git a/freebsd/sys/dev/usb/usb_hub.c b/freebsd/sys/dev/usb/usb_hub.c index 2dee6784..9b3bd076 100644 --- a/freebsd/sys/dev/usb/usb_hub.c +++ b/freebsd/sys/dev/usb/usb_hub.c @@ -52,7 +52,6 @@ #include #include -#include #include #include @@ -73,7 +72,13 @@ #include #define UHUB_INTR_INTERVAL 250 /* ms */ -#define UHUB_N_TRANSFER 1 +enum { + UHUB_INTR_TRANSFER, +#if USB_HAVE_TT_SUPPORT + UHUB_RESET_TT_TRANSFER, +#endif + UHUB_N_TRANSFER, +}; #ifdef USB_DEBUG static int uhub_debug = 0; @@ -126,6 +131,9 @@ static bus_child_location_str_t uhub_child_location_string; static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string; static usb_callback_t uhub_intr_callback; +#if USB_HAVE_TT_SUPPORT +static usb_callback_t uhub_reset_tt_callback; +#endif static void usb_dev_resume_peer(struct usb_device *udev); static void usb_dev_suspend_peer(struct usb_device *udev); @@ -133,7 +141,7 @@ static uint8_t usb_peer_should_wakeup(struct usb_device *udev); static const struct usb_config uhub_config[UHUB_N_TRANSFER] = { - [0] = { + [UHUB_INTR_TRANSFER] = { .type = UE_INTERRUPT, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_ANY, @@ -143,6 +151,17 @@ static const struct usb_config uhub_config[UHUB_N_TRANSFER] = { .callback = &uhub_intr_callback, .interval = UHUB_INTR_INTERVAL, }, +#if USB_HAVE_TT_SUPPORT + [UHUB_RESET_TT_TRANSFER] = { + .type = UE_CONTROL, + .endpoint = 0x00, /* Control pipe */ + .direction = UE_DIR_ANY, + .bufsize = sizeof(struct usb_device_request), + .callback = &uhub_reset_tt_callback, + .timeout = 1000, /* 1 second */ + .usb_mode = USB_MODE_HOST, + }, +#endif }; /* @@ -211,6 +230,279 @@ uhub_intr_callback(struct usb_xfer *xfer, usb_error_t error) } } +/*------------------------------------------------------------------------* + * uhub_reset_tt_proc + * + * This function starts the TT reset USB request + *------------------------------------------------------------------------*/ +#if USB_HAVE_TT_SUPPORT +static void +uhub_reset_tt_proc(struct usb_proc_msg *_pm) +{ + struct usb_udev_msg *pm = (void *)_pm; + struct usb_device *udev = pm->udev; + struct usb_hub *hub; + struct uhub_softc *sc; + + hub = udev->hub; + if (hub == NULL) + return; + sc = hub->hubsoftc; + if (sc == NULL) + return; + + /* Change lock */ + USB_BUS_UNLOCK(udev->bus); + mtx_lock(&sc->sc_mtx); + /* Start transfer */ + usbd_transfer_start(sc->sc_xfer[UHUB_RESET_TT_TRANSFER]); + /* Change lock */ + mtx_unlock(&sc->sc_mtx); + USB_BUS_LOCK(udev->bus); +} +#endif + +/*------------------------------------------------------------------------* + * uhub_tt_buffer_reset_async_locked + * + * This function queues a TT reset for the given USB device and endpoint. + *------------------------------------------------------------------------*/ +#if USB_HAVE_TT_SUPPORT +void +uhub_tt_buffer_reset_async_locked(struct usb_device *child, struct usb_endpoint *ep) +{ + struct usb_device_request req; + struct usb_device *udev; + struct usb_hub *hub; + struct usb_port *up; + uint16_t wValue; + uint8_t port; + + if (child == NULL || ep == NULL) + return; + + udev = child->parent_hs_hub; + port = child->hs_port_no; + + if (udev == NULL) + return; + + hub = udev->hub; + if ((hub == NULL) || + (udev->speed != USB_SPEED_HIGH) || + (child->speed != USB_SPEED_LOW && + child->speed != USB_SPEED_FULL) || + (child->flags.usb_mode != USB_MODE_HOST) || + (port == 0) || (ep->edesc == NULL)) { + /* not applicable */ + return; + } + + USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED); + + up = hub->ports + port - 1; + + if (udev->ddesc.bDeviceClass == UDCLASS_HUB && + udev->ddesc.bDeviceProtocol == UDPROTO_HSHUBSTT) + port = 1; + + /* if we already received a clear buffer request, reset the whole TT */ + if (up->req_reset_tt.bRequest != 0) { + req.bmRequestType = UT_WRITE_CLASS_OTHER; + req.bRequest = UR_RESET_TT; + USETW(req.wValue, 0); + req.wIndex[0] = port; + req.wIndex[1] = 0; + USETW(req.wLength, 0); + } else { + wValue = (ep->edesc->bEndpointAddress & 0xF) | + ((child->address & 0x7F) << 4) | + ((ep->edesc->bEndpointAddress & 0x80) << 8) | + ((ep->edesc->bmAttributes & 3) << 12); + + req.bmRequestType = UT_WRITE_CLASS_OTHER; + req.bRequest = UR_CLEAR_TT_BUFFER; + USETW(req.wValue, wValue); + req.wIndex[0] = port; + req.wIndex[1] = 0; + USETW(req.wLength, 0); + } + up->req_reset_tt = req; + /* get reset transfer started */ + usb_proc_msignal(&udev->bus->non_giant_callback_proc, + &hub->tt_msg[0], &hub->tt_msg[1]); +} +#endif + +#if USB_HAVE_TT_SUPPORT +static void +uhub_reset_tt_callback(struct usb_xfer *xfer, usb_error_t error) +{ + struct uhub_softc *sc; + struct usb_device *udev; + struct usb_port *up; + uint8_t x; + + DPRINTF("TT buffer reset\n"); + + sc = usbd_xfer_softc(xfer); + udev = sc->sc_udev; + + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: + case USB_ST_SETUP: +tr_setup: + USB_BUS_LOCK(udev->bus); + /* find first port which needs a TT reset */ + for (x = 0; x != udev->hub->nports; x++) { + up = udev->hub->ports + x; + + if (up->req_reset_tt.bRequest == 0) + continue; + + /* copy in the transfer */ + usbd_copy_in(xfer->frbuffers, 0, &up->req_reset_tt, + sizeof(up->req_reset_tt)); + /* reset buffer */ + memset(&up->req_reset_tt, 0, sizeof(up->req_reset_tt)); + + /* set length */ + usbd_xfer_set_frame_len(xfer, 0, sizeof(up->req_reset_tt)); + xfer->nframes = 1; + USB_BUS_UNLOCK(udev->bus); + + usbd_transfer_submit(xfer); + return; + } + USB_BUS_UNLOCK(udev->bus); + break; + + default: + if (error == USB_ERR_CANCELLED) + break; + + DPRINTF("TT buffer reset failed (%s)\n", usbd_errstr(error)); + goto tr_setup; + } +} +#endif + +/*------------------------------------------------------------------------* + * uhub_count_active_host_ports + * + * This function counts the number of active ports at the given speed. + *------------------------------------------------------------------------*/ +uint8_t +uhub_count_active_host_ports(struct usb_device *udev, enum usb_dev_speed speed) +{ + struct uhub_softc *sc; + struct usb_device *child; + struct usb_hub *hub; + struct usb_port *up; + uint8_t retval = 0; + uint8_t x; + + if (udev == NULL) + goto done; + hub = udev->hub; + if (hub == NULL) + goto done; + sc = hub->hubsoftc; + if (sc == NULL) + goto done; + + for (x = 0; x != hub->nports; x++) { + up = hub->ports + x; + child = usb_bus_port_get_device(udev->bus, up); + if (child != NULL && + child->flags.usb_mode == USB_MODE_HOST && + child->speed == speed) + retval++; + } +done: + return (retval); +} + +void +uhub_explore_handle_re_enumerate(struct usb_device *child) +{ + uint8_t do_unlock; + usb_error_t err; + + /* check if device should be re-enumerated */ + if (child->flags.usb_mode != USB_MODE_HOST) + return; + + do_unlock = usbd_enum_lock(child); + switch (child->re_enumerate_wait) { + case USB_RE_ENUM_START: + err = usbd_set_config_index(child, + USB_UNCONFIG_INDEX); + if (err != 0) { + DPRINTF("Unconfigure failed: %s: Ignored.\n", + usbd_errstr(err)); + } + if (child->parent_hub == NULL) { + /* the root HUB cannot be re-enumerated */ + DPRINTFN(6, "cannot reset root HUB\n"); + err = 0; + } else { + err = usbd_req_re_enumerate(child, NULL); + } + if (err == 0) + err = usbd_set_config_index(child, 0); + if (err == 0) { + err = usb_probe_and_attach(child, + USB_IFACE_INDEX_ANY); + } + child->re_enumerate_wait = USB_RE_ENUM_DONE; + break; + + case USB_RE_ENUM_PWR_OFF: + /* get the device unconfigured */ + err = usbd_set_config_index(child, + USB_UNCONFIG_INDEX); + if (err) { + DPRINTFN(0, "Could not unconfigure " + "device (ignored)\n"); + } + if (child->parent_hub == NULL) { + /* the root HUB cannot be re-enumerated */ + DPRINTFN(6, "cannot set port feature\n"); + err = 0; + } else { + /* clear port enable */ + err = usbd_req_clear_port_feature(child->parent_hub, + NULL, child->port_no, UHF_PORT_ENABLE); + if (err) { + DPRINTFN(0, "Could not disable port " + "(ignored)\n"); + } + } + child->re_enumerate_wait = USB_RE_ENUM_DONE; + break; + + case USB_RE_ENUM_SET_CONFIG: + err = usbd_set_config_index(child, + child->next_config_index); + if (err != 0) { + DPRINTF("Configure failed: %s: Ignored.\n", + usbd_errstr(err)); + } else { + err = usb_probe_and_attach(child, + USB_IFACE_INDEX_ANY); + } + child->re_enumerate_wait = USB_RE_ENUM_DONE; + break; + + default: + child->re_enumerate_wait = USB_RE_ENUM_DONE; + break; + } + if (do_unlock) + usbd_enum_unlock(child); +} + /*------------------------------------------------------------------------* * uhub_explore_sub - subroutine * @@ -239,33 +531,7 @@ uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up) goto done; } - /* check if device should be re-enumerated */ - - if (child->flags.usb_mode == USB_MODE_HOST) { - uint8_t do_unlock; - - do_unlock = usbd_enum_lock(child); - if (child->re_enumerate_wait) { - err = usbd_set_config_index(child, - USB_UNCONFIG_INDEX); - if (err != 0) { - DPRINTF("Unconfigure failed: " - "%s: Ignored.\n", - usbd_errstr(err)); - } - err = usbd_req_re_enumerate(child, NULL); - if (err == 0) - err = usbd_set_config_index(child, 0); - if (err == 0) { - err = usb_probe_and_attach(child, - USB_IFACE_INDEX_ANY); - } - child->re_enumerate_wait = 0; - err = 0; - } - if (do_unlock) - usbd_enum_unlock(child); - } + uhub_explore_handle_re_enumerate(child); /* check if probe and attach should be done */ @@ -522,7 +788,10 @@ repeat: * * NOTE: This part is currently FreeBSD specific. */ - if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE) + if (udev->parent_hub != NULL) { + /* inherit mode from the parent HUB */ + mode = udev->parent_hub->flags.usb_mode; + } else if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE) mode = USB_MODE_DEVICE; else mode = USB_MODE_HOST; @@ -1079,7 +1348,12 @@ uhub_attach(device_t dev) hub->explore = &uhub_explore; hub->nports = nports; hub->hubudev = udev; - +#if USB_HAVE_TT_SUPPORT + hub->tt_msg[0].hdr.pm_callback = &uhub_reset_tt_proc; + hub->tt_msg[0].udev = udev; + hub->tt_msg[1].hdr.pm_callback = &uhub_reset_tt_proc; + hub->tt_msg[1].udev = udev; +#endif /* if self powered hub, give ports maximum current */ if (udev->flags.self_powered) { hub->portpower = USB_MAX_POWER; @@ -1181,11 +1455,9 @@ uhub_attach(device_t dev) /* Start the interrupt endpoint, if any */ - if (sc->sc_xfer[0] != NULL) { - mtx_lock(&sc->sc_mtx); - usbd_transfer_start(sc->sc_xfer[0]); - mtx_unlock(&sc->sc_mtx); - } + mtx_lock(&sc->sc_mtx); + usbd_transfer_start(sc->sc_xfer[UHUB_INTR_TRANSFER]); + mtx_unlock(&sc->sc_mtx); /* Enable automatic power save on all USB HUBs */ @@ -1215,6 +1487,7 @@ uhub_detach(device_t dev) { struct uhub_softc *sc = device_get_softc(dev); struct usb_hub *hub = sc->sc_udev->hub; + struct usb_bus *bus = sc->sc_udev->bus; struct usb_device *child; uint8_t x; @@ -1227,7 +1500,7 @@ uhub_detach(device_t dev) /* Detach all ports */ for (x = 0; x != hub->nports; x++) { - child = usb_bus_port_get_device(sc->sc_udev->bus, hub->ports + x); + child = usb_bus_port_get_device(bus, hub->ports + x); if (child == NULL) { continue; @@ -1239,6 +1512,13 @@ uhub_detach(device_t dev) usb_free_device(child, 0); } +#if USB_HAVE_TT_SUPPORT + /* Make sure our TT messages are not queued anywhere */ + USB_BUS_LOCK(bus); + usb_proc_mwait(&bus->non_giant_callback_proc, + &hub->tt_msg[0], &hub->tt_msg[1]); + USB_BUS_UNLOCK(bus); +#endif free(hub, M_USBDEV); sc->sc_udev->hub = NULL; @@ -2070,9 +2350,10 @@ usbd_transfer_power_ref(struct usb_xfer *xfer, int val) static uint8_t usb_peer_should_wakeup(struct usb_device *udev) { - return ((udev->power_mode == USB_POWER_MODE_ON) || + return (((udev->power_mode == USB_POWER_MODE_ON) && + (udev->flags.usb_mode == USB_MODE_HOST)) || (udev->driver_added_refcount != udev->bus->driver_added_refcount) || - (udev->re_enumerate_wait != 0) || + (udev->re_enumerate_wait != USB_RE_ENUM_DONE) || (udev->pwr_save.type_refs[UE_ISOCHRONOUS] != 0) || (udev->pwr_save.write_refs != 0) || ((udev->pwr_save.read_refs != 0) && @@ -2488,6 +2769,8 @@ usbd_set_power_mode(struct usb_device *udev, uint8_t power_mode) #if USB_HAVE_POWERD usb_bus_power_update(udev->bus); +#else + usb_needs_explore(udev->bus, 0 /* no probe */ ); #endif } @@ -2526,8 +2809,36 @@ usbd_filter_power_mode(struct usb_device *udev, uint8_t power_mode) void usbd_start_re_enumerate(struct usb_device *udev) { - if (udev->re_enumerate_wait == 0) { - udev->re_enumerate_wait = 1; + if (udev->re_enumerate_wait == USB_RE_ENUM_DONE) { + udev->re_enumerate_wait = USB_RE_ENUM_START; usb_needs_explore(udev->bus, 0); } } + +/*-----------------------------------------------------------------------* + * usbd_start_set_config + * + * This function starts setting a USB configuration. This function + * does not need to be called BUS-locked. This function does not wait + * until the set USB configuratino is completed. + *------------------------------------------------------------------------*/ +usb_error_t +usbd_start_set_config(struct usb_device *udev, uint8_t index) +{ + if (udev->re_enumerate_wait == USB_RE_ENUM_DONE) { + if (udev->curr_config_index == index) { + /* no change needed */ + return (0); + } + udev->next_config_index = index; + udev->re_enumerate_wait = USB_RE_ENUM_SET_CONFIG; + usb_needs_explore(udev->bus, 0); + return (0); + } else if (udev->re_enumerate_wait == USB_RE_ENUM_SET_CONFIG) { + if (udev->next_config_index == index) { + /* no change needed */ + return (0); + } + } + return (USB_ERR_PENDING_REQUESTS); +} diff --git a/freebsd/sys/dev/usb/usb_hub.h b/freebsd/sys/dev/usb/usb_hub.h index 23a1fa4f..557a0565 100644 --- a/freebsd/sys/dev/usb/usb_hub.h +++ b/freebsd/sys/dev/usb/usb_hub.h @@ -35,6 +35,9 @@ struct usb_port { #define USB_RESTART_MAX 5 uint8_t device_index; /* zero means not valid */ enum usb_hc_mode usb_mode; /* host or device mode */ +#if USB_HAVE_TT_SUPPORT + struct usb_device_request req_reset_tt __aligned(4); +#endif }; /* @@ -44,6 +47,9 @@ struct usb_hub { struct usb_device *hubudev; /* the HUB device */ usb_error_t (*explore) (struct usb_device *hub); void *hubsoftc; +#if USB_HAVE_TT_SUPPORT + struct usb_udev_msg tt_msg[2]; +#endif usb_size_t uframe_usage[USB_HS_MICRO_FRAMES_MAX]; uint16_t portpower; /* mA per USB port */ uint8_t isoc_last_time; @@ -65,5 +71,6 @@ void usb_bus_power_update(struct usb_bus *bus); void usb_bus_powerd(struct usb_bus *bus); void uhub_root_intr(struct usb_bus *, const uint8_t *, uint8_t); usb_error_t uhub_query_info(struct usb_device *, uint8_t *, uint8_t *); +void uhub_explore_handle_re_enumerate(struct usb_device *); #endif /* _USB_HUB_H_ */ diff --git a/freebsd/sys/dev/usb/usb_ioctl.h b/freebsd/sys/dev/usb/usb_ioctl.h index 9e66bd5a..d5be169b 100644 --- a/freebsd/sys/dev/usb/usb_ioctl.h +++ b/freebsd/sys/dev/usb/usb_ioctl.h @@ -30,6 +30,7 @@ #define _USB_IOCTL_H_ #include +#include /* Building "kdump" depends on these includes */ @@ -41,6 +42,16 @@ #define USB_GENERIC_NAME "ugen" #define USB_TEMPLATE_SYSCTL "hw.usb.template" /* integer type */ +/* + * Align IOCTL structures to hide differences when running 32-bit + * programs under 64-bit kernels: + */ +#ifdef COMPAT_32BIT +#define USB_IOCTL_STRUCT_ALIGN(n) __aligned(n) +#else +#define USB_IOCTL_STRUCT_ALIGN(n) +#endif + /* Definition of valid template sysctl values */ enum { @@ -62,7 +73,7 @@ struct usb_read_dir { #endif uint32_t urd_startentry; uint32_t urd_maxlen; -}; +} USB_IOCTL_STRUCT_ALIGN(8); struct usb_ctl_request { #ifdef COMPAT_32BIT @@ -74,12 +85,12 @@ struct usb_ctl_request { uint16_t ucr_actlen; /* actual length transferred */ uint8_t ucr_addr; /* zero - currently not used */ struct usb_device_request ucr_request; -}; +} USB_IOCTL_STRUCT_ALIGN(8); struct usb_alt_interface { uint8_t uai_interface_index; uint8_t uai_alt_index; -}; +} USB_IOCTL_STRUCT_ALIGN(1); struct usb_gen_descriptor { #ifdef COMPAT_32BIT @@ -98,7 +109,7 @@ struct usb_gen_descriptor { uint8_t ugd_endpt_index; uint8_t ugd_report_type; uint8_t reserved[8]; -}; +} USB_IOCTL_STRUCT_ALIGN(8); struct usb_device_info { uint16_t udi_productNo; @@ -127,24 +138,33 @@ struct usb_device_info { char udi_vendor[128]; char udi_serial[64]; char udi_release[8]; -}; +} USB_IOCTL_STRUCT_ALIGN(2); + +#define USB_DEVICE_PORT_PATH_MAX 32 + +struct usb_device_port_path { + uint8_t udp_bus; /* which bus we are on */ + uint8_t udp_index; /* which device index */ + uint8_t udp_port_level; /* how many levels: 0, 1, 2 ... */ + uint8_t udp_port_no[USB_DEVICE_PORT_PATH_MAX]; +} USB_IOCTL_STRUCT_ALIGN(1); struct usb_device_stats { uint32_t uds_requests_ok[4]; /* Indexed by transfer type UE_XXX */ uint32_t uds_requests_fail[4]; /* Indexed by transfer type UE_XXX */ -}; +} USB_IOCTL_STRUCT_ALIGN(4); struct usb_fs_start { uint8_t ep_index; -}; +} USB_IOCTL_STRUCT_ALIGN(1); struct usb_fs_stop { uint8_t ep_index; -}; +} USB_IOCTL_STRUCT_ALIGN(1); struct usb_fs_complete { uint8_t ep_index; -}; +} USB_IOCTL_STRUCT_ALIGN(1); /* This structure is used for all endpoint types */ struct usb_fs_endpoint { @@ -177,7 +197,7 @@ struct usb_fs_endpoint { /* timeout value for no timeout */ #define USB_FS_TIMEOUT_NONE 0 int status; /* see USB_ERR_XXX */ -}; +} USB_IOCTL_STRUCT_ALIGN(8); struct usb_fs_init { /* userland pointer to endpoints structure */ @@ -188,11 +208,11 @@ struct usb_fs_init { #endif /* maximum number of endpoints */ uint8_t ep_index_max; -}; +} USB_IOCTL_STRUCT_ALIGN(8); struct usb_fs_uninit { uint8_t dummy; /* zero */ -}; +} USB_IOCTL_STRUCT_ALIGN(1); struct usb_fs_open { #define USB_FS_MAX_BUFSIZE (1 << 18) @@ -204,15 +224,20 @@ struct usb_fs_open { uint8_t dev_index; /* currently unused */ uint8_t ep_index; uint8_t ep_no; /* bEndpointNumber */ -}; +} USB_IOCTL_STRUCT_ALIGN(4); + +struct usb_fs_open_stream { + struct usb_fs_open fs_open; + uint16_t stream_id; /* stream ID */ +} USB_IOCTL_STRUCT_ALIGN(4); struct usb_fs_close { uint8_t ep_index; -}; +} USB_IOCTL_STRUCT_ALIGN(1); struct usb_fs_clear_stall_sync { uint8_t ep_index; -}; +} USB_IOCTL_STRUCT_ALIGN(1); struct usb_gen_quirk { uint16_t index; /* Quirk Index */ @@ -222,11 +247,11 @@ struct usb_gen_quirk { uint16_t bcdDeviceHigh; /* High Device Revision */ uint16_t reserved[2]; /* - * String version of quirk including terminating zero. See UQ_XXX in - * "usb_quirk.h". + * String version of quirk including terminating zero. See + * UQ_XXX in "usb_quirk.h". */ char quirkname[64 - 14]; -}; +} USB_IOCTL_STRUCT_ALIGN(2); /* USB controller */ #define USB_REQUEST _IOWR('U', 1, struct usb_ctl_request) @@ -270,7 +295,8 @@ struct usb_gen_quirk { #define USB_IFACE_DRIVER_DETACH _IOW ('U', 125, int) #define USB_GET_PLUGTIME _IOR ('U', 126, uint32_t) #define USB_READ_DIR _IOW ('U', 127, struct usb_read_dir) -/* 128 - 134 unused */ +/* 128 - 133 unused */ +#define USB_GET_DEV_PORT_PATH _IOR ('U', 134, struct usb_device_port_path) #define USB_GET_POWER_USAGE _IOR ('U', 135, int) #define USB_SET_TX_FORCE_SHORT _IOW ('U', 136, int) #define USB_SET_TX_TIMEOUT _IOW ('U', 137, int) diff --git a/freebsd/sys/dev/usb/usb_msctest.c b/freebsd/sys/dev/usb/usb_msctest.c index fcb9f026..4d28346c 100644 --- a/freebsd/sys/dev/usb/usb_msctest.c +++ b/freebsd/sys/dev/usb/usb_msctest.c @@ -85,7 +85,7 @@ enum { DIR_NONE, }; -#define SCSI_MAX_LEN 0x100 +#define SCSI_MAX_LEN MAX(0x100, BULK_SIZE) #define SCSI_INQ_LEN 0x24 #define SCSI_SENSE_LEN 0xFF @@ -141,8 +141,8 @@ struct bbb_csw { struct bbb_transfer { struct mtx mtx; struct cv cv; - struct bbb_cbw cbw; - struct bbb_csw csw; + struct bbb_cbw *cbw; + struct bbb_csw *csw; struct usb_xfer *xfer[ST_MAX]; @@ -152,6 +152,7 @@ struct bbb_transfer { usb_size_t data_rem; /* bytes */ usb_timeout_t data_timeout; /* ms */ usb_frlength_t actlen; /* bytes */ + usb_frlength_t buffer_size; /* bytes */ uint8_t cmd_len; /* bytes */ uint8_t dir; @@ -160,7 +161,7 @@ struct bbb_transfer { uint8_t status_try; int error; - uint8_t buffer[SCSI_MAX_LEN] __aligned(4); + uint8_t *buffer; }; static usb_callback_t bbb_command_callback; @@ -186,7 +187,6 @@ static const struct usb_config bbb_config[ST_MAX] = { .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .bufsize = sizeof(struct bbb_cbw), - .flags = {.ext_buffer = 1,}, .callback = &bbb_command_callback, .timeout = 4 * USB_MS_HZ, /* 4 seconds */ }, @@ -195,8 +195,8 @@ static const struct usb_config bbb_config[ST_MAX] = { .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, - .bufsize = BULK_SIZE, - .flags = {.ext_buffer = 1,.proxy_buffer = 1,.short_xfer_ok = 1,}, + .bufsize = SCSI_MAX_LEN, + .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,}, .callback = &bbb_data_read_callback, .timeout = 4 * USB_MS_HZ, /* 4 seconds */ }, @@ -214,7 +214,7 @@ static const struct usb_config bbb_config[ST_MAX] = { .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, - .bufsize = BULK_SIZE, + .bufsize = SCSI_MAX_LEN, .flags = {.ext_buffer = 1,.proxy_buffer = 1,}, .callback = &bbb_data_write_callback, .timeout = 4 * USB_MS_HZ, /* 4 seconds */ @@ -234,7 +234,7 @@ static const struct usb_config bbb_config[ST_MAX] = { .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .bufsize = sizeof(struct bbb_csw), - .flags = {.ext_buffer = 1,.short_xfer_ok = 1,}, + .flags = {.short_xfer_ok = 1,}, .callback = &bbb_status_callback, .timeout = 1 * USB_MS_HZ, /* 1 second */ }, @@ -243,7 +243,6 @@ static const struct usb_config bbb_config[ST_MAX] = { static void bbb_done(struct bbb_transfer *sc, int error) { - sc->error = error; sc->state = ST_COMMAND; sc->status_try = 1; @@ -292,18 +291,19 @@ bbb_command_callback(struct usb_xfer *xfer, usb_error_t error) case USB_ST_SETUP: sc->status_try = 0; - tag = UGETDW(sc->cbw.dCBWTag) + 1; - USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE); - USETDW(sc->cbw.dCBWTag, tag); - USETDW(sc->cbw.dCBWDataTransferLength, (uint32_t)sc->data_len); - sc->cbw.bCBWFlags = ((sc->dir == DIR_IN) ? CBWFLAGS_IN : CBWFLAGS_OUT); - sc->cbw.bCBWLUN = sc->lun; - sc->cbw.bCDBLength = sc->cmd_len; - if (sc->cbw.bCDBLength > sizeof(sc->cbw.CBWCDB)) { - sc->cbw.bCDBLength = sizeof(sc->cbw.CBWCDB); + tag = UGETDW(sc->cbw->dCBWTag) + 1; + USETDW(sc->cbw->dCBWSignature, CBWSIGNATURE); + USETDW(sc->cbw->dCBWTag, tag); + USETDW(sc->cbw->dCBWDataTransferLength, (uint32_t)sc->data_len); + sc->cbw->bCBWFlags = ((sc->dir == DIR_IN) ? CBWFLAGS_IN : CBWFLAGS_OUT); + sc->cbw->bCBWLUN = sc->lun; + sc->cbw->bCDBLength = sc->cmd_len; + if (sc->cbw->bCDBLength > sizeof(sc->cbw->CBWCDB)) { + sc->cbw->bCDBLength = sizeof(sc->cbw->CBWCDB); DPRINTFN(0, "Truncating long command\n"); } - usbd_xfer_set_frame_data(xfer, 0, &sc->cbw, sizeof(sc->cbw)); + usbd_xfer_set_frame_len(xfer, 0, + sizeof(struct bbb_cbw)); usbd_transfer_submit(xfer); break; @@ -390,7 +390,7 @@ bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error) if (sc->data_rem == 0) { bbb_transfer_start(sc, ST_STATUS); - return; + break; } if (max_bulk > sc->data_rem) { max_bulk = sc->data_rem; @@ -398,7 +398,7 @@ bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error) usbd_xfer_set_timeout(xfer, sc->data_timeout); usbd_xfer_set_frame_data(xfer, 0, sc->data_ptr, max_bulk); usbd_transfer_submit(xfer); - return; + break; default: /* Error */ if (error == USB_ERR_CANCELLED) { @@ -406,8 +406,7 @@ bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error) } else { bbb_transfer_start(sc, ST_DATA_WR_CS); } - return; - + break; } } @@ -432,9 +431,9 @@ bbb_status_callback(struct usb_xfer *xfer, usb_error_t error) /* very simple status check */ - if (actlen < (int)sizeof(sc->csw)) { + if (actlen < (int)sizeof(struct bbb_csw)) { bbb_done(sc, USB_ERR_SHORT_XFER); - } else if (sc->csw.bCSWStatus == CSWSTATUS_GOOD) { + } else if (sc->csw->bCSWStatus == CSWSTATUS_GOOD) { bbb_done(sc, 0); /* success */ } else { bbb_done(sc, ERR_CSW_FAILED); /* error */ @@ -442,7 +441,8 @@ bbb_status_callback(struct usb_xfer *xfer, usb_error_t error) break; case USB_ST_SETUP: - usbd_xfer_set_frame_data(xfer, 0, &sc->csw, sizeof(sc->csw)); + usbd_xfer_set_frame_len(xfer, 0, + sizeof(struct bbb_csw)); usbd_transfer_submit(xfer); break; @@ -480,9 +480,9 @@ bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun, sc->data_timeout = (data_timeout + USB_MS_HZ); sc->actlen = 0; sc->cmd_len = cmd_len; - memset(&sc->cbw.CBWCDB, 0, sizeof(sc->cbw.CBWCDB)); - memcpy(&sc->cbw.CBWCDB, cmd_ptr, cmd_len); - DPRINTFN(1, "SCSI cmd = %*D\n", (int)cmd_len, (char *)sc->cbw.CBWCDB, ":"); + memset(&sc->cbw->CBWCDB, 0, sizeof(sc->cbw->CBWCDB)); + memcpy(&sc->cbw->CBWCDB, cmd_ptr, cmd_len); + DPRINTFN(1, "SCSI cmd = %*D\n", (int)cmd_len, (char *)sc->cbw->CBWCDB, ":"); mtx_lock(&sc->mtx); usbd_transfer_start(sc->xfer[sc->state]); @@ -551,6 +551,16 @@ bbb_attach(struct usb_device *udev, uint8_t iface_index) bbb_detach(sc); return (NULL); } + /* store pointer to DMA buffers */ + sc->buffer = usbd_xfer_get_frame_buffer( + sc->xfer[ST_DATA_RD], 0); + sc->buffer_size = + usbd_xfer_max_len(sc->xfer[ST_DATA_RD]); + sc->cbw = usbd_xfer_get_frame_buffer( + sc->xfer[ST_COMMAND], 0); + sc->csw = usbd_xfer_get_frame_buffer( + sc->xfer[ST_STATUS], 0); + return (sc); } @@ -826,8 +836,8 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method) * TCTMobile needs DIR_IN flag. To get it, we * supply a dummy data with the command. */ - err = bbb_command_start(sc, DIR_IN, 0, &sc->buffer, - sizeof(sc->buffer), &scsi_tct_eject, + err = bbb_command_start(sc, DIR_IN, 0, sc->buffer, + sc->buffer_size, &scsi_tct_eject, sizeof(scsi_tct_eject), USB_MS_HZ); break; default: diff --git a/freebsd/sys/dev/usb/usb_process.c b/freebsd/sys/dev/usb/usb_process.c index 59b26567..d36df36e 100644 --- a/freebsd/sys/dev/usb/usb_process.c +++ b/freebsd/sys/dev/usb/usb_process.c @@ -503,3 +503,15 @@ usb_proc_rewakeup(struct usb_process *up) cv_signal(&up->up_cv); } } + +/*------------------------------------------------------------------------* + * usb_proc_is_called_from + * + * This function will return non-zero if called from inside the USB + * process passed as first argument. Else this function returns zero. + *------------------------------------------------------------------------*/ +int +usb_proc_is_called_from(struct usb_process *up) +{ + return (up->up_curtd == curthread); +} diff --git a/freebsd/sys/dev/usb/usb_process.h b/freebsd/sys/dev/usb/usb_process.h index 9b1a8534..06feee8b 100644 --- a/freebsd/sys/dev/usb/usb_process.h +++ b/freebsd/sys/dev/usb/usb_process.h @@ -79,6 +79,7 @@ void usb_proc_mwait(struct usb_process *up, void *pm0, void *pm1); void usb_proc_free(struct usb_process *up); void *usb_proc_msignal(struct usb_process *up, void *pm0, void *pm1); void usb_proc_rewakeup(struct usb_process *up); +int usb_proc_is_called_from(struct usb_process *up); void usb_proc_explore_mwait(struct usb_device *, void *, void *); void *usb_proc_explore_msignal(struct usb_device *, void *, void *); diff --git a/freebsd/sys/dev/usb/usb_request.c b/freebsd/sys/dev/usb/usb_request.c index 167a7228..e9137bd2 100644 --- a/freebsd/sys/dev/usb/usb_request.c +++ b/freebsd/sys/dev/usb/usb_request.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #define USB_DEBUG_VAR usb_debug @@ -74,6 +73,11 @@ static int usb_no_cs_fail; SYSCTL_INT(_hw_usb, OID_AUTO, no_cs_fail, CTLFLAG_RW, &usb_no_cs_fail, 0, "USB clear stall failures are ignored, if set"); +static int usb_full_ddesc; + +SYSCTL_INT(_hw_usb, OID_AUTO, full_ddesc, CTLFLAG_RW, + &usb_full_ddesc, 0, "USB always read complete device descriptor, if set"); + #ifdef USB_DEBUG #ifdef USB_REQ_DEBUG /* The following structures are used in connection to fault injection. */ @@ -712,6 +716,17 @@ done: if ((mtx != NULL) && (mtx != &Giant)) mtx_lock(mtx); + switch (err) { + case USB_ERR_NORMAL_COMPLETION: + case USB_ERR_SHORT_XFER: + case USB_ERR_STALLED: + case USB_ERR_CANCELLED: + break; + default: + DPRINTF("I/O error - waiting a bit for TT cleanup\n"); + usb_pause_mtx(mtx, hz / 16); + break; + } return ((usb_error_t)err); } @@ -999,7 +1014,7 @@ usbd_req_get_desc(struct usb_device *udev, USETW(req.wLength, min_len); err = usbd_do_request_flags(udev, mtx, &req, - desc, 0, NULL, 1000); + desc, 0, NULL, 500 /* ms */); if (err) { if (!retries) { @@ -1884,32 +1899,41 @@ usbd_setup_device_desc(struct usb_device *udev, struct mtx *mtx) */ switch (udev->speed) { case USB_SPEED_FULL: - case USB_SPEED_LOW: + if (usb_full_ddesc != 0) { + /* get full device descriptor */ + err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc); + if (err == 0) + break; + } + + /* get partial device descriptor, some devices crash on this */ err = usbd_req_get_desc(udev, mtx, NULL, &udev->ddesc, USB_MAX_IPACKET, USB_MAX_IPACKET, 0, UDESC_DEVICE, 0, 0); - if (err != 0) { - DPRINTFN(0, "getting device descriptor " - "at addr %d failed, %s\n", udev->address, - usbd_errstr(err)); - return (err); - } + if (err != 0) + break; + + /* get the full device descriptor */ + err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc); break; + default: DPRINTF("Minimum MaxPacketSize is large enough " - "to hold the complete device descriptor\n"); - break; - } - - /* get the full device descriptor */ - err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc); + "to hold the complete device descriptor or " + "only once MaxPacketSize choice\n"); - /* try one more time, if error */ - if (err) + /* get the full device descriptor */ err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc); - if (err) { - DPRINTF("addr=%d, getting full desc failed\n", - udev->address); + /* try one more time, if error */ + if (err != 0) + err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc); + break; + } + + if (err != 0) { + DPRINTFN(0, "getting device descriptor " + "at addr %d failed, %s\n", udev->address, + usbd_errstr(err)); return (err); } @@ -1954,6 +1978,7 @@ usbd_req_re_enumerate(struct usb_device *udev, struct mtx *mtx) return (USB_ERR_INVAL); } retry: +#if USB_HAVE_TT_SUPPORT /* * Try to reset the High Speed parent HUB of a LOW- or FULL- * speed device, if any. @@ -1961,15 +1986,24 @@ retry: if (udev->parent_hs_hub != NULL && udev->speed != USB_SPEED_HIGH) { DPRINTF("Trying to reset parent High Speed TT.\n"); - err = usbd_req_reset_tt(udev->parent_hs_hub, NULL, - udev->hs_port_no); + if (udev->parent_hs_hub == parent_hub && + (uhub_count_active_host_ports(parent_hub, USB_SPEED_LOW) + + uhub_count_active_host_ports(parent_hub, USB_SPEED_FULL)) == 1) { + /* we can reset the whole TT */ + err = usbd_req_reset_tt(parent_hub, NULL, + udev->hs_port_no); + } else { + /* only reset a particular device and endpoint */ + err = usbd_req_clear_tt_buffer(udev->parent_hs_hub, NULL, + udev->hs_port_no, old_addr, UE_CONTROL, 0); + } if (err) { DPRINTF("Resetting parent High " "Speed TT failed (%s).\n", usbd_errstr(err)); } } - +#endif /* Try to warm reset first */ if (parent_hub->speed == USB_SPEED_SUPER) usbd_req_warm_reset_port(parent_hub, mtx, udev->port_no); diff --git a/freebsd/sys/dev/usb/usb_transfer.c b/freebsd/sys/dev/usb/usb_transfer.c index b2528186..205a72f7 100644 --- a/freebsd/sys/dev/usb/usb_transfer.c +++ b/freebsd/sys/dev/usb/usb_transfer.c @@ -334,6 +334,7 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm) usb_frcount_t n_frlengths; usb_frcount_t n_frbuffers; usb_frcount_t x; + uint16_t maxp_old; uint8_t type; uint8_t zmps; @@ -419,6 +420,11 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm) if (xfer->max_packet_count > parm->hc_max_packet_count) { xfer->max_packet_count = parm->hc_max_packet_count; } + + /* store max packet size value before filtering */ + + maxp_old = xfer->max_packet_size; + /* filter "wMaxPacketSize" according to HC capabilities */ if ((xfer->max_packet_size > parm->hc_max_packet_size) || @@ -451,6 +457,13 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm) } } + /* + * Check if the max packet size was outside its allowed range + * and clamped to a valid value: + */ + if (maxp_old != xfer->max_packet_size) + xfer->flags_int.maxp_was_clamped = 1; + /* compute "max_frame_size" */ usbd_update_max_frame_size(xfer); @@ -2396,7 +2409,9 @@ usbd_transfer_enqueue(struct usb_xfer_queue *pq, struct usb_xfer *xfer) void usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error) { - USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED); + struct usb_xfer_root *info = xfer->xroot; + + USB_BUS_LOCK_ASSERT(info->bus, MA_OWNED); DPRINTF("err=%s\n", usbd_errstr(error)); @@ -2410,10 +2425,10 @@ usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error) xfer->flags_int.control_act = 0; return; } - /* only set transfer error if not already set */ - if (!xfer->error) { + /* only set transfer error, if not already set */ + if (xfer->error == USB_ERR_NORMAL_COMPLETION) xfer->error = error; - } + /* stop any callouts */ usb_callout_stop(&xfer->timeout_handle); @@ -2425,14 +2440,14 @@ usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error) usbd_transfer_dequeue(xfer); #if USB_HAVE_BUSDMA - if (mtx_owned(xfer->xroot->xfer_mtx)) { + if (mtx_owned(info->xfer_mtx)) { struct usb_xfer_queue *pq; /* * If the private USB lock is not locked, then we assume * that the BUS-DMA load stage has been passed: */ - pq = &xfer->xroot->dma_q; + pq = &info->dma_q; if (pq->curr == xfer) { /* start the next BUS-DMA load, if any */ @@ -2442,10 +2457,10 @@ usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error) #endif /* keep some statistics */ if (xfer->error) { - xfer->xroot->bus->stats_err.uds_requests + info->bus->stats_err.uds_requests [xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE]++; } else { - xfer->xroot->bus->stats_ok.uds_requests + info->bus->stats_ok.uds_requests [xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE]++; } @@ -2685,7 +2700,7 @@ usbd_transfer_timeout_ms(struct usb_xfer *xfer, /* defer delay */ usb_callout_reset(&xfer->timeout_handle, - USB_MS_TO_TICKS(ms), cb, xfer); + USB_MS_TO_TICKS(ms) + USB_CALLOUT_ZERO_TICKS, cb, xfer); } /*------------------------------------------------------------------------* @@ -2811,6 +2826,22 @@ usbd_callback_wrapper_sub(struct usb_xfer *xfer) /* end of control transfer, if any */ xfer->flags_int.control_act = 0; +#if USB_HAVE_TT_SUPPORT + switch (xfer->error) { + case USB_ERR_NORMAL_COMPLETION: + case USB_ERR_SHORT_XFER: + case USB_ERR_STALLED: + case USB_ERR_CANCELLED: + /* nothing to do */ + break; + default: + /* try to reset the TT, if any */ + USB_BUS_LOCK(bus); + uhub_tt_buffer_reset_async_locked(xfer->xroot->udev, xfer->endpoint); + USB_BUS_UNLOCK(bus); + break; + } +#endif /* check if we should block the execution queue */ if ((xfer->error != USB_ERR_CANCELLED) && (xfer->flags.pipe_bof)) { @@ -3377,3 +3408,13 @@ usbd_xfer_get_timestamp(struct usb_xfer *xfer) { return (xfer->isoc_time_complete); } + +/* + * The following function returns non-zero if the max packet size + * field was clamped to a valid value. Else it returns zero. + */ +uint8_t +usbd_xfer_maxp_was_clamped(struct usb_xfer *xfer) +{ + return (xfer->flags_int.maxp_was_clamped); +} diff --git a/freebsd/sys/dev/usb/usbdi.h b/freebsd/sys/dev/usb/usbdi.h index 245777f0..6ec26a4a 100644 --- a/freebsd/sys/dev/usb/usbdi.h +++ b/freebsd/sys/dev/usb/usbdi.h @@ -558,6 +558,7 @@ int usbd_xfer_is_stalled(struct usb_xfer *xfer); void usbd_xfer_set_flag(struct usb_xfer *xfer, int flag); void usbd_xfer_clr_flag(struct usb_xfer *xfer, int flag); uint16_t usbd_xfer_get_timestamp(struct usb_xfer *xfer); +uint8_t usbd_xfer_maxp_was_clamped(struct usb_xfer *xfer); void usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len); @@ -574,6 +575,8 @@ void usbd_m_copy_in(struct usb_page_cache *cache, usb_frlength_t dst_offset, void usbd_frame_zero(struct usb_page_cache *cache, usb_frlength_t offset, usb_frlength_t len); void usbd_start_re_enumerate(struct usb_device *udev); +usb_error_t + usbd_start_set_config(struct usb_device *, uint8_t); int usb_fifo_attach(struct usb_device *udev, void *priv_sc, struct mtx *priv_mtx, struct usb_fifo_methods *pm, diff --git a/freebsd/sys/i386/include/machine/specialreg.h b/freebsd/sys/i386/include/machine/specialreg.h index 3ca5e7ae..be36a914 100644 --- a/freebsd/sys/i386/include/machine/specialreg.h +++ b/freebsd/sys/i386/include/machine/specialreg.h @@ -180,9 +180,15 @@ #define AMDID2_WDT 0x00002000 #define AMDID2_LWP 0x00008000 #define AMDID2_FMA4 0x00010000 +#define AMDID2_TCE 0x00020000 #define AMDID2_NODE_ID 0x00080000 #define AMDID2_TBM 0x00200000 #define AMDID2_TOPOLOGY 0x00400000 +#define AMDID2_PCXC 0x00800000 +#define AMDID2_PNXC 0x01000000 +#define AMDID2_DBE 0x04000000 +#define AMDID2_PTSC 0x08000000 +#define AMDID2_PTSCEL2I 0x10000000 /* * CPUID instruction 1 eax info diff --git a/freebsd/sys/kern/init_main.c b/freebsd/sys/kern/init_main.c index 88f5f685..f8d04f2c 100644 --- a/freebsd/sys/kern/init_main.c +++ b/freebsd/sys/kern/init_main.c @@ -250,9 +250,6 @@ restart: /* * Traverse the (now) ordered list of system initialization tasks. * Perform each task, and continue on to the next task. - * - * The last item on the list is expected to be the scheduler, - * which will not return. */ for (sipp = sysinit; sipp < sysinit_end; sipp++) { @@ -312,8 +309,14 @@ restart: #endif /* __rtems__ */ } + mtx_assert(&Giant, MA_OWNED | MA_NOTRECURSED); + mtx_unlock(&Giant); + #ifndef __rtems__ - panic("Shouldn't get here!"); + /* + * Now hand over this thread to swapper. + */ + swapper(); /* NOTREACHED*/ #endif /* __rtems__ */ } @@ -358,7 +361,7 @@ static char wit_warn[] = "WARNING: WITNESS option enabled, expect reduced performance.\n"; SYSINIT(witwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 1, print_caddr_t, wit_warn); -SYSINIT(witwarn2, SI_SUB_RUN_SCHEDULER, SI_ORDER_THIRD + 1, +SYSINIT(witwarn2, SI_SUB_LAST, SI_ORDER_THIRD + 1, print_caddr_t, wit_warn); #endif @@ -367,7 +370,7 @@ static char diag_warn[] = "WARNING: DIAGNOSTIC option enabled, expect reduced performance.\n"; SYSINIT(diagwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 2, print_caddr_t, diag_warn); -SYSINIT(diagwarn2, SI_SUB_RUN_SCHEDULER, SI_ORDER_THIRD + 2, +SYSINIT(diagwarn2, SI_SUB_LAST, SI_ORDER_THIRD + 2, print_caddr_t, diag_warn); #endif @@ -494,6 +497,7 @@ proc0_init(void *dummy __unused) p->p_sysent = &null_sysvec; p->p_flag = P_SYSTEM | P_INMEM; + p->p_flag2 = 0; p->p_state = PRS_NORMAL; knlist_init_mtx(&p->p_klist, &p->p_mtx); STAILQ_INIT(&p->p_ktr); diff --git a/freebsd/sys/kern/kern_event.c b/freebsd/sys/kern/kern_event.c index 69c47246..89cd1765 100644 --- a/freebsd/sys/kern/kern_event.c +++ b/freebsd/sys/kern/kern_event.c @@ -464,8 +464,11 @@ filt_proc(struct knote *kn, long hint) if (!(kn->kn_status & KN_DETACHED)) knlist_remove_inevent(&p->p_klist, kn); kn->kn_flags |= (EV_EOF | EV_ONESHOT); - kn->kn_data = p->p_xstat; kn->kn_ptr.p_proc = NULL; + if (kn->kn_fflags & NOTE_EXIT) + kn->kn_data = p->p_xstat; + if (kn->kn_fflags == 0) + kn->kn_flags |= EV_DROP; return (1); } @@ -497,7 +500,7 @@ knote_fork(struct knlist *list, int pid) continue; kq = kn->kn_kq; KQ_LOCK(kq); - if ((kn->kn_status & KN_INFLUX) == KN_INFLUX) { + if ((kn->kn_status & (KN_INFLUX | KN_SCAN)) == KN_INFLUX) { KQ_UNLOCK(kq); continue; } @@ -507,7 +510,7 @@ knote_fork(struct knlist *list, int pid) */ if ((kn->kn_sfflags & NOTE_TRACK) == 0) { kn->kn_status |= KN_HASKQLOCK; - if (kn->kn_fop->f_event(kn, NOTE_FORK | pid)) + if (kn->kn_fop->f_event(kn, NOTE_FORK)) KNOTE_ACTIVATE(kn, 1); kn->kn_status &= ~KN_HASKQLOCK; KQ_UNLOCK(kq); @@ -535,10 +538,10 @@ knote_fork(struct knlist *list, int pid) kev.data = kn->kn_id; /* parent */ kev.udata = kn->kn_kevent.udata;/* preserve udata */ error = kqueue_register(kq, &kev, NULL, 0); - if (kn->kn_fop->f_event(kn, NOTE_FORK | pid)) - KNOTE_ACTIVATE(kn, 0); if (error) kn->kn_fflags |= NOTE_TRACKERR; + if (kn->kn_fop->f_event(kn, NOTE_FORK)) + KNOTE_ACTIVATE(kn, 0); KQ_LOCK(kq); kn->kn_status &= ~KN_INFLUX; KQ_UNLOCK_FLUX(kq); @@ -753,11 +756,11 @@ sys_kqueue(struct thread *td, struct kqueue_args *uap) #ifndef __rtems__ FILEDESC_XLOCK(fdp); - SLIST_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list); + TAILQ_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list); FILEDESC_XUNLOCK(fdp); #else /* __rtems__ */ rtems_libio_lock(); - SLIST_INSERT_HEAD(&fd_kqlist, kq, kq_list); + TAILQ_INSERT_HEAD(&fd_kqlist, kq, kq_list); rtems_libio_unlock(); #endif /* __rtems__ */ @@ -1076,12 +1079,13 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int wa struct file *fp; struct knote *kn, *tkn; int error, filt, event; - int haskqglobal; + int haskqglobal, filedesc_unlock; fp = NULL; kn = NULL; error = 0; haskqglobal = 0; + filedesc_unlock = 0; filt = kev->filter; fops = kqueue_fo_find(filt); @@ -1125,6 +1129,13 @@ findkn: goto done; } + /* + * Pre-lock the filedesc before the global + * lock mutex, see the comment in + * kqueue_close(). + */ + FILEDESC_XLOCK(td->td_proc->p_fd); + filedesc_unlock = 1; KQ_GLOBAL_LOCK(&kq_global, haskqglobal); } @@ -1154,6 +1165,10 @@ findkn: /* knote is in the process of changing, wait for it to stablize. */ if (kn != NULL && (kn->kn_status & KN_INFLUX) == KN_INFLUX) { KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal); + if (filedesc_unlock) { + FILEDESC_XUNLOCK(td->td_proc->p_fd); + filedesc_unlock = 0; + } kq->kq_state |= KQ_FLUXWAIT; msleep(kq, &kq->kq_lock, PSOCK | PDROP, "kqflxwt", 0); if (fp != NULL) { @@ -1229,7 +1244,7 @@ findkn: * but doing so will not reset any filter which has already been * triggered. */ - kn->kn_status |= KN_INFLUX; + kn->kn_status |= KN_INFLUX | KN_SCAN; KQ_UNLOCK(kq); KN_LIST_LOCK(kn); kn->kn_kevent.udata = kev->udata; @@ -1252,7 +1267,7 @@ done_ev_add: KQ_LOCK(kq); if (event) KNOTE_ACTIVATE(kn, 1); - kn->kn_status &= ~KN_INFLUX; + kn->kn_status &= ~(KN_INFLUX | KN_SCAN); KN_LIST_UNLOCK(kn); if ((kev->flags & EV_DISABLE) && @@ -1270,6 +1285,8 @@ done_ev_add: done: KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal); + if (filedesc_unlock) + FILEDESC_XUNLOCK(td->td_proc->p_fd); if (fp != NULL) fdrop(fp, td); if (tkn != NULL) @@ -1541,7 +1558,21 @@ start: KASSERT((kn->kn_status & KN_INFLUX) == 0, ("KN_INFLUX set when not suppose to be")); - if ((kn->kn_flags & EV_ONESHOT) == EV_ONESHOT) { + if ((kn->kn_flags & EV_DROP) == EV_DROP) { + kn->kn_status &= ~KN_QUEUED; + kn->kn_status |= KN_INFLUX; + kq->kq_count--; + KQ_UNLOCK(kq); + /* + * We don't need to lock the list since we've marked + * it _INFLUX. + */ + if (!(kn->kn_status & KN_DETACHED)) + kn->kn_fop->f_detach(kn); + knote_drop(kn, td); + KQ_LOCK(kq); + continue; + } else if ((kn->kn_flags & EV_ONESHOT) == EV_ONESHOT) { kn->kn_status &= ~KN_QUEUED; kn->kn_status |= KN_INFLUX; kq->kq_count--; @@ -1557,7 +1588,7 @@ start: KQ_LOCK(kq); kn = NULL; } else { - kn->kn_status |= KN_INFLUX; + kn->kn_status |= KN_INFLUX | KN_SCAN; KQ_UNLOCK(kq); if ((kn->kn_status & KN_KQUEUE) == KN_KQUEUE) KQ_GLOBAL_LOCK(&kq_global, haskqglobal); @@ -1566,7 +1597,8 @@ start: KQ_LOCK(kq); KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal); kn->kn_status &= - ~(KN_QUEUED | KN_ACTIVE | KN_INFLUX); + ~(KN_QUEUED | KN_ACTIVE | KN_INFLUX | + KN_SCAN); kq->kq_count--; KN_LIST_UNLOCK(kn); influx = 1; @@ -1596,7 +1628,7 @@ start: } else TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe); - kn->kn_status &= ~(KN_INFLUX); + kn->kn_status &= ~(KN_INFLUX | KN_SCAN); KN_LIST_UNLOCK(kn); influx = 1; } @@ -1788,6 +1820,7 @@ kqueue_close(struct file *fp, struct thread *td) struct knote *kn; int i; int error; + int filedesc_unlock; #ifdef __rtems__ /* FIXME: Move this to the RTEMS close() function */ @@ -1797,6 +1830,7 @@ kqueue_close(struct file *fp, struct thread *td) if ((error = kqueue_acquire(fp, &kq))) return error; + filedesc_unlock = 0; KQ_LOCK(kq); KASSERT((kq->kq_state & KQ_CLOSING) != KQ_CLOSING, @@ -1863,12 +1897,24 @@ kqueue_close(struct file *fp, struct thread *td) KQ_UNLOCK(kq); #ifndef __rtems__ - FILEDESC_XLOCK(fdp); - SLIST_REMOVE(&fdp->fd_kqlist, kq, kqueue, kq_list); - FILEDESC_XUNLOCK(fdp); + /* + * We could be called due to the knote_drop() doing fdrop(), + * called from kqueue_register(). In this case the global + * lock is owned, and filedesc sx is locked before, to not + * take the sleepable lock after non-sleepable. + */ + if (!sx_xlocked(FILEDESC_LOCK(fdp))) { + FILEDESC_XLOCK(fdp); + filedesc_unlock = 1; + } else + filedesc_unlock = 0; + TAILQ_REMOVE(&fdp->fd_kqlist, kq, kq_list); + if (filedesc_unlock) + FILEDESC_XUNLOCK(fdp); #else /* __rtems__ */ + (void)filedesc_unlock; rtems_libio_lock(); - SLIST_REMOVE(&fd_kqlist, kq, kqueue, kq_list); + TAILQ_REMOVE(&fd_kqlist, kq, kq_list); rtems_libio_unlock(); #endif /* __rtems__ */ @@ -1966,28 +2012,33 @@ knote(struct knlist *list, long hint, int lockflags) */ SLIST_FOREACH(kn, &list->kl_list, kn_selnext) { kq = kn->kn_kq; - if ((kn->kn_status & KN_INFLUX) != KN_INFLUX) { + KQ_LOCK(kq); + if ((kn->kn_status & (KN_INFLUX | KN_SCAN)) == KN_INFLUX) { + /* + * Do not process the influx notes, except for + * the influx coming from the kq unlock in the + * kqueue_scan(). In the later case, we do + * not interfere with the scan, since the code + * fragment in kqueue_scan() locks the knlist, + * and cannot proceed until we finished. + */ + KQ_UNLOCK(kq); + } else if ((lockflags & KNF_NOKQLOCK) != 0) { + kn->kn_status |= KN_INFLUX; + KQ_UNLOCK(kq); + error = kn->kn_fop->f_event(kn, hint); KQ_LOCK(kq); - if ((kn->kn_status & KN_INFLUX) == KN_INFLUX) { - KQ_UNLOCK(kq); - } else if ((lockflags & KNF_NOKQLOCK) != 0) { - kn->kn_status |= KN_INFLUX; - KQ_UNLOCK(kq); - error = kn->kn_fop->f_event(kn, hint); - KQ_LOCK(kq); - kn->kn_status &= ~KN_INFLUX; - if (error) - KNOTE_ACTIVATE(kn, 1); - KQ_UNLOCK_FLUX(kq); - } else { - kn->kn_status |= KN_HASKQLOCK; - if (kn->kn_fop->f_event(kn, hint)) - KNOTE_ACTIVATE(kn, 1); - kn->kn_status &= ~KN_HASKQLOCK; - KQ_UNLOCK(kq); - } + kn->kn_status &= ~KN_INFLUX; + if (error) + KNOTE_ACTIVATE(kn, 1); + KQ_UNLOCK_FLUX(kq); + } else { + kn->kn_status |= KN_HASKQLOCK; + if (kn->kn_fop->f_event(kn, hint)) + KNOTE_ACTIVATE(kn, 1); + kn->kn_status &= ~KN_HASKQLOCK; + KQ_UNLOCK(kq); } - kq = NULL; } if ((lockflags & KNF_LISTLOCKED) == 0) list->kl_unlock(list->kl_lockarg); @@ -2231,11 +2282,11 @@ knote_fdclose(struct thread *td, int fd) * since filedesc is locked. */ #ifndef __rtems__ - SLIST_FOREACH(kq, &fdp->fd_kqlist, kq_list) { + TAILQ_FOREACH(kq, &fdp->fd_kqlist, kq_list) { #else /* __rtems__ */ /* FIXME: Use separate lock? */ rtems_libio_lock(); - SLIST_FOREACH(kq, &fd_kqlist, kq_list) { + TAILQ_FOREACH(kq, &fd_kqlist, kq_list) { #endif /* __rtems__ */ KQ_LOCK(kq); diff --git a/freebsd/sys/kern/kern_linker.c b/freebsd/sys/kern/kern_linker.c index b1b46d7a..39664a85 100644 --- a/freebsd/sys/kern/kern_linker.c +++ b/freebsd/sys/kern/kern_linker.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -71,17 +72,6 @@ SYSCTL_INT(_debug, OID_AUTO, kld_debug, CTLFLAG_RW, &kld_debug, 0, "Set various levels of KLD debug"); #endif -#define KLD_LOCK() sx_xlock(&kld_sx) -#define KLD_UNLOCK() sx_xunlock(&kld_sx) -#define KLD_DOWNGRADE() sx_downgrade(&kld_sx) -#define KLD_LOCK_READ() sx_slock(&kld_sx) -#define KLD_UNLOCK_READ() sx_sunlock(&kld_sx) -#define KLD_LOCKED() sx_xlocked(&kld_sx) -#define KLD_LOCK_ASSERT() do { \ - if (!cold) \ - sx_assert(&kld_sx, SX_XLOCKED); \ -} while (0) - /* * static char *linker_search_path(const char *name, struct mod_depend * *verinfo); @@ -123,7 +113,8 @@ static int linker_no_more_classes = 0; #define LINKER_GET_NEXT_FILE_ID(a) do { \ linker_file_t lftmp; \ \ - KLD_LOCK_ASSERT(); \ + if (!cold) \ + sx_assert(&kld_sx, SA_XLOCKED); \ retry: \ TAILQ_FOREACH(lftmp, &linker_files, link) { \ if (next_file_id == lftmp->id) { \ @@ -210,6 +201,8 @@ linker_file_sysinit(linker_file_t lf) KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n", lf->filename)); + sx_assert(&kld_sx, SA_XLOCKED); + if (linker_file_lookup_set(lf, "sysinit_set", &start, &stop, NULL) != 0) return; /* @@ -235,6 +228,7 @@ linker_file_sysinit(linker_file_t lf) * Traverse the (now) ordered list of system initialization tasks. * Perform each task, and continue on to the next task. */ + sx_xunlock(&kld_sx); mtx_lock(&Giant); for (sipp = start; sipp < stop; sipp++) { if ((*sipp)->subsystem == SI_SUB_DUMMY) @@ -244,6 +238,7 @@ linker_file_sysinit(linker_file_t lf) (*((*sipp)->func)) ((*sipp)->udata); } mtx_unlock(&Giant); + sx_xlock(&kld_sx); } static void @@ -254,6 +249,8 @@ linker_file_sysuninit(linker_file_t lf) KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n", lf->filename)); + sx_assert(&kld_sx, SA_XLOCKED); + if (linker_file_lookup_set(lf, "sysuninit_set", &start, &stop, NULL) != 0) return; @@ -281,6 +278,7 @@ linker_file_sysuninit(linker_file_t lf) * Traverse the (now) ordered list of system initialization tasks. * Perform each task, and continue on to the next task. */ + sx_xunlock(&kld_sx); mtx_lock(&Giant); for (sipp = start; sipp < stop; sipp++) { if ((*sipp)->subsystem == SI_SUB_DUMMY) @@ -290,6 +288,7 @@ linker_file_sysuninit(linker_file_t lf) (*((*sipp)->func)) ((*sipp)->udata); } mtx_unlock(&Giant); + sx_xlock(&kld_sx); } static void @@ -301,13 +300,17 @@ linker_file_register_sysctls(linker_file_t lf) ("linker_file_register_sysctls: registering SYSCTLs for %s\n", lf->filename)); + sx_assert(&kld_sx, SA_XLOCKED); + if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0) return; + sx_xunlock(&kld_sx); sysctl_lock(); for (oidp = start; oidp < stop; oidp++) sysctl_register_oid(*oidp); sysctl_unlock(); + sx_xlock(&kld_sx); } static void @@ -318,13 +321,17 @@ linker_file_unregister_sysctls(linker_file_t lf) KLD_DPF(FILE, ("linker_file_unregister_sysctls: registering SYSCTLs" " for %s\n", lf->filename)); + sx_assert(&kld_sx, SA_XLOCKED); + if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0) return; + sx_xunlock(&kld_sx); sysctl_lock(); for (oidp = start; oidp < stop; oidp++) sysctl_unregister_oid(*oidp); sysctl_unlock(); + sx_xlock(&kld_sx); } #endif /* __rtems__ */ @@ -339,6 +346,8 @@ linker_file_register_modules(linker_file_t lf) " in %s\n", lf->filename)); #ifndef __rtems__ + sx_assert(&kld_sx, SA_XLOCKED); + if (linker_file_lookup_set(lf, "modmetadata_set", &start, &stop, NULL) != 0) { /* @@ -379,7 +388,9 @@ linker_init_kernel_modules(void) { #ifndef __rtems__ + sx_xlock(&kld_sx); linker_file_register_modules(linker_kernel_file); + sx_xunlock(&kld_sx); #else /* __rtems__ */ linker_file_register_modules(NULL); #endif /* __rtems__ */ @@ -400,7 +411,7 @@ linker_load_file(const char *filename, linker_file_t *result) if (prison0.pr_securelevel > 0) return (EPERM); - KLD_LOCK_ASSERT(); + sx_assert(&kld_sx, SA_XLOCKED); lf = linker_find_file_by_name(filename); if (lf) { KLD_DPF(FILE, ("linker_load_file: file %s is already loaded," @@ -434,10 +445,8 @@ linker_load_file(const char *filename, linker_file_t *result) return (error); } modules = !TAILQ_EMPTY(&lf->modules); - KLD_UNLOCK(); linker_file_register_sysctls(lf); linker_file_sysinit(lf); - KLD_LOCK(); lf->flags |= LINKER_FILE_LINKED; /* @@ -449,6 +458,7 @@ linker_load_file(const char *filename, linker_file_t *result) linker_file_unload(lf, LINKER_UNLOAD_FORCE); return (ENOEXEC); } + EVENTHANDLER_INVOKE(kld_load, lf); *result = lf; return (0); } @@ -488,16 +498,16 @@ linker_reference_module(const char *modname, struct mod_depend *verinfo, modlist_t mod; int error; - KLD_LOCK(); + sx_xlock(&kld_sx); if ((mod = modlist_lookup2(modname, verinfo)) != NULL) { *result = mod->container; (*result)->refs++; - KLD_UNLOCK(); + sx_xunlock(&kld_sx); return (0); } error = linker_load_module(NULL, modname, NULL, verinfo, result); - KLD_UNLOCK(); + sx_xunlock(&kld_sx); return (error); } @@ -508,13 +518,13 @@ linker_release_module(const char *modname, struct mod_depend *verinfo, modlist_t mod; int error; - KLD_LOCK(); + sx_xlock(&kld_sx); if (lf == NULL) { KASSERT(modname != NULL, ("linker_release_module: no file or name")); mod = modlist_lookup2(modname, verinfo); if (mod == NULL) { - KLD_UNLOCK(); + sx_xunlock(&kld_sx); return (ESRCH); } lf = mod->container; @@ -522,7 +532,7 @@ linker_release_module(const char *modname, struct mod_depend *verinfo, KASSERT(modname == NULL && verinfo == NULL, ("linker_release_module: both file and name")); error = linker_file_unload(lf, LINKER_UNLOAD_NORMAL); - KLD_UNLOCK(); + sx_xunlock(&kld_sx); return (error); } @@ -535,7 +545,7 @@ linker_find_file_by_name(const char *filename) koname = malloc(strlen(filename) + 4, M_LINKER, M_WAITOK); sprintf(koname, "%s.ko", filename); - KLD_LOCK_ASSERT(); + sx_assert(&kld_sx, SA_XLOCKED); TAILQ_FOREACH(lf, &linker_files, link) { if (strcmp(lf->filename, koname) == 0) break; @@ -551,7 +561,7 @@ linker_find_file_by_id(int fileid) { linker_file_t lf; - KLD_LOCK_ASSERT(); + sx_assert(&kld_sx, SA_XLOCKED); TAILQ_FOREACH(lf, &linker_files, link) if (lf->id == fileid && lf->flags & LINKER_FILE_LINKED) break; @@ -564,13 +574,13 @@ linker_file_foreach(linker_predicate_t *predicate, void *context) linker_file_t lf; int retval = 0; - KLD_LOCK(); + sx_xlock(&kld_sx); TAILQ_FOREACH(lf, &linker_files, link) { retval = predicate(lf, context); if (retval != 0) break; } - KLD_UNLOCK(); + sx_xunlock(&kld_sx); return (retval); } @@ -580,7 +590,8 @@ linker_make_file(const char *pathname, linker_class_t lc) linker_file_t lf; const char *filename; - KLD_LOCK_ASSERT(); + if (!cold) + sx_assert(&kld_sx, SA_XLOCKED); filename = linker_basename(pathname); KLD_DPF(FILE, ("linker_make_file: new file, filename='%s' for pathname='%s'\n", filename, pathname)); @@ -596,8 +607,6 @@ linker_make_file(const char *pathname, linker_class_t lc) lf->ndeps = 0; lf->deps = NULL; lf->loadcnt = ++loadcnt; - lf->sdt_probes = NULL; - lf->sdt_nprobes = 0; STAILQ_INIT(&lf->common); TAILQ_INIT(&lf->modules); TAILQ_INSERT_TAIL(&linker_files, lf, link); @@ -616,7 +625,7 @@ linker_file_unload(linker_file_t file, int flags) if (prison0.pr_securelevel > 0) return (EPERM); - KLD_LOCK_ASSERT(); + sx_assert(&kld_sx, SA_XLOCKED); KLD_DPF(FILE, ("linker_file_unload: lf->refs=%d\n", file->refs)); /* Easy case of just dropping a reference. */ @@ -625,6 +634,12 @@ linker_file_unload(linker_file_t file, int flags) return (0); } + /* Give eventhandlers a chance to prevent the unload. */ + error = 0; + EVENTHANDLER_INVOKE(kld_unload_try, file, &error); + if (error != 0) + return (EBUSY); + KLD_DPF(FILE, ("linker_file_unload: file is unloading," " informing modules\n")); @@ -689,10 +704,8 @@ linker_file_unload(linker_file_t file, int flags) */ if (file->flags & LINKER_FILE_LINKED) { file->flags &= ~LINKER_FILE_LINKED; - KLD_UNLOCK(); linker_file_sysuninit(file); linker_file_unregister_sysctls(file); - KLD_LOCK(); } TAILQ_REMOVE(&linker_files, file, link); @@ -708,6 +721,10 @@ linker_file_unload(linker_file_t file, int flags) } LINKER_UNLOAD(file); + + EVENTHANDLER_INVOKE(kld_unload, file->filename, file->address, + file->size); + if (file->filename) { free(file->filename, M_LINKER); file->filename = NULL; @@ -731,18 +748,9 @@ linker_file_add_dependency(linker_file_t file, linker_file_t dep) { linker_file_t *newdeps; - KLD_LOCK_ASSERT(); - newdeps = malloc((file->ndeps + 1) * sizeof(linker_file_t *), + sx_assert(&kld_sx, SA_XLOCKED); + file->deps = realloc(file->deps, (file->ndeps + 1) * sizeof(*newdeps), M_LINKER, M_WAITOK | M_ZERO); - if (newdeps == NULL) - return (ENOMEM); - - if (file->deps) { - bcopy(file->deps, newdeps, - file->ndeps * sizeof(linker_file_t *)); - free(file->deps, M_LINKER); - } - file->deps = newdeps; file->deps[file->ndeps] = dep; file->ndeps++; KLD_DPF(FILE, ("linker_file_add_dependency:" @@ -761,15 +769,9 @@ int linker_file_lookup_set(linker_file_t file, const char *name, void *firstp, void *lastp, int *countp) { - int error, locked; - locked = KLD_LOCKED(); - if (!locked) - KLD_LOCK(); - error = LINKER_LOOKUP_SET(file, name, firstp, lastp, countp); - if (!locked) - KLD_UNLOCK(); - return (error); + sx_assert(&kld_sx, SA_LOCKED); + return (LINKER_LOOKUP_SET(file, name, firstp, lastp, countp)); } /* @@ -788,12 +790,12 @@ linker_file_lookup_symbol(linker_file_t file, const char *name, int deps) caddr_t sym; int locked; - locked = KLD_LOCKED(); + locked = sx_xlocked(&kld_sx); if (!locked) - KLD_LOCK(); + sx_xlock(&kld_sx); sym = linker_file_lookup_symbol_internal(file, name, deps); if (!locked) - KLD_UNLOCK(); + sx_xunlock(&kld_sx); return (sym); } @@ -807,7 +809,7 @@ linker_file_lookup_symbol_internal(linker_file_t file, const char *name, size_t common_size = 0; int i; - KLD_LOCK_ASSERT(); + sx_assert(&kld_sx, SA_XLOCKED); KLD_DPF(SYM, ("linker_file_lookup_symbol: file=%p, name=%s, deps=%d\n", file, name, deps)); @@ -1007,9 +1009,9 @@ linker_search_symbol_name(caddr_t value, char *buf, u_int buflen, { int error; - KLD_LOCK(); + sx_xlock(&kld_sx); error = linker_debug_search_symbol_name(value, buf, buflen, offset); - KLD_UNLOCK(); + sx_xunlock(&kld_sx); return (error); } @@ -1019,9 +1021,6 @@ linker_search_symbol_name(caddr_t value, char *buf, u_int buflen, int kern_kldload(struct thread *td, const char *file, int *fileid) { -#ifdef HWPMC_HOOKS - struct pmckern_map_in pkm; -#endif const char *kldname, *modname; linker_file_t lf; int error; @@ -1051,24 +1050,16 @@ kern_kldload(struct thread *td, const char *file, int *fileid) modname = file; } - KLD_LOCK(); + sx_xlock(&kld_sx); error = linker_load_module(kldname, modname, NULL, NULL, &lf); if (error) { - KLD_UNLOCK(); + sx_xunlock(&kld_sx); goto done; } lf->userrefs++; if (fileid != NULL) *fileid = lf->id; -#ifdef HWPMC_HOOKS - KLD_DOWNGRADE(); - pkm.pm_file = lf->filename; - pkm.pm_address = (uintptr_t) lf->address; - PMC_CALL_HOOK(td, PMC_FN_KLD_LOAD, (void *) &pkm); - KLD_UNLOCK_READ(); -#else - KLD_UNLOCK(); -#endif + sx_xunlock(&kld_sx); done: CURVNET_RESTORE(); @@ -1097,9 +1088,6 @@ sys_kldload(struct thread *td, struct kldload_args *uap) int kern_kldunload(struct thread *td, int fileid, int flags) { -#ifdef HWPMC_HOOKS - struct pmckern_map_out pkm; -#endif linker_file_t lf; int error = 0; @@ -1110,17 +1098,12 @@ kern_kldunload(struct thread *td, int fileid, int flags) return (error); CURVNET_SET(TD_TO_VNET(td)); - KLD_LOCK(); + sx_xlock(&kld_sx); lf = linker_find_file_by_id(fileid); if (lf) { KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs)); - /* Check if there are DTrace probes enabled on this file. */ - if (lf->nenabled > 0) { - printf("kldunload: attempt to unload file that has" - " DTrace probes enabled\n"); - error = EBUSY; - } else if (lf->userrefs == 0) { + if (lf->userrefs == 0) { /* * XXX: maybe LINKER_UNLOAD_FORCE should override ? */ @@ -1128,11 +1111,6 @@ kern_kldunload(struct thread *td, int fileid, int flags) " loaded by the kernel\n"); error = EBUSY; } else { -#ifdef HWPMC_HOOKS - /* Save data needed by hwpmc(4) before unloading. */ - pkm.pm_address = (uintptr_t) lf->address; - pkm.pm_size = lf->size; -#endif lf->userrefs--; error = linker_file_unload(lf, flags); if (error) @@ -1140,17 +1118,8 @@ kern_kldunload(struct thread *td, int fileid, int flags) } } else error = ENOENT; + sx_xunlock(&kld_sx); -#ifdef HWPMC_HOOKS - if (error == 0) { - KLD_DOWNGRADE(); - PMC_CALL_HOOK(td, PMC_FN_KLD_UNLOAD, (void *) &pkm); - KLD_UNLOCK_READ(); - } else - KLD_UNLOCK(); -#else - KLD_UNLOCK(); -#endif CURVNET_RESTORE(); return (error); } @@ -1193,13 +1162,13 @@ sys_kldfind(struct thread *td, struct kldfind_args *uap) goto out; filename = linker_basename(pathname); - KLD_LOCK(); + sx_xlock(&kld_sx); lf = linker_find_file_by_name(filename); if (lf) td->td_retval[0] = lf->id; else error = ENOENT; - KLD_UNLOCK(); + sx_xunlock(&kld_sx); out: free(pathname, M_TEMP); return (error); @@ -1217,7 +1186,7 @@ sys_kldnext(struct thread *td, struct kldnext_args *uap) return (error); #endif - KLD_LOCK(); + sx_xlock(&kld_sx); if (uap->fileid == 0) lf = TAILQ_FIRST(&linker_files); else { @@ -1238,7 +1207,7 @@ sys_kldnext(struct thread *td, struct kldnext_args *uap) else td->td_retval[0] = 0; out: - KLD_UNLOCK(); + sx_xunlock(&kld_sx); return (error); } @@ -1277,10 +1246,10 @@ kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat) return (error); #endif - KLD_LOCK(); + sx_xlock(&kld_sx); lf = linker_find_file_by_id(fileid); if (lf == NULL) { - KLD_UNLOCK(); + sx_xunlock(&kld_sx); return (ENOENT); } @@ -1298,7 +1267,7 @@ kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat) if (namelen > MAXPATHLEN) namelen = MAXPATHLEN; bcopy(lf->pathname, &stat->pathname[0], namelen); - KLD_UNLOCK(); + sx_xunlock(&kld_sx); td->td_retval[0] = 0; return (0); @@ -1317,7 +1286,7 @@ sys_kldfirstmod(struct thread *td, struct kldfirstmod_args *uap) return (error); #endif - KLD_LOCK(); + sx_xlock(&kld_sx); lf = linker_find_file_by_id(uap->fileid); if (lf) { MOD_SLOCK; @@ -1329,7 +1298,7 @@ sys_kldfirstmod(struct thread *td, struct kldfirstmod_args *uap) MOD_SUNLOCK; } else error = ENOENT; - KLD_UNLOCK(); + sx_xunlock(&kld_sx); return (error); } @@ -1357,7 +1326,7 @@ sys_kldsym(struct thread *td, struct kldsym_args *uap) symstr = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); if ((error = copyinstr(lookup.symname, symstr, MAXPATHLEN, NULL)) != 0) goto out; - KLD_LOCK(); + sx_xlock(&kld_sx); if (uap->fileid != 0) { lf = linker_find_file_by_id(uap->fileid); if (lf == NULL) @@ -1383,7 +1352,7 @@ sys_kldsym(struct thread *td, struct kldsym_args *uap) if (lf == NULL) error = ENOENT; } - KLD_UNLOCK(); + sx_xunlock(&kld_sx); out: free(symstr, M_TEMP); return (error); @@ -1492,6 +1461,7 @@ linker_preload(void *arg) error = 0; modptr = NULL; + sx_xlock(&kld_sx); while ((modptr = preload_search_next_name(modptr)) != NULL) { modname = (char *)preload_search_info(modptr, MODINFO_NAME); modtype = (char *)preload_search_info(modptr, MODINFO_TYPE); @@ -1673,6 +1643,7 @@ fail: TAILQ_REMOVE(&depended_files, lf, loaded); linker_file_unload(lf, LINKER_UNLOAD_FORCE); } + sx_xunlock(&kld_sx); /* woohoo! we made it! */ } @@ -1978,7 +1949,7 @@ linker_hwpmc_list_objects(void) int i, nmappings; nmappings = 0; - KLD_LOCK_READ(); + sx_slock(&kld_sx); TAILQ_FOREACH(lf, &linker_files, link) nmappings++; @@ -1993,7 +1964,7 @@ linker_hwpmc_list_objects(void) kobase[i].pm_address = (uintptr_t)lf->address; i++; } - KLD_UNLOCK_READ(); + sx_sunlock(&kld_sx); KASSERT(i > 0, ("linker_hpwmc_list_objects: no kernel objects?")); @@ -2019,7 +1990,7 @@ linker_load_module(const char *kldname, const char *modname, char *pathname; int error; - KLD_LOCK_ASSERT(); + sx_assert(&kld_sx, SA_XLOCKED); if (modname == NULL) { /* * We have to load KLD @@ -2093,7 +2064,7 @@ linker_load_dependencies(linker_file_t lf) /* * All files are dependant on /kernel. */ - KLD_LOCK_ASSERT(); + sx_assert(&kld_sx, SA_XLOCKED); if (linker_kernel_file) { linker_kernel_file->refs++; error = linker_file_add_dependency(lf, linker_kernel_file); @@ -2185,16 +2156,16 @@ sysctl_kern_function_list(SYSCTL_HANDLER_ARGS) error = sysctl_wire_old_buffer(req, 0); if (error != 0) return (error); - KLD_LOCK(); + sx_xlock(&kld_sx); TAILQ_FOREACH(lf, &linker_files, link) { error = LINKER_EACH_FUNCTION_NAME(lf, sysctl_kern_function_list_iterate, req); if (error) { - KLD_UNLOCK(); + sx_xunlock(&kld_sx); return (error); } } - KLD_UNLOCK(); + sx_xunlock(&kld_sx); return (SYSCTL_OUT(req, "", 1)); } diff --git a/freebsd/sys/kern/kern_mbuf.c b/freebsd/sys/kern/kern_mbuf.c index 98cfb1f0..74e7aa10 100644 --- a/freebsd/sys/kern/kern_mbuf.c +++ b/freebsd/sys/kern/kern_mbuf.c @@ -2,7 +2,7 @@ /*- * Copyright (c) 2004, 2005, - * Bosko Milekic . All rights reserved. + * Bosko Milekic . All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -49,9 +49,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include +#ifdef __rtems__ +#include +#endif /* __rtems__ */ /* * In FreeBSD, Mbufs and Mbuf Clusters are allocated from UMA @@ -78,7 +82,7 @@ __FBSDID("$FreeBSD$"); * [ Cluster Zone ] [ Zone ] [ Mbuf Master Zone ] * | \________ | * [ Cluster Keg ] \ / - * | [ Mbuf Keg ] + * | [ Mbuf Keg ] * [ Cluster Slabs ] | * | [ Mbuf Slabs ] * \____________(VM)_________________/ @@ -98,39 +102,69 @@ __FBSDID("$FreeBSD$"); * */ +int nmbufs; /* limits number of mbufs */ int nmbclusters; /* limits number of mbuf clusters */ int nmbjumbop; /* limits number of page size jumbo clusters */ int nmbjumbo9; /* limits number of 9k jumbo clusters */ int nmbjumbo16; /* limits number of 16k jumbo clusters */ struct mbstat mbstat; +static quad_t maxmbufmem; /* overall real memory limit for all mbufs */ + +SYSCTL_QUAD(_kern_ipc, OID_AUTO, maxmbufmem, CTLFLAG_RDTUN, &maxmbufmem, 0, + "Maximum real memory allocateable to various mbuf types"); + /* - * tunable_mbinit() has to be run before init_maxsockets() thus - * the SYSINIT order below is SI_ORDER_MIDDLE while init_maxsockets() - * runs at SI_ORDER_ANY. + * tunable_mbinit() has to be run before any mbuf allocations are done. */ static void tunable_mbinit(void *dummy) { +#ifndef __rtems__ + quad_t realmem; + + /* + * The default limit for all mbuf related memory is 1/2 of all + * available kernel memory (physical or kmem). + * At most it can be 3/4 of available kernel memory. + */ + realmem = qmin((quad_t)physmem * PAGE_SIZE, + vm_map_max(kmem_map) - vm_map_min(kmem_map)); + maxmbufmem = realmem / 2; + TUNABLE_QUAD_FETCH("kern.ipc.maxmbufmem", &maxmbufmem); + if (maxmbufmem > realmem / 4 * 3) + maxmbufmem = realmem / 4 * 3; +#else /* __rtems__ */ + maxmbufmem = rtems_bsd_get_allocator_domain_size( + RTEMS_BSD_ALLOCATOR_DOMAIN_MBUF); +#endif /* __rtems__ */ - /* This has to be done before VM init. */ TUNABLE_INT_FETCH("kern.ipc.nmbclusters", &nmbclusters); if (nmbclusters == 0) - nmbclusters = 1024 + maxusers * 64; + nmbclusters = maxmbufmem / MCLBYTES / 4; TUNABLE_INT_FETCH("kern.ipc.nmbjumbop", &nmbjumbop); if (nmbjumbop == 0) - nmbjumbop = nmbclusters / 2; + nmbjumbop = maxmbufmem / MJUMPAGESIZE / 4; TUNABLE_INT_FETCH("kern.ipc.nmbjumbo9", &nmbjumbo9); if (nmbjumbo9 == 0) - nmbjumbo9 = nmbclusters / 4; + nmbjumbo9 = maxmbufmem / MJUM9BYTES / 6; TUNABLE_INT_FETCH("kern.ipc.nmbjumbo16", &nmbjumbo16); if (nmbjumbo16 == 0) - nmbjumbo16 = nmbclusters / 8; + nmbjumbo16 = maxmbufmem / MJUM16BYTES / 6; + + /* + * We need at least as many mbufs as we have clusters of + * the various types added together. + */ + TUNABLE_INT_FETCH("kern.ipc.nmbufs", &nmbufs); + if (nmbufs < nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) + nmbufs = lmax(maxmbufmem / MSIZE / 5, + nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16); } -SYSINIT(tunable_mbinit, SI_SUB_TUNABLES, SI_ORDER_MIDDLE, tunable_mbinit, NULL); +SYSINIT(tunable_mbinit, SI_SUB_KMEM, SI_ORDER_MIDDLE, tunable_mbinit, NULL); static int sysctl_nmbclusters(SYSCTL_HANDLER_ARGS) @@ -138,11 +172,12 @@ sysctl_nmbclusters(SYSCTL_HANDLER_ARGS) int error, newnmbclusters; newnmbclusters = nmbclusters; - error = sysctl_handle_int(oidp, &newnmbclusters, 0, req); - if (error == 0 && req->newptr) { - if (newnmbclusters > nmbclusters) { + error = sysctl_handle_int(oidp, &newnmbclusters, 0, req); + if (error == 0 && req->newptr && newnmbclusters != nmbclusters) { + if (newnmbclusters > nmbclusters && + nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) { nmbclusters = newnmbclusters; - uma_zone_set_max(zone_clust, nmbclusters); + nmbclusters = uma_zone_set_max(zone_clust, nmbclusters); #ifndef __rtems__ EVENTHANDLER_INVOKE(nmbclusters_change); #endif /* __rtems__ */ @@ -161,11 +196,12 @@ sysctl_nmbjumbop(SYSCTL_HANDLER_ARGS) int error, newnmbjumbop; newnmbjumbop = nmbjumbop; - error = sysctl_handle_int(oidp, &newnmbjumbop, 0, req); - if (error == 0 && req->newptr) { - if (newnmbjumbop> nmbjumbop) { + error = sysctl_handle_int(oidp, &newnmbjumbop, 0, req); + if (error == 0 && req->newptr && newnmbjumbop != nmbjumbop) { + if (newnmbjumbop > nmbjumbop && + nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) { nmbjumbop = newnmbjumbop; - uma_zone_set_max(zone_jumbop, nmbjumbop); + nmbjumbop = uma_zone_set_max(zone_jumbop, nmbjumbop); } else error = EINVAL; } @@ -173,8 +209,7 @@ sysctl_nmbjumbop(SYSCTL_HANDLER_ARGS) } SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbjumbop, CTLTYPE_INT|CTLFLAG_RW, &nmbjumbop, 0, sysctl_nmbjumbop, "IU", - "Maximum number of mbuf page size jumbo clusters allowed"); - + "Maximum number of mbuf page size jumbo clusters allowed"); static int sysctl_nmbjumbo9(SYSCTL_HANDLER_ARGS) @@ -182,11 +217,12 @@ sysctl_nmbjumbo9(SYSCTL_HANDLER_ARGS) int error, newnmbjumbo9; newnmbjumbo9 = nmbjumbo9; - error = sysctl_handle_int(oidp, &newnmbjumbo9, 0, req); - if (error == 0 && req->newptr) { - if (newnmbjumbo9> nmbjumbo9) { + error = sysctl_handle_int(oidp, &newnmbjumbo9, 0, req); + if (error == 0 && req->newptr && newnmbjumbo9 != nmbjumbo9) { + if (newnmbjumbo9 > nmbjumbo9 && + nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) { nmbjumbo9 = newnmbjumbo9; - uma_zone_set_max(zone_jumbo9, nmbjumbo9); + nmbjumbo9 = uma_zone_set_max(zone_jumbo9, nmbjumbo9); } else error = EINVAL; } @@ -194,7 +230,7 @@ sysctl_nmbjumbo9(SYSCTL_HANDLER_ARGS) } SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbjumbo9, CTLTYPE_INT|CTLFLAG_RW, &nmbjumbo9, 0, sysctl_nmbjumbo9, "IU", - "Maximum number of mbuf 9k jumbo clusters allowed"); + "Maximum number of mbuf 9k jumbo clusters allowed"); static int sysctl_nmbjumbo16(SYSCTL_HANDLER_ARGS) @@ -202,11 +238,12 @@ sysctl_nmbjumbo16(SYSCTL_HANDLER_ARGS) int error, newnmbjumbo16; newnmbjumbo16 = nmbjumbo16; - error = sysctl_handle_int(oidp, &newnmbjumbo16, 0, req); - if (error == 0 && req->newptr) { - if (newnmbjumbo16> nmbjumbo16) { + error = sysctl_handle_int(oidp, &newnmbjumbo16, 0, req); + if (error == 0 && req->newptr && newnmbjumbo16 != nmbjumbo16) { + if (newnmbjumbo16 > nmbjumbo16 && + nmbufs >= nmbclusters + nmbjumbop + nmbjumbo9 + nmbjumbo16) { nmbjumbo16 = newnmbjumbo16; - uma_zone_set_max(zone_jumbo16, nmbjumbo16); + nmbjumbo16 = uma_zone_set_max(zone_jumbo16, nmbjumbo16); } else error = EINVAL; } @@ -216,7 +253,26 @@ SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbjumbo16, CTLTYPE_INT|CTLFLAG_RW, &nmbjumbo16, 0, sysctl_nmbjumbo16, "IU", "Maximum number of mbuf 16k jumbo clusters allowed"); - +static int +sysctl_nmbufs(SYSCTL_HANDLER_ARGS) +{ + int error, newnmbufs; + + newnmbufs = nmbufs; + error = sysctl_handle_int(oidp, &newnmbufs, 0, req); + if (error == 0 && req->newptr && newnmbufs != nmbufs) { + if (newnmbufs > nmbufs) { + nmbufs = newnmbufs; + nmbufs = uma_zone_set_max(zone_mbuf, nmbufs); + EVENTHANDLER_INVOKE(nmbufs_change); + } else + error = EINVAL; + } + return (error); +} +SYSCTL_PROC(_kern_ipc, OID_AUTO, nmbufs, CTLTYPE_INT|CTLFLAG_RW, +&nmbufs, 0, sysctl_nmbufs, "IU", + "Maximum number of mbufs allowed"); SYSCTL_STRUCT(_kern_ipc, OID_AUTO, mbstat, CTLFLAG_RD, &mbstat, mbstat, "Mbuf general information and statistics"); @@ -245,7 +301,6 @@ static int mb_zinit_pack(void *, int, int); static void mb_zfini_pack(void *, int); static void mb_reclaim(void *); -static void mbuf_init(void *); static void *mbuf_jumbo_alloc(uma_zone_t, int, uint8_t *, int); /* Ensure that MSIZE doesn't break dtom() - it must be a power of 2 */ @@ -254,7 +309,6 @@ CTASSERT((((MSIZE - 1) ^ MSIZE) + 1) >> 1 == MSIZE); /* * Initialize FreeBSD Network buffer allocation. */ -SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbuf_init, NULL); static void mbuf_init(void *dummy) { @@ -270,6 +324,8 @@ mbuf_init(void *dummy) NULL, NULL, #endif MSIZE - 1, UMA_ZONE_MAXBUCKET); + if (nmbufs > 0) + nmbufs = uma_zone_set_max(zone_mbuf, nmbufs); zone_clust = uma_zcreate(MBUF_CLUSTER_MEM_NAME, MCLBYTES, mb_ctor_clust, mb_dtor_clust, @@ -280,7 +336,7 @@ mbuf_init(void *dummy) #endif UMA_ALIGN_PTR, UMA_ZONE_REFCNT); if (nmbclusters > 0) - uma_zone_set_max(zone_clust, nmbclusters); + nmbclusters = uma_zone_set_max(zone_clust, nmbclusters); zone_pack = uma_zsecond_create(MBUF_PACKET_MEM_NAME, mb_ctor_pack, mb_dtor_pack, mb_zinit_pack, mb_zfini_pack, zone_mbuf); @@ -295,7 +351,7 @@ mbuf_init(void *dummy) #endif UMA_ALIGN_PTR, UMA_ZONE_REFCNT); if (nmbjumbop > 0) - uma_zone_set_max(zone_jumbop, nmbjumbop); + nmbjumbop = uma_zone_set_max(zone_jumbop, nmbjumbop); zone_jumbo9 = uma_zcreate(MBUF_JUMBO9_MEM_NAME, MJUM9BYTES, mb_ctor_clust, mb_dtor_clust, @@ -305,9 +361,9 @@ mbuf_init(void *dummy) NULL, NULL, #endif UMA_ALIGN_PTR, UMA_ZONE_REFCNT); - if (nmbjumbo9 > 0) - uma_zone_set_max(zone_jumbo9, nmbjumbo9); uma_zone_set_allocf(zone_jumbo9, mbuf_jumbo_alloc); + if (nmbjumbo9 > 0) + nmbjumbo9 = uma_zone_set_max(zone_jumbo9, nmbjumbo9); zone_jumbo16 = uma_zcreate(MBUF_JUMBO16_MEM_NAME, MJUM16BYTES, mb_ctor_clust, mb_dtor_clust, @@ -317,9 +373,9 @@ mbuf_init(void *dummy) NULL, NULL, #endif UMA_ALIGN_PTR, UMA_ZONE_REFCNT); - if (nmbjumbo16 > 0) - uma_zone_set_max(zone_jumbo16, nmbjumbo16); uma_zone_set_allocf(zone_jumbo16, mbuf_jumbo_alloc); + if (nmbjumbo16 > 0) + nmbjumbo16 = uma_zone_set_max(zone_jumbo16, nmbjumbo16); zone_ext_refcnt = uma_zcreate(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int), NULL, NULL, @@ -357,6 +413,7 @@ mbuf_init(void *dummy) mbstat.sf_iocnt = 0; mbstat.sf_allocwait = mbstat.sf_allocfail = 0; } +SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbuf_init, NULL); /* * UMA backend page allocator for the jumbo frame zones. @@ -445,7 +502,7 @@ static void mb_dtor_mbuf(void *mem, int size, void *arg) { struct mbuf *m; - unsigned long flags; + unsigned long flags; m = (struct mbuf *)mem; flags = (unsigned long)arg; diff --git a/freebsd/sys/kern/kern_mib.c b/freebsd/sys/kern/kern_mib.c index a8215b39..c3605582 100644 --- a/freebsd/sys/kern/kern_mib.c +++ b/freebsd/sys/kern/kern_mib.c @@ -271,6 +271,13 @@ SYSCTL_PROC(_hw, HW_MACHINE_ARCH, machine_arch, CTLTYPE_STRING | CTLFLAG_RD, NULL, 0, sysctl_hw_machine_arch, "A", "System architecture"); #endif /* __rtems__ */ +SYSCTL_STRING(_kern, OID_AUTO, supported_archs, CTLFLAG_RD | CTLFLAG_MPSAFE, +#ifdef COMPAT_FREEBSD32 + MACHINE_ARCH " " MACHINE_ARCH32, 0, "Supported architectures for binaries"); +#else + MACHINE_ARCH, 0, "Supported architectures for binaries"); +#endif + static int sysctl_hostname(SYSCTL_HANDLER_ARGS) { diff --git a/freebsd/sys/kern/kern_time.c b/freebsd/sys/kern/kern_time.c index e113aef6..dbb10d01 100644 --- a/freebsd/sys/kern/kern_time.c +++ b/freebsd/sys/kern/kern_time.c @@ -60,6 +60,12 @@ __FBSDID("$FreeBSD$"); #include #define MAX_CLOCKS (CLOCK_MONOTONIC+1) +#define CPUCLOCK_BIT 0x80000000 +#define CPUCLOCK_PROCESS_BIT 0x40000000 +#define CPUCLOCK_ID_MASK (~(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT)) +#define MAKE_THREAD_CPUCLOCK(tid) (CPUCLOCK_BIT|(tid)) +#define MAKE_PROCESS_CPUCLOCK(pid) \ + (CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT|(pid)) #ifndef __rtems__ static struct kclock posix_clocks[MAX_CLOCKS]; @@ -96,9 +102,6 @@ static int realtimer_settime(struct itimer *, int, static int realtimer_delete(struct itimer *); static void realtimer_clocktime(clockid_t, struct timespec *); static void realtimer_expire(void *); -static int kern_timer_create(struct thread *, clockid_t, - struct sigevent *, int *, int); -static int kern_timer_delete(struct thread *, int); int register_posix_clock(int, struct kclock *); void itimer_fire(struct itimer *it); @@ -169,6 +172,60 @@ settime(struct thread *td, struct timeval *tv) return (0); } +#ifndef _SYS_SYSPROTO_H_ +struct clock_getcpuclockid2_args { + id_t id; + int which, + clockid_t *clock_id; +}; +#endif +/* ARGSUSED */ +int +sys_clock_getcpuclockid2(struct thread *td, struct clock_getcpuclockid2_args *uap) +{ + clockid_t clk_id; + int error; + + error = kern_clock_getcpuclockid2(td, uap->id, uap->which, &clk_id); + if (error == 0) + error = copyout(&clk_id, uap->clock_id, sizeof(clockid_t)); + return (error); +} + +int +kern_clock_getcpuclockid2(struct thread *td, id_t id, int which, + clockid_t *clk_id) +{ + struct proc *p; + pid_t pid; + lwpid_t tid; + int error; + + switch (which) { + case CPUCLOCK_WHICH_PID: + if (id != 0) { + p = pfind(id); + if (p == NULL) + return (ESRCH); + error = p_cansee(td, p); + PROC_UNLOCK(p); + if (error != 0) + return (error); + pid = id; + } else { + pid = td->td_proc->p_pid; + } + *clk_id = MAKE_PROCESS_CPUCLOCK(pid); + return (0); + case CPUCLOCK_WHICH_TID: + tid = id == 0 ? td->td_tid : id; + *clk_id = MAKE_THREAD_CPUCLOCK(tid); + return (0); + default: + return (EINVAL); + } +} + #ifndef _SYS_SYSPROTO_H_ struct clock_gettime_args { clockid_t clock_id; @@ -192,12 +249,80 @@ sys_clock_gettime(struct thread *td, struct clock_gettime_args *uap) #endif #ifndef __rtems__ +static inline void +cputick2timespec(uint64_t runtime, struct timespec *ats) +{ + runtime = cputick2usec(runtime); + ats->tv_sec = runtime / 1000000; + ats->tv_nsec = runtime % 1000000 * 1000; +} + +static void +get_thread_cputime(struct thread *targettd, struct timespec *ats) +{ + uint64_t runtime, curtime, switchtime; + + if (targettd == NULL) { /* current thread */ + critical_enter(); + switchtime = PCPU_GET(switchtime); + curtime = cpu_ticks(); + runtime = curthread->td_runtime; + critical_exit(); + runtime += curtime - switchtime; + } else { + thread_lock(targettd); + runtime = targettd->td_runtime; + thread_unlock(targettd); + } + cputick2timespec(runtime, ats); +} + +static void +get_process_cputime(struct proc *targetp, struct timespec *ats) +{ + uint64_t runtime; + struct rusage ru; + + PROC_SLOCK(targetp); + rufetch(targetp, &ru); + runtime = targetp->p_rux.rux_runtime; + PROC_SUNLOCK(targetp); + cputick2timespec(runtime, ats); +} + +static int +get_cputime(struct thread *td, clockid_t clock_id, struct timespec *ats) +{ + struct proc *p, *p2; + struct thread *td2; + lwpid_t tid; + pid_t pid; + int error; + + p = td->td_proc; + if ((clock_id & CPUCLOCK_PROCESS_BIT) == 0) { + tid = clock_id & CPUCLOCK_ID_MASK; + td2 = tdfind(tid, p->p_pid); + if (td2 == NULL) + return (EINVAL); + get_thread_cputime(td2, ats); + PROC_UNLOCK(td2->td_proc); + } else { + pid = clock_id & CPUCLOCK_ID_MASK; + error = pget(pid, PGET_CANSEE, &p2); + if (error != 0) + return (EINVAL); + get_process_cputime(p2, ats); + PROC_UNLOCK(p2); + } + return (0); +} + int kern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats) { struct timeval sys, user; struct proc *p; - uint64_t runtime, curtime, switchtime; p = td->td_proc; switch (clock_id) { @@ -240,17 +365,17 @@ kern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats) ats->tv_nsec = 0; break; case CLOCK_THREAD_CPUTIME_ID: - critical_enter(); - switchtime = PCPU_GET(switchtime); - curtime = cpu_ticks(); - runtime = td->td_runtime; - critical_exit(); - runtime = cputick2usec(runtime + curtime - switchtime); - ats->tv_sec = runtime / 1000000; - ats->tv_nsec = runtime % 1000000 * 1000; + get_thread_cputime(NULL, ats); + break; + case CLOCK_PROCESS_CPUTIME_ID: + PROC_LOCK(p); + get_process_cputime(p, ats); + PROC_UNLOCK(p); break; default: - return (EINVAL); + if ((int)clock_id >= 0) + return (EINVAL); + return (get_cputime(td, clock_id, ats)); } return (0); } @@ -348,12 +473,16 @@ kern_clock_getres(struct thread *td, clockid_t clock_id, struct timespec *ts) ts->tv_nsec = 0; break; case CLOCK_THREAD_CPUTIME_ID: + case CLOCK_PROCESS_CPUTIME_ID: + cputime: /* sync with cputick2usec */ ts->tv_nsec = 1000000 / cpu_tickrate(); if (ts->tv_nsec == 0) ts->tv_nsec = 1000; break; default: + if ((int)clock_id < 0) + goto cputime; return (EINVAL); } return (0); @@ -939,31 +1068,30 @@ struct ktimer_create_args { int sys_ktimer_create(struct thread *td, struct ktimer_create_args *uap) { - struct sigevent *evp1, ev; + struct sigevent *evp, ev; int id; int error; - if (uap->evp != NULL) { + if (uap->evp == NULL) { + evp = NULL; + } else { error = copyin(uap->evp, &ev, sizeof(ev)); if (error != 0) return (error); - evp1 = &ev; - } else - evp1 = NULL; - - error = kern_timer_create(td, uap->clock_id, evp1, &id, -1); - + evp = &ev; + } + error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1); if (error == 0) { error = copyout(&id, uap->timerid, sizeof(int)); if (error != 0) - kern_timer_delete(td, id); + kern_ktimer_delete(td, id); } return (error); } -static int -kern_timer_create(struct thread *td, clockid_t clock_id, - struct sigevent *evp, int *timerid, int preset_id) +int +kern_ktimer_create(struct thread *td, clockid_t clock_id, struct sigevent *evp, + int *timerid, int preset_id) { struct proc *p = td->td_proc; struct itimer *it; @@ -1078,7 +1206,8 @@ struct ktimer_delete_args { int sys_ktimer_delete(struct thread *td, struct ktimer_delete_args *uap) { - return (kern_timer_delete(td, uap->timerid)); + + return (kern_ktimer_delete(td, uap->timerid)); } static struct itimer * @@ -1100,8 +1229,8 @@ itimer_find(struct proc *p, int timerid) return (it); } -static int -kern_timer_delete(struct thread *td, int timerid) +int +kern_ktimer_delete(struct thread *td, int timerid) { struct proc *p = td->td_proc; struct itimer *it; @@ -1143,35 +1272,40 @@ struct ktimer_settime_args { int sys_ktimer_settime(struct thread *td, struct ktimer_settime_args *uap) { - struct proc *p = td->td_proc; - struct itimer *it; struct itimerspec val, oval, *ovalp; int error; error = copyin(uap->value, &val, sizeof(val)); if (error != 0) return (error); - - if (uap->ovalue != NULL) - ovalp = &oval; - else - ovalp = NULL; + ovalp = uap->ovalue != NULL ? &oval : NULL; + error = kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp); + if (error == 0 && uap->ovalue != NULL) + error = copyout(ovalp, uap->ovalue, sizeof(*ovalp)); + return (error); +} +int +kern_ktimer_settime(struct thread *td, int timer_id, int flags, + struct itimerspec *val, struct itimerspec *oval) +{ + struct proc *p; + struct itimer *it; + int error; + + p = td->td_proc; PROC_LOCK(p); - if (uap->timerid < 3 || - (it = itimer_find(p, uap->timerid)) == NULL) { + if (timer_id < 3 || (it = itimer_find(p, timer_id)) == NULL) { PROC_UNLOCK(p); error = EINVAL; } else { PROC_UNLOCK(p); itimer_enter(it); - error = CLOCK_CALL(it->it_clockid, timer_settime, - (it, uap->flags, &val, ovalp)); + error = CLOCK_CALL(it->it_clockid, timer_settime, (it, + flags, val, oval)); itimer_leave(it); ITIMER_UNLOCK(it); } - if (error == 0 && uap->ovalue != NULL) - error = copyout(ovalp, uap->ovalue, sizeof(*ovalp)); return (error); } @@ -1184,26 +1318,34 @@ struct ktimer_gettime_args { int sys_ktimer_gettime(struct thread *td, struct ktimer_gettime_args *uap) { - struct proc *p = td->td_proc; - struct itimer *it; struct itimerspec val; int error; + error = kern_ktimer_gettime(td, uap->timerid, &val); + if (error == 0) + error = copyout(&val, uap->value, sizeof(val)); + return (error); +} + +int +kern_ktimer_gettime(struct thread *td, int timer_id, struct itimerspec *val) +{ + struct proc *p; + struct itimer *it; + int error; + + p = td->td_proc; PROC_LOCK(p); - if (uap->timerid < 3 || - (it = itimer_find(p, uap->timerid)) == NULL) { + if (timer_id < 3 || (it = itimer_find(p, timer_id)) == NULL) { PROC_UNLOCK(p); error = EINVAL; } else { PROC_UNLOCK(p); itimer_enter(it); - error = CLOCK_CALL(it->it_clockid, timer_gettime, - (it, &val)); + error = CLOCK_CALL(it->it_clockid, timer_gettime, (it, val)); itimer_leave(it); ITIMER_UNLOCK(it); } - if (error == 0) - error = copyout(&val, uap->value, sizeof(val)); return (error); } @@ -1498,7 +1640,7 @@ itimers_event_hook_exit(void *arg, struct proc *p) panic("unhandled event"); for (; i < TIMER_MAX; ++i) { if ((it = its->its_timers[i]) != NULL) - kern_timer_delete(curthread, i); + kern_ktimer_delete(curthread, i); } if (its->its_timers[0] == NULL && its->its_timers[1] == NULL && diff --git a/freebsd/sys/kern/kern_timeout.c b/freebsd/sys/kern/kern_timeout.c index 1ca98d9e..821b035d 100644 --- a/freebsd/sys/kern/kern_timeout.c +++ b/freebsd/sys/kern/kern_timeout.c @@ -66,11 +66,9 @@ __FBSDID("$FreeBSD$"); #define ncallout 16 #endif /* __rtems__ */ SDT_PROVIDER_DEFINE(callout_execute); -SDT_PROBE_DEFINE(callout_execute, kernel, , callout_start, callout-start); -SDT_PROBE_ARGTYPE(callout_execute, kernel, , callout_start, 0, +SDT_PROBE_DEFINE1(callout_execute, kernel, , callout__start, "struct callout *"); -SDT_PROBE_DEFINE(callout_execute, kernel, , callout_end, callout-end); -SDT_PROBE_ARGTYPE(callout_execute, kernel, , callout_end, 0, +SDT_PROBE_DEFINE1(callout_execute, kernel, , callout__end, "struct callout *"); static int avg_depth; @@ -251,7 +249,7 @@ rtems_bsd_timeout_init_late(void *unused) SYSINIT(rtems_bsd_timeout_early, SI_SUB_VM, SI_ORDER_FIRST, rtems_bsd_timeout_init_early, NULL); -SYSINIT(rtems_bsd_timeout_late, SI_SUB_RUN_SCHEDULER, SI_ORDER_FIRST, +SYSINIT(rtems_bsd_timeout_late, SI_SUB_LAST, SI_ORDER_FIRST, rtems_bsd_timeout_init_late, NULL); static void @@ -580,11 +578,11 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc, int *mpcalls, #endif #ifndef __rtems__ THREAD_NO_SLEEPING(); - SDT_PROBE(callout_execute, kernel, , callout_start, c, 0, 0, 0, 0); + SDT_PROBE(callout_execute, kernel, , callout__start, c, 0, 0, 0, 0); #endif /* __rtems__ */ c_func(c_arg); #ifndef __rtems__ - SDT_PROBE(callout_execute, kernel, , callout_end, c, 0, 0, 0, 0); + SDT_PROBE(callout_execute, kernel, , callout__end, c, 0, 0, 0, 0); THREAD_SLEEPING_OK(); #endif /* __rtems__ */ #ifdef DIAGNOSTIC @@ -943,11 +941,13 @@ _callout_stop_safe(c, safe) struct callout *c; int safe; { +#ifndef __rtems__ struct callout_cpu *cc, *old_cc; struct lock_class *class; -#ifndef __rtems__ int use_lock, sq_locked; #else /* __rtems__ */ + struct callout_cpu *cc; + struct lock_class *class; int use_lock; #endif /* __rtems__ */ diff --git a/freebsd/sys/kern/subr_lock.c b/freebsd/sys/kern/subr_lock.c index dea7d408..4a55a95a 100644 --- a/freebsd/sys/kern/subr_lock.c +++ b/freebsd/sys/kern/subr_lock.c @@ -12,9 +12,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -69,6 +66,7 @@ struct lock_class *lock_classes[LOCK_CLASS_MAX + 1] = { &lock_class_sx, #ifndef __rtems__ &lock_class_rm, + &lock_class_rm_sleepable, #endif /* __rtems__ */ &lock_class_rw, #ifndef __rtems__ diff --git a/freebsd/sys/kern/subr_rman.c b/freebsd/sys/kern/subr_rman.c index 668201a9..c158b36e 100644 --- a/freebsd/sys/kern/subr_rman.c +++ b/freebsd/sys/kern/subr_rman.c @@ -453,7 +453,7 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, mtx_lock(rm->rm_mtx); for (r = TAILQ_FIRST(&rm->rm_list); - r && r->r_end < start; + r && r->r_end < start + count - 1; r = TAILQ_NEXT(r, r_link)) ; @@ -463,6 +463,11 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, } amask = (1ul << RF_ALIGNMENT(flags)) - 1; + if (start > ULONG_MAX - amask) { + DPRINTF(("start+amask would wrap around\n")); + goto out; + } + /* If bound is 0, bmask will also be 0 */ bmask = ~(bound - 1); /* @@ -470,11 +475,20 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, */ for (s = r; s; s = TAILQ_NEXT(s, r_link)) { DPRINTF(("considering [%#lx, %#lx]\n", s->r_start, s->r_end)); - if (s->r_start + count - 1 > end) { + /* + * The resource list is sorted, so there is no point in + * searching further once r_start is too large. + */ + if (s->r_start > end - (count - 1)) { DPRINTF(("s->r_start (%#lx) + count - 1> end (%#lx)\n", s->r_start, end)); break; } + if (s->r_start > ULONG_MAX - amask) { + DPRINTF(("s->r_start (%#lx) + amask (%#lx) too large\n", + s->r_start, amask)); + break; + } if (s->r_flags & RF_ALLOCATED) { DPRINTF(("region is allocated\n")); continue; @@ -585,15 +599,10 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, if ((flags & (RF_SHAREABLE | RF_TIMESHARE)) == 0) goto out; - for (s = r; s; s = TAILQ_NEXT(s, r_link)) { - if (s->r_start > end) - break; - if ((s->r_flags & flags) != flags) - continue; - rstart = ulmax(s->r_start, start); - rend = ulmin(s->r_end, ulmax(start + count - 1, end)); - if (s->r_start >= start && s->r_end <= end - && (s->r_end - s->r_start + 1) == count && + for (s = r; s && s->r_end <= end; s = TAILQ_NEXT(s, r_link)) { + if ((s->r_flags & flags) == flags && + s->r_start >= start && + (s->r_end - s->r_start + 1) == count && (s->r_start & amask) == 0 && ((s->r_start ^ s->r_end) & bmask) == 0) { rv = int_alloc_resource(M_NOWAIT); diff --git a/freebsd/sys/kern/subr_sbuf.c b/freebsd/sys/kern/subr_sbuf.c index 9ea11990..e61b0844 100644 --- a/freebsd/sys/kern/subr_sbuf.c +++ b/freebsd/sys/kern/subr_sbuf.c @@ -708,9 +708,10 @@ sbuf_finish(struct sbuf *s) #ifdef _KERNEL return (s->s_error); #else - errno = s->s_error; - if (s->s_error) + if (s->s_error != 0) { + errno = s->s_error; return (-1); + } return (0); #endif } diff --git a/freebsd/sys/kern/subr_taskqueue.c b/freebsd/sys/kern/subr_taskqueue.c index 867b0e6b..259b152d 100644 --- a/freebsd/sys/kern/subr_taskqueue.c +++ b/freebsd/sys/kern/subr_taskqueue.c @@ -291,6 +291,15 @@ taskqueue_enqueue_timeout(struct taskqueue *queue, return (res); } +static void +taskqueue_drain_running(struct taskqueue *queue) +{ + + while (!TAILQ_EMPTY(&queue->tq_active)) + TQ_SLEEP(queue, &queue->tq_active, &queue->tq_mutex, + PWAIT, "-", 0); +} + void taskqueue_block(struct taskqueue *queue) { @@ -343,6 +352,8 @@ taskqueue_run_locked(struct taskqueue *queue) wakeup(task); } TAILQ_REMOVE(&queue->tq_active, &tb, tb_link); + if (TAILQ_EMPTY(&queue->tq_active)) + wakeup(&queue->tq_active); } void @@ -383,11 +394,9 @@ taskqueue_cancel_locked(struct taskqueue *queue, struct task *task, int taskqueue_cancel(struct taskqueue *queue, struct task *task, u_int *pendp) { - u_int pending; int error; TQ_LOCK(queue); - pending = task->ta_pending; error = taskqueue_cancel_locked(queue, task, pendp); TQ_UNLOCK(queue); @@ -430,6 +439,27 @@ taskqueue_drain(struct taskqueue *queue, struct task *task) TQ_UNLOCK(queue); } +void +taskqueue_drain_all(struct taskqueue *queue) +{ + struct task *task; + +#ifndef __rtems__ + if (!queue->tq_spin) + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, __func__); +#endif /* __rtems__ */ + + TQ_LOCK(queue); + task = STAILQ_LAST(&queue->tq_queue, task, ta_link); + if (task != NULL) + while (task->ta_pending != 0) + TQ_SLEEP(queue, task, &queue->tq_mutex, PWAIT, "-", 0); + taskqueue_drain_running(queue); + KASSERT(STAILQ_EMPTY(&queue->tq_queue), + ("taskqueue queue is not empty after draining")); + TQ_UNLOCK(queue); +} + void taskqueue_drain_timeout(struct taskqueue *queue, struct timeout_task *timeout_task) @@ -614,7 +644,6 @@ taskqueue_member(struct taskqueue *queue, struct thread *td) { int i, j, ret = 0; - TQ_LOCK(queue); for (i = 0, j = 0; ; i++) { if (queue->tq_threads[i] == NULL) continue; @@ -625,6 +654,5 @@ taskqueue_member(struct taskqueue *queue, struct thread *td) if (++j >= queue->tq_tcount) break; } - TQ_UNLOCK(queue); return (ret); } diff --git a/freebsd/sys/kern/sys_generic.c b/freebsd/sys/kern/sys_generic.c index 6fc16fc5..eb1ed37d 100644 --- a/freebsd/sys/kern/sys_generic.c +++ b/freebsd/sys/kern/sys_generic.c @@ -83,6 +83,10 @@ __FBSDID("$FreeBSD$"); int iosize_max_clamp = 1; SYSCTL_INT(_debug, OID_AUTO, iosize_max_clamp, CTLFLAG_RW, &iosize_max_clamp, 0, "Clamp max i/o size to INT_MAX"); +int devfs_iosize_max_clamp = 1; +SYSCTL_INT(_debug, OID_AUTO, devfs_iosize_max_clamp, CTLFLAG_RW, + &devfs_iosize_max_clamp, 0, "Clamp max i/o size to INT_MAX for devices"); + /* * Assert that the return value of read(2) and write(2) syscalls fits * into a register. If not, an architecture will need to provide the diff --git a/freebsd/sys/kern/uipc_sockbuf.c b/freebsd/sys/kern/uipc_sockbuf.c index 2a0e527d..03b18b92 100644 --- a/freebsd/sys/kern/uipc_sockbuf.c +++ b/freebsd/sys/kern/uipc_sockbuf.c @@ -623,29 +623,12 @@ sbappendrecord(struct sockbuf *sb, struct mbuf *m0) SOCKBUF_UNLOCK(sb); } -/* - * Append address and data, and optionally, control (ancillary) data to the - * receive queue of a socket. If present, m0 must include a packet header - * with total length. Returns 0 if no space in sockbuf or insufficient - * mbufs. - */ -int -sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa, - struct mbuf *m0, struct mbuf *control) +/* Helper routine that appends data, control, and address to a sockbuf. */ +static int +sbappendaddr_locked_internal(struct sockbuf *sb, const struct sockaddr *asa, + struct mbuf *m0, struct mbuf *control, struct mbuf *ctrl_last) { struct mbuf *m, *n, *nlast; - int space = asa->sa_len; - - SOCKBUF_LOCK_ASSERT(sb); - - if (m0 && (m0->m_flags & M_PKTHDR) == 0) - panic("sbappendaddr_locked"); - if (m0) - space += m0->m_pkthdr.len; - space += m_length(control, &n); - - if (space > sbspace(sb)) - return (0); #if MSIZE <= 256 if (asa->sa_len > MLEN) return (0); @@ -655,8 +638,8 @@ sbappendaddr_locked(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 (n) - n->m_next = m0; /* concatenate data to control */ + if (ctrl_last) + ctrl_last->m_next = m0; /* concatenate data to control */ else control = m0; m->m_next = control; @@ -673,6 +656,50 @@ sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa, return (1); } +/* + * Append address and data, and optionally, control (ancillary) data to the + * receive queue of a socket. If present, m0 must include a packet header + * with total length. Returns 0 if no space in sockbuf or insufficient + * mbufs. + */ +int +sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa, + struct mbuf *m0, struct mbuf *control) +{ + struct mbuf *ctrl_last; + int space = asa->sa_len; + + SOCKBUF_LOCK_ASSERT(sb); + + if (m0 && (m0->m_flags & M_PKTHDR) == 0) + panic("sbappendaddr_locked"); + if (m0) + space += m0->m_pkthdr.len; + space += m_length(control, &ctrl_last); + + if (space > sbspace(sb)) + return (0); + return (sbappendaddr_locked_internal(sb, asa, m0, control, ctrl_last)); +} + +/* + * Append address and data, and optionally, control (ancillary) data to the + * receive queue of a socket. If present, m0 must include a packet header + * with total length. Returns 0 if insufficient mbufs. Does not validate space + * on the receiving sockbuf. + */ +int +sbappendaddr_nospacecheck_locked(struct sockbuf *sb, const struct sockaddr *asa, + struct mbuf *m0, struct mbuf *control) +{ + struct mbuf *ctrl_last; + + SOCKBUF_LOCK_ASSERT(sb); + + ctrl_last = (control == NULL) ? NULL : m_last(control); + return (sbappendaddr_locked_internal(sb, asa, m0, control, ctrl_last)); +} + /* * Append address and data, and optionally, control (ancillary) data to the * receive queue of a socket. If present, m0 must include a packet header @@ -1024,6 +1051,11 @@ sbcreatecontrol(caddr_t p, int size, int type, int level) m->m_len = 0; KASSERT(CMSG_SPACE((u_int)size) <= M_TRAILINGSPACE(m), ("sbcreatecontrol: short mbuf")); + /* + * Don't leave the padding between the msg header and the + * cmsg data and the padding after the cmsg data un-initialized. + */ + bzero(cp, CMSG_SPACE((u_int)size)); if (p != NULL) (void)memcpy(CMSG_DATA(cp), p, size); m->m_len = CMSG_SPACE(size); diff --git a/freebsd/sys/kern/uipc_socket.c b/freebsd/sys/kern/uipc_socket.c index 9ca2c14c..2dc76a9f 100644 --- a/freebsd/sys/kern/uipc_socket.c +++ b/freebsd/sys/kern/uipc_socket.c @@ -151,6 +151,10 @@ __FBSDID("$FreeBSD$"); #include #include #endif +#ifdef __rtems__ +#include +#define maxfiles rtems_libio_number_iops +#endif /* __rtems__ */ static int soreceive_rcvoob(struct socket *so, struct uio *uio, int flags); @@ -256,12 +260,14 @@ SYSCTL_NODE(_kern, KERN_IPC, ipc, CTLFLAG_RW, 0, "IPC"); uma_zone_t socket_zone; int maxsockets; +#ifndef __rtems__ static void socket_zone_change(void *tag) { uma_zone_set_max(socket_zone, maxsockets); } +#endif /* __rtems__ */ static void socket_init(void *tag) @@ -270,8 +276,10 @@ socket_init(void *tag) socket_zone = uma_zcreate("socket", sizeof(struct socket), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); uma_zone_set_max(socket_zone, maxsockets); +#ifndef __rtems__ EVENTHANDLER_REGISTER(maxsockets_change, socket_zone_change, NULL, EVENTHANDLER_PRI_FIRST); +#endif /* __rtems__ */ } SYSINIT(socket, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, socket_init, NULL); @@ -284,11 +292,7 @@ init_maxsockets(void *ignored) { TUNABLE_INT_FETCH("kern.ipc.maxsockets", &maxsockets); -#ifndef __rtems__ - maxsockets = imax(maxsockets, imax(maxfiles, nmbclusters)); -#else /* __rtems__ */ - maxsockets = imax(maxsockets, nmbclusters); -#endif /* __rtems__ */ + maxsockets = imax(maxsockets, maxfiles); } SYSINIT(param, SI_SUB_TUNABLES, SI_ORDER_ANY, init_maxsockets, NULL); @@ -304,15 +308,12 @@ sysctl_maxsockets(SYSCTL_HANDLER_ARGS) newmaxsockets = maxsockets; error = sysctl_handle_int(oidp, &newmaxsockets, 0, req); if (error == 0 && req->newptr) { - if (newmaxsockets > maxsockets) { + if (newmaxsockets > maxsockets && + newmaxsockets <= maxfiles) { maxsockets = newmaxsockets; #ifndef __rtems__ - if (maxsockets > ((maxfiles / 4) * 3)) { - maxfiles = (maxsockets * 5) / 4; - maxfilesperproc = (maxfiles * 9) / 10; - } -#endif /* __rtems__ */ EVENTHANDLER_INVOKE(maxsockets_change); +#endif /* __rtems__ */ } else error = EINVAL; } @@ -498,6 +499,10 @@ SYSCTL_INT(_regression, OID_AUTO, sonewconn_earlytest, CTLFLAG_RW, struct socket * sonewconn(struct socket *head, int connstatus) { + static struct timeval lastover; + static struct timeval overinterval = { 60, 0 }; + static int overcount; + struct socket *so; int over; @@ -509,9 +514,17 @@ sonewconn(struct socket *head, int connstatus) #else if (over) { #endif - log(LOG_DEBUG, "%s: pcb %p: Listen queue overflow: " - "%i already in queue awaiting acceptance\n", - __func__, head->so_pcb, head->so_qlen); + overcount++; + + if (ratecheck(&lastover, &overinterval)) { + log(LOG_DEBUG, "%s: pcb %p: Listen queue overflow: " + "%i already in queue awaiting acceptance " + "(%d occurrences)\n", + __func__, head->so_pcb, head->so_qlen, overcount); + + overcount = 0; + } + return (NULL); } VNET_ASSERT(head->so_vnet != NULL, ("%s:%d so_vnet is NULL, head=%p", @@ -2679,22 +2692,12 @@ sosetopt(struct socket *so, struct sockopt *sopt) sizeof tv); if (error) goto bad; - - /* assert(hz > 0); */ - if (tv.tv_sec < 0 || tv.tv_sec > INT_MAX / hz || - tv.tv_usec < 0 || tv.tv_usec >= 1000000) { + if (tv.tv_sec < 0 || tv.tv_usec < 0 || + tv.tv_usec >= 1000000) { error = EDOM; goto bad; } - /* assert(tick > 0); */ - /* assert(ULONG_MAX - INT_MAX >= 1000000); */ - val = (u_long)(tv.tv_sec * hz) + tv.tv_usec / tick; - if (val > INT_MAX) { - error = EDOM; - goto bad; - } - if (val == 0 && tv.tv_usec != 0) - val = 1; + val = tvtohz(&tv); switch (sopt->sopt_name) { case SO_SNDTIMEO: @@ -3039,8 +3042,10 @@ void sohasoutofband(struct socket *so) { +#ifndef __rtems__ if (so->so_sigio != NULL) pgsigio(&so->so_sigio, SIGURG, 0); +#endif /* __rtems__ */ selwakeuppri(&so->so_rcv.sb_sel, PSOCK); } diff --git a/freebsd/sys/kern/uipc_syscalls.c b/freebsd/sys/kern/uipc_syscalls.c index 738b5c3c..b0c83e60 100644 --- a/freebsd/sys/kern/uipc_syscalls.c +++ b/freebsd/sys/kern/uipc_syscalls.c @@ -111,6 +111,13 @@ static int kern_getsockopt( struct thread *td, int s, int level, int name, void *val, enum uio_seg valseg, socklen_t *valsize); #endif /* __rtems__ */ +/* + * Creation flags, OR'ed into socket() and socketpair() type argument. + * For stable/9, these are supported but not exposed in the header file. + */ +#define SOCK_CLOEXEC 0x10000000 +#define SOCK_NONBLOCK 0x20000000 + static int sendit(struct thread *td, int s, struct msghdr *mp, int flags); static int recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp); @@ -239,11 +246,26 @@ sys_socket(td, uap) #endif /* __rtems__ */ struct socket *so; struct file *fp; - int fd, error; + int fd, error, type, oflag, fflag; AUDIT_ARG_SOCKET(uap->domain, uap->type, uap->protocol); + + type = uap->type; + oflag = 0; + fflag = 0; +#ifndef __rtems__ + if ((type & SOCK_CLOEXEC) != 0) { + type &= ~SOCK_CLOEXEC; + oflag |= O_CLOEXEC; + } +#endif /* __rtems__ */ + if ((type & SOCK_NONBLOCK) != 0) { + type &= ~SOCK_NONBLOCK; + fflag |= FNONBLOCK; + } + #ifdef MAC - error = mac_socket_check_create(td->td_ucred, uap->domain, uap->type, + error = mac_socket_check_create(td->td_ucred, uap->domain, type, uap->protocol); if (error) return (error); @@ -251,16 +273,18 @@ sys_socket(td, uap) #ifndef __rtems__ fdp = td->td_proc->p_fd; #endif /* __rtems__ */ - error = falloc(td, &fp, &fd, 0); + error = falloc(td, &fp, &fd, oflag); if (error) return (error); /* An extra reference on `fp' has been held for us by falloc(). */ - error = socreate(uap->domain, &so, uap->type, uap->protocol, + error = socreate(uap->domain, &so, type, uap->protocol, td->td_ucred, td); if (error) { fdclose(fdp, fp, fd, td); } else { - finit(fp, FREAD | FWRITE, DTYPE_SOCKET, so, &socketops); + finit(fp, FREAD | FWRITE | fflag, DTYPE_SOCKET, so, &socketops); + if ((fflag & FNONBLOCK) != 0) + (void) fo_ioctl(fp, FIONBIO, &fflag, td->td_ucred, td); td->td_retval[0] = fd; } fdrop(fp, td); @@ -798,9 +822,20 @@ kern_socketpair(struct thread *td, int domain, int type, int protocol, struct filedesc *fdp = td->td_proc->p_fd; struct file *fp1, *fp2; struct socket *so1, *so2; - int fd, error; + int fd, error, oflag, fflag; AUDIT_ARG_SOCKET(domain, type, protocol); + + oflag = 0; + fflag = 0; + if ((type & SOCK_CLOEXEC) != 0) { + type &= ~SOCK_CLOEXEC; + oflag |= O_CLOEXEC; + } + if ((type & SOCK_NONBLOCK) != 0) { + type &= ~SOCK_NONBLOCK; + fflag |= FNONBLOCK; + } #ifdef MAC /* We might want to have a separate check for socket pairs. */ error = mac_socket_check_create(td->td_ucred, domain, type, @@ -815,12 +850,12 @@ kern_socketpair(struct thread *td, int domain, int type, int protocol, if (error) goto free1; /* On success extra reference to `fp1' and 'fp2' is set by falloc. */ - error = falloc(td, &fp1, &fd, 0); + error = falloc(td, &fp1, &fd, oflag); if (error) goto free2; rsv[0] = fd; fp1->f_data = so1; /* so1 already has ref count */ - error = falloc(td, &fp2, &fd, 0); + error = falloc(td, &fp2, &fd, oflag); if (error) goto free3; fp2->f_data = so2; /* so2 already has ref count */ @@ -836,8 +871,14 @@ kern_socketpair(struct thread *td, int domain, int type, int protocol, if (error) goto free4; } - finit(fp1, FREAD | FWRITE, DTYPE_SOCKET, fp1->f_data, &socketops); - finit(fp2, FREAD | FWRITE, DTYPE_SOCKET, fp2->f_data, &socketops); + finit(fp1, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp1->f_data, + &socketops); + finit(fp2, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp2->f_data, + &socketops); + if ((fflag & FNONBLOCK) != 0) { + (void) fo_ioctl(fp1, FIONBIO, &fflag, td->td_ucred, td); + (void) fo_ioctl(fp2, FIONBIO, &fflag, td->td_ucred, td); + } fdrop(fp1, td); fdrop(fp2, td); return (0); diff --git a/freebsd/sys/kern/uipc_usrreq.c b/freebsd/sys/kern/uipc_usrreq.c index 9254e9b2..b7cc060d 100644 --- a/freebsd/sys/kern/uipc_usrreq.c +++ b/freebsd/sys/kern/uipc_usrreq.c @@ -339,6 +339,7 @@ static struct protosw localsw[] = { */ .pr_flags = PR_ADDR|PR_ATOMIC|PR_CONNREQUIRED|PR_WANTRCVD| PR_RIGHTS, + .pr_ctloutput = &uipc_ctloutput, .pr_usrreqs = &uipc_usrreqs_seqpacket, }, }; @@ -985,7 +986,8 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, from = &sun_noname; so2 = unp2->unp_socket; SOCKBUF_LOCK(&so2->so_rcv); - if (sbappendaddr_locked(&so2->so_rcv, from, m, control)) { + if (sbappendaddr_nospacecheck_locked(&so2->so_rcv, from, m, + control)) { sorwakeup_locked(so2); m = NULL; control = NULL; @@ -1047,7 +1049,8 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, if (unp2->unp_flags & UNP_WANTCRED) { #ifndef __rtems__ /* - * Credentials are passed only once on SOCK_STREAM. + * Credentials are passed only once on SOCK_STREAM + * and SOCK_SEQPACKET. */ unp2->unp_flags &= ~UNP_WANTCRED; control = unp_addsockcred(td, control); @@ -1071,8 +1074,14 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, const struct sockaddr *from; from = &sun_noname; - if (sbappendaddr_locked(&so2->so_rcv, from, m, - control)) + /* + * Don't check for space available in so2->so_rcv. + * Unix domain sockets only check for space in the + * sending sockbuf, and that check is performed one + * level up the stack. + */ + if (sbappendaddr_nospacecheck_locked(&so2->so_rcv, + from, m, control)) control = NULL; break; } @@ -1495,7 +1504,7 @@ unp_connect(struct socket *so, struct sockaddr *nam, struct thread *td) } /* - * The connecter's (client's) credentials are copied from its + * The connector's (client's) credentials are copied from its * process structure at the time of connect() (which is now). */ cru2x(td->td_ucred, &unp3->unp_peercred); diff --git a/freebsd/sys/mips/include/machine/cpufunc.h b/freebsd/sys/mips/include/machine/cpufunc.h index bfabe90b..7429312c 100644 --- a/freebsd/sys/mips/include/machine/cpufunc.h +++ b/freebsd/sys/mips/include/machine/cpufunc.h @@ -70,7 +70,7 @@ static __inline void mips_barrier(void) { #ifdef CPU_CNMIPS - __asm __volatile("" : : : "memory"); + __compiler_membar(); #else __asm __volatile (".set noreorder\n\t" "nop\n\t" diff --git a/freebsd/sys/net/ieee8023ad_lacp.c b/freebsd/sys/net/ieee8023ad_lacp.c index a1c1e49e..20288926 100644 --- a/freebsd/sys/net/ieee8023ad_lacp.c +++ b/freebsd/sys/net/ieee8023ad_lacp.c @@ -1030,8 +1030,45 @@ lacp_compose_key(struct lacp_port *lp) KASSERT(IFM_TYPE(media) == IFM_ETHER, ("invalid media type")); KASSERT((media & IFM_FDX) != 0, ("aggregating HDX interface")); - /* bit 0..4: IFM_SUBTYPE */ - key = subtype; + /* bit 0..4: IFM_SUBTYPE modulo speed */ + switch (subtype) { + case IFM_10_T: + case IFM_10_2: + case IFM_10_5: + case IFM_10_STP: + case IFM_10_FL: + key = IFM_10_T; + break; + case IFM_100_TX: + case IFM_100_FX: + case IFM_100_T4: + case IFM_100_VG: + case IFM_100_T2: + key = IFM_100_TX; + break; + case IFM_1000_SX: + case IFM_1000_LX: + case IFM_1000_CX: + case IFM_1000_T: + key = IFM_1000_SX; + break; + case IFM_10G_LR: + case IFM_10G_SR: + case IFM_10G_CX4: + case IFM_10G_TWINAX: + case IFM_10G_TWINAX_LONG: + case IFM_10G_LRM: + case IFM_10G_T: + key = IFM_10G_LR; + break; + case IFM_40G_CR4: + case IFM_40G_SR4: + case IFM_40G_LR4: + key = IFM_40G_CR4; + break; + default: + key = subtype; + } /* bit 5..14: (some bits of) if_index of lagg device */ key |= 0x7fe0 & ((sc->sc_ifp->if_index) << 5); /* bit 15: 0 */ diff --git a/freebsd/sys/net/if.c b/freebsd/sys/net/if.c index ea4a8a46..0bd72e44 100644 --- a/freebsd/sys/net/if.c +++ b/freebsd/sys/net/if.c @@ -76,6 +76,7 @@ #include #if defined(INET) || defined(INET6) +#include #include #include #include @@ -676,7 +677,8 @@ if_attach_internal(struct ifnet *ifp, int vmove) #if defined(INET) || defined(INET6) /* Initialize to max value. */ if (ifp->if_hw_tsomax == 0) - ifp->if_hw_tsomax = IP_MAXPACKET; + ifp->if_hw_tsomax = min(IP_MAXPACKET, 32 * MCLBYTES - + (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN)); KASSERT(ifp->if_hw_tsomax <= IP_MAXPACKET && ifp->if_hw_tsomax >= IP_MAXPACKET / 8, ("%s: tsomax outside of range", __func__)); diff --git a/freebsd/sys/net/if_lagg.c b/freebsd/sys/net/if_lagg.c index 4dee2afe..b0be3643 100644 --- a/freebsd/sys/net/if_lagg.c +++ b/freebsd/sys/net/if_lagg.c @@ -56,11 +56,11 @@ __FBSDID("$FreeBSD$"); #if defined(INET) || defined(INET6) #include +#include #endif #ifdef INET #include #include -#include #endif #ifdef INET6 @@ -408,6 +408,11 @@ lagg_capabilities(struct lagg_softc *sc) struct lagg_port *lp; int cap = ~0, ena = ~0; u_long hwa = ~0UL; +#if defined(INET) || defined(INET6) + u_int hw_tsomax = IP_MAXPACKET; /* Initialize to the maximum value. */ +#else + u_int hw_tsomax = ~0; /* if_hw_tsomax is only for INET/INET6, but.. */ +#endif LAGG_WLOCK_ASSERT(sc); @@ -416,6 +421,10 @@ lagg_capabilities(struct lagg_softc *sc) cap &= lp->lp_ifp->if_capabilities; ena &= lp->lp_ifp->if_capenable; hwa &= lp->lp_ifp->if_hwassist; + /* Set to the minimum value of the lagg ports. */ + if (lp->lp_ifp->if_hw_tsomax < hw_tsomax && + lp->lp_ifp->if_hw_tsomax > 0) + hw_tsomax = lp->lp_ifp->if_hw_tsomax; } cap = (cap == ~0 ? 0 : cap); ena = (ena == ~0 ? 0 : ena); @@ -423,10 +432,12 @@ lagg_capabilities(struct lagg_softc *sc) if (sc->sc_ifp->if_capabilities != cap || sc->sc_ifp->if_capenable != ena || - sc->sc_ifp->if_hwassist != hwa) { + sc->sc_ifp->if_hwassist != hwa || + sc->sc_ifp->if_hw_tsomax != hw_tsomax) { sc->sc_ifp->if_capabilities = cap; sc->sc_ifp->if_capenable = ena; sc->sc_ifp->if_hwassist = hwa; + sc->sc_ifp->if_hw_tsomax = hw_tsomax; getmicrotime(&sc->sc_ifp->if_lastchange); if (sc->sc_ifflags & IFF_DEBUG) @@ -822,7 +833,7 @@ lagg_port_output(struct ifnet *ifp, struct mbuf *m, /* drop any other frames */ m_freem(m); - return (EBUSY); + return (ENETDOWN); } static void @@ -1895,7 +1906,7 @@ lagg_lacp_start(struct lagg_softc *sc, struct mbuf *m) lp = lacp_select_tx_port(sc, m); if (lp == NULL) { m_freem(m); - return (EBUSY); + return (ENETDOWN); } /* Send mbuf */ diff --git a/freebsd/sys/net/if_media.h b/freebsd/sys/net/if_media.h index 6424d662..12585095 100644 --- a/freebsd/sys/net/if_media.h +++ b/freebsd/sys/net/if_media.h @@ -153,7 +153,10 @@ uint64_t ifmedia_baudrate(int); #define IFM_40G_CR4 27 /* 40GBase-CR4 */ #define IFM_40G_SR4 28 /* 40GBase-SR4 */ #define IFM_40G_LR4 29 /* 40GBase-LR4 */ - +/* + * Please update ieee8023ad_lacp.c:lacp_compose_key() + * after adding new Ethernet media types. + */ /* note 31 is the max! */ #define IFM_ETH_MASTER 0x00000100 /* master mode (1000baseT) */ diff --git a/freebsd/sys/net/if_spppsubr.c b/freebsd/sys/net/if_spppsubr.c index 4f2f6d05..fa6a7c1b 100644 --- a/freebsd/sys/net/if_spppsubr.c +++ b/freebsd/sys/net/if_spppsubr.c @@ -3621,7 +3621,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len) continue; } - bzero(&suggestaddr, sizeof(&suggestaddr)); + bzero(&suggestaddr, sizeof(suggestaddr)); if (collision && nohisaddr) { /* collision, hisaddr unknown - Conf-Rej */ type = CONF_REJ; diff --git a/freebsd/sys/net/if_tap.c b/freebsd/sys/net/if_tap.c index 9c501f16..599905e8 100644 --- a/freebsd/sys/net/if_tap.c +++ b/freebsd/sys/net/if_tap.c @@ -215,14 +215,10 @@ tap_destroy(struct tap_softc *tp) { struct ifnet *ifp = tp->tap_ifp; - /* Unlocked read. */ - KASSERT(!(tp->tap_flags & TAP_OPEN), - ("%s flags is out of sync", ifp->if_xname)); - CURVNET_SET(ifp->if_vnet); + destroy_dev(tp->tap_dev); seldrain(&tp->tap_rsel); knlist_destroy(&tp->tap_rsel.si_note); - destroy_dev(tp->tap_dev); ether_ifdetach(ifp); if_free_type(ifp, IFT_ETHER); diff --git a/freebsd/sys/net/if_tun.c b/freebsd/sys/net/if_tun.c index 25b73294..556a4860 100644 --- a/freebsd/sys/net/if_tun.c +++ b/freebsd/sys/net/if_tun.c @@ -324,6 +324,7 @@ static moduledata_t tun_mod = { }; DECLARE_MODULE(if_tun, tun_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +MODULE_VERSION(if_tun, 1); static void tunstart(struct ifnet *ifp) diff --git a/freebsd/sys/net/if_vlan.c b/freebsd/sys/net/if_vlan.c index f31b9be2..accfbbb6 100644 --- a/freebsd/sys/net/if_vlan.c +++ b/freebsd/sys/net/if_vlan.c @@ -1503,6 +1503,8 @@ vlan_capabilities(struct ifvlan *ifv) * propagate the hardware-assisted flag. TSO on VLANs * does not necessarily require hardware VLAN tagging. */ + if (p->if_hw_tsomax > 0) + ifp->if_hw_tsomax = p->if_hw_tsomax; if (p->if_capabilities & IFCAP_VLAN_HWTSO) ifp->if_capabilities |= p->if_capabilities & IFCAP_TSO; if (p->if_capenable & IFCAP_VLAN_HWTSO) { diff --git a/freebsd/sys/net/radix.c b/freebsd/sys/net/radix.c index 875a482c..ba15eb51 100644 --- a/freebsd/sys/net/radix.c +++ b/freebsd/sys/net/radix.c @@ -68,27 +68,27 @@ static struct radix_node *rn_search(void *, struct radix_node *), *rn_search_m(void *, struct radix_node *, void *); -static int max_keylen; -static struct radix_mask *rn_mkfreelist; -static struct radix_node_head *mask_rnhead; +static void rn_detachhead_internal(void **head); +static int rn_inithead_internal(void **head, int off); + +#define RADIX_MAX_KEY_LEN 32 + +static char rn_zeros[RADIX_MAX_KEY_LEN]; +static char rn_ones[RADIX_MAX_KEY_LEN] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, +}; + /* - * Work area -- the following point to 3 buffers of size max_keylen, - * allocated in this order in a block of memory malloc'ed by rn_init. - * rn_zeros, rn_ones are set in rn_init and used in readonly afterwards. - * addmask_key is used in rn_addmask in rw mode and not thread-safe. + * XXX: Compat stuff for old rn_addmask() users */ -static char *rn_zeros, *rn_ones, *addmask_key; - -#define MKGet(m) { \ - if (rn_mkfreelist) { \ - m = rn_mkfreelist; \ - rn_mkfreelist = (m)->rm_mklist; \ - } else \ - R_Malloc(m, struct radix_mask *, sizeof (struct radix_mask)); } - -#define MKFree(m) { (m)->rm_mklist = rn_mkfreelist; rn_mkfreelist = (m);} +static struct radix_node_head *mask_rnhead_compat; +#ifdef _KERNEL +static struct mtx mask_mtx; +#endif -#define rn_masktop (mask_rnhead->rnh_treetop) static int rn_lexobetter(void *m_arg, void *n_arg); static struct radix_mask * @@ -158,12 +158,10 @@ static int rn_satisfies_leaf(char *trial, struct radix_node *leaf, * Search a node in the tree matching the key. */ static struct radix_node * -rn_search(v_arg, head) - void *v_arg; - struct radix_node *head; +rn_search(void *v_arg, struct radix_node *head) { - register struct radix_node *x; - register caddr_t v; + struct radix_node *x; + caddr_t v; for (x = head, v = v_arg; x->rn_bit >= 0;) { if (x->rn_bmask & v[x->rn_offset]) @@ -179,12 +177,10 @@ rn_search(v_arg, head) * XXX note this function is used only once. */ static struct radix_node * -rn_search_m(v_arg, head, m_arg) - struct radix_node *head; - void *v_arg, *m_arg; +rn_search_m(void *v_arg, struct radix_node *head, void *m_arg) { - register struct radix_node *x; - register caddr_t v = v_arg, m = m_arg; + struct radix_node *x; + caddr_t v = v_arg, m = m_arg; for (x = head; x->rn_bit >= 0;) { if ((x->rn_bmask & m[x->rn_offset]) && @@ -193,15 +189,14 @@ rn_search_m(v_arg, head, m_arg) else x = x->rn_left; } - return x; + return (x); } int -rn_refines(m_arg, n_arg) - void *m_arg, *n_arg; +rn_refines(void *m_arg, void *n_arg) { - register caddr_t m = m_arg, n = n_arg; - register caddr_t lim, lim2 = lim = n + LEN(n); + caddr_t m = m_arg, n = n_arg; + caddr_t lim, lim2 = lim = n + LEN(n); int longer = LEN(n++) - LEN(m++); int masks_are_equal = 1; @@ -209,49 +204,71 @@ rn_refines(m_arg, n_arg) lim -= longer; while (n < lim) { if (*n & ~(*m)) - return 0; + return (0); if (*n++ != *m++) masks_are_equal = 0; } while (n < lim2) if (*n++) - return 0; + return (0); if (masks_are_equal && (longer < 0)) for (lim2 = m - longer; m < lim2; ) if (*m++) - return 1; + return (1); return (!masks_are_equal); } +/* + * Search for exact match in given @head. + * Assume host bits are cleared in @v_arg if @m_arg is not NULL + * Note that prefixes with /32 or /128 masks are treated differently + * from host routes. + */ struct radix_node * -rn_lookup(v_arg, m_arg, head) - void *v_arg, *m_arg; - struct radix_node_head *head; +rn_lookup(void *v_arg, void *m_arg, struct radix_node_head *head) { - register struct radix_node *x; - caddr_t netmask = 0; + struct radix_node *x; + caddr_t netmask; - if (m_arg) { - x = rn_addmask(m_arg, 1, head->rnh_treetop->rn_offset); - if (x == 0) - return (0); + if (m_arg != NULL) { + /* + * Most common case: search exact prefix/mask + */ + x = rn_addmask_r(m_arg, head->rnh_masks, 1, + head->rnh_treetop->rn_offset); + if (x == NULL) + return (NULL); netmask = x->rn_key; - } - x = rn_match(v_arg, head); - if (x && netmask) { - while (x && x->rn_mask != netmask) + + x = rn_match(v_arg, head); + + while (x != NULL && x->rn_mask != netmask) x = x->rn_dupedkey; + + return (x); } - return x; + + /* + * Search for host address. + */ + if ((x = rn_match(v_arg, head)) == NULL) + return (NULL); + + /* Check if found key is the same */ + if (LEN(x->rn_key) != LEN(v_arg) || bcmp(x->rn_key, v_arg, LEN(v_arg))) + return (NULL); + + /* Check if this is not host route */ + if (x->rn_mask != NULL) + return (NULL); + + return (x); } static int -rn_satisfies_leaf(trial, leaf, skip) - char *trial; - register struct radix_node *leaf; - int skip; +rn_satisfies_leaf(char *trial, struct radix_node *leaf, int skip) { - register char *cp = trial, *cp2 = leaf->rn_key, *cp3 = leaf->rn_mask; + char *cp = trial, *cp2 = leaf->rn_key, *cp3 = leaf->rn_mask; char *cplim; int length = min(LEN(cp), LEN(cp2)); @@ -262,22 +279,23 @@ rn_satisfies_leaf(trial, leaf, skip) cplim = cp + length; cp3 += skip; cp2 += skip; for (cp += skip; cp < cplim; cp++, cp2++, cp3++) if ((*cp ^ *cp2) & *cp3) - return 0; - return 1; + return (0); + return (1); } +/* + * Search for longest-prefix match in given @head + */ struct radix_node * -rn_match(v_arg, head) - void *v_arg; - struct radix_node_head *head; +rn_match(void *v_arg, struct radix_node_head *head) { caddr_t v = v_arg; - register struct radix_node *t = head->rnh_treetop, *x; - register caddr_t cp = v, cp2; + struct radix_node *t = head->rnh_treetop, *x; + caddr_t cp = v, cp2; caddr_t cplim; struct radix_node *saved_t, *top = t; int off = t->rn_offset, vlen = LEN(cp), matched_off; - register int test, b, rn_bit; + int test, b, rn_bit; /* * Open code rn_search(v, top) to avoid overhead of extra @@ -315,7 +333,7 @@ rn_match(v_arg, head) */ if (t->rn_flags & RNF_ROOT) t = t->rn_dupedkey; - return t; + return (t); on1: test = (*cp ^ *cp2) & 0xff; /* find first bit that differs */ for (b = 7; (test >>= 1) > 0;) @@ -336,13 +354,13 @@ on1: */ if (t->rn_flags & RNF_NORMAL) { if (rn_bit <= t->rn_bit) - return t; + return (t); } else if (rn_satisfies_leaf(v, t, matched_off)) - return t; + return (t); t = saved_t; /* start searching up the tree */ do { - register struct radix_mask *m; + struct radix_mask *m; t = t->rn_parent; m = t->rn_mklist; /* @@ -361,12 +379,12 @@ on1: while (x && x->rn_mask != m->rm_mask) x = x->rn_dupedkey; if (x && rn_satisfies_leaf(v, x, off)) - return x; + return (x); } m = m->rm_mklist; } } while (t != top); - return 0; + return (0); } #ifdef RN_DEBUG @@ -388,12 +406,9 @@ int rn_debug = 1; */ static struct radix_node * -rn_newpair(v, b, nodes) - void *v; - int b; - struct radix_node nodes[2]; +rn_newpair(void *v, int b, struct radix_node nodes[2]) { - register struct radix_node *tt = nodes, *t = tt + 1; + struct radix_node *tt = nodes, *t = tt + 1; t->rn_bit = b; t->rn_bmask = 0x80 >> (b & 7); t->rn_left = tt; @@ -417,44 +432,39 @@ rn_newpair(v, b, nodes) tt->rn_ybro = rn_clist; rn_clist = tt; #endif - return t; + return (t); } static struct radix_node * -rn_insert(v_arg, head, dupentry, nodes) - void *v_arg; - struct radix_node_head *head; - int *dupentry; - struct radix_node nodes[2]; +rn_insert(void *v_arg, struct radix_node_head *head, int *dupentry, + struct radix_node nodes[2]) { caddr_t v = v_arg; struct radix_node *top = head->rnh_treetop; int head_off = top->rn_offset, vlen = LEN(v); - register struct radix_node *t = rn_search(v_arg, top); - register caddr_t cp = v + head_off; - register int b; - struct radix_node *tt; + struct radix_node *t = rn_search(v_arg, top); + caddr_t cp = v + head_off; + int b; + struct radix_node *p, *tt, *x; /* * Find first bit at which v and t->rn_key differ */ - { - register caddr_t cp2 = t->rn_key + head_off; - register int cmp_res; + caddr_t cp2 = t->rn_key + head_off; + int cmp_res; caddr_t cplim = v + vlen; while (cp < cplim) if (*cp2++ != *cp++) goto on1; *dupentry = 1; - return t; + return (t); on1: *dupentry = 0; cmp_res = (cp[-1] ^ cp2[-1]) & 0xff; for (b = (cp - v) << 3; cmp_res; b--) cmp_res >>= 1; - } - { - register struct radix_node *p, *x = top; + + x = top; cp = v; do { p = x; @@ -486,58 +496,51 @@ on1: if (rn_debug) log(LOG_DEBUG, "rn_insert: Coming Out:\n"), traverse(p); #endif - } return (tt); } struct radix_node * -rn_addmask(n_arg, search, skip) - int search, skip; - void *n_arg; +rn_addmask_r(void *arg, struct radix_node_head *maskhead, int search, int skip) { - caddr_t netmask = (caddr_t)n_arg; - register struct radix_node *x; - register caddr_t cp, cplim; - register int b = 0, mlen, j; - int maskduplicated, m0, isnormal; + unsigned char *netmask = arg; + unsigned char *cp, *cplim; + struct radix_node *x; + int b = 0, mlen, j; + int maskduplicated, isnormal; struct radix_node *saved_x; - static int last_zeroed = 0; + unsigned char addmask_key[RADIX_MAX_KEY_LEN]; - if ((mlen = LEN(netmask)) > max_keylen) - mlen = max_keylen; + if ((mlen = LEN(netmask)) > RADIX_MAX_KEY_LEN) + mlen = RADIX_MAX_KEY_LEN; if (skip == 0) skip = 1; if (mlen <= skip) - return (mask_rnhead->rnh_nodes); + return (maskhead->rnh_nodes); + + bzero(addmask_key, RADIX_MAX_KEY_LEN); if (skip > 1) bcopy(rn_ones + 1, addmask_key + 1, skip - 1); - if ((m0 = mlen) > skip) - bcopy(netmask + skip, addmask_key + skip, mlen - skip); + bcopy(netmask + skip, addmask_key + skip, mlen - skip); /* * Trim trailing zeroes. */ for (cp = addmask_key + mlen; (cp > addmask_key) && cp[-1] == 0;) cp--; mlen = cp - addmask_key; - if (mlen <= skip) { - if (m0 >= last_zeroed) - last_zeroed = mlen; - return (mask_rnhead->rnh_nodes); - } - if (m0 < last_zeroed) - bzero(addmask_key + m0, last_zeroed - m0); - *addmask_key = last_zeroed = mlen; - x = rn_search(addmask_key, rn_masktop); + if (mlen <= skip) + return (maskhead->rnh_nodes); + *addmask_key = mlen; + x = rn_search(addmask_key, maskhead->rnh_treetop); if (bcmp(addmask_key, x->rn_key, mlen) != 0) x = 0; if (x || search) return (x); - R_Zalloc(x, struct radix_node *, max_keylen + 2 * sizeof (*x)); + R_Zalloc(x, struct radix_node *, RADIX_MAX_KEY_LEN + 2 * sizeof (*x)); if ((saved_x = x) == 0) return (0); netmask = cp = (caddr_t)(x + 2); bcopy(addmask_key, cp, mlen); - x = rn_insert(cp, mask_rnhead, &maskduplicated, x); + x = rn_insert(cp, maskhead, &maskduplicated, x); if (maskduplicated) { log(LOG_ERR, "rn_addmask: mask impossibly already in tree"); Free(saved_x); @@ -547,20 +550,18 @@ rn_addmask(n_arg, search, skip) * Calculate index of mask, and check for normalcy. * First find the first byte with a 0 bit, then if there are * more bits left (remember we already trimmed the trailing 0's), - * the pattern must be one of those in normal_chars[], or we have + * the bits should be contiguous, otherwise we have got * a non-contiguous mask. */ +#define CONTIG(_c) (((~(_c) + 1) & (_c)) == (unsigned char)(~(_c) + 1)) cplim = netmask + mlen; isnormal = 1; for (cp = netmask + skip; (cp < cplim) && *(u_char *)cp == 0xff;) cp++; if (cp != cplim) { - static char normal_chars[] = { - 0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; - for (j = 0x80; (j & *cp) != 0; j >>= 1) b++; - if (*cp != normal_chars[b] || cp != (cplim - 1)) + if (!CONTIG(*cp) || cp != (cplim - 1)) isnormal = 0; } b += (cp - netmask) << 3; @@ -570,34 +571,48 @@ rn_addmask(n_arg, search, skip) return (x); } +struct radix_node * +rn_addmask(void *n_arg, int search, int skip) +{ + struct radix_node *tt; + +#ifdef _KERNEL + mtx_lock(&mask_mtx); +#endif + tt = rn_addmask_r(&mask_rnhead_compat, n_arg, search, skip); + +#ifdef _KERNEL + mtx_unlock(&mask_mtx); +#endif + + return (tt); +} + static int /* XXX: arbitrary ordering for non-contiguous masks */ -rn_lexobetter(m_arg, n_arg) - void *m_arg, *n_arg; +rn_lexobetter(void *m_arg, void *n_arg) { - register u_char *mp = m_arg, *np = n_arg, *lim; + u_char *mp = m_arg, *np = n_arg, *lim; if (LEN(mp) > LEN(np)) - return 1; /* not really, but need to check longer one first */ + return (1); /* not really, but need to check longer one first */ if (LEN(mp) == LEN(np)) for (lim = mp + LEN(mp); mp < lim;) if (*mp++ > *np++) - return 1; - return 0; + return (1); + return (0); } static struct radix_mask * -rn_new_radix_mask(tt, next) - register struct radix_node *tt; - register struct radix_mask *next; +rn_new_radix_mask(struct radix_node *tt, struct radix_mask *next) { - register struct radix_mask *m; + struct radix_mask *m; - MKGet(m); - if (m == 0) { - log(LOG_ERR, "Mask for route not entered\n"); + R_Malloc(m, struct radix_mask *, sizeof (struct radix_mask)); + if (m == NULL) { + log(LOG_ERR, "Failed to allocate route mask\n"); return (0); } - bzero(m, sizeof *m); + bzero(m, sizeof(*m)); m->rm_bit = tt->rn_bit; m->rm_flags = tt->rn_flags; if (tt->rn_flags & RNF_NORMAL) @@ -606,17 +621,15 @@ rn_new_radix_mask(tt, next) m->rm_mask = tt->rn_mask; m->rm_mklist = next; tt->rn_mklist = m; - return m; + return (m); } struct radix_node * -rn_addroute(v_arg, n_arg, head, treenodes) - void *v_arg, *n_arg; - struct radix_node_head *head; - struct radix_node treenodes[2]; +rn_addroute(void *v_arg, void *n_arg, struct radix_node_head *head, + struct radix_node treenodes[2]) { caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg; - register struct radix_node *t, *x = 0, *tt; + struct radix_node *t, *x = 0, *tt; struct radix_node *saved_tt, *top = head->rnh_treetop; short b = 0, b_leaf = 0; int keyduplicated; @@ -631,7 +644,8 @@ rn_addroute(v_arg, n_arg, head, treenodes) * nodes and possibly save time in calculating indices. */ if (netmask) { - if ((x = rn_addmask(netmask, 0, top->rn_offset)) == 0) + x = rn_addmask_r(netmask, head->rnh_masks, 0, top->rn_offset); + if (x == NULL) return (0); b_leaf = x->rn_bit; b = -1 - x->rn_bit; @@ -743,7 +757,7 @@ rn_addroute(v_arg, n_arg, head, treenodes) on2: /* Add new route to highest possible ancestor's list */ if ((netmask == 0) || (b > t->rn_bit )) - return tt; /* can't lift at all */ + return (tt); /* can't lift at all */ b_leaf = tt->rn_bit; do { x = t; @@ -767,29 +781,27 @@ on2: log(LOG_ERR, "Non-unique normal route, mask not entered\n"); #endif - return tt; + return (tt); } } else mmask = m->rm_mask; if (mmask == netmask) { m->rm_refs++; tt->rn_mklist = m; - return tt; + return (tt); } if (rn_refines(netmask, mmask) || rn_lexobetter(netmask, mmask)) break; } *mp = rn_new_radix_mask(tt, *mp); - return tt; + return (tt); } struct radix_node * -rn_delete(v_arg, netmask_arg, head) - void *v_arg, *netmask_arg; - struct radix_node_head *head; +rn_delete(void *v_arg, void *netmask_arg, struct radix_node_head *head) { - register struct radix_node *t, *p, *x, *tt; + struct radix_node *t, *p, *x, *tt; struct radix_mask *m, *saved_m, **mp; struct radix_node *dupedkey, *saved_tt, *top; caddr_t v, netmask; @@ -810,7 +822,8 @@ rn_delete(v_arg, netmask_arg, head) * Delete our route from mask lists. */ if (netmask) { - if ((x = rn_addmask(netmask, 1, head_off)) == 0) + x = rn_addmask_r(netmask, head->rnh_masks, 1, head_off); + if (x == NULL) return (0); netmask = x->rn_key; while (tt->rn_mask != netmask) @@ -822,7 +835,7 @@ rn_delete(v_arg, netmask_arg, head) if (tt->rn_flags & RNF_NORMAL) { if (m->rm_leaf != tt || m->rm_refs > 0) { log(LOG_ERR, "rn_delete: inconsistent annotation\n"); - return 0; /* dangling ref could cause disaster */ + return (0); /* dangling ref could cause disaster */ } } else { if (m->rm_mask != tt->rn_mask) { @@ -843,7 +856,7 @@ rn_delete(v_arg, netmask_arg, head) for (mp = &x->rn_mklist; (m = *mp); mp = &m->rm_mklist) if (m == saved_m) { *mp = m->rm_mklist; - MKFree(m); + Free(m); break; } if (m == 0) { @@ -934,7 +947,7 @@ on1: struct radix_mask *mm = m->rm_mklist; x->rn_mklist = 0; if (--(m->rm_refs) < 0) - MKFree(m); + Free(m); m = mm; } if (m) @@ -974,17 +987,14 @@ out: * exit. */ static int -rn_walktree_from(h, a, m, f, w) - struct radix_node_head *h; - void *a, *m; - walktree_f_t *f; - void *w; +rn_walktree_from(struct radix_node_head *h, void *a, void *m, + walktree_f_t *f, void *w) { int error; struct radix_node *base, *next; u_char *xa = (u_char *)a; u_char *xm = (u_char *)m; - register struct radix_node *rn, *last = 0 /* shut up gcc */; + struct radix_node *rn, *last = NULL; /* shut up gcc */ int stopping = 0; int lastb; @@ -1077,18 +1087,15 @@ rn_walktree_from(h, a, m, f, w) } } - return 0; + return (0); } static int -rn_walktree(h, f, w) - struct radix_node_head *h; - walktree_f_t *f; - void *w; +rn_walktree(struct radix_node_head *h, walktree_f_t *f, void *w) { int error; struct radix_node *base, *next; - register struct radix_node *rn = h->rnh_treetop; + struct radix_node *rn = h->rnh_treetop; /* * This gets complicated because we may delete the node * while applying the function f to it, so we need to calculate @@ -1130,13 +1137,11 @@ rn_walktree(h, f, w) * bits starting at 'off'. * Return 1 on success, 0 on error. */ -int -rn_inithead(head, off) - void **head; - int off; +static int +rn_inithead_internal(void **head, int off) { - register struct radix_node_head *rnh; - register struct radix_node *t, *tt, *ttt; + struct radix_node_head *rnh; + struct radix_node *t, *tt, *ttt; if (*head) return (1); R_Zalloc(rnh, struct radix_node_head *, sizeof (*rnh)); @@ -1165,8 +1170,8 @@ rn_inithead(head, off) return (1); } -int -rn_detachhead(void **head) +static void +rn_detachhead_internal(void **head) { struct radix_node_head *rnh; @@ -1178,28 +1183,60 @@ rn_detachhead(void **head) Free(rnh); *head = NULL; +} + +int +rn_inithead(void **head, int off) +{ + struct radix_node_head *rnh; + + if (*head != NULL) + return (1); + + if (rn_inithead_internal(head, off) == 0) + return (0); + + rnh = (struct radix_node_head *)(*head); + + if (rn_inithead_internal((void **)&rnh->rnh_masks, 0) == 0) { + rn_detachhead_internal(head); + return (0); + } + + return (1); +} + +int +rn_detachhead(void **head) +{ + struct radix_node_head *rnh; + + KASSERT((head != NULL && *head != NULL), + ("%s: head already freed", __func__)); + + rnh = *head; + + rn_detachhead_internal((void **)&rnh->rnh_masks); + rn_detachhead_internal(head); return (1); } void rn_init(int maxk) { - char *cp, *cplim; - - max_keylen = maxk; - if (max_keylen == 0) { + if ((maxk <= 0) || (maxk > RADIX_MAX_KEY_LEN)) { log(LOG_ERR, - "rn_init: radix functions require max_keylen be set\n"); + "rn_init: max_keylen must be within 1..%d\n", + RADIX_MAX_KEY_LEN); return; } - R_Malloc(rn_zeros, char *, 3 * max_keylen); - if (rn_zeros == NULL) - panic("rn_init"); - bzero(rn_zeros, 3 * max_keylen); - rn_ones = cp = rn_zeros + max_keylen; - addmask_key = cplim = rn_ones + max_keylen; - while (cp < cplim) - *cp++ = -1; - if (rn_inithead((void **)(void *)&mask_rnhead, 0) == 0) + + /* + * XXX: Compat for old rn_addmask() users + */ + if (rn_inithead((void **)(void *)&mask_rnhead_compat, 0) == 0) panic("rn_init 2"); +#ifdef _KERNEL + mtx_init(&mask_mtx, "radix_mask", NULL, MTX_DEF); +#endif } diff --git a/freebsd/sys/net/radix.h b/freebsd/sys/net/radix.h index 5bacaa3a..3554c77c 100644 --- a/freebsd/sys/net/radix.h +++ b/freebsd/sys/net/radix.h @@ -119,9 +119,9 @@ struct radix_node_head { (void *v, void *mask, struct radix_node_head *head); struct radix_node *(*rnh_delpkt) /* remove based on packet hdr */ (void *v, void *mask, struct radix_node_head *head); - struct radix_node *(*rnh_matchaddr) /* locate based on sockaddr */ + struct radix_node *(*rnh_matchaddr) /* longest match for sockaddr */ (void *v, struct radix_node_head *head); - struct radix_node *(*rnh_lookup) /* locate based on sockaddr */ + struct radix_node *(*rnh_lookup) /*exact match for sockaddr*/ (void *v, void *mask, struct radix_node_head *head); struct radix_node *(*rnh_matchpkt) /* locate based on packet hdr */ (void *v, struct radix_node_head *head); @@ -136,6 +136,7 @@ struct radix_node_head { #ifdef _KERNEL struct rwlock rnh_lock; /* locks entire radix tree */ #endif + struct radix_node_head *rnh_masks; /* Storage for our masks */ }; #ifndef _KERNEL @@ -167,6 +168,7 @@ int rn_detachhead(void **); int rn_refines(void *, void *); struct radix_node *rn_addmask(void *, int, int), + *rn_addmask_r(void *, struct radix_node_head *, int, int), *rn_addroute (void *, void *, struct radix_node_head *, struct radix_node [2]), *rn_delete(void *, void *, struct radix_node_head *), diff --git a/freebsd/sys/net/radix_mpath.c b/freebsd/sys/net/radix_mpath.c index 0f89bf5e..1bce388e 100644 --- a/freebsd/sys/net/radix_mpath.c +++ b/freebsd/sys/net/radix_mpath.c @@ -118,11 +118,16 @@ rt_mpath_matchgate(struct rtentry *rt, struct sockaddr *gate) if (rt->rt_gateway->sa_family == AF_LINK) { if (!memcmp(rt->rt_ifa->ifa_addr, gate, gate->sa_len)) break; - } else { - if (rt->rt_gateway->sa_len == gate->sa_len && - !memcmp(rt->rt_gateway, gate, gate->sa_len)) - break; } + + /* + * Check for other options: + * 1) Routes with 'real' IPv4/IPv6 gateway + * 2) Loopback host routes (another AF_LINK/sockadd_dl check) + * */ + if (rt->rt_gateway->sa_len == gate->sa_len && + !memcmp(rt->rt_gateway, gate, gate->sa_len)) + break; } while ((rn = rn_mpath_next(rn)) != NULL); return (struct rtentry *)rn; @@ -157,6 +162,7 @@ rt_mpath_deldup(struct rtentry *headrt, struct rtentry *rt) /* * check if we have the same key/mask/gateway on the table already. + * Assume @rt rt_key host bits are cleared according to @netmask */ int rt_mpath_conflict(struct radix_node_head *rnh, struct rtentry *rt, @@ -164,76 +170,13 @@ rt_mpath_conflict(struct radix_node_head *rnh, struct rtentry *rt, { struct radix_node *rn, *rn1; struct rtentry *rt1; - char *p, *q, *eq; - int same, l, skip; rn = (struct radix_node *)rt; rn1 = rnh->rnh_lookup(rt_key(rt), netmask, rnh); if (!rn1 || rn1->rn_flags & RNF_ROOT) - return 0; - - /* - * unlike other functions we have in this file, we have to check - * all key/mask/gateway as rnh_lookup can match less specific entry. - */ - rt1 = (struct rtentry *)rn1; - - /* compare key. */ - if (rt_key(rt1)->sa_len != rt_key(rt)->sa_len || - bcmp(rt_key(rt1), rt_key(rt), rt_key(rt1)->sa_len)) - goto different; - - /* key was the same. compare netmask. hairy... */ - if (rt_mask(rt1) && netmask) { - skip = rnh->rnh_treetop->rn_offset; - if (rt_mask(rt1)->sa_len > netmask->sa_len) { - /* - * as rt_mask(rt1) is made optimal by radix.c, - * there must be some 1-bits on rt_mask(rt1) - * after netmask->sa_len. therefore, in - * this case, the entries are different. - */ - if (rt_mask(rt1)->sa_len > skip) - goto different; - else { - /* no bits to compare, i.e. same*/ - goto maskmatched; - } - } - - l = rt_mask(rt1)->sa_len; - if (skip > l) { - /* no bits to compare, i.e. same */ - goto maskmatched; - } - p = (char *)rt_mask(rt1); - q = (char *)netmask; - if (bcmp(p + skip, q + skip, l - skip)) - goto different; - /* - * need to go through all the bit, as netmask is not - * optimal and can contain trailing 0s - */ - eq = (char *)netmask + netmask->sa_len; - q += l; - same = 1; - while (eq > q) - if (*q++) { - same = 0; - break; - } - if (!same) - goto different; - } else if (!rt_mask(rt1) && !netmask) - ; /* no mask to compare, i.e. same */ - else { - /* one has mask and the other does not, different */ - goto different; - } - -maskmatched: + return (0); - /* key/mask were the same. compare gateway for all multipaths */ + /* key/mask are the same. compare gateway for all multipaths */ do { rt1 = (struct rtentry *)rn1; @@ -254,11 +197,10 @@ maskmatched: } /* all key/mask/gateway are the same. conflicting entry. */ - return EEXIST; + return (EEXIST); } while ((rn1 = rn_mpath_next(rn1)) != NULL); -different: - return 0; + return (0); } void diff --git a/freebsd/sys/net/route.c b/freebsd/sys/net/route.c index fdd8a12c..b444b740 100644 --- a/freebsd/sys/net/route.c +++ b/freebsd/sys/net/route.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -92,6 +93,14 @@ #define RT_NUMFIBS 1 #endif +#if defined(INET) || defined(INET6) +#ifdef SCTP +extern void sctp_addr_change(struct ifaddr *ifa, int cmd); +#endif /* SCTP */ +#endif + + +/* This is read-only.. */ u_int rt_numfibs = RT_NUMFIBS; SYSCTL_UINT(_net, OID_AUTO, fibs, CTLFLAG_RD, &rt_numfibs, 0, ""); /* @@ -131,7 +140,8 @@ VNET_DEFINE(int, rttrash); /* routes not in table but not freed */ /* compare two sockaddr structures */ -#define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0) +#define sa_equal(a1, a2) (((a1)->sa_len == (a2)->sa_len) && \ + (bcmp((a1), (a2), (a1)->sa_len) == 0)) /* * Convert a 'struct radix_node *' to a 'struct rtentry *'. @@ -974,6 +984,57 @@ bad: return (error); } +#if 0 +int p_sockaddr(char *buf, int buflen, struct sockaddr *s); +int rt_print(char *buf, int buflen, struct rtentry *rt); + +int +p_sockaddr(char *buf, int buflen, struct sockaddr *s) +{ + void *paddr = NULL; + + switch (s->sa_family) { + case AF_INET: + paddr = &((struct sockaddr_in *)s)->sin_addr; + break; + case AF_INET6: + paddr = &((struct sockaddr_in6 *)s)->sin6_addr; + break; + } + + if (paddr == NULL) + return (0); + + if (inet_ntop(s->sa_family, paddr, buf, buflen) == NULL) + return (0); + + return (strlen(buf)); +} + +int +rt_print(char *buf, int buflen, struct rtentry *rt) +{ + struct sockaddr *addr, *mask; + int i = 0; + + addr = rt_key(rt); + mask = rt_mask(rt); + + i = p_sockaddr(buf, buflen, addr); + if (!(rt->rt_flags & RTF_HOST)) { + buf[i++] = '/'; + i += p_sockaddr(buf + i, buflen - i, mask); + } + + if (rt->rt_flags & RTF_GATEWAY) { + buf[i++] = '>'; + i += p_sockaddr(buf + i, buflen - i, rt->rt_gateway); + } + + return (i); +} +#endif + #ifdef RADIX_MPATH static int rn_mpath_update(int req, struct rt_addrinfo *info, @@ -987,10 +1048,11 @@ rn_mpath_update(int req, struct rt_addrinfo *info, register struct radix_node *rn; int error = 0; - rn = rnh->rnh_matchaddr(dst, rnh); + rn = rnh->rnh_lookup(dst, netmask, rnh); if (rn == NULL) return (ESRCH); rto = rt = RNTORT(rn); + rt = rt_mpath_matchgate(rt, gateway); if (rt == NULL) return (ESRCH); @@ -1495,7 +1557,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum) fibnum = RT_DEFAULT_FIB; break; } - if (fibnum == -1) { + if (fibnum == RT_ALL_FIBS) { if (rt_add_addr_allfibs == 0 && cmd == (int)RTM_ADD) { #ifndef __rtems__ startfib = endfib = curthread->td_proc->p_fibnum; @@ -1548,10 +1610,10 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum) /* this table doesn't exist but others might */ continue; RADIX_NODE_HEAD_RLOCK(rnh); + rn = rnh->rnh_lookup(dst, netmask, rnh); #ifdef RADIX_MPATH if (rn_mpath_capable(rnh)) { - rn = rnh->rnh_matchaddr(dst, rnh); if (rn == NULL) error = ESRCH; else { @@ -1565,17 +1627,14 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum) */ rt = rt_mpath_matchgate(rt, ifa->ifa_addr); - if (!rt) + if (rt == NULL) error = ESRCH; } } - else #endif - rn = rnh->rnh_lookup(dst, netmask, rnh); error = (rn == NULL || (rn->rn_flags & RNF_ROOT) || - RNTORT(rn)->rt_ifa != ifa || - !sa_equal((struct sockaddr *)rn->rn_key, dst)); + RNTORT(rn)->rt_ifa != ifa); RADIX_NODE_HEAD_RUNLOCK(rnh); if (error) { /* this is only an error if bad on ALL tables */ @@ -1706,7 +1765,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum) int rtinit_fib(struct ifaddr *ifa, int cmd, int flags) { - return (rtinit1(ifa, cmd, flags, -1)); + return (rtinit1(ifa, cmd, flags, RT_ALL_FIBS)); } #endif @@ -1730,8 +1789,94 @@ rtinit(struct ifaddr *ifa, int cmd, int flags) case AF_INET6: case AF_INET: /* We do support multiple FIBs. */ - fib = -1; + fib = RT_ALL_FIBS; break; } return (rtinit1(ifa, cmd, flags, fib)); } + +/* + * Announce interface address arrival/withdraw + * Returns 0 on success. + */ +int +rt_addrmsg(int cmd, struct ifaddr *ifa, int fibnum) +{ + + KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE, + ("unexpected cmd %d", cmd)); + + KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs), + ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs)); + +#if defined(INET) || defined(INET6) +#ifdef SCTP + /* + * notify the SCTP stack + * this will only get called when an address is added/deleted + * XXX pass the ifaddr struct instead if ifa->ifa_addr... + */ + sctp_addr_change(ifa, cmd); +#endif /* SCTP */ +#endif + return (rtsock_addrmsg(cmd, ifa, fibnum)); +} + +/* + * Announce route addition/removal. + * Users of this function MUST validate input data BEFORE calling. + * However we have to be able to handle invalid data: + * if some userland app sends us "invalid" route message (invalid mask, + * no dst, wrong address families, etc...) we need to pass it back + * to app (and any other rtsock consumers) with rtm_errno field set to + * non-zero value. + * Returns 0 on success. + */ +int +rt_routemsg(int cmd, struct ifnet *ifp, int error, struct rtentry *rt, + int fibnum) +{ + + KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE, + ("unexpected cmd %d", cmd)); + + KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs), + ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs)); + + KASSERT(rt_key(rt) != NULL, (":%s: rt_key must be supplied", __func__)); + + return (rtsock_routemsg(cmd, ifp, error, rt, fibnum)); +} + +void +rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt) +{ + + rt_newaddrmsg_fib(cmd, ifa, error, rt, RT_ALL_FIBS); +} + +/* + * This is called to generate messages from the routing socket + * indicating a network interface has had addresses associated with it. + */ +void +rt_newaddrmsg_fib(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt, + int fibnum) +{ + + KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE, + ("unexpected cmd %u", cmd)); + KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs), + ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs)); + + if (cmd == RTM_ADD) { + rt_addrmsg(cmd, ifa, fibnum); + if (rt != NULL) + rt_routemsg(cmd, ifa->ifa_ifp, error, rt, fibnum); + } else { + if (rt != NULL) + rt_routemsg(cmd, ifa->ifa_ifp, error, rt, fibnum); + rt_addrmsg(cmd, ifa, fibnum); + } +} + diff --git a/freebsd/sys/net/route.h b/freebsd/sys/net/route.h index 997f3cd6..0baa9a4c 100644 --- a/freebsd/sys/net/route.h +++ b/freebsd/sys/net/route.h @@ -92,7 +92,9 @@ struct rt_metrics { #define RTTTOPRHZ(r) ((r) / (RTM_RTTUNIT / PR_SLOWHZ)) #define RT_DEFAULT_FIB 0 /* Explicitly mark fib=0 restricted cases */ -extern u_int rt_numfibs; /* number fo usable routing tables */ +#define RT_ALL_FIBS -1 /* Announce event for every fib */ +extern u_int rt_numfibs; /* number of usable routing tables */ +extern u_int rt_add_addr_allfibs; /* Announce interfaces to all fibs */ /* * XXX kernel function pointer `rt_output' is visible to applications. */ @@ -365,10 +367,15 @@ void rt_missmsg(int, struct rt_addrinfo *, int, int); void rt_missmsg_fib(int, struct rt_addrinfo *, int, int, int); void rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *); void rt_newaddrmsg_fib(int, struct ifaddr *, int, struct rtentry *, int); +int rt_addrmsg(int, struct ifaddr *, int); +int rt_routemsg(int, struct ifnet *ifp, int, struct rtentry *, int); void rt_newmaddrmsg(int, struct ifmultiaddr *); int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *); void rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *); +int rtsock_addrmsg(int, struct ifaddr *, int); +int rtsock_routemsg(int, struct ifnet *ifp, int, struct rtentry *, int); + /* * Note the following locking behavior: * diff --git a/freebsd/sys/net/rtsock.c b/freebsd/sys/net/rtsock.c index 1eebe095..e768e17b 100644 --- a/freebsd/sys/net/rtsock.c +++ b/freebsd/sys/net/rtsock.c @@ -32,7 +32,6 @@ * $FreeBSD$ */ #include -#include #include #include #include @@ -69,12 +68,6 @@ #include #endif -#if defined(INET) || defined(INET6) -#ifdef SCTP -extern void sctp_addr_change(struct ifaddr *ifa, int cmd); -#endif /* SCTP */ -#endif - #ifdef COMPAT_FREEBSD32 #include #include @@ -156,7 +149,6 @@ static struct sockaddr sa_zero = { sizeof(sa_zero), AF_INET, }; * notification to a socket bound to a particular FIB. */ #define RTS_FILTER_FIB M_PROTO8 -#define RTS_ALLFIBS -1 static struct { int ip_count; /* attached w/ AF_INET */ @@ -716,10 +708,24 @@ route_output(struct mbuf *m, struct socket *so) info.rti_info[RTAX_DST]->sa_family); if (rnh == NULL) senderr(EAFNOSUPPORT); + RADIX_NODE_HEAD_RLOCK(rnh); - rt = (struct rtentry *) rnh->rnh_lookup(info.rti_info[RTAX_DST], - info.rti_info[RTAX_NETMASK], rnh); - if (rt == NULL) { /* XXX looks bogus */ + + if (info.rti_info[RTAX_NETMASK] == NULL && + rtm->rtm_type == RTM_GET) { + /* + * Provide logest prefix match for + * address lookup (no mask). + * 'route -n get addr' + */ + rt = (struct rtentry *) rnh->rnh_matchaddr( + info.rti_info[RTAX_DST], rnh); + } else + rt = (struct rtentry *) rnh->rnh_lookup( + info.rti_info[RTAX_DST], + info.rti_info[RTAX_NETMASK], rnh); + + if (rt == NULL) { RADIX_NODE_HEAD_RUNLOCK(rnh); senderr(ESRCH); } @@ -776,25 +782,6 @@ route_output(struct mbuf *m, struct socket *so) RT_ADDREF(rt); RADIX_NODE_HEAD_RUNLOCK(rnh); - /* - * Fix for PR: 82974 - * - * RTM_CHANGE/LOCK need a perfect match, rn_lookup() - * returns a perfect match in case a netmask is - * specified. For host routes only a longest prefix - * match is returned so it is necessary to compare the - * existence of the netmask. If both have a netmask - * rnh_lookup() did a perfect match and if none of them - * have a netmask both are host routes which is also a - * perfect match. - */ - - if (rtm->rtm_type != RTM_GET && - (!rt_mask(rt) != !info.rti_info[RTAX_NETMASK])) { - RT_UNLOCK(rt); - senderr(ESRCH); - } - switch(rtm->rtm_type) { case RTM_GET: @@ -1235,7 +1222,7 @@ rt_missmsg_fib(int type, struct rt_addrinfo *rtinfo, int flags, int error, if (m == NULL) return; - if (fibnum != RTS_ALLFIBS) { + if (fibnum != RT_ALL_FIBS) { KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: fibnum out " "of range 0 <= %d < %d", __func__, fibnum, rt_numfibs)); M_SETFIB(m, fibnum); @@ -1253,7 +1240,7 @@ void rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error) { - rt_missmsg_fib(type, rtinfo, flags, error, RTS_ALLFIBS); + rt_missmsg_fib(type, rtinfo, flags, error, RT_ALL_FIBS); } /* @@ -1282,89 +1269,92 @@ rt_ifmsg(struct ifnet *ifp) } /* - * This is called to generate messages from the routing socket - * indicating a network interface has had addresses associated with it. - * if we ever reverse the logic and replace messages TO the routing - * socket indicate a request to configure interfaces, then it will - * be unnecessary as the routing socket will automatically generate - * copies of it. + * Announce interface address arrival/withdraw. + * Please do not call directly, use rt_addrmsg(). + * Assume input data to be valid. + * Returns 0 on success. */ -void -rt_newaddrmsg_fib(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt, - int fibnum) +int +rtsock_addrmsg(int cmd, struct ifaddr *ifa, int fibnum) { struct rt_addrinfo info; - struct sockaddr *sa = NULL; - int pass; - struct mbuf *m = NULL; + struct sockaddr *sa; + int ncmd; + struct mbuf *m; + struct ifa_msghdr *ifam; struct ifnet *ifp = ifa->ifa_ifp; - KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE, - ("unexpected cmd %u", cmd)); -#if defined(INET) || defined(INET6) -#ifdef SCTP - /* - * notify the SCTP stack - * this will only get called when an address is added/deleted - * XXX pass the ifaddr struct instead if ifa->ifa_addr... - */ - sctp_addr_change(ifa, cmd); -#endif /* SCTP */ -#endif if (route_cb.any_count == 0) - return; - for (pass = 1; pass < 3; pass++) { - bzero((caddr_t)&info, sizeof(info)); - if ((cmd == RTM_ADD && pass == 1) || - (cmd == RTM_DELETE && pass == 2)) { - struct ifa_msghdr *ifam; - int ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR; - - info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr; - info.rti_info[RTAX_IFP] = ifp->if_addr->ifa_addr; - info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; - info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; - if ((m = rt_msg1(ncmd, &info)) == NULL) - continue; - ifam = mtod(m, struct ifa_msghdr *); - ifam->ifam_index = ifp->if_index; - ifam->ifam_metric = ifa->ifa_metric; - ifam->ifam_flags = ifa->ifa_flags; - ifam->ifam_addrs = info.rti_addrs; - } - if ((cmd == RTM_ADD && pass == 2) || - (cmd == RTM_DELETE && pass == 1)) { - struct rt_msghdr *rtm; + return (0); - if (rt == NULL) - continue; - info.rti_info[RTAX_NETMASK] = rt_mask(rt); - info.rti_info[RTAX_DST] = sa = rt_key(rt); - info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; - if ((m = rt_msg1(cmd, &info)) == NULL) - continue; - rtm = mtod(m, struct rt_msghdr *); - rtm->rtm_index = ifp->if_index; - rtm->rtm_flags |= rt->rt_flags; - rtm->rtm_errno = error; - rtm->rtm_addrs = info.rti_addrs; - } - if (fibnum != RTS_ALLFIBS) { - KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: " - "fibnum out of range 0 <= %d < %d", __func__, - fibnum, rt_numfibs)); - M_SETFIB(m, fibnum); - m->m_flags |= RTS_FILTER_FIB; - } - rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC); + ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR; + + bzero((caddr_t)&info, sizeof(info)); + info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr; + info.rti_info[RTAX_IFP] = ifp->if_addr->ifa_addr; + info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; + info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; + if ((m = rt_msg1(ncmd, &info)) == NULL) + return (ENOBUFS); + ifam = mtod(m, struct ifa_msghdr *); + ifam->ifam_index = ifp->if_index; + ifam->ifam_metric = ifa->ifa_metric; + ifam->ifam_flags = ifa->ifa_flags; + ifam->ifam_addrs = info.rti_addrs; + + if (fibnum != RT_ALL_FIBS) { + M_SETFIB(m, fibnum); + m->m_flags |= RTS_FILTER_FIB; } + + rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC); + + return (0); } -void -rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt) +/* + * Announce route addition/removal. + * Please do not call directly, use rt_routemsg(). + * Note that @rt data MAY be inconsistent/invalid: + * if some userland app sends us "invalid" route message (invalid mask, + * no dst, wrong address families, etc...) we need to pass it back + * to app (and any other rtsock consumers) with rtm_errno field set to + * non-zero value. + * + * Returns 0 on success. + */ +int +rtsock_routemsg(int cmd, struct ifnet *ifp, int error, struct rtentry *rt, + int fibnum) { + struct rt_addrinfo info; + struct sockaddr *sa; + struct mbuf *m; + struct rt_msghdr *rtm; + + if (route_cb.any_count == 0) + return (0); - rt_newaddrmsg_fib(cmd, ifa, error, rt, RTS_ALLFIBS); + bzero((caddr_t)&info, sizeof(info)); + info.rti_info[RTAX_NETMASK] = rt_mask(rt); + info.rti_info[RTAX_DST] = sa = rt_key(rt); + info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; + if ((m = rt_msg1(cmd, &info)) == NULL) + return (ENOBUFS); + rtm = mtod(m, struct rt_msghdr *); + rtm->rtm_index = ifp->if_index; + rtm->rtm_flags |= rt->rt_flags; + rtm->rtm_errno = error; + rtm->rtm_addrs = info.rti_addrs; + + if (fibnum != RT_ALL_FIBS) { + M_SETFIB(m, fibnum); + m->m_flags |= RTS_FILTER_FIB; + } + + rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC); + + return (0); } /* @@ -1839,7 +1829,7 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS) fib = BSD_DEFAULT_FIB; #endif /* __rtems__ */ else if (namelen == 4) - fib = (name[3] == -1) ? + fib = (name[3] == RT_ALL_FIBS) ? #ifndef __rtems__ req->td->td_proc->p_fibnum : name[3]; #else /* __rtems__ */ diff --git a/freebsd/sys/net80211/ieee80211.h b/freebsd/sys/net80211/ieee80211.h index 9c12ef0c..43d87b3a 100644 --- a/freebsd/sys/net80211/ieee80211.h +++ b/freebsd/sys/net80211/ieee80211.h @@ -701,6 +701,7 @@ enum { IEEE80211_ELEMID_IBSSDFS = 41, IEEE80211_ELEMID_ERP = 42, IEEE80211_ELEMID_HTCAP = 45, + IEEE80211_ELEMID_QOS = 46, IEEE80211_ELEMID_RSN = 48, IEEE80211_ELEMID_XRATES = 50, IEEE80211_ELEMID_HTINFO = 61, diff --git a/freebsd/sys/net80211/ieee80211_proto.h b/freebsd/sys/net80211/ieee80211_proto.h index 7e882161..b2ed3e80 100644 --- a/freebsd/sys/net80211/ieee80211_proto.h +++ b/freebsd/sys/net80211/ieee80211_proto.h @@ -134,6 +134,9 @@ struct mbuf *ieee80211_alloc_cts(struct ieee80211com *, uint8_t *ieee80211_add_rates(uint8_t *, const struct ieee80211_rateset *); uint8_t *ieee80211_add_xrates(uint8_t *, const struct ieee80211_rateset *); +uint8_t *ieee80211_add_wpa(uint8_t *, const struct ieee80211vap *); +uint8_t *ieee80211_add_rsn(uint8_t *, const struct ieee80211vap *); +uint8_t *ieee80211_add_qos(uint8_t *, const struct ieee80211_node *); uint16_t ieee80211_getcapinfo(struct ieee80211vap *, struct ieee80211_channel *); diff --git a/freebsd/sys/netinet/if_ether.c b/freebsd/sys/netinet/if_ether.c index 98ed0b36..e4f76fee 100644 --- a/freebsd/sys/netinet/if_ether.c +++ b/freebsd/sys/netinet/if_ether.c @@ -156,10 +156,10 @@ arp_ifscrub(struct ifnet *ifp, uint32_t addr) addr4.sin_len = sizeof(addr4); addr4.sin_family = AF_INET; addr4.sin_addr.s_addr = addr; - IF_AFDATA_LOCK(ifp); + IF_AFDATA_RLOCK(ifp); lla_lookup(LLTABLE(ifp), (LLE_DELETE | LLE_IFADDR), (struct sockaddr *)&addr4); - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_RUNLOCK(ifp); } #endif @@ -792,9 +792,9 @@ reply: struct llentry *lle = NULL; sin.sin_addr = itaddr; - IF_AFDATA_LOCK(ifp); + IF_AFDATA_RLOCK(ifp); lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin); - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_RUNLOCK(ifp); if ((lle != NULL) && (lle->la_flags & LLE_PUB)) { (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln); diff --git a/freebsd/sys/netinet/in.c b/freebsd/sys/netinet/in.c index 0c3f72bc..bc7323e3 100644 --- a/freebsd/sys/netinet/in.c +++ b/freebsd/sys/netinet/in.c @@ -962,45 +962,6 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, ((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \ ? RTF_HOST : 0) -/* - * Generate a routing message when inserting or deleting - * an interface address alias. - */ -static void in_addralias_rtmsg(int cmd, struct in_addr *prefix, - struct in_ifaddr *target) -{ - struct route pfx_ro; - struct sockaddr_in *pfx_addr; - struct rtentry msg_rt; - - /* QL: XXX - * This is a bit questionable because there is no - * additional route entry added/deleted for an address - * alias. Therefore this route report is inaccurate. - */ - bzero(&pfx_ro, sizeof(pfx_ro)); - pfx_addr = (struct sockaddr_in *)(&pfx_ro.ro_dst); - pfx_addr->sin_len = sizeof(*pfx_addr); - pfx_addr->sin_family = AF_INET; - pfx_addr->sin_addr = *prefix; - rtalloc_ign_fib(&pfx_ro, 0, 0); - if (pfx_ro.ro_rt != NULL) { - msg_rt = *pfx_ro.ro_rt; - - /* QL: XXX - * Point the gateway to the new interface - * address as if a new prefix route entry has - * been added through the new address alias. - * All other parts of the rtentry is accurate, - * e.g., rt_key, rt_mask, rt_ifp etc. - */ - msg_rt.rt_gateway = (struct sockaddr *)&target->ia_addr; - rt_newaddrmsg(cmd, (struct ifaddr *)target, 0, &msg_rt); - RTFREE(pfx_ro.ro_rt); - } - return; -} - /* * Check if we have a route for the given prefix already or add one accordingly. */ @@ -1009,7 +970,7 @@ in_addprefix(struct in_ifaddr *target, int flags) { struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; - int error; + int error, fibnum; if ((flags & RTF_HOST) != 0) { prefix = target->ia_dstaddr.sin_addr; @@ -1020,6 +981,8 @@ in_addprefix(struct in_ifaddr *target, int flags) prefix.s_addr &= mask.s_addr; } + fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib; + IN_IFADDR_RLOCK(); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (rtinitflags(ia)) { @@ -1056,7 +1019,7 @@ in_addprefix(struct in_ifaddr *target, int flags) IN_IFADDR_RUNLOCK(); return (EEXIST); } else { - in_addralias_rtmsg(RTM_ADD, &prefix, target); + rt_addrmsg(RTM_ADD, &target->ia_ifa, fibnum); IN_IFADDR_RUNLOCK(); return (0); } @@ -1085,9 +1048,11 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) { struct in_ifaddr *ia; struct in_addr prefix, mask, p; - int error = 0; + int error = 0, fibnum; struct sockaddr_in prefix0, mask0; + fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib; + /* * Remove the loopback route to the interface address. * The "useloopback" setting is not consulted because if the @@ -1139,7 +1104,7 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) } if ((target->ia_flags & IFA_ROUTE) == 0) { - in_addralias_rtmsg(RTM_DELETE, &prefix, target); + rt_addrmsg(RTM_DELETE, &target->ia_ifa, fibnum); return (0); } @@ -1501,6 +1466,7 @@ in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3add #endif if (!(flags & LLE_CREATE)) return (NULL); + IF_AFDATA_WLOCK_ASSERT(ifp); /* * A route that covers the given address must have * been installed 1st because we are doing a resolution, diff --git a/freebsd/sys/netinet/in_mcast.c b/freebsd/sys/netinet/in_mcast.c index 6d748f1f..4112046c 100644 --- a/freebsd/sys/netinet/in_mcast.c +++ b/freebsd/sys/netinet/in_mcast.c @@ -140,7 +140,9 @@ static int in_getmulti(struct ifnet *, const struct in_addr *, struct in_multi **); static int inm_get_source(struct in_multi *inm, const in_addr_t haddr, const int noalloc, struct ip_msource **pims); +#ifdef KTR static int inm_is_ifp_detached(const struct in_multi *); +#endif static int inm_merge(struct in_multi *, /*const*/ struct in_mfilter *); static void inm_purge(struct in_multi *); static void inm_reap(struct in_multi *); @@ -181,6 +183,7 @@ static SYSCTL_NODE(_net_inet_ip_mcast, OID_AUTO, filters, CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_ip_mcast_filters, "Per-interface stack-wide source filters"); +#ifdef KTR /* * Inline function which wraps assertions for a valid ifp. * The ifnet layer will set the ifma's ifp pointer to NULL if the ifp @@ -203,6 +206,7 @@ inm_is_ifp_detached(const struct in_multi *inm) return (ifp == NULL); } +#endif /* * Initialize an in_mfilter structure to a known state at t0, t1 @@ -1444,7 +1448,7 @@ inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt) error = inm_merge(inm, imf); if (error) { CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__); - goto out_imf_rollback; + goto out_in_multi_locked; } CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__); @@ -1452,6 +1456,8 @@ inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt) if (error) CTR1(KTR_IGMPV3, "%s: failed igmp downcall", __func__); +out_in_multi_locked: + IN_MULTI_UNLOCK(); out_imf_rollback: @@ -2092,8 +2098,12 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt) if (is_new) { error = in_joingroup_locked(ifp, &gsa->sin.sin_addr, imf, &inm); - if (error) + if (error) { + CTR1(KTR_IGMPV3, "%s: in_joingroup_locked failed", + __func__); + IN_MULTI_UNLOCK(); goto out_imo_free; + } imo->imo_membership[idx] = inm; } else { CTR1(KTR_IGMPV3, "%s: merge inm state", __func__); @@ -2101,20 +2111,21 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt) if (error) { CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__); - goto out_imf_rollback; + goto out_in_multi_locked; } CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__); error = igmp_change_state(inm); if (error) { CTR1(KTR_IGMPV3, "%s: failed igmp downcall", __func__); - goto out_imf_rollback; + goto out_in_multi_locked; } } +out_in_multi_locked: + IN_MULTI_UNLOCK(); -out_imf_rollback: INP_WLOCK_ASSERT(inp); if (error) { imf_rollback(imf); @@ -2318,7 +2329,7 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt) if (error) { CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__); - goto out_imf_rollback; + goto out_in_multi_locked; } CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__); @@ -2329,9 +2340,10 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt) } } +out_in_multi_locked: + IN_MULTI_UNLOCK(); -out_imf_rollback: if (error) imf_rollback(imf); else @@ -2565,7 +2577,7 @@ inp_set_source_filters(struct inpcb *inp, struct sockopt *sopt) error = inm_merge(inm, imf); if (error) { CTR1(KTR_IGMPV3, "%s: failed to merge inm state", __func__); - goto out_imf_rollback; + goto out_in_multi_locked; } CTR1(KTR_IGMPV3, "%s: doing igmp downcall", __func__); @@ -2573,6 +2585,8 @@ inp_set_source_filters(struct inpcb *inp, struct sockopt *sopt) if (error) CTR1(KTR_IGMPV3, "%s: failed igmp downcall", __func__); +out_in_multi_locked: + IN_MULTI_UNLOCK(); out_imf_rollback: diff --git a/freebsd/sys/netinet/in_pcb.c b/freebsd/sys/netinet/in_pcb.c index 5100ac9b..b93abadf 100644 --- a/freebsd/sys/netinet/in_pcb.c +++ b/freebsd/sys/netinet/in_pcb.c @@ -559,7 +559,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp, * and a multicast address is bound on both * new and duplicated sockets. */ - if (so->so_options & SO_REUSEADDR) + if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) != 0) reuseport = SO_REUSEADDR|SO_REUSEPORT; } else if (sin->sin_addr.s_addr != INADDR_ANY) { sin->sin_port = 0; /* yech... */ diff --git a/freebsd/sys/netinet/ip_icmp.c b/freebsd/sys/netinet/ip_icmp.c index b003d03f..b6876f77 100644 --- a/freebsd/sys/netinet/ip_icmp.c +++ b/freebsd/sys/netinet/ip_icmp.c @@ -345,6 +345,7 @@ stdreply: icmpelen = max(8, min(V_icmp_quotelen, oip->ip_len - oiphlen)); nip->ip_hl = 5; nip->ip_p = IPPROTO_ICMP; nip->ip_tos = 0; + nip->ip_off = 0; icmp_reflect(m); freeit: diff --git a/freebsd/sys/netinet/ip_input.c b/freebsd/sys/netinet/ip_input.c index 2dbb2a7a..2247c1a8 100644 --- a/freebsd/sys/netinet/ip_input.c +++ b/freebsd/sys/netinet/ip_input.c @@ -1110,8 +1110,9 @@ found: * (and not in for{} loop), though it implies we are not going to * reassemble more than 64k fragments. */ - m->m_pkthdr.csum_data = - (m->m_pkthdr.csum_data & 0xffff) + (m->m_pkthdr.csum_data >> 16); + while (m->m_pkthdr.csum_data & 0xffff0000) + m->m_pkthdr.csum_data = (m->m_pkthdr.csum_data & 0xffff) + + (m->m_pkthdr.csum_data >> 16); #ifdef MAC mac_ipq_reassemble(fp, m); mac_ipq_destroy(fp); diff --git a/freebsd/sys/netinet/ip_mroute.c b/freebsd/sys/netinet/ip_mroute.c index 6fc5cc68..20daee5a 100644 --- a/freebsd/sys/netinet/ip_mroute.c +++ b/freebsd/sys/netinet/ip_mroute.c @@ -610,7 +610,7 @@ static void if_detached_event(void *arg __unused, struct ifnet *ifp) { vifi_t vifi; - int i; + u_long i; MROUTER_LOCK(); @@ -705,10 +705,9 @@ ip_mrouter_init(struct socket *so, int version) static int X_ip_mrouter_done(void) { - vifi_t vifi; - int i; struct ifnet *ifp; - struct ifreq ifr; + u_long i; + vifi_t vifi; MROUTER_LOCK(); @@ -733,11 +732,6 @@ X_ip_mrouter_done(void) for (vifi = 0; vifi < V_numvifs; vifi++) { if (!in_nullhost(V_viftable[vifi].v_lcl_addr) && !(V_viftable[vifi].v_flags & (VIFF_TUNNEL | VIFF_REGISTER))) { - struct sockaddr_in *so = (struct sockaddr_in *)&(ifr.ifr_addr); - - so->sin_len = sizeof(struct sockaddr_in); - so->sin_family = AF_INET; - so->sin_addr.s_addr = INADDR_ANY; ifp = V_viftable[vifi].v_ifp; if_allmulti(ifp, 0); } @@ -804,7 +798,7 @@ set_assert(int i) int set_api_config(uint32_t *apival) { - int i; + u_long i; /* * We can set the API capabilities only if it is the first operation @@ -826,6 +820,7 @@ set_api_config(uint32_t *apival) for (i = 0; i < mfchashsize; i++) { if (LIST_FIRST(&V_mfchashtbl[i]) != NULL) { + MFC_UNLOCK(); *apival = 0; return EPERM; } @@ -1439,7 +1434,7 @@ non_fatal: static void expire_upcalls(void *arg) { - int i; + u_long i; CURVNET_SET((struct vnet *) arg); @@ -2848,7 +2843,8 @@ ip_mroute_modevent(module_t mod, int type, void *unused) if_detach_event_tag = EVENTHANDLER_REGISTER(ifnet_departure_event, if_detached_event, NULL, EVENTHANDLER_PRI_ANY); if (if_detach_event_tag == NULL) { - printf("ip_mroute: unable to ifnet_deperture_even handler\n"); + printf("ip_mroute: unable to register " + "ifnet_departure_event handler\n"); MROUTER_LOCK_DESTROY(); return (EINVAL); } diff --git a/freebsd/sys/netinet/ip_output.c b/freebsd/sys/netinet/ip_output.c index a70d3142..93ebf4d6 100644 --- a/freebsd/sys/netinet/ip_output.c +++ b/freebsd/sys/netinet/ip_output.c @@ -869,17 +869,13 @@ in_delayed_cksum(struct mbuf *m) csum = 0xffff; offset += m->m_pkthdr.csum_data; /* checksum offset */ - if (offset + sizeof(u_short) > m->m_len) { - printf("delayed m_pullup, m->len: %d off: %d p: %d\n", - m->m_len, offset, ip->ip_p); - /* - * XXX - * this shouldn't happen, but if it does, the - * correct behavior may be to insert the checksum - * in the appropriate next mbuf in the chain. - */ - return; + /* find the mbuf in the chain where the checksum starts*/ + while ((m != NULL) && (offset >= m->m_len)) { + offset -= m->m_len; + m = m->m_next; } + KASSERT(m != NULL, ("in_delayed_cksum: checksum outside mbuf chain.")); + KASSERT(offset + sizeof(u_short) <= m->m_len, ("in_delayed_cksum: checksum split between mbufs.")); *(u_short *)(m->m_data + offset) = csum; } diff --git a/freebsd/sys/netinet/sctp.h b/freebsd/sys/netinet/sctp.h index 03cf86a3..d0b90d34 100644 --- a/freebsd/sys/netinet/sctp.h +++ b/freebsd/sys/netinet/sctp.h @@ -43,13 +43,13 @@ __FBSDID("$FreeBSD$"); #define SCTP_PACKED __attribute__((packed)) /* - * SCTP protocol - RFC2960. + * SCTP protocol - RFC4960. */ struct sctphdr { uint16_t src_port; /* source port */ uint16_t dest_port; /* destination port */ uint32_t v_tag; /* verification tag of packet */ - uint32_t checksum; /* Adler32 C-Sum */ + uint32_t checksum; /* CRC32C checksum */ /* chunks follow... */ } SCTP_PACKED; @@ -365,6 +365,12 @@ struct sctp_paramhdr { /* * error cause parameters (user visible) */ +struct sctp_gen_error_cause { + uint16_t code; + uint16_t length; + uint8_t info[]; +} SCTP_PACKED; + struct sctp_error_cause { uint16_t code; uint16_t length; @@ -402,6 +408,11 @@ struct sctp_error_unrecognized_chunk { struct sctp_chunkhdr ch;/* header from chunk in error */ } SCTP_PACKED; +struct sctp_error_no_user_data { + struct sctp_error_cause cause; /* code=SCTP_CAUSE_NO_USER_DATA */ + uint32_t tsn; /* TSN of the empty data chunk */ +} SCTP_PACKED; + /* * Main SCTP chunk types we place these here so natd and f/w's in user land * can find them. @@ -425,7 +436,7 @@ struct sctp_error_unrecognized_chunk { /* RFC4895 */ #define SCTP_AUTHENTICATION 0x0f /* EY nr_sack chunk id*/ -#define SCTP_NR_SELECTIVE_ACK 0x10 +#define SCTP_NR_SELECTIVE_ACK 0x10 /************0x40 series ***********/ /************0x80 series ***********/ /* RFC5061 */ @@ -509,38 +520,38 @@ struct sctp_error_unrecognized_chunk { /* * PCB Features (in sctp_features bitmask) */ -#define SCTP_PCB_FLAGS_DO_NOT_PMTUD 0x00000001 -#define SCTP_PCB_FLAGS_EXT_RCVINFO 0x00000002 /* deprecated */ -#define SCTP_PCB_FLAGS_DONOT_HEARTBEAT 0x00000004 -#define SCTP_PCB_FLAGS_FRAG_INTERLEAVE 0x00000008 -#define SCTP_PCB_FLAGS_INTERLEAVE_STRMS 0x00000010 -#define SCTP_PCB_FLAGS_DO_ASCONF 0x00000020 -#define SCTP_PCB_FLAGS_AUTO_ASCONF 0x00000040 -#define SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE 0x00000080 +#define SCTP_PCB_FLAGS_DO_NOT_PMTUD 0x0000000000000001 +#define SCTP_PCB_FLAGS_EXT_RCVINFO 0x0000000000000002 /* deprecated */ +#define SCTP_PCB_FLAGS_DONOT_HEARTBEAT 0x0000000000000004 +#define SCTP_PCB_FLAGS_FRAG_INTERLEAVE 0x0000000000000008 +#define SCTP_PCB_FLAGS_INTERLEAVE_STRMS 0x0000000000000010 +#define SCTP_PCB_FLAGS_DO_ASCONF 0x0000000000000020 +#define SCTP_PCB_FLAGS_AUTO_ASCONF 0x0000000000000040 +#define SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE 0x0000000000000080 /* socket options */ -#define SCTP_PCB_FLAGS_NODELAY 0x00000100 -#define SCTP_PCB_FLAGS_AUTOCLOSE 0x00000200 -#define SCTP_PCB_FLAGS_RECVDATAIOEVNT 0x00000400 /* deprecated */ -#define SCTP_PCB_FLAGS_RECVASSOCEVNT 0x00000800 -#define SCTP_PCB_FLAGS_RECVPADDREVNT 0x00001000 -#define SCTP_PCB_FLAGS_RECVPEERERR 0x00002000 -#define SCTP_PCB_FLAGS_RECVSENDFAILEVNT 0x00004000 /* deprecated */ -#define SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT 0x00008000 -#define SCTP_PCB_FLAGS_ADAPTATIONEVNT 0x00010000 -#define SCTP_PCB_FLAGS_PDAPIEVNT 0x00020000 -#define SCTP_PCB_FLAGS_AUTHEVNT 0x00040000 -#define SCTP_PCB_FLAGS_STREAM_RESETEVNT 0x00080000 -#define SCTP_PCB_FLAGS_NO_FRAGMENT 0x00100000 -#define SCTP_PCB_FLAGS_EXPLICIT_EOR 0x00400000 -#define SCTP_PCB_FLAGS_NEEDS_MAPPED_V4 0x00800000 -#define SCTP_PCB_FLAGS_MULTIPLE_ASCONFS 0x01000000 -#define SCTP_PCB_FLAGS_PORTREUSE 0x02000000 -#define SCTP_PCB_FLAGS_DRYEVNT 0x04000000 -#define SCTP_PCB_FLAGS_RECVRCVINFO 0x08000000 -#define SCTP_PCB_FLAGS_RECVNXTINFO 0x10000000 -#define SCTP_PCB_FLAGS_ASSOC_RESETEVNT 0x20000000 -#define SCTP_PCB_FLAGS_STREAM_CHANGEEVNT 0x40000000 -#define SCTP_PCB_FLAGS_RECVNSENDFAILEVNT 0x80000000 +#define SCTP_PCB_FLAGS_NODELAY 0x0000000000000100 +#define SCTP_PCB_FLAGS_AUTOCLOSE 0x0000000000000200 +#define SCTP_PCB_FLAGS_RECVDATAIOEVNT 0x0000000000000400 /* deprecated */ +#define SCTP_PCB_FLAGS_RECVASSOCEVNT 0x0000000000000800 +#define SCTP_PCB_FLAGS_RECVPADDREVNT 0x0000000000001000 +#define SCTP_PCB_FLAGS_RECVPEERERR 0x0000000000002000 +#define SCTP_PCB_FLAGS_RECVSENDFAILEVNT 0x0000000000004000 /* deprecated */ +#define SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT 0x0000000000008000 +#define SCTP_PCB_FLAGS_ADAPTATIONEVNT 0x0000000000010000 +#define SCTP_PCB_FLAGS_PDAPIEVNT 0x0000000000020000 +#define SCTP_PCB_FLAGS_AUTHEVNT 0x0000000000040000 +#define SCTP_PCB_FLAGS_STREAM_RESETEVNT 0x0000000000080000 +#define SCTP_PCB_FLAGS_NO_FRAGMENT 0x0000000000100000 +#define SCTP_PCB_FLAGS_EXPLICIT_EOR 0x0000000000400000 +#define SCTP_PCB_FLAGS_NEEDS_MAPPED_V4 0x0000000000800000 +#define SCTP_PCB_FLAGS_MULTIPLE_ASCONFS 0x0000000001000000 +#define SCTP_PCB_FLAGS_PORTREUSE 0x0000000002000000 +#define SCTP_PCB_FLAGS_DRYEVNT 0x0000000004000000 +#define SCTP_PCB_FLAGS_RECVRCVINFO 0x0000000008000000 +#define SCTP_PCB_FLAGS_RECVNXTINFO 0x0000000010000000 +#define SCTP_PCB_FLAGS_ASSOC_RESETEVNT 0x0000000020000000 +#define SCTP_PCB_FLAGS_STREAM_CHANGEEVNT 0x0000000040000000 +#define SCTP_PCB_FLAGS_RECVNSENDFAILEVNT 0x0000000080000000 /*- * mobility_features parameters (by micchie).Note diff --git a/freebsd/sys/netinet/sctp_asconf.c b/freebsd/sys/netinet/sctp_asconf.c index 71fa307c..551f0690 100644 --- a/freebsd/sys/netinet/sctp_asconf.c +++ b/freebsd/sys/netinet/sctp_asconf.c @@ -152,7 +152,12 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap struct mbuf *m_reply = NULL; struct sockaddr_storage sa_store; struct sctp_paramhdr *ph; - uint16_t param_type, param_length, aparam_length; + uint16_t param_type, aparam_length; + +#if defined(INET) || defined(INET6) + uint16_t param_length; + +#endif struct sockaddr *sa; int zero_address = 0; int bad_address = 0; @@ -171,8 +176,9 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap aparam_length = ntohs(aph->ph.param_length); ph = (struct sctp_paramhdr *)(aph + 1); param_type = ntohs(ph->param_type); +#if defined(INET) || defined(INET6) param_length = ntohs(ph->param_length); - +#endif sa = (struct sockaddr *)&sa_store; switch (param_type) { #ifdef INET @@ -300,7 +306,12 @@ sctp_process_asconf_delete_ip(struct sockaddr *src, struct mbuf *m_reply = NULL; struct sockaddr_storage sa_store; struct sctp_paramhdr *ph; - uint16_t param_type, param_length, aparam_length; + uint16_t param_type, aparam_length; + +#if defined(INET) || defined(INET6) + uint16_t param_length; + +#endif struct sockaddr *sa; int zero_address = 0; int result; @@ -319,8 +330,9 @@ sctp_process_asconf_delete_ip(struct sockaddr *src, aparam_length = ntohs(aph->ph.param_length); ph = (struct sctp_paramhdr *)(aph + 1); param_type = ntohs(ph->param_type); +#if defined(INET) || defined(INET6) param_length = ntohs(ph->param_length); - +#endif sa = (struct sockaddr *)&sa_store; switch (param_type) { #ifdef INET @@ -429,7 +441,12 @@ sctp_process_asconf_set_primary(struct sockaddr *src, struct mbuf *m_reply = NULL; struct sockaddr_storage sa_store; struct sctp_paramhdr *ph; - uint16_t param_type, param_length, aparam_length; + uint16_t param_type, aparam_length; + +#if defined(INET) || defined(INET6) + uint16_t param_length; + +#endif struct sockaddr *sa; int zero_address = 0; @@ -447,8 +464,9 @@ sctp_process_asconf_set_primary(struct sockaddr *src, aparam_length = ntohs(aph->ph.param_length); ph = (struct sctp_paramhdr *)(aph + 1); param_type = ntohs(ph->param_type); +#if defined(INET) || defined(INET6) param_length = ntohs(ph->param_length); - +#endif sa = (struct sockaddr *)&sa_store; switch (param_type) { #ifdef INET @@ -862,10 +880,12 @@ sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa) static uint32_t sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa) { +#if defined(INET) || defined(INET6) uint16_t param_type, param_length; param_type = ntohs(ph->param_type); param_length = ntohs(ph->param_length); +#endif switch (sa->sa_family) { #ifdef INET6 case AF_INET6: @@ -876,7 +896,7 @@ sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa) v6addr = (struct sctp_ipv6addr_param *)ph; if ((param_type == SCTP_IPV6_ADDRESS) && - param_length == sizeof(struct sctp_ipv6addr_param) && + (param_length == sizeof(struct sctp_ipv6addr_param)) && (memcmp(&v6addr->addr, &sin6->sin6_addr, sizeof(struct in6_addr)) == 0)) { return (1); @@ -892,7 +912,7 @@ sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa) v4addr = (struct sctp_ipv4addr_param *)ph; if ((param_type == SCTP_IPV4_ADDRESS) && - param_length == sizeof(struct sctp_ipv4addr_param) && + (param_length == sizeof(struct sctp_ipv4addr_param)) && (memcmp(&v4addr->addr, &sin->sin_addr, sizeof(struct in_addr)) == 0)) { return (1); @@ -1193,7 +1213,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa, uint16_t type) { struct sctp_asconf_addr *aa, *aa_next; - struct sockaddr *sa; /* make sure the request isn't already in the queue */ TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) { @@ -1257,7 +1276,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa, struct sockaddr_in6 *sin6; sin6 = (struct sockaddr_in6 *)&ifa->address.sa; - sa = (struct sockaddr *)sin6; aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS; aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param)); aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + @@ -1273,7 +1291,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa, struct sockaddr_in *sin; sin = (struct sockaddr_in *)&ifa->address.sa; - sa = (struct sockaddr *)sin; aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS; aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param)); aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + @@ -1296,13 +1313,13 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa, if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) { if (type == SCTP_ADD_IP_ADDRESS) { SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: "); - SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa); + SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa); } else if (type == SCTP_DEL_IP_ADDRESS) { SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: "); - SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa); + SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa); } else { SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: "); - SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa); + SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa); } } #endif @@ -1874,14 +1891,22 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, * this is boundall or subset bound w/ASCONF allowed */ - /* first, make sure it's a good address family */ + /* first, make sure that the address is IPv4 or IPv6 and not jailed */ switch (ifa->address.sa.sa_family) { #ifdef INET6 case AF_INET6: + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &ifa->address.sin6.sin6_addr) != 0) { + return; + } break; #endif #ifdef INET case AF_INET: + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &ifa->address.sin.sin_addr) != 0) { + return; + } break; #endif default: @@ -2107,6 +2132,10 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb, /* we skip unspecifed addresses */ continue; } + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (stcb->asoc.scope.local_scope == 0) { continue; @@ -2137,6 +2166,10 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb, /* we skip unspecifed addresses */ continue; } + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } if (stcb->asoc.scope.ipv4_local_scope == 0 && IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { continue; @@ -2450,6 +2483,10 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked) /* skip unspecifed addresses */ continue; } + if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } if (stcb->asoc.scope.ipv4_local_scope == 0 && IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) continue; @@ -2483,6 +2520,10 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked) */ continue; } + if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } if (stcb->asoc.scope.local_scope == 0 && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) continue; @@ -2601,7 +2642,8 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked) /* get the parameter length */ p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length); /* will it fit in current chunk? */ - if (SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) { + if ((SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) || + (SCTP_BUF_LEN(m_asconf) + p_length > MCLBYTES)) { /* won't fit, so we're done with this chunk */ break; } @@ -2722,7 +2764,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked) /* chain it all together */ SCTP_BUF_NEXT(m_asconf_chk) = m_asconf; *retlen = SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf); - acp->ch.chunk_length = ntohs(*retlen); + acp->ch.chunk_length = htons(*retlen); return (m_asconf_chk); } @@ -3096,6 +3138,10 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset, #ifdef INET case AF_INET: sin = (struct sockaddr_in *)&sctp_ifa->address.sin; + if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } if ((ipv4_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { /* private address not in scope */ @@ -3106,6 +3152,10 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset, #ifdef INET6 case AF_INET6: sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sin6; + if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } if ((local_scope == 0) && (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) { continue; @@ -3391,6 +3441,10 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb, #ifdef INET case AF_INET: to = &sctp_ifap->address.sin; + if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, + &to->sin_addr) != 0) { + continue; + } if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) { continue; } @@ -3402,6 +3456,10 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb, #ifdef INET6 case AF_INET6: to6 = &sctp_ifap->address.sin6; + if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, + &to6->sin6_addr) != 0) { + continue; + } if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) { continue; } diff --git a/freebsd/sys/netinet/sctp_auth.c b/freebsd/sys/netinet/sctp_auth.c index ddb12560..fc649032 100644 --- a/freebsd/sys/netinet/sctp_auth.c +++ b/freebsd/sys/netinet/sctp_auth.c @@ -335,10 +335,6 @@ sctp_generate_random_key(uint32_t keylen) { sctp_key_t *new_key; - /* validate keylen */ - if (keylen > SCTP_AUTH_RANDOM_SIZE_MAX) - keylen = SCTP_AUTH_RANDOM_SIZE_MAX; - new_key = sctp_alloc_key(keylen); if (new_key == NULL) { /* out of memory */ @@ -376,7 +372,7 @@ sctp_compare_key(sctp_key_t * key1, sctp_key_t * key2) uint32_t i; uint32_t key1len, key2len; uint8_t *key_1, *key_2; - uint8_t temp[SCTP_AUTH_RANDOM_SIZE_MAX]; + uint8_t val1, val2; /* sanity/length check */ key1len = sctp_get_keylen(key1); @@ -388,38 +384,24 @@ sctp_compare_key(sctp_key_t * key1, sctp_key_t * key2) else if (key2len == 0) return (1); - if (key1len != key2len) { - if (key1len >= key2len) - maxlen = key1len; - else - maxlen = key2len; - bzero(temp, maxlen); - if (key1len < maxlen) { - /* prepend zeroes to key1 */ - bcopy(key1->key, temp + (maxlen - key1len), key1len); - key_1 = temp; - key_2 = key2->key; - } else { - /* prepend zeroes to key2 */ - bcopy(key2->key, temp + (maxlen - key2len), key2len); - key_1 = key1->key; - key_2 = temp; - } + if (key1len < key2len) { + maxlen = key2len; } else { maxlen = key1len; - key_1 = key1->key; - key_2 = key2->key; } - + key_1 = key1->key; + key_2 = key2->key; + /* check for numeric equality */ for (i = 0; i < maxlen; i++) { - if (*key_1 > *key_2) + /* left-pad with zeros */ + val1 = (i < (maxlen - key1len)) ? 0 : *(key_1++); + val2 = (i < (maxlen - key2len)) ? 0 : *(key_2++); + if (val1 > val2) { return (1); - else if (*key_1 < *key_2) + } else if (val1 < val2) { return (-1); - key_1++; - key_2++; + } } - /* keys are equal value, so check lengths */ if (key1len == key2len) return (0); @@ -705,15 +687,7 @@ sctp_auth_add_hmacid(sctp_hmaclist_t * list, uint16_t hmac_id) return (-1); } if ((hmac_id != SCTP_AUTH_HMAC_ID_SHA1) && -#ifdef HAVE_SHA224 - (hmac_id != SCTP_AUTH_HMAC_ID_SHA224) && -#endif -#ifdef HAVE_SHA2 - (hmac_id != SCTP_AUTH_HMAC_ID_SHA256) && - (hmac_id != SCTP_AUTH_HMAC_ID_SHA384) && - (hmac_id != SCTP_AUTH_HMAC_ID_SHA512) && -#endif - 1) { + (hmac_id != SCTP_AUTH_HMAC_ID_SHA256)) { return (-1); } /* Now is it already in the list */ @@ -756,8 +730,9 @@ sctp_default_supported_hmaclist(void) new_list = sctp_alloc_hmaclist(2); if (new_list == NULL) return (NULL); - (void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA1); + /* We prefer SHA256, so list it first */ (void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA256); + (void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA1); return (new_list); } @@ -813,19 +788,13 @@ int sctp_verify_hmac_param(struct sctp_auth_hmac_algo *hmacs, uint32_t num_hmacs) { uint32_t i; - uint16_t hmac_id; - uint32_t sha1_supported = 0; for (i = 0; i < num_hmacs; i++) { - hmac_id = ntohs(hmacs->hmac_ids[i]); - if (hmac_id == SCTP_AUTH_HMAC_ID_SHA1) - sha1_supported = 1; + if (ntohs(hmacs->hmac_ids[i]) == SCTP_AUTH_HMAC_ID_SHA1) { + return (0); + } } - /* all HMAC id's are supported */ - if (sha1_supported == 0) - return (-1); - else - return (0); + return (-1); } sctp_authinfo_t * @@ -879,18 +848,8 @@ sctp_get_hmac_digest_len(uint16_t hmac_algo) switch (hmac_algo) { case SCTP_AUTH_HMAC_ID_SHA1: return (SCTP_AUTH_DIGEST_LEN_SHA1); -#ifdef HAVE_SHA224 - case SCTP_AUTH_HMAC_ID_SHA224: - return (SCTP_AUTH_DIGEST_LEN_SHA224); -#endif -#ifdef HAVE_SHA2 case SCTP_AUTH_HMAC_ID_SHA256: return (SCTP_AUTH_DIGEST_LEN_SHA256); - case SCTP_AUTH_HMAC_ID_SHA384: - return (SCTP_AUTH_DIGEST_LEN_SHA384); - case SCTP_AUTH_HMAC_ID_SHA512: - return (SCTP_AUTH_DIGEST_LEN_SHA512); -#endif default: /* unknown HMAC algorithm: can't do anything */ return (0); @@ -902,17 +861,9 @@ sctp_get_hmac_block_len(uint16_t hmac_algo) { switch (hmac_algo) { case SCTP_AUTH_HMAC_ID_SHA1: -#ifdef HAVE_SHA224 - case SCTP_AUTH_HMAC_ID_SHA224: -#endif return (64); -#ifdef HAVE_SHA2 case SCTP_AUTH_HMAC_ID_SHA256: return (64); - case SCTP_AUTH_HMAC_ID_SHA384: - case SCTP_AUTH_HMAC_ID_SHA512: - return (128); -#endif case SCTP_AUTH_HMAC_ID_RSVD: default: /* unknown HMAC algorithm: can't do anything */ @@ -925,23 +876,11 @@ sctp_hmac_init(uint16_t hmac_algo, sctp_hash_context_t * ctx) { switch (hmac_algo) { case SCTP_AUTH_HMAC_ID_SHA1: - SHA1_Init(&ctx->sha1); + SCTP_SHA1_INIT(&ctx->sha1); break; -#ifdef HAVE_SHA224 - case SCTP_AUTH_HMAC_ID_SHA224: - break; -#endif -#ifdef HAVE_SHA2 case SCTP_AUTH_HMAC_ID_SHA256: - SHA256_Init(&ctx->sha256); + SCTP_SHA256_INIT(&ctx->sha256); break; - case SCTP_AUTH_HMAC_ID_SHA384: - SHA384_Init(&ctx->sha384); - break; - case SCTP_AUTH_HMAC_ID_SHA512: - SHA512_Init(&ctx->sha512); - break; -#endif case SCTP_AUTH_HMAC_ID_RSVD: default: /* unknown HMAC algorithm: can't do anything */ @@ -955,23 +894,11 @@ sctp_hmac_update(uint16_t hmac_algo, sctp_hash_context_t * ctx, { switch (hmac_algo) { case SCTP_AUTH_HMAC_ID_SHA1: - SHA1_Update(&ctx->sha1, text, textlen); - break; -#ifdef HAVE_SHA224 - case SCTP_AUTH_HMAC_ID_SHA224: + SCTP_SHA1_UPDATE(&ctx->sha1, text, textlen); break; -#endif -#ifdef HAVE_SHA2 case SCTP_AUTH_HMAC_ID_SHA256: - SHA256_Update(&ctx->sha256, text, textlen); - break; - case SCTP_AUTH_HMAC_ID_SHA384: - SHA384_Update(&ctx->sha384, text, textlen); - break; - case SCTP_AUTH_HMAC_ID_SHA512: - SHA512_Update(&ctx->sha512, text, textlen); + SCTP_SHA256_UPDATE(&ctx->sha256, text, textlen); break; -#endif case SCTP_AUTH_HMAC_ID_RSVD: default: /* unknown HMAC algorithm: can't do anything */ @@ -985,24 +912,11 @@ sctp_hmac_final(uint16_t hmac_algo, sctp_hash_context_t * ctx, { switch (hmac_algo) { case SCTP_AUTH_HMAC_ID_SHA1: - SHA1_Final(digest, &ctx->sha1); - break; -#ifdef HAVE_SHA224 - case SCTP_AUTH_HMAC_ID_SHA224: + SCTP_SHA1_FINAL(digest, &ctx->sha1); break; -#endif -#ifdef HAVE_SHA2 case SCTP_AUTH_HMAC_ID_SHA256: - SHA256_Final(digest, &ctx->sha256); - break; - case SCTP_AUTH_HMAC_ID_SHA384: - /* SHA384 is truncated SHA512 */ - SHA384_Final(digest, &ctx->sha384); + SCTP_SHA256_FINAL(digest, &ctx->sha256); break; - case SCTP_AUTH_HMAC_ID_SHA512: - SHA512_Final(digest, &ctx->sha512); - break; -#endif case SCTP_AUTH_HMAC_ID_RSVD: default: /* unknown HMAC algorithm: can't do anything */ @@ -1878,6 +1792,7 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication, SCTP_BUF_LEN(m_notify) = 0; auth = mtod(m_notify, struct sctp_authkey_event *); + memset(auth, 0, sizeof(struct sctp_authkey_event)); auth->auth_type = SCTP_AUTHENTICATION_EVENT; auth->auth_flags = 0; auth->auth_length = sizeof(*auth); diff --git a/freebsd/sys/netinet/sctp_auth.h b/freebsd/sys/netinet/sctp_auth.h index eac89f6f..535c0fc0 100644 --- a/freebsd/sys/netinet/sctp_auth.h +++ b/freebsd/sys/netinet/sctp_auth.h @@ -36,28 +36,21 @@ __FBSDID("$FreeBSD$"); #ifndef _NETINET_SCTP_AUTH_H_ #define _NETINET_SCTP_AUTH_H_ +#include /* digest lengths */ #define SCTP_AUTH_DIGEST_LEN_SHA1 20 -#define SCTP_AUTH_DIGEST_LEN_SHA224 28 #define SCTP_AUTH_DIGEST_LEN_SHA256 32 -#define SCTP_AUTH_DIGEST_LEN_SHA384 48 -#define SCTP_AUTH_DIGEST_LEN_SHA512 64 -#define SCTP_AUTH_DIGEST_LEN_MAX 64 +#define SCTP_AUTH_DIGEST_LEN_MAX SCTP_AUTH_DIGEST_LEN_SHA256 /* random sizes */ #define SCTP_AUTH_RANDOM_SIZE_DEFAULT 32 #define SCTP_AUTH_RANDOM_SIZE_REQUIRED 32 -#define SCTP_AUTH_RANDOM_SIZE_MAX 256 /* union of all supported HMAC algorithm contexts */ typedef union sctp_hash_context { - SHA1_CTX sha1; -#ifdef HAVE_SHA2 - SHA256_CTX sha256; - SHA384_CTX sha384; - SHA512_CTX sha512; -#endif + SCTP_SHA1_CTX sha1; + SCTP_SHA256_CTX sha256; } sctp_hash_context_t; typedef struct sctp_key { diff --git a/freebsd/sys/netinet/sctp_bsd_addr.c b/freebsd/sys/netinet/sctp_bsd_addr.c index 4653b251..d558bd82 100644 --- a/freebsd/sys/netinet/sctp_bsd_addr.c +++ b/freebsd/sys/netinet/sctp_bsd_addr.c @@ -98,22 +98,15 @@ sctp_iterator_thread(void *v SCTP_UNUSED) void sctp_startup_iterator(void) { - static int called = 0; - int ret; - - if (called) { + if (sctp_it_ctl.thread_proc) { /* You only get one */ return; } - /* init the iterator head */ - called = 1; - sctp_it_ctl.iterator_running = 0; - sctp_it_ctl.iterator_flags = 0; - sctp_it_ctl.cur_it = NULL; + /* Initialize global locks here, thus only once. */ SCTP_ITERATOR_LOCK_INIT(); SCTP_IPI_ITERATOR_WQ_INIT(); TAILQ_INIT(&sctp_it_ctl.iteratorhead); - ret = kproc_create(sctp_iterator_thread, + kproc_create(sctp_iterator_thread, (void *)NULL, &sctp_it_ctl.thread_proc, RFPROC, diff --git a/freebsd/sys/netinet/sctp_constants.h b/freebsd/sys/netinet/sctp_constants.h index 58ca808e..0ede04ca 100644 --- a/freebsd/sys/netinet/sctp_constants.h +++ b/freebsd/sys/netinet/sctp_constants.h @@ -36,16 +36,10 @@ __FBSDID("$FreeBSD$"); #ifndef _NETINET_SCTP_CONSTANTS_H_ #define _NETINET_SCTP_CONSTANTS_H_ + /* IANA assigned port number for SCTP over UDP encapsulation */ -/* For freebsd we cannot bind the port at - * startup. Otherwise what will happen is - * we really won't be bound. The user must - * put it into the sysctl... or we need - * to build a special timer for this to allow - * us to wait 1 second or so after the system - * comes up. - */ -#define SCTP_OVER_UDP_TUNNELING_PORT 0 +#define SCTP_OVER_UDP_TUNNELING_PORT 9899 + /* Number of packets to get before sack sent by default */ #define SCTP_DEFAULT_SACK_FREQ 2 @@ -726,7 +720,6 @@ __FBSDID("$FreeBSD$"); /* small chunk store for looking at chunk_list in auth */ #define SCTP_SMALL_CHUNK_STORE 260 -#define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */ #define SCTP_HOW_MANY_SECRETS 2 /* how many secrets I keep */ #define SCTP_NUMBER_OF_SECRETS 8 /* or 8 * 4 = 32 octets */ @@ -772,6 +765,9 @@ __FBSDID("$FreeBSD$"); */ #define SCTP_DEFAULT_SPLIT_POINT_MIN 2904 +/* Maximum length of diagnostic information in error causes */ +#define SCTP_DIAG_INFO_LEN 64 + /* ABORT CODES and other tell-tale location * codes are generated by adding the below * to the instance id. diff --git a/freebsd/sys/netinet/sctp_dtrace_define.h b/freebsd/sys/netinet/sctp_dtrace_define.h index 1eb28f65..0bfe18c0 100644 --- a/freebsd/sys/netinet/sctp_dtrace_define.h +++ b/freebsd/sys/netinet/sctp_dtrace_define.h @@ -45,189 +45,132 @@ SDT_PROVIDER_DEFINE(sctp); /* Cwnd probe - tracks changes in the congestion window on a netp */ /********************************************************/ /* Initial */ -SDT_PROBE_DEFINE(sctp, cwnd, net, init, init); -/* The Vtag for this end */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 0, "uint32_t"); -/* The port number of the local side << 16 | port number of remote - * in network byte order. - */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 1, "uint32_t"); -/* The pointer to the struct sctp_nets * changing */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 2, "uintptr_t"); -/* The old value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 3, "int"); -/* The new value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 4, "int"); - +SDT_PROBE_DEFINE5(sctp, cwnd, net, init, + "uint32_t", /* The Vtag for this end */ + "uint32_t", /* + * The port number of the local side << 16 | port number + * of remote in network byte order. + */ + "uintptr_t", /* The pointer to the struct sctp_nets * changing */ + "int", /* The old value of the cwnd */ + "int"); /* The new value of the cwnd */ /* ACK-INCREASE */ -SDT_PROBE_DEFINE(sctp, cwnd, net, ack, ack); -/* The Vtag for this end */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 0, "uint32_t"); -/* The port number of the local side << 16 | port number of remote - * in network byte order. - */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 1, "uint32_t"); -/* The pointer to the struct sctp_nets * changing */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 2, "uintptr_t"); -/* The old value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 3, "int"); -/* The new value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 4, "int"); - +SDT_PROBE_DEFINE5(sctp, cwnd, net, ack, + "uint32_t", /* The Vtag for this end */ + "uint32_t", /* + * The port number of the local side << 16 | port number + * of remote in network byte order. + */ + "uintptr_t", /* The pointer to the struct sctp_nets * changing */ + "int", /* The old value of the cwnd */ + "int"); /* The new value of the cwnd */ /* ACK-INCREASE */ -SDT_PROBE_DEFINE(sctp, cwnd, net, rttvar, rttvar); -/* The Vtag << 32 | localport << 16 | remoteport */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 0, "uint64_t"); -/* obw | nbw */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 1, "uint64_t"); -/* bwrtt | newrtt */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 2, "uint64_t"); -/* flight */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 3, "uint64_t"); -/* (cwnd << 32) | point << 16 | retval(0/1) */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 4, "uint64_t"); - - -SDT_PROBE_DEFINE(sctp, cwnd, net, rttstep, rttstep); -/* The Vtag << 32 | localport << 16 | remoteport */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 0, "uint64_t"); -/* obw | nbw */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 1, "uint64_t"); -/* bwrtt | nrtt */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 2, "uint64_t"); -/* cwnd_saved | stepcnt << 16 | oldstep */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 3, "uint64_t"); -/* (cwnd << 32) | point << 16 | retval(0/1) */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 4, "uint64_t"); - +SDT_PROBE_DEFINE5(sctp, cwnd, net, rttvar, + "uint64_t", /* The Vtag << 32 | localport << 16 | remoteport */ + "uint64_t", /* obw | nbw */ + "uint64_t", /* bwrtt | newrtt */ + "uint64_t", /* flight */ + "uint64_t"); /* (cwnd << 32) | point << 16 | retval(0/1) */ + +SDT_PROBE_DEFINE5(sctp, cwnd, net, rttstep, + "uint64_t", /* The Vtag << 32 | localport << 16 | remoteport */ + "uint64_t", /* obw | nbw */ + "uint64_t", /* bwrtt | newrtt */ + "uint64_t", /* flight */ + "uint64_t"); /* (cwnd << 32) | point << 16 | retval(0/1) */ /* FastRetransmit-DECREASE */ -SDT_PROBE_DEFINE(sctp, cwnd, net, fr, fr); -/* The Vtag for this end */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 0, "uint32_t"); -/* The port number of the local side << 16 | port number of remote - * in network byte order. - */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 1, "uint32_t"); -/* The pointer to the struct sctp_nets * changing */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 2, "uintptr_t"); -/* The old value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 3, "int"); -/* The new value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 4, "int"); - +SDT_PROBE_DEFINE5(sctp, cwnd, net, fr, + "uint32_t", /* The Vtag for this end */ + "uint32_t", /* + * The port number of the local side << 16 | port number + * of remote in network byte order. + */ + "uintptr_t", /* The pointer to the struct sctp_nets * changing */ + "int", /* The old value of the cwnd */ + "int"); /* The new value of the cwnd */ /* TimeOut-DECREASE */ -SDT_PROBE_DEFINE(sctp, cwnd, net, to, to); -/* The Vtag for this end */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 0, "uint32_t"); -/* The port number of the local side << 16 | port number of remote - * in network byte order. - */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 1, "uint32_t"); -/* The pointer to the struct sctp_nets * changing */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 2, "uintptr_t"); -/* The old value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 3, "int"); -/* The new value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 4, "int"); - +SDT_PROBE_DEFINE5(sctp, cwnd, net, to, + "uint32_t", /* The Vtag for this end */ + "uint32_t", /* + * The port number of the local side << 16 | port number + * of remote in network byte order. + */ + "uintptr_t", /* The pointer to the struct sctp_nets * changing */ + "int", /* The old value of the cwnd */ + "int"); /* The new value of the cwnd */ /* BurstLimit-DECREASE */ -SDT_PROBE_DEFINE(sctp, cwnd, net, bl, bl); -/* The Vtag for this end */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 0, "uint32_t"); -/* The port number of the local side << 16 | port number of remote - * in network byte order. - */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 1, "uint32_t"); -/* The pointer to the struct sctp_nets * changing */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 2, "uintptr_t"); -/* The old value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 3, "int"); -/* The new value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 4, "int"); - +SDT_PROBE_DEFINE5(sctp, cwnd, net, bl, + "uint32_t", /* The Vtag for this end */ + "uint32_t", /* + * The port number of the local side << 16 | port number + * of remote in network byte order. + */ + "uintptr_t", /* The pointer to the struct sctp_nets * changing */ + "int", /* The old value of the cwnd */ + "int"); /* The new value of the cwnd */ /* ECN-DECREASE */ -SDT_PROBE_DEFINE(sctp, cwnd, net, ecn, ecn); -/* The Vtag for this end */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 0, "uint32_t"); -/* The port number of the local side << 16 | port number of remote - * in network byte order. - */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 1, "uint32_t"); -/* The pointer to the struct sctp_nets * changing */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 2, "uintptr_t"); -/* The old value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 3, "int"); -/* The new value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 4, "int"); - +SDT_PROBE_DEFINE5(sctp, cwnd, net, ecn, + "uint32_t", /* The Vtag for this end */ + "uint32_t", /* + * The port number of the local side << 16 | port number + * of remote in network byte order. + */ + "uintptr_t", /* The pointer to the struct sctp_nets * changing */ + "int", /* The old value of the cwnd */ + "int"); /* The new value of the cwnd */ /* PacketDrop-DECREASE */ -SDT_PROBE_DEFINE(sctp, cwnd, net, pd, pd); -/* The Vtag for this end */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 0, "uint32_t"); -/* The port number of the local side << 16 | port number of remote - * in network byte order. - */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 1, "uint32_t"); -/* The pointer to the struct sctp_nets * changing */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 2, "uintptr_t"); -/* The old value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 3, "int"); -/* The new value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 4, "int"); - - +SDT_PROBE_DEFINE5(sctp, cwnd, net, pd, + "uint32_t", /* The Vtag for this end */ + "uint32_t", /* + * The port number of the local side << 16 | port number + * of remote in network byte order. + */ + "uintptr_t", /* The pointer to the struct sctp_nets * changing */ + "int", /* The old value of the cwnd */ + "int"); /* The new value of the cwnd */ /********************************************************/ /* Rwnd probe - tracks changes in the receiver window for an assoc */ /********************************************************/ -SDT_PROBE_DEFINE(sctp, rwnd, assoc, val, val); -/* The Vtag for this end */ -SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 0, "uint32_t"); -/* The port number of the local side << 16 | port number of remote - * in network byte order. - */ -SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 1, "uint32_t"); -/* The up/down amount */ -SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 2, "int"); -/* The new value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 3, "int"); +SDT_PROBE_DEFINE4(sctp, rwnd, assoc, val, + "uint32_t", /* The Vtag for this end */ + "uint32_t", /* + * The port number of the local side << 16 | port number + * of remote in network byte order. + */ + "int", /* The up/down amount */ + "int"); /* The new value of the cwnd */ /********************************************************/ /* flight probe - tracks changes in the flight size on a net or assoc */ /********************************************************/ -SDT_PROBE_DEFINE(sctp, flightsize, net, val, val); -/* The Vtag for this end */ -SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 0, "uint32_t"); -/* The port number of the local side << 16 | port number of remote - * in network byte order. - */ -SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 1, "uint32_t"); -/* The pointer to the struct sctp_nets * changing */ -SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 2, "uintptr_t"); -/* The up/down amount */ -SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 3, "int"); -/* The new value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 4, "int"); +SDT_PROBE_DEFINE5(sctp, flightsize, net, val, + "uint32_t", /* The Vtag for this end */ + "uint32_t", /* + * The port number of the local side << 16 | port number + * of remote in network byte order. + */ + "uintptr_t", /* The pointer to the struct sctp_nets * changing */ + "int", /* The up/down amount */ + "int"); /* The new value of the cwnd */ + /********************************************************/ /* The total flight version */ /********************************************************/ -SDT_PROBE_DEFINE(sctp, flightsize, assoc, val, val); -/* The Vtag for this end */ -SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 0, "uint32_t"); -/* The port number of the local side << 16 | port number of remote - * in network byte order. - */ -SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 1, "uint32_t"); -/* The up/down amount */ -SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 2, "int"); -/* The new value of the cwnd */ -SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 3, "int"); +SDT_PROBE_DEFINE4(sctp, flightsize, assoc, val, + "uint32_t", /* The Vtag for this end */ + "uint32_t", /* + * The port number of the local side << 16 | port number + * of remote in network byte order. + */ + "int", /* The up/down amount */ + "int"); /* The new value of the cwnd */ #endif diff --git a/freebsd/sys/netinet/sctp_indata.c b/freebsd/sys/netinet/sctp_indata.c index e00a470d..07d8fd2b 100644 --- a/freebsd/sys/netinet/sctp_indata.c +++ b/freebsd/sys/netinet/sctp_indata.c @@ -252,6 +252,11 @@ sctp_build_ctl_nchunk(struct sctp_inpcb *inp, struct sctp_sndrcvinfo *sinfo) /* We need a CMSG header followed by the struct */ cmh = mtod(ret, struct cmsghdr *); + /* + * Make sure that there is no un-initialized padding between the + * cmsg header and cmsg data and after the cmsg data. + */ + memset(cmh, 0, len); if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO)) { cmh->cmsg_level = IPPROTO_SCTP; cmh->cmsg_len = CMSG_LEN(sizeof(struct sctp_rcvinfo)); @@ -563,7 +568,8 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_queued_to_read *at; int queue_needed; uint16_t nxt_todel; - struct mbuf *oper; + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; queue_needed = 1; asoc->size_on_all_streams += control->length; @@ -580,7 +586,7 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc, (uint32_t) nxt_todel); if (SCTP_SSN_GE(strm->last_sequence_delivered, control->sinfo_ssn)) { /* The incoming sseq is behind where we last delivered? */ - SCTPDBG(SCTP_DEBUG_INDATA1, "Duplicate S-SEQ:%d delivered:%d from peer, Abort association\n", + SCTPDBG(SCTP_DEBUG_INDATA1, "Duplicate S-SEQ:%d delivered:%d from peer, Abort association\n", control->sinfo_ssn, strm->last_sequence_delivered); protocol_error: /* @@ -588,26 +594,12 @@ protocol_error: * association destruction */ TAILQ_INSERT_HEAD(&strm->inqueue, control, next); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) + - (sizeof(uint32_t) * 3); - ph = mtod(oper, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_1); - ippp++; - *ippp = control->sinfo_tsn; - ippp++; - *ippp = ((control->sinfo_stream << 16) | control->sinfo_ssn); - } + snprintf(msg, sizeof(msg), "Delivered SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + strm->last_sequence_delivered, control->sinfo_tsn, + control->sinfo_stream, control->sinfo_ssn); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_1; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; return; @@ -791,13 +783,12 @@ doit_again: * but should we? */ if (stcb->sctp_socket) { - pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket), + pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT, stcb->sctp_ep->partial_delivery_point); } else { pd_point = stcb->sctp_ep->partial_delivery_point; } if (sctp_is_all_msg_on_reasm(asoc, &tsize) || (tsize >= pd_point)) { - /* * Yes, we setup to start reception, by * backing down the TSN just in case we @@ -842,7 +833,8 @@ static void sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_tmit_chunk *chk, int *abort_flag) { - struct mbuf *oper; + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; uint32_t cum_ackp1, prev_tsn, post_tsn; struct sctp_tmit_chunk *at, *prev, *next; @@ -867,30 +859,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, * a FIRST fragment mark. */ SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, its not first, no fragmented delivery in progress\n"); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (sizeof(uint32_t) * 3); - ph = mtod(oper, struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_2); - ippp++; - *ippp = chk->rec.data.TSN_seq; - ippp++; - *ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq); - - } + snprintf(msg, sizeof(msg), + "Expected B-bit for TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + chk->rec.data.TSN_seq, + chk->rec.data.stream_number, + chk->rec.data.stream_seq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_2; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; } else if (asoc->fragmented_delivery_inprogress && (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) == SCTP_DATA_FIRST_FRAG) { @@ -900,28 +876,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, * MIDDLE fragment NOT a FIRST */ SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it IS a first and fragmented delivery in progress\n"); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_3); - ippp++; - *ippp = chk->rec.data.TSN_seq; - ippp++; - *ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq); - } + snprintf(msg, sizeof(msg), + "Didn't expect B-bit for TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + chk->rec.data.TSN_seq, + chk->rec.data.stream_number, + chk->rec.data.stream_seq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_3; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; } else if (asoc->fragmented_delivery_inprogress) { /* @@ -934,30 +896,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it IS not same stream number %d vs %d\n", chk->rec.data.stream_number, asoc->str_of_pdapi); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (sizeof(uint32_t) * 3); - ph = mtod(oper, - struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = - htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_4); - ippp++; - *ippp = chk->rec.data.TSN_seq; - ippp++; - *ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq); - } + snprintf(msg, sizeof(msg), + "Expected SID=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + asoc->str_of_pdapi, + chk->rec.data.TSN_seq, + chk->rec.data.stream_number, + chk->rec.data.stream_seq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_4; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; } else if ((asoc->fragment_flags & SCTP_DATA_UNORDERED) != SCTP_DATA_UNORDERED && @@ -966,31 +913,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it IS not same stream seq %d vs %d\n", chk->rec.data.stream_seq, asoc->ssn_of_pdapi); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, - struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = - htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_5); - ippp++; - *ippp = chk->rec.data.TSN_seq; - ippp++; - *ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq); - - } + snprintf(msg, sizeof(msg), + "Expected SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + asoc->ssn_of_pdapi, + chk->rec.data.TSN_seq, + chk->rec.data.stream_number, + chk->rec.data.stream_seq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_5; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; } } @@ -1060,31 +991,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, SCTP_DATA_FIRST_FRAG) { SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - It can be a midlle or last but not a first\n"); SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it's a FIRST!\n"); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, - struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = - htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_6); - ippp++; - *ippp = chk->rec.data.TSN_seq; - ippp++; - *ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq); - - } + snprintf(msg, sizeof(msg), + "Can't handle B-bit, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + chk->rec.data.TSN_seq, + chk->rec.data.stream_number, + chk->rec.data.stream_seq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_6; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; return; } @@ -1094,33 +1008,36 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, * Huh, need the correct STR here, * they must be the same. */ - SCTP_PRINTF("Prev check - Gak, Evil plot, ssn:%d not the same as at:%d\n", + SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - Gak, Evil plot, sid:%d not the same as at:%d\n", chk->rec.data.stream_number, prev->rec.data.stream_number); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, - struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = - htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_7); - ippp++; - *ippp = chk->rec.data.TSN_seq; - ippp++; - *ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq); - } + snprintf(msg, sizeof(msg), + "Expect SID=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + prev->rec.data.stream_number, + chk->rec.data.TSN_seq, + chk->rec.data.stream_number, + chk->rec.data.stream_seq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_7; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); + *abort_flag = 1; + return; + } + if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) != + (prev->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) { + /* + * Huh, need the same ordering here, + * they must be the same. + */ + SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - Gak, Evil plot, U-bit not constant\n"); + snprintf(msg, sizeof(msg), + "Expect U-bit=%d for TSN=%8.8x, got U-bit=%d", + (prev->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0, + chk->rec.data.TSN_seq, + (chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); + stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_7; + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; return; } @@ -1134,30 +1051,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - Gak, Evil plot, sseq:%d not the same as at:%d\n", chk->rec.data.stream_seq, prev->rec.data.stream_seq); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, - struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = - htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_8); - ippp++; - *ippp = chk->rec.data.TSN_seq; - ippp++; - *ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq); - } + snprintf(msg, sizeof(msg), + "Expect SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + prev->rec.data.stream_seq, + chk->rec.data.TSN_seq, + chk->rec.data.stream_number, + chk->rec.data.stream_seq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_8; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; return; } @@ -1167,31 +1069,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, if ((chk->rec.data.rcv_flags & SCTP_DATA_FRAG_MASK) != SCTP_DATA_FIRST_FRAG) { SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - Gak, evil plot, its not FIRST and it must be!\n"); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, - struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = - htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_9); - ippp++; - *ippp = chk->rec.data.TSN_seq; - ippp++; - *ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq); - - } + snprintf(msg, sizeof(msg), + "Expect B-bit, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + chk->rec.data.TSN_seq, + chk->rec.data.stream_number, + chk->rec.data.stream_seq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_9; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; return; } @@ -1211,30 +1096,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, != SCTP_DATA_LAST_FRAG) { SCTPDBG(SCTP_DEBUG_INDATA1, "Next chk - Next is FIRST, we must be LAST\n"); SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, its not a last!\n"); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, - struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = - htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_10); - ippp++; - *ippp = chk->rec.data.TSN_seq; - ippp++; - *ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq); - } + snprintf(msg, sizeof(msg), + "Expect only E-bit, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + chk->rec.data.TSN_seq, + chk->rec.data.stream_number, + chk->rec.data.stream_seq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_10; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; return; } @@ -1250,31 +1119,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, SCTP_DATA_LAST_FRAG) { SCTPDBG(SCTP_DEBUG_INDATA1, "Next chk - Next is a MIDDLE/LAST\n"); SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, new prev chunk is a LAST\n"); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, - struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = - htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_11); - ippp++; - *ippp = chk->rec.data.TSN_seq; - ippp++; - *ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq); - - } + snprintf(msg, sizeof(msg), + "Didn't expect E-bit, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + chk->rec.data.TSN_seq, + chk->rec.data.stream_number, + chk->rec.data.stream_seq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_11; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; return; } @@ -1287,31 +1139,33 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, SCTPDBG(SCTP_DEBUG_INDATA1, "Next chk - Gak, Evil plot, ssn:%d not the same as at:%d\n", chk->rec.data.stream_number, next->rec.data.stream_number); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, - struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = - htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_12); - ippp++; - *ippp = chk->rec.data.TSN_seq; - ippp++; - *ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq); - - } + snprintf(msg, sizeof(msg), + "Required SID %4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + next->rec.data.stream_number, + chk->rec.data.TSN_seq, + chk->rec.data.stream_number, + chk->rec.data.stream_seq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_12; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); + *abort_flag = 1; + return; + } + if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) != + (next->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) { + /* + * Huh, need the same ordering here, + * they must be the same. + */ + SCTPDBG(SCTP_DEBUG_INDATA1, "Next check - Gak, Evil plot, U-bit not constant\n"); + snprintf(msg, sizeof(msg), + "Expect U-bit=%d for TSN=%8.8x, got U-bit=%d", + (next->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0, + chk->rec.data.TSN_seq, + (chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); + stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_12; + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; return; } @@ -1325,30 +1179,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, SCTPDBG(SCTP_DEBUG_INDATA1, "Next chk - Gak, Evil plot, sseq:%d not the same as at:%d\n", chk->rec.data.stream_seq, next->rec.data.stream_seq); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, - struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = - htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_13); - ippp++; - *ippp = chk->rec.data.TSN_seq; - ippp++; - *ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq); - } + snprintf(msg, sizeof(msg), + "Required SSN %4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + next->rec.data.stream_seq, + chk->rec.data.TSN_seq, + chk->rec.data.stream_number, + chk->rec.data.stream_seq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_13; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; return; } @@ -1419,7 +1258,6 @@ sctp_does_tsn_belong_to_reasm(struct sctp_association *asoc, return (0); } - static int sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc, struct mbuf **m, int offset, struct sctp_data_chunk *ch, int chk_length, @@ -1434,7 +1272,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc, int the_len; int need_reasm_check = 0; uint16_t strmno, strmseq; - struct mbuf *oper; + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; struct sctp_queued_to_read *control; int ordered; uint32_t protocol_id; @@ -1501,15 +1340,12 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc, */ if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || - (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) - ) { + (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET))) { /* * wait a minute, this guy is gone, there is no longer a * receiver. Send peer an ABORT! */ - struct mbuf *op_err; - - op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC); + op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, ""); sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; return (0); @@ -1637,27 +1473,12 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc, /* The incoming sseq is behind where we last delivered? */ SCTPDBG(SCTP_DEBUG_INDATA1, "EVIL/Broken-Dup S-SEQ:%d delivered:%d from peer, Abort!\n", strmseq, asoc->strmin[strmno].last_sequence_delivered); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_14); - ippp++; - *ippp = tsn; - ippp++; - *ippp = ((strmno << 16) | strmseq); - - } + snprintf(msg, sizeof(msg), "Delivered SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + asoc->strmin[strmno].last_sequence_delivered, + tsn, strmno, strmseq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_14; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; return (0); } @@ -1791,7 +1612,6 @@ failed_express_del: asoc->highest_tsn_inside_nr_map = tsn; } SCTP_STAT_INCR(sctps_recvexpressm); - control->sinfo_tsn = tsn; asoc->tsn_last_delivered = tsn; asoc->fragment_flags = chunk_flags; asoc->tsn_of_pdapi_last_delivered = tsn; @@ -1897,29 +1717,15 @@ failed_pdapi_express_del: control->whoFrom = NULL; } sctp_free_a_readq(stcb, control); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_15); - ippp++; - *ippp = tsn; - ippp++; - *ippp = ((strmno << 16) | strmseq); - } + snprintf(msg, sizeof(msg), "Reas. queue emtpy, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + tsn, strmno, strmseq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_15; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; + if (last_chunk) { + *m = NULL; + } return (0); } else { if (sctp_does_tsn_belong_to_reasm(asoc, control->sinfo_tsn)) { @@ -1930,32 +1736,15 @@ failed_pdapi_express_del: control->whoFrom = NULL; } sctp_free_a_readq(stcb, control); - - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, - struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = - htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_16); - ippp++; - *ippp = tsn; - ippp++; - *ippp = ((strmno << 16) | strmseq); - } + snprintf(msg, sizeof(msg), "PD ongoing, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + tsn, strmno, strmseq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_16; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; + if (last_chunk) { + *m = NULL; + } return (0); } } @@ -1976,31 +1765,15 @@ failed_pdapi_express_del: control->whoFrom = NULL; } sctp_free_a_readq(stcb, control); - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = - sizeof(struct sctp_paramhdr) + - (3 * sizeof(uint32_t)); - ph = mtod(oper, - struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = - htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_17); - ippp++; - *ippp = tsn; - ippp++; - *ippp = ((strmno << 16) | strmseq); - } + snprintf(msg, sizeof(msg), "No PD ongoing, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x", + tsn, strmno, strmseq); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_17; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_flag = 1; + if (last_chunk) { + *m = NULL; + } return (0); } } @@ -2064,6 +1837,9 @@ failed_pdapi_express_del: } else { sctp_queue_data_to_stream(stcb, asoc, control, abort_flag); if (*abort_flag) { + if (last_chunk) { + *m = NULL; + } return (0); } } @@ -2076,7 +1852,9 @@ failed_pdapi_express_del: * the assoc is now gone and chk was put onto the * reasm queue, which has all been freed. */ - *m = NULL; + if (last_chunk) { + *m = NULL; + } return (0); } } @@ -2494,7 +2272,7 @@ doit_again: * delivery queue and something can be delivered. */ if (stcb->sctp_socket) { - pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket), + pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT, stcb->sctp_ep->partial_delivery_point); } else { pd_point = stcb->sctp_ep->partial_delivery_point; @@ -2600,32 +2378,32 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, continue; } if (ch->ch.chunk_type == SCTP_DATA) { - if ((size_t)chk_length < sizeof(struct sctp_data_chunk) + 1) { + if ((size_t)chk_length < sizeof(struct sctp_data_chunk)) { /* * Need to send an abort since we had a * invalid data chunk. */ struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; - op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 2 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - - if (op_err) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr) + - (2 * sizeof(uint32_t)); - ph = mtod(op_err, struct sctp_paramhdr *); - ph->param_type = - htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = htons(SCTP_BUF_LEN(op_err)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_19); - ippp++; - *ippp = asoc->cumulative_tsn; + snprintf(msg, sizeof(msg), "DATA chunk of length %d", + chk_length); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); + stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_19; + sctp_abort_association(inp, stcb, m, iphlen, + src, dst, sh, op_err, + use_mflowid, mflowid, + vrf_id, port); + return (2); + } + if ((size_t)chk_length == sizeof(struct sctp_data_chunk)) { + /* + * Need to send an abort since we had an + * empty data chunk. + */ + struct mbuf *op_err; - } + op_err = sctp_generate_no_user_data_cause(ch->dp.tsn); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_19; sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err, @@ -2693,7 +2471,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, if (SCTP_BASE_SYSCTL(sctp_strict_data_order)) { struct mbuf *op_err; - op_err = sctp_generate_invmanparam(SCTP_CAUSE_PROTOCOL_VIOLATION); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, ""); sctp_abort_association(inp, stcb, m, iphlen, src, dst, @@ -3842,7 +3620,8 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, } if (SCTP_TSN_GE(cumack, send_s)) { #ifndef INVARIANTS - struct mbuf *oper; + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; #endif #ifdef INVARIANTS @@ -3851,22 +3630,11 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, *abort_now = 1; /* XXX */ - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) + - sizeof(uint32_t); - ph = mtod(oper, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_25); - } + snprintf(msg, sizeof(msg), "Cum ack %8.8x greater or equal then TSN %8.8x", + cumack, send_s); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); return; #endif } @@ -4216,23 +3984,14 @@ again: (asoc->stream_queue_cnt == 0)) { if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) { /* Need to abort here */ - struct mbuf *oper; + struct mbuf *op_err; abort_out_now: *abort_now = 1; /* XXX */ - oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - - SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr); - ph = mtod(oper, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); - ph->param_length = htons(SCTP_BUF_LEN(oper)); - } + op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, ""); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_24; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); } else { struct sctp_nets *netp; @@ -4425,7 +4184,8 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, send_s = asoc->sending_seq; } if (SCTP_TSN_GE(cum_ack, send_s)) { - struct mbuf *oper; + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; /* * no way, we have not even sent this TSN out yet. @@ -4440,22 +4200,11 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, hopeless_peer: *abort_now = 1; /* XXX */ - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) + - sizeof(uint32_t); - ph = mtod(oper, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_25); - } + snprintf(msg, sizeof(msg), "Cum ack %8.8x greater or equal then TSN %8.8x", + cum_ack, send_s); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); return; } } @@ -4721,7 +4470,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, } } TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next); - if (tp1->pr_sctp_on) { + if (PR_SCTP_ENABLED(tp1->flags)) { if (asoc->pr_sctp_cnt != 0) asoc->pr_sctp_cnt--; } @@ -4944,23 +4693,14 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, (asoc->stream_queue_cnt == 0)) { if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) { /* Need to abort here */ - struct mbuf *oper; + struct mbuf *op_err; abort_out_now: *abort_now = 1; /* XXX */ - oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - - SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr); - ph = mtod(oper, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); - ph->param_length = htons(SCTP_BUF_LEN(oper)); - } + op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, ""); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_31; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); return; } else { struct sctp_nets *netp; @@ -5389,33 +5129,20 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, asoc->cumulative_tsn = new_cum_tsn; if (gap >= m_size) { if ((long)gap > sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv)) { - struct mbuf *oper; + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; /* * out of range (of single byte chunks in the rwnd I * give out). This must be an attacker. */ *abort_flag = 1; - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) + - (sizeof(uint32_t) * 3); - ph = mtod(oper, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_33); - ippp++; - *ippp = asoc->highest_tsn_inside_map; - ippp++; - *ippp = new_cum_tsn; - } + snprintf(msg, sizeof(msg), + "New cum ack %8.8x too high, highest TSN %8.8x", + new_cum_tsn, asoc->highest_tsn_inside_map); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_33; - sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); return; } SCTP_STAT_INCR(sctps_fwdtsn_map_over); diff --git a/freebsd/sys/netinet/sctp_input.c b/freebsd/sys/netinet/sctp_input.c index 7cdb5b09..baf25af8 100644 --- a/freebsd/sys/netinet/sctp_input.c +++ b/freebsd/sys/netinet/sctp_input.c @@ -99,7 +99,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, } /* validate length */ if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_chunk)) { - op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); + op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, ""); sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, vrf_id, port); @@ -111,7 +111,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, init = &cp->init; if (init->initiate_tag == 0) { /* protocol error... send abort */ - op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); + op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, ""); sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, vrf_id, port); @@ -121,7 +121,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, } if (ntohl(init->a_rwnd) < SCTP_MIN_RWND) { /* invalid parameter... send abort */ - op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); + op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, ""); sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, vrf_id, port); @@ -131,7 +131,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, } if (init->num_inbound_streams == 0) { /* protocol error... send abort */ - op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); + op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, ""); sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, vrf_id, port); @@ -141,7 +141,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, } if (init->num_outbound_streams == 0) { /* protocol error... send abort */ - op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); + op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, ""); sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, vrf_id, port); @@ -152,7 +152,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, if (sctp_validate_init_auth_params(m, offset + sizeof(*cp), offset + ntohs(cp->ch.chunk_length))) { /* auth parameter(s) error... send abort */ - sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, NULL, + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + "Problem with AUTH parameters"); + sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, vrf_id, port); if (stcb) @@ -181,7 +183,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, * state :-) */ if (SCTP_BASE_SYSCTL(sctp_blackhole) == 0) { - sctp_send_abort(m, iphlen, src, dst, sh, 0, NULL, + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + "No listener"); + sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err, use_mflowid, mflowid, vrf_id, port); } @@ -441,7 +445,6 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, /* First verify that we have no illegal param's */ abort_flag = 0; - op_err = NULL; op_err = sctp_arethere_unrecognized_parameters(m, (offset + sizeof(struct sctp_init_chunk)), @@ -464,12 +467,13 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, if ((retval = sctp_load_addresses_from_init(stcb, m, (offset + sizeof(struct sctp_init_chunk)), initack_limit, src, dst, NULL))) { - /* Huh, we should abort */ + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + "Problem with address parameters"); SCTPDBG(SCTP_DEBUG_INPUT1, "Load addresses from INIT causes an abort %d\n", retval); sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, - src, dst, sh, NULL, + src, dst, sh, op_err, use_mflowid, mflowid, vrf_id, net->port); *abort_no_unlock = 1; @@ -524,8 +528,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, */ if (retval == -3) { /* We abort with an error of missing mandatory param */ - op_err = - sctp_generate_invmanparam(SCTP_CAUSE_MISSING_PARAM); + op_err = sctp_generate_cause(SCTP_CAUSE_MISSING_PARAM, ""); if (op_err) { /* * Expand beyond to include the mandatory @@ -1308,7 +1311,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, } if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_ack_chunk)) { /* Invalid length */ - op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); + op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, ""); sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, @@ -1320,7 +1323,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, /* validate parameters */ if (init_ack->initiate_tag == 0) { /* protocol error... send an abort */ - op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); + op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, ""); sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, @@ -1330,7 +1333,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, } if (ntohl(init_ack->a_rwnd) < SCTP_MIN_RWND) { /* protocol error... send an abort */ - op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); + op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, ""); sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, @@ -1340,7 +1343,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, } if (init_ack->num_inbound_streams == 0) { /* protocol error... send an abort */ - op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); + op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, ""); sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, @@ -1350,7 +1353,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, } if (init_ack->num_outbound_streams == 0) { /* protocol error... send an abort */ - op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM); + op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, ""); sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, @@ -1460,7 +1463,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, struct sctp_init_ack_chunk *initack_cp, initack_buf; struct sctp_nets *net; struct mbuf *op_err; - struct sctp_paramhdr *ph; int init_offset, initack_offset, i; int retval; int spec_flag = 0; @@ -1479,17 +1481,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) { /* SHUTDOWN came in after sending INIT-ACK */ sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination); - op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), - 0, M_DONTWAIT, 1, MT_DATA); - if (op_err == NULL) { - /* FOOBAR */ - return (NULL); - } - /* Set the len */ - SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr); - ph = mtod(op_err, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_COOKIE_IN_SHUTDOWN); - ph->param_length = htons(sizeof(struct sctp_paramhdr)); + op_err = sctp_generate_cause(SCTP_CAUSE_COOKIE_IN_SHUTDOWN, ""); sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err, use_mflowid, mflowid, vrf_id, net->port); @@ -1555,8 +1547,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, return (NULL); } - switch SCTP_GET_STATE - (asoc) { + switch (SCTP_GET_STATE(asoc)) { case SCTP_STATE_COOKIE_WAIT: case SCTP_STATE_COOKIE_ECHOED: /* @@ -1646,7 +1637,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, * have simply lost the COOKIE-ACK */ break; - } /* end switch */ + } /* end switch */ sctp_stop_all_cookie_timers(stcb); /* * We ignore the return code here.. not sure if we should @@ -1697,25 +1688,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, * Now we have colliding state. We must send an abort here * with colliding state indication. */ - op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), - 0, M_DONTWAIT, 1, MT_DATA); - if (op_err == NULL) { - /* FOOBAR */ - return (NULL); - } - /* pre-reserve some space */ -#ifdef INET6 - SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr)); -#else - SCTP_BUF_RESV_UF(op_err, sizeof(struct ip)); -#endif - SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr)); - SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr)); - /* Set the len */ - SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr); - ph = mtod(op_err, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_NAT_COLLIDING_STATE); - ph->param_length = htons(sizeof(struct sctp_paramhdr)); + op_err = sctp_generate_cause(SCTP_CAUSE_NAT_COLLIDING_STATE, ""); sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err, use_mflowid, mflowid, vrf_id, port); @@ -2128,8 +2101,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, /* memory problem? */ SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: no room for another TCB!\n"); - op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC); - + op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, ""); sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, @@ -2157,7 +2129,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, * association. */ atomic_add_int(&stcb->asoc.refcnt, 1); - op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC); + op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, ""); sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, @@ -2776,7 +2748,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset, #endif /* Too many sockets */ SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: no room for another socket!\n"); - op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC); + op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, ""); sctp_abort_association(*inp_p, NULL, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, @@ -4398,6 +4370,8 @@ __attribute__((noinline)) uint32_t vrf_id, uint16_t port) { struct sctp_association *asoc; + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; uint32_t vtag_in; int num_chunks = 0; /* number of control chunks processed */ uint32_t chk_length; @@ -4551,8 +4525,11 @@ __attribute__((noinline)) } } if (stcb == NULL) { + snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + msg); /* no association, so it's out of the blue... */ - sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp, + sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp, op_err, use_mflowid, mflowid, vrf_id, port); *offset = length; @@ -4592,8 +4569,11 @@ __attribute__((noinline)) if (locked_tcb) { SCTP_TCB_UNLOCK(locked_tcb); } + snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + msg); sctp_handle_ootb(m, iphlen, *offset, src, dst, - sh, inp, + sh, inp, op_err, use_mflowid, mflowid, vrf_id, port); return (NULL); @@ -4735,8 +4715,10 @@ process_control_chunks: /* The INIT chunk must be the only chunk. */ if ((num_chunks > 1) || (length - *offset > (int)SCTP_SIZE32(chk_length))) { + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + "INIT not the only chunk"); sctp_abort_association(inp, stcb, m, iphlen, - src, dst, sh, NULL, + src, dst, sh, op_err, use_mflowid, mflowid, vrf_id, port); *offset = length; @@ -4744,9 +4726,7 @@ process_control_chunks: } /* Honor our resource limit. */ if (chk_length > SCTP_LARGEST_INIT_ACCEPTED) { - struct mbuf *op_err; - - op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC); + op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, ""); sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, @@ -5114,9 +5094,7 @@ process_control_chunks: if ((stcb == NULL) && (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))) { - struct mbuf *op_err; - - op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC); + op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, ""); sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err, use_mflowid, mflowid, @@ -5601,7 +5579,8 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt { uint32_t high_tsn; int fwd_tsn_seen = 0, data_processed = 0; - struct mbuf *m = *mm; + struct mbuf *m = *mm, *op_err; + char msg[SCTP_DIAG_INFO_LEN]; int un_sent; int cnt_ctrl_ready = 0; struct sctp_inpcb *inp = NULL, *inp_decr = NULL; @@ -5687,8 +5666,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) || ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) && (ch->chunk_type != SCTP_INIT))) { + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + "Out of the blue"); sctp_send_abort(m, iphlen, src, dst, - sh, 0, NULL, + sh, 0, op_err, use_mflowid, mflowid, vrf_id, port); } @@ -5746,7 +5727,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt */ SCTP_TCB_UNLOCK(stcb); stcb = NULL; - sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, + snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + msg); + sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err, use_mflowid, mflowid, vrf_id, port); goto out; @@ -5793,7 +5777,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt } if (stcb == NULL) { /* out of the blue DATA chunk */ - sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, + snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + msg); + sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err, use_mflowid, mflowid, vrf_id, port); goto out; @@ -5862,7 +5849,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt /* * We consider OOTB any data sent during asoc setup. */ - sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, + snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + msg); + sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err, use_mflowid, mflowid, vrf_id, port); goto out; diff --git a/freebsd/sys/netinet/sctp_os_bsd.h b/freebsd/sys/netinet/sctp_os_bsd.h index ca4be706..d33d1fd3 100644 --- a/freebsd/sys/netinet/sctp_os_bsd.h +++ b/freebsd/sys/netinet/sctp_os_bsd.h @@ -104,6 +104,9 @@ __FBSDID("$FreeBSD$"); #include +#include +#include + #ifndef in6pcb #define in6pcb inpcb #endif @@ -461,23 +464,18 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, /* * SCTP AUTH */ -#define HAVE_SHA2 - #define SCTP_READ_RANDOM(buf, len) read_random(buf, len) -#ifdef USE_SCTP_SHA1 -#include -#else -#include /* map standard crypto API names */ -#define SHA1_Init SHA1Init -#define SHA1_Update SHA1Update -#define SHA1_Final(x,y) SHA1Final((caddr_t)x, y) -#endif - -#if defined(HAVE_SHA2) -#include -#endif +#define SCTP_SHA1_CTX SHA1_CTX +#define SCTP_SHA1_INIT SHA1Init +#define SCTP_SHA1_UPDATE SHA1Update +#define SCTP_SHA1_FINAL(x,y) SHA1Final((caddr_t)x, y) + +#define SCTP_SHA256_CTX SHA256_CTX +#define SCTP_SHA256_INIT SHA256_Init +#define SCTP_SHA256_UPDATE SHA256_Update +#define SCTP_SHA256_FINAL(x,y) SHA256_Final((caddr_t)x, y) #endif diff --git a/freebsd/sys/netinet/sctp_output.c b/freebsd/sys/netinet/sctp_output.c index 61260fb7..f3cb4b44 100644 --- a/freebsd/sys/netinet/sctp_output.c +++ b/freebsd/sys/netinet/sctp_output.c @@ -1939,10 +1939,13 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa, static struct mbuf * sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t * len) { +#if defined(INET) || defined(INET6) struct sctp_paramhdr *parmh; struct mbuf *mret; uint16_t plen; +#endif + switch (ifa->address.sa.sa_family) { #ifdef INET case AF_INET: @@ -1957,6 +1960,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t * len) default: return (m); } +#if defined(INET) || defined(INET6) if (M_TRAILINGSPACE(m) >= plen) { /* easy side we just drop it on the end */ parmh = (struct sctp_paramhdr *)(SCTP_BUF_AT(m, SCTP_BUF_LEN(m))); @@ -2017,6 +2021,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t * len) *len += plen; } return (mret); +#endif } @@ -2057,6 +2062,20 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb, continue; } LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) { +#ifdef INET + if ((sctp_ifap->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifap->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifap->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifap->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif if (sctp_is_addr_restricted(stcb, sctp_ifap)) { continue; } @@ -2086,6 +2105,20 @@ skip_count: continue; } LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) { +#ifdef INET + if ((sctp_ifap->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifap->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifap->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifap->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif if (sctp_is_addr_restricted(stcb, sctp_ifap)) { continue; } @@ -2450,6 +2483,20 @@ sctp_choose_boundspecific_inp(struct sctp_inpcb *inp, if (sctp_ifn) { /* is a preferred one on the interface we route out? */ LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { +#ifdef INET + if ((sctp_ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) continue; @@ -2573,6 +2620,20 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp, if (sctp_ifn) { /* first try for a preferred address on the ep */ LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { +#ifdef INET + if ((sctp_ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) continue; if (sctp_is_addr_in_ep(inp, sctp_ifa)) { @@ -2593,6 +2654,20 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp, } /* next try for an acceptable address on the ep */ LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { +#ifdef INET + if ((sctp_ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) continue; if (sctp_is_addr_in_ep(inp, sctp_ifa)) { @@ -2697,6 +2772,7 @@ sctp_from_the_top2: static struct sctp_ifa * sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn, + struct sctp_inpcb *inp, struct sctp_tcb *stcb, int non_asoc_addr_ok, uint8_t dest_is_loop, @@ -2718,6 +2794,20 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn, } #endif /* INET6 */ LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) { +#ifdef INET + if ((ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) continue; @@ -2803,6 +2893,7 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn, static int sctp_count_num_preferred_boundall(struct sctp_ifn *ifn, + struct sctp_inpcb *inp, struct sctp_tcb *stcb, int non_asoc_addr_ok, uint8_t dest_is_loop, @@ -2813,6 +2904,21 @@ sctp_count_num_preferred_boundall(struct sctp_ifn *ifn, int num_eligible_addr = 0; LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) { +#ifdef INET + if ((ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((ifa->address.sa.sa_family == AF_INET6) && + (stcb != NULL) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) { continue; @@ -2844,7 +2950,8 @@ sctp_count_num_preferred_boundall(struct sctp_ifn *ifn, } static struct sctp_ifa * -sctp_choose_boundall(struct sctp_tcb *stcb, +sctp_choose_boundall(struct sctp_inpcb *inp, + struct sctp_tcb *stcb, struct sctp_nets *net, sctp_route_t * ro, uint32_t vrf_id, @@ -2899,7 +3006,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb, cur_addr_num = net->indx_of_eligible_next_to_use; } num_preferred = sctp_count_num_preferred_boundall(sctp_ifn, - stcb, + inp, stcb, non_asoc_addr_ok, dest_is_loop, dest_is_priv, fam); @@ -2926,7 +3033,7 @@ sctp_choose_boundall(struct sctp_tcb *stcb, */ SCTPDBG(SCTP_DEBUG_OUTPUT2, "cur_addr_num:%d\n", cur_addr_num); - sctp_ifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop, + sctp_ifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok, dest_is_loop, dest_is_priv, cur_addr_num, fam, ro); /* if sctp_ifa is NULL something changed??, fall to plan b. */ @@ -2957,7 +3064,7 @@ bound_all_plan_b: SCTPDBG(SCTP_DEBUG_OUTPUT2, "already seen\n"); continue; } - num_preferred = sctp_count_num_preferred_boundall(sctp_ifn, stcb, non_asoc_addr_ok, + num_preferred = sctp_count_num_preferred_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok, dest_is_loop, dest_is_priv, fam); SCTPDBG(SCTP_DEBUG_OUTPUT2, "Found ifn:%p %d preferred source addresses\n", @@ -2979,7 +3086,7 @@ bound_all_plan_b: if (cur_addr_num >= num_preferred) { cur_addr_num = 0; } - sifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop, + sifa = sctp_select_nth_preferred_addr_from_ifn_boundall(sctp_ifn, inp, stcb, non_asoc_addr_ok, dest_is_loop, dest_is_priv, cur_addr_num, fam, ro); if (sifa == NULL) continue; @@ -3007,6 +3114,22 @@ again_with_private_addresses_allowed: } LIST_FOREACH(sctp_ifa, &emit_ifn->ifalist, next_ifa) { SCTPDBG(SCTP_DEBUG_OUTPUT2, "ifa:%p\n", (void *)sctp_ifa); +#ifdef INET + if ((sctp_ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin.sin_addr) != 0)) { + SCTPDBG(SCTP_DEBUG_OUTPUT2, "Jailed\n"); + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin6.sin6_addr) != 0)) { + SCTPDBG(SCTP_DEBUG_OUTPUT2, "Jailed\n"); + continue; + } +#endif if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) { SCTPDBG(SCTP_DEBUG_OUTPUT2, "Defer\n"); @@ -3057,6 +3180,20 @@ plan_d: continue; } LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { +#ifdef INET + if ((sctp_ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) continue; @@ -3107,6 +3244,20 @@ out: LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { struct sctp_ifa *tmp_sifa; +#ifdef INET + if ((sctp_ifa->address.sa.sa_family == AF_INET) && + (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin.sin_addr) != 0)) { + continue; + } +#endif +#ifdef INET6 + if ((sctp_ifa->address.sa.sa_family == AF_INET6) && + (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sctp_ifa->address.sin6.sin6_addr) != 0)) { + continue; + } +#endif if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) continue; @@ -3292,7 +3443,7 @@ sctp_source_address_selection(struct sctp_inpcb *inp, /* * Bound all case */ - answer = sctp_choose_boundall(stcb, net, ro, vrf_id, + answer = sctp_choose_boundall(inp, stcb, net, ro, vrf_id, dest_is_priv, dest_is_loop, non_asoc_addr_ok, fam); SCTP_IPI_ADDR_RUNLOCK(); @@ -3386,7 +3537,11 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize) return (found); } m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_prinfo), (caddr_t)&prinfo); - sndrcvinfo->sinfo_timetolive = prinfo.pr_value; + if (prinfo.pr_policy != SCTP_PR_SCTP_NONE) { + sndrcvinfo->sinfo_timetolive = prinfo.pr_value; + } else { + sndrcvinfo->sinfo_timetolive = 0; + } sndrcvinfo->sinfo_flags |= prinfo.pr_policy; break; case SCTP_AUTHINFO: @@ -3563,7 +3718,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er static struct sctp_tcb * sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p, - in_port_t port, + uint16_t port, struct mbuf *control, struct sctp_nets **net_p, int *error) @@ -3664,7 +3819,6 @@ sctp_add_cookie(struct mbuf *init, int init_offset, int sig_offset; uint16_t cookie_sz; - mret = NULL; mret = sctp_get_mbuf_for_msg((sizeof(struct sctp_state_cookie) + sizeof(struct sctp_paramhdr)), 0, M_DONTWAIT, 1, MT_DATA); @@ -3857,8 +4011,11 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, struct sctphdr *sctphdr; int packet_length; int ret; + +#if defined(INET) || defined(INET6) uint32_t vrf_id; +#endif #if defined(INET) || defined(INET6) struct mbuf *o_pak; sctp_route_t *ro = NULL; @@ -3877,12 +4034,13 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, sctp_m_freem(m); return (EFAULT); } +#if defined(INET) || defined(INET6) if (stcb) { vrf_id = stcb->asoc.vrf_id; } else { vrf_id = inp->def_vrf_id; } - +#endif /* fill in the HMAC digest for any AUTH chunk in the packet */ if ((auth != NULL) && (stcb != NULL)) { sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb, auth_keyid); @@ -4098,7 +4256,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, SCTP_STAT_INCR(sctps_sendnocrc); #else m->m_pkthdr.csum_flags = CSUM_SCTP; - m->m_pkthdr.csum_data = 0; + m->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum); SCTP_STAT_INCR(sctps_sendhwcrc); #endif } @@ -4447,7 +4605,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, SCTP_STAT_INCR(sctps_sendnocrc); #else m->m_pkthdr.csum_flags = CSUM_SCTP_IPV6; - m->m_pkthdr.csum_data = 0; + m->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum); SCTP_STAT_INCR(sctps_sendhwcrc); #endif } @@ -4545,11 +4703,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked struct mbuf *m; struct sctp_nets *net; struct sctp_init_chunk *init; - -#if defined(INET) || defined(INET6) struct sctp_supported_addr_param *sup_addr; - -#endif struct sctp_adaptation_layer_indication *ali; struct sctp_supported_chunk_types_param *pr_supported; struct sctp_paramhdr *ph; @@ -5386,7 +5540,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, * though we even set the T bit and copy in the 0 tag.. this * looks no different than if no listener was present. */ - sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, NULL, + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + "Address added"); + sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, op_err, use_mflowid, mflowid, vrf_id, port); return; @@ -5397,6 +5553,13 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, &abort_flag, (struct sctp_chunkhdr *)init_chk, &nat_friendly); if (abort_flag) { do_a_abort: + if (op_err == NULL) { + char msg[SCTP_DIAG_INFO_LEN]; + + snprintf(msg, sizeof(msg), "%s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + msg); + } sctp_send_abort(init_pkt, iphlen, src, dst, sh, init_chk->init.initiate_tag, op_err, use_mflowid, mflowid, @@ -6073,17 +6236,15 @@ sctp_get_frag_point(struct sctp_tcb *stcb, static void sctp_set_prsctp_policy(struct sctp_stream_queue_pending *sp) { - sp->pr_sctp_on = 0; /* * We assume that the user wants PR_SCTP_TTL if the user provides a - * positive lifetime but does not specify any PR_SCTP policy. This - * is a BAD assumption and causes problems at least with the - * U-Vancovers MPI folks. I will change this to be no policy means - * NO PR-SCTP. + * positive lifetime but does not specify any PR_SCTP policy. */ if (PR_SCTP_ENABLED(sp->sinfo_flags)) { sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags); - sp->pr_sctp_on = 1; + } else if (sp->timetolive > 0) { + sp->sinfo_flags |= SCTP_PR_SCTP_TTL; + sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags); } else { return; } @@ -6420,7 +6581,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr, /* TSNH */ return; } - if ((ca->m) && ca->sndlen) { + if (ca->sndlen > 0) { m = SCTP_M_COPYM(ca->m, 0, M_COPYALL, M_DONTWAIT); if (m == NULL) { /* can't copy so we are done */ @@ -6449,38 +6610,40 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr, } if (ca->sndrcv.sinfo_flags & SCTP_ABORT) { /* Abort this assoc with m as the user defined reason */ - if (m) { + if (m != NULL) { + SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_NOWAIT); + } else { + m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), + 0, M_NOWAIT, 1, MT_DATA); + SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr); + } + if (m != NULL) { struct sctp_paramhdr *ph; - SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_DONTWAIT); - if (m) { - ph = mtod(m, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); - ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen); - } - /* - * We add one here to keep the assoc from - * dis-appearing on us. - */ - atomic_add_int(&stcb->asoc.refcnt, 1); - sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED); - /* - * sctp_abort_an_association calls sctp_free_asoc() - * free association will NOT free it since we - * incremented the refcnt .. we do this to prevent - * it being freed and things getting tricky since we - * could end up (from free_asoc) calling inpcb_free - * which would get a recursive lock call to the - * iterator lock.. But as a consequence of that the - * stcb will return to us un-locked.. since - * free_asoc returns with either no TCB or the TCB - * unlocked, we must relock.. to unlock in the - * iterator timer :-0 - */ - SCTP_TCB_LOCK(stcb); - atomic_add_int(&stcb->asoc.refcnt, -1); - goto no_chunk_output; + ph = mtod(m, struct sctp_paramhdr *); + ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); + ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen); } + /* + * We add one here to keep the assoc from dis-appearing on + * us. + */ + atomic_add_int(&stcb->asoc.refcnt, 1); + sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED); + /* + * sctp_abort_an_association calls sctp_free_asoc() free + * association will NOT free it since we incremented the + * refcnt .. we do this to prevent it being freed and things + * getting tricky since we could end up (from free_asoc) + * calling inpcb_free which would get a recursive lock call + * to the iterator lock.. But as a consequence of that the + * stcb will return to us un-locked.. since free_asoc + * returns with either no TCB or the TCB unlocked, we must + * relock.. to unlock in the iterator timer :-0 + */ + SCTP_TCB_LOCK(stcb); + atomic_add_int(&stcb->asoc.refcnt, -1); + goto no_chunk_output; } else { if (m) { ret = sctp_msg_append(stcb, net, m, @@ -6574,8 +6737,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr, if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) && (stcb->asoc.total_flight > 0) && - (un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD)) - ) { + (un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))) { do_chunk_output = 0; } if (do_chunk_output) @@ -6704,13 +6866,10 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m, /* Gather the length of the send */ struct mbuf *mat; - mat = m; ca->sndlen = 0; - while (m) { - ca->sndlen += SCTP_BUF_LEN(m); - m = SCTP_BUF_NEXT(m); + for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) { + ca->sndlen += SCTP_BUF_LEN(mat); } - ca->m = mat; } ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL, SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES, @@ -7356,7 +7515,8 @@ dont_do_it: chk->pad_inplace = 0; chk->no_fr_allowed = 0; chk->rec.data.stream_seq = strq->next_sequence_send; - if (rcv_flags & SCTP_DATA_LAST_FRAG) { + if ((rcv_flags & SCTP_DATA_LAST_FRAG) && + !(rcv_flags & SCTP_DATA_UNORDERED)) { strq->next_sequence_send++; } chk->rec.data.stream_number = sp->stream; @@ -7431,13 +7591,8 @@ dont_do_it: } chk->send_size += pads; } - /* We only re-set the policy if it is on */ - if (sp->pr_sctp_on) { - sctp_set_prsctp_policy(sp); + if (PR_SCTP_ENABLED(chk->flags)) { asoc->pr_sctp_cnt++; - chk->pr_sctp_on = 1; - } else { - chk->pr_sctp_on = 0; } if (sp->msg_is_complete && (sp->length == 0) && (sp->sender_all_done)) { /* All done pull and kill the message */ @@ -7627,7 +7782,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp, #endif ) { - /* + /** * Ok this is the generic chunk service queue. we must do the * following: - Service the stream queue that is next, moving any * message (note I must get a complete message i.e. FIRST/MIDDLE and @@ -8962,7 +9117,6 @@ sctp_send_cookie_ack(struct sctp_tcb *stcb) struct sctp_chunkhdr *hdr; struct sctp_tmit_chunk *chk; - cookie_ack = NULL; SCTP_TCB_LOCK_ASSERT(stcb); cookie_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 0, M_DONTWAIT, 1, MT_HEADER); @@ -10813,8 +10967,12 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, struct sctphdr *shout; struct sctp_chunkhdr *ch; struct udphdr *udp; - int len, cause_len, padding_len, ret; + int len, cause_len, padding_len; +#if defined(INET) || defined(INET6) + int ret; + +#endif #ifdef INET struct sockaddr_in *src_sin, *dst_sin; struct ip *ip; @@ -11007,7 +11165,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, SCTP_STAT_INCR(sctps_sendnocrc); #else mout->m_pkthdr.csum_flags = CSUM_SCTP; - mout->m_pkthdr.csum_data = 0; + mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum); SCTP_STAT_INCR(sctps_sendhwcrc); #endif } @@ -11037,7 +11195,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, SCTP_STAT_INCR(sctps_sendnocrc); #else mout->m_pkthdr.csum_flags = CSUM_SCTP_IPV6; - mout->m_pkthdr.csum_data = 0; + mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum); SCTP_STAT_INCR(sctps_sendhwcrc); #endif } diff --git a/freebsd/sys/netinet/sctp_pcb.c b/freebsd/sys/netinet/sctp_pcb.c index e21c2e03..16dc231f 100644 --- a/freebsd/sys/netinet/sctp_pcb.c +++ b/freebsd/sys/netinet/sctp_pcb.c @@ -774,7 +774,14 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr, } SCTPDBG(SCTP_DEBUG_PCB4, "Deleting ifa %p\n", (void *)sctp_ifap); sctp_ifap->localifa_flags &= SCTP_ADDR_VALID; - sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; + /* + * We don't set the flag. This means that the structure will + * hang around in EP's that have bound specific to it until + * they close. This gives us TCP like behavior if someone + * removes an address (or for that matter adds it right + * back). + */ + /* sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; */ vrf->total_ifa_count--; LIST_REMOVE(sctp_ifap, next_bucket); sctp_remove_ifa_from_ifn(sctp_ifap); @@ -829,18 +836,30 @@ out_now: static int sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) { - int loopback_scope, ipv4_local_scope, local_scope, site_scope; - int ipv4_addr_legal, ipv6_addr_legal; + int loopback_scope; + +#if defined(INET) + int ipv4_local_scope, ipv4_addr_legal; + +#endif +#if defined(INET6) + int local_scope, site_scope, ipv6_addr_legal; + +#endif struct sctp_vrf *vrf; struct sctp_ifn *sctp_ifn; struct sctp_ifa *sctp_ifa; loopback_scope = stcb->asoc.scope.loopback_scope; +#if defined(INET) ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; + ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; +#endif +#if defined(INET6) local_scope = stcb->asoc.scope.local_scope; site_scope = stcb->asoc.scope.site_scope; - ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; +#endif SCTP_IPI_ADDR_RLOCK(); vrf = sctp_find_vrf(stcb->asoc.vrf_id); @@ -865,6 +884,9 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) */ continue; } + if (sctp_ifa->address.sa.sa_family != to->sa_family) { + continue; + } switch (sctp_ifa->address.sa.sa_family) { #ifdef INET case AF_INET: @@ -878,6 +900,10 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { continue; } + if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) { SCTP_IPI_ADDR_RUNLOCK(); return (1); @@ -893,6 +919,10 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) sin6 = &sctp_ifa->address.sin6; rsin6 = (struct sockaddr_in6 *)to; + if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (local_scope == 0) continue; @@ -1040,6 +1070,39 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from, SCTP_INP_RUNLOCK(inp); continue; } + switch (to->sa_family) { +#ifdef INET + case AF_INET: + { + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *)to; + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + SCTP_INP_RUNLOCK(inp); + continue; + } + break; + } +#endif +#ifdef INET6 + case AF_INET6: + { + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)to; + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + SCTP_INP_RUNLOCK(inp); + continue; + } + break; + } +#endif + default: + SCTP_INP_RUNLOCK(inp); + continue; + } if (inp->def_vrf_id != vrf_id) { SCTP_INP_RUNLOCK(inp); continue; @@ -1608,23 +1671,45 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head, if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) && (inp->sctp_lport == lport)) { /* got it */ + switch (nam->sa_family) { #ifdef INET - if ((nam->sa_family == AF_INET) && - (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && - SCTP_IPV6_V6ONLY(inp)) { - /* IPv4 on a IPv6 socket with ONLY IPv6 set */ - SCTP_INP_RUNLOCK(inp); - continue; - } + case AF_INET: + if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && + SCTP_IPV6_V6ONLY(inp)) { + /* + * IPv4 on a IPv6 socket with ONLY + * IPv6 set + */ + SCTP_INP_RUNLOCK(inp); + continue; + } + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + SCTP_INP_RUNLOCK(inp); + continue; + } + break; #endif #ifdef INET6 - /* A V6 address and the endpoint is NOT bound V6 */ - if (nam->sa_family == AF_INET6 && - (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { - SCTP_INP_RUNLOCK(inp); - continue; - } + case AF_INET6: + /* + * A V6 address and the endpoint is NOT + * bound V6 + */ + if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { + SCTP_INP_RUNLOCK(inp); + continue; + } + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + SCTP_INP_RUNLOCK(inp); + continue; + } + break; #endif + default: + break; + } /* does a VRF id match? */ fnd = 0; if (inp->def_vrf_id == vrf_id) @@ -1973,8 +2058,13 @@ sctp_findassociation_special_addr(struct mbuf *m, int offset, struct sockaddr *dst) { struct sctp_paramhdr *phdr, parm_buf; + +#if defined(INET) || defined(INET6) struct sctp_tcb *stcb; - uint32_t ptype, plen; + uint16_t ptype; + +#endif + uint16_t plen; #ifdef INET struct sockaddr_in sin4; @@ -1998,13 +2088,14 @@ sctp_findassociation_special_addr(struct mbuf *m, int offset, sin6.sin6_port = sh->src_port; #endif - stcb = NULL; offset += sizeof(struct sctp_init_chunk); phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf)); while (phdr != NULL) { /* now we must see if we want the parameter */ +#if defined(INET) || defined(INET6) ptype = ntohs(phdr->param_type); +#endif plen = ntohs(phdr->param_length); if (plen == 0) { break; @@ -2377,6 +2468,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) /* setup socket pointers */ inp->sctp_socket = so; inp->ip_inp.inp.inp_socket = so; + inp->ip_inp.inp.inp_cred = crhold(so->so_cred); #ifdef INET6 if (INP_SOCKAF(so) == AF_INET6) { if (MODULE_GLOBAL(ip6_auto_flowlabel)) { @@ -2395,6 +2487,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) /* init the small hash table we use to track asocid <-> tcb */ inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, &inp->hashasocidmark); if (inp->sctp_asocidhash == NULL) { + crfree(inp->ip_inp.inp.inp_cred); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); SCTP_INP_INFO_WUNLOCK(); return (ENOBUFS); @@ -2409,6 +2502,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) ((struct in6pcb *)(&inp->ip_inp.inp))->in6p_sp = pcb_sp; } if (error != 0) { + crfree(inp->ip_inp.inp.inp_cred); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); SCTP_INP_INFO_WUNLOCK(); return error; @@ -2439,6 +2533,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) */ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EOPNOTSUPP); so->so_pcb = NULL; + crfree(inp->ip_inp.inp.inp_cred); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); return (EOPNOTSUPP); } @@ -2458,6 +2553,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) SCTP_PRINTF("Out of SCTP-INPCB->hashinit - no resources\n"); SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS); so->so_pcb = NULL; + crfree(inp->ip_inp.inp.inp_cred); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); return (ENOBUFS); } @@ -2709,7 +2805,6 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, uint32_t vrf_id; lport = 0; - error = 0; bindall = 1; inp = (struct sctp_inpcb *)so->so_pcb; ip_inp = (struct inpcb *)so->so_pcb; @@ -2830,13 +2925,6 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, return (error); } } - if (p == NULL) { - SCTP_INP_DECR_REF(inp); - SCTP_INP_WUNLOCK(inp); - SCTP_INP_INFO_WUNLOCK(); - SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error); - return (error); - } SCTP_INP_WUNLOCK(inp); if (bindall) { vrf_id = inp->def_vrf_id; @@ -3314,17 +3402,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) /* Left with Data unread */ struct mbuf *op_err; - op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), - 0, M_DONTWAIT, 1, MT_DATA); - if (op_err) { - /* Fill in the user initiated abort */ - struct sctp_paramhdr *ph; - - SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr); - ph = mtod(op_err, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); - ph->param_length = htons(SCTP_BUF_LEN(op_err)); - } + op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, ""); asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_3; sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED); SCTP_STAT_INCR_COUNTER32(sctps_aborted); @@ -3395,20 +3473,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) struct mbuf *op_err; abort_anyway: - op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), - 0, M_DONTWAIT, 1, MT_DATA); - if (op_err) { - /* - * Fill in the user - * initiated abort - */ - struct sctp_paramhdr *ph; - - SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr); - ph = mtod(op_err, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); - ph->param_length = htons(SCTP_BUF_LEN(op_err)); - } + op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, ""); asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_5; sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED); SCTP_STAT_INCR_COUNTER32(sctps_aborted); @@ -3472,17 +3537,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) ((asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) { struct mbuf *op_err; - op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), - 0, M_DONTWAIT, 1, MT_DATA); - if (op_err) { - /* Fill in the user initiated abort */ - struct sctp_paramhdr *ph; - - SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr); - ph = mtod(op_err, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); - ph->param_length = htons(SCTP_BUF_LEN(op_err)); - } + op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, ""); asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_7; sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED); SCTP_STAT_INCR_COUNTER32(sctps_aborted); @@ -3647,6 +3702,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) inp->sctp_tcbhash = NULL; } /* Now we must put the ep memory back into the zone pool */ + crfree(inp->ip_inp.inp.inp_cred); INP_LOCK_DESTROY(&inp->ip_inp.inp); SCTP_INP_LOCK_DESTROY(inp); SCTP_INP_READ_DESTROY(inp); @@ -3744,7 +3800,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, sin->sin_len = sizeof(struct sockaddr_in); if (set_scope) { #ifdef SCTP_DONT_DO_PRIVADDR_SCOPE - stcb->ipv4_local_scope = 1; + stcb->asoc.scope.ipv4_local_scope = 1; #else if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { stcb->asoc.scope.ipv4_local_scope = 1; @@ -4318,6 +4374,7 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr, asoc->nr_mapping_array = NULL; } SCTP_DECR_ASOC_COUNT(); + SCTP_TCB_UNLOCK(stcb); SCTP_TCB_LOCK_DESTROY(stcb); SCTP_TCB_SEND_LOCK_DESTROY(stcb); LIST_REMOVE(stcb, sctp_tcbasocidhash); @@ -5120,6 +5177,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre /* Insert new items here :> */ /* Get rid of LOCK */ + SCTP_TCB_UNLOCK(stcb); SCTP_TCB_LOCK_DESTROY(stcb); SCTP_TCB_SEND_LOCK_DESTROY(stcb); if (from_inpcbfree == SCTP_NORMAL_PROC) { @@ -5845,7 +5903,6 @@ sctp_pcb_init() for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) { LIST_INIT(&SCTP_BASE_INFO(vtag_timewait)[i]); } - sctp_startup_iterator(); #if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) @@ -5874,35 +5931,31 @@ sctp_pcb_finish(void) struct sctp_tagblock *twait_block, *prev_twait_block; struct sctp_laddr *wi, *nwi; int i; + struct sctp_iterator *it, *nit; /* - * Free BSD the it thread never exits but we do clean up. The only - * way freebsd reaches here if we have VRF's but we still add the - * ifdef to make it compile on old versions. + * In FreeBSD the iterator thread never exits but we do clean up. + * The only way FreeBSD reaches here is if we have VRF's but we + * still add the ifdef to make it compile on old versions. */ - { - struct sctp_iterator *it, *nit; - - SCTP_IPI_ITERATOR_WQ_LOCK(); - TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) { - if (it->vn != curvnet) { - continue; - } - TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr); - if (it->function_atend != NULL) { - (*it->function_atend) (it->pointer, it->val); - } - SCTP_FREE(it, SCTP_M_ITER); + SCTP_IPI_ITERATOR_WQ_LOCK(); + TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) { + if (it->vn != curvnet) { + continue; } - SCTP_IPI_ITERATOR_WQ_UNLOCK(); - SCTP_ITERATOR_LOCK(); - if ((sctp_it_ctl.cur_it) && - (sctp_it_ctl.cur_it->vn == curvnet)) { - sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT; + TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr); + if (it->function_atend != NULL) { + (*it->function_atend) (it->pointer, it->val); } - SCTP_ITERATOR_UNLOCK(); + SCTP_FREE(it, SCTP_M_ITER); } - + SCTP_IPI_ITERATOR_WQ_UNLOCK(); + SCTP_ITERATOR_LOCK(); + if ((sctp_it_ctl.cur_it) && + (sctp_it_ctl.cur_it->vn == curvnet)) { + sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT; + } + SCTP_ITERATOR_UNLOCK(); SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer)); SCTP_WQ_ADDR_LOCK(); LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) { diff --git a/freebsd/sys/netinet/sctp_pcb.h b/freebsd/sys/netinet/sctp_pcb.h index 91807c7c..8045765c 100644 --- a/freebsd/sys/netinet/sctp_pcb.h +++ b/freebsd/sys/netinet/sctp_pcb.h @@ -388,8 +388,8 @@ struct sctp_inpcb { /* back pointer to our socket */ struct socket *sctp_socket; + uint64_t sctp_features; /* Feature flags */ uint32_t sctp_flags; /* INP state flag set */ - uint32_t sctp_features; /* Feature flags */ uint32_t sctp_mobility_features; /* Mobility Feature flags */ struct sctp_pcb sctp_ep;/* SCTP ep data */ /* head of the hash of all associations */ diff --git a/freebsd/sys/netinet/sctp_structs.h b/freebsd/sys/netinet/sctp_structs.h index bc18f0e8..a8b86c62 100644 --- a/freebsd/sys/netinet/sctp_structs.h +++ b/freebsd/sys/netinet/sctp_structs.h @@ -446,7 +446,6 @@ struct sctp_tmit_chunk { uint8_t do_rtt; uint8_t book_size_scale; uint8_t no_fr_allowed; - uint8_t pr_sctp_on; uint8_t copy_by_ref; uint8_t window_probe; }; @@ -522,7 +521,6 @@ struct sctp_stream_queue_pending { uint8_t holds_key_ref; uint8_t msg_is_complete; uint8_t some_taken; - uint8_t pr_sctp_on; uint8_t sender_all_done; uint8_t put_last_out; uint8_t discard_rest; @@ -1205,7 +1203,7 @@ struct sctp_association { /* JRS 5/21/07 - CMT PF variable */ uint8_t sctp_cmt_pf; uint8_t use_precise_time; - uint32_t sctp_features; + uint64_t sctp_features; uint16_t port; /* remote UDP encapsulation port */ /* * The mapping array is used to track out of order sequences above diff --git a/freebsd/sys/netinet/sctp_sysctl.c b/freebsd/sys/netinet/sctp_sysctl.c index 95e3c589..ba7a00bf 100644 --- a/freebsd/sys/netinet/sctp_sysctl.c +++ b/freebsd/sys/netinet/sctp_sysctl.c @@ -118,7 +118,7 @@ sctp_init_sysctls() SCTP_BASE_SYSCTL(sctp_steady_step) = SCTPCTL_RTTVAR_STEADYS_DEFAULT; SCTP_BASE_SYSCTL(sctp_use_dccc_ecn) = SCTPCTL_RTTVAR_DCCCECN_DEFAULT; SCTP_BASE_SYSCTL(sctp_blackhole) = SCTPCTL_BLACKHOLE_DEFAULT; - + SCTP_BASE_SYSCTL(sctp_diag_info_code) = SCTPCTL_DIAG_INFO_CODE_DEFAULT; #if defined(SCTP_LOCAL_TRACE_BUF) memset(&SCTP_BASE_SYSCTL(sctp_log), 0, sizeof(struct sctp_log)); #endif @@ -254,6 +254,10 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s sin = (struct sockaddr_in *)&sctp_ifa->address.sa; if (sin->sin_addr.s_addr == 0) continue; + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } if ((ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) continue; } else { @@ -269,6 +273,10 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa; if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) continue; + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (local_scope == 0) continue; @@ -404,7 +412,7 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS) xinpcb.last = 0; xinpcb.local_port = ntohs(inp->sctp_lport); xinpcb.flags = inp->sctp_flags; - xinpcb.features = inp->sctp_features; + xinpcb.features = (uint32_t) inp->sctp_features; xinpcb.total_sends = inp->total_sends; xinpcb.total_recvs = inp->total_recvs; xinpcb.total_nospaces = inp->total_nospaces; @@ -661,6 +669,7 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS) RANGECHK(SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN, SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), SCTPCTL_NAT_FRIENDLY_INITS_MIN, SCTPCTL_NAT_FRIENDLY_INITS_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_blackhole), SCTPCTL_BLACKHOLE_MIN, SCTPCTL_BLACKHOLE_MAX); + RANGECHK(SCTP_BASE_SYSCTL(sctp_diag_info_code), SCTPCTL_DIAG_INFO_CODE_MIN, SCTPCTL_DIAG_INFO_CODE_MAX); #ifdef SCTP_DEBUG RANGECHK(SCTP_BASE_SYSCTL(sctp_debug_on), SCTPCTL_DEBUG_MIN, SCTPCTL_DEBUG_MAX); @@ -1119,6 +1128,10 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, blackhole, CTLTYPE_UINT | CTLFLAG_RW, &SCTP_BASE_SYSCTL(sctp_blackhole), 0, sysctl_sctp_check, "IU", SCTPCTL_BLACKHOLE_DESC); +SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, diag_info_code, CTLTYPE_UINT | CTLFLAG_RW, + &SCTP_BASE_SYSCTL(sctp_diag_info_code), 0, sysctl_sctp_check, "IU", + SCTPCTL_DIAG_INFO_CODE_DESC); + #ifdef SCTP_DEBUG SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, debug, CTLTYPE_UINT | CTLFLAG_RW, &SCTP_BASE_SYSCTL(sctp_debug_on), 0, sysctl_sctp_check, "IU", diff --git a/freebsd/sys/netinet/sctp_sysctl.h b/freebsd/sys/netinet/sctp_sysctl.h index 8090373e..432d36a4 100644 --- a/freebsd/sys/netinet/sctp_sysctl.h +++ b/freebsd/sys/netinet/sctp_sysctl.h @@ -104,6 +104,7 @@ struct sctp_sysctl { uint32_t sctp_rttvar_eqret; uint32_t sctp_steady_step; uint32_t sctp_use_dccc_ecn; + uint32_t sctp_diag_info_code; #if defined(SCTP_LOCAL_TRACE_BUF) struct sctp_log sctp_log; #endif @@ -465,7 +466,7 @@ struct sctp_sysctl { #define SCTPCTL_UDP_TUNNELING_PORT_DESC "Set the SCTP/UDP tunneling port" #define SCTPCTL_UDP_TUNNELING_PORT_MIN 0 #define SCTPCTL_UDP_TUNNELING_PORT_MAX 65535 -#define SCTPCTL_UDP_TUNNELING_PORT_DEFAULT SCTP_OVER_UDP_TUNNELING_PORT +#define SCTPCTL_UDP_TUNNELING_PORT_DEFAULT 0 /* Enable sending of the SACK-IMMEDIATELY bit */ #define SCTPCTL_SACK_IMMEDIATELY_ENABLE_DESC "Enable sending of the SACK-IMMEDIATELY-bit." @@ -529,6 +530,11 @@ struct sctp_sysctl { #define SCTPCTL_BLACKHOLE_MAX 2 #define SCTPCTL_BLACKHOLE_DEFAULT SCTPCTL_BLACKHOLE_MIN +#define SCTPCTL_DIAG_INFO_CODE_DESC "Diagnostic information error cause code" +#define SCTPCTL_DIAG_INFO_CODE_MIN 0 +#define SCTPCTL_DIAG_INFO_CODE_MAX 65535 +#define SCTPCTL_DIAG_INFO_CODE_DEFAULT 0 + #if defined(SCTP_DEBUG) /* debug: Configure debug output */ #define SCTPCTL_DEBUG_DESC "Configure debug output" diff --git a/freebsd/sys/netinet/sctp_timer.c b/freebsd/sys/netinet/sctp_timer.c index be601113..7d010c7b 100644 --- a/freebsd/sys/netinet/sctp_timer.c +++ b/freebsd/sys/netinet/sctp_timer.c @@ -149,24 +149,12 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb, */ if (stcb->asoc.overall_error_count > threshold) { /* Abort notification sends a ULP notify */ - struct mbuf *oper; - - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) + - sizeof(uint32_t); - ph = mtod(oper, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_1); - } + struct mbuf *op_err; + + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, + "Association error couter exceeded"); inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_1; - sctp_abort_an_association(inp, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED); return (1); } return (0); @@ -448,7 +436,7 @@ sctp_recover_sent_list(struct sctp_tcb *stcb) } } TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); - if (chk->pr_sctp_on) { + if (PR_SCTP_ENABLED(chk->flags)) { if (asoc->pr_sctp_cnt != 0) asoc->pr_sctp_cnt--; } @@ -554,7 +542,7 @@ start_again: TAILQ_FOREACH_SAFE(chk, &stcb->asoc.sent_queue, sctp_next, nchk) { if (SCTP_TSN_GE(stcb->asoc.last_acked_seq, chk->rec.data.TSN_seq)) { /* Strange case our list got out of order? */ - SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x", + SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x\n", (unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.TSN_seq); recovery_cnt++; #ifdef INVARIANTS @@ -1053,24 +1041,12 @@ sctp_cookie_timer(struct sctp_inpcb *inp, if (cookie == NULL) { if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) { /* FOOBAR! */ - struct mbuf *oper; - - oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)), - 0, M_DONTWAIT, 1, MT_DATA); - if (oper) { - struct sctp_paramhdr *ph; - uint32_t *ippp; - - SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) + - sizeof(uint32_t); - ph = mtod(oper, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION); - ph->param_length = htons(SCTP_BUF_LEN(oper)); - ippp = (uint32_t *) (ph + 1); - *ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); - } + struct mbuf *op_err; + + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, + "Cookie timer expired, but no cookie"); inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_4; - sctp_abort_an_association(inp, stcb, oper, SCTP_SO_NOT_LOCKED); + sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED); } else { #ifdef INVARIANTS panic("Cookie timer expires in wrong state?"); diff --git a/freebsd/sys/netinet/sctp_uio.h b/freebsd/sys/netinet/sctp_uio.h index 063fd9f1..df9c2d2d 100644 --- a/freebsd/sys/netinet/sctp_uio.h +++ b/freebsd/sys/netinet/sctp_uio.h @@ -662,10 +662,6 @@ struct sctp_hmacalgo { #define SCTP_AUTH_HMAC_ID_RSVD 0x0000 #define SCTP_AUTH_HMAC_ID_SHA1 0x0001 /* default, mandatory */ #define SCTP_AUTH_HMAC_ID_SHA256 0x0003 -#define SCTP_AUTH_HMAC_ID_SHA224 0x0004 -#define SCTP_AUTH_HMAC_ID_SHA384 0x0005 -#define SCTP_AUTH_HMAC_ID_SHA512 0x0006 - /* SCTP_AUTH_ACTIVE_KEY / SCTP_AUTH_DELETE_KEY */ struct sctp_authkeyid { diff --git a/freebsd/sys/netinet/sctp_usrreq.c b/freebsd/sys/netinet/sctp_usrreq.c index 81db1dc1..e2bbced4 100644 --- a/freebsd/sys/netinet/sctp_usrreq.c +++ b/freebsd/sys/netinet/sctp_usrreq.c @@ -856,20 +856,7 @@ sctp_disconnect(struct socket *so) struct mbuf *op_err; abort_anyway: - op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), - 0, M_DONTWAIT, 1, MT_DATA); - if (op_err) { - /* - * Fill in the user - * initiated abort - */ - struct sctp_paramhdr *ph; - - SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr); - ph = mtod(op_err, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); - ph->param_length = htons(SCTP_BUF_LEN(op_err)); - } + op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, ""); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4; sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED); SCTP_STAT_INCR_COUNTER32(sctps_aborted); @@ -1065,17 +1052,7 @@ sctp_shutdown(struct socket *so) struct mbuf *op_err; abort_anyway: - op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), - 0, M_DONTWAIT, 1, MT_DATA); - if (op_err) { - /* Fill in the user initiated abort */ - struct sctp_paramhdr *ph; - - SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr); - ph = mtod(op_err, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); - ph->param_length = htons(SCTP_BUF_LEN(op_err)); - } + op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, ""); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6; sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_LOCKED); @@ -1122,9 +1099,17 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, { struct sctp_ifn *sctp_ifn; struct sctp_ifa *sctp_ifa; - int loopback_scope, ipv4_local_scope, local_scope, site_scope; size_t actual; - int ipv4_addr_legal, ipv6_addr_legal; + int loopback_scope; + +#if defined(INET) + int ipv4_local_scope, ipv4_addr_legal; + +#endif +#if defined(INET6) + int local_scope, site_scope, ipv6_addr_legal; + +#endif struct sctp_vrf *vrf; actual = 0; @@ -1134,27 +1119,43 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, if (stcb) { /* Turn on all the appropriate scope */ loopback_scope = stcb->asoc.scope.loopback_scope; +#if defined(INET) ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; + ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; +#endif +#if defined(INET6) local_scope = stcb->asoc.scope.local_scope; site_scope = stcb->asoc.scope.site_scope; - ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; +#endif } else { /* Use generic values for endpoints. */ loopback_scope = 1; +#if defined(INET) ipv4_local_scope = 1; +#endif +#if defined(INET6) local_scope = 1; site_scope = 1; +#endif if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { +#if defined(INET6) ipv6_addr_legal = 1; +#endif +#if defined(INET) if (SCTP_IPV6_V6ONLY(inp)) { ipv4_addr_legal = 0; } else { ipv4_addr_legal = 1; } +#endif } else { +#if defined(INET6) ipv6_addr_legal = 0; +#endif +#if defined(INET) ipv4_addr_legal = 1; +#endif } } vrf = sctp_find_vrf(vrf_id); @@ -1198,6 +1199,10 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, */ continue; } + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } if ((ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { continue; @@ -1239,6 +1244,10 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, */ continue; } + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (local_scope == 0) continue; @@ -2766,7 +2775,7 @@ flags_out: if (stcb) { /* simply copy out the sockaddr_storage... */ - int len; + size_t len; len = *optsize; if (len > stcb->asoc.primary_destination->ro._l_addr.sa.sa_len) @@ -3283,7 +3292,7 @@ flags_out: } } if (error == 0) { - *optsize = sizeof(struct sctp_paddrparams); + *optsize = sizeof(struct sctp_udpencaps); } break; } @@ -3944,7 +3953,6 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, sctp_hmaclist_t *hmaclist; uint16_t hmacid; uint32_t i; - size_t found; SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, optsize); if (optsize < sizeof(struct sctp_hmacalgo) + shmac->shmac_number_of_idents * sizeof(uint16_t)) { @@ -3968,14 +3976,14 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, goto sctp_set_hmac_done; } } - found = 0; for (i = 0; i < hmaclist->num_algo; i++) { if (hmaclist->hmac[i] == SCTP_AUTH_HMAC_ID_SHA1) { /* already in list */ - found = 1; + break; } } - if (!found) { + if (i == hmaclist->num_algo) { + /* not found in list */ sctp_free_hmaclist(hmaclist); SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); error = EINVAL; @@ -4799,11 +4807,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10); } net->dest_state |= SCTP_ADDR_NO_PMTUD; - if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) { - net->mtu = paddrp->spp_pathmtu + ovh; - if (net->mtu < stcb->asoc.smallest_mtu) { - sctp_pathmtu_adjustment(stcb, net->mtu); - } + net->mtu = paddrp->spp_pathmtu + ovh; + if (net->mtu < stcb->asoc.smallest_mtu) { + sctp_pathmtu_adjustment(stcb, net->mtu); } } if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { @@ -4923,11 +4929,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10); } net->dest_state |= SCTP_ADDR_NO_PMTUD; - if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) { - net->mtu = paddrp->spp_pathmtu + ovh; - if (net->mtu < stcb->asoc.smallest_mtu) { - sctp_pathmtu_adjustment(stcb, net->mtu); - } + net->mtu = paddrp->spp_pathmtu + ovh; + if (net->mtu < stcb->asoc.smallest_mtu) { + sctp_pathmtu_adjustment(stcb, net->mtu); } } sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD); @@ -5245,6 +5249,43 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, error = EINVAL; goto out_of_it; } + } else { + switch (sspp->sspp_addr.ss_family) { +#ifdef INET + case AF_INET: + { + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *)&sspp->sspp_addr; + if (prison_check_ip4(inp->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + goto out_of_it; + } + break; + } +#endif +#ifdef INET6 + case AF_INET6: + { + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)&sspp->sspp_addr; + if (prison_check_ip6(inp->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + goto out_of_it; + } + break; + } +#endif + default: + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + goto out_of_it; + } } if (sctp_set_primary_ip_address_sa(stcb, (struct sockaddr *)&sspp->sspp_addr) != 0) { @@ -5603,7 +5644,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id); net = NULL; if (stcb) { - net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_assoc_id); + net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_address); } else { /* * We increment here since @@ -5614,7 +5655,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, */ SCTP_INP_INCR_REF(inp); stcb = sctp_findassociation_ep_addr(&inp, - (struct sockaddr *)&thlds->spt_assoc_id, + (struct sockaddr *)&thlds->spt_address, &net, NULL, NULL); if (stcb == NULL) { SCTP_INP_DECR_REF(inp); @@ -5623,7 +5664,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, if (stcb && (net == NULL)) { struct sockaddr *sa; - sa = (struct sockaddr *)&thlds->spt_assoc_id; + sa = (struct sockaddr *)&thlds->spt_address; #ifdef INET if (sa->sa_family == AF_INET) { @@ -6059,30 +6100,29 @@ sctp_listen(struct socket *so, int backlog, struct thread *p) if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) { /* See if we have a listener */ struct sctp_inpcb *tinp; - union sctp_sockstore store, *sp; + union sctp_sockstore store; - sp = &store; if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { /* not bound all */ struct sctp_laddr *laddr; LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { memcpy(&store, &laddr->ifa->address, sizeof(store)); - switch (sp->sa.sa_family) { + switch (store.sa.sa_family) { #ifdef INET case AF_INET: - sp->sin.sin_port = inp->sctp_lport; + store.sin.sin_port = inp->sctp_lport; break; #endif #ifdef INET6 case AF_INET6: - sp->sin6.sin6_port = inp->sctp_lport; + store.sin6.sin6_port = inp->sctp_lport; break; #endif default: break; } - tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id); + tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id); if (tinp && (tinp != inp) && ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && @@ -6100,20 +6140,6 @@ sctp_listen(struct socket *so, int backlog, struct thread *p) } else { /* Setup a local addr bound all */ memset(&store, 0, sizeof(store)); - switch (sp->sa.sa_family) { -#ifdef INET - case AF_INET: - store.sin.sin_port = inp->sctp_lport; - break; -#endif -#ifdef INET6 - case AF_INET6: - sp->sin6.sin6_port = inp->sctp_lport; - break; -#endif - default: - break; - } #ifdef INET6 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { store.sa.sa_family = AF_INET6; @@ -6126,7 +6152,21 @@ sctp_listen(struct socket *so, int backlog, struct thread *p) store.sa.sa_len = sizeof(struct sockaddr_in); } #endif - tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id); + switch (store.sa.sa_family) { +#ifdef INET + case AF_INET: + store.sin.sin_port = inp->sctp_lport; + break; +#endif +#ifdef INET6 + case AF_INET6: + store.sin6.sin6_port = inp->sctp_lport; + break; +#endif + default: + break; + } + tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id); if (tinp && (tinp != inp) && ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && diff --git a/freebsd/sys/netinet/sctputil.c b/freebsd/sys/netinet/sctputil.c index 15928d8b..6cd82739 100644 --- a/freebsd/sys/netinet/sctputil.c +++ b/freebsd/sys/netinet/sctputil.c @@ -2604,7 +2604,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb, if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT)) { notif_len = sizeof(struct sctp_assoc_change); if (abort != NULL) { - abort_len = htons(abort->ch.chunk_length); + abort_len = ntohs(abort->ch.chunk_length); } else { abort_len = 0; } @@ -2624,6 +2624,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb, } SCTP_BUF_NEXT(m_notify) = NULL; sac = mtod(m_notify, struct sctp_assoc_change *); + memset(sac, 0, notif_len); sac->sac_type = SCTP_ASSOC_CHANGE; sac->sac_flags = 0; sac->sac_length = sizeof(struct sctp_assoc_change); @@ -2837,21 +2838,21 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error, if (m_notify == NULL) /* no space left */ return; - length += chk->send_size; - length -= sizeof(struct sctp_data_chunk); SCTP_BUF_LEN(m_notify) = 0; if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { ssfe = mtod(m_notify, struct sctp_send_failed_event *); + memset(ssfe, 0, length); ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT; if (sent) { ssfe->ssfe_flags = SCTP_DATA_SENT; } else { ssfe->ssfe_flags = SCTP_DATA_UNSENT; } + length += chk->send_size; + length -= sizeof(struct sctp_data_chunk); ssfe->ssfe_length = length; ssfe->ssfe_error = error; /* not exactly what the user sent in, but should be close :) */ - bzero(&ssfe->ssfe_info, sizeof(ssfe->ssfe_info)); ssfe->ssfe_info.snd_sid = chk->rec.data.stream_number; ssfe->ssfe_info.snd_flags = chk->rec.data.rcv_flags; ssfe->ssfe_info.snd_ppid = chk->rec.data.payloadtype; @@ -2861,12 +2862,15 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error, SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event); } else { ssf = mtod(m_notify, struct sctp_send_failed *); + memset(ssf, 0, length); ssf->ssf_type = SCTP_SEND_FAILED; if (sent) { ssf->ssf_flags = SCTP_DATA_SENT; } else { ssf->ssf_flags = SCTP_DATA_UNSENT; } + length += chk->send_size; + length -= sizeof(struct sctp_data_chunk); ssf->ssf_length = length; ssf->ssf_error = error; /* not exactly what the user sent in, but should be close :) */ @@ -2950,16 +2954,16 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error, /* no space left */ return; } - length += sp->length; SCTP_BUF_LEN(m_notify) = 0; if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { ssfe = mtod(m_notify, struct sctp_send_failed_event *); + memset(ssfe, 0, length); ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT; ssfe->ssfe_flags = SCTP_DATA_UNSENT; + length += sp->length; ssfe->ssfe_length = length; ssfe->ssfe_error = error; /* not exactly what the user sent in, but should be close :) */ - bzero(&ssfe->ssfe_info, sizeof(ssfe->ssfe_info)); ssfe->ssfe_info.snd_sid = sp->stream; if (sp->some_taken) { ssfe->ssfe_info.snd_flags = SCTP_DATA_LAST_FRAG; @@ -2973,12 +2977,13 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error, SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event); } else { ssf = mtod(m_notify, struct sctp_send_failed *); + memset(ssf, 0, length); ssf->ssf_type = SCTP_SEND_FAILED; ssf->ssf_flags = SCTP_DATA_UNSENT; + length += sp->length; ssf->ssf_length = length; ssf->ssf_error = error; /* not exactly what the user sent in, but should be close :) */ - bzero(&ssf->ssf_info, sizeof(ssf->ssf_info)); ssf->ssf_info.sinfo_stream = sp->stream; ssf->ssf_info.sinfo_ssn = 0; if (sp->some_taken) { @@ -3040,6 +3045,7 @@ sctp_notify_adaptation_layer(struct sctp_tcb *stcb) return; SCTP_BUF_LEN(m_notify) = 0; sai = mtod(m_notify, struct sctp_adaptation_event *); + memset(sai, 0, sizeof(struct sctp_adaptation_event)); sai->sai_type = SCTP_ADAPTATION_INDICATION; sai->sai_flags = 0; sai->sai_length = sizeof(struct sctp_adaptation_event); @@ -3095,6 +3101,7 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error, return; SCTP_BUF_LEN(m_notify) = 0; pdapi = mtod(m_notify, struct sctp_pdapi_event *); + memset(pdapi, 0, sizeof(struct sctp_pdapi_event)); pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT; pdapi->pdapi_flags = 0; pdapi->pdapi_length = sizeof(struct sctp_pdapi_event); @@ -3204,6 +3211,7 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb) /* no space left */ return; sse = mtod(m_notify, struct sctp_shutdown_event *); + memset(sse, 0, sizeof(struct sctp_shutdown_event)); sse->sse_type = SCTP_SHUTDOWN_EVENT; sse->sse_flags = 0; sse->sse_length = sizeof(struct sctp_shutdown_event); @@ -3254,6 +3262,7 @@ sctp_notify_sender_dry_event(struct sctp_tcb *stcb, } SCTP_BUF_LEN(m_notify) = 0; event = mtod(m_notify, struct sctp_sender_dry_event *); + memset(event, 0, sizeof(struct sctp_sender_dry_event)); event->sender_dry_type = SCTP_SENDER_DRY_EVENT; event->sender_dry_flags = 0; event->sender_dry_length = sizeof(struct sctp_sender_dry_event); @@ -3286,7 +3295,6 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t struct mbuf *m_notify; struct sctp_queued_to_read *control; struct sctp_stream_change_event *stradd; - int len; if ((stcb == NULL) || (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_CHANGEEVNT))) { @@ -3299,25 +3307,20 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t return; } stcb->asoc.peer_req_out = 0; - m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA); + m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_stream_change_event), 0, M_DONTWAIT, 1, MT_DATA); if (m_notify == NULL) /* no space left */ return; SCTP_BUF_LEN(m_notify) = 0; - len = sizeof(struct sctp_stream_change_event); - if (len > M_TRAILINGSPACE(m_notify)) { - /* never enough room */ - sctp_m_freem(m_notify); - return; - } stradd = mtod(m_notify, struct sctp_stream_change_event *); + memset(stradd, 0, sizeof(struct sctp_stream_change_event)); stradd->strchange_type = SCTP_STREAM_CHANGE_EVENT; stradd->strchange_flags = flag; - stradd->strchange_length = len; + stradd->strchange_length = sizeof(struct sctp_stream_change_event); stradd->strchange_assoc_id = sctp_get_associd(stcb); stradd->strchange_instrms = numberin; stradd->strchange_outstrms = numberout; - SCTP_BUF_LEN(m_notify) = len; + SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_stream_change_event); SCTP_BUF_NEXT(m_notify) = NULL; if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { /* no space */ @@ -3348,32 +3351,26 @@ sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32 struct mbuf *m_notify; struct sctp_queued_to_read *control; struct sctp_assoc_reset_event *strasoc; - int len; if ((stcb == NULL) || (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ASSOC_RESETEVNT))) { /* event not enabled */ return; } - m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA); + m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_reset_event), 0, M_DONTWAIT, 1, MT_DATA); if (m_notify == NULL) /* no space left */ return; SCTP_BUF_LEN(m_notify) = 0; - len = sizeof(struct sctp_assoc_reset_event); - if (len > M_TRAILINGSPACE(m_notify)) { - /* never enough room */ - sctp_m_freem(m_notify); - return; - } strasoc = mtod(m_notify, struct sctp_assoc_reset_event *); + memset(strasoc, 0, sizeof(struct sctp_assoc_reset_event)); strasoc->assocreset_type = SCTP_ASSOC_RESET_EVENT; strasoc->assocreset_flags = flag; - strasoc->assocreset_length = len; + strasoc->assocreset_length = sizeof(struct sctp_assoc_reset_event); strasoc->assocreset_assoc_id = sctp_get_associd(stcb); strasoc->assocreset_local_tsn = sending_tsn; strasoc->assocreset_remote_tsn = recv_tsn; - SCTP_BUF_LEN(m_notify) = len; + SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_assoc_reset_event); SCTP_BUF_NEXT(m_notify) = NULL; if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { /* no space */ @@ -3426,6 +3423,7 @@ sctp_notify_stream_reset(struct sctp_tcb *stcb, return; } strreset = mtod(m_notify, struct sctp_stream_reset_event *); + memset(strreset, 0, len); strreset->strreset_type = SCTP_STREAM_RESET_EVENT; strreset->strreset_flags = flag; strreset->strreset_length = len; @@ -3476,7 +3474,7 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_erro return; } if (chunk != NULL) { - chunk_len = htons(chunk->ch.chunk_length); + chunk_len = ntohs(chunk->ch.chunk_length); } else { chunk_len = 0; } @@ -4020,6 +4018,7 @@ void sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, struct sctp_inpcb *inp, + struct mbuf *cause, uint8_t use_mflowid, uint32_t mflowid, uint32_t vrf_id, uint16_t port) { @@ -4048,9 +4047,6 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, case SCTP_INIT: contains_init_chunk = 1; break; - case SCTP_COOKIE_ECHO: - /* We hit here only if the assoc is being freed */ - return; case SCTP_PACKET_DROPPED: /* we don't respond to pkt-dropped */ return; @@ -4078,7 +4074,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) || ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) && (contains_init_chunk == 0))) { - sctp_send_abort(m, iphlen, src, dst, sh, 0, NULL, + sctp_send_abort(m, iphlen, src, dst, sh, 0, cause, use_mflowid, mflowid, vrf_id, port); } @@ -4633,19 +4629,43 @@ get_out: */ struct mbuf * -sctp_generate_invmanparam(int err) +sctp_generate_cause(uint16_t code, char *info) { - /* Return a MBUF with a invalid mandatory parameter */ struct mbuf *m; + struct sctp_gen_error_cause *cause; + size_t info_len, len; - m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), 0, M_DONTWAIT, 1, MT_DATA); - if (m) { - struct sctp_paramhdr *ph; + if ((code == 0) || (info == NULL)) { + return (NULL); + } + info_len = strlen(info); + len = sizeof(struct sctp_paramhdr) + info_len; + m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA); + if (m != NULL) { + SCTP_BUF_LEN(m) = len; + cause = mtod(m, struct sctp_gen_error_cause *); + cause->code = htons(code); + cause->length = htons((uint16_t) len); + memcpy(cause->info, info, info_len); + } + return (m); +} - SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr); - ph = mtod(m, struct sctp_paramhdr *); - ph->param_length = htons(sizeof(struct sctp_paramhdr)); - ph->param_type = htons(err); +struct mbuf * +sctp_generate_no_user_data_cause(uint32_t tsn) +{ + struct mbuf *m; + struct sctp_error_no_user_data *no_user_data_cause; + size_t len; + + len = sizeof(struct sctp_error_no_user_data); + m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA); + if (m != NULL) { + SCTP_BUF_LEN(m) = len; + no_user_data_cause = mtod(m, struct sctp_error_no_user_data *); + no_user_data_cause->cause.code = htons(SCTP_CAUSE_NO_USER_DATA); + no_user_data_cause->cause.length = htons((uint16_t) len); + no_user_data_cause->tsn = tsn; /* tsn is passed in as NBO */ } return (m); } @@ -4835,7 +4855,6 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1, atomic_add_int(&chk->whoTo->ref_count, 1); chk->rec.data.TSN_seq = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1); stcb->asoc.pr_sctp_cnt++; - chk->pr_sctp_on = 1; TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next); stcb->asoc.sent_queue_cnt++; stcb->asoc.pr_sctp_cnt++; @@ -5871,8 +5890,8 @@ get_more_data: goto release; } if ((uio->uio_resid == 0) || - ((in_eeor_mode) && (copied_so_far >= max(so->so_rcv.sb_lowat, 1))) - ) { + ((in_eeor_mode) && + (copied_so_far >= (uint32_t) max(so->so_rcv.sb_lowat, 1)))) { goto release; } /* @@ -6217,9 +6236,12 @@ sctp_soreceive(struct socket *so, fromlen = 0; } + if (filling_sinfo) { + memset(&sinfo, 0, sizeof(struct sctp_extrcvinfo)); + } error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, flagsp, (struct sctp_sndrcvinfo *)&sinfo, filling_sinfo); - if ((controlp) && (filling_sinfo)) { + if (controlp != NULL) { /* copy back the sinfo in a CMSG format */ if (filling_sinfo) *controlp = sctp_build_ctl_nchunk(inp, @@ -6615,8 +6637,16 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp, int sctp_local_addr_count(struct sctp_tcb *stcb) { - int loopback_scope, ipv4_local_scope, local_scope, site_scope; - int ipv4_addr_legal, ipv6_addr_legal; + int loopback_scope; + +#if defined(INET) + int ipv4_local_scope, ipv4_addr_legal; + +#endif +#if defined (INET6) + int local_scope, site_scope, ipv6_addr_legal; + +#endif struct sctp_vrf *vrf; struct sctp_ifn *sctp_ifn; struct sctp_ifa *sctp_ifa; @@ -6624,11 +6654,15 @@ sctp_local_addr_count(struct sctp_tcb *stcb) /* Turn on all the appropriate scopes */ loopback_scope = stcb->asoc.scope.loopback_scope; +#if defined(INET) ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; + ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; +#endif +#if defined(INET6) local_scope = stcb->asoc.scope.local_scope; site_scope = stcb->asoc.scope.site_scope; - ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; +#endif SCTP_IPI_ADDR_RLOCK(); vrf = sctp_find_vrf(stcb->asoc.vrf_id); if (vrf == NULL) { @@ -6662,6 +6696,10 @@ sctp_local_addr_count(struct sctp_tcb *stcb) */ continue; } + if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin->sin_addr) != 0) { + continue; + } if ((ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { continue; @@ -6682,6 +6720,10 @@ sctp_local_addr_count(struct sctp_tcb *stcb) if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { continue; } + if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, + &sin6->sin6_addr) != 0) { + continue; + } if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (local_scope == 0) continue; diff --git a/freebsd/sys/netinet/sctputil.h b/freebsd/sys/netinet/sctputil.h index 411bfafc..af5a0f29 100644 --- a/freebsd/sys/netinet/sctputil.h +++ b/freebsd/sys/netinet/sctputil.h @@ -205,6 +205,7 @@ void sctp_handle_ootb(struct mbuf *, int, int, struct sockaddr *, struct sockaddr *, struct sctphdr *, struct sctp_inpcb *, + struct mbuf *, uint8_t, uint32_t, uint32_t, uint16_t); @@ -252,7 +253,8 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *, struct sctp_tmit_chunk *, #endif ); -struct mbuf *sctp_generate_invmanparam(int); +struct mbuf *sctp_generate_cause(uint16_t, char *); +struct mbuf *sctp_generate_no_user_data_cause(uint32_t); void sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp, diff --git a/freebsd/sys/netinet/tcp_input.c b/freebsd/sys/netinet/tcp_input.c index 50dfc1ce..20d645f0 100644 --- a/freebsd/sys/netinet/tcp_input.c +++ b/freebsd/sys/netinet/tcp_input.c @@ -163,10 +163,10 @@ SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, rfc3390, CTLFLAG_RW, SYSCTL_NODE(_net_inet_tcp, OID_AUTO, experimental, CTLFLAG_RW, 0, "Experimental TCP extensions"); -VNET_DEFINE(int, tcp_do_initcwnd10) = 0; +VNET_DEFINE(int, tcp_do_initcwnd10) = 1; SYSCTL_VNET_INT(_net_inet_tcp_experimental, OID_AUTO, initcwnd10, CTLFLAG_RW, &VNET_NAME(tcp_do_initcwnd10), 0, - "Enable draft-ietf-tcpm-initcwnd-05 (Increasing initial CWND to 10)"); + "Enable RFC 6928 (Increasing initial CWND to 10)"); VNET_DEFINE(int, tcp_do_rfc3465) = 1; SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO, rfc3465, CTLFLAG_RW, @@ -356,7 +356,7 @@ cc_conn_init(struct tcpcb *tp) * * RFC5681 Section 3.1 specifies the default conservative values. * RFC3390 specifies slightly more aggressive values. - * Draft-ietf-tcpm-initcwnd-05 increases it to ten segments. + * RFC6928 increases it to ten segments. * * If a SYN or SYN/ACK was lost and retransmitted, we have to * reduce the initial CWND to one segment as congestion is likely diff --git a/freebsd/sys/netinet/tcp_reass.c b/freebsd/sys/netinet/tcp_reass.c index aebda9db..d4f0bcde 100644 --- a/freebsd/sys/netinet/tcp_reass.c +++ b/freebsd/sys/netinet/tcp_reass.c @@ -207,7 +207,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) * Investigate why and re-evaluate the below limit after the behaviour * is understood. */ - if (th->th_seq != tp->rcv_nxt && + if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) { V_tcp_reass_overflows++; TCPSTAT_INC(tcps_rcvmemdrop); @@ -230,7 +230,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) */ te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT); if (te == NULL) { - if (th->th_seq != tp->rcv_nxt) { + if (th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) { TCPSTAT_INC(tcps_rcvmemdrop); m_freem(m); *tlenp = 0; @@ -278,7 +278,8 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); - uma_zfree(V_tcp_reass_zone, te); + if (te != &tqs) + uma_zfree(V_tcp_reass_zone, te); tp->t_segqlen--; /* * Try to present any queued data diff --git a/freebsd/sys/netinet/tcp_subr.c b/freebsd/sys/netinet/tcp_subr.c index 4c6d14eb..d577f18f 100644 --- a/freebsd/sys/netinet/tcp_subr.c +++ b/freebsd/sys/netinet/tcp_subr.c @@ -1747,9 +1747,10 @@ tcp_maxmtu(struct in_conninfo *inc, struct tcp_ifcap *cap) /* Report additional interface capabilities. */ if (cap != NULL) { if (ifp->if_capenable & IFCAP_TSO4 && - ifp->if_hwassist & CSUM_TSO) + ifp->if_hwassist & CSUM_TSO) { cap->ifcap |= CSUM_TSO; cap->tsomax = ifp->if_hw_tsomax; + } } RTFREE(sro.ro_rt); } @@ -1785,9 +1786,10 @@ tcp_maxmtu6(struct in_conninfo *inc, struct tcp_ifcap *cap) /* Report additional interface capabilities. */ if (cap != NULL) { if (ifp->if_capenable & IFCAP_TSO6 && - ifp->if_hwassist & CSUM_TSO) + ifp->if_hwassist & CSUM_TSO) { cap->ifcap |= CSUM_TSO; cap->tsomax = ifp->if_hw_tsomax; + } } RTFREE(sro6.ro_rt); } diff --git a/freebsd/sys/netinet6/frag6.c b/freebsd/sys/netinet6/frag6.c index 8e6b0680..28b2b469 100644 --- a/freebsd/sys/netinet6/frag6.c +++ b/freebsd/sys/netinet6/frag6.c @@ -224,9 +224,8 @@ frag6_input(struct mbuf **mp, int *offp, int proto) offset += sizeof(struct ip6_frag); /* - * XXX-BZ RFC XXXX (draft-gont-6man-ipv6-atomic-fragments) - * Handle "atomic" fragments (offset and m bit set to 0) upfront, - * unrelated to any reassembly. Just skip the fragment header. + * RFC 6946: Handle "atomic" fragments (offset and m bit set to 0) + * upfront, unrelated to any reassembly. Just skip the fragment header. */ if ((ip6f->ip6f_offlg & ~IP6F_RESERVED_MASK) == 0) { /* XXX-BZ we want dedicated counters for this. */ diff --git a/freebsd/sys/netinet6/icmp6.c b/freebsd/sys/netinet6/icmp6.c index 32d50e94..20b03a21 100644 --- a/freebsd/sys/netinet6/icmp6.c +++ b/freebsd/sys/netinet6/icmp6.c @@ -1248,6 +1248,7 @@ icmp6_mtudisc_update(struct ip6ctlparam *ip6cp, int validated) mtu = IPV6_MMTU - 8; bzero(&inc, sizeof(inc)); + inc.inc_fibnum = M_GETFIB(m); inc.inc_flags |= INC_ISIPV6; inc.inc6_faddr = *dst; if (in6_setscope(&inc.inc6_faddr, m->m_pkthdr.rcvif, NULL)) diff --git a/freebsd/sys/netinet6/in6.c b/freebsd/sys/netinet6/in6.c index eac5e11e..f68f21f2 100644 --- a/freebsd/sys/netinet6/in6.c +++ b/freebsd/sys/netinet6/in6.c @@ -2605,6 +2605,7 @@ in6_lltable_lookup(struct lltable *llt, u_int flags, if (lle == NULL) { if (!(flags & LLE_CREATE)) return (NULL); + IF_AFDATA_WLOCK_ASSERT(ifp); /* * A route that covers the given address must have * been installed 1st because we are doing a resolution, diff --git a/freebsd/sys/netinet6/in6_mcast.c b/freebsd/sys/netinet6/in6_mcast.c index 55f2fab2..e5457707 100644 --- a/freebsd/sys/netinet6/in6_mcast.c +++ b/freebsd/sys/netinet6/in6_mcast.c @@ -133,7 +133,9 @@ static int in6_mc_get(struct ifnet *, const struct in6_addr *, static int in6m_get_source(struct in6_multi *inm, const struct in6_addr *addr, const int noalloc, struct ip6_msource **pims); +#ifdef KTR static int in6m_is_ifp_detached(const struct in6_multi *); +#endif static int in6m_merge(struct in6_multi *, /*const*/ struct in6_mfilter *); static void in6m_purge(struct in6_multi *); static void in6m_reap(struct in6_multi *); @@ -177,6 +179,7 @@ static SYSCTL_NODE(_net_inet6_ip6_mcast, OID_AUTO, filters, CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_ip6_mcast_filters, "Per-interface stack-wide source filters"); +#ifdef KTR /* * Inline function which wraps assertions for a valid ifp. * The ifnet layer will set the ifma's ifp pointer to NULL if the ifp @@ -199,6 +202,7 @@ in6m_is_ifp_detached(const struct in6_multi *inm) return (ifp == NULL); } +#endif /* * Initialize an in6_mfilter structure to a known state at t0, t1 @@ -1447,16 +1451,15 @@ in6p_block_unblock_source(struct inpcb *inp, struct sockopt *sopt) CTR1(KTR_MLD, "%s: merge inm state", __func__); error = in6m_merge(inm, imf); - if (error) { + if (error) CTR1(KTR_MLD, "%s: failed to merge inm state", __func__); - goto out_im6f_rollback; + else { + CTR1(KTR_MLD, "%s: doing mld downcall", __func__); + error = mld_change_state(inm, 0); + if (error) + CTR1(KTR_MLD, "%s: failed mld downcall", __func__); } - CTR1(KTR_MLD, "%s: doing mld downcall", __func__); - error = mld_change_state(inm, 0); - if (error) - CTR1(KTR_MLD, "%s: failed mld downcall", __func__); - IN6_MULTI_UNLOCK(); out_im6f_rollback: @@ -2044,29 +2047,27 @@ in6p_join_group(struct inpcb *inp, struct sockopt *sopt) if (is_new) { error = in6_mc_join_locked(ifp, &gsa->sin6.sin6_addr, imf, &inm, 0); - if (error) + if (error) { + IN6_MULTI_UNLOCK(); goto out_im6o_free; + } imo->im6o_membership[idx] = inm; } else { CTR1(KTR_MLD, "%s: merge inm state", __func__); error = in6m_merge(inm, imf); - if (error) { + if (error) CTR1(KTR_MLD, "%s: failed to merge inm state", __func__); - goto out_im6f_rollback; - } - CTR1(KTR_MLD, "%s: doing mld downcall", __func__); - error = mld_change_state(inm, 0); - if (error) { - CTR1(KTR_MLD, "%s: failed mld downcall", - __func__); - goto out_im6f_rollback; + else { + CTR1(KTR_MLD, "%s: doing mld downcall", __func__); + error = mld_change_state(inm, 0); + if (error) + CTR1(KTR_MLD, "%s: failed mld downcall", + __func__); } } IN6_MULTI_UNLOCK(); - -out_im6f_rollback: INP_WLOCK_ASSERT(inp); if (error) { im6f_rollback(imf); @@ -2293,23 +2294,20 @@ in6p_leave_group(struct inpcb *inp, struct sockopt *sopt) } else { CTR1(KTR_MLD, "%s: merge inm state", __func__); error = in6m_merge(inm, imf); - if (error) { + if (error) CTR1(KTR_MLD, "%s: failed to merge inm state", __func__); - goto out_im6f_rollback; - } - - CTR1(KTR_MLD, "%s: doing mld downcall", __func__); - error = mld_change_state(inm, 0); - if (error) { - CTR1(KTR_MLD, "%s: failed mld downcall", - __func__); + else { + CTR1(KTR_MLD, "%s: doing mld downcall", __func__); + error = mld_change_state(inm, 0); + if (error) + CTR1(KTR_MLD, "%s: failed mld downcall", + __func__); } } IN6_MULTI_UNLOCK(); -out_im6f_rollback: if (error) im6f_rollback(imf); else @@ -2518,16 +2516,15 @@ in6p_set_source_filters(struct inpcb *inp, struct sockopt *sopt) */ CTR1(KTR_MLD, "%s: merge inm state", __func__); error = in6m_merge(inm, imf); - if (error) { + if (error) CTR1(KTR_MLD, "%s: failed to merge inm state", __func__); - goto out_im6f_rollback; + else { + CTR1(KTR_MLD, "%s: doing mld downcall", __func__); + error = mld_change_state(inm, 0); + if (error) + CTR1(KTR_MLD, "%s: failed mld downcall", __func__); } - CTR1(KTR_MLD, "%s: doing mld downcall", __func__); - error = mld_change_state(inm, 0); - if (error) - CTR1(KTR_MLD, "%s: failed mld downcall", __func__); - IN6_MULTI_UNLOCK(); out_im6f_rollback: diff --git a/freebsd/sys/netinet6/in6_pcb.c b/freebsd/sys/netinet6/in6_pcb.c index 4d607f71..4b0b3389 100644 --- a/freebsd/sys/netinet6/in6_pcb.c +++ b/freebsd/sys/netinet6/in6_pcb.c @@ -164,7 +164,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, * and a multicast address is bound on both * new and duplicated sockets. */ - if (so->so_options & SO_REUSEADDR) + if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) != 0) reuseport = SO_REUSEADDR|SO_REUSEPORT; } else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { struct ifaddr *ifa; diff --git a/freebsd/sys/netinet6/ip6_forward.c b/freebsd/sys/netinet6/ip6_forward.c index 2b45804f..c45ab10b 100644 --- a/freebsd/sys/netinet6/ip6_forward.c +++ b/freebsd/sys/netinet6/ip6_forward.c @@ -565,10 +565,8 @@ skip_routing: odst = ip6->ip6_dst; /* Run through list of hooks for output packets. */ error = pfil_run_hooks(&V_inet6_pfil_hook, &m, rt->rt_ifp, PFIL_OUT, NULL); - if (error != 0) - goto senderr; - if (m == NULL) - goto freecopy; + if (error != 0 || m == NULL) + goto freecopy; /* consumed by filter */ ip6 = mtod(m, struct ip6_hdr *); /* See if destination IP address was changed by packet filter. */ @@ -637,7 +635,6 @@ pass: } } -senderr: if (mcopy == NULL) goto out; switch (error) { diff --git a/freebsd/sys/netinet6/ip6_input.c b/freebsd/sys/netinet6/ip6_input.c index aba38ecf..0de64eb7 100644 --- a/freebsd/sys/netinet6/ip6_input.c +++ b/freebsd/sys/netinet6/ip6_input.c @@ -560,7 +560,18 @@ ip6_input(struct mbuf *m) in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); goto bad; } - + if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) && + IPV6_ADDR_MC_SCOPE(&ip6->ip6_dst) == 0) { + /* + * RFC4291 2.7: + * Nodes must not originate a packet to a multicast address + * whose scop field contains the reserved value 0; if such + * a packet is received, it must be silently dropped. + */ + IP6STAT_INC(ip6s_badscope); + in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); + goto bad; + } #ifdef ALTQ if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) { /* packet is dropped by traffic conditioner */ @@ -1076,7 +1087,6 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, struct mbuf *m = *mp; int off = *offp, hbhlen; struct ip6_hbh *hbh; - u_int8_t *opt; /* validation of the length of the header */ #ifndef PULLDOWN_TEST @@ -1103,8 +1113,6 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, #endif off += hbhlen; hbhlen -= sizeof(struct ip6_hbh); - opt = (u_int8_t *)hbh + sizeof(struct ip6_hbh); - if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh), hbhlen, rtalertp, plenp) < 0) return (-1); diff --git a/freebsd/sys/netinet6/ip6_mroute.c b/freebsd/sys/netinet6/ip6_mroute.c index 00eab8ed..044b96b8 100644 --- a/freebsd/sys/netinet6/ip6_mroute.c +++ b/freebsd/sys/netinet6/ip6_mroute.c @@ -220,6 +220,14 @@ static VNET_DEFINE(u_int, mrt6debug) = 0; /* debug level */ #define DEBUG_XMIT 0x10 #define DEBUG_REG 0x20 #define DEBUG_PIM 0x40 +#define DEBUG_ERR 0x80 +#define DEBUG_ANY 0x7f +#define MRT6_DLOG(m, fmt, ...) \ + if (V_mrt6debug & (m)) \ + log(((m) & DEBUG_ERR) ? LOG_ERR: LOG_DEBUG, \ + "%s: " fmt "\n", __func__, ##__VA_ARGS__) +#else +#define MRT6_DLOG(m, fmt, ...) #endif static void expire_upcalls(void *); @@ -274,7 +282,6 @@ static VNET_DEFINE(int, pim6); #define MF6CFIND(o, g, rt) do { \ struct mf6c *_rt = mf6ctable[MF6CHASH(o,g)]; \ rt = NULL; \ - MRT6STAT_INC(mrt6s_mfc_lookups); \ while (_rt) { \ if (IN6_ARE_ADDR_EQUAL(&_rt->mf6c_origin.sin6_addr, &(o)) && \ IN6_ARE_ADDR_EQUAL(&_rt->mf6c_mcastgrp.sin6_addr, &(g)) && \ @@ -525,12 +532,8 @@ static int ip6_mrouter_init(struct socket *so, int v, int cmd) { -#ifdef MRT6DEBUG - if (V_mrt6debug) - log(LOG_DEBUG, - "ip6_mrouter_init: so_type = %d, pr_protocol = %d\n", - so->so_type, so->so_proto->pr_protocol); -#endif + MRT6_DLOG(DEBUG_ANY, "so_type = %d, pr_protocol = %d", + so->so_type, so->so_proto->pr_protocol); if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_ICMPV6) @@ -559,11 +562,7 @@ ip6_mrouter_init(struct socket *so, int v, int cmd) expire_upcalls, NULL); MROUTER6_UNLOCK(); - -#ifdef MRT6DEBUG - if (V_mrt6debug) - log(LOG_DEBUG, "ip6_mrouter_init\n"); -#endif + MRT6_DLOG(DEBUG_ANY, "finished"); return (0); } @@ -575,7 +574,7 @@ int X_ip6_mrouter_done(void) { mifi_t mifi; - int i; + u_long i; struct mf6c *rt; struct rtdetq *rte; @@ -641,11 +640,7 @@ X_ip6_mrouter_done(void) V_ip6_mrouter_ver = 0; MROUTER6_UNLOCK(); - -#ifdef MRT6DEBUG - if (V_mrt6debug) - log(LOG_DEBUG, "ip6_mrouter_done\n"); -#endif + MRT6_DLOG(DEBUG_ANY, "finished"); return (0); } @@ -726,14 +721,8 @@ add_m6if(struct mif6ctl *mifcp) nummifs = mifcp->mif6c_mifi + 1; MIF6_UNLOCK(); - -#ifdef MRT6DEBUG - if (V_mrt6debug) - log(LOG_DEBUG, - "add_mif #%d, phyint %s\n", - mifcp->mif6c_mifi, - ifp->if_xname); -#endif + MRT6_DLOG(DEBUG_ANY, "mif #%d, phyint %s", mifcp->mif6c_mifi, + if_name(ifp)); return (0); } @@ -776,11 +765,7 @@ del_m6if_locked(mifi_t *mifip) if (mif6table[mifi - 1].m6_ifp) break; nummifs = mifi; - -#ifdef MRT6DEBUG - if (V_mrt6debug) - log(LOG_DEBUG, "del_m6if %d, nummifs %d\n", *mifip, nummifs); -#endif + MRT6_DLOG(DEBUG_ANY, "mif %d, nummifs %d", *mifip, nummifs); return (0); } @@ -816,15 +801,10 @@ add_m6fc(struct mf6cctl *mfccp) /* If an entry already exists, just update the fields */ if (rt) { -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_MFC) { - log(LOG_DEBUG, - "add_m6fc no upcall h %d o %s g %s p %x\n", - ip6_sprintf(ip6bufo, &mfccp->mf6cc_origin.sin6_addr), - ip6_sprintf(ip6bufg, &mfccp->mf6cc_mcastgrp.sin6_addr), - mfccp->mf6cc_parent); - } -#endif + MRT6_DLOG(DEBUG_MFC, "no upcall o %s g %s p %x", + ip6_sprintf(ip6bufo, &mfccp->mf6cc_origin.sin6_addr), + ip6_sprintf(ip6bufg, &mfccp->mf6cc_mcastgrp.sin6_addr), + mfccp->mf6cc_parent); rt->mf6c_parent = mfccp->mf6cc_parent; rt->mf6c_ifset = mfccp->mf6cc_ifset; @@ -855,16 +835,12 @@ add_m6fc(struct mf6cctl *mfccp) &mfccp->mf6cc_mcastgrp.sin6_addr), mfccp->mf6cc_parent, rt->mf6c_stall); -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_MFC) - log(LOG_DEBUG, - "add_m6fc o %s g %s p %x dbg %x\n", - ip6_sprintf(ip6bufo, - &mfccp->mf6cc_origin.sin6_addr), - ip6_sprintf(ip6bufg, - &mfccp->mf6cc_mcastgrp.sin6_addr), - mfccp->mf6cc_parent, rt->mf6c_stall); -#endif + MRT6_DLOG(DEBUG_MFC, "o %s g %s p %x dbg %p", + ip6_sprintf(ip6bufo, + &mfccp->mf6cc_origin.sin6_addr), + ip6_sprintf(ip6bufg, + &mfccp->mf6cc_mcastgrp.sin6_addr), + mfccp->mf6cc_parent, rt->mf6c_stall); rt->mf6c_origin = mfccp->mf6cc_origin; rt->mf6c_mcastgrp = mfccp->mf6cc_mcastgrp; @@ -897,15 +873,10 @@ add_m6fc(struct mf6cctl *mfccp) * It is possible that an entry is being inserted without an upcall */ if (nstl == 0) { -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_MFC) - log(LOG_DEBUG, - "add_mfc no upcall h %d o %s g %s p %x\n", - hash, - ip6_sprintf(ip6bufo, &mfccp->mf6cc_origin.sin6_addr), - ip6_sprintf(ip6bufg, &mfccp->mf6cc_mcastgrp.sin6_addr), - mfccp->mf6cc_parent); -#endif + MRT6_DLOG(DEBUG_MFC, "no upcall h %lu o %s g %s p %x", hash, + ip6_sprintf(ip6bufo, &mfccp->mf6cc_origin.sin6_addr), + ip6_sprintf(ip6bufg, &mfccp->mf6cc_mcastgrp.sin6_addr), + mfccp->mf6cc_parent); for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) { @@ -991,6 +962,9 @@ collate(struct timeval *t) static int del_m6fc(struct mf6cctl *mfccp) { +#ifdef MRT6DEBUG + char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN]; +#endif struct sockaddr_in6 origin; struct sockaddr_in6 mcastgrp; struct mf6c *rt; @@ -1001,14 +975,9 @@ del_m6fc(struct mf6cctl *mfccp) mcastgrp = mfccp->mf6cc_mcastgrp; hash = MF6CHASH(origin.sin6_addr, mcastgrp.sin6_addr); -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_MFC) { - char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN]; - log(LOG_DEBUG,"del_m6fc orig %s mcastgrp %s\n", - ip6_sprintf(ip6bufo, &origin.sin6_addr), - ip6_sprintf(ip6bufg, &mcastgrp.sin6_addr)); - } -#endif + MRT6_DLOG(DEBUG_MFC, "orig %s mcastgrp %s", + ip6_sprintf(ip6bufo, &origin.sin6_addr), + ip6_sprintf(ip6bufg, &mcastgrp.sin6_addr)); MFC6_LOCK(); @@ -1073,19 +1042,23 @@ socket_send(struct socket *s, struct mbuf *mm, struct sockaddr_in6 *src) int X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m) { + struct rtdetq *rte; + struct mbuf *mb0; struct mf6c *rt; struct mif6 *mifp; struct mbuf *mm; + u_long hash; mifi_t mifi; char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; +#ifdef UPCALL_TIMING + struct timeval tp; -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_FORWARD) - log(LOG_DEBUG, "ip6_mforward: src %s, dst %s, ifindex %d\n", - ip6_sprintf(ip6bufs, &ip6->ip6_src), - ip6_sprintf(ip6bufd, &ip6->ip6_dst), - ifp->if_index); -#endif + GET_TIME(tp); +#endif /* UPCALL_TIMING */ + + MRT6_DLOG(DEBUG_FORWARD, "src %s, dst %s, ifindex %d", + ip6_sprintf(ip6bufs, &ip6->ip6_src), + ip6_sprintf(ip6bufd, &ip6->ip6_dst), ifp->if_index); /* * Don't forward a packet with Hop limit of zero or one, @@ -1124,211 +1097,184 @@ X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m) * Determine forwarding mifs from the forwarding cache table */ MF6CFIND(ip6->ip6_src, ip6->ip6_dst, rt); + MRT6STAT_INC(mrt6s_mfc_lookups); /* Entry exists, so forward if necessary */ if (rt) { MFC6_UNLOCK(); return (ip6_mdq(m, ifp, rt)); - } else { - /* - * If we don't have a route for packet's origin, - * Make a copy of the packet & - * send message to routing daemon - */ + } - struct mbuf *mb0; - struct rtdetq *rte; - u_long hash; -/* int i, npkts;*/ -#ifdef UPCALL_TIMING - struct timeval tp; + /* + * If we don't have a route for packet's origin, + * Make a copy of the packet & send message to routing daemon. + */ + MRT6STAT_INC(mrt6s_no_route); + MRT6_DLOG(DEBUG_FORWARD | DEBUG_MFC, "no rte s %s g %s", + ip6_sprintf(ip6bufs, &ip6->ip6_src), + ip6_sprintf(ip6bufd, &ip6->ip6_dst)); - GET_TIME(tp); -#endif /* UPCALL_TIMING */ + /* + * Allocate mbufs early so that we don't do extra work if we + * are just going to fail anyway. + */ + rte = (struct rtdetq *)malloc(sizeof(*rte), M_MRTABLE6, M_NOWAIT); + if (rte == NULL) { + MFC6_UNLOCK(); + return (ENOBUFS); + } + mb0 = m_copy(m, 0, M_COPYALL); + /* + * Pullup packet header if needed before storing it, + * as other references may modify it in the meantime. + */ + if (mb0 && (M_HASCL(mb0) || mb0->m_len < sizeof(struct ip6_hdr))) + mb0 = m_pullup(mb0, sizeof(struct ip6_hdr)); + if (mb0 == NULL) { + free(rte, M_MRTABLE6); + MFC6_UNLOCK(); + return (ENOBUFS); + } - MRT6STAT_INC(mrt6s_no_route); -#ifdef MRT6DEBUG - if (V_mrt6debug & (DEBUG_FORWARD | DEBUG_MFC)) - log(LOG_DEBUG, "ip6_mforward: no rte s %s g %s\n", - ip6_sprintf(ip6bufs, &ip6->ip6_src), - ip6_sprintf(ip6bufd, &ip6->ip6_dst)); -#endif + /* is there an upcall waiting for this packet? */ + hash = MF6CHASH(ip6->ip6_src, ip6->ip6_dst); + for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) { + if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, + &rt->mf6c_origin.sin6_addr) && + IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, + &rt->mf6c_mcastgrp.sin6_addr) && (rt->mf6c_stall != NULL)) + break; + } - /* - * Allocate mbufs early so that we don't do extra work if we - * are just going to fail anyway. - */ - rte = (struct rtdetq *)malloc(sizeof(*rte), M_MRTABLE6, - M_NOWAIT); - if (rte == NULL) { + if (rt == NULL) { + struct mrt6msg *im; +#ifdef MRT6_OINIT + struct omrt6msg *oim; +#endif + /* no upcall, so make a new entry */ + rt = (struct mf6c *)malloc(sizeof(*rt), M_MRTABLE6, M_NOWAIT); + if (rt == NULL) { + free(rte, M_MRTABLE6); + m_freem(mb0); MFC6_UNLOCK(); return (ENOBUFS); } - mb0 = m_copy(m, 0, M_COPYALL); /* - * Pullup packet header if needed before storing it, - * as other references may modify it in the meantime. + * Make a copy of the header to send to the user + * level process */ - if (mb0 && - (M_HASCL(mb0) || mb0->m_len < sizeof(struct ip6_hdr))) - mb0 = m_pullup(mb0, sizeof(struct ip6_hdr)); - if (mb0 == NULL) { + mm = m_copy(mb0, 0, sizeof(struct ip6_hdr)); + if (mm == NULL) { free(rte, M_MRTABLE6); + m_freem(mb0); + free(rt, M_MRTABLE6); MFC6_UNLOCK(); return (ENOBUFS); } - /* is there an upcall waiting for this packet? */ - hash = MF6CHASH(ip6->ip6_src, ip6->ip6_dst); - for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) { - if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, - &rt->mf6c_origin.sin6_addr) && - IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, - &rt->mf6c_mcastgrp.sin6_addr) && - (rt->mf6c_stall != NULL)) - break; - } - - if (rt == NULL) { - struct mrt6msg *im; -#ifdef MRT6_OINIT - struct omrt6msg *oim; -#endif - - /* no upcall, so make a new entry */ - rt = (struct mf6c *)malloc(sizeof(*rt), M_MRTABLE6, - M_NOWAIT); - if (rt == NULL) { - free(rte, M_MRTABLE6); - m_freem(mb0); - MFC6_UNLOCK(); - return (ENOBUFS); - } - /* - * Make a copy of the header to send to the user - * level process - */ - mm = m_copy(mb0, 0, sizeof(struct ip6_hdr)); - - if (mm == NULL) { - free(rte, M_MRTABLE6); - m_freem(mb0); - free(rt, M_MRTABLE6); - MFC6_UNLOCK(); - return (ENOBUFS); - } - - /* - * Send message to routing daemon - */ - sin6.sin6_addr = ip6->ip6_src; - - im = NULL; + /* + * Send message to routing daemon + */ + sin6.sin6_addr = ip6->ip6_src; + im = NULL; #ifdef MRT6_OINIT - oim = NULL; + oim = NULL; #endif - switch (V_ip6_mrouter_ver) { + switch (V_ip6_mrouter_ver) { #ifdef MRT6_OINIT - case MRT6_OINIT: - oim = mtod(mm, struct omrt6msg *); - oim->im6_msgtype = MRT6MSG_NOCACHE; - oim->im6_mbz = 0; - break; -#endif - case MRT6_INIT: - im = mtod(mm, struct mrt6msg *); - im->im6_msgtype = MRT6MSG_NOCACHE; - im->im6_mbz = 0; - break; - default: - free(rte, M_MRTABLE6); - m_freem(mb0); - free(rt, M_MRTABLE6); - MFC6_UNLOCK(); - return (EINVAL); - } - -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_FORWARD) - log(LOG_DEBUG, - "getting the iif info in the kernel\n"); + case MRT6_OINIT: + oim = mtod(mm, struct omrt6msg *); + oim->im6_msgtype = MRT6MSG_NOCACHE; + oim->im6_mbz = 0; + break; #endif + case MRT6_INIT: + im = mtod(mm, struct mrt6msg *); + im->im6_msgtype = MRT6MSG_NOCACHE; + im->im6_mbz = 0; + break; + default: + free(rte, M_MRTABLE6); + m_freem(mb0); + free(rt, M_MRTABLE6); + MFC6_UNLOCK(); + return (EINVAL); + } - for (mifp = mif6table, mifi = 0; - mifi < nummifs && mifp->m6_ifp != ifp; - mifp++, mifi++) + MRT6_DLOG(DEBUG_FORWARD, "getting the iif info in the kernel"); + for (mifp = mif6table, mifi = 0; + mifi < nummifs && mifp->m6_ifp != ifp; mifp++, mifi++) ; - switch (V_ip6_mrouter_ver) { + switch (V_ip6_mrouter_ver) { #ifdef MRT6_OINIT - case MRT6_OINIT: - oim->im6_mif = mifi; - break; + case MRT6_OINIT: + oim->im6_mif = mifi; + break; #endif - case MRT6_INIT: - im->im6_mif = mifi; - break; - } + case MRT6_INIT: + im->im6_mif = mifi; + break; + } + + if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) { + log(LOG_WARNING, "ip6_mforward: ip6_mrouter " + "socket queue full\n"); + MRT6STAT_INC(mrt6s_upq_sockfull); + free(rte, M_MRTABLE6); + m_freem(mb0); + free(rt, M_MRTABLE6); + MFC6_UNLOCK(); + return (ENOBUFS); + } + + MRT6STAT_INC(mrt6s_upcalls); + + /* insert new entry at head of hash chain */ + bzero(rt, sizeof(*rt)); + rt->mf6c_origin.sin6_family = AF_INET6; + rt->mf6c_origin.sin6_len = sizeof(struct sockaddr_in6); + rt->mf6c_origin.sin6_addr = ip6->ip6_src; + rt->mf6c_mcastgrp.sin6_family = AF_INET6; + rt->mf6c_mcastgrp.sin6_len = sizeof(struct sockaddr_in6); + rt->mf6c_mcastgrp.sin6_addr = ip6->ip6_dst; + rt->mf6c_expire = UPCALL_EXPIRE; + n6expire[hash]++; + rt->mf6c_parent = MF6C_INCOMPLETE_PARENT; + + /* link into table */ + rt->mf6c_next = mf6ctable[hash]; + mf6ctable[hash] = rt; + /* Add this entry to the end of the queue */ + rt->mf6c_stall = rte; + } else { + /* determine if q has overflowed */ + struct rtdetq **p; + int npkts = 0; - if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) { - log(LOG_WARNING, "ip6_mforward: ip6_mrouter " - "socket queue full\n"); - MRT6STAT_INC(mrt6s_upq_sockfull); + for (p = &rt->mf6c_stall; *p != NULL; p = &(*p)->next) + if (++npkts > MAX_UPQ6) { + MRT6STAT_INC(mrt6s_upq_ovflw); free(rte, M_MRTABLE6); m_freem(mb0); - free(rt, M_MRTABLE6); MFC6_UNLOCK(); - return (ENOBUFS); + return (0); } - MRT6STAT_INC(mrt6s_upcalls); - - /* insert new entry at head of hash chain */ - bzero(rt, sizeof(*rt)); - rt->mf6c_origin.sin6_family = AF_INET6; - rt->mf6c_origin.sin6_len = sizeof(struct sockaddr_in6); - rt->mf6c_origin.sin6_addr = ip6->ip6_src; - rt->mf6c_mcastgrp.sin6_family = AF_INET6; - rt->mf6c_mcastgrp.sin6_len = sizeof(struct sockaddr_in6); - rt->mf6c_mcastgrp.sin6_addr = ip6->ip6_dst; - rt->mf6c_expire = UPCALL_EXPIRE; - n6expire[hash]++; - rt->mf6c_parent = MF6C_INCOMPLETE_PARENT; - - /* link into table */ - rt->mf6c_next = mf6ctable[hash]; - mf6ctable[hash] = rt; - /* Add this entry to the end of the queue */ - rt->mf6c_stall = rte; - } else { - /* determine if q has overflowed */ - struct rtdetq **p; - int npkts = 0; - - for (p = &rt->mf6c_stall; *p != NULL; p = &(*p)->next) - if (++npkts > MAX_UPQ6) { - MRT6STAT_INC(mrt6s_upq_ovflw); - free(rte, M_MRTABLE6); - m_freem(mb0); - MFC6_UNLOCK(); - return (0); - } - - /* Add this entry to the end of the queue */ - *p = rte; - } + /* Add this entry to the end of the queue */ + *p = rte; + } - rte->next = NULL; - rte->m = mb0; - rte->ifp = ifp; + rte->next = NULL; + rte->m = mb0; + rte->ifp = ifp; #ifdef UPCALL_TIMING - rte->t = tp; + rte->t = tp; #endif /* UPCALL_TIMING */ - MFC6_UNLOCK(); + MFC6_UNLOCK(); - return (0); - } + return (0); } /* @@ -1338,9 +1284,12 @@ X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m) static void expire_upcalls(void *unused) { +#ifdef MRT6DEBUG + char ip6bufo[INET6_ADDRSTRLEN], ip6bufg[INET6_ADDRSTRLEN]; +#endif struct rtdetq *rte; struct mf6c *mfc, **nptr; - int i; + u_long i; MFC6_LOCK(); for (i = 0; i < MF6CTBLSIZ; i++) { @@ -1357,15 +1306,9 @@ expire_upcalls(void *unused) if (rte != NULL && mfc->mf6c_expire != 0 && --mfc->mf6c_expire == 0) { -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_EXPIRE) { - char ip6bufo[INET6_ADDRSTRLEN]; - char ip6bufg[INET6_ADDRSTRLEN]; - log(LOG_DEBUG, "expire_upcalls: expiring (%s %s)\n", - ip6_sprintf(ip6bufo, &mfc->mf6c_origin.sin6_addr), - ip6_sprintf(ip6bufg, &mfc->mf6c_mcastgrp.sin6_addr)); - } -#endif + MRT6_DLOG(DEBUG_EXPIRE, "expiring (%s %s)", + ip6_sprintf(ip6bufo, &mfc->mf6c_origin.sin6_addr), + ip6_sprintf(ip6bufg, &mfc->mf6c_mcastgrp.sin6_addr)); /* * drop all the packets * free the mbuf with the pkt, if, timing info @@ -1425,13 +1368,9 @@ ip6_mdq(struct mbuf *m, struct ifnet *ifp, struct mf6c *rt) mifi = rt->mf6c_parent; if ((mifi >= nummifs) || (mif6table[mifi].m6_ifp != ifp)) { /* came in the wrong interface */ -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_FORWARD) - log(LOG_DEBUG, - "wrong if: ifid %d mifi %d mififid %x\n", - ifp->if_index, mifi, - mif6table[mifi].m6_ifp->if_index); -#endif + MRT6_DLOG(DEBUG_FORWARD, + "wrong if: ifid %d mifi %d mififid %x", ifp->if_index, + mifi, mif6table[mifi].m6_ifp->if_index); MRT6STAT_INC(mrt6s_wrong_if); rt->mf6c_wrong_if++; /* @@ -1508,10 +1447,8 @@ ip6_mdq(struct mbuf *m, struct ifnet *ifp, struct mf6c *rt) MRT6STAT_INC(mrt6s_upcalls); if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) { -#ifdef MRT6DEBUG - if (V_mrt6debug) - log(LOG_WARNING, "mdq, ip6_mrouter socket queue full\n"); -#endif + MRT6_DLOG(DEBUG_ANY, + "ip6_mrouter socket queue full"); MRT6STAT_INC(mrt6s_upq_sockfull); return (ENOBUFS); } /* if socket Q full */ @@ -1575,6 +1512,9 @@ ip6_mdq(struct mbuf *m, struct ifnet *ifp, struct mf6c *rt) static void phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m) { +#ifdef MRT6DEBUG + char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; +#endif struct mbuf *mb_copy; struct ifnet *ifp = mifp->m6_ifp; int error = 0; @@ -1612,11 +1552,8 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m) error = ip6_output(mb_copy, NULL, NULL, IPV6_FORWARDING, &im6o, NULL, NULL); -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_XMIT) - log(LOG_DEBUG, "phyint_send on mif %d err %d\n", - mifp - mif6table, error); -#endif + MRT6_DLOG(DEBUG_XMIT, "mif %u err %d", + (uint16_t)(mifp - mif6table), error); return; } @@ -1652,11 +1589,8 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m) */ error = (*ifp->if_output)(ifp, mb_copy, (struct sockaddr *)&dst6, NULL); -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_XMIT) - log(LOG_DEBUG, "phyint_send on mif %d err %d\n", - mifp - mif6table, error); -#endif + MRT6_DLOG(DEBUG_XMIT, "mif %u err %d", + (uint16_t)(mifp - mif6table), error); } else { /* * pMTU discovery is intentionally disabled by default, since @@ -1666,19 +1600,11 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m) if (V_ip6_mcast_pmtu) icmp6_error(mb_copy, ICMP6_PACKET_TOO_BIG, 0, linkmtu); else { -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_XMIT) { - char ip6bufs[INET6_ADDRSTRLEN]; - char ip6bufd[INET6_ADDRSTRLEN]; - log(LOG_DEBUG, - "phyint_send: packet too big on %s o %s " - "g %s size %d(discarded)\n", - if_name(ifp), - ip6_sprintf(ip6bufs, &ip6->ip6_src), - ip6_sprintf(ip6bufd, &ip6->ip6_dst), - mb_copy->m_pkthdr.len); - } -#endif /* MRT6DEBUG */ + MRT6_DLOG(DEBUG_XMIT, " packet too big on %s o %s " + "g %s size %d (discarded)", if_name(ifp), + ip6_sprintf(ip6bufs, &ip6->ip6_src), + ip6_sprintf(ip6bufd, &ip6->ip6_dst), + mb_copy->m_pkthdr.len); m_freem(mb_copy); /* simply discard the packet */ } } @@ -1687,19 +1613,17 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m) static int register_send(struct ip6_hdr *ip6, struct mif6 *mif, struct mbuf *m) { +#ifdef MRT6DEBUG + char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; +#endif struct mbuf *mm; int i, len = m->m_pkthdr.len; static struct sockaddr_in6 sin6 = { sizeof(sin6), AF_INET6 }; struct mrt6msg *im6; -#ifdef MRT6DEBUG - if (V_mrt6debug) { - char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; - log(LOG_DEBUG, "** IPv6 register_send **\n src %s dst %s\n", - ip6_sprintf(ip6bufs, &ip6->ip6_src), - ip6_sprintf(ip6bufd, &ip6->ip6_dst)); - } -#endif + MRT6_DLOG(DEBUG_ANY, "src %s dst %s", + ip6_sprintf(ip6bufs, &ip6->ip6_src), + ip6_sprintf(ip6bufd, &ip6->ip6_dst)); PIM6STAT_INC(pim6s_snd_registers); /* Make a copy of the packet to send to the user level process */ @@ -1738,11 +1662,7 @@ register_send(struct ip6_hdr *ip6, struct mif6 *mif, struct mbuf *m) MRT6STAT_INC(mrt6s_upcalls); if (socket_send(V_ip6_mrouter, mm, &sin6) < 0) { -#ifdef MRT6DEBUG - if (V_mrt6debug) - log(LOG_WARNING, - "register_send: ip6_mrouter socket queue full\n"); -#endif + MRT6_DLOG(DEBUG_ANY, "ip6_mrouter socket queue full"); MRT6STAT_INC(mrt6s_upq_sockfull); return (ENOBUFS); } @@ -1794,10 +1714,7 @@ pim6_input(struct mbuf **mp, int *offp, int proto) */ if (pimlen < PIM_MINLEN) { PIM6STAT_INC(pim6s_rcv_tooshort); -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_PIM) - log(LOG_DEBUG,"pim6_input: PIM packet too short\n"); -#endif + MRT6_DLOG(DEBUG_PIM, "PIM packet too short"); m_freem(m); return (IPPROTO_DONE); } @@ -1847,11 +1764,7 @@ pim6_input(struct mbuf **mp, int *offp, int proto) if (in6_cksum(m, IPPROTO_PIM, off, cksumlen)) { PIM6STAT_INC(pim6s_rcv_badsum); -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_PIM) - log(LOG_DEBUG, - "pim6_input: invalid checksum\n"); -#endif + MRT6_DLOG(DEBUG_PIM, "invalid checksum"); m_freem(m); return (IPPROTO_DONE); } @@ -1861,11 +1774,9 @@ pim6_input(struct mbuf **mp, int *offp, int proto) /* PIM version check */ if (pim->pim_ver != PIM_VERSION) { PIM6STAT_INC(pim6s_rcv_badversion); -#ifdef MRT6DEBUG - log(LOG_ERR, - "pim6_input: incorrect version %d, expecting %d\n", + MRT6_DLOG(DEBUG_ANY | DEBUG_ERR, + "incorrect version %d, expecting %d", pim->pim_ver, PIM_VERSION); -#endif m_freem(m); return (IPPROTO_DONE); } @@ -1889,12 +1800,8 @@ pim6_input(struct mbuf **mp, int *offp, int proto) PIM6STAT_INC(pim6s_rcv_registers); if ((reg_mif_num >= nummifs) || (reg_mif_num == (mifi_t) -1)) { -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_PIM) - log(LOG_DEBUG, - "pim6_input: register mif not set: %d\n", - reg_mif_num); -#endif + MRT6_DLOG(DEBUG_PIM, "register mif not set: %d", + reg_mif_num); m_freem(m); return (IPPROTO_DONE); } @@ -1910,35 +1817,25 @@ pim6_input(struct mbuf **mp, int *offp, int proto) if (pimlen < PIM6_REG_MINLEN) { PIM6STAT_INC(pim6s_rcv_tooshort); PIM6STAT_INC(pim6s_rcv_badregisters); -#ifdef MRT6DEBUG - log(LOG_ERR, - "pim6_input: register packet size too " - "small %d from %s\n", + MRT6_DLOG(DEBUG_ANY | DEBUG_ERR, "register packet " + "size too small %d from %s", pimlen, ip6_sprintf(ip6bufs, &ip6->ip6_src)); -#endif m_freem(m); return (IPPROTO_DONE); } eip6 = (struct ip6_hdr *) (reghdr + 1); -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_PIM) - log(LOG_DEBUG, - "pim6_input[register], eip6: %s -> %s, " - "eip6 plen %d\n", - ip6_sprintf(ip6bufs, &eip6->ip6_src), - ip6_sprintf(ip6bufd, &eip6->ip6_dst), - ntohs(eip6->ip6_plen)); -#endif + MRT6_DLOG(DEBUG_PIM, "eip6: %s -> %s, eip6 plen %d", + ip6_sprintf(ip6bufs, &eip6->ip6_src), + ip6_sprintf(ip6bufd, &eip6->ip6_dst), + ntohs(eip6->ip6_plen)); /* verify the version number of the inner packet */ if ((eip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { PIM6STAT_INC(pim6s_rcv_badregisters); -#ifdef MRT6DEBUG - log(LOG_DEBUG, "pim6_input: invalid IP version (%d) " - "of the inner packet\n", + MRT6_DLOG(DEBUG_ANY, "invalid IP version (%d) " + "of the inner packet", (eip6->ip6_vfc & IPV6_VERSION)); -#endif m_freem(m); return (IPPROTO_NONE); } @@ -1946,13 +1843,9 @@ pim6_input(struct mbuf **mp, int *offp, int proto) /* verify the inner packet is destined to a mcast group */ if (!IN6_IS_ADDR_MULTICAST(&eip6->ip6_dst)) { PIM6STAT_INC(pim6s_rcv_badregisters); -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_PIM) - log(LOG_DEBUG, - "pim6_input: inner packet of register " - "is not multicast %s\n", - ip6_sprintf(ip6bufd, &eip6->ip6_dst)); -#endif + MRT6_DLOG(DEBUG_PIM, "inner packet of register " + "is not multicast %s", + ip6_sprintf(ip6bufd, &eip6->ip6_dst)); m_freem(m); return (IPPROTO_DONE); } @@ -1962,11 +1855,8 @@ pim6_input(struct mbuf **mp, int *offp, int proto) */ mcp = m_copy(m, 0, off + PIM6_REG_MINLEN); if (mcp == NULL) { -#ifdef MRT6DEBUG - log(LOG_ERR, - "pim6_input: pim register: " - "could not copy register head\n"); -#endif + MRT6_DLOG(DEBUG_ANY | DEBUG_ERR, "pim register: " + "could not copy register head"); m_freem(m); return (IPPROTO_DONE); } @@ -1975,16 +1865,10 @@ pim6_input(struct mbuf **mp, int *offp, int proto) * forward the inner ip6 packet; point m_data at the inner ip6. */ m_adj(m, off + PIM_MINLEN); -#ifdef MRT6DEBUG - if (V_mrt6debug & DEBUG_PIM) { - log(LOG_DEBUG, - "pim6_input: forwarding decapsulated register: " - "src %s, dst %s, mif %d\n", - ip6_sprintf(ip6bufs, &eip6->ip6_src), - ip6_sprintf(ip6bufd, &eip6->ip6_dst), - reg_mif_num); - } -#endif + MRT6_DLOG(DEBUG_PIM, "forwarding decapsulated register: " + "src %s, dst %s, mif %d", + ip6_sprintf(ip6bufs, &eip6->ip6_src), + ip6_sprintf(ip6bufd, &eip6->ip6_dst), reg_mif_num); rc = if_simloop(mif6table[reg_mif_num].m6_ifp, m, dst.sin6_family, 0); diff --git a/freebsd/sys/netinet6/ip6_mroute.h b/freebsd/sys/netinet6/ip6_mroute.h index d2df0dbe..33b41310 100644 --- a/freebsd/sys/netinet6/ip6_mroute.h +++ b/freebsd/sys/netinet6/ip6_mroute.h @@ -145,11 +145,6 @@ struct mrt6stat { struct omrt6msg { u_long unused1; u_char im6_msgtype; /* what type of message */ -#if 0 -#define MRT6MSG_NOCACHE 1 -#define MRT6MSG_WRONGMIF 2 -#define MRT6MSG_WHOLEPKT 3 /* used for user level encap*/ -#endif u_char im6_mbz; /* must be zero */ u_char im6_mif; /* mif rec'd on */ u_char unused2; diff --git a/freebsd/sys/netinet6/nd6.c b/freebsd/sys/netinet6/nd6.c index b84baf18..9233bef5 100644 --- a/freebsd/sys/netinet6/nd6.c +++ b/freebsd/sys/netinet6/nd6.c @@ -1156,9 +1156,9 @@ nd6_nud_hint(struct rtentry *rt, struct in6_addr *dst6, int force) return; ifp = rt->rt_ifp; - IF_AFDATA_LOCK(ifp); + IF_AFDATA_RLOCK(ifp); ln = nd6_lookup(dst6, ND6_EXCLUSIVE, NULL); - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_RUNLOCK(ifp); if (ln == NULL) return; @@ -1585,16 +1585,16 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr, * description on it in NS section (RFC 2461 7.2.3). */ flags = lladdr ? ND6_EXCLUSIVE : 0; - IF_AFDATA_LOCK(ifp); + IF_AFDATA_RLOCK(ifp); ln = nd6_lookup(from, flags, ifp); - + IF_AFDATA_RUNLOCK(ifp); if (ln == NULL) { flags |= ND6_EXCLUSIVE; + IF_AFDATA_LOCK(ifp); ln = nd6_lookup(from, flags | ND6_CREATE, ifp); IF_AFDATA_UNLOCK(ifp); is_newentry = 1; } else { - IF_AFDATA_UNLOCK(ifp); /* do nothing if static ndp is set */ if (ln->la_flags & LLE_STATIC) { static_route = 1; @@ -1897,12 +1897,12 @@ nd6_output_lle(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0, * or an anycast address(i.e. not a multicast). */ - flags = ((m != NULL) || (lle != NULL)) ? LLE_EXCLUSIVE : 0; + flags = (lle != NULL) ? LLE_EXCLUSIVE : 0; if (ln == NULL) { retry: - IF_AFDATA_LOCK(ifp); + IF_AFDATA_RLOCK(ifp); ln = lla_lookup(LLTABLE6(ifp), flags, (struct sockaddr *)dst); - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_RUNLOCK(ifp); if ((ln == NULL) && nd6_is_addr_neighbor(dst, ifp)) { /* * Since nd6_is_addr_neighbor() internally calls nd6_lookup(), @@ -1933,6 +1933,7 @@ nd6_output_lle(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0, ln->ln_state < ND6_LLINFO_REACHABLE) { if ((flags & LLE_EXCLUSIVE) == 0) { flags |= LLE_EXCLUSIVE; + LLE_RUNLOCK(ln); goto retry; } ln->ln_state = ND6_LLINFO_STALE; diff --git a/freebsd/sys/netinet6/nd6_nbr.c b/freebsd/sys/netinet6/nd6_nbr.c index 4574145f..09011b7e 100644 --- a/freebsd/sys/netinet6/nd6_nbr.c +++ b/freebsd/sys/netinet6/nd6_nbr.c @@ -736,9 +736,9 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) * If no neighbor cache entry is found, NA SHOULD silently be * discarded. */ - IF_AFDATA_LOCK(ifp); + IF_AFDATA_RLOCK(ifp); ln = nd6_lookup(&taddr6, LLE_EXCLUSIVE, ifp); - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_RUNLOCK(ifp); if (ln == NULL) { goto freeit; } diff --git a/freebsd/sys/netinet6/sctp6_usrreq.c b/freebsd/sys/netinet6/sctp6_usrreq.c index f4dfe819..c8bc6620 100644 --- a/freebsd/sys/netinet6/sctp6_usrreq.c +++ b/freebsd/sys/netinet6/sctp6_usrreq.c @@ -843,16 +843,18 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p) uint32_t vrf_id; int error = 0; struct sctp_inpcb *inp; - struct in6pcb *inp6; struct sctp_tcb *stcb; #ifdef INET + struct in6pcb *inp6; struct sockaddr_in6 *sin6; struct sockaddr_storage ss; #endif +#ifdef INET inp6 = (struct in6pcb *)so->so_pcb; +#endif inp = (struct sctp_inpcb *)so->so_pcb; if (inp == NULL) { SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET); diff --git a/freebsd/sys/netpfil/ipfw/ip_dummynet.c b/freebsd/sys/netpfil/ipfw/ip_dummynet.c index bd7e3c0b..bb9a6736 100644 --- a/freebsd/sys/netpfil/ipfw/ip_dummynet.c +++ b/freebsd/sys/netpfil/ipfw/ip_dummynet.c @@ -619,7 +619,7 @@ fsk_detach(struct dn_fsk *fs, int flags) fs->sched->fp->free_fsk(fs); fs->sched = NULL; if (flags & DN_DELETE_FS) { - bzero(fs, sizeof(fs)); /* safety */ + bzero(fs, sizeof(*fs)); /* safety */ free(fs, M_DUMMYNET); dn_cfg.fsk_count--; } else { diff --git a/freebsd/sys/netpfil/ipfw/ip_fw2.c b/freebsd/sys/netpfil/ipfw/ip_fw2.c index 1bd1b6fc..224ba937 100644 --- a/freebsd/sys/netpfil/ipfw/ip_fw2.c +++ b/freebsd/sys/netpfil/ipfw/ip_fw2.c @@ -144,6 +144,8 @@ VNET_DEFINE(int, verbose_limit); /* layer3_chain contains the list of rules for layer 3 */ VNET_DEFINE(struct ip_fw_chain, layer3_chain); +VNET_DEFINE(int, ipfw_nat_ready) = 0; + ipfw_nat_t *ipfw_nat_ptr = NULL; struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int); ipfw_nat_cfg_t *ipfw_nat_cfg_ptr; @@ -2411,38 +2413,35 @@ do { \ } case O_NAT: + l = 0; /* exit inner loop */ + done = 1; /* exit outer loop */ if (!IPFW_NAT_LOADED) { retval = IP_FW_DENY; - } else { - struct cfg_nat *t; - int nat_id; + break; + } - set_match(args, f_pos, chain); - /* Check if this is 'global' nat rule */ - if (cmd->arg1 == 0) { - retval = ipfw_nat_ptr(args, NULL, m); - l = 0; - done = 1; - break; - } - t = ((ipfw_insn_nat *)cmd)->nat; - if (t == NULL) { + struct cfg_nat *t; + int nat_id; + + set_match(args, f_pos, chain); + /* Check if this is 'global' nat rule */ + if (cmd->arg1 == 0) { + retval = ipfw_nat_ptr(args, NULL, m); + break; + } + t = ((ipfw_insn_nat *)cmd)->nat; + if (t == NULL) { nat_id = IP_FW_ARG_TABLEARG(cmd->arg1); t = (*lookup_nat_ptr)(&chain->nat, nat_id); if (t == NULL) { retval = IP_FW_DENY; - l = 0; /* exit inner loop */ - done = 1; /* exit outer loop */ break; } if (cmd->arg1 != IP_FW_TABLEARG) ((ipfw_insn_nat *)cmd)->nat = t; - } - retval = ipfw_nat_ptr(args, t, m); } - l = 0; /* exit inner loop */ - done = 1; /* exit outer loop */ + retval = ipfw_nat_ptr(args, t, m); break; case O_REASS: { @@ -2675,7 +2674,7 @@ vnet_ipfw_init(const void *unused) rule->set = RESVD_SET; rule->cmd[0].len = 1; rule->cmd[0].opcode = default_to_accept ? O_ACCEPT : O_DENY; - chain->rules = chain->default_rule = chain->map[0] = rule; + chain->default_rule = chain->map[0] = rule; chain->id = rule->id = 1; IPFW_LOCK_INIT(chain); diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_log.c b/freebsd/sys/netpfil/ipfw/ip_fw_log.c index 97132257..60b0df7d 100644 --- a/freebsd/sys/netpfil/ipfw/ip_fw_log.c +++ b/freebsd/sys/netpfil/ipfw/ip_fw_log.c @@ -175,11 +175,18 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args, if (args->eh) /* layer2, use orig hdr */ BPF_MTAP2(log_if, args->eh, ETHER_HDR_LEN, m); - else + else { /* Add fake header. Later we will store * more info in the header. */ - BPF_MTAP2(log_if, "DDDDDDSSSSSS\x08\x00", ETHER_HDR_LEN, m); + if (ip->ip_v == 4) + BPF_MTAP2(log_if, "DDDDDDSSSSSS\x08\x00", ETHER_HDR_LEN, m); + else if (ip->ip_v == 6) + BPF_MTAP2(log_if, "DDDDDDSSSSSS\x86\xdd", ETHER_HDR_LEN, m); + else + /* Obviously bogus EtherType. */ + BPF_MTAP2(log_if, "DDDDDDSSSSSS\xff\xff", ETHER_HDR_LEN, m); + } #endif /* !WITHOUT_BPF */ return; } diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_nat.c b/freebsd/sys/netpfil/ipfw/ip_fw_nat.c index 142c46c5..5d4dcc9f 100644 --- a/freebsd/sys/netpfil/ipfw/ip_fw_nat.c +++ b/freebsd/sys/netpfil/ipfw/ip_fw_nat.c @@ -55,8 +55,7 @@ __FBSDID("$FreeBSD$"); #include /* XXX for in_cksum */ -static VNET_DEFINE(eventhandler_tag, ifaddr_event_tag); -#define V_ifaddr_event_tag VNET(ifaddr_event_tag) +static eventhandler_tag ifaddr_event_tag; static void ifaddr_change(void *arg __unused, struct ifnet *ifp) @@ -65,6 +64,8 @@ ifaddr_change(void *arg __unused, struct ifnet *ifp) struct ifaddr *ifa; struct ip_fw_chain *chain; + KASSERT(curvnet == ifp->if_vnet, + ("curvnet(%p) differs from iface vnet(%p)", curvnet, ifp->if_vnet)); chain = &V_layer3_chain; IPFW_WLOCK(chain); /* Check every nat entry... */ @@ -443,7 +444,7 @@ ipfw_nat_cfg(struct sockopt *sopt) ptr->ip = cfg->ip; ptr->redir_cnt = cfg->redir_cnt; ptr->mode = cfg->mode; - LibAliasSetMode(ptr->lib, cfg->mode, cfg->mode); + LibAliasSetMode(ptr->lib, cfg->mode, ~0); LibAliasSetAddress(ptr->lib, ptr->ip); memcpy(ptr->if_name, cfg->if_name, IF_NAMESIZE); @@ -592,11 +593,38 @@ ipfw_nat_get_log(struct sockopt *sopt) return(0); } +static int +vnet_ipfw_nat_init(const void *arg __unused) +{ + + V_ipfw_nat_ready = 1; + return (0); +} + +static int +vnet_ipfw_nat_uninit(const void *arg __unused) +{ + struct cfg_nat *ptr, *ptr_temp; + struct ip_fw_chain *chain; + + chain = &V_layer3_chain; + IPFW_WLOCK(chain); + LIST_FOREACH_SAFE(ptr, &chain->nat, _next, ptr_temp) { + LIST_REMOVE(ptr, _next); + del_redir_spool_cfg(ptr, &ptr->redir_chain); + LibAliasUninit(ptr->lib); + free(ptr, M_IPFW); + } + flush_nat_ptrs(chain, -1 /* flush all */); + V_ipfw_nat_ready = 0; + IPFW_WUNLOCK(chain); + return (0); +} + static void ipfw_nat_init(void) { - IPFW_WLOCK(&V_layer3_chain); /* init ipfw hooks */ ipfw_nat_ptr = ipfw_nat; lookup_nat_ptr = lookup_nat; @@ -604,28 +632,16 @@ ipfw_nat_init(void) ipfw_nat_del_ptr = ipfw_nat_del; ipfw_nat_get_cfg_ptr = ipfw_nat_get_cfg; ipfw_nat_get_log_ptr = ipfw_nat_get_log; - IPFW_WUNLOCK(&V_layer3_chain); - V_ifaddr_event_tag = EVENTHANDLER_REGISTER( - ifaddr_event, ifaddr_change, + + ifaddr_event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_change, NULL, EVENTHANDLER_PRI_ANY); } static void ipfw_nat_destroy(void) { - struct cfg_nat *ptr, *ptr_temp; - struct ip_fw_chain *chain; - chain = &V_layer3_chain; - IPFW_WLOCK(chain); - LIST_FOREACH_SAFE(ptr, &chain->nat, _next, ptr_temp) { - LIST_REMOVE(ptr, _next); - del_redir_spool_cfg(ptr, &ptr->redir_chain); - LibAliasUninit(ptr->lib); - free(ptr, M_IPFW); - } - EVENTHANDLER_DEREGISTER(ifaddr_event, V_ifaddr_event_tag); - flush_nat_ptrs(chain, -1 /* flush all */); + EVENTHANDLER_DEREGISTER(ifaddr_event, ifaddr_event_tag); /* deregister ipfw_nat */ ipfw_nat_ptr = NULL; lookup_nat_ptr = NULL; @@ -633,7 +649,6 @@ ipfw_nat_destroy(void) ipfw_nat_del_ptr = NULL; ipfw_nat_get_cfg_ptr = NULL; ipfw_nat_get_log_ptr = NULL; - IPFW_WUNLOCK(chain); } static int @@ -643,11 +658,9 @@ ipfw_nat_modevent(module_t mod, int type, void *unused) switch (type) { case MOD_LOAD: - ipfw_nat_init(); break; case MOD_UNLOAD: - ipfw_nat_destroy(); break; default: @@ -663,8 +676,25 @@ static moduledata_t ipfw_nat_mod = { 0 }; -DECLARE_MODULE(ipfw_nat, ipfw_nat_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); +/* Define startup order. */ +#define IPFW_NAT_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN +#define IPFW_NAT_MODEVENT_ORDER (SI_ORDER_ANY - 128) +#define IPFW_NAT_MODULE_ORDER (IPFW_NAT_MODEVENT_ORDER + 1) +#define IPFW_NAT_VNET_ORDER (IPFW_NAT_MODEVENT_ORDER + 2) + +DECLARE_MODULE(ipfw_nat, ipfw_nat_mod, IPFW_NAT_SI_SUB_FIREWALL, SI_ORDER_ANY); MODULE_DEPEND(ipfw_nat, libalias, 1, 1, 1); MODULE_DEPEND(ipfw_nat, ipfw, 2, 2, 2); MODULE_VERSION(ipfw_nat, 1); + +SYSINIT(ipfw_nat_init, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_MODULE_ORDER, + ipfw_nat_init, NULL); +VNET_SYSINIT(vnet_ipfw_nat_init, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_VNET_ORDER, + vnet_ipfw_nat_init, NULL); + +SYSUNINIT(ipfw_nat_destroy, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_MODULE_ORDER, + ipfw_nat_destroy, NULL); +VNET_SYSUNINIT(vnet_ipfw_nat_uninit, IPFW_NAT_SI_SUB_FIREWALL, + IPFW_NAT_VNET_ORDER, vnet_ipfw_nat_uninit, NULL); + /* end of file */ diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_private.h b/freebsd/sys/netpfil/ipfw/ip_fw_private.h index 869d9721..ceabf88d 100644 --- a/freebsd/sys/netpfil/ipfw/ip_fw_private.h +++ b/freebsd/sys/netpfil/ipfw/ip_fw_private.h @@ -213,25 +213,27 @@ VNET_DECLARE(unsigned int, fw_tables_max); #define V_fw_tables_max VNET(fw_tables_max) struct ip_fw_chain { - struct ip_fw *rules; /* list of rules */ - struct ip_fw *reap; /* list of rules to reap */ - struct ip_fw *default_rule; - int n_rules; /* number of static rules */ - int static_len; /* total len of static rules */ struct ip_fw **map; /* array of rule ptrs to ease lookup */ + uint32_t id; /* ruleset id */ + int n_rules; /* number of static rules */ LIST_HEAD(nat_list, cfg_nat) nat; /* list of nat entries */ struct radix_node_head **tables; /* IPv4 tables */ struct radix_node_head **xtables; /* extended tables */ uint8_t *tabletype; /* Array of table types */ #if defined( __linux__ ) || defined( _WIN32 ) spinlock_t rwmtx; - spinlock_t uh_lock; #else struct rwlock rwmtx; +#endif + int static_len; /* total len of static rules */ + uint32_t gencnt; /* NAT generation count */ + struct ip_fw *reap; /* list of rules to reap */ + struct ip_fw *default_rule; +#if defined( __linux__ ) || defined( _WIN32 ) + spinlock_t uh_lock; +#else struct rwlock uh_lock; /* lock for upper half */ #endif - uint32_t id; /* ruleset id */ - uint32_t gencnt; /* generation count */ }; struct sockopt; /* used by tcp_var.h */ @@ -329,9 +331,11 @@ extern struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int); typedef int ipfw_nat_t(struct ip_fw_args *, struct cfg_nat *, struct mbuf *); typedef int ipfw_nat_cfg_t(struct sockopt *); -extern ipfw_nat_t *ipfw_nat_ptr; -#define IPFW_NAT_LOADED (ipfw_nat_ptr != NULL) +VNET_DECLARE(int, ipfw_nat_ready); +#define V_ipfw_nat_ready VNET(ipfw_nat_ready) +#define IPFW_NAT_LOADED (V_ipfw_nat_ready) +extern ipfw_nat_t *ipfw_nat_ptr; extern ipfw_nat_cfg_t *ipfw_nat_cfg_ptr; extern ipfw_nat_cfg_t *ipfw_nat_del_ptr; extern ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr; diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c b/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c index 40448a86..95cd8c81 100644 --- a/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c +++ b/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c @@ -161,7 +161,7 @@ ipfw_add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule) int i, l, insert_before; struct ip_fw **map; /* the new array of pointers */ - if (chain->rules == NULL || input_rule->rulenum > IPFW_DEFAULT_RULE-1) + if (chain->map == NULL || input_rule->rulenum > IPFW_DEFAULT_RULE - 1) return (EINVAL); l = RULESIZE(input_rule); @@ -657,7 +657,7 @@ check_ipfw_struct(struct ip_fw *rule, int size) case O_IP_SRC_LOOKUP: case O_IP_DST_LOOKUP: - if (cmd->arg1 >= IPFW_TABLES_MAX) { + if (cmd->arg1 >= V_fw_tables_max) { printf("ipfw: invalid table number %d\n", cmd->arg1); return (EINVAL); @@ -1045,8 +1045,10 @@ ipfw_ctl(struct sockopt *sopt) if (sopt->sopt_valsize == RULESIZE7(rule)) { is7 = 1; error = convert_rule_to_8(rule); - if (error) + if (error) { + free(rule, M_TEMP); return error; + } if (error == 0) error = check_ipfw_struct(rule, RULESIZE(rule)); } else { @@ -1062,11 +1064,13 @@ ipfw_ctl(struct sockopt *sopt) if (is7) { error = convert_rule_to_7(rule); size = RULESIZE7(rule); - if (error) + if (error) { + free(rule, M_TEMP); return error; + } } error = sooptcopyout(sopt, rule, size); - } + } } free(rule, M_TEMP); break; diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_table.c b/freebsd/sys/netpfil/ipfw/ip_fw_table.c index 58ee16e9..71579795 100644 --- a/freebsd/sys/netpfil/ipfw/ip_fw_table.c +++ b/freebsd/sys/netpfil/ipfw/ip_fw_table.c @@ -125,6 +125,7 @@ struct table_xentry { #define OFF_LEN_IFACE (8 * offsetof(struct xaddr_iface, ifname)) +#ifdef INET6 static inline void ipv6_writemask(struct in6_addr *addr6, uint8_t mask) { @@ -134,6 +135,7 @@ ipv6_writemask(struct in6_addr *addr6, uint8_t mask) *cp++ = 0xFFFFFFFF; *cp = htonl(mask ? ~((1 << (32 - mask)) - 1) : 0); } +#endif int ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, @@ -544,7 +546,7 @@ ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr, return (0); KEY_LEN(sa) = KEY_LEN_INET; sa.sin_addr.s_addr = addr; - ent = (struct table_entry *)(rnh->rnh_lookup(&sa, NULL, rnh)); + ent = (struct table_entry *)(rnh->rnh_matchaddr(&sa, rnh)); if (ent != NULL) { *val = ent->value; return (1); @@ -570,7 +572,7 @@ ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, case IPFW_TABLE_CIDR: KEY_LEN(sa6) = KEY_LEN_INET6; memcpy(&sa6.sin6_addr, paddr, sizeof(struct in6_addr)); - xent = (struct table_xentry *)(rnh->rnh_lookup(&sa6, NULL, rnh)); + xent = (struct table_xentry *)(rnh->rnh_matchaddr(&sa6, rnh)); break; case IPFW_TABLE_INTERFACE: @@ -578,7 +580,7 @@ ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr, strlcpy(iface.ifname, (char *)paddr, IF_NAMESIZE) + 1; /* Assume direct match */ /* FIXME: Add interface pattern matching */ - xent = (struct table_xentry *)(rnh->rnh_lookup(&iface, NULL, rnh)); + xent = (struct table_xentry *)(rnh->rnh_matchaddr(&iface, rnh)); break; default: diff --git a/freebsd/sys/opencrypto/deflate.c b/freebsd/sys/opencrypto/deflate.c index f8a46405..f29dfb42 100644 --- a/freebsd/sys/opencrypto/deflate.c +++ b/freebsd/sys/opencrypto/deflate.c @@ -52,13 +52,13 @@ __FBSDID("$FreeBSD$"); #include SDT_PROVIDER_DECLARE(opencrypto); -SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, entry, entry, +SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, entry, "int", "u_int32_t"); -SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, bad, bad, +SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, bad, "int", "int", "int", "int", "int"); -SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, iter, iter, +SDT_PROBE_DEFINE5(opencrypto, deflate, deflate_global, iter, "int", "int", "int", "int", "int"); -SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, return, return, +SDT_PROBE_DEFINE2(opencrypto, deflate, deflate_global, return, "int", "u_int32_t"); int window_inflate = -1 * MAX_WBITS; diff --git a/freebsd/sys/pci/if_rlreg.h b/freebsd/sys/pci/if_rlreg.h index be89c4f5..b0de60f4 100644 --- a/freebsd/sys/pci/if_rlreg.h +++ b/freebsd/sys/pci/if_rlreg.h @@ -145,6 +145,7 @@ #define RL_PMCH 0x006F /* 8 bits */ #define RL_MAXRXPKTLEN 0x00DA /* 16 bits, chip multiplies by 8 */ #define RL_INTRMOD 0x00E2 /* 16 bits */ +#define RL_MISC 0x00F0 /* * TX config register bits @@ -163,7 +164,6 @@ #define RL_LOOPTEST_ON_CPLUS 0x00060000 /* Known revision codes. */ - #define RL_HWREV_8169 0x00000000 #define RL_HWREV_8169S 0x00800000 #define RL_HWREV_8110S 0x04000000 @@ -189,8 +189,13 @@ #define RL_HWREV_8105E 0x40800000 #define RL_HWREV_8105E_SPIN1 0x40C00000 #define RL_HWREV_8402 0x44000000 +#define RL_HWREV_8106E 0x44800000 #define RL_HWREV_8168F 0x48000000 #define RL_HWREV_8411 0x48800000 +#define RL_HWREV_8168G 0x4C000000 +#define RL_HWREV_8168EP 0x50000000 +#define RL_HWREV_8168GU 0x50800000 +#define RL_HWREV_8411B 0x5C800000 #define RL_HWREV_8139 0x60000000 #define RL_HWREV_8139A 0x70000000 #define RL_HWREV_8139AG 0x70800000 @@ -282,8 +287,10 @@ #define RL_RXCFG_RX_RUNT 0x00000010 #define RL_RXCFG_RX_ERRPKT 0x00000020 #define RL_RXCFG_WRAP 0x00000080 +#define RL_RXCFG_EARLYOFFV2 0x00000800 #define RL_RXCFG_MAXDMA 0x00000700 #define RL_RXCFG_BUFSZ 0x00001800 +#define RL_RXCFG_EARLYOFF 0x00003800 #define RL_RXCFG_FIFOTHRESH 0x0000E000 #define RL_RXCFG_EARLYTHRESH 0x07000000 @@ -324,8 +331,8 @@ #define RL_RXSTAT_INDIV 0x00004000 #define RL_RXSTAT_MULTI 0x00008000 #define RL_RXSTAT_LENMASK 0xFFFF0000 +#define RL_RXSTAT_UNFINISHED 0x0000FFF0 /* DMA still in progress */ -#define RL_RXSTAT_UNFINISHED 0xFFF0 /* DMA still in progress */ /* * Command register. */ @@ -356,6 +363,7 @@ #define RL_PARA7C 0x7C #define RL_PARA7C_DEF 0xcb38de43 #define RL_PARA7C_RETUNE 0xfb38de03 + /* * EEPROM control register */ @@ -468,11 +476,9 @@ */ /* RL_DUMPSTATS_LO register */ - #define RL_DUMPSTATS_START 0x00000008 /* Transmit start register */ - #define RL_TXSTART_SWI 0x01 /* generate TX interrupt */ #define RL_TXSTART_START 0x40 /* start normal queue transmit */ #define RL_TXSTART_HPRIO_START 0x80 /* start hi prio queue transmit */ @@ -491,7 +497,6 @@ #define RL_BUSWIDTH_64BITS 0x08 /* C+ mode command register */ - #define RL_CPLUSCMD_TXENB 0x0001 /* enable C+ transmit mode */ #define RL_CPLUSCMD_RXENB 0x0002 /* enable C+ receive mode */ #define RL_CPLUSCMD_PCI_MRW 0x0008 /* enable PCI multi-read/write */ @@ -509,7 +514,6 @@ #define RL_CPLUSCMD_BIST_ENB 0x8000 /* 8168C/CP */ /* C+ early transmit threshold */ - #define RL_EARLYTXTHRESH_CNT 0x003F /* byte count times 8 */ /* Timer interrupt register */ @@ -523,7 +527,6 @@ /* * Gigabit PHY access register (8169 only) */ - #define RL_PHYAR_PHYDATA 0x0000FFFF #define RL_PHYAR_PHYREG 0x001F0000 #define RL_PHYAR_BUSY 0x80000000 @@ -554,7 +557,6 @@ * For reception, there's just one large buffer where the chip stores * all received packets. */ - #define RL_RX_BUF_SZ RL_RXBUF_64 #define RL_RXBUFLEN (1 << ((RL_RX_BUF_SZ >> 11) + 13)) #define RL_TX_LIST_CNT 4 @@ -637,11 +639,10 @@ struct rl_hwrev { /* * RX/TX descriptor definition. When large send mode is enabled, the - * lower 11 bits of the TX rl_cmd word are used to hold the MSS, and + * lower 11 bits of the TX rl_cmdstat word are used to hold the MSS, and * the checksum offload bits are disabled. The structure layout is * the same for RX and TX descriptors */ - struct rl_desc { uint32_t rl_cmdstat; uint32_t rl_vlanctl; @@ -674,7 +675,6 @@ struct rl_desc { * Error bits are valid only on the last descriptor of a frame * (i.e. RL_TDESC_CMD_EOF == 1) */ - #define RL_TDESC_STAT_COLCNT 0x000F0000 /* collision count */ #define RL_TDESC_STAT_EXCESSCOL 0x00100000 /* excessive collisions */ #define RL_TDESC_STAT_LINKFAIL 0x00200000 /* link faulure */ @@ -686,7 +686,6 @@ struct rl_desc { /* * RX descriptor cmd/vlan definitions */ - #define RL_RDESC_CMD_EOR 0x40000000 #define RL_RDESC_CMD_OWN 0x80000000 #define RL_RDESC_CMD_BUFLEN 0x00001FFF @@ -777,7 +776,7 @@ struct rl_stats { #define RL_TX_DESC_CNT RL_8169_TX_DESC_CNT #define RL_RX_DESC_CNT RL_8169_RX_DESC_CNT #define RL_RX_JUMBO_DESC_CNT RL_RX_DESC_CNT -#define RL_NTXSEGS 32 +#define RL_NTXSEGS 35 #define RL_RING_ALIGN 256 #define RL_DUMP_ALIGN 64 @@ -877,6 +876,7 @@ struct rl_softc { bus_dma_tag_t rl_parent_tag; uint8_t rl_type; const struct rl_hwrev *rl_hwrev; + uint32_t rl_macrev; int rl_eecmd_read; int rl_eewidth; int rl_expcap; @@ -929,6 +929,9 @@ struct rl_softc { #define RL_FLAG_WAIT_TXPOLL 0x00004000 #define RL_FLAG_CMDSTOP_WAIT_TXQ 0x00008000 #define RL_FLAG_WOL_MANLINK 0x00010000 +#define RL_FLAG_EARLYOFF 0x00020000 +#define RL_FLAG_EARLYOFFV2 0x00040000 +#define RL_FLAG_RXDV_GATED 0x00080000 #define RL_FLAG_PCIE 0x40000000 #define RL_FLAG_LINK 0x80000000 }; diff --git a/freebsd/sys/rpc/types.h b/freebsd/sys/rpc/types.h index 5634c4dd..754d6279 100644 --- a/freebsd/sys/rpc/types.h +++ b/freebsd/sys/rpc/types.h @@ -1,32 +1,31 @@ /* $NetBSD: types.h,v 1.13 2000/06/13 01:02:44 thorpej Exp $ */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * from: @(#)types.h 1.18 87/07/24 SMI * from: @(#)types.h 2.3 88/08/15 4.0 RPCSRC diff --git a/freebsd/sys/sys/_rmlock.h b/freebsd/sys/sys/_rmlock.h index 283ea379..46672bb2 100644 --- a/freebsd/sys/sys/_rmlock.h +++ b/freebsd/sys/sys/_rmlock.h @@ -45,14 +45,17 @@ LIST_HEAD(rmpriolist,rm_priotracker); #ifndef __rtems__ struct rmlock { - struct lock_object lock_object; + struct lock_object lock_object; volatile cpuset_t rm_writecpus; LIST_HEAD(,rm_priotracker) rm_activeReaders; union { + struct lock_object _rm_wlock_object; struct mtx _rm_lock_mtx; struct sx _rm_lock_sx; } _rm_lock; }; + +#define rm_wlock_object _rm_lock._rm_wlock_object #define rm_lock_mtx _rm_lock._rm_lock_mtx #define rm_lock_sx _rm_lock._rm_lock_sx #else /* __rtems__ */ diff --git a/freebsd/sys/sys/_rwlock.h b/freebsd/sys/sys/_rwlock.h index 25eb55e9..95b21283 100644 --- a/freebsd/sys/sys/_rwlock.h +++ b/freebsd/sys/sys/_rwlock.h @@ -10,9 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/freebsd/sys/sys/ata.h b/freebsd/sys/sys/ata.h index 76d8f646..f46dd50c 100644 --- a/freebsd/sys/sys/ata.h +++ b/freebsd/sys/sys/ata.h @@ -130,6 +130,7 @@ struct ata_params { #define ATA_SATA_CURR_GEN_MASK 0x0006 #define ATA_SUPPORT_NCQ_STREAM 0x0010 #define ATA_SUPPORT_NCQ_QMANAGEMENT 0x0020 +#define ATA_SUPPORT_RCVSND_FPDMA_QUEUED 0x0040 /*78*/ u_int16_t satasupport; #define ATA_SUPPORT_NONZERO 0x0002 #define ATA_SUPPORT_AUTOACTIVATE 0x0004 @@ -214,6 +215,8 @@ struct ata_params { #define ATA_PSS_LSPPS 0x000F #define ATA_PSS_LSSABOVE512 0x1000 #define ATA_PSS_MULTLS 0x2000 +#define ATA_PSS_VALID_MASK 0xC000 +#define ATA_PSS_VALID_VALUE 0x4000 /*107*/ u_int16_t isd; /*108*/ u_int16_t wwn[4]; u_int16_t reserved112[5]; @@ -347,6 +350,7 @@ struct ata_params { #define ATA_READ_NATIVE_MAX_ADDRESS48 0x27 /* read native max addr 48bit */ #define ATA_READ_MUL48 0x29 /* read multi 48bit LBA */ #define ATA_READ_STREAM_DMA48 0x2a /* read DMA stream 48bit LBA */ +#define ATA_READ_LOG_EXT 0x2f /* read log ext - PIO Data-In */ #define ATA_READ_STREAM48 0x2b /* read stream 48bit LBA */ #define ATA_WRITE 0x30 /* write */ #define ATA_WRITE48 0x34 /* write 48bit LBA */ @@ -361,8 +365,11 @@ struct ata_params { #define ATA_WRITE_LOG_EXT 0x3f #define ATA_READ_VERIFY 0x40 #define ATA_READ_VERIFY48 0x42 +#define ATA_READ_LOG_DMA_EXT 0x47 /* read log DMA ext - PIO Data-In */ #define ATA_READ_FPDMA_QUEUED 0x60 /* read DMA NCQ */ #define ATA_WRITE_FPDMA_QUEUED 0x61 /* write DMA NCQ */ +#define ATA_SEND_FPDMA_QUEUED 0x64 /* send DMA NCQ */ +#define ATA_RECV_FPDMA_QUEUED 0x65 /* recieve DMA NCQ */ #define ATA_SEP_ATTN 0x67 /* SEP request */ #define ATA_SEEK 0x70 /* seek */ #define ATA_PACKET_CMD 0xa0 /* packet command */ diff --git a/freebsd/sys/sys/bus_dma.h b/freebsd/sys/sys/bus_dma.h index 6fbac13b..6e91a012 100644 --- a/freebsd/sys/sys/bus_dma.h +++ b/freebsd/sys/sys/bus_dma.h @@ -16,13 +16,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED diff --git a/freebsd/sys/sys/conf.h b/freebsd/sys/sys/conf.h index a8dfc300..a0a73522 100644 --- a/freebsd/sys/sys/conf.h +++ b/freebsd/sys/sys/conf.h @@ -64,6 +64,7 @@ struct cdev { #define SI_DUMPDEV 0x0080 /* is kernel dumpdev */ #define SI_CANDELETE 0x0100 /* can do BIO_DELETE */ #define SI_CLONELIST 0x0200 /* on a clone list */ +#define SI_UNMAPPED 0x0400 /* can handle unmapped I/O */ #ifndef __rtems__ struct timespec si_atime; struct timespec si_ctime; diff --git a/freebsd/sys/sys/eventhandler.h b/freebsd/sys/sys/eventhandler.h index 47bc8940..95d03b83 100644 --- a/freebsd/sys/sys/eventhandler.h +++ b/freebsd/sys/sys/eventhandler.h @@ -253,6 +253,24 @@ EVENTHANDLER_DECLARE(thread_fini, thread_fini_fn); typedef void (*uma_zone_chfn)(void *); EVENTHANDLER_DECLARE(nmbclusters_change, uma_zone_chfn); +EVENTHANDLER_DECLARE(nmbufs_change, uma_zone_chfn); EVENTHANDLER_DECLARE(maxsockets_change, uma_zone_chfn); +/* Kernel linker file load and unload events */ +struct linker_file; +typedef void (*kld_load_fn)(void *, struct linker_file *); +typedef void (*kld_unload_fn)(void *, const char *, caddr_t, size_t); +typedef void (*kld_unload_try_fn)(void *, struct linker_file *, int *); +EVENTHANDLER_DECLARE(kld_load, kld_load_fn); +EVENTHANDLER_DECLARE(kld_unload, kld_unload_fn); +EVENTHANDLER_DECLARE(kld_unload_try, kld_unload_try_fn); + +/* Generic graphics framebuffer interface */ +struct fb_info; +typedef void (*register_framebuffer_fn)(void *, struct fb_info *); +typedef void (*unregister_framebuffer_fn)(void *, struct fb_info *); +EVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn); +EVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn); + #endif /* SYS_EVENTHANDLER_H */ + diff --git a/freebsd/sys/sys/eventvar.h b/freebsd/sys/sys/eventvar.h index 26fe34b4..6af0fe82 100644 --- a/freebsd/sys/sys/eventvar.h +++ b/freebsd/sys/sys/eventvar.h @@ -41,7 +41,7 @@ struct kqueue { struct mtx kq_lock; int kq_refcnt; - SLIST_ENTRY(kqueue) kq_list; + TAILQ_ENTRY(kqueue) kq_list; TAILQ_HEAD(, knote) kq_head; /* list of pending event */ int kq_count; /* number of pending events */ struct selinfo kq_sel; diff --git a/freebsd/sys/sys/kernel.h b/freebsd/sys/sys/kernel.h index 1318243f..c739cd55 100644 --- a/freebsd/sys/sys/kernel.h +++ b/freebsd/sys/sys/kernel.h @@ -86,7 +86,7 @@ extern volatile int ticks; * enumeration values are explicit rather than implicit to provide * for binary compatibility with inserted elements. * - * The SI_SUB_RUN_SCHEDULER value must have the highest lexical value. + * The SI_SUB_LAST value must have the highest lexical value. * * The SI_SUB_SWAP values represent a value used by * the BSD 4.4Lite but not by FreeBSD; it is maintained in dependent @@ -172,7 +172,7 @@ enum sysinit_sub_id { SI_SUB_KTHREAD_IDLE = 0xee00000, /* idle procs*/ SI_SUB_SMP = 0xf000000, /* start the APs*/ SI_SUB_RACCTD = 0xf100000, /* start raccd*/ - SI_SUB_RUN_SCHEDULER = 0xfffffff /* scheduler*/ + SI_SUB_LAST = 0xfffffff /* final initialization */ }; diff --git a/freebsd/sys/sys/linker.h b/freebsd/sys/sys/linker.h index 6948bb22..29db893f 100644 --- a/freebsd/sys/sys/linker.h +++ b/freebsd/sys/sys/linker.h @@ -92,10 +92,6 @@ struct linker_file { */ int nenabled; /* number of enabled probes. */ int fbt_nentries; /* number of fbt entries created. */ - void *sdt_probes; - int sdt_nentries; - size_t sdt_nprobes; - size_t sdt_size; }; /* diff --git a/freebsd/sys/sys/lockmgr.h b/freebsd/sys/sys/lockmgr.h index 4c3a272a..10227cdd 100644 --- a/freebsd/sys/sys/lockmgr.h +++ b/freebsd/sys/sys/lockmgr.h @@ -168,6 +168,7 @@ _lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk, #define LK_RELEASE 0x100000 #define LK_SHARED 0x200000 #define LK_UPGRADE 0x400000 +#define LK_TRYUPGRADE 0x800000 #define LK_TOTAL_MASK (LK_INIT_MASK | LK_EATTR_MASK | LK_TYPE_MASK) diff --git a/freebsd/sys/sys/mbuf.h b/freebsd/sys/sys/mbuf.h index 12328751..b6d58a25 100644 --- a/freebsd/sys/sys/mbuf.h +++ b/freebsd/sys/sys/mbuf.h @@ -396,7 +396,6 @@ struct mbstat { * * The rest of it is defined in kern/kern_mbuf.c */ - extern uma_zone_t zone_mbuf; extern uma_zone_t zone_clust; extern uma_zone_t zone_pack; @@ -451,6 +450,28 @@ m_gettype(int size) return (type); } +/* + * Associated an external reference counted buffer with an mbuf. + */ +static __inline void +m_extaddref(struct mbuf *m, caddr_t buf, u_int size, u_int *ref_cnt, + void (*freef)(void *, void *), void *arg1, void *arg2) +{ + + KASSERT(ref_cnt != NULL, ("%s: ref_cnt not provided", __func__)); + + atomic_add_int((int*)ref_cnt, 1); + m->m_flags |= M_EXT; + m->m_ext.ext_buf = buf; + m->m_ext.ref_cnt = ref_cnt; + m->m_data = m->m_ext.ext_buf; + m->m_ext.ext_size = size; + m->m_ext.ext_free = freef; + m->m_ext.ext_arg1 = arg1; + m->m_ext.ext_arg2 = arg2; + m->m_ext.ext_type = EXT_EXTREF; +} + static __inline uma_zone_t m_getzone(int size) { diff --git a/freebsd/sys/sys/mman.h b/freebsd/sys/sys/mman.h index 5ed9cdd6..c79ad86d 100644 --- a/freebsd/sys/sys/mman.h +++ b/freebsd/sys/sys/mman.h @@ -91,6 +91,17 @@ */ #define MAP_NOCORE 0x00020000 /* dont include these pages in a coredump */ #define MAP_PREFAULT_READ 0x00040000 /* prefault mapping for reading */ + +/* + * Request specific alignment (n == log2 of the desired alignment). + * + * MAP_ALIGNED_SUPER requests optimal superpage alignment, but does + * not enforce a specific alignment. + */ +#define MAP_ALIGNED(n) ((n) << MAP_ALIGNMENT_SHIFT) +#define MAP_ALIGNMENT_SHIFT 24 +#define MAP_ALIGNMENT_MASK MAP_ALIGNED(0xff) +#define MAP_ALIGNED_SUPER MAP_ALIGNED(1) /* align on a superpage */ #endif /* __BSD_VISIBLE */ #if __POSIX_VISIBLE >= 199309 diff --git a/freebsd/sys/sys/pciio.h b/freebsd/sys/sys/pciio.h index a0c4560e..d70bfbcf 100644 --- a/freebsd/sys/sys/pciio.h +++ b/freebsd/sys/sys/pciio.h @@ -116,10 +116,31 @@ struct pci_bar_io { uint64_t pbi_length; /* length of BAR */ }; +struct pci_vpd_element { + char pve_keyword[2]; + uint8_t pve_flags; + uint8_t pve_datalen; + uint8_t pve_data[0]; +}; + +#define PVE_FLAG_IDENT 0x01 /* Element is the string identifier */ +#define PVE_FLAG_RW 0x02 /* Element is read/write */ + +#define PVE_NEXT(pve) \ + ((struct pci_vpd_element *)((char *)(pve) + \ + sizeof(struct pci_vpd_element) + (pve)->pve_datalen)) + +struct pci_list_vpd_io { + struct pcisel plvi_sel; /* device to operate on */ + size_t plvi_len; /* size of the data area */ + struct pci_vpd_element *plvi_data; +}; + #define PCIOCGETCONF _IOWR('p', 5, struct pci_conf_io) #define PCIOCREAD _IOWR('p', 2, struct pci_io) #define PCIOCWRITE _IOWR('p', 3, struct pci_io) #define PCIOCATTACHED _IOWR('p', 4, struct pci_io) #define PCIOCGETBAR _IOWR('p', 6, struct pci_bar_io) +#define PCIOCLISTVPD _IOWR('p', 7, struct pci_list_vpd_io) #endif /* !_SYS_PCIIO_H_ */ diff --git a/freebsd/sys/sys/proc.h b/freebsd/sys/sys/proc.h index 58d7d6cc..1db9f8c2 100644 --- a/freebsd/sys/sys/proc.h +++ b/freebsd/sys/sys/proc.h @@ -438,6 +438,8 @@ do { \ #define TDP_RESETSPUR 0x04000000 /* Reset spurious page fault history. */ #define TDP_NERRNO 0x08000000 /* Last errno is already in td_errno */ #define TDP_UIOHELD 0x10000000 /* Current uio has pages held in td_ma */ +#define TDP_DEVMEMIO 0x20000000 /* Accessing memory for /dev/mem */ +#define TDP_EXECVMSPC 0x40000000 /* Execve destroyed old vmspace */ /* * Reasons that the current thread can not be run yet. @@ -507,11 +509,8 @@ struct proc { struct callout p_limco; /* (c) Limit callout handle */ struct sigacts *p_sigacts; /* (x) Signal actions, state (CPU). */ - /* - * The following don't make too much sense. - * See the td_ or ke_ versions of the same flags. - */ int p_flag; /* (c) P_* flags. */ + int p_flag2; /* (c) P2_* flags. */ enum { PRS_NEW = 0, /* In creation */ PRS_NORMAL, /* threads can be run. */ @@ -658,6 +657,9 @@ struct proc { #define P_SHOULDSTOP(p) ((p)->p_flag & P_STOPPED) #define P_KILLED(p) ((p)->p_flag & P_WKILLED) +/* These flags are kept in p_flag2. */ +#define P2_INHERIT_PROTECTED 0x00000001 /* New children get P_PROTECTED. */ + /* * These were process status values (p_stat), now they are only used in * legacy conversion code. diff --git a/freebsd/sys/sys/refcount.h b/freebsd/sys/sys/refcount.h index 572a64e1..b169f542 100644 --- a/freebsd/sys/sys/refcount.h +++ b/freebsd/sys/sys/refcount.h @@ -10,9 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/freebsd/sys/sys/rmlock.h b/freebsd/sys/sys/rmlock.h index 487cb392..e71789ac 100644 --- a/freebsd/sys/sys/rmlock.h +++ b/freebsd/sys/sys/rmlock.h @@ -66,6 +66,10 @@ void _rm_wunlock(struct rmlock *rm); int _rm_rlock(struct rmlock *rm, struct rm_priotracker *tracker, int trylock); void _rm_runlock(struct rmlock *rm, struct rm_priotracker *tracker); +#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT) +void _rm_assert(struct rmlock *rm, int what, const char *file, + int line); +#endif /* * Public interface for lock operations. @@ -90,6 +94,9 @@ void _rm_runlock(struct rmlock *rm, struct rm_priotracker *tracker); #define rm_try_rlock(rm,tracker) _rm_rlock((rm),(tracker), 1) #define rm_runlock(rm,tracker) _rm_runlock((rm), (tracker)) #endif +#define rm_sleep(chan, rm, pri, wmesg, timo) \ + _sleep((chan), &(rm)->lock_object, (pri), (wmesg), \ + tick_sbt * (timo), 0, C_HARDCLOCK) #else /* __rtems__ */ #define rm_init(rm, name) rw_init(rm, name) @@ -140,5 +147,20 @@ struct rm_args_flags { SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ rm_destroy, (rm)) +#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT) +#define RA_LOCKED LA_LOCKED +#define RA_RLOCKED LA_SLOCKED +#define RA_WLOCKED LA_XLOCKED +#define RA_UNLOCKED LA_UNLOCKED +#define RA_RECURSED LA_RECURSED +#define RA_NOTRECURSED LA_NOTRECURSED +#endif + +#ifdef INVARIANTS +#define rm_assert(rm, what) _rm_assert((rm), (what), LOCK_FILE, LOCK_LINE) +#else +#define rm_assert(rm, what) +#endif + #endif /* _KERNEL */ #endif /* !_SYS_RMLOCK_H_ */ diff --git a/freebsd/sys/sys/rwlock.h b/freebsd/sys/sys/rwlock.h index ec2aed27..2dd1a257 100644 --- a/freebsd/sys/sys/rwlock.h +++ b/freebsd/sys/sys/rwlock.h @@ -10,9 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/freebsd/sys/sys/sdt.h b/freebsd/sys/sys/sdt.h index f2f9b317..ca820f68 100644 --- a/freebsd/sys/sys/sdt.h +++ b/freebsd/sys/sys/sdt.h @@ -77,23 +77,27 @@ #else /* _KERNEL */ +#include +#include + #ifndef KDTRACE_HOOKS #define SDT_PROVIDER_DEFINE(prov) #define SDT_PROVIDER_DECLARE(prov) -#define SDT_PROBE_DEFINE(prov, mod, func, name, sname) +#define SDT_PROBE_DEFINE(prov, mod, func, name) #define SDT_PROBE_DECLARE(prov, mod, func, name) #define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) -#define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type) - -#define SDT_PROBE_DEFINE1(prov, mod, func, name, sname, arg0) -#define SDT_PROBE_DEFINE2(prov, mod, func, name, sname, arg0, arg1) -#define SDT_PROBE_DEFINE3(prov, mod, func, name, sname, arg0, arg1, arg2) -#define SDT_PROBE_DEFINE4(prov, mod, func, name, sname, arg0, arg1, arg2, arg3) -#define SDT_PROBE_DEFINE5(prov, mod, func, name, sname, arg0, arg1, arg2, arg3, arg4) -#define SDT_PROBE_DEFINE6(prov, mod, func, name, snamp, arg0, arg1, arg2, \ +#define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type, xtype) + +#define SDT_PROBE_DEFINE0(prov, mod, func, name) +#define SDT_PROBE_DEFINE1(prov, mod, func, name, arg0) +#define SDT_PROBE_DEFINE2(prov, mod, func, name, arg0, arg1) +#define SDT_PROBE_DEFINE3(prov, mod, func, name, arg0, arg1, arg2) +#define SDT_PROBE_DEFINE4(prov, mod, func, name, arg0, arg1, arg2, arg3) +#define SDT_PROBE_DEFINE5(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) +#define SDT_PROBE_DEFINE6(prov, mod, func, name, arg0, arg1, arg2, \ arg3, arg4, arg5) -#define SDT_PROBE_DEFINE7(prov, mod, func, name, snamp, arg0, arg1, arg2, \ +#define SDT_PROBE_DEFINE7(prov, mod, func, name, arg0, arg1, arg2, \ arg3, arg4, arg5, arg6) #define SDT_PROBE0(prov, mod, func, name) @@ -106,159 +110,182 @@ #define SDT_PROBE7(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4, arg5, \ arg6) -#else - -/* - * This type definition must match that of dtrace_probe. It is defined this - * way to avoid having to rely on CDDL code. - */ -typedef void (*sdt_probe_func_t)(u_int32_t, uintptr_t arg0, uintptr_t arg1, - uintptr_t arg2, uintptr_t arg3, uintptr_t arg4); +#define SDT_PROBE_DEFINE0_XLATE(prov, mod, func, name) +#define SDT_PROBE_DEFINE1_XLATE(prov, mod, func, name, arg0, xarg0) +#define SDT_PROBE_DEFINE2_XLATE(prov, mod, func, name, arg0, xarg0, \ + arg1, xarg1) +#define SDT_PROBE_DEFINE3_XLATE(prov, mod, func, name, arg0, xarg0, \ + arg1, xarg1, arg2, xarg2) +#define SDT_PROBE_DEFINE4_XLATE(prov, mod, func, name, arg0, xarg0, \ + arg1, xarg1, arg2, xarg2, arg3, xarg3) +#define SDT_PROBE_DEFINE5_XLATE(prov, mod, func, name, arg0, xarg0, \ + arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4) +#define SDT_PROBE_DEFINE6_XLATE(prov, mod, func, name, arg0, xarg0, \ + arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4, arg5, xarg5) +#define SDT_PROBE_DEFINE7_XLATE(prov, mod, func, name, arg0, xarg0, \ + arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4, arg5, xarg5, arg6, \ + xarg6) + +#define DTRACE_PROBE(name) +#define DTRACE_PROBE1(name, type0, arg0) +#define DTRACE_PROBE2(name, type0, arg0, type1, arg1) +#define DTRACE_PROBE3(name, type0, arg0, type1, arg1, type2, arg2) +#define DTRACE_PROBE4(name, type0, arg0, type1, arg1, type2, arg2, type3, arg3) +#define DTRACE_PROBE5(name, type0, arg0, type1, arg1, type2, arg2, type3, arg3,\ + type4, arg4) -/* - * The hook for the probe function. See kern_sdt.c which defaults this to - * it's own stub. The 'sdt' provider will set it to dtrace_probe when it - * loads. - */ -extern sdt_probe_func_t sdt_probe_func; - -typedef enum { - SDT_UNINIT = 1, - SDT_INIT, -} sdt_state_t; - -struct sdt_probe; -struct sdt_provider; - -struct sdt_argtype { - int ndx; /* Argument index. */ - const char *type; /* Argument type string. */ - TAILQ_ENTRY(sdt_argtype) - argtype_entry; /* Argument type list entry. */ - struct sdt_probe - *probe; /* Ptr to the probe structure. */ -}; - -struct sdt_probe { - int version; /* Set to sizeof(struct sdt_ref). */ - sdt_state_t state; - struct sdt_provider - *prov; /* Ptr to the provider structure. */ - TAILQ_ENTRY(sdt_probe) - probe_entry; /* SDT probe list entry. */ - TAILQ_HEAD(argtype_list_head, sdt_argtype) argtype_list; - const char *mod; - const char *func; - const char *name; - id_t id; /* DTrace probe ID. */ - int n_args; /* Number of arguments. */ -}; +#else -struct sdt_provider { - const char *name; /* Provider name. */ - TAILQ_ENTRY(sdt_provider) - prov_entry; /* SDT provider list entry. */ - TAILQ_HEAD(probe_list_head, sdt_probe) probe_list; - uintptr_t id; /* DTrace provider ID. */ -}; +SET_DECLARE(sdt_providers_set, struct sdt_provider); +SET_DECLARE(sdt_probes_set, struct sdt_probe); +SET_DECLARE(sdt_argtypes_set, struct sdt_argtype); #define SDT_PROVIDER_DEFINE(prov) \ struct sdt_provider sdt_provider_##prov[1] = { \ - { #prov, { NULL, NULL }, { NULL, NULL } } \ + { #prov, { NULL, NULL }, 0, 0 } \ }; \ - SYSINIT(sdt_provider_##prov##_init, SI_SUB_KDTRACE, \ - SI_ORDER_SECOND, sdt_provider_register, \ - sdt_provider_##prov ); \ - SYSUNINIT(sdt_provider_##prov##_uninit, SI_SUB_KDTRACE, \ - SI_ORDER_SECOND, sdt_provider_deregister, \ - sdt_provider_##prov ) + DATA_SET(sdt_providers_set, sdt_provider_##prov); #define SDT_PROVIDER_DECLARE(prov) \ extern struct sdt_provider sdt_provider_##prov[1] -#define SDT_PROBE_DEFINE(prov, mod, func, name, sname) \ +#define SDT_PROBE_DEFINE(prov, mod, func, name) \ struct sdt_probe sdt_##prov##_##mod##_##func##_##name[1] = { \ - { sizeof(struct sdt_probe), 0, sdt_provider_##prov, \ - { NULL, NULL }, { NULL, NULL }, #mod, #func, #sname, 0, 0 } \ + { sizeof(struct sdt_probe), sdt_provider_##prov, \ + { NULL, NULL }, { NULL, NULL }, #mod, #func, #name, 0, 0, \ + NULL } \ }; \ - SYSINIT(sdt_##prov##_##mod##_##func##_##name##_init, SI_SUB_KDTRACE, \ - SI_ORDER_SECOND + 1, sdt_probe_register, \ - sdt_##prov##_##mod##_##func##_##name ); \ - SYSUNINIT(sdt_##prov##_##mod##_##func##_##name##_uninit, \ - SI_SUB_KDTRACE, SI_ORDER_SECOND + 1, sdt_probe_deregister, \ - sdt_##prov##_##mod##_##func##_##name ) + DATA_SET(sdt_probes_set, sdt_##prov##_##mod##_##func##_##name); #define SDT_PROBE_DECLARE(prov, mod, func, name) \ extern struct sdt_probe sdt_##prov##_##mod##_##func##_##name[1] -#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) \ +#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) do { \ if (sdt_##prov##_##mod##_##func##_##name->id) \ (*sdt_probe_func)(sdt_##prov##_##mod##_##func##_##name->id, \ (uintptr_t) arg0, (uintptr_t) arg1, (uintptr_t) arg2, \ - (uintptr_t) arg3, (uintptr_t) arg4) + (uintptr_t) arg3, (uintptr_t) arg4); \ +} while (0) -#define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type) \ - struct sdt_argtype sdt_##prov##_##mod##_##func##_##name##num[1] \ - = { { num, type, { NULL, NULL }, \ +#define SDT_PROBE_ARGTYPE(prov, mod, func, name, num, type, xtype) \ + static struct sdt_argtype sdta_##prov##_##mod##_##func##_##name##num[1] \ + = { { num, type, xtype, { NULL, NULL }, \ sdt_##prov##_##mod##_##func##_##name } \ }; \ - SYSINIT(sdt_##prov##_##mod##_##func##_##name##num##_init, \ - SI_SUB_KDTRACE, SI_ORDER_SECOND + 2, sdt_argtype_register, \ - sdt_##prov##_##mod##_##func##_##name##num ); \ - SYSUNINIT(sdt_##prov##_##mod##_##func##_##name##num##_uninit, \ - SI_SUB_KDTRACE, SI_ORDER_SECOND + 2, sdt_argtype_deregister, \ - sdt_##prov##_##mod##_##func##_##name##num ) - -#define SDT_PROBE_DEFINE1(prov, mod, func, name, sname, arg0) \ - SDT_PROBE_DEFINE(prov, mod, func, name, sname); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0) - -#define SDT_PROBE_DEFINE2(prov, mod, func, name, sname, arg0, arg1) \ - SDT_PROBE_DEFINE(prov, mod, func, name, sname); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1) - -#define SDT_PROBE_DEFINE3(prov, mod, func, name, sname, arg0, arg1, arg2)\ - SDT_PROBE_DEFINE(prov, mod, func, name, sname); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2) - -#define SDT_PROBE_DEFINE4(prov, mod, func, name, sname, arg0, arg1, arg2, arg3) \ - SDT_PROBE_DEFINE(prov, mod, func, name, sname); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3) - -#define SDT_PROBE_DEFINE5(prov, mod, func, name, sname, arg0, arg1, arg2, arg3, arg4) \ - SDT_PROBE_DEFINE(prov, mod, func, name, sname); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4) - -#define SDT_PROBE_DEFINE6(prov, mod, func, name, sname, arg0, arg1, arg2, arg3,\ + DATA_SET(sdt_argtypes_set, sdta_##prov##_##mod##_##func##_##name##num); + +#define SDT_PROBE_DEFINE0(prov, mod, func, name) \ + SDT_PROBE_DEFINE(prov, mod, func, name) + +#define SDT_PROBE_DEFINE1(prov, mod, func, name, arg0) \ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL) + +#define SDT_PROBE_DEFINE2(prov, mod, func, name, arg0, arg1) \ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, NULL) + +#define SDT_PROBE_DEFINE3(prov, mod, func, name, arg0, arg1, arg2)\ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, NULL) + +#define SDT_PROBE_DEFINE4(prov, mod, func, name, arg0, arg1, arg2, arg3) \ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, NULL) + +#define SDT_PROBE_DEFINE5(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) \ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4, NULL) + +#define SDT_PROBE_DEFINE6(prov, mod, func, name, arg0, arg1, arg2, arg3,\ arg4, arg5) \ - SDT_PROBE_DEFINE(prov, mod, func, name, sname); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 5, arg5); - -#define SDT_PROBE_DEFINE7(prov, mod, func, name, sname, arg0, arg1, arg2, arg3,\ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 5, arg5, NULL) + +#define SDT_PROBE_DEFINE7(prov, mod, func, name, arg0, arg1, arg2, arg3,\ arg4, arg5, arg6) \ - SDT_PROBE_DEFINE(prov, mod, func, name, sname); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 5, arg5); \ - SDT_PROBE_ARGTYPE(prov, mod, func, name, 6, arg6); + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 5, arg5, NULL); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 6, arg6, NULL) + +#define SDT_PROBE_DEFINE0_XLATE(prov, mod, func, name) \ + SDT_PROBE_DEFINE(prov, mod, func, name) + +#define SDT_PROBE_DEFINE1_XLATE(prov, mod, func, name, arg0, xarg0) \ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0) + +#define SDT_PROBE_DEFINE2_XLATE(prov, mod, func, name, arg0, xarg0, \ + arg1, xarg1) \ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, xarg1) + +#define SDT_PROBE_DEFINE3_XLATE(prov, mod, func, name, arg0, xarg0, \ + arg1, xarg1, arg2, xarg2) \ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, xarg1); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, xarg2) + +#define SDT_PROBE_DEFINE4_XLATE(prov, mod, func, name, arg0, xarg0, \ + arg1, xarg1, arg2, xarg2, arg3, xarg3) \ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, xarg1); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, xarg2); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, xarg3) + +#define SDT_PROBE_DEFINE5_XLATE(prov, mod, func, name, arg0, xarg0, \ + arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4) \ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, xarg1); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, xarg2); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, xarg3); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4, xarg4) + +#define SDT_PROBE_DEFINE6_XLATE(prov, mod, func, name, arg0, xarg0, \ + arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4, arg5, xarg5) \ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, xarg1); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, xarg2); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, xarg3); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4, xarg4); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 5, arg5, xarg5) + +#define SDT_PROBE_DEFINE7_XLATE(prov, mod, func, name, arg0, xarg0, \ + arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4, arg5, xarg5, arg6, \ + xarg6) \ + SDT_PROBE_DEFINE(prov, mod, func, name); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 0, arg0, xarg0); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 1, arg1, xarg1); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 2, arg2, xarg2); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 3, arg3, xarg3); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 4, arg4, xarg4); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 5, arg5, xarg5); \ + SDT_PROBE_ARGTYPE(prov, mod, func, name, 6, arg6, xarg6) #define SDT_PROBE0(prov, mod, func, name) \ SDT_PROBE(prov, mod, func, name, 0, 0, 0, 0, 0) @@ -294,28 +321,105 @@ struct sdt_provider { (uintptr_t)arg6); \ } while (0) -typedef int (*sdt_argtype_listall_func_t)(struct sdt_argtype *, void *); -typedef int (*sdt_probe_listall_func_t)(struct sdt_probe *, void *); -typedef int (*sdt_provider_listall_func_t)(struct sdt_provider *, void *); - -void sdt_argtype_deregister(void *); -void sdt_argtype_register(void *); -void sdt_probe_deregister(void *); -void sdt_probe_register(void *); -void sdt_provider_deregister(void *); -void sdt_provider_register(void *); -void sdt_probe_stub(u_int32_t, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, - uintptr_t arg3, uintptr_t arg4); -int sdt_argtype_listall(struct sdt_probe *, sdt_argtype_listall_func_t, void *); -int sdt_probe_listall(struct sdt_provider *, sdt_probe_listall_func_t, void *); -int sdt_provider_listall(sdt_provider_listall_func_t,void *); - -void sdt_register_callbacks(sdt_provider_listall_func_t, void *, - sdt_provider_listall_func_t, void *, sdt_probe_listall_func_t, void *); -void sdt_deregister_callbacks(void); +#define DTRACE_PROBE_IMPL_START(name, arg0, arg1, arg2, arg3, arg4) do { \ + static SDT_PROBE_DEFINE(sdt, , , name); \ + SDT_PROBE(sdt, , , name, arg0, arg1, arg2, arg3, arg4); +#define DTRACE_PROBE_IMPL_END } while (0) + +#define DTRACE_PROBE(name) \ + DTRACE_PROBE_IMPL_START(name, 0, 0, 0, 0, 0) \ + DTRACE_PROBE_IMPL_END + +#define DTRACE_PROBE1(name, type0, arg0) \ + DTRACE_PROBE_IMPL_START(name, arg0, 0, 0, 0, 0) \ + SDT_PROBE_ARGTYPE(sdt, , , name, 0, #type0, NULL); \ + DTRACE_PROBE_IMPL_END + +#define DTRACE_PROBE2(name, type0, arg0, type1, arg1) \ + DTRACE_PROBE_IMPL_START(name, arg0, arg1, 0, 0, 0) \ + SDT_PROBE_ARGTYPE(sdt, , , name, 0, #type0, NULL); \ + SDT_PROBE_ARGTYPE(sdt, , , name, 1, #type1, NULL); \ + DTRACE_PROBE_IMPL_END + +#define DTRACE_PROBE3(name, type0, arg0, type1, arg1, type2, arg2) \ + DTRACE_PROBE_IMPL_START(name, arg0, arg1, arg2, 0, 0) \ + SDT_PROBE_ARGTYPE(sdt, , , name, 0, #type0, NULL); \ + SDT_PROBE_ARGTYPE(sdt, , , name, 1, #type1, NULL); \ + SDT_PROBE_ARGTYPE(sdt, , , name, 2, #type2, NULL); \ + DTRACE_PROBE_IMPL_END + +#define DTRACE_PROBE4(name, type0, arg0, type1, arg1, type2, arg2, type3, arg3) \ + DTRACE_PROBE_IMPL_START(name, arg0, arg1, arg2, arg3, 0) \ + SDT_PROBE_ARGTYPE(sdt, , , name, 0, #type0, NULL); \ + SDT_PROBE_ARGTYPE(sdt, , , name, 1, #type1, NULL); \ + SDT_PROBE_ARGTYPE(sdt, , , name, 2, #type2, NULL); \ + SDT_PROBE_ARGTYPE(sdt, , , name, 3, #type3, NULL); \ + DTRACE_PROBE_IMPL_END + +#define DTRACE_PROBE5(name, type0, arg0, type1, arg1, type2, arg2, type3, arg3, \ + type4, arg4) \ + DTRACE_PROBE_IMPL_START(name, arg0, arg1, arg2, arg3, arg4) \ + SDT_PROBE_ARGTYPE(sdt, , , name, 0, #type0, NULL); \ + SDT_PROBE_ARGTYPE(sdt, , , name, 1, #type1, NULL); \ + SDT_PROBE_ARGTYPE(sdt, , , name, 2, #type2, NULL); \ + SDT_PROBE_ARGTYPE(sdt, , , name, 3, #type3, NULL); \ + SDT_PROBE_ARGTYPE(sdt, , , name, 4, #type4, NULL); \ + DTRACE_PROBE_IMPL_END #endif /* KDTRACE_HOOKS */ +/* + * This type definition must match that of dtrace_probe. It is defined this + * way to avoid having to rely on CDDL code. + */ +typedef void (*sdt_probe_func_t)(uint32_t, uintptr_t arg0, uintptr_t arg1, + uintptr_t arg2, uintptr_t arg3, uintptr_t arg4); + +/* + * The 'sdt' provider will set it to dtrace_probe when it loads. + */ +extern sdt_probe_func_t sdt_probe_func; + +struct sdt_probe; +struct sdt_provider; +struct linker_file; + +struct sdt_argtype { + int ndx; /* Argument index. */ + const char *type; /* Argument type string. */ + const char *xtype; /* Translated argument type. */ + TAILQ_ENTRY(sdt_argtype) + argtype_entry; /* Argument type list entry. */ + struct sdt_probe *probe; /* Ptr to the probe structure. */ +}; + +struct sdt_probe { + int version; /* Set to sizeof(struct sdt_probe). */ + struct sdt_provider *prov; /* Ptr to the provider structure. */ + TAILQ_ENTRY(sdt_probe) + probe_entry; /* SDT probe list entry. */ + TAILQ_HEAD(argtype_list_head, sdt_argtype) argtype_list; + const char *mod; + const char *func; + const char *name; + id_t id; /* DTrace probe ID. */ + int n_args; /* Number of arguments. */ + struct linker_file *sdtp_lf; /* Module in which we're defined. */ +}; + +struct sdt_provider { + char *name; /* Provider name. */ + TAILQ_ENTRY(sdt_provider) + prov_entry; /* SDT provider list entry. */ + uintptr_t id; /* DTrace provider ID. */ + int sdt_refs; /* Number of module references. */ +}; + +void sdt_probe_stub(uint32_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, + uintptr_t); + +SDT_PROVIDER_DECLARE(sdt); + #endif /* _KERNEL */ #endif /* _SYS_SDT_H */ diff --git a/freebsd/sys/sys/sockbuf.h b/freebsd/sys/sys/sockbuf.h index bfccd74f..84fd1aa1 100644 --- a/freebsd/sys/sys/sockbuf.h +++ b/freebsd/sys/sys/sockbuf.h @@ -127,6 +127,8 @@ int sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa, struct mbuf *m0, struct mbuf *control); int sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa, struct mbuf *m0, struct mbuf *control); +int sbappendaddr_nospacecheck_locked(struct sockbuf *sb, + const struct sockaddr *asa, struct mbuf *m0, struct mbuf *control); int sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control); int sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0, diff --git a/freebsd/sys/sys/sysctl.h b/freebsd/sys/sys/sysctl.h index cf7b90ce..1fca343c 100644 --- a/freebsd/sys/sys/sysctl.h +++ b/freebsd/sys/sys/sysctl.h @@ -593,6 +593,7 @@ SYSCTL_ALLOWED_TYPES(UINT64, uint64_t *a; unsigned long long *b; ); #define KERN_PROC_PS_STRINGS 38 /* get ps_strings location */ #define KERN_PROC_UMASK 39 /* process umask */ #define KERN_PROC_OSREL 40 /* osreldate for process binary */ +#define KERN_PROC_SIGTRAMP 41 /* signal trampoline location */ /* * KERN_IPC identifiers diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h index 5b7b190a..ed58a487 100644 --- a/freebsd/sys/sys/sysproto.h +++ b/freebsd/sys/sys/sysproto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: stable/9/sys/kern/syscalls.master 251051 2013-05-28 05:51:00Z kib + * created from FreeBSD: stable/9/sys/kern/syscalls.master 260208 2014-01-02 21:57:03Z jhb */ #ifndef _SYS_SYSPROTO_H_ @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -765,6 +766,11 @@ struct nanosleep_args { char rqtp_l_[PADL_(const struct timespec *)]; const struct timespec * rqtp; char rqtp_r_[PADR_(const struct timespec *)]; char rmtp_l_[PADL_(struct timespec *)]; struct timespec * rmtp; char rmtp_r_[PADR_(struct timespec *)]; }; +struct clock_getcpuclockid2_args { + char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)]; + char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)]; + char clock_id_l_[PADL_(clockid_t *)]; clockid_t * clock_id; char clock_id_r_[PADR_(clockid_t *)]; +}; struct ntp_gettime_args { char ntvp_l_[PADL_(struct ntptimeval *)]; struct ntptimeval * ntvp; char ntvp_r_[PADR_(struct ntptimeval *)]; }; @@ -1785,13 +1791,19 @@ struct posix_fadvise_args { char advice_l_[PADL_(int)]; int advice; char advice_r_[PADR_(int)]; }; struct wait6_args { - char idtype_l_[PADL_(int)]; int idtype; char idtype_r_[PADR_(int)]; + char idtype_l_[PADL_(idtype_t)]; idtype_t idtype; char idtype_r_[PADR_(idtype_t)]; char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)]; char status_l_[PADL_(int *)]; int * status; char status_r_[PADR_(int *)]; char options_l_[PADL_(int)]; int options; char options_r_[PADR_(int)]; char wrusage_l_[PADL_(struct __wrusage *)]; struct __wrusage * wrusage; char wrusage_r_[PADR_(struct __wrusage *)]; char info_l_[PADL_(siginfo_t *)]; siginfo_t * info; char info_r_[PADR_(siginfo_t *)]; }; +struct procctl_args { + char idtype_l_[PADL_(idtype_t)]; idtype_t idtype; char idtype_r_[PADR_(idtype_t)]; + char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)]; + char com_l_[PADL_(int)]; int com; char com_r_[PADR_(int)]; + char data_l_[PADL_(void *)]; void * data; char data_r_[PADR_(void *)]; +}; 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 *); @@ -1947,6 +1959,7 @@ int sys_ktimer_settime(struct thread *, struct ktimer_settime_args *); int sys_ktimer_gettime(struct thread *, struct ktimer_gettime_args *); int sys_ktimer_getoverrun(struct thread *, struct ktimer_getoverrun_args *); int sys_nanosleep(struct thread *, struct nanosleep_args *); +int sys_clock_getcpuclockid2(struct thread *, struct clock_getcpuclockid2_args *); int sys_ntp_gettime(struct thread *, struct ntp_gettime_args *); int sys_minherit(struct thread *, struct minherit_args *); int sys_rfork(struct thread *, struct rfork_args *); @@ -2170,6 +2183,7 @@ int sys_rctl_remove_rule(struct thread *, struct rctl_remove_rule_args *); int sys_posix_fallocate(struct thread *, struct posix_fallocate_args *); int sys_posix_fadvise(struct thread *, struct posix_fadvise_args *); int sys_wait6(struct thread *, struct wait6_args *); +int sys_procctl(struct thread *, struct procctl_args *); #ifdef COMPAT_43 @@ -2635,6 +2649,7 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *); #define SYS_AUE_ktimer_gettime AUE_NULL #define SYS_AUE_ktimer_getoverrun AUE_NULL #define SYS_AUE_nanosleep AUE_NULL +#define SYS_AUE_clock_getcpuclockid2 AUE_NULL #define SYS_AUE_ntp_gettime AUE_NULL #define SYS_AUE_minherit AUE_MINHERIT #define SYS_AUE_rfork AUE_RFORK @@ -2862,6 +2877,7 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *); #define SYS_AUE_posix_fallocate AUE_NULL #define SYS_AUE_posix_fadvise AUE_NULL #define SYS_AUE_wait6 AUE_WAIT6 +#define SYS_AUE_procctl AUE_NULL #endif /* __rtems__ */ #undef PAD_ diff --git a/freebsd/sys/sys/systm.h b/freebsd/sys/sys/systm.h index 44d2208f..18ca646f 100644 --- a/freebsd/sys/sys/systm.h +++ b/freebsd/sys/sys/systm.h @@ -156,7 +156,9 @@ extern const void *zero_region; /* address space maps to a zeroed page */ extern int unmapped_buf_allowed; extern int iosize_max_clamp; +extern int devfs_iosize_max_clamp; #define IOSIZE_MAX (iosize_max_clamp ? INT_MAX : SSIZE_MAX) +#define DEVFS_IOSIZE_MAX (devfs_iosize_max_clamp ? INT_MAX : SSIZE_MAX) /* * General function declarations. diff --git a/freebsd/sys/sys/taskqueue.h b/freebsd/sys/sys/taskqueue.h index b4c7d208..68000026 100644 --- a/freebsd/sys/sys/taskqueue.h +++ b/freebsd/sys/sys/taskqueue.h @@ -71,6 +71,7 @@ int taskqueue_cancel_timeout(struct taskqueue *queue, void taskqueue_drain(struct taskqueue *queue, struct task *task); void taskqueue_drain_timeout(struct taskqueue *queue, struct timeout_task *timeout_task); +void taskqueue_drain_all(struct taskqueue *queue); void taskqueue_free(struct taskqueue *queue); void taskqueue_run(struct taskqueue *queue); void taskqueue_block(struct taskqueue *queue); diff --git a/freebsd/sys/sys/tty.h b/freebsd/sys/sys/tty.h index 70617205..00cf4e6c 100644 --- a/freebsd/sys/sys/tty.h +++ b/freebsd/sys/sys/tty.h @@ -166,6 +166,7 @@ void tty_rel_gone(struct tty *tp); #define tty_lock(tp) mtx_lock((tp)->t_mtx) #define tty_unlock(tp) mtx_unlock((tp)->t_mtx) +#define tty_lock_owned(tp) mtx_owned((tp)->t_mtx) #define tty_lock_assert(tp,ma) mtx_assert((tp)->t_mtx, (ma)) #define tty_getlock(tp) ((tp)->t_mtx) @@ -192,6 +193,7 @@ int tty_ioctl(struct tty *tp, u_long cmd, void *data, int fflag, struct thread *td); int tty_ioctl_compat(struct tty *tp, u_long cmd, caddr_t data, int fflag, struct thread *td); +void tty_set_winsize(struct tty *tp, const struct winsize *wsz); void tty_init_console(struct tty *tp, speed_t speed); void tty_flush(struct tty *tp, int flags); void tty_hiwat_in_block(struct tty *tp); diff --git a/freebsd/sys/sys/user.h b/freebsd/sys/sys/user.h index 46401674..659a610c 100644 --- a/freebsd/sys/sys/user.h +++ b/freebsd/sys/sys/user.h @@ -83,7 +83,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 9 +#define KI_NSPARE_INT 7 #define KI_NSPARE_LONG 12 #define KI_NSPARE_PTR 6 @@ -186,6 +186,8 @@ struct kinfo_proc { */ char ki_sparestrings[50]; /* spare string space */ int ki_spareints[KI_NSPARE_INT]; /* spare room for growth */ + int ki_flag2; /* P2_* flags */ + int ki_fibnum; /* Default FIB number */ u_int ki_cr_flags; /* Credential flags */ int ki_jid; /* Process jail ID */ int ki_numthreads; /* XXXKSE number of threads in total */ @@ -407,6 +409,7 @@ struct kinfo_file { #define KVME_TYPE_PHYS 5 #define KVME_TYPE_DEAD 6 #define KVME_TYPE_SG 7 +#define KVME_TYPE_MGTDEVICE 8 #define KVME_TYPE_UNKNOWN 255 #define KVME_PROT_READ 0x00000001 @@ -496,6 +499,12 @@ struct kinfo_kstack { int _kkst_ispare[16]; /* Space for more stuff. */ }; +struct kinfo_sigtramp { + void *ksigtramp_start; + void *ksigtramp_end; + void *ksigtramp_spare[4]; +}; + #ifdef _KERNEL /* Flags for kern_proc_out function. */ #define KERN_PROC_NOTHREADS 0x1 diff --git a/freebsd/sys/vm/uma_core.c b/freebsd/sys/vm/uma_core.c index e147c2a7..8a88caaf 100644 --- a/freebsd/sys/vm/uma_core.c +++ b/freebsd/sys/vm/uma_core.c @@ -1154,7 +1154,9 @@ keg_small_init(uma_keg_t keg) keg->uk_rsize = rsize; keg->uk_ppera = 1; - if (keg->uk_flags & UMA_ZONE_REFCNT) { + if (keg->uk_flags & UMA_ZONE_OFFPAGE) { + shsize = 0; + } else if (keg->uk_flags & UMA_ZONE_REFCNT) { rsize += UMA_FRITMREF_SZ; /* linkage & refcnt */ shsize = sizeof(struct uma_slab_refcnt); } else { @@ -1265,7 +1267,7 @@ keg_cachespread_init(uma_keg_t keg) keg->uk_ipers = ((pages * PAGE_SIZE) + trailer) / rsize; keg->uk_flags |= UMA_ZONE_OFFPAGE | UMA_ZONE_VTOSLAB; KASSERT(keg->uk_ipers <= uma_max_ipers, - ("keg_small_init: keg->uk_ipers too high(%d) increase max_ipers", + ("%s: keg->uk_ipers too high(%d) increase max_ipers", __func__, keg->uk_ipers)); } @@ -1547,8 +1549,9 @@ keg_dtor(void *arg, int size, void *udata) keg = (uma_keg_t)arg; KEG_LOCK(keg); if (keg->uk_free != 0) { - printf("Freed UMA keg was not empty (%d items). " + printf("Freed UMA keg (%s) was not empty (%d items). " " Lost %d pages of memory.\n", + keg->uk_name ? keg->uk_name : "", keg->uk_free, keg->uk_pages); } KEG_UNLOCK(keg); @@ -1720,7 +1723,7 @@ uma_startup(void *bootmem, int boot_pages) #ifdef UMA_DEBUG printf("Calculated uma_max_ipers (for OFFPAGE) is %d\n", uma_max_ipers); - printf("Calculated uma_max_ipers_slab (for OFFPAGE) is %d\n", + printf("Calculated uma_max_ipers_ref (for OFFPAGE) is %d\n", uma_max_ipers_ref); #endif diff --git a/freebsd/sys/vm/vm.h b/freebsd/sys/vm/vm.h index 106c510c..17aea47e 100644 --- a/freebsd/sys/vm/vm.h +++ b/freebsd/sys/vm/vm.h @@ -151,6 +151,7 @@ int swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred); void swap_reserve_force(vm_ooffset_t incr); void swap_release(vm_ooffset_t decr); void swap_release_by_cred(vm_ooffset_t decr, struct ucred *cred); +void swapper(void); #endif /* VM_H */ diff --git a/freebsd/sys/vm/vm_extern.h b/freebsd/sys/vm/vm_extern.h index 8b6c7ac5..3b5be268 100644 --- a/freebsd/sys/vm/vm_extern.h +++ b/freebsd/sys/vm/vm_extern.h @@ -44,8 +44,8 @@ vm_offset_t kmem_alloc(vm_map_t, vm_size_t); vm_offset_t kmem_alloc_attr(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low, vm_paddr_t high, vm_memattr_t memattr); vm_offset_t kmem_alloc_contig(vm_map_t map, vm_size_t size, int flags, - vm_paddr_t low, vm_paddr_t high, unsigned long alignment, - unsigned long boundary, vm_memattr_t memattr); + vm_paddr_t low, vm_paddr_t high, u_long alignment, u_long boundary, + vm_memattr_t memattr); vm_offset_t kmem_alloc_nofault(vm_map_t, vm_size_t); vm_offset_t kmem_alloc_nofault_space(vm_map_t, vm_size_t, int); vm_offset_t kmem_alloc_wait(vm_map_t, vm_size_t); diff --git a/freebsd/usr.bin/netstat/main.c b/freebsd/usr.bin/netstat/main.c index f3d1003f..1caecbe0 100644 --- a/freebsd/usr.bin/netstat/main.c +++ b/freebsd/usr.bin/netstat/main.c @@ -444,9 +444,23 @@ main(int argc, char *argv[]) af = AF_UNSPEC; - while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:Qq:rSTsuWw:xz")) + while ((ch = getopt(argc, argv, "46AaBbdf:ghI:iLlM:mN:np:Qq:rSTsuWw:xz")) != -1) switch(ch) { + case '4': +#ifdef INET + af = AF_INET; +#else + errx(1, "IPv4 support is not compiled in"); +#endif + break; + case '6': +#ifdef INET6 + af = AF_INET6; +#else + errx(1, "IPv6 support is not compiled in"); +#endif + break; case 'A': Aflag = 1; break; @@ -891,21 +905,21 @@ static void usage(void) { (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", -"usage: netstat [-AaLnSTWx] [-f protocol_family | -p protocol]\n" +"usage: netstat [-46AaLnSTWx] [-f protocol_family | -p protocol]\n" " [-M core] [-N system]", -" netstat -i | -I interface [-abdhnW] [-f address_family]\n" +" netstat -i | -I interface [-46abdhnW] [-f address_family]\n" " [-M core] [-N system]", -" netstat -w wait [-I interface] [-d] [-M core] [-N system] [-q howmany]", -" netstat -s [-s] [-z] [-f protocol_family | -p protocol]\n" +" netstat -w wait [-I interface] [-46d] [-M core] [-N system] [-q howmany]", +" netstat -s [-s] [-46z] [-f protocol_family | -p protocol]\n" " [-M core] [-N system]", -" netstat -i | -I interface -s [-f protocol_family | -p protocol]\n" +" netstat -i | -I interface [-46s] [-f protocol_family | -p protocol]\n" " [-M core] [-N system]", " netstat -m [-M core] [-N system]", " netstat -B [-I interface]", -" netstat -r [-AanW] [-f address_family] [-M core] [-N system]", +" netstat -r [-46AanW] [-f address_family] [-M core] [-N system]", " netstat -rs [-s] [-M core] [-N system]", -" netstat -g [-W] [-f address_family] [-M core] [-N system]", -" netstat -gs [-s] [-f address_family] [-M core] [-N system]", +" netstat -g [-46W] [-f address_family] [-M core] [-N system]", +" netstat -gs [-46s] [-f address_family] [-M core] [-N system]", " netstat -Q"); exit(1); } diff --git a/rtemsbsd/include/rtems/bsd/local/miidevs.h b/rtemsbsd/include/rtems/bsd/local/miidevs.h index 66cb2ac8..e7646c8d 100644 --- a/rtemsbsd/include/rtems/bsd/local/miidevs.h +++ b/rtemsbsd/include/rtems/bsd/local/miidevs.h @@ -59,6 +59,7 @@ #define MII_OUI_BROADCOM 0x001018 /* Broadcom Corporation */ #define MII_OUI_BROADCOM2 0x000af7 /* Broadcom Corporation */ #define MII_OUI_BROADCOM3 0x001be9 /* Broadcom Corporation */ +#define MII_OUI_BROADCOM4 0x18c086 /* Broadcom Corporation */ #define MII_OUI_CICADA 0x0003F1 /* Cicada Semiconductor */ #define MII_OUI_DAVICOM 0x00606e /* Davicom Semiconductor */ #define MII_OUI_ENABLESEMI 0x0010dd /* Enable Semiconductor */ @@ -251,6 +252,8 @@ #define MII_STR_BROADCOM3_BCM57765 "BCM57765 1000BASE-T media interface" #define MII_MODEL_BROADCOM3_BCM5720C 0x0036 #define MII_STR_BROADCOM3_BCM5720C "BCM5720C 1000BASE-T media interface" +#define MII_MODEL_BROADCOM4_BCM5725C 0x0038 +#define MII_STR_BROADCOM4_BCM5725C "BCM5725C 1000BASE-T media interface" #define MII_MODEL_xxBROADCOM_ALT1_BCM5906 0x0004 #define MII_STR_xxBROADCOM_ALT1_BCM5906 "BCM5906 10/100baseTX media interface" @@ -449,6 +452,8 @@ #define MII_STR_REALTEK_RTL8305SC "RTL8305SC 10/100 802.1q switch" #define MII_MODEL_REALTEK_RTL8201E 0x0008 #define MII_STR_REALTEK_RTL8201E "RTL8201E 10/100 media interface" +#define MII_MODEL_REALTEK_RTL8251 0x0000 +#define MII_STR_REALTEK_RTL8251 "RTL8251 1000BASE-T media interface" #define MII_MODEL_REALTEK_RTL8169S 0x0011 #define MII_STR_REALTEK_RTL8169S "RTL8169S/8110S/8211 1000BASE-T media interface" diff --git a/rtemsbsd/include/rtems/bsd/local/usbdevs.h b/rtemsbsd/include/rtems/bsd/local/usbdevs.h index 0a3d105c..3543d85a 100644 --- a/rtemsbsd/include/rtems/bsd/local/usbdevs.h +++ b/rtemsbsd/include/rtems/bsd/local/usbdevs.h @@ -522,11 +522,13 @@ #define USB_VENDOR_AMBIT 0x0bb2 /* Ambit Microsystems */ #define USB_VENDOR_HTC 0x0bb4 /* HTC */ #define USB_VENDOR_REALTEK 0x0bda /* Realtek */ +#define USB_VENDOR_ERICSSON2 0x0bdb /* Ericsson */ #define USB_VENDOR_MEI 0x0bed /* MEI */ #define USB_VENDOR_ADDONICS2 0x0bf6 /* Addonics Technology */ #define USB_VENDOR_FSC 0x0bf8 /* Fujitsu Siemens Computers */ #define USB_VENDOR_AGATE 0x0c08 /* Agate Technologies */ #define USB_VENDOR_DMI 0x0c0b /* DMI */ +#define USB_VENDOR_CANYON 0x0c10 /* Canyon */ #define USB_VENDOR_ICOM 0x0c26 /* Icom Inc. */ #define USB_VENDOR_GNOTOMETRICS 0x0c33 /* GN Otometrics */ #define USB_VENDOR_CHICONY2 0x0c45 /* Chicony */ @@ -574,10 +576,12 @@ #define USB_VENDOR_RIM 0x0fca /* Research In Motion */ #define USB_VENDOR_DYNASTREAM 0x0fcf /* Dynastream Innovations */ #define USB_VENDOR_LARSENBRUSGAARD 0x0fd8 /* Larsen and Brusgaard */ +#define USB_VENDOR_OWL 0x0fde /* OWL */ #define USB_VENDOR_KONTRON 0x0fe6 /* Kontron AG */ #define USB_VENDOR_QUALCOMM 0x1004 /* Qualcomm */ #define USB_VENDOR_APACER 0x1005 /* Apacer */ #define USB_VENDOR_MOTOROLA4 0x100d /* Motorola */ +#define USB_VENDOR_HP3 0x103c /* Hewlett Packard */ #define USB_VENDOR_AIRPLUS 0x1011 /* Airplus */ #define USB_VENDOR_DESKNOTE 0x1019 /* Desknote */ #define USB_VENDOR_NEC3 0x1033 /* NEC */ @@ -589,6 +593,7 @@ #define USB_VENDOR_CURITEL 0x106c /* Curitel Communications Inc */ #define USB_VENDOR_SILABS2 0x10a6 /* SILABS2 */ #define USB_VENDOR_USI 0x10ab /* USI */ +#define USB_VENDOR_LIEBERT2 0x10af /* Liebert */ #define USB_VENDOR_PLX 0x10b5 /* PLX */ #define USB_VENDOR_ASANTE 0x10bd /* Asante */ #define USB_VENDOR_SILABS 0x10c4 /* Silicon Labs */ @@ -645,6 +650,7 @@ #define USB_VENDOR_SILICOM 0x1485 /* Silicom */ #define USB_VENDOR_RALINK 0x148f /* Ralink Technology */ #define USB_VENDOR_IMAGINATION 0x149a /* Imagination Technologies */ +#define USB_VENDOR_ATP 0x14af /* ATP Electronics */ #define USB_VENDOR_CONCEPTRONIC2 0x14b2 /* Conceptronic */ #define USB_VENDOR_SUPERTOP 0x14cd /* Super Top */ #define USB_VENDOR_PLANEX3 0x14ea /* Planex Communications */ @@ -657,6 +663,8 @@ #define USB_VENDOR_OQO 0x1557 /* OQO */ #define USB_VENDOR_UMEDIA 0x157e /* U-MEDIA Communications */ #define USB_VENDOR_FIBERLINE 0x1582 /* Fiberline */ +#define USB_VENDOR_FREESCALE 0x15a2 /* Freescale Semiconductor, Inc. */ +#define USB_VENDOR_AFATECH 0x15a4 /* Afatech Technologies, Inc. */ #define USB_VENDOR_SPARKLAN 0x15a9 /* SparkLAN */ #define USB_VENDOR_OLIMEX 0x15ba /* Olimex */ #define USB_VENDOR_SOUNDGRAPH 0x15c2 /* Soundgraph, Inc. */ @@ -697,6 +705,7 @@ #define USB_VENDOR_BAYER 0x1a79 /* Bayer */ #define USB_VENDOR_WCH2 0x1a86 /* QinHeng Electronics */ #define USB_VENDOR_STELERA 0x1a8d /* Stelera Wireless */ +#define USB_VENDOR_SEL 0x1adb /* Schweitzer Engineering Laboratories */ #define USB_VENDOR_CORSAIR 0x1b1c /* Corsair */ #define USB_VENDOR_MATRIXORBITAL 0x1b3d /* Matrix Orbital */ #define USB_VENDOR_OVISLINK 0x1b75 /* OvisLink */ @@ -717,6 +726,7 @@ #define USB_VENDOR_ALINK 0x1e0e /* Alink */ #define USB_VENDOR_AIRTIES 0x1eda /* AirTies */ #define USB_VENDOR_FESTO 0x1e29 /* Festo */ +#define USB_VENDOR_LAKESHORE 0x1fb9 /* Lake Shore Cryotronics, Inc. */ #define USB_VENDOR_VERTEX 0x1fe7 /* Vertex Wireless Co., Ltd. */ #define USB_VENDOR_DLINK 0x2001 /* D-Link */ #define USB_VENDOR_PLANEX2 0x2019 /* Planex Communications */ @@ -726,10 +736,13 @@ #define USB_VENDOR_QIHARDWARE 0x20b7 /* QI-hardware */ #define USB_VENDOR_PARA 0x20b8 /* PARA Industrial */ #define USB_VENDOR_SIMTEC 0x20df /* Simtec Electronics */ +#define USB_VENDOR_TRENDNET 0x20f4 /* TRENDnet */ #define USB_VENDOR_RTSYSTEMS 0x2100 /* RTSYSTEMS */ #define USB_VENDOR_VIALABS 0x2109 /* VIA Labs */ #define USB_VENDOR_ERICSSON 0x2282 /* Ericsson */ #define USB_VENDOR_MOTOROLA2 0x22b8 /* Motorola */ +#define USB_VENDOR_WETELECOM 0x22de /* WeTelecom */ +#define USB_VENDOR_WESTMOUNTAIN 0x2405 /* West Mountain Radio */ #define USB_VENDOR_TRIPPLITE 0x2478 /* Tripp-Lite */ #define USB_VENDOR_HIROSE 0x2631 /* Hirose Electric */ #define USB_VENDOR_NHJ 0x2770 /* NHJ */ @@ -747,6 +760,7 @@ #define USB_VENDOR_DELL 0x413c /* Dell */ #define USB_VENDOR_WCH 0x4348 /* QinHeng Electronics */ #define USB_VENDOR_ACEECA 0x4766 /* Aceeca */ +#define USB_VENDOR_FEIXUN 0x4855 /* FeiXun Communication */ #define USB_VENDOR_PAPOUCH 0x5050 /* Papouch products */ #define USB_VENDOR_AVERATEC 0x50c2 /* Averatec */ #define USB_VENDOR_SWEEX 0x5173 /* Sweex */ @@ -762,6 +776,7 @@ #define USB_VENDOR_ALLWIN 0x8516 /* ALLWIN Tech */ #define USB_VENDOR_SITECOM2 0x9016 /* Sitecom */ #define USB_VENDOR_MOSCHIP 0x9710 /* MosChip Semiconductor */ +#define USB_VENDOR_NETGEAR4 0x9846 /* Netgear */ #define USB_VENDOR_MARVELL 0x9e88 /* Marvell Technology Group Ltd. */ #define USB_VENDOR_3COM3 0xa727 /* 3Com */ #define USB_VENDOR_EVOLUTION 0xdeee /* Evolution Robotics products */ @@ -819,6 +834,9 @@ #define USB_PRODUCT_ABOCOM_RT2573_2 0xb21c /* RT2573 */ #define USB_PRODUCT_ABOCOM_RT2573_3 0xb21d /* RT2573 */ #define USB_PRODUCT_ABOCOM_RT2573_4 0xb21e /* RT2573 */ +#define USB_PRODUCT_ABOCOM_RTL8188CU_1 0x8188 /* RTL8188CU */ +#define USB_PRODUCT_ABOCOM_RTL8188CU_2 0x8189 /* RTL8188CU */ +#define USB_PRODUCT_ABOCOM_RTL8192CU 0x8178 /* RTL8192CU */ #define USB_PRODUCT_ABOCOM_WUG2700 0xb21f /* WUG2700 */ /* Acton Research Corp. */ @@ -846,6 +864,7 @@ #define USB_PRODUCT_ACCTON_RT2870_1 0xb522 /* RT2870 */ #define USB_PRODUCT_ACCTON_RT3070_3 0xc522 /* RT3070 */ #define USB_PRODUCT_ACCTON_RT3070_5 0xd522 /* RT3070 */ +#define USB_PRODUCT_ACCTON_RTL8192SU 0xc512 /* RTL8192SU */ #define USB_PRODUCT_ACCTON_ZD1211B 0xe501 /* ZD1211B */ /* Aceeca products */ @@ -923,6 +942,9 @@ /* AEI products */ #define USB_PRODUCT_AEI_FASTETHERNET 0x1701 /* Fast Ethernet */ +/* Afatech Technologies, Inc. */ +#define USB_PRODUCT_AFATECH_AFATECH1336 0x1336 /* Flash Card Reader */ + /* Agate Technologies products */ #define USB_PRODUCT_AGATE_QDRIVE 0x0378 /* Q-Drive */ @@ -1062,12 +1084,54 @@ #define USB_PRODUCT_APPLE_IMAC_KBD 0x0201 /* USB iMac Keyboard */ #define USB_PRODUCT_APPLE_KBD 0x0202 /* USB Keyboard M2452 */ #define USB_PRODUCT_APPLE_EXT_KBD 0x020c /* Apple Extended USB Keyboard */ -#define USB_PRODUCT_APPLE_KBD_TP_ANSI 0x0223 /* Apple Internal Keyboard/Trackpad (Wellspring/ANSI) */ -#define USB_PRODUCT_APPLE_KBD_TP_ISO 0x0224 /* Apple Internal Keyboard/Trackpad (Wellspring/ISO) */ -#define USB_PRODUCT_APPLE_KBD_TP_JIS 0x0225 /* Apple Internal Keyboard/Trackpad (Wellspring/JIS) */ -#define USB_PRODUCT_APPLE_KBD_TP_ANSI2 0x0230 /* Apple Internal Keyboard/Trackpad (Wellspring2/ANSI) */ -#define USB_PRODUCT_APPLE_KBD_TP_ISO2 0x0231 /* Apple Internal Keyboard/Trackpad (Wellspring2/ISO) */ -#define USB_PRODUCT_APPLE_KBD_TP_JIS2 0x0232 /* Apple Internal Keyboard/Trackpad (Wellspring2/JIS) */ +/* MacbookAir, aka wellspring */ +#define USB_PRODUCT_APPLE_WELLSPRING_ANSI 0x0223 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING_ISO 0x0224 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING_JIS 0x0225 /* Apple Internal Keyboard/Trackpad */ +/* MacbookProPenryn, aka wellspring2 */ +#define USB_PRODUCT_APPLE_WELLSPRING2_ANSI 0x0230 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING2_ISO 0x0231 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING2_JIS 0x0232 /* Apple Internal Keyboard/Trackpad */ +/* Macbook5,1 (unibody), aka wellspring3 */ +#define USB_PRODUCT_APPLE_WELLSPRING3_ANSI 0x0236 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING3_ISO 0x0237 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING3_JIS 0x0238 /* Apple Internal Keyboard/Trackpad */ +/* MacbookAir3,2 (unibody), aka wellspring4 */ +#define USB_PRODUCT_APPLE_WELLSPRING4_ANSI 0x023f /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING4_ISO 0x0240 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING4_JIS 0x0241 /* Apple Internal Keyboard/Trackpad */ +/* MacbookAir3,1 (unibody), aka wellspring4 */ +#define USB_PRODUCT_APPLE_WELLSPRING4A_ANSI 0x0242 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING4A_ISO 0x0243 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING4A_JIS 0x0244 /* Apple Internal Keyboard/Trackpad */ +/* Macbook8 (unibody, March 2011) */ +#define USB_PRODUCT_APPLE_WELLSPRING5_ANSI 0x0245 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING5_ISO 0x0246 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING5_JIS 0x0247 /* Apple Internal Keyboard/Trackpad */ +/* MacbookAir4,1 (unibody, July 2011) */ +#define USB_PRODUCT_APPLE_WELLSPRING6A_ANSI 0x0249 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING6A_ISO 0x024a /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING6A_JIS 0x024b /* Apple Internal Keyboard/Trackpad */ +/* MacbookAir4,2 (unibody, July 2011) */ +#define USB_PRODUCT_APPLE_WELLSPRING6_ANSI 0x024c /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING6_ISO 0x024d /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING6_JIS 0x024e /* Apple Internal Keyboard/Trackpad */ +/* Macbook8,2 (unibody) */ +#define USB_PRODUCT_APPLE_WELLSPRING5A_ANSI 0x0252 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING5A_ISO 0x0253 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING5A_JIS 0x0254 /* Apple Internal Keyboard/Trackpad */ +/* MacbookPro10,1 (unibody, June 2012) */ +#define USB_PRODUCT_APPLE_WELLSPRING7_ANSI 0x0262 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING7_ISO 0x0263 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING7_JIS 0x0264 /* Apple Internal Keyboard/Trackpad */ +/* MacbookPro10,2 (unibody, October 2012) */ +#define USB_PRODUCT_APPLE_WELLSPRING7A_ANSI 0x0259 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING7A_ISO 0x025a /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING7A_JIS 0x025b /* Apple Internal Keyboard/Trackpad */ +/* MacbookAir6,2 (unibody, June 2013) */ +#define USB_PRODUCT_APPLE_WELLSPRING8_ANSI 0x0290 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING8_ISO 0x0291 /* Apple Internal Keyboard/Trackpad */ +#define USB_PRODUCT_APPLE_WELLSPRING8_JIS 0x0292 /* Apple Internal Keyboard/Trackpad */ #define USB_PRODUCT_APPLE_MOUSE 0x0301 /* Mouse M4848 */ #define USB_PRODUCT_APPLE_OPTMOUSE 0x0302 /* Optical mouse */ #define USB_PRODUCT_APPLE_MIGHTYMOUSE 0x0304 /* Mighty Mouse */ @@ -1107,6 +1171,8 @@ /* ASIX Electronics products */ #define USB_PRODUCT_ASIX_AX88172 0x1720 /* 10/100 Ethernet */ #define USB_PRODUCT_ASIX_AX88178 0x1780 /* AX88178 */ +#define USB_PRODUCT_ASIX_AX88178A 0x178a /* AX88178A USB 2.0 10/100/1000 Ethernet */ +#define USB_PRODUCT_ASIX_AX88179 0x1790 /* AX88179 USB 3.0 10/100/1000 Ethernet */ #define USB_PRODUCT_ASIX_AX88772 0x7720 /* AX88772 */ #define USB_PRODUCT_ASIX_AX88772A 0x772a /* AX88772A USB 2.0 10/100 Ethernet */ #define USB_PRODUCT_ASIX_AX88772B 0x772b /* AX88772B USB 2.0 10/100 Ethernet */ @@ -1128,6 +1194,10 @@ #define USB_PRODUCT_ASUS_RT2870_5 0x1761 /* RT2870 */ #define USB_PRODUCT_ASUS_USBN13 0x1784 /* USB-N13 */ #define USB_PRODUCT_ASUS_RT3070_1 0x1790 /* RT3070 */ +#define USB_PRODUCT_ASUS_USBN10 0x1786 /* USB-N10 */ +#define USB_PRODUCT_ASUS_RTL8192CU 0x17ab /* RTL8192CU */ +#define USB_PRODUCT_ASUS_USBN66 0x17ad /* USB-N66 */ +#define USB_PRODUCT_ASUS_RTL8192SU 0x1791 /* RTL8192SU */ #define USB_PRODUCT_ASUS_A730W 0x4202 /* ASUS MyPal A730W */ #define USB_PRODUCT_ASUS_P535 0x420f /* ASUS P535 PDA */ #define USB_PRODUCT_ASUS_GMSC 0x422f /* ASUS Generic Mass Storage */ @@ -1142,6 +1212,9 @@ #define USB_PRODUCT_ATEN_UC210T 0x2009 /* UC-210T Ethernet */ #define USB_PRODUCT_ATEN_DSB650C 0x4000 /* DSB-650C */ +/* ATP Electronics products */ +#define USB_PRODUCT_ATP_EUSB 0xaf01 /* ATP IG eUSB SSD */ + /* Atheros Communications products */ #define USB_PRODUCT_ATHEROS_AR5523 0x0001 /* AR5523 */ #define USB_PRODUCT_ATHEROS_AR5523_NF 0x0002 /* AR5523 (no firmware) */ @@ -1175,6 +1248,14 @@ #define USB_PRODUCT_AZUREWAVE_RT3070_1 0x3273 /* RT3070 */ #define USB_PRODUCT_AZUREWAVE_RT3070_2 0x3284 /* RT3070 */ #define USB_PRODUCT_AZUREWAVE_RT3070_3 0x3305 /* RT3070 */ +#define USB_PRODUCT_AZUREWAVE_RTL8188CU 0x3357 /* RTL8188CU */ +#define USB_PRODUCT_AZUREWAVE_RTL8188CE_1 0x3358 /* RTL8188CE */ +#define USB_PRODUCT_AZUREWAVE_RTL8188CE_2 0x3359 /* RTL8188CE */ +#define USB_PRODUCT_AZUREWAVE_RTL8192SU_1 0x3306 /* RTL8192SU */ +#define USB_PRODUCT_AZUREWAVE_RTL8192SU_2 0x3309 /* RTL8192SU */ +#define USB_PRODUCT_AZUREWAVE_RTL8192SU_3 0x3310 /* RTL8192SU */ +#define USB_PRODUCT_AZUREWAVE_RTL8192SU_4 0x3311 /* RTL8192SU */ +#define USB_PRODUCT_AZUREWAVE_RTL8192SU_5 0x3325 /* RTL8192SU */ /* Baltech products */ #define USB_PRODUCT_BALTECH_CARDREADER 0x9999 /* Card reader */ @@ -1217,6 +1298,10 @@ #define USB_PRODUCT_BELKIN_F5U409 0x0409 /* F5U409 Serial */ #define USB_PRODUCT_BELKIN_F6C550AVR 0x0551 /* F6C550-AVR UPS */ #define USB_PRODUCT_BELKIN_F5U120 0x1203 /* F5U120-PC Hub */ +#define USB_PRODUCT_BELKIN_RTL8188CU 0x1102 /* RTL8188CU Wireless Adapter */ +#define USB_PRODUCT_BELKIN_F9L1103 0x1103 /* F9L1103 Wireless Adapter */ +#define USB_PRODUCT_BELKIN_RTL8192CU 0x2102 /* RTL8192CU Wireless Adapter */ +#define USB_PRODUCT_BELKIN_F7D2102 0x2103 /* F7D2102 Wireless Adapter */ #define USB_PRODUCT_BELKIN_ZD1211B 0x4050 /* ZD1211B */ #define USB_PRODUCT_BELKIN_F5D5055 0x5055 /* F5D5055 */ #define USB_PRODUCT_BELKIN_F5D7050 0x7050 /* F5D7050 Wireless Adapter */ @@ -1228,11 +1313,15 @@ #define USB_PRODUCT_BELKIN_RT2870_1 0x8053 /* RT2870 */ #define USB_PRODUCT_BELKIN_RT2870_2 0x805c /* RT2870 */ #define USB_PRODUCT_BELKIN_F5D8053V3 0x815c /* F5D8053 v3 */ +#define USB_PRODUCT_BELKIN_RTL8192SU_1 0x815f /* RTL8192SU */ +#define USB_PRODUCT_BELKIN_RTL8192SU_2 0x845a /* RTL8192SU */ +#define USB_PRODUCT_BELKIN_RTL8192SU_3 0x945a /* RTL8192SU */ #define USB_PRODUCT_BELKIN_F5D8055 0x825a /* F5D8055 */ #define USB_PRODUCT_BELKIN_F5D8055V2 0x825b /* F5D8055 v2 */ #define USB_PRODUCT_BELKIN_F5D9050V3 0x905b /* F5D9050 ver 3 Wireless Adapter */ #define USB_PRODUCT_BELKIN2_F5U002 0x0002 /* F5U002 Parallel printer */ #define USB_PRODUCT_BELKIN_F6D4050V1 0x935a /* F6D4050 v1 */ +#define USB_PRODUCT_BELKIN_F6D4050V2 0x935b /* F6D4050 v2 */ /* Billionton products */ #define USB_PRODUCT_BILLIONTON_USB100 0x0986 /* USB100N 10/100 FastEthernet */ @@ -1296,6 +1385,11 @@ #define USB_PRODUCT_CHICONY_KB8933 0x0001 /* KB-8933 keyboard */ #define USB_PRODUCT_CHICONY_KU0325 0x0116 /* KU-0325 keyboard */ #define USB_PRODUCT_CHICONY_CNF7129 0xb071 /* Notebook Web Camera */ +#define USB_PRODUCT_CHICONY_RTL8188CUS_1 0xaff7 /* RTL8188CUS */ +#define USB_PRODUCT_CHICONY_RTL8188CUS_2 0xaff8 /* RTL8188CUS */ +#define USB_PRODUCT_CHICONY_RTL8188CUS_3 0xaff9 /* RTL8188CUS */ +#define USB_PRODUCT_CHICONY_RTL8188CUS_4 0xaffa /* RTL8188CUS */ +#define USB_PRODUCT_CHICONY_RTL8188CUS_5 0xaffa /* RTL8188CUS */ #define USB_PRODUCT_CHICONY2_TWINKLECAM 0x600d /* TwinkleCam USB camera */ /* CH Products */ @@ -1349,6 +1443,9 @@ #define USB_PRODUCT_CONCEPTRONIC_AR5523_1_NF 0x7802 /* AR5523 (no firmware) */ #define USB_PRODUCT_CONCEPTRONIC_AR5523_2 0x7811 /* AR5523 */ #define USB_PRODUCT_CONCEPTRONIC_AR5523_2_NF 0x7812 /* AR5523 (no firmware) */ +#define USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_1 0x3300 /* RTL8192SU */ +#define USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_2 0x3301 /* RTL8192SU */ +#define USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_3 0x3302 /* RTL8192SU */ #define USB_PRODUCT_CONCEPTRONIC2_C54RU 0x3c02 /* C54RU WLAN */ #define USB_PRODUCT_CONCEPTRONIC2_C54RU2 0x3c22 /* C54RU */ #define USB_PRODUCT_CONCEPTRONIC2_RT3070_1 0x3c08 /* RT3070 */ @@ -1385,6 +1482,8 @@ #define USB_PRODUCT_COREGA_RT2870_3 0x003f /* RT2870 */ #define USB_PRODUCT_COREGA_RT3070 0x0041 /* RT3070 */ #define USB_PRODUCT_COREGA_CGWLUSB300GNM 0x0042 /* CG-WLUSB300GNM */ +#define USB_PRODUCT_COREGA_RTL8192SU 0x0047 /* RTL8192SU */ +#define USB_PRODUCT_COREGA_RTL8192CU 0x0056 /* RTL8192CU */ #define USB_PRODUCT_COREGA_WLUSB_11_STICK 0x7613 /* WLAN USB Stick 11 */ #define USB_PRODUCT_COREGA_FETHER_USB_TXC 0x9601 /* FEther USB-TXC */ @@ -1495,6 +1594,7 @@ /* D-Link products */ /*product DLINK DSBS25 0x0100 DSB-S25 serial*/ #define USB_PRODUCT_DLINK_DUBE100 0x1a00 /* 10/100 Ethernet */ +#define USB_PRODUCT_DLINK_DUBE100C1 0x1a02 /* DUB-E100 rev C1 */ #define USB_PRODUCT_DLINK_DSB650TX4 0x200c /* 10/100 Ethernet */ #define USB_PRODUCT_DLINK_DWL120E 0x3200 /* DWL-120 rev E */ #define USB_PRODUCT_DLINK_DWL122 0x3700 /* DWL-122 */ @@ -1510,16 +1610,30 @@ #define USB_PRODUCT_DLINK_DUBE100B1 0x3c05 /* DUB-E100 rev B1 */ #define USB_PRODUCT_DLINK_RT2870 0x3c09 /* RT2870 */ #define USB_PRODUCT_DLINK_RT3072 0x3c0a /* RT3072 */ +#define USB_PRODUCT_DLINK_DWA140B3 0x3c15 /* DWA-140 rev B3 */ +#define USB_PRODUCT_DLINK_DWA160B2 0x3c1a /* DWA-160 rev B2 */ +#define USB_PRODUCT_DLINK_DWA127 0x3c1b /* DWA-127 Wireless Adapter */ +#define USB_PRODUCT_DLINK_DWA162 0x3c1f /* DWA-162 Wireless Adapter */ +#define USB_PRODUCT_DLINK_DWA140D1 0x3c20 /* DWA-140 rev D1 */ #define USB_PRODUCT_DLINK_DSB650C 0x4000 /* 10Mbps Ethernet */ #define USB_PRODUCT_DLINK_DSB650TX1 0x4001 /* 10/100 Ethernet */ #define USB_PRODUCT_DLINK_DSB650TX 0x4002 /* 10/100 Ethernet */ #define USB_PRODUCT_DLINK_DSB650TX_PNA 0x4003 /* 1/10/100 Ethernet */ #define USB_PRODUCT_DLINK_DSB650TX3 0x400b /* 10/100 Ethernet */ #define USB_PRODUCT_DLINK_DSB650TX2 0x4102 /* 10/100 Ethernet */ +#define USB_PRODUCT_DLINK_DUB1312 0x4a00 /* 10/100/1000 Ethernet */ #define USB_PRODUCT_DLINK_DSB650 0xabc1 /* 10/100 Ethernet */ #define USB_PRODUCT_DLINK_DUBH7 0xf103 /* DUB-H7 USB 2.0 7-Port Hub */ #define USB_PRODUCT_DLINK_DWR510_CD 0xa805 /* DWR-510 CD-ROM Mode */ #define USB_PRODUCT_DLINK_DWR510 0x7e12 /* DWR-510 */ +#define USB_PRODUCT_DLINK_RTL8188CU 0x3308 /* RTL8188CU */ +#define USB_PRODUCT_DLINK_RTL8192CU_1 0x3307 /* RTL8192CU */ +#define USB_PRODUCT_DLINK_RTL8192CU_2 0x3309 /* RTL8192CU */ +#define USB_PRODUCT_DLINK_RTL8192CU_3 0x330a /* RTL8192CU */ +#define USB_PRODUCT_DLINK_DWA131B 0x330d /* DWA-131 rev B */ +#define USB_PRODUCT_DLINK2_RTL8192SU_1 0x3300 /* RTL8192SU */ +#define USB_PRODUCT_DLINK2_RTL8192SU_2 0x3302 /* RTL8192SU */ +#define USB_PRODUCT_DLINK2_DWA131A1 0x3303 /* DWA-131 A1 */ #define USB_PRODUCT_DLINK2_DWA120 0x3a0c /* DWA-120 */ #define USB_PRODUCT_DLINK2_DWA120_NF 0x3a0d /* DWA-120 (no firmware) */ #define USB_PRODUCT_DLINK2_DWLG122C1 0x3c03 /* DWL-G122 c1 */ @@ -1548,6 +1662,7 @@ /* dresden elektronik products */ #define USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD 0x0001 /* SensorTerminalBoard */ #define USB_PRODUCT_DRESDENELEKTRONIK_WIRELESSHANDHELDTERMINAL 0x0004 /* Wireless Handheld Terminal */ +#define USB_PRODUCT_DRESDENELEKTRONIK_LEVELSHIFTERSTICKLOWCOST 0x0022 /* Levelshifter Stick Low Cost */ /* Dynastream Innovations */ #define USB_PRODUCT_DYNASTREAM_ANTDEVBOARD 0x1003 /* ANT dev board */ @@ -1556,9 +1671,15 @@ /* Edimax products */ #define USB_PRODUCT_EDIMAX_EW7318USG 0x7318 /* USB Wireless dongle */ +#define USB_PRODUCT_EDIMAX_RTL8192SU_1 0x7611 /* RTL8192SU */ +#define USB_PRODUCT_EDIMAX_RTL8192SU_2 0x7612 /* RTL8192SU */ +#define USB_PRODUCT_EDIMAX_EW7622UMN 0x7622 /* EW-7622UMn */ #define USB_PRODUCT_EDIMAX_RT2870_1 0x7711 /* RT2870 */ #define USB_PRODUCT_EDIMAX_EW7717 0x7717 /* EW-7717 */ #define USB_PRODUCT_EDIMAX_EW7718 0x7718 /* EW-7718 */ +#define USB_PRODUCT_EDIMAX_EW7733UND 0x7733 /* EW-7733UnD */ +#define USB_PRODUCT_EDIMAX_EW7811UN 0x7811 /* EW-7811Un */ +#define USB_PRODUCT_EDIMAX_RTL8192CU 0x7822 /* RTL8192CU */ /* eGalax Products */ #define USB_PRODUCT_EGALAX_TPANEL 0x0001 /* Touch Panel */ @@ -1691,6 +1812,10 @@ #define USB_PRODUCT_FEIYA_ELANGO 0x6200 /* MicroSDHC Card Reader */ #define USB_PRODUCT_FEIYA_AC110 0x6300 /* AC-110 Card Reader */ +/* FeiXun Communication products */ +#define USB_PRODUCT_FEIXUN_RTL8188CU 0x0090 /* RTL8188CU */ +#define USB_PRODUCT_FEIXUN_RTL8192CU 0x0091 /* RTL8192CU */ + /* Festo */ #define USB_PRODUCT_FESTO_CPX_USB 0x0102 /* CPX-USB */ #define USB_PRODUCT_FESTO_CMSP 0x0501 /* CMSP */ @@ -1722,6 +1847,7 @@ #define USB_PRODUCT_FTDI_SERIAL_232RL 0x6006 /* FT232RL Serial */ #define USB_PRODUCT_FTDI_SERIAL_2232C 0x6010 /* FT2232C Dual port Serial */ #define USB_PRODUCT_FTDI_232H 0x6014 /* FTDI compatible adapter */ +#define USB_PRODUCT_FTDI_232EX 0x6015 /* FTDI compatible adapter */ #define USB_PRODUCT_FTDI_SERIAL_2232D 0x9e90 /* FT2232D Dual port Serial */ #define USB_PRODUCT_FTDI_SERIAL_4232H 0x6011 /* FT4232H Quad port Serial */ #define USB_PRODUCT_FTDI_BEAGLEBONE 0xa6d0 /* BeagleBone */ @@ -1879,6 +2005,7 @@ #define USB_PRODUCT_FTDI_LENZ_LIUSB 0xd780 /* FTDI compatible adapter */ #define USB_PRODUCT_FTDI_LM3S_DEVEL_BOARD 0xbcd8 /* FTDI compatible adapter */ #define USB_PRODUCT_FTDI_LM3S_EVAL_BOARD 0xbcd9 /* FTDI compatible adapter */ +#define USB_PRODUCT_FTDI_LM3S_ICDI_B_BOARD 0xbcda /* FTDI compatible adapter */ #define USB_PRODUCT_FTDI_MASTERDEVEL2 0xf449 /* FTDI compatible adapter */ #define USB_PRODUCT_FTDI_MHAM_DB9 0xeeed /* FTDI compatible adapter */ #define USB_PRODUCT_FTDI_MHAM_IC 0xeeec /* FTDI compatible adapter */ @@ -2042,6 +2169,9 @@ #define USB_PRODUCT_GUILLEMOT_HWGUSB254LB 0xe010 /* HWGUSB2-54-LB */ #define USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP 0xe020 /* HWGUSB2-54V2-AP */ #define USB_PRODUCT_GUILLEMOT_HWNU300 0xe030 /* HWNU-300 */ +#define USB_PRODUCT_GUILLEMOT_HWNUM300 0xe031 /* HWNUm-300 */ +#define USB_PRODUCT_GUILLEMOT_HWGUN54 0xe032 /* HWGUn-54 */ +#define USB_PRODUCT_GUILLEMOT_HWNUP150 0xe033 /* HWNUP-150 */ /* Hagiwara products */ #define USB_PRODUCT_HAGIWARA_FGSM 0x0002 /* FlashGate SmartMedia Card Reader */ @@ -2065,7 +2195,10 @@ #define USB_PRODUCT_HAWKING_RT2870_2 0x0003 /* RT2870 */ #define USB_PRODUCT_HAWKING_HWUN2 0x0009 /* HWUN2 */ #define USB_PRODUCT_HAWKING_RT3070 0x000b /* RT3070 */ +#define USB_PRODUCT_HAWKING_RTL8192CU 0x0019 /* RTL8192CU */ #define USB_PRODUCT_HAWKING_UF100 0x400c /* 10/100 USB Ethernet */ +#define USB_PRODUCT_HAWKING_RTL8192SU_1 0x0015 /* RTL8192SU */ +#define USB_PRODUCT_HAWKING_RTL8192SU_2 0x0016 /* RTL8192SU */ /* HID Global GmbH products */ #define USB_PRODUCT_HIDGLOBAL_CM2020 0x0596 /* Omnikey Cardman 2020 */ @@ -2114,6 +2247,7 @@ #define USB_PRODUCT_HP_2215 0x1016 /* iPAQ 22xx/Jornada 548 */ #define USB_PRODUCT_HP_568J 0x1116 /* Jornada 568 */ #define USB_PRODUCT_HP_930C 0x1204 /* DeskJet 930c */ +#define USB_PRODUCT_HP3_RTL8188CU 0x1629 /* RTL8188CU */ #define USB_PRODUCT_HP_P2000U 0x1801 /* Inkjet P-2000U */ #define USB_PRODUCT_HP_HS2300 0x1e1d /* HS2300 HSDPA (aka MC8775) */ #define USB_PRODUCT_HP_640C 0x2004 /* DeskJet 640c */ @@ -2379,6 +2513,7 @@ /* Kingston products */ #define USB_PRODUCT_KINGSTON_XX1 0x0008 /* Ethernet */ #define USB_PRODUCT_KINGSTON_KNU101TX 0x000a /* KNU101TX USB Ethernet */ +#define USB_PRODUCT_KINGSTON_HYPERX3_0 0x162b /* DT HyperX 3.0 */ /* Kawasaki products */ #define USB_PRODUCT_KLSI_DUH3E10BT 0x0008 /* USB Ethernet */ @@ -2422,6 +2557,27 @@ #define USB_PRODUCT_LACIE_HD 0xa601 /* Hard Disk */ #define USB_PRODUCT_LACIE_CDRW 0xa602 /* CD R/W */ +/* Lake Shore Cryotronics products */ +#define USB_PRODUCT_LAKESHORE_121 0x0100 /* 121 Current Source */ +#define USB_PRODUCT_LAKESHORE_218A 0x0200 /* 218A Temperature Monitor */ +#define USB_PRODUCT_LAKESHORE_219 0x0201 /* 219 Temperature Monitor */ +#define USB_PRODUCT_LAKESHORE_233 0x0202 /* 233 Temperature Transmitter */ +#define USB_PRODUCT_LAKESHORE_235 0x0203 /* 235 Temperature Transmitter */ +#define USB_PRODUCT_LAKESHORE_335 0x0300 /* 335 Temperature Controller */ +#define USB_PRODUCT_LAKESHORE_336 0x0301 /* 336 Temperature Controller */ +#define USB_PRODUCT_LAKESHORE_350 0x0302 /* 350 Temperature Controller */ +#define USB_PRODUCT_LAKESHORE_371 0x0303 /* 371 AC Bridge */ +#define USB_PRODUCT_LAKESHORE_411 0x0400 /* 411 Handheld Gaussmeter */ +#define USB_PRODUCT_LAKESHORE_425 0x0401 /* 425 Gaussmeter */ +#define USB_PRODUCT_LAKESHORE_455A 0x0402 /* 455A DSP Gaussmeter */ +#define USB_PRODUCT_LAKESHORE_475A 0x0403 /* 475A DSP Gaussmeter */ +#define USB_PRODUCT_LAKESHORE_465 0x0404 /* 465 Gaussmeter */ +#define USB_PRODUCT_LAKESHORE_625A 0x0600 /* 625A Magnet PSU */ +#define USB_PRODUCT_LAKESHORE_642A 0x0601 /* 642A Magnet PSU */ +#define USB_PRODUCT_LAKESHORE_648 0x0602 /* 648 Magnet PSU */ +#define USB_PRODUCT_LAKESHORE_737 0x0700 /* 737 VSM Controller */ +#define USB_PRODUCT_LAKESHORE_776 0x0701 /* 776 Matrix Switch */ + /* Larsen and Brusgaard products */ #define USB_PRODUCT_LARSENBRUSGAARD_ALTITRACK 0x0001 /* FTDI compatible adapter */ @@ -2440,6 +2596,7 @@ /* Liebert products */ #define USB_PRODUCT_LIEBERT_POWERSURE_PXT 0xffff /* PowerSure Personal XT */ +#define USB_PRODUCT_LIEBERT2_PSI1000 0x0004 /* UPS PSI 1000 FW:08 */ /* Link Instruments Inc. products */ #define USB_PRODUCT_LINKINSTRUMENTS_MSO19 0xf190 /* Link Instruments MSO-19 */ @@ -2475,6 +2632,7 @@ #define USB_PRODUCT_LOGITECH_PAGESCAN 0x040f /* PageScan */ #define USB_PRODUCT_LOGITECH_QUICKCAMWEB 0x0801 /* QuickCam Web */ #define USB_PRODUCT_LOGITECH_QUICKCAMPRO 0x0810 /* QuickCam Pro */ +#define USB_PRODUCT_LOGITECH_WEBCAMC100 0X0817 /* Webcam C100 */ #define USB_PRODUCT_LOGITECH_QUICKCAMEXP 0x0840 /* QuickCam Express */ #define USB_PRODUCT_LOGITECH_QUICKCAM 0x0850 /* QuickCam */ #define USB_PRODUCT_LOGITECH_QUICKCAMPRO3 0x0990 /* QuickCam Pro 9000 */ @@ -3011,18 +3169,23 @@ /* NetChip Technology Products */ #define USB_PRODUCT_NETCHIP_TURBOCONNECT 0x1080 /* Turbo-Connect */ #define USB_PRODUCT_NETCHIP_CLIK_40 0xa140 /* USB Clik! 40 */ +#define USB_PRODUCT_NETCHIP_GADGETZERO 0xa4a0 /* Linux Gadget Zero */ #define USB_PRODUCT_NETCHIP_ETHERNETGADGET 0xa4a2 /* Linux Ethernet/RNDIS gadget on pxa210/25x/26x */ +#define USB_PRODUCT_NETCHIP_POCKETBOOK 0xa4a5 /* PocketBook */ /* Netgear products */ #define USB_PRODUCT_NETGEAR_EA101 0x1001 /* Ethernet */ #define USB_PRODUCT_NETGEAR_EA101X 0x1002 /* Ethernet */ #define USB_PRODUCT_NETGEAR_FA101 0x1020 /* Ethernet 10/100, USB1.1 */ #define USB_PRODUCT_NETGEAR_FA120 0x1040 /* USB 2.0 Ethernet */ +#define USB_PRODUCT_NETGEAR_M4100 0x1100 /* M4100/M5300/M7100 series switch */ #define USB_PRODUCT_NETGEAR_WG111V2_2 0x4240 /* PrismGT USB 2.0 WLAN */ #define USB_PRODUCT_NETGEAR_WG111V3 0x4260 /* WG111v3 */ #define USB_PRODUCT_NETGEAR_WG111U 0x4300 /* WG111U */ #define USB_PRODUCT_NETGEAR_WG111U_NF 0x4301 /* WG111U (no firmware) */ #define USB_PRODUCT_NETGEAR_WG111V2 0x6a00 /* WG111V2 */ +#define USB_PRODUCT_NETGEAR_RTL8192CU 0x9021 /* RTL8192CU */ +#define USB_PRODUCT_NETGEAR_WNA1000M 0x9041 /* WNA1000M */ #define USB_PRODUCT_NETGEAR2_MA101 0x4100 /* MA101 */ #define USB_PRODUCT_NETGEAR2_MA101B 0x4102 /* MA101 Rev B */ #define USB_PRODUCT_NETGEAR3_WG111T 0x4250 /* WG111T */ @@ -3030,6 +3193,7 @@ #define USB_PRODUCT_NETGEAR3_WPN111 0x5f00 /* WPN111 */ #define USB_PRODUCT_NETGEAR3_WPN111_NF 0x5f01 /* WPN111 (no firmware) */ #define USB_PRODUCT_NETGEAR3_WPN111_2 0x5f02 /* WPN111 */ +#define USB_PRODUCT_NETGEAR4_RTL8188CU 0x9041 /* RTL8188CU */ /* NetIndex products */ #define USB_PRODUCT_NETINDEX_WS002IN 0x2001 /* Willcom WS002IN */ @@ -3045,6 +3209,7 @@ /* NovaTech Products */ #define USB_PRODUCT_NOVATECH_NV902 0x9020 /* NovaTech NV-902W */ #define USB_PRODUCT_NOVATECH_RT2573 0x9021 /* RT2573 */ +#define USB_PRODUCT_NOVATECH_RTL8188CU 0x9071 /* RTL8188CU */ /* Nokia products */ #define USB_PRODUCT_NOKIA_N958GB 0x0070 /* Nokia N95 8GBc */ @@ -3072,6 +3237,7 @@ #define USB_PRODUCT_NOVATEL_U727 0x4100 /* Merlin U727 CDMA */ #define USB_PRODUCT_NOVATEL_MC950D 0x4400 /* Novatel MC950D HSUPA */ #define USB_PRODUCT_NOVATEL_ZEROCD 0x5010 /* Novatel ZeroCD */ +#define USB_PRODUCT_NOVATEL_MIFI2200V 0x5020 /* Novatel MiFi 2200 CDMA Virgin Mobile */ #define USB_PRODUCT_NOVATEL_ZEROCD2 0x5030 /* Novatel ZeroCD */ #define USB_PRODUCT_NOVATEL_MIFI2200 0x5041 /* Novatel MiFi 2200 CDMA */ #define USB_PRODUCT_NOVATEL_U727_2 0x5100 /* Merlin U727 CDMA */ @@ -3150,6 +3316,7 @@ #define USB_PRODUCT_OPTION_GE40X_1 0x7301 /* Globetrotter HSUPA */ #define USB_PRODUCT_OPTION_GE40X_2 0x7361 /* Globetrotter HSUPA */ #define USB_PRODUCT_OPTION_GE40X_3 0x7381 /* Globetrotter HSUPA */ +#define USB_PRODUCT_OPTION_GTM661W 0x9000 /* GTM661W */ #define USB_PRODUCT_OPTION_ICONEDGE 0xc031 /* GlobeSurfer iCON EDGE */ #define USB_PRODUCT_OPTION_MODHSXPA 0xd013 /* Globetrotter HSUPA */ #define USB_PRODUCT_OPTION_ICON321 0xd031 /* Globetrotter HSUPA */ @@ -3178,6 +3345,9 @@ /* Owen.ru products */ #define USB_PRODUCT_OWEN_AC4 0x0004 /* AC4 USB-RS485 converter */ +/* OWL producs */ +#define USB_PRODUCT_OWL_CM_160 0xca05 /* OWL CM-160 power monitor */ + /* Palm Computing, Inc. product */ #define USB_PRODUCT_PALM_SERIAL 0x0080 /* USB Serial */ #define USB_PRODUCT_PALM_M500 0x0001 /* Palm m500 */ @@ -3273,8 +3443,14 @@ /* Planex Communications products */ #define USB_PRODUCT_PLANEX_GW_US11H 0x14ea /* GW-US11H WLAN */ +#define USB_PRODUCT_PLANEX2_RTL8188CUS 0x1201 /* RTL8188CUS */ #define USB_PRODUCT_PLANEX2_GW_US11S 0x3220 /* GW-US11S WLAN */ #define USB_PRODUCT_PLANEX2_GW_US54GXS 0x5303 /* GW-US54GXS WLAN */ +#define USB_PRODUCT_PLANEX2_RTL8188CU_1 0xab2a /* RTL8188CU */ +#define USB_PRODUCT_PLANEX2_RTL8188CU_2 0xed17 /* RTL8188CU */ +#define USB_PRODUCT_PLANEX2_RTL8188CU_3 0x4902 /* RTL8188CU */ +#define USB_PRODUCT_PLANEX2_RTL8188CU_4 0xab2e /* RTL8188CU */ +#define USB_PRODUCT_PLANEX2_RTL8192CU 0xab2b /* RTL8192CU */ #define USB_PRODUCT_PLANEX2_GWUS54HP 0xab01 /* GW-US54HP */ #define USB_PRODUCT_PLANEX2_GWUS300MINIS 0xab24 /* GW-US300MiniS */ #define USB_PRODUCT_PLANEX2_RT3070 0xab25 /* RT3070 */ @@ -3290,6 +3466,7 @@ #define USB_PRODUCT_PLANEX3_GWUS54GZ 0xab10 /* GW-US54GZ */ #define USB_PRODUCT_PLANEX3_GU1000T 0xab11 /* GU-1000T */ #define USB_PRODUCT_PLANEX3_GWUS54MINI 0xab13 /* GW-US54Mini */ +#define USB_PRODUCT_PLANEX2_GWUSNANO 0xab28 /* GW-USNano */ /* Plextor Corp. */ #define USB_PRODUCT_PLEXTOR_40_12_40U 0x0011 /* PlexWriter 40/12/40U */ @@ -3486,12 +3663,15 @@ #define USB_PRODUCT_RALINK_RT2671 0x2671 /* RT2601USB Wireless Adapter */ #define USB_PRODUCT_RALINK_RT2770 0x2770 /* RT2770 */ #define USB_PRODUCT_RALINK_RT2870 0x2870 /* RT2870 */ +#define USB_PRODUCT_RALINK_RT_STOR 0x2878 /* USB Storage */ #define USB_PRODUCT_RALINK_RT3070 0x3070 /* RT3070 */ #define USB_PRODUCT_RALINK_RT3071 0x3071 /* RT3071 */ #define USB_PRODUCT_RALINK_RT3072 0x3072 /* RT3072 */ #define USB_PRODUCT_RALINK_RT3370 0x3370 /* RT3370 */ #define USB_PRODUCT_RALINK_RT3572 0x3572 /* RT3572 */ +#define USB_PRODUCT_RALINK_RT3573 0x3573 /* RT3573 */ #define USB_PRODUCT_RALINK_RT5370 0x5370 /* RT5370 */ +#define USB_PRODUCT_RALINK_RT5572 0x5572 /* RT5572 */ #define USB_PRODUCT_RALINK_RT8070 0x8070 /* RT8070 */ #define USB_PRODUCT_RALINK_RT2570_3 0x9020 /* RT2500USB Wireless Adapter */ #define USB_PRODUCT_RALINK_RT2573_2 0x9021 /* RT2501USB Wireless Adapter */ @@ -3500,15 +3680,37 @@ #define USB_PRODUCT_RATOC_REXUSB60 0xb000 /* USB serial adapter REX-USB60 */ #define USB_PRODUCT_RATOC_REXUSB60F 0xb020 /* USB serial adapter REX-USB60F */ -/* ReakTek products */ +/* Realtek products */ /* Green House and CompUSA OEM this part */ #define USB_PRODUCT_REALTEK_DUMMY 0x0000 /* Dummy product */ #define USB_PRODUCT_REALTEK_USB20CRW 0x0158 /* USB20CRW Card Reader */ +#define USB_PRODUCT_REALTEK_RTL8188CTV 0x018a /* RTL8188CTV */ #define USB_PRODUCT_REALTEK_USBKR100 0x8150 /* USBKR100 USB Ethernet */ +#define USB_PRODUCT_REALTEK_RTL8188CE_0 0x8170 /* RTL8188CE */ +#define USB_PRODUCT_REALTEK_RTL8171 0x8171 /* RTL8171 */ +#define USB_PRODUCT_REALTEK_RTL8172 0x8172 /* RTL8172 */ +#define USB_PRODUCT_REALTEK_RTL8173 0x8173 /* RTL8173 */ +#define USB_PRODUCT_REALTEK_RTL8174 0x8174 /* RTL8174 */ +#define USB_PRODUCT_REALTEK_RTL8188CU_0 0x8176 /* RTL8188CU */ +#define USB_PRODUCT_REALTEK_RTL8188EU 0x8179 /* RTL8188EU */ +#define USB_PRODUCT_REALTEK_RTL8188CE_1 0x817e /* RTL8188CE */ +#define USB_PRODUCT_REALTEK_RTL8188CU_1 0x817a /* RTL8188CU */ +#define USB_PRODUCT_REALTEK_RTL8188CU_2 0x817b /* RTL8188CU */ #define USB_PRODUCT_REALTEK_RTL8187 0x8187 /* RTL8187 Wireless Adapter */ #define USB_PRODUCT_REALTEK_RTL8187B_0 0x8189 /* RTL8187B Wireless Adapter */ +#define USB_PRODUCT_REALTEK_RTL8196EU 0x8196 /* RTL8196EU */ #define USB_PRODUCT_REALTEK_RTL8187B_1 0x8197 /* RTL8187B Wireless Adapter */ #define USB_PRODUCT_REALTEK_RTL8187B_2 0x8198 /* RTL8187B Wireless Adapter */ +#define USB_PRODUCT_REALTEK_RTL8188CUS 0x818a /* RTL8188CUS */ +#define USB_PRODUCT_REALTEK_RTL8188CU_COMBO 0x8754 /* RTL8188CU */ +#define USB_PRODUCT_REALTEK_RTL8191CU 0x8177 /* RTL8191CU */ +#define USB_PRODUCT_REALTEK_RTL8192CU 0x8178 /* RTL8192CU */ +#define USB_PRODUCT_REALTEK_RTL8192CE 0x817c /* RTL8192CE */ +#define USB_PRODUCT_REALTEK_RTL8188RU_1 0x817d /* RTL8188RU */ +#define USB_PRODUCT_REALTEK_RTL8712 0x8712 /* RTL8712 */ +#define USB_PRODUCT_REALTEK_RTL8713 0x8712 /* RTL8713 */ +#define USB_PRODUCT_REALTEK_RTL8188RU_2 0x317f /* RTL8188RU */ +#define USB_PRODUCT_REALTEK_RTL8192SU 0xc512 /* RTL8192SU */ /* RedOctane products */ #define USB_PRODUCT_REDOCTANE_DUMMY 0x0000 /* Dummy product */ @@ -3582,6 +3784,7 @@ #define USB_PRODUCT_SANDISK_SDDR12 0x0100 /* ImageMate SDDR-12 */ #define USB_PRODUCT_SANDISK_SDDR09 0x0200 /* ImageMate SDDR-09 */ #define USB_PRODUCT_SANDISK_SDDR75 0x0810 /* ImageMate SDDR-75 */ +#define USB_PRODUCT_SANDISK_SDCZ2_128 0x7100 /* Cruzer Mini 128MB */ #define USB_PRODUCT_SANDISK_SDCZ2_256 0x7104 /* Cruzer Mini 256MB */ #define USB_PRODUCT_SANDISK_SDCZ4_128 0x7112 /* Cruzer Micro 128MB */ #define USB_PRODUCT_SANDISK_SDCZ4_256 0x7113 /* Cruzer Micro 256MB */ @@ -3597,6 +3800,9 @@ #define USB_PRODUCT_SCANLOGIC_SL11R 0x0002 /* SL11R IDE Adapter */ #define USB_PRODUCT_SCANLOGIC_336CX 0x0300 /* Phantom 336CX - C3 scanner */ +/* Schweitzer Engineering Laboratories products */ +#define USB_PRODUCT_SEL_C662 0x0001 /* C662 Cable */ + /* Sealevel products */ #define USB_PRODUCT_SEALEVEL_2101 0x2101 /* FTDI compatible adapter */ #define USB_PRODUCT_SEALEVEL_2102 0x2102 /* FTDI compatible adapter */ @@ -3659,6 +3865,8 @@ #define USB_PRODUCT_SENAO_RT3072_3 0x9708 /* RT3072 */ #define USB_PRODUCT_SENAO_RT3072_4 0x9709 /* RT3072 */ #define USB_PRODUCT_SENAO_RT3072_5 0x9801 /* RT3072 */ +#define USB_PRODUCT_SENAO_RTL8192SU_1 0x9603 /* RTL8192SU */ +#define USB_PRODUCT_SENAO_RTL8192SU_2 0x9605 /* RTL8192SU */ /* ShanTou products */ #define USB_PRODUCT_SHANTOU_ST268 0x0268 /* ST268 */ @@ -3835,8 +4043,11 @@ #define USB_PRODUCT_SILABS_BALLUFF_RFID 0x8477 /* Balluff RFID reader */ #define USB_PRODUCT_SILABS_AC_SERV_IBUS 0x85ea /* AC-Services IBUS Interface */ #define USB_PRODUCT_SILABS_AC_SERV_CIS 0x85eb /* AC-Services CIS-IBUS */ +#define USB_PRODUCT_SILABS_V_PREON32 0x85f8 /* Virtenio Preon32 */ #define USB_PRODUCT_SILABS_AC_SERV_CAN 0x8664 /* AC-Services CAN Interface */ #define USB_PRODUCT_SILABS_AC_SERV_OBD 0x8665 /* AC-Services OBD Interface */ +#define USB_PRODUCT_SILABS_MMB_ZIGBEE 0x88a4 /* MMB Networks ZigBee */ +#define USB_PRODUCT_SILABS_INGENI_ZIGBEE 0x88a5 /* Planet Innovation Ingeni ZigBee */ #define USB_PRODUCT_SILABS_CP2102 0xea60 /* SILABS USB UART */ #define USB_PRODUCT_SILABS_CP210X_2 0xea61 /* CP210x Serial */ #define USB_PRODUCT_SILABS_CP210X_3 0xea70 /* CP210x Serial */ @@ -3879,10 +4090,16 @@ #define USB_PRODUCT_SITECOMEU_RT3071 0x0040 /* RT3071 */ #define USB_PRODUCT_SITECOMEU_RT3072_1 0x0041 /* RT3072 */ #define USB_PRODUCT_SITECOMEU_RT3072_2 0x0042 /* RT3072 */ +#define USB_PRODUCT_SITECOMEU_WL353 0x0045 /* WL-353 */ #define USB_PRODUCT_SITECOMEU_RT3072_3 0x0047 /* RT3072 */ #define USB_PRODUCT_SITECOMEU_RT3072_4 0x0048 /* RT3072 */ #define USB_PRODUCT_SITECOMEU_RT3072_5 0x004a /* RT3072 */ +#define USB_PRODUCT_SITECOMEU_WL349V1 0x004b /* WL-349 v1 */ #define USB_PRODUCT_SITECOMEU_RT3072_6 0x004d /* RT3072 */ +#define USB_PRODUCT_SITECOMEU_RTL8188CU_1 0x0052 /* RTL8188CU */ +#define USB_PRODUCT_SITECOMEU_RTL8188CU_2 0x005c /* RTL8188CU */ +#define USB_PRODUCT_SITECOMEU_RTL8192CU 0x0061 /* RTL8192CU */ +#define USB_PRODUCT_SITECOMEU_LN032 0x0072 /* LN-032 */ #define USB_PRODUCT_SITECOMEU_LN028 0x061c /* LN-028 */ #define USB_PRODUCT_SITECOMEU_WL113 0x9071 /* WL-113 */ #define USB_PRODUCT_SITECOMEU_ZD1211B 0x9075 /* ZD1211B */ @@ -3908,6 +4125,7 @@ #define USB_PRODUCT_SMC2_2020HUB 0x2020 /* USB Hub */ #define USB_PRODUCT_SMC2_2514HUB 0x2514 /* USB Hub */ #define USB_PRODUCT_SMC3_2662WUSB 0xa002 /* 2662W-AR Wireless */ +#define USB_PRODUCT_SMC2_LAN9514_ETH 0xec00 /* USB/Ethernet */ /* SOHOware products */ #define USB_PRODUCT_SOHOWARE_NUB100 0x9100 /* 10/100 USB Ethernet */ @@ -4008,6 +4226,7 @@ /* Super Top products */ #define USB_PRODUCT_SUPERTOP_IDE 0x6600 /* USB-IDE */ +#define USB_PRODUCT_SUPERTOP_FLASHDRIVE 0x121c /* extrememory Snippy */ /* Syntech products */ #define USB_PRODUCT_SYNTECH_CPT8001C 0x0001 /* CPT-8001C Barcode scanner */ @@ -4044,6 +4263,7 @@ /* Sweex products */ #define USB_PRODUCT_SWEEX_ZD1211 0x1809 /* ZD1211 */ #define USB_PRODUCT_SWEEX2_LW153 0x0153 /* LW153 */ +#define USB_PRODUCT_SWEEX2_LW154 0x0154 /* LW154 */ #define USB_PRODUCT_SWEEX2_LW303 0x0302 /* LW303 */ #define USB_PRODUCT_SWEEX2_LW313 0x0313 /* LW313 */ @@ -4110,6 +4330,10 @@ #define USB_PRODUCT_TREK_MEMKEY 0x8888 /* IBM USB Memory Key */ #define USB_PRODUCT_TREK_THUMBDRIVE_8MB 0x9988 /* ThumbDrive_8MB */ +/* TRENDnet products */ +#define USB_PRODUCT_TRENDNET_RTL8192CU 0x624d /* RTL8192CU */ +#define USB_PRODUCT_TRENDNET_RTL8188CU 0x648b /* RTL8188CU */ + /* Tripp-Lite products */ #define USB_PRODUCT_TRIPPLITE_U209 0x2008 /* Serial */ @@ -4214,12 +4438,19 @@ #define USB_PRODUCT_WCH2_CH341SER 0x7523 /* CH341/CH340 USB-Serial Bridge */ #define USB_PRODUCT_WCH2_U2M 0X752d /* CH345 USB2.0-MIDI */ +/* West Mountain Radio products */ +#define USB_PRODUCT_WESTMOUNTAIN_RIGBLASTER_ADVANTAGE 0x0003 /* RIGblaster Advantage */ + /* Western Digital products */ #define USB_PRODUCT_WESTERN_COMBO 0x0200 /* Firewire USB Combo */ #define USB_PRODUCT_WESTERN_EXTHDD 0x0400 /* External HDD */ #define USB_PRODUCT_WESTERN_HUB 0x0500 /* USB HUB */ #define USB_PRODUCT_WESTERN_MYBOOK 0x0901 /* MyBook External HDD */ #define USB_PRODUCT_WESTERN_MYPASSWORD 0x0704 /* MyPassword External HDD */ +#define USB_PRODUCT_WESTERN_MYPASSPORT 0x0748 /* MyPassport External HDD */ + +/* WeTelecom products */ +#define USB_PRODUCT_WETELECOM_WM_D200 0x6801 /* WM-D200 */ /* WIENER Plein & Baus GmbH products */ #define USB_PRODUCT_WIENERPLEINBAUS_PL512 0x0010 /* PL512 PSU */ @@ -4315,3 +4546,5 @@ #define USB_PRODUCT_ZYXEL_G202 0x3410 /* G-202 */ #define USB_PRODUCT_ZYXEL_RT2870_1 0x3416 /* RT2870 */ #define USB_PRODUCT_ZYXEL_RT2870_2 0x341a /* RT2870 */ +#define USB_PRODUCT_ZYXEL_RTL8192CU 0x341f /* RTL8192CU */ +#define USB_PRODUCT_ZYXEL_NWD2705 0x3421 /* NWD2705 */ diff --git a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h index 9ac09b57..c31eb4ba 100644 --- a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h +++ b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h @@ -285,6 +285,24 @@ const struct usb_knowndev usb_knowndevs[] = { "AboCom Systems", "RT2573", }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_1, + 0, + "AboCom Systems", + "RTL8188CU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_2, + 0, + "AboCom Systems", + "RTL8188CU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8192CU, + 0, + "AboCom Systems", + "RTL8192CU", + }, { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700, 0, @@ -423,6 +441,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Accton Technology", "RT3070", }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RTL8192SU, + 0, + "Accton Technology", + "RTL8192SU", + }, { USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_ZD1211B, 0, @@ -669,6 +693,12 @@ const struct usb_knowndev usb_knowndevs[] = { "AEI", "Fast Ethernet", }, + { + USB_VENDOR_AFATECH, USB_PRODUCT_AFATECH_AFATECH1336, + 0, + "Afatech Technologies, Inc.", + "Flash Card Reader", + }, { USB_VENDOR_AGATE, USB_PRODUCT_AGATE_QDRIVE, 0, @@ -1144,40 +1174,220 @@ const struct usb_knowndev usb_knowndevs[] = { "Apple Extended USB Keyboard", }, { - USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_ANSI, + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_ANSI, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_ISO, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_JIS, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_ANSI, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_ISO, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_JIS, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_ANSI, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_ISO, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_JIS, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_ANSI, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_ISO, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_JIS, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_ANSI, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_ISO, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_JIS, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_ANSI, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_ISO, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_JIS, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_ANSI, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_ISO, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_JIS, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_ANSI, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_ISO, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_JIS, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_ANSI, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_ISO, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_JIS, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_ANSI, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_ISO, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_JIS, + 0, + "Apple Computer", + "Apple Internal Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_ANSI, 0, "Apple Computer", - "Apple Internal Keyboard/Trackpad (Wellspring/ANSI)", + "Apple Internal Keyboard/Trackpad", }, { - USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_ISO, + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_ISO, 0, "Apple Computer", - "Apple Internal Keyboard/Trackpad (Wellspring/ISO)", + "Apple Internal Keyboard/Trackpad", }, { - USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_JIS, + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_JIS, 0, "Apple Computer", - "Apple Internal Keyboard/Trackpad (Wellspring/JIS)", + "Apple Internal Keyboard/Trackpad", }, { - USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_ANSI2, + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_ANSI, 0, "Apple Computer", - "Apple Internal Keyboard/Trackpad (Wellspring2/ANSI)", + "Apple Internal Keyboard/Trackpad", }, { - USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_ISO2, + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_ISO, 0, "Apple Computer", - "Apple Internal Keyboard/Trackpad (Wellspring2/ISO)", + "Apple Internal Keyboard/Trackpad", }, { - USB_VENDOR_APPLE, USB_PRODUCT_APPLE_KBD_TP_JIS2, + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_JIS, 0, "Apple Computer", - "Apple Internal Keyboard/Trackpad (Wellspring2/JIS)", + "Apple Internal Keyboard/Trackpad", }, { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_MOUSE, @@ -1365,6 +1575,18 @@ const struct usb_knowndev usb_knowndevs[] = { "ASIX Electronics", "AX88178", }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178A, + 0, + "ASIX Electronics", + "AX88178A USB 2.0 10/100/1000 Ethernet", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88179, + 0, + "ASIX Electronics", + "AX88179 USB 3.0 10/100/1000 Ethernet", + }, { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772, 0, @@ -1479,6 +1701,30 @@ const struct usb_knowndev usb_knowndevs[] = { "ASUSTeK Computer", "RT3070", }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN10, + 0, + "ASUSTeK Computer", + "USB-N10", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU, + 0, + "ASUSTeK Computer", + "RTL8192CU", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN66, + 0, + "ASUSTeK Computer", + "USB-N66", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192SU, + 0, + "ASUSTeK Computer", + "RTL8192SU", + }, { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_A730W, 0, @@ -1545,6 +1791,12 @@ const struct usb_knowndev usb_knowndevs[] = { "ATEN International", "DSB-650C", }, + { + USB_VENDOR_ATP, USB_PRODUCT_ATP_EUSB, + 0, + "ATP Electronics", + "ATP IG eUSB SSD", + }, { USB_VENDOR_ATHEROS, USB_PRODUCT_ATHEROS_AR5523, 0, @@ -1677,6 +1929,54 @@ const struct usb_knowndev usb_knowndevs[] = { "AsureWave", "RT3070", }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CU, + 0, + "AsureWave", + "RTL8188CU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_1, + 0, + "AsureWave", + "RTL8188CE", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_2, + 0, + "AsureWave", + "RTL8188CE", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_1, + 0, + "AsureWave", + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_2, + 0, + "AsureWave", + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_3, + 0, + "AsureWave", + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_4, + 0, + "AsureWave", + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_5, + 0, + "AsureWave", + "RTL8192SU", + }, { USB_VENDOR_BALTECH, USB_PRODUCT_BALTECH_CARDREADER, 0, @@ -1875,6 +2175,30 @@ const struct usb_knowndev usb_knowndevs[] = { "Belkin Components", "F5U120-PC Hub", }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8188CU, + 0, + "Belkin Components", + "RTL8188CU Wireless Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F9L1103, + 0, + "Belkin Components", + "F9L1103 Wireless Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192CU, + 0, + "Belkin Components", + "RTL8192CU Wireless Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F7D2102, + 0, + "Belkin Components", + "F7D2102 Wireless Adapter", + }, { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_ZD1211B, 0, @@ -1935,6 +2259,24 @@ const struct usb_knowndev usb_knowndevs[] = { "Belkin Components", "F5D8053 v3", }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_1, + 0, + "Belkin Components", + "RTL8192SU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_2, + 0, + "Belkin Components", + "RTL8192SU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_3, + 0, + "Belkin Components", + "RTL8192SU", + }, { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D8055, 0, @@ -1965,6 +2307,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Belkin Components", "F6D4050 v1", }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6D4050V2, + 0, + "Belkin Components", + "F6D4050 v2", + }, { USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100, 0, @@ -2199,6 +2547,36 @@ const struct usb_knowndev usb_knowndevs[] = { "Chicony Electronics", "Notebook Web Camera", }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_1, + 0, + "Chicony Electronics", + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_2, + 0, + "Chicony Electronics", + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_3, + 0, + "Chicony Electronics", + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_4, + 0, + "Chicony Electronics", + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_5, + 0, + "Chicony Electronics", + "RTL8188CUS", + }, { USB_VENDOR_CHICONY2, USB_PRODUCT_CHICONY2_TWINKLECAM, 0, @@ -2433,6 +2811,24 @@ const struct usb_knowndev usb_knowndevs[] = { "Conceptronic", "AR5523 (no firmware)", }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_1, + 0, + "Conceptronic", + "RTL8192SU", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_2, + 0, + "Conceptronic", + "RTL8192SU", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_3, + 0, + "Conceptronic", + "RTL8192SU", + }, { USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU, 0, @@ -2613,6 +3009,18 @@ const struct usb_knowndev usb_knowndevs[] = { "Corega", "CG-WLUSB300GNM", }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RTL8192SU, + 0, + "Corega", + "RTL8192SU", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RTL8192CU, + 0, + "Corega", + "RTL8192CU", + }, { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLUSB_11_STICK, 0, @@ -3015,6 +3423,12 @@ const struct usb_knowndev usb_knowndevs[] = { "D-Link", "10/100 Ethernet", }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100C1, + 0, + "D-Link", + "DUB-E100 rev C1", + }, { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX4, 0, @@ -3070,40 +3484,70 @@ const struct usb_knowndev usb_knowndevs[] = { "DWL-G132 (no firmware)", }, { - USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG122, + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG122, + 0, + "D-Link", + "DWL-AG122", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG122_NF, + 0, + "D-Link", + "DWL-AG122 (no firmware)", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG122, + 0, + "D-Link", + "DWL-G122 b1 Wireless Adapter", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1, + 0, + "D-Link", + "DUB-E100 rev B1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT2870, + 0, + "D-Link", + "RT2870", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT3072, 0, "D-Link", - "DWL-AG122", + "RT3072", }, { - USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG122_NF, + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA140B3, 0, "D-Link", - "DWL-AG122 (no firmware)", + "DWA-140 rev B3", }, { - USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG122, + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA160B2, 0, "D-Link", - "DWL-G122 b1 Wireless Adapter", + "DWA-160 rev B2", }, { - USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1, + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA127, 0, "D-Link", - "DUB-E100 rev B1", + "DWA-127 Wireless Adapter", }, { - USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT2870, + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA162, 0, "D-Link", - "RT2870", + "DWA-162 Wireless Adapter", }, { - USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT3072, + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA140D1, 0, "D-Link", - "RT3072", + "DWA-140 rev D1", }, { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C, @@ -3141,6 +3585,12 @@ const struct usb_knowndev usb_knowndevs[] = { "D-Link", "10/100 Ethernet", }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUB1312, + 0, + "D-Link", + "10/100/1000 Ethernet", + }, { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650, 0, @@ -3165,6 +3615,54 @@ const struct usb_knowndev usb_knowndevs[] = { "D-Link", "DWR-510", }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8188CU, + 0, + "D-Link", + "RTL8188CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_1, + 0, + "D-Link", + "RTL8192CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_2, + 0, + "D-Link", + "RTL8192CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_3, + 0, + "D-Link", + "RTL8192CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA131B, + 0, + "D-Link", + "DWA-131 rev B", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RTL8192SU_1, + 0, + "D-Link", + "RTL8192SU", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RTL8192SU_2, + 0, + "D-Link", + "RTL8192SU", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA131A1, + 0, + "D-Link", + "DWA-131 A1", + }, { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA120, 0, @@ -3297,6 +3795,12 @@ const struct usb_knowndev usb_knowndevs[] = { "dresden elektronik", "Wireless Handheld Terminal", }, + { + USB_VENDOR_DRESDENELEKTRONIK, USB_PRODUCT_DRESDENELEKTRONIK_LEVELSHIFTERSTICKLOWCOST, + 0, + "dresden elektronik", + "Levelshifter Stick Low Cost", + }, { USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTDEVBOARD, 0, @@ -3321,6 +3825,24 @@ const struct usb_knowndev usb_knowndevs[] = { "Edimax", "USB Wireless dongle", }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_1, + 0, + "Edimax", + "RTL8192SU", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_2, + 0, + "Edimax", + "RTL8192SU", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7622UMN, + 0, + "Edimax", + "EW-7622UMn", + }, { USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RT2870_1, 0, @@ -3339,6 +3861,24 @@ const struct usb_knowndev usb_knowndevs[] = { "Edimax", "EW-7718", }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7733UND, + 0, + "Edimax", + "EW-7733UnD", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7811UN, + 0, + "Edimax", + "EW-7811Un", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192CU, + 0, + "Edimax", + "RTL8192CU", + }, { USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL, 0, @@ -3885,6 +4425,18 @@ const struct usb_knowndev usb_knowndevs[] = { "Feiya", "AC-110 Card Reader", }, + { + USB_VENDOR_FEIXUN, USB_PRODUCT_FEIXUN_RTL8188CU, + 0, + "FeiXun Communication", + "RTL8188CU", + }, + { + USB_VENDOR_FEIXUN, USB_PRODUCT_FEIXUN_RTL8192CU, + 0, + "FeiXun Communication", + "RTL8192CU", + }, { USB_VENDOR_FESTO, USB_PRODUCT_FESTO_CPX_USB, 0, @@ -3981,6 +4533,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Future Technology Devices", "FTDI compatible adapter", }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_232EX, + 0, + "Future Technology Devices", + "FTDI compatible adapter", + }, { USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232D, 0, @@ -4905,6 +5463,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Future Technology Devices", "FTDI compatible adapter", }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LM3S_ICDI_B_BOARD, + 0, + "Future Technology Devices", + "FTDI compatible adapter", + }, { USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MASTERDEVEL2, 0, @@ -5643,6 +6207,24 @@ const struct usb_knowndev usb_knowndevs[] = { "Guillemot", "HWNU-300", }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNUM300, + 0, + "Guillemot", + "HWNUm-300", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUN54, + 0, + "Guillemot", + "HWGUn-54", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNUP150, + 0, + "Guillemot", + "HWNUP-150", + }, { USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM, 0, @@ -5721,12 +6303,30 @@ const struct usb_knowndev usb_knowndevs[] = { "Hawking", "RT3070", }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192CU, + 0, + "Hawking", + "RTL8192CU", + }, { USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100, 0, "Hawking", "10/100 USB Ethernet", }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192SU_1, + 0, + "Hawking", + "RTL8192SU", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192SU_2, + 0, + "Hawking", + "RTL8192SU", + }, { USB_VENDOR_HIDGLOBAL, USB_PRODUCT_HIDGLOBAL_CM2020, 0, @@ -5979,6 +6579,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Hewlett Packard", "DeskJet 930c", }, + { + USB_VENDOR_HP3, USB_PRODUCT_HP3_RTL8188CU, + 0, + "Hewlett Packard", + "RTL8188CU", + }, { USB_VENDOR_HP, USB_PRODUCT_HP_P2000U, 0, @@ -7185,6 +7791,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Kingston Technology", "KNU101TX USB Ethernet", }, + { + USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_HYPERX3_0, + 0, + "Kingston Technology", + "DT HyperX 3.0", + }, { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT, 0, @@ -7341,6 +7953,120 @@ const struct usb_knowndev usb_knowndevs[] = { "LaCie", "CD R/W", }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_121, + 0, + "Lake Shore Cryotronics, Inc.", + "121 Current Source", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_218A, + 0, + "Lake Shore Cryotronics, Inc.", + "218A Temperature Monitor", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_219, + 0, + "Lake Shore Cryotronics, Inc.", + "219 Temperature Monitor", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_233, + 0, + "Lake Shore Cryotronics, Inc.", + "233 Temperature Transmitter", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_235, + 0, + "Lake Shore Cryotronics, Inc.", + "235 Temperature Transmitter", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_335, + 0, + "Lake Shore Cryotronics, Inc.", + "335 Temperature Controller", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_336, + 0, + "Lake Shore Cryotronics, Inc.", + "336 Temperature Controller", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_350, + 0, + "Lake Shore Cryotronics, Inc.", + "350 Temperature Controller", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_371, + 0, + "Lake Shore Cryotronics, Inc.", + "371 AC Bridge", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_411, + 0, + "Lake Shore Cryotronics, Inc.", + "411 Handheld Gaussmeter", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_425, + 0, + "Lake Shore Cryotronics, Inc.", + "425 Gaussmeter", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_455A, + 0, + "Lake Shore Cryotronics, Inc.", + "455A DSP Gaussmeter", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_475A, + 0, + "Lake Shore Cryotronics, Inc.", + "475A DSP Gaussmeter", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_465, + 0, + "Lake Shore Cryotronics, Inc.", + "465 Gaussmeter", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_625A, + 0, + "Lake Shore Cryotronics, Inc.", + "625A Magnet PSU", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_642A, + 0, + "Lake Shore Cryotronics, Inc.", + "642A Magnet PSU", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_648, + 0, + "Lake Shore Cryotronics, Inc.", + "648 Magnet PSU", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_737, + 0, + "Lake Shore Cryotronics, Inc.", + "737 VSM Controller", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_776, + 0, + "Lake Shore Cryotronics, Inc.", + "776 Matrix Switch", + }, { USB_VENDOR_LARSENBRUSGAARD, USB_PRODUCT_LARSENBRUSGAARD_ALTITRACK, 0, @@ -7383,6 +8109,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Liebert", "PowerSure Personal XT", }, + { + USB_VENDOR_LIEBERT2, USB_PRODUCT_LIEBERT2_PSI1000, + 0, + "Liebert", + "UPS PSI 1000 FW:08", + }, { USB_VENDOR_LINKINSTRUMENTS, USB_PRODUCT_LINKINSTRUMENTS_MSO19, 0, @@ -7545,6 +8277,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Logitech", "QuickCam Pro", }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC100, + 0, + "Logitech", + "Webcam C100", + }, { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMEXP, 0, @@ -10239,12 +10977,24 @@ const struct usb_knowndev usb_knowndevs[] = { "NetChip Technology", "USB Clik! 40", }, + { + USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_GADGETZERO, + 0, + "NetChip Technology", + "Linux Gadget Zero", + }, { USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_ETHERNETGADGET, 0, "NetChip Technology", "Linux Ethernet/RNDIS gadget on pxa210/25x/26x", }, + { + USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_POCKETBOOK, + 0, + "NetChip Technology", + "PocketBook", + }, { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101, 0, @@ -10269,6 +11019,12 @@ const struct usb_knowndev usb_knowndevs[] = { "BayNETGEAR", "USB 2.0 Ethernet", }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_M4100, + 0, + "BayNETGEAR", + "M4100/M5300/M7100 series switch", + }, { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111V2_2, 0, @@ -10299,6 +11055,18 @@ const struct usb_knowndev usb_knowndevs[] = { "BayNETGEAR", "WG111V2", }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_RTL8192CU, + 0, + "BayNETGEAR", + "RTL8192CU", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000M, + 0, + "BayNETGEAR", + "WNA1000M", + }, { USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101, 0, @@ -10341,6 +11109,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Netgear", "WPN111", }, + { + USB_VENDOR_NETGEAR4, USB_PRODUCT_NETGEAR4_RTL8188CU, + 0, + "Netgear", + "RTL8188CU", + }, { USB_VENDOR_NETINDEX, USB_PRODUCT_NETINDEX_WS002IN, 0, @@ -10383,6 +11157,12 @@ const struct usb_knowndev usb_knowndevs[] = { "NovaTech", "RT2573", }, + { + USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RTL8188CU, + 0, + "NovaTech", + "RTL8188CU", + }, { USB_VENDOR_NOKIA, USB_PRODUCT_NOKIA_N958GB, 0, @@ -10521,6 +11301,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Novatel Wireless", "Novatel ZeroCD", }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MIFI2200V, + 0, + "Novatel Wireless", + "Novatel MiFi 2200 CDMA Virgin Mobile", + }, { USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD2, 0, @@ -10905,6 +11691,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Option N.V.", "Globetrotter HSUPA", }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTM661W, + 0, + "Option N.V.", + "GTM661W", + }, { USB_VENDOR_OPTION, USB_PRODUCT_OPTION_ICONEDGE, 0, @@ -11007,6 +11799,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Owen", "AC4 USB-RS485 converter", }, + { + USB_VENDOR_OWL, USB_PRODUCT_OWL_CM_160, + 0, + "OWL", + "OWL CM-160 power monitor", + }, { USB_VENDOR_PALM, USB_PRODUCT_PALM_SERIAL, 0, @@ -11439,6 +12237,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Planex Communications", "GW-US11H WLAN", }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CUS, + 0, + "Planex Communications", + "RTL8188CUS", + }, { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US11S, 0, @@ -11449,7 +12253,37 @@ const struct usb_knowndev usb_knowndevs[] = { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US54GXS, 0, "Planex Communications", - "GW-US54GXS WLAN", + "GW-US54GXS WLAN", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_1, + 0, + "Planex Communications", + "RTL8188CU", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_2, + 0, + "Planex Communications", + "RTL8188CU", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_3, + 0, + "Planex Communications", + "RTL8188CU", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_4, + 0, + "Planex Communications", + "RTL8188CU", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8192CU, + 0, + "Planex Communications", + "RTL8192CU", }, { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP, @@ -11541,6 +12375,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Planex Communications", "GW-US54Mini", }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSNANO, + 0, + "Planex Communications", + "GW-USNano", + }, { USB_VENDOR_PLEXTOR, USB_PRODUCT_PLEXTOR_40_12_40U, 0, @@ -12489,6 +13329,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Ralink Technology", "RT2870", }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT_STOR, + 0, + "Ralink Technology", + "USB Storage", + }, { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3070, 0, @@ -12519,12 +13365,24 @@ const struct usb_knowndev usb_knowndevs[] = { "Ralink Technology", "RT3572", }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3573, + 0, + "Ralink Technology", + "RT3573", + }, { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT5370, 0, "Ralink Technology", "RT5370", }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT5572, + 0, + "Ralink Technology", + "RT5572", + }, { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT8070, 0, @@ -12567,12 +13425,78 @@ const struct usb_knowndev usb_knowndevs[] = { "Realtek", "USB20CRW Card Reader", }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CTV, + 0, + "Realtek", + "RTL8188CTV", + }, { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_USBKR100, 0, "Realtek", "USBKR100 USB Ethernet", }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_0, + 0, + "Realtek", + "RTL8188CE", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8171, + 0, + "Realtek", + "RTL8171", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8172, + 0, + "Realtek", + "RTL8172", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8173, + 0, + "Realtek", + "RTL8173", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8174, + 0, + "Realtek", + "RTL8174", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_0, + 0, + "Realtek", + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188EU, + 0, + "Realtek", + "RTL8188EU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_1, + 0, + "Realtek", + "RTL8188CE", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_1, + 0, + "Realtek", + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_2, + 0, + "Realtek", + "RTL8188CU", + }, { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187, 0, @@ -12585,6 +13509,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Realtek", "RTL8187B Wireless Adapter", }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8196EU, + 0, + "Realtek", + "RTL8196EU", + }, { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187B_1, 0, @@ -12597,6 +13527,66 @@ const struct usb_knowndev usb_knowndevs[] = { "Realtek", "RTL8187B Wireless Adapter", }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CUS, + 0, + "Realtek", + "RTL8188CUS", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_COMBO, + 0, + "Realtek", + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8191CU, + 0, + "Realtek", + "RTL8191CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CU, + 0, + "Realtek", + "RTL8192CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CE, + 0, + "Realtek", + "RTL8192CE", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_1, + 0, + "Realtek", + "RTL8188RU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8712, + 0, + "Realtek", + "RTL8712", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8713, + 0, + "Realtek", + "RTL8713", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_2, + 0, + "Realtek", + "RTL8188RU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192SU, + 0, + "Realtek", + "RTL8192SU", + }, { USB_VENDOR_REDOCTANE, USB_PRODUCT_REDOCTANE_DUMMY, 0, @@ -12891,6 +13881,12 @@ const struct usb_knowndev usb_knowndevs[] = { "SanDisk", "ImageMate SDDR-75", }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_128, + 0, + "SanDisk", + "Cruzer Mini 128MB", + }, { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_256, 0, @@ -12939,6 +13935,12 @@ const struct usb_knowndev usb_knowndevs[] = { "ScanLogic", "Phantom 336CX - C3 scanner", }, + { + USB_VENDOR_SEL, USB_PRODUCT_SEL_C662, + 0, + "Schweitzer Engineering Laboratories", + "C662 Cable", + }, { USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2101, 0, @@ -13293,6 +14295,18 @@ const struct usb_knowndev usb_knowndevs[] = { "Senao", "RT3072", }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RTL8192SU_1, + 0, + "Senao", + "RTL8192SU", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RTL8192SU_2, + 0, + "Senao", + "RTL8192SU", + }, { USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268, 0, @@ -14223,6 +15237,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Silicon Labs", "AC-Services CIS-IBUS", }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_V_PREON32, + 0, + "Silicon Labs", + "Virtenio Preon32", + }, { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AC_SERV_CAN, 0, @@ -14235,6 +15255,18 @@ const struct usb_knowndev usb_knowndevs[] = { "Silicon Labs", "AC-Services OBD Interface", }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_MMB_ZIGBEE, + 0, + "Silicon Labs", + "MMB Networks ZigBee", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_INGENI_ZIGBEE, + 0, + "Silicon Labs", + "Planet Innovation Ingeni ZigBee", + }, { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2102, 0, @@ -14439,6 +15471,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Sitecom Europe", "RT3072", }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL353, + 0, + "Sitecom Europe", + "WL-353", + }, { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_3, 0, @@ -14457,12 +15495,42 @@ const struct usb_knowndev usb_knowndevs[] = { "Sitecom Europe", "RT3072", }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL349V1, + 0, + "Sitecom Europe", + "WL-349 v1", + }, { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_6, 0, "Sitecom Europe", "RT3072", }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU_1, + 0, + "Sitecom Europe", + "RTL8188CU", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU_2, + 0, + "Sitecom Europe", + "RTL8188CU", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8192CU, + 0, + "Sitecom Europe", + "RTL8192CU", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN032, + 0, + "Sitecom Europe", + "LN-032", + }, { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028, 0, @@ -14565,6 +15633,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Standard Microsystems", "2662W-AR Wireless", }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9514_ETH, + 0, + "Standard Microsystems", + "USB/Ethernet", + }, { USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100, 0, @@ -14967,6 +16041,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Super Top", "USB-IDE", }, + { + USB_VENDOR_SUPERTOP, USB_PRODUCT_SUPERTOP_FLASHDRIVE, + 0, + "Super Top", + "extrememory Snippy", + }, { USB_VENDOR_SYNTECH, USB_PRODUCT_SYNTECH_CPT8001C, 0, @@ -15075,6 +16155,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Sweex", "LW153", }, + { + USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW154, + 0, + "Sweex", + "LW154", + }, { USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW303, 0, @@ -15273,6 +16359,18 @@ const struct usb_knowndev usb_knowndevs[] = { "Trek Technology", "ThumbDrive_8MB", }, + { + USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8192CU, + 0, + "TRENDnet", + "RTL8192CU", + }, + { + USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8188CU, + 0, + "TRENDnet", + "RTL8188CU", + }, { USB_VENDOR_TRIPPLITE, USB_PRODUCT_TRIPPLITE_U209, 0, @@ -15609,6 +16707,12 @@ const struct usb_knowndev usb_knowndevs[] = { "QinHeng Electronics", "CH345 USB2.0-MIDI", }, + { + USB_VENDOR_WESTMOUNTAIN, USB_PRODUCT_WESTMOUNTAIN_RIGBLASTER_ADVANTAGE, + 0, + "West Mountain Radio", + "RIGblaster Advantage", + }, { USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_COMBO, 0, @@ -15639,6 +16743,18 @@ const struct usb_knowndev usb_knowndevs[] = { "Western Digital", "MyPassword External HDD", }, + { + USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYPASSPORT, + 0, + "Western Digital", + "MyPassport External HDD", + }, + { + USB_VENDOR_WETELECOM, USB_PRODUCT_WETELECOM_WM_D200, + 0, + "WeTelecom", + "WM-D200", + }, { USB_VENDOR_WIENERPLEINBAUS, USB_PRODUCT_WIENERPLEINBAUS_PL512, 0, @@ -15993,6 +17109,18 @@ const struct usb_knowndev usb_knowndevs[] = { "ZyXEL Communication", "RT2870", }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RTL8192CU, + 0, + "ZyXEL Communication", + "RTL8192CU", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD2705, + 0, + "ZyXEL Communication", + "NWD2705", + }, { USB_VENDOR_UNKNOWN1, 0, USB_KNOWNDEV_NOPROD, @@ -18753,6 +19881,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Realtek", NULL, }, + { + USB_VENDOR_ERICSSON2, 0, + USB_KNOWNDEV_NOPROD, + "Ericsson", + NULL, + }, { USB_VENDOR_MEI, 0, USB_KNOWNDEV_NOPROD, @@ -18783,6 +19917,12 @@ const struct usb_knowndev usb_knowndevs[] = { "DMI", NULL, }, + { + USB_VENDOR_CANYON, 0, + USB_KNOWNDEV_NOPROD, + "Canyon", + NULL, + }, { USB_VENDOR_ICOM, 0, USB_KNOWNDEV_NOPROD, @@ -19065,6 +20205,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Larsen and Brusgaard", NULL, }, + { + USB_VENDOR_OWL, 0, + USB_KNOWNDEV_NOPROD, + "OWL", + NULL, + }, { USB_VENDOR_KONTRON, 0, USB_KNOWNDEV_NOPROD, @@ -19089,6 +20235,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Motorola", NULL, }, + { + USB_VENDOR_HP3, 0, + USB_KNOWNDEV_NOPROD, + "Hewlett Packard", + NULL, + }, { USB_VENDOR_AIRPLUS, 0, USB_KNOWNDEV_NOPROD, @@ -19155,6 +20307,12 @@ const struct usb_knowndev usb_knowndevs[] = { "USI", NULL, }, + { + USB_VENDOR_LIEBERT2, 0, + USB_KNOWNDEV_NOPROD, + "Liebert", + NULL, + }, { USB_VENDOR_PLX, 0, USB_KNOWNDEV_NOPROD, @@ -19491,6 +20649,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Imagination Technologies", NULL, }, + { + USB_VENDOR_ATP, 0, + USB_KNOWNDEV_NOPROD, + "ATP Electronics", + NULL, + }, { USB_VENDOR_CONCEPTRONIC2, 0, USB_KNOWNDEV_NOPROD, @@ -19563,6 +20727,18 @@ const struct usb_knowndev usb_knowndevs[] = { "Fiberline", NULL, }, + { + USB_VENDOR_FREESCALE, 0, + USB_KNOWNDEV_NOPROD, + "Freescale Semiconductor, Inc.", + NULL, + }, + { + USB_VENDOR_AFATECH, 0, + USB_KNOWNDEV_NOPROD, + "Afatech Technologies, Inc.", + NULL, + }, { USB_VENDOR_SPARKLAN, 0, USB_KNOWNDEV_NOPROD, @@ -19803,6 +20979,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Stelera Wireless", NULL, }, + { + USB_VENDOR_SEL, 0, + USB_KNOWNDEV_NOPROD, + "Schweitzer Engineering Laboratories", + NULL, + }, { USB_VENDOR_CORSAIR, 0, USB_KNOWNDEV_NOPROD, @@ -19923,6 +21105,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Festo", NULL, }, + { + USB_VENDOR_LAKESHORE, 0, + USB_KNOWNDEV_NOPROD, + "Lake Shore Cryotronics, Inc.", + NULL, + }, { USB_VENDOR_VERTEX, 0, USB_KNOWNDEV_NOPROD, @@ -19977,6 +21165,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Simtec Electronics", NULL, }, + { + USB_VENDOR_TRENDNET, 0, + USB_KNOWNDEV_NOPROD, + "TRENDnet", + NULL, + }, { USB_VENDOR_RTSYSTEMS, 0, USB_KNOWNDEV_NOPROD, @@ -20001,6 +21195,18 @@ const struct usb_knowndev usb_knowndevs[] = { "Motorola", NULL, }, + { + USB_VENDOR_WETELECOM, 0, + USB_KNOWNDEV_NOPROD, + "WeTelecom", + NULL, + }, + { + USB_VENDOR_WESTMOUNTAIN, 0, + USB_KNOWNDEV_NOPROD, + "West Mountain Radio", + NULL, + }, { USB_VENDOR_TRIPPLITE, 0, USB_KNOWNDEV_NOPROD, @@ -20103,6 +21309,12 @@ const struct usb_knowndev usb_knowndevs[] = { "Aceeca", NULL, }, + { + USB_VENDOR_FEIXUN, 0, + USB_KNOWNDEV_NOPROD, + "FeiXun Communication", + NULL, + }, { USB_VENDOR_PAPOUCH, 0, USB_KNOWNDEV_NOPROD, @@ -20193,6 +21405,12 @@ const struct usb_knowndev usb_knowndevs[] = { "MosChip Semiconductor", NULL, }, + { + USB_VENDOR_NETGEAR4, 0, + USB_KNOWNDEV_NOPROD, + "Netgear", + NULL, + }, { USB_VENDOR_MARVELL, 0, USB_KNOWNDEV_NOPROD, diff --git a/rtemsbsd/include/rtems/bsd/sys/param.h b/rtemsbsd/include/rtems/bsd/sys/param.h index 76ba0b7b..2945691f 100644 --- a/rtemsbsd/include/rtems/bsd/sys/param.h +++ b/rtemsbsd/include/rtems/bsd/sys/param.h @@ -61,7 +61,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 802000 /* Master, propagated to newvers */ +#define __FreeBSD_version 903000 /* Master, propagated to newvers */ #ifdef _KERNEL #define P_OSREL_SIGSEGV 700004 diff --git a/rtemsbsd/rtems/rtems-bsd-mutex.c b/rtemsbsd/rtems/rtems-bsd-mutex.c index 37cc04ca..26f6ce28 100644 --- a/rtemsbsd/rtems/rtems-bsd-mutex.c +++ b/rtemsbsd/rtems/rtems-bsd-mutex.c @@ -222,4 +222,5 @@ void mutex_init(void) { mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE); + mtx_lock(&Giant); } diff --git a/rtemsbsd/rtems/rtems-bsd-thread.c b/rtemsbsd/rtems/rtems-bsd-thread.c index 4fd5184c..ef94188f 100644 --- a/rtemsbsd/rtems/rtems-bsd-thread.c +++ b/rtemsbsd/rtems/rtems-bsd-thread.c @@ -238,7 +238,7 @@ rtems_bsd_threads_init_late(void *arg) SYSINIT(rtems_bsd_threads_early, SI_SUB_INTRINSIC, SI_ORDER_ANY, rtems_bsd_threads_init_early, NULL); -SYSINIT(rtems_bsd_threads_late, SI_SUB_RUN_SCHEDULER, SI_ORDER_ANY, +SYSINIT(rtems_bsd_threads_late, SI_SUB_LAST, SI_ORDER_ANY, rtems_bsd_threads_init_late, NULL); static int -- cgit v1.2.3