diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index be9f81dd3cb0..30f129d66487 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -1,16880 +1,16883 @@ # # $FreeBSD$ # # This file lists old files (OLD_FILES), libraries (OLD_LIBS, MOVED_LIBS) # and directories (OLD_DIRS) which should get removed after an update. # Recently removed entries should be listed first (with the date as a # comment). OLD_LIBS and MOVED_LIBS should only list dynamic libraries. # Static libraries, links to dynamic libraries (lib*.so), and linker scripts # should be listed in OLD_FILES. OLD_LIBS and MOVED_LIBS are removed by the # delete-old-libs target, whereas OLD_FILES and OLD_DIRS are removed by the # delete-old target. This separation allows users to avoid deleting old # dynamic libraries still required by existing binaries. # # MOVED_LIBS should be used instead of OLD_LIBS when a library is moved # from usr/lib to lib or vice versa. This avoids removing libraries for # alternate ABIs (such as lib32) which store all libraries in a single # directory (e.g. usr/lib32). # # For files listed in OLD_FILES, OLD_LIBS, and MOVED_LIBS, the check-old* # and delete-old* targets will also delete associated debug symbols from # usr/lib/debug. # # In case of a complete directory hierarchy the sorting is in depth first # order. # # Files that are installed or removed depending on some build option # should be listed in /usr/src/tools/build/mk/OptionalObsoleteFiles.inc # instead of in this file. # # Before you commit changes to this file please check if any entries in # tools/build/mk/OptionalObsoleteFiles.inc can be removed. The following # command tells which files are listed more than once regardless of some # architecture specific conditionals, so you can not blindly trust the # output: # ( grep '+=' /usr/src/ObsoleteFiles.inc | sort -u ; \ # grep '+=' /usr/src/tools/build/mk/OptionalObsoleteFiles.inc | sort -u) | \ # sort | uniq -d # # To find regular duplicates not dependent on optional components, you can # also use something that will not give you false positives, e.g.: # for t in `make -V TARGETS universe`; do # __MAKE_CONF=/dev/null make -f Makefile.inc1 TARGET=$t \ # -V OLD_FILES -V OLD_LIBS -V MOVED_LIBS -V OLD_DIRS check-old | \ # xargs -n1 | sort | uniq -d; # done # # For optional components, you can use the following to see if some entries # in OptionalObsoleteFiles.inc have been obsoleted by ObsoleteFiles.inc # for o in tools/build/options/WITH*; do # __MAKE_CONF=/dev/null make -f Makefile.inc1 -D${o##*/} \ # -V OLD_FILES -V OLD_LIBS -V MOVED_LIBS -V OLD_DIRS check-old | \ # xargs -n1 | sort | uniq -d; # done +# 20221214: TCPDEBUG removed +OLD_FILES+=usr/include/netinet/tcp_debug.h + # 20221213: remove sync serial drivers and utilities OLD_FILES+=sbin/sconfig OLD_FILES+=usr/share/man/man4/ce.4 OLD_FILES+=usr/share/man/man4/cp.4 OLD_FILES+=usr/share/man/man8/sconfig.8.gz # 20221202: remove trpt(8) OLD_FILES+=usr/sbin/trpt OLD_FILES+=usr/share/man/man8/trpt.8.gz # 20221117: remove typo'd man page link OLD_FILES+=usr/share/man/man9/vm_map_wire_mapped.9.gz # 20221114: remove othermta OLD_FILES+=etc/rc.d/othermta # 20221109: remove rc.sendmail(8) OLD_FILES+=etc/rc.sendmail OLD_FILES+=usr/share/man/man8/rc.sendmail.8.gz # 20221015: update the ithread(9) man page OLD_FILES+=usr/share/man/man9/ithread.9.gz OLD_FILES+=usr/share/man/man9/ithread_add_handler.9.gz OLD_FILES+=usr/share/man/man9/ithread_create.9.gz OLD_FILES+=usr/share/man/man9/ithread_destroy.9.gz OLD_FILES+=usr/share/man/man9/ithread_priority.9.gz OLD_FILES+=usr/share/man/man9/ithread_remove_handler.9.gz OLD_FILES+=usr/share/man/man9/ithread_schedule.9.gz # 20221012: remove nls support from sort OLD_FILES+=usr/share/nls/hu_HU.ISO8859-2/sort.cat # 20221003: ip6protosw.h removed OLD_FILES+=usr/include/netinet6/ip6protosw.h # 20221001: deorbit opie OLD_FILES+=etc/opieaccess OLD_FILES+=etc/opiekeys OLD_FILES+=usr/bin/opieinfo OLD_FILES+=usr/bin/opiekey OLD_FILES+=usr/bin/opiepasswd OLD_FILES+=usr/bin/otp-md4 OLD_FILES+=usr/bin/otp-md5 OLD_FILES+=usr/bin/otp-sha1 OLD_FILES+=usr/lib/libopie.a OLD_FILES+=usr/lib/libopie.so OLD_LIBS+=usr/lib/libopie.so.8 OLD_FILES+=usr/lib/libopie_p.a OLD_FILES+=usr/lib/pam_opie.so OLD_LIBS+=usr/lib/pam_opie.so.6 OLD_FILES+=usr/lib/pam_opieaccess.so OLD_LIBS+=usr/lib/pam_opieaccess.so.6 OLD_FILES+=usr/share/man/man1/opieinfo.1.gz OLD_FILES+=usr/share/man/man1/opiekey.1.gz OLD_FILES+=usr/share/man/man1/opiepasswd.1.gz OLD_FILES+=usr/share/man/man1/otp-md4.1.gz OLD_FILES+=usr/share/man/man1/otp-md5.1.gz OLD_FILES+=usr/share/man/man1/otp-sha1.1.gz OLD_FILES+=usr/share/man/man4/opie.4.gz OLD_FILES+=usr/share/man/man5/opieaccess.5.gz OLD_FILES+=usr/share/man/man5/opiekeys.5.gz OLD_FILES+=usr/share/man/man8/pam_opie.8.gz OLD_FILES+=usr/share/man/man8/pam_opieaccess.8.gz # 20220928: telnetd(8) removed OLD_FILES+=etc/pam.d/telnetd OLD_FILES+=usr/libexec/telnetd OLD_FILES+=usr/share/man/man8/telnetd.8.gz # 20220914: domain(9) updated OLD_FILES+=usr/share/man/man9/domain_init.9.gz OLD_FILES+=usr/share/man/man9/pfctlinput.9.gz OLD_FILES+=usr/share/man/man9/pffinddomain.9.gz OLD_FILES+=usr/share/man/man9/pffindproto.9.gz OLD_FILES+=usr/share/man/man9/pffindtype.9.gz # 20220825: awk tests moved to subdirs OLD_FILES+=usr/tests/usr.bin/awk/awk_test OLD_FILES+=usr/tests/usr.bin/awk/d_assign_NF.awk OLD_FILES+=usr/tests/usr.bin/awk/d_assign_NF.in OLD_FILES+=usr/tests/usr.bin/awk/d_assign_NF.out OLD_FILES+=usr/tests/usr.bin/awk/d_big_regexp.awk OLD_FILES+=usr/tests/usr.bin/awk/d_big_regexp.in OLD_FILES+=usr/tests/usr.bin/awk/d_big_regexp.out OLD_FILES+=usr/tests/usr.bin/awk/d_end1.awk OLD_FILES+=usr/tests/usr.bin/awk/d_end1.in OLD_FILES+=usr/tests/usr.bin/awk/d_end1.out OLD_FILES+=usr/tests/usr.bin/awk/d_end2.awk OLD_FILES+=usr/tests/usr.bin/awk/d_end2.in OLD_FILES+=usr/tests/usr.bin/awk/d_end2.out OLD_FILES+=usr/tests/usr.bin/awk/d_period.awk OLD_FILES+=usr/tests/usr.bin/awk/d_period.in OLD_FILES+=usr/tests/usr.bin/awk/d_period.out OLD_FILES+=usr/tests/usr.bin/awk/d_string1.awk OLD_FILES+=usr/tests/usr.bin/awk/d_string1.out OLD_FILES+=usr/tests/usr.bin/awk/d_tolower.awk OLD_FILES+=usr/tests/usr.bin/awk/d_tolower.in OLD_FILES+=usr/tests/usr.bin/awk/d_tolower.out OLD_FILES+=usr/tests/usr.bin/awk/d_toupper.awk OLD_FILES+=usr/tests/usr.bin/awk/d_toupper.in OLD_FILES+=usr/tests/usr.bin/awk/d_toupper.out # 20220820: remove knlist_init_rw_reader() OLD_FILES+=usr/share/man/man9/knlist_init_rw_reader.9.gz # 20220813: minigzip(1) removed in favor of gzip(1) OLD_FILES+=usr/bin/minigzip OLD_FILES+=usr/share/man/man1/minigzip.1.gz # 20220811: new iconv encoder trait added OLD_LIBS+=usr/lib/i18n/libBIG5.so.4 OLD_LIBS+=usr/lib/i18n/libDECHanyu.so.4 OLD_LIBS+=usr/lib/i18n/libEUC.so.4 OLD_LIBS+=usr/lib/i18n/libEUCTW.so.4 OLD_LIBS+=usr/lib/i18n/libGBK2K.so.4 OLD_LIBS+=usr/lib/i18n/libHZ.so.4 OLD_LIBS+=usr/lib/i18n/libISO2022.so.4 OLD_LIBS+=usr/lib/i18n/libJOHAB.so.4 OLD_LIBS+=usr/lib/i18n/libMSKanji.so.4 OLD_LIBS+=usr/lib/i18n/libUES.so.4 OLD_LIBS+=usr/lib/i18n/libUTF1632.so.4 OLD_LIBS+=usr/lib/i18n/libUTF7.so.4 OLD_LIBS+=usr/lib/i18n/libUTF8.so.4 OLD_LIBS+=usr/lib/i18n/libVIQR.so.4 OLD_LIBS+=usr/lib/i18n/libZW.so.4 OLD_LIBS+=usr/lib/i18n/libiconv_none.so.4 OLD_LIBS+=usr/lib/i18n/libiconv_std.so.4 OLD_LIBS+=usr/lib/i18n/libmapper_646.so.4 OLD_LIBS+=usr/lib/i18n/libmapper_none.so.4 OLD_LIBS+=usr/lib/i18n/libmapper_parallel.so.4 OLD_LIBS+=usr/lib/i18n/libmapper_serial.so.4 OLD_LIBS+=usr/lib/i18n/libmapper_std.so.4 OLD_LIBS+=usr/lib/i18n/libmapper_zone.so.4 # 20220811: raw socket layer removed OLD_FILES+=usr/include/net/raw_cb.h # 20220721: libnv version bumps OLD_LIBS+=lib/libnv.so.0 # 20220624: unix_passfd_test -> unix_passfd_stream/unix_passfd_dgram OLD_FILES+=usr/tests/sys/kern/unix_passfd_test # 20220621: ISA sound card drivers removed OLD_FILES+=usr/share/man/man4/snd_ad1816.4.gz OLD_FILES+=usr/share/man/man4/snd_ess.4.gz OLD_FILES+=usr/share/man/man4/snd_gusc.4.gz OLD_FILES+=usr/share/man/man4/snd_mss.4.gz OLD_FILES+=usr/share/man/man4/snd_sb16.4.gz OLD_FILES+=usr/share/man/man4/snd_sb8.4.gz OLD_FILES+=usr/share/man/man4/snd_sbc.4.gz # 20220612: new clang import which bumps version from 14.0.4 to 14.0.5 OLD_FILES+=usr/lib/clang/14.0.4/include/cuda_wrappers/algorithm OLD_FILES+=usr/lib/clang/14.0.4/include/cuda_wrappers/complex OLD_FILES+=usr/lib/clang/14.0.4/include/cuda_wrappers/new OLD_DIRS+=usr/lib/clang/14.0.4/include/cuda_wrappers OLD_FILES+=usr/lib/clang/14.0.4/include/fuzzer/FuzzedDataProvider.h OLD_DIRS+=usr/lib/clang/14.0.4/include/fuzzer OLD_FILES+=usr/lib/clang/14.0.4/include/openmp_wrappers/__clang_openmp_device_functions.h OLD_FILES+=usr/lib/clang/14.0.4/include/openmp_wrappers/cmath OLD_FILES+=usr/lib/clang/14.0.4/include/openmp_wrappers/complex OLD_FILES+=usr/lib/clang/14.0.4/include/openmp_wrappers/complex.h OLD_FILES+=usr/lib/clang/14.0.4/include/openmp_wrappers/complex_cmath.h OLD_FILES+=usr/lib/clang/14.0.4/include/openmp_wrappers/math.h OLD_FILES+=usr/lib/clang/14.0.4/include/openmp_wrappers/new OLD_DIRS+=usr/lib/clang/14.0.4/include/openmp_wrappers OLD_FILES+=usr/lib/clang/14.0.4/include/ppc_wrappers/emmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/ppc_wrappers/mm_malloc.h OLD_FILES+=usr/lib/clang/14.0.4/include/ppc_wrappers/mmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/ppc_wrappers/pmmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/ppc_wrappers/smmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/ppc_wrappers/tmmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/ppc_wrappers/xmmintrin.h OLD_DIRS+=usr/lib/clang/14.0.4/include/ppc_wrappers OLD_FILES+=usr/lib/clang/14.0.4/include/profile/InstrProfData.inc OLD_FILES+=usr/lib/clang/14.0.4/include/profile/MemProfData.inc OLD_DIRS+=usr/lib/clang/14.0.4/include/profile OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/memprof_interface.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/tsan_interface_atomic.h OLD_FILES+=usr/lib/clang/14.0.4/include/sanitizer/ubsan_interface.h OLD_DIRS+=usr/lib/clang/14.0.4/include/sanitizer OLD_FILES+=usr/lib/clang/14.0.4/include/xray/xray_interface.h OLD_FILES+=usr/lib/clang/14.0.4/include/xray/xray_log_interface.h OLD_FILES+=usr/lib/clang/14.0.4/include/xray/xray_records.h OLD_DIRS+=usr/lib/clang/14.0.4/include/xray OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_cuda_math.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_cuda_texture_intrinsics.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_hip_cmath.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_hip_libdevice_declares.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_hip_math.h OLD_FILES+=usr/lib/clang/14.0.4/include/__clang_hip_runtime_wrapper.h OLD_FILES+=usr/lib/clang/14.0.4/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/14.0.4/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/14.0.4/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/14.0.4/include/adxintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/altivec.h OLD_FILES+=usr/lib/clang/14.0.4/include/ammintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/amxintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/arm64intr.h OLD_FILES+=usr/lib/clang/14.0.4/include/arm_acle.h OLD_FILES+=usr/lib/clang/14.0.4/include/arm_bf16.h OLD_FILES+=usr/lib/clang/14.0.4/include/arm_cde.h OLD_FILES+=usr/lib/clang/14.0.4/include/arm_cmse.h OLD_FILES+=usr/lib/clang/14.0.4/include/arm_fp16.h OLD_FILES+=usr/lib/clang/14.0.4/include/arm_mve.h OLD_FILES+=usr/lib/clang/14.0.4/include/arm_neon.h OLD_FILES+=usr/lib/clang/14.0.4/include/arm_neon_sve_bridge.h OLD_FILES+=usr/lib/clang/14.0.4/include/arm_sve.h OLD_FILES+=usr/lib/clang/14.0.4/include/armintr.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx2intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512bf16intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512fp16intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vlbf16intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vlfp16intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vlvp2intersectintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vp2intersectintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avxintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/avxvnniintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/bmiintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/builtins.h OLD_FILES+=usr/lib/clang/14.0.4/include/cet.h OLD_FILES+=usr/lib/clang/14.0.4/include/cetintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/clwbintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/clzerointrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/cpuid.h OLD_FILES+=usr/lib/clang/14.0.4/include/crc32intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/emmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/enqcmdintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/f16cintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/float.h OLD_FILES+=usr/lib/clang/14.0.4/include/fma4intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/fmaintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/gfniintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/hexagon_circ_brev_intrinsics.h OLD_FILES+=usr/lib/clang/14.0.4/include/hexagon_protos.h OLD_FILES+=usr/lib/clang/14.0.4/include/hexagon_types.h OLD_FILES+=usr/lib/clang/14.0.4/include/hresetintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/htmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/hvx_hexagon_protos.h OLD_FILES+=usr/lib/clang/14.0.4/include/ia32intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/immintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/inttypes.h OLD_FILES+=usr/lib/clang/14.0.4/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/iso646.h OLD_FILES+=usr/lib/clang/14.0.4/include/keylockerintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/limits.h OLD_FILES+=usr/lib/clang/14.0.4/include/lwpintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/mm3dnow.h OLD_FILES+=usr/lib/clang/14.0.4/include/mm_malloc.h OLD_FILES+=usr/lib/clang/14.0.4/include/mmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/module.modulemap OLD_FILES+=usr/lib/clang/14.0.4/include/movdirintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/msa.h OLD_FILES+=usr/lib/clang/14.0.4/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/nmmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/omp-tools.h OLD_FILES+=usr/lib/clang/14.0.4/include/omp.h OLD_FILES+=usr/lib/clang/14.0.4/include/ompt.h OLD_FILES+=usr/lib/clang/14.0.4/include/opencl-c-base.h OLD_FILES+=usr/lib/clang/14.0.4/include/opencl-c.h OLD_FILES+=usr/lib/clang/14.0.4/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/pkuintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/pmmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/popcntintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/riscv_vector.h OLD_FILES+=usr/lib/clang/14.0.4/include/rtmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/s390intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/serializeintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/sgxintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/shaintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/smmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/stdalign.h OLD_FILES+=usr/lib/clang/14.0.4/include/stdarg.h OLD_FILES+=usr/lib/clang/14.0.4/include/stdatomic.h OLD_FILES+=usr/lib/clang/14.0.4/include/stdbool.h OLD_FILES+=usr/lib/clang/14.0.4/include/stddef.h OLD_FILES+=usr/lib/clang/14.0.4/include/stdint.h OLD_FILES+=usr/lib/clang/14.0.4/include/stdnoreturn.h OLD_FILES+=usr/lib/clang/14.0.4/include/tbmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/tgmath.h OLD_FILES+=usr/lib/clang/14.0.4/include/tmmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/tsxldtrkintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/uintrintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/unwind.h OLD_FILES+=usr/lib/clang/14.0.4/include/vadefs.h OLD_FILES+=usr/lib/clang/14.0.4/include/vaesintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/varargs.h OLD_FILES+=usr/lib/clang/14.0.4/include/vecintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/wasm_simd128.h OLD_FILES+=usr/lib/clang/14.0.4/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/wmmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/x86gprintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/x86intrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/xmmintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/xopintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/14.0.4/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/14.0.4/include OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-aarch64.so OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-arm.so OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-armhf.so OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-preinit-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-preinit-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-preinit-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan_cxx-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan_cxx-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan_static-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.asan_static-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.cfi-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.cfi-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.cfi-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.cfi-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.cfi-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.cfi_diag-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.cfi_diag-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.cfi_diag-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.cfi_diag-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.cfi_diag-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.dd-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.dd-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.fuzzer-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.fuzzer-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.fuzzer_interceptors-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.msan-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.msan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.profile-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.profile-powerpc.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.profile-powerpc64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.profile-powerpc64le.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.safestack-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.stats-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.stats-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.stats-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.stats_client-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.stats_client-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.stats_client-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.tsan-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_minimal-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_standalone-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-basic-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-basic-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-basic-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-basic-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-fdr-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-fdr-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-fdr-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-fdr-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-profiling-aarch64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-profiling-arm.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-profiling-armhf.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-profiling-x86_64.a OLD_FILES+=usr/lib/clang/14.0.4/lib/freebsd/libclang_rt.xray-x86_64.a OLD_DIRS+=usr/lib/clang/14.0.4/lib/freebsd OLD_DIRS+=usr/lib/clang/14.0.4/lib/share OLD_DIRS+=usr/lib/clang/14.0.4/lib OLD_FILES+=usr/lib/clang/14.0.4/share/asan_ignorelist.txt OLD_FILES+=usr/lib/clang/14.0.4/share/cfi_ignorelist.txt OLD_FILES+=usr/lib/clang/14.0.4/share/msan_ignorelist.txt OLD_DIRS+=usr/lib/clang/14.0.4/share OLD_DIRS+=usr/lib/clang/14.0.4 # 20220605: new clang import which bumps version from 14.0.3 to 14.0.4 OLD_FILES+=usr/lib/clang/14.0.3/include/cuda_wrappers/algorithm OLD_FILES+=usr/lib/clang/14.0.3/include/cuda_wrappers/complex OLD_FILES+=usr/lib/clang/14.0.3/include/cuda_wrappers/new OLD_DIRS+=usr/lib/clang/14.0.3/include/cuda_wrappers OLD_FILES+=usr/lib/clang/14.0.3/include/fuzzer/FuzzedDataProvider.h OLD_DIRS+=usr/lib/clang/14.0.3/include/fuzzer OLD_FILES+=usr/lib/clang/14.0.3/include/openmp_wrappers/__clang_openmp_device_functions.h OLD_FILES+=usr/lib/clang/14.0.3/include/openmp_wrappers/cmath OLD_FILES+=usr/lib/clang/14.0.3/include/openmp_wrappers/complex OLD_FILES+=usr/lib/clang/14.0.3/include/openmp_wrappers/complex.h OLD_FILES+=usr/lib/clang/14.0.3/include/openmp_wrappers/complex_cmath.h OLD_FILES+=usr/lib/clang/14.0.3/include/openmp_wrappers/math.h OLD_FILES+=usr/lib/clang/14.0.3/include/openmp_wrappers/new OLD_DIRS+=usr/lib/clang/14.0.3/include/openmp_wrappers OLD_FILES+=usr/lib/clang/14.0.3/include/ppc_wrappers/emmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/ppc_wrappers/mm_malloc.h OLD_FILES+=usr/lib/clang/14.0.3/include/ppc_wrappers/mmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/ppc_wrappers/pmmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/ppc_wrappers/smmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/ppc_wrappers/tmmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/ppc_wrappers/xmmintrin.h OLD_DIRS+=usr/lib/clang/14.0.3/include/ppc_wrappers OLD_FILES+=usr/lib/clang/14.0.3/include/profile/InstrProfData.inc OLD_FILES+=usr/lib/clang/14.0.3/include/profile/MemProfData.inc OLD_DIRS+=usr/lib/clang/14.0.3/include/profile OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/memprof_interface.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/tsan_interface_atomic.h OLD_FILES+=usr/lib/clang/14.0.3/include/sanitizer/ubsan_interface.h OLD_DIRS+=usr/lib/clang/14.0.3/include/sanitizer OLD_FILES+=usr/lib/clang/14.0.3/include/xray/xray_interface.h OLD_FILES+=usr/lib/clang/14.0.3/include/xray/xray_log_interface.h OLD_FILES+=usr/lib/clang/14.0.3/include/xray/xray_records.h OLD_DIRS+=usr/lib/clang/14.0.3/include/xray OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_cuda_math.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_cuda_texture_intrinsics.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_hip_cmath.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_hip_libdevice_declares.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_hip_math.h OLD_FILES+=usr/lib/clang/14.0.3/include/__clang_hip_runtime_wrapper.h OLD_FILES+=usr/lib/clang/14.0.3/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/14.0.3/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/14.0.3/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/14.0.3/include/adxintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/altivec.h OLD_FILES+=usr/lib/clang/14.0.3/include/ammintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/amxintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/arm64intr.h OLD_FILES+=usr/lib/clang/14.0.3/include/arm_acle.h OLD_FILES+=usr/lib/clang/14.0.3/include/arm_bf16.h OLD_FILES+=usr/lib/clang/14.0.3/include/arm_cde.h OLD_FILES+=usr/lib/clang/14.0.3/include/arm_cmse.h OLD_FILES+=usr/lib/clang/14.0.3/include/arm_fp16.h OLD_FILES+=usr/lib/clang/14.0.3/include/arm_mve.h OLD_FILES+=usr/lib/clang/14.0.3/include/arm_neon.h OLD_FILES+=usr/lib/clang/14.0.3/include/arm_neon_sve_bridge.h OLD_FILES+=usr/lib/clang/14.0.3/include/arm_sve.h OLD_FILES+=usr/lib/clang/14.0.3/include/armintr.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx2intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512bf16intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512fp16intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vlbf16intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vlfp16intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vlvp2intersectintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vp2intersectintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avxintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/avxvnniintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/bmiintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/builtins.h OLD_FILES+=usr/lib/clang/14.0.3/include/cet.h OLD_FILES+=usr/lib/clang/14.0.3/include/cetintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/clwbintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/clzerointrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/cpuid.h OLD_FILES+=usr/lib/clang/14.0.3/include/crc32intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/emmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/enqcmdintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/f16cintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/float.h OLD_FILES+=usr/lib/clang/14.0.3/include/fma4intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/fmaintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/gfniintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/hexagon_circ_brev_intrinsics.h OLD_FILES+=usr/lib/clang/14.0.3/include/hexagon_protos.h OLD_FILES+=usr/lib/clang/14.0.3/include/hexagon_types.h OLD_FILES+=usr/lib/clang/14.0.3/include/hresetintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/htmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/hvx_hexagon_protos.h OLD_FILES+=usr/lib/clang/14.0.3/include/ia32intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/immintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/inttypes.h OLD_FILES+=usr/lib/clang/14.0.3/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/iso646.h OLD_FILES+=usr/lib/clang/14.0.3/include/keylockerintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/limits.h OLD_FILES+=usr/lib/clang/14.0.3/include/lwpintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/mm3dnow.h OLD_FILES+=usr/lib/clang/14.0.3/include/mm_malloc.h OLD_FILES+=usr/lib/clang/14.0.3/include/mmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/module.modulemap OLD_FILES+=usr/lib/clang/14.0.3/include/movdirintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/msa.h OLD_FILES+=usr/lib/clang/14.0.3/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/nmmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/omp-tools.h OLD_FILES+=usr/lib/clang/14.0.3/include/omp.h OLD_FILES+=usr/lib/clang/14.0.3/include/ompt.h OLD_FILES+=usr/lib/clang/14.0.3/include/opencl-c-base.h OLD_FILES+=usr/lib/clang/14.0.3/include/opencl-c.h OLD_FILES+=usr/lib/clang/14.0.3/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/pkuintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/pmmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/popcntintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/riscv_vector.h OLD_FILES+=usr/lib/clang/14.0.3/include/rtmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/s390intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/serializeintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/sgxintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/shaintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/smmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/stdalign.h OLD_FILES+=usr/lib/clang/14.0.3/include/stdarg.h OLD_FILES+=usr/lib/clang/14.0.3/include/stdatomic.h OLD_FILES+=usr/lib/clang/14.0.3/include/stdbool.h OLD_FILES+=usr/lib/clang/14.0.3/include/stddef.h OLD_FILES+=usr/lib/clang/14.0.3/include/stdint.h OLD_FILES+=usr/lib/clang/14.0.3/include/stdnoreturn.h OLD_FILES+=usr/lib/clang/14.0.3/include/tbmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/tgmath.h OLD_FILES+=usr/lib/clang/14.0.3/include/tmmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/tsxldtrkintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/uintrintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/unwind.h OLD_FILES+=usr/lib/clang/14.0.3/include/vadefs.h OLD_FILES+=usr/lib/clang/14.0.3/include/vaesintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/varargs.h OLD_FILES+=usr/lib/clang/14.0.3/include/vecintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/wasm_simd128.h OLD_FILES+=usr/lib/clang/14.0.3/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/wmmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/x86gprintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/x86intrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/xmmintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/xopintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/14.0.3/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/14.0.3/include OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-aarch64.so OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-arm.so OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-armhf.so OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-preinit-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-preinit-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-preinit-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan_cxx-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan_cxx-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan_static-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.asan_static-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.cfi-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.cfi-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.cfi-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.cfi-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.cfi-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.cfi_diag-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.cfi_diag-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.cfi_diag-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.cfi_diag-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.cfi_diag-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.dd-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.dd-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.fuzzer-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.fuzzer-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.fuzzer_interceptors-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.msan-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.msan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.profile-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.profile-powerpc.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.profile-powerpc64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.profile-powerpc64le.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.safestack-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.stats-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.stats-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.stats-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.stats_client-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.stats_client-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.stats_client-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.tsan-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_minimal-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_standalone-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-basic-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-basic-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-basic-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-basic-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-fdr-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-fdr-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-fdr-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-fdr-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-profiling-aarch64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-profiling-arm.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-profiling-armhf.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-profiling-x86_64.a OLD_FILES+=usr/lib/clang/14.0.3/lib/freebsd/libclang_rt.xray-x86_64.a OLD_DIRS+=usr/lib/clang/14.0.3/lib/freebsd OLD_DIRS+=usr/lib/clang/14.0.3/lib/share OLD_DIRS+=usr/lib/clang/14.0.3/lib OLD_FILES+=usr/lib/clang/14.0.3/share/asan_ignorelist.txt OLD_FILES+=usr/lib/clang/14.0.3/share/cfi_ignorelist.txt OLD_FILES+=usr/lib/clang/14.0.3/share/msan_ignorelist.txt OLD_DIRS+=usr/lib/clang/14.0.3/share OLD_DIRS+=usr/lib/clang/14.0.3 # 20220524: libkqueue test updates OLD_FILES+=usr/tests/sys/kqueue/libkqueue/kqtest # 20220514: new clang import which bumps version from 13.0.0 to 14.0.3 OLD_FILES+=usr/lib/clang/13.0.0/include/cuda_wrappers/algorithm OLD_FILES+=usr/lib/clang/13.0.0/include/cuda_wrappers/complex OLD_FILES+=usr/lib/clang/13.0.0/include/cuda_wrappers/new OLD_DIRS+=usr/lib/clang/13.0.0/include/cuda_wrappers OLD_FILES+=usr/lib/clang/13.0.0/include/fuzzer/FuzzedDataProvider.h OLD_DIRS+=usr/lib/clang/13.0.0/include/fuzzer OLD_FILES+=usr/lib/clang/13.0.0/include/openmp_wrappers/__clang_openmp_device_functions.h OLD_FILES+=usr/lib/clang/13.0.0/include/openmp_wrappers/cmath OLD_FILES+=usr/lib/clang/13.0.0/include/openmp_wrappers/complex OLD_FILES+=usr/lib/clang/13.0.0/include/openmp_wrappers/complex.h OLD_FILES+=usr/lib/clang/13.0.0/include/openmp_wrappers/complex_cmath.h OLD_FILES+=usr/lib/clang/13.0.0/include/openmp_wrappers/math.h OLD_FILES+=usr/lib/clang/13.0.0/include/openmp_wrappers/new OLD_DIRS+=usr/lib/clang/13.0.0/include/openmp_wrappers OLD_FILES+=usr/lib/clang/13.0.0/include/ppc_wrappers/emmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/ppc_wrappers/mm_malloc.h OLD_FILES+=usr/lib/clang/13.0.0/include/ppc_wrappers/mmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/ppc_wrappers/pmmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/ppc_wrappers/smmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/ppc_wrappers/tmmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/ppc_wrappers/xmmintrin.h OLD_DIRS+=usr/lib/clang/13.0.0/include/ppc_wrappers OLD_FILES+=usr/lib/clang/13.0.0/include/profile/InstrProfData.inc OLD_DIRS+=usr/lib/clang/13.0.0/include/profile OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/tsan_interface_atomic.h OLD_FILES+=usr/lib/clang/13.0.0/include/sanitizer/ubsan_interface.h OLD_DIRS+=usr/lib/clang/13.0.0/include/sanitizer OLD_FILES+=usr/lib/clang/13.0.0/include/xray/xray_interface.h OLD_FILES+=usr/lib/clang/13.0.0/include/xray/xray_log_interface.h OLD_FILES+=usr/lib/clang/13.0.0/include/xray/xray_records.h OLD_DIRS+=usr/lib/clang/13.0.0/include/xray OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_cuda_math.h OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_hip_cmath.h OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_hip_libdevice_declares.h OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_hip_math.h OLD_FILES+=usr/lib/clang/13.0.0/include/__clang_hip_runtime_wrapper.h OLD_FILES+=usr/lib/clang/13.0.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/13.0.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/13.0.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/13.0.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/altivec.h OLD_FILES+=usr/lib/clang/13.0.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/amxintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/arm64intr.h OLD_FILES+=usr/lib/clang/13.0.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/13.0.0/include/arm_bf16.h OLD_FILES+=usr/lib/clang/13.0.0/include/arm_cde.h OLD_FILES+=usr/lib/clang/13.0.0/include/arm_cmse.h OLD_FILES+=usr/lib/clang/13.0.0/include/arm_fp16.h OLD_FILES+=usr/lib/clang/13.0.0/include/arm_mve.h OLD_FILES+=usr/lib/clang/13.0.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/13.0.0/include/arm_sve.h OLD_FILES+=usr/lib/clang/13.0.0/include/armintr.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512bf16intrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vlbf16intrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vlvp2intersectintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vp2intersectintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/avxvnniintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/builtins.h OLD_FILES+=usr/lib/clang/13.0.0/include/cet.h OLD_FILES+=usr/lib/clang/13.0.0/include/cetintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/clwbintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/clzerointrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/cpuid.h OLD_FILES+=usr/lib/clang/13.0.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/enqcmdintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/float.h OLD_FILES+=usr/lib/clang/13.0.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/gfniintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/hexagon_circ_brev_intrinsics.h OLD_FILES+=usr/lib/clang/13.0.0/include/hexagon_protos.h OLD_FILES+=usr/lib/clang/13.0.0/include/hexagon_types.h OLD_FILES+=usr/lib/clang/13.0.0/include/hresetintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/htmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/hvx_hexagon_protos.h OLD_FILES+=usr/lib/clang/13.0.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/immintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/intrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/inttypes.h OLD_FILES+=usr/lib/clang/13.0.0/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/iso646.h OLD_FILES+=usr/lib/clang/13.0.0/include/keylockerintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/limits.h OLD_FILES+=usr/lib/clang/13.0.0/include/lwpintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/13.0.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/13.0.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/module.modulemap OLD_FILES+=usr/lib/clang/13.0.0/include/movdirintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/msa.h OLD_FILES+=usr/lib/clang/13.0.0/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/omp-tools.h OLD_FILES+=usr/lib/clang/13.0.0/include/omp.h OLD_FILES+=usr/lib/clang/13.0.0/include/ompt.h OLD_FILES+=usr/lib/clang/13.0.0/include/opencl-c-base.h OLD_FILES+=usr/lib/clang/13.0.0/include/opencl-c.h OLD_FILES+=usr/lib/clang/13.0.0/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/pkuintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/riscv_vector.h OLD_FILES+=usr/lib/clang/13.0.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/s390intrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/serializeintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/sgxintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/stdalign.h OLD_FILES+=usr/lib/clang/13.0.0/include/stdarg.h OLD_FILES+=usr/lib/clang/13.0.0/include/stdatomic.h OLD_FILES+=usr/lib/clang/13.0.0/include/stdbool.h OLD_FILES+=usr/lib/clang/13.0.0/include/stddef.h OLD_FILES+=usr/lib/clang/13.0.0/include/stdint.h OLD_FILES+=usr/lib/clang/13.0.0/include/stdnoreturn.h OLD_FILES+=usr/lib/clang/13.0.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/tgmath.h OLD_FILES+=usr/lib/clang/13.0.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/tsxldtrkintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/uintrintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/unwind.h OLD_FILES+=usr/lib/clang/13.0.0/include/vadefs.h OLD_FILES+=usr/lib/clang/13.0.0/include/vaesintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/varargs.h OLD_FILES+=usr/lib/clang/13.0.0/include/vecintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/wasm_simd128.h OLD_FILES+=usr/lib/clang/13.0.0/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/x86gprintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/xopintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/13.0.0/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/13.0.0/include OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-aarch64.so OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-arm.so OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-armhf.so OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-preinit-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-preinit-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-preinit-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan_cxx-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan_cxx-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.cfi-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.cfi-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.cfi-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.cfi-i386.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.cfi-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.cfi_diag-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.cfi_diag-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.cfi_diag-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.cfi_diag-i386.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.cfi_diag-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.dd-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.dd-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.fuzzer-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.fuzzer-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.msan-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.msan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.profile-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.profile-powerpc.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.profile-powerpc64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.profile-powerpc64le.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.safestack-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.stats-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.stats-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.stats-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.stats_client-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.stats_client-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.stats_client-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.tsan-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_minimal-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_standalone-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-basic-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-basic-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-basic-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-basic-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-fdr-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-fdr-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-fdr-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-fdr-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-profiling-aarch64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-profiling-arm.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-profiling-armhf.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-profiling-x86_64.a OLD_FILES+=usr/lib/clang/13.0.0/lib/freebsd/libclang_rt.xray-x86_64.a OLD_DIRS+=usr/lib/clang/13.0.0/lib/freebsd OLD_DIRS+=usr/lib/clang/13.0.0/lib OLD_DIRS+=usr/lib/clang/13.0.0 # 20220514: new libc++ import which bumps version from 13.0.0 to 14.0.3 OLD_FILES+=usr/include/c++/v1/__function_like.h OLD_FILES+=usr/include/c++/v1/__memory/pointer_safety.h OLD_FILES+=usr/include/c++/v1/__utility/__decay_copy.h # 20220418: uudecode merged into uuencode and renamed to bintrans OLD_FILES+=usr/lib/debug/usr/bin/uuencode.debug OLD_FILES+=usr/lib/debug/usr/bin/uudecode.debug OLD_FILES+=usr/tests/usr.bin/uuencode/Kyuafile OLD_FILES+=usr/tests/usr.bin/uuencode/legacy_test OLD_FILES+=usr/tests/usr.bin/uuencode/regress.base64.in OLD_FILES+=usr/tests/usr.bin/uuencode/regress.traditional.out OLD_FILES+=usr/tests/usr.bin/uuencode/regress.traditional.in OLD_FILES+=usr/tests/usr.bin/uuencode/regress.out OLD_FILES+=usr/tests/usr.bin/uuencode/regress.sh OLD_FILES+=usr/tests/usr.bin/uuencode/regress.in OLD_FILES+=usr/tests/usr.bin/uuencode/regress.153276.in OLD_FILES+=usr/tests/usr.bin/uuencode/regress.base64.out OLD_FILES+=usr/tests/usr.bin/uuencode/regress.153276.out OLD_FILES+=usr/tests/usr.bin/uudecode/regress.base64.in OLD_FILES+=usr/tests/usr.bin/uudecode/Kyuafile OLD_FILES+=usr/tests/usr.bin/uudecode/regress.out OLD_FILES+=usr/tests/usr.bin/uudecode/regress.sh OLD_FILES+=usr/tests/usr.bin/uudecode/regress.153276.out OLD_FILES+=usr/tests/usr.bin/uudecode/regress.traditional.in OLD_FILES+=usr/tests/usr.bin/uudecode/legacy_test OLD_FILES+=usr/tests/usr.bin/uudecode/regress.153276.in OLD_DIRS+=usr/tests/usr.bin/uuencode OLD_DIRS+=usr/tests/usr.bin/uudecode # 20220318: snd_ds1 and snd_maestro drivers removed OLD_FILES+=usr/share/man/man4/snd_ds1.4.gz OLD_FILES+=usr/share/man/man4/snd_maestro.4.gz # 20220307: remove 330.news OLD_FILES+=etc/periodic/daily/330.news # 20220210: unwind.h moved to /usr/include OLD_FILES+=usr/include/c++/v1/unwind-arm.h OLD_FILES+=usr/include/c++/v1/unwind-itanium.h OLD_FILES+=usr/include/c++/v1/unwind.h # 20220128: mips pmc events removed OLD_FILES+=usr/share/man/man3/pmc.mips24k.3.gz OLD_FILES+=usr/share/man/man3/pmc.octeon.3.gz # 20220127: terasic_mtl.4 removed OLD_FILES+=usr/share/man/man4/terasic_mtl.4.gz # 20211229: libc++ moved to /lib MOVED_LIBS+=usr/lib/libc++.so.1 # 20211221: efi_set_variables_supported.3 should be efi_variables_supported.3 OLD_FILES+=usr/share/man/man3/efi_set_variables_supported.3.gz # 20211218: meteor.4 removed, see also 20200301 entry below OLD_FILES+=usr/share/man/man4/meteor.4.gz # 20211125: Old SCSI drivers removed OLD_FILES+=usr/share/man/man4/amr.4.gz OLD_FILES+=usr/share/man/man4/esp.4.gz OLD_FILES+=usr/share/man/man4/iir.4.gz OLD_FILES+=usr/share/man/man4/mly.4.gz OLD_FILES+=usr/share/man/man4/twa.4.gz # 20211120: kernel_vmount function removed OLD_FILES+=usr/share/man/man9/kernel_vmount.9.gz # 20211115: vm_page busy functions removed OLD_FILES+=share/man/man9/vm_page_sbusy.9.gz OLD_FILES+=share/man/man9/vm_page_xbusy.9.gz OLD_FILES+=share/man/man9/vm_page_sleep_if_busy.9.gz # 20211113: new clang import which bumps version from 12.0.1 to 13.0.0 OLD_FILES+=usr/lib/clang/12.0.1/include/cuda_wrappers/algorithm OLD_FILES+=usr/lib/clang/12.0.1/include/cuda_wrappers/complex OLD_FILES+=usr/lib/clang/12.0.1/include/cuda_wrappers/new OLD_DIRS+=usr/lib/clang/12.0.1/include/cuda_wrappers OLD_FILES+=usr/lib/clang/12.0.1/include/fuzzer/FuzzedDataProvider.h OLD_DIRS+=usr/lib/clang/12.0.1/include/fuzzer OLD_FILES+=usr/lib/clang/12.0.1/include/openmp_wrappers/__clang_openmp_device_functions.h OLD_FILES+=usr/lib/clang/12.0.1/include/openmp_wrappers/cmath OLD_FILES+=usr/lib/clang/12.0.1/include/openmp_wrappers/complex OLD_FILES+=usr/lib/clang/12.0.1/include/openmp_wrappers/complex.h OLD_FILES+=usr/lib/clang/12.0.1/include/openmp_wrappers/complex_cmath.h OLD_FILES+=usr/lib/clang/12.0.1/include/openmp_wrappers/math.h OLD_FILES+=usr/lib/clang/12.0.1/include/openmp_wrappers/new OLD_DIRS+=usr/lib/clang/12.0.1/include/openmp_wrappers OLD_FILES+=usr/lib/clang/12.0.1/include/ppc_wrappers/emmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/ppc_wrappers/mm_malloc.h OLD_FILES+=usr/lib/clang/12.0.1/include/ppc_wrappers/mmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/ppc_wrappers/pmmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/ppc_wrappers/smmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/ppc_wrappers/tmmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/ppc_wrappers/xmmintrin.h OLD_DIRS+=usr/lib/clang/12.0.1/include/ppc_wrappers OLD_FILES+=usr/lib/clang/12.0.1/include/profile/InstrProfData.inc OLD_DIRS+=usr/lib/clang/12.0.1/include/profile OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/tsan_interface_atomic.h OLD_FILES+=usr/lib/clang/12.0.1/include/sanitizer/ubsan_interface.h OLD_DIRS+=usr/lib/clang/12.0.1/include/sanitizer OLD_FILES+=usr/lib/clang/12.0.1/include/xray/xray_interface.h OLD_FILES+=usr/lib/clang/12.0.1/include/xray/xray_log_interface.h OLD_FILES+=usr/lib/clang/12.0.1/include/xray/xray_records.h OLD_DIRS+=usr/lib/clang/12.0.1/include/xray OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_cuda_math.h OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_hip_cmath.h OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_hip_libdevice_declares.h OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_hip_math.h OLD_FILES+=usr/lib/clang/12.0.1/include/__clang_hip_runtime_wrapper.h OLD_FILES+=usr/lib/clang/12.0.1/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/12.0.1/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/12.0.1/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/12.0.1/include/adxintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/altivec.h OLD_FILES+=usr/lib/clang/12.0.1/include/ammintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/amxintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/arm64intr.h OLD_FILES+=usr/lib/clang/12.0.1/include/arm_acle.h OLD_FILES+=usr/lib/clang/12.0.1/include/arm_bf16.h OLD_FILES+=usr/lib/clang/12.0.1/include/arm_cde.h OLD_FILES+=usr/lib/clang/12.0.1/include/arm_cmse.h OLD_FILES+=usr/lib/clang/12.0.1/include/arm_fp16.h OLD_FILES+=usr/lib/clang/12.0.1/include/arm_mve.h OLD_FILES+=usr/lib/clang/12.0.1/include/arm_neon.h OLD_FILES+=usr/lib/clang/12.0.1/include/arm_sve.h OLD_FILES+=usr/lib/clang/12.0.1/include/armintr.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx2intrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512bf16intrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vlbf16intrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vlvp2intersectintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vp2intersectintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avxintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/avxvnniintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/bmiintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/cet.h OLD_FILES+=usr/lib/clang/12.0.1/include/cetintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/clwbintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/clzerointrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/cpuid.h OLD_FILES+=usr/lib/clang/12.0.1/include/emmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/enqcmdintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/f16cintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/float.h OLD_FILES+=usr/lib/clang/12.0.1/include/fma4intrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/fmaintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/gfniintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/hresetintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/htmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/ia32intrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/immintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/intrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/inttypes.h OLD_FILES+=usr/lib/clang/12.0.1/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/iso646.h OLD_FILES+=usr/lib/clang/12.0.1/include/keylockerintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/limits.h OLD_FILES+=usr/lib/clang/12.0.1/include/lwpintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/mm3dnow.h OLD_FILES+=usr/lib/clang/12.0.1/include/mm_malloc.h OLD_FILES+=usr/lib/clang/12.0.1/include/mmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/module.modulemap OLD_FILES+=usr/lib/clang/12.0.1/include/movdirintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/msa.h OLD_FILES+=usr/lib/clang/12.0.1/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/nmmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/omp-tools.h OLD_FILES+=usr/lib/clang/12.0.1/include/omp.h OLD_FILES+=usr/lib/clang/12.0.1/include/ompt.h OLD_FILES+=usr/lib/clang/12.0.1/include/opencl-c-base.h OLD_FILES+=usr/lib/clang/12.0.1/include/opencl-c.h OLD_FILES+=usr/lib/clang/12.0.1/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/pkuintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/pmmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/popcntintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/rtmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/s390intrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/serializeintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/sgxintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/shaintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/smmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/stdalign.h OLD_FILES+=usr/lib/clang/12.0.1/include/stdarg.h OLD_FILES+=usr/lib/clang/12.0.1/include/stdatomic.h OLD_FILES+=usr/lib/clang/12.0.1/include/stdbool.h OLD_FILES+=usr/lib/clang/12.0.1/include/stddef.h OLD_FILES+=usr/lib/clang/12.0.1/include/stdint.h OLD_FILES+=usr/lib/clang/12.0.1/include/stdnoreturn.h OLD_FILES+=usr/lib/clang/12.0.1/include/tbmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/tgmath.h OLD_FILES+=usr/lib/clang/12.0.1/include/tmmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/tsxldtrkintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/uintrintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/unwind.h OLD_FILES+=usr/lib/clang/12.0.1/include/vadefs.h OLD_FILES+=usr/lib/clang/12.0.1/include/vaesintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/varargs.h OLD_FILES+=usr/lib/clang/12.0.1/include/vecintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/wasm_simd128.h OLD_FILES+=usr/lib/clang/12.0.1/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/wmmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/x86gprintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/x86intrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/xmmintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/xopintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/12.0.1/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/12.0.1/include OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-aarch64.so OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-arm.so OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-armhf.so OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-preinit-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-preinit-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-preinit-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan_cxx-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan_cxx-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.cfi-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.cfi-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.cfi-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.cfi-i386.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.cfi-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.cfi_diag-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.cfi_diag-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.cfi_diag-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.cfi_diag-i386.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.cfi_diag-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.dd-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.dd-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.fuzzer-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.fuzzer-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.msan-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.msan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.profile-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.profile-powerpc.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.profile-powerpc64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.profile-powerpc64le.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.safestack-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.stats-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.stats-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.stats-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.stats_client-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.stats_client-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.stats_client-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.tsan-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_minimal-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_standalone-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-basic-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-basic-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-basic-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-basic-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-fdr-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-fdr-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-fdr-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-fdr-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-profiling-aarch64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-profiling-arm.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-profiling-armhf.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-profiling-x86_64.a OLD_FILES+=usr/lib/clang/12.0.1/lib/freebsd/libclang_rt.xray-x86_64.a OLD_DIRS+=usr/lib/clang/12.0.1/lib/freebsd OLD_DIRS+=usr/lib/clang/12.0.1/lib OLD_DIRS+=usr/lib/clang/12.0.1 # 20211113: new libc++ import which bumps version from 12.0.1 to 13.0.0 OLD_FILES+=usr/include/c++/v1/__functional_03 OLD_FILES+=usr/include/c++/v1/__functional_base_03 OLD_FILES+=usr/include/c++/v1/__memory/base.h OLD_FILES+=usr/include/c++/v1/__memory/utilities.h OLD_FILES+=usr/include/c++/v1/__sso_allocator OLD_FILES+=usr/include/c++/v1/tr1/__availability OLD_FILES+=usr/include/c++/v1/tr1/__bit_reference OLD_FILES+=usr/include/c++/v1/tr1/__bits OLD_FILES+=usr/include/c++/v1/tr1/__bsd_locale_defaults.h OLD_FILES+=usr/include/c++/v1/tr1/__bsd_locale_fallbacks.h OLD_FILES+=usr/include/c++/v1/tr1/__config OLD_FILES+=usr/include/c++/v1/tr1/__debug OLD_FILES+=usr/include/c++/v1/tr1/__errc OLD_FILES+=usr/include/c++/v1/tr1/__functional_03 OLD_FILES+=usr/include/c++/v1/tr1/__functional_base OLD_FILES+=usr/include/c++/v1/tr1/__functional_base_03 OLD_FILES+=usr/include/c++/v1/tr1/__hash_table OLD_FILES+=usr/include/c++/v1/tr1/__libcpp_version OLD_FILES+=usr/include/c++/v1/tr1/__locale OLD_FILES+=usr/include/c++/v1/tr1/__mutex_base OLD_FILES+=usr/include/c++/v1/tr1/__node_handle OLD_FILES+=usr/include/c++/v1/tr1/__nullptr OLD_FILES+=usr/include/c++/v1/tr1/__split_buffer OLD_FILES+=usr/include/c++/v1/tr1/__sso_allocator OLD_FILES+=usr/include/c++/v1/tr1/__std_stream OLD_FILES+=usr/include/c++/v1/tr1/__string OLD_FILES+=usr/include/c++/v1/tr1/__threading_support OLD_FILES+=usr/include/c++/v1/tr1/__tree OLD_FILES+=usr/include/c++/v1/tr1/__tuple OLD_FILES+=usr/include/c++/v1/tr1/__undef_macros OLD_FILES+=usr/include/c++/v1/tr1/algorithm OLD_FILES+=usr/include/c++/v1/tr1/any OLD_FILES+=usr/include/c++/v1/tr1/array OLD_FILES+=usr/include/c++/v1/tr1/atomic OLD_FILES+=usr/include/c++/v1/tr1/barrier OLD_FILES+=usr/include/c++/v1/tr1/bit OLD_FILES+=usr/include/c++/v1/tr1/bitset OLD_FILES+=usr/include/c++/v1/tr1/cassert OLD_FILES+=usr/include/c++/v1/tr1/ccomplex OLD_FILES+=usr/include/c++/v1/tr1/cctype OLD_FILES+=usr/include/c++/v1/tr1/cerrno OLD_FILES+=usr/include/c++/v1/tr1/cfenv OLD_FILES+=usr/include/c++/v1/tr1/cfloat OLD_FILES+=usr/include/c++/v1/tr1/charconv OLD_FILES+=usr/include/c++/v1/tr1/chrono OLD_FILES+=usr/include/c++/v1/tr1/cinttypes OLD_FILES+=usr/include/c++/v1/tr1/ciso646 OLD_FILES+=usr/include/c++/v1/tr1/climits OLD_FILES+=usr/include/c++/v1/tr1/clocale OLD_FILES+=usr/include/c++/v1/tr1/cmath OLD_FILES+=usr/include/c++/v1/tr1/codecvt OLD_FILES+=usr/include/c++/v1/tr1/compare OLD_FILES+=usr/include/c++/v1/tr1/complex OLD_FILES+=usr/include/c++/v1/tr1/complex.h OLD_FILES+=usr/include/c++/v1/tr1/concepts OLD_FILES+=usr/include/c++/v1/tr1/condition_variable OLD_FILES+=usr/include/c++/v1/tr1/csetjmp OLD_FILES+=usr/include/c++/v1/tr1/csignal OLD_FILES+=usr/include/c++/v1/tr1/cstdarg OLD_FILES+=usr/include/c++/v1/tr1/cstdbool OLD_FILES+=usr/include/c++/v1/tr1/cstddef OLD_FILES+=usr/include/c++/v1/tr1/cstdint OLD_FILES+=usr/include/c++/v1/tr1/cstdio OLD_FILES+=usr/include/c++/v1/tr1/cstdlib OLD_FILES+=usr/include/c++/v1/tr1/cstring OLD_FILES+=usr/include/c++/v1/tr1/ctgmath OLD_FILES+=usr/include/c++/v1/tr1/ctime OLD_FILES+=usr/include/c++/v1/tr1/ctype.h OLD_FILES+=usr/include/c++/v1/tr1/cwchar OLD_FILES+=usr/include/c++/v1/tr1/cwctype OLD_FILES+=usr/include/c++/v1/tr1/deque OLD_FILES+=usr/include/c++/v1/tr1/errno.h OLD_FILES+=usr/include/c++/v1/tr1/exception OLD_FILES+=usr/include/c++/v1/tr1/execution OLD_FILES+=usr/include/c++/v1/tr1/fenv.h OLD_FILES+=usr/include/c++/v1/tr1/filesystem OLD_FILES+=usr/include/c++/v1/tr1/float.h OLD_FILES+=usr/include/c++/v1/tr1/forward_list OLD_FILES+=usr/include/c++/v1/tr1/fstream OLD_FILES+=usr/include/c++/v1/tr1/functional OLD_FILES+=usr/include/c++/v1/tr1/future OLD_FILES+=usr/include/c++/v1/tr1/initializer_list OLD_FILES+=usr/include/c++/v1/tr1/inttypes.h OLD_FILES+=usr/include/c++/v1/tr1/iomanip OLD_FILES+=usr/include/c++/v1/tr1/ios OLD_FILES+=usr/include/c++/v1/tr1/iosfwd OLD_FILES+=usr/include/c++/v1/tr1/iostream OLD_FILES+=usr/include/c++/v1/tr1/istream OLD_FILES+=usr/include/c++/v1/tr1/iterator OLD_FILES+=usr/include/c++/v1/tr1/latch OLD_FILES+=usr/include/c++/v1/tr1/limits OLD_FILES+=usr/include/c++/v1/tr1/limits.h OLD_FILES+=usr/include/c++/v1/tr1/list OLD_FILES+=usr/include/c++/v1/tr1/locale OLD_FILES+=usr/include/c++/v1/tr1/locale.h OLD_FILES+=usr/include/c++/v1/tr1/map OLD_FILES+=usr/include/c++/v1/tr1/math.h OLD_FILES+=usr/include/c++/v1/tr1/memory OLD_FILES+=usr/include/c++/v1/tr1/mutex OLD_FILES+=usr/include/c++/v1/tr1/new OLD_FILES+=usr/include/c++/v1/tr1/numbers OLD_FILES+=usr/include/c++/v1/tr1/numeric OLD_FILES+=usr/include/c++/v1/tr1/optional OLD_FILES+=usr/include/c++/v1/tr1/ostream OLD_FILES+=usr/include/c++/v1/tr1/queue OLD_FILES+=usr/include/c++/v1/tr1/random OLD_FILES+=usr/include/c++/v1/tr1/ratio OLD_FILES+=usr/include/c++/v1/tr1/regex OLD_FILES+=usr/include/c++/v1/tr1/scoped_allocator OLD_FILES+=usr/include/c++/v1/tr1/semaphore OLD_FILES+=usr/include/c++/v1/tr1/set OLD_FILES+=usr/include/c++/v1/tr1/setjmp.h OLD_FILES+=usr/include/c++/v1/tr1/shared_mutex OLD_FILES+=usr/include/c++/v1/tr1/span OLD_FILES+=usr/include/c++/v1/tr1/sstream OLD_FILES+=usr/include/c++/v1/tr1/stack OLD_FILES+=usr/include/c++/v1/tr1/stdbool.h OLD_FILES+=usr/include/c++/v1/tr1/stddef.h OLD_FILES+=usr/include/c++/v1/tr1/stdexcept OLD_FILES+=usr/include/c++/v1/tr1/stdint.h OLD_FILES+=usr/include/c++/v1/tr1/stdio.h OLD_FILES+=usr/include/c++/v1/tr1/stdlib.h OLD_FILES+=usr/include/c++/v1/tr1/streambuf OLD_FILES+=usr/include/c++/v1/tr1/string OLD_FILES+=usr/include/c++/v1/tr1/string.h OLD_FILES+=usr/include/c++/v1/tr1/string_view OLD_FILES+=usr/include/c++/v1/tr1/strstream OLD_FILES+=usr/include/c++/v1/tr1/system_error OLD_FILES+=usr/include/c++/v1/tr1/tgmath.h OLD_FILES+=usr/include/c++/v1/tr1/thread OLD_FILES+=usr/include/c++/v1/tr1/tuple OLD_FILES+=usr/include/c++/v1/tr1/type_traits OLD_FILES+=usr/include/c++/v1/tr1/typeindex OLD_FILES+=usr/include/c++/v1/tr1/typeinfo OLD_FILES+=usr/include/c++/v1/tr1/unordered_map OLD_FILES+=usr/include/c++/v1/tr1/unordered_set OLD_FILES+=usr/include/c++/v1/tr1/utility OLD_FILES+=usr/include/c++/v1/tr1/valarray OLD_FILES+=usr/include/c++/v1/tr1/variant OLD_FILES+=usr/include/c++/v1/tr1/vector OLD_FILES+=usr/include/c++/v1/tr1/version OLD_FILES+=usr/include/c++/v1/tr1/wchar.h OLD_FILES+=usr/include/c++/v1/tr1/wctype.h OLD_DIRS+=usr/include/c++/v1/tr1 # 20211027: libdialog shlib bumped to version 10 for dialog 1.3 OLD_LIBS+=usr/lib/libdialog.so.9 OLD_LIBS+=usr/lib/libdpv.so.2 # 20211026: retire obsolete iscsi initiator OLD_FILES+=sbin/iscontrol OLD_FILES+=usr/share/man/man4/iscsi_initiator.4.gz OLD_FILES+=usr/share/man/man8/iscontrol.8.gz # 20211022 OLD_FILES+=etc/rc.d/sppp OLD_FILES+=rescue/spppcontrol OLD_FILES+=sbin/spppcontrol .if ${TARGET_ARCH} == "i386" OLD_FILES+=usr/include/machine/cserial.h .endif OLD_FILES+=usr/include/net/if_sppp.h OLD_FILES+=usr/include/netgraph/ng_sppp.h OLD_FILES+=usr/share/man/man4/ng_sppp.4.gz OLD_FILES+=usr/share/man/man4/sppp.4.gz OLD_FILES+=usr/share/man/man8/spppcontrol.8.gz # 20211004: Removed sparc64 tests for lastcomm/sa OLD_FILES+=usr/tests/usr.bin/lastcomm/v1-sparc64-acct.in OLD_FILES+=usr/tests/usr.bin/lastcomm/v1-sparc64.out OLD_FILES+=usr/tests/usr.bin/lastcomm/v2-sparc64-acct.in OLD_FILES+=usr/tests/usr.bin/lastcomm/v2-sparc64.out OLD_FILES+=usr/tests/usr.sbin/sa/v1-sparc64-sav.in OLD_FILES+=usr/tests/usr.sbin/sa/v1-sparc64-sav.out OLD_FILES+=usr/tests/usr.sbin/sa/v1-sparc64-u.out OLD_FILES+=usr/tests/usr.sbin/sa/v1-sparc64-usr.in OLD_FILES+=usr/tests/usr.sbin/sa/v1-sparc64-usr.out OLD_FILES+=usr/tests/usr.sbin/sa/v2-sparc64-sav.in OLD_FILES+=usr/tests/usr.sbin/sa/v2-sparc64-u.out OLD_FILES+=usr/tests/usr.sbin/sa/v2-sparc64-usr.in # 20210929: OLD_FILES+=usr/sbin/hcseriald OLD_FILES+=usr/share/man/man8/hcseriald.8.gz # 20210929: Remove ng_h4 OLD_FILES+=usr/include/netgraph/bluetooth/include/ng_h4.h OLD_FILES+=usr/share/man/man4/ng_h4.4.gz # 20210923: rename boot(9) to kern_reboot(9) OLD_FILES+=usr/share/man/man9/boot.9.gz # 20210921: remove cloudabi OLD_FILES+=usr/share/man/man4/cloudabi.4.gz OLD_FILES+=usr/share/man/man4/cloudabi32.4.gz OLD_FILES+=usr/share/man/man4/cloudabi64.4.gz # 20210906: stop installing {llvm,clang,lldb}-tblgen OLD_FILES+=usr/bin/llvm-tblgen OLD_FILES+=usr/bin/clang-tblgen OLD_FILES+=usr/bin/lldb-tblgen OLD_FILES+=usr/share/man/man1/llvm-tblgen.1.gz # 20210810: remove Pentium-related man pages and references OLD_FILES+=usr/share/man/man3/pmc.p4.3.gz OLD_FILES+=usr/share/man/man3/pmc.p5.3.gz OLD_FILES+=usr/share/man/man3/pmc.p6.3.gz # 20210805: C.UTF-8 installed to the wrong location OLD_FILES+=usr/share/C.UTF-8.LC_CTYPE # 20210619: new clang import which bumps version from 12.0.0 to 12.0.1 OLD_FILES+=usr/lib/clang/12.0.0/include/cuda_wrappers/algorithm OLD_FILES+=usr/lib/clang/12.0.0/include/cuda_wrappers/complex OLD_FILES+=usr/lib/clang/12.0.0/include/cuda_wrappers/new OLD_DIRS+=usr/lib/clang/12.0.0/include/cuda_wrappers OLD_FILES+=usr/lib/clang/12.0.0/include/fuzzer/FuzzedDataProvider.h OLD_DIRS+=usr/lib/clang/12.0.0/include/fuzzer OLD_FILES+=usr/lib/clang/12.0.0/include/openmp_wrappers/__clang_openmp_device_functions.h OLD_FILES+=usr/lib/clang/12.0.0/include/openmp_wrappers/cmath OLD_FILES+=usr/lib/clang/12.0.0/include/openmp_wrappers/complex OLD_FILES+=usr/lib/clang/12.0.0/include/openmp_wrappers/complex.h OLD_FILES+=usr/lib/clang/12.0.0/include/openmp_wrappers/complex_cmath.h OLD_FILES+=usr/lib/clang/12.0.0/include/openmp_wrappers/math.h OLD_FILES+=usr/lib/clang/12.0.0/include/openmp_wrappers/new OLD_DIRS+=usr/lib/clang/12.0.0/include/openmp_wrappers OLD_FILES+=usr/lib/clang/12.0.0/include/ppc_wrappers/emmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/ppc_wrappers/mm_malloc.h OLD_FILES+=usr/lib/clang/12.0.0/include/ppc_wrappers/mmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/ppc_wrappers/pmmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/ppc_wrappers/smmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/ppc_wrappers/tmmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/ppc_wrappers/xmmintrin.h OLD_DIRS+=usr/lib/clang/12.0.0/include/ppc_wrappers OLD_FILES+=usr/lib/clang/12.0.0/include/profile/InstrProfData.inc OLD_DIRS+=usr/lib/clang/12.0.0/include/profile OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/tsan_interface_atomic.h OLD_FILES+=usr/lib/clang/12.0.0/include/sanitizer/ubsan_interface.h OLD_DIRS+=usr/lib/clang/12.0.0/include/sanitizer OLD_FILES+=usr/lib/clang/12.0.0/include/xray/xray_interface.h OLD_FILES+=usr/lib/clang/12.0.0/include/xray/xray_log_interface.h OLD_FILES+=usr/lib/clang/12.0.0/include/xray/xray_records.h OLD_DIRS+=usr/lib/clang/12.0.0/include/xray OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_cuda_math.h OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_hip_cmath.h OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_hip_libdevice_declares.h OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_hip_math.h OLD_FILES+=usr/lib/clang/12.0.0/include/__clang_hip_runtime_wrapper.h OLD_FILES+=usr/lib/clang/12.0.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/12.0.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/12.0.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/12.0.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/altivec.h OLD_FILES+=usr/lib/clang/12.0.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/amxintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/arm64intr.h OLD_FILES+=usr/lib/clang/12.0.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/12.0.0/include/arm_bf16.h OLD_FILES+=usr/lib/clang/12.0.0/include/arm_cde.h OLD_FILES+=usr/lib/clang/12.0.0/include/arm_cmse.h OLD_FILES+=usr/lib/clang/12.0.0/include/arm_fp16.h OLD_FILES+=usr/lib/clang/12.0.0/include/arm_mve.h OLD_FILES+=usr/lib/clang/12.0.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/12.0.0/include/arm_sve.h OLD_FILES+=usr/lib/clang/12.0.0/include/armintr.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512bf16intrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vlbf16intrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vlvp2intersectintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vp2intersectintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/avxvnniintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/cet.h OLD_FILES+=usr/lib/clang/12.0.0/include/cetintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/clwbintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/clzerointrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/cpuid.h OLD_FILES+=usr/lib/clang/12.0.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/enqcmdintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/float.h OLD_FILES+=usr/lib/clang/12.0.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/gfniintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/hresetintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/htmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/immintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/intrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/inttypes.h OLD_FILES+=usr/lib/clang/12.0.0/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/iso646.h OLD_FILES+=usr/lib/clang/12.0.0/include/keylockerintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/limits.h OLD_FILES+=usr/lib/clang/12.0.0/include/lwpintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/12.0.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/12.0.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/module.modulemap OLD_FILES+=usr/lib/clang/12.0.0/include/movdirintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/msa.h OLD_FILES+=usr/lib/clang/12.0.0/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/omp-tools.h OLD_FILES+=usr/lib/clang/12.0.0/include/omp.h OLD_FILES+=usr/lib/clang/12.0.0/include/ompt.h OLD_FILES+=usr/lib/clang/12.0.0/include/opencl-c-base.h OLD_FILES+=usr/lib/clang/12.0.0/include/opencl-c.h OLD_FILES+=usr/lib/clang/12.0.0/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/pkuintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/s390intrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/serializeintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/sgxintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/stdalign.h OLD_FILES+=usr/lib/clang/12.0.0/include/stdarg.h OLD_FILES+=usr/lib/clang/12.0.0/include/stdatomic.h OLD_FILES+=usr/lib/clang/12.0.0/include/stdbool.h OLD_FILES+=usr/lib/clang/12.0.0/include/stddef.h OLD_FILES+=usr/lib/clang/12.0.0/include/stdint.h OLD_FILES+=usr/lib/clang/12.0.0/include/stdnoreturn.h OLD_FILES+=usr/lib/clang/12.0.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/tgmath.h OLD_FILES+=usr/lib/clang/12.0.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/tsxldtrkintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/uintrintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/unwind.h OLD_FILES+=usr/lib/clang/12.0.0/include/vadefs.h OLD_FILES+=usr/lib/clang/12.0.0/include/vaesintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/varargs.h OLD_FILES+=usr/lib/clang/12.0.0/include/vecintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/wasm_simd128.h OLD_FILES+=usr/lib/clang/12.0.0/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/x86gprintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/xopintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/12.0.0/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/12.0.0/include OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-aarch64.so OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-arm.so OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-armhf.so OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-preinit-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-preinit-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-preinit-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan_cxx-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan_cxx-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.cfi-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.cfi-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.cfi-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.cfi-i386.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.cfi-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.cfi_diag-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.cfi_diag-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.cfi_diag-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.cfi_diag-i386.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.cfi_diag-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.dd-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.dd-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.fuzzer-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.fuzzer-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.msan-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.msan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.profile-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.profile-powerpc.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.profile-powerpc64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.profile-powerpc64le.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.safestack-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.stats-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.stats-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.stats-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.stats_client-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.stats_client-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.stats_client-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.tsan-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_minimal-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_standalone-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-basic-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-basic-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-basic-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-basic-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-fdr-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-fdr-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-fdr-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-fdr-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-profiling-aarch64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-profiling-arm.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-profiling-armhf.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-profiling-x86_64.a OLD_FILES+=usr/lib/clang/12.0.0/lib/freebsd/libclang_rt.xray-x86_64.a OLD_DIRS+=usr/lib/clang/12.0.0/lib/freebsd OLD_DIRS+=usr/lib/clang/12.0.0/lib OLD_DIRS+=usr/lib/clang/12.0.0 # 20210616: Remove crypto_cursor_seg{base,len} OLD_FILES+=usr/share/man/man9/crypto_cursor_segbase.9.gz OLD_FILES+=usr/share/man/man9/crypto_cursor_seglen.9.gz # 20210618: rename of usr/share/certs/blacklisted OLD_FILES+=usr/share/certs/blacklisted/AddTrust_External_Root.pem OLD_FILES+=usr/share/certs/blacklisted/AddTrust_Low-Value_Services_Root.pem OLD_FILES+=usr/share/certs/blacklisted/Camerfirma_Chambers_of_Commerce_Root.pem OLD_FILES+=usr/share/certs/blacklisted/Camerfirma_Global_Chambersign_Root.pem OLD_FILES+=usr/share/certs/blacklisted/Certum_Root_CA.pem OLD_FILES+=usr/share/certs/blacklisted/Chambers_of_Commerce_Root_-_2008.pem OLD_FILES+=usr/share/certs/blacklisted/D-TRUST_Root_CA_3_2013.pem OLD_FILES+=usr/share/certs/blacklisted/EC-ACC.pem OLD_FILES+=usr/share/certs/blacklisted/EE_Certification_Centre_Root_CA.pem OLD_FILES+=usr/share/certs/blacklisted/GeoTrust_Global_CA.pem OLD_FILES+=usr/share/certs/blacklisted/GeoTrust_Primary_Certification_Authority_-_G2.pem OLD_FILES+=usr/share/certs/blacklisted/GeoTrust_Primary_Certification_Authority_-_G3.pem OLD_FILES+=usr/share/certs/blacklisted/GeoTrust_Primary_Certification_Authority.pem OLD_FILES+=usr/share/certs/blacklisted/GeoTrust_Universal_CA_2.pem OLD_FILES+=usr/share/certs/blacklisted/GeoTrust_Universal_CA.pem OLD_FILES+=usr/share/certs/blacklisted/Global_Chambersign_Root_-_2008.pem OLD_FILES+=usr/share/certs/blacklisted/LuxTrust_Global_Root_2.pem OLD_FILES+=usr/share/certs/blacklisted/OISTE_WISeKey_Global_Root_GA_CA.pem OLD_FILES+=usr/share/certs/blacklisted/Staat_der_Nederlanden_Root_CA_-_G2.pem OLD_FILES+=usr/share/certs/blacklisted/Staat_der_Nederlanden_Root_CA_-_G3.pem OLD_FILES+=usr/share/certs/blacklisted/SwissSign_Platinum_CA_-_G2.pem OLD_FILES+=usr/share/certs/blacklisted/Symantec_Class_1_Public_Primary_Certification_Authority_-_G4.pem OLD_FILES+=usr/share/certs/blacklisted/Symantec_Class_1_Public_Primary_Certification_Authority_-_G6.pem OLD_FILES+=usr/share/certs/blacklisted/Symantec_Class_2_Public_Primary_Certification_Authority_-_G4.pem OLD_FILES+=usr/share/certs/blacklisted/Symantec_Class_2_Public_Primary_Certification_Authority_-_G6.pem OLD_FILES+=usr/share/certs/blacklisted/Taiwan_GRCA.pem OLD_FILES+=usr/share/certs/blacklisted/thawte_Primary_Root_CA_-_G2.pem OLD_FILES+=usr/share/certs/blacklisted/thawte_Primary_Root_CA_-_G3.pem OLD_FILES+=usr/share/certs/blacklisted/thawte_Primary_Root_CA.pem OLD_FILES+=usr/share/certs/blacklisted/Trustis_FPS_Root_CA.pem OLD_FILES+=usr/share/certs/blacklisted/Verisign_Class_1_Public_Primary_Certification_Authority_-_G3.pem OLD_FILES+=usr/share/certs/blacklisted/Verisign_Class_2_Public_Primary_Certification_Authority_-_G3.pem OLD_FILES+=usr/share/certs/blacklisted/Verisign_Class_3_Public_Primary_Certification_Authority_-_G3.pem OLD_FILES+=usr/share/certs/blacklisted/VeriSign_Class_3_Public_Primary_Certification_Authority_-_G4.pem OLD_FILES+=usr/share/certs/blacklisted/VeriSign_Class_3_Public_Primary_Certification_Authority_-_G5.pem OLD_FILES+=usr/share/certs/blacklisted/VeriSign_Universal_Root_Certification_Authority.pem OLD_DIRS+=usr/share/certs/blacklisted # 20210613: new clang import which bumps version from 11.0.1 to 12.0.0 OLD_FILES+=usr/lib/clang/11.0.1/include/cuda_wrappers/algorithm OLD_FILES+=usr/lib/clang/11.0.1/include/cuda_wrappers/complex OLD_FILES+=usr/lib/clang/11.0.1/include/cuda_wrappers/new OLD_DIRS+=usr/lib/clang/11.0.1/include/cuda_wrappers OLD_FILES+=usr/lib/clang/11.0.1/include/fuzzer/FuzzedDataProvider.h OLD_DIRS+=usr/lib/clang/11.0.1/include/fuzzer OLD_FILES+=usr/lib/clang/11.0.1/include/openmp_wrappers/__clang_openmp_device_functions.h OLD_FILES+=usr/lib/clang/11.0.1/include/openmp_wrappers/cmath OLD_FILES+=usr/lib/clang/11.0.1/include/openmp_wrappers/complex OLD_FILES+=usr/lib/clang/11.0.1/include/openmp_wrappers/complex.h OLD_FILES+=usr/lib/clang/11.0.1/include/openmp_wrappers/math.h OLD_FILES+=usr/lib/clang/11.0.1/include/openmp_wrappers/new OLD_DIRS+=usr/lib/clang/11.0.1/include/openmp_wrappers OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/emmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/mm_malloc.h OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/mmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/pmmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/smmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/tmmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/xmmintrin.h OLD_DIRS+=usr/lib/clang/11.0.1/include/ppc_wrappers OLD_FILES+=usr/lib/clang/11.0.1/include/profile/InstrProfData.inc OLD_DIRS+=usr/lib/clang/11.0.1/include/profile OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/tsan_interface_atomic.h OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/ubsan_interface.h OLD_DIRS+=usr/lib/clang/11.0.1/include/sanitizer OLD_FILES+=usr/lib/clang/11.0.1/include/xray/xray_interface.h OLD_FILES+=usr/lib/clang/11.0.1/include/xray/xray_log_interface.h OLD_FILES+=usr/lib/clang/11.0.1/include/xray/xray_records.h OLD_DIRS+=usr/lib/clang/11.0.1/include/xray OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_math.h OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_hip_libdevice_declares.h OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_hip_math.h OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_hip_runtime_wrapper.h OLD_FILES+=usr/lib/clang/11.0.1/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/11.0.1/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/11.0.1/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/11.0.1/include/adxintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/altivec.h OLD_FILES+=usr/lib/clang/11.0.1/include/ammintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/amxintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/arm64intr.h OLD_FILES+=usr/lib/clang/11.0.1/include/arm_acle.h OLD_FILES+=usr/lib/clang/11.0.1/include/arm_bf16.h OLD_FILES+=usr/lib/clang/11.0.1/include/arm_cde.h OLD_FILES+=usr/lib/clang/11.0.1/include/arm_cmse.h OLD_FILES+=usr/lib/clang/11.0.1/include/arm_fp16.h OLD_FILES+=usr/lib/clang/11.0.1/include/arm_mve.h OLD_FILES+=usr/lib/clang/11.0.1/include/arm_neon.h OLD_FILES+=usr/lib/clang/11.0.1/include/arm_sve.h OLD_FILES+=usr/lib/clang/11.0.1/include/armintr.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx2intrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512bf16intrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlbf16intrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlvp2intersectintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vp2intersectintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/avxintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/bmiintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/cet.h OLD_FILES+=usr/lib/clang/11.0.1/include/cetintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/clwbintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/clzerointrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/cpuid.h OLD_FILES+=usr/lib/clang/11.0.1/include/emmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/enqcmdintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/f16cintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/float.h OLD_FILES+=usr/lib/clang/11.0.1/include/fma4intrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/fmaintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/gfniintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/htmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/ia32intrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/immintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/intrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/inttypes.h OLD_FILES+=usr/lib/clang/11.0.1/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/iso646.h OLD_FILES+=usr/lib/clang/11.0.1/include/limits.h OLD_FILES+=usr/lib/clang/11.0.1/include/lwpintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/mm3dnow.h OLD_FILES+=usr/lib/clang/11.0.1/include/mm_malloc.h OLD_FILES+=usr/lib/clang/11.0.1/include/mmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/module.modulemap OLD_FILES+=usr/lib/clang/11.0.1/include/movdirintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/msa.h OLD_FILES+=usr/lib/clang/11.0.1/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/nmmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/omp-tools.h OLD_FILES+=usr/lib/clang/11.0.1/include/omp.h OLD_FILES+=usr/lib/clang/11.0.1/include/ompt.h OLD_FILES+=usr/lib/clang/11.0.1/include/opencl-c-base.h OLD_FILES+=usr/lib/clang/11.0.1/include/opencl-c.h OLD_FILES+=usr/lib/clang/11.0.1/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/pkuintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/pmmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/popcntintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/rtmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/s390intrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/serializeintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/sgxintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/shaintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/smmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/stdalign.h OLD_FILES+=usr/lib/clang/11.0.1/include/stdarg.h OLD_FILES+=usr/lib/clang/11.0.1/include/stdatomic.h OLD_FILES+=usr/lib/clang/11.0.1/include/stdbool.h OLD_FILES+=usr/lib/clang/11.0.1/include/stddef.h OLD_FILES+=usr/lib/clang/11.0.1/include/stdint.h OLD_FILES+=usr/lib/clang/11.0.1/include/stdnoreturn.h OLD_FILES+=usr/lib/clang/11.0.1/include/tbmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/tgmath.h OLD_FILES+=usr/lib/clang/11.0.1/include/tmmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/tsxldtrkintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/unwind.h OLD_FILES+=usr/lib/clang/11.0.1/include/vadefs.h OLD_FILES+=usr/lib/clang/11.0.1/include/vaesintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/varargs.h OLD_FILES+=usr/lib/clang/11.0.1/include/vecintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/wasm_simd128.h OLD_FILES+=usr/lib/clang/11.0.1/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/wmmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/x86intrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/xmmintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/xopintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/11.0.1/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/11.0.1/include OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-aarch64.so OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-arm.so OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-armhf.so OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-preinit-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-preinit-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-preinit-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan_cxx-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan_cxx-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi-i386.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi_diag-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi_diag-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi_diag-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi_diag-i386.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi_diag-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.dd-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.dd-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.fuzzer-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.fuzzer-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.msan-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.msan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-powerpc.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-powerpc64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-powerpc64le.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.safestack-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats_client-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats_client-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats_client-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.tsan-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_minimal-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-basic-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-basic-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-basic-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-basic-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-fdr-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-fdr-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-fdr-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-fdr-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-profiling-aarch64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-profiling-arm.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-profiling-armhf.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-profiling-x86_64.a OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-x86_64.a OLD_DIRS+=usr/lib/clang/11.0.1/lib/freebsd OLD_DIRS+=usr/lib/clang/11.0.1/lib OLD_DIRS+=usr/lib/clang/11.0.1 # 20210613: Rename OpenZFS manual pages OLD_FILES+=usr/share/man/man5/spl-module-parameters.5.gz OLD_FILES+=usr/share/man/man5/zfs-events.5.gz OLD_FILES+=usr/share/man/man5/zfs-module-parameters.5.gz OLD_FILES+=usr/share/man/man8/zfsconcepts.8.gz OLD_FILES+=usr/share/man/man8/zfsprops.8.gz OLD_FILES+=usr/share/man/man5/zpool-features.5.gz OLD_FILES+=usr/share/man/man8/zpoolconcepts.8.gz OLD_FILES+=usr/share/man/man8/zpoolprops.8.gz # 20210611: Remove svn and svnlite OLD_FILES+=usr/bin/svn OLD_FILES+=usr/bin/svnadmin OLD_FILES+=usr/bin/svnbench OLD_FILES+=usr/bin/svndumpfilter OLD_FILES+=usr/bin/svnfsfs OLD_FILES+=usr/bin/svnlite OLD_FILES+=usr/bin/svnliteadmin OLD_FILES+=usr/bin/svnlitebench OLD_FILES+=usr/bin/svnlitedumpfilter OLD_FILES+=usr/bin/svnlitefsfs OLD_FILES+=usr/bin/svnlitelook OLD_FILES+=usr/bin/svnlitemucc OLD_FILES+=usr/bin/svnliterdump OLD_FILES+=usr/bin/svnliteserve OLD_FILES+=usr/bin/svnlitesync OLD_FILES+=usr/bin/svnliteversion OLD_FILES+=usr/bin/svnlook OLD_FILES+=usr/bin/svnmucc OLD_FILES+=usr/bin/svnrdump OLD_FILES+=usr/bin/svnserve OLD_FILES+=usr/bin/svnsync OLD_FILES+=usr/bin/svnversion OLD_FILES+=usr/share/man/man1/svnlite.1.gz # 20210607: remove ancontrol(8) related programs OLD_FILES+=usr/sbin/ancontrol OLD_FILES+=usr/share/man/man8/ancontrol.8.gz # 20210607: remove an(4) OLD_FILES+=usr/include/dev/an/if_aironet_ieee.h OLD_FILES+=usr/include/dev/an/if_anreg.h OLD_FILES+=usr/share/man/man4/an.4.gz # 20210426: remove unused libexec/rc.d/addswap OLD_FILES+=etc/rc.d/addswap # 20210413: Remove pfctlinput2 OLD_FILES+=usr/share/man/man9/pfctlinput2.9.gz # 20210412: Remove kernel asymmetric crypto OLD_FILES+=usr/share/man/man9/crypto_asym.9.gz OLD_FILES+=usr/share/man/man9/crypto_kdispatch.9.gz OLD_FILES+=usr/share/man/man9/crypto_kdone.9.gz OLD_FILES+=usr/share/man/man9/crypto_kregister.9.gz OLD_FILES+=usr/share/man/man9/CRYPTODEV_KPROCESS.9.gz # 20210410: remove unused libexec/rc.d/archdep OLD_FILES+=etc/rc.d/archdep # 20210408: remove tcp_hostcache.h OLD_FILES+=usr/include/netinet/tcp_hostcache.h # 20210403: remove kgmon(8) OLD_FILES+=usr/sbin/kgmon OLD_FILES+=usr/share/man/man8/kgmon.8.gz # 20210401: remove bt(4) man page OLD_FILES+=usr/share/man/man4/bt.4.gz # 20210322: retire mn(4) sync serial driver OLD_FILES+=usr/share/man/man4/if_mn.4.gz OLD_FILES+=usr/share/man/man4/mn.4.gz # 20210318: remove the terminfo database OLD_FILES+=usr/share/terminfo/1/1178 OLD_FILES+=usr/share/terminfo/1/1730-lm OLD_DIRS+=usr/share/terminfo/1 OLD_FILES+=usr/share/terminfo/2/2621 OLD_FILES+=usr/share/terminfo/2/2621-wl OLD_FILES+=usr/share/terminfo/2/2621A OLD_FILES+=usr/share/terminfo/2/2621a OLD_DIRS+=usr/share/terminfo/2/ OLD_FILES+=usr/share/terminfo/3/386at OLD_FILES+=usr/share/terminfo/3/3b1 OLD_DIRS+=usr/share/terminfo/3/ OLD_FILES+=usr/share/terminfo/4/4025ex OLD_FILES+=usr/share/terminfo/4/4027ex OLD_FILES+=usr/share/terminfo/4/4410-w OLD_DIRS+=usr/share/terminfo/4/ OLD_FILES+=usr/share/terminfo/5/5051 OLD_FILES+=usr/share/terminfo/5/5410-w OLD_FILES+=usr/share/terminfo/5/5620 OLD_FILES+=usr/share/terminfo/5/5630-24 OLD_FILES+=usr/share/terminfo/5/5630DMD-24 OLD_DIRS+=usr/share/terminfo/5/ OLD_FILES+=usr/share/terminfo/6/6053 OLD_FILES+=usr/share/terminfo/6/6053-dg OLD_FILES+=usr/share/terminfo/6/605x OLD_FILES+=usr/share/terminfo/6/605x-dg OLD_FILES+=usr/share/terminfo/6/630-lm OLD_FILES+=usr/share/terminfo/6/630MTG-24 OLD_DIRS+=usr/share/terminfo/6/ OLD_FILES+=usr/share/terminfo/7/730MTG-24 OLD_FILES+=usr/share/terminfo/7/730MTG-41 OLD_FILES+=usr/share/terminfo/7/730MTG-41r OLD_FILES+=usr/share/terminfo/7/730MTGr OLD_FILES+=usr/share/terminfo/7/730MTGr-24 OLD_DIRS+=usr/share/terminfo/7/ OLD_FILES+=usr/share/terminfo/8/8510 OLD_DIRS+=usr/share/terminfo/8/ OLD_FILES+=usr/share/terminfo/9/955-hb OLD_FILES+=usr/share/terminfo/9/955-w OLD_FILES+=usr/share/terminfo/9/9term OLD_DIRS+=usr/share/terminfo/9/ OLD_FILES+=usr/share/terminfo/A/Apple_Terminal OLD_DIRS+=usr/share/terminfo/A/ OLD_FILES+=usr/share/terminfo/E/Eterm OLD_FILES+=usr/share/terminfo/E/Eterm-256color OLD_FILES+=usr/share/terminfo/E/Eterm-88color OLD_FILES+=usr/share/terminfo/E/Eterm-color OLD_DIRS+=usr/share/terminfo/E/ OLD_FILES+=usr/share/terminfo/L/LFT-PC850 OLD_DIRS+=usr/share/terminfo/L/ OLD_FILES+=usr/share/terminfo/M/MtxOrb OLD_FILES+=usr/share/terminfo/M/MtxOrb162 OLD_FILES+=usr/share/terminfo/M/MtxOrb204 OLD_DIRS+=usr/share/terminfo/M/ OLD_FILES+=usr/share/terminfo/N/NCR260VT300WPP OLD_FILES+=usr/share/terminfo/N/NCRVT100WPP OLD_DIRS+=usr/share/terminfo/N/ OLD_FILES+=usr/share/terminfo/P/P12 OLD_FILES+=usr/share/terminfo/P/P12-M OLD_FILES+=usr/share/terminfo/P/P12-M-W OLD_FILES+=usr/share/terminfo/P/P12-W OLD_FILES+=usr/share/terminfo/P/P14 OLD_FILES+=usr/share/terminfo/P/P14-M OLD_FILES+=usr/share/terminfo/P/P14-M-W OLD_FILES+=usr/share/terminfo/P/P14-W OLD_FILES+=usr/share/terminfo/P/P4 OLD_FILES+=usr/share/terminfo/P/P5 OLD_FILES+=usr/share/terminfo/P/P7 OLD_FILES+=usr/share/terminfo/P/P8 OLD_FILES+=usr/share/terminfo/P/P8-W OLD_FILES+=usr/share/terminfo/P/P9 OLD_FILES+=usr/share/terminfo/P/P9-8 OLD_FILES+=usr/share/terminfo/P/P9-8-W OLD_FILES+=usr/share/terminfo/P/P9-W OLD_DIRS+=usr/share/terminfo/P/ OLD_FILES+=usr/share/terminfo/Q/Q306-8-pc OLD_FILES+=usr/share/terminfo/Q/Q310-vip-H OLD_FILES+=usr/share/terminfo/Q/Q310-vip-H-am OLD_FILES+=usr/share/terminfo/Q/Q310-vip-Hw OLD_FILES+=usr/share/terminfo/Q/Q310-vip-w OLD_FILES+=usr/share/terminfo/Q/Q310-vip-w-am OLD_DIRS+=usr/share/terminfo/Q/ OLD_FILES+=usr/share/terminfo/X/X-hpterm OLD_DIRS+=usr/share/terminfo/X/ OLD_FILES+=usr/share/terminfo/a/a210 OLD_FILES+=usr/share/terminfo/a/a80 OLD_FILES+=usr/share/terminfo/a/a980 OLD_FILES+=usr/share/terminfo/a/aa4080 OLD_FILES+=usr/share/terminfo/a/aaa OLD_FILES+=usr/share/terminfo/a/aaa+dec OLD_FILES+=usr/share/terminfo/a/aaa+rv OLD_FILES+=usr/share/terminfo/a/aaa+unk OLD_FILES+=usr/share/terminfo/a/aaa-18 OLD_FILES+=usr/share/terminfo/a/aaa-18-rv OLD_FILES+=usr/share/terminfo/a/aaa-20 OLD_FILES+=usr/share/terminfo/a/aaa-22 OLD_FILES+=usr/share/terminfo/a/aaa-24 OLD_FILES+=usr/share/terminfo/a/aaa-24-rv OLD_FILES+=usr/share/terminfo/a/aaa-26 OLD_FILES+=usr/share/terminfo/a/aaa-28 OLD_FILES+=usr/share/terminfo/a/aaa-30 OLD_FILES+=usr/share/terminfo/a/aaa-30-ctxt OLD_FILES+=usr/share/terminfo/a/aaa-30-rv OLD_FILES+=usr/share/terminfo/a/aaa-30-rv-ctxt OLD_FILES+=usr/share/terminfo/a/aaa-30-s OLD_FILES+=usr/share/terminfo/a/aaa-30-s-ctxt OLD_FILES+=usr/share/terminfo/a/aaa-30-s-rv OLD_FILES+=usr/share/terminfo/a/aaa-30-s-rv-ct OLD_FILES+=usr/share/terminfo/a/aaa-36 OLD_FILES+=usr/share/terminfo/a/aaa-36-rv OLD_FILES+=usr/share/terminfo/a/aaa-40 OLD_FILES+=usr/share/terminfo/a/aaa-40-rv OLD_FILES+=usr/share/terminfo/a/aaa-48 OLD_FILES+=usr/share/terminfo/a/aaa-48-rv OLD_FILES+=usr/share/terminfo/a/aaa-60 OLD_FILES+=usr/share/terminfo/a/aaa-60-dec-rv OLD_FILES+=usr/share/terminfo/a/aaa-60-rv OLD_FILES+=usr/share/terminfo/a/aaa-60-s OLD_FILES+=usr/share/terminfo/a/aaa-60-s-rv OLD_FILES+=usr/share/terminfo/a/aaa-ctxt OLD_FILES+=usr/share/terminfo/a/aaa-db OLD_FILES+=usr/share/terminfo/a/aaa-rv OLD_FILES+=usr/share/terminfo/a/aaa-rv-ctxt OLD_FILES+=usr/share/terminfo/a/aaa-rv-unk OLD_FILES+=usr/share/terminfo/a/aaa-s OLD_FILES+=usr/share/terminfo/a/aaa-s-ctxt OLD_FILES+=usr/share/terminfo/a/aaa-s-rv OLD_FILES+=usr/share/terminfo/a/aaa-s-rv-ctxt OLD_FILES+=usr/share/terminfo/a/aaa-unk OLD_FILES+=usr/share/terminfo/a/aas1901 OLD_FILES+=usr/share/terminfo/a/abm80 OLD_FILES+=usr/share/terminfo/a/abm85 OLD_FILES+=usr/share/terminfo/a/abm85e OLD_FILES+=usr/share/terminfo/a/abm85h OLD_FILES+=usr/share/terminfo/a/abm85h-old OLD_FILES+=usr/share/terminfo/a/absolute OLD_FILES+=usr/share/terminfo/a/act4 OLD_FILES+=usr/share/terminfo/a/act5 OLD_FILES+=usr/share/terminfo/a/addrinfo OLD_FILES+=usr/share/terminfo/a/adds200 OLD_FILES+=usr/share/terminfo/a/adds980 OLD_FILES+=usr/share/terminfo/a/addsviewpoint OLD_FILES+=usr/share/terminfo/a/addsvp60 OLD_FILES+=usr/share/terminfo/a/adm+sgr OLD_FILES+=usr/share/terminfo/a/adm1 OLD_FILES+=usr/share/terminfo/a/adm11 OLD_FILES+=usr/share/terminfo/a/adm1178 OLD_FILES+=usr/share/terminfo/a/adm12 OLD_FILES+=usr/share/terminfo/a/adm1a OLD_FILES+=usr/share/terminfo/a/adm2 OLD_FILES+=usr/share/terminfo/a/adm20 OLD_FILES+=usr/share/terminfo/a/adm21 OLD_FILES+=usr/share/terminfo/a/adm22 OLD_FILES+=usr/share/terminfo/a/adm3 OLD_FILES+=usr/share/terminfo/a/adm31 OLD_FILES+=usr/share/terminfo/a/adm31-old OLD_FILES+=usr/share/terminfo/a/adm36 OLD_FILES+=usr/share/terminfo/a/adm3a OLD_FILES+=usr/share/terminfo/a/adm3a+ OLD_FILES+=usr/share/terminfo/a/adm42 OLD_FILES+=usr/share/terminfo/a/adm42-ns OLD_FILES+=usr/share/terminfo/a/adm5 OLD_FILES+=usr/share/terminfo/a/aepro OLD_FILES+=usr/share/terminfo/a/aixterm OLD_FILES+=usr/share/terminfo/a/aixterm-16color OLD_FILES+=usr/share/terminfo/a/aixterm-m OLD_FILES+=usr/share/terminfo/a/aixterm-m-old OLD_FILES+=usr/share/terminfo/a/aj OLD_FILES+=usr/share/terminfo/a/aj510 OLD_FILES+=usr/share/terminfo/a/aj830 OLD_FILES+=usr/share/terminfo/a/aj832 OLD_FILES+=usr/share/terminfo/a/alacritty OLD_FILES+=usr/share/terminfo/a/alacritty+common OLD_FILES+=usr/share/terminfo/a/alacritty-direct OLD_FILES+=usr/share/terminfo/a/alt2 OLD_FILES+=usr/share/terminfo/a/alt3 OLD_FILES+=usr/share/terminfo/a/alt4 OLD_FILES+=usr/share/terminfo/a/alt5 OLD_FILES+=usr/share/terminfo/a/alt7 OLD_FILES+=usr/share/terminfo/a/alt7pc OLD_FILES+=usr/share/terminfo/a/alto-h19 OLD_FILES+=usr/share/terminfo/a/alto-heath OLD_FILES+=usr/share/terminfo/a/altoh19 OLD_FILES+=usr/share/terminfo/a/altoheath OLD_FILES+=usr/share/terminfo/a/altos-2 OLD_FILES+=usr/share/terminfo/a/altos-3 OLD_FILES+=usr/share/terminfo/a/altos-4 OLD_FILES+=usr/share/terminfo/a/altos-5 OLD_FILES+=usr/share/terminfo/a/altos2 OLD_FILES+=usr/share/terminfo/a/altos3 OLD_FILES+=usr/share/terminfo/a/altos4 OLD_FILES+=usr/share/terminfo/a/altos5 OLD_FILES+=usr/share/terminfo/a/altos7 OLD_FILES+=usr/share/terminfo/a/altos7pc OLD_FILES+=usr/share/terminfo/a/ambas OLD_FILES+=usr/share/terminfo/a/ambassador OLD_FILES+=usr/share/terminfo/a/amiga OLD_FILES+=usr/share/terminfo/a/amiga-8bit OLD_FILES+=usr/share/terminfo/a/amiga-h OLD_FILES+=usr/share/terminfo/a/amiga-vnc OLD_FILES+=usr/share/terminfo/a/amp219 OLD_FILES+=usr/share/terminfo/a/amp219w OLD_FILES+=usr/share/terminfo/a/ampex-219 OLD_FILES+=usr/share/terminfo/a/ampex-219w OLD_FILES+=usr/share/terminfo/a/ampex-232 OLD_FILES+=usr/share/terminfo/a/ampex175 OLD_FILES+=usr/share/terminfo/a/ampex175-b OLD_FILES+=usr/share/terminfo/a/ampex210 OLD_FILES+=usr/share/terminfo/a/ampex219 OLD_FILES+=usr/share/terminfo/a/ampex219w OLD_FILES+=usr/share/terminfo/a/ampex232 OLD_FILES+=usr/share/terminfo/a/ampex232w OLD_FILES+=usr/share/terminfo/a/ampex80 OLD_FILES+=usr/share/terminfo/a/annarbor4080 OLD_FILES+=usr/share/terminfo/a/ansi OLD_FILES+=usr/share/terminfo/a/ansi+arrows OLD_FILES+=usr/share/terminfo/a/ansi+csr OLD_FILES+=usr/share/terminfo/a/ansi+cup OLD_FILES+=usr/share/terminfo/a/ansi+enq OLD_FILES+=usr/share/terminfo/a/ansi+erase OLD_FILES+=usr/share/terminfo/a/ansi+idc OLD_FILES+=usr/share/terminfo/a/ansi+idc1 OLD_FILES+=usr/share/terminfo/a/ansi+idl OLD_FILES+=usr/share/terminfo/a/ansi+idl1 OLD_FILES+=usr/share/terminfo/a/ansi+inittabs OLD_FILES+=usr/share/terminfo/a/ansi+local OLD_FILES+=usr/share/terminfo/a/ansi+local1 OLD_FILES+=usr/share/terminfo/a/ansi+pp OLD_FILES+=usr/share/terminfo/a/ansi+rca OLD_FILES+=usr/share/terminfo/a/ansi+rep OLD_FILES+=usr/share/terminfo/a/ansi+sgr OLD_FILES+=usr/share/terminfo/a/ansi+sgrbold OLD_FILES+=usr/share/terminfo/a/ansi+sgrdim OLD_FILES+=usr/share/terminfo/a/ansi+sgrso OLD_FILES+=usr/share/terminfo/a/ansi+sgrul OLD_FILES+=usr/share/terminfo/a/ansi+tabs OLD_FILES+=usr/share/terminfo/a/ansi-color-2-emx OLD_FILES+=usr/share/terminfo/a/ansi-color-3-emx OLD_FILES+=usr/share/terminfo/a/ansi-emx OLD_FILES+=usr/share/terminfo/a/ansi-generic OLD_FILES+=usr/share/terminfo/a/ansi-m OLD_FILES+=usr/share/terminfo/a/ansi-mini OLD_FILES+=usr/share/terminfo/a/ansi-mono OLD_FILES+=usr/share/terminfo/a/ansi-mr OLD_FILES+=usr/share/terminfo/a/ansi-mtabs OLD_FILES+=usr/share/terminfo/a/ansi-nt OLD_FILES+=usr/share/terminfo/a/ansi.sys OLD_FILES+=usr/share/terminfo/a/ansi.sys-old OLD_FILES+=usr/share/terminfo/a/ansi.sysk OLD_FILES+=usr/share/terminfo/a/ansi43m OLD_FILES+=usr/share/terminfo/a/ansi77 OLD_FILES+=usr/share/terminfo/a/ansi80x25 OLD_FILES+=usr/share/terminfo/a/ansi80x25-mono OLD_FILES+=usr/share/terminfo/a/ansi80x25-raw OLD_FILES+=usr/share/terminfo/a/ansi80x30 OLD_FILES+=usr/share/terminfo/a/ansi80x30-mono OLD_FILES+=usr/share/terminfo/a/ansi80x43 OLD_FILES+=usr/share/terminfo/a/ansi80x43-mono OLD_FILES+=usr/share/terminfo/a/ansi80x50 OLD_FILES+=usr/share/terminfo/a/ansi80x50-mono OLD_FILES+=usr/share/terminfo/a/ansi80x60 OLD_FILES+=usr/share/terminfo/a/ansi80x60-mono OLD_FILES+=usr/share/terminfo/a/ansil OLD_FILES+=usr/share/terminfo/a/ansil-mono OLD_FILES+=usr/share/terminfo/a/ansis OLD_FILES+=usr/share/terminfo/a/ansis-mono OLD_FILES+=usr/share/terminfo/a/ansisysk OLD_FILES+=usr/share/terminfo/a/ansiterm OLD_FILES+=usr/share/terminfo/a/ansiw OLD_FILES+=usr/share/terminfo/a/ap-vm80 OLD_FILES+=usr/share/terminfo/a/apl OLD_FILES+=usr/share/terminfo/a/apollo OLD_FILES+=usr/share/terminfo/a/apollo_15P OLD_FILES+=usr/share/terminfo/a/apollo_19L OLD_FILES+=usr/share/terminfo/a/apollo_color OLD_FILES+=usr/share/terminfo/a/apple-80 OLD_FILES+=usr/share/terminfo/a/apple-ae OLD_FILES+=usr/share/terminfo/a/apple-soroc OLD_FILES+=usr/share/terminfo/a/apple-uterm OLD_FILES+=usr/share/terminfo/a/apple-uterm-vb OLD_FILES+=usr/share/terminfo/a/apple-videx OLD_FILES+=usr/share/terminfo/a/apple-videx2 OLD_FILES+=usr/share/terminfo/a/apple-videx3 OLD_FILES+=usr/share/terminfo/a/apple-vm80 OLD_FILES+=usr/share/terminfo/a/apple2e OLD_FILES+=usr/share/terminfo/a/apple2e-p OLD_FILES+=usr/share/terminfo/a/apple80p OLD_FILES+=usr/share/terminfo/a/appleII OLD_FILES+=usr/share/terminfo/a/appleIIc OLD_FILES+=usr/share/terminfo/a/appleIIe OLD_FILES+=usr/share/terminfo/a/appleIIgs OLD_FILES+=usr/share/terminfo/a/arm100 OLD_FILES+=usr/share/terminfo/a/arm100-am OLD_FILES+=usr/share/terminfo/a/arm100-w OLD_FILES+=usr/share/terminfo/a/arm100-wam OLD_FILES+=usr/share/terminfo/a/at OLD_FILES+=usr/share/terminfo/a/at-color OLD_FILES+=usr/share/terminfo/a/at-m OLD_FILES+=usr/share/terminfo/a/at386 OLD_FILES+=usr/share/terminfo/a/atari OLD_FILES+=usr/share/terminfo/a/atari-color OLD_FILES+=usr/share/terminfo/a/atari-m OLD_FILES+=usr/share/terminfo/a/atari-old OLD_FILES+=usr/share/terminfo/a/atari_st OLD_FILES+=usr/share/terminfo/a/atari_st-color OLD_FILES+=usr/share/terminfo/a/atarist-m OLD_FILES+=usr/share/terminfo/a/aterm OLD_FILES+=usr/share/terminfo/a/att2300 OLD_FILES+=usr/share/terminfo/a/att2350 OLD_FILES+=usr/share/terminfo/a/att4410 OLD_FILES+=usr/share/terminfo/a/att4410-w OLD_FILES+=usr/share/terminfo/a/att4410v1 OLD_FILES+=usr/share/terminfo/a/att4410v1-w OLD_FILES+=usr/share/terminfo/a/att4415 OLD_FILES+=usr/share/terminfo/a/att4415+nl OLD_FILES+=usr/share/terminfo/a/att4415-nl OLD_FILES+=usr/share/terminfo/a/att4415-rv OLD_FILES+=usr/share/terminfo/a/att4415-rv-nl OLD_FILES+=usr/share/terminfo/a/att4415-w OLD_FILES+=usr/share/terminfo/a/att4415-w-nl OLD_FILES+=usr/share/terminfo/a/att4415-w-rv OLD_FILES+=usr/share/terminfo/a/att4415-w-rv-n OLD_FILES+=usr/share/terminfo/a/att4418 OLD_FILES+=usr/share/terminfo/a/att4418-w OLD_FILES+=usr/share/terminfo/a/att4420 OLD_FILES+=usr/share/terminfo/a/att4424 OLD_FILES+=usr/share/terminfo/a/att4424-1 OLD_FILES+=usr/share/terminfo/a/att4424m OLD_FILES+=usr/share/terminfo/a/att4425 OLD_FILES+=usr/share/terminfo/a/att4425-nl OLD_FILES+=usr/share/terminfo/a/att4425-w OLD_FILES+=usr/share/terminfo/a/att4426 OLD_FILES+=usr/share/terminfo/a/att500 OLD_FILES+=usr/share/terminfo/a/att505 OLD_FILES+=usr/share/terminfo/a/att505-24 OLD_FILES+=usr/share/terminfo/a/att510a OLD_FILES+=usr/share/terminfo/a/att510d OLD_FILES+=usr/share/terminfo/a/att513 OLD_FILES+=usr/share/terminfo/a/att5310 OLD_FILES+=usr/share/terminfo/a/att5320 OLD_FILES+=usr/share/terminfo/a/att5410 OLD_FILES+=usr/share/terminfo/a/att5410-w OLD_FILES+=usr/share/terminfo/a/att5410v1 OLD_FILES+=usr/share/terminfo/a/att5410v1-w OLD_FILES+=usr/share/terminfo/a/att5418 OLD_FILES+=usr/share/terminfo/a/att5418-w OLD_FILES+=usr/share/terminfo/a/att5420 OLD_FILES+=usr/share/terminfo/a/att5420+nl OLD_FILES+=usr/share/terminfo/a/att5420-nl OLD_FILES+=usr/share/terminfo/a/att5420-rv OLD_FILES+=usr/share/terminfo/a/att5420-rv-nl OLD_FILES+=usr/share/terminfo/a/att5420-w OLD_FILES+=usr/share/terminfo/a/att5420-w-nl OLD_FILES+=usr/share/terminfo/a/att5420-w-rv OLD_FILES+=usr/share/terminfo/a/att5420-w-rv-n OLD_FILES+=usr/share/terminfo/a/att5420_2 OLD_FILES+=usr/share/terminfo/a/att5420_2-w OLD_FILES+=usr/share/terminfo/a/att5425 OLD_FILES+=usr/share/terminfo/a/att5425-nl OLD_FILES+=usr/share/terminfo/a/att5425-w OLD_FILES+=usr/share/terminfo/a/att5430 OLD_FILES+=usr/share/terminfo/a/att5620 OLD_FILES+=usr/share/terminfo/a/att5620-1 OLD_FILES+=usr/share/terminfo/a/att5620-24 OLD_FILES+=usr/share/terminfo/a/att5620-34 OLD_FILES+=usr/share/terminfo/a/att5620-s OLD_FILES+=usr/share/terminfo/a/att605 OLD_FILES+=usr/share/terminfo/a/att605-pc OLD_FILES+=usr/share/terminfo/a/att605-w OLD_FILES+=usr/share/terminfo/a/att610 OLD_FILES+=usr/share/terminfo/a/att610+cvis OLD_FILES+=usr/share/terminfo/a/att610+cvis0 OLD_FILES+=usr/share/terminfo/a/att610-103k OLD_FILES+=usr/share/terminfo/a/att610-103k-w OLD_FILES+=usr/share/terminfo/a/att610-w OLD_FILES+=usr/share/terminfo/a/att615 OLD_FILES+=usr/share/terminfo/a/att615-103k OLD_FILES+=usr/share/terminfo/a/att615-103k-w OLD_FILES+=usr/share/terminfo/a/att615-w OLD_FILES+=usr/share/terminfo/a/att620 OLD_FILES+=usr/share/terminfo/a/att620-103k OLD_FILES+=usr/share/terminfo/a/att620-103k-w OLD_FILES+=usr/share/terminfo/a/att620-w OLD_FILES+=usr/share/terminfo/a/att630 OLD_FILES+=usr/share/terminfo/a/att630-24 OLD_FILES+=usr/share/terminfo/a/att6386 OLD_FILES+=usr/share/terminfo/a/att700 OLD_FILES+=usr/share/terminfo/a/att730 OLD_FILES+=usr/share/terminfo/a/att730-24 OLD_FILES+=usr/share/terminfo/a/att730-41 OLD_FILES+=usr/share/terminfo/a/att7300 OLD_FILES+=usr/share/terminfo/a/att730r OLD_FILES+=usr/share/terminfo/a/att730r-24 OLD_FILES+=usr/share/terminfo/a/att730r-41 OLD_FILES+=usr/share/terminfo/a/avatar OLD_FILES+=usr/share/terminfo/a/avatar0 OLD_FILES+=usr/share/terminfo/a/avatar0+ OLD_FILES+=usr/share/terminfo/a/avatar1 OLD_FILES+=usr/share/terminfo/a/avt OLD_FILES+=usr/share/terminfo/a/avt+s OLD_FILES+=usr/share/terminfo/a/avt-ns OLD_FILES+=usr/share/terminfo/a/avt-rv OLD_FILES+=usr/share/terminfo/a/avt-rv-ns OLD_FILES+=usr/share/terminfo/a/avt-rv-s OLD_FILES+=usr/share/terminfo/a/avt-s OLD_FILES+=usr/share/terminfo/a/avt-w OLD_FILES+=usr/share/terminfo/a/avt-w-ns OLD_FILES+=usr/share/terminfo/a/avt-w-rv OLD_FILES+=usr/share/terminfo/a/avt-w-rv-ns OLD_FILES+=usr/share/terminfo/a/avt-w-rv-s OLD_FILES+=usr/share/terminfo/a/avt-w-s OLD_FILES+=usr/share/terminfo/a/aws OLD_FILES+=usr/share/terminfo/a/awsc OLD_DIRS+=usr/share/terminfo/a/ OLD_FILES+=usr/share/terminfo/b/b-128 OLD_FILES+=usr/share/terminfo/b/bantam OLD_FILES+=usr/share/terminfo/b/basic4 OLD_FILES+=usr/share/terminfo/b/basis OLD_FILES+=usr/share/terminfo/b/bct510a OLD_FILES+=usr/share/terminfo/b/bct510d OLD_FILES+=usr/share/terminfo/b/beacon OLD_FILES+=usr/share/terminfo/b/bee OLD_FILES+=usr/share/terminfo/b/beehive OLD_FILES+=usr/share/terminfo/b/beehive3 OLD_FILES+=usr/share/terminfo/b/beehive4 OLD_FILES+=usr/share/terminfo/b/beehiveIIIm OLD_FILES+=usr/share/terminfo/b/beterm OLD_FILES+=usr/share/terminfo/b/bg1.25 OLD_FILES+=usr/share/terminfo/b/bg1.25nv OLD_FILES+=usr/share/terminfo/b/bg1.25rv OLD_FILES+=usr/share/terminfo/b/bg2.0 OLD_FILES+=usr/share/terminfo/b/bg2.0nv OLD_FILES+=usr/share/terminfo/b/bg2.0rv OLD_FILES+=usr/share/terminfo/b/bg3.10 OLD_FILES+=usr/share/terminfo/b/bg3.10nv OLD_FILES+=usr/share/terminfo/b/bg3.10rv OLD_FILES+=usr/share/terminfo/b/bh3m OLD_FILES+=usr/share/terminfo/b/bh4 OLD_FILES+=usr/share/terminfo/b/bitgraph OLD_FILES+=usr/share/terminfo/b/blit OLD_FILES+=usr/share/terminfo/b/bobcat OLD_FILES+=usr/share/terminfo/b/bq300 OLD_FILES+=usr/share/terminfo/b/bq300-8 OLD_FILES+=usr/share/terminfo/b/bq300-8-pc OLD_FILES+=usr/share/terminfo/b/bq300-8-pc-rv OLD_FILES+=usr/share/terminfo/b/bq300-8-pc-w OLD_FILES+=usr/share/terminfo/b/bq300-8-pc-w-rv OLD_FILES+=usr/share/terminfo/b/bq300-8rv OLD_FILES+=usr/share/terminfo/b/bq300-8w OLD_FILES+=usr/share/terminfo/b/bq300-pc OLD_FILES+=usr/share/terminfo/b/bq300-pc-rv OLD_FILES+=usr/share/terminfo/b/bq300-pc-w OLD_FILES+=usr/share/terminfo/b/bq300-pc-w-rv OLD_FILES+=usr/share/terminfo/b/bq300-rv OLD_FILES+=usr/share/terminfo/b/bq300-w OLD_FILES+=usr/share/terminfo/b/bq300-w-8rv OLD_FILES+=usr/share/terminfo/b/bq300-w-rv OLD_FILES+=usr/share/terminfo/b/bsdos-pc OLD_FILES+=usr/share/terminfo/b/bsdos-pc-m OLD_FILES+=usr/share/terminfo/b/bsdos-pc-mono OLD_FILES+=usr/share/terminfo/b/bsdos-pc-nobold OLD_FILES+=usr/share/terminfo/b/bsdos-ppc OLD_FILES+=usr/share/terminfo/b/bsdos-sparc OLD_FILES+=usr/share/terminfo/b/bterm OLD_DIRS+=usr/share/terminfo/b/ OLD_FILES+=usr/share/terminfo/c/c100 OLD_FILES+=usr/share/terminfo/c/c100-1p OLD_FILES+=usr/share/terminfo/c/c100-4p OLD_FILES+=usr/share/terminfo/c/c100-rv OLD_FILES+=usr/share/terminfo/c/c100-rv-4p OLD_FILES+=usr/share/terminfo/c/c104 OLD_FILES+=usr/share/terminfo/c/c108 OLD_FILES+=usr/share/terminfo/c/c108-4p OLD_FILES+=usr/share/terminfo/c/c108-8p OLD_FILES+=usr/share/terminfo/c/c108-rv OLD_FILES+=usr/share/terminfo/c/c108-rv-4p OLD_FILES+=usr/share/terminfo/c/c108-rv-8p OLD_FILES+=usr/share/terminfo/c/c108-w OLD_FILES+=usr/share/terminfo/c/c108-w-8p OLD_FILES+=usr/share/terminfo/c/c300 OLD_FILES+=usr/share/terminfo/c/c301 OLD_FILES+=usr/share/terminfo/c/c321 OLD_FILES+=usr/share/terminfo/c/ca22851 OLD_FILES+=usr/share/terminfo/c/cad68-2 OLD_FILES+=usr/share/terminfo/c/cad68-3 OLD_FILES+=usr/share/terminfo/c/cbblit OLD_FILES+=usr/share/terminfo/c/cbunix OLD_FILES+=usr/share/terminfo/c/cci OLD_FILES+=usr/share/terminfo/c/cci1 OLD_FILES+=usr/share/terminfo/c/cdc456 OLD_FILES+=usr/share/terminfo/c/cdc721 OLD_FILES+=usr/share/terminfo/c/cdc721-esc OLD_FILES+=usr/share/terminfo/c/cdc721ll OLD_FILES+=usr/share/terminfo/c/cdc752 OLD_FILES+=usr/share/terminfo/c/cdc756 OLD_FILES+=usr/share/terminfo/c/cg7900 OLD_FILES+=usr/share/terminfo/c/cgc2 OLD_FILES+=usr/share/terminfo/c/cgc3 OLD_FILES+=usr/share/terminfo/c/chromatics OLD_FILES+=usr/share/terminfo/c/ci8510 OLD_FILES+=usr/share/terminfo/c/cit-80 OLD_FILES+=usr/share/terminfo/c/cit101 OLD_FILES+=usr/share/terminfo/c/cit101e OLD_FILES+=usr/share/terminfo/c/cit101e-132 OLD_FILES+=usr/share/terminfo/c/cit101e-n OLD_FILES+=usr/share/terminfo/c/cit101e-n132 OLD_FILES+=usr/share/terminfo/c/cit101e-rv OLD_FILES+=usr/share/terminfo/c/cit500 OLD_FILES+=usr/share/terminfo/c/cit80 OLD_FILES+=usr/share/terminfo/c/citc OLD_FILES+=usr/share/terminfo/c/citoh OLD_FILES+=usr/share/terminfo/c/citoh-6lpi OLD_FILES+=usr/share/terminfo/c/citoh-8lpi OLD_FILES+=usr/share/terminfo/c/citoh-comp OLD_FILES+=usr/share/terminfo/c/citoh-elite OLD_FILES+=usr/share/terminfo/c/citoh-pica OLD_FILES+=usr/share/terminfo/c/citoh-prop OLD_FILES+=usr/share/terminfo/c/citoh-ps OLD_FILES+=usr/share/terminfo/c/coco3 OLD_FILES+=usr/share/terminfo/c/coherent OLD_FILES+=usr/share/terminfo/c/color_xterm OLD_FILES+=usr/share/terminfo/c/colorscan OLD_FILES+=usr/share/terminfo/c/commodore OLD_FILES+=usr/share/terminfo/c/concept OLD_FILES+=usr/share/terminfo/c/concept-avt OLD_FILES+=usr/share/terminfo/c/concept100 OLD_FILES+=usr/share/terminfo/c/concept100-rv OLD_FILES+=usr/share/terminfo/c/concept108 OLD_FILES+=usr/share/terminfo/c/concept108-4p OLD_FILES+=usr/share/terminfo/c/concept108-8p OLD_FILES+=usr/share/terminfo/c/concept108-w-8 OLD_FILES+=usr/share/terminfo/c/concept108-w8p OLD_FILES+=usr/share/terminfo/c/concept108rv4p OLD_FILES+=usr/share/terminfo/c/cons25 OLD_FILES+=usr/share/terminfo/c/cons25-debian OLD_FILES+=usr/share/terminfo/c/cons25-iso-m OLD_FILES+=usr/share/terminfo/c/cons25-iso8859 OLD_FILES+=usr/share/terminfo/c/cons25-koi8-r OLD_FILES+=usr/share/terminfo/c/cons25-koi8r-m OLD_FILES+=usr/share/terminfo/c/cons25-m OLD_FILES+=usr/share/terminfo/c/cons25l1 OLD_FILES+=usr/share/terminfo/c/cons25l1-m OLD_FILES+=usr/share/terminfo/c/cons25r OLD_FILES+=usr/share/terminfo/c/cons25r-m OLD_FILES+=usr/share/terminfo/c/cons25w OLD_FILES+=usr/share/terminfo/c/cons30 OLD_FILES+=usr/share/terminfo/c/cons30-m OLD_FILES+=usr/share/terminfo/c/cons43 OLD_FILES+=usr/share/terminfo/c/cons43-m OLD_FILES+=usr/share/terminfo/c/cons50 OLD_FILES+=usr/share/terminfo/c/cons50-iso-m OLD_FILES+=usr/share/terminfo/c/cons50-iso8859 OLD_FILES+=usr/share/terminfo/c/cons50-koi8r OLD_FILES+=usr/share/terminfo/c/cons50-koi8r-m OLD_FILES+=usr/share/terminfo/c/cons50-m OLD_FILES+=usr/share/terminfo/c/cons50l1 OLD_FILES+=usr/share/terminfo/c/cons50l1-m OLD_FILES+=usr/share/terminfo/c/cons50r OLD_FILES+=usr/share/terminfo/c/cons50r-m OLD_FILES+=usr/share/terminfo/c/cons60 OLD_FILES+=usr/share/terminfo/c/cons60-iso OLD_FILES+=usr/share/terminfo/c/cons60-iso-m OLD_FILES+=usr/share/terminfo/c/cons60-koi8r OLD_FILES+=usr/share/terminfo/c/cons60-koi8r-m OLD_FILES+=usr/share/terminfo/c/cons60-m OLD_FILES+=usr/share/terminfo/c/cons60l1 OLD_FILES+=usr/share/terminfo/c/cons60l1-m OLD_FILES+=usr/share/terminfo/c/cons60r OLD_FILES+=usr/share/terminfo/c/cons60r-m OLD_FILES+=usr/share/terminfo/c/contel300 OLD_FILES+=usr/share/terminfo/c/contel301 OLD_FILES+=usr/share/terminfo/c/contel320 OLD_FILES+=usr/share/terminfo/c/contel321 OLD_FILES+=usr/share/terminfo/c/cops OLD_FILES+=usr/share/terminfo/c/cops-10 OLD_FILES+=usr/share/terminfo/c/cops10 OLD_FILES+=usr/share/terminfo/c/crt OLD_FILES+=usr/share/terminfo/c/crt-vt220 OLD_FILES+=usr/share/terminfo/c/cs10 OLD_FILES+=usr/share/terminfo/c/cs10-w OLD_FILES+=usr/share/terminfo/c/ct82 OLD_FILES+=usr/share/terminfo/c/ct8500 OLD_FILES+=usr/share/terminfo/c/ctrm OLD_FILES+=usr/share/terminfo/c/cx OLD_FILES+=usr/share/terminfo/c/cx100 OLD_FILES+=usr/share/terminfo/c/cyb110 OLD_FILES+=usr/share/terminfo/c/cyb83 OLD_FILES+=usr/share/terminfo/c/cygwin OLD_FILES+=usr/share/terminfo/c/cygwinB19 OLD_FILES+=usr/share/terminfo/c/cygwinDBG OLD_DIRS+=usr/share/terminfo/c/ OLD_FILES+=usr/share/terminfo/d/d132 OLD_FILES+=usr/share/terminfo/d/d2 OLD_FILES+=usr/share/terminfo/d/d2-dg OLD_FILES+=usr/share/terminfo/d/d200 OLD_FILES+=usr/share/terminfo/d/d200-dg OLD_FILES+=usr/share/terminfo/d/d210 OLD_FILES+=usr/share/terminfo/d/d210-dg OLD_FILES+=usr/share/terminfo/d/d211 OLD_FILES+=usr/share/terminfo/d/d211-7b OLD_FILES+=usr/share/terminfo/d/d211-dg OLD_FILES+=usr/share/terminfo/d/d214 OLD_FILES+=usr/share/terminfo/d/d214-dg OLD_FILES+=usr/share/terminfo/d/d215 OLD_FILES+=usr/share/terminfo/d/d215-7b OLD_FILES+=usr/share/terminfo/d/d215-dg OLD_FILES+=usr/share/terminfo/d/d216+ OLD_FILES+=usr/share/terminfo/d/d216+25 OLD_FILES+=usr/share/terminfo/d/d216+dg OLD_FILES+=usr/share/terminfo/d/d216-dg OLD_FILES+=usr/share/terminfo/d/d216-unix OLD_FILES+=usr/share/terminfo/d/d216-unix-25 OLD_FILES+=usr/share/terminfo/d/d216e+ OLD_FILES+=usr/share/terminfo/d/d216e+dg OLD_FILES+=usr/share/terminfo/d/d216e-dg OLD_FILES+=usr/share/terminfo/d/d216e-unix OLD_FILES+=usr/share/terminfo/d/d217-dg OLD_FILES+=usr/share/terminfo/d/d217-unix OLD_FILES+=usr/share/terminfo/d/d217-unix-25 OLD_FILES+=usr/share/terminfo/d/d220 OLD_FILES+=usr/share/terminfo/d/d220-7b OLD_FILES+=usr/share/terminfo/d/d220-dg OLD_FILES+=usr/share/terminfo/d/d230 OLD_FILES+=usr/share/terminfo/d/d230-dg OLD_FILES+=usr/share/terminfo/d/d230c OLD_FILES+=usr/share/terminfo/d/d230c-dg OLD_FILES+=usr/share/terminfo/d/d400 OLD_FILES+=usr/share/terminfo/d/d400-dg OLD_FILES+=usr/share/terminfo/d/d410 OLD_FILES+=usr/share/terminfo/d/d410-7b OLD_FILES+=usr/share/terminfo/d/d410-7b-w OLD_FILES+=usr/share/terminfo/d/d410-dg OLD_FILES+=usr/share/terminfo/d/d410-w OLD_FILES+=usr/share/terminfo/d/d411 OLD_FILES+=usr/share/terminfo/d/d411-7b OLD_FILES+=usr/share/terminfo/d/d411-7b-w OLD_FILES+=usr/share/terminfo/d/d411-dg OLD_FILES+=usr/share/terminfo/d/d411-w OLD_FILES+=usr/share/terminfo/d/d412+ OLD_FILES+=usr/share/terminfo/d/d412+25 OLD_FILES+=usr/share/terminfo/d/d412+dg OLD_FILES+=usr/share/terminfo/d/d412+s OLD_FILES+=usr/share/terminfo/d/d412+sr OLD_FILES+=usr/share/terminfo/d/d412+w OLD_FILES+=usr/share/terminfo/d/d412-dg OLD_FILES+=usr/share/terminfo/d/d412-unix OLD_FILES+=usr/share/terminfo/d/d412-unix-25 OLD_FILES+=usr/share/terminfo/d/d412-unix-s OLD_FILES+=usr/share/terminfo/d/d412-unix-sr OLD_FILES+=usr/share/terminfo/d/d412-unix-w OLD_FILES+=usr/share/terminfo/d/d413-dg OLD_FILES+=usr/share/terminfo/d/d413-unix OLD_FILES+=usr/share/terminfo/d/d413-unix-25 OLD_FILES+=usr/share/terminfo/d/d413-unix-s OLD_FILES+=usr/share/terminfo/d/d413-unix-sr OLD_FILES+=usr/share/terminfo/d/d413-unix-w OLD_FILES+=usr/share/terminfo/d/d414-unix OLD_FILES+=usr/share/terminfo/d/d414-unix-25 OLD_FILES+=usr/share/terminfo/d/d414-unix-s OLD_FILES+=usr/share/terminfo/d/d414-unix-sr OLD_FILES+=usr/share/terminfo/d/d414-unix-w OLD_FILES+=usr/share/terminfo/d/d430-dg OLD_FILES+=usr/share/terminfo/d/d430-dg-ccc OLD_FILES+=usr/share/terminfo/d/d430-unix OLD_FILES+=usr/share/terminfo/d/d430-unix-25 OLD_FILES+=usr/share/terminfo/d/d430-unix-25-ccc OLD_FILES+=usr/share/terminfo/d/d430-unix-ccc OLD_FILES+=usr/share/terminfo/d/d430-unix-s OLD_FILES+=usr/share/terminfo/d/d430-unix-s-ccc OLD_FILES+=usr/share/terminfo/d/d430-unix-sr OLD_FILES+=usr/share/terminfo/d/d430-unix-sr-ccc OLD_FILES+=usr/share/terminfo/d/d430-unix-w OLD_FILES+=usr/share/terminfo/d/d430-unix-w-ccc OLD_FILES+=usr/share/terminfo/d/d430c-dg OLD_FILES+=usr/share/terminfo/d/d430c-dg-ccc OLD_FILES+=usr/share/terminfo/d/d430c-unix OLD_FILES+=usr/share/terminfo/d/d430c-unix-25 OLD_FILES+=usr/share/terminfo/d/d430c-unix-25-ccc OLD_FILES+=usr/share/terminfo/d/d430c-unix-ccc OLD_FILES+=usr/share/terminfo/d/d430c-unix-s OLD_FILES+=usr/share/terminfo/d/d430c-unix-s-ccc OLD_FILES+=usr/share/terminfo/d/d430c-unix-sr OLD_FILES+=usr/share/terminfo/d/d430c-unix-sr-ccc OLD_FILES+=usr/share/terminfo/d/d430c-unix-w OLD_FILES+=usr/share/terminfo/d/d430c-unix-w-ccc OLD_FILES+=usr/share/terminfo/d/d450 OLD_FILES+=usr/share/terminfo/d/d450-dg OLD_FILES+=usr/share/terminfo/d/d460 OLD_FILES+=usr/share/terminfo/d/d460-7b OLD_FILES+=usr/share/terminfo/d/d460-7b-w OLD_FILES+=usr/share/terminfo/d/d460-dg OLD_FILES+=usr/share/terminfo/d/d460-w OLD_FILES+=usr/share/terminfo/d/d461 OLD_FILES+=usr/share/terminfo/d/d461-7b OLD_FILES+=usr/share/terminfo/d/d461-7b-w OLD_FILES+=usr/share/terminfo/d/d461-dg OLD_FILES+=usr/share/terminfo/d/d461-w OLD_FILES+=usr/share/terminfo/d/d462+ OLD_FILES+=usr/share/terminfo/d/d462+25 OLD_FILES+=usr/share/terminfo/d/d462+dg OLD_FILES+=usr/share/terminfo/d/d462+s OLD_FILES+=usr/share/terminfo/d/d462+sr OLD_FILES+=usr/share/terminfo/d/d462+w OLD_FILES+=usr/share/terminfo/d/d462-dg OLD_FILES+=usr/share/terminfo/d/d462-unix OLD_FILES+=usr/share/terminfo/d/d462-unix-25 OLD_FILES+=usr/share/terminfo/d/d462-unix-s OLD_FILES+=usr/share/terminfo/d/d462-unix-sr OLD_FILES+=usr/share/terminfo/d/d462-unix-w OLD_FILES+=usr/share/terminfo/d/d462e-dg OLD_FILES+=usr/share/terminfo/d/d463-dg OLD_FILES+=usr/share/terminfo/d/d463-unix OLD_FILES+=usr/share/terminfo/d/d463-unix-25 OLD_FILES+=usr/share/terminfo/d/d463-unix-s OLD_FILES+=usr/share/terminfo/d/d463-unix-sr OLD_FILES+=usr/share/terminfo/d/d463-unix-w OLD_FILES+=usr/share/terminfo/d/d464-unix OLD_FILES+=usr/share/terminfo/d/d464-unix-25 OLD_FILES+=usr/share/terminfo/d/d464-unix-s OLD_FILES+=usr/share/terminfo/d/d464-unix-sr OLD_FILES+=usr/share/terminfo/d/d464-unix-w OLD_FILES+=usr/share/terminfo/d/d470 OLD_FILES+=usr/share/terminfo/d/d470-7b OLD_FILES+=usr/share/terminfo/d/d470-dg OLD_FILES+=usr/share/terminfo/d/d470c OLD_FILES+=usr/share/terminfo/d/d470c-7b OLD_FILES+=usr/share/terminfo/d/d470c-dg OLD_FILES+=usr/share/terminfo/d/d555 OLD_FILES+=usr/share/terminfo/d/d555-7b OLD_FILES+=usr/share/terminfo/d/d555-7b-w OLD_FILES+=usr/share/terminfo/d/d555-dg OLD_FILES+=usr/share/terminfo/d/d555-w OLD_FILES+=usr/share/terminfo/d/d577 OLD_FILES+=usr/share/terminfo/d/d577-7b OLD_FILES+=usr/share/terminfo/d/d577-7b-w OLD_FILES+=usr/share/terminfo/d/d577-dg OLD_FILES+=usr/share/terminfo/d/d577-w OLD_FILES+=usr/share/terminfo/d/d578 OLD_FILES+=usr/share/terminfo/d/d578-7b OLD_FILES+=usr/share/terminfo/d/d578-dg OLD_FILES+=usr/share/terminfo/d/d80 OLD_FILES+=usr/share/terminfo/d/d800 OLD_FILES+=usr/share/terminfo/d/darwin OLD_FILES+=usr/share/terminfo/d/darwin-100x37 OLD_FILES+=usr/share/terminfo/d/darwin-100x37-m OLD_FILES+=usr/share/terminfo/d/darwin-112x37 OLD_FILES+=usr/share/terminfo/d/darwin-112x37-m OLD_FILES+=usr/share/terminfo/d/darwin-128x40 OLD_FILES+=usr/share/terminfo/d/darwin-128x40-m OLD_FILES+=usr/share/terminfo/d/darwin-128x48 OLD_FILES+=usr/share/terminfo/d/darwin-128x48-m OLD_FILES+=usr/share/terminfo/d/darwin-144x48 OLD_FILES+=usr/share/terminfo/d/darwin-144x48-m OLD_FILES+=usr/share/terminfo/d/darwin-160x64 OLD_FILES+=usr/share/terminfo/d/darwin-160x64-m OLD_FILES+=usr/share/terminfo/d/darwin-200x64 OLD_FILES+=usr/share/terminfo/d/darwin-200x64-m OLD_FILES+=usr/share/terminfo/d/darwin-200x75 OLD_FILES+=usr/share/terminfo/d/darwin-200x75-m OLD_FILES+=usr/share/terminfo/d/darwin-256x96 OLD_FILES+=usr/share/terminfo/d/darwin-256x96-m OLD_FILES+=usr/share/terminfo/d/darwin-80x25 OLD_FILES+=usr/share/terminfo/d/darwin-80x25-m OLD_FILES+=usr/share/terminfo/d/darwin-80x30 OLD_FILES+=usr/share/terminfo/d/darwin-80x30-m OLD_FILES+=usr/share/terminfo/d/darwin-90x30 OLD_FILES+=usr/share/terminfo/d/darwin-90x30-m OLD_FILES+=usr/share/terminfo/d/darwin-b OLD_FILES+=usr/share/terminfo/d/darwin-f OLD_FILES+=usr/share/terminfo/d/darwin-f2 OLD_FILES+=usr/share/terminfo/d/darwin-m OLD_FILES+=usr/share/terminfo/d/darwin-m-b OLD_FILES+=usr/share/terminfo/d/darwin-m-f OLD_FILES+=usr/share/terminfo/d/darwin-m-f2 OLD_FILES+=usr/share/terminfo/d/datagraphix OLD_FILES+=usr/share/terminfo/d/datamedia2500 OLD_FILES+=usr/share/terminfo/d/datapoint OLD_FILES+=usr/share/terminfo/d/dataspeed40 OLD_FILES+=usr/share/terminfo/d/dd5000 OLD_FILES+=usr/share/terminfo/d/ddr OLD_FILES+=usr/share/terminfo/d/ddr3180 OLD_FILES+=usr/share/terminfo/d/dec+pp OLD_FILES+=usr/share/terminfo/d/dec+sl OLD_FILES+=usr/share/terminfo/d/dec-vt100 OLD_FILES+=usr/share/terminfo/d/dec-vt220 OLD_FILES+=usr/share/terminfo/d/dec-vt330 OLD_FILES+=usr/share/terminfo/d/dec-vt340 OLD_FILES+=usr/share/terminfo/d/dec-vt400 OLD_FILES+=usr/share/terminfo/d/decansi OLD_FILES+=usr/share/terminfo/d/decpro OLD_FILES+=usr/share/terminfo/d/decwriter OLD_FILES+=usr/share/terminfo/d/delta OLD_FILES+=usr/share/terminfo/d/dg+ccc OLD_FILES+=usr/share/terminfo/d/dg+color OLD_FILES+=usr/share/terminfo/d/dg+color8 OLD_FILES+=usr/share/terminfo/d/dg+fixed OLD_FILES+=usr/share/terminfo/d/dg-ansi OLD_FILES+=usr/share/terminfo/d/dg-generic OLD_FILES+=usr/share/terminfo/d/dg100 OLD_FILES+=usr/share/terminfo/d/dg200 OLD_FILES+=usr/share/terminfo/d/dg210 OLD_FILES+=usr/share/terminfo/d/dg211 OLD_FILES+=usr/share/terminfo/d/dg450 OLD_FILES+=usr/share/terminfo/d/dg460-ansi OLD_FILES+=usr/share/terminfo/d/dg6053 OLD_FILES+=usr/share/terminfo/d/dg6053-old OLD_FILES+=usr/share/terminfo/d/dg605x OLD_FILES+=usr/share/terminfo/d/dg6134 OLD_FILES+=usr/share/terminfo/d/dgkeys+11 OLD_FILES+=usr/share/terminfo/d/dgkeys+15 OLD_FILES+=usr/share/terminfo/d/dgkeys+7b OLD_FILES+=usr/share/terminfo/d/dgkeys+8b OLD_FILES+=usr/share/terminfo/d/dgmode+color OLD_FILES+=usr/share/terminfo/d/dgmode+color8 OLD_FILES+=usr/share/terminfo/d/dgunix+ccc OLD_FILES+=usr/share/terminfo/d/dgunix+fixed OLD_FILES+=usr/share/terminfo/d/diablo OLD_FILES+=usr/share/terminfo/d/diablo-lm OLD_FILES+=usr/share/terminfo/d/diablo1620 OLD_FILES+=usr/share/terminfo/d/diablo1620-m8 OLD_FILES+=usr/share/terminfo/d/diablo1640 OLD_FILES+=usr/share/terminfo/d/diablo1640-lm OLD_FILES+=usr/share/terminfo/d/diablo1640-m8 OLD_FILES+=usr/share/terminfo/d/diablo1720 OLD_FILES+=usr/share/terminfo/d/diablo1730 OLD_FILES+=usr/share/terminfo/d/diablo1740 OLD_FILES+=usr/share/terminfo/d/diablo1740-lm OLD_FILES+=usr/share/terminfo/d/diablo450 OLD_FILES+=usr/share/terminfo/d/diablo630 OLD_FILES+=usr/share/terminfo/d/dialogue OLD_FILES+=usr/share/terminfo/d/dialogue80 OLD_FILES+=usr/share/terminfo/d/digilog OLD_FILES+=usr/share/terminfo/d/djgpp OLD_FILES+=usr/share/terminfo/d/djgpp203 OLD_FILES+=usr/share/terminfo/d/djgpp204 OLD_FILES+=usr/share/terminfo/d/dku7003 OLD_FILES+=usr/share/terminfo/d/dku7003-dumb OLD_FILES+=usr/share/terminfo/d/dku7102 OLD_FILES+=usr/share/terminfo/d/dku7102-old OLD_FILES+=usr/share/terminfo/d/dku7102-sna OLD_FILES+=usr/share/terminfo/d/dku7103-sna OLD_FILES+=usr/share/terminfo/d/dku7202 OLD_FILES+=usr/share/terminfo/d/dm1520 OLD_FILES+=usr/share/terminfo/d/dm1521 OLD_FILES+=usr/share/terminfo/d/dm2500 OLD_FILES+=usr/share/terminfo/d/dm3025 OLD_FILES+=usr/share/terminfo/d/dm3045 OLD_FILES+=usr/share/terminfo/d/dm80 OLD_FILES+=usr/share/terminfo/d/dm80w OLD_FILES+=usr/share/terminfo/d/dmchat OLD_FILES+=usr/share/terminfo/d/dmd OLD_FILES+=usr/share/terminfo/d/dmd-24 OLD_FILES+=usr/share/terminfo/d/dmd-34 OLD_FILES+=usr/share/terminfo/d/dmd1 OLD_FILES+=usr/share/terminfo/d/dmdt80 OLD_FILES+=usr/share/terminfo/d/dmdt80w OLD_FILES+=usr/share/terminfo/d/dmterm OLD_FILES+=usr/share/terminfo/d/domterm OLD_FILES+=usr/share/terminfo/d/dp3360 OLD_FILES+=usr/share/terminfo/d/dp8242 OLD_FILES+=usr/share/terminfo/d/ds40 OLD_FILES+=usr/share/terminfo/d/ds40-2 OLD_FILES+=usr/share/terminfo/d/dt-100 OLD_FILES+=usr/share/terminfo/d/dt-100w OLD_FILES+=usr/share/terminfo/d/dt100 OLD_FILES+=usr/share/terminfo/d/dt100w OLD_FILES+=usr/share/terminfo/d/dt110 OLD_FILES+=usr/share/terminfo/d/dt80 OLD_FILES+=usr/share/terminfo/d/dt80-sas OLD_FILES+=usr/share/terminfo/d/dt80w OLD_FILES+=usr/share/terminfo/d/dtc300s OLD_FILES+=usr/share/terminfo/d/dtc382 OLD_FILES+=usr/share/terminfo/d/dtterm OLD_FILES+=usr/share/terminfo/d/dumb OLD_FILES+=usr/share/terminfo/d/dumb-emacs-ansi OLD_FILES+=usr/share/terminfo/d/dvtm OLD_FILES+=usr/share/terminfo/d/dvtm-256color OLD_FILES+=usr/share/terminfo/d/dw OLD_FILES+=usr/share/terminfo/d/dw1 OLD_FILES+=usr/share/terminfo/d/dw2 OLD_FILES+=usr/share/terminfo/d/dw3 OLD_FILES+=usr/share/terminfo/d/dw4 OLD_FILES+=usr/share/terminfo/d/dwk OLD_FILES+=usr/share/terminfo/d/dwk-vt OLD_DIRS+=usr/share/terminfo/d/ OLD_FILES+=usr/share/terminfo/e/ecma+color OLD_FILES+=usr/share/terminfo/e/ecma+index OLD_FILES+=usr/share/terminfo/e/ecma+italics OLD_FILES+=usr/share/terminfo/e/ecma+sgr OLD_FILES+=usr/share/terminfo/e/ecma+strikeout OLD_FILES+=usr/share/terminfo/e/elks OLD_FILES+=usr/share/terminfo/e/elks-ansi OLD_FILES+=usr/share/terminfo/e/elks-glasstty OLD_FILES+=usr/share/terminfo/e/elks-vt52 OLD_FILES+=usr/share/terminfo/e/emots OLD_FILES+=usr/share/terminfo/e/emu OLD_FILES+=usr/share/terminfo/e/emu-220 OLD_FILES+=usr/share/terminfo/e/emx-base OLD_FILES+=usr/share/terminfo/e/env230 OLD_FILES+=usr/share/terminfo/e/envision230 OLD_FILES+=usr/share/terminfo/e/ep40 OLD_FILES+=usr/share/terminfo/e/ep4000 OLD_FILES+=usr/share/terminfo/e/ep4080 OLD_FILES+=usr/share/terminfo/e/ep48 OLD_FILES+=usr/share/terminfo/e/ergo4000 OLD_FILES+=usr/share/terminfo/e/esprit OLD_FILES+=usr/share/terminfo/e/esprit-am OLD_FILES+=usr/share/terminfo/e/eterm OLD_FILES+=usr/share/terminfo/e/eterm-color OLD_FILES+=usr/share/terminfo/e/ex155 OLD_FILES+=usr/share/terminfo/e/excel62 OLD_FILES+=usr/share/terminfo/e/excel62-rv OLD_FILES+=usr/share/terminfo/e/excel62-w OLD_FILES+=usr/share/terminfo/e/excel64 OLD_FILES+=usr/share/terminfo/e/excel64-rv OLD_FILES+=usr/share/terminfo/e/excel64-w OLD_FILES+=usr/share/terminfo/e/exec80 OLD_DIRS+=usr/share/terminfo/e/ OLD_FILES+=usr/share/terminfo/f/f100 OLD_FILES+=usr/share/terminfo/f/f100-rv OLD_FILES+=usr/share/terminfo/f/f110 OLD_FILES+=usr/share/terminfo/f/f110-14 OLD_FILES+=usr/share/terminfo/f/f110-14w OLD_FILES+=usr/share/terminfo/f/f110-w OLD_FILES+=usr/share/terminfo/f/f1720 OLD_FILES+=usr/share/terminfo/f/f1720a OLD_FILES+=usr/share/terminfo/f/f200 OLD_FILES+=usr/share/terminfo/f/f200-w OLD_FILES+=usr/share/terminfo/f/f200vi OLD_FILES+=usr/share/terminfo/f/f200vi-w OLD_FILES+=usr/share/terminfo/f/falco OLD_FILES+=usr/share/terminfo/f/falco-p OLD_FILES+=usr/share/terminfo/f/fbterm OLD_FILES+=usr/share/terminfo/f/fenix OLD_FILES+=usr/share/terminfo/f/fenixw OLD_FILES+=usr/share/terminfo/f/fixterm OLD_FILES+=usr/share/terminfo/f/fortune OLD_FILES+=usr/share/terminfo/f/fos OLD_FILES+=usr/share/terminfo/f/fox OLD_FILES+=usr/share/terminfo/f/freedom OLD_FILES+=usr/share/terminfo/f/freedom-rv OLD_FILES+=usr/share/terminfo/f/freedom100 OLD_FILES+=usr/share/terminfo/f/freedom110 OLD_FILES+=usr/share/terminfo/f/freedom200 OLD_DIRS+=usr/share/terminfo/f/ OLD_FILES+=usr/share/terminfo/g/gator OLD_FILES+=usr/share/terminfo/g/gator-52 OLD_FILES+=usr/share/terminfo/g/gator-52t OLD_FILES+=usr/share/terminfo/g/gator-t OLD_FILES+=usr/share/terminfo/g/gigi OLD_FILES+=usr/share/terminfo/g/glasstty OLD_FILES+=usr/share/terminfo/g/gnome OLD_FILES+=usr/share/terminfo/g/gnome+pcfkeys OLD_FILES+=usr/share/terminfo/g/gnome-2007 OLD_FILES+=usr/share/terminfo/g/gnome-2008 OLD_FILES+=usr/share/terminfo/g/gnome-2012 OLD_FILES+=usr/share/terminfo/g/gnome-256color OLD_FILES+=usr/share/terminfo/g/gnome-fc5 OLD_FILES+=usr/share/terminfo/g/gnome-rh62 OLD_FILES+=usr/share/terminfo/g/gnome-rh72 OLD_FILES+=usr/share/terminfo/g/gnome-rh80 OLD_FILES+=usr/share/terminfo/g/gnome-rh90 OLD_FILES+=usr/share/terminfo/g/go-225 OLD_FILES+=usr/share/terminfo/g/go140 OLD_FILES+=usr/share/terminfo/g/go140w OLD_FILES+=usr/share/terminfo/g/go225 OLD_FILES+=usr/share/terminfo/g/graphos OLD_FILES+=usr/share/terminfo/g/graphos-30 OLD_FILES+=usr/share/terminfo/g/gs5430 OLD_FILES+=usr/share/terminfo/g/gs5430-22 OLD_FILES+=usr/share/terminfo/g/gs5430-24 OLD_FILES+=usr/share/terminfo/g/gs6300 OLD_FILES+=usr/share/terminfo/g/gsi OLD_FILES+=usr/share/terminfo/g/gt100 OLD_FILES+=usr/share/terminfo/g/gt100a OLD_FILES+=usr/share/terminfo/g/gt40 OLD_FILES+=usr/share/terminfo/g/gt42 OLD_FILES+=usr/share/terminfo/g/guru OLD_FILES+=usr/share/terminfo/g/guru+rv OLD_FILES+=usr/share/terminfo/g/guru+s OLD_FILES+=usr/share/terminfo/g/guru+unk OLD_FILES+=usr/share/terminfo/g/guru-24 OLD_FILES+=usr/share/terminfo/g/guru-33 OLD_FILES+=usr/share/terminfo/g/guru-33-rv OLD_FILES+=usr/share/terminfo/g/guru-33-s OLD_FILES+=usr/share/terminfo/g/guru-44 OLD_FILES+=usr/share/terminfo/g/guru-44-s OLD_FILES+=usr/share/terminfo/g/guru-76 OLD_FILES+=usr/share/terminfo/g/guru-76-lp OLD_FILES+=usr/share/terminfo/g/guru-76-s OLD_FILES+=usr/share/terminfo/g/guru-76-w OLD_FILES+=usr/share/terminfo/g/guru-76-w-s OLD_FILES+=usr/share/terminfo/g/guru-76-wm OLD_FILES+=usr/share/terminfo/g/guru-lp OLD_FILES+=usr/share/terminfo/g/guru-nctxt OLD_FILES+=usr/share/terminfo/g/guru-rv OLD_FILES+=usr/share/terminfo/g/guru-s OLD_DIRS+=usr/share/terminfo/g/ OLD_FILES+=usr/share/terminfo/h/h-100 OLD_FILES+=usr/share/terminfo/h/h-100bw OLD_FILES+=usr/share/terminfo/h/h100 OLD_FILES+=usr/share/terminfo/h/h100bw OLD_FILES+=usr/share/terminfo/h/h19 OLD_FILES+=usr/share/terminfo/h/h19-a OLD_FILES+=usr/share/terminfo/h/h19-b OLD_FILES+=usr/share/terminfo/h/h19-bs OLD_FILES+=usr/share/terminfo/h/h19-g OLD_FILES+=usr/share/terminfo/h/h19-smul OLD_FILES+=usr/share/terminfo/h/h19-u OLD_FILES+=usr/share/terminfo/h/h19-us OLD_FILES+=usr/share/terminfo/h/h19a OLD_FILES+=usr/share/terminfo/h/h19g OLD_FILES+=usr/share/terminfo/h/h19k OLD_FILES+=usr/share/terminfo/h/h19kermit OLD_FILES+=usr/share/terminfo/h/h19us OLD_FILES+=usr/share/terminfo/h/h29a-kc-bc OLD_FILES+=usr/share/terminfo/h/h29a-kc-uc OLD_FILES+=usr/share/terminfo/h/h29a-nkc-bc OLD_FILES+=usr/share/terminfo/h/h29a-nkc-uc OLD_FILES+=usr/share/terminfo/h/h80 OLD_FILES+=usr/share/terminfo/h/ha8675 OLD_FILES+=usr/share/terminfo/h/ha8686 OLD_FILES+=usr/share/terminfo/h/hazel OLD_FILES+=usr/share/terminfo/h/hds200 OLD_FILES+=usr/share/terminfo/h/he80 OLD_FILES+=usr/share/terminfo/h/heath OLD_FILES+=usr/share/terminfo/h/heath-19 OLD_FILES+=usr/share/terminfo/h/heath-ansi OLD_FILES+=usr/share/terminfo/h/heathkit OLD_FILES+=usr/share/terminfo/h/heathkit-a OLD_FILES+=usr/share/terminfo/h/hft OLD_FILES+=usr/share/terminfo/h/hft-c OLD_FILES+=usr/share/terminfo/h/hft-c-old OLD_FILES+=usr/share/terminfo/h/hft-old OLD_FILES+=usr/share/terminfo/h/hirez100 OLD_FILES+=usr/share/terminfo/h/hirez100-w OLD_FILES+=usr/share/terminfo/h/hmod1 OLD_FILES+=usr/share/terminfo/h/hp OLD_FILES+=usr/share/terminfo/h/hp+arrows OLD_FILES+=usr/share/terminfo/h/hp+color OLD_FILES+=usr/share/terminfo/h/hp+labels OLD_FILES+=usr/share/terminfo/h/hp+pfk+arrows OLD_FILES+=usr/share/terminfo/h/hp+pfk+cr OLD_FILES+=usr/share/terminfo/h/hp+pfk-cr OLD_FILES+=usr/share/terminfo/h/hp+printer OLD_FILES+=usr/share/terminfo/h/hp110 OLD_FILES+=usr/share/terminfo/h/hp150 OLD_FILES+=usr/share/terminfo/h/hp2 OLD_FILES+=usr/share/terminfo/h/hp236 OLD_FILES+=usr/share/terminfo/h/hp2382 OLD_FILES+=usr/share/terminfo/h/hp2382a OLD_FILES+=usr/share/terminfo/h/hp2392 OLD_FILES+=usr/share/terminfo/h/hp2397 OLD_FILES+=usr/share/terminfo/h/hp2397a OLD_FILES+=usr/share/terminfo/h/hp2621 OLD_FILES+=usr/share/terminfo/h/hp2621-48 OLD_FILES+=usr/share/terminfo/h/hp2621-a OLD_FILES+=usr/share/terminfo/h/hp2621-ba OLD_FILES+=usr/share/terminfo/h/hp2621-fl OLD_FILES+=usr/share/terminfo/h/hp2621-k45 OLD_FILES+=usr/share/terminfo/h/hp2621-nl OLD_FILES+=usr/share/terminfo/h/hp2621-nt OLD_FILES+=usr/share/terminfo/h/hp2621-wl OLD_FILES+=usr/share/terminfo/h/hp2621A OLD_FILES+=usr/share/terminfo/h/hp2621a OLD_FILES+=usr/share/terminfo/h/hp2621a-a OLD_FILES+=usr/share/terminfo/h/hp2621b OLD_FILES+=usr/share/terminfo/h/hp2621b-kx OLD_FILES+=usr/share/terminfo/h/hp2621b-kx-p OLD_FILES+=usr/share/terminfo/h/hp2621b-p OLD_FILES+=usr/share/terminfo/h/hp2621k45 OLD_FILES+=usr/share/terminfo/h/hp2621p OLD_FILES+=usr/share/terminfo/h/hp2621p-a OLD_FILES+=usr/share/terminfo/h/hp2622 OLD_FILES+=usr/share/terminfo/h/hp2622a OLD_FILES+=usr/share/terminfo/h/hp2623 OLD_FILES+=usr/share/terminfo/h/hp2623a OLD_FILES+=usr/share/terminfo/h/hp2624 OLD_FILES+=usr/share/terminfo/h/hp2624-10p OLD_FILES+=usr/share/terminfo/h/hp2624a OLD_FILES+=usr/share/terminfo/h/hp2624a-10p OLD_FILES+=usr/share/terminfo/h/hp2624b OLD_FILES+=usr/share/terminfo/h/hp2624b-10p OLD_FILES+=usr/share/terminfo/h/hp2624b-10p-p OLD_FILES+=usr/share/terminfo/h/hp2624b-4p OLD_FILES+=usr/share/terminfo/h/hp2624b-4p-p OLD_FILES+=usr/share/terminfo/h/hp2624b-p OLD_FILES+=usr/share/terminfo/h/hp2626 OLD_FILES+=usr/share/terminfo/h/hp2626-12 OLD_FILES+=usr/share/terminfo/h/hp2626-12-s OLD_FILES+=usr/share/terminfo/h/hp2626-12x40 OLD_FILES+=usr/share/terminfo/h/hp2626-ns OLD_FILES+=usr/share/terminfo/h/hp2626-s OLD_FILES+=usr/share/terminfo/h/hp2626-x40 OLD_FILES+=usr/share/terminfo/h/hp2626a OLD_FILES+=usr/share/terminfo/h/hp2626p OLD_FILES+=usr/share/terminfo/h/hp2627a OLD_FILES+=usr/share/terminfo/h/hp2627a-rev OLD_FILES+=usr/share/terminfo/h/hp2627c OLD_FILES+=usr/share/terminfo/h/hp262x OLD_FILES+=usr/share/terminfo/h/hp2640a OLD_FILES+=usr/share/terminfo/h/hp2640b OLD_FILES+=usr/share/terminfo/h/hp2641a OLD_FILES+=usr/share/terminfo/h/hp2644a OLD_FILES+=usr/share/terminfo/h/hp2645 OLD_FILES+=usr/share/terminfo/h/hp2645a OLD_FILES+=usr/share/terminfo/h/hp2647a OLD_FILES+=usr/share/terminfo/h/hp2648 OLD_FILES+=usr/share/terminfo/h/hp2648a OLD_FILES+=usr/share/terminfo/h/hp300h OLD_FILES+=usr/share/terminfo/h/hp45 OLD_FILES+=usr/share/terminfo/h/hp700 OLD_FILES+=usr/share/terminfo/h/hp700-wy OLD_FILES+=usr/share/terminfo/h/hp70092 OLD_FILES+=usr/share/terminfo/h/hp70092A OLD_FILES+=usr/share/terminfo/h/hp70092a OLD_FILES+=usr/share/terminfo/h/hp9837 OLD_FILES+=usr/share/terminfo/h/hp9845 OLD_FILES+=usr/share/terminfo/h/hp98550 OLD_FILES+=usr/share/terminfo/h/hp98550a OLD_FILES+=usr/share/terminfo/h/hp98720 OLD_FILES+=usr/share/terminfo/h/hp98721 OLD_FILES+=usr/share/terminfo/h/hpansi OLD_FILES+=usr/share/terminfo/h/hpex OLD_FILES+=usr/share/terminfo/h/hpex2 OLD_FILES+=usr/share/terminfo/h/hpgeneric OLD_FILES+=usr/share/terminfo/h/hpsub OLD_FILES+=usr/share/terminfo/h/hpterm OLD_FILES+=usr/share/terminfo/h/hpterm-color OLD_FILES+=usr/share/terminfo/h/htx11 OLD_FILES+=usr/share/terminfo/h/hurd OLD_FILES+=usr/share/terminfo/h/hz1000 OLD_FILES+=usr/share/terminfo/h/hz1420 OLD_FILES+=usr/share/terminfo/h/hz1500 OLD_FILES+=usr/share/terminfo/h/hz1510 OLD_FILES+=usr/share/terminfo/h/hz1520 OLD_FILES+=usr/share/terminfo/h/hz1520-noesc OLD_FILES+=usr/share/terminfo/h/hz1552 OLD_FILES+=usr/share/terminfo/h/hz1552-rv OLD_FILES+=usr/share/terminfo/h/hz2000 OLD_DIRS+=usr/share/terminfo/h/ OLD_FILES+=usr/share/terminfo/i/i100 OLD_FILES+=usr/share/terminfo/i/i3101 OLD_FILES+=usr/share/terminfo/i/i3164 OLD_FILES+=usr/share/terminfo/i/i400 OLD_FILES+=usr/share/terminfo/i/iTerm.app OLD_FILES+=usr/share/terminfo/i/iTerm2.app OLD_FILES+=usr/share/terminfo/i/ibcs2 OLD_FILES+=usr/share/terminfo/i/ibm+16color OLD_FILES+=usr/share/terminfo/i/ibm+color OLD_FILES+=usr/share/terminfo/i/ibm-apl OLD_FILES+=usr/share/terminfo/i/ibm-pc OLD_FILES+=usr/share/terminfo/i/ibm-system1 OLD_FILES+=usr/share/terminfo/i/ibm3101 OLD_FILES+=usr/share/terminfo/i/ibm3151 OLD_FILES+=usr/share/terminfo/i/ibm3161 OLD_FILES+=usr/share/terminfo/i/ibm3161-C OLD_FILES+=usr/share/terminfo/i/ibm3162 OLD_FILES+=usr/share/terminfo/i/ibm3163 OLD_FILES+=usr/share/terminfo/i/ibm3164 OLD_FILES+=usr/share/terminfo/i/ibm327x OLD_FILES+=usr/share/terminfo/i/ibm5051 OLD_FILES+=usr/share/terminfo/i/ibm5081 OLD_FILES+=usr/share/terminfo/i/ibm5081-c OLD_FILES+=usr/share/terminfo/i/ibm5151 OLD_FILES+=usr/share/terminfo/i/ibm5154 OLD_FILES+=usr/share/terminfo/i/ibm5154-c OLD_FILES+=usr/share/terminfo/i/ibm6153 OLD_FILES+=usr/share/terminfo/i/ibm6153-40 OLD_FILES+=usr/share/terminfo/i/ibm6153-90 OLD_FILES+=usr/share/terminfo/i/ibm6154 OLD_FILES+=usr/share/terminfo/i/ibm6154-c OLD_FILES+=usr/share/terminfo/i/ibm6155 OLD_FILES+=usr/share/terminfo/i/ibm8503 OLD_FILES+=usr/share/terminfo/i/ibm8507 OLD_FILES+=usr/share/terminfo/i/ibm8512 OLD_FILES+=usr/share/terminfo/i/ibm8513 OLD_FILES+=usr/share/terminfo/i/ibm8514 OLD_FILES+=usr/share/terminfo/i/ibm8514-c OLD_FILES+=usr/share/terminfo/i/ibm8604 OLD_FILES+=usr/share/terminfo/i/ibmaed OLD_FILES+=usr/share/terminfo/i/ibmapa16 OLD_FILES+=usr/share/terminfo/i/ibmapa8 OLD_FILES+=usr/share/terminfo/i/ibmapa8c OLD_FILES+=usr/share/terminfo/i/ibmapa8c-c OLD_FILES+=usr/share/terminfo/i/ibmega OLD_FILES+=usr/share/terminfo/i/ibmega-c OLD_FILES+=usr/share/terminfo/i/ibmmono OLD_FILES+=usr/share/terminfo/i/ibmmpel-c OLD_FILES+=usr/share/terminfo/i/ibmpc OLD_FILES+=usr/share/terminfo/i/ibmpc3 OLD_FILES+=usr/share/terminfo/i/ibmpc3r OLD_FILES+=usr/share/terminfo/i/ibmpc3r-mono OLD_FILES+=usr/share/terminfo/i/ibmpcx OLD_FILES+=usr/share/terminfo/i/ibmvga OLD_FILES+=usr/share/terminfo/i/ibmvga-c OLD_FILES+=usr/share/terminfo/i/ibmx OLD_FILES+=usr/share/terminfo/i/icl6402 OLD_FILES+=usr/share/terminfo/i/icl6404 OLD_FILES+=usr/share/terminfo/i/icl6404-w OLD_FILES+=usr/share/terminfo/i/ifmr OLD_FILES+=usr/share/terminfo/i/ims-ansi OLD_FILES+=usr/share/terminfo/i/ims950 OLD_FILES+=usr/share/terminfo/i/ims950-b OLD_FILES+=usr/share/terminfo/i/ims950-rv OLD_FILES+=usr/share/terminfo/i/infoton OLD_FILES+=usr/share/terminfo/i/interix OLD_FILES+=usr/share/terminfo/i/interix-nti OLD_FILES+=usr/share/terminfo/i/intertec OLD_FILES+=usr/share/terminfo/i/intertube OLD_FILES+=usr/share/terminfo/i/intertube2 OLD_FILES+=usr/share/terminfo/i/intext OLD_FILES+=usr/share/terminfo/i/intext2 OLD_FILES+=usr/share/terminfo/i/intextii OLD_FILES+=usr/share/terminfo/i/ips OLD_FILES+=usr/share/terminfo/i/ipsi OLD_FILES+=usr/share/terminfo/i/iq120 OLD_FILES+=usr/share/terminfo/i/iq140 OLD_FILES+=usr/share/terminfo/i/iris-ansi OLD_FILES+=usr/share/terminfo/i/iris-ansi-ap OLD_FILES+=usr/share/terminfo/i/iris-ansi-net OLD_FILES+=usr/share/terminfo/i/iris-color OLD_FILES+=usr/share/terminfo/i/iris40 OLD_FILES+=usr/share/terminfo/i/iterm OLD_FILES+=usr/share/terminfo/i/iterm2 OLD_FILES+=usr/share/terminfo/i/iterm2-direct OLD_DIRS+=usr/share/terminfo/i/ OLD_FILES+=usr/share/terminfo/j/jaixterm OLD_FILES+=usr/share/terminfo/j/jaixterm-m OLD_FILES+=usr/share/terminfo/j/jerq OLD_FILES+=usr/share/terminfo/j/jfbterm OLD_DIRS+=usr/share/terminfo/j/ OLD_FILES+=usr/share/terminfo/k/k45 OLD_FILES+=usr/share/terminfo/k/kaypro OLD_FILES+=usr/share/terminfo/k/kaypro2 OLD_FILES+=usr/share/terminfo/k/kds6402 OLD_FILES+=usr/share/terminfo/k/kds7372 OLD_FILES+=usr/share/terminfo/k/kds7372-w OLD_FILES+=usr/share/terminfo/k/kermit OLD_FILES+=usr/share/terminfo/k/kermit-am OLD_FILES+=usr/share/terminfo/k/kitty OLD_FILES+=usr/share/terminfo/k/kitty+common OLD_FILES+=usr/share/terminfo/k/kitty-direct OLD_FILES+=usr/share/terminfo/k/klone+acs OLD_FILES+=usr/share/terminfo/k/klone+color OLD_FILES+=usr/share/terminfo/k/klone+koi8acs OLD_FILES+=usr/share/terminfo/k/klone+sgr OLD_FILES+=usr/share/terminfo/k/klone+sgr-dumb OLD_FILES+=usr/share/terminfo/k/klone+sgr8 OLD_FILES+=usr/share/terminfo/k/kon OLD_FILES+=usr/share/terminfo/k/kon2 OLD_FILES+=usr/share/terminfo/k/konsole OLD_FILES+=usr/share/terminfo/k/konsole+pcfkeys OLD_FILES+=usr/share/terminfo/k/konsole-16color OLD_FILES+=usr/share/terminfo/k/konsole-256color OLD_FILES+=usr/share/terminfo/k/konsole-base OLD_FILES+=usr/share/terminfo/k/konsole-direct OLD_FILES+=usr/share/terminfo/k/konsole-linux OLD_FILES+=usr/share/terminfo/k/konsole-solaris OLD_FILES+=usr/share/terminfo/k/konsole-vt100 OLD_FILES+=usr/share/terminfo/k/konsole-vt420pc OLD_FILES+=usr/share/terminfo/k/konsole-xf3x OLD_FILES+=usr/share/terminfo/k/konsole-xf4x OLD_FILES+=usr/share/terminfo/k/kt7 OLD_FILES+=usr/share/terminfo/k/kt7ix OLD_FILES+=usr/share/terminfo/k/kterm OLD_FILES+=usr/share/terminfo/k/kterm-co OLD_FILES+=usr/share/terminfo/k/kterm-color OLD_FILES+=usr/share/terminfo/k/ktm OLD_FILES+=usr/share/terminfo/k/kvt OLD_DIRS+=usr/share/terminfo/k/ OLD_FILES+=usr/share/terminfo/l/la120 OLD_FILES+=usr/share/terminfo/l/layer OLD_FILES+=usr/share/terminfo/l/lft OLD_FILES+=usr/share/terminfo/l/lft-pc850 OLD_FILES+=usr/share/terminfo/l/linux OLD_FILES+=usr/share/terminfo/l/linux+decid OLD_FILES+=usr/share/terminfo/l/linux+sfkeys OLD_FILES+=usr/share/terminfo/l/linux-16color OLD_FILES+=usr/share/terminfo/l/linux-basic OLD_FILES+=usr/share/terminfo/l/linux-c OLD_FILES+=usr/share/terminfo/l/linux-c-nc OLD_FILES+=usr/share/terminfo/l/linux-koi8 OLD_FILES+=usr/share/terminfo/l/linux-koi8r OLD_FILES+=usr/share/terminfo/l/linux-lat OLD_FILES+=usr/share/terminfo/l/linux-m OLD_FILES+=usr/share/terminfo/l/linux-m1 OLD_FILES+=usr/share/terminfo/l/linux-m1b OLD_FILES+=usr/share/terminfo/l/linux-m2 OLD_FILES+=usr/share/terminfo/l/linux-nic OLD_FILES+=usr/share/terminfo/l/linux-s OLD_FILES+=usr/share/terminfo/l/linux-vt OLD_FILES+=usr/share/terminfo/l/linux2.2 OLD_FILES+=usr/share/terminfo/l/linux2.6 OLD_FILES+=usr/share/terminfo/l/linux2.6.26 OLD_FILES+=usr/share/terminfo/l/linux3.0 OLD_FILES+=usr/share/terminfo/l/lisa OLD_FILES+=usr/share/terminfo/l/lisaterm OLD_FILES+=usr/share/terminfo/l/lisaterm-w OLD_FILES+=usr/share/terminfo/l/liswb OLD_FILES+=usr/share/terminfo/l/ln03 OLD_FILES+=usr/share/terminfo/l/ln03-w OLD_FILES+=usr/share/terminfo/l/lpr OLD_FILES+=usr/share/terminfo/l/luna OLD_FILES+=usr/share/terminfo/l/luna68k OLD_DIRS+=usr/share/terminfo/l/ OLD_FILES+=usr/share/terminfo/m/m2-nam OLD_FILES+=usr/share/terminfo/m/mac OLD_FILES+=usr/share/terminfo/m/mac-w OLD_FILES+=usr/share/terminfo/m/mach OLD_FILES+=usr/share/terminfo/m/mach-bold OLD_FILES+=usr/share/terminfo/m/mach-color OLD_FILES+=usr/share/terminfo/m/mach-gnu OLD_FILES+=usr/share/terminfo/m/mach-gnu-color OLD_FILES+=usr/share/terminfo/m/macintosh OLD_FILES+=usr/share/terminfo/m/macterminal-w OLD_FILES+=usr/share/terminfo/m/mai OLD_FILES+=usr/share/terminfo/m/masscomp OLD_FILES+=usr/share/terminfo/m/masscomp1 OLD_FILES+=usr/share/terminfo/m/masscomp2 OLD_FILES+=usr/share/terminfo/m/mdl110 OLD_FILES+=usr/share/terminfo/m/megatek OLD_FILES+=usr/share/terminfo/m/memhp OLD_FILES+=usr/share/terminfo/m/mgr OLD_FILES+=usr/share/terminfo/m/mgr-linux OLD_FILES+=usr/share/terminfo/m/mgr-sun OLD_FILES+=usr/share/terminfo/m/mgt OLD_FILES+=usr/share/terminfo/m/mgterm OLD_FILES+=usr/share/terminfo/m/microb OLD_FILES+=usr/share/terminfo/m/microbee OLD_FILES+=usr/share/terminfo/m/microterm OLD_FILES+=usr/share/terminfo/m/microterm5 OLD_FILES+=usr/share/terminfo/m/mime OLD_FILES+=usr/share/terminfo/m/mime-3ax OLD_FILES+=usr/share/terminfo/m/mime-fb OLD_FILES+=usr/share/terminfo/m/mime-hb OLD_FILES+=usr/share/terminfo/m/mime1 OLD_FILES+=usr/share/terminfo/m/mime2 OLD_FILES+=usr/share/terminfo/m/mime2a OLD_FILES+=usr/share/terminfo/m/mime2a-s OLD_FILES+=usr/share/terminfo/m/mime2a-v OLD_FILES+=usr/share/terminfo/m/mime314 OLD_FILES+=usr/share/terminfo/m/mime340 OLD_FILES+=usr/share/terminfo/m/mime3a OLD_FILES+=usr/share/terminfo/m/mime3ax OLD_FILES+=usr/share/terminfo/m/mimei OLD_FILES+=usr/share/terminfo/m/mimeii OLD_FILES+=usr/share/terminfo/m/minitel OLD_FILES+=usr/share/terminfo/m/minitel-2 OLD_FILES+=usr/share/terminfo/m/minitel-2-nam OLD_FILES+=usr/share/terminfo/m/minitel1 OLD_FILES+=usr/share/terminfo/m/minitel1-nb OLD_FILES+=usr/share/terminfo/m/minitel12-80 OLD_FILES+=usr/share/terminfo/m/minitel1b OLD_FILES+=usr/share/terminfo/m/minitel1b-80 OLD_FILES+=usr/share/terminfo/m/minitel1b-nb OLD_FILES+=usr/share/terminfo/m/minitel2-80 OLD_FILES+=usr/share/terminfo/m/minix OLD_FILES+=usr/share/terminfo/m/minix-1.5 OLD_FILES+=usr/share/terminfo/m/minix-1.7 OLD_FILES+=usr/share/terminfo/m/minix-3.0 OLD_FILES+=usr/share/terminfo/m/minix-old OLD_FILES+=usr/share/terminfo/m/minix-old-am OLD_FILES+=usr/share/terminfo/m/mintty OLD_FILES+=usr/share/terminfo/m/mintty+common OLD_FILES+=usr/share/terminfo/m/mintty-direct OLD_FILES+=usr/share/terminfo/m/mlterm OLD_FILES+=usr/share/terminfo/m/mlterm+pcfkeys OLD_FILES+=usr/share/terminfo/m/mlterm-256color OLD_FILES+=usr/share/terminfo/m/mlterm-direct OLD_FILES+=usr/share/terminfo/m/mlterm2 OLD_FILES+=usr/share/terminfo/m/mlterm3 OLD_FILES+=usr/share/terminfo/m/mm314 OLD_FILES+=usr/share/terminfo/m/mm340 OLD_FILES+=usr/share/terminfo/m/mod OLD_FILES+=usr/share/terminfo/m/mod24 OLD_FILES+=usr/share/terminfo/m/modgraph OLD_FILES+=usr/share/terminfo/m/modgraph2 OLD_FILES+=usr/share/terminfo/m/modgraph48 OLD_FILES+=usr/share/terminfo/m/mono-emx OLD_FILES+=usr/share/terminfo/m/morphos OLD_FILES+=usr/share/terminfo/m/mouse-sun OLD_FILES+=usr/share/terminfo/m/mrxvt OLD_FILES+=usr/share/terminfo/m/mrxvt-256color OLD_FILES+=usr/share/terminfo/m/ms-terminal OLD_FILES+=usr/share/terminfo/m/ms-vt-utf8 OLD_FILES+=usr/share/terminfo/m/ms-vt100 OLD_FILES+=usr/share/terminfo/m/ms-vt100+ OLD_FILES+=usr/share/terminfo/m/ms-vt100-color OLD_FILES+=usr/share/terminfo/m/msk227 OLD_FILES+=usr/share/terminfo/m/msk22714 OLD_FILES+=usr/share/terminfo/m/msk227am OLD_FILES+=usr/share/terminfo/m/mskermit227 OLD_FILES+=usr/share/terminfo/m/mskermit22714 OLD_FILES+=usr/share/terminfo/m/mskermit227am OLD_FILES+=usr/share/terminfo/m/mt-70 OLD_FILES+=usr/share/terminfo/m/mt4520-rv OLD_FILES+=usr/share/terminfo/m/mt70 OLD_FILES+=usr/share/terminfo/m/mterm OLD_FILES+=usr/share/terminfo/m/mterm-ansi OLD_FILES+=usr/share/terminfo/m/mvterm OLD_DIRS+=usr/share/terminfo/m/ OLD_FILES+=usr/share/terminfo/n/n7900 OLD_FILES+=usr/share/terminfo/n/nansi.sys OLD_FILES+=usr/share/terminfo/n/nansi.sysk OLD_FILES+=usr/share/terminfo/n/nansisys OLD_FILES+=usr/share/terminfo/n/nansisysk OLD_FILES+=usr/share/terminfo/n/ncr160vppp OLD_FILES+=usr/share/terminfo/n/ncr160vpwpp OLD_FILES+=usr/share/terminfo/n/ncr160vt100an OLD_FILES+=usr/share/terminfo/n/ncr160vt100pp OLD_FILES+=usr/share/terminfo/n/ncr160vt100wan OLD_FILES+=usr/share/terminfo/n/ncr160vt100wpp OLD_FILES+=usr/share/terminfo/n/ncr160vt200an OLD_FILES+=usr/share/terminfo/n/ncr160vt200pp OLD_FILES+=usr/share/terminfo/n/ncr160vt200wan OLD_FILES+=usr/share/terminfo/n/ncr160vt200wpp OLD_FILES+=usr/share/terminfo/n/ncr160vt300an OLD_FILES+=usr/share/terminfo/n/ncr160vt300pp OLD_FILES+=usr/share/terminfo/n/ncr160vt300wan OLD_FILES+=usr/share/terminfo/n/ncr160vt300wpp OLD_FILES+=usr/share/terminfo/n/ncr160wy50+pp OLD_FILES+=usr/share/terminfo/n/ncr160wy50+wpp OLD_FILES+=usr/share/terminfo/n/ncr160wy60pp OLD_FILES+=usr/share/terminfo/n/ncr160wy60wpp OLD_FILES+=usr/share/terminfo/n/ncr260intan OLD_FILES+=usr/share/terminfo/n/ncr260intpp OLD_FILES+=usr/share/terminfo/n/ncr260intwan OLD_FILES+=usr/share/terminfo/n/ncr260intwpp OLD_FILES+=usr/share/terminfo/n/ncr260vppp OLD_FILES+=usr/share/terminfo/n/ncr260vpwpp OLD_FILES+=usr/share/terminfo/n/ncr260vt100an OLD_FILES+=usr/share/terminfo/n/ncr260vt100pp OLD_FILES+=usr/share/terminfo/n/ncr260vt100wan OLD_FILES+=usr/share/terminfo/n/ncr260vt100wpp OLD_FILES+=usr/share/terminfo/n/ncr260vt200an OLD_FILES+=usr/share/terminfo/n/ncr260vt200pp OLD_FILES+=usr/share/terminfo/n/ncr260vt200wan OLD_FILES+=usr/share/terminfo/n/ncr260vt200wpp OLD_FILES+=usr/share/terminfo/n/ncr260vt300an OLD_FILES+=usr/share/terminfo/n/ncr260vt300pp OLD_FILES+=usr/share/terminfo/n/ncr260vt300wan OLD_FILES+=usr/share/terminfo/n/ncr260vt300wpp OLD_FILES+=usr/share/terminfo/n/ncr260wy325pp OLD_FILES+=usr/share/terminfo/n/ncr260wy325wpp OLD_FILES+=usr/share/terminfo/n/ncr260wy350pp OLD_FILES+=usr/share/terminfo/n/ncr260wy350wpp OLD_FILES+=usr/share/terminfo/n/ncr260wy50+pp OLD_FILES+=usr/share/terminfo/n/ncr260wy50+wpp OLD_FILES+=usr/share/terminfo/n/ncr260wy60pp OLD_FILES+=usr/share/terminfo/n/ncr260wy60wpp OLD_FILES+=usr/share/terminfo/n/ncr7900 OLD_FILES+=usr/share/terminfo/n/ncr7900i OLD_FILES+=usr/share/terminfo/n/ncr7900iv OLD_FILES+=usr/share/terminfo/n/ncr7901 OLD_FILES+=usr/share/terminfo/n/ncrvt100an OLD_FILES+=usr/share/terminfo/n/ncrvt100pp OLD_FILES+=usr/share/terminfo/n/ncrvt100wan OLD_FILES+=usr/share/terminfo/n/ncrvt100wpp OLD_FILES+=usr/share/terminfo/n/ncsa OLD_FILES+=usr/share/terminfo/n/ncsa-m OLD_FILES+=usr/share/terminfo/n/ncsa-m-ns OLD_FILES+=usr/share/terminfo/n/ncsa-ns OLD_FILES+=usr/share/terminfo/n/ncsa-vt220 OLD_FILES+=usr/share/terminfo/n/ncsa-vt220-8 OLD_FILES+=usr/share/terminfo/n/nd9500 OLD_FILES+=usr/share/terminfo/n/ndr9500 OLD_FILES+=usr/share/terminfo/n/ndr9500-25 OLD_FILES+=usr/share/terminfo/n/ndr9500-25-mc OLD_FILES+=usr/share/terminfo/n/ndr9500-25-mc-nl OLD_FILES+=usr/share/terminfo/n/ndr9500-25-nl OLD_FILES+=usr/share/terminfo/n/ndr9500-mc OLD_FILES+=usr/share/terminfo/n/ndr9500-mc-nl OLD_FILES+=usr/share/terminfo/n/ndr9500-nl OLD_FILES+=usr/share/terminfo/n/nec OLD_FILES+=usr/share/terminfo/n/nec5520 OLD_FILES+=usr/share/terminfo/n/netbsd6 OLD_FILES+=usr/share/terminfo/n/newhp OLD_FILES+=usr/share/terminfo/n/newhpkeyboard OLD_FILES+=usr/share/terminfo/n/news OLD_FILES+=usr/share/terminfo/n/news-29 OLD_FILES+=usr/share/terminfo/n/news-29-euc OLD_FILES+=usr/share/terminfo/n/news-29-sjis OLD_FILES+=usr/share/terminfo/n/news-33 OLD_FILES+=usr/share/terminfo/n/news-33-euc OLD_FILES+=usr/share/terminfo/n/news-33-sjis OLD_FILES+=usr/share/terminfo/n/news-42 OLD_FILES+=usr/share/terminfo/n/news-42-euc OLD_FILES+=usr/share/terminfo/n/news-42-sjis OLD_FILES+=usr/share/terminfo/n/news-a OLD_FILES+=usr/share/terminfo/n/news-o OLD_FILES+=usr/share/terminfo/n/news-old-unk OLD_FILES+=usr/share/terminfo/n/news-unk OLD_FILES+=usr/share/terminfo/n/news28 OLD_FILES+=usr/share/terminfo/n/news28-a OLD_FILES+=usr/share/terminfo/n/news29 OLD_FILES+=usr/share/terminfo/n/news31 OLD_FILES+=usr/share/terminfo/n/news31-a OLD_FILES+=usr/share/terminfo/n/news31-o OLD_FILES+=usr/share/terminfo/n/news33 OLD_FILES+=usr/share/terminfo/n/news40 OLD_FILES+=usr/share/terminfo/n/news40-a OLD_FILES+=usr/share/terminfo/n/news40-o OLD_FILES+=usr/share/terminfo/n/news42 OLD_FILES+=usr/share/terminfo/n/newscbm OLD_FILES+=usr/share/terminfo/n/newscbm-a OLD_FILES+=usr/share/terminfo/n/newscbm-o OLD_FILES+=usr/share/terminfo/n/newscbm33 OLD_FILES+=usr/share/terminfo/n/next OLD_FILES+=usr/share/terminfo/n/nextshell OLD_FILES+=usr/share/terminfo/n/northstar OLD_FILES+=usr/share/terminfo/n/nsterm OLD_FILES+=usr/share/terminfo/n/nsterm+7 OLD_FILES+=usr/share/terminfo/n/nsterm+acs OLD_FILES+=usr/share/terminfo/n/nsterm+c OLD_FILES+=usr/share/terminfo/n/nsterm+c41 OLD_FILES+=usr/share/terminfo/n/nsterm+mac OLD_FILES+=usr/share/terminfo/n/nsterm+s OLD_FILES+=usr/share/terminfo/n/nsterm-16color OLD_FILES+=usr/share/terminfo/n/nsterm-256color OLD_FILES+=usr/share/terminfo/n/nsterm-7 OLD_FILES+=usr/share/terminfo/n/nsterm-7-c OLD_FILES+=usr/share/terminfo/n/nsterm-7-c-s OLD_FILES+=usr/share/terminfo/n/nsterm-7-m OLD_FILES+=usr/share/terminfo/n/nsterm-7-m-s OLD_FILES+=usr/share/terminfo/n/nsterm-7-s OLD_FILES+=usr/share/terminfo/n/nsterm-acs OLD_FILES+=usr/share/terminfo/n/nsterm-acs-c OLD_FILES+=usr/share/terminfo/n/nsterm-acs-c-s OLD_FILES+=usr/share/terminfo/n/nsterm-acs-m OLD_FILES+=usr/share/terminfo/n/nsterm-acs-m-s OLD_FILES+=usr/share/terminfo/n/nsterm-acs-s OLD_FILES+=usr/share/terminfo/n/nsterm-bce OLD_FILES+=usr/share/terminfo/n/nsterm-build309 OLD_FILES+=usr/share/terminfo/n/nsterm-build326 OLD_FILES+=usr/share/terminfo/n/nsterm-build343 OLD_FILES+=usr/share/terminfo/n/nsterm-build361 OLD_FILES+=usr/share/terminfo/n/nsterm-build400 OLD_FILES+=usr/share/terminfo/n/nsterm-c OLD_FILES+=usr/share/terminfo/n/nsterm-c-7 OLD_FILES+=usr/share/terminfo/n/nsterm-c-acs OLD_FILES+=usr/share/terminfo/n/nsterm-c-s OLD_FILES+=usr/share/terminfo/n/nsterm-c-s-7 OLD_FILES+=usr/share/terminfo/n/nsterm-c-s-acs OLD_FILES+=usr/share/terminfo/n/nsterm-direct OLD_FILES+=usr/share/terminfo/n/nsterm-m OLD_FILES+=usr/share/terminfo/n/nsterm-m-7 OLD_FILES+=usr/share/terminfo/n/nsterm-m-acs OLD_FILES+=usr/share/terminfo/n/nsterm-m-s OLD_FILES+=usr/share/terminfo/n/nsterm-m-s-7 OLD_FILES+=usr/share/terminfo/n/nsterm-m-s-acs OLD_FILES+=usr/share/terminfo/n/nsterm-old OLD_FILES+=usr/share/terminfo/n/nsterm-s OLD_FILES+=usr/share/terminfo/n/nsterm-s-7 OLD_FILES+=usr/share/terminfo/n/nsterm-s-acs OLD_FILES+=usr/share/terminfo/n/ntconsole OLD_FILES+=usr/share/terminfo/n/ntconsole-100 OLD_FILES+=usr/share/terminfo/n/ntconsole-100-nti OLD_FILES+=usr/share/terminfo/n/ntconsole-25 OLD_FILES+=usr/share/terminfo/n/ntconsole-25-nti OLD_FILES+=usr/share/terminfo/n/ntconsole-25-w OLD_FILES+=usr/share/terminfo/n/ntconsole-25-w-vt OLD_FILES+=usr/share/terminfo/n/ntconsole-35 OLD_FILES+=usr/share/terminfo/n/ntconsole-35-nti OLD_FILES+=usr/share/terminfo/n/ntconsole-35-w OLD_FILES+=usr/share/terminfo/n/ntconsole-50 OLD_FILES+=usr/share/terminfo/n/ntconsole-50-nti OLD_FILES+=usr/share/terminfo/n/ntconsole-50-w OLD_FILES+=usr/share/terminfo/n/ntconsole-60 OLD_FILES+=usr/share/terminfo/n/ntconsole-60-nti OLD_FILES+=usr/share/terminfo/n/ntconsole-60-w OLD_FILES+=usr/share/terminfo/n/ntconsole-w OLD_FILES+=usr/share/terminfo/n/ntconsole-w-vt OLD_FILES+=usr/share/terminfo/n/nwe501 OLD_FILES+=usr/share/terminfo/n/nwe501-a OLD_FILES+=usr/share/terminfo/n/nwe501-o OLD_FILES+=usr/share/terminfo/n/nwp-511 OLD_FILES+=usr/share/terminfo/n/nwp-517 OLD_FILES+=usr/share/terminfo/n/nwp-517-w OLD_FILES+=usr/share/terminfo/n/nwp251-a OLD_FILES+=usr/share/terminfo/n/nwp251-o OLD_FILES+=usr/share/terminfo/n/nwp511 OLD_FILES+=usr/share/terminfo/n/nwp512 OLD_FILES+=usr/share/terminfo/n/nwp512-a OLD_FILES+=usr/share/terminfo/n/nwp512-o OLD_FILES+=usr/share/terminfo/n/nwp513 OLD_FILES+=usr/share/terminfo/n/nwp513-a OLD_FILES+=usr/share/terminfo/n/nwp513-o OLD_FILES+=usr/share/terminfo/n/nwp514 OLD_FILES+=usr/share/terminfo/n/nwp514-a OLD_FILES+=usr/share/terminfo/n/nwp514-o OLD_FILES+=usr/share/terminfo/n/nwp517 OLD_FILES+=usr/share/terminfo/n/nwp517-w OLD_FILES+=usr/share/terminfo/n/nwp518 OLD_FILES+=usr/share/terminfo/n/nwp518-a OLD_FILES+=usr/share/terminfo/n/nwp518-o OLD_FILES+=usr/share/terminfo/n/nxterm OLD_DIRS+=usr/share/terminfo/n/ OLD_FILES+=usr/share/terminfo/o/o31 OLD_FILES+=usr/share/terminfo/o/o4112-nd OLD_FILES+=usr/share/terminfo/o/o85h OLD_FILES+=usr/share/terminfo/o/oabm85h OLD_FILES+=usr/share/terminfo/o/oblit OLD_FILES+=usr/share/terminfo/o/oc100 OLD_FILES+=usr/share/terminfo/o/oconcept OLD_FILES+=usr/share/terminfo/o/ofcons OLD_FILES+=usr/share/terminfo/o/ojerq OLD_FILES+=usr/share/terminfo/o/old-st OLD_FILES+=usr/share/terminfo/o/oldibmpc3 OLD_FILES+=usr/share/terminfo/o/oldpc3 OLD_FILES+=usr/share/terminfo/o/oldsun OLD_FILES+=usr/share/terminfo/o/omron OLD_FILES+=usr/share/terminfo/o/opennt OLD_FILES+=usr/share/terminfo/o/opennt-100 OLD_FILES+=usr/share/terminfo/o/opennt-100-nti OLD_FILES+=usr/share/terminfo/o/opennt-25 OLD_FILES+=usr/share/terminfo/o/opennt-25-nti OLD_FILES+=usr/share/terminfo/o/opennt-25-w OLD_FILES+=usr/share/terminfo/o/opennt-25-w-vt OLD_FILES+=usr/share/terminfo/o/opennt-35 OLD_FILES+=usr/share/terminfo/o/opennt-35-nti OLD_FILES+=usr/share/terminfo/o/opennt-35-w OLD_FILES+=usr/share/terminfo/o/opennt-50 OLD_FILES+=usr/share/terminfo/o/opennt-50-nti OLD_FILES+=usr/share/terminfo/o/opennt-50-w OLD_FILES+=usr/share/terminfo/o/opennt-60 OLD_FILES+=usr/share/terminfo/o/opennt-60-nti OLD_FILES+=usr/share/terminfo/o/opennt-60-w OLD_FILES+=usr/share/terminfo/o/opennt-nti OLD_FILES+=usr/share/terminfo/o/opennt-w OLD_FILES+=usr/share/terminfo/o/opennt-w-vt OLD_FILES+=usr/share/terminfo/o/opus3n1+ OLD_FILES+=usr/share/terminfo/o/origibmpc3 OLD_FILES+=usr/share/terminfo/o/origpc3 OLD_FILES+=usr/share/terminfo/o/os9LII OLD_FILES+=usr/share/terminfo/o/osborne OLD_FILES+=usr/share/terminfo/o/osborne-w OLD_FILES+=usr/share/terminfo/o/osborne1 OLD_FILES+=usr/share/terminfo/o/osborne1-w OLD_FILES+=usr/share/terminfo/o/osexec OLD_FILES+=usr/share/terminfo/o/otek4112 OLD_FILES+=usr/share/terminfo/o/otek4113 OLD_FILES+=usr/share/terminfo/o/otek4114 OLD_FILES+=usr/share/terminfo/o/otek4115 OLD_FILES+=usr/share/terminfo/o/owl OLD_DIRS+=usr/share/terminfo/o/ OLD_FILES+=usr/share/terminfo/p/p12 OLD_FILES+=usr/share/terminfo/p/p12-m OLD_FILES+=usr/share/terminfo/p/p12-m-w OLD_FILES+=usr/share/terminfo/p/p12-w OLD_FILES+=usr/share/terminfo/p/p14 OLD_FILES+=usr/share/terminfo/p/p14-m OLD_FILES+=usr/share/terminfo/p/p14-m-w OLD_FILES+=usr/share/terminfo/p/p14-w OLD_FILES+=usr/share/terminfo/p/p19 OLD_FILES+=usr/share/terminfo/p/p4 OLD_FILES+=usr/share/terminfo/p/p5 OLD_FILES+=usr/share/terminfo/p/p7 OLD_FILES+=usr/share/terminfo/p/p8 OLD_FILES+=usr/share/terminfo/p/p8-w OLD_FILES+=usr/share/terminfo/p/p8gl OLD_FILES+=usr/share/terminfo/p/p9 OLD_FILES+=usr/share/terminfo/p/p9-8 OLD_FILES+=usr/share/terminfo/p/p9-8-w OLD_FILES+=usr/share/terminfo/p/p9-w OLD_FILES+=usr/share/terminfo/p/pc-coherent OLD_FILES+=usr/share/terminfo/p/pc-minix OLD_FILES+=usr/share/terminfo/p/pc-venix OLD_FILES+=usr/share/terminfo/p/pc3 OLD_FILES+=usr/share/terminfo/p/pc3-bold OLD_FILES+=usr/share/terminfo/p/pc3r OLD_FILES+=usr/share/terminfo/p/pc3r-m OLD_FILES+=usr/share/terminfo/p/pc6300plus OLD_FILES+=usr/share/terminfo/p/pc7300 OLD_FILES+=usr/share/terminfo/p/pcansi OLD_FILES+=usr/share/terminfo/p/pcansi-25 OLD_FILES+=usr/share/terminfo/p/pcansi-25-m OLD_FILES+=usr/share/terminfo/p/pcansi-33 OLD_FILES+=usr/share/terminfo/p/pcansi-33-m OLD_FILES+=usr/share/terminfo/p/pcansi-43 OLD_FILES+=usr/share/terminfo/p/pcansi-43-m OLD_FILES+=usr/share/terminfo/p/pcansi-m OLD_FILES+=usr/share/terminfo/p/pcansi-mono OLD_FILES+=usr/share/terminfo/p/pcansi25 OLD_FILES+=usr/share/terminfo/p/pcansi25m OLD_FILES+=usr/share/terminfo/p/pcansi33 OLD_FILES+=usr/share/terminfo/p/pcansi33m OLD_FILES+=usr/share/terminfo/p/pcansi43 OLD_FILES+=usr/share/terminfo/p/pccon OLD_FILES+=usr/share/terminfo/p/pccon+base OLD_FILES+=usr/share/terminfo/p/pccon+colors OLD_FILES+=usr/share/terminfo/p/pccon+keys OLD_FILES+=usr/share/terminfo/p/pccon+sgr+acs OLD_FILES+=usr/share/terminfo/p/pccon+sgr+acs0 OLD_FILES+=usr/share/terminfo/p/pccon-m OLD_FILES+=usr/share/terminfo/p/pccon0 OLD_FILES+=usr/share/terminfo/p/pccon0-m OLD_FILES+=usr/share/terminfo/p/pccons OLD_FILES+=usr/share/terminfo/p/pcconsole OLD_FILES+=usr/share/terminfo/p/pcix OLD_FILES+=usr/share/terminfo/p/pckermit OLD_FILES+=usr/share/terminfo/p/pckermit12 OLD_FILES+=usr/share/terminfo/p/pckermit120 OLD_FILES+=usr/share/terminfo/p/pcmw OLD_FILES+=usr/share/terminfo/p/pcplot OLD_FILES+=usr/share/terminfo/p/pcvt25 OLD_FILES+=usr/share/terminfo/p/pcvt25-color OLD_FILES+=usr/share/terminfo/p/pcvt25w OLD_FILES+=usr/share/terminfo/p/pcvt28 OLD_FILES+=usr/share/terminfo/p/pcvt28w OLD_FILES+=usr/share/terminfo/p/pcvt35 OLD_FILES+=usr/share/terminfo/p/pcvt35w OLD_FILES+=usr/share/terminfo/p/pcvt40 OLD_FILES+=usr/share/terminfo/p/pcvt40w OLD_FILES+=usr/share/terminfo/p/pcvt43 OLD_FILES+=usr/share/terminfo/p/pcvt43w OLD_FILES+=usr/share/terminfo/p/pcvt50 OLD_FILES+=usr/share/terminfo/p/pcvt50w OLD_FILES+=usr/share/terminfo/p/pcvtXX OLD_FILES+=usr/share/terminfo/p/pcz19 OLD_FILES+=usr/share/terminfo/p/pe1100 OLD_FILES+=usr/share/terminfo/p/pe1200 OLD_FILES+=usr/share/terminfo/p/pe1251 OLD_FILES+=usr/share/terminfo/p/pe550 OLD_FILES+=usr/share/terminfo/p/pe6100 OLD_FILES+=usr/share/terminfo/p/pe6300 OLD_FILES+=usr/share/terminfo/p/pe6312 OLD_FILES+=usr/share/terminfo/p/pe7000c OLD_FILES+=usr/share/terminfo/p/pe7000m OLD_FILES+=usr/share/terminfo/p/pilot OLD_FILES+=usr/share/terminfo/p/pmcons OLD_FILES+=usr/share/terminfo/p/pmconsole OLD_FILES+=usr/share/terminfo/p/printer OLD_FILES+=usr/share/terminfo/p/prism12 OLD_FILES+=usr/share/terminfo/p/prism12-m OLD_FILES+=usr/share/terminfo/p/prism12-m-w OLD_FILES+=usr/share/terminfo/p/prism12-w OLD_FILES+=usr/share/terminfo/p/prism14 OLD_FILES+=usr/share/terminfo/p/prism14-m OLD_FILES+=usr/share/terminfo/p/prism14-m-w OLD_FILES+=usr/share/terminfo/p/prism14-w OLD_FILES+=usr/share/terminfo/p/prism2 OLD_FILES+=usr/share/terminfo/p/prism4 OLD_FILES+=usr/share/terminfo/p/prism5 OLD_FILES+=usr/share/terminfo/p/prism7 OLD_FILES+=usr/share/terminfo/p/prism8 OLD_FILES+=usr/share/terminfo/p/prism8-w OLD_FILES+=usr/share/terminfo/p/prism8gl OLD_FILES+=usr/share/terminfo/p/prism9 OLD_FILES+=usr/share/terminfo/p/prism9-8 OLD_FILES+=usr/share/terminfo/p/prism9-8-w OLD_FILES+=usr/share/terminfo/p/prism9-w OLD_FILES+=usr/share/terminfo/p/pro350 OLD_FILES+=usr/share/terminfo/p/ps300 OLD_FILES+=usr/share/terminfo/p/psterm OLD_FILES+=usr/share/terminfo/p/psterm-80x24 OLD_FILES+=usr/share/terminfo/p/psterm-90x28 OLD_FILES+=usr/share/terminfo/p/psterm-96x48 OLD_FILES+=usr/share/terminfo/p/psterm-basic OLD_FILES+=usr/share/terminfo/p/psterm-fast OLD_FILES+=usr/share/terminfo/p/psx_ansi OLD_FILES+=usr/share/terminfo/p/pt100 OLD_FILES+=usr/share/terminfo/p/pt100w OLD_FILES+=usr/share/terminfo/p/pt200 OLD_FILES+=usr/share/terminfo/p/pt200w OLD_FILES+=usr/share/terminfo/p/pt210 OLD_FILES+=usr/share/terminfo/p/pt250 OLD_FILES+=usr/share/terminfo/p/pt250w OLD_FILES+=usr/share/terminfo/p/pt505 OLD_FILES+=usr/share/terminfo/p/pt505-22 OLD_FILES+=usr/share/terminfo/p/pt505-24 OLD_FILES+=usr/share/terminfo/p/pty OLD_FILES+=usr/share/terminfo/p/putty OLD_FILES+=usr/share/terminfo/p/putty+fnkeys OLD_FILES+=usr/share/terminfo/p/putty+fnkeys+esc OLD_FILES+=usr/share/terminfo/p/putty+fnkeys+linux OLD_FILES+=usr/share/terminfo/p/putty+fnkeys+sco OLD_FILES+=usr/share/terminfo/p/putty+fnkeys+vt100 OLD_FILES+=usr/share/terminfo/p/putty+fnkeys+vt400 OLD_FILES+=usr/share/terminfo/p/putty+fnkeys+xterm OLD_FILES+=usr/share/terminfo/p/putty+keypad OLD_FILES+=usr/share/terminfo/p/putty+screen OLD_FILES+=usr/share/terminfo/p/putty-256color OLD_FILES+=usr/share/terminfo/p/putty-m1 OLD_FILES+=usr/share/terminfo/p/putty-m1b OLD_FILES+=usr/share/terminfo/p/putty-m2 OLD_FILES+=usr/share/terminfo/p/putty-noapp OLD_FILES+=usr/share/terminfo/p/putty-sco OLD_FILES+=usr/share/terminfo/p/putty-screen OLD_FILES+=usr/share/terminfo/p/putty-vt100 OLD_DIRS+=usr/share/terminfo/p/ OLD_FILES+=usr/share/terminfo/q/qansi OLD_FILES+=usr/share/terminfo/q/qansi-g OLD_FILES+=usr/share/terminfo/q/qansi-m OLD_FILES+=usr/share/terminfo/q/qansi-t OLD_FILES+=usr/share/terminfo/q/qansi-w OLD_FILES+=usr/share/terminfo/q/qdcons OLD_FILES+=usr/share/terminfo/q/qdss OLD_FILES+=usr/share/terminfo/q/qnx OLD_FILES+=usr/share/terminfo/q/qnx4 OLD_FILES+=usr/share/terminfo/q/qnxm OLD_FILES+=usr/share/terminfo/q/qnxt OLD_FILES+=usr/share/terminfo/q/qnxt2 OLD_FILES+=usr/share/terminfo/q/qnxt4 OLD_FILES+=usr/share/terminfo/q/qnxtmono OLD_FILES+=usr/share/terminfo/q/qnxw OLD_FILES+=usr/share/terminfo/q/qume OLD_FILES+=usr/share/terminfo/q/qume5 OLD_FILES+=usr/share/terminfo/q/qvt101 OLD_FILES+=usr/share/terminfo/q/qvt101+ OLD_FILES+=usr/share/terminfo/q/qvt101p OLD_FILES+=usr/share/terminfo/q/qvt102 OLD_FILES+=usr/share/terminfo/q/qvt103 OLD_FILES+=usr/share/terminfo/q/qvt103-w OLD_FILES+=usr/share/terminfo/q/qvt108 OLD_FILES+=usr/share/terminfo/q/qvt119 OLD_FILES+=usr/share/terminfo/q/qvt119+ OLD_FILES+=usr/share/terminfo/q/qvt119+-25 OLD_FILES+=usr/share/terminfo/q/qvt119+-25-w OLD_FILES+=usr/share/terminfo/q/qvt119+-w OLD_FILES+=usr/share/terminfo/q/qvt119-25-w OLD_FILES+=usr/share/terminfo/q/qvt119-w OLD_FILES+=usr/share/terminfo/q/qvt119p OLD_FILES+=usr/share/terminfo/q/qvt119p-25 OLD_FILES+=usr/share/terminfo/q/qvt119p-25-w OLD_FILES+=usr/share/terminfo/q/qvt119p-w OLD_FILES+=usr/share/terminfo/q/qvt203 OLD_FILES+=usr/share/terminfo/q/qvt203+ OLD_FILES+=usr/share/terminfo/q/qvt203-25 OLD_FILES+=usr/share/terminfo/q/qvt203-25-w OLD_FILES+=usr/share/terminfo/q/qvt203-w OLD_FILES+=usr/share/terminfo/q/qvt203-w-am OLD_DIRS+=usr/share/terminfo/q/ OLD_FILES+=usr/share/terminfo/r/rbcomm OLD_FILES+=usr/share/terminfo/r/rbcomm-nam OLD_FILES+=usr/share/terminfo/r/rbcomm-w OLD_FILES+=usr/share/terminfo/r/rca OLD_FILES+=usr/share/terminfo/r/rcons OLD_FILES+=usr/share/terminfo/r/rcons-color OLD_FILES+=usr/share/terminfo/r/rebus3180 OLD_FILES+=usr/share/terminfo/r/regent OLD_FILES+=usr/share/terminfo/r/regent100 OLD_FILES+=usr/share/terminfo/r/regent20 OLD_FILES+=usr/share/terminfo/r/regent200 OLD_FILES+=usr/share/terminfo/r/regent25 OLD_FILES+=usr/share/terminfo/r/regent40 OLD_FILES+=usr/share/terminfo/r/regent40+ OLD_FILES+=usr/share/terminfo/r/regent60 OLD_FILES+=usr/share/terminfo/r/rt6221 OLD_FILES+=usr/share/terminfo/r/rt6221-w OLD_FILES+=usr/share/terminfo/r/rtpc OLD_FILES+=usr/share/terminfo/r/rxvt OLD_FILES+=usr/share/terminfo/r/rxvt+pcfkeys OLD_FILES+=usr/share/terminfo/r/rxvt-16color OLD_FILES+=usr/share/terminfo/r/rxvt-256color OLD_FILES+=usr/share/terminfo/r/rxvt-88color OLD_FILES+=usr/share/terminfo/r/rxvt-basic OLD_FILES+=usr/share/terminfo/r/rxvt-color OLD_FILES+=usr/share/terminfo/r/rxvt-cygwin OLD_FILES+=usr/share/terminfo/r/rxvt-cygwin-native OLD_FILES+=usr/share/terminfo/r/rxvt-xpm OLD_DIRS+=usr/share/terminfo/r/ OLD_FILES+=usr/share/terminfo/s/s4 OLD_FILES+=usr/share/terminfo/s/sb1 OLD_FILES+=usr/share/terminfo/s/sb2 OLD_FILES+=usr/share/terminfo/s/sb3 OLD_FILES+=usr/share/terminfo/s/sbi OLD_FILES+=usr/share/terminfo/s/sbobcat OLD_FILES+=usr/share/terminfo/s/sc410 OLD_FILES+=usr/share/terminfo/s/sc415 OLD_FILES+=usr/share/terminfo/s/scanset OLD_FILES+=usr/share/terminfo/s/scoansi OLD_FILES+=usr/share/terminfo/s/scoansi-new OLD_FILES+=usr/share/terminfo/s/scoansi-old OLD_FILES+=usr/share/terminfo/s/screen OLD_FILES+=usr/share/terminfo/s/screen+fkeys OLD_FILES+=usr/share/terminfo/s/screen+italics OLD_FILES+=usr/share/terminfo/s/screen-16color OLD_FILES+=usr/share/terminfo/s/screen-16color-bce OLD_FILES+=usr/share/terminfo/s/screen-16color-bce-s OLD_FILES+=usr/share/terminfo/s/screen-16color-s OLD_FILES+=usr/share/terminfo/s/screen-256color OLD_FILES+=usr/share/terminfo/s/screen-256color-bce OLD_FILES+=usr/share/terminfo/s/screen-256color-bce-s OLD_FILES+=usr/share/terminfo/s/screen-256color-s OLD_FILES+=usr/share/terminfo/s/screen-bce OLD_FILES+=usr/share/terminfo/s/screen-bce.Eterm OLD_FILES+=usr/share/terminfo/s/screen-bce.gnome OLD_FILES+=usr/share/terminfo/s/screen-bce.konsole OLD_FILES+=usr/share/terminfo/s/screen-bce.linux OLD_FILES+=usr/share/terminfo/s/screen-bce.mrxvt OLD_FILES+=usr/share/terminfo/s/screen-bce.rxvt OLD_FILES+=usr/share/terminfo/s/screen-bce.xterm-new OLD_FILES+=usr/share/terminfo/s/screen-s OLD_FILES+=usr/share/terminfo/s/screen-w OLD_FILES+=usr/share/terminfo/s/screen.Eterm OLD_FILES+=usr/share/terminfo/s/screen.gnome OLD_FILES+=usr/share/terminfo/s/screen.konsole OLD_FILES+=usr/share/terminfo/s/screen.konsole-256color OLD_FILES+=usr/share/terminfo/s/screen.linux OLD_FILES+=usr/share/terminfo/s/screen.linux-m1 OLD_FILES+=usr/share/terminfo/s/screen.linux-m1b OLD_FILES+=usr/share/terminfo/s/screen.linux-m2 OLD_FILES+=usr/share/terminfo/s/screen.linux-s OLD_FILES+=usr/share/terminfo/s/screen.minitel1 OLD_FILES+=usr/share/terminfo/s/screen.minitel1-nb OLD_FILES+=usr/share/terminfo/s/screen.minitel12-80 OLD_FILES+=usr/share/terminfo/s/screen.minitel1b OLD_FILES+=usr/share/terminfo/s/screen.minitel1b-80 OLD_FILES+=usr/share/terminfo/s/screen.minitel1b-nb OLD_FILES+=usr/share/terminfo/s/screen.minitel2-80 OLD_FILES+=usr/share/terminfo/s/screen.mlterm OLD_FILES+=usr/share/terminfo/s/screen.mlterm-256color OLD_FILES+=usr/share/terminfo/s/screen.mrxvt OLD_FILES+=usr/share/terminfo/s/screen.putty OLD_FILES+=usr/share/terminfo/s/screen.putty-256color OLD_FILES+=usr/share/terminfo/s/screen.putty-m1 OLD_FILES+=usr/share/terminfo/s/screen.putty-m1b OLD_FILES+=usr/share/terminfo/s/screen.putty-m2 OLD_FILES+=usr/share/terminfo/s/screen.rxvt OLD_FILES+=usr/share/terminfo/s/screen.teraterm OLD_FILES+=usr/share/terminfo/s/screen.vte OLD_FILES+=usr/share/terminfo/s/screen.vte-256color OLD_FILES+=usr/share/terminfo/s/screen.xterm-256color OLD_FILES+=usr/share/terminfo/s/screen.xterm-new OLD_FILES+=usr/share/terminfo/s/screen.xterm-r6 OLD_FILES+=usr/share/terminfo/s/screen.xterm-xfree86 OLD_FILES+=usr/share/terminfo/s/screen2 OLD_FILES+=usr/share/terminfo/s/screen3 OLD_FILES+=usr/share/terminfo/s/screen4 OLD_FILES+=usr/share/terminfo/s/screen5 OLD_FILES+=usr/share/terminfo/s/screwpoint OLD_FILES+=usr/share/terminfo/s/scrhp OLD_FILES+=usr/share/terminfo/s/scrt OLD_FILES+=usr/share/terminfo/s/securecrt OLD_FILES+=usr/share/terminfo/s/sibo OLD_FILES+=usr/share/terminfo/s/simpleterm OLD_FILES+=usr/share/terminfo/s/simterm OLD_FILES+=usr/share/terminfo/s/soroc OLD_FILES+=usr/share/terminfo/s/soroc120 OLD_FILES+=usr/share/terminfo/s/soroc140 OLD_FILES+=usr/share/terminfo/s/spinwriter OLD_FILES+=usr/share/terminfo/s/st OLD_FILES+=usr/share/terminfo/s/st-0.6 OLD_FILES+=usr/share/terminfo/s/st-0.7 OLD_FILES+=usr/share/terminfo/s/st-0.8 OLD_FILES+=usr/share/terminfo/s/st-16color OLD_FILES+=usr/share/terminfo/s/st-256color OLD_FILES+=usr/share/terminfo/s/st-direct OLD_FILES+=usr/share/terminfo/s/st52 OLD_FILES+=usr/share/terminfo/s/st52-color OLD_FILES+=usr/share/terminfo/s/st52-m OLD_FILES+=usr/share/terminfo/s/st52-old OLD_FILES+=usr/share/terminfo/s/stterm OLD_FILES+=usr/share/terminfo/s/stterm-16color OLD_FILES+=usr/share/terminfo/s/stterm-256color OLD_FILES+=usr/share/terminfo/s/stv52 OLD_FILES+=usr/share/terminfo/s/stv52pc OLD_FILES+=usr/share/terminfo/s/sun OLD_FILES+=usr/share/terminfo/s/sun+sl OLD_FILES+=usr/share/terminfo/s/sun-1 OLD_FILES+=usr/share/terminfo/s/sun-12 OLD_FILES+=usr/share/terminfo/s/sun-17 OLD_FILES+=usr/share/terminfo/s/sun-24 OLD_FILES+=usr/share/terminfo/s/sun-34 OLD_FILES+=usr/share/terminfo/s/sun-48 OLD_FILES+=usr/share/terminfo/s/sun-c OLD_FILES+=usr/share/terminfo/s/sun-cgsix OLD_FILES+=usr/share/terminfo/s/sun-cmd OLD_FILES+=usr/share/terminfo/s/sun-color OLD_FILES+=usr/share/terminfo/s/sun-e OLD_FILES+=usr/share/terminfo/s/sun-e-s OLD_FILES+=usr/share/terminfo/s/sun-il OLD_FILES+=usr/share/terminfo/s/sun-nic OLD_FILES+=usr/share/terminfo/s/sun-s OLD_FILES+=usr/share/terminfo/s/sun-s-e OLD_FILES+=usr/share/terminfo/s/sun-ss5 OLD_FILES+=usr/share/terminfo/s/sun-type4 OLD_FILES+=usr/share/terminfo/s/sun1 OLD_FILES+=usr/share/terminfo/s/sun2 OLD_FILES+=usr/share/terminfo/s/sune OLD_FILES+=usr/share/terminfo/s/superbee OLD_FILES+=usr/share/terminfo/s/superbee-xsb OLD_FILES+=usr/share/terminfo/s/superbeeic OLD_FILES+=usr/share/terminfo/s/superbrain OLD_FILES+=usr/share/terminfo/s/sv80 OLD_FILES+=usr/share/terminfo/s/swtp OLD_FILES+=usr/share/terminfo/s/synertek OLD_FILES+=usr/share/terminfo/s/synertek380 OLD_FILES+=usr/share/terminfo/s/system1 OLD_DIRS+=usr/share/terminfo/s/ OLD_FILES+=usr/share/terminfo/t/t10 OLD_FILES+=usr/share/terminfo/t/t1061 OLD_FILES+=usr/share/terminfo/t/t1061f OLD_FILES+=usr/share/terminfo/t/t16 OLD_FILES+=usr/share/terminfo/t/t3700 OLD_FILES+=usr/share/terminfo/t/t3800 OLD_FILES+=usr/share/terminfo/t/t653x OLD_FILES+=usr/share/terminfo/t/tab OLD_FILES+=usr/share/terminfo/t/tab132 OLD_FILES+=usr/share/terminfo/t/tab132-15 OLD_FILES+=usr/share/terminfo/t/tab132-rv OLD_FILES+=usr/share/terminfo/t/tab132-w OLD_FILES+=usr/share/terminfo/t/tab132-w-rv OLD_FILES+=usr/share/terminfo/t/tandem6510 OLD_FILES+=usr/share/terminfo/t/tandem653 OLD_FILES+=usr/share/terminfo/t/tek OLD_FILES+=usr/share/terminfo/t/tek4012 OLD_FILES+=usr/share/terminfo/t/tek4013 OLD_FILES+=usr/share/terminfo/t/tek4014 OLD_FILES+=usr/share/terminfo/t/tek4014-sm OLD_FILES+=usr/share/terminfo/t/tek4015 OLD_FILES+=usr/share/terminfo/t/tek4015-sm OLD_FILES+=usr/share/terminfo/t/tek4023 OLD_FILES+=usr/share/terminfo/t/tek4024 OLD_FILES+=usr/share/terminfo/t/tek4025 OLD_FILES+=usr/share/terminfo/t/tek4025-17 OLD_FILES+=usr/share/terminfo/t/tek4025-17-ws OLD_FILES+=usr/share/terminfo/t/tek4025-cr OLD_FILES+=usr/share/terminfo/t/tek4025-ex OLD_FILES+=usr/share/terminfo/t/tek4025a OLD_FILES+=usr/share/terminfo/t/tek4025ex OLD_FILES+=usr/share/terminfo/t/tek4027 OLD_FILES+=usr/share/terminfo/t/tek4027-ex OLD_FILES+=usr/share/terminfo/t/tek4105 OLD_FILES+=usr/share/terminfo/t/tek4105-30 OLD_FILES+=usr/share/terminfo/t/tek4105a OLD_FILES+=usr/share/terminfo/t/tek4106brl OLD_FILES+=usr/share/terminfo/t/tek4107 OLD_FILES+=usr/share/terminfo/t/tek4107brl OLD_FILES+=usr/share/terminfo/t/tek4109 OLD_FILES+=usr/share/terminfo/t/tek4109brl OLD_FILES+=usr/share/terminfo/t/tek4112 OLD_FILES+=usr/share/terminfo/t/tek4112-5 OLD_FILES+=usr/share/terminfo/t/tek4112-nd OLD_FILES+=usr/share/terminfo/t/tek4113 OLD_FILES+=usr/share/terminfo/t/tek4113-34 OLD_FILES+=usr/share/terminfo/t/tek4113-nd OLD_FILES+=usr/share/terminfo/t/tek4114 OLD_FILES+=usr/share/terminfo/t/tek4115 OLD_FILES+=usr/share/terminfo/t/tek4125 OLD_FILES+=usr/share/terminfo/t/tek4205 OLD_FILES+=usr/share/terminfo/t/tek4207 OLD_FILES+=usr/share/terminfo/t/tek4207-s OLD_FILES+=usr/share/terminfo/t/tek4404 OLD_FILES+=usr/share/terminfo/t/teken OLD_FILES+=usr/share/terminfo/t/teleray OLD_FILES+=usr/share/terminfo/t/teletec OLD_FILES+=usr/share/terminfo/t/teraterm OLD_FILES+=usr/share/terminfo/t/teraterm-256color OLD_FILES+=usr/share/terminfo/t/teraterm2.3 OLD_FILES+=usr/share/terminfo/t/teraterm4.59 OLD_FILES+=usr/share/terminfo/t/teraterm4.97 OLD_FILES+=usr/share/terminfo/t/terminator OLD_FILES+=usr/share/terminfo/t/terminet OLD_FILES+=usr/share/terminfo/t/terminet1200 OLD_FILES+=usr/share/terminfo/t/terminet300 OLD_FILES+=usr/share/terminfo/t/terminology OLD_FILES+=usr/share/terminfo/t/terminology-0.6.1 OLD_FILES+=usr/share/terminfo/t/terminology-1.0.0 OLD_FILES+=usr/share/terminfo/t/terminology-1.8.1 OLD_FILES+=usr/share/terminfo/t/termite OLD_FILES+=usr/share/terminfo/t/tgtelnet OLD_FILES+=usr/share/terminfo/t/ti700 OLD_FILES+=usr/share/terminfo/t/ti703 OLD_FILES+=usr/share/terminfo/t/ti703-w OLD_FILES+=usr/share/terminfo/t/ti707 OLD_FILES+=usr/share/terminfo/t/ti707-w OLD_FILES+=usr/share/terminfo/t/ti733 OLD_FILES+=usr/share/terminfo/t/ti735 OLD_FILES+=usr/share/terminfo/t/ti745 OLD_FILES+=usr/share/terminfo/t/ti800 OLD_FILES+=usr/share/terminfo/t/ti916 OLD_FILES+=usr/share/terminfo/t/ti916-132 OLD_FILES+=usr/share/terminfo/t/ti916-220-7 OLD_FILES+=usr/share/terminfo/t/ti916-220-8 OLD_FILES+=usr/share/terminfo/t/ti916-8 OLD_FILES+=usr/share/terminfo/t/ti916-8-132 OLD_FILES+=usr/share/terminfo/t/ti924 OLD_FILES+=usr/share/terminfo/t/ti924-8 OLD_FILES+=usr/share/terminfo/t/ti924-8w OLD_FILES+=usr/share/terminfo/t/ti924w OLD_FILES+=usr/share/terminfo/t/ti926 OLD_FILES+=usr/share/terminfo/t/ti926-8 OLD_FILES+=usr/share/terminfo/t/ti928 OLD_FILES+=usr/share/terminfo/t/ti928-8 OLD_FILES+=usr/share/terminfo/t/ti931 OLD_FILES+=usr/share/terminfo/t/ti_ansi OLD_FILES+=usr/share/terminfo/t/tkterm OLD_FILES+=usr/share/terminfo/t/tmux OLD_FILES+=usr/share/terminfo/t/tmux-256color OLD_FILES+=usr/share/terminfo/t/tmux-direct OLD_FILES+=usr/share/terminfo/t/tn1200 OLD_FILES+=usr/share/terminfo/t/tn300 OLD_FILES+=usr/share/terminfo/t/trs16 OLD_FILES+=usr/share/terminfo/t/trs2 OLD_FILES+=usr/share/terminfo/t/trs80II OLD_FILES+=usr/share/terminfo/t/trsII OLD_FILES+=usr/share/terminfo/t/ts-1 OLD_FILES+=usr/share/terminfo/t/ts-1p OLD_FILES+=usr/share/terminfo/t/ts1 OLD_FILES+=usr/share/terminfo/t/ts100 OLD_FILES+=usr/share/terminfo/t/ts100-ctxt OLD_FILES+=usr/share/terminfo/t/ts100-sp OLD_FILES+=usr/share/terminfo/t/ts1p OLD_FILES+=usr/share/terminfo/t/tt OLD_FILES+=usr/share/terminfo/t/tt505-22 OLD_FILES+=usr/share/terminfo/t/tt52 OLD_FILES+=usr/share/terminfo/t/tty33 OLD_FILES+=usr/share/terminfo/t/tty35 OLD_FILES+=usr/share/terminfo/t/tty37 OLD_FILES+=usr/share/terminfo/t/tty40 OLD_FILES+=usr/share/terminfo/t/tty43 OLD_FILES+=usr/share/terminfo/t/tty4420 OLD_FILES+=usr/share/terminfo/t/tty4424 OLD_FILES+=usr/share/terminfo/t/tty4424-1 OLD_FILES+=usr/share/terminfo/t/tty4424m OLD_FILES+=usr/share/terminfo/t/tty4426 OLD_FILES+=usr/share/terminfo/t/tty5410 OLD_FILES+=usr/share/terminfo/t/tty5410-w OLD_FILES+=usr/share/terminfo/t/tty5410v1 OLD_FILES+=usr/share/terminfo/t/tty5410v1-w OLD_FILES+=usr/share/terminfo/t/tty5420 OLD_FILES+=usr/share/terminfo/t/tty5420+nl OLD_FILES+=usr/share/terminfo/t/tty5420-nl OLD_FILES+=usr/share/terminfo/t/tty5420-rv OLD_FILES+=usr/share/terminfo/t/tty5420-rv-nl OLD_FILES+=usr/share/terminfo/t/tty5420-w OLD_FILES+=usr/share/terminfo/t/tty5420-w-nl OLD_FILES+=usr/share/terminfo/t/tty5420-w-rv OLD_FILES+=usr/share/terminfo/t/tty5420-w-rv-n OLD_FILES+=usr/share/terminfo/t/tty5425 OLD_FILES+=usr/share/terminfo/t/tty5425-nl OLD_FILES+=usr/share/terminfo/t/tty5425-w OLD_FILES+=usr/share/terminfo/t/tty5620 OLD_FILES+=usr/share/terminfo/t/tty5620-1 OLD_FILES+=usr/share/terminfo/t/tty5620-24 OLD_FILES+=usr/share/terminfo/t/tty5620-34 OLD_FILES+=usr/share/terminfo/t/tty5620-s OLD_FILES+=usr/share/terminfo/t/ttydmd OLD_FILES+=usr/share/terminfo/t/tvi803 OLD_FILES+=usr/share/terminfo/t/tvi9065 OLD_FILES+=usr/share/terminfo/t/tvi910 OLD_FILES+=usr/share/terminfo/t/tvi910+ OLD_FILES+=usr/share/terminfo/t/tvi912 OLD_FILES+=usr/share/terminfo/t/tvi912b OLD_FILES+=usr/share/terminfo/t/tvi912b+2p OLD_FILES+=usr/share/terminfo/t/tvi912b+dim OLD_FILES+=usr/share/terminfo/t/tvi912b+mc OLD_FILES+=usr/share/terminfo/t/tvi912b+printer OLD_FILES+=usr/share/terminfo/t/tvi912b+vb OLD_FILES+=usr/share/terminfo/t/tvi912b-2p OLD_FILES+=usr/share/terminfo/t/tvi912b-2p-mc OLD_FILES+=usr/share/terminfo/t/tvi912b-2p-p OLD_FILES+=usr/share/terminfo/t/tvi912b-2p-unk OLD_FILES+=usr/share/terminfo/t/tvi912b-mc OLD_FILES+=usr/share/terminfo/t/tvi912b-mc-2p OLD_FILES+=usr/share/terminfo/t/tvi912b-mc-vb OLD_FILES+=usr/share/terminfo/t/tvi912b-p OLD_FILES+=usr/share/terminfo/t/tvi912b-p-2p OLD_FILES+=usr/share/terminfo/t/tvi912b-p-vb OLD_FILES+=usr/share/terminfo/t/tvi912b-unk OLD_FILES+=usr/share/terminfo/t/tvi912b-unk-2p OLD_FILES+=usr/share/terminfo/t/tvi912b-unk-vb OLD_FILES+=usr/share/terminfo/t/tvi912b-vb OLD_FILES+=usr/share/terminfo/t/tvi912b-vb-mc OLD_FILES+=usr/share/terminfo/t/tvi912b-vb-p OLD_FILES+=usr/share/terminfo/t/tvi912b-vb-unk OLD_FILES+=usr/share/terminfo/t/tvi912c OLD_FILES+=usr/share/terminfo/t/tvi912c-2p OLD_FILES+=usr/share/terminfo/t/tvi912c-2p-mc OLD_FILES+=usr/share/terminfo/t/tvi912c-2p-p OLD_FILES+=usr/share/terminfo/t/tvi912c-2p-unk OLD_FILES+=usr/share/terminfo/t/tvi912c-mc OLD_FILES+=usr/share/terminfo/t/tvi912c-mc-2p OLD_FILES+=usr/share/terminfo/t/tvi912c-mc-vb OLD_FILES+=usr/share/terminfo/t/tvi912c-p OLD_FILES+=usr/share/terminfo/t/tvi912c-p-2p OLD_FILES+=usr/share/terminfo/t/tvi912c-p-vb OLD_FILES+=usr/share/terminfo/t/tvi912c-unk OLD_FILES+=usr/share/terminfo/t/tvi912c-unk-2p OLD_FILES+=usr/share/terminfo/t/tvi912c-unk-vb OLD_FILES+=usr/share/terminfo/t/tvi912c-vb OLD_FILES+=usr/share/terminfo/t/tvi912c-vb-mc OLD_FILES+=usr/share/terminfo/t/tvi912c-vb-p OLD_FILES+=usr/share/terminfo/t/tvi912c-vb-unk OLD_FILES+=usr/share/terminfo/t/tvi912cc OLD_FILES+=usr/share/terminfo/t/tvi914 OLD_FILES+=usr/share/terminfo/t/tvi920 OLD_FILES+=usr/share/terminfo/t/tvi920b OLD_FILES+=usr/share/terminfo/t/tvi920b+fn OLD_FILES+=usr/share/terminfo/t/tvi920b-2p OLD_FILES+=usr/share/terminfo/t/tvi920b-2p-mc OLD_FILES+=usr/share/terminfo/t/tvi920b-2p-p OLD_FILES+=usr/share/terminfo/t/tvi920b-2p-unk OLD_FILES+=usr/share/terminfo/t/tvi920b-mc OLD_FILES+=usr/share/terminfo/t/tvi920b-mc-2p OLD_FILES+=usr/share/terminfo/t/tvi920b-mc-vb OLD_FILES+=usr/share/terminfo/t/tvi920b-p OLD_FILES+=usr/share/terminfo/t/tvi920b-p-2p OLD_FILES+=usr/share/terminfo/t/tvi920b-p-vb OLD_FILES+=usr/share/terminfo/t/tvi920b-unk OLD_FILES+=usr/share/terminfo/t/tvi920b-unk-2p OLD_FILES+=usr/share/terminfo/t/tvi920b-unk-vb OLD_FILES+=usr/share/terminfo/t/tvi920b-vb OLD_FILES+=usr/share/terminfo/t/tvi920b-vb-mc OLD_FILES+=usr/share/terminfo/t/tvi920b-vb-p OLD_FILES+=usr/share/terminfo/t/tvi920b-vb-unk OLD_FILES+=usr/share/terminfo/t/tvi920c OLD_FILES+=usr/share/terminfo/t/tvi920c-2p OLD_FILES+=usr/share/terminfo/t/tvi920c-2p-mc OLD_FILES+=usr/share/terminfo/t/tvi920c-2p-p OLD_FILES+=usr/share/terminfo/t/tvi920c-2p-unk OLD_FILES+=usr/share/terminfo/t/tvi920c-mc OLD_FILES+=usr/share/terminfo/t/tvi920c-mc-2p OLD_FILES+=usr/share/terminfo/t/tvi920c-mc-vb OLD_FILES+=usr/share/terminfo/t/tvi920c-p OLD_FILES+=usr/share/terminfo/t/tvi920c-p-2p OLD_FILES+=usr/share/terminfo/t/tvi920c-p-vb OLD_FILES+=usr/share/terminfo/t/tvi920c-unk OLD_FILES+=usr/share/terminfo/t/tvi920c-unk-2p OLD_FILES+=usr/share/terminfo/t/tvi920c-unk-vb OLD_FILES+=usr/share/terminfo/t/tvi920c-vb OLD_FILES+=usr/share/terminfo/t/tvi920c-vb-mc OLD_FILES+=usr/share/terminfo/t/tvi920c-vb-p OLD_FILES+=usr/share/terminfo/t/tvi920c-vb-unk OLD_FILES+=usr/share/terminfo/t/tvi921 OLD_FILES+=usr/share/terminfo/t/tvi924 OLD_FILES+=usr/share/terminfo/t/tvi925 OLD_FILES+=usr/share/terminfo/t/tvi925-hi OLD_FILES+=usr/share/terminfo/t/tvi92B OLD_FILES+=usr/share/terminfo/t/tvi92D OLD_FILES+=usr/share/terminfo/t/tvi950 OLD_FILES+=usr/share/terminfo/t/tvi950-2p OLD_FILES+=usr/share/terminfo/t/tvi950-4p OLD_FILES+=usr/share/terminfo/t/tvi950-rv OLD_FILES+=usr/share/terminfo/t/tvi950-rv-2p OLD_FILES+=usr/share/terminfo/t/tvi950-rv-4p OLD_FILES+=usr/share/terminfo/t/tvi955 OLD_FILES+=usr/share/terminfo/t/tvi955-hb OLD_FILES+=usr/share/terminfo/t/tvi955-w OLD_FILES+=usr/share/terminfo/t/tvi970 OLD_FILES+=usr/share/terminfo/t/tvi970-2p OLD_FILES+=usr/share/terminfo/t/tvi970-vb OLD_FILES+=usr/share/terminfo/t/tvipt OLD_FILES+=usr/share/terminfo/t/tw100 OLD_FILES+=usr/share/terminfo/t/tw52 OLD_FILES+=usr/share/terminfo/t/tw52-color OLD_FILES+=usr/share/terminfo/t/tw52-m OLD_FILES+=usr/share/terminfo/t/tws-generic OLD_FILES+=usr/share/terminfo/t/tws2102-sna OLD_FILES+=usr/share/terminfo/t/tws2103 OLD_FILES+=usr/share/terminfo/t/tws2103-sna OLD_DIRS+=usr/share/terminfo/t/ OLD_FILES+=usr/share/terminfo/u/ultima2 OLD_FILES+=usr/share/terminfo/u/ultimaII OLD_FILES+=usr/share/terminfo/u/uniterm OLD_FILES+=usr/share/terminfo/u/uniterm49 OLD_FILES+=usr/share/terminfo/u/unixpc OLD_FILES+=usr/share/terminfo/u/unknown OLD_FILES+=usr/share/terminfo/u/uts30 OLD_FILES+=usr/share/terminfo/u/uwin OLD_DIRS+=usr/share/terminfo/u/ OLD_FILES+=usr/share/terminfo/v/v200-nam OLD_FILES+=usr/share/terminfo/v/v320n OLD_FILES+=usr/share/terminfo/v/v3220 OLD_FILES+=usr/share/terminfo/v/v5410 OLD_FILES+=usr/share/terminfo/v/vanilla OLD_FILES+=usr/share/terminfo/v/vapple OLD_FILES+=usr/share/terminfo/v/vc103 OLD_FILES+=usr/share/terminfo/v/vc203 OLD_FILES+=usr/share/terminfo/v/vc303 OLD_FILES+=usr/share/terminfo/v/vc303a OLD_FILES+=usr/share/terminfo/v/vc403a OLD_FILES+=usr/share/terminfo/v/vc404 OLD_FILES+=usr/share/terminfo/v/vc404-s OLD_FILES+=usr/share/terminfo/v/vc414 OLD_FILES+=usr/share/terminfo/v/vc414h OLD_FILES+=usr/share/terminfo/v/vc415 OLD_FILES+=usr/share/terminfo/v/venix OLD_FILES+=usr/share/terminfo/v/versaterm OLD_FILES+=usr/share/terminfo/v/vi200 OLD_FILES+=usr/share/terminfo/v/vi200-f OLD_FILES+=usr/share/terminfo/v/vi200-rv OLD_FILES+=usr/share/terminfo/v/vi300 OLD_FILES+=usr/share/terminfo/v/vi300-old OLD_FILES+=usr/share/terminfo/v/vi50 OLD_FILES+=usr/share/terminfo/v/vi500 OLD_FILES+=usr/share/terminfo/v/vi50adm OLD_FILES+=usr/share/terminfo/v/vi55 OLD_FILES+=usr/share/terminfo/v/vi550 OLD_FILES+=usr/share/terminfo/v/vi603 OLD_FILES+=usr/share/terminfo/v/viewdata OLD_FILES+=usr/share/terminfo/v/viewdata-o OLD_FILES+=usr/share/terminfo/v/viewdata-rv OLD_FILES+=usr/share/terminfo/v/viewpoint OLD_FILES+=usr/share/terminfo/v/viewpoint3a+ OLD_FILES+=usr/share/terminfo/v/viewpoint60 OLD_FILES+=usr/share/terminfo/v/viewpoint90 OLD_FILES+=usr/share/terminfo/v/vip OLD_FILES+=usr/share/terminfo/v/vip-H OLD_FILES+=usr/share/terminfo/v/vip-Hw OLD_FILES+=usr/share/terminfo/v/vip-w OLD_FILES+=usr/share/terminfo/v/vip7800-H OLD_FILES+=usr/share/terminfo/v/vip7800-Hw OLD_FILES+=usr/share/terminfo/v/vip7800-w OLD_FILES+=usr/share/terminfo/v/visa50 OLD_FILES+=usr/share/terminfo/v/visual603 OLD_FILES+=usr/share/terminfo/v/vitty OLD_FILES+=usr/share/terminfo/v/vk100 OLD_FILES+=usr/share/terminfo/v/vp3a+ OLD_FILES+=usr/share/terminfo/v/vp60 OLD_FILES+=usr/share/terminfo/v/vp90 OLD_FILES+=usr/share/terminfo/v/vremote OLD_FILES+=usr/share/terminfo/v/vs100 OLD_FILES+=usr/share/terminfo/v/vs100-x10 OLD_FILES+=usr/share/terminfo/v/vsc OLD_FILES+=usr/share/terminfo/v/vscode OLD_FILES+=usr/share/terminfo/v/vscode-direct OLD_FILES+=usr/share/terminfo/v/vt-61 OLD_FILES+=usr/share/terminfo/v/vt-utf8 OLD_FILES+=usr/share/terminfo/v/vt100 OLD_FILES+=usr/share/terminfo/v/vt100+ OLD_FILES+=usr/share/terminfo/v/vt100+4bsd OLD_FILES+=usr/share/terminfo/v/vt100+enq OLD_FILES+=usr/share/terminfo/v/vt100+fnkeys OLD_FILES+=usr/share/terminfo/v/vt100+keypad OLD_FILES+=usr/share/terminfo/v/vt100+pfkeys OLD_FILES+=usr/share/terminfo/v/vt100-am OLD_FILES+=usr/share/terminfo/v/vt100-bm OLD_FILES+=usr/share/terminfo/v/vt100-bm-o OLD_FILES+=usr/share/terminfo/v/vt100-bot-s OLD_FILES+=usr/share/terminfo/v/vt100-nam OLD_FILES+=usr/share/terminfo/v/vt100-nam-w OLD_FILES+=usr/share/terminfo/v/vt100-nav OLD_FILES+=usr/share/terminfo/v/vt100-nav-w OLD_FILES+=usr/share/terminfo/v/vt100-putty OLD_FILES+=usr/share/terminfo/v/vt100-s OLD_FILES+=usr/share/terminfo/v/vt100-s-bot OLD_FILES+=usr/share/terminfo/v/vt100-s-top OLD_FILES+=usr/share/terminfo/v/vt100-top-s OLD_FILES+=usr/share/terminfo/v/vt100-vb OLD_FILES+=usr/share/terminfo/v/vt100-w OLD_FILES+=usr/share/terminfo/v/vt100-w-am OLD_FILES+=usr/share/terminfo/v/vt100-w-nam OLD_FILES+=usr/share/terminfo/v/vt100-w-nav OLD_FILES+=usr/share/terminfo/v/vt100nam OLD_FILES+=usr/share/terminfo/v/vt102 OLD_FILES+=usr/share/terminfo/v/vt102+enq OLD_FILES+=usr/share/terminfo/v/vt102-nsgr OLD_FILES+=usr/share/terminfo/v/vt102-w OLD_FILES+=usr/share/terminfo/v/vt125 OLD_FILES+=usr/share/terminfo/v/vt131 OLD_FILES+=usr/share/terminfo/v/vt132 OLD_FILES+=usr/share/terminfo/v/vt200 OLD_FILES+=usr/share/terminfo/v/vt200-8 OLD_FILES+=usr/share/terminfo/v/vt200-8bit OLD_FILES+=usr/share/terminfo/v/vt200-js OLD_FILES+=usr/share/terminfo/v/vt200-old OLD_FILES+=usr/share/terminfo/v/vt200-w OLD_FILES+=usr/share/terminfo/v/vt220 OLD_FILES+=usr/share/terminfo/v/vt220+cvis OLD_FILES+=usr/share/terminfo/v/vt220+cvis8 OLD_FILES+=usr/share/terminfo/v/vt220+keypad OLD_FILES+=usr/share/terminfo/v/vt220+pcedit OLD_FILES+=usr/share/terminfo/v/vt220+vtedit OLD_FILES+=usr/share/terminfo/v/vt220-8 OLD_FILES+=usr/share/terminfo/v/vt220-8bit OLD_FILES+=usr/share/terminfo/v/vt220-base OLD_FILES+=usr/share/terminfo/v/vt220-js OLD_FILES+=usr/share/terminfo/v/vt220-nam OLD_FILES+=usr/share/terminfo/v/vt220-old OLD_FILES+=usr/share/terminfo/v/vt220-w OLD_FILES+=usr/share/terminfo/v/vt220d OLD_FILES+=usr/share/terminfo/v/vt300 OLD_FILES+=usr/share/terminfo/v/vt300-nam OLD_FILES+=usr/share/terminfo/v/vt300-w OLD_FILES+=usr/share/terminfo/v/vt300-w-nam OLD_FILES+=usr/share/terminfo/v/vt320 OLD_FILES+=usr/share/terminfo/v/vt320-k3 OLD_FILES+=usr/share/terminfo/v/vt320-k311 OLD_FILES+=usr/share/terminfo/v/vt320-nam OLD_FILES+=usr/share/terminfo/v/vt320-w OLD_FILES+=usr/share/terminfo/v/vt320-w-nam OLD_FILES+=usr/share/terminfo/v/vt320nam OLD_FILES+=usr/share/terminfo/v/vt330 OLD_FILES+=usr/share/terminfo/v/vt340 OLD_FILES+=usr/share/terminfo/v/vt400 OLD_FILES+=usr/share/terminfo/v/vt400-24 OLD_FILES+=usr/share/terminfo/v/vt420 OLD_FILES+=usr/share/terminfo/v/vt420+lrmm OLD_FILES+=usr/share/terminfo/v/vt420f OLD_FILES+=usr/share/terminfo/v/vt420pc OLD_FILES+=usr/share/terminfo/v/vt420pcdos OLD_FILES+=usr/share/terminfo/v/vt50 OLD_FILES+=usr/share/terminfo/v/vt50h OLD_FILES+=usr/share/terminfo/v/vt510 OLD_FILES+=usr/share/terminfo/v/vt510pc OLD_FILES+=usr/share/terminfo/v/vt510pcdos OLD_FILES+=usr/share/terminfo/v/vt52 OLD_FILES+=usr/share/terminfo/v/vt52+keypad OLD_FILES+=usr/share/terminfo/v/vt52-basic OLD_FILES+=usr/share/terminfo/v/vt520 OLD_FILES+=usr/share/terminfo/v/vt520ansi OLD_FILES+=usr/share/terminfo/v/vt525 OLD_FILES+=usr/share/terminfo/v/vt61 OLD_FILES+=usr/share/terminfo/v/vt61.5 OLD_FILES+=usr/share/terminfo/v/vte OLD_FILES+=usr/share/terminfo/v/vte+pcfkeys OLD_FILES+=usr/share/terminfo/v/vte-2007 OLD_FILES+=usr/share/terminfo/v/vte-2008 OLD_FILES+=usr/share/terminfo/v/vte-2012 OLD_FILES+=usr/share/terminfo/v/vte-2014 OLD_FILES+=usr/share/terminfo/v/vte-2017 OLD_FILES+=usr/share/terminfo/v/vte-2018 OLD_FILES+=usr/share/terminfo/v/vte-256color OLD_FILES+=usr/share/terminfo/v/vte-direct OLD_FILES+=usr/share/terminfo/v/vtnt OLD_FILES+=usr/share/terminfo/v/vv100 OLD_FILES+=usr/share/terminfo/v/vwmterm OLD_DIRS+=usr/share/terminfo/v/ OLD_FILES+=usr/share/terminfo/w/wren OLD_FILES+=usr/share/terminfo/w/wrenw OLD_FILES+=usr/share/terminfo/w/wsiris OLD_FILES+=usr/share/terminfo/w/wsvt25 OLD_FILES+=usr/share/terminfo/w/wsvt25m OLD_FILES+=usr/share/terminfo/w/wy-75ap OLD_FILES+=usr/share/terminfo/w/wy-99fgt OLD_FILES+=usr/share/terminfo/w/wy-99fgta OLD_FILES+=usr/share/terminfo/w/wy100 OLD_FILES+=usr/share/terminfo/w/wy100q OLD_FILES+=usr/share/terminfo/w/wy120 OLD_FILES+=usr/share/terminfo/w/wy120-25 OLD_FILES+=usr/share/terminfo/w/wy120-25-w OLD_FILES+=usr/share/terminfo/w/wy120-vb OLD_FILES+=usr/share/terminfo/w/wy120-w OLD_FILES+=usr/share/terminfo/w/wy120-w-vb OLD_FILES+=usr/share/terminfo/w/wy120-wvb OLD_FILES+=usr/share/terminfo/w/wy150 OLD_FILES+=usr/share/terminfo/w/wy150-25 OLD_FILES+=usr/share/terminfo/w/wy150-25-w OLD_FILES+=usr/share/terminfo/w/wy150-vb OLD_FILES+=usr/share/terminfo/w/wy150-w OLD_FILES+=usr/share/terminfo/w/wy150-w-vb OLD_FILES+=usr/share/terminfo/w/wy160 OLD_FILES+=usr/share/terminfo/w/wy160-25 OLD_FILES+=usr/share/terminfo/w/wy160-25-w OLD_FILES+=usr/share/terminfo/w/wy160-42 OLD_FILES+=usr/share/terminfo/w/wy160-42-w OLD_FILES+=usr/share/terminfo/w/wy160-43 OLD_FILES+=usr/share/terminfo/w/wy160-43-w OLD_FILES+=usr/share/terminfo/w/wy160-tek OLD_FILES+=usr/share/terminfo/w/wy160-vb OLD_FILES+=usr/share/terminfo/w/wy160-w OLD_FILES+=usr/share/terminfo/w/wy160-w-vb OLD_FILES+=usr/share/terminfo/w/wy160-wvb OLD_FILES+=usr/share/terminfo/w/wy185 OLD_FILES+=usr/share/terminfo/w/wy185-24 OLD_FILES+=usr/share/terminfo/w/wy185-vb OLD_FILES+=usr/share/terminfo/w/wy185-w OLD_FILES+=usr/share/terminfo/w/wy185-wvb OLD_FILES+=usr/share/terminfo/w/wy30 OLD_FILES+=usr/share/terminfo/w/wy30-mc OLD_FILES+=usr/share/terminfo/w/wy30-vb OLD_FILES+=usr/share/terminfo/w/wy325 OLD_FILES+=usr/share/terminfo/w/wy325-25 OLD_FILES+=usr/share/terminfo/w/wy325-25w OLD_FILES+=usr/share/terminfo/w/wy325-42 OLD_FILES+=usr/share/terminfo/w/wy325-42w OLD_FILES+=usr/share/terminfo/w/wy325-42w-vb OLD_FILES+=usr/share/terminfo/w/wy325-42wvb OLD_FILES+=usr/share/terminfo/w/wy325-43 OLD_FILES+=usr/share/terminfo/w/wy325-43w OLD_FILES+=usr/share/terminfo/w/wy325-43w-vb OLD_FILES+=usr/share/terminfo/w/wy325-43wvb OLD_FILES+=usr/share/terminfo/w/wy325-80 OLD_FILES+=usr/share/terminfo/w/wy325-vb OLD_FILES+=usr/share/terminfo/w/wy325-w OLD_FILES+=usr/share/terminfo/w/wy325-w-vb OLD_FILES+=usr/share/terminfo/w/wy325-wvb OLD_FILES+=usr/share/terminfo/w/wy325w-24 OLD_FILES+=usr/share/terminfo/w/wy350 OLD_FILES+=usr/share/terminfo/w/wy350-vb OLD_FILES+=usr/share/terminfo/w/wy350-w OLD_FILES+=usr/share/terminfo/w/wy350-wvb OLD_FILES+=usr/share/terminfo/w/wy370 OLD_FILES+=usr/share/terminfo/w/wy370-101k OLD_FILES+=usr/share/terminfo/w/wy370-105k OLD_FILES+=usr/share/terminfo/w/wy370-EPC OLD_FILES+=usr/share/terminfo/w/wy370-nk OLD_FILES+=usr/share/terminfo/w/wy370-rv OLD_FILES+=usr/share/terminfo/w/wy370-tek OLD_FILES+=usr/share/terminfo/w/wy370-vb OLD_FILES+=usr/share/terminfo/w/wy370-w OLD_FILES+=usr/share/terminfo/w/wy370-wvb OLD_FILES+=usr/share/terminfo/w/wy50 OLD_FILES+=usr/share/terminfo/w/wy50-mc OLD_FILES+=usr/share/terminfo/w/wy50-vb OLD_FILES+=usr/share/terminfo/w/wy50-w OLD_FILES+=usr/share/terminfo/w/wy50-wvb OLD_FILES+=usr/share/terminfo/w/wy520 OLD_FILES+=usr/share/terminfo/w/wy520-24 OLD_FILES+=usr/share/terminfo/w/wy520-36 OLD_FILES+=usr/share/terminfo/w/wy520-36pc OLD_FILES+=usr/share/terminfo/w/wy520-36w OLD_FILES+=usr/share/terminfo/w/wy520-36wpc OLD_FILES+=usr/share/terminfo/w/wy520-48 OLD_FILES+=usr/share/terminfo/w/wy520-48pc OLD_FILES+=usr/share/terminfo/w/wy520-48w OLD_FILES+=usr/share/terminfo/w/wy520-48wpc OLD_FILES+=usr/share/terminfo/w/wy520-epc OLD_FILES+=usr/share/terminfo/w/wy520-epc-24 OLD_FILES+=usr/share/terminfo/w/wy520-epc-vb OLD_FILES+=usr/share/terminfo/w/wy520-epc-w OLD_FILES+=usr/share/terminfo/w/wy520-epc-wvb OLD_FILES+=usr/share/terminfo/w/wy520-vb OLD_FILES+=usr/share/terminfo/w/wy520-w OLD_FILES+=usr/share/terminfo/w/wy520-wvb OLD_FILES+=usr/share/terminfo/w/wy60 OLD_FILES+=usr/share/terminfo/w/wy60-25 OLD_FILES+=usr/share/terminfo/w/wy60-25-w OLD_FILES+=usr/share/terminfo/w/wy60-316X OLD_FILES+=usr/share/terminfo/w/wy60-42 OLD_FILES+=usr/share/terminfo/w/wy60-42-w OLD_FILES+=usr/share/terminfo/w/wy60-43 OLD_FILES+=usr/share/terminfo/w/wy60-43-w OLD_FILES+=usr/share/terminfo/w/wy60-AT OLD_FILES+=usr/share/terminfo/w/wy60-PC OLD_FILES+=usr/share/terminfo/w/wy60-vb OLD_FILES+=usr/share/terminfo/w/wy60-w OLD_FILES+=usr/share/terminfo/w/wy60-w-vb OLD_FILES+=usr/share/terminfo/w/wy60-wvb OLD_FILES+=usr/share/terminfo/w/wy75 OLD_FILES+=usr/share/terminfo/w/wy75-mc OLD_FILES+=usr/share/terminfo/w/wy75-vb OLD_FILES+=usr/share/terminfo/w/wy75-w OLD_FILES+=usr/share/terminfo/w/wy75-wvb OLD_FILES+=usr/share/terminfo/w/wy75ap OLD_FILES+=usr/share/terminfo/w/wy85 OLD_FILES+=usr/share/terminfo/w/wy85-8bit OLD_FILES+=usr/share/terminfo/w/wy85-vb OLD_FILES+=usr/share/terminfo/w/wy85-w OLD_FILES+=usr/share/terminfo/w/wy85-wvb OLD_FILES+=usr/share/terminfo/w/wy99-ansi OLD_FILES+=usr/share/terminfo/w/wy99a-ansi OLD_FILES+=usr/share/terminfo/w/wy99f OLD_FILES+=usr/share/terminfo/w/wy99fa OLD_FILES+=usr/share/terminfo/w/wy99fgt OLD_FILES+=usr/share/terminfo/w/wy99fgta OLD_FILES+=usr/share/terminfo/w/wy99gt OLD_FILES+=usr/share/terminfo/w/wy99gt-25 OLD_FILES+=usr/share/terminfo/w/wy99gt-25-w OLD_FILES+=usr/share/terminfo/w/wy99gt-tek OLD_FILES+=usr/share/terminfo/w/wy99gt-vb OLD_FILES+=usr/share/terminfo/w/wy99gt-w OLD_FILES+=usr/share/terminfo/w/wy99gt-w-vb OLD_FILES+=usr/share/terminfo/w/wy99gt-wvb OLD_FILES+=usr/share/terminfo/w/wyse-325 OLD_FILES+=usr/share/terminfo/w/wyse-75ap OLD_FILES+=usr/share/terminfo/w/wyse-vp OLD_FILES+=usr/share/terminfo/w/wyse120 OLD_FILES+=usr/share/terminfo/w/wyse120-25 OLD_FILES+=usr/share/terminfo/w/wyse120-25-w OLD_FILES+=usr/share/terminfo/w/wyse120-vb OLD_FILES+=usr/share/terminfo/w/wyse120-w OLD_FILES+=usr/share/terminfo/w/wyse120-wvb OLD_FILES+=usr/share/terminfo/w/wyse150 OLD_FILES+=usr/share/terminfo/w/wyse150-25 OLD_FILES+=usr/share/terminfo/w/wyse150-25-w OLD_FILES+=usr/share/terminfo/w/wyse150-vb OLD_FILES+=usr/share/terminfo/w/wyse150-w OLD_FILES+=usr/share/terminfo/w/wyse150-w-vb OLD_FILES+=usr/share/terminfo/w/wyse160 OLD_FILES+=usr/share/terminfo/w/wyse160-25 OLD_FILES+=usr/share/terminfo/w/wyse160-25-w OLD_FILES+=usr/share/terminfo/w/wyse160-42 OLD_FILES+=usr/share/terminfo/w/wyse160-42-w OLD_FILES+=usr/share/terminfo/w/wyse160-43 OLD_FILES+=usr/share/terminfo/w/wyse160-43-w OLD_FILES+=usr/share/terminfo/w/wyse160-vb OLD_FILES+=usr/share/terminfo/w/wyse160-w OLD_FILES+=usr/share/terminfo/w/wyse160-wvb OLD_FILES+=usr/share/terminfo/w/wyse185 OLD_FILES+=usr/share/terminfo/w/wyse185-24 OLD_FILES+=usr/share/terminfo/w/wyse185-vb OLD_FILES+=usr/share/terminfo/w/wyse185-w OLD_FILES+=usr/share/terminfo/w/wyse185-wvb OLD_FILES+=usr/share/terminfo/w/wyse30 OLD_FILES+=usr/share/terminfo/w/wyse30-mc OLD_FILES+=usr/share/terminfo/w/wyse30-vb OLD_FILES+=usr/share/terminfo/w/wyse325 OLD_FILES+=usr/share/terminfo/w/wyse325-25 OLD_FILES+=usr/share/terminfo/w/wyse325-25w OLD_FILES+=usr/share/terminfo/w/wyse325-42 OLD_FILES+=usr/share/terminfo/w/wyse325-42w OLD_FILES+=usr/share/terminfo/w/wyse325-43 OLD_FILES+=usr/share/terminfo/w/wyse325-43w OLD_FILES+=usr/share/terminfo/w/wyse325-vb OLD_FILES+=usr/share/terminfo/w/wyse325-w OLD_FILES+=usr/share/terminfo/w/wyse325-wvb OLD_FILES+=usr/share/terminfo/w/wyse350 OLD_FILES+=usr/share/terminfo/w/wyse350-vb OLD_FILES+=usr/share/terminfo/w/wyse350-w OLD_FILES+=usr/share/terminfo/w/wyse350-wvb OLD_FILES+=usr/share/terminfo/w/wyse370 OLD_FILES+=usr/share/terminfo/w/wyse50 OLD_FILES+=usr/share/terminfo/w/wyse50-mc OLD_FILES+=usr/share/terminfo/w/wyse50-vb OLD_FILES+=usr/share/terminfo/w/wyse50-w OLD_FILES+=usr/share/terminfo/w/wyse50-wvb OLD_FILES+=usr/share/terminfo/w/wyse520 OLD_FILES+=usr/share/terminfo/w/wyse520-24 OLD_FILES+=usr/share/terminfo/w/wyse520-36 OLD_FILES+=usr/share/terminfo/w/wyse520-36pc OLD_FILES+=usr/share/terminfo/w/wyse520-36w OLD_FILES+=usr/share/terminfo/w/wyse520-36wpc OLD_FILES+=usr/share/terminfo/w/wyse520-48 OLD_FILES+=usr/share/terminfo/w/wyse520-48pc OLD_FILES+=usr/share/terminfo/w/wyse520-48w OLD_FILES+=usr/share/terminfo/w/wyse520-48wpc OLD_FILES+=usr/share/terminfo/w/wyse520-epc OLD_FILES+=usr/share/terminfo/w/wyse520-epc-w OLD_FILES+=usr/share/terminfo/w/wyse520-p-wvb OLD_FILES+=usr/share/terminfo/w/wyse520-pc-24 OLD_FILES+=usr/share/terminfo/w/wyse520-pc-vb OLD_FILES+=usr/share/terminfo/w/wyse520-vb OLD_FILES+=usr/share/terminfo/w/wyse520-w OLD_FILES+=usr/share/terminfo/w/wyse520-wvb OLD_FILES+=usr/share/terminfo/w/wyse60 OLD_FILES+=usr/share/terminfo/w/wyse60-25 OLD_FILES+=usr/share/terminfo/w/wyse60-25-w OLD_FILES+=usr/share/terminfo/w/wyse60-316X OLD_FILES+=usr/share/terminfo/w/wyse60-42 OLD_FILES+=usr/share/terminfo/w/wyse60-42-w OLD_FILES+=usr/share/terminfo/w/wyse60-43 OLD_FILES+=usr/share/terminfo/w/wyse60-43-w OLD_FILES+=usr/share/terminfo/w/wyse60-AT OLD_FILES+=usr/share/terminfo/w/wyse60-PC OLD_FILES+=usr/share/terminfo/w/wyse60-vb OLD_FILES+=usr/share/terminfo/w/wyse60-w OLD_FILES+=usr/share/terminfo/w/wyse60-wvb OLD_FILES+=usr/share/terminfo/w/wyse75 OLD_FILES+=usr/share/terminfo/w/wyse75-mc OLD_FILES+=usr/share/terminfo/w/wyse75-vb OLD_FILES+=usr/share/terminfo/w/wyse75-w OLD_FILES+=usr/share/terminfo/w/wyse75-wvb OLD_FILES+=usr/share/terminfo/w/wyse75ap OLD_FILES+=usr/share/terminfo/w/wyse85 OLD_FILES+=usr/share/terminfo/w/wyse85-8bit OLD_FILES+=usr/share/terminfo/w/wyse85-vb OLD_FILES+=usr/share/terminfo/w/wyse85-w OLD_FILES+=usr/share/terminfo/w/wyse85-wvb OLD_FILES+=usr/share/terminfo/w/wyse99gt OLD_FILES+=usr/share/terminfo/w/wyse99gt-25 OLD_FILES+=usr/share/terminfo/w/wyse99gt-25-w OLD_FILES+=usr/share/terminfo/w/wyse99gt-vb OLD_FILES+=usr/share/terminfo/w/wyse99gt-w OLD_FILES+=usr/share/terminfo/w/wyse99gt-wvb OLD_DIRS+=usr/share/terminfo/w/ OLD_FILES+=usr/share/terminfo/x/x10term OLD_FILES+=usr/share/terminfo/x/x1700 OLD_FILES+=usr/share/terminfo/x/x1700-lm OLD_FILES+=usr/share/terminfo/x/x1720 OLD_FILES+=usr/share/terminfo/x/x1750 OLD_FILES+=usr/share/terminfo/x/x68k OLD_FILES+=usr/share/terminfo/x/x68k-ite OLD_FILES+=usr/share/terminfo/x/x820 OLD_FILES+=usr/share/terminfo/x/xdku OLD_FILES+=usr/share/terminfo/x/xenix OLD_FILES+=usr/share/terminfo/x/xerox OLD_FILES+=usr/share/terminfo/x/xerox-lm OLD_FILES+=usr/share/terminfo/x/xerox1720 OLD_FILES+=usr/share/terminfo/x/xerox820 OLD_FILES+=usr/share/terminfo/x/xfce OLD_FILES+=usr/share/terminfo/x/xiterm OLD_FILES+=usr/share/terminfo/x/xl83 OLD_FILES+=usr/share/terminfo/x/xnuppc OLD_FILES+=usr/share/terminfo/x/xnuppc+100x37 OLD_FILES+=usr/share/terminfo/x/xnuppc+112x37 OLD_FILES+=usr/share/terminfo/x/xnuppc+128x40 OLD_FILES+=usr/share/terminfo/x/xnuppc+128x48 OLD_FILES+=usr/share/terminfo/x/xnuppc+144x48 OLD_FILES+=usr/share/terminfo/x/xnuppc+160x64 OLD_FILES+=usr/share/terminfo/x/xnuppc+200x64 OLD_FILES+=usr/share/terminfo/x/xnuppc+200x75 OLD_FILES+=usr/share/terminfo/x/xnuppc+256x96 OLD_FILES+=usr/share/terminfo/x/xnuppc+80x25 OLD_FILES+=usr/share/terminfo/x/xnuppc+80x30 OLD_FILES+=usr/share/terminfo/x/xnuppc+90x30 OLD_FILES+=usr/share/terminfo/x/xnuppc+b OLD_FILES+=usr/share/terminfo/x/xnuppc+basic OLD_FILES+=usr/share/terminfo/x/xnuppc+c OLD_FILES+=usr/share/terminfo/x/xnuppc+f OLD_FILES+=usr/share/terminfo/x/xnuppc+f2 OLD_FILES+=usr/share/terminfo/x/xnuppc-100x37 OLD_FILES+=usr/share/terminfo/x/xnuppc-100x37-m OLD_FILES+=usr/share/terminfo/x/xnuppc-112x37 OLD_FILES+=usr/share/terminfo/x/xnuppc-112x37-m OLD_FILES+=usr/share/terminfo/x/xnuppc-128x40 OLD_FILES+=usr/share/terminfo/x/xnuppc-128x40-m OLD_FILES+=usr/share/terminfo/x/xnuppc-128x48 OLD_FILES+=usr/share/terminfo/x/xnuppc-128x48-m OLD_FILES+=usr/share/terminfo/x/xnuppc-144x48 OLD_FILES+=usr/share/terminfo/x/xnuppc-144x48-m OLD_FILES+=usr/share/terminfo/x/xnuppc-160x64 OLD_FILES+=usr/share/terminfo/x/xnuppc-160x64-m OLD_FILES+=usr/share/terminfo/x/xnuppc-200x64 OLD_FILES+=usr/share/terminfo/x/xnuppc-200x64-m OLD_FILES+=usr/share/terminfo/x/xnuppc-200x75 OLD_FILES+=usr/share/terminfo/x/xnuppc-200x75-m OLD_FILES+=usr/share/terminfo/x/xnuppc-256x96 OLD_FILES+=usr/share/terminfo/x/xnuppc-256x96-m OLD_FILES+=usr/share/terminfo/x/xnuppc-80x25 OLD_FILES+=usr/share/terminfo/x/xnuppc-80x25-m OLD_FILES+=usr/share/terminfo/x/xnuppc-80x30 OLD_FILES+=usr/share/terminfo/x/xnuppc-80x30-m OLD_FILES+=usr/share/terminfo/x/xnuppc-90x30 OLD_FILES+=usr/share/terminfo/x/xnuppc-90x30-m OLD_FILES+=usr/share/terminfo/x/xnuppc-b OLD_FILES+=usr/share/terminfo/x/xnuppc-f OLD_FILES+=usr/share/terminfo/x/xnuppc-f2 OLD_FILES+=usr/share/terminfo/x/xnuppc-m OLD_FILES+=usr/share/terminfo/x/xnuppc-m-b OLD_FILES+=usr/share/terminfo/x/xnuppc-m-f OLD_FILES+=usr/share/terminfo/x/xnuppc-m-f2 OLD_FILES+=usr/share/terminfo/x/xtalk OLD_FILES+=usr/share/terminfo/x/xterm OLD_FILES+=usr/share/terminfo/x/xterm+256color OLD_FILES+=usr/share/terminfo/x/xterm+256color2 OLD_FILES+=usr/share/terminfo/x/xterm+256setaf OLD_FILES+=usr/share/terminfo/x/xterm+88color OLD_FILES+=usr/share/terminfo/x/xterm+88color2 OLD_FILES+=usr/share/terminfo/x/xterm+alt+title OLD_FILES+=usr/share/terminfo/x/xterm+alt1049 OLD_FILES+=usr/share/terminfo/x/xterm+app OLD_FILES+=usr/share/terminfo/x/xterm+direct OLD_FILES+=usr/share/terminfo/x/xterm+direct16 OLD_FILES+=usr/share/terminfo/x/xterm+direct2 OLD_FILES+=usr/share/terminfo/x/xterm+direct256 OLD_FILES+=usr/share/terminfo/x/xterm+edit OLD_FILES+=usr/share/terminfo/x/xterm+indirect OLD_FILES+=usr/share/terminfo/x/xterm+kbs OLD_FILES+=usr/share/terminfo/x/xterm+keypad OLD_FILES+=usr/share/terminfo/x/xterm+meta OLD_FILES+=usr/share/terminfo/x/xterm+noalt OLD_FILES+=usr/share/terminfo/x/xterm+noapp OLD_FILES+=usr/share/terminfo/x/xterm+nofkeys OLD_FILES+=usr/share/terminfo/x/xterm+osc104 OLD_FILES+=usr/share/terminfo/x/xterm+pc+edit OLD_FILES+=usr/share/terminfo/x/xterm+pcc0 OLD_FILES+=usr/share/terminfo/x/xterm+pcc1 OLD_FILES+=usr/share/terminfo/x/xterm+pcc2 OLD_FILES+=usr/share/terminfo/x/xterm+pcc3 OLD_FILES+=usr/share/terminfo/x/xterm+pce2 OLD_FILES+=usr/share/terminfo/x/xterm+pcf0 OLD_FILES+=usr/share/terminfo/x/xterm+pcf2 OLD_FILES+=usr/share/terminfo/x/xterm+pcfkeys OLD_FILES+=usr/share/terminfo/x/xterm+r6f2 OLD_FILES+=usr/share/terminfo/x/xterm+sl OLD_FILES+=usr/share/terminfo/x/xterm+sl-twm OLD_FILES+=usr/share/terminfo/x/xterm+sm+1002 OLD_FILES+=usr/share/terminfo/x/xterm+sm+1003 OLD_FILES+=usr/share/terminfo/x/xterm+sm+1005 OLD_FILES+=usr/share/terminfo/x/xterm+sm+1006 OLD_FILES+=usr/share/terminfo/x/xterm+titlestack OLD_FILES+=usr/share/terminfo/x/xterm+tmux OLD_FILES+=usr/share/terminfo/x/xterm+vt+edit OLD_FILES+=usr/share/terminfo/x/xterm+x10mouse OLD_FILES+=usr/share/terminfo/x/xterm+x11hilite OLD_FILES+=usr/share/terminfo/x/xterm+x11mouse OLD_FILES+=usr/share/terminfo/x/xterm-1002 OLD_FILES+=usr/share/terminfo/x/xterm-1003 OLD_FILES+=usr/share/terminfo/x/xterm-1005 OLD_FILES+=usr/share/terminfo/x/xterm-1006 OLD_FILES+=usr/share/terminfo/x/xterm-16color OLD_FILES+=usr/share/terminfo/x/xterm-24 OLD_FILES+=usr/share/terminfo/x/xterm-256color OLD_FILES+=usr/share/terminfo/x/xterm-88color OLD_FILES+=usr/share/terminfo/x/xterm-8bit OLD_FILES+=usr/share/terminfo/x/xterm-basic OLD_FILES+=usr/share/terminfo/x/xterm-bold OLD_FILES+=usr/share/terminfo/x/xterm-color OLD_FILES+=usr/share/terminfo/x/xterm-direct OLD_FILES+=usr/share/terminfo/x/xterm-direct16 OLD_FILES+=usr/share/terminfo/x/xterm-direct2 OLD_FILES+=usr/share/terminfo/x/xterm-direct256 OLD_FILES+=usr/share/terminfo/x/xterm-hp OLD_FILES+=usr/share/terminfo/x/xterm-mono OLD_FILES+=usr/share/terminfo/x/xterm-new OLD_FILES+=usr/share/terminfo/x/xterm-nic OLD_FILES+=usr/share/terminfo/x/xterm-noapp OLD_FILES+=usr/share/terminfo/x/xterm-old OLD_FILES+=usr/share/terminfo/x/xterm-pcolor OLD_FILES+=usr/share/terminfo/x/xterm-r5 OLD_FILES+=usr/share/terminfo/x/xterm-r6 OLD_FILES+=usr/share/terminfo/x/xterm-sco OLD_FILES+=usr/share/terminfo/x/xterm-sun OLD_FILES+=usr/share/terminfo/x/xterm-utf8 OLD_FILES+=usr/share/terminfo/x/xterm-vt220 OLD_FILES+=usr/share/terminfo/x/xterm-vt52 OLD_FILES+=usr/share/terminfo/x/xterm-x10mouse OLD_FILES+=usr/share/terminfo/x/xterm-x11hilite OLD_FILES+=usr/share/terminfo/x/xterm-x11mouse OLD_FILES+=usr/share/terminfo/x/xterm-xf86-v32 OLD_FILES+=usr/share/terminfo/x/xterm-xf86-v33 OLD_FILES+=usr/share/terminfo/x/xterm-xf86-v333 OLD_FILES+=usr/share/terminfo/x/xterm-xf86-v40 OLD_FILES+=usr/share/terminfo/x/xterm-xf86-v43 OLD_FILES+=usr/share/terminfo/x/xterm-xf86-v44 OLD_FILES+=usr/share/terminfo/x/xterm-xfree86 OLD_FILES+=usr/share/terminfo/x/xterm-xi OLD_FILES+=usr/share/terminfo/x/xterm.js OLD_FILES+=usr/share/terminfo/x/xterm1 OLD_FILES+=usr/share/terminfo/x/xtermc OLD_FILES+=usr/share/terminfo/x/xtermm OLD_FILES+=usr/share/terminfo/x/xterms OLD_FILES+=usr/share/terminfo/x/xterms-sun OLD_FILES+=usr/share/terminfo/x/xwsh OLD_DIRS+=usr/share/terminfo/x/ OLD_FILES+=usr/share/terminfo/z/z-100 OLD_FILES+=usr/share/terminfo/z/z-100bw OLD_FILES+=usr/share/terminfo/z/z100 OLD_FILES+=usr/share/terminfo/z/z100bw OLD_FILES+=usr/share/terminfo/z/z110 OLD_FILES+=usr/share/terminfo/z/z110bw OLD_FILES+=usr/share/terminfo/z/z19 OLD_FILES+=usr/share/terminfo/z/z29 OLD_FILES+=usr/share/terminfo/z/z29a OLD_FILES+=usr/share/terminfo/z/z29a-kc-bc OLD_FILES+=usr/share/terminfo/z/z29a-kc-uc OLD_FILES+=usr/share/terminfo/z/z29a-nkc-bc OLD_FILES+=usr/share/terminfo/z/z29a-nkc-uc OLD_FILES+=usr/share/terminfo/z/z29b OLD_FILES+=usr/share/terminfo/z/z30 OLD_FILES+=usr/share/terminfo/z/z340 OLD_FILES+=usr/share/terminfo/z/z340-nam OLD_FILES+=usr/share/terminfo/z/z39-a OLD_FILES+=usr/share/terminfo/z/z39a OLD_FILES+=usr/share/terminfo/z/z50 OLD_FILES+=usr/share/terminfo/z/z8001 OLD_FILES+=usr/share/terminfo/z/zen30 OLD_FILES+=usr/share/terminfo/z/zen50 OLD_FILES+=usr/share/terminfo/z/zen8001 OLD_FILES+=usr/share/terminfo/z/zenith OLD_FILES+=usr/share/terminfo/z/zenith29 OLD_FILES+=usr/share/terminfo/z/zenith39-a OLD_FILES+=usr/share/terminfo/z/zenith39-ansi OLD_FILES+=usr/share/terminfo/z/zt-1 OLD_FILES+=usr/share/terminfo/z/ztx OLD_FILES+=usr/share/terminfo/z/ztx-1-a OLD_FILES+=usr/share/terminfo/z/ztx11 OLD_DIRS+=usr/share/terminfo/z/ OLD_DIRS+=usr/share/terminfo/ # 20210316: remove obsolete NFS headers OLD_FILES+=usr/include/nfs/nfs_common.h OLD_FILES+=usr/include/nfsclient/nfsm_subs.h OLD_FILES+=usr/include/nfsclient/nlminfo.h OLD_FILES+=usr/include/nfsserver/nfs_fha_old.h OLD_FILES+=usr/include/nfsserver/nfsm_subs.h OLD_FILES+=usr/include/nfsserver/nfsrvcache.h # 20210315: Remove kernel-only crypto headers from /usr/include OLD_FILES+=usr/include/crypto/_cryptodev.h OLD_FILES+=usr/include/crypto/cbc_mac.h OLD_FILES+=usr/include/crypto/deflate.h OLD_FILES+=usr/include/crypto/gfmult.h OLD_FILES+=usr/include/crypto/gmac.h OLD_FILES+=usr/include/crypto/rijndael.h OLD_FILES+=usr/include/crypto/rmd160.h OLD_FILES+=usr/include/crypto/xform.h OLD_FILES+=usr/include/crypto/xform_auth.h OLD_FILES+=usr/include/crypto/xform_comp.h OLD_FILES+=usr/include/crypto/xform_enc.h # 20210305: removed Poly1305_* symbols OLD_FILES+=usr/include/crypto/xform_poly1305.h # 20210302: fmtree removed OLD_FILES+=usr/sbin/fmtree OLD_FILES+=usr/share/man/man8/fmtree.8.gz # 20210201: bump shared libraries which link against ncurses OLD_LIBS+=lib/libedit.so.7 OLD_LIBS+=usr/lib/libdialog.so.8 OLD_LIBS+=usr/lib/libdpv.so.1 OLD_LIBS+=usr/lib/libform.so.5 OLD_LIBS+=usr/lib/libformw.so.5 OLD_LIBS+=usr/lib/libmenu.so.5 OLD_LIBS+=usr/lib/libmenuw.so.5 OLD_LIBS+=usr/lib/libpanel.so.5 OLD_LIBS+=usr/lib/libpanelw.so.5 # 20210125: ndis driver support removed OLD_FILES+=usr/sbin/ndis_events OLD_FILES+=usr/sbin/ndiscvt OLD_FILES+=usr/sbin/ndisgen OLD_FILES+=usr/share/man/man4/ndis.4.gz OLD_FILES+=usr/share/man/man4/if_ndis.4.gz OLD_FILES+=usr/share/man/man8/ndis_events.8.gz OLD_FILES+=usr/share/man/man8/ndiscvt.8.gz OLD_FILES+=usr/share/man/man8/ndisgen.8.gz OLD_FILES+=usr/share/misc/windrv_stub.c # 20210116: if_wl_wavelan.h removed .if ${TARGET_ARCH} == "i386" OLD_FILES+=usr/include/machine/if_wl_wavelan.h .endif # 20210108: retire cmx, ng_bt3c, wi drivers OLD_FILES+=usr/include/dev/wi/if_wireg.h OLD_FILES+=usr/include/dev/wi/if_wavelan_ieee.h OLD_FILES+=usr/include/dev/wi/if_wivar.h OLD_FILES+=usr/sbin/bt3cfw OLD_FILES+=usr/share/man/man4/cmw.4.gz OLD_FILES+=usr/share/man/man4/if_wi.4.gz OLD_FILES+=usr/share/man/man4/ng_bt3c.4.gz OLD_FILES+=usr/share/man/man4/wi.4.gz OLD_FILES+=usr/share/man/man8/bt3cfw.8.gz # 20210107: retire a.out support OLD_DIRS+=usr/lib/aout OLD_DIRS+=usr/lib/compat/aout # 20210107: remove cmx(4) OLD_FILES+=usr/share/man/man4/cmx.4.gz # 20210105: remove non widechar version of ncurses OLD_LIBS+=lib/libncurses.so.9 # 20210103: new clang import which bumps version from 11.0.0 to 11.0.1 OLD_FILES+=usr/lib/clang/11.0.0/include/cuda_wrappers/algorithm OLD_FILES+=usr/lib/clang/11.0.0/include/cuda_wrappers/complex OLD_FILES+=usr/lib/clang/11.0.0/include/cuda_wrappers/new OLD_DIRS+=usr/lib/clang/11.0.0/include/cuda_wrappers OLD_FILES+=usr/lib/clang/11.0.0/include/fuzzer/FuzzedDataProvider.h OLD_DIRS+=usr/lib/clang/11.0.0/include/fuzzer OLD_FILES+=usr/lib/clang/11.0.0/include/openmp_wrappers/__clang_openmp_device_functions.h OLD_FILES+=usr/lib/clang/11.0.0/include/openmp_wrappers/cmath OLD_FILES+=usr/lib/clang/11.0.0/include/openmp_wrappers/complex OLD_FILES+=usr/lib/clang/11.0.0/include/openmp_wrappers/complex.h OLD_FILES+=usr/lib/clang/11.0.0/include/openmp_wrappers/math.h OLD_FILES+=usr/lib/clang/11.0.0/include/openmp_wrappers/new OLD_DIRS+=usr/lib/clang/11.0.0/include/openmp_wrappers OLD_FILES+=usr/lib/clang/11.0.0/include/ppc_wrappers/emmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/ppc_wrappers/mm_malloc.h OLD_FILES+=usr/lib/clang/11.0.0/include/ppc_wrappers/mmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/ppc_wrappers/pmmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/ppc_wrappers/smmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/ppc_wrappers/tmmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/ppc_wrappers/xmmintrin.h OLD_DIRS+=usr/lib/clang/11.0.0/include/ppc_wrappers OLD_FILES+=usr/lib/clang/11.0.0/include/profile/InstrProfData.inc OLD_DIRS+=usr/lib/clang/11.0.0/include/profile OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/tsan_interface_atomic.h OLD_FILES+=usr/lib/clang/11.0.0/include/sanitizer/ubsan_interface.h OLD_DIRS+=usr/lib/clang/11.0.0/include/sanitizer OLD_FILES+=usr/lib/clang/11.0.0/include/xray/xray_interface.h OLD_FILES+=usr/lib/clang/11.0.0/include/xray/xray_log_interface.h OLD_FILES+=usr/lib/clang/11.0.0/include/xray/xray_records.h OLD_DIRS+=usr/lib/clang/11.0.0/include/xray OLD_FILES+=usr/lib/clang/11.0.0/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/11.0.0/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/11.0.0/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/11.0.0/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/11.0.0/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/11.0.0/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/11.0.0/include/__clang_cuda_math.h OLD_FILES+=usr/lib/clang/11.0.0/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/11.0.0/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/11.0.0/include/__clang_hip_libdevice_declares.h OLD_FILES+=usr/lib/clang/11.0.0/include/__clang_hip_math.h OLD_FILES+=usr/lib/clang/11.0.0/include/__clang_hip_runtime_wrapper.h OLD_FILES+=usr/lib/clang/11.0.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/11.0.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/11.0.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/11.0.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/altivec.h OLD_FILES+=usr/lib/clang/11.0.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/amxintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/arm64intr.h OLD_FILES+=usr/lib/clang/11.0.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/11.0.0/include/arm_bf16.h OLD_FILES+=usr/lib/clang/11.0.0/include/arm_cde.h OLD_FILES+=usr/lib/clang/11.0.0/include/arm_cmse.h OLD_FILES+=usr/lib/clang/11.0.0/include/arm_fp16.h OLD_FILES+=usr/lib/clang/11.0.0/include/arm_mve.h OLD_FILES+=usr/lib/clang/11.0.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/11.0.0/include/arm_sve.h OLD_FILES+=usr/lib/clang/11.0.0/include/armintr.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512bf16intrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vlbf16intrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vlvp2intersectintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vp2intersectintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/cet.h OLD_FILES+=usr/lib/clang/11.0.0/include/cetintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/clwbintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/clzerointrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/cpuid.h OLD_FILES+=usr/lib/clang/11.0.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/enqcmdintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/gfniintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/htmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/immintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/lwpintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/11.0.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/11.0.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/module.modulemap OLD_FILES+=usr/lib/clang/11.0.0/include/movdirintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/msa.h OLD_FILES+=usr/lib/clang/11.0.0/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/opencl-c-base.h OLD_FILES+=usr/lib/clang/11.0.0/include/opencl-c.h OLD_FILES+=usr/lib/clang/11.0.0/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/pkuintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/s390intrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/serializeintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/sgxintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/tsxldtrkintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/vadefs.h OLD_FILES+=usr/lib/clang/11.0.0/include/vaesintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/vecintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/wasm_simd128.h OLD_FILES+=usr/lib/clang/11.0.0/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/xopintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/11.0.0/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/11.0.0/include OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-aarch64.so OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-arm.so OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-armhf.so OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-preinit-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-preinit-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-preinit-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan_cxx-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan_cxx-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.cfi-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.cfi-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.cfi-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.cfi-i386.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.cfi-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.cfi_diag-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.cfi_diag-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.cfi_diag-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.cfi_diag-i386.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.cfi_diag-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.dd-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.dd-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.fuzzer-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.fuzzer-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.msan-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.msan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.profile-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.profile-powerpc.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.profile-powerpc64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.profile-powerpc64le.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.safestack-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.stats-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.stats-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.stats-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.stats_client-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.stats_client-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.stats_client-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.tsan-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_minimal-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_standalone-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-basic-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-basic-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-basic-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-basic-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-fdr-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-fdr-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-fdr-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-fdr-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-profiling-aarch64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-profiling-arm.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-profiling-armhf.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-profiling-x86_64.a OLD_FILES+=usr/lib/clang/11.0.0/lib/freebsd/libclang_rt.xray-x86_64.a OLD_DIRS+=usr/lib/clang/11.0.0/lib/freebsd OLD_DIRS+=usr/lib/clang/11.0.0/lib OLD_DIRS+=usr/lib/clang/11.0.0 # 20201225: PMC for Xscale removed OLD_FILES+=usr/share/man/man3/pmc.xscale.3.gz # 20201225: libregex removed OLD_FILES+=usr/include/gnu/posix/regex.h OLD_DIRS+=usr/include/gnu/posix OLD_FILES+=usr/include/gnu/regex.h OLD_DIRS+=usr/include/gnu OLD_FILES+=usr/include/gnuregex.h OLD_FILES+=usr/lib/libgnuregex.a OLD_FILES+=usr/lib/libgnuregex.so OLD_LIBS+=usr/lib/libgnuregex.so.5 OLD_FILES+=usr/lib/libgnuregex_p.a # 20201225: gnugrep removed OLD_FILES+=usr/bin/bsdgrep OLD_FILES+=usr/bin/gnugrep OLD_FILES+=usr/share/man/man1/bsdgrep.1.gz OLD_FILES+=usr/share/man/man1/gnugrep.1.gz # 20201224: mk48txx(4) removed OLD_FILES+=usr/share/man/man4/mk48txx.4.gz # 20201215: in-tree gdb removed OLD_FILES+=usr/libexec/gdb OLD_FILES+=usr/libexec/kgdb # 20201211: hme(4) removed OLD_FILES+=usr/share/man/man4/hme.4.gz OLD_FILES+=usr/share/man/man4/if_hme.4.gz # 20201129: RADIX_MPATH removed OLD_FILES+=usr/include/net/radix_mpath.h # 20201124: ping6(8) was merged into ping(8) OLD_FILES+=usr/share/man/man8/ping6.8.gz OLD_FILES+=usr/tests/sbin/ping6/Kyuafile OLD_FILES+=usr/tests/sbin/ping6/ping6_c1_s8_t1.out OLD_FILES+=usr/tests/sbin/ping6/ping6_test OLD_DIRS+=usr/tests/sbin/ping6 # 20201025: Remove cal data files OLD_FILES+=usr/share/calendar/calendar.all OLD_FILES+=usr/share/calendar/calendar.australia OLD_FILES+=usr/share/calendar/calendar.birthday OLD_FILES+=usr/share/calendar/calendar.brazilian OLD_FILES+=usr/share/calendar/calendar.christian OLD_FILES+=usr/share/calendar/calendar.computer OLD_FILES+=usr/share/calendar/calendar.croatian OLD_FILES+=usr/share/calendar/calendar.dutch OLD_FILES+=usr/share/calendar/calendar.french OLD_FILES+=usr/share/calendar/calendar.german OLD_FILES+=usr/share/calendar/calendar.history OLD_FILES+=usr/share/calendar/calendar.holiday OLD_FILES+=usr/share/calendar/calendar.hungarian OLD_FILES+=usr/share/calendar/calendar.judaic OLD_FILES+=usr/share/calendar/calendar.lotr OLD_FILES+=usr/share/calendar/calendar.music OLD_FILES+=usr/share/calendar/calendar.newzealand OLD_FILES+=usr/share/calendar/calendar.russian OLD_FILES+=usr/share/calendar/calendar.southafrica OLD_FILES+=usr/share/calendar/calendar.ukrainian OLD_FILES+=usr/share/calendar/calendar.usholiday OLD_FILES+=usr/share/calendar/calendar.world OLD_FILES+=usr/share/calendar/de_AT.ISO_8859-15/calendar.feiertag OLD_FILES+=usr/share/calendar/de_DE.ISO8859-1/calendar.all OLD_FILES+=usr/share/calendar/de_DE.ISO8859-1/calendar.feiertag OLD_FILES+=usr/share/calendar/de_DE.ISO8859-1/calendar.geschichte OLD_FILES+=usr/share/calendar/de_DE.ISO8859-1/calendar.kirche OLD_FILES+=usr/share/calendar/de_DE.ISO8859-1/calendar.literatur OLD_FILES+=usr/share/calendar/de_DE.ISO8859-1/calendar.musik OLD_FILES+=usr/share/calendar/de_DE.ISO8859-1/calendar.wissenschaft OLD_FILES+=usr/share/calendar/fr_FR.ISO8859-1/calendar.all OLD_FILES+=usr/share/calendar/fr_FR.ISO8859-1/calendar.fetes OLD_FILES+=usr/share/calendar/fr_FR.ISO8859-1/calendar.french OLD_FILES+=usr/share/calendar/fr_FR.ISO8859-1/calendar.jferies OLD_FILES+=usr/share/calendar/fr_FR.ISO8859-1/calendar.proverbes OLD_FILES+=usr/share/calendar/hr_HR.ISO8859-2/calendar.all OLD_FILES+=usr/share/calendar/hr_HR.ISO8859-2/calendar.praznici OLD_FILES+=usr/share/calendar/hu_HU.ISO8859-2/calendar.all OLD_FILES+=usr/share/calendar/hu_HU.ISO8859-2/calendar.nevnapok OLD_FILES+=usr/share/calendar/hu_HU.ISO8859-2/calendar.unnepek OLD_FILES+=usr/share/calendar/pt_BR.ISO8859-1/calendar.all OLD_FILES+=usr/share/calendar/pt_BR.ISO8859-1/calendar.commemorative OLD_FILES+=usr/share/calendar/pt_BR.ISO8859-1/calendar.holidays OLD_FILES+=usr/share/calendar/pt_BR.ISO8859-1/calendar.mcommemorative OLD_FILES+=usr/share/calendar/pt_BR.UTF-8/calendar.all OLD_FILES+=usr/share/calendar/pt_BR.UTF-8/calendar.commemorative OLD_FILES+=usr/share/calendar/pt_BR.UTF-8/calendar.holidays OLD_FILES+=usr/share/calendar/pt_BR.UTF-8/calendar.mcommemorative OLD_FILES+=usr/share/calendar/ru_RU.KOI8-R/calendar.all OLD_FILES+=usr/share/calendar/ru_RU.KOI8-R/calendar.common OLD_FILES+=usr/share/calendar/ru_RU.KOI8-R/calendar.holiday OLD_FILES+=usr/share/calendar/ru_RU.KOI8-R/calendar.military OLD_FILES+=usr/share/calendar/ru_RU.KOI8-R/calendar.orthodox OLD_FILES+=usr/share/calendar/ru_RU.KOI8-R/calendar.pagan OLD_FILES+=usr/share/calendar/ru_RU.UTF-8/calendar.all OLD_FILES+=usr/share/calendar/ru_RU.UTF-8/calendar.common OLD_FILES+=usr/share/calendar/ru_RU.UTF-8/calendar.holiday OLD_FILES+=usr/share/calendar/ru_RU.UTF-8/calendar.military OLD_FILES+=usr/share/calendar/ru_RU.UTF-8/calendar.orthodox OLD_FILES+=usr/share/calendar/ru_RU.UTF-8/calendar.pagan OLD_FILES+=usr/share/calendar/uk_UA.KOI8-U/calendar.all OLD_FILES+=usr/share/calendar/uk_UA.KOI8-U/calendar.holiday OLD_FILES+=usr/share/calendar/uk_UA.KOI8-U/calendar.misc OLD_FILES+=usr/share/calendar/uk_UA.KOI8-U/calendar.orthodox # 20201004: logo files renamed to type-agnostic gfx-*.lua OLD_FILES+=boot/lua/logo-beastie.lua OLD_FILES+=boot/lua/logo-beastiebw.lua OLD_FILES+=boot/lua/logo-fbsdbw.lua OLD_FILES+=boot/lua/logo-orb.lua OLD_FILES+=boot/lua/logo-orbbw.lua # 20200828: net/route/shared.h moved to net/route/route_var.h OLD_FILES+=usr/include/net/route/shared.h # 20200825: merged OpenZFS support OLD_LIBS+=lib/libzfs.so.3 OLD_FILES+=usr/share/man/man1/zstreamdump.1.gz #OLD_FILES+=usr/share/man/man7/zpool-features.7.gz # 20200923: memfd_test moved to /usr/tests/sys/posixshm OLD_FILES+=usr/tests/sys/kern/memfd_test # 20200910: remove vm_map_create(9) to sync with the code OLD_FILES+=usr/share/man/man9/vm_map_create.9.gz # 20200820: Removal of the ufm driver OLD_FILES+=usr/share/man/man4/ufm.4.gz # 20200816: new clang import which bumps version from 10.0.1 to 11.0.0 OLD_FILES+=usr/lib/clang/10.0.1/include/cuda_wrappers/algorithm OLD_FILES+=usr/lib/clang/10.0.1/include/cuda_wrappers/complex OLD_FILES+=usr/lib/clang/10.0.1/include/cuda_wrappers/new OLD_DIRS+=usr/lib/clang/10.0.1/include/cuda_wrappers OLD_FILES+=usr/lib/clang/10.0.1/include/fuzzer/FuzzedDataProvider.h OLD_DIRS+=usr/lib/clang/10.0.1/include/fuzzer OLD_FILES+=usr/lib/clang/10.0.1/include/openmp_wrappers/__clang_openmp_math.h OLD_FILES+=usr/lib/clang/10.0.1/include/openmp_wrappers/__clang_openmp_math_declares.h OLD_FILES+=usr/lib/clang/10.0.1/include/openmp_wrappers/cmath OLD_FILES+=usr/lib/clang/10.0.1/include/openmp_wrappers/math.h OLD_DIRS+=usr/lib/clang/10.0.1/include/openmp_wrappers OLD_FILES+=usr/lib/clang/10.0.1/include/ppc_wrappers/emmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/ppc_wrappers/mm_malloc.h OLD_FILES+=usr/lib/clang/10.0.1/include/ppc_wrappers/mmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/ppc_wrappers/pmmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/ppc_wrappers/smmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/ppc_wrappers/tmmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/ppc_wrappers/xmmintrin.h OLD_DIRS+=usr/lib/clang/10.0.1/include/ppc_wrappers OLD_FILES+=usr/lib/clang/10.0.1/include/profile/InstrProfData.inc OLD_DIRS+=usr/lib/clang/10.0.1/include/profile OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/tsan_interface_atomic.h OLD_FILES+=usr/lib/clang/10.0.1/include/sanitizer/ubsan_interface.h OLD_DIRS+=usr/lib/clang/10.0.1/include/sanitizer OLD_FILES+=usr/lib/clang/10.0.1/include/xray/xray_interface.h OLD_FILES+=usr/lib/clang/10.0.1/include/xray/xray_log_interface.h OLD_FILES+=usr/lib/clang/10.0.1/include/xray/xray_records.h OLD_DIRS+=usr/lib/clang/10.0.1/include/xray OLD_FILES+=usr/lib/clang/10.0.1/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/10.0.1/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/10.0.1/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/10.0.1/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/10.0.1/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/10.0.1/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/10.0.1/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/10.0.1/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/10.0.1/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/10.0.1/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/10.0.1/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/10.0.1/include/adxintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/altivec.h OLD_FILES+=usr/lib/clang/10.0.1/include/ammintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/arm64intr.h OLD_FILES+=usr/lib/clang/10.0.1/include/arm_acle.h OLD_FILES+=usr/lib/clang/10.0.1/include/arm_cmse.h OLD_FILES+=usr/lib/clang/10.0.1/include/arm_fp16.h OLD_FILES+=usr/lib/clang/10.0.1/include/arm_mve.h OLD_FILES+=usr/lib/clang/10.0.1/include/arm_neon.h OLD_FILES+=usr/lib/clang/10.0.1/include/armintr.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx2intrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512bf16intrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vlbf16intrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vlvp2intersectintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vp2intersectintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/avxintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/bmiintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/cetintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/clwbintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/clzerointrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/cpuid.h OLD_FILES+=usr/lib/clang/10.0.1/include/emmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/enqcmdintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/f16cintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/fma4intrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/fmaintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/gfniintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/htmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/ia32intrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/immintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/lwpintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/mm3dnow.h OLD_FILES+=usr/lib/clang/10.0.1/include/mm_malloc.h OLD_FILES+=usr/lib/clang/10.0.1/include/mmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/module.modulemap OLD_FILES+=usr/lib/clang/10.0.1/include/movdirintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/msa.h OLD_FILES+=usr/lib/clang/10.0.1/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/nmmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/opencl-c-base.h OLD_FILES+=usr/lib/clang/10.0.1/include/opencl-c.h OLD_FILES+=usr/lib/clang/10.0.1/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/pkuintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/pmmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/popcntintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/rtmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/s390intrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/sgxintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/shaintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/smmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/tbmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/tmmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/vadefs.h OLD_FILES+=usr/lib/clang/10.0.1/include/vaesintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/vecintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/wmmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/x86intrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/xmmintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/xopintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/10.0.1/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/10.0.1/include OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-aarch64.so OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-arm.so OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-armhf.so OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-preinit-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-preinit-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-preinit-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan_cxx-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan_cxx-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.cfi-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.cfi-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.cfi-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.cfi-i386.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.cfi-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.cfi_diag-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.cfi_diag-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.cfi_diag-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.cfi_diag-i386.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.cfi_diag-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.dd-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.dd-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.fuzzer-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.fuzzer-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.msan-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.msan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.profile-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.profile-powerpc.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.profile-powerpc64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.safestack-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.stats-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.stats-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.stats-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.stats_client-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.stats_client-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.stats_client-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.tsan-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_minimal-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_standalone-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-basic-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-basic-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-basic-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-basic-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-fdr-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-fdr-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-fdr-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-fdr-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-profiling-aarch64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-profiling-arm.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-profiling-armhf.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-profiling-x86_64.a OLD_FILES+=usr/lib/clang/10.0.1/lib/freebsd/libclang_rt.xray-x86_64.a OLD_DIRS+=usr/lib/clang/10.0.1/lib/freebsd OLD_DIRS+=usr/lib/clang/10.0.1/lib OLD_DIRS+=usr/lib/clang/10.0.1 # 20200803: remove free_domain(9) and uma_zfree_domain(9) OLD_FILES+=usr/share/man/man9/free_domain.9.gz OLD_FILES+=usr/share/man/man9/uma_zfree_domain.9.gz # 20200729: remove long expired serial drivers OLD_FILES+=usr/share/man/man4/cy.4.gz OLD_FILES+=usr/share/man/man4/rc.4.gz OLD_FILES+=usr/share/man/man4/rp.4.gz # 20200721: sys/iommu.h moved to dev/iommu/ OLD_FILES+=usr/include/sys/iommu.h # 20200715: rework of devstat(9) man page OLD_FILES+=usr/share/man/man9/devstat_add_entry.9.gz # 20200714: update byacc to 20200330 OLD_FILES+=usr/tests/usr.bin/yacc/btyacc_calc1.y OLD_FILES+=usr/tests/usr.bin/yacc/btyacc_demo.y OLD_FILES+=usr/tests/usr.bin/yacc/btyacc_destroy1.y OLD_FILES+=usr/tests/usr.bin/yacc/btyacc_destroy2.y OLD_FILES+=usr/tests/usr.bin/yacc/btyacc_destroy3.y OLD_FILES+=usr/tests/usr.bin/yacc/err_inherit1.y OLD_FILES+=usr/tests/usr.bin/yacc/err_inherit2.y OLD_FILES+=usr/tests/usr.bin/yacc/err_inherit3.y OLD_FILES+=usr/tests/usr.bin/yacc/err_inherit4.y OLD_FILES+=usr/tests/usr.bin/yacc/err_inherit5.y OLD_FILES+=usr/tests/usr.bin/yacc/inherit0.y OLD_FILES+=usr/tests/usr.bin/yacc/inherit1.y OLD_FILES+=usr/tests/usr.bin/yacc/inherit2.y # 20200706: update of sglist(9), r360574 OLD_FILES+=usr/share/man/man9/sglist_append_ext_pgs.9.gz OLD_FILES+=usr/share/man/man9/sglist_append_mb_ext_pgs.9.gz OLD_FILES+=usr/share/man/man9/sglist_count_ext_pgs.9.gz OLD_FILES+=usr/share/man/man9/sglist_count_mb_ext_pgs.9.gz # 20200617: update opencsd to 0.14.2 OLD_FILES+=usr/include/opencsd/etmv4/trc_pkt_elem_etmv4d.h # 20200606: retire binutils build infrastructure .if !defined(WITH_PORT_BASE_BINUTILS) OLD_FILES+=usr/bin/as OLD_FILES+=usr/bin/ld.bfd OLD_FILES+=usr/share/man/man1/as.1.gz OLD_FILES+=usr/share/man/man1/ld.bfd.1.gz OLD_FILES+=usr/share/man/man7/as.7.gz OLD_FILES+=usr/share/man/man7/ld.7.gz OLD_FILES+=usr/share/man/man7/ldint.7.gz OLD_FILES+=usr/share/man/man7/binutils.7.gz .endif OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.x OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/armelf_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.x OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/armelfb_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.x OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xbn OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xc OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xd OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xdc OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xdw OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xn OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xr OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xs OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xsc OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xsw OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xu OLD_FILES+=usr/libdata/ldscripts/elf32_sparc.xw OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf32btsmip_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf32btsmipn32_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf32ltsmip_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf32ltsmipn32_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf32ppc_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.x OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xbn OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xc OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xd OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xdc OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xdw OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xn OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xr OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xs OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xsc OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xsw OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xu OLD_FILES+=usr/libdata/ldscripts/elf64_sparc.xw OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf64_sparc_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf64btsmip_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf64ltsmip_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf64ppc_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf_i386_fbsd.xw OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xc OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xd OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xdc OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xdw OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xn OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xr OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xs OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xsc OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xw # 20200601: OpenSSL 32-bit compat engines moved to /usr/lib32/engines OLD_LIBS+=usr/lib32/capi.so OLD_LIBS+=usr/lib32/padlock.so # 20200528: libevent renamed libevent1 OLD_FILES+=usr/include/private/event/event.h OLD_DIRS+=usr/include/private/event OLD_FILES+=usr/lib/libprivateevent.a OLD_FILES+=usr/lib/libprivateevent.so OLD_LIBS+=usr/lib/libprivateevent.so.1 OLD_FILES+=usr/lib/libprivateevent_p.a # 20200523: new clang import which bumps version from 10.0.0 to 10.0.1 OLD_FILES+=usr/lib/clang/10.0.0/include/cuda_wrappers/algorithm OLD_FILES+=usr/lib/clang/10.0.0/include/cuda_wrappers/complex OLD_FILES+=usr/lib/clang/10.0.0/include/cuda_wrappers/new OLD_DIRS+=usr/lib/clang/10.0.0/include/cuda_wrappers OLD_FILES+=usr/lib/clang/10.0.0/include/fuzzer/FuzzedDataProvider.h OLD_DIRS+=usr/lib/clang/10.0.0/include/fuzzer OLD_FILES+=usr/lib/clang/10.0.0/include/openmp_wrappers/__clang_openmp_math.h OLD_FILES+=usr/lib/clang/10.0.0/include/openmp_wrappers/__clang_openmp_math_declares.h OLD_FILES+=usr/lib/clang/10.0.0/include/openmp_wrappers/cmath OLD_FILES+=usr/lib/clang/10.0.0/include/openmp_wrappers/math.h OLD_DIRS+=usr/lib/clang/10.0.0/include/openmp_wrappers OLD_FILES+=usr/lib/clang/10.0.0/include/ppc_wrappers/emmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/ppc_wrappers/mm_malloc.h OLD_FILES+=usr/lib/clang/10.0.0/include/ppc_wrappers/mmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/ppc_wrappers/pmmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/ppc_wrappers/smmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/ppc_wrappers/tmmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/ppc_wrappers/xmmintrin.h OLD_DIRS+=usr/lib/clang/10.0.0/include/ppc_wrappers OLD_FILES+=usr/lib/clang/10.0.0/include/profile/InstrProfData.inc OLD_DIRS+=usr/lib/clang/10.0.0/include/profile OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/tsan_interface_atomic.h OLD_FILES+=usr/lib/clang/10.0.0/include/sanitizer/ubsan_interface.h OLD_DIRS+=usr/lib/clang/10.0.0/include/sanitizer OLD_FILES+=usr/lib/clang/10.0.0/include/xray/xray_interface.h OLD_FILES+=usr/lib/clang/10.0.0/include/xray/xray_log_interface.h OLD_FILES+=usr/lib/clang/10.0.0/include/xray/xray_records.h OLD_DIRS+=usr/lib/clang/10.0.0/include/xray OLD_FILES+=usr/lib/clang/10.0.0/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/10.0.0/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/10.0.0/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/10.0.0/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/10.0.0/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/10.0.0/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/10.0.0/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/10.0.0/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/10.0.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/10.0.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/10.0.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/10.0.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/altivec.h OLD_FILES+=usr/lib/clang/10.0.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/arm64intr.h OLD_FILES+=usr/lib/clang/10.0.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/10.0.0/include/arm_cmse.h OLD_FILES+=usr/lib/clang/10.0.0/include/arm_fp16.h OLD_FILES+=usr/lib/clang/10.0.0/include/arm_mve.h OLD_FILES+=usr/lib/clang/10.0.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/10.0.0/include/armintr.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512bf16intrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vlbf16intrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vlvp2intersectintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vp2intersectintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/cetintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/clwbintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/clzerointrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/cpuid.h OLD_FILES+=usr/lib/clang/10.0.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/enqcmdintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/gfniintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/htmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/immintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/lwpintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/10.0.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/10.0.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/module.modulemap OLD_FILES+=usr/lib/clang/10.0.0/include/movdirintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/msa.h OLD_FILES+=usr/lib/clang/10.0.0/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/opencl-c-base.h OLD_FILES+=usr/lib/clang/10.0.0/include/opencl-c.h OLD_FILES+=usr/lib/clang/10.0.0/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/pkuintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/s390intrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/sgxintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/vadefs.h OLD_FILES+=usr/lib/clang/10.0.0/include/vaesintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/vecintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/xopintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/10.0.0/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/10.0.0/include OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-aarch64.so OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-arm.so OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-armhf.so OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-preinit-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-preinit-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-preinit-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan_cxx-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan_cxx-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.cfi-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.cfi-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.cfi-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.cfi-i386.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.cfi-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.cfi_diag-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.cfi_diag-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.cfi_diag-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.cfi_diag-i386.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.cfi_diag-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.dd-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.dd-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.fuzzer-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.fuzzer-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.msan-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.msan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.profile-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.profile-powerpc.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.profile-powerpc64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.safestack-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.stats-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.stats-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.stats-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.stats_client-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.stats_client-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.stats_client-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.tsan-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_minimal-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_standalone-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-basic-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-basic-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-basic-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-basic-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-fdr-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-fdr-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-fdr-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-fdr-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-profiling-aarch64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-profiling-arm.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-profiling-armhf.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-profiling-x86_64.a OLD_FILES+=usr/lib/clang/10.0.0/lib/freebsd/libclang_rt.xray-x86_64.a OLD_DIRS+=usr/lib/clang/10.0.0/lib/freebsd OLD_DIRS+=usr/lib/clang/10.0.0/lib OLD_DIRS+=usr/lib/clang/10.0.0 # 20200520: xform_userland.h removed OLD_FILES+=usr/include/crypto/xform_userland.h # 20200515: libalias cuseeme protocol support retired OLD_LIBS+=lib/libalias_cuseeme.so OLD_FILES+=usr/lib/libalias_cuseeme.a OLD_FILES+=usr/lib/libalias_cuseeme_p.a # 20200511: Remove deprecated crypto algorithms OLD_FILES+=usr/include/crypto/cast.h OLD_FILES+=usr/include/crypto/castsb.h OLD_FILES+=usr/include/crypto/skipjack.h # 20200511: Remove ubsec(4) OLD_FILES+=usr/share/man/man4/ubsec.4.gz # 20200428: route_var.h moved to net/route OLD_FILES+=usr/include/net/route_var.h # 20200418: Make libauditd private OLD_FILES+=usr/lib/libauditd.a OLD_FILES+=usr/lib/libauditd.so OLD_LIBS+=usr/lib/libauditd.so.5 OLD_FILES+=usr/lib/libauditd_p.a # 20200418: Remove bogus man links OLD_FILES+=usr/share/man/man3/getauusernam_R.3.gz OLD_FILES+=usr/share/man/man3/getauclassnam_3.3.gz # 20200414: NFS file handle affinity code for the NFS server re-organized OLD_FILES+=usr/include/nfs/nfs_fha.h # 20200401: Remove procfs-based process debugging OLD_FILES+=usr/include/sys/pioctl.h # 20200330: GDB_LIBEXEC option retired (always true) OLD_FILES+=usr/bin/gdb OLD_FILES+=usr/bin/gdbserver OLD_FILES+=usr/bin/kgdb OLD_FILES+=usr/share/man/man1/gdb.1.gz OLD_FILES+=usr/share/man/man1/gdbserver.1.gz OLD_FILES+=usr/share/man/man1/kgdb.1.gz # 20200327: OCF refactoring OLD_FILES+=usr/include/crypto/cryptosoft.h OLD_FILES+=usr/share/man/man9/crypto_find_driver.9.gz OLD_FILES+=usr/share/man/man9/crypto_register.9.gz OLD_FILES+=usr/share/man/man9/crypto_unregister.9.gz # 20200326: compat libs for libl are no longer built OLD_FILES+=usr/lib32/libfl.a OLD_FILES+=usr/lib32/libl.a OLD_FILES+=usr/lib32/libln.a # 20200323: INTERNALLIB don't install headers anymore OLD_FILES+=usr/include/libelftc.h OLD_FILES+=usr/include/libifconfig.h OLD_FILES+=usr/include/libpmcstat.h # 20200320: cx and ctau drivers retired OLD_FILES+=usr/share/man/man4/ctau.4.gz OLD_FILES+=usr/share/man/man4/cx.4.gz # 20200318: host.conf was deprecated a long time ago OLD_FILES+=etc/host.conf OLD_FILES+=etc/rc.d/nsswitch # 20200310: new clang import which bumps version from 9.0.1 to 10.0.0 OLD_FILES+=usr/lib/clang/9.0.1/include/cuda_wrappers/algorithm OLD_FILES+=usr/lib/clang/9.0.1/include/cuda_wrappers/complex OLD_FILES+=usr/lib/clang/9.0.1/include/cuda_wrappers/new OLD_DIRS+=usr/lib/clang/9.0.1/include/cuda_wrappers OLD_FILES+=usr/lib/clang/9.0.1/include/openmp_wrappers/__clang_openmp_math.h OLD_FILES+=usr/lib/clang/9.0.1/include/openmp_wrappers/__clang_openmp_math_declares.h OLD_FILES+=usr/lib/clang/9.0.1/include/openmp_wrappers/cmath OLD_FILES+=usr/lib/clang/9.0.1/include/openmp_wrappers/math.h OLD_DIRS+=usr/lib/clang/9.0.1/include/openmp_wrappers OLD_FILES+=usr/lib/clang/9.0.1/include/ppc_wrappers/emmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/ppc_wrappers/mm_malloc.h OLD_FILES+=usr/lib/clang/9.0.1/include/ppc_wrappers/mmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/ppc_wrappers/xmmintrin.h OLD_DIRS+=usr/lib/clang/9.0.1/include/ppc_wrappers OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/9.0.1/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/9.0.1/include/sanitizer OLD_FILES+=usr/lib/clang/9.0.1/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/9.0.1/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/9.0.1/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/9.0.1/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/9.0.1/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/9.0.1/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/9.0.1/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/9.0.1/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/9.0.1/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/9.0.1/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/9.0.1/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/9.0.1/include/adxintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/altivec.h OLD_FILES+=usr/lib/clang/9.0.1/include/ammintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/arm64intr.h OLD_FILES+=usr/lib/clang/9.0.1/include/arm_acle.h OLD_FILES+=usr/lib/clang/9.0.1/include/arm_fp16.h OLD_FILES+=usr/lib/clang/9.0.1/include/arm_neon.h OLD_FILES+=usr/lib/clang/9.0.1/include/armintr.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx2intrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512bf16intrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vlbf16intrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vlvp2intersectintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vp2intersectintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/avxintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/bmiintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/cetintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/clwbintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/clzerointrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/cpuid.h OLD_FILES+=usr/lib/clang/9.0.1/include/emmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/enqcmdintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/f16cintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/fma4intrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/fmaintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/gfniintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/htmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/ia32intrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/immintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/lwpintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/mm3dnow.h OLD_FILES+=usr/lib/clang/9.0.1/include/mm_malloc.h OLD_FILES+=usr/lib/clang/9.0.1/include/mmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/module.modulemap OLD_FILES+=usr/lib/clang/9.0.1/include/movdirintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/msa.h OLD_FILES+=usr/lib/clang/9.0.1/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/nmmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/opencl-c-base.h OLD_FILES+=usr/lib/clang/9.0.1/include/opencl-c.h OLD_FILES+=usr/lib/clang/9.0.1/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/pkuintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/pmmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/popcntintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/rtmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/s390intrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/sgxintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/shaintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/smmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/tbmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/tmmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/vadefs.h OLD_FILES+=usr/lib/clang/9.0.1/include/vaesintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/vecintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/wmmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/x86intrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/xmmintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/xopintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/9.0.1/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/9.0.1/include OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-aarch64.so OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-arm.so OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-armhf.so OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-preinit-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-preinit-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-preinit-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan_cxx-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan_cxx-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.cfi-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.cfi-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.cfi-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.cfi-i386.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.cfi-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.cfi_diag-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.cfi_diag-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.cfi_diag-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.cfi_diag-i386.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.cfi_diag-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.dd-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.dd-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.fuzzer-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.fuzzer-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.msan-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.msan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.profile-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.profile-powerpc.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.profile-powerpc64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.safestack-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.stats-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.stats-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.stats-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.stats_client-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.stats_client-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.stats_client-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.tsan-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_minimal-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_standalone-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-basic-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-basic-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-basic-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-basic-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-fdr-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-fdr-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-fdr-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-fdr-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-profiling-aarch64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-profiling-arm.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-profiling-armhf.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-profiling-x86_64.a OLD_FILES+=usr/lib/clang/9.0.1/lib/freebsd/libclang_rt.xray-x86_64.a OLD_DIRS+=usr/lib/clang/9.0.1/lib/freebsd OLD_DIRS+=usr/lib/clang/9.0.1/lib OLD_DIRS+=usr/lib/clang/9.0.1 # 20200309: amd(8) retired OLD_FILES+=etc/amd.map OLD_FILES+=etc/newsyslog.conf.d/amd.conf OLD_FILES+=etc/rc.d/amd OLD_FILES+=usr/bin/pawd OLD_FILES+=usr/sbin/amd OLD_FILES+=usr/sbin/amq OLD_FILES+=usr/sbin/fixmount OLD_FILES+=usr/sbin/fsinfo OLD_FILES+=usr/sbin/hlfsd OLD_FILES+=usr/sbin/mk-amd-map OLD_FILES+=usr/sbin/wire-test OLD_FILES+=usr/share/examples/etc/amd.map OLD_FILES+=usr/share/man/man1/pawd.1.gz OLD_FILES+=usr/share/man/man5/amd.conf.5.gz OLD_FILES+=usr/share/man/man8/amd.8.gz OLD_FILES+=usr/share/man/man8/amq.8.gz OLD_FILES+=usr/share/man/man8/fixmount.8.gz OLD_FILES+=usr/share/man/man8/fsinfo.8.gz OLD_FILES+=usr/share/man/man8/hlfsd.8.gz OLD_FILES+=usr/share/man/man8/mk-amd-map.8.gz OLD_FILES+=usr/share/man/man8/wire-test.8.gz # 20200301: bktr removed OLD_DIRS+=usr/include/dev/bktr OLD_FILES+=usr/include/dev/bktr/ioctl_bktr.h OLD_FILES+=usr/include/dev/bktr/ioctl_bt848.h OLD_FILES+=usr/include/dev/bktr/ioctl_meteor.h .if ${TARGET_ARCH} == "i386" OLD_FILES+=usr/include/machine/ioctl_bktr.h OLD_FILES+=usr/include/machine/ioctl_meteor.h .endif OLD_FILES+=usr/share/man/man4/bktr.4.gz OLD_FILES+=usr/share/man/man4/brooktree.4.gz # 20200229: GCC 4.2.1 removed .if !defined(WITH_PORT_BASE_GCC) OLD_FILES+=usr/bin/g++ OLD_FILES+=usr/bin/gcc OLD_FILES+=usr/share/man/man1/g++.1.gz OLD_FILES+=usr/share/man/man1/gcc.1.gz .endif OLD_FILES+=usr/bin/gcpp OLD_FILES+=usr/bin/gperf OLD_FILES+=usr/include/c++/4.2/algorithm OLD_FILES+=usr/include/c++/4.2/backward/algo.h OLD_FILES+=usr/include/c++/4.2/backward/algobase.h OLD_FILES+=usr/include/c++/4.2/backward/alloc.h OLD_FILES+=usr/include/c++/4.2/backward/backward_warning.h OLD_FILES+=usr/include/c++/4.2/backward/bvector.h OLD_FILES+=usr/include/c++/4.2/backward/complex.h OLD_FILES+=usr/include/c++/4.2/backward/defalloc.h OLD_FILES+=usr/include/c++/4.2/backward/deque.h OLD_FILES+=usr/include/c++/4.2/backward/fstream.h OLD_FILES+=usr/include/c++/4.2/backward/function.h OLD_FILES+=usr/include/c++/4.2/backward/hash_map.h OLD_FILES+=usr/include/c++/4.2/backward/hash_set.h OLD_FILES+=usr/include/c++/4.2/backward/hashtable.h OLD_FILES+=usr/include/c++/4.2/backward/heap.h OLD_FILES+=usr/include/c++/4.2/backward/iomanip.h OLD_FILES+=usr/include/c++/4.2/backward/iostream.h OLD_FILES+=usr/include/c++/4.2/backward/istream.h OLD_FILES+=usr/include/c++/4.2/backward/iterator.h OLD_FILES+=usr/include/c++/4.2/backward/list.h OLD_FILES+=usr/include/c++/4.2/backward/map.h OLD_FILES+=usr/include/c++/4.2/backward/multimap.h OLD_FILES+=usr/include/c++/4.2/backward/multiset.h OLD_FILES+=usr/include/c++/4.2/backward/new.h OLD_FILES+=usr/include/c++/4.2/backward/ostream.h OLD_FILES+=usr/include/c++/4.2/backward/pair.h OLD_FILES+=usr/include/c++/4.2/backward/queue.h OLD_FILES+=usr/include/c++/4.2/backward/rope.h OLD_FILES+=usr/include/c++/4.2/backward/set.h OLD_FILES+=usr/include/c++/4.2/backward/slist.h OLD_FILES+=usr/include/c++/4.2/backward/stack.h OLD_FILES+=usr/include/c++/4.2/backward/stream.h OLD_FILES+=usr/include/c++/4.2/backward/streambuf.h OLD_FILES+=usr/include/c++/4.2/backward/strstream OLD_FILES+=usr/include/c++/4.2/backward/tempbuf.h OLD_FILES+=usr/include/c++/4.2/backward/tree.h OLD_FILES+=usr/include/c++/4.2/backward/vector.h OLD_FILES+=usr/include/c++/4.2/bits/allocator.h OLD_FILES+=usr/include/c++/4.2/bits/atomic_word.h OLD_FILES+=usr/include/c++/4.2/bits/basic_file.h OLD_FILES+=usr/include/c++/4.2/bits/basic_ios.h OLD_FILES+=usr/include/c++/4.2/bits/basic_ios.tcc OLD_FILES+=usr/include/c++/4.2/bits/basic_string.h OLD_FILES+=usr/include/c++/4.2/bits/basic_string.tcc OLD_FILES+=usr/include/c++/4.2/bits/boost_concept_check.h OLD_FILES+=usr/include/c++/4.2/bits/c++allocator.h OLD_FILES+=usr/include/c++/4.2/bits/c++config.h OLD_FILES+=usr/include/c++/4.2/bits/c++io.h OLD_FILES+=usr/include/c++/4.2/bits/c++locale.h OLD_FILES+=usr/include/c++/4.2/bits/c++locale_internal.h OLD_FILES+=usr/include/c++/4.2/bits/char_traits.h OLD_FILES+=usr/include/c++/4.2/bits/cmath.tcc OLD_FILES+=usr/include/c++/4.2/bits/codecvt.h OLD_FILES+=usr/include/c++/4.2/bits/compatibility.h OLD_FILES+=usr/include/c++/4.2/bits/concept_check.h OLD_FILES+=usr/include/c++/4.2/bits/cpp_type_traits.h OLD_FILES+=usr/include/c++/4.2/bits/cpu_defines.h OLD_FILES+=usr/include/c++/4.2/bits/ctype_base.h OLD_FILES+=usr/include/c++/4.2/bits/ctype_inline.h OLD_FILES+=usr/include/c++/4.2/bits/ctype_noninline.h OLD_FILES+=usr/include/c++/4.2/bits/cxxabi_tweaks.h OLD_FILES+=usr/include/c++/4.2/bits/deque.tcc OLD_FILES+=usr/include/c++/4.2/bits/fstream.tcc OLD_FILES+=usr/include/c++/4.2/bits/functexcept.h OLD_FILES+=usr/include/c++/4.2/bits/gslice.h OLD_FILES+=usr/include/c++/4.2/bits/gslice_array.h OLD_FILES+=usr/include/c++/4.2/bits/gthr-default.h OLD_FILES+=usr/include/c++/4.2/bits/gthr-posix.h OLD_FILES+=usr/include/c++/4.2/bits/gthr-single.h OLD_FILES+=usr/include/c++/4.2/bits/gthr-tpf.h OLD_FILES+=usr/include/c++/4.2/bits/gthr.h OLD_FILES+=usr/include/c++/4.2/bits/indirect_array.h OLD_FILES+=usr/include/c++/4.2/bits/ios_base.h OLD_FILES+=usr/include/c++/4.2/bits/istream.tcc OLD_FILES+=usr/include/c++/4.2/bits/list.tcc OLD_FILES+=usr/include/c++/4.2/bits/locale_classes.h OLD_FILES+=usr/include/c++/4.2/bits/locale_facets.h OLD_FILES+=usr/include/c++/4.2/bits/locale_facets.tcc OLD_FILES+=usr/include/c++/4.2/bits/localefwd.h OLD_FILES+=usr/include/c++/4.2/bits/mask_array.h OLD_FILES+=usr/include/c++/4.2/bits/messages_members.h OLD_FILES+=usr/include/c++/4.2/bits/os_defines.h OLD_FILES+=usr/include/c++/4.2/bits/ostream.tcc OLD_FILES+=usr/include/c++/4.2/bits/ostream_insert.h OLD_FILES+=usr/include/c++/4.2/bits/postypes.h OLD_FILES+=usr/include/c++/4.2/bits/slice_array.h OLD_FILES+=usr/include/c++/4.2/bits/sstream.tcc OLD_FILES+=usr/include/c++/4.2/bits/stl_algo.h OLD_FILES+=usr/include/c++/4.2/bits/stl_algobase.h OLD_FILES+=usr/include/c++/4.2/bits/stl_bvector.h OLD_FILES+=usr/include/c++/4.2/bits/stl_construct.h OLD_FILES+=usr/include/c++/4.2/bits/stl_deque.h OLD_FILES+=usr/include/c++/4.2/bits/stl_function.h OLD_FILES+=usr/include/c++/4.2/bits/stl_heap.h OLD_FILES+=usr/include/c++/4.2/bits/stl_iterator.h OLD_FILES+=usr/include/c++/4.2/bits/stl_iterator_base_funcs.h OLD_FILES+=usr/include/c++/4.2/bits/stl_iterator_base_types.h OLD_FILES+=usr/include/c++/4.2/bits/stl_list.h OLD_FILES+=usr/include/c++/4.2/bits/stl_map.h OLD_FILES+=usr/include/c++/4.2/bits/stl_multimap.h OLD_FILES+=usr/include/c++/4.2/bits/stl_multiset.h OLD_FILES+=usr/include/c++/4.2/bits/stl_numeric.h OLD_FILES+=usr/include/c++/4.2/bits/stl_pair.h OLD_FILES+=usr/include/c++/4.2/bits/stl_queue.h OLD_FILES+=usr/include/c++/4.2/bits/stl_raw_storage_iter.h OLD_FILES+=usr/include/c++/4.2/bits/stl_relops.h OLD_FILES+=usr/include/c++/4.2/bits/stl_set.h OLD_FILES+=usr/include/c++/4.2/bits/stl_stack.h OLD_FILES+=usr/include/c++/4.2/bits/stl_tempbuf.h OLD_FILES+=usr/include/c++/4.2/bits/stl_tree.h OLD_FILES+=usr/include/c++/4.2/bits/stl_uninitialized.h OLD_FILES+=usr/include/c++/4.2/bits/stl_vector.h OLD_FILES+=usr/include/c++/4.2/bits/stream_iterator.h OLD_FILES+=usr/include/c++/4.2/bits/streambuf.tcc OLD_FILES+=usr/include/c++/4.2/bits/streambuf_iterator.h OLD_FILES+=usr/include/c++/4.2/bits/stringfwd.h OLD_FILES+=usr/include/c++/4.2/bits/time_members.h OLD_FILES+=usr/include/c++/4.2/bits/valarray_after.h OLD_FILES+=usr/include/c++/4.2/bits/valarray_array.h OLD_FILES+=usr/include/c++/4.2/bits/valarray_array.tcc OLD_FILES+=usr/include/c++/4.2/bits/valarray_before.h OLD_FILES+=usr/include/c++/4.2/bits/vector.tcc OLD_FILES+=usr/include/c++/4.2/bitset OLD_FILES+=usr/include/c++/4.2/cassert OLD_FILES+=usr/include/c++/4.2/cctype OLD_FILES+=usr/include/c++/4.2/cerrno OLD_FILES+=usr/include/c++/4.2/cfloat OLD_FILES+=usr/include/c++/4.2/ciso646 OLD_FILES+=usr/include/c++/4.2/climits OLD_FILES+=usr/include/c++/4.2/clocale OLD_FILES+=usr/include/c++/4.2/cmath OLD_FILES+=usr/include/c++/4.2/complex OLD_FILES+=usr/include/c++/4.2/csetjmp OLD_FILES+=usr/include/c++/4.2/csignal OLD_FILES+=usr/include/c++/4.2/cstdarg OLD_FILES+=usr/include/c++/4.2/cstddef OLD_FILES+=usr/include/c++/4.2/cstdio OLD_FILES+=usr/include/c++/4.2/cstdlib OLD_FILES+=usr/include/c++/4.2/cstring OLD_FILES+=usr/include/c++/4.2/ctime OLD_FILES+=usr/include/c++/4.2/cwchar OLD_FILES+=usr/include/c++/4.2/cwctype OLD_FILES+=usr/include/c++/4.2/cxxabi.h OLD_FILES+=usr/include/c++/4.2/debug/bitset OLD_FILES+=usr/include/c++/4.2/debug/debug.h OLD_FILES+=usr/include/c++/4.2/debug/deque OLD_FILES+=usr/include/c++/4.2/debug/formatter.h OLD_FILES+=usr/include/c++/4.2/debug/functions.h OLD_FILES+=usr/include/c++/4.2/debug/hash_map OLD_FILES+=usr/include/c++/4.2/debug/hash_map.h OLD_FILES+=usr/include/c++/4.2/debug/hash_multimap.h OLD_FILES+=usr/include/c++/4.2/debug/hash_multiset.h OLD_FILES+=usr/include/c++/4.2/debug/hash_set OLD_FILES+=usr/include/c++/4.2/debug/hash_set.h OLD_FILES+=usr/include/c++/4.2/debug/list OLD_FILES+=usr/include/c++/4.2/debug/macros.h OLD_FILES+=usr/include/c++/4.2/debug/map OLD_FILES+=usr/include/c++/4.2/debug/map.h OLD_FILES+=usr/include/c++/4.2/debug/multimap.h OLD_FILES+=usr/include/c++/4.2/debug/multiset.h OLD_FILES+=usr/include/c++/4.2/debug/safe_base.h OLD_FILES+=usr/include/c++/4.2/debug/safe_iterator.h OLD_FILES+=usr/include/c++/4.2/debug/safe_iterator.tcc OLD_FILES+=usr/include/c++/4.2/debug/safe_sequence.h OLD_FILES+=usr/include/c++/4.2/debug/set OLD_FILES+=usr/include/c++/4.2/debug/set.h OLD_FILES+=usr/include/c++/4.2/debug/string OLD_FILES+=usr/include/c++/4.2/debug/vector OLD_FILES+=usr/include/c++/4.2/deque OLD_FILES+=usr/include/c++/4.2/exception OLD_FILES+=usr/include/c++/4.2/exception_defines.h OLD_FILES+=usr/include/c++/4.2/ext/algorithm OLD_FILES+=usr/include/c++/4.2/ext/array_allocator.h OLD_FILES+=usr/include/c++/4.2/ext/atomicity.h OLD_FILES+=usr/include/c++/4.2/ext/bitmap_allocator.h OLD_FILES+=usr/include/c++/4.2/ext/codecvt_specializations.h OLD_FILES+=usr/include/c++/4.2/ext/concurrence.h OLD_FILES+=usr/include/c++/4.2/ext/debug_allocator.h OLD_FILES+=usr/include/c++/4.2/ext/functional OLD_FILES+=usr/include/c++/4.2/ext/hash_fun.h OLD_FILES+=usr/include/c++/4.2/ext/hash_map OLD_FILES+=usr/include/c++/4.2/ext/hash_set OLD_FILES+=usr/include/c++/4.2/ext/hashtable.h OLD_FILES+=usr/include/c++/4.2/ext/iterator OLD_FILES+=usr/include/c++/4.2/ext/malloc_allocator.h OLD_FILES+=usr/include/c++/4.2/ext/memory OLD_FILES+=usr/include/c++/4.2/ext/mt_allocator.h OLD_FILES+=usr/include/c++/4.2/ext/new_allocator.h OLD_FILES+=usr/include/c++/4.2/ext/numeric OLD_FILES+=usr/include/c++/4.2/ext/numeric_traits.h OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/assoc_container.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/basic_tree_policy/traits.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/basic_types.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/cond_dtor_entry_dealtor.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/cond_key_dtor_entry_dealtor.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/node_iterators.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/point_iterators.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/r_erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_/traits.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/const_iterator.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/const_point_iterator.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/entry_cmp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/entry_pred.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/resize_policy.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/cmp_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/find_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/standard_policies.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/cond_dealtor.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/container_base_dispatch.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/eq_fn/eq_by_less.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/find_no_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/find_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/standard_policies.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/probe_fn_base.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/sample_probe_fn.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/sample_range_hashing.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/sample_ranged_hash_fn.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn/sample_ranged_probe_fn.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/const_point_iterator.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/node.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_map_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_map_/entry_metadata_base.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_map_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_map_/find_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_map_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_map_/lu_map_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_map_/trace_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_policy/counter_lu_metadata.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_policy/counter_lu_policy_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_policy/mtf_lu_policy_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_policy/sample_update_policy.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/map_debug_base.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_/node_iterators.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_/policy_access_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_/traits.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pairing_heap_/find_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/child_iterator.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/cond_dtor_entry_dealtor.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/const_child_iterator.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/head.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/internal_node.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/leaf.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/node_base.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/node_iterators.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/node_metadata_base.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/point_iterators.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/r_erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/rotate_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/split_join_branch_bag.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/traits.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/priority_queue_base_dispatch.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rb_tree_map_/find_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rb_tree_map_/node.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rb_tree_map_/traits.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/resize_policy/sample_resize_policy.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/resize_policy/sample_resize_trigger.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/resize_policy/sample_size_policy.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/splay_tree_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/splay_tree_/find_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/splay_tree_/info_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/splay_tree_/node.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/splay_tree_/splay_tree_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/splay_tree_/traits.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/standard_policies.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/tree_policy/node_metadata_selector.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/tree_policy/null_node_update_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/tree_policy/sample_tree_node_update.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/tree_trace_base.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/trie_policy/node_metadata_selector.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/trie_policy/null_node_update_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/trie_policy/order_statistics_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/trie_policy/sample_trie_e_access_traits.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/trie_policy/sample_trie_node_update.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/trie_policy/string_trie_e_access_traits_imp.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/trie_policy/trie_policy_base.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/type_utils.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/types_traits.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/unordered_iterator/const_iterator.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/unordered_iterator/iterator.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/detail/unordered_iterator/point_iterator.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/exception.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/hash_policy.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/list_update_policy.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/priority_queue.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/tag_and_trait.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/tree_policy.hpp OLD_FILES+=usr/include/c++/4.2/ext/pb_ds/trie_policy.hpp OLD_FILES+=usr/include/c++/4.2/ext/pod_char_traits.h OLD_FILES+=usr/include/c++/4.2/ext/pool_allocator.h OLD_FILES+=usr/include/c++/4.2/ext/rb_tree OLD_FILES+=usr/include/c++/4.2/ext/rc_string_base.h OLD_FILES+=usr/include/c++/4.2/ext/rope OLD_FILES+=usr/include/c++/4.2/ext/ropeimpl.h OLD_FILES+=usr/include/c++/4.2/ext/slist OLD_FILES+=usr/include/c++/4.2/ext/sso_string_base.h OLD_FILES+=usr/include/c++/4.2/ext/stdio_filebuf.h OLD_FILES+=usr/include/c++/4.2/ext/stdio_sync_filebuf.h OLD_FILES+=usr/include/c++/4.2/ext/throw_allocator.h OLD_FILES+=usr/include/c++/4.2/ext/type_traits.h OLD_FILES+=usr/include/c++/4.2/ext/typelist.h OLD_FILES+=usr/include/c++/4.2/ext/vstring.h OLD_FILES+=usr/include/c++/4.2/ext/vstring.tcc OLD_FILES+=usr/include/c++/4.2/ext/vstring_fwd.h OLD_FILES+=usr/include/c++/4.2/ext/vstring_util.h OLD_FILES+=usr/include/c++/4.2/fstream OLD_FILES+=usr/include/c++/4.2/functional OLD_FILES+=usr/include/c++/4.2/iomanip OLD_FILES+=usr/include/c++/4.2/ios OLD_FILES+=usr/include/c++/4.2/iosfwd OLD_FILES+=usr/include/c++/4.2/iostream OLD_FILES+=usr/include/c++/4.2/istream OLD_FILES+=usr/include/c++/4.2/iterator OLD_FILES+=usr/include/c++/4.2/limits OLD_FILES+=usr/include/c++/4.2/list OLD_FILES+=usr/include/c++/4.2/locale OLD_FILES+=usr/include/c++/4.2/map OLD_FILES+=usr/include/c++/4.2/memory OLD_FILES+=usr/include/c++/4.2/new OLD_FILES+=usr/include/c++/4.2/numeric OLD_FILES+=usr/include/c++/4.2/ostream OLD_FILES+=usr/include/c++/4.2/queue OLD_FILES+=usr/include/c++/4.2/set OLD_FILES+=usr/include/c++/4.2/sstream OLD_FILES+=usr/include/c++/4.2/stack OLD_FILES+=usr/include/c++/4.2/stdexcept OLD_FILES+=usr/include/c++/4.2/streambuf OLD_FILES+=usr/include/c++/4.2/string OLD_FILES+=usr/include/c++/4.2/tr1/array OLD_FILES+=usr/include/c++/4.2/tr1/bind_iterate.h OLD_FILES+=usr/include/c++/4.2/tr1/bind_repeat.h OLD_FILES+=usr/include/c++/4.2/tr1/boost_shared_ptr.h OLD_FILES+=usr/include/c++/4.2/tr1/cctype OLD_FILES+=usr/include/c++/4.2/tr1/cfenv OLD_FILES+=usr/include/c++/4.2/tr1/cfloat OLD_FILES+=usr/include/c++/4.2/tr1/cinttypes OLD_FILES+=usr/include/c++/4.2/tr1/climits OLD_FILES+=usr/include/c++/4.2/tr1/cmath OLD_FILES+=usr/include/c++/4.2/tr1/common.h OLD_FILES+=usr/include/c++/4.2/tr1/complex OLD_FILES+=usr/include/c++/4.2/tr1/cstdarg OLD_FILES+=usr/include/c++/4.2/tr1/cstdbool OLD_FILES+=usr/include/c++/4.2/tr1/cstdint OLD_FILES+=usr/include/c++/4.2/tr1/cstdio OLD_FILES+=usr/include/c++/4.2/tr1/cstdlib OLD_FILES+=usr/include/c++/4.2/tr1/ctgmath OLD_FILES+=usr/include/c++/4.2/tr1/ctime OLD_FILES+=usr/include/c++/4.2/tr1/ctype.h OLD_FILES+=usr/include/c++/4.2/tr1/cwchar OLD_FILES+=usr/include/c++/4.2/tr1/cwctype OLD_FILES+=usr/include/c++/4.2/tr1/fenv.h OLD_FILES+=usr/include/c++/4.2/tr1/float.h OLD_FILES+=usr/include/c++/4.2/tr1/functional OLD_FILES+=usr/include/c++/4.2/tr1/functional_hash.h OLD_FILES+=usr/include/c++/4.2/tr1/functional_iterate.h OLD_FILES+=usr/include/c++/4.2/tr1/hashtable OLD_FILES+=usr/include/c++/4.2/tr1/hashtable_policy.h OLD_FILES+=usr/include/c++/4.2/tr1/inttypes.h OLD_FILES+=usr/include/c++/4.2/tr1/limits.h OLD_FILES+=usr/include/c++/4.2/tr1/math.h OLD_FILES+=usr/include/c++/4.2/tr1/memory OLD_FILES+=usr/include/c++/4.2/tr1/mu_iterate.h OLD_FILES+=usr/include/c++/4.2/tr1/random OLD_FILES+=usr/include/c++/4.2/tr1/random.tcc OLD_FILES+=usr/include/c++/4.2/tr1/ref_fwd.h OLD_FILES+=usr/include/c++/4.2/tr1/ref_wrap_iterate.h OLD_FILES+=usr/include/c++/4.2/tr1/repeat.h OLD_FILES+=usr/include/c++/4.2/tr1/stdarg.h OLD_FILES+=usr/include/c++/4.2/tr1/stdbool.h OLD_FILES+=usr/include/c++/4.2/tr1/stdint.h OLD_FILES+=usr/include/c++/4.2/tr1/stdio.h OLD_FILES+=usr/include/c++/4.2/tr1/stdlib.h OLD_FILES+=usr/include/c++/4.2/tr1/tgmath.h OLD_FILES+=usr/include/c++/4.2/tr1/tuple OLD_FILES+=usr/include/c++/4.2/tr1/tuple_defs.h OLD_FILES+=usr/include/c++/4.2/tr1/tuple_iterate.h OLD_FILES+=usr/include/c++/4.2/tr1/type_traits OLD_FILES+=usr/include/c++/4.2/tr1/type_traits_fwd.h OLD_FILES+=usr/include/c++/4.2/tr1/unordered_map OLD_FILES+=usr/include/c++/4.2/tr1/unordered_set OLD_FILES+=usr/include/c++/4.2/tr1/utility OLD_FILES+=usr/include/c++/4.2/tr1/wchar.h OLD_FILES+=usr/include/c++/4.2/tr1/wctype.h OLD_FILES+=usr/include/c++/4.2/typeinfo OLD_FILES+=usr/include/c++/4.2/utility OLD_FILES+=usr/include/c++/4.2/valarray OLD_FILES+=usr/include/c++/4.2/vector .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386" OLD_FILES+=usr/include/gcc/4.2/__wmmintrin_aes.h OLD_FILES+=usr/include/gcc/4.2/__wmmintrin_pclmul.h OLD_FILES+=usr/include/gcc/4.2/ammintrin.h OLD_FILES+=usr/include/gcc/4.2/emmintrin.h OLD_FILES+=usr/include/gcc/4.2/mm3dnow.h OLD_FILES+=usr/include/gcc/4.2/mm_malloc.h OLD_FILES+=usr/include/gcc/4.2/mmintrin.h OLD_FILES+=usr/include/gcc/4.2/pmmintrin.h OLD_FILES+=usr/include/gcc/4.2/tmmintrin.h OLD_FILES+=usr/include/gcc/4.2/wmmintrin.h OLD_FILES+=usr/include/gcc/4.2/xmmintrin.h .elif ${TARGET_ARCH} == "arm" OLD_FILES+=usr/include/gcc/4.2/mmintrin.h .elif ${TARGET_ARCH} == "powerpc" || ${TARGET_ARCH} == "powerpc64" OLD_FILES+=usr/include/gcc/4.2/altivec.h OLD_FILES+=usr/include/gcc/4.2/ppc-asm.h OLD_FILES+=usr/include/gcc/4.2/spe.h .endif OLD_FILES+=usr/lib/libgcov.a OLD_FILES+=usr/lib/libgomp.a OLD_FILES+=usr/lib/libstdc++.a OLD_FILES+=usr/lib/libstdc++.so OLD_LIBS+=usr/lib/libstdc++.so.6 OLD_FILES+=usr/lib/libstdc++_p.a OLD_FILES+=usr/lib/libsupc++.a OLD_FILES+=usr/lib/libsupc++.so OLD_LIBS+=usr/lib/libsupc++.so.1 OLD_FILES+=usr/lib/libsupc++_p.a OLD_LIBS+=usr/lib/libgomp.so.1 OLD_FILES+=usr/lib/libgomp_p.a OLD_FILES+=usr/libexec/cc1 OLD_FILES+=usr/libexec/cc1plus OLD_FILES+=usr/share/man/man1/gcpp.1.gz OLD_FILES+=usr/share/man/man1/gperf.1.gz OLD_FILES+=usr/share/man/man7/gperf.7.gz OLD_DIRS+=usr/include/c++/4.2/tr1 OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/unordered_iterator OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/trie_policy OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/tree_policy OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/thin_heap_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/splay_tree_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/resize_policy OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/rc_binomial_heap_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/rb_tree_map_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/pat_trie_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/pairing_heap_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/ov_tree_map_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_policy OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/list_update_map_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/left_child_next_sibling_heap_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/hash_fn OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/gp_hash_table_map_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/eq_fn OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/cc_hash_table_map_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/binomial_heap_base_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/binomial_heap_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/binary_heap_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/bin_search_tree_ OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail/basic_tree_policy OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds/detail OLD_DIRS+=usr/include/c++/4.2/ext/pb_ds OLD_DIRS+=usr/include/c++/4.2/ext OLD_DIRS+=usr/include/c++/4.2/debug OLD_DIRS+=usr/include/c++/4.2/bits OLD_DIRS+=usr/include/c++/4.2/backward OLD_DIRS+=usr/include/c++/4.2 # 20200220: Upgrade of ncurses, shlib bumped to version 9 OLD_LIBS+=lib/libncurses.so.8 OLD_LIBS+=lib/libncursesw.so.8 # 20200206: Remove elf2aout OLD_FILES+=usr/bin/elf2aout OLD_FILES+=usr/share/man/man1/elf2aout.1.gz # 20200204: simple_httpd removed OLD_FILES+=usr/sbin/simple_httpd # 20200127: vpo removed OLD_FILES+=usr/include/dev/ppbus/vpoio.h OLD_FILES+=usr/share/man/man4/imm.4.gz OLD_FILES+=usr/share/man/man4/vpo.4.gz # 20200104: gcc libssp removed OLD_FILES+=usr/include/ssp/ssp.h OLD_FILES+=usr/include/ssp/stdio.h OLD_FILES+=usr/include/ssp/string.h OLD_FILES+=usr/include/ssp/unistd.h OLD_DIRS+=usr/include/ssp OLD_FILES+=usr/lib/libssp.a # 20191229: GEOM_SCHED class and gsched tool removed OLD_LIBS+=lib/geom/geom_sched.so OLD_FILES+=sbin/gsched OLD_FILES+=usr/share/man/man8/gsched.8.gz # 20191222: new clang import which bumps version from 9.0.0 to 9.0.1 OLD_FILES+=usr/lib/clang/9.0.0/include/cuda_wrappers/algorithm OLD_FILES+=usr/lib/clang/9.0.0/include/cuda_wrappers/complex OLD_FILES+=usr/lib/clang/9.0.0/include/cuda_wrappers/new OLD_DIRS+=usr/lib/clang/9.0.0/include/cuda_wrappers OLD_FILES+=usr/lib/clang/9.0.0/include/openmp_wrappers/__clang_openmp_math.h OLD_FILES+=usr/lib/clang/9.0.0/include/openmp_wrappers/__clang_openmp_math_declares.h OLD_FILES+=usr/lib/clang/9.0.0/include/openmp_wrappers/cmath OLD_FILES+=usr/lib/clang/9.0.0/include/openmp_wrappers/math.h OLD_DIRS+=usr/lib/clang/9.0.0/include/openmp_wrappers OLD_FILES+=usr/lib/clang/9.0.0/include/ppc_wrappers/emmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/ppc_wrappers/mm_malloc.h OLD_FILES+=usr/lib/clang/9.0.0/include/ppc_wrappers/mmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/ppc_wrappers/xmmintrin.h OLD_DIRS+=usr/lib/clang/9.0.0/include/ppc_wrappers OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/9.0.0/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/9.0.0/include/sanitizer OLD_FILES+=usr/lib/clang/9.0.0/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/9.0.0/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/9.0.0/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/9.0.0/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/9.0.0/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/9.0.0/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/9.0.0/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/9.0.0/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/9.0.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/9.0.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/9.0.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/9.0.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/altivec.h OLD_FILES+=usr/lib/clang/9.0.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/arm64intr.h OLD_FILES+=usr/lib/clang/9.0.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/9.0.0/include/arm_fp16.h OLD_FILES+=usr/lib/clang/9.0.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/9.0.0/include/armintr.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512bf16intrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vlbf16intrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vlvp2intersectintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vp2intersectintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/cetintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/clwbintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/clzerointrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/cpuid.h OLD_FILES+=usr/lib/clang/9.0.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/enqcmdintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/gfniintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/htmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/immintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/lwpintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/9.0.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/9.0.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/module.modulemap OLD_FILES+=usr/lib/clang/9.0.0/include/movdirintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/msa.h OLD_FILES+=usr/lib/clang/9.0.0/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/opencl-c-base.h OLD_FILES+=usr/lib/clang/9.0.0/include/opencl-c.h OLD_FILES+=usr/lib/clang/9.0.0/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/pkuintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/s390intrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/sgxintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/vadefs.h OLD_FILES+=usr/lib/clang/9.0.0/include/vaesintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/vecintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/xopintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/9.0.0/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/9.0.0/include OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-aarch64.so OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-arm.so OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-armhf.so OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-preinit-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-preinit-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-preinit-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan_cxx-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan_cxx-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.cfi-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.cfi-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.cfi-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.cfi-i386.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.cfi-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.cfi_diag-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.cfi_diag-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.cfi_diag-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.cfi_diag-i386.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.cfi_diag-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.dd-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.dd-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.fuzzer-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.fuzzer-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.msan-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.msan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.profile-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.profile-powerpc.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.profile-powerpc64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.safestack-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.stats-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.stats-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.stats-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.stats_client-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.stats_client-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.stats_client-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.tsan-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_minimal-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_standalone-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-basic-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-basic-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-basic-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-basic-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-fdr-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-fdr-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-fdr-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-fdr-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-profiling-aarch64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-profiling-arm.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-profiling-armhf.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-profiling-x86_64.a OLD_FILES+=usr/lib/clang/9.0.0/lib/freebsd/libclang_rt.xray-x86_64.a OLD_DIRS+=usr/lib/clang/9.0.0/lib/freebsd OLD_DIRS+=usr/lib/clang/9.0.0/lib OLD_DIRS+=usr/lib/clang/9.0.0 # 20191221: Update libpcap from 1.9.0 to 1.9.1 OLD_FILES+=usr/share/man/man3/pcap_set_immediate_mode.3.gz OLD_FILES+=usr/share/man/man3/pcap_set_protocol.3.gz # 20191214: Removal of sranddev(3) OLD_FILES+=usr/share/man/man3/sranddev.3.gz # 20191213: Renamed (BIT|CPU)_NAND to (BIT|CPU)_ANDNOT OLD_FILES+=usr/share/man/man9/BIT_NAND.9.gz OLD_FILES+=usr/share/man/man9/CPU_NAND.9.gz # 20191213: remove timeout(9) OLD_FILES+=usr/share/man/man9/callout_handle_init.9.gz OLD_FILES+=usr/share/man/man9/timeout.9.gz OLD_FILES+=usr/share/man/man9/untimeout.9.gz # 20191128: Removal of trm(4) OLD_FILES+=usr/share/man/man4/trm.4.gz # 20191121: Removal of sio(4) OLD_FILES+=usr/share/man/man4/sio.4.gz # 20191105: picobsd(8), et al, removed OLD_FILES+=usr/share/man/man8/picobsd.8.gz # 20191017: taskqueue_start_threads_pinned became taskqueue_start_threads_cpuset OLD_FILES+=usr/share/man/man9/taskqueue_start_threads_pinned.9.gz # 20191009: new clang import which bumps version from 8.0.1 to 9.0.0 OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/esan_interface.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/8.0.1/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/8.0.1/include/sanitizer OLD_FILES+=usr/lib/clang/8.0.1/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/8.0.1/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/8.0.1/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/8.0.1/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/8.0.1/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/8.0.1/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/8.0.1/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/8.0.1/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/8.0.1/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/8.0.1/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/8.0.1/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/8.0.1/include/adxintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/altivec.h OLD_FILES+=usr/lib/clang/8.0.1/include/ammintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/arm64intr.h OLD_FILES+=usr/lib/clang/8.0.1/include/arm_acle.h OLD_FILES+=usr/lib/clang/8.0.1/include/arm_fp16.h OLD_FILES+=usr/lib/clang/8.0.1/include/arm_neon.h OLD_FILES+=usr/lib/clang/8.0.1/include/armintr.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx2intrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/avxintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/bmiintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/cetintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/clwbintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/clzerointrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/cpuid.h OLD_FILES+=usr/lib/clang/8.0.1/include/emmintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/f16cintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/fma4intrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/fmaintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/gfniintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/htmintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/ia32intrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/immintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/lwpintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/mm3dnow.h OLD_FILES+=usr/lib/clang/8.0.1/include/mm_malloc.h OLD_FILES+=usr/lib/clang/8.0.1/include/mmintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/module.modulemap OLD_FILES+=usr/lib/clang/8.0.1/include/movdirintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/msa.h OLD_FILES+=usr/lib/clang/8.0.1/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/nmmintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/opencl-c.h OLD_FILES+=usr/lib/clang/8.0.1/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/pkuintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/pmmintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/popcntintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/rtmintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/s390intrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/sgxintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/shaintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/smmintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/tbmintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/tmmintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/vadefs.h OLD_FILES+=usr/lib/clang/8.0.1/include/vaesintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/vecintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/wmmintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/x86intrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/xmmintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/xopintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/8.0.1/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/8.0.1/include OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.profile-aarch64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/8.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/8.0.1/lib/freebsd OLD_DIRS+=usr/lib/clang/8.0.1/lib OLD_DIRS+=usr/lib/clang/8.0.1 # 20191009: libc++ 9.0.0 removed some experimental files OLD_FILES+=usr/include/c++/v1/experimental/any OLD_FILES+=usr/include/c++/v1/experimental/chrono OLD_FILES+=usr/include/c++/v1/experimental/numeric OLD_FILES+=usr/include/c++/v1/experimental/optional OLD_FILES+=usr/include/c++/v1/experimental/ratio OLD_FILES+=usr/include/c++/v1/experimental/string_view OLD_FILES+=usr/include/c++/v1/experimental/system_error OLD_FILES+=usr/include/c++/v1/experimental/tuple OLD_FILES+=usr/lib/libc++fs.a # 20191003: Remove useless ZFS tests OLD_FILES+=usr/tests/sys/cddl/zfs/tests/cli_root/zpool_create/zpool_create_013_neg.ksh OLD_FILES+=usr/tests/sys/cddl/zfs/tests/cli_root/zpool_create/zpool_create_014_neg.ksh OLD_FILES+=usr/tests/sys/cddl/zfs/tests/cli_root/zpool_create/zpool_create_016_pos.ksh # 20190910: mklocale(1) and colldef(1) removed OLD_FILES+=usr/bin/mklocale OLD_FILES+=usr/share/man/man1/mklocale.1.gz OLD_FILES+=usr/bin/colldef OLD_FILES+=usr/share/man/man1/colldef.1.gz # 20190904: Remove boot1.efifat and gptboot.efifat (which never should have been) OLD_FILES+=boot/boot1.efifat OLD_FILES+=boot/gptboot.efifat # 20190903: pc-sysinstall(8) removed OLD_FILES+=usr/share/examples/pc-sysinstall/README OLD_FILES+=usr/share/examples/pc-sysinstall/pc-autoinstall.conf OLD_FILES+=usr/share/examples/pc-sysinstall/pcinstall.cfg.fbsd-netinstall OLD_FILES+=usr/share/examples/pc-sysinstall/pcinstall.cfg.geli OLD_FILES+=usr/share/examples/pc-sysinstall/pcinstall.cfg.gmirror OLD_FILES+=usr/share/examples/pc-sysinstall/pcinstall.cfg.netinstall OLD_FILES+=usr/share/examples/pc-sysinstall/pcinstall.cfg.restore OLD_FILES+=usr/share/examples/pc-sysinstall/pcinstall.cfg.rsync OLD_FILES+=usr/share/examples/pc-sysinstall/pcinstall.cfg.upgrade OLD_FILES+=usr/share/examples/pc-sysinstall/pcinstall.cfg.zfs OLD_FILES+=usr/share/man/man8/pc-sysinstall.8.gz OLD_FILES+=usr/share/pc-sysinstall/backend-partmanager/create-part.sh OLD_FILES+=usr/share/pc-sysinstall/backend-partmanager/delete-part.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/detect-emulation.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/detect-laptop.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/detect-nics.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/disk-info.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/disk-list.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/disk-part.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/enable-net.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/get-packages.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/list-components.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/list-config.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/list-mirrors.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/list-packages.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/list-rsync-backups.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/list-tzones.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/query-langs.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/send-logs.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/setup-ssh-keys.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/set-mirror.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/sys-mem.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/test-live.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/test-netup.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/update-part-list.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/xkeyboard-layouts.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/xkeyboard-models.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/xkeyboard-variants.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-bsdlabel.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-cleanup.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-disk.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-extractimage.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-ftp.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-installcomponents.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-installpackages.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-localize.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-mountdisk.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-mountoptical.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-networking.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-newfs.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-parse.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-packages.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-runcommands.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-unmount.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-upgrade.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions-users.sh OLD_FILES+=usr/share/pc-sysinstall/backend/functions.sh OLD_FILES+=usr/share/pc-sysinstall/backend/installimage.sh OLD_FILES+=usr/share/pc-sysinstall/backend/parseconfig.sh OLD_FILES+=usr/share/pc-sysinstall/backend/startautoinstall.sh OLD_FILES+=usr/share/pc-sysinstall/conf/avail-langs OLD_FILES+=usr/share/pc-sysinstall/conf/exclude-from-upgrade OLD_FILES+=usr/share/pc-sysinstall/conf/license/bsd-en.txt OLD_FILES+=usr/share/pc-sysinstall/conf/license/intel-en.txt OLD_FILES+=usr/share/pc-sysinstall/conf/license/nvidia-en.txt OLD_FILES+=usr/share/pc-sysinstall/conf/pc-sysinstall.conf OLD_FILES+=usr/share/pc-sysinstall/doc/help-disk-list OLD_FILES+=usr/share/pc-sysinstall/doc/help-disk-size OLD_FILES+=usr/share/pc-sysinstall/doc/help-index OLD_FILES+=usr/share/pc-sysinstall/doc/help-start-autoinstall OLD_FILES+=usr/sbin/pc-sysinstall OLD_DIRS+=usr/share/examples/pc-sysinstall OLD_DIRS+=usr/share/pc-sysinstall/backend OLD_DIRS+=usr/share/pc-sysinstall/backend-partmanager OLD_DIRS+=usr/share/pc-sysinstall/backend-query OLD_DIRS+=usr/share/pc-sysinstall/conf/license OLD_DIRS+=usr/share/pc-sysinstall/conf OLD_DIRS+=usr/share/pc-sysinstall/doc OLD_DIRS+=usr/share/pc-sysinstall # 20190825: zlib 1.0.4 removed from kernel OLD_FILES+=usr/include/sys/zlib.h OLD_FILES+=usr/include/sys/zutil.h # 20190817: pft_ping.py and sniffer.py moved to /usr/tests/sys/netpfil/common OLD_FILES+=usr/tests/sys/netpfil/pf/sniffer.py OLD_FILES+=usr/tests/sys/netpfil/pf/pft_ping.py # 20190816: dir.h removed from POSIX OLD_FILES+=usr/include/sys/dir.h # 20190813: deprecated GEOM classes removed OLD_FILES+=usr/share/man/man4/geom_fox.4.gz # 20190729: gzip'ed a.out support removed OLD_FILES+=usr/include/sys/inflate.h # 20190722: cap_random(3) removed OLD_LIBS+=lib/casper/libcap_random.so.1 OLD_FILES+=usr/include/casper/cap_random.h OLD_LIBS+=usr/lib/libcap_random.so OLD_FILES+=usr/share/man/man3/libcap_random.3.gz OLD_FILES+=usr/share/man/man3/cap_random.3.gz OLD_FILES+=usr/share/man/man3/cap_random_buf.3.gz # 20190708: vm_page_hold() and _unhold() removed OLD_FILES+=usr/share/man/man9/vm_page_hold.9.gz OLD_FILES+=usr/share/man/man9/vm_page_unhold.9.gz # 20190625: Remove NAND and NANDFS support OLD_FILES+=usr/share/man/man4/nand.4.gz OLD_FILES+=usr/share/man/man4/nandsim.4.gz # 20190618: sys/capability.h removed (sys/capsicum.h is the one to use) OLD_FILES+=usr/include/sys/capability.h # 20190615: sys/pwm.h renamed to dev/pwmc.h OLD_FILES+=usr/include/sys/pwm.h # 20190612: new clang import which bumps version from 8.0.0 to 8.0.1 OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/esan_interface.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/8.0.0/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/8.0.0/include/sanitizer OLD_FILES+=usr/lib/clang/8.0.0/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/8.0.0/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/8.0.0/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/8.0.0/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/8.0.0/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/8.0.0/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/8.0.0/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/8.0.0/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/8.0.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/8.0.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/8.0.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/8.0.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/altivec.h OLD_FILES+=usr/lib/clang/8.0.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/arm64intr.h OLD_FILES+=usr/lib/clang/8.0.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/8.0.0/include/arm_fp16.h OLD_FILES+=usr/lib/clang/8.0.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/8.0.0/include/armintr.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/cetintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/clwbintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/clzerointrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/cpuid.h OLD_FILES+=usr/lib/clang/8.0.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/gfniintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/htmintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/immintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/lwpintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/8.0.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/8.0.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/module.modulemap OLD_FILES+=usr/lib/clang/8.0.0/include/movdirintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/msa.h OLD_FILES+=usr/lib/clang/8.0.0/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/opencl-c.h OLD_FILES+=usr/lib/clang/8.0.0/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/pkuintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/s390intrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/sgxintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/vadefs.h OLD_FILES+=usr/lib/clang/8.0.0/include/vaesintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/vecintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/xopintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/8.0.0/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/8.0.0/include OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/8.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/8.0.0/lib/freebsd OLD_DIRS+=usr/lib/clang/8.0.0/lib OLD_DIRS+=usr/lib/clang/8.0.0 # 20190523: Remove obsolete kgzip and support files OLD_FILES+=usr/sbin/kgzip OLD_FILES+=usr/lib/kgzldr.o OLD_FILES+=usr/share/man/man8/kgzip.8.gz # 20190517: Remove obsolete 10 and 10/100 ethernet drivers OLD_FILES+=usr/share/man/man4/bm.4.gz OLD_FILES+=usr/share/man/man4/cs.4.gz OLD_FILES+=usr/share/man/man4/de.4.gz OLD_FILES+=usr/share/man/man4/if_de.4.gz OLD_FILES+=usr/share/man/man4/ed.4.gz OLD_FILES+=usr/share/man/man4/if_ed.4.gz OLD_FILES+=usr/share/man/man4/ep.4.gz OLD_FILES+=usr/share/man/man4/ex.4.gz OLD_FILES+=usr/share/man/man4/fe.4.gz OLD_FILES+=usr/share/man/man4/pcn.4.gz OLD_FILES+=usr/share/man/man4/if_pcn.4.gz OLD_FILES+=usr/share/man/man4/sf.4.gz OLD_FILES+=usr/share/man/man4/if_sf.4.gz OLD_FILES+=usr/share/man/man4/sn.4.gz OLD_FILES+=usr/share/man/man4/if_sn.4.gz OLD_FILES+=usr/share/man/man4/tl.4.gz OLD_FILES+=usr/share/man/man4/if_tl.4.gz OLD_FILES+=usr/share/man/man4/tx.4.gz OLD_FILES+=usr/share/man/man4/if_tx.4.gz OLD_FILES+=usr/share/man/man4/txp.4.gz OLD_FILES+=usr/share/man/man4/if_txp.4.gz OLD_FILES+=usr/share/man/man4/vx.4.gz OLD_FILES+=usr/share/man/man4/wb.4.gz OLD_FILES+=usr/share/man/man4/if_wb.4.gz OLD_FILES+=usr/share/man/man4/xe.4.gz OLD_FILES+=usr/share/man/man4/if_xe.4.gz # 20190513: libcap_sysctl interface change OLD_LIBS+=lib/casper/libcap_sysctl.so.1 # 20190509: tests/sys/opencrypto requires the net/py-dpkt package OLD_FILES+=usr/tests/sys/opencrypto/dpkt.py OLD_FILES+=usr/tests/sys/opencrypto/dpkt.pyc # 20190304: new libc++ import which bumps version from 7.0.1 to 8.0.0 OLD_FILES+=usr/include/c++/v1/experimental/dynarray # 20190304: new clang import which bumps version from 7.0.1 to 8.0.0 OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/esan_interface.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/netbsd_syscall_hooks.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/7.0.1/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/7.0.1/include/sanitizer OLD_FILES+=usr/lib/clang/7.0.1/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/7.0.1/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/7.0.1/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/7.0.1/include/__clang_cuda_device_functions.h OLD_FILES+=usr/lib/clang/7.0.1/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/7.0.1/include/__clang_cuda_libdevice_declares.h OLD_FILES+=usr/lib/clang/7.0.1/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/7.0.1/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/7.0.1/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/7.0.1/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/7.0.1/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/7.0.1/include/adxintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/altivec.h OLD_FILES+=usr/lib/clang/7.0.1/include/ammintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/arm64intr.h OLD_FILES+=usr/lib/clang/7.0.1/include/arm_acle.h OLD_FILES+=usr/lib/clang/7.0.1/include/arm_fp16.h OLD_FILES+=usr/lib/clang/7.0.1/include/arm_neon.h OLD_FILES+=usr/lib/clang/7.0.1/include/armintr.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx2intrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/avxintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/bmiintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/cetintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/cldemoteintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/clwbintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/clzerointrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/cpuid.h OLD_FILES+=usr/lib/clang/7.0.1/include/emmintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/f16cintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/fma4intrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/fmaintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/gfniintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/htmintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/ia32intrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/immintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/invpcidintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/lwpintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/mm3dnow.h OLD_FILES+=usr/lib/clang/7.0.1/include/mm_malloc.h OLD_FILES+=usr/lib/clang/7.0.1/include/mmintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/module.modulemap OLD_FILES+=usr/lib/clang/7.0.1/include/movdirintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/msa.h OLD_FILES+=usr/lib/clang/7.0.1/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/nmmintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/opencl-c.h OLD_FILES+=usr/lib/clang/7.0.1/include/pconfigintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/pkuintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/pmmintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/popcntintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/ptwriteintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/rtmintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/s390intrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/sgxintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/shaintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/smmintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/tbmintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/tmmintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/vadefs.h OLD_FILES+=usr/lib/clang/7.0.1/include/vaesintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/vecintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/waitpkgintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/wbnoinvdintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/wmmintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/x86intrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/xmmintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/xopintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/7.0.1/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/7.0.1/include OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.msan-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.msan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/7.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/7.0.1/lib/freebsd OLD_DIRS+=usr/lib/clang/7.0.1/lib OLD_DIRS+=usr/lib/clang/7.0.1 # 20190227: rename seq.h to seqc.h OLD_FILES+=usr/include/sys/seq.h # 20190222: libifconfig made INTERNALLIB OLD_FILES+=usr/lib/libprivateifconfig.a OLD_FILES+=usr/lib/libprivateifconfig_p.a # 20190131: pfil(9) changed OLD_FILES+=usr/share/man/man9/pfil_hook_get.9.gz OLD_FILES+=usr/share/man/man9/pfil_rlock.9.gz OLD_FILES+=usr/share/man/man9/pfil_runlock.9.gz OLD_FILES+=usr/share/man/man9/pfil_wlock.9.gz OLD_FILES+=usr/share/man/man9/pfil_wunlock.9.gz # 20190126: adv(4) / adw(4) removal OLD_FILES+=usr/share/man/man4/adv.4.gz OLD_FILES+=usr/share/man/man4/adw.4.gz # 20190123: nonexistant cred_update_thread(9) removed OLD_FILES+=usr/share/man/man9/cred_update_thread.9.gz # 20190114: old pbuf allocator removed OLD_FILES+=usr/share/man/man9/getpbuf.9.gz OLD_FILES+=usr/share/man/man9/pbuf.9.gz OLD_FILES+=usr/share/man/man9/relpbuf.9.gz OLD_FILES+=usr/share/man/man9/trypbuf.9.gz # 20181219: ibcs removal OLD_FILES+=usr/share/examples/ibcs2/hello.uu OLD_FILES+=usr/share/examples/ibcs2/README OLD_DIRS+=usr/share/examples/ibcs2 # 20181215: Migration of CTM to ports OLD_FILES+=usr/sbin/ctm OLD_FILES+=usr/sbin/ctm_dequeue OLD_FILES+=usr/sbin/ctm_rmail OLD_FILES+=usr/sbin/ctm_smail OLD_FILES+=usr/share/man/man1/ctm.1.gz OLD_FILES+=usr/share/man/man1/ctm_dequeue.1.gz OLD_FILES+=usr/share/man/man1/ctm_rmail.1.gz OLD_FILES+=usr/share/man/man1/ctm_smail.1.gz OLD_FILES+=usr/share/man/man5/ctm.5.gz # 20181214: Remove timed files OLD_FILES+=etc/rc.d/timed OLD_FILES+=usr/sbin/timed OLD_FILES+=usr/sbin/timedc OLD_FILES+=usr/share/man/man8/timed.8.gz OLD_FILES+=usr/share/man/man8/timedc.8.gz # 20181211: new clang import which bumps version from 6.0.1 to 7.0.1 OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/esan_interface.h OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/6.0.1/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/6.0.1/include/sanitizer OLD_FILES+=usr/lib/clang/6.0.1/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/6.0.1/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/6.0.1/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/6.0.1/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/6.0.1/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/6.0.1/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/6.0.1/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/6.0.1/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/6.0.1/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/6.0.1/include/adxintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/altivec.h OLD_FILES+=usr/lib/clang/6.0.1/include/ammintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/arm64intr.h OLD_FILES+=usr/lib/clang/6.0.1/include/arm_acle.h OLD_FILES+=usr/lib/clang/6.0.1/include/arm_neon.h OLD_FILES+=usr/lib/clang/6.0.1/include/armintr.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx2intrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/avxintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/bmiintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/cetintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/clwbintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/clzerointrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/cpuid.h OLD_FILES+=usr/lib/clang/6.0.1/include/emmintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/f16cintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/fma4intrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/fmaintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/gfniintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/htmintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/ia32intrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/immintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/lwpintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/mm3dnow.h OLD_FILES+=usr/lib/clang/6.0.1/include/mm_malloc.h OLD_FILES+=usr/lib/clang/6.0.1/include/mmintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/module.modulemap OLD_FILES+=usr/lib/clang/6.0.1/include/msa.h OLD_FILES+=usr/lib/clang/6.0.1/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/nmmintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/opencl-c.h OLD_FILES+=usr/lib/clang/6.0.1/include/pkuintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/pmmintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/popcntintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/rtmintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/s390intrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/shaintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/smmintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/tbmintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/tmmintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/vadefs.h OLD_FILES+=usr/lib/clang/6.0.1/include/vaesintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/vecintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/wmmintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/x86intrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/xmmintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/xopintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/6.0.1/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/6.0.1/include OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/6.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/6.0.1/lib/freebsd OLD_DIRS+=usr/lib/clang/6.0.1/lib OLD_DIRS+=usr/lib/clang/6.0.1 # 20181116: Rename test file OLD_FILES+=usr/tests/sys/netinet/reuseport_lb # 20181113: libufs version bumped to 7 OLD_LIBS+=lib/libufs.so.6 # 20181112: Cleanup old libcap_dns OLD_LIBS+=lib/casper/libcap_dns.so.1 # 20181030: malloc_domain(9) KPI change OLD_FILES+=usr/share/man/man9/malloc_domain.9.gz # 20181026: joy(4) removal OLD_FILES+=usr/share/man/man4/joy.4.gz # 20181025: OpenSSL libraries version bump to avoid conflict with ports OLD_LIBS+=lib/libcrypto.so.9 OLD_LIBS+=usr/lib/libssl.so.9 # 20181022: aha(4) removal OLD_FILES+=usr/share/man/man4/aha.4.gz # 20181022: dpt(4) removal OLD_FILES+=usr/share/man/man4/dpt.4.gz # 20181022: ncr(4) removal OLD_FILES+=usr/share/man/man4/ncr.4.gz # 20181022: ncv(4) removal OLD_FILES+=usr/share/man/man4/ncv.4.gz # 20181022: nsp(4) removal OLD_FILES+=usr/share/man/man4/nsp.4.gz # 20181022: stg(4) removal OLD_FILES+=usr/share/man/man4/stg.4.gz # 20181021: mse(4) removal OLD_FILES+=usr/share/man/man4/mse.4.gz # 20181015: Stale libcasper(3) files following r329452 OLD_LIBS+=lib/casper/libcap_sysctl.so.0 OLD_LIBS+=lib/casper/libcap_grp.so.0 OLD_LIBS+=lib/casper/libcap_pwd.so.0 OLD_LIBS+=lib/casper/libcap_random.so.0 OLD_LIBS+=lib/casper/libcap_dns.so.0 OLD_LIBS+=lib/casper/libcap_syslog.so.0 # 20181012: rename of ixlv(4) to iavf(4) OLD_FILES+=usr/share/man/man4/if_ixlv.4.gz OLD_FILES+=usr/share/man/man4/ixlv.4.gz # 20181009: OpenSSL 1.1.1 OLD_FILES+=usr/include/openssl/des_old.h OLD_FILES+=usr/include/openssl/dso.h OLD_FILES+=usr/include/openssl/krb5_asn.h OLD_FILES+=usr/include/openssl/kssl.h OLD_FILES+=usr/include/openssl/pqueue.h OLD_FILES+=usr/include/openssl/ssl23.h OLD_FILES+=usr/include/openssl/ui_compat.h OLD_FILES+=usr/share/openssl/man/man1/dss1.1.gz OLD_FILES+=usr/share/openssl/man/man1/md2.1.gz OLD_FILES+=usr/share/openssl/man/man1/md4.1.gz OLD_FILES+=usr/share/openssl/man/man1/md5.1.gz OLD_FILES+=usr/share/openssl/man/man1/mdc2.1.gz OLD_FILES+=usr/share/openssl/man/man1/ripemd160.1.gz OLD_FILES+=usr/share/openssl/man/man1/sha.1.gz OLD_FILES+=usr/share/openssl/man/man1/sha1.1.gz OLD_FILES+=usr/share/openssl/man/man1/sha224.1.gz OLD_FILES+=usr/share/openssl/man/man1/sha256.1.gz OLD_FILES+=usr/share/openssl/man/man1/sha384.1.gz OLD_FILES+=usr/share/openssl/man/man1/sha512.1.gz OLD_FILES+=usr/share/openssl/man/man1/x509v3_config.1.gz OLD_FILES+=usr/share/openssl/man/man3/ASN1_STRING_length_set.3.gz OLD_FILES+=usr/share/openssl/man/man3/BIO_get_conn_int_port.3.gz OLD_FILES+=usr/share/openssl/man/man3/BIO_get_conn_ip.3.gz OLD_FILES+=usr/share/openssl/man/man3/BIO_set.3.gz OLD_FILES+=usr/share/openssl/man/man3/BIO_set_conn_int_port.3.gz OLD_FILES+=usr/share/openssl/man/man3/BIO_set_conn_ip.3.gz OLD_FILES+=usr/share/openssl/man/man3/BN_BLINDING_get_thread_id.3.gz OLD_FILES+=usr/share/openssl/man/man3/BN_BLINDING_set_thread_id.3.gz OLD_FILES+=usr/share/openssl/man/man3/BN_BLINDING_thread_id.3.gz OLD_FILES+=usr/share/openssl/man/man3/BN_CTX_init.3.gz OLD_FILES+=usr/share/openssl/man/man3/BN_MONT_CTX_init.3.gz OLD_FILES+=usr/share/openssl/man/man3/BN_RECP_CTX_init.3.gz OLD_FILES+=usr/share/openssl/man/man3/BN_init.3.gz OLD_FILES+=usr/share/openssl/man/man3/BUF_memdup.3.gz OLD_FILES+=usr/share/openssl/man/man3/BUF_memdup.3.gz OLD_FILES+=usr/share/openssl/man/man3/BUF_strdup.3.gz OLD_FILES+=usr/share/openssl/man/man3/BUF_strlcat.3.gz OLD_FILES+=usr/share/openssl/man/man3/BUF_strlcpy.3.gz OLD_FILES+=usr/share/openssl/man/man3/BUF_strndup.3.gz OLD_FILES+=usr/share/openssl/man/man3/CMS_set1_signer_cert.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_THREADID_cmp.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_THREADID_cpy.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_THREADID_current.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_THREADID_get_callback.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_THREADID_hash.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_THREADID_set_callback.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_destroy_dynlockid.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_get_new_dynlockid.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_lock.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_num_locks.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_set_dynlock_create_callback.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_set_dynlock_destroy_callback.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_set_dynlock_lock_callback.3.gz OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_set_locking_callback.3.gz OLD_FILES+=usr/share/openssl/man/man3/DES_ede3_cbcm_encrypt.3.gz OLD_FILES+=usr/share/openssl/man/man3/DES_enc_read.3.gz OLD_FILES+=usr/share/openssl/man/man3/DES_enc_write.3.gz OLD_FILES+=usr/share/openssl/man/man3/EC_KEY_get_key_method_data.3.gz OLD_FILES+=usr/share/openssl/man/man3/EC_KEY_insert_key_method_data.3.gz OLD_FILES+=usr/share/openssl/man/man3/EC_POINT_set_Jprojective_coordinates.3.gz OLD_FILES+=usr/share/openssl/man/man3/ERR_load_UI_strings.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_CIPHER_CTX_cleanup.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_CIPHER_CTX_init.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_MAX_MD_SIZE.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_MD_CTX_cleanup.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_MD_CTX_create.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_MD_CTX_destroy.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_MD_CTX_init.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_PKEVP_PKEY_CTX_set_app_data.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_PKEY_CTX_set_rsa_rsa_keygen_bits.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_PKEY_get_default_digest.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_dss.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_dss1.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_sha.3.gz OLD_FILES+=usr/share/openssl/man/man3/HMAC_CTX_cleanup.3.gz OLD_FILES+=usr/share/openssl/man/man3/HMAC_CTX_init.3.gz OLD_FILES+=usr/share/openssl/man/man3/HMAC_cleanup.3.gz OLD_FILES+=usr/share/openssl/man/man3/OPENSSL_ia32cap_loc.3.gz OLD_FILES+=usr/share/openssl/man/man3/PEM.3.gz OLD_FILES+=usr/share/openssl/man/man3/RAND_SSLeay.3.gz OLD_FILES+=usr/share/openssl/man/man3/RSA_PKCS1_SSLeay.3.gz OLD_FILES+=usr/share/openssl/man/man3/RSA_null_method.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_CTX_get_ex_new_index.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_CTX_need_tmp_rsa.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_CTX_set_custom_cli_ext.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_CTX_set_default_read_ahead.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_CTX_set_ecdh_auto.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_CTX_set_tmp_rsa.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_CTX_set_tmp_rsa_callback.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_SESSION_get_ex_new_index.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_add_session.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_flush_sessions.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_get_accept_state.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_get_ex_new_index.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_get_msg_callback_arg.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_need_tmp_rsa.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_remove_session.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_set_ecdh_auto.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_set_tmp_rsa.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSL_set_tmp_rsa_callback.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSLeay.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSLeay_add_ssl_algorithms.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSLeay_version.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSLv2_client_method.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSLv2_method.3.gz OLD_FILES+=usr/share/openssl/man/man3/SSLv2_server_method.3.gz OLD_FILES+=usr/share/openssl/man/man3/X509_STORE_CTX_set_chain.3.gz OLD_FILES+=usr/share/openssl/man/man3/X509_STORE_CTX_trusted_stack.3.gz OLD_FILES+=usr/share/openssl/man/man3/bio.3.gz OLD_FILES+=usr/share/openssl/man/man3/blowfish.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_add_words.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_check_top.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_cmp_words.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_div_words.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_dump.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_expand.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_expand2.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_fix_top.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_internal.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_mul_add_words.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_mul_comba4.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_mul_comba8.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_mul_high.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_mul_low_normal.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_mul_low_recursive.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_mul_normal.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_mul_part_recursive.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_mul_recursive.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_mul_words.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_print.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_set_high.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_set_low.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_set_max.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_sqr_comba4.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_sqr_comba8.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_sqr_normal.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_sqr_recursive.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_sqr_words.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_sub_words.3.gz OLD_FILES+=usr/share/openssl/man/man3/bn_wexpand.3.gz OLD_FILES+=usr/share/openssl/man/man3/buffer.3.gz OLD_FILES+=usr/share/openssl/man/man3/crypto.3.gz OLD_FILES+=usr/share/openssl/man/man3/d2i_ECPKParameters_bio.3.gz OLD_FILES+=usr/share/openssl/man/man3/d2i_ECPKParameters_fp.3.gz OLD_FILES+=usr/share/openssl/man/man3/d2i_ECPrivate_key.3.gz OLD_FILES+=usr/share/openssl/man/man3/d2i_Netscape_RSA.3.gz OLD_FILES+=usr/share/openssl/man/man3/d2i_PKCS8PrivateKey.3.gz OLD_FILES+=usr/share/openssl/man/man3/d2i_Private_key.3.gz OLD_FILES+=usr/share/openssl/man/man3/des.3.gz OLD_FILES+=usr/share/openssl/man/man3/des_read_2passwords.3.gz OLD_FILES+=usr/share/openssl/man/man3/des_read_password.3.gz OLD_FILES+=usr/share/openssl/man/man3/des_read_pw.3.gz OLD_FILES+=usr/share/openssl/man/man3/des_read_pw_string.3.gz OLD_FILES+=usr/share/openssl/man/man3/dh.3.gz OLD_FILES+=usr/share/openssl/man/man3/dsa.3.gz OLD_FILES+=usr/share/openssl/man/man3/ec.3.gz OLD_FILES+=usr/share/openssl/man/man3/ecdsa.3.gz OLD_FILES+=usr/share/openssl/man/man3/engine.3.gz OLD_FILES+=usr/share/openssl/man/man3/err.3.gz OLD_FILES+=usr/share/openssl/man/man3/evp.3.gz OLD_FILES+=usr/share/openssl/man/man3/hmac.3.gz OLD_FILES+=usr/share/openssl/man/man3/i2d_ECPKParameters_bio.3.gz OLD_FILES+=usr/share/openssl/man/man3/i2d_ECPKParameters_fp.3.gz OLD_FILES+=usr/share/openssl/man/man3/i2d_Netscape_RSA.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_delete.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_doall.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_doall_arg.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_error.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_free.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_insert.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_new.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_node_stats.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_node_stats_bio.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_node_usage_stats.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_node_usage_stats_bio.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_retrieve.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_stats.3.gz OLD_FILES+=usr/share/openssl/man/man3/lh_stats_bio.3.gz OLD_FILES+=usr/share/openssl/man/man3/lhash.3.gz OLD_FILES+=usr/share/openssl/man/man3/md5.3.gz OLD_FILES+=usr/share/openssl/man/man3/mdc2.3.gz OLD_FILES+=usr/share/openssl/man/man3/pem.3.gz OLD_FILES+=usr/share/openssl/man/man3/rand.3.gz OLD_FILES+=usr/share/openssl/man/man3/rc4.3.gz OLD_FILES+=usr/share/openssl/man/man3/ripemd.3.gz OLD_FILES+=usr/share/openssl/man/man3/rsa.3.gz OLD_FILES+=usr/share/openssl/man/man3/sha.3.gz OLD_FILES+=usr/share/openssl/man/man3/ssl.3.gz OLD_FILES+=usr/share/openssl/man/man3/threads.3.gz OLD_FILES+=usr/share/openssl/man/man3/ui.3.gz OLD_FILES+=usr/share/openssl/man/man3/ui_compat.3.gz OLD_FILES+=usr/share/openssl/man/man3/x509.3.gz OLD_LIBS+=lib/libcrypto.so.8 OLD_LIBS+=usr/lib/engines/lib4758cca.so OLD_LIBS+=usr/lib/engines/libaep.so OLD_LIBS+=usr/lib/engines/libatalla.so OLD_LIBS+=usr/lib/engines/libcapi.so OLD_LIBS+=usr/lib/engines/libchil.so OLD_LIBS+=usr/lib/engines/libcswift.so OLD_LIBS+=usr/lib/engines/libgost.so OLD_LIBS+=usr/lib/engines/libnuron.so OLD_LIBS+=usr/lib/engines/libsureware.so OLD_LIBS+=usr/lib/engines/libubsec.so OLD_LIBS+=usr/lib/libssl.so.8 OLD_LIBS+=usr/lib32/lib4758cca.so OLD_LIBS+=usr/lib32/libaep.so OLD_LIBS+=usr/lib32/libatalla.so OLD_LIBS+=usr/lib32/libcapi.so OLD_LIBS+=usr/lib32/libchil.so OLD_LIBS+=usr/lib32/libcswift.so OLD_LIBS+=usr/lib32/libgost.so OLD_LIBS+=usr/lib32/libnuron.so OLD_LIBS+=usr/lib32/libsureware.so OLD_LIBS+=usr/lib32/libubsec.so # 20180824: libbe(3) SHLIBDIR fixed to reflect correct location MOVED_LIBS+=usr/lib/libbe.so.1 # 20180819: Remove deprecated arc4random(3) stir/addrandom interfaces OLD_FILES+=usr/share/man/man3/arc4random_addrandom.3.gz OLD_FILES+=usr/share/man/man3/arc4random_stir.3.gz # 20180819: send-pr(1) placeholder removal OLD_FILES+=usr/bin/send-pr # 20180801: jedec_ts(4) removed OLD_FILES+=usr/share/man/man4/jedec_ts.4.gz # 20180725: Cleanup old libcasper.so.0 OLD_LIBS+=lib/libcasper.so.0 # 20180722: indent(1) option renamed, test files follow OLD_FILES+=usr/bin/indent/tests/nsac.0 OLD_FILES+=usr/bin/indent/tests/nsac.0.pro OLD_FILES+=usr/bin/indent/tests/nsac.0.stdout OLD_FILES+=usr/bin/indent/tests/sac.0 OLD_FILES+=usr/bin/indent/tests/sac.0.pro OLD_FILES+=usr/bin/indent/tests/sac.0.stdout # 20180721: move of libmlx5.so.1 and libibverbs.so.1 MOVED_LIBS+=usr/lib/libmlx5.so.1 MOVED_LIBS+=usr/lib/libibverbs.so.1 # 20180720: zfsloader.8 merged into loader.8 OLD_FILES+=usr/share/man/man8/zfsloader.8.gz # 20180710: old numa cleanup OLD_FILES+=usr/include/sys/numa.h OLD_FILES+=usr/share/man/man2/numa_getaffinity.2.gz OLD_FILES+=usr/share/man/man2/numa_setaffinity.2.gz OLD_FILES+=usr/share/man/man1/numactl.1.gz OLD_FILES+=usr/bin/numactl # 20180630: new clang import which bumps version from 6.0.0 to 6.0.1 OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/esan_interface.h OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/hwasan_interface.h OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/scudo_interface.h OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/6.0.0/include/sanitizer OLD_FILES+=usr/lib/clang/6.0.0/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/6.0.0/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/6.0.0/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/6.0.0/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/6.0.0/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/6.0.0/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/6.0.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/6.0.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/6.0.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/6.0.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/altivec.h OLD_FILES+=usr/lib/clang/6.0.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/arm64intr.h OLD_FILES+=usr/lib/clang/6.0.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/6.0.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/6.0.0/include/armintr.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512bitalgintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vbmi2intrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vlbitalgintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vlvbmi2intrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vlvnniintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vnniintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avx512vpopcntdqvlintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/cetintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/clwbintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/clzerointrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/cpuid.h OLD_FILES+=usr/lib/clang/6.0.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/gfniintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/htmintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/immintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/lwpintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/6.0.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/6.0.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/module.modulemap OLD_FILES+=usr/lib/clang/6.0.0/include/msa.h OLD_FILES+=usr/lib/clang/6.0.0/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/opencl-c.h OLD_FILES+=usr/lib/clang/6.0.0/include/pkuintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/s390intrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/vadefs.h OLD_FILES+=usr/lib/clang/6.0.0/include/vaesintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/vecintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/vpclmulqdqintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/xopintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/6.0.0/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/6.0.0/include OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.tsan-x86_64.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.ubsan_minimal-i386.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/6.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/6.0.0/lib/freebsd OLD_DIRS+=usr/lib/clang/6.0.0/lib OLD_DIRS+=usr/lib/clang/6.0.0 # 20180615: asf(8) removed OLD_FILES+=usr/sbin/asf OLD_FILES+=usr/share/man/man8/asf.8.gz # 20180609: obsolete libc++ files missed from the 5.0.0 import OLD_FILES+=usr/include/c++/v1/__refstring OLD_FILES+=usr/include/c++/v1/__undef_min_max OLD_FILES+=usr/include/c++/v1/tr1/__refstring OLD_FILES+=usr/include/c++/v1/tr1/__undef_min_max # 20180607: remove nls support from grep OLD_FILES+=usr/share/nls/pt_BR.ISO8859-1/grep.cat OLD_FILES+=usr/share/nls/hu_HU.ISO8859-2/grep.cat OLD_FILES+=usr/share/nls/ja_JP.SJIS/grep.cat OLD_FILES+=usr/share/nls/ja_JP.eucJP/grep.cat OLD_FILES+=usr/share/nls/gl_ES.ISO8859-1/grep.cat OLD_FILES+=usr/share/nls/zh_CN.UTF-8/grep.cat OLD_FILES+=usr/share/nls/es_ES.ISO8859-1/grep.cat OLD_FILES+=usr/share/nls/ru_RU.KOI8-R/grep.cat OLD_FILES+=usr/share/nls/uk_UA.UTF-8/grep.cat OLD_FILES+=usr/share/nls/ja_JP.UTF-8/grep.cat # 20180528: libpcap update removed header file OLD_FILES+=usr/include/pcap/export-defs.h # 20180517: retire vxge OLD_FILES+=usr/share/man/man4/if_vxge.4.gz OLD_FILES+=usr/share/man/man4/vxge.4.gz # 20180512: Rename Unbound tools OLD_FILES+=usr/sbin/unbound OLD_FILES+=usr/sbin/unbound-anchor OLD_FILES+=usr/sbin/unbound-checkconf OLD_FILES+=usr/sbin/unbound-control OLD_FILES+=usr/share/man/man5/unbound.conf.5.gz OLD_FILES+=usr/share/man/man8/unbound-anchor.8.gz OLD_FILES+=usr/share/man/man8/unbound-checkconf.8.gz OLD_FILES+=usr/share/man/man8/unbound-control.8.gz OLD_FILES+=usr/share/man/man8/unbound.8.gz # 20180508: retire nxge OLD_FILES+=usr/share/man/man4/if_nxge.4.gz OLD_FILES+=usr/share/man/man4/nxge.4.gz # 20180505: rhosts OLD_FILES+=usr/share/skel/dot.rhosts # 20180502: retire ixgb OLD_FILES+=usr/share/man/man4/if_ixgb.4.gz OLD_FILES+=usr/share/man/man4/ixgb.4.gz # 20180501: retire lmc OLD_FILES+=usr/include/dev/lmc/if_lmc.h OLD_DIRS+=usr/include/dev/lmc OLD_FILES+=usr/sbin/lmcconfig OLD_FILES+=usr/share/man/man4/lmc.4.gz OLD_FILES+=usr/share/man/man4/if_lmc.4.gz OLD_FILES+=usr/share/man/man8/lmcconfig.8.gz # 20180417: remove fuswintr and suswintr OLD_FILES+=usr/share/man/man9/fuswintr.9.gz OLD_FILES+=usr/share/man/man9/suswintr.9.gz # 20180413: remove Arcnet support OLD_FILES+=usr/include/net/if_arc.h OLD_FILES+=usr/share/man/man4/cm.4.gz # 20180409: remove FDDI support OLD_FILES+=usr/include/net/fddi.h OLD_FILES+=usr/share/man/man4/fpa.4.gz # 20180319: remove /boot/overlays, replaced by /boot/dtb/overlays OLD_DIRS+=boot/overlays # 20180311: remove sys/sys/i386/include/pcaudioio.h .if ${TARGET_ARCH} == "i386" OLD_FILES+=usr/include/machine/pcaudioio.h .endif # 20180310: remove sys/sys/dataacq.h OLD_FILES+=usr/include/sys/dataacq.h # 20180306: remove DTrace scripts made obsolete by dwatch(1) OLD_FILES+=usr/share/dtrace/watch_execve OLD_FILES+=usr/share/dtrace/watch_kill OLD_FILES+=usr/share/dtrace/watch_vop_remove # 20180212: move devmatch OLD_FILES+=usr/sbin/devmatch # 20180211: remove usb.conf OLD_FILES+=etc/devd/usb.conf # 20180208: remove c_rehash(1) OLD_FILES+=usr/share/openssl/man/man1/c_rehash.1.gz # 20180206: remove gdbtui OLD_FILES+=usr/bin/gdbtui # 20180201: Obsolete forth files OLD_FILES+=boot/pcibios.4th # 20180114: new clang import which bumps version from 5.0.1 to 6.0.0 OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/esan_interface.h OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/5.0.1/include/sanitizer OLD_FILES+=usr/lib/clang/5.0.1/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/5.0.1/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/5.0.1/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/5.0.1/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/5.0.1/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/5.0.1/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/5.0.1/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/5.0.1/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/5.0.1/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/5.0.1/include/adxintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/altivec.h OLD_FILES+=usr/lib/clang/5.0.1/include/ammintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/arm_acle.h OLD_FILES+=usr/lib/clang/5.0.1/include/arm_neon.h OLD_FILES+=usr/lib/clang/5.0.1/include/armintr.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx2intrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/avxintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/bmiintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/clzerointrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/cpuid.h OLD_FILES+=usr/lib/clang/5.0.1/include/emmintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/f16cintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/fma4intrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/fmaintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/htmintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/ia32intrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/immintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/lwpintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/mm3dnow.h OLD_FILES+=usr/lib/clang/5.0.1/include/mm_malloc.h OLD_FILES+=usr/lib/clang/5.0.1/include/mmintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/module.modulemap OLD_FILES+=usr/lib/clang/5.0.1/include/msa.h OLD_FILES+=usr/lib/clang/5.0.1/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/nmmintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/opencl-c.h OLD_FILES+=usr/lib/clang/5.0.1/include/pkuintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/pmmintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/popcntintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/rtmintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/s390intrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/shaintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/smmintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/tbmintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/tmmintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/vadefs.h OLD_FILES+=usr/lib/clang/5.0.1/include/vecintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/wmmintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/x86intrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/xmmintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/xopintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/5.0.1/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/5.0.1/include OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/5.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/5.0.1/lib/freebsd OLD_DIRS+=usr/lib/clang/5.0.1/lib OLD_DIRS+=usr/lib/clang/5.0.1 # 20180109: Remove vestiges of digi(4) driver OLD_FILES+=usr/include/sys/digiio.h OLD_FILES+=usr/sbin/digictl OLD_FILES+=usr/share/man/man8/digictl.8.gz # 20180107: Convert remaining geli(8) tests to ATF OLD_FILES+=tests/sys/geom/class/eli/nokey_test.sh OLD_FILES+=tests/sys/geom/class/eli/readonly_test.sh # 20180106: Convert most geli(8) tests to ATF OLD_FILES+=tests/sys/geom/class/eli/attach_d_test.sh OLD_FILES+=tests/sys/geom/class/eli/configure_b_B_test.sh OLD_FILES+=tests/sys/geom/class/eli/detach_l_test.sh OLD_FILES+=tests/sys/geom/class/eli/init_B_test.sh OLD_FILES+=tests/sys/geom/class/eli/init_J_test.sh OLD_FILES+=tests/sys/geom/class/eli/init_a_test.sh OLD_FILES+=tests/sys/geom/class/eli/init_alias_test.sh OLD_FILES+=tests/sys/geom/class/eli/init_i_P_test.sh OLD_FILES+=tests/sys/geom/class/eli/integrity_copy_test.sh OLD_FILES+=tests/sys/geom/class/eli/integrity_data_test.sh OLD_FILES+=tests/sys/geom/class/eli/integrity_hmac_test.sh OLD_FILES+=tests/sys/geom/class/eli/onetime_a_test.sh OLD_FILES+=tests/sys/geom/class/eli/onetime_d_test.sh # 20171230: Remove /etc/skel from mtree OLD_DIRS+=etc/skel # 20171208: Remove basename_r(3) OLD_FILES+=usr/share/man/man3/basename_r.3.gz # 20171206: Remove sponge(1) OLD_FILES+=usr/bin/sponge OLD_FILES+=usr/share/man/man1/sponge.1.gz # 20171204: Move fdformat man page from volume 1 to volume 8 OLD_FILES+=usr/share/man/man1/fdformat.1.gz # 20171203: libproc version bump OLD_LIBS+=usr/lib/libproc.so.4 # 20171203: new clang import which bumps version from 5.0.0 to 5.0.1 OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/esan_interface.h OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/tsan_interface.h OLD_FILES+=usr/lib/clang/5.0.0/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/5.0.0/include/sanitizer OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/5.0.0/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/5.0.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/5.0.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/5.0.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/5.0.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/altivec.h OLD_FILES+=usr/lib/clang/5.0.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/5.0.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/5.0.0/include/armintr.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avx512vpopcntdqintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/clzerointrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/cpuid.h OLD_FILES+=usr/lib/clang/5.0.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/htmintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/immintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/lwpintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/5.0.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/5.0.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/module.modulemap OLD_FILES+=usr/lib/clang/5.0.0/include/msa.h OLD_FILES+=usr/lib/clang/5.0.0/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/opencl-c.h OLD_FILES+=usr/lib/clang/5.0.0/include/pkuintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/s390intrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/vadefs.h OLD_FILES+=usr/lib/clang/5.0.0/include/vecintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/xopintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/5.0.0/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/5.0.0/include OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-armhf.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/5.0.0/lib/freebsd OLD_DIRS+=usr/lib/clang/5.0.0/lib OLD_DIRS+=usr/lib/clang/5.0.0 # 20171118: Remove old etc casper files OLD_FILES+=etc/casper/system.dns OLD_FILES+=etc/casper/system.grp OLD_FILES+=etc/casper/system.pwd OLD_FILES+=etc/casper/system.random OLD_FILES+=etc/casper/system.sysctl OLD_DIRS+=etc/casper # 20171116: lint(1) removal OLD_FILES+=usr/bin/lint OLD_FILES+=usr/libexec/lint1 OLD_FILES+=usr/libexec/lint2 OLD_FILES+=usr/libdata/lint/llib-lposix.ln OLD_FILES+=usr/libdata/lint/llib-lstdc.ln OLD_FILES+=usr/share/man/man1/lint.1.gz OLD_FILES+=usr/share/man/man7/lint.7.gz OLD_DIRS+=usr/libdata/lint # 20171114: Removal of all fortune datfiles other than freebsd-tips OLD_FILES+=usr/share/games/fortune/fortunes OLD_FILES+=usr/share/games/fortune/fortunes.dat OLD_FILES+=usr/share/games/fortune/gerrold.limerick OLD_FILES+=usr/share/games/fortune/gerrold.limerick.dat OLD_FILES+=usr/share/games/fortune/limerick OLD_FILES+=usr/share/games/fortune/limerick.dat OLD_FILES+=usr/share/games/fortune/murphy OLD_FILES+=usr/share/games/fortune/murphy-o OLD_FILES+=usr/share/games/fortune/murphy-o.dat OLD_FILES+=usr/share/games/fortune/murphy.dat OLD_FILES+=usr/share/games/fortune/startrek OLD_FILES+=usr/share/games/fortune/startrek.dat OLD_FILES+=usr/share/games/fortune/zippy OLD_FILES+=usr/share/games/fortune/zippy.dat # 20171112: Removal of eqnchar definition OLD_FILES+=usr/share/misc/eqnchar # 20171110: Removal of mailaddr man page OLD_FILES+=usr/share/man/man7/mailaddr.7.gz # 20171108: Rename of NgSendMsgReply to NgSendReplyMsg OLD_FILES+=usr/share/man/man3/NgSendMsgReply.3.gz # 20171108: badsect(8) removal OLD_FILES+=sbin/badsect OLD_FILES+=rescue/badsect OLD_FILES+=usr/share/man/man8/badsect.8.gz # 20171105: fixing lib/libclang_rt CRTARCH for arm:armv[67] .if ${MACHINE_ARCH:Marmv[67]*} != "" && \ (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "") OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-preinit-arm.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-arm.a OLD_LIBS+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan-arm.so OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.asan_cxx-arm.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.safestack-arm.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats-arm.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.stats_client-arm.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone-arm.a OLD_FILES+=usr/lib/clang/5.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a .endif # 20171104: libcap_random should be in /lib not in /usr/lib OLD_LIBS+=usr/lib/libcap_random.so.0 # 20171104: Casper can work only as shared library OLD_FILES+=usr/lib/libcap_dns.a OLD_FILES+=usr/lib/libcap_dns_p.a OLD_FILES+=usr/lib/libcap_grp.a OLD_FILES+=usr/lib/libcap_grp_p.a OLD_FILES+=usr/lib/libcap_pwd.a OLD_FILES+=usr/lib/libcap_pwd_p.a OLD_FILES+=usr/lib/libcap_random.a OLD_FILES+=usr/lib/libcap_random_p.a OLD_FILES+=usr/lib/libcap_sysctl.a OLD_FILES+=usr/lib/libcap_sysctl_p.a OLD_FILES+=usr/lib/libcasper.a OLD_FILES+=usr/lib/libcasper_p.a # 20171031: Removal of adding_user man page OLD_FILES+=usr/share/man/man7/adding_user.7.gz # 20171031: Disconnected libpathconv tests OLD_DIRS+=usr/tests/lib/libpathconv # 20171017: Removal of mbpool(9) OLD_FILES+=usr/include/sys/mbpool.h OLD_FILES+=usr/share/man/man9/mbpool.9.gz OLD_FILES+=usr/share/man/man9/mbp_destroy.9.gz OLD_FILES+=usr/share/man/man9/mbp_alloc.9.gz OLD_FILES+=usr/share/man/man9/mbp_ext_free.9.gz OLD_FILES+=usr/share/man/man9/mbp_count.9.gz OLD_FILES+=usr/share/man/man9/mbp_card_free.9.gz OLD_FILES+=usr/share/man/man9/mbp_get_keep.9.gz OLD_FILES+=usr/share/man/man9/mbp_free.9.gz OLD_FILES+=usr/share/man/man9/mbp_get.9.gz OLD_FILES+=usr/share/man/man9/mbp_create.9.gz OLD_FILES+=usr/share/man/man9/mbp_sync.9.gz # 20171010: Remove libstand OLD_FILES+=usr/lib/libstand.a OLD_FILES+=usr/lib/libstand_p.a OLD_FILES+=usr/include/stand.h OLD_FILES+=usr/share/man/man3/libstand.3.gz # 20171003: remove RCMDS OLD_FILES+=bin/rcp OLD_FILES+=rescue/rcp OLD_FILES+=usr/bin/rlogin OLD_FILES+=usr/bin/rsh OLD_FILES+=usr/libexec/rlogind OLD_FILES+=usr/libexec/rshd OLD_FILES+=usr/share/man/man1/rcp.1.gz OLD_FILES+=usr/share/man/man1/rlogin.1.gz OLD_FILES+=usr/share/man/man1/rsh.1.gz OLD_FILES+=usr/share/man/man8/rlogind.8.gz OLD_FILES+=usr/share/man/man8/rshd.8.gz # 20170927: crshared OLD_FILES+=usr/share/man/man9/crshared.9.gz # 20170927: procctl OLD_FILES+=usr/share/man/man8/procctl.8.gz OLD_FILES+=usr/sbin/procctl # 20170926: remove unneeded man aliases and locales directory OLD_FILES+=usr/share/man/en.ISO8859-1/man1 OLD_FILES+=usr/share/man/en.ISO8859-1/man2 OLD_FILES+=usr/share/man/en.ISO8859-1/man3 OLD_FILES+=usr/share/man/en.ISO8859-1/man4 OLD_FILES+=usr/share/man/en.ISO8859-1/man5 OLD_FILES+=usr/share/man/en.ISO8859-1/man6 OLD_FILES+=usr/share/man/en.ISO8859-1/man7 OLD_FILES+=usr/share/man/en.ISO8859-1/man8 OLD_FILES+=usr/share/man/en.ISO8859-1/man9 OLD_DIRS+=usr/share/man/en.ISO8859-1 OLD_FILES+=usr/share/man/en.ISO8859-1/mandoc.db OLD_FILES+=usr/share/man/en.UTF-8/man1 OLD_FILES+=usr/share/man/en.UTF-8/man2 OLD_FILES+=usr/share/man/en.UTF-8/man3 OLD_FILES+=usr/share/man/en.UTF-8/man4 OLD_FILES+=usr/share/man/en.UTF-8/man5 OLD_FILES+=usr/share/man/en.UTF-8/man6 OLD_FILES+=usr/share/man/en.UTF-8/man7 OLD_FILES+=usr/share/man/en.UTF-8/man8 OLD_FILES+=usr/share/man/en.UTF-8/man9 OLD_FILES+=usr/share/man/en.UTF-8/mandoc.db OLD_DIRS+=usr/share/man/en.UTF-8 OLD_FILES+=usr/share/man/en.ISO8859-15 OLD_FILES+=usr/share/openssl/man/en.ISO8859-1/man1 OLD_FILES+=usr/share/openssl/man/en.ISO8859-1/man3 OLD_FILES+=usr/share/openssl/man/en.ISO8859-1/mandoc.db OLD_DIRS+=usr/share/openssl/man/en.ISO8859-1 OLD_FILES+=usr/share/openssl/man/en.ISO8859-15 OLD_DIRS+=usr/share/man/ja/man1 OLD_DIRS+=usr/share/man/ja/man2 OLD_DIRS+=usr/share/man/ja/man3 OLD_DIRS+=usr/share/man/ja/man4 OLD_DIRS+=usr/share/man/ja/man5 OLD_DIRS+=usr/share/man/ja/man6 OLD_DIRS+=usr/share/man/ja/man7 OLD_DIRS+=usr/share/man/ja/man8 OLD_DIRS+=usr/share/man/ja/man9 OLD_DIRS+=usr/share/man/ja # 20170913: remove unneeded catman utility OLD_FILES+=etc/periodic/weekly/330.catman OLD_FILES+=usr/bin/catman OLD_FILES+=usr/libexec/catman.local OLD_FILES+=usr/share/man/man1/catman.1.gz OLD_FILES+=usr/share/man/man8/catman.local.8.gz OLD_DIRS+=usr/share/man/cat1 OLD_DIRS+=usr/share/man/cat2 OLD_DIRS+=usr/share/man/cat3 OLD_DIRS+=usr/share/man/cat4/amd64 OLD_DIRS+=usr/share/man/cat4/arm OLD_DIRS+=usr/share/man/cat4/i386 OLD_DIRS+=usr/share/man/cat4/powerpc OLD_DIRS+=usr/share/man/cat4/sparc64 OLD_DIRS+=usr/share/man/cat4 OLD_DIRS+=usr/share/man/cat5 OLD_DIRS+=usr/share/man/cat6 OLD_DIRS+=usr/share/man/cat7 OLD_DIRS+=usr/share/man/cat8/amd64 OLD_DIRS+=usr/share/man/cat8/arm OLD_DIRS+=usr/share/man/cat8/i386 OLD_DIRS+=usr/share/man/cat8/powerpc OLD_DIRS+=usr/share/man/cat8/sparc64 OLD_DIRS+=usr/share/man/cat8 OLD_DIRS+=usr/share/man/cat9 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat1 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat2 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat3 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat4/amd64 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat4/arm OLD_DIRS+=usr/share/man/en.ISO8859-1/cat4/i386 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat4/powerpc OLD_DIRS+=usr/share/man/en.ISO8859-1/cat4/sparc64 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat4 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat5 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat6 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat7 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat8/amd64 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat8/arm OLD_DIRS+=usr/share/man/en.ISO8859-1/cat8/i386 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat8/powerpc OLD_DIRS+=usr/share/man/en.ISO8859-1/cat8/sparc64 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat8 OLD_DIRS+=usr/share/man/en.ISO8859-1/cat9 OLD_DIRS+=usr/share/man/en.UTF-8/cat1 OLD_DIRS+=usr/share/man/en.UTF-8/cat2 OLD_DIRS+=usr/share/man/en.UTF-8/cat3 OLD_DIRS+=usr/share/man/en.UTF-8/cat4/amd64 OLD_DIRS+=usr/share/man/en.UTF-8/cat4/arm OLD_DIRS+=usr/share/man/en.UTF-8/cat4/i386 OLD_DIRS+=usr/share/man/en.UTF-8/cat4/powerpc OLD_DIRS+=usr/share/man/en.UTF-8/cat4/sparc64 OLD_DIRS+=usr/share/man/en.UTF-8/cat4 OLD_DIRS+=usr/share/man/en.UTF-8/cat5 OLD_DIRS+=usr/share/man/en.UTF-8/cat6 OLD_DIRS+=usr/share/man/en.UTF-8/cat7 OLD_DIRS+=usr/share/man/en.UTF-8/cat8/amd64 OLD_DIRS+=usr/share/man/en.UTF-8/cat8/arm OLD_DIRS+=usr/share/man/en.UTF-8/cat8/i386 OLD_DIRS+=usr/share/man/en.UTF-8/cat8/powerpc OLD_DIRS+=usr/share/man/en.UTF-8/cat8/sparc64 OLD_DIRS+=usr/share/man/en.UTF-8/cat8 OLD_DIRS+=usr/share/man/en.UTF-8/cat9 OLD_DIRS+=usr/share/man/ja/cat1 OLD_DIRS+=usr/share/man/ja/cat2 OLD_DIRS+=usr/share/man/ja/cat3 OLD_DIRS+=usr/share/man/ja/cat4/amd64 OLD_DIRS+=usr/share/man/ja/cat4/arm OLD_DIRS+=usr/share/man/ja/cat4/i386 OLD_DIRS+=usr/share/man/ja/cat4/powerpc OLD_DIRS+=usr/share/man/ja/cat4/sparc64 OLD_DIRS+=usr/share/man/ja/cat4 OLD_DIRS+=usr/share/man/ja/cat5 OLD_DIRS+=usr/share/man/ja/cat6 OLD_DIRS+=usr/share/man/ja/cat7 OLD_DIRS+=usr/share/man/ja/cat8/amd64 OLD_DIRS+=usr/share/man/ja/cat8/arm OLD_DIRS+=usr/share/man/ja/cat8/powerpc OLD_DIRS+=usr/share/man/ja/cat8/sparc64 OLD_DIRS+=usr/share/man/ja/cat8 OLD_DIRS+=usr/share/man/ja/cat9 OLD_DIRS+=usr/share/openssl/man/cat1 OLD_DIRS+=usr/share/openssl/man/cat3 OLD_DIRS+=usr/share/openssl/man/en.ISO8859-1/cat1 OLD_DIRS+=usr/share/openssl/man/en.ISO8859-1/cat3 # 20170830: rename ntb_hw(4) to ntb_hw_intel(4) OLD_FILES+=usr/share/man/man4/ntb_hw.4.gz # 20170802: ksyms(4) ioctl interface was removed OLD_FILES+=usr/include/sys/ksyms.h # 20170729: the iicbus/pcf8563 driver is replaced with iicbus/nxprtc OLD_FILES+=usr/include/dev/iicbus/pcf8563reg.h # 20170727: options FLOWTABLE removed OLD_FILES+=usr/include/net/flowtable.h # 20170722: new clang import which bumps version from 4.0.0 to 5.0.0 OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/esan_interface.h OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/4.0.0/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/4.0.0/include/sanitizer OLD_FILES+=usr/lib/clang/4.0.0/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/4.0.0/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/4.0.0/include/__clang_cuda_complex_builtins.h OLD_FILES+=usr/lib/clang/4.0.0/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/4.0.0/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/4.0.0/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/4.0.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/4.0.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/4.0.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/4.0.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/altivec.h OLD_FILES+=usr/lib/clang/4.0.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/4.0.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/4.0.0/include/armintr.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/cpuid.h OLD_FILES+=usr/lib/clang/4.0.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/htmintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/immintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/4.0.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/4.0.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/module.modulemap OLD_FILES+=usr/lib/clang/4.0.0/include/msa.h OLD_FILES+=usr/lib/clang/4.0.0/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/opencl-c.h OLD_FILES+=usr/lib/clang/4.0.0/include/pkuintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/s390intrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/vadefs.h OLD_FILES+=usr/lib/clang/4.0.0/include/vecintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/xopintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/4.0.0/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/4.0.0/include OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/4.0.0/lib/freebsd OLD_DIRS+=usr/lib/clang/4.0.0/lib OLD_DIRS+=usr/lib/clang/4.0.0 OLD_FILES+=usr/bin/llvm-pdbdump # 20170717: Remove documentation of vaporware OLD_FILES+=usr/share/man/man2/pdwait4.2.gz # 20170610: chown-f_test replaced by chown_test OLD_FILES+=usr/tests/usr.sbin/chown/chown-f_test # 20170609: drop obsolete manpage link (if_rtwn.ko -> rtwn.ko) OLD_FILES+=usr/share/man/man4/if_rtwn.4.gz # 20170531: removal of groff OLD_FILES+=usr/bin/addftinfo OLD_FILES+=usr/bin/afmtodit OLD_FILES+=usr/bin/checknr OLD_FILES+=usr/bin/colcrt OLD_FILES+=usr/bin/eqn OLD_FILES+=usr/bin/grn OLD_FILES+=usr/bin/grodvi OLD_FILES+=usr/bin/groff OLD_FILES+=usr/bin/grog OLD_FILES+=usr/bin/grolbp OLD_FILES+=usr/bin/grolj4 OLD_FILES+=usr/bin/grops OLD_FILES+=usr/bin/grotty OLD_FILES+=usr/bin/hpftodit OLD_FILES+=usr/bin/indxbib OLD_FILES+=usr/bin/lkbib OLD_FILES+=usr/bin/lookbib OLD_FILES+=usr/bin/mmroff OLD_FILES+=usr/bin/neqn OLD_FILES+=usr/bin/nroff OLD_FILES+=usr/bin/pfbtops OLD_FILES+=usr/bin/pic OLD_FILES+=usr/bin/post-grohtml OLD_FILES+=usr/bin/pre-grohtml OLD_FILES+=usr/bin/psroff OLD_FILES+=usr/bin/refer OLD_FILES+=usr/bin/tbl OLD_FILES+=usr/bin/tfmtodit OLD_FILES+=usr/bin/troff OLD_FILES+=usr/bin/vgrind OLD_FILES+=usr/libexec/vfontedpr OLD_FILES+=usr/share/dict/eign OLD_FILES+=usr/share/groff_font/devX100-12/CB OLD_FILES+=usr/share/groff_font/devX100-12/CBI OLD_FILES+=usr/share/groff_font/devX100-12/CI OLD_FILES+=usr/share/groff_font/devX100-12/CR OLD_FILES+=usr/share/groff_font/devX100-12/DESC OLD_FILES+=usr/share/groff_font/devX100-12/HB OLD_FILES+=usr/share/groff_font/devX100-12/HBI OLD_FILES+=usr/share/groff_font/devX100-12/HI OLD_FILES+=usr/share/groff_font/devX100-12/HR OLD_FILES+=usr/share/groff_font/devX100-12/NB OLD_FILES+=usr/share/groff_font/devX100-12/NBI OLD_FILES+=usr/share/groff_font/devX100-12/NI OLD_FILES+=usr/share/groff_font/devX100-12/NR OLD_FILES+=usr/share/groff_font/devX100-12/S OLD_FILES+=usr/share/groff_font/devX100-12/TB OLD_FILES+=usr/share/groff_font/devX100-12/TBI OLD_FILES+=usr/share/groff_font/devX100-12/TI OLD_FILES+=usr/share/groff_font/devX100-12/TR OLD_DIRS+=usr/share/groff_font/devX100-12 OLD_FILES+=usr/share/groff_font/devX100/CB OLD_FILES+=usr/share/groff_font/devX100/CBI OLD_FILES+=usr/share/groff_font/devX100/CI OLD_FILES+=usr/share/groff_font/devX100/CR OLD_FILES+=usr/share/groff_font/devX100/DESC OLD_FILES+=usr/share/groff_font/devX100/HB OLD_FILES+=usr/share/groff_font/devX100/HBI OLD_FILES+=usr/share/groff_font/devX100/HI OLD_FILES+=usr/share/groff_font/devX100/HR OLD_FILES+=usr/share/groff_font/devX100/NB OLD_FILES+=usr/share/groff_font/devX100/NBI OLD_FILES+=usr/share/groff_font/devX100/NI OLD_FILES+=usr/share/groff_font/devX100/NR OLD_FILES+=usr/share/groff_font/devX100/S OLD_FILES+=usr/share/groff_font/devX100/TB OLD_FILES+=usr/share/groff_font/devX100/TBI OLD_FILES+=usr/share/groff_font/devX100/TI OLD_FILES+=usr/share/groff_font/devX100/TR OLD_DIRS+=usr/share/groff_font/devX100 OLD_FILES+=usr/share/groff_font/devX75-12/CB OLD_FILES+=usr/share/groff_font/devX75-12/CBI OLD_FILES+=usr/share/groff_font/devX75-12/CI OLD_FILES+=usr/share/groff_font/devX75-12/CR OLD_FILES+=usr/share/groff_font/devX75-12/DESC OLD_FILES+=usr/share/groff_font/devX75-12/HB OLD_FILES+=usr/share/groff_font/devX75-12/HBI OLD_FILES+=usr/share/groff_font/devX75-12/HI OLD_FILES+=usr/share/groff_font/devX75-12/HR OLD_FILES+=usr/share/groff_font/devX75-12/NB OLD_FILES+=usr/share/groff_font/devX75-12/NBI OLD_FILES+=usr/share/groff_font/devX75-12/NI OLD_FILES+=usr/share/groff_font/devX75-12/NR OLD_FILES+=usr/share/groff_font/devX75-12/S OLD_FILES+=usr/share/groff_font/devX75-12/TB OLD_FILES+=usr/share/groff_font/devX75-12/TBI OLD_FILES+=usr/share/groff_font/devX75-12/TI OLD_FILES+=usr/share/groff_font/devX75-12/TR OLD_DIRS+=usr/share/groff_font/devX75-12 OLD_FILES+=usr/share/groff_font/devX75/CB OLD_FILES+=usr/share/groff_font/devX75/CBI OLD_FILES+=usr/share/groff_font/devX75/CI OLD_FILES+=usr/share/groff_font/devX75/CR OLD_FILES+=usr/share/groff_font/devX75/DESC OLD_FILES+=usr/share/groff_font/devX75/HB OLD_FILES+=usr/share/groff_font/devX75/HBI OLD_FILES+=usr/share/groff_font/devX75/HI OLD_FILES+=usr/share/groff_font/devX75/HR OLD_FILES+=usr/share/groff_font/devX75/NB OLD_FILES+=usr/share/groff_font/devX75/NBI OLD_FILES+=usr/share/groff_font/devX75/NI OLD_FILES+=usr/share/groff_font/devX75/NR OLD_FILES+=usr/share/groff_font/devX75/S OLD_FILES+=usr/share/groff_font/devX75/TB OLD_FILES+=usr/share/groff_font/devX75/TBI OLD_FILES+=usr/share/groff_font/devX75/TI OLD_FILES+=usr/share/groff_font/devX75/TR OLD_DIRS+=usr/share/groff_font/devX75 OLD_FILES+=usr/share/groff_font/devascii/B OLD_FILES+=usr/share/groff_font/devascii/BI OLD_FILES+=usr/share/groff_font/devascii/CW OLD_FILES+=usr/share/groff_font/devascii/DESC OLD_FILES+=usr/share/groff_font/devascii/I OLD_FILES+=usr/share/groff_font/devascii/L OLD_FILES+=usr/share/groff_font/devascii/R OLD_FILES+=usr/share/groff_font/devascii/S OLD_DIRS+=usr/share/groff_font/devascii OLD_FILES+=usr/share/groff_font/devcp1047/B OLD_FILES+=usr/share/groff_font/devcp1047/BI OLD_FILES+=usr/share/groff_font/devcp1047/CW OLD_FILES+=usr/share/groff_font/devcp1047/DESC OLD_FILES+=usr/share/groff_font/devcp1047/I OLD_FILES+=usr/share/groff_font/devcp1047/L OLD_FILES+=usr/share/groff_font/devcp1047/R OLD_FILES+=usr/share/groff_font/devcp1047/S OLD_DIRS+=usr/share/groff_font/devcp1047 OLD_FILES+=usr/share/groff_font/devdvi/CW OLD_FILES+=usr/share/groff_font/devdvi/CWEC OLD_FILES+=usr/share/groff_font/devdvi/CWI OLD_FILES+=usr/share/groff_font/devdvi/CWIEC OLD_FILES+=usr/share/groff_font/devdvi/CWITC OLD_FILES+=usr/share/groff_font/devdvi/CWTC OLD_FILES+=usr/share/groff_font/devdvi/CompileFonts OLD_FILES+=usr/share/groff_font/devdvi/DESC OLD_FILES+=usr/share/groff_font/devdvi/EX OLD_FILES+=usr/share/groff_font/devdvi/HB OLD_FILES+=usr/share/groff_font/devdvi/HBEC OLD_FILES+=usr/share/groff_font/devdvi/HBI OLD_FILES+=usr/share/groff_font/devdvi/HBIEC OLD_FILES+=usr/share/groff_font/devdvi/HBITC OLD_FILES+=usr/share/groff_font/devdvi/HBTC OLD_FILES+=usr/share/groff_font/devdvi/HI OLD_FILES+=usr/share/groff_font/devdvi/HIEC OLD_FILES+=usr/share/groff_font/devdvi/HITC OLD_FILES+=usr/share/groff_font/devdvi/HR OLD_FILES+=usr/share/groff_font/devdvi/HREC OLD_FILES+=usr/share/groff_font/devdvi/HRTC OLD_FILES+=usr/share/groff_font/devdvi/MI OLD_FILES+=usr/share/groff_font/devdvi/Makefile OLD_FILES+=usr/share/groff_font/devdvi/S OLD_FILES+=usr/share/groff_font/devdvi/SA OLD_FILES+=usr/share/groff_font/devdvi/SB OLD_FILES+=usr/share/groff_font/devdvi/SC OLD_FILES+=usr/share/groff_font/devdvi/TB OLD_FILES+=usr/share/groff_font/devdvi/TBEC OLD_FILES+=usr/share/groff_font/devdvi/TBI OLD_FILES+=usr/share/groff_font/devdvi/TBIEC OLD_FILES+=usr/share/groff_font/devdvi/TBITC OLD_FILES+=usr/share/groff_font/devdvi/TBTC OLD_FILES+=usr/share/groff_font/devdvi/TI OLD_FILES+=usr/share/groff_font/devdvi/TIEC OLD_FILES+=usr/share/groff_font/devdvi/TITC OLD_FILES+=usr/share/groff_font/devdvi/TR OLD_FILES+=usr/share/groff_font/devdvi/TREC OLD_FILES+=usr/share/groff_font/devdvi/TRTC OLD_FILES+=usr/share/groff_font/devdvi/ec.map OLD_FILES+=usr/share/groff_font/devdvi/msam.map OLD_FILES+=usr/share/groff_font/devdvi/msbm.map OLD_FILES+=usr/share/groff_font/devdvi/tc.map OLD_FILES+=usr/share/groff_font/devdvi/texb.map OLD_FILES+=usr/share/groff_font/devdvi/texex.map OLD_FILES+=usr/share/groff_font/devdvi/texi.map OLD_FILES+=usr/share/groff_font/devdvi/texmi.map OLD_FILES+=usr/share/groff_font/devdvi/texr.map OLD_FILES+=usr/share/groff_font/devdvi/texsy.map OLD_FILES+=usr/share/groff_font/devdvi/textex.map OLD_FILES+=usr/share/groff_font/devdvi/textt.map OLD_DIRS+=usr/share/groff_font/devdvi OLD_FILES+=usr/share/groff_font/devhtml/B OLD_FILES+=usr/share/groff_font/devhtml/BI OLD_FILES+=usr/share/groff_font/devhtml/CB OLD_FILES+=usr/share/groff_font/devhtml/CBI OLD_FILES+=usr/share/groff_font/devhtml/CI OLD_FILES+=usr/share/groff_font/devhtml/CR OLD_FILES+=usr/share/groff_font/devhtml/DESC OLD_FILES+=usr/share/groff_font/devhtml/I OLD_FILES+=usr/share/groff_font/devhtml/R OLD_FILES+=usr/share/groff_font/devhtml/S OLD_DIRS+=usr/share/groff_font/devhtml OLD_FILES+=usr/share/groff_font/devkoi8-r/B OLD_FILES+=usr/share/groff_font/devkoi8-r/BI OLD_FILES+=usr/share/groff_font/devkoi8-r/CW OLD_FILES+=usr/share/groff_font/devkoi8-r/DESC OLD_FILES+=usr/share/groff_font/devkoi8-r/I OLD_FILES+=usr/share/groff_font/devkoi8-r/L OLD_FILES+=usr/share/groff_font/devkoi8-r/R OLD_FILES+=usr/share/groff_font/devkoi8-r/S OLD_DIRS+=usr/share/groff_font/devkoi8-r OLD_FILES+=usr/share/groff_font/devlatin1/B OLD_FILES+=usr/share/groff_font/devlatin1/BI OLD_FILES+=usr/share/groff_font/devlatin1/CW OLD_FILES+=usr/share/groff_font/devlatin1/DESC OLD_FILES+=usr/share/groff_font/devlatin1/I OLD_FILES+=usr/share/groff_font/devlatin1/L OLD_FILES+=usr/share/groff_font/devlatin1/R OLD_FILES+=usr/share/groff_font/devlatin1/S OLD_DIRS+=usr/share/groff_font/devlatin1 OLD_FILES+=usr/share/groff_font/devlbp/CB OLD_FILES+=usr/share/groff_font/devlbp/CI OLD_FILES+=usr/share/groff_font/devlbp/CR OLD_FILES+=usr/share/groff_font/devlbp/DESC OLD_FILES+=usr/share/groff_font/devlbp/EB OLD_FILES+=usr/share/groff_font/devlbp/EI OLD_FILES+=usr/share/groff_font/devlbp/ER OLD_FILES+=usr/share/groff_font/devlbp/HB OLD_FILES+=usr/share/groff_font/devlbp/HBI OLD_FILES+=usr/share/groff_font/devlbp/HI OLD_FILES+=usr/share/groff_font/devlbp/HNB OLD_FILES+=usr/share/groff_font/devlbp/HNBI OLD_FILES+=usr/share/groff_font/devlbp/HNI OLD_FILES+=usr/share/groff_font/devlbp/HNR OLD_FILES+=usr/share/groff_font/devlbp/HR OLD_FILES+=usr/share/groff_font/devlbp/TB OLD_FILES+=usr/share/groff_font/devlbp/TBI OLD_FILES+=usr/share/groff_font/devlbp/TI OLD_FILES+=usr/share/groff_font/devlbp/TR OLD_DIRS+=usr/share/groff_font/devlbp OLD_FILES+=usr/share/groff_font/devlj4/AB OLD_FILES+=usr/share/groff_font/devlj4/ABI OLD_FILES+=usr/share/groff_font/devlj4/AI OLD_FILES+=usr/share/groff_font/devlj4/ALBB OLD_FILES+=usr/share/groff_font/devlj4/ALBR OLD_FILES+=usr/share/groff_font/devlj4/AOB OLD_FILES+=usr/share/groff_font/devlj4/AOI OLD_FILES+=usr/share/groff_font/devlj4/AOR OLD_FILES+=usr/share/groff_font/devlj4/AR OLD_FILES+=usr/share/groff_font/devlj4/CB OLD_FILES+=usr/share/groff_font/devlj4/CBI OLD_FILES+=usr/share/groff_font/devlj4/CI OLD_FILES+=usr/share/groff_font/devlj4/CLARENDON OLD_FILES+=usr/share/groff_font/devlj4/CORONET OLD_FILES+=usr/share/groff_font/devlj4/CR OLD_FILES+=usr/share/groff_font/devlj4/DESC OLD_FILES+=usr/share/groff_font/devlj4/GB OLD_FILES+=usr/share/groff_font/devlj4/GBI OLD_FILES+=usr/share/groff_font/devlj4/GI OLD_FILES+=usr/share/groff_font/devlj4/GR OLD_FILES+=usr/share/groff_font/devlj4/LGB OLD_FILES+=usr/share/groff_font/devlj4/LGI OLD_FILES+=usr/share/groff_font/devlj4/LGR OLD_FILES+=usr/share/groff_font/devlj4/MARIGOLD OLD_FILES+=usr/share/groff_font/devlj4/OB OLD_FILES+=usr/share/groff_font/devlj4/OBI OLD_FILES+=usr/share/groff_font/devlj4/OI OLD_FILES+=usr/share/groff_font/devlj4/OR OLD_FILES+=usr/share/groff_font/devlj4/S OLD_FILES+=usr/share/groff_font/devlj4/SYMBOL OLD_FILES+=usr/share/groff_font/devlj4/TB OLD_FILES+=usr/share/groff_font/devlj4/TBI OLD_FILES+=usr/share/groff_font/devlj4/TI OLD_FILES+=usr/share/groff_font/devlj4/TNRB OLD_FILES+=usr/share/groff_font/devlj4/TNRBI OLD_FILES+=usr/share/groff_font/devlj4/TNRI OLD_FILES+=usr/share/groff_font/devlj4/TNRR OLD_FILES+=usr/share/groff_font/devlj4/TR OLD_FILES+=usr/share/groff_font/devlj4/UB OLD_FILES+=usr/share/groff_font/devlj4/UBI OLD_FILES+=usr/share/groff_font/devlj4/UCB OLD_FILES+=usr/share/groff_font/devlj4/UCBI OLD_FILES+=usr/share/groff_font/devlj4/UCI OLD_FILES+=usr/share/groff_font/devlj4/UCR OLD_FILES+=usr/share/groff_font/devlj4/UI OLD_FILES+=usr/share/groff_font/devlj4/UR OLD_FILES+=usr/share/groff_font/devlj4/WINGDINGS OLD_DIRS+=usr/share/groff_font/devlj4 OLD_FILES+=usr/share/groff_font/devps/AB OLD_FILES+=usr/share/groff_font/devps/ABI OLD_FILES+=usr/share/groff_font/devps/AI OLD_FILES+=usr/share/groff_font/devps/AR OLD_FILES+=usr/share/groff_font/devps/BMB OLD_FILES+=usr/share/groff_font/devps/BMBI OLD_FILES+=usr/share/groff_font/devps/BMI OLD_FILES+=usr/share/groff_font/devps/BMR OLD_FILES+=usr/share/groff_font/devps/CB OLD_FILES+=usr/share/groff_font/devps/CBI OLD_FILES+=usr/share/groff_font/devps/CI OLD_FILES+=usr/share/groff_font/devps/CR OLD_FILES+=usr/share/groff_font/devps/DESC OLD_FILES+=usr/share/groff_font/devps/EURO OLD_FILES+=usr/share/groff_font/devps/HB OLD_FILES+=usr/share/groff_font/devps/HBI OLD_FILES+=usr/share/groff_font/devps/HI OLD_FILES+=usr/share/groff_font/devps/HNB OLD_FILES+=usr/share/groff_font/devps/HNBI OLD_FILES+=usr/share/groff_font/devps/HNI OLD_FILES+=usr/share/groff_font/devps/HNR OLD_FILES+=usr/share/groff_font/devps/HR OLD_FILES+=usr/share/groff_font/devps/Makefile OLD_FILES+=usr/share/groff_font/devps/NB OLD_FILES+=usr/share/groff_font/devps/NBI OLD_FILES+=usr/share/groff_font/devps/NI OLD_FILES+=usr/share/groff_font/devps/NR OLD_FILES+=usr/share/groff_font/devps/PB OLD_FILES+=usr/share/groff_font/devps/PBI OLD_FILES+=usr/share/groff_font/devps/PI OLD_FILES+=usr/share/groff_font/devps/PR OLD_FILES+=usr/share/groff_font/devps/S OLD_FILES+=usr/share/groff_font/devps/SS OLD_FILES+=usr/share/groff_font/devps/TB OLD_FILES+=usr/share/groff_font/devps/TBI OLD_FILES+=usr/share/groff_font/devps/TI OLD_FILES+=usr/share/groff_font/devps/TR OLD_FILES+=usr/share/groff_font/devps/ZCMI OLD_FILES+=usr/share/groff_font/devps/ZD OLD_FILES+=usr/share/groff_font/devps/ZDR OLD_FILES+=usr/share/groff_font/devps/afmname OLD_FILES+=usr/share/groff_font/devps/dingbats.map OLD_FILES+=usr/share/groff_font/devps/dingbats.rmap OLD_FILES+=usr/share/groff_font/devps/download OLD_FILES+=usr/share/groff_font/devps/freeeuro.pfa OLD_FILES+=usr/share/groff_font/devps/lgreekmap OLD_FILES+=usr/share/groff_font/devps/prologue OLD_FILES+=usr/share/groff_font/devps/symbol.sed OLD_FILES+=usr/share/groff_font/devps/symbolchars OLD_FILES+=usr/share/groff_font/devps/symbolsl.afm OLD_FILES+=usr/share/groff_font/devps/symbolsl.pfa OLD_FILES+=usr/share/groff_font/devps/text.enc OLD_FILES+=usr/share/groff_font/devps/textmap OLD_FILES+=usr/share/groff_font/devps/zapfdr.pfa OLD_DIRS+=usr/share/groff_font/devps OLD_FILES+=usr/share/groff_font/devutf8/B OLD_FILES+=usr/share/groff_font/devutf8/BI OLD_FILES+=usr/share/groff_font/devutf8/CW OLD_FILES+=usr/share/groff_font/devutf8/DESC OLD_FILES+=usr/share/groff_font/devutf8/I OLD_FILES+=usr/share/groff_font/devutf8/L OLD_FILES+=usr/share/groff_font/devutf8/R OLD_FILES+=usr/share/groff_font/devutf8/S OLD_DIRS+=usr/share/groff_font/devutf8 OLD_DIRS+=usr/share/groff_font OLD_FILES+=usr/share/man/man1/addftinfo.1.gz OLD_FILES+=usr/share/man/man1/afmtodit.1.gz OLD_FILES+=usr/share/man/man1/checknr.1.gz OLD_FILES+=usr/share/man/man1/colcrt.1.gz OLD_FILES+=usr/share/man/man1/eqn.1.gz OLD_FILES+=usr/share/man/man1/grn.1.gz OLD_FILES+=usr/share/man/man1/grodvi.1.gz OLD_FILES+=usr/share/man/man1/groff.1.gz OLD_FILES+=usr/share/man/man1/grog.1.gz OLD_FILES+=usr/share/man/man1/grolbp.1.gz OLD_FILES+=usr/share/man/man1/grolj4.1.gz OLD_FILES+=usr/share/man/man1/grops.1.gz OLD_FILES+=usr/share/man/man1/grotty.1.gz OLD_FILES+=usr/share/man/man1/hpftodit.1.gz OLD_FILES+=usr/share/man/man1/indxbib.1.gz OLD_FILES+=usr/share/man/man1/lkbib.1.gz OLD_FILES+=usr/share/man/man1/lookbib.1.gz OLD_FILES+=usr/share/man/man1/mmroff.1.gz OLD_FILES+=usr/share/man/man1/neqn.1.gz OLD_FILES+=usr/share/man/man1/nroff.1.gz OLD_FILES+=usr/share/man/man1/pfbtops.1.gz OLD_FILES+=usr/share/man/man1/pic.1.gz OLD_FILES+=usr/share/man/man1/psroff.1.gz OLD_FILES+=usr/share/man/man1/refer.1.gz OLD_FILES+=usr/share/man/man1/tbl.1.gz OLD_FILES+=usr/share/man/man1/tfmtodit.1.gz OLD_FILES+=usr/share/man/man1/troff.1.gz OLD_FILES+=usr/share/man/man1/vgrind.1.gz OLD_FILES+=usr/share/man/man5/groff_font.5.gz OLD_FILES+=usr/share/man/man5/groff_out.5.gz OLD_FILES+=usr/share/man/man5/groff_tmac.5.gz OLD_FILES+=usr/share/man/man5/lj4_font.5.gz OLD_FILES+=usr/share/man/man5/tmac.5.gz OLD_FILES+=usr/share/man/man5/vgrindefs.5.gz OLD_FILES+=usr/share/man/man7/ditroff.7.gz OLD_FILES+=usr/share/man/man7/groff.7.gz OLD_FILES+=usr/share/man/man7/groff_char.7.gz OLD_FILES+=usr/share/man/man7/groff_diff.7.gz OLD_FILES+=usr/share/man/man7/groff_man.7.gz OLD_FILES+=usr/share/man/man7/groff_mdoc.7.gz OLD_FILES+=usr/share/man/man7/groff_me.7.gz OLD_FILES+=usr/share/man/man7/groff_mm.7.gz OLD_FILES+=usr/share/man/man7/groff_mmse.7.gz OLD_FILES+=usr/share/man/man7/groff_ms.7.gz OLD_FILES+=usr/share/man/man7/groff_trace.7.gz OLD_FILES+=usr/share/man/man7/groff_www.7.gz OLD_FILES+=usr/share/man/man7/mdoc.samples.7.gz OLD_FILES+=usr/share/man/man7/me.7.gz OLD_FILES+=usr/share/man/man7/mm.7.gz OLD_FILES+=usr/share/man/man7/mmse.7.gz OLD_FILES+=usr/share/man/man7/ms.7.gz OLD_FILES+=usr/share/man/man7/orig_me.7.gz OLD_FILES+=usr/share/me/acm.me OLD_FILES+=usr/share/me/chars.me OLD_FILES+=usr/share/me/deltext.me OLD_FILES+=usr/share/me/eqn.me OLD_FILES+=usr/share/me/float.me OLD_FILES+=usr/share/me/footnote.me OLD_FILES+=usr/share/me/index.me OLD_FILES+=usr/share/me/letterhead.me OLD_FILES+=usr/share/me/local.me OLD_FILES+=usr/share/me/null.me OLD_FILES+=usr/share/me/refer.me OLD_FILES+=usr/share/me/revisions OLD_FILES+=usr/share/me/sh.me OLD_FILES+=usr/share/me/tbl.me OLD_FILES+=usr/share/me/thesis.me OLD_DIRS+=usr/share/me OLD_FILES+=usr/share/misc/vgrindefs OLD_FILES+=usr/share/misc/vgrindefs.db OLD_FILES+=usr/share/tmac/X.tmac OLD_FILES+=usr/share/tmac/Xps.tmac OLD_FILES+=usr/share/tmac/a4.tmac OLD_FILES+=usr/share/tmac/an-old.tmac OLD_FILES+=usr/share/tmac/an.tmac OLD_FILES+=usr/share/tmac/andoc.tmac OLD_FILES+=usr/share/tmac/composite.tmac OLD_FILES+=usr/share/tmac/cp1047.tmac OLD_FILES+=usr/share/tmac/devtag.tmac OLD_FILES+=usr/share/tmac/doc.tmac OLD_FILES+=usr/share/tmac/dvi.tmac OLD_FILES+=usr/share/tmac/e.tmac OLD_FILES+=usr/share/tmac/ec.tmac OLD_FILES+=usr/share/tmac/eqnrc OLD_FILES+=usr/share/tmac/europs.tmac OLD_FILES+=usr/share/tmac/html-end.tmac OLD_FILES+=usr/share/tmac/html.tmac OLD_FILES+=usr/share/tmac/hyphen.ru OLD_FILES+=usr/share/tmac/hyphen.us OLD_FILES+=usr/share/tmac/hyphenex.us OLD_FILES+=usr/share/tmac/koi8-r.tmac OLD_FILES+=usr/share/tmac/latin1.tmac OLD_FILES+=usr/share/tmac/latin2.tmac OLD_FILES+=usr/share/tmac/latin9.tmac OLD_FILES+=usr/share/tmac/lbp.tmac OLD_FILES+=usr/share/tmac/lj4.tmac OLD_FILES+=usr/share/tmac/m.tmac OLD_FILES+=usr/share/tmac/man.local OLD_FILES+=usr/share/tmac/man.tmac OLD_FILES+=usr/share/tmac/mandoc.tmac OLD_FILES+=usr/share/tmac/mdoc.local OLD_FILES+=usr/share/tmac/mdoc.tmac OLD_FILES+=usr/share/tmac/mdoc/doc-common OLD_FILES+=usr/share/tmac/mdoc/doc-ditroff OLD_FILES+=usr/share/tmac/mdoc/doc-nroff OLD_FILES+=usr/share/tmac/mdoc/doc-syms OLD_FILES+=usr/share/tmac/mdoc/fr.ISO8859-1 OLD_FILES+=usr/share/tmac/mdoc/ru.KOI8-R OLD_DIRS+=usr/share/tmac/mdoc OLD_FILES+=usr/share/tmac/me.tmac OLD_FILES+=usr/share/tmac/mm/0.MT OLD_FILES+=usr/share/tmac/mm/4.MT OLD_FILES+=usr/share/tmac/mm/5.MT OLD_FILES+=usr/share/tmac/mm/locale OLD_FILES+=usr/share/tmac/mm/mm.tmac OLD_FILES+=usr/share/tmac/mm/mmse.tmac OLD_FILES+=usr/share/tmac/mm/ms.cov OLD_FILES+=usr/share/tmac/mm/se_locale OLD_FILES+=usr/share/tmac/mm/se_ms.cov OLD_DIRS+=usr/share/tmac/mm OLD_FILES+=usr/share/tmac/ms.tmac OLD_FILES+=usr/share/tmac/mse.tmac OLD_FILES+=usr/share/tmac/papersize.tmac OLD_FILES+=usr/share/tmac/pic.tmac OLD_FILES+=usr/share/tmac/ps.tmac OLD_FILES+=usr/share/tmac/psatk.tmac OLD_FILES+=usr/share/tmac/psold.tmac OLD_FILES+=usr/share/tmac/pspic.tmac OLD_FILES+=usr/share/tmac/s.tmac OLD_FILES+=usr/share/tmac/safer.tmac OLD_FILES+=usr/share/tmac/tmac.orig_me OLD_FILES+=usr/share/tmac/tmac.vgrind OLD_FILES+=usr/share/tmac/trace.tmac OLD_FILES+=usr/share/tmac/troffrc OLD_FILES+=usr/share/tmac/troffrc-end OLD_FILES+=usr/share/tmac/tty-char.tmac OLD_FILES+=usr/share/tmac/tty.tmac OLD_FILES+=usr/share/tmac/unicode.tmac OLD_FILES+=usr/share/tmac/www.tmac OLD_DIRS+=usr/share/tmac # 20170607: remove incorrect atf_check(1) manpage link OLD_FILES+=usr/share/man/man1/atf_check.1.gz # 20170601: remove stale manpage OLD_FILES+=usr/share/man/man2/cap_rights_get.2.gz # 20170601: old libifconfig and libifc OLD_FILES+=usr/lib/libifc.a OLD_FILES+=usr/lib/libifc_p.a OLD_FILES+=usr/lib/libifconfig.a OLD_FILES+=usr/lib/libifconfig_p.a # 20170529: mount.conf(8) -> mount.conf(5) OLD_FILES+=usr/share/man/man8/mount.conf.8.gz # 20170525: remove misleading template OLD_FILES+=usr/share/misc/man.template # 20170525: disconnect the roff docs from the build OLD_FILES+=usr/share/doc/papers/beyond43.ascii.gz OLD_FILES+=usr/share/doc/papers/bio.ascii.gz OLD_FILES+=usr/share/doc/papers/contents.ascii.gz OLD_FILES+=usr/share/doc/papers/devfs.ascii.gz OLD_FILES+=usr/share/doc/papers/diskperf.ascii.gz OLD_FILES+=usr/share/doc/papers/fsinterface.ascii.gz OLD_FILES+=usr/share/doc/papers/hwpmc.ascii.gz OLD_FILES+=usr/share/doc/papers/jail.ascii.gz OLD_FILES+=usr/share/doc/papers/kernmalloc.ascii.gz OLD_FILES+=usr/share/doc/papers/kerntune.ascii.gz OLD_FILES+=usr/share/doc/papers/malloc.ascii.gz OLD_FILES+=usr/share/doc/papers/newvm.ascii.gz OLD_FILES+=usr/share/doc/papers/releng.ascii.gz OLD_FILES+=usr/share/doc/papers/sysperf.ascii.gz OLD_FILES+=usr/share/doc/papers/timecounter.ascii.gz OLD_DIRS+=usr/share/doc/papers OLD_FILES+=usr/share/doc/psd/01.cacm/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/01.cacm OLD_FILES+=usr/share/doc/psd/02.implement/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/02.implement OLD_FILES+=usr/share/doc/psd/03.iosys/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/03.iosys OLD_FILES+=usr/share/doc/psd/04.uprog/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/04.uprog OLD_FILES+=usr/share/doc/psd/05.sysman/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/05.sysman OLD_FILES+=usr/share/doc/psd/06.Clang/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/06.Clang OLD_FILES+=usr/share/doc/psd/12.make/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/12.make OLD_FILES+=usr/share/doc/psd/13.rcs/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/13.rcs OLD_FILES+=usr/share/doc/psd/13.rcs/rcs_func.ascii.gz OLD_DIRS+=usr/share/doc/psd/13.rcs OLD_FILES+=usr/share/doc/psd/15.yacc/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/15.yacc OLD_FILES+=usr/share/doc/psd/16.lex/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/16.lex OLD_FILES+=usr/share/doc/psd/17.m4/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/17.m4 OLD_FILES+=usr/share/doc/psd/18.gprof/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/18.gprof OLD_FILES+=usr/share/doc/psd/20.ipctut/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/20.ipctut OLD_FILES+=usr/share/doc/psd/21.ipc/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/21.ipc OLD_FILES+=usr/share/doc/psd/22.rpcgen/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/22.rpcgen OLD_FILES+=usr/share/doc/psd/23.rpc/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/23.rpc OLD_FILES+=usr/share/doc/psd/24.xdr/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/24.xdr OLD_FILES+=usr/share/doc/psd/25.xdrrfc/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/25.xdrrfc OLD_FILES+=usr/share/doc/psd/26.rpcrfc/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/26.rpcrfc OLD_FILES+=usr/share/doc/psd/27.nfsrfc/paper.ascii.gz OLD_DIRS+=usr/share/doc/psd/27.nfsrfc OLD_FILES+=usr/share/doc/psd/Title.ascii.gz OLD_FILES+=usr/share/doc/psd/contents.ascii.gz OLD_DIRS+=usr/share/doc/psd/ OLD_FILES+=usr/share/doc/smm/01.setup/paper.ascii.gz OLD_DIRS+=usr/share/doc/smm/01.setup OLD_FILES+=usr/share/doc/smm/02.config/paper.ascii.gz OLD_DIRS+=usr/share/doc/smm/02.config OLD_FILES+=usr/share/doc/smm/03.fsck/paper.ascii.gz OLD_DIRS+=usr/share/doc/smm/03.fsck OLD_FILES+=usr/share/doc/smm/04.quotas/paper.ascii.gz OLD_DIRS+=usr/share/doc/smm/04.quotas OLD_FILES+=usr/share/doc/smm/05.fastfs/paper.ascii.gz OLD_DIRS+=usr/share/doc/smm/05.fastfs OLD_FILES+=usr/share/doc/smm/06.nfs/paper.ascii.gz OLD_DIRS+=usr/share/doc/smm/06.nfs OLD_FILES+=usr/share/doc/smm/07.lpd/paper.ascii.gz OLD_DIRS+=usr/share/doc/smm/07.lpd OLD_FILES+=usr/share/doc/smm/08.sendmailop/paper.ascii.gz OLD_DIRS+=usr/share/doc/smm/08.sendmailop OLD_FILES+=usr/share/doc/smm/11.timedop/paper.ascii.gz OLD_DIRS+=usr/share/doc/smm/11.timedop OLD_FILES+=usr/share/doc/smm/12.timed/paper.ascii.gz OLD_DIRS+=usr/share/doc/smm/12.timed OLD_FILES+=usr/share/doc/smm/18.net/paper.ascii.gz OLD_DIRS+=usr/share/doc/smm/18.net OLD_FILES+=usr/share/doc/smm/Title.ascii.gz OLD_FILES+=usr/share/doc/smm/contents.ascii.gz OLD_DIRS+=usr/share/doc/smm OLD_FILES+=usr/share/doc/usd/04.csh/paper.ascii.gz OLD_DIRS+=usr/share/doc/usd/04.csh OLD_FILES+=usr/share/doc/usd/05.dc/paper.ascii.gz OLD_DIRS+=usr/share/doc/usd/05.dc OLD_FILES+=usr/share/doc/usd/06.bc/paper.ascii.gz OLD_DIRS+=usr/share/doc/usd/06.bc OLD_FILES+=usr/share/doc/usd/07.mail/paper.ascii.gz OLD_DIRS+=usr/share/doc/usd/07.mail OLD_FILES+=usr/share/doc/usd/10.exref/paper.ascii.gz OLD_FILES+=usr/share/doc/usd/10.exref/summary.ascii.gz OLD_DIRS+=usr/share/doc/usd/10.exref OLD_FILES+=usr/share/doc/usd/11.edit/paper.ascii.gz OLD_DIRS+=usr/share/doc/usd/11.edit OLD_FILES+=usr/share/doc/usd/12.vi/paper.ascii.gz OLD_FILES+=usr/share/doc/usd/12.vi/summary.ascii.gz OLD_FILES+=usr/share/doc/usd/12.vi/viapwh.ascii.gz OLD_DIRS+=usr/share/doc/usd/12.vi OLD_FILES+=usr/share/doc/usd/13.viref/paper.ascii.gz OLD_DIRS+=usr/share/doc/usd/13.viref OLD_FILES+=usr/share/doc/usd/18.msdiffs/paper.ascii.gz OLD_DIRS+=usr/share/doc/usd/18.msdiffs OLD_FILES+=usr/share/doc/usd/19.memacros/paper.ascii.gz OLD_DIRS+=usr/share/doc/usd/19.memacros OLD_FILES+=usr/share/doc/usd/20.meref/paper.ascii.gz OLD_DIRS+=usr/share/doc/usd/20.meref OLD_FILES+=usr/share/doc/usd/21.troff/paper.ascii.gz OLD_DIRS+=usr/share/doc/usd/21.troff OLD_FILES+=usr/share/doc/usd/22.trofftut/paper.ascii.gz OLD_DIRS+=usr/share/doc/usd/22.trofftut OLD_FILES+=usr/share/doc/usd/Title.ascii.gz OLD_FILES+=usr/share/doc/usd/contents.ascii.gz OLD_DIRS+=usr/share/doc/usd # 20170523: 64-bit inode support, library version bumps OLD_LIBS+=lib/libzfs.so.2 OLD_LIBS+=usr/lib/libarchive.so.6 OLD_LIBS+=usr/lib/libmilter.so.5 # 20170427: NATM configuration support removed OLD_FILES+=etc/rc.d/atm1 OLD_FILES+=etc/rc.d/atm2 OLD_FILES+=etc/rc.d/atm3 OLD_FILES+=usr/share/man/man8/rc.atm.8.gz # 20170426: UMA_ZONE_REFCNT removed OLD_FILES+=usr/share/man/man9/uma_find_refcnt.9.gz # 20170424: NATM support removed OLD_FILES+=rescue/atmconfig OLD_FILES+=sbin/atmconfig OLD_FILES+=usr/include/bsnmp/snmp_atm.h OLD_FILES+=usr/include/dev/utopia/idtphy.h OLD_FILES+=usr/include/dev/utopia/suni.h OLD_FILES+=usr/include/dev/utopia/utopia.h OLD_FILES+=usr/include/dev/utopia/utopia_priv.h OLD_DIRS+=usr/include/dev/utopia OLD_FILES+=usr/include/net/if_atm.h OLD_FILES+=usr/include/netgraph/atm/ng_atm.h OLD_FILES+=usr/include/netinet/if_atm.h OLD_FILES+=usr/include/netnatm/natm.h OLD_FILES+=usr/lib/snmp_atm.so OLD_LIBS+=usr/lib/snmp_atm.so.6 OLD_FILES+=usr/share/doc/atm/atmconfig.help OLD_FILES+=usr/share/doc/atm/atmconfig_device.help OLD_DIRS+=usr/share/doc/atm OLD_FILES+=usr/share/man/man3/snmp_atm.3.gz OLD_FILES+=usr/share/man/man4/en.4.gz OLD_FILES+=usr/share/man/man4/fatm.4.gz OLD_FILES+=usr/share/man/man4/hatm.4.gz OLD_FILES+=usr/share/man/man4/if_en.4.gz OLD_FILES+=usr/share/man/man4/if_fatm.4.gz OLD_FILES+=usr/share/man/man4/if_hatm.4.gz OLD_FILES+=usr/share/man/man4/if_patm.4.gz OLD_FILES+=usr/share/man/man4/natm.4.gz OLD_FILES+=usr/share/man/man4/natmip.4.gz OLD_FILES+=usr/share/man/man4/ng_atm.4.gz OLD_FILES+=usr/share/man/man4/patm.4.gz OLD_FILES+=usr/share/man/man4/utopia.4.gz OLD_FILES+=usr/share/man/man8/atmconfig.8.gz OLD_FILES+=usr/share/man/man9/utopia.9.gz OLD_FILES+=usr/share/snmp/defs/atm_freebsd.def OLD_FILES+=usr/share/snmp/defs/atm_tree.def OLD_FILES+=usr/share/snmp/mibs/BEGEMOT-ATM-FREEBSD-MIB.txt OLD_FILES+=usr/share/snmp/mibs/BEGEMOT-ATM.txt # 20170420: remove GNU diff OLD_FILES+=usr/share/man/man7/diff.7.gz # 20170322: rename to _test to match the FreeBSD test suite name scheme OLD_FILES+=usr/tests/usr.bin/col/col OLD_FILES+=usr/tests/usr.bin/diff/diff OLD_FILES+=usr/tests/usr.bin/ident/ident OLD_FILES+=usr/tests/usr.bin/mkimg/mkimg OLD_FILES+=usr/tests/usr.bin/sdiff/sdiff OLD_FILES+=usr/tests/usr.bin/soelim/soelim OLD_FILES+=usr/tests/usr.sbin/pw/pw_config OLD_FILES+=usr/tests/usr.sbin/pw/pw_etcdir OLD_FILES+=usr/tests/usr.sbin/pw/pw_groupadd OLD_FILES+=usr/tests/usr.sbin/pw/pw_groupdel OLD_FILES+=usr/tests/usr.sbin/pw/pw_groupmod OLD_FILES+=usr/tests/usr.sbin/pw/pw_lock OLD_FILES+=usr/tests/usr.sbin/pw/pw_useradd OLD_FILES+=usr/tests/usr.sbin/pw/pw_userdel OLD_FILES+=usr/tests/usr.sbin/pw/pw_usermod OLD_FILES+=usr/tests/usr.sbin/pw/pw_usernext # 20170319: io_test requires zh_TW.Big5 locale OLD_FILES+=usr/tests/lib/libc/locale/io_test # 20170319: remove nls for non supported Big5* locales OLD_DIRS+=usr/share/nls/zh_HK.Big5HKSCS OLD_DIRS+=usr/share/nls/zh_TW.Big5 # 20170313: move .../sys/geom/eli/... to .../sys/geom/class/eli/... OLD_FILES+=usr/tests/sys/geom/eli/pbkdf2/pbkdf2 OLD_FILES+=usr/tests/sys/geom/eli/pbkdf2/Kyuafile OLD_FILES+=usr/tests/sys/geom/eli/Kyuafile OLD_DIRS+=usr/tests/sys/geom/eli/pbkdf2 OLD_DIRS+=usr/tests/sys/geom/eli # 20170313: sbin/ipftest and ipresend temporarily disconnected OLD_FILES+=sbin/ipftest OLD_FILES+=sbin/ipresend OLD_FILES+=usr/share/man/man1/ipftest.1.gz OLD_FILES+=usr/share/man/man1/ipresend.1.gz # 20170311: Remove WITHOUT_MANDOCDB option OLD_FILES+=usr/share/man/man1/makewhatis.1.gz # 20170308: rename some tests OLD_FILES+=usr/tests/bin/pwait/pwait OLD_FILES+=usr/tests/usr.bin/timeout/timeout # 20170307: remove pcap-int.h OLD_FILES+=usr/include/pcap-int.h # 20170302: new libc++ import which bumps version from 3.9.1 to 4.0.0 OLD_FILES+=usr/include/c++/v1/__undef___deallocate OLD_FILES+=usr/include/c++/v1/tr1/__undef___deallocate # 20170302: new clang import which bumps version from 3.9.1 to 4.0.0 OLD_FILES+=usr/lib/clang/3.9.1/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/3.9.1/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/3.9.1/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/3.9.1/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/3.9.1/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/3.9.1/include/sanitizer/esan_interface.h OLD_FILES+=usr/lib/clang/3.9.1/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/3.9.1/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/3.9.1/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/3.9.1/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/3.9.1/include/sanitizer OLD_FILES+=usr/lib/clang/3.9.1/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/3.9.1/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/3.9.1/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/3.9.1/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/3.9.1/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/3.9.1/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/3.9.1/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/3.9.1/include/adxintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/altivec.h OLD_FILES+=usr/lib/clang/3.9.1/include/ammintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/arm_acle.h OLD_FILES+=usr/lib/clang/3.9.1/include/arm_neon.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx2intrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/avxintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/bmiintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/cpuid.h OLD_FILES+=usr/lib/clang/3.9.1/include/cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/3.9.1/include/emmintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/f16cintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/fma4intrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/fmaintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/htmintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/ia32intrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/immintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/mm3dnow.h OLD_FILES+=usr/lib/clang/3.9.1/include/mm_malloc.h OLD_FILES+=usr/lib/clang/3.9.1/include/mmintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/module.modulemap OLD_FILES+=usr/lib/clang/3.9.1/include/msa.h OLD_FILES+=usr/lib/clang/3.9.1/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/nmmintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/opencl-c.h OLD_FILES+=usr/lib/clang/3.9.1/include/pkuintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/pmmintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/popcntintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/rtmintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/s390intrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/shaintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/smmintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/tbmintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/tmmintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/vadefs.h OLD_FILES+=usr/lib/clang/3.9.1/include/vecintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/wmmintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/x86intrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/xmmintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/xopintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/3.9.1/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/3.9.1/include OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/3.9.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/3.9.1/lib/freebsd OLD_DIRS+=usr/lib/clang/3.9.1/lib OLD_DIRS+=usr/lib/clang/3.9.1 # 20170226: SVR4 compatibility removed .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386" OLD_FILES+=usr/share/man/man4/streams.4 OLD_FILES+=usr/share/man/man4/svr4.4 .endif # 20170219: OpenPAM RADULA upgrade removed the libpam tests OLD_FILES+=usr/tests/lib/libpam/Kyuafile OLD_FILES+=usr/tests/lib/libpam/t_openpam_ctype OLD_FILES+=usr/tests/lib/libpam/t_openpam_readlinev OLD_FILES+=usr/tests/lib/libpam/t_openpam_readword OLD_DIRS+=usr/test/lib/libpam # 20170216: remove ahb(4) OLD_FILES+=usr/share/man/man4/ahb.4.gz # 20170216: remove fea(4) OLD_FILES+=usr/share/man/man4/fea.4.gz # 20170206: remove bdes(1) OLD_FILES+=usr/bin/bdes OLD_FILES+=usr/share/man/man1/bdes.1.gz # 20170206: merged projects/ipsec OLD_FILES+=usr/include/netinet/ip_ipsec.h OLD_FILES+=usr/include/netinet6/ip6_ipsec.h # 20170128: remove pc98 support OLD_FILES+=usr/include/dev/ic/i8251.h OLD_FILES+=usr/include/dev/ic/i8255.h OLD_FILES+=usr/include/dev/ic/rsa.h OLD_FILES+=usr/include/dev/ic/wd33c93reg.h OLD_FILES+=usr/include/sys/disk/pc98.h OLD_FILES+=usr/include/sys/diskpc98.h OLD_FILES+=usr/share/man/man4/i386/ct.4.gz OLD_FILES+=usr/share/man/man4/i386/snc.4.gz OLD_FILES+=usr/share/syscons/keymaps/jp.pc98.iso.kbd OLD_FILES+=usr/share/syscons/keymaps/jp.pc98.kbd OLD_FILES+=usr/share/vt/keymaps/jp.pc98.iso.kbd OLD_FILES+=usr/share/vt/keymaps/jp.pc98.kbd # 20170110: Four files from ggate tests consolidated into one OLD_FILES+=usr/tests/sys/geom/class/gate/1_test OLD_FILES+=usr/tests/sys/geom/class/gate/2_test OLD_FILES+=usr/tests/sys/geom/class/gate/3_test OLD_FILES+=usr/tests/sys/geom/class/gate/conf.sh # 20170103: libbsnmptools.so made into an INTERNALLIB OLD_FILES+=usr/lib/libbsnmptools.a OLD_FILES+=usr/lib/libbsnmptools_p.a OLD_LIBS+=usr/lib/libbsnmptools.so.0 OLD_FILES+=usr/lib/libbsnmptools.so # 20170102: sysdecode_getfsstat_flags() renamed to sysdecode_getfsstat_mode() OLD_FILES+=usr/share/man/man3/sysdecode_getfsstat_flags.3.gz # 20161230: libarchive ACL pax test renamed to test_acl_pax_posix1e.tar.uu OLD_FILES+=usr/tests/lib/libarchive/test_acl_pax.tar.uu # 20161229: Three files from gnop tests consolidated into one OLD_FILES+=usr/tests/sys/geom/class/nop/1_test OLD_FILES+=usr/tests/sys/geom/class/nop/2_test OLD_FILES+=usr/tests/sys/geom/class/nop/conf.sh # 20161217: new clang import which bumps version from 3.9.0 to 3.9.1 OLD_FILES+=usr/lib/clang/3.9.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/3.9.0/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/3.9.0/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/3.9.0/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/3.9.0/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/3.9.0/include/sanitizer/esan_interface.h OLD_FILES+=usr/lib/clang/3.9.0/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/3.9.0/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/3.9.0/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/3.9.0/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/3.9.0/include/sanitizer OLD_FILES+=usr/lib/clang/3.9.0/include/__clang_cuda_cmath.h OLD_FILES+=usr/lib/clang/3.9.0/include/__clang_cuda_intrinsics.h OLD_FILES+=usr/lib/clang/3.9.0/include/__clang_cuda_math_forward_declares.h OLD_FILES+=usr/lib/clang/3.9.0/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/3.9.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/3.9.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/3.9.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/3.9.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/altivec.h OLD_FILES+=usr/lib/clang/3.9.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/3.9.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512ifmaintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512ifmavlintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512pfintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512vbmiintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512vbmivlintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512vlcdintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/clflushoptintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/cpuid.h OLD_FILES+=usr/lib/clang/3.9.0/include/cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/3.9.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/htmintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/immintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/3.9.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/3.9.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/module.modulemap OLD_FILES+=usr/lib/clang/3.9.0/include/mwaitxintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/opencl-c.h OLD_FILES+=usr/lib/clang/3.9.0/include/pkuintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/s390intrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/vadefs.h OLD_FILES+=usr/lib/clang/3.9.0/include/vecintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/xopintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/3.9.0/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/3.9.0/include OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.stats-i386.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.stats-x86_64.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.stats_client-i386.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.stats_client-x86_64.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/3.9.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/3.9.0/lib/freebsd OLD_DIRS+=usr/lib/clang/3.9.0/lib OLD_DIRS+=usr/lib/clang/3.9.0 # 20161205: libproc version bump OLD_LIBS+=usr/lib/libproc.so.3 # 20161127: Remove vm_page_cache(9) OLD_FILES+=usr/share/man/man9/vm_page_cache.9.gz # 20161124: new clang import which bumps version from 3.8.0 to 3.9.0 OLD_FILES+=usr/lib/clang/3.8.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/3.8.0/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/3.8.0/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/3.8.0/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/3.8.0/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/3.8.0/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/3.8.0/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/3.8.0/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/3.8.0/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/3.8.0/include/sanitizer OLD_FILES+=usr/lib/clang/3.8.0/include/__clang_cuda_runtime_wrapper.h OLD_FILES+=usr/lib/clang/3.8.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/3.8.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/3.8.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/3.8.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/altivec.h OLD_FILES+=usr/lib/clang/3.8.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/3.8.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/3.8.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/cpuid.h OLD_FILES+=usr/lib/clang/3.8.0/include/cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/3.8.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/htmintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/immintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/3.8.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/3.8.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/module.modulemap OLD_FILES+=usr/lib/clang/3.8.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/pkuintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/s390intrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/vadefs.h OLD_FILES+=usr/lib/clang/3.8.0/include/vecintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/xopintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/xsavecintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/xsaveintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/xsaveoptintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/xsavesintrin.h OLD_FILES+=usr/lib/clang/3.8.0/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/3.8.0/include OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.asan-i386.so OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.asan-x86_64.so OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/3.8.0/lib/freebsd OLD_DIRS+=usr/lib/clang/3.8.0/lib OLD_DIRS+=usr/lib/clang/3.8.0 # 20161121: Hyper-V manuals only apply to amd64 and i386 .if ${TARGET_ARCH} != "amd64" && ${TARGET_ARCH} != "i386" OLD_FILES+=usr/share/man/man4/hv_kvp.4.gz OLD_FILES+=usr/share/man/man4/hv_netvsc.4.gz OLD_FILES+=usr/share/man/man4/hv_storvsc.4.gz OLD_FILES+=usr/share/man/man4/hv_utils.4.gz OLD_FILES+=usr/share/man/man4/hv_vmbus.4.gz OLD_FILES+=usr/share/man/man4/hv_vss.4.gz .endif # 20161118: Remove hv_ata_pci_disengage(4) OLD_FILES+=usr/share/man/man4/hv_ata_pci_disengage.4.gz # 20161017: urtwn(4) was merged into rtwn(4) OLD_FILES+=usr/share/man/man4/if_urtwn.4.gz OLD_FILES+=usr/share/man/man4/urtwn.4.gz OLD_FILES+=usr/share/man/man4/urtwnfw.4.gz # 20161015: Remove GNU rcs OLD_FILES+=usr/bin/ci OLD_FILES+=usr/bin/co OLD_FILES+=usr/bin/merge OLD_FILES+=usr/bin/rcs OLD_FILES+=usr/bin/rcsclean OLD_FILES+=usr/bin/rcsdiff OLD_FILES+=usr/bin/rcsfreeze OLD_FILES+=usr/bin/rcsmerge OLD_FILES+=usr/bin/rlog OLD_FILES+=usr/share/doc/psd/13.rcs/paper.ascii.gz OLD_FILES+=usr/share/doc/psd/13.rcs/rcs_func.ascii.gz OLD_DIRS+=usr/share/doc/psd/13.rcs OLD_FILES+=usr/share/man/man1/ci.1.gz OLD_FILES+=usr/share/man/man1/co.1.gz OLD_FILES+=usr/share/man/man1/merge.1.gz OLD_FILES+=usr/share/man/man1/rcs.1.gz OLD_FILES+=usr/share/man/man1/rcsclean.1.gz OLD_FILES+=usr/share/man/man1/rcsdiff.1.gz OLD_FILES+=usr/share/man/man1/rcsfreeze.1.gz OLD_FILES+=usr/share/man/man1/rcsintro.1.gz OLD_FILES+=usr/share/man/man1/rcsmerge.1.gz OLD_FILES+=usr/share/man/man1/rlog.1.gz OLD_FILES+=usr/share/man/man5/rcsfile.5.gz # 20161010: remove link to removed m_getclr(9) macro OLD_FILES+=usr/share/man/man9/m_getclr.9.gz # 20161003: MK_ELFCOPY_AS_OBJCOPY option retired OLD_FILES+=usr/bin/elfcopy OLD_FILES+=usr/share/man/man1/elfcopy.1.gz # 20160906: libkqueue tests moved to /usr/tests/sys/kqueue/libkqueue OLD_FILES+=usr/tests/sys/kqueue/kqtest OLD_FILES+=usr/tests/sys/kqueue/kqueue_test # 20160903: idle page zeroing support removed OLD_FILES+=usr/share/man/man9/pmap_zero_idle.9.gz # 20160901: Remove digi(4) OLD_FILES+=usr/share/man/man4/digi.4.gz # 20160819: Remove ie(4) OLD_FILES+=usr/share/man/man4/i386/ie.4.gz # 20160819: Remove spic(4) OLD_FILES+=usr/share/man/man4/spic.4.gz # 20160819: Remove wl(4) and wlconfig(8) OLD_FILES+=usr/share/man/man4/i386/wl.4.gz OLD_FILES+=usr/sbin/wlconfig OLD_FILES+=usr/share/man/man8/i386/wlconfig.8.gz # 20160819: Remove si(4) and sicontrol(8) OLD_FILES+=usr/share/man/man4/si.4.gz OLD_FILES+=usr/sbin/sicontrol OLD_FILES+=usr/share/man/man8/sicontrol.8.gz # 20160819: Remove scd(4) OLD_FILES+=usr/share/man/man4/scd.4.gz # 20160815: Remove mcd(4) OLD_FILES+=usr/share/man/man4/mcd.4.gz # 20160805: lockmgr_waiters(9) removed OLD_FILES+=usr/share/man/man9/lockmgr_waiters.9.gz # 20160703: POSIXify locales with variants OLD_FILES+=usr/share/locale/zh_Hant_TW.UTF-8/LC_COLLATE OLD_FILES+=usr/share/locale/zh_Hant_TW.UTF-8/LC_CTYPE OLD_FILES+=usr/share/locale/zh_Hant_TW.UTF-8/LC_MESSAGES OLD_FILES+=usr/share/locale/zh_Hant_TW.UTF-8/LC_MONETARY OLD_FILES+=usr/share/locale/zh_Hant_TW.UTF-8/LC_NUMERIC OLD_FILES+=usr/share/locale/zh_Hant_TW.UTF-8/LC_TIME OLD_DIRS+=usr/share/locale/zh_Hant_TW.UTF-8 OLD_FILES+=usr/share/locale/zh_Hant_TW.Big5/LC_COLLATE OLD_FILES+=usr/share/locale/zh_Hant_TW.Big5/LC_CTYPE OLD_FILES+=usr/share/locale/zh_Hant_TW.Big5/LC_MESSAGES OLD_FILES+=usr/share/locale/zh_Hant_TW.Big5/LC_MONETARY OLD_FILES+=usr/share/locale/zh_Hant_TW.Big5/LC_NUMERIC OLD_FILES+=usr/share/locale/zh_Hant_TW.Big5/LC_TIME OLD_DIRS+=usr/share/locale/zh_Hant_TW.Big5 OLD_FILES+=usr/share/locale/zh_Hant_HK.UTF-8/LC_COLLATE OLD_FILES+=usr/share/locale/zh_Hant_HK.UTF-8/LC_CTYPE OLD_FILES+=usr/share/locale/zh_Hant_HK.UTF-8/LC_MESSAGES OLD_FILES+=usr/share/locale/zh_Hant_HK.UTF-8/LC_MONETARY OLD_FILES+=usr/share/locale/zh_Hant_HK.UTF-8/LC_NUMERIC OLD_FILES+=usr/share/locale/zh_Hant_HK.UTF-8/LC_TIME OLD_DIRS+=usr/share/locale/zh_Hant_HK.UTF-8 OLD_FILES+=usr/share/locale/zh_Hans_CN.eucCN/LC_COLLATE OLD_FILES+=usr/share/locale/zh_Hans_CN.eucCN/LC_CTYPE OLD_FILES+=usr/share/locale/zh_Hans_CN.eucCN/LC_MESSAGES OLD_FILES+=usr/share/locale/zh_Hans_CN.eucCN/LC_MONETARY OLD_FILES+=usr/share/locale/zh_Hans_CN.eucCN/LC_NUMERIC OLD_FILES+=usr/share/locale/zh_Hans_CN.eucCN/LC_TIME OLD_DIRS+=usr/share/locale/zh_Hans_CN.eucCN OLD_FILES+=usr/share/locale/zh_Hans_CN.UTF-8/LC_COLLATE OLD_FILES+=usr/share/locale/zh_Hans_CN.UTF-8/LC_CTYPE OLD_FILES+=usr/share/locale/zh_Hans_CN.UTF-8/LC_MESSAGES OLD_FILES+=usr/share/locale/zh_Hans_CN.UTF-8/LC_MONETARY OLD_FILES+=usr/share/locale/zh_Hans_CN.UTF-8/LC_NUMERIC OLD_FILES+=usr/share/locale/zh_Hans_CN.UTF-8/LC_TIME OLD_DIRS+=usr/share/locale/zh_Hans_CN.UTF-8 OLD_FILES+=usr/share/locale/zh_Hans_CN.GBK/LC_COLLATE OLD_FILES+=usr/share/locale/zh_Hans_CN.GBK/LC_CTYPE OLD_FILES+=usr/share/locale/zh_Hans_CN.GBK/LC_MESSAGES OLD_FILES+=usr/share/locale/zh_Hans_CN.GBK/LC_MONETARY OLD_FILES+=usr/share/locale/zh_Hans_CN.GBK/LC_NUMERIC OLD_FILES+=usr/share/locale/zh_Hans_CN.GBK/LC_TIME OLD_DIRS+=usr/share/locale/zh_Hans_CN.GBK OLD_FILES+=usr/share/locale/zh_Hans_CN.GB2312/LC_COLLATE OLD_FILES+=usr/share/locale/zh_Hans_CN.GB2312/LC_CTYPE OLD_FILES+=usr/share/locale/zh_Hans_CN.GB2312/LC_MESSAGES OLD_FILES+=usr/share/locale/zh_Hans_CN.GB2312/LC_MONETARY OLD_FILES+=usr/share/locale/zh_Hans_CN.GB2312/LC_NUMERIC OLD_FILES+=usr/share/locale/zh_Hans_CN.GB2312/LC_TIME OLD_DIRS+=usr/share/locale/zh_Hans_CN.GB2312 OLD_FILES+=usr/share/locale/zh_Hans_CN.GB18030/LC_COLLATE OLD_FILES+=usr/share/locale/zh_Hans_CN.GB18030/LC_CTYPE OLD_FILES+=usr/share/locale/zh_Hans_CN.GB18030/LC_MESSAGES OLD_FILES+=usr/share/locale/zh_Hans_CN.GB18030/LC_MONETARY OLD_FILES+=usr/share/locale/zh_Hans_CN.GB18030/LC_NUMERIC OLD_FILES+=usr/share/locale/zh_Hans_CN.GB18030/LC_TIME OLD_DIRS+=usr/share/locale/zh_Hans_CN.GB18030 OLD_FILES+=usr/share/locale/sr_Latn_RS.UTF-8/LC_COLLATE OLD_FILES+=usr/share/locale/sr_Latn_RS.UTF-8/LC_CTYPE OLD_FILES+=usr/share/locale/sr_Latn_RS.UTF-8/LC_MESSAGES OLD_FILES+=usr/share/locale/sr_Latn_RS.UTF-8/LC_MONETARY OLD_FILES+=usr/share/locale/sr_Latn_RS.UTF-8/LC_NUMERIC OLD_FILES+=usr/share/locale/sr_Latn_RS.UTF-8/LC_TIME OLD_DIRS+=usr/share/locale/sr_Latn_RS.UTF-8 OLD_FILES+=usr/share/locale/sr_Latn_RS.ISO8859-2/LC_COLLATE OLD_FILES+=usr/share/locale/sr_Latn_RS.ISO8859-2/LC_CTYPE OLD_FILES+=usr/share/locale/sr_Latn_RS.ISO8859-2/LC_MESSAGES OLD_FILES+=usr/share/locale/sr_Latn_RS.ISO8859-2/LC_MONETARY OLD_FILES+=usr/share/locale/sr_Latn_RS.ISO8859-2/LC_NUMERIC OLD_FILES+=usr/share/locale/sr_Latn_RS.ISO8859-2/LC_TIME OLD_DIRS+=usr/share/locale/sr_Latn_RS.ISO8859-2 OLD_FILES+=usr/share/locale/sr_Cyrl_RS.UTF-8/LC_COLLATE OLD_FILES+=usr/share/locale/sr_Cyrl_RS.UTF-8/LC_CTYPE OLD_FILES+=usr/share/locale/sr_Cyrl_RS.UTF-8/LC_MESSAGES OLD_FILES+=usr/share/locale/sr_Cyrl_RS.UTF-8/LC_MONETARY OLD_FILES+=usr/share/locale/sr_Cyrl_RS.UTF-8/LC_NUMERIC OLD_FILES+=usr/share/locale/sr_Cyrl_RS.UTF-8/LC_TIME OLD_DIRS+=usr/share/locale/sr_Cyrl_RS.UTF-8 OLD_FILES+=usr/share/locale/sr_Cyrl_RS.ISO8859-5/LC_COLLATE OLD_FILES+=usr/share/locale/sr_Cyrl_RS.ISO8859-5/LC_CTYPE OLD_FILES+=usr/share/locale/sr_Cyrl_RS.ISO8859-5/LC_MESSAGES OLD_FILES+=usr/share/locale/sr_Cyrl_RS.ISO8859-5/LC_MONETARY OLD_FILES+=usr/share/locale/sr_Cyrl_RS.ISO8859-5/LC_NUMERIC OLD_FILES+=usr/share/locale/sr_Cyrl_RS.ISO8859-5/LC_TIME OLD_DIRS+=usr/share/locale/sr_Cyrl_RS.ISO8859-5 OLD_FILES+=usr/share/locale/mn_Cyrl_MN.UTF-8/LC_COLLATE OLD_FILES+=usr/share/locale/mn_Cyrl_MN.UTF-8/LC_CTYPE OLD_FILES+=usr/share/locale/mn_Cyrl_MN.UTF-8/LC_MESSAGES OLD_FILES+=usr/share/locale/mn_Cyrl_MN.UTF-8/LC_MONETARY OLD_FILES+=usr/share/locale/mn_Cyrl_MN.UTF-8/LC_NUMERIC OLD_FILES+=usr/share/locale/mn_Cyrl_MN.UTF-8/LC_TIME OLD_DIRS+=usr/share/locale/mn_Cyrl_MN.UTF-8 OLD_FILES+=usr/share/locale/kk_Cyrl_KZ.UTF-8/LC_COLLATE OLD_FILES+=usr/share/locale/kk_Cyrl_KZ.UTF-8/LC_CTYPE OLD_FILES+=usr/share/locale/kk_Cyrl_KZ.UTF-8/LC_MESSAGES OLD_FILES+=usr/share/locale/kk_Cyrl_KZ.UTF-8/LC_MONETARY OLD_FILES+=usr/share/locale/kk_Cyrl_KZ.UTF-8/LC_NUMERIC OLD_FILES+=usr/share/locale/kk_Cyrl_KZ.UTF-8/LC_TIME OLD_DIRS+=usr/share/locale/kk_Cyrl_KZ.UTF-8 # 20160608: removed pam_verbose_error OLD_LIBS+=usr/lib/libpam.so.5 OLD_LIBS+=usr/lib/pam_chroot.so.5 OLD_LIBS+=usr/lib/pam_deny.so.5 OLD_LIBS+=usr/lib/pam_echo.so.5 OLD_LIBS+=usr/lib/pam_exec.so.5 OLD_LIBS+=usr/lib/pam_ftpusers.so.5 OLD_LIBS+=usr/lib/pam_group.so.5 OLD_LIBS+=usr/lib/pam_guest.so.5 OLD_LIBS+=usr/lib/pam_krb5.so.5 OLD_LIBS+=usr/lib/pam_ksu.so.5 OLD_LIBS+=usr/lib/pam_lastlog.so.5 OLD_LIBS+=usr/lib/pam_login_access.so.5 OLD_LIBS+=usr/lib/pam_nologin.so.5 OLD_LIBS+=usr/lib/pam_opie.so.5 OLD_LIBS+=usr/lib/pam_opieaccess.so.5 OLD_LIBS+=usr/lib/pam_passwdqc.so.5 OLD_LIBS+=usr/lib/pam_permit.so.5 OLD_LIBS+=usr/lib/pam_radius.so.5 OLD_LIBS+=usr/lib/pam_rhosts.so.5 OLD_LIBS+=usr/lib/pam_rootok.so.5 OLD_LIBS+=usr/lib/pam_securetty.so.5 OLD_LIBS+=usr/lib/pam_self.so.5 OLD_LIBS+=usr/lib/pam_ssh.so.5 OLD_LIBS+=usr/lib/pam_tacplus.so.5 OLD_LIBS+=usr/lib/pam_unix.so.5 # 20160523: remove extranous ALTQ files OLD_FILES+=usr/include/altq/altq_codel.h OLD_FILES+=usr/include/altq/altq_fairq.h # 20160519: remove DTrace Toolkit from base OLD_FILES+=usr/sbin/dtruss OLD_FILES+=usr/share/dtrace/toolkit/execsnoop OLD_FILES+=usr/share/dtrace/toolkit/hotkernel OLD_FILES+=usr/share/dtrace/toolkit/hotuser OLD_FILES+=usr/share/dtrace/toolkit/opensnoop OLD_FILES+=usr/share/dtrace/toolkit/procsystime OLD_DIRS+=usr/share/dtrace/toolkit OLD_FILES+=usr/share/man/man1/dtruss.1.gz # 20160519: stale MLINK removed OLD_FILES+=usr/share/man/man9/rman_await_resource.9.gz # 20160517: ReiserFS removed OLD_FILES+=usr/share/man/man5/reiserfs.5.gz # 20160504: tests rework OLD_FILES+=usr/tests/lib/libc/regex/data/README # 20160430: kvm_getfiles(3) removed from kvm(3) OLD_LIBS+=lib/libkvm.so.6 OLD_FILES+=usr/share/man/man3/kvm_getfiles.3.gz # 20160423: remove mroute6d OLD_FILES+=etc/rc.d/mroute6d # 20160419: rename units.lib -> definitions.units OLD_FILES+=usr/share/misc/units.lib # 20160419: remove Big5HKSCS locales OLD_FILES+=usr/share/locale/zh_HK.Big5HKSCS/LC_COLLATE OLD_FILES+=usr/share/locale/zh_HK.Big5HKSCS/LC_CTYPE OLD_FILES+=usr/share/locale/zh_HK.Big5HKSCS/LC_MESSAGES OLD_FILES+=usr/share/locale/zh_HK.Big5HKSCS/LC_MONETARY OLD_FILES+=usr/share/locale/zh_HK.Big5HKSCS/LC_NUMERIC OLD_FILES+=usr/share/locale/zh_HK.Big5HKSCS/LC_TIME OLD_DIRS+=usr/share/locale/zh_HK.Big5HKSCS OLD_FILES+=usr/share/locale/zh_Hant_HK.Big5HKSCS/LC_COLLATE OLD_FILES+=usr/share/locale/zh_Hant_HK.Big5HKSCS/LC_CTYPE OLD_FILES+=usr/share/locale/zh_Hant_HK.Big5HKSCS/LC_MESSAGES OLD_FILES+=usr/share/locale/zh_Hant_HK.Big5HKSCS/LC_MONETARY OLD_FILES+=usr/share/locale/zh_Hant_HK.Big5HKSCS/LC_NUMERIC OLD_FILES+=usr/share/locale/zh_Hant_HK.Big5HKSCS/LC_TIME OLD_DIRS+=usr/share/locale/zh_Hant_HK.Big5HKSCS # 20160317: rman_res_t size bump to uintmax_t OLD_LIBS+=usr/lib/libdevinfo.so.5 # 20160305: new clang import which bumps version from 3.7.1 to 3.8.0 OLD_FILES+=usr/bin/macho-dump OLD_FILES+=usr/bin/tblgen OLD_FILES+=usr/lib/clang/3.7.1/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/3.7.1/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/3.7.1/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/3.7.1/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/3.7.1/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/3.7.1/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/3.7.1/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/3.7.1/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/3.7.1/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/3.7.1/include/sanitizer OLD_FILES+=usr/lib/clang/3.7.1/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/3.7.1/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/3.7.1/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/3.7.1/include/adxintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/altivec.h OLD_FILES+=usr/lib/clang/3.7.1/include/ammintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/arm_acle.h OLD_FILES+=usr/lib/clang/3.7.1/include/arm_neon.h OLD_FILES+=usr/lib/clang/3.7.1/include/avx2intrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/avxintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/bmiintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/cpuid.h OLD_FILES+=usr/lib/clang/3.7.1/include/cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/3.7.1/include/emmintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/f16cintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/fma4intrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/fmaintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/htmintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/ia32intrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/immintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/mm3dnow.h OLD_FILES+=usr/lib/clang/3.7.1/include/mm_malloc.h OLD_FILES+=usr/lib/clang/3.7.1/include/mmintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/module.modulemap OLD_FILES+=usr/lib/clang/3.7.1/include/nmmintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/pmmintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/popcntintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/rtmintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/s390intrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/shaintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/smmintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/tbmintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/tmmintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/vadefs.h OLD_FILES+=usr/lib/clang/3.7.1/include/vecintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/wmmintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/x86intrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/xmmintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/xopintrin.h OLD_FILES+=usr/lib/clang/3.7.1/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/3.7.1/include OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/3.7.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/3.7.1/lib/freebsd OLD_DIRS+=usr/lib/clang/3.7.1/lib OLD_DIRS+=usr/lib/clang/3.7.1 OLD_FILES+=usr/share/man/man1/tblgen.1.gz # 20160301: Remove taskqueue_enqueue_fast OLD_FILES+=usr/share/man/man9/taskqueue_enqueue_fast.9.gz # 20160225: Remove casperd and libcapsicum OLD_FILES+=sbin/casperd OLD_FILES+=etc/rc.d/casperd OLD_FILES+=usr/share/man/man8/casperd.8.gz OLD_FILES+=usr/include/libcapsicum.h OLD_FILES+=usr/include/libcapsicum_service.h OLD_FILES+=usr/include/libcapsicum.h OLD_FILES+=usr/share/man/man3/libcapsicum.3.gz OLD_FILES+=usr/include/libcapsicum_dns.h OLD_FILES+=usr/include/libcapsicum_grp.h OLD_FILES+=usr/include/libcapsicum_impl.h OLD_FILES+=usr/include/libcapsicum_pwd.h OLD_FILES+=usr/include/libcapsicum_random.h OLD_FILES+=usr/include/libcapsicum_sysctl.h OLD_FILES+=libexec/casper/dns OLD_FILES+=libexec/casper/grp OLD_FILES+=libexec/casper/pwd OLD_FILES+=libexec/casper/random OLD_FILES+=libexec/casper/sysctl OLD_FILES+=libexec/casper/.debug/random.debug OLD_FILES+=libexec/casper/.debug/dns.debug OLD_FILES+=libexec/casper/.debug/sysctl.debug OLD_FILES+=libexec/casper/.debug/pwd.debug OLD_FILES+=libexec/casper/.debug/grp.debug OLD_DIRS+=libexec/casper/.debug OLD_DIRS+=libexec/casper OLD_FILES+=usr/lib/libcapsicum.a OLD_FILES+=usr/lib/libcapsicum.so OLD_LIBS+=lib/libcapsicum.so.0 OLD_FILES+=usr/lib/libcapsicum_p.a # 20160223: functionality from mkulzma(1) merged into mkuzip(1) OLD_FILES+=usr/bin/mkulzma OLD_FILES+=usr/share/man/man4/geom_uncompress.4.gz OLD_FILES+=usr/share/man/man8/mkulzma.8.gz # 20160211: Remove obsolete unbound-control-setup OLD_FILES+=usr/sbin/unbound-control-setup # 20160121: cc.h moved OLD_FILES+=usr/include/netinet/cc.h # 20160116: Update mandoc to cvs snapshot 20160116 OLD_FILES+=usr/share/mdocml/example.style.css OLD_FILES+=usr/share/mdocml/style.css OLD_DIRS+=usr/share/mdocml # 20160114: SA-16:06.snmpd OLD_FILES+=usr/share/examples/etc/snmpd.config # 20160107: GNU ld installed as ld.bfd and linked as ld OLD_FILES+=usr/lib/debug/usr/bin/ld.debug # 20151225: new clang import which bumps version from 3.7.0 to 3.7.1 OLD_FILES+=usr/lib/clang/3.7.0/include/sanitizer/allocator_interface.h OLD_FILES+=usr/lib/clang/3.7.0/include/sanitizer/asan_interface.h OLD_FILES+=usr/lib/clang/3.7.0/include/sanitizer/common_interface_defs.h OLD_FILES+=usr/lib/clang/3.7.0/include/sanitizer/coverage_interface.h OLD_FILES+=usr/lib/clang/3.7.0/include/sanitizer/dfsan_interface.h OLD_FILES+=usr/lib/clang/3.7.0/include/sanitizer/linux_syscall_hooks.h OLD_FILES+=usr/lib/clang/3.7.0/include/sanitizer/lsan_interface.h OLD_FILES+=usr/lib/clang/3.7.0/include/sanitizer/msan_interface.h OLD_FILES+=usr/lib/clang/3.7.0/include/sanitizer/tsan_interface_atomic.h OLD_DIRS+=usr/lib/clang/3.7.0/include/sanitizer OLD_FILES+=usr/lib/clang/3.7.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/3.7.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/3.7.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/3.7.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/altivec.h OLD_FILES+=usr/lib/clang/3.7.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/3.7.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/3.7.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/avx512cdintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/avx512dqintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/avx512vldqintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/cpuid.h OLD_FILES+=usr/lib/clang/3.7.0/include/cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/3.7.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/fxsrintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/htmintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/htmxlintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/immintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/3.7.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/3.7.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/module.modulemap OLD_FILES+=usr/lib/clang/3.7.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/s390intrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/vadefs.h OLD_FILES+=usr/lib/clang/3.7.0/include/vecintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/xopintrin.h OLD_FILES+=usr/lib/clang/3.7.0/include/xtestintrin.h OLD_DIRS+=usr/lib/clang/3.7.0/include OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan-preinit-i386.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan-preinit-x86_64.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.safestack-i386.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.safestack-x86_64.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.ubsan_standalone-i386.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/3.7.0/lib/freebsd OLD_DIRS+=usr/lib/clang/3.7.0/lib OLD_DIRS+=usr/lib/clang/3.7.0 # 20151130: libelf moved from /usr/lib to /lib (libkvm dependency in r291406) MOVED_LIBS+=usr/lib/libelf.so.2 # 20151115: Fox bad upgrade scheme OLD_FILES+=usr/share/locale/zh_CN.GB18030/zh_Hans_CN.GB18030 OLD_FILES+=usr/share/locale/zh_CN.GB2312/zh_Hans_CN.GB2312 OLD_FILES+=usr/share/locale/zh_CN.GBK/zh_Hans_CN.GBK OLD_FILES+=usr/share/locale/zh_CN.UTF-8/zh_Hans_CN.UTF-8 OLD_FILES+=usr/share/locale/zh_CN.eucCN/zh_Hans_CN.eucCN OLD_FILES+=usr/share/locale/zh_TW.Big5/zh_Hant_TW.Big5 OLD_FILES+=usr/share/locale/zh_TW.UTF-8/zh_Hant_TW.UTF-8 # 20151107: String collation improvements OLD_FILES+=usr/share/locale/UTF-8/LC_CTYPE OLD_DIRS+=usr/share/locale/UTF-8 OLD_FILES+=usr/share/locale/kk_KZ.PT154/LC_COLLATE OLD_FILES+=usr/share/locale/kk_KZ.PT154/LC_CTYPE OLD_FILES+=usr/share/locale/kk_KZ.PT154/LC_MESSAGES OLD_FILES+=usr/share/locale/kk_KZ.PT154/LC_MONETARY OLD_FILES+=usr/share/locale/kk_KZ.PT154/LC_NUMERIC OLD_FILES+=usr/share/locale/kk_KZ.PT154/LC_TIME OLD_DIRS+=usr/share/locale/kk_KZ.PT154/ OLD_FILES+=usr/share/locale/la_LN.ISO8859-1/LC_COLLATE OLD_FILES+=usr/share/locale/la_LN.ISO8859-1/LC_CTYPE OLD_FILES+=usr/share/locale/la_LN.ISO8859-1/LC_TIME OLD_DIRS+=usr/share/locale/la_LN.ISO8859-1 OLD_FILES+=usr/share/locale/la_LN.ISO8859-13/LC_COLLATE OLD_FILES+=usr/share/locale/la_LN.ISO8859-13/LC_CTYPE OLD_DIRS+=usr/share/locale/la_LN.ISO8859-13 OLD_FILES+=usr/share/locale/la_LN.ISO8859-15/LC_COLLATE OLD_FILES+=usr/share/locale/la_LN.ISO8859-15/LC_CTYPE OLD_FILES+=usr/share/locale/la_LN.ISO8859-15/LC_TIME OLD_DIRS+=usr/share/locale/la_LN.ISO8859-15 OLD_FILES+=usr/share/locale/la_LN.ISO8859-2/LC_COLLATE OLD_FILES+=usr/share/locale/la_LN.ISO8859-2/LC_CTYPE OLD_FILES+=usr/share/locale/la_LN.ISO8859-2/LC_TIME OLD_DIRS+=usr/share/locale/la_LN.ISO8859-2 OLD_FILES+=usr/share/locale/la_LN.ISO8859-4/LC_COLLATE OLD_FILES+=usr/share/locale/la_LN.ISO8859-4/LC_CTYPE OLD_FILES+=usr/share/locale/la_LN.ISO8859-4/LC_TIME OLD_DIRS+=usr/share/locale/la_LN.ISO8859-4 OLD_FILES+=usr/share/locale/la_LN.US-ASCII/LC_COLLATE OLD_FILES+=usr/share/locale/la_LN.US-ASCII/LC_CTYPE OLD_FILES+=usr/share/locale/la_LN.US-ASCII/LC_TIME OLD_DIRS+=usr/share/locale/la_LN.US-ASCII OLD_FILES+=usr/share/locale/lt_LT.ISO8859-4/LC_MESSAGES OLD_FILES+=usr/share/locale/lt_LT.ISO8859-4/LC_TIME OLD_FILES+=usr/share/locale/lt_LT.ISO8859-4/LC_COLLATE OLD_FILES+=usr/share/locale/lt_LT.ISO8859-4/LC_MONETARY OLD_FILES+=usr/share/locale/lt_LT.ISO8859-4/LC_CTYPE OLD_FILES+=usr/share/locale/lt_LT.ISO8859-4/LC_NUMERIC OLD_DIRS+=usr/share/locale/lt_LT.ISO8859-4 OLD_FILES+=usr/share/locale/no_NO.ISO8859-1/LC_COLLATE OLD_FILES+=usr/share/locale/no_NO.ISO8859-1/LC_CTYPE OLD_FILES+=usr/share/locale/no_NO.ISO8859-1/LC_MESSAGES OLD_FILES+=usr/share/locale/no_NO.ISO8859-1/LC_MONETARY OLD_FILES+=usr/share/locale/no_NO.ISO8859-1/LC_NUMERIC OLD_FILES+=usr/share/locale/no_NO.ISO8859-1/LC_TIME OLD_DIRS+=usr/share/locale/no_NO.ISO8859-1 OLD_FILES+=usr/share/locale/no_NO.ISO8859-15/LC_COLLATE OLD_FILES+=usr/share/locale/no_NO.ISO8859-15/LC_CTYPE OLD_FILES+=usr/share/locale/no_NO.ISO8859-15/LC_MESSAGES OLD_FILES+=usr/share/locale/no_NO.ISO8859-15/LC_MONETARY OLD_FILES+=usr/share/locale/no_NO.ISO8859-15/LC_NUMERIC OLD_FILES+=usr/share/locale/no_NO.ISO8859-15/LC_TIME OLD_DIRS+=usr/share/locale/no_NO.ISO8859-15 OLD_FILES+=usr/share/locale/no_NO.UTF-8/LC_COLLATE OLD_FILES+=usr/share/locale/no_NO.UTF-8/LC_CTYPE OLD_FILES+=usr/share/locale/no_NO.UTF-8/LC_MESSAGES OLD_FILES+=usr/share/locale/no_NO.UTF-8/LC_MONETARY OLD_FILES+=usr/share/locale/no_NO.UTF-8/LC_NUMERIC OLD_FILES+=usr/share/locale/no_NO.UTF-8/LC_TIME OLD_DIRS+=usr/share/locale/no_NO.UTF-8 OLD_FILES+=usr/share/locale/sr_YU.ISO8859-2/LC_COLLATE OLD_FILES+=usr/share/locale/sr_YU.ISO8859-2/LC_TIME OLD_FILES+=usr/share/locale/sr_YU.ISO8859-2/LC_CTYPE OLD_FILES+=usr/share/locale/sr_YU.ISO8859-2/LC_MESSAGES OLD_FILES+=usr/share/locale/sr_YU.ISO8859-2/LC_NUMERIC OLD_FILES+=usr/share/locale/sr_YU.ISO8859-2/LC_MONETARY OLD_DIRS+=usr/share/locale/sr_YU.ISO8859-2 OLD_FILES+=usr/share/locale/sr_YU.ISO8859-5/LC_COLLATE OLD_FILES+=usr/share/locale/sr_YU.ISO8859-5/LC_MONETARY OLD_FILES+=usr/share/locale/sr_YU.ISO8859-5/LC_NUMERIC OLD_FILES+=usr/share/locale/sr_YU.ISO8859-5/LC_CTYPE OLD_FILES+=usr/share/locale/sr_YU.ISO8859-5/LC_TIME OLD_FILES+=usr/share/locale/sr_YU.ISO8859-5/LC_MESSAGES OLD_DIRS+=usr/share/locale/sr_YU.ISO8859-5 OLD_FILES+=usr/share/locale/sr_YU.UTF-8/LC_COLLATE OLD_FILES+=usr/share/locale/sr_YU.UTF-8/LC_MONETARY OLD_FILES+=usr/share/locale/sr_YU.UTF-8/LC_CTYPE OLD_FILES+=usr/share/locale/sr_YU.UTF-8/LC_TIME OLD_FILES+=usr/share/locale/sr_YU.UTF-8/LC_NUMERIC OLD_FILES+=usr/share/locale/sr_YU.UTF-8/LC_MESSAGES OLD_DIRS+=usr/share/locale/sr_YU.UTF-8 # 20151101: added missing _test suffix on multiple tests in lib/libc OLD_FILES+=usr/tests/lib/libc/c063/faccessat OLD_FILES+=usr/tests/lib/libc/c063/fchmodat OLD_FILES+=usr/tests/lib/libc/c063/fchownat OLD_FILES+=usr/tests/lib/libc/c063/fexecve OLD_FILES+=usr/tests/lib/libc/c063/fstatat OLD_FILES+=usr/tests/lib/libc/c063/linkat OLD_FILES+=usr/tests/lib/libc/c063/mkdirat OLD_FILES+=usr/tests/lib/libc/c063/mkfifoat OLD_FILES+=usr/tests/lib/libc/c063/mknodat OLD_FILES+=usr/tests/lib/libc/c063/openat OLD_FILES+=usr/tests/lib/libc/c063/readlinkat OLD_FILES+=usr/tests/lib/libc/c063/renameat OLD_FILES+=usr/tests/lib/libc/c063/symlinkat OLD_FILES+=usr/tests/lib/libc/c063/unlinkat OLD_FILES+=usr/tests/lib/libc/c063/utimensat OLD_FILES+=usr/tests/lib/libc/string/memchr OLD_FILES+=usr/tests/lib/libc/string/memcpy OLD_FILES+=usr/tests/lib/libc/string/memmem OLD_FILES+=usr/tests/lib/libc/string/memset OLD_FILES+=usr/tests/lib/libc/string/strcat OLD_FILES+=usr/tests/lib/libc/string/strchr OLD_FILES+=usr/tests/lib/libc/string/strcmp OLD_FILES+=usr/tests/lib/libc/string/strcpy OLD_FILES+=usr/tests/lib/libc/string/strcspn OLD_FILES+=usr/tests/lib/libc/string/strerror OLD_FILES+=usr/tests/lib/libc/string/strlen OLD_FILES+=usr/tests/lib/libc/string/strpbrk OLD_FILES+=usr/tests/lib/libc/string/strrchr OLD_FILES+=usr/tests/lib/libc/string/strspn OLD_FILES+=usr/tests/lib/libc/string/swab # 20151101: 430.status-rwho was renamed to 430.status-uptime OLD_FILES+=etc/periodic/daily/430.status-rwho # 20151030: OpenSSL 1.0.2d import OLD_FILES+=usr/share/openssl/man/man3/CMS_set1_signer_certs.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_PKEY_ctrl.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_PKEY_ctrl_str.3.gz OLD_FILES+=usr/share/openssl/man/man3/d2i_509_CRL_fp.3.gz OLD_LIBS+=lib/libcrypto.so.7 OLD_LIBS+=usr/lib/libssl.so.7 # 20151029: LinuxKPI moved to sys/compat/linuxkpi OLD_FILES+=usr/include/dev/usb/usb_compat_linux.h # 20151015: test symbols moved to /usr/lib/debug OLD_DIRS+=usr/tests/lib/atf/libatf-c++/.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/.debug/atf_c++_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/.debug/build_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/.debug/check_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/.debug/config_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/.debug/macros_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/.debug/tests_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/.debug/utils_test.debug OLD_DIRS+=usr/tests/lib/atf/libatf-c++/detail/.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/detail/.debug/application_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/detail/.debug/env_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/detail/.debug/exceptions_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/detail/.debug/fs_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/detail/.debug/process_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/detail/.debug/sanity_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/detail/.debug/text_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c++/detail/.debug/version_helper.debug OLD_DIRS+=usr/tests/lib/atf/libatf-c/.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/.debug/atf_c_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/.debug/build_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/.debug/check_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/.debug/config_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/.debug/error_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/.debug/macros_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/.debug/tc_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/.debug/tp_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/.debug/utils_test.debug OLD_DIRS+=usr/tests/lib/atf/libatf-c/detail/.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/detail/.debug/dynstr_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/detail/.debug/env_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/detail/.debug/fs_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/detail/.debug/list_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/detail/.debug/map_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/detail/.debug/process_helpers.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/detail/.debug/process_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/detail/.debug/sanity_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/detail/.debug/text_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/detail/.debug/user_test.debug OLD_FILES+=usr/tests/lib/atf/libatf-c/detail/.debug/version_helper.debug OLD_DIRS+=usr/tests/lib/atf/test-programs/.debug OLD_FILES+=usr/tests/lib/atf/test-programs/.debug/c_helpers.debug OLD_FILES+=usr/tests/lib/atf/test-programs/.debug/cpp_helpers.debug OLD_DIRS+=usr/tests/lib/libc/c063/.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/faccessat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/fchmodat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/fchownat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/fexecve.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/fstatat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/linkat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/mkdirat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/mkfifoat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/mknodat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/openat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/readlinkat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/renameat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/symlinkat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/unlinkat.debug OLD_FILES+=usr/tests/lib/libc/c063/.debug/utimensat.debug OLD_DIRS+=usr/tests/lib/libc/db/.debug OLD_FILES+=usr/tests/lib/libc/db/.debug/h_db.debug OLD_DIRS+=usr/tests/lib/libc/gen/.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/alarm_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/arc4random_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/assert_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/basedirname_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/dir_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/floatunditf_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/fnmatch_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/fpclassify2_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/fpclassify_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/fpsetmask_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/fpsetround_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/ftok_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/getcwd_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/getgrent_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/glob_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/humanize_number_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/isnan_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/nice_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/pause_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/raise_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/realpath_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/setdomainname_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/sethostname_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/sleep_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/syslog_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/time_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/ttyname_test.debug OLD_FILES+=usr/tests/lib/libc/gen/.debug/vis_test.debug OLD_DIRS+=usr/tests/lib/libc/gen/execve/.debug OLD_FILES+=usr/tests/lib/libc/gen/execve/.debug/execve_test.debug OLD_DIRS+=usr/tests/lib/libc/gen/posix_spawn/.debug OLD_FILES+=usr/tests/lib/libc/gen/posix_spawn/.debug/fileactions_test.debug OLD_FILES+=usr/tests/lib/libc/gen/posix_spawn/.debug/h_fileactions.debug OLD_FILES+=usr/tests/lib/libc/gen/posix_spawn/.debug/h_spawn.debug OLD_FILES+=usr/tests/lib/libc/gen/posix_spawn/.debug/h_spawnattr.debug OLD_FILES+=usr/tests/lib/libc/gen/posix_spawn/.debug/spawn_test.debug OLD_FILES+=usr/tests/lib/libc/gen/posix_spawn/.debug/spawnattr_test.debug OLD_DIRS+=usr/tests/lib/libc/hash/.debug OLD_FILES+=usr/tests/lib/libc/hash/.debug/h_hash.debug OLD_FILES+=usr/tests/lib/libc/hash/.debug/sha2_test.debug OLD_DIRS+=usr/tests/lib/libc/inet/.debug OLD_FILES+=usr/tests/lib/libc/inet/.debug/inet_network_test.debug OLD_DIRS+=usr/tests/lib/libc/locale/.debug OLD_FILES+=usr/tests/lib/libc/locale/.debug/io_test.debug OLD_FILES+=usr/tests/lib/libc/locale/.debug/mbrtowc_test.debug OLD_FILES+=usr/tests/lib/libc/locale/.debug/mbsnrtowcs_test.debug OLD_FILES+=usr/tests/lib/libc/locale/.debug/mbstowcs_test.debug OLD_FILES+=usr/tests/lib/libc/locale/.debug/mbtowc_test.debug OLD_FILES+=usr/tests/lib/libc/locale/.debug/wcscspn_test.debug OLD_FILES+=usr/tests/lib/libc/locale/.debug/wcspbrk_test.debug OLD_FILES+=usr/tests/lib/libc/locale/.debug/wcsspn_test.debug OLD_FILES+=usr/tests/lib/libc/locale/.debug/wcstod_test.debug OLD_FILES+=usr/tests/lib/libc/locale/.debug/wctomb_test.debug OLD_DIRS+=usr/tests/lib/libc/net/.debug OLD_FILES+=usr/tests/lib/libc/net/.debug/ether_aton_test.debug OLD_FILES+=usr/tests/lib/libc/net/.debug/getprotoent_test.debug OLD_FILES+=usr/tests/lib/libc/net/.debug/h_dns_server.debug OLD_FILES+=usr/tests/lib/libc/net/.debug/h_nsd_recurse.debug OLD_FILES+=usr/tests/lib/libc/net/.debug/h_protoent.debug OLD_FILES+=usr/tests/lib/libc/net/.debug/h_servent.debug OLD_DIRS+=usr/tests/lib/libc/regex/.debug OLD_FILES+=usr/tests/lib/libc/regex/.debug/exhaust_test.debug OLD_FILES+=usr/tests/lib/libc/regex/.debug/h_regex.debug OLD_FILES+=usr/tests/lib/libc/regex/.debug/regex_att_test.debug OLD_DIRS+=usr/tests/lib/libc/ssp/.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_fgets.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_getcwd.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_gets.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_memcpy.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_memmove.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_memset.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_raw.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_read.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_readlink.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_snprintf.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_sprintf.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_stpcpy.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_stpncpy.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_strcat.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_strcpy.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_strncat.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_strncpy.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_vsnprintf.debug OLD_FILES+=usr/tests/lib/libc/ssp/.debug/h_vsprintf.debug OLD_DIRS+=usr/tests/lib/libc/stdio/.debug OLD_FILES+=usr/tests/lib/libc/stdio/.debug/clearerr_test.debug OLD_FILES+=usr/tests/lib/libc/stdio/.debug/fflush_test.debug OLD_FILES+=usr/tests/lib/libc/stdio/.debug/fmemopen2_test.debug OLD_FILES+=usr/tests/lib/libc/stdio/.debug/fmemopen_test.debug OLD_FILES+=usr/tests/lib/libc/stdio/.debug/fopen_test.debug OLD_FILES+=usr/tests/lib/libc/stdio/.debug/fputc_test.debug OLD_FILES+=usr/tests/lib/libc/stdio/.debug/mktemp_test.debug OLD_FILES+=usr/tests/lib/libc/stdio/.debug/popen_test.debug OLD_FILES+=usr/tests/lib/libc/stdio/.debug/printf_test.debug OLD_FILES+=usr/tests/lib/libc/stdio/.debug/scanf_test.debug OLD_DIRS+=usr/tests/lib/libc/stdlib/.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/abs_test.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/atoi_test.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/div_test.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/exit_test.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/getenv_test.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/h_getopt.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/h_getopt_long.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/hsearch_test.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/posix_memalign_test.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/random_test.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/strtod_test.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/strtol_test.debug OLD_FILES+=usr/tests/lib/libc/stdlib/.debug/system_test.debug OLD_DIRS+=usr/tests/lib/libc/string/.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/memchr.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/memcpy.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/memmem.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/memset.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/strcat.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/strchr.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/strcmp.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/strcpy.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/strcspn.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/strerror.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/strlen.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/strpbrk.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/strrchr.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/strspn.debug OLD_FILES+=usr/tests/lib/libc/string/.debug/swab.debug OLD_DIRS+=usr/tests/lib/libc/sys/.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/access_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/chroot_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/clock_gettime_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/connect_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/dup_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/fsync_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/getcontext_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/getgroups_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/getitimer_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/getlogin_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/getpid_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/getrusage_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/getsid_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/gettimeofday_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/issetugid_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/kevent_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/kill_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/link_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/listen_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/mincore_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/mkdir_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/mkfifo_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/mknod_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/mlock_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/mmap_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/mprotect_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/msgctl_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/msgget_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/msgrcv_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/msgsnd_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/msync_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/nanosleep_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/pipe2_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/pipe_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/poll_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/revoke_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/select_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/setrlimit_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/setuid_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/sigaction_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/sigqueue_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/sigtimedwait_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/socketpair_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/stat_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/timer_create_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/truncate_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/ucontext_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/umask_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/unlink_test.debug OLD_FILES+=usr/tests/lib/libc/sys/.debug/write_test.debug OLD_DIRS+=usr/tests/lib/libc/termios/.debug OLD_FILES+=usr/tests/lib/libc/termios/.debug/tcsetpgrp_test.debug OLD_DIRS+=usr/tests/lib/libc/tls/.debug OLD_FILES+=usr/tests/lib/libc/tls/.debug/h_tls_dlopen.so.debug OLD_FILES+=usr/tests/lib/libc/tls/.debug/libh_tls_dynamic.so.1.debug OLD_FILES+=usr/tests/lib/libc/tls/.debug/tls_dlopen_test.debug OLD_FILES+=usr/tests/lib/libc/tls/.debug/tls_dynamic_test.debug OLD_DIRS+=usr/tests/lib/libc/ttyio/.debug OLD_FILES+=usr/tests/lib/libc/ttyio/.debug/ttyio_test.debug OLD_DIRS+=usr/tests/lib/libcrypt/.debug OLD_FILES+=usr/tests/lib/libcrypt/.debug/crypt_tests.debug OLD_DIRS+=usr/tests/lib/libmp/.debug OLD_FILES+=usr/tests/lib/libmp/.debug/legacy_test.debug OLD_DIRS+=usr/tests/lib/libnv/.debug OLD_FILES+=usr/tests/lib/libnv/.debug/dnv_tests.debug OLD_FILES+=usr/tests/lib/libnv/.debug/nv_array_tests.debug OLD_FILES+=usr/tests/lib/libnv/.debug/nv_tests.debug OLD_FILES+=usr/tests/lib/libnv/.debug/nvlist_add_test.debug OLD_FILES+=usr/tests/lib/libnv/.debug/nvlist_exists_test.debug OLD_FILES+=usr/tests/lib/libnv/.debug/nvlist_free_test.debug OLD_FILES+=usr/tests/lib/libnv/.debug/nvlist_get_test.debug OLD_FILES+=usr/tests/lib/libnv/.debug/nvlist_move_test.debug OLD_FILES+=usr/tests/lib/libnv/.debug/nvlist_send_recv_test.debug OLD_DIRS+=usr/tests/lib/libpam/.debug OLD_FILES+=usr/tests/lib/libpam/.debug/t_openpam_ctype.debug OLD_FILES+=usr/tests/lib/libpam/.debug/t_openpam_readlinev.debug OLD_FILES+=usr/tests/lib/libpam/.debug/t_openpam_readword.debug OLD_DIRS+=usr/tests/lib/libproc/.debug OLD_FILES+=usr/tests/lib/libproc/.debug/proc_test.debug OLD_FILES+=usr/tests/lib/libproc/.debug/target_prog.debug OLD_DIRS+=usr/tests/lib/librt/.debug OLD_FILES+=usr/tests/lib/librt/.debug/sched_test.debug OLD_FILES+=usr/tests/lib/librt/.debug/sem_test.debug OLD_DIRS+=usr/tests/lib/libthr/.debug OLD_FILES+=usr/tests/lib/libthr/.debug/barrier_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/cond_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/condwait_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/detach_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/equal_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/fork_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/fpu_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/h_atexit.debug OLD_FILES+=usr/tests/lib/libthr/.debug/h_cancel.debug OLD_FILES+=usr/tests/lib/libthr/.debug/h_exit.debug OLD_FILES+=usr/tests/lib/libthr/.debug/h_resolv.debug OLD_FILES+=usr/tests/lib/libthr/.debug/join_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/kill_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/mutex_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/once_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/preempt_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/rwlock_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/sem_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/siglongjmp_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/sigmask_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/sigsuspend_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/sleep_test.debug OLD_FILES+=usr/tests/lib/libthr/.debug/swapcontext_test.debug OLD_DIRS+=usr/tests/lib/libthr/dlopen/.debug OLD_FILES+=usr/tests/lib/libthr/dlopen/.debug/dlopen_test.debug OLD_FILES+=usr/tests/lib/libthr/dlopen/.debug/h_pthread_dlopen.so.1.debug OLD_FILES+=usr/tests/lib/libthr/dlopen/.debug/main_pthread_create_test.debug OLD_DIRS+=usr/tests/lib/libutil/.debug OLD_FILES+=usr/tests/lib/libutil/.debug/flopen_test.debug OLD_FILES+=usr/tests/lib/libutil/.debug/grp_test.debug OLD_FILES+=usr/tests/lib/libutil/.debug/humanize_number_test.debug OLD_FILES+=usr/tests/lib/libutil/.debug/pidfile_test.debug OLD_FILES+=usr/tests/lib/libutil/.debug/trimdomain-nodomain_test.debug OLD_FILES+=usr/tests/lib/libutil/.debug/trimdomain_test.debug OLD_DIRS+=usr/tests/lib/libxo/.debug OLD_FILES+=usr/tests/lib/libxo/.debug/libenc_test.so.debug OLD_FILES+=usr/tests/lib/libxo/.debug/test_01.debug OLD_FILES+=usr/tests/lib/libxo/.debug/test_02.debug OLD_FILES+=usr/tests/lib/libxo/.debug/test_03.debug OLD_FILES+=usr/tests/lib/libxo/.debug/test_04.debug OLD_FILES+=usr/tests/lib/libxo/.debug/test_05.debug OLD_FILES+=usr/tests/lib/libxo/.debug/test_06.debug OLD_FILES+=usr/tests/lib/libxo/.debug/test_07.debug OLD_FILES+=usr/tests/lib/libxo/.debug/test_08.debug OLD_FILES+=usr/tests/lib/libxo/.debug/test_09.debug OLD_FILES+=usr/tests/lib/libxo/.debug/test_10.debug OLD_FILES+=usr/tests/lib/libxo/.debug/test_11.debug OLD_DIRS+=usr/tests/lib/msun/.debug OLD_FILES+=usr/tests/lib/msun/.debug/acos_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/asin_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/atan_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/cbrt_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/ceil_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/cos_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/cosh_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/erf_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/exp_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/fmod_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/infinity_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/ldexp_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/log_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/pow_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/precision_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/round_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/scalbn_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/sin_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/sinh_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/sqrt_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/tan_test.debug OLD_FILES+=usr/tests/lib/msun/.debug/tanh_test.debug OLD_DIRS+=usr/tests/libexec/rtld-elf/.debug OLD_FILES+=usr/tests/libexec/rtld-elf/.debug/ld_library_pathfds.debug OLD_FILES+=usr/tests/libexec/rtld-elf/.debug/libpythagoras.so.0.debug OLD_FILES+=usr/tests/libexec/rtld-elf/.debug/target.debug OLD_DIRS+=usr/tests/sbin/devd/.debug OLD_FILES+=usr/tests/sbin/devd/.debug/client_test.debug OLD_DIRS+=usr/tests/sbin/dhclient/.debug OLD_FILES+=usr/tests/sbin/dhclient/.debug/option-domain-search_test.debug OLD_DIRS+=usr/tests/share/examples/tests/atf/.debug OLD_FILES+=usr/tests/share/examples/tests/atf/.debug/printf_test.debug OLD_DIRS+=usr/tests/share/examples/tests/plain/.debug OLD_FILES+=usr/tests/share/examples/tests/plain/.debug/printf_test.debug OLD_DIRS+=usr/tests/sys/aio/.debug OLD_FILES+=usr/tests/sys/aio/.debug/aio_kqueue_test.debug OLD_FILES+=usr/tests/sys/aio/.debug/aio_test.debug OLD_FILES+=usr/tests/sys/aio/.debug/lio_kqueue_test.debug OLD_DIRS+=usr/tests/sys/fifo/.debug OLD_FILES+=usr/tests/sys/fifo/.debug/fifo_create.debug OLD_FILES+=usr/tests/sys/fifo/.debug/fifo_io.debug OLD_FILES+=usr/tests/sys/fifo/.debug/fifo_misc.debug OLD_FILES+=usr/tests/sys/fifo/.debug/fifo_open.debug OLD_DIRS+=usr/tests/sys/file/.debug OLD_FILES+=usr/tests/sys/file/.debug/closefrom_test.debug OLD_FILES+=usr/tests/sys/file/.debug/dup_test.debug OLD_FILES+=usr/tests/sys/file/.debug/fcntlflags_test.debug OLD_FILES+=usr/tests/sys/file/.debug/flock_helper.debug OLD_FILES+=usr/tests/sys/file/.debug/ftruncate_test.debug OLD_FILES+=usr/tests/sys/file/.debug/newfileops_on_fork_test.debug OLD_DIRS+=usr/tests/sys/kern/.debug OLD_FILES+=usr/tests/sys/kern/.debug/kern_descrip_test.debug OLD_FILES+=usr/tests/sys/kern/.debug/ptrace_test.debug OLD_FILES+=usr/tests/sys/kern/.debug/unix_seqpacket_test.debug OLD_DIRS+=usr/tests/sys/kern/execve/.debug OLD_FILES+=usr/tests/sys/kern/execve/.debug/execve_helper.debug OLD_FILES+=usr/tests/sys/kern/execve/.debug/good_aout.debug OLD_DIRS+=usr/tests/sys/kqueue/.debug OLD_FILES+=usr/tests/sys/kqueue/.debug/kqtest.debug OLD_DIRS+=usr/tests/sys/mqueue/.debug OLD_FILES+=usr/tests/sys/mqueue/.debug/mqtest1.debug OLD_FILES+=usr/tests/sys/mqueue/.debug/mqtest2.debug OLD_FILES+=usr/tests/sys/mqueue/.debug/mqtest3.debug OLD_FILES+=usr/tests/sys/mqueue/.debug/mqtest4.debug OLD_FILES+=usr/tests/sys/mqueue/.debug/mqtest5.debug OLD_DIRS+=usr/tests/sys/netinet/.debug OLD_FILES+=usr/tests/sys/netinet/.debug/udp_dontroute.debug OLD_DIRS+=usr/tests/sys/pjdfstest/.debug OLD_FILES+=usr/tests/sys/pjdfstest/.debug/pjdfstest.debug OLD_DIRS+=usr/tests/sys/vm/.debug OLD_FILES+=usr/tests/sys/vm/.debug/mmap_test.debug # 20151015: Rename files due to file-installed-as-dir bug OLD_FILES+=usr/share/doc/legal/realtek OLD_FILES+=usr/share/doc/legal/realtek/LICENSE OLD_DIRS+=usr/share/doc/legal/realtek OLD_DIRS+=usr/share/doc/legal/intel_ipw OLD_FILES+=usr/share/doc/legal/intel_ipw/LICENSE OLD_FILES+=usr/share/doc/legal/intel_iwn OLD_FILES+=usr/share/doc/legal/intel_iwn/LICENSE OLD_DIRS+=usr/share/doc/legal/intel_iwn OLD_DIRS+=usr/share/doc/legal/intel_iwi OLD_FILES+=usr/share/doc/legal/intel_iwi/LICENSE OLD_DIRS+=usr/share/doc/legal/intel_wpi OLD_FILES+=usr/share/doc/legal/intel_wpi/LICENSE # 20151006: new libc++ import OLD_FILES+=usr/include/c++/__tuple_03 OLD_FILES+=usr/include/c++/v1/__tuple_03 OLD_FILES+=usr/include/c++/v1/tr1/__tuple_03 # 20151006: new clang import which bumps version from 3.6.1 to 3.7.0 OLD_FILES+=usr/lib/clang/3.6.1/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/3.6.1/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/3.6.1/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/3.6.1/include/adxintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/altivec.h OLD_FILES+=usr/lib/clang/3.6.1/include/ammintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/arm_acle.h OLD_FILES+=usr/lib/clang/3.6.1/include/arm_neon.h OLD_FILES+=usr/lib/clang/3.6.1/include/avx2intrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/avxintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/bmiintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/cpuid.h OLD_FILES+=usr/lib/clang/3.6.1/include/emmintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/f16cintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/fma4intrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/fmaintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/ia32intrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/immintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/mm3dnow.h OLD_FILES+=usr/lib/clang/3.6.1/include/mm_malloc.h OLD_FILES+=usr/lib/clang/3.6.1/include/mmintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/module.modulemap OLD_FILES+=usr/lib/clang/3.6.1/include/nmmintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/pmmintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/popcntintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/rtmintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/shaintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/smmintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/tbmintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/tmmintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/wmmintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/x86intrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/xmmintrin.h OLD_FILES+=usr/lib/clang/3.6.1/include/xopintrin.h OLD_DIRS+=usr/lib/clang/3.6.1/include OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.san-i386.a OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.san-x86_64.a OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.ubsan-i386.a OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.ubsan-x86_64.a OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.ubsan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.6.1/lib/freebsd/libclang_rt.ubsan_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/3.6.1/lib/freebsd OLD_DIRS+=usr/lib/clang/3.6.1/lib OLD_DIRS+=usr/lib/clang/3.6.1 # 20150928: unused sgsmsg utility is removed OLD_FILES+=usr/bin/sgsmsg # 20150926: remove links to removed/unimplemented mbuf(9) macros OLD_FILES+=usr/share/man/man9/MEXT_ADD_REF.9.gz OLD_FILES+=usr/share/man/man9/MEXTFREE.9.gz OLD_FILES+=usr/share/man/man9/MEXT_IS_REF.9.gz OLD_FILES+=usr/share/man/man9/MEXT_REM_REF.9.gz OLD_FILES+=usr/share/man/man9/MFREE.9.gz # 20150818: *allocm() are gone in jemalloc 4.0.0 OLD_FILES+=usr/share/man/man3/allocm.3.gz OLD_FILES+=usr/share/man/man3/dallocm.3.gz OLD_FILES+=usr/share/man/man3/nallocm.3.gz OLD_FILES+=usr/share/man/man3/rallocm.3.gz OLD_FILES+=usr/share/man/man3/sallocm.3.gz # 20150802: Remove netbsd's test on pw(8) OLD_FILES+=usr/tests/usr.sbin/pw/pw_test # 20150719: Remove libarchive.pc OLD_FILES+=usr/libdata/pkgconfig/libarchive.pc # 20150705: Rename DTrace provider man pages OLD_FILES+=usr/share/man/man4/dtrace-io.4.gz OLD_FILES+=usr/share/man/man4/dtrace-ip.4.gz OLD_FILES+=usr/share/man/man4/dtrace-proc.4.gz OLD_FILES+=usr/share/man/man4/dtrace-sched.4.gz OLD_FILES+=usr/share/man/man4/dtrace-tcp.4.gz OLD_FILES+=usr/share/man/man4/dtrace-udp.4.gz # 20150704: nvlist private headers no longer installed OLD_FILES+=usr/include/sys/nv_impl.h OLD_FILES+=usr/include/sys/nvlist_impl.h OLD_FILES+=usr/include/sys/nvpair_impl.h # 20150624 OLD_LIBS+=usr/lib/libugidfw.so.4 # 20150604: Move nvlist man pages to section 9 OLD_FILES+=usr/share/man/man3/libnv.3.gz OLD_FILES+=usr/share/man/man3/nv.3.gz OLD_FILES+=usr/share/man/man3/nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_add_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_add_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_add_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_add_null.3.gz OLD_FILES+=usr/share/man/man3/nvlist_add_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_add_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_add_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_add_stringf.3.gz OLD_FILES+=usr/share/man/man3/nvlist_add_stringv.3.gz OLD_FILES+=usr/share/man/man3/nvlist_clone.3.gz OLD_FILES+=usr/share/man/man3/nvlist_create.3.gz OLD_FILES+=usr/share/man/man3/nvlist_destroy.3.gz OLD_FILES+=usr/share/man/man3/nvlist_dump.3.gz OLD_FILES+=usr/share/man/man3/nvlist_empty.3.gz OLD_FILES+=usr/share/man/man3/nvlist_error.3.gz OLD_FILES+=usr/share/man/man3/nvlist_exists.3.gz OLD_FILES+=usr/share/man/man3/nvlist_exists_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_exists_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_exists_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_exists_null.3.gz OLD_FILES+=usr/share/man/man3/nvlist_exists_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_exists_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_exists_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_exists_type.3.gz OLD_FILES+=usr/share/man/man3/nvlist_fdump.3.gz OLD_FILES+=usr/share/man/man3/nvlist_flags.3.gz OLD_FILES+=usr/share/man/man3/nvlist_free.3.gz OLD_FILES+=usr/share/man/man3/nvlist_free_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_free_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_free_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_free_null.3.gz OLD_FILES+=usr/share/man/man3/nvlist_free_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_free_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_free_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_free_type.3.gz OLD_FILES+=usr/share/man/man3/nvlist_get_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_get_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_get_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_get_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_get_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_get_parent.3.gz OLD_FILES+=usr/share/man/man3/nvlist_get_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_move_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_move_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_move_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_move_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_next.3.gz OLD_FILES+=usr/share/man/man3/nvlist_pack.3.gz OLD_FILES+=usr/share/man/man3/nvlist_recv.3.gz OLD_FILES+=usr/share/man/man3/nvlist_send.3.gz OLD_FILES+=usr/share/man/man3/nvlist_set_error.3.gz OLD_FILES+=usr/share/man/man3/nvlist_size.3.gz OLD_FILES+=usr/share/man/man3/nvlist_take_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_take_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_take_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_take_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_take_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_take_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_unpack.3.gz OLD_FILES+=usr/share/man/man3/nvlist_xfer.3.gz # 20150702: Remove duplicated nvlist includes OLD_FILES+=usr/include/dnv.h OLD_FILES+=usr/include/nv.h # 20150528: PCI IOV device driver methods moved to a separate kobj interface OLD_FILES+=usr/share/man/man9/PCI_ADD_VF.9.gz OLD_FILES+=usr/share/man/man9/PCI_INIT_IOV.9.gz OLD_FILES+=usr/share/man/man9/PCI_UNINIT_IOV.9.gz # 20150525: new clang import which bumps version from 3.6.0 to 3.6.1 OLD_FILES+=usr/lib/clang/3.6.0/include/__stddef_max_align_t.h OLD_FILES+=usr/lib/clang/3.6.0/include/__wmmintrin_aes.h OLD_FILES+=usr/lib/clang/3.6.0/include/__wmmintrin_pclmul.h OLD_FILES+=usr/lib/clang/3.6.0/include/adxintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/altivec.h OLD_FILES+=usr/lib/clang/3.6.0/include/ammintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/arm_acle.h OLD_FILES+=usr/lib/clang/3.6.0/include/arm_neon.h OLD_FILES+=usr/lib/clang/3.6.0/include/avx2intrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/avx512bwintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/avx512erintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/avx512fintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/avx512vlbwintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/avx512vlintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/avxintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/bmi2intrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/bmiintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/cpuid.h OLD_FILES+=usr/lib/clang/3.6.0/include/emmintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/f16cintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/fma4intrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/fmaintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/ia32intrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/immintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/lzcntintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/mm3dnow.h OLD_FILES+=usr/lib/clang/3.6.0/include/mm_malloc.h OLD_FILES+=usr/lib/clang/3.6.0/include/mmintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/module.modulemap OLD_FILES+=usr/lib/clang/3.6.0/include/nmmintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/pmmintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/popcntintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/prfchwintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/rdseedintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/rtmintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/shaintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/smmintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/tbmintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/tmmintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/wmmintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/x86intrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/xmmintrin.h OLD_FILES+=usr/lib/clang/3.6.0/include/xopintrin.h OLD_DIRS+=usr/lib/clang/3.6.0/include OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.san-i386.a OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.san-x86_64.a OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.ubsan-i386.a OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.ubsan-x86_64.a OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.ubsan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.6.0/lib/freebsd/libclang_rt.ubsan_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/3.6.0/lib/freebsd OLD_DIRS+=usr/lib/clang/3.6.0/lib OLD_DIRS+=usr/lib/clang/3.6.0 # 20150521 OLD_FILES+=usr/bin/demandoc OLD_FILES+=usr/share/man/man1/demandoc.1.gz OLD_FILES+=usr/share/man/man3/mandoc.3.gz OLD_FILES+=usr/share/man/man3/mandoc_headers.3.gz # 20150520 OLD_FILES+=usr/lib/libheimsqlite.a OLD_FILES+=usr/lib/libheimsqlite.so OLD_LIBS+=usr/lib/libheimsqlite.so.11 OLD_FILES+=usr/lib/libheimsqlite_p.a # 20150506 OLD_FILES+=usr/share/man/man9/NDHASGIANT.9.gz # 20150504 OLD_FILES+=usr/share/examples/etc/libmap32.conf OLD_FILES+=usr/include/bsdstat.h OLD_DIRS+=usr/lib32/private OLD_LIBS+=usr/lib/private/libatf-c++.so.2 OLD_LIBS+=usr/lib/private/libbsdstat.so.1 OLD_LIBS+=usr/lib/private/libheimipcs.so.11 OLD_LIBS+=usr/lib/private/libsqlite3.so.0 OLD_LIBS+=usr/lib/private/libunbound.so.5 OLD_LIBS+=usr/lib/private/libatf-c.so.1 OLD_LIBS+=usr/lib/private/libheimipcc.so.11 OLD_LIBS+=usr/lib/private/libldns.so.5 OLD_LIBS+=usr/lib/private/libssh.so.5 OLD_LIBS+=usr/lib/private/libucl.so.1 OLD_DIRS+=usr/lib/private # 20150501 OLD_FILES+=usr/bin/soeliminate OLD_FILES+=usr/share/man/man1/soeliminate.1.gz # 20150501: Remove the nvlist_.*[vf] functions manpages OLD_FILES+=usr/share/man/man3/nvlist_addf_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addf_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addf_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addf_null.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addf_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addf_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addf_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addv_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addv_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addv_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addv_null.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addv_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addv_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_addv_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsf.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsf_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsf_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsf_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsf_null.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsf_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsf_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsf_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsf_type.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsv.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsv_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsv_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsv_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsv_null.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsv_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsv_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsv_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_existsv_type.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freef.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freef_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freef_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freef_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freef_null.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freef_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freef_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freef_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freef_type.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freev.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freev_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freev_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freev_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freev_null.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freev_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freev_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freev_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_freev_type.3.gz OLD_FILES+=usr/share/man/man3/nvlist_getf_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_getf_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_getf_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_getf_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_getf_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_getf_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_getv_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_getv_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_getv_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_getv_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_getv_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_getv_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_movef_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_movef_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_movef_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_movef_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_movev_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_movev_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_movev_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_movev_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_takef_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_takef_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_takef_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_takef_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_takef_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_takef_string.3.gz OLD_FILES+=usr/share/man/man3/nvlist_takev_binary.3.gz OLD_FILES+=usr/share/man/man3/nvlist_takev_bool.3.gz OLD_FILES+=usr/share/man/man3/nvlist_takev_descriptor.3.gz OLD_FILES+=usr/share/man/man3/nvlist_takev_number.3.gz OLD_FILES+=usr/share/man/man3/nvlist_takev_nvlist.3.gz OLD_FILES+=usr/share/man/man3/nvlist_takev_string.3.gz # 20150429: remove never written documentation OLD_FILES+=usr/share/doc/papers/hwpmc.ascii.gz # 20150427: test/sys/kern/mmap_test moved to test/sys/vm/mmap_test OLD_FILES+=usr/tests/sys/kern/mmap_test # 20150422: zlib.c moved from net to libkern OLD_FILES+=usr/include/net/zlib.h OLD_FILES+=usr/include/net/zutil.h # 20150418 OLD_FILES+=sbin/mount_oldnfs OLD_FILES+=usr/share/man/man8/mount_oldnfs.8.gz # 20150416: ALTQ moved to net/altq OLD_FILES+=usr/include/altq/altq_rmclass_debug.h OLD_FILES+=usr/include/altq/altq.h OLD_FILES+=usr/include/altq/altq_cdnr.h OLD_FILES+=usr/include/altq/altq_hfsc.h OLD_FILES+=usr/include/altq/altq_priq.h OLD_FILES+=usr/include/altq/altqconf.h OLD_FILES+=usr/include/altq/altq_classq.h OLD_FILES+=usr/include/altq/altq_red.h OLD_FILES+=usr/include/altq/if_altq.h OLD_FILES+=usr/include/altq/altq_var.h OLD_FILES+=usr/include/altq/altq_rmclass.h OLD_FILES+=usr/include/altq/altq_cbq.h OLD_FILES+=usr/include/altq/altq_rio.h OLD_DIRS+=usr/include/altq # 20150330: ntp 4.2.8p1 OLD_FILES+=usr/share/doc/ntp/driver1.html OLD_FILES+=usr/share/doc/ntp/driver10.html OLD_FILES+=usr/share/doc/ntp/driver11.html OLD_FILES+=usr/share/doc/ntp/driver12.html OLD_FILES+=usr/share/doc/ntp/driver16.html OLD_FILES+=usr/share/doc/ntp/driver18.html OLD_FILES+=usr/share/doc/ntp/driver19.html OLD_FILES+=usr/share/doc/ntp/driver2.html OLD_FILES+=usr/share/doc/ntp/driver20.html OLD_FILES+=usr/share/doc/ntp/driver22.html OLD_FILES+=usr/share/doc/ntp/driver26.html OLD_FILES+=usr/share/doc/ntp/driver27.html OLD_FILES+=usr/share/doc/ntp/driver28.html OLD_FILES+=usr/share/doc/ntp/driver29.html OLD_FILES+=usr/share/doc/ntp/driver3.html OLD_FILES+=usr/share/doc/ntp/driver30.html OLD_FILES+=usr/share/doc/ntp/driver32.html OLD_FILES+=usr/share/doc/ntp/driver33.html OLD_FILES+=usr/share/doc/ntp/driver34.html OLD_FILES+=usr/share/doc/ntp/driver35.html OLD_FILES+=usr/share/doc/ntp/driver36.html OLD_FILES+=usr/share/doc/ntp/driver37.html OLD_FILES+=usr/share/doc/ntp/driver4.html OLD_FILES+=usr/share/doc/ntp/driver5.html OLD_FILES+=usr/share/doc/ntp/driver6.html OLD_FILES+=usr/share/doc/ntp/driver7.html OLD_FILES+=usr/share/doc/ntp/driver8.html OLD_FILES+=usr/share/doc/ntp/driver9.html OLD_FILES+=usr/share/doc/ntp/ldisc.html OLD_FILES+=usr/share/doc/ntp/measure.html OLD_FILES+=usr/share/doc/ntp/mx4200data.html OLD_FILES+=usr/share/doc/ntp/notes.html OLD_FILES+=usr/share/doc/ntp/patches.html OLD_FILES+=usr/share/doc/ntp/porting.html OLD_FILES+=usr/share/man/man1/sntp.1.gz # 20150329 .if ${TARGET_ARCH} == "arm" OLD_FILES+=usr/include/bootconfig.h .endif # 20150326 OLD_FILES+=usr/share/man/man1/pmcstudy.1.gz # 20150315: new clang import which bumps version from 3.5.1 to 3.6.0 OLD_FILES+=usr/include/clang/3.5.1/__wmmintrin_aes.h OLD_FILES+=usr/include/clang/3.5.1/__wmmintrin_pclmul.h OLD_FILES+=usr/include/clang/3.5.1/altivec.h OLD_FILES+=usr/include/clang/3.5.1/ammintrin.h OLD_FILES+=usr/include/clang/3.5.1/arm_acle.h OLD_FILES+=usr/include/clang/3.5.1/arm_neon.h OLD_FILES+=usr/include/clang/3.5.1/avx2intrin.h OLD_FILES+=usr/include/clang/3.5.1/avxintrin.h OLD_FILES+=usr/include/clang/3.5.1/bmi2intrin.h OLD_FILES+=usr/include/clang/3.5.1/bmiintrin.h OLD_FILES+=usr/include/clang/3.5.1/cpuid.h OLD_FILES+=usr/include/clang/3.5.1/emmintrin.h OLD_FILES+=usr/include/clang/3.5.1/f16cintrin.h OLD_FILES+=usr/include/clang/3.5.1/fma4intrin.h OLD_FILES+=usr/include/clang/3.5.1/fmaintrin.h OLD_FILES+=usr/include/clang/3.5.1/ia32intrin.h OLD_FILES+=usr/include/clang/3.5.1/immintrin.h OLD_FILES+=usr/include/clang/3.5.1/lzcntintrin.h OLD_FILES+=usr/include/clang/3.5.1/mm3dnow.h OLD_FILES+=usr/include/clang/3.5.1/mm_malloc.h OLD_FILES+=usr/include/clang/3.5.1/mmintrin.h OLD_FILES+=usr/include/clang/3.5.1/module.modulemap OLD_FILES+=usr/include/clang/3.5.1/nmmintrin.h OLD_FILES+=usr/include/clang/3.5.1/pmmintrin.h OLD_FILES+=usr/include/clang/3.5.1/popcntintrin.h OLD_FILES+=usr/include/clang/3.5.1/prfchwintrin.h OLD_FILES+=usr/include/clang/3.5.1/rdseedintrin.h OLD_FILES+=usr/include/clang/3.5.1/rtmintrin.h OLD_FILES+=usr/include/clang/3.5.1/shaintrin.h OLD_FILES+=usr/include/clang/3.5.1/smmintrin.h OLD_FILES+=usr/include/clang/3.5.1/tbmintrin.h OLD_FILES+=usr/include/clang/3.5.1/tmmintrin.h OLD_FILES+=usr/include/clang/3.5.1/wmmintrin.h OLD_FILES+=usr/include/clang/3.5.1/x86intrin.h OLD_FILES+=usr/include/clang/3.5.1/xmmintrin.h OLD_FILES+=usr/include/clang/3.5.1/xopintrin.h OLD_DIRS+=usr/include/clang/3.5.1 OLD_DIRS+=usr/include/clang OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.san-i386.a OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.san-x86_64.a OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.ubsan-i386.a OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.ubsan-x86_64.a OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.ubsan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.5.1/lib/freebsd/libclang_rt.ubsan_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/3.5.1/lib/freebsd OLD_DIRS+=usr/lib/clang/3.5.1/lib OLD_DIRS+=usr/lib/clang/3.5.1 # 20150302: binutils documentation distributed as a manpage OLD_FILES+=usr/share/doc/binutils/as.txt OLD_FILES+=usr/share/doc/binutils/ld.txt OLD_DIRS+=usr/share/doc/binutils # 20150222: Removed bcd(6) and ppt(6) OLD_FILES+=usr/bin/bcd OLD_FILES+=usr/bin/ppt OLD_FILES+=usr/share/man/man6/bcd.6.gz OLD_FILES+=usr/share/man/man6/ppt.6.gz # 20150217: Removed remnants of ar(4) driver OLD_FILES+=usr/include/dev/ic/hd64570.h # 20150212: /usr/games moving into /usr/bin OLD_FILES+=usr/games/bcd OLD_FILES+=usr/games/caesar OLD_FILES+=usr/games/factor OLD_FILES+=usr/games/fortune OLD_FILES+=usr/games/grdc OLD_FILES+=usr/games/morse OLD_FILES+=usr/games/number OLD_FILES+=usr/games/pom OLD_FILES+=usr/games/ppt OLD_FILES+=usr/games/primes OLD_FILES+=usr/games/random OLD_FILES+=usr/games/rot13 OLD_FILES+=usr/games/strfile OLD_FILES+=usr/games/unstr OLD_DIRS+=usr/games # 20150209: liblzma header OLD_FILES+=usr/include/lzma/lzma.h # 20150124: spl.9 and friends OLD_FILES+=usr/share/man/man9/spl.9.gz OLD_FILES+=usr/share/man/man9/spl0.9.gz OLD_FILES+=usr/share/man/man9/splbio.9.gz OLD_FILES+=usr/share/man/man9/splclock.9.gz OLD_FILES+=usr/share/man/man9/splhigh.9.gz OLD_FILES+=usr/share/man/man9/splimp.9.gz OLD_FILES+=usr/share/man/man9/splnet.9.gz OLD_FILES+=usr/share/man/man9/splsoftclock.9.gz OLD_FILES+=usr/share/man/man9/splsofttty.9.gz OLD_FILES+=usr/share/man/man9/splstatclock.9.gz OLD_FILES+=usr/share/man/man9/spltty.9.gz OLD_FILES+=usr/share/man/man9/splvm.9.gz OLD_FILES+=usr/share/man/man9/splx.9.gz # 20150118: toeplitz.c moved from netinet to net OLD_FILES+=usr/include/netinet/toeplitz.h # 20150118: new clang import which bumps version from 3.5.0 to 3.5.1 OLD_FILES+=usr/include/clang/3.5.0/__wmmintrin_aes.h OLD_FILES+=usr/include/clang/3.5.0/__wmmintrin_pclmul.h OLD_FILES+=usr/include/clang/3.5.0/altivec.h OLD_FILES+=usr/include/clang/3.5.0/ammintrin.h OLD_FILES+=usr/include/clang/3.5.0/arm_acle.h OLD_FILES+=usr/include/clang/3.5.0/arm_neon.h OLD_FILES+=usr/include/clang/3.5.0/avx2intrin.h OLD_FILES+=usr/include/clang/3.5.0/avxintrin.h OLD_FILES+=usr/include/clang/3.5.0/bmi2intrin.h OLD_FILES+=usr/include/clang/3.5.0/bmiintrin.h OLD_FILES+=usr/include/clang/3.5.0/cpuid.h OLD_FILES+=usr/include/clang/3.5.0/emmintrin.h OLD_FILES+=usr/include/clang/3.5.0/f16cintrin.h OLD_FILES+=usr/include/clang/3.5.0/fma4intrin.h OLD_FILES+=usr/include/clang/3.5.0/fmaintrin.h OLD_FILES+=usr/include/clang/3.5.0/ia32intrin.h OLD_FILES+=usr/include/clang/3.5.0/immintrin.h OLD_FILES+=usr/include/clang/3.5.0/lzcntintrin.h OLD_FILES+=usr/include/clang/3.5.0/mm3dnow.h OLD_FILES+=usr/include/clang/3.5.0/mm_malloc.h OLD_FILES+=usr/include/clang/3.5.0/mmintrin.h OLD_FILES+=usr/include/clang/3.5.0/module.modulemap OLD_FILES+=usr/include/clang/3.5.0/nmmintrin.h OLD_FILES+=usr/include/clang/3.5.0/pmmintrin.h OLD_FILES+=usr/include/clang/3.5.0/popcntintrin.h OLD_FILES+=usr/include/clang/3.5.0/prfchwintrin.h OLD_FILES+=usr/include/clang/3.5.0/rdseedintrin.h OLD_FILES+=usr/include/clang/3.5.0/rtmintrin.h OLD_FILES+=usr/include/clang/3.5.0/shaintrin.h OLD_FILES+=usr/include/clang/3.5.0/smmintrin.h OLD_FILES+=usr/include/clang/3.5.0/tbmintrin.h OLD_FILES+=usr/include/clang/3.5.0/tmmintrin.h OLD_FILES+=usr/include/clang/3.5.0/wmmintrin.h OLD_FILES+=usr/include/clang/3.5.0/x86intrin.h OLD_FILES+=usr/include/clang/3.5.0/xmmintrin.h OLD_FILES+=usr/include/clang/3.5.0/xopintrin.h OLD_DIRS+=usr/include/clang/3.5.0 OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.asan-i386.a OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.asan-x86_64.a OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.asan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.asan_cxx-x86_64.a OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.profile-arm.a OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.profile-i386.a OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.profile-x86_64.a OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.san-i386.a OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.san-x86_64.a OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.ubsan-i386.a OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.ubsan-x86_64.a OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.ubsan_cxx-i386.a OLD_FILES+=usr/lib/clang/3.5.0/lib/freebsd/libclang_rt.ubsan_cxx-x86_64.a OLD_DIRS+=usr/lib/clang/3.5.0/lib/freebsd OLD_DIRS+=usr/lib/clang/3.5.0/lib OLD_DIRS+=usr/lib/clang/3.5.0 # 20150102: removal of asr(4) OLD_FILES+=usr/share/man/man4/asr.4.gz # 20150102: removal of texinfo OLD_FILES+=usr/bin/info OLD_FILES+=usr/bin/infokey OLD_FILES+=usr/bin/install-info OLD_FILES+=usr/bin/makeinfo OLD_FILES+=usr/bin/texindex OLD_FILES+=usr/share/info/am-utils.info.gz OLD_FILES+=usr/share/info/as.info.gz OLD_FILES+=usr/share/info/binutils.info.gz OLD_FILES+=usr/share/info/com_err.info.gz OLD_FILES+=usr/share/info/cpp.info.gz OLD_FILES+=usr/share/info/cppinternals.info.gz OLD_FILES+=usr/share/info/diff.info.gz OLD_FILES+=usr/share/info/dir OLD_FILES+=usr/share/info/gcc.info.gz OLD_FILES+=usr/share/info/gccint.info.gz OLD_FILES+=usr/share/info/gdb.info.gz OLD_FILES+=usr/share/info/gdbint.info.gz OLD_FILES+=usr/share/info/gperf.info.gz OLD_FILES+=usr/share/info/grep.info.gz OLD_FILES+=usr/share/info/groff.info.gz OLD_FILES+=usr/share/info/heimdal.info.gz OLD_FILES+=usr/share/info/history.info.gz OLD_FILES+=usr/share/info/info-stnd.info.gz OLD_FILES+=usr/share/info/info.info.gz OLD_FILES+=usr/share/info/ld.info.gz OLD_FILES+=usr/share/info/regex.info.gz OLD_FILES+=usr/share/info/rluserman.info.gz OLD_FILES+=usr/share/info/stabs.info.gz OLD_FILES+=usr/share/info/texinfo.info.gz OLD_FILES+=usr/share/man/man1/info.1.gz OLD_FILES+=usr/share/man/man1/infokey.1.gz OLD_FILES+=usr/share/man/man1/install-info.1.gz OLD_FILES+=usr/share/man/man1/makeinfo.1.gz OLD_FILES+=usr/share/man/man1/texindex.1.gz OLD_FILES+=usr/share/man/man5/info.5.gz OLD_FILES+=usr/share/man/man5/texinfo.5.gz OLD_DIRS+=usr/share/info # 20141231: new clang import which bumps version from 3.4.1 to 3.5.0 OLD_FILES+=usr/include/clang/3.4.1/__wmmintrin_aes.h OLD_FILES+=usr/include/clang/3.4.1/__wmmintrin_pclmul.h OLD_FILES+=usr/include/clang/3.4.1/altivec.h OLD_FILES+=usr/include/clang/3.4.1/ammintrin.h OLD_FILES+=usr/include/clang/3.4.1/arm_neon.h OLD_FILES+=usr/include/clang/3.4.1/avx2intrin.h OLD_FILES+=usr/include/clang/3.4.1/avxintrin.h OLD_FILES+=usr/include/clang/3.4.1/bmi2intrin.h OLD_FILES+=usr/include/clang/3.4.1/bmiintrin.h OLD_FILES+=usr/include/clang/3.4.1/cpuid.h OLD_FILES+=usr/include/clang/3.4.1/emmintrin.h OLD_FILES+=usr/include/clang/3.4.1/f16cintrin.h OLD_FILES+=usr/include/clang/3.4.1/fma4intrin.h OLD_FILES+=usr/include/clang/3.4.1/fmaintrin.h OLD_FILES+=usr/include/clang/3.4.1/immintrin.h OLD_FILES+=usr/include/clang/3.4.1/lzcntintrin.h OLD_FILES+=usr/include/clang/3.4.1/mm3dnow.h OLD_FILES+=usr/include/clang/3.4.1/mm_malloc.h OLD_FILES+=usr/include/clang/3.4.1/mmintrin.h OLD_FILES+=usr/include/clang/3.4.1/module.map OLD_FILES+=usr/include/clang/3.4.1/nmmintrin.h OLD_FILES+=usr/include/clang/3.4.1/pmmintrin.h OLD_FILES+=usr/include/clang/3.4.1/popcntintrin.h OLD_FILES+=usr/include/clang/3.4.1/prfchwintrin.h OLD_FILES+=usr/include/clang/3.4.1/rdseedintrin.h OLD_FILES+=usr/include/clang/3.4.1/rtmintrin.h OLD_FILES+=usr/include/clang/3.4.1/shaintrin.h OLD_FILES+=usr/include/clang/3.4.1/smmintrin.h OLD_FILES+=usr/include/clang/3.4.1/tbmintrin.h OLD_FILES+=usr/include/clang/3.4.1/tmmintrin.h OLD_FILES+=usr/include/clang/3.4.1/wmmintrin.h OLD_FILES+=usr/include/clang/3.4.1/x86intrin.h OLD_FILES+=usr/include/clang/3.4.1/xmmintrin.h OLD_FILES+=usr/include/clang/3.4.1/xopintrin.h OLD_DIRS+=usr/include/clang/3.4.1 # 20141225: Remove gpib/ieee488 OLD_FILES+=usr/include/dev/ieee488/ibfoo_int.h OLD_FILES+=usr/include/dev/ieee488/tnt4882.h OLD_FILES+=usr/include/dev/ieee488/ugpib.h OLD_FILES+=usr/include/dev/ieee488/upd7210.h OLD_DIRS+=usr/include/dev/ieee488 OLD_FILES+=usr/include/gpib/gpib.h OLD_DIRS+=usr/include/gpib OLD_FILES+=usr/lib/libgpib.a OLD_FILES+=usr/lib/libgpib_p.a OLD_FILES+=usr/lib/libgpib.so OLD_LIBS+=usr/lib/libgpib.so.3 OLD_FILES+=usr/share/man/man3/gpib.3.gz OLD_FILES+=usr/share/man/man3/ibclr.3.gz OLD_FILES+=usr/share/man/man3/ibdev.3.gz OLD_FILES+=usr/share/man/man3/ibdma.3.gz OLD_FILES+=usr/share/man/man3/ibeos.3.gz OLD_FILES+=usr/share/man/man3/ibeot.3.gz OLD_FILES+=usr/share/man/man3/ibloc.3.gz OLD_FILES+=usr/share/man/man3/ibonl.3.gz OLD_FILES+=usr/share/man/man3/ibpad.3.gz OLD_FILES+=usr/share/man/man3/ibrd.3.gz OLD_FILES+=usr/share/man/man3/ibsad.3.gz OLD_FILES+=usr/share/man/man3/ibsic.3.gz OLD_FILES+=usr/share/man/man3/ibtmo.3.gz OLD_FILES+=usr/share/man/man3/ibtrg.3.gz OLD_FILES+=usr/share/man/man3/ibwrt.3.gz OLD_FILES+=usr/share/man/man4/gpib.4.gz OLD_FILES+=usr/share/man/man4/pcii.4.gz OLD_FILES+=usr/share/man/man4/tnt4882.4.gz # 20141224: libxo moved to /lib MOVED_LIBS+=usr/lib/libxo.so.0 # 20141223: remove in6_gif.h and in_gif.h OLD_FILES+=usr/include/netinet/in_gif.h OLD_FILES+=usr/include/netinet6/in6_gif.h # 20141209: pw tests broken into a file per command OLD_FILES+=usr/tests/usr.sbin/pw/pw_delete OLD_FILES+=usr/tests/usr.sbin/pw/pw_modify # 20141202: update to mandoc CVS 20141201 OLD_FILES+=usr.bin/preconv OLD_FILES+=usr/share/man/man1/preconv.1.gz # 20141129: mrouted rc.d scripts removed from base OLD_FILES+=etc/rc.d/mrouted # 20141126: convert sbin/mdconfig/tests to ATF format tests OLD_FILES+=usr/tests/sbin/mdconfig/legacy_test OLD_FILES+=usr/tests/sbin/mdconfig/mdconfig.test OLD_FILES+=usr/tests/sbin/mdconfig/run.pl # 20141126: remove xform_ipip decapsulation fallback OLD_FILES+=usr/include/netipsec/ipip_var.h # 20141122: mandoc updated to 1.13.1 OLD_FILES+=usr/share/mdocml/external.png # 20141111: SF_KQUEUE code removed OLD_FILES+=usr/include/sys/sf_base.h OLD_FILES+=usr/include/sys/sf_sync.h # 20141109: faith/faithd removal OLD_FILES+=etc/rc.d/faith OLD_FILES+=usr/share/man/man4/faith.4.gz OLD_FILES+=usr/share/man/man4/if_faith.4.gz OLD_FILES+=usr/sbin/faithd OLD_FILES+=usr/share/man/man8/faithd.8.gz # 20141107: overhaul if_gre(4) OLD_FILES+=usr/include/netinet/ip_gre.h # 20141102: postrandom obsoleted by new /dev/random code OLD_FILES+=etc/rc.d/postrandom # 20141031: initrandom obsoleted by new /dev/random code OLD_FILES+=etc/rc.d/initrandom # 20141030: atf 0.21 import OLD_FILES+=usr/share/man/man3/atf-c++-api.3.gz # 20141028: debug files accidentally installed as directory name OLD_FILES+=usr/lib/debug/usr/lib/i18n OLD_FILES+=usr/lib/debug/usr/lib/private OLD_FILES+=usr/lib/debug/usr/lib32/i18n OLD_FILES+=usr/lib/debug/usr/lib32/private # 20141015: OpenSSL 1.0.1j import OLD_FILES+=usr/share/openssl/man/man3/CMS_sign_add1_signer.3.gz # 20141003: libproc version bump OLD_LIBS+=usr/lib/libproc.so.2 # 20140922: sleepq_calc_signal_retval.9 and sleepq_catch_signals.9 removed OLD_FILES+=usr/share/man/man9/sleepq_calc_signal_retval.9.gz OLD_FILES+=usr/share/man/man9/sleepq_catch_signals.9.gz # 20140917: hv_kvpd rc.d script removed in favor of devd configuration OLD_FILES+=etc/rc.d/hv_kvpd # 20140917: libnv was accidentally being installed to /usr/lib instead of /lib MOVED_LIBS+=usr/lib/libnv.so.0 # 20140829: rc.d/kerberos removed OLD_FILES+=etc/rc.d/kerberos # 20140814: libopie version bump OLD_LIBS+=usr/lib/libopie.so.7 # 20140811: otp-sha renamed to otp-sha1 OLD_FILES+=usr/bin/otp-sha OLD_FILES+=usr/share/man/man1/otp-sha.1.gz # 20140807: Remove private lib files that should not be installed OLD_FILES+=usr/lib/private/libatf-c.a OLD_FILES+=usr/lib/private/libatf-c.so OLD_FILES+=usr/lib/private/libatf-c_p.a OLD_FILES+=usr/lib/private/libatf-c++.a OLD_FILES+=usr/lib/private/libatf-c++.so OLD_FILES+=usr/lib/private/libatf-c++_p.a OLD_FILES+=usr/lib/private/libbsdstat.a OLD_FILES+=usr/lib/private/libbsdstat.so OLD_FILES+=usr/lib/private/libbsdstat_p.a OLD_FILES+=usr/lib/private/libheimipcc.a OLD_FILES+=usr/lib/private/libheimipcc.so OLD_FILES+=usr/lib/private/libheimipcc_p.a OLD_FILES+=usr/lib/private/libheimipcs.a OLD_FILES+=usr/lib/private/libheimipcs.so OLD_FILES+=usr/lib/private/libheimipcs_p.a OLD_FILES+=usr/lib/private/libldns.a OLD_FILES+=usr/lib/private/libldns.so OLD_FILES+=usr/lib/private/libldns_p.a OLD_FILES+=usr/lib/private/libssh.a OLD_FILES+=usr/lib/private/libssh.so OLD_FILES+=usr/lib/private/libssh_p.a OLD_FILES+=usr/lib/private/libunbound.a OLD_FILES+=usr/lib/private/libunbound.so OLD_FILES+=usr/lib/private/libunbound_p.a OLD_FILES+=usr/lib/private/libucl.a OLD_FILES+=usr/lib/private/libucl.so OLD_FILES+=usr/lib/private/libucl_p.a # 20140803: Remove an obsolete man page OLD_FILES+=usr/share/man/man9/pmap_change_wiring.9.gz # 20140731 OLD_FILES+=usr/share/man/man9/SYSCTL_ADD_OID.9.gz # 20140728: libsbuf restored to old version OLD_LIBS+=lib/libsbuf.so.7 # 20140728: Remove an obsolete man page OLD_FILES+=usr/share/man/man9/VOP_GETVOBJECT.9.gz OLD_FILES+=usr/share/man/man9/VOP_CREATEVOBJECT.9.gz OLD_FILES+=usr/share/man/man9/VOP_DESTROYVOBJECT.9.gz # 20140723: renamed to PCBGROUP.9 OLD_FILES+=usr/share/man/man9/PCBGROUPS.9.gz # 20140722: browse_packages_ftp.sh removed OLD_FILES+=usr/share/examples/bsdconfig/browse_packages_ftp.sh # 20140718: Remove obsolete man pages OLD_FILES+=usr/share/man/man9/zero_copy.9.gz OLD_FILES+=usr/share/man/man9/zero_copy_sockets.9.gz # 20140718: Remove an obsolete man page OLD_FILES+=usr/share/man/man9/pmap_page_protect.9.gz # 20140717: Remove an obsolete man page OLD_FILES+=usr/share/man/man9/pmap_clear_reference.9.gz # 20140716: Remove an incorrectly named man page OLD_FILES+=usr/share/man/man9/pmap_ts_modified.9.gz # 20140712: Removal of bsd.dtrace.mk OLD_FILES+=usr/share/mk/bsd.dtrace.mk # 20140705: turn libreadline into an internal lib OLD_LIBS+=lib/libreadline.so.8 OLD_FILES+=usr/lib/libreadline.a OLD_FILES+=usr/lib/libreadline_p.a OLD_FILES+=usr/lib/libreadline.so OLD_FILES+=usr/lib/libhistory.a OLD_FILES+=usr/lib/libhistory_p.a OLD_FILES+=usr/lib/libhistory.so OLD_LIBS+=usr/lib/libhistory.so.8 OLD_FILES+=usr/include/readline/chardefs.h OLD_FILES+=usr/include/readline/history.h OLD_FILES+=usr/include/readline/keymaps.h OLD_FILES+=usr/include/readline/readline.h OLD_FILES+=usr/include/readline/tilde.h OLD_FILES+=usr/include/readline/rlconf.h OLD_FILES+=usr/include/readline/rlstdc.h OLD_FILES+=usr/include/readline/rltypedefs.h OLD_FILES+=usr/include/readline/rltypedefs.h OLD_DIRS+=usr/include/readline OLD_FILES+=usr/share/info/readline.info.gz OLD_FILES+=usr/share/man/man3/readline.3.gz OLD_FILES+=usr/share/man/man3/rlhistory.3.gz # 20140625: csup removal OLD_FILES+=usr/bin/csup OLD_FILES+=usr/bin/cpasswd OLD_FILES+=usr/share/man/man1/csup.1.gz OLD_FILES+=usr/share/man/man1/cpasswd.1.gz OLD_FILES+=usr/share/examples/cvsup/README OLD_FILES+=usr/share/examples/cvsup/cvs-supfile OLD_FILES+=usr/share/examples/cvsup/stable-supfile OLD_FILES+=usr/share/examples/cvsup/standard-supfile OLD_DIRS+=usr/share/examples/cvsup # 20140614: send-pr removal OLD_FILES+=usr/bin/sendbug OLD_FILES+=usr/share/info/send-pr.info.gz OLD_FILES+=usr/share/man/man1/send-pr.1.gz OLD_FILES+=usr/share/man/man1/sendbug.1.gz OLD_FILES+=etc/gnats/freefall OLD_DIRS+=etc/gnats # 20140512: new clang import which bumps version from 3.4 to 3.4.1 OLD_FILES+=usr/include/clang/3.4/__wmmintrin_aes.h OLD_FILES+=usr/include/clang/3.4/__wmmintrin_pclmul.h OLD_FILES+=usr/include/clang/3.4/altivec.h OLD_FILES+=usr/include/clang/3.4/ammintrin.h OLD_FILES+=usr/include/clang/3.4/avx2intrin.h OLD_FILES+=usr/include/clang/3.4/avxintrin.h OLD_FILES+=usr/include/clang/3.4/bmi2intrin.h OLD_FILES+=usr/include/clang/3.4/bmiintrin.h OLD_FILES+=usr/include/clang/3.4/cpuid.h OLD_FILES+=usr/include/clang/3.4/emmintrin.h OLD_FILES+=usr/include/clang/3.4/f16cintrin.h OLD_FILES+=usr/include/clang/3.4/fma4intrin.h OLD_FILES+=usr/include/clang/3.4/fmaintrin.h OLD_FILES+=usr/include/clang/3.4/immintrin.h OLD_FILES+=usr/include/clang/3.4/lzcntintrin.h OLD_FILES+=usr/include/clang/3.4/mm3dnow.h OLD_FILES+=usr/include/clang/3.4/mm_malloc.h OLD_FILES+=usr/include/clang/3.4/mmintrin.h OLD_FILES+=usr/include/clang/3.4/module.map OLD_FILES+=usr/include/clang/3.4/nmmintrin.h OLD_FILES+=usr/include/clang/3.4/pmmintrin.h OLD_FILES+=usr/include/clang/3.4/popcntintrin.h OLD_FILES+=usr/include/clang/3.4/prfchwintrin.h OLD_FILES+=usr/include/clang/3.4/rdseedintrin.h OLD_FILES+=usr/include/clang/3.4/rtmintrin.h OLD_FILES+=usr/include/clang/3.4/shaintrin.h OLD_FILES+=usr/include/clang/3.4/smmintrin.h OLD_FILES+=usr/include/clang/3.4/tbmintrin.h OLD_FILES+=usr/include/clang/3.4/tmmintrin.h OLD_FILES+=usr/include/clang/3.4/wmmintrin.h OLD_FILES+=usr/include/clang/3.4/x86intrin.h OLD_FILES+=usr/include/clang/3.4/xmmintrin.h OLD_FILES+=usr/include/clang/3.4/xopintrin.h OLD_FILES+=usr/include/clang/3.4/arm_neon.h OLD_FILES+=usr/include/clang/3.4/module.map OLD_DIRS+=usr/include/clang/3.4 # 20140505: Bogusly installing src.opts.mk OLD_FILES+=usr/share/mk/src.opts.mk # 20140505: Reject PR kern/187551 OLD_FILES+=usr/tests/sbin/ifconfig/fibs_test # 20140502: Removal of lindev(4) OLD_FILES+=usr/share/man/man4/lindev.4.gz # 20140425 OLD_FILES+=usr/lib/libssp_p.a OLD_FILES+=usr/lib/libstand_p.a # 20140413: Removed NO_MANCOMPRESS from mount_fusefs OLD_FILES+=usr/share/man/man8/mount_fusefs.8 # 20140314: AppleTalk OLD_DIRS+=usr/include/netatalk OLD_FILES+=usr/include/netatalk/aarp.h OLD_FILES+=usr/include/netatalk/at.h OLD_FILES+=usr/include/netatalk/at_extern.h OLD_FILES+=usr/include/netatalk/at_var.h OLD_FILES+=usr/include/netatalk/ddp.h OLD_FILES+=usr/include/netatalk/ddp_pcb.h OLD_FILES+=usr/include/netatalk/ddp_var.h OLD_FILES+=usr/include/netatalk/endian.h OLD_FILES+=usr/include/netatalk/phase2.h # 20140314: Remove IPX/SPX OLD_LIBS+=lib/libipx.so.5 OLD_FILES+=usr/include/netipx/ipx.h OLD_FILES+=usr/include/netipx/ipx_if.h OLD_FILES+=usr/include/netipx/ipx_pcb.h OLD_FILES+=usr/include/netipx/ipx_var.h OLD_FILES+=usr/include/netipx/spx.h OLD_FILES+=usr/include/netipx/spx_debug.h OLD_FILES+=usr/include/netipx/spx_timer.h OLD_FILES+=usr/include/netipx/spx_var.h OLD_DIRS+=usr/include/netipx OLD_FILES+=usr/lib/libipx.a OLD_FILES+=usr/lib/libipx.so OLD_FILES+=usr/lib/libipx_p.a OLD_FILES+=usr/sbin/IPXrouted OLD_FILES+=usr/share/man/man3/ipx.3.gz OLD_FILES+=usr/share/man/man3/ipx_addr.3.gz OLD_FILES+=usr/share/man/man3/ipx_ntoa.3.gz OLD_FILES+=usr/share/man/man4/ef.4.gz OLD_FILES+=usr/share/man/man4/if_ef.4.gz OLD_FILES+=usr/share/man/man8/IPXrouted.8.gz # 20140314: bsdconfig usermgmt rewrite OLD_FILES+=usr/libexec/bsdconfig/070.usermgmt/userinput # 20140307: bsdconfig groupmgmt rewrite OLD_FILES+=usr/libexec/bsdconfig/070.usermgmt/groupinput # 20140223: Remove libyaml OLD_FILES+=usr/lib/private/libyaml.a OLD_FILES+=usr/lib/private/libyaml.so OLD_LIBS+=usr/lib/private/libyaml.so.1 OLD_FILES+=usr/lib/private/libyaml_p.a # 20140216: new clang import which bumps version from 3.3 to 3.4 OLD_FILES+=usr/bin/llvm-prof OLD_FILES+=usr/include/clang/3.3/__wmmintrin_aes.h OLD_FILES+=usr/include/clang/3.3/__wmmintrin_pclmul.h OLD_FILES+=usr/include/clang/3.3/altivec.h OLD_FILES+=usr/include/clang/3.3/ammintrin.h OLD_FILES+=usr/include/clang/3.3/avx2intrin.h OLD_FILES+=usr/include/clang/3.3/avxintrin.h OLD_FILES+=usr/include/clang/3.3/bmi2intrin.h OLD_FILES+=usr/include/clang/3.3/bmiintrin.h OLD_FILES+=usr/include/clang/3.3/cpuid.h OLD_FILES+=usr/include/clang/3.3/emmintrin.h OLD_FILES+=usr/include/clang/3.3/f16cintrin.h OLD_FILES+=usr/include/clang/3.3/fma4intrin.h OLD_FILES+=usr/include/clang/3.3/fmaintrin.h OLD_FILES+=usr/include/clang/3.3/immintrin.h OLD_FILES+=usr/include/clang/3.3/lzcntintrin.h OLD_FILES+=usr/include/clang/3.3/mm3dnow.h OLD_FILES+=usr/include/clang/3.3/mm_malloc.h OLD_FILES+=usr/include/clang/3.3/mmintrin.h OLD_FILES+=usr/include/clang/3.3/module.map OLD_FILES+=usr/include/clang/3.3/nmmintrin.h OLD_FILES+=usr/include/clang/3.3/pmmintrin.h OLD_FILES+=usr/include/clang/3.3/popcntintrin.h OLD_FILES+=usr/include/clang/3.3/prfchwintrin.h OLD_FILES+=usr/include/clang/3.3/rdseedintrin.h OLD_FILES+=usr/include/clang/3.3/rtmintrin.h OLD_FILES+=usr/include/clang/3.3/smmintrin.h OLD_FILES+=usr/include/clang/3.3/tmmintrin.h OLD_FILES+=usr/include/clang/3.3/wmmintrin.h OLD_FILES+=usr/include/clang/3.3/x86intrin.h OLD_FILES+=usr/include/clang/3.3/xmmintrin.h OLD_FILES+=usr/include/clang/3.3/xopintrin.h OLD_FILES+=usr/share/man/man1/llvm-prof.1.gz OLD_DIRS+=usr/include/clang/3.3 # 20140216: nve(4) removed OLD_FILES+=usr/share/man/man4/if_nve.4.gz OLD_FILES+=usr/share/man/man4/nve.4.gz # 20140205: Open Firmware device moved OLD_FILES+=usr/include/dev/ofw/ofw_nexus.h # 20140128: libelf and libdwarf import OLD_LIBS+=usr/lib/libelf.so.1 OLD_LIBS+=usr/lib/libdwarf.so.3 # 20140123: apicvar header moved to x86 OLD_FILES+=usr/include/machine/apicvar.h # 20131215: libcam version bumped OLD_LIBS+=lib/libcam.so.6 # 20131202: libcapsicum and libcasper moved to /lib/ MOVED_LIBS+=usr/lib/libcapsicum.so.0 MOVED_LIBS+=usr/lib/libcasper.so.0 # 20131109: extattr(2) mlinks fixed OLD_FILES+=usr/share/man/man2/extattr_delete_list.2.gz OLD_FILES+=usr/share/man/man2/extattr_get_list.2.gz # 20131107: example files removed OLD_FILES+=usr/share/examples/libusb20/aux.c OLD_FILES+=usr/share/examples/libusb20/aux.h # 20131103: WITH_LIBICONV_COMPAT removal OLD_FILES+=usr/include/_libiconv_compat.h OLD_FILES+=usr/lib/libiconv.a OLD_FILES+=usr/lib/libiconv.so OLD_LIBS+=usr/lib/libiconv.so.3 OLD_FILES+=usr/lib/libiconv_p.a # 20131103: removal of utxrm(8), use 'utx rm' instead OLD_FILES+=usr/sbin/utxrm OLD_FILES+=usr/share/man/man8/utxrm.8.gz # 20131031: pkg_install has been removed OLD_FILES+=etc/periodic/daily/220.backup-pkgdb OLD_FILES+=etc/periodic/daily/490.status-pkg-changes OLD_FILES+=etc/periodic/security/460.chkportsum OLD_FILES+=etc/periodic/weekly/400.status-pkg OLD_FILES+=usr/sbin/pkg_add OLD_FILES+=usr/sbin/pkg_create OLD_FILES+=usr/sbin/pkg_delete OLD_FILES+=usr/sbin/pkg_info OLD_FILES+=usr/sbin/pkg_updating OLD_FILES+=usr/sbin/pkg_version OLD_FILES+=usr/share/man/man1/pkg_add.1.gz OLD_FILES+=usr/share/man/man1/pkg_create.1.gz OLD_FILES+=usr/share/man/man1/pkg_delete.1.gz OLD_FILES+=usr/share/man/man1/pkg_info.1.gz OLD_FILES+=usr/share/man/man1/pkg_updating.1.gz OLD_FILES+=usr/share/man/man1/pkg_version.1.gz # 20131030: /etc/keys moved to /usr/share/keys OLD_DIRS+=etc/keys OLD_DIRS+=etc/keys/pkg OLD_DIRS+=etc/keys/pkg/revoked OLD_DIRS+=etc/keys/pkg/trusted OLD_FILES+=etc/keys/pkg/trusted/pkg.freebsd.org.2013102301 # 20131028: ng_fec(4) removed OLD_FILES+=usr/include/netgraph/ng_fec.h OLD_FILES+=usr/share/man/man4/ng_fec.4.gz # 20131027: header moved OLD_FILES+=usr/include/net/pf_mtag.h # 20131023: remove never used iscsi directory OLD_DIRS+=usr/share/examples/iscsi # 20131021: isf(4) removed OLD_FILES+=usr/sbin/isfctl OLD_FILES+=usr/share/man/man4/isf.4.gz OLD_FILES+=usr/share/man/man8/isfctl.8.gz # 20131014: libbsdyml becomes private OLD_FILES+=usr/lib/libbsdyml.a OLD_FILES+=usr/lib/libbsdyml.so OLD_LIBS+=usr/lib/libbsdyml.so.0 OLD_FILES+=usr/lib/libbsdyml_p.a OLD_FILES+=usr/share/man/man3/libbsdyml.3.gz OLD_FILES+=usr/include/bsdyml.h # 20131013: Removal of the ATF tools OLD_FILES+=etc/atf/FreeBSD.conf OLD_FILES+=etc/atf/atf-run.hooks OLD_FILES+=etc/atf/common.conf OLD_FILES+=usr/bin/atf-config OLD_FILES+=usr/bin/atf-report OLD_FILES+=usr/bin/atf-run OLD_FILES+=usr/bin/atf-version OLD_FILES+=usr/share/atf/atf-run.hooks OLD_FILES+=usr/share/examples/atf/atf-run.hooks OLD_FILES+=usr/share/examples/atf/tests-results.css OLD_FILES+=usr/share/man/man1/atf-config.1.gz OLD_FILES+=usr/share/man/man1/atf-report.1.gz OLD_FILES+=usr/share/man/man1/atf-run.1.gz OLD_FILES+=usr/share/man/man1/atf-version.1.gz OLD_FILES+=usr/share/man/man5/atf-formats.5.gz OLD_FILES+=usr/share/xml/atf/tests-results.dtd OLD_FILES+=usr/share/xsl/atf/tests-results.xsl OLD_DIRS+=etc/atf OLD_DIRS+=usr/share/examples/atf OLD_DIRS+=usr/share/xml/atf OLD_DIRS+=usr/share/xml OLD_DIRS+=usr/share/xsl/atf OLD_DIRS+=usr/share/xsl # 20131009: freebsd-version moved from /libexec to /bin OLD_FILES+=libexec/freebsd-version # 20131001: ar and ranlib from binutils not used OLD_FILES+=usr/bin/gnu-ar OLD_FILES+=usr/bin/gnu-ranlib OLD_FILES+=usr/share/man/man1/gnu-ar.1.gz OLD_FILES+=usr/share/man/man1/gnu-ranlib.1.gz # 20130930: BIND removed from base OLD_FILES+=etc/mtree/BIND.chroot.dist OLD_FILES+=etc/namedb OLD_FILES+=etc/periodic/daily/470.status-named OLD_FILES+=usr/bin/dig OLD_FILES+=usr/bin/nslookup OLD_FILES+=usr/bin/nsupdate OLD_DIRS+=usr/include/lwres OLD_FILES+=usr/include/lwres/context.h OLD_FILES+=usr/include/lwres/int.h OLD_FILES+=usr/include/lwres/ipv6.h OLD_FILES+=usr/include/lwres/lang.h OLD_FILES+=usr/include/lwres/list.h OLD_FILES+=usr/include/lwres/lwbuffer.h OLD_FILES+=usr/include/lwres/lwpacket.h OLD_FILES+=usr/include/lwres/lwres.h OLD_FILES+=usr/include/lwres/net.h OLD_FILES+=usr/include/lwres/netdb.h OLD_FILES+=usr/include/lwres/platform.h OLD_FILES+=usr/include/lwres/result.h OLD_FILES+=usr/include/lwres/string.h OLD_FILES+=usr/include/lwres/version.h OLD_FILES+=usr/lib/liblwres.a OLD_FILES+=usr/lib/liblwres.so OLD_LIBS+=usr/lib/liblwres.so.90 OLD_FILES+=usr/lib/liblwres_p.a OLD_FILES+=usr/sbin/arpaname OLD_FILES+=usr/sbin/ddns-confgen OLD_FILES+=usr/sbin/dnssec-dsfromkey OLD_FILES+=usr/sbin/dnssec-keyfromlabel OLD_FILES+=usr/sbin/dnssec-keygen OLD_FILES+=usr/sbin/dnssec-revoke OLD_FILES+=usr/sbin/dnssec-settime OLD_FILES+=usr/sbin/dnssec-signzone OLD_FILES+=usr/sbin/dnssec-verify OLD_FILES+=usr/sbin/genrandom OLD_FILES+=usr/sbin/isc-hmac-fixup OLD_FILES+=usr/sbin/lwresd OLD_FILES+=usr/sbin/named OLD_FILES+=usr/sbin/named-checkconf OLD_FILES+=usr/sbin/named-checkzone OLD_FILES+=usr/sbin/named-compilezone OLD_FILES+=usr/sbin/named-journalprint OLD_FILES+=usr/sbin/named.reconfig OLD_FILES+=usr/sbin/named.reload OLD_FILES+=usr/sbin/nsec3hash OLD_FILES+=usr/sbin/rndc OLD_FILES+=usr/sbin/rndc-confgen OLD_DIRS+=usr/share/doc/bind9 OLD_FILES+=usr/share/doc/bind9/CHANGES OLD_FILES+=usr/share/doc/bind9/COPYRIGHT OLD_FILES+=usr/share/doc/bind9/FAQ OLD_FILES+=usr/share/doc/bind9/HISTORY OLD_FILES+=usr/share/doc/bind9/README OLD_DIRS+=usr/share/doc/bind9/arm OLD_FILES+=usr/share/doc/bind9/arm/Bv9ARM.ch01.html OLD_FILES+=usr/share/doc/bind9/arm/Bv9ARM.ch02.html OLD_FILES+=usr/share/doc/bind9/arm/Bv9ARM.ch03.html OLD_FILES+=usr/share/doc/bind9/arm/Bv9ARM.ch04.html OLD_FILES+=usr/share/doc/bind9/arm/Bv9ARM.ch05.html OLD_FILES+=usr/share/doc/bind9/arm/Bv9ARM.ch06.html OLD_FILES+=usr/share/doc/bind9/arm/Bv9ARM.ch07.html OLD_FILES+=usr/share/doc/bind9/arm/Bv9ARM.ch08.html OLD_FILES+=usr/share/doc/bind9/arm/Bv9ARM.ch09.html OLD_FILES+=usr/share/doc/bind9/arm/Bv9ARM.ch10.html OLD_FILES+=usr/share/doc/bind9/arm/Bv9ARM.html OLD_FILES+=usr/share/doc/bind9/arm/Bv9ARM.pdf OLD_FILES+=usr/share/doc/bind9/arm/man.arpaname.html OLD_FILES+=usr/share/doc/bind9/arm/man.ddns-confgen.html OLD_FILES+=usr/share/doc/bind9/arm/man.dig.html OLD_FILES+=usr/share/doc/bind9/arm/man.dnssec-dsfromkey.html OLD_FILES+=usr/share/doc/bind9/arm/man.dnssec-keyfromlabel.html OLD_FILES+=usr/share/doc/bind9/arm/man.dnssec-keygen.html OLD_FILES+=usr/share/doc/bind9/arm/man.dnssec-revoke.html OLD_FILES+=usr/share/doc/bind9/arm/man.dnssec-settime.html OLD_FILES+=usr/share/doc/bind9/arm/man.dnssec-signzone.html OLD_FILES+=usr/share/doc/bind9/arm/man.dnssec-verify.html OLD_FILES+=usr/share/doc/bind9/arm/man.genrandom.html OLD_FILES+=usr/share/doc/bind9/arm/man.host.html OLD_FILES+=usr/share/doc/bind9/arm/man.isc-hmac-fixup.html OLD_FILES+=usr/share/doc/bind9/arm/man.named-checkconf.html OLD_FILES+=usr/share/doc/bind9/arm/man.named-checkzone.html OLD_FILES+=usr/share/doc/bind9/arm/man.named-journalprint.html OLD_FILES+=usr/share/doc/bind9/arm/man.named.html OLD_FILES+=usr/share/doc/bind9/arm/man.nsec3hash.html OLD_FILES+=usr/share/doc/bind9/arm/man.nsupdate.html OLD_FILES+=usr/share/doc/bind9/arm/man.rndc-confgen.html OLD_FILES+=usr/share/doc/bind9/arm/man.rndc.conf.html OLD_FILES+=usr/share/doc/bind9/arm/man.rndc.html OLD_DIRS+=usr/share/doc/bind9/misc OLD_FILES+=usr/share/doc/bind9/misc/dnssec OLD_FILES+=usr/share/doc/bind9/misc/format-options.pl OLD_FILES+=usr/share/doc/bind9/misc/ipv6 OLD_FILES+=usr/share/doc/bind9/misc/migration OLD_FILES+=usr/share/doc/bind9/misc/migration-4to9 OLD_FILES+=usr/share/doc/bind9/misc/options OLD_FILES+=usr/share/doc/bind9/misc/rfc-compliance OLD_FILES+=usr/share/doc/bind9/misc/roadmap OLD_FILES+=usr/share/doc/bind9/misc/sdb OLD_FILES+=usr/share/doc/bind9/misc/sort-options.pl OLD_FILES+=usr/share/man/man1/arpaname.1.gz OLD_FILES+=usr/share/man/man1/dig.1.gz OLD_FILES+=usr/share/man/man1/nslookup.1.gz OLD_FILES+=usr/share/man/man1/nsupdate.1.gz OLD_FILES+=usr/share/man/man3/lwres.3.gz OLD_FILES+=usr/share/man/man3/lwres_addr_parse.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_add.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_back.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_clear.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_first.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_forward.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_getmem.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_getuint16.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_getuint32.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_getuint8.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_init.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_invalidate.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_putmem.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_putuint16.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_putuint32.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_putuint8.3.gz OLD_FILES+=usr/share/man/man3/lwres_buffer_subtract.3.gz OLD_FILES+=usr/share/man/man3/lwres_conf_clear.3.gz OLD_FILES+=usr/share/man/man3/lwres_conf_get.3.gz OLD_FILES+=usr/share/man/man3/lwres_conf_init.3.gz OLD_FILES+=usr/share/man/man3/lwres_conf_parse.3.gz OLD_FILES+=usr/share/man/man3/lwres_conf_print.3.gz OLD_FILES+=usr/share/man/man3/lwres_config.3.gz OLD_FILES+=usr/share/man/man3/lwres_context.3.gz OLD_FILES+=usr/share/man/man3/lwres_context_allocmem.3.gz OLD_FILES+=usr/share/man/man3/lwres_context_create.3.gz OLD_FILES+=usr/share/man/man3/lwres_context_destroy.3.gz OLD_FILES+=usr/share/man/man3/lwres_context_freemem.3.gz OLD_FILES+=usr/share/man/man3/lwres_context_initserial.3.gz OLD_FILES+=usr/share/man/man3/lwres_context_nextserial.3.gz OLD_FILES+=usr/share/man/man3/lwres_context_sendrecv.3.gz OLD_FILES+=usr/share/man/man3/lwres_endhostent.3.gz OLD_FILES+=usr/share/man/man3/lwres_endhostent_r.3.gz OLD_FILES+=usr/share/man/man3/lwres_freeaddrinfo.3.gz OLD_FILES+=usr/share/man/man3/lwres_freehostent.3.gz OLD_FILES+=usr/share/man/man3/lwres_gabn.3.gz OLD_FILES+=usr/share/man/man3/lwres_gabnrequest_free.3.gz OLD_FILES+=usr/share/man/man3/lwres_gabnrequest_parse.3.gz OLD_FILES+=usr/share/man/man3/lwres_gabnrequest_render.3.gz OLD_FILES+=usr/share/man/man3/lwres_gabnresponse_free.3.gz OLD_FILES+=usr/share/man/man3/lwres_gabnresponse_parse.3.gz OLD_FILES+=usr/share/man/man3/lwres_gabnresponse_render.3.gz OLD_FILES+=usr/share/man/man3/lwres_gai_strerror.3.gz OLD_FILES+=usr/share/man/man3/lwres_getaddrinfo.3.gz OLD_FILES+=usr/share/man/man3/lwres_getaddrsbyname.3.gz OLD_FILES+=usr/share/man/man3/lwres_gethostbyaddr.3.gz OLD_FILES+=usr/share/man/man3/lwres_gethostbyaddr_r.3.gz OLD_FILES+=usr/share/man/man3/lwres_gethostbyname.3.gz OLD_FILES+=usr/share/man/man3/lwres_gethostbyname2.3.gz OLD_FILES+=usr/share/man/man3/lwres_gethostbyname_r.3.gz OLD_FILES+=usr/share/man/man3/lwres_gethostent.3.gz OLD_FILES+=usr/share/man/man3/lwres_gethostent_r.3.gz OLD_FILES+=usr/share/man/man3/lwres_getipnode.3.gz OLD_FILES+=usr/share/man/man3/lwres_getipnodebyaddr.3.gz OLD_FILES+=usr/share/man/man3/lwres_getipnodebyname.3.gz OLD_FILES+=usr/share/man/man3/lwres_getnamebyaddr.3.gz OLD_FILES+=usr/share/man/man3/lwres_getnameinfo.3.gz OLD_FILES+=usr/share/man/man3/lwres_getrrsetbyname.3.gz OLD_FILES+=usr/share/man/man3/lwres_gnba.3.gz OLD_FILES+=usr/share/man/man3/lwres_gnbarequest_free.3.gz OLD_FILES+=usr/share/man/man3/lwres_gnbarequest_parse.3.gz OLD_FILES+=usr/share/man/man3/lwres_gnbarequest_render.3.gz OLD_FILES+=usr/share/man/man3/lwres_gnbaresponse_free.3.gz OLD_FILES+=usr/share/man/man3/lwres_gnbaresponse_parse.3.gz OLD_FILES+=usr/share/man/man3/lwres_gnbaresponse_render.3.gz OLD_FILES+=usr/share/man/man3/lwres_herror.3.gz OLD_FILES+=usr/share/man/man3/lwres_hstrerror.3.gz OLD_FILES+=usr/share/man/man3/lwres_inetntop.3.gz OLD_FILES+=usr/share/man/man3/lwres_lwpacket_parseheader.3.gz OLD_FILES+=usr/share/man/man3/lwres_lwpacket_renderheader.3.gz OLD_FILES+=usr/share/man/man3/lwres_net_ntop.3.gz OLD_FILES+=usr/share/man/man3/lwres_noop.3.gz OLD_FILES+=usr/share/man/man3/lwres_nooprequest_free.3.gz OLD_FILES+=usr/share/man/man3/lwres_nooprequest_parse.3.gz OLD_FILES+=usr/share/man/man3/lwres_nooprequest_render.3.gz OLD_FILES+=usr/share/man/man3/lwres_noopresponse_free.3.gz OLD_FILES+=usr/share/man/man3/lwres_noopresponse_parse.3.gz OLD_FILES+=usr/share/man/man3/lwres_noopresponse_render.3.gz OLD_FILES+=usr/share/man/man3/lwres_packet.3.gz OLD_FILES+=usr/share/man/man3/lwres_resutil.3.gz OLD_FILES+=usr/share/man/man3/lwres_sethostent.3.gz OLD_FILES+=usr/share/man/man3/lwres_sethostent_r.3.gz OLD_FILES+=usr/share/man/man3/lwres_string_parse.3.gz OLD_FILES+=usr/share/man/man5/named.conf.5.gz OLD_FILES+=usr/share/man/man5/rndc.conf.5.gz OLD_FILES+=usr/share/man/man8/ddns-confgen.8.gz OLD_FILES+=usr/share/man/man8/dnssec-dsfromkey.8.gz OLD_FILES+=usr/share/man/man8/dnssec-keyfromlabel.8.gz OLD_FILES+=usr/share/man/man8/dnssec-keygen.8.gz OLD_FILES+=usr/share/man/man8/dnssec-revoke.8.gz OLD_FILES+=usr/share/man/man8/dnssec-settime.8.gz OLD_FILES+=usr/share/man/man8/dnssec-signzone.8.gz OLD_FILES+=usr/share/man/man8/dnssec-verify.8.gz OLD_FILES+=usr/share/man/man8/genrandom.8.gz OLD_FILES+=usr/share/man/man8/isc-hmac-fixup.8.gz OLD_FILES+=usr/share/man/man8/lwresd.8.gz OLD_FILES+=usr/share/man/man8/named-checkconf.8.gz OLD_FILES+=usr/share/man/man8/named-checkzone.8.gz OLD_FILES+=usr/share/man/man8/named-compilezone.8.gz OLD_FILES+=usr/share/man/man8/named-journalprint.8.gz OLD_FILES+=usr/share/man/man8/named.8.gz OLD_FILES+=usr/share/man/man8/named.reconfig.8.gz OLD_FILES+=usr/share/man/man8/named.reload.8.gz OLD_FILES+=usr/share/man/man8/nsec3hash.8.gz OLD_FILES+=usr/share/man/man8/rndc-confgen.8.gz OLD_FILES+=usr/share/man/man8/rndc.8.gz OLD_DIRS+=var/named/dev OLD_DIRS+=var/named/etc OLD_DIRS+=var/named/etc/namedb OLD_FILES+=var/named/etc/namedb/PROTO.localhost-v6.rev OLD_FILES+=var/named/etc/namedb/PROTO.localhost.rev OLD_DIRS+=var/named/etc/namedb/dynamic OLD_FILES+=var/named/etc/namedb/make-localhost OLD_DIRS+=var/named/etc/namedb/master OLD_FILES+=var/named/etc/namedb/master/empty.db OLD_FILES+=var/named/etc/namedb/master/localhost-forward.db OLD_FILES+=var/named/etc/namedb/master/localhost-reverse.db #OLD_FILES+=var/named/etc/namedb/named.conf # intentionally left out OLD_FILES+=var/named/etc/namedb/named.root OLD_DIRS+=var/named/etc/namedb/working OLD_DIRS+=var/named/etc/namedb/slave OLD_DIRS+=var/named/var OLD_DIRS+=var/named/var/dump OLD_DIRS+=var/named/var/log OLD_DIRS+=var/named/var/run OLD_DIRS+=var/named/var/run/named OLD_DIRS+=var/named/var/stats OLD_DIRS+=var/run/named # 20130923: example moved OLD_FILES+=usr/share/examples/bsdconfig/browse_packages.sh # 20130908: libssh becomes private OLD_FILES+=usr/lib/libssh.a OLD_FILES+=usr/lib/libssh.so OLD_LIBS+=usr/lib/libssh.so.5 OLD_FILES+=usr/lib/libssh_p.a # 20130903: gnupatch is no more OLD_FILES+=usr/bin/gnupatch OLD_FILES+=usr/share/man/man1/gnupatch.1.gz # 20130829: bsdpatch is patch unconditionally OLD_FILES+=usr/bin/bsdpatch OLD_FILES+=usr/share/man/man1/bsdpatch.1.gz # 20130822: bind 9.9.3-P2 import OLD_LIBS+=usr/lib/liblwres.so.80 # 20130814: vm_page_busy(9) OLD_FILES+=usr/share/man/man9/vm_page_flash.9.gz OLD_FILES+=usr/share/man/man9/vm_page_io.9.gz OLD_FILES+=usr/share/man/man9/vm_page_io_finish.9.gz OLD_FILES+=usr/share/man/man9/vm_page_io_start.9.gz OLD_FILES+=usr/share/man/man9/vm_page_wakeup.9.gz # 20130710: libkvm version bump OLD_LIBS+=lib/libkvm.so.5 # 20130623: dialog update from 1.1 to 1.2 OLD_LIBS+=usr/lib/libdialog.so.7 # 20130616: vfs_mount.9 removed OLD_FILES+=usr/share/man/man9/vfs_mount.9.gz # 20130614: remove CVS from base OLD_FILES+=usr/bin/cvs OLD_FILES+=usr/bin/cvsbug OLD_FILES+=usr/share/doc/psd/28.cvs/paper.ascii.gz OLD_FILES+=usr/share/doc/psd/28.cvs/paper.ps.gz OLD_DIRS+=usr/share/doc/psd/28.cvs OLD_FILES+=usr/share/examples/cvs/contrib/README OLD_FILES+=usr/share/examples/cvs/contrib/clmerge OLD_FILES+=usr/share/examples/cvs/contrib/cln_hist OLD_FILES+=usr/share/examples/cvs/contrib/commit_prep OLD_FILES+=usr/share/examples/cvs/contrib/cvs2vendor OLD_FILES+=usr/share/examples/cvs/contrib/cvs_acls OLD_FILES+=usr/share/examples/cvs/contrib/cvscheck OLD_FILES+=usr/share/examples/cvs/contrib/cvscheck.man OLD_FILES+=usr/share/examples/cvs/contrib/cvshelp.man OLD_FILES+=usr/share/examples/cvs/contrib/descend.man OLD_FILES+=usr/share/examples/cvs/contrib/easy-import OLD_FILES+=usr/share/examples/cvs/contrib/intro.doc OLD_FILES+=usr/share/examples/cvs/contrib/log OLD_FILES+=usr/share/examples/cvs/contrib/log_accum OLD_FILES+=usr/share/examples/cvs/contrib/mfpipe OLD_FILES+=usr/share/examples/cvs/contrib/rcs-to-cvs OLD_FILES+=usr/share/examples/cvs/contrib/rcs2log OLD_FILES+=usr/share/examples/cvs/contrib/rcslock OLD_FILES+=usr/share/examples/cvs/contrib/sccs2rcs OLD_DIRS+=usr/share/examples/cvs/contrib OLD_DIRS+=usr/share/examples/cvs OLD_FILES+=usr/share/info/cvs.info.gz OLD_FILES+=usr/share/info/cvsclient.info.gz OLD_FILES+=usr/share/man/man1/cvs.1.gz OLD_FILES+=usr/share/man/man5/cvs.5.gz OLD_FILES+=usr/share/man/man8/cvsbug.8.gz # 20130607: WITH_DEBUG_FILES added OLD_FILES+=lib/libufs.so.6.symbols # 20130417: nfs fha moved from nfsserver to nfs OLD_FILES+=usr/include/nfsserver/nfs_fha.h # 20130411: new clang import which bumps version from 3.2 to 3.3 OLD_FILES+=usr/include/clang/3.2/__wmmintrin_aes.h OLD_FILES+=usr/include/clang/3.2/__wmmintrin_pclmul.h OLD_FILES+=usr/include/clang/3.2/altivec.h OLD_FILES+=usr/include/clang/3.2/ammintrin.h OLD_FILES+=usr/include/clang/3.2/avx2intrin.h OLD_FILES+=usr/include/clang/3.2/avxintrin.h OLD_FILES+=usr/include/clang/3.2/bmi2intrin.h OLD_FILES+=usr/include/clang/3.2/bmiintrin.h OLD_FILES+=usr/include/clang/3.2/cpuid.h OLD_FILES+=usr/include/clang/3.2/emmintrin.h OLD_FILES+=usr/include/clang/3.2/f16cintrin.h OLD_FILES+=usr/include/clang/3.2/fma4intrin.h OLD_FILES+=usr/include/clang/3.2/fmaintrin.h OLD_FILES+=usr/include/clang/3.2/immintrin.h OLD_FILES+=usr/include/clang/3.2/lzcntintrin.h OLD_FILES+=usr/include/clang/3.2/mm3dnow.h OLD_FILES+=usr/include/clang/3.2/mm_malloc.h OLD_FILES+=usr/include/clang/3.2/mmintrin.h OLD_FILES+=usr/include/clang/3.2/module.map OLD_FILES+=usr/include/clang/3.2/nmmintrin.h OLD_FILES+=usr/include/clang/3.2/pmmintrin.h OLD_FILES+=usr/include/clang/3.2/popcntintrin.h OLD_FILES+=usr/include/clang/3.2/rtmintrin.h OLD_FILES+=usr/include/clang/3.2/smmintrin.h OLD_FILES+=usr/include/clang/3.2/tmmintrin.h OLD_FILES+=usr/include/clang/3.2/wmmintrin.h OLD_FILES+=usr/include/clang/3.2/x86intrin.h OLD_FILES+=usr/include/clang/3.2/xmmintrin.h OLD_FILES+=usr/include/clang/3.2/xopintrin.h OLD_DIRS+=usr/include/clang/3.2 # 20130404: legacy ATA stack removed OLD_FILES+=etc/periodic/daily/405.status-ata-raid OLD_FILES+=rescue/atacontrol OLD_FILES+=sbin/atacontrol OLD_FILES+=usr/share/man/man8/atacontrol.8.gz OLD_FILES+=usr/share/man/man4/atapicam.4.gz OLD_FILES+=usr/share/man/man4/ataraid.4.gz OLD_FILES+=usr/sbin/burncd OLD_FILES+=usr/share/man/man8/burncd.8.gz # 20130316: vinum.4 removed OLD_FILES+=usr/share/man/man4/vinum.4.gz # 20130312: fortunes-o removed OLD_FILES+=usr/share/games/fortune/fortunes-o OLD_FILES+=usr/share/games/fortune/fortunes-o.dat # 20130311: Ports are no more available via cvsup OLD_FILES+=usr/share/examples/cvsup/ports-supfile OLD_FILES+=usr/share/examples/cvsup/refuse OLD_FILES+=usr/share/examples/cvsup/refuse.README # 20130309: NWFS and NCP supports removed OLD_FILES+=usr/bin/ncplist OLD_FILES+=usr/bin/ncplogin OLD_FILES+=usr/bin/ncplogout OLD_FILES+=usr/include/fs/nwfs/nwfs.h OLD_FILES+=usr/include/fs/nwfs/nwfs_mount.h OLD_FILES+=usr/include/fs/nwfs/nwfs_node.h OLD_FILES+=usr/include/fs/nwfs/nwfs_subr.h OLD_DIRS+=usr/include/fs/nwfs OLD_FILES+=usr/include/netncp/ncp.h OLD_FILES+=usr/include/netncp/ncp_cfg.h OLD_FILES+=usr/include/netncp/ncp_conn.h OLD_FILES+=usr/include/netncp/ncp_file.h OLD_FILES+=usr/include/netncp/ncp_lib.h OLD_FILES+=usr/include/netncp/ncp_ncp.h OLD_FILES+=usr/include/netncp/ncp_nls.h OLD_FILES+=usr/include/netncp/ncp_rcfile.h OLD_FILES+=usr/include/netncp/ncp_rq.h OLD_FILES+=usr/include/netncp/ncp_sock.h OLD_FILES+=usr/include/netncp/ncp_subr.h OLD_FILES+=usr/include/netncp/ncp_user.h OLD_FILES+=usr/include/netncp/ncpio.h OLD_FILES+=usr/include/netncp/nwerror.h OLD_DIRS+=usr/include/netncp OLD_FILES+=usr/lib/libncp.a OLD_FILES+=usr/lib/libncp.so OLD_LIBS+=usr/lib/libncp.so.4 OLD_FILES+=usr/lib/libncp_p.a OLD_FILES+=usr/sbin/mount_nwfs OLD_FILES+=usr/share/examples/nwclient/dot.nwfsrc OLD_FILES+=usr/share/examples/nwclient/nwfs.sh.sample OLD_DIRS+=usr/share/examples/nwclient OLD_FILES+=usr/share/man/man1/ncplist.1.gz OLD_FILES+=usr/share/man/man1/ncplogin.1.gz OLD_FILES+=usr/share/man/man1/ncplogout.1.gz OLD_FILES+=usr/share/man/man8/mount_nwfs.8.gz # 20130302: NTFS support removed OLD_FILES+=rescue/mount_ntfs OLD_FILES+=sbin/mount_ntfs OLD_FILES+=usr/include/fs/ntfs/ntfs.h OLD_FILES+=usr/include/fs/ntfs/ntfs_compr.h OLD_FILES+=usr/include/fs/ntfs/ntfs_ihash.h OLD_FILES+=usr/include/fs/ntfs/ntfs_inode.h OLD_FILES+=usr/include/fs/ntfs/ntfs_subr.h OLD_FILES+=usr/include/fs/ntfs/ntfs_vfsops.h OLD_FILES+=usr/include/fs/ntfs/ntfsmount.h OLD_DIRS+=usr/include/fs/ntfs OLD_FILES+=usr/share/man/man8/mount_ntfs.8.gz # 20130302: PORTALFS support removed OLD_FILES+=usr/include/fs/portalfs/portal.h OLD_DIRS+=usr/include/fs/portalfs OLD_FILES+=usr/sbin/mount_portalfs OLD_FILES+=usr/share/examples/portal/README OLD_FILES+=usr/share/examples/portal/portal.conf OLD_DIRS+=usr/share/examples/portal OLD_FILES+=usr/share/man/man8/mount_portalfs.8.gz # 20130302: CODAFS support removed OLD_FILES+=usr/share/man/man4/coda.4.gz # 20130302: XFS support removed OLD_FILES+=usr/share/man/man5/xfs.5.gz # 20130302: Capsicum overhaul OLD_FILES+=usr/share/man/man2/cap_getrights.2.gz OLD_FILES+=usr/share/man/man2/cap_new.2.gz # 20130213: OpenSSL 1.0.1e import OLD_FILES+=usr/share/openssl/man/man3/EVP_PKEY_verifyrecover.3.gz OLD_FILES+=usr/share/openssl/man/man3/EVP_PKEY_verifyrecover_init.3.gz # 20130116: removed long unused directories for .1aout section manpages OLD_FILES+=usr/share/man/en.ISO8859-1/man1aout OLD_FILES+=usr/share/man/en.UTF-8/man1aout OLD_DIRS+=usr/share/man/man1aout OLD_DIRS+=usr/share/man/cat1aout OLD_DIRS+=usr/share/man/en.ISO8859-1/cat1aout OLD_DIRS+=usr/share/man/en.UTF-8/cat1aout # 20130103: gnats-supfile removed OLD_FILES+=usr/share/examples/cvsup/gnats-supfile # 20121230: libdisk removed OLD_FILES+=usr/share/man/man3/libdisk.3.gz usr/include/libdisk.h OLD_FILES+=usr/lib/libdisk.a # 20121230: remove wrongly created directories for auditdistd OLD_DIRS+=var/dist OLD_DIRS+=var/remote # 20121022: remove harp, hfa and idt man page OLD_FILES+=usr/share/man/man4/harp.4.gz OLD_FILES+=usr/share/man/man4/hfa.4.gz OLD_FILES+=usr/share/man/man4/idt.4.gz OLD_FILES+=usr/share/man/man4/if_idt.4.gz # 20121022: VFS_LOCK_GIANT elimination OLD_FILES+=usr/share/man/man9/VFS_LOCK_GIANT.9.gz OLD_FILES+=usr/share/man/man9/VFS_UNLOCK_GIANT.9.gz # 20121004: remove incomplete unwind.h OLD_FILES+=usr/include/clang/3.2/unwind.h # 20120910: NetBSD compat shims removed OLD_FILES+=usr/include/cam/scsi/scsi_low_pisa.h OLD_FILES+=usr/include/sys/device_port.h # 20120909: doc and www supfiles removed OLD_FILES+=usr/share/examples/cvsup/doc-supfile OLD_FILES+=usr/share/examples/cvsup/www-supfile # 20120908: pf cleanup OLD_FILES+=usr/include/net/if_pflow.h # 20120816: new clang import which bumps version from 3.1 to 3.2 OLD_FILES+=usr/bin/llvm-ld OLD_FILES+=usr/bin/llvm-stub OLD_FILES+=usr/include/clang/3.1/altivec.h OLD_FILES+=usr/include/clang/3.1/avx2intrin.h OLD_FILES+=usr/include/clang/3.1/avxintrin.h OLD_FILES+=usr/include/clang/3.1/bmi2intrin.h OLD_FILES+=usr/include/clang/3.1/bmiintrin.h OLD_FILES+=usr/include/clang/3.1/cpuid.h OLD_FILES+=usr/include/clang/3.1/emmintrin.h OLD_FILES+=usr/include/clang/3.1/fma4intrin.h OLD_FILES+=usr/include/clang/3.1/immintrin.h OLD_FILES+=usr/include/clang/3.1/lzcntintrin.h OLD_FILES+=usr/include/clang/3.1/mm3dnow.h OLD_FILES+=usr/include/clang/3.1/mm_malloc.h OLD_FILES+=usr/include/clang/3.1/mmintrin.h OLD_FILES+=usr/include/clang/3.1/module.map OLD_FILES+=usr/include/clang/3.1/nmmintrin.h OLD_FILES+=usr/include/clang/3.1/pmmintrin.h OLD_FILES+=usr/include/clang/3.1/popcntintrin.h OLD_FILES+=usr/include/clang/3.1/smmintrin.h OLD_FILES+=usr/include/clang/3.1/tmmintrin.h OLD_FILES+=usr/include/clang/3.1/unwind.h OLD_FILES+=usr/include/clang/3.1/wmmintrin.h OLD_FILES+=usr/include/clang/3.1/x86intrin.h OLD_FILES+=usr/include/clang/3.1/xmmintrin.h OLD_DIRS+=usr/include/clang/3.1 OLD_FILES+=usr/share/man/man1/llvm-ld.1.gz # 20120712: OpenSSL 1.0.1c import OLD_LIBS+=lib/libcrypto.so.6 OLD_LIBS+=usr/lib/libssl.so.6 OLD_FILES+=usr/include/openssl/aes_locl.h OLD_FILES+=usr/include/openssl/bio_lcl.h OLD_FILES+=usr/include/openssl/e_os.h OLD_FILES+=usr/include/openssl/fips.h OLD_FILES+=usr/include/openssl/fips_rand.h OLD_FILES+=usr/include/openssl/pq_compat.h OLD_FILES+=usr/include/openssl/tmdiff.h OLD_FILES+=usr/include/openssl/ui_locl.h OLD_FILES+=usr/share/openssl/man/man3/CRYPTO_set_id_callback.3.gz # 20120621: remove old man page OLD_FILES+=usr/share/man/man8/vnconfig.8.gz # 20120619: TOE support updated OLD_FILES+=usr/include/netinet/toedev.h # 20120613: auth.conf removed OLD_FILES+=etc/auth.conf OLD_FILES+=usr/share/examples/etc/auth.conf OLD_FILES+=usr/share/man/man3/auth.3.gz OLD_FILES+=usr/share/man/man3/auth_getval.3.gz OLD_FILES+=usr/share/man/man5/auth.conf.5.gz # 20120530: kde pam lives now in ports OLD_FILES+=etc/pam.d/kde # 20120521: byacc import OLD_FILES+=usr/bin/yyfix OLD_FILES+=usr/share/man/man1/yyfix.1.gz # 20120505: new clang import installed a redundant internal header OLD_FILES+=usr/include/clang/3.1/stdalign.h # 20120428: MD2 removed from libmd OLD_LIBS+=lib/libmd.so.5 OLD_FILES+=usr/include/md2.h OLD_FILES+=usr/share/man/man3/MD2Data.3.gz OLD_FILES+=usr/share/man/man3/MD2End.3.gz OLD_FILES+=usr/share/man/man3/MD2File.3.gz OLD_FILES+=usr/share/man/man3/MD2FileChunk.3.gz OLD_FILES+=usr/share/man/man3/MD2Final.3.gz OLD_FILES+=usr/share/man/man3/MD2Init.3.gz OLD_FILES+=usr/share/man/man3/MD2Update.3.gz OLD_FILES+=usr/share/man/man3/md2.3.gz # 20120425: libusb version bump (r234684) OLD_LIBS+=usr/lib/libusb.so.2 OLD_FILES+=usr/share/man/man3/libsub_get_active_config_descriptor.3.gz # 20120415: new clang import which bumps version from 3.0 to 3.1 OLD_FILES+=usr/include/clang/3.0/altivec.h OLD_FILES+=usr/include/clang/3.0/avxintrin.h OLD_FILES+=usr/include/clang/3.0/emmintrin.h OLD_FILES+=usr/include/clang/3.0/immintrin.h OLD_FILES+=usr/include/clang/3.0/mm3dnow.h OLD_FILES+=usr/include/clang/3.0/mm_malloc.h OLD_FILES+=usr/include/clang/3.0/mmintrin.h OLD_FILES+=usr/include/clang/3.0/nmmintrin.h OLD_FILES+=usr/include/clang/3.0/pmmintrin.h OLD_FILES+=usr/include/clang/3.0/smmintrin.h OLD_FILES+=usr/include/clang/3.0/tmmintrin.h OLD_FILES+=usr/include/clang/3.0/wmmintrin.h OLD_FILES+=usr/include/clang/3.0/x86intrin.h OLD_FILES+=usr/include/clang/3.0/xmmintrin.h OLD_DIRS+=usr/include/clang/3.0 # 20120412: BIND 9.8.1 release notes removed OLD_FILES+=usr/share/doc/bind9/RELEASE-NOTES-BIND-9.8.1.pdf OLD_FILES+=usr/share/doc/bind9/RELEASE-NOTES-BIND-9.8.1.txt OLD_FILES+=usr/share/doc/bind9/RELEASE-NOTES-BIND-9.8.1.html OLD_FILES+=usr/share/doc/bind9/release-notes.css # 20120330: legacy(4) moved to x86 OLD_FILES+=usr/include/machine/legacyvar.h # 20120324: MPI headers updated OLD_FILES+=usr/include/dev/mpt/mpilib/mpi_inb.h # 20120322: hwpmc_mips24k.h removed OLD_FILES+=usr/include/dev/hwpmc/hwpmc_mips24k.h # 20120322: Update heimdal to 1.5.1 OLD_FILES+=usr/include/krb5-v4compat.h \ usr/include/krb_err.h \ usr/include/hdb-private.h \ usr/share/man/man3/krb5_addresses.3.gz \ usr/share/man/man3/krb5_cc_cursor.3.gz \ usr/share/man/man3/krb5_cc_ops.3.gz \ usr/share/man/man3/krb5_config.3.gz \ usr/share/man/man3/krb5_config_get_int_default.3.gz \ usr/share/man/man3/krb5_context.3.gz \ usr/share/man/man3/krb5_data.3.gz \ usr/share/man/man3/krb5_err.3.gz \ usr/share/man/man3/krb5_errx.3.gz \ usr/share/man/man3/krb5_keyblock.3.gz \ usr/share/man/man3/krb5_keytab_entry.3.gz \ usr/share/man/man3/krb5_kt_cursor.3.gz \ usr/share/man/man3/krb5_kt_ops.3.gz \ usr/share/man/man3/krb5_set_warn_dest.3.gz \ usr/share/man/man3/krb5_verr.3.gz \ usr/share/man/man3/krb5_verrx.3.gz \ usr/share/man/man3/krb5_vwarnx.3.gz \ usr/share/man/man3/krb5_warn.3.gz \ usr/share/man/man3/krb5_warnx.3.gz OLD_LIBS+=usr/lib/libasn1.so.10 \ usr/lib/libhdb.so.10 \ usr/lib/libheimntlm.so.10 \ usr/lib/libhx509.so.10 \ usr/lib/libkadm5clnt.so.10 \ usr/lib/libkadm5srv.so.10 \ usr/lib/libkafs5.so.10 \ usr/lib/libkrb5.so.10 \ usr/lib/libroken.so.10 # 20120309: Remove fifofs header files OLD_FILES+=usr/include/fs/fifofs/fifo.h OLD_DIRS+=usr/include/fs/fifofs # 20120304: xlocale cleanup OLD_FILES+=usr/include/_xlocale_ctype.h # 20120225: libarchive 3.0.3 OLD_FILES+=usr/share/man/man3/archive_read_data_into_buffer.3.gz \ usr/share/man/man3/archive_read_support_compression_all.3.gz \ usr/share/man/man3/archive_read_support_compression_bzip2.3.gz \ usr/share/man/man3/archive_read_support_compression_compress.3.gz \ usr/share/man/man3/archive_read_support_compression_gzip.3.gz \ usr/share/man/man3/archive_read_support_compression_lzma.3.gz \ usr/share/man/man3/archive_read_support_compression_none.3.gz \ usr/share/man/man3/archive_read_support_compression_program.3.gz \ usr/share/man/man3/archive_read_support_compression_program_signature.3.gz \ usr/share/man/man3/archive_read_support_compression_xz.3.gz \ usr/share/man/man3/archive_write_set_callbacks.3.gz \ usr/share/man/man3/archive_write_set_compression_bzip2.3.gz \ usr/share/man/man3/archive_write_set_compression_compress.3.gz \ usr/share/man/man3/archive_write_set_compression_gzip.3.gz \ usr/share/man/man3/archive_write_set_compression_none.3.gz \ usr/share/man/man3/archive_write_set_compression_program.3.gz OLD_LIBS+=usr/lib/libarchive.so.5 # 20120113: removal of wtmpcvt(1) OLD_FILES+=usr/bin/wtmpcvt OLD_FILES+=usr/share/man/man1/wtmpcvt.1.gz # 20111214: eventtimers(7) moved to eventtimers(4) OLD_FILES+=usr/share/man/man7/eventtimers.7.gz # 20111125: amd(4) removed OLD_FILES+=usr/share/man/man4/amd.4.gz # 20111125: libodialog removed OLD_FILES+=usr/lib/libodialog.a OLD_FILES+=usr/lib/libodialog.so OLD_LIBS+=usr/lib/libodialog.so.7 OLD_FILES+=usr/lib/libodialog_p.a # 20110930: sysinstall removed OLD_FILES+=usr/sbin/sysinstall OLD_FILES+=usr/share/man/man8/sysinstall.8.gz OLD_FILES+=usr/lib/libftpio.a OLD_FILES+=usr/lib/libftpio.so OLD_LIBS+=usr/lib/libftpio.so.8 OLD_FILES+=usr/lib/libftpio_p.a OLD_FILES+=usr/include/ftpio.h OLD_FILES+=usr/share/man/man3/ftpio.3.gz # 20110915: rename congestion control manpages OLD_FILES+=usr/share/man/man9/cc.9.gz # 20110831: atomic page flags operations OLD_FILES+=usr/share/man/man9/vm_page_flag.9.gz OLD_FILES+=usr/share/man/man9/vm_page_flag_clear.9.gz OLD_FILES+=usr/share/man/man9/vm_page_flag_set.9.gz # 20110828: library version bump for 9.0 OLD_LIBS+=lib/libcam.so.5 OLD_LIBS+=lib/libpcap.so.7 OLD_LIBS+=lib/libufs.so.5 OLD_LIBS+=usr/lib/libbsnmp.so.5 OLD_LIBS+=usr/lib/libdwarf.so.2 OLD_LIBS+=usr/lib/libopie.so.6 OLD_LIBS+=usr/lib/librtld_db.so.1 OLD_LIBS+=usr/lib/libtacplus.so.4 # 20110817: no more acd.4, ad.4, afd.4 and ast.4 OLD_FILES+=usr/share/man/man4/acd.4.gz OLD_FILES+=usr/share/man/man4/ad.4.gz OLD_FILES+=usr/share/man/man4/afd.4.gz OLD_FILES+=usr/share/man/man4/ast.4.gz # 20110718: no longer useful in the age of rc.d OLD_FILES+=usr/sbin/named.reconfig OLD_FILES+=usr/sbin/named.reload OLD_FILES+=usr/share/man/man8/named.reconfig.8.gz OLD_FILES+=usr/share/man/man8/named.reload.8.gz # 20110716: bind 9.8.0 import OLD_LIBS+=usr/lib/liblwres.so.50 OLD_FILES+=usr/share/doc/bind9/KNOWN-DEFECTS OLD_FILES+=usr/share/doc/bind9/NSEC3-NOTES OLD_FILES+=usr/share/doc/bind9/README.idnkit OLD_FILES+=usr/share/doc/bind9/README.pkcs11 # 20110709: vm_map_clean.9 -> vm_map_sync.9 OLD_FILES+=usr/share/man/man9/vm_map_clean.9.gz # 20110709: Catch up with removal of these functions OLD_FILES+=usr/share/man/man9/vm_page_copy.9.gz OLD_FILES+=usr/share/man/man9/vm_page_protect.9.gz OLD_FILES+=usr/share/man/man9/vm_page_zero_fill.9.gz # 20110707: script no longer needed by /etc/rc.d/nfsd OLD_FILES+=etc/rc.d/nfsserver # 20110705: files moved so both NFS clients can share them OLD_FILES+=usr/include/nfsclient/krpc.h OLD_FILES+=usr/include/nfsclient/nfsdiskless.h # 20110705: the switch of default NFS client to the new one OLD_FILES+=sbin/mount_newnfs OLD_FILES+=usr/share/man/man8/mount_newnfs.8.gz OLD_FILES+=usr/include/nfsclient/nfs_kdtrace.h # 20110628: calendar.msk removed OLD_FILES+=usr/share/calendar/ru_RU.KOI8-R/calendar.msk # 20110517: libpkg removed OLD_FILES+=usr/include/pkg.h OLD_FILES+=usr/lib/libpkg.a OLD_FILES+=usr/lib/libpkg.so OLD_LIBS+=usr/lib/libpkg.so.0 OLD_FILES+=usr/lib/libpkg_p.a # 20110517: libsbuf version bump OLD_LIBS+=lib/libsbuf.so.5 # 20110502: new clang import which bumps version from 2.9 to 3.0 OLD_FILES+=usr/include/clang/2.9/emmintrin.h OLD_FILES+=usr/include/clang/2.9/mm_malloc.h OLD_FILES+=usr/include/clang/2.9/mmintrin.h OLD_FILES+=usr/include/clang/2.9/pmmintrin.h OLD_FILES+=usr/include/clang/2.9/tmmintrin.h OLD_FILES+=usr/include/clang/2.9/xmmintrin.h OLD_DIRS+=usr/include/clang/2.9 # 20110417: removal of Objective-C support OLD_FILES+=usr/include/objc/encoding.h OLD_FILES+=usr/include/objc/hash.h OLD_FILES+=usr/include/objc/NXConstStr.h OLD_FILES+=usr/include/objc/objc-api.h OLD_FILES+=usr/include/objc/objc-decls.h OLD_FILES+=usr/include/objc/objc-list.h OLD_FILES+=usr/include/objc/objc.h OLD_FILES+=usr/include/objc/Object.h OLD_FILES+=usr/include/objc/Protocol.h OLD_FILES+=usr/include/objc/runtime.h OLD_FILES+=usr/include/objc/sarray.h OLD_FILES+=usr/include/objc/thr.h OLD_FILES+=usr/include/objc/typedstream.h OLD_FILES+=usr/lib/libobjc.a OLD_FILES+=usr/lib/libobjc.so OLD_FILES+=usr/lib/libobjc_p.a OLD_FILES+=usr/libexec/cc1obj OLD_LIBS+=usr/lib/libobjc.so.4 OLD_DIRS+=usr/include/objc # 20110331: firmware.img created at build time OLD_FILES+=usr/share/examples/kld/firmware/fwimage/firmware.img # 20110224: sticky.8 -> sticky.7 OLD_FILES+=usr/share/man/man8/sticky.8.gz # 20110220: new clang import which bumps version from 2.8 to 2.9 OLD_FILES+=usr/include/clang/2.8/emmintrin.h OLD_FILES+=usr/include/clang/2.8/mm_malloc.h OLD_FILES+=usr/include/clang/2.8/mmintrin.h OLD_FILES+=usr/include/clang/2.8/pmmintrin.h OLD_FILES+=usr/include/clang/2.8/tmmintrin.h OLD_FILES+=usr/include/clang/2.8/xmmintrin.h OLD_DIRS+=usr/include/clang/2.8 # 20110119: netinet/sctp_cc_functions.h removed OLD_FILES+=usr/include/netinet/sctp_cc_functions.h # 20110119: Remove SYSCTL_*X* sysctl additions OLD_FILES+=usr/share/man/man9/SYSCTL_XINT.9.gz \ usr/share/man/man9/SYSCTL_XLONG.9.gz # 20110112: Update dialog to new version, rename old libdialog to libodialog, # removing associated man pages and header files. OLD_FILES+=usr/share/man/man3/draw_shadow.3.gz \ usr/share/man/man3/draw_box.3.gz usr/share/man/man3/line_edit.3.gz \ usr/share/man/man3/strheight.3.gz usr/share/man/man3/strwidth.3.gz \ usr/share/man/man3/dialog_create_rc.3.gz \ usr/share/man/man3/dialog_yesno.3.gz usr/share/man/man3/dialog_noyes.3.gz \ usr/share/man/man3/dialog_prgbox.3.gz \ usr/share/man/man3/dialog_textbox.3.gz usr/share/man/man3/dialog_menu.3.gz \ usr/share/man/man3/dialog_checklist.3.gz \ usr/share/man/man3/dialog_radiolist.3.gz \ usr/share/man/man3/dialog_inputbox.3.gz \ usr/share/man/man3/dialog_clear_norefresh.3.gz \ usr/share/man/man3/dialog_clear.3.gz usr/share/man/man3/dialog_update.3.gz \ usr/share/man/man3/dialog_fselect.3.gz \ usr/share/man/man3/dialog_notify.3.gz \ usr/share/man/man3/dialog_mesgbox.3.gz \ usr/share/man/man3/dialog_gauge.3.gz usr/share/man/man3/init_dialog.3.gz \ usr/share/man/man3/end_dialog.3.gz usr/share/man/man3/use_helpfile.3.gz \ usr/share/man/man3/use_helpline.3.gz usr/share/man/man3/get_helpline.3.gz \ usr/share/man/man3/restore_helpline.3.gz \ usr/share/man/man3/dialog_msgbox.3.gz \ usr/share/man/man3/dialog_ftree.3.gz usr/share/man/man3/dialog_tree.3.gz \ usr/share/examples/dialog/README usr/share/examples/dialog/checklist \ usr/share/examples/dialog/ftreebox usr/share/examples/dialog/infobox \ usr/share/examples/dialog/inputbox usr/share/examples/dialog/menubox \ usr/share/examples/dialog/msgbox usr/share/examples/dialog/prgbox \ usr/share/examples/dialog/radiolist usr/share/examples/dialog/textbox \ usr/share/examples/dialog/treebox usr/share/examples/dialog/yesno \ usr/share/examples/libdialog/Makefile usr/share/examples/libdialog/check1.c\ usr/share/examples/libdialog/check2.c usr/share/examples/libdialog/check3.c\ usr/share/examples/libdialog/dselect.c \ usr/share/examples/libdialog/fselect.c \ usr/share/examples/libdialog/ftree1.c \ usr/share/examples/libdialog/ftree1.test \ usr/share/examples/libdialog/ftree2.c \ usr/share/examples/libdialog/ftree2.test \ usr/share/examples/libdialog/gauge.c usr/share/examples/libdialog/input1.c \ usr/share/examples/libdialog/input2.c usr/share/examples/libdialog/menu1.c \ usr/share/examples/libdialog/menu2.c usr/share/examples/libdialog/menu3.c \ usr/share/examples/libdialog/msg.c usr/share/examples/libdialog/prgbox.c \ usr/share/examples/libdialog/radio1.c usr/share/examples/libdialog/radio2.c\ usr/share/examples/libdialog/radio3.c usr/share/examples/libdialog/text.c \ usr/share/examples/libdialog/tree.c usr/share/examples/libdialog/yesno.c OLD_DIRS+=usr/share/examples/libdialog usr/share/examples/dialog # 20101114: Remove long-obsolete MAKEDEV.8 OLD_FILES+=usr/share/man/man8/MAKEDEV.8.gz # 20101112: vgonel(9) has gone to private API a while ago OLD_FILES+=usr/share/man/man9/vgonel.9.gz # 20101112: removed gasp.info OLD_FILES+=usr/share/info/gasp.info.gz # 20101109: machine/mutex.h removed OLD_FILES+=usr/include/machine/mutex.h # 20101109: headers moved from machine/ to x86/ .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386" OLD_FILES+=usr/include/machine/mptable.h .endif # 20101101: headers moved from machine/ to x86/ .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386" OLD_FILES+=usr/include/machine/apicreg.h OLD_FILES+=usr/include/machine/mca.h .endif # 20101020: catch up with vm_page_sleep_if_busy rename OLD_FILES+=usr/share/man/man9/vm_page_sleep_busy.9.gz # 20101018: taskqueue(9) updates OLD_FILES+=usr/share/man/man9/taskqueue_find.9.gz # 20101011: removed subblock.h from liblzma OLD_FILES+=usr/include/lzma/subblock.h # 20101002: removed manpath.config OLD_FILES+=etc/manpath.config OLD_FILES+=usr/share/examples/etc/manpath.config # 20100910: renamed sbuf_overflowed to sbuf_error OLD_FILES+=usr/share/man/man9/sbuf_overflowed.9.gz # 20100815: retired last traces of chooseproc(9) OLD_FILES+=usr/share/man/man9/chooseproc.9.gz # 20100806: removal of unused libcompat routines OLD_FILES+=usr/share/man/man3/ascftime.3.gz OLD_FILES+=usr/share/man/man3/cfree.3.gz OLD_FILES+=usr/share/man/man3/cftime.3.gz OLD_FILES+=usr/share/man/man3/getpw.3.gz # 20100725: acpi_aiboost(4) removal OLD_FILES+=usr/share/man/man4/acpi_aiboost.4.gz # 20100724: nfsclient/nfs_lock.h moved to nfs/nfs_lock.h OLD_FILES+=usr/include/nfsclient/nfs_lock.h # 20100720: new clang import which bumps version from 2.0 to 2.8 OLD_FILES+=usr/include/clang/2.0/emmintrin.h OLD_FILES+=usr/include/clang/2.0/mm_malloc.h OLD_FILES+=usr/include/clang/2.0/mmintrin.h OLD_FILES+=usr/include/clang/2.0/pmmintrin.h OLD_FILES+=usr/include/clang/2.0/tmmintrin.h OLD_FILES+=usr/include/clang/2.0/xmmintrin.h OLD_DIRS+=usr/include/clang/2.0 # 20100706: removed pc-sysinstall's detect-vmware.sh OLD_FILES+=usr/share/pc-sysinstall/backend-query/detect-vmware.sh # 20100701: [powerpc] removed .if ${TARGET_ARCH} == "powerpc" OLD_FILES+=usr/include/machine/intr.h .endif # 20100514: library version bump for versioned symbols for liblzma OLD_LIBS+=usr/lib/liblzma.so.0 # 20100511: move GCC-specific headers to /usr/include/gcc .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386" OLD_FILES+=usr/include/emmintrin.h OLD_FILES+=usr/include/mm_malloc.h OLD_FILES+=usr/include/pmmintrin.h OLD_FILES+=usr/include/xmmintrin.h .endif .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386" || ${TARGET_ARCH} == "arm" OLD_FILES+=usr/include/mmintrin.h .endif .if ${TARGET_ARCH} == "powerpc" OLD_FILES+=usr/include/altivec.h OLD_FILES+=usr/include/ppc-asm.h OLD_FILES+=usr/include/spe.h .endif # 20100416: [mips] removed .if ${TARGET_ARCH} == "mips" OLD_FILES+=usr/include/machine/psl.h .endif # 20100415: [mips] removed unused headers .if ${TARGET_ARCH} == "mips" OLD_FILES+=usr/include/machine/archtype.h OLD_FILES+=usr/include/machine/segments.h OLD_FILES+=usr/include/machine/rm7000.h OLD_FILES+=usr/include/machine/defs.h OLD_FILES+=usr/include/machine/queue.h .endif # 20100326: gcpio removal OLD_FILES+=usr/bin/gcpio OLD_FILES+=usr/share/info/cpio.info.gz OLD_FILES+=usr/share/man/man1/gcpio.1.gz # 20100322: libz update OLD_LIBS+=lib/libz.so.5 # 20100314: removal of regexp.h OLD_FILES+=usr/include/regexp.h OLD_FILES+=usr/share/man/man3/regexp.3.gz OLD_FILES+=usr/share/man/man3/regsub.3.gz # 20100303: actual removal of utmp.h OLD_FILES+=usr/include/utmp.h # 20100208: man pages moved .if ${TARGET_ARCH} == "i386" OLD_FILES+=usr/share/man/man4/i386/alpm.4.gz OLD_FILES+=usr/share/man/man4/i386/amdpm.4.gz OLD_FILES+=usr/share/man/man4/i386/mcd.4.gz OLD_FILES+=usr/share/man/man4/i386/padlock.4.gz OLD_FILES+=usr/share/man/man4/i386/pcf.4.gz OLD_FILES+=usr/share/man/man4/i386/scd.4.gz OLD_FILES+=usr/share/man/man4/i386/viapm.4.gz .endif # 20100122: move BSDL bc/dc USD documents to /usr/share/doc/usd OLD_FILES+=usr/share/doc/papers/bc.ascii.gz OLD_FILES+=usr/share/doc/papers/dc.ascii.gz # 20100120: replacing GNU bc/dc with BSDL versions OLD_FILES+=usr/share/examples/bc/ckbook.b OLD_FILES+=usr/share/examples/bc/pi.b OLD_FILES+=usr/share/examples/bc/primes.b OLD_FILES+=usr/share/examples/bc/twins.b OLD_FILES+=usr/share/info/dc.info.gz OLD_DIRS+=usr/share/examples/bc # 20100114: removal of ttyslot(3) OLD_FILES+=usr/share/man/man3/ttyslot.3.gz # 20100113: remove utmp.h, replace it by utmpx.h OLD_FILES+=usr/share/man/man3/login.3.gz OLD_FILES+=usr/share/man/man3/logout.3.gz OLD_FILES+=usr/share/man/man3/logwtmp.3.gz OLD_FILES+=usr/share/man/man3/ulog_endutxent.3.gz OLD_FILES+=usr/share/man/man3/ulog_getutxent.3.gz OLD_FILES+=usr/share/man/man3/ulog_getutxline.3.gz OLD_FILES+=usr/share/man/man3/ulog_getutxuser.3.gz OLD_FILES+=usr/share/man/man3/ulog_pututxline.3.gz OLD_FILES+=usr/share/man/man3/ulog_setutxent.3.gz OLD_FILES+=usr/share/man/man3/ulog_setutxfile.3.gz OLD_FILES+=usr/share/man/man5/lastlog.5.gz OLD_FILES+=usr/share/man/man5/utmp.5.gz OLD_FILES+=usr/share/man/man5/wtmp.5.gz OLD_LIBS+=lib/libutil.so.8 # 20100105: new userland semaphore implementation OLD_FILES+=usr/include/sys/semaphore.h # 20100103: ntptrace(8) removed OLD_FILES+=usr/sbin/ntptrace OLD_FILES+=usr/share/man/man8/ntptrace.8.gz # 20091229: remove no longer relevant examples OLD_FILES+=usr/share/examples/pppd/auth-down.sample OLD_FILES+=usr/share/examples/pppd/auth-up.sample OLD_FILES+=usr/share/examples/pppd/chap-secrets.sample OLD_FILES+=usr/share/examples/pppd/chat.sh.sample OLD_FILES+=usr/share/examples/pppd/ip-down.sample OLD_FILES+=usr/share/examples/pppd/ip-up.sample OLD_FILES+=usr/share/examples/pppd/options.sample OLD_FILES+=usr/share/examples/pppd/pap-secrets.sample OLD_FILES+=usr/share/examples/pppd/ppp.deny.sample OLD_FILES+=usr/share/examples/pppd/ppp.shells.sample OLD_DIRS+=usr/share/examples/pppd OLD_FILES+=usr/share/examples/slattach/unit-command.sh OLD_DIRS+=usr/share/examples/slattach OLD_FILES+=usr/share/examples/sliplogin/slip.hosts OLD_FILES+=usr/share/examples/sliplogin/slip.login OLD_FILES+=usr/share/examples/sliplogin/slip.logout OLD_FILES+=usr/share/examples/sliplogin/slip.slparms OLD_DIRS+=usr/share/examples/sliplogin OLD_FILES+=usr/share/examples/startslip/sldown.sh OLD_FILES+=usr/share/examples/startslip/slip.sh OLD_FILES+=usr/share/examples/startslip/slup.sh OLD_DIRS+=usr/share/examples/startslip # 20091202: unify rc.firewall and rc.firewall6 OLD_FILES+=etc/rc.d/ip6fw OLD_FILES+=etc/rc.firewall6 OLD_FILES+=usr/share/examples/etc/rc.firewall6 # 20091117: removal of rc.early(8) link OLD_FILES+=usr/share/man/man8/rc.early.8.gz # 20091027: pselect.3 implemented as syscall OLD_FILES+=usr/share/man/man3/pselect.3.gz # 20091005: fusword.9 and susword.9 removed OLD_FILES+=usr/share/man/man9/fusword.9.gz OLD_FILES+=usr/share/man/man9/susword.9.gz # 20090909: vesa and dpms promoted to be i386/amd64 common OLD_FILES+=usr/include/machine/pc/vesa.h OLD_FILES+=usr/share/man/man4/i386/dpms.4.gz # 20090904: remove lukemftpd OLD_FILES+=usr/libexec/lukemftpd OLD_FILES+=usr/share/man/man5/ftpd.conf.5.gz OLD_FILES+=usr/share/man/man5/ftpusers.5.gz OLD_FILES+=usr/share/man/man8/lukemftpd.8.gz # 20090902: BSD.{x11,x11-4}.dist are dead and BSD.local.dist lives in ports/ OLD_FILES+=etc/mtree/BSD.local.dist OLD_FILES+=etc/mtree/BSD.x11.dist OLD_FILES+=etc/mtree/BSD.x11-4.dist # 20090812: net80211 documentation overhaul OLD_FILES+=usr/share/man/man9/ieee80211_add_rates.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_add_xrates.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_alloc_node.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_attach.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_begin_scan.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_cfgget.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_cfgset.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_chan2ieee.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_chan2mode.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_create_ibss.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_crypto_attach.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_crypto_detach.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_decap.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_dump_pkt.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_dup_bss.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_encap.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_end_scan.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_find_node.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_fix_rate.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_free_allnodes.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_ieee2mhz.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_ioctl.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_lookup_node.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_media2rate.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_media_change.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_media_init.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_media_status.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_mhz2ieee.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_next_scan.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_node_attach.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_node_detach.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_node_lateattach.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_print_essid.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_proto_attach.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_proto_detach.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_rate2media.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_recv_mgmt.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_send_mgmt.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_setmode.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_timeout_nodes.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_watchdog.9.gz OLD_FILES+=usr/share/man/man9/ieee80211_wep_crypt.9.gz # 20090801: vimage.h removed in favour of vnet.h OLD_FILES+=usr/include/sys/vimage.h # 20101208: libbsnmp was moved to usr/lib MOVED_LIBS+=lib/libbsnmp.so.5 # 20090719: library version bump for 8.0 OLD_LIBS+=lib/libalias.so.6 OLD_LIBS+=lib/libavl.so.1 OLD_LIBS+=lib/libbegemot.so.3 OLD_LIBS+=lib/libbsdxml.so.3 OLD_LIBS+=lib/libbsnmp.so.4 OLD_LIBS+=lib/libcam.so.4 OLD_LIBS+=lib/libcrypt.so.4 OLD_LIBS+=lib/libcrypto.so.5 OLD_LIBS+=lib/libctf.so.1 OLD_LIBS+=lib/libdevstat.so.6 OLD_LIBS+=lib/libdtrace.so.1 OLD_LIBS+=lib/libedit.so.6 OLD_LIBS+=lib/libgeom.so.4 OLD_LIBS+=lib/libipsec.so.3 OLD_LIBS+=lib/libipx.so.4 OLD_LIBS+=lib/libkiconv.so.3 OLD_LIBS+=lib/libkvm.so.4 OLD_LIBS+=lib/libmd.so.4 OLD_LIBS+=lib/libncurses.so.7 OLD_LIBS+=lib/libncursesw.so.7 OLD_LIBS+=lib/libnvpair.so.1 OLD_LIBS+=lib/libpcap.so.6 OLD_LIBS+=lib/libreadline.so.7 OLD_LIBS+=lib/libsbuf.so.4 OLD_LIBS+=lib/libufs.so.4 OLD_LIBS+=lib/libumem.so.1 OLD_LIBS+=lib/libutil.so.7 OLD_LIBS+=lib/libuutil.so.1 OLD_LIBS+=lib/libz.so.4 OLD_LIBS+=lib/libzfs.so.1 OLD_LIBS+=lib/libzpool.so.1 OLD_LIBS+=usr/lib/libarchive.so.4 OLD_LIBS+=usr/lib/libauditd.so.4 OLD_LIBS+=usr/lib/libbluetooth.so.3 OLD_LIBS+=usr/lib/libbsm.so.2 OLD_LIBS+=usr/lib/libbz2.so.3 OLD_LIBS+=usr/lib/libcalendar.so.4 OLD_LIBS+=usr/lib/libcom_err.so.4 OLD_LIBS+=usr/lib/libdevinfo.so.4 OLD_LIBS+=usr/lib/libdialog.so.6 OLD_LIBS+=usr/lib/libdwarf.so.1 OLD_LIBS+=usr/lib/libfetch.so.5 OLD_LIBS+=usr/lib/libform.so.4 OLD_LIBS+=usr/lib/libformw.so.4 OLD_LIBS+=usr/lib/libftpio.so.7 OLD_LIBS+=usr/lib/libgnuregex.so.4 OLD_LIBS+=usr/lib/libgpib.so.2 OLD_LIBS+=usr/lib/libhistory.so.7 OLD_LIBS+=usr/lib/libmagic.so.3 OLD_LIBS+=usr/lib/libmemstat.so.2 OLD_LIBS+=usr/lib/libmenu.so.4 OLD_LIBS+=usr/lib/libmenuw.so.4 OLD_LIBS+=usr/lib/libmilter.so.4 OLD_LIBS+=usr/lib/libncp.so.3 OLD_LIBS+=usr/lib/libnetgraph.so.3 OLD_LIBS+=usr/lib/libngatm.so.3 OLD_LIBS+=usr/lib/libobjc.so.3 OLD_LIBS+=usr/lib/libopie.so.5 OLD_LIBS+=usr/lib/libpam.so.4 OLD_LIBS+=usr/lib/libpanel.so.4 OLD_LIBS+=usr/lib/libpanelw.so.4 OLD_LIBS+=usr/lib/libpmc.so.4 OLD_LIBS+=usr/lib/libproc.so.1 OLD_LIBS+=usr/lib/libradius.so.3 OLD_LIBS+=usr/lib/librpcsvc.so.4 OLD_LIBS+=usr/lib/libsdp.so.3 OLD_LIBS+=usr/lib/libsmb.so.3 OLD_LIBS+=usr/lib/libssh.so.4 OLD_LIBS+=usr/lib/libssl.so.5 OLD_LIBS+=usr/lib/libtacplus.so.3 OLD_LIBS+=usr/lib/libugidfw.so.3 OLD_LIBS+=usr/lib/libusb.so.1 OLD_LIBS+=usr/lib/libusbhid.so.3 OLD_LIBS+=usr/lib/libvgl.so.5 OLD_LIBS+=usr/lib/libwrap.so.5 OLD_LIBS+=usr/lib/libypclnt.so.3 OLD_LIBS+=usr/lib/pam_chroot.so.4 OLD_LIBS+=usr/lib/pam_deny.so.4 OLD_LIBS+=usr/lib/pam_echo.so.4 OLD_LIBS+=usr/lib/pam_exec.so.4 OLD_LIBS+=usr/lib/pam_ftpusers.so.4 OLD_LIBS+=usr/lib/pam_group.so.4 OLD_LIBS+=usr/lib/pam_guest.so.4 OLD_LIBS+=usr/lib/pam_krb5.so.4 OLD_LIBS+=usr/lib/pam_ksu.so.4 OLD_LIBS+=usr/lib/pam_lastlog.so.4 OLD_LIBS+=usr/lib/pam_login_access.so.4 OLD_LIBS+=usr/lib/pam_nologin.so.4 OLD_LIBS+=usr/lib/pam_opie.so.4 OLD_LIBS+=usr/lib/pam_opieaccess.so.4 OLD_LIBS+=usr/lib/pam_passwdqc.so.4 OLD_LIBS+=usr/lib/pam_permit.so.4 OLD_LIBS+=usr/lib/pam_radius.so.4 OLD_LIBS+=usr/lib/pam_rhosts.so.4 OLD_LIBS+=usr/lib/pam_rootok.so.4 OLD_LIBS+=usr/lib/pam_securetty.so.4 OLD_LIBS+=usr/lib/pam_self.so.4 OLD_LIBS+=usr/lib/pam_ssh.so.4 OLD_LIBS+=usr/lib/pam_tacplus.so.4 OLD_LIBS+=usr/lib/pam_unix.so.4 OLD_LIBS+=usr/lib/snmp_atm.so.5 OLD_LIBS+=usr/lib/snmp_bridge.so.5 OLD_LIBS+=usr/lib/snmp_hostres.so.5 OLD_LIBS+=usr/lib/snmp_mibII.so.5 OLD_LIBS+=usr/lib/snmp_netgraph.so.5 OLD_LIBS+=usr/lib/snmp_pf.so.5 # 20090718: the gdm pam.d file is no longer required OLD_FILES+=etc/pam.d/gdm # 20090714: net_add_domain(9) renamed to domain_add(9) OLD_FILES+=usr/share/man/man9/net_add_domain.9.gz # 20090713: vimage container structs removed OLD_FILES+=usr/include/netinet/vinet.h OLD_FILES+=usr/include/netinet6/vinet6.h OLD_FILES+=usr/include/netipsec/vipsec.h # 20090712: ieee80211.4 -> net80211.4 OLD_FILES+=usr/share/man/man4/ieee80211.4.gz # 20090711: typo fixed, kproc_resume,.9 -> kproc_resume.9 OLD_FILES+=usr/share/man/man9/kproc_resume,.9.gz # 20090709: msgctl.3 msgget.3 msgrcv.3 msgsnd.3 manual pages moved OLD_FILES+=usr/share/man/man3/msgctl.3.gz OLD_FILES+=usr/share/man/man3/msgget.3.gz OLD_FILES+=usr/share/man/man3/msgrcv.3.gz OLD_FILES+=usr/share/man/man3/msgsnd.3.gz # 20090630: old kernel RPC implementation removal OLD_FILES+=usr/include/nfs/rpcv2.h # 20090624: update usbdi(9) OLD_FILES+=usr/share/man/man9/usbd_abort_default_pipe.9.gz OLD_FILES+=usr/share/man/man9/usbd_abort_pipe.9.gz OLD_FILES+=usr/share/man/man9/usbd_alloc_buffer.9.gz OLD_FILES+=usr/share/man/man9/usbd_alloc_xfer.9.gz OLD_FILES+=usr/share/man/man9/usbd_clear_endpoint_stall.9.gz OLD_FILES+=usr/share/man/man9/usbd_clear_endpoint_stall_async.9.gz OLD_FILES+=usr/share/man/man9/usbd_clear_endpoint_toggle.9.gz OLD_FILES+=usr/share/man/man9/usbd_close_pipe.9.gz OLD_FILES+=usr/share/man/man9/usbd_device2interface_handle.9.gz OLD_FILES+=usr/share/man/man9/usbd_do_request_async.9.gz OLD_FILES+=usr/share/man/man9/usbd_do_request_flags_pipe.9.gz OLD_FILES+=usr/share/man/man9/usbd_endpoint_count.9.gz OLD_FILES+=usr/share/man/man9/usbd_find_edesc.9.gz OLD_FILES+=usr/share/man/man9/usbd_find_idesc.9.gz OLD_FILES+=usr/share/man/man9/usbd_free_buffer.9.gz OLD_FILES+=usr/share/man/man9/usbd_free_xfer.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_buffer.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_config.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_config_desc.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_config_desc_full.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_config_descriptor.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_device_descriptor.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_endpoint_descriptor.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_interface_altindex.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_interface_descriptor.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_no_alts.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_quirks.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_speed.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_string.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_string_desc.9.gz OLD_FILES+=usr/share/man/man9/usbd_get_xfer_status.9.gz OLD_FILES+=usr/share/man/man9/usbd_interface2device_handle.9.gz OLD_FILES+=usr/share/man/man9/usbd_interface2endpoint_descriptor.9.gz OLD_FILES+=usr/share/man/man9/usbd_interface_count.9.gz OLD_FILES+=usr/share/man/man9/usbd_open_pipe.9.gz OLD_FILES+=usr/share/man/man9/usbd_open_pipe_intr.9.gz OLD_FILES+=usr/share/man/man9/usbd_pipe2device_handle.9.gz OLD_FILES+=usr/share/man/man9/usbd_set_config_index.9.gz OLD_FILES+=usr/share/man/man9/usbd_set_config_no.9.gz OLD_FILES+=usr/share/man/man9/usbd_set_interface.9.gz OLD_FILES+=usr/share/man/man9/usbd_setup_default_xfer.9.gz OLD_FILES+=usr/share/man/man9/usbd_setup_isoc_xfer.9.gz OLD_FILES+=usr/share/man/man9/usbd_setup_xfer.9.gz OLD_FILES+=usr/share/man/man9/usbd_sync_transfer.9.gz OLD_FILES+=usr/share/man/man9/usbd_transfer.9.gz OLD_FILES+=usr/share/man/man9/usb_find_desc.9.gz # 20090623: number of headers needed for a usb driver reduced OLD_FILES+=usr/include/dev/usb/usb_defs.h OLD_FILES+=usr/include/dev/usb/usb_error.h OLD_FILES+=usr/include/dev/usb/usb_handle_request.h OLD_FILES+=usr/include/dev/usb/usb_hid.h OLD_FILES+=usr/include/dev/usb/usb_lookup.h OLD_FILES+=usr/include/dev/usb/usb_mfunc.h OLD_FILES+=usr/include/dev/usb/usb_parse.h OLD_FILES+=usr/include/dev/usb/usb_revision.h # 20090609: devclass_add_driver is no longer public OLD_FILES+=usr/share/man/man9/devclass_add_driver.9.gz OLD_FILES+=usr/share/man/man9/devclass_delete_driver.9.gz OLD_FILES+=usr/share/man/man9/devclass_find_driver.9.gz # 20090605: removal of clists OLD_FILES+=usr/include/sys/clist.h # 20090602: removal of window(1) OLD_FILES+=usr/bin/window OLD_FILES+=usr/share/man/man1/window.1.gz # 20090531: bind 9.6.1rc1 import OLD_LIBS+=usr/lib/liblwres.so.30 # 20090530: removal of early.sh OLD_FILES+=etc/rc.d/early.sh # 20090527: renaming of S{LIST,TAILQ}_REMOVE_NEXT() to _REMOVE_AFTER() OLD_FILES+=usr/share/man/man3/SLIST_REMOVE_NEXT.3.gz OLD_FILES+=usr/share/man/man3/STAILQ_REMOVE_NEXT.3.gz # 20090527: removal of legacy USB stack OLD_FILES+=usr/include/legacy/dev/usb/dsbr100io.h OLD_FILES+=usr/include/legacy/dev/usb/ehcireg.h OLD_FILES+=usr/include/legacy/dev/usb/ehcivar.h OLD_FILES+=usr/include/legacy/dev/usb/hid.h OLD_FILES+=usr/include/legacy/dev/usb/if_urtwreg.h OLD_FILES+=usr/include/legacy/dev/usb/if_urtwvar.h OLD_FILES+=usr/include/legacy/dev/usb/ohcireg.h OLD_FILES+=usr/include/legacy/dev/usb/ohcivar.h OLD_FILES+=usr/include/legacy/dev/usb/rio500_usb.h OLD_FILES+=usr/include/legacy/dev/usb/rt2573_ucode.h OLD_FILES+=usr/include/legacy/dev/usb/sl811hsreg.h OLD_FILES+=usr/include/legacy/dev/usb/sl811hsvar.h OLD_FILES+=usr/include/legacy/dev/usb/ubser.h OLD_FILES+=usr/include/legacy/dev/usb/ucomvar.h OLD_FILES+=usr/include/legacy/dev/usb/udbp.h OLD_FILES+=usr/include/legacy/dev/usb/uftdireg.h OLD_FILES+=usr/include/legacy/dev/usb/ugraphire_rdesc.h OLD_FILES+=usr/include/legacy/dev/usb/uhcireg.h OLD_FILES+=usr/include/legacy/dev/usb/uhcivar.h OLD_FILES+=usr/include/legacy/dev/usb/usb.h OLD_FILES+=usr/include/legacy/dev/usb/usb_mem.h OLD_FILES+=usr/include/legacy/dev/usb/usb_port.h OLD_FILES+=usr/include/legacy/dev/usb/usb_quirks.h OLD_FILES+=usr/include/legacy/dev/usb/usbcdc.h OLD_FILES+=usr/include/legacy/dev/usb/usbdi.h OLD_FILES+=usr/include/legacy/dev/usb/usbdi_util.h OLD_FILES+=usr/include/legacy/dev/usb/usbdivar.h OLD_FILES+=usr/include/legacy/dev/usb/usbhid.h OLD_FILES+=usr/include/legacy/dev/usb/uxb360gp_rdesc.h OLD_DIRS+=usr/include/legacy/dev/usb OLD_DIRS+=usr/include/legacy/dev OLD_DIRS+=usr/include/legacy # 20090526: removal of makekey(8) OLD_FILES+=usr/libexec/makekey OLD_FILES+=usr/share/man/man8/makekey.8.gz # 20090522: removal of University of Michigan NFSv4 client OLD_FILES+=etc/rc.d/idmapd OLD_FILES+=sbin/idmapd OLD_FILES+=sbin/mount_nfs4 OLD_FILES+=usr/share/man/man8/idmapd.8.gz OLD_FILES+=usr/share/man/man8/mount_nfs4.8.gz # 20090513: removal of legacy versions of USB network interface drivers OLD_FILES+=usr/include/legacy/dev/usb/if_upgtvar.h OLD_FILES+=usr/include/legacy/dev/usb/usb_ethersubr.h # 20090417: removal of legacy versions of USB network interface drivers OLD_FILES+=usr/include/legacy/dev/usb/if_auereg.h OLD_FILES+=usr/include/legacy/dev/usb/if_axereg.h OLD_FILES+=usr/include/legacy/dev/usb/if_cdcereg.h OLD_FILES+=usr/include/legacy/dev/usb/if_cuereg.h OLD_FILES+=usr/include/legacy/dev/usb/if_kuereg.h OLD_FILES+=usr/include/legacy/dev/usb/if_ruereg.h OLD_FILES+=usr/include/legacy/dev/usb/if_rumreg.h OLD_FILES+=usr/include/legacy/dev/usb/if_rumvar.h OLD_FILES+=usr/include/legacy/dev/usb/if_udavreg.h OLD_FILES+=usr/include/legacy/dev/usb/if_uralreg.h OLD_FILES+=usr/include/legacy/dev/usb/if_uralvar.h OLD_FILES+=usr/include/legacy/dev/usb/if_zydfw.h OLD_FILES+=usr/include/legacy/dev/usb/if_zydreg.h OLD_FILES+=usr/include/legacy/dev/usb/kue_fw.h # 20090416: removal of ar(4), ray(4), sr(4), raycontrol(8) OLD_FILES+=usr/sbin/raycontrol OLD_FILES+=usr/share/man/man4/i386/ar.4.gz OLD_FILES+=usr/share/man/man4/i386/ray.4.gz OLD_FILES+=usr/share/man/man4/i386/sr.4.gz OLD_FILES+=usr/share/man/man8/raycontrol.8.gz # 20090410: VOP_LEASE.9 removed OLD_FILES+=usr/share/man/man9/VOP_LEASE.9.gz # 20090406: usb_sw_transfer.h removed OLD_FILES+=usr/include/dev/usb/usb_sw_transfer.h # 20090405: removal of if_ppp(4) and if_sl(4) OLD_FILES+=sbin/slattach rescue/slattach OLD_FILES+=sbin/startslip rescue/startslip OLD_FILES+=usr/include/net/if_ppp.h OLD_FILES+=usr/include/net/if_pppvar.h OLD_FILES+=usr/include/net/if_slvar.h OLD_FILES+=usr/include/net/ppp_comp.h OLD_FILES+=usr/include/net/slip.h OLD_FILES+=usr/sbin/sliplogin OLD_FILES+=usr/sbin/slstat OLD_FILES+=usr/sbin/pppd OLD_FILES+=usr/sbin/pppstats OLD_FILES+=usr/share/man/man1/startslip.1.gz OLD_FILES+=usr/share/man/man4/if_ppp.4.gz OLD_FILES+=usr/share/man/man4/if_sl.4.gz OLD_FILES+=usr/share/man/man4/ppp.4.gz OLD_FILES+=usr/share/man/man4/sl.4.gz OLD_FILES+=usr/share/man/man8/pppd.8.gz OLD_FILES+=usr/share/man/man8/pppstats.8.gz OLD_FILES+=usr/share/man/man8/slattach.8.gz OLD_FILES+=usr/share/man/man8/slip.8.gz OLD_FILES+=usr/share/man/man8/sliplogin.8.gz OLD_FILES+=usr/share/man/man8/slstat.8.gz # 20090321: libpcap upgraded to 1.0.0 OLD_LIBS+=lib/libpcap.so.5 # 20090319: uscanner(4) has been removed OLD_FILES+=usr/share/man/man4/uscanner.4.gz # 20090313: k8temp(4) renamed to amdtemp(4) OLD_FILES+=usr/share/man/man4/k8temp.4.gz # 20090308: libusb.so.1 renamed OLD_LIBS+=usr/lib/libusb20.so.1 OLD_FILES+=usr/lib/libusb20.a OLD_FILES+=usr/lib/libusb20.so OLD_FILES+=usr/lib/libusb20_p.a OLD_FILES+=usr/include/libusb20_compat01.h OLD_FILES+=usr/include/libusb20_compat10.h # 20090226: libmp(3) functions renamed OLD_LIBS+=usr/lib/libmp.so.6 # 20090223: changeover of USB stacks OLD_FILES+=usr/include/dev/usb2/include/ufm2_ioctl.h OLD_FILES+=usr/include/dev/usb2/include/urio2_ioctl.h OLD_FILES+=usr/include/dev/usb2/include/usb2_cdc.h OLD_FILES+=usr/include/dev/usb2/include/usb2_defs.h OLD_FILES+=usr/include/dev/usb2/include/usb2_devid.h OLD_FILES+=usr/include/dev/usb2/include/usb2_devtable.h OLD_FILES+=usr/include/dev/usb2/include/usb2_endian.h OLD_FILES+=usr/include/dev/usb2/include/usb2_error.h OLD_FILES+=usr/include/dev/usb2/include/usb2_hid.h OLD_FILES+=usr/include/dev/usb2/include/usb2_ioctl.h OLD_FILES+=usr/include/dev/usb2/include/usb2_mfunc.h OLD_FILES+=usr/include/dev/usb2/include/usb2_revision.h OLD_FILES+=usr/include/dev/usb2/include/usb2_standard.h OLD_DIRS+=usr/include/dev/usb2/include OLD_DIRS+=usr/include/dev/usb2 OLD_FILES+=usr/include/dev/usb/dsbr100io.h OLD_FILES+=usr/include/dev/usb/ehcireg.h OLD_FILES+=usr/include/dev/usb/ehcivar.h OLD_FILES+=usr/include/dev/usb/hid.h OLD_FILES+=usr/include/dev/usb/if_auereg.h OLD_FILES+=usr/include/dev/usb/if_axereg.h OLD_FILES+=usr/include/dev/usb/if_cdcereg.h OLD_FILES+=usr/include/dev/usb/if_cuereg.h OLD_FILES+=usr/include/dev/usb/if_kuereg.h OLD_FILES+=usr/include/dev/usb/if_ruereg.h OLD_FILES+=usr/include/dev/usb/if_rumreg.h OLD_FILES+=usr/include/dev/usb/if_rumvar.h OLD_FILES+=usr/include/dev/usb/if_udavreg.h OLD_FILES+=usr/include/dev/usb/if_upgtvar.h OLD_FILES+=usr/include/dev/usb/if_uralreg.h OLD_FILES+=usr/include/dev/usb/if_uralvar.h OLD_FILES+=usr/include/dev/usb/if_urtwreg.h OLD_FILES+=usr/include/dev/usb/if_urtwvar.h OLD_FILES+=usr/include/dev/usb/if_zydfw.h OLD_FILES+=usr/include/dev/usb/if_zydreg.h OLD_FILES+=usr/include/dev/usb/kue_fw.h OLD_FILES+=usr/include/dev/usb/ohcireg.h OLD_FILES+=usr/include/dev/usb/ohcivar.h OLD_FILES+=usr/include/dev/usb/rio500_usb.h OLD_FILES+=usr/include/dev/usb/rt2573_ucode.h OLD_FILES+=usr/include/dev/usb/sl811hsreg.h OLD_FILES+=usr/include/dev/usb/sl811hsvar.h OLD_FILES+=usr/include/dev/usb/ubser.h OLD_FILES+=usr/include/dev/usb/ucomvar.h OLD_FILES+=usr/include/dev/usb/udbp.h OLD_FILES+=usr/include/dev/usb/uftdireg.h OLD_FILES+=usr/include/dev/usb/ugraphire_rdesc.h OLD_FILES+=usr/include/dev/usb/uhcireg.h OLD_FILES+=usr/include/dev/usb/uhcivar.h OLD_FILES+=usr/include/dev/usb/usb_ethersubr.h OLD_FILES+=usr/include/dev/usb/usb_mem.h OLD_FILES+=usr/include/dev/usb/usb_port.h OLD_FILES+=usr/include/dev/usb/usb_quirks.h OLD_FILES+=usr/include/dev/usb/usbcdc.h OLD_FILES+=usr/include/dev/usb/usbdivar.h OLD_FILES+=usr/include/dev/usb/uxb360gp_rdesc.h OLD_FILES+=usr/sbin/usbdevs OLD_FILES+=usr/share/man/man8/usbdevs.8.gz # 20090203: removal of pccard header files OLD_FILES+=usr/include/pccard/cardinfo.h OLD_FILES+=usr/include/pccard/cis.h OLD_DIRS+=usr/include/pccard # 20090203: adding_user.8 moved to adding_user.7 OLD_FILES+=usr/share/man/man8/adding_user.8.gz # 20090102: file 4.26 import OLD_FILES+=usr/share/misc/magic.mime OLD_FILES+=usr/share/misc/magic.mime.mgc # 20081223: bind 9.4.3 import, nsupdate.8 moved to nsupdate.1 OLD_FILES+=usr/share/man/man8/nsupdate.8.gz # 20081223: ipprotosw.h removed OLD_FILES+=usr/include/netinet/ipprotosw.h # 20081123: vfs_mountedon.9 removed OLD_FILES+=usr/share/man/man9/vfs_mountedon.9.gz # 20081023: FREE.9 and MALLOC.9 removed OLD_FILES+=usr/share/man/man9/FREE.9.gz OLD_FILES+=usr/share/man/man9/MALLOC.9.gz # 20080928: removal of inaccurate device_ids(9) manual page OLD_FILES+=usr/share/man/man9/device_ids.9.gz OLD_FILES+=usr/share/man/man9/major.9.gz OLD_FILES+=usr/share/man/man9/minor.9.gz OLD_FILES+=usr/share/man/man9/umajor.9.gz OLD_FILES+=usr/share/man/man9/uminor.9.gz # 20080917: removal of manpage for axed kernel primitive suser(9) OLD_FILES+=usr/share/man/man9/suser.9.gz OLD_FILES+=usr/share/man/man9/suser_cred.9.gz # 20080913: pax removed from rescue OLD_FILES+=rescue/pax # 20080823: removal of unneeded pt_chown, to implement grantpt(3) OLD_FILES+=usr/libexec/pt_chown # 20080822: ntp 4.2.4p5 import OLD_FILES+=usr/share/doc/ntp/driver23.html OLD_FILES+=usr/share/doc/ntp/driver24.html # 20080821: several man pages moved from man4.i386 to man4 .if ${TARGET_ARCH} == "i386" OLD_FILES+=usr/share/man/man4/i386/acpi_aiboost.4.gz OLD_FILES+=usr/share/man/man4/i386/acpi_asus.4.gz OLD_FILES+=usr/share/man/man4/i386/acpi_fujitsu.4.gz OLD_FILES+=usr/share/man/man4/i386/acpi_ibm.4.gz OLD_FILES+=usr/share/man/man4/i386/acpi_panasonic.4.gz OLD_FILES+=usr/share/man/man4/i386/acpi_sony.4.gz OLD_FILES+=usr/share/man/man4/i386/acpi_toshiba.4.gz OLD_FILES+=usr/share/man/man4/i386/ichwd.4.gz OLD_FILES+=usr/share/man/man4/i386/if_ndis.4.gz OLD_FILES+=usr/share/man/man4/i386/io.4.gz OLD_FILES+=usr/share/man/man4/i386/linux.4.gz OLD_FILES+=usr/share/man/man4/i386/ndis.4.gz .endif # 20080820: MPSAFE TTY layer integrated OLD_FILES+=usr/include/sys/linedisc.h OLD_FILES+=usr/share/man/man3/posix_openpt.3.gz # 20080725: sgtty.h removed OLD_FILES+=usr/include/sgtty.h # 20080706: bsdlabel(8) removed on powerpc .if ${TARGET_ARCH} == "powerpc" OLD_FILES+=sbin/bsdlabel OLD_FILES+=usr/share/man/man8/bsdlabel.8.gz .endif # 20080704: sbsh(4) removed OLD_FILES+=usr/share/man/man4/if_sbsh.4.gz OLD_FILES+=usr/share/man/man4/sbsh.4.gz # 20080704: cnw(4) removed OLD_FILES+=usr/share/man/man4/if_cnw.4.gz OLD_FILES+=usr/share/man/man4/cnw.4.gz # 20080704: oltr(4) removed .if ${TARGET_ARCH} == "i386" OLD_FILES+=usr/share/man/man4/i386/if_oltr.4.gz OLD_FILES+=usr/share/man/man4/i386/oltr.4.gz .endif # 20080704: arl(4) removed .if ${TARGET_ARCH} == "i386" OLD_FILES+=usr/sbin/arlcontrol OLD_FILES+=usr/share/man/man4/i386/arl.4.gz OLD_FILES+=usr/share/man/man8/arlcontrol.8.gz .endif # 20080703: sunlabel only for sparc64 .if ${TARGET_ARCH} != "sparc64" OLD_FILES+=sbin/sunlabel OLD_FILES+=usr/share/man/man8/sunlabel.8.gz .endif # 20080701: wpa_supplicant.conf moved to share/examples/etc/ OLD_FILES+=usr/share/examples/wpa_supplicant/wpa_supplicant.conf OLD_DIRS+=usr/share/examples/wpa_supplicant # 20080614: pecoff image activator removed .if ${TARGET_ARCH} == "i386" OLD_FILES+=usr/include/machine/pecoff_machdep.h .endif # 20080614: sgtty removed OLD_FILES+=usr/include/sys/ttychars.h OLD_FILES+=usr/include/sys/ttydev.h OLD_FILES+=usr/share/man/man3/gtty.3.gz OLD_FILES+=usr/share/man/man3/stty.3.gz # 20080609: gpt(8) removed OLD_FILES+=sbin/gpt OLD_FILES+=usr/share/man/man8/gpt.8.gz # 20080525: I4B removed OLD_FILES+=etc/isdn/answer OLD_FILES+=etc/isdn/isdntel OLD_FILES+=etc/isdn/record OLD_FILES+=etc/isdn/tell OLD_FILES+=etc/isdn/tell-record OLD_FILES+=etc/isdn/unknown_incoming OLD_FILES+=etc/isdn/holidays.D OLD_FILES+=etc/isdn/isdnd.rates.A OLD_FILES+=etc/isdn/isdnd.rates.D OLD_FILES+=etc/isdn/isdnd.rates.F OLD_FILES+=etc/isdn/isdnd.rates.L OLD_FILES+=etc/isdn/isdnd.rates.UK.BT OLD_FILES+=etc/isdn/isdnd.rc.sample OLD_FILES+=etc/isdn/isdntel.alias.sample OLD_DIRS+=etc/isdn OLD_FILES+=etc/rc.d/isdnd OLD_FILES+=usr/include/i4b/i4b_cause.h OLD_FILES+=usr/include/i4b/i4b_debug.h OLD_FILES+=usr/include/i4b/i4b_ioctl.h OLD_FILES+=usr/include/i4b/i4b_rbch_ioctl.h OLD_FILES+=usr/include/i4b/i4b_tel_ioctl.h OLD_FILES+=usr/include/i4b/i4b_trace.h OLD_DIRS+=usr/include/i4b OLD_FILES+=usr/sbin/dtmfdecode OLD_FILES+=usr/sbin/g711conv OLD_FILES+=usr/sbin/isdnd OLD_FILES+=usr/sbin/isdndebug OLD_FILES+=usr/sbin/isdndecode OLD_FILES+=usr/sbin/isdnmonitor OLD_FILES+=usr/sbin/isdnphone OLD_FILES+=usr/sbin/isdntel OLD_FILES+=usr/sbin/isdntelctl OLD_FILES+=usr/sbin/isdntrace OLD_FILES+=usr/share/isdn/0.al OLD_FILES+=usr/share/isdn/1.al OLD_FILES+=usr/share/isdn/2.al OLD_FILES+=usr/share/isdn/3.al OLD_FILES+=usr/share/isdn/4.al OLD_FILES+=usr/share/isdn/5.al OLD_FILES+=usr/share/isdn/6.al OLD_FILES+=usr/share/isdn/7.al OLD_FILES+=usr/share/isdn/8.al OLD_FILES+=usr/share/isdn/9.al OLD_FILES+=usr/share/isdn/beep.al OLD_FILES+=usr/share/isdn/msg.al OLD_DIRS+=usr/share/isdn OLD_FILES+=usr/share/man/man1/dtmfdecode.1.gz OLD_FILES+=usr/share/man/man1/g711conv.1.gz OLD_FILES+=usr/share/man/man4/i4b.4.gz OLD_FILES+=usr/share/man/man4/i4bcapi.4.gz OLD_FILES+=usr/share/man/man4/i4bctl.4.gz OLD_FILES+=usr/share/man/man4/i4bing.4.gz OLD_FILES+=usr/share/man/man4/i4bipr.4.gz OLD_FILES+=usr/share/man/man4/i4bisppp.4.gz OLD_FILES+=usr/share/man/man4/i4bq921.4.gz OLD_FILES+=usr/share/man/man4/i4bq931.4.gz OLD_FILES+=usr/share/man/man4/i4brbch.4.gz OLD_FILES+=usr/share/man/man4/i4btel.4.gz OLD_FILES+=usr/share/man/man4/i4btrc.4.gz OLD_FILES+=usr/share/man/man4/iavc.4.gz OLD_FILES+=usr/share/man/man4/isic.4.gz OLD_FILES+=usr/share/man/man4/ifpi.4.gz OLD_FILES+=usr/share/man/man4/ifpi2.4.gz OLD_FILES+=usr/share/man/man4/ifpnp.4.gz OLD_FILES+=usr/share/man/man4/ihfc.4.gz OLD_FILES+=usr/share/man/man4/itjc.4.gz OLD_FILES+=usr/share/man/man4/iwic.4.gz OLD_FILES+=usr/share/man/man5/isdnd.rc.5.gz OLD_FILES+=usr/share/man/man5/isdnd.rates.5.gz OLD_FILES+=usr/share/man/man5/isdnd.acct.5.gz OLD_FILES+=usr/share/man/man8/isdnd.8.gz OLD_FILES+=usr/share/man/man8/isdndebug.8.gz OLD_FILES+=usr/share/man/man8/isdndecode.8.gz OLD_FILES+=usr/share/man/man8/isdnmonitor.8.gz OLD_FILES+=usr/share/man/man8/isdnphone.8.gz OLD_FILES+=usr/share/man/man8/isdntel.8.gz OLD_FILES+=usr/share/man/man8/isdntelctl.8.gz OLD_FILES+=usr/share/man/man8/isdntrace.8.gz OLD_FILES+=usr/share/examples/isdn/contrib/README OLD_FILES+=usr/share/examples/isdn/contrib/anleitung.ppp OLD_FILES+=usr/share/examples/isdn/contrib/answer.c OLD_FILES+=usr/share/examples/isdn/contrib/answer.sh OLD_FILES+=usr/share/examples/isdn/contrib/convert.sh OLD_FILES+=usr/share/examples/isdn/contrib/hplay.c OLD_FILES+=usr/share/examples/isdn/contrib/i4b-ppp-newbie.txt OLD_FILES+=usr/share/examples/isdn/contrib/isdnctl OLD_FILES+=usr/share/examples/isdn/contrib/isdnd_acct OLD_FILES+=usr/share/examples/isdn/contrib/isdnd_acct.pl OLD_FILES+=usr/share/examples/isdn/contrib/isdntelmux.c OLD_FILES+=usr/share/examples/isdn/contrib/mrtg-isp0.sh OLD_FILES+=usr/share/examples/isdn/i4brunppp/Makefile OLD_FILES+=usr/share/examples/isdn/i4brunppp/README OLD_FILES+=usr/share/examples/isdn/i4brunppp/i4brunppp-isdnd.rc OLD_FILES+=usr/share/examples/isdn/i4brunppp/i4brunppp.8 OLD_FILES+=usr/share/examples/isdn/i4brunppp/i4brunppp.c OLD_FILES+=usr/share/examples/isdn/v21/Makefile OLD_FILES+=usr/share/examples/isdn/v21/README OLD_FILES+=usr/share/examples/isdn/v21/v21modem.c OLD_FILES+=usr/share/examples/isdn/FAQ OLD_FILES+=usr/share/examples/isdn/KERNEL OLD_FILES+=usr/share/examples/isdn/Overview OLD_FILES+=usr/share/examples/isdn/README OLD_FILES+=usr/share/examples/isdn/ROADMAP OLD_FILES+=usr/share/examples/isdn/ReleaseNotes OLD_FILES+=usr/share/examples/isdn/Resources OLD_FILES+=usr/share/examples/isdn/SupportedCards OLD_FILES+=usr/share/examples/isdn/ThankYou OLD_DIRS+=usr/share/examples/isdn/contrib OLD_DIRS+=usr/share/examples/isdn/i4brunppp OLD_DIRS+=usr/share/examples/isdn/v21 OLD_DIRS+=usr/share/examples/isdn OLD_FILES+=usr/share/examples/ppp/isdnd.rc OLD_FILES+=usr/share/examples/ppp/ppp.conf.isdn # 20080525: ng_atmpif removed OLD_FILES+=usr/include/netgraph/atm/ng_atmpif.h OLD_FILES+=usr/share/man/man4/ng_atmpif.4.gz # 20080522: pmap_addr_hint removed OLD_FILES+=usr/share/man/man9/pmap_addr_hint.9.gz # 20080517: ipsec_osdep.h removed OLD_FILES+=usr/include/netipsec/ipsec_osdep.h # 20080507: heimdal 1.1 import OLD_LIBS+=usr/lib/libasn1.so.9 OLD_LIBS+=usr/lib/libgssapi.so.9 OLD_LIBS+=usr/lib/libgssapi_krb5.so.9 OLD_LIBS+=usr/lib/libhdb.so.9 OLD_LIBS+=usr/lib/libkadm5clnt.so.9 OLD_LIBS+=usr/lib/libkadm5srv.so.9 OLD_LIBS+=usr/lib/libkafs5.so.9 OLD_LIBS+=usr/lib/libkrb5.so.9 OLD_LIBS+=usr/lib/libroken.so.9 # 20080420: Symbol card support dropped OLD_FILES+=usr/include/dev/wi/spectrum24t_cf.h # 20080420: awi removal OLD_FILES+=usr/share/man/man4/awi.4.gz OLD_FILES+=usr/share/man/man4/if_awi.4.gz # 20080331: pkg_sign has been removed OLD_FILES+=usr/sbin/pkg_check OLD_FILES+=usr/sbin/pkg_sign OLD_FILES+=usr/share/man/man1/pkg_check.1.gz OLD_FILES+=usr/share/man/man1/pkg_sign.1.gz # 20080314: stack_print(9) mlink fixed OLD_FILES+=usr/share/man/man9/stack_printf.9.gz # 20080312: libkse removal OLD_FILES+=usr/include/sys/kse.h OLD_FILES+=usr/lib/libkse.so OLD_LIBS+=usr/lib/libkse.so.3 OLD_FILES+=usr/share/man/man2/kse.2.gz OLD_FILES+=usr/share/man/man2/kse_create.2.gz OLD_FILES+=usr/share/man/man2/kse_exit.2.gz OLD_FILES+=usr/share/man/man2/kse_release.2.gz OLD_FILES+=usr/share/man/man2/kse_switchin.2.gz OLD_FILES+=usr/share/man/man2/kse_thr_interrupt.2.gz OLD_FILES+=usr/share/man/man2/kse_wakeup.2.gz # 20080225: bsdar/bsdranlib rename to ar/ranlib OLD_FILES+=usr/bin/bsdar OLD_FILES+=usr/bin/bsdranlib OLD_FILES+=usr/share/man/man1/bsdar.1.gz OLD_FILES+=usr/share/man/man1/bsdranlib.1.gz # 20080220: geom_lvm rename to geom_linux_lvm OLD_FILES+=usr/share/man/man4/geom_lvm.4.gz # 20080126: oldcard.4 removal OLD_FILES+=usr/share/man/man4/card.4.gz OLD_FILES+=usr/share/man/man4/oldcard.4.gz # 20080122: Removed from the tree OLD_FILES+=usr/share/man/man9/BUF_REFCNT.9.gz # 20080108: Moved to section 2 OLD_FILES+=usr/share/man/man3/shm_open.3.gz OLD_FILES+=usr/share/man/man3/shm_unlink.3.gz # 20071207: Merged with fortunes-o.real OLD_FILES+=usr/share/games/fortune/fortunes2-o OLD_FILES+=usr/share/games/fortune/fortunes2-o.dat # 20071201: Removal of XRPU driver OLD_FILES+=usr/include/sys/xrpuio.h # 20071129: Disabled static versions of libkse by default OLD_FILES+=usr/lib/libkse.a OLD_FILES+=usr/lib/libkse_p.a OLD_FILES+=usr/lib/libkse_pic.a # 20071129: Removed a Solaris compatibility header OLD_FILES+=usr/include/sys/_elf_solaris.h # 20071125: Renamed to pmc_get_msr() OLD_FILES+=usr/share/man/man3/pmc_x86_get_msr.3.gz # 20071108: Removed very crunch OLDCARD support file OLD_FILES+=etc/defaults/pccard.conf # 20071025: rc.d/nfslocking superseded by rc.d/lockd and rc.d/statd OLD_FILES+=etc/rc.d/nfslocking # 20070930: rename of cached to nscd OLD_FILES+=etc/cached.conf OLD_FILES+=etc/rc.d/cached OLD_FILES+=usr/sbin/cached OLD_FILES+=usr/share/man/man5/cached.conf.5.gz OLD_FILES+=usr/share/man/man8/cached.8.gz # 20070807: removal of PowerPC specific header file .if ${TARGET_ARCH} == "powerpc" OLD_FILES+=usr/include/machine/interruptvar.h .endif # 20070801: fast_ipsec.4 gone OLD_FILES+=usr/share/man/man4/fast_ipsec.4.gz # 20070715: netatm temporarily disconnected (removed 20080525) OLD_FILES+=rescue/atm OLD_FILES+=rescue/fore_dnld OLD_FILES+=rescue/ilmid OLD_FILES+=sbin/atm OLD_FILES+=sbin/fore_dnld OLD_FILES+=sbin/ilmid OLD_FILES+=usr/include/libatm.h OLD_FILES+=usr/include/netatm/atm.h OLD_FILES+=usr/include/netatm/atm_cm.h OLD_FILES+=usr/include/netatm/atm_if.h OLD_FILES+=usr/include/netatm/atm_ioctl.h OLD_FILES+=usr/include/netatm/atm_pcb.h OLD_FILES+=usr/include/netatm/atm_sap.h OLD_FILES+=usr/include/netatm/atm_sigmgr.h OLD_FILES+=usr/include/netatm/atm_stack.h OLD_FILES+=usr/include/netatm/atm_sys.h OLD_FILES+=usr/include/netatm/atm_var.h OLD_FILES+=usr/include/netatm/atm_vc.h OLD_FILES+=usr/include/netatm/ipatm/ipatm.h OLD_FILES+=usr/include/netatm/ipatm/ipatm_serv.h OLD_FILES+=usr/include/netatm/ipatm/ipatm_var.h OLD_FILES+=usr/include/netatm/port.h OLD_FILES+=usr/include/netatm/queue.h OLD_FILES+=usr/include/netatm/sigpvc/sigpvc_var.h OLD_FILES+=usr/include/netatm/spans/spans_cls.h OLD_FILES+=usr/include/netatm/spans/spans_kxdr.h OLD_FILES+=usr/include/netatm/spans/spans_var.h OLD_FILES+=usr/include/netatm/uni/sscf_uni.h OLD_FILES+=usr/include/netatm/uni/sscf_uni_var.h OLD_FILES+=usr/include/netatm/uni/sscop.h OLD_FILES+=usr/include/netatm/uni/sscop_misc.h OLD_FILES+=usr/include/netatm/uni/sscop_pdu.h OLD_FILES+=usr/include/netatm/uni/sscop_var.h OLD_FILES+=usr/include/netatm/uni/uni.h OLD_FILES+=usr/include/netatm/uni/uniip_var.h OLD_FILES+=usr/include/netatm/uni/unisig.h OLD_FILES+=usr/include/netatm/uni/unisig_decode.h OLD_FILES+=usr/include/netatm/uni/unisig_mbuf.h OLD_FILES+=usr/include/netatm/uni/unisig_msg.h OLD_FILES+=usr/include/netatm/uni/unisig_print.h OLD_FILES+=usr/include/netatm/uni/unisig_var.h OLD_FILES+=usr/lib/libatm.a OLD_FILES+=usr/lib/libatm_p.a OLD_FILES+=usr/sbin/atmarpd OLD_FILES+=usr/sbin/scspd OLD_FILES+=usr/share/man/en.ISO8859-1/man8/atm.8.gz OLD_FILES+=usr/share/man/en.ISO8859-1/man8/atmarpd.8.gz OLD_FILES+=usr/share/man/en.ISO8859-1/man8/fore_dnld.8.gz OLD_FILES+=usr/share/man/en.ISO8859-1/man8/ilmid.8.gz OLD_FILES+=usr/share/man/en.ISO8859-1/man8/scspd.8.gz OLD_FILES+=usr/share/man/man8/atm.8.gz OLD_FILES+=usr/share/man/man8/atmarpd.8.gz OLD_FILES+=usr/share/man/man8/fore_dnld.8.gz OLD_FILES+=usr/share/man/man8/ilmid.8.gz OLD_FILES+=usr/share/man/man8/scspd.8.gz OLD_FILES+=usr/share/examples/atm/NOTES OLD_FILES+=usr/share/examples/atm/README OLD_FILES+=usr/share/examples/atm/Startup OLD_FILES+=usr/share/examples/atm/atm-config.sh OLD_FILES+=usr/share/examples/atm/atm-sockets.txt OLD_FILES+=usr/share/examples/atm/cpcs-design.txt OLD_FILES+=usr/share/examples/atm/fore-microcode.txt OLD_FILES+=usr/share/examples/atm/sscf-design.txt OLD_FILES+=usr/share/examples/atm/sscop-design.txt OLD_LIBS+=lib/libatm.so.5 OLD_FILES+=usr/lib/libatm.so OLD_DIRS+=usr/include/netatm/sigpvc OLD_DIRS+=usr/include/netatm/spans OLD_DIRS+=usr/include/netatm/ipatm OLD_DIRS+=usr/include/netatm/uni OLD_DIRS+=usr/include/netatm OLD_DIRS+=usr/share/examples/atm # 20070705: I4B headers repo-copied to include/i4b/ .if ${TARGET_ARCH} == "i386" OLD_FILES+=usr/include/machine/i4b_cause.h OLD_FILES+=usr/include/machine/i4b_debug.h OLD_FILES+=usr/include/machine/i4b_ioctl.h OLD_FILES+=usr/include/machine/i4b_rbch_ioctl.h OLD_FILES+=usr/include/machine/i4b_tel_ioctl.h OLD_FILES+=usr/include/machine/i4b_trace.h .endif # 20070703: pf 4.1 import OLD_FILES+=usr/libexec/ftp-proxy # 20070701: KAME IPSec removal OLD_FILES+=usr/include/netinet6/ah.h OLD_FILES+=usr/include/netinet6/ah6.h OLD_FILES+=usr/include/netinet6/ah_aesxcbcmac.h OLD_FILES+=usr/include/netinet6/esp.h OLD_FILES+=usr/include/netinet6/esp6.h OLD_FILES+=usr/include/netinet6/esp_aesctr.h OLD_FILES+=usr/include/netinet6/esp_camellia.h OLD_FILES+=usr/include/netinet6/esp_rijndael.h OLD_FILES+=usr/include/netinet6/ipsec.h OLD_FILES+=usr/include/netinet6/ipsec6.h OLD_FILES+=usr/include/netinet6/ipcomp.h OLD_FILES+=usr/include/netinet6/ipcomp6.h OLD_FILES+=usr/include/netkey/key.h OLD_FILES+=usr/include/netkey/key_debug.h OLD_FILES+=usr/include/netkey/key_var.h OLD_FILES+=usr/include/netkey/keydb.h OLD_FILES+=usr/include/netkey/keysock.h OLD_DIRS+=usr/include/netkey # 20070701: remove wicontrol OLD_FILES+=usr/sbin/wicontrol OLD_FILES+=usr/share/man/man8/wicontrol.8.gz # 20070625: umapfs removal OLD_FILES+=rescue/mount_umapfs OLD_FILES+=sbin/mount_umapfs OLD_FILES+=usr/include/fs/umapfs/umap.h OLD_FILES+=usr/share/man/man8/mount_umapfs.8.gz OLD_DIRS+=usr/include/fs/umapfs # 20070618: Removal of the PROTO.localhost* files OLD_FILES+=etc/namedb/PROTO.localhost-v6.rev OLD_FILES+=etc/namedb/PROTO.localhost.rev OLD_FILES+=etc/namedb/make-localhost # 20070618: shared library version bump OLD_LIBS+=lib/libalias.so.5 OLD_LIBS+=lib/libbsnmp.so.3 OLD_LIBS+=lib/libncurses.so.6 OLD_LIBS+=lib/libncursesw.so.6 OLD_LIBS+=lib/libreadline.so.6 OLD_LIBS+=usr/lib/libdialog.so.5 OLD_LIBS+=usr/lib/libgnuregex.so.3 OLD_LIBS+=usr/lib/libhistory.so.6 OLD_LIBS+=usr/lib/libpam.so.3 OLD_LIBS+=usr/lib/libssh.so.3 OLD_LIBS+=usr/lib/pam_chroot.so.3 OLD_LIBS+=usr/lib/pam_deny.so.3 OLD_LIBS+=usr/lib/pam_echo.so.3 OLD_LIBS+=usr/lib/pam_exec.so.3 OLD_LIBS+=usr/lib/pam_ftpusers.so.3 OLD_LIBS+=usr/lib/pam_group.so.3 OLD_LIBS+=usr/lib/pam_guest.so.3 OLD_LIBS+=usr/lib/pam_krb5.so.3 OLD_LIBS+=usr/lib/pam_ksu.so.3 OLD_LIBS+=usr/lib/pam_lastlog.so.3 OLD_LIBS+=usr/lib/pam_login_access.so.3 OLD_LIBS+=usr/lib/pam_nologin.so.3 OLD_LIBS+=usr/lib/pam_opie.so.3 OLD_LIBS+=usr/lib/pam_opieaccess.so.3 OLD_LIBS+=usr/lib/pam_passwdqc.so.3 OLD_LIBS+=usr/lib/pam_permit.so.3 OLD_LIBS+=usr/lib/pam_radius.so.3 OLD_LIBS+=usr/lib/pam_rhosts.so.3 OLD_LIBS+=usr/lib/pam_rootok.so.3 OLD_LIBS+=usr/lib/pam_securetty.so.3 OLD_LIBS+=usr/lib/pam_self.so.3 OLD_LIBS+=usr/lib/pam_ssh.so.3 OLD_LIBS+=usr/lib/pam_tacplus.so.3 OLD_LIBS+=usr/lib/pam_unix.so.3 OLD_LIBS+=usr/lib/snmp_atm.so.4 OLD_LIBS+=usr/lib/snmp_bridge.so.4 OLD_LIBS+=usr/lib/snmp_hostres.so.4 OLD_LIBS+=usr/lib/snmp_mibII.so.4 OLD_LIBS+=usr/lib/snmp_netgraph.so.4 OLD_LIBS+=usr/lib/snmp_pf.so.4 # 20070613: IPX over IP tunnel removal OLD_FILES+=usr/include/netipx/ipx_ip.h # 20070605: sched_core removal OLD_FILES+=usr/share/man/man4/sched_core.4.gz # 20070603: BIND 9.4.1 import OLD_LIBS+=usr/lib/liblwres.so.10 # 20070521: shared library version bump OLD_LIBS+=lib/libatm.so.4 OLD_LIBS+=lib/libbegemot.so.2 OLD_LIBS+=lib/libbsdxml.so.2 OLD_LIBS+=lib/libcam.so.3 OLD_LIBS+=lib/libcrypt.so.3 OLD_LIBS+=lib/libdevstat.so.5 OLD_LIBS+=lib/libedit.so.5 OLD_LIBS+=lib/libgeom.so.3 OLD_LIBS+=lib/libipsec.so.2 OLD_LIBS+=lib/libipx.so.3 OLD_LIBS+=lib/libkiconv.so.2 OLD_LIBS+=lib/libkse.so.2 OLD_LIBS+=lib/libkvm.so.3 OLD_LIBS+=lib/libm.so.4 OLD_LIBS+=lib/libmd.so.3 OLD_LIBS+=lib/libpcap.so.4 OLD_LIBS+=lib/libpthread.so.2 OLD_LIBS+=lib/libsbuf.so.3 OLD_LIBS+=lib/libthr.so.2 OLD_LIBS+=lib/libufs.so.3 OLD_LIBS+=lib/libutil.so.6 OLD_LIBS+=lib/libz.so.3 OLD_LIBS+=usr/lib/libbluetooth.so.2 OLD_LIBS+=usr/lib/libbsm.so.1 OLD_LIBS+=usr/lib/libbz2.so.2 OLD_LIBS+=usr/lib/libcalendar.so.3 OLD_LIBS+=usr/lib/libcom_err.so.3 OLD_LIBS+=usr/lib/libdevinfo.so.3 OLD_LIBS+=usr/lib/libfetch.so.4 OLD_LIBS+=usr/lib/libform.so.3 OLD_LIBS+=usr/lib/libformw.so.3 OLD_LIBS+=usr/lib/libftpio.so.6 OLD_LIBS+=usr/lib/libgpib.so.1 OLD_LIBS+=usr/lib/libkse.so.2 OLD_LIBS+=usr/lib/libmagic.so.2 OLD_LIBS+=usr/lib/libmemstat.so.1 OLD_LIBS+=usr/lib/libmenu.so.3 OLD_LIBS+=usr/lib/libmenuw.so.3 OLD_LIBS+=usr/lib/libmilter.so.3 OLD_LIBS+=usr/lib/libmp.so.5 OLD_LIBS+=usr/lib/libncp.so.2 OLD_LIBS+=usr/lib/libnetgraph.so.2 OLD_LIBS+=usr/lib/libngatm.so.2 OLD_LIBS+=usr/lib/libopie.so.4 OLD_LIBS+=usr/lib/libpanel.so.3 OLD_LIBS+=usr/lib/libpanelw.so.3 OLD_LIBS+=usr/lib/libpmc.so.3 OLD_LIBS+=usr/lib/libradius.so.2 OLD_LIBS+=usr/lib/librpcsvc.so.3 OLD_LIBS+=usr/lib/libsdp.so.2 OLD_LIBS+=usr/lib/libsmb.so.2 OLD_LIBS+=usr/lib/libstdc++.so.5 OLD_LIBS+=usr/lib/libtacplus.so.2 OLD_LIBS+=usr/lib/libthr.so.2 OLD_LIBS+=usr/lib/libthread_db.so.2 OLD_LIBS+=usr/lib/libugidfw.so.2 OLD_LIBS+=usr/lib/libusbhid.so.2 OLD_LIBS+=usr/lib/libvgl.so.4 OLD_LIBS+=usr/lib/libwrap.so.4 OLD_LIBS+=usr/lib/libypclnt.so.2 OLD_LIBS+=usr/lib/snmp_bridge.so.3 OLD_LIBS+=usr/lib/snmp_hostres.so.3 # 20070519: GCC 4.2 OLD_FILES+=usr/bin/f77 OLD_FILES+=usr/bin/protoize OLD_FILES+=usr/include/g2c.h OLD_FILES+=usr/libexec/f771 OLD_FILES+=usr/share/info/g77.info.gz OLD_FILES+=usr/share/man/man1/f77.1.gz OLD_FILES+=usr/include/c++/3.4/algorithm OLD_FILES+=usr/include/c++/3.4/backward/algo.h OLD_FILES+=usr/include/c++/3.4/backward/algobase.h OLD_FILES+=usr/include/c++/3.4/backward/alloc.h OLD_FILES+=usr/include/c++/3.4/backward/backward_warning.h OLD_FILES+=usr/include/c++/3.4/backward/bvector.h OLD_FILES+=usr/include/c++/3.4/backward/complex.h OLD_FILES+=usr/include/c++/3.4/backward/defalloc.h OLD_FILES+=usr/include/c++/3.4/backward/deque.h OLD_FILES+=usr/include/c++/3.4/backward/fstream.h OLD_FILES+=usr/include/c++/3.4/backward/function.h OLD_FILES+=usr/include/c++/3.4/backward/hash_map.h OLD_FILES+=usr/include/c++/3.4/backward/hash_set.h OLD_FILES+=usr/include/c++/3.4/backward/hashtable.h OLD_FILES+=usr/include/c++/3.4/backward/heap.h OLD_FILES+=usr/include/c++/3.4/backward/iomanip.h OLD_FILES+=usr/include/c++/3.4/backward/iostream.h OLD_FILES+=usr/include/c++/3.4/backward/istream.h OLD_FILES+=usr/include/c++/3.4/backward/iterator.h OLD_FILES+=usr/include/c++/3.4/backward/list.h OLD_FILES+=usr/include/c++/3.4/backward/map.h OLD_FILES+=usr/include/c++/3.4/backward/multimap.h OLD_FILES+=usr/include/c++/3.4/backward/multiset.h OLD_FILES+=usr/include/c++/3.4/backward/new.h OLD_FILES+=usr/include/c++/3.4/backward/ostream.h OLD_FILES+=usr/include/c++/3.4/backward/pair.h OLD_FILES+=usr/include/c++/3.4/backward/queue.h OLD_FILES+=usr/include/c++/3.4/backward/rope.h OLD_FILES+=usr/include/c++/3.4/backward/set.h OLD_FILES+=usr/include/c++/3.4/backward/slist.h OLD_FILES+=usr/include/c++/3.4/backward/stack.h OLD_FILES+=usr/include/c++/3.4/backward/stream.h OLD_FILES+=usr/include/c++/3.4/backward/streambuf.h OLD_FILES+=usr/include/c++/3.4/backward/strstream OLD_FILES+=usr/include/c++/3.4/backward/tempbuf.h OLD_FILES+=usr/include/c++/3.4/backward/tree.h OLD_FILES+=usr/include/c++/3.4/backward/vector.h OLD_FILES+=usr/include/c++/3.4/bits/allocator.h OLD_FILES+=usr/include/c++/3.4/bits/atomic_word.h OLD_FILES+=usr/include/c++/3.4/bits/atomicity.h OLD_FILES+=usr/include/c++/3.4/bits/basic_file.h OLD_FILES+=usr/include/c++/3.4/bits/basic_ios.h OLD_FILES+=usr/include/c++/3.4/bits/basic_ios.tcc OLD_FILES+=usr/include/c++/3.4/bits/basic_string.h OLD_FILES+=usr/include/c++/3.4/bits/basic_string.tcc OLD_FILES+=usr/include/c++/3.4/bits/boost_concept_check.h OLD_FILES+=usr/include/c++/3.4/bits/c++allocator.h OLD_FILES+=usr/include/c++/3.4/bits/c++config.h OLD_FILES+=usr/include/c++/3.4/bits/c++io.h OLD_FILES+=usr/include/c++/3.4/bits/c++locale.h OLD_FILES+=usr/include/c++/3.4/bits/c++locale_internal.h OLD_FILES+=usr/include/c++/3.4/bits/char_traits.h OLD_FILES+=usr/include/c++/3.4/bits/cmath.tcc OLD_FILES+=usr/include/c++/3.4/bits/codecvt.h OLD_FILES+=usr/include/c++/3.4/bits/codecvt_specializations.h OLD_FILES+=usr/include/c++/3.4/bits/concept_check.h OLD_FILES+=usr/include/c++/3.4/bits/concurrence.h OLD_FILES+=usr/include/c++/3.4/bits/cpp_type_traits.h OLD_FILES+=usr/include/c++/3.4/bits/ctype_base.h OLD_FILES+=usr/include/c++/3.4/bits/ctype_inline.h OLD_FILES+=usr/include/c++/3.4/bits/ctype_noninline.h OLD_FILES+=usr/include/c++/3.4/bits/deque.tcc OLD_FILES+=usr/include/c++/3.4/bits/fstream.tcc OLD_FILES+=usr/include/c++/3.4/bits/functexcept.h OLD_FILES+=usr/include/c++/3.4/bits/gslice.h OLD_FILES+=usr/include/c++/3.4/bits/gslice_array.h OLD_FILES+=usr/include/c++/3.4/bits/gthr-default.h OLD_FILES+=usr/include/c++/3.4/bits/gthr-posix.h OLD_FILES+=usr/include/c++/3.4/bits/gthr-single.h OLD_FILES+=usr/include/c++/3.4/bits/gthr.h OLD_FILES+=usr/include/c++/3.4/bits/indirect_array.h OLD_FILES+=usr/include/c++/3.4/bits/ios_base.h OLD_FILES+=usr/include/c++/3.4/bits/istream.tcc OLD_FILES+=usr/include/c++/3.4/bits/list.tcc OLD_FILES+=usr/include/c++/3.4/bits/locale_classes.h OLD_FILES+=usr/include/c++/3.4/bits/locale_facets.h OLD_FILES+=usr/include/c++/3.4/bits/locale_facets.tcc OLD_FILES+=usr/include/c++/3.4/bits/localefwd.h OLD_FILES+=usr/include/c++/3.4/bits/mask_array.h OLD_FILES+=usr/include/c++/3.4/bits/messages_members.h OLD_FILES+=usr/include/c++/3.4/bits/os_defines.h OLD_FILES+=usr/include/c++/3.4/bits/ostream.tcc OLD_FILES+=usr/include/c++/3.4/bits/postypes.h OLD_FILES+=usr/include/c++/3.4/bits/slice_array.h OLD_FILES+=usr/include/c++/3.4/bits/sstream.tcc OLD_FILES+=usr/include/c++/3.4/bits/stl_algo.h OLD_FILES+=usr/include/c++/3.4/bits/stl_algobase.h OLD_FILES+=usr/include/c++/3.4/bits/stl_bvector.h OLD_FILES+=usr/include/c++/3.4/bits/stl_construct.h OLD_FILES+=usr/include/c++/3.4/bits/stl_deque.h OLD_FILES+=usr/include/c++/3.4/bits/stl_function.h OLD_FILES+=usr/include/c++/3.4/bits/stl_heap.h OLD_FILES+=usr/include/c++/3.4/bits/stl_iterator.h OLD_FILES+=usr/include/c++/3.4/bits/stl_iterator_base_funcs.h OLD_FILES+=usr/include/c++/3.4/bits/stl_iterator_base_types.h OLD_FILES+=usr/include/c++/3.4/bits/stl_list.h OLD_FILES+=usr/include/c++/3.4/bits/stl_map.h OLD_FILES+=usr/include/c++/3.4/bits/stl_multimap.h OLD_FILES+=usr/include/c++/3.4/bits/stl_multiset.h OLD_FILES+=usr/include/c++/3.4/bits/stl_numeric.h OLD_FILES+=usr/include/c++/3.4/bits/stl_pair.h OLD_FILES+=usr/include/c++/3.4/bits/stl_queue.h OLD_FILES+=usr/include/c++/3.4/bits/stl_raw_storage_iter.h OLD_FILES+=usr/include/c++/3.4/bits/stl_relops.h OLD_FILES+=usr/include/c++/3.4/bits/stl_set.h OLD_FILES+=usr/include/c++/3.4/bits/stl_stack.h OLD_FILES+=usr/include/c++/3.4/bits/stl_tempbuf.h OLD_FILES+=usr/include/c++/3.4/bits/stl_threads.h OLD_FILES+=usr/include/c++/3.4/bits/stl_tree.h OLD_FILES+=usr/include/c++/3.4/bits/stl_uninitialized.h OLD_FILES+=usr/include/c++/3.4/bits/stl_vector.h OLD_FILES+=usr/include/c++/3.4/bits/stream_iterator.h OLD_FILES+=usr/include/c++/3.4/bits/streambuf.tcc OLD_FILES+=usr/include/c++/3.4/bits/streambuf_iterator.h OLD_FILES+=usr/include/c++/3.4/bits/stringfwd.h OLD_FILES+=usr/include/c++/3.4/bits/time_members.h OLD_FILES+=usr/include/c++/3.4/bits/type_traits.h OLD_FILES+=usr/include/c++/3.4/bits/valarray_after.h OLD_FILES+=usr/include/c++/3.4/bits/valarray_array.h OLD_FILES+=usr/include/c++/3.4/bits/valarray_array.tcc OLD_FILES+=usr/include/c++/3.4/bits/valarray_before.h OLD_FILES+=usr/include/c++/3.4/bits/vector.tcc OLD_FILES+=usr/include/c++/3.4/bitset OLD_FILES+=usr/include/c++/3.4/cassert OLD_FILES+=usr/include/c++/3.4/cctype OLD_FILES+=usr/include/c++/3.4/cerrno OLD_FILES+=usr/include/c++/3.4/cfloat OLD_FILES+=usr/include/c++/3.4/ciso646 OLD_FILES+=usr/include/c++/3.4/climits OLD_FILES+=usr/include/c++/3.4/clocale OLD_FILES+=usr/include/c++/3.4/cmath OLD_FILES+=usr/include/c++/3.4/complex OLD_FILES+=usr/include/c++/3.4/csetjmp OLD_FILES+=usr/include/c++/3.4/csignal OLD_FILES+=usr/include/c++/3.4/cstdarg OLD_FILES+=usr/include/c++/3.4/cstddef OLD_FILES+=usr/include/c++/3.4/cstdio OLD_FILES+=usr/include/c++/3.4/cstdlib OLD_FILES+=usr/include/c++/3.4/cstring OLD_FILES+=usr/include/c++/3.4/ctime OLD_FILES+=usr/include/c++/3.4/cwchar OLD_FILES+=usr/include/c++/3.4/cwctype OLD_FILES+=usr/include/c++/3.4/cxxabi.h OLD_FILES+=usr/include/c++/3.4/debug/bitset OLD_FILES+=usr/include/c++/3.4/debug/debug.h OLD_FILES+=usr/include/c++/3.4/debug/deque OLD_FILES+=usr/include/c++/3.4/debug/formatter.h OLD_FILES+=usr/include/c++/3.4/debug/hash_map OLD_FILES+=usr/include/c++/3.4/debug/hash_map.h OLD_FILES+=usr/include/c++/3.4/debug/hash_multimap.h OLD_FILES+=usr/include/c++/3.4/debug/hash_multiset.h OLD_FILES+=usr/include/c++/3.4/debug/hash_set OLD_FILES+=usr/include/c++/3.4/debug/hash_set.h OLD_FILES+=usr/include/c++/3.4/debug/list OLD_FILES+=usr/include/c++/3.4/debug/map OLD_FILES+=usr/include/c++/3.4/debug/map.h OLD_FILES+=usr/include/c++/3.4/debug/multimap.h OLD_FILES+=usr/include/c++/3.4/debug/multiset.h OLD_FILES+=usr/include/c++/3.4/debug/safe_base.h OLD_FILES+=usr/include/c++/3.4/debug/safe_iterator.h OLD_FILES+=usr/include/c++/3.4/debug/safe_iterator.tcc OLD_FILES+=usr/include/c++/3.4/debug/safe_sequence.h OLD_FILES+=usr/include/c++/3.4/debug/set OLD_FILES+=usr/include/c++/3.4/debug/set.h OLD_FILES+=usr/include/c++/3.4/debug/string OLD_FILES+=usr/include/c++/3.4/debug/vector OLD_FILES+=usr/include/c++/3.4/deque OLD_FILES+=usr/include/c++/3.4/exception OLD_FILES+=usr/include/c++/3.4/exception_defines.h OLD_FILES+=usr/include/c++/3.4/ext/algorithm OLD_FILES+=usr/include/c++/3.4/ext/bitmap_allocator.h OLD_FILES+=usr/include/c++/3.4/ext/debug_allocator.h OLD_FILES+=usr/include/c++/3.4/ext/enc_filebuf.h OLD_FILES+=usr/include/c++/3.4/ext/functional OLD_FILES+=usr/include/c++/3.4/ext/hash_fun.h OLD_FILES+=usr/include/c++/3.4/ext/hash_map OLD_FILES+=usr/include/c++/3.4/ext/hash_set OLD_FILES+=usr/include/c++/3.4/ext/hashtable.h OLD_FILES+=usr/include/c++/3.4/ext/iterator OLD_FILES+=usr/include/c++/3.4/ext/malloc_allocator.h OLD_FILES+=usr/include/c++/3.4/ext/memory OLD_FILES+=usr/include/c++/3.4/ext/mt_allocator.h OLD_FILES+=usr/include/c++/3.4/ext/new_allocator.h OLD_FILES+=usr/include/c++/3.4/ext/numeric OLD_FILES+=usr/include/c++/3.4/ext/pod_char_traits.h OLD_FILES+=usr/include/c++/3.4/ext/pool_allocator.h OLD_FILES+=usr/include/c++/3.4/ext/rb_tree OLD_FILES+=usr/include/c++/3.4/ext/rope OLD_FILES+=usr/include/c++/3.4/ext/ropeimpl.h OLD_FILES+=usr/include/c++/3.4/ext/slist OLD_FILES+=usr/include/c++/3.4/ext/stdio_filebuf.h OLD_FILES+=usr/include/c++/3.4/ext/stdio_sync_filebuf.h OLD_FILES+=usr/include/c++/3.4/fstream OLD_FILES+=usr/include/c++/3.4/functional OLD_FILES+=usr/include/c++/3.4/iomanip OLD_FILES+=usr/include/c++/3.4/ios OLD_FILES+=usr/include/c++/3.4/iosfwd OLD_FILES+=usr/include/c++/3.4/iostream OLD_FILES+=usr/include/c++/3.4/istream OLD_FILES+=usr/include/c++/3.4/iterator OLD_FILES+=usr/include/c++/3.4/limits OLD_FILES+=usr/include/c++/3.4/list OLD_FILES+=usr/include/c++/3.4/locale OLD_FILES+=usr/include/c++/3.4/map OLD_FILES+=usr/include/c++/3.4/memory OLD_FILES+=usr/include/c++/3.4/new OLD_FILES+=usr/include/c++/3.4/numeric OLD_FILES+=usr/include/c++/3.4/ostream OLD_FILES+=usr/include/c++/3.4/queue OLD_FILES+=usr/include/c++/3.4/set OLD_FILES+=usr/include/c++/3.4/sstream OLD_FILES+=usr/include/c++/3.4/stack OLD_FILES+=usr/include/c++/3.4/stdexcept OLD_FILES+=usr/include/c++/3.4/streambuf OLD_FILES+=usr/include/c++/3.4/string OLD_FILES+=usr/include/c++/3.4/typeinfo OLD_FILES+=usr/include/c++/3.4/utility OLD_FILES+=usr/include/c++/3.4/valarray OLD_FILES+=usr/include/c++/3.4/vector OLD_DIRS+=usr/include/c++/3.4/backward OLD_DIRS+=usr/include/c++/3.4/bits OLD_DIRS+=usr/include/c++/3.4/debug OLD_DIRS+=usr/include/c++/3.4/ext OLD_DIRS+=usr/include/c++/3.4 # 20070510: zpool/zfs moved to /sbin OLD_FILES+=usr/sbin/zfs OLD_FILES+=usr/sbin/zpool # 20070423: rc.bluetooth (examples) removed OLD_FILES+=usr/share/examples/netgraph/bluetooth/rc.bluetooth OLD_DIRS+=usr/share/examples/netgraph/bluetooth # 20070421: worm.4 removed OLD_FILES+=usr/share/man/man4/worm.4.gz # 20070417: trunk(4) renamed to lagg(4) OLD_FILES+=usr/include/net/if_trunk.h # 20070409: uuidgen moved to /bin/ OLD_FILES+=usr/bin/uuidgen # 20070328: bzip2 1.0.4 OLD_FILES+=usr/share/info/bzip2.info.gz # 20070303: libarchive 2.0 OLD_LIBS+=usr/lib/libarchive.so.3 # 20070301: remove addr2ascii and ascii2addr OLD_FILES+=usr/share/man/man3/addr2ascii.3.gz OLD_FILES+=usr/share/man/man3/ascii2addr.3.gz # 20070225: vm_page_unmanage() removed OLD_FILES+=usr/share/man/man9/vm_page_unmanage.9.gz # 20070216: VFS_VPTOFH(9) -> VOP_VPTOFH(9) OLD_FILES+=usr/share/man/man9/VFS_VPTOFH.9.gz # 20070212: kame.4 removed OLD_FILES+=usr/share/man/man4/kame.4.gz # 20070201: remove libmytinfo link OLD_FILES+=usr/lib/libmytinfo.a OLD_FILES+=usr/lib/libmytinfo.so OLD_FILES+=usr/lib/libmytinfo_p.a OLD_FILES+=usr/lib/libmytinfow.a OLD_FILES+=usr/lib/libmytinfow.so OLD_FILES+=usr/lib/libmytinfow_p.a # 20070128: remove vnconfig OLD_FILES+=usr/sbin/vnconfig # 20070127: remove bpf_compat.h OLD_FILES+=usr/include/net/bpf_compat.h # 20070125: objformat bites the dust OLD_FILES+=usr/bin/objformat OLD_FILES+=usr/share/man/man1/objformat.1.gz OLD_FILES+=usr/include/objformat.h OLD_FILES+=usr/share/man/man3/getobjformat.3.gz # 20061008: rename *.so.4 libalias modules to *.so and move to /lib # This uses MOVED_LIBS because the new files are libraries even though # the old files to remove are symlinks MOVED_LIBS+=usr/lib/libalias_cuseeme.so MOVED_LIBS+=usr/lib/libalias_dummy.so MOVED_LIBS+=usr/lib/libalias_ftp.so MOVED_LIBS+=usr/lib/libalias_irc.so MOVED_LIBS+=usr/lib/libalias_nbt.so MOVED_LIBS+=usr/lib/libalias_pptp.so MOVED_LIBS+=usr/lib/libalias_skinny.so MOVED_LIBS+=usr/lib/libalias_smedia.so OLD_LIBS+=lib/libalias_cuseeme.so.4 OLD_LIBS+=lib/libalias_dummy.so.4 OLD_LIBS+=lib/libalias_ftp.so.4 OLD_LIBS+=lib/libalias_irc.so.4 OLD_LIBS+=lib/libalias_nbt.so.4 OLD_LIBS+=lib/libalias_pptp.so.4 OLD_LIBS+=lib/libalias_skinny.so.4 OLD_LIBS+=lib/libalias_smedia.so.4 # 20061126: remove old man page OLD_FILES+=usr/share/man/man3/archive_read_set_bytes_per_block.3.gz # 20061125: remove old man page OLD_FILES+=usr/share/man/man9/devsw.9.gz # 20061122: remove obsolete mount programs OLD_FILES+=sbin/mount_devfs OLD_FILES+=sbin/mount_ext2fs OLD_FILES+=sbin/mount_fdescfs OLD_FILES+=sbin/mount_linprocfs OLD_FILES+=sbin/mount_procfs OLD_FILES+=sbin/mount_std OLD_FILES+=rescue/mount_devfs OLD_FILES+=rescue/mount_ext2fs OLD_FILES+=rescue/mount_fdescfs OLD_FILES+=rescue/mount_linprocfs OLD_FILES+=rescue/mount_procfs OLD_FILES+=rescue/mount_std OLD_FILES+=usr/share/man/man8/mount_devfs.8.gz OLD_FILES+=usr/share/man/man8/mount_ext2fs.8.gz OLD_FILES+=usr/share/man/man8/mount_fdescfs.8.gz OLD_FILES+=usr/share/man/man8/mount_linprocfs.8.gz OLD_FILES+=usr/share/man/man8/mount_procfs.8.gz OLD_FILES+=usr/share/man/man8/mount_std.8.gz # 20061116: uhidev.4 removed OLD_FILES+=usr/share/man/man4/uhidev.4.gz # 20061106: archive_write_prepare.3 removed OLD_FILES+=usr/share/man/man3/archive_write_prepare.3.gz # 20061018: pccardc removed OLD_FILES+=usr/sbin/pccardc usr/share/man/man8/pccardc.8.gz # 20060930: demangle.h from contrib/libstdc++/include/ext/ OLD_FILES+=usr/include/c++/3.4/ext/demangle.h # 20060929: mrouted removed OLD_FILES+=usr/sbin/map-mbone OLD_FILES+=usr/sbin/mrinfo OLD_FILES+=usr/sbin/mrouted OLD_FILES+=usr/sbin/mtrace OLD_FILES+=usr/share/man/man8/map-mbone.8.gz OLD_FILES+=usr/share/man/man8/mrinfo.8.gz OLD_FILES+=usr/share/man/man8/mrouted.8.gz OLD_FILES+=usr/share/man/man8/mtrace.8.gz # 20060924: tcpslice removed OLD_FILES+=usr/sbin/tcpslice OLD_FILES+=usr/share/man/man1/tcpslice.1.gz # 20060829: kvmdb cleanup script removed OLD_FILES+=etc/periodic/weekly/120.clean-kvmdb # 20060822: ramdisk{,-own} have been replaced by mdconfig{,2} OLD_FILES+=etc/rc.d/ramdisk OLD_FILES+=etc/rc.d/ramdisk-own # 20060729: OpenSSL 0.9.7e -> 0.9.8b upgrade OLD_FILES+=usr/include/openssl/eng_int.h OLD_FILES+=usr/include/openssl/hw_4758_cca_err.h OLD_FILES+=usr/include/openssl/hw_aep_err.h OLD_FILES+=usr/include/openssl/hw_atalla_err.h OLD_FILES+=usr/include/openssl/hw_cswift_err.h OLD_FILES+=usr/include/openssl/hw_ncipher_err.h OLD_FILES+=usr/include/openssl/hw_nuron_err.h OLD_FILES+=usr/include/openssl/hw_sureware_err.h OLD_FILES+=usr/include/openssl/hw_ubsec_err.h # 20060713: mount_linsysfs(8) never existed in 7.x OLD_FILES+=sbin/mount_linsysfs OLD_FILES+=usr/share/man/man8/mount_linsysfs.8.gz # 20060704: KAME compat file net_osdep.h removed OLD_FILES+=usr/include/net/net_osdep.h # 20060605: man page links removed by OpenBSM 1.0 alpha 6 import OLD_FILES+=usr/share/man/man3/au_to_socket.3.gz OLD_FILES+=usr/share/man/man3/au_to_socket_ex_128.3.gz OLD_FILES+=usr/share/man/man3/au_to_socket_ex_32.3.gz # 20060517: pcvt removed OLD_FILES+=usr/share/pcvt/README.FIRST OLD_FILES+=usr/share/pcvt/Etc/xmodmap-german OLD_FILES+=usr/share/pcvt/Etc/pcvt.sh OLD_FILES+=usr/share/pcvt/Etc/pcvt.el OLD_FILES+=usr/share/pcvt/Etc/Terminfo OLD_FILES+=usr/share/pcvt/Etc/Termcap OLD_DIRS+=usr/share/pcvt/Etc OLD_FILES+=usr/share/pcvt/Doc/NotesAndHints OLD_FILES+=usr/share/pcvt/Doc/Keyboard.VT OLD_FILES+=usr/share/pcvt/Doc/Keyboard.HP OLD_FILES+=usr/share/pcvt/Doc/EscapeSequences OLD_FILES+=usr/share/pcvt/Doc/Charsets OLD_FILES+=usr/share/pcvt/Doc/CharGen OLD_FILES+=usr/share/pcvt/Doc/Bibliography OLD_FILES+=usr/share/pcvt/Doc/Acknowledgements OLD_DIRS+=usr/share/pcvt/Doc OLD_DIRS+=usr/share/pcvt OLD_FILES+=usr/share/misc/pcvtfonts/vt220l.816 OLD_FILES+=usr/share/misc/pcvtfonts/vt220l.814 OLD_FILES+=usr/share/misc/pcvtfonts/vt220l.810 OLD_FILES+=usr/share/misc/pcvtfonts/vt220l.808 OLD_FILES+=usr/share/misc/pcvtfonts/vt220h.816 OLD_FILES+=usr/share/misc/pcvtfonts/vt220h.814 OLD_FILES+=usr/share/misc/pcvtfonts/vt220h.810 OLD_FILES+=usr/share/misc/pcvtfonts/vt220h.808 OLD_DIRS+=usr/share/misc/pcvtfonts OLD_FILES+=usr/share/misc/keycap.pcvt OLD_FILES+=usr/share/man/man8/ispcvt.8.gz OLD_FILES+=usr/share/man/man5/keycap.5.gz OLD_FILES+=usr/share/man/man4/pcvt.4.gz OLD_FILES+=usr/share/man/man3/kgetstr.3.gz OLD_FILES+=usr/share/man/man3/kgetnum.3.gz OLD_FILES+=usr/share/man/man3/kgetflag.3.gz OLD_FILES+=usr/share/man/man3/kgetent.3.gz OLD_FILES+=usr/share/man/man3/keycap.3.gz OLD_FILES+=usr/share/man/man1/vt220keys.1.gz OLD_FILES+=usr/share/man/man1/scon.1.gz OLD_FILES+=usr/share/man/man1/loadfont.1.gz OLD_FILES+=usr/share/man/man1/kcon.1.gz OLD_FILES+=usr/share/man/man1/fontedit.1.gz OLD_FILES+=usr/share/man/man1/cursor.1.gz OLD_FILES+=usr/sbin/vt220keys OLD_FILES+=usr/sbin/scon OLD_FILES+=usr/sbin/loadfont OLD_FILES+=usr/sbin/kcon OLD_FILES+=usr/sbin/ispcvt OLD_FILES+=usr/sbin/fontedit OLD_FILES+=usr/sbin/cursor OLD_FILES+=usr/lib/libkeycap_p.a OLD_FILES+=usr/lib/libkeycap.a OLD_FILES+=usr/include/machine/pcvt_ioctl.h # 20060514: lnc(4) replaced by le(4) OLD_FILES+=usr/share/man/man4/i386/lnc.4.gz # 20060512: remove ip6fw OLD_FILES+=etc/periodic/security/600.ip6fwdenied OLD_FILES+=etc/periodic/security/650.ip6fwlimit OLD_FILES+=sbin/ip6fw OLD_FILES+=usr/include/netinet6/ip6_fw.h OLD_FILES+=usr/share/man/man8/ip6fw.8.gz # 20060424: sab(4) removed OLD_FILES+=usr/share/man/man4/sab.4.gz # 20060328: remove redundant rc.d script OLD_FILES+=etc/rc.d/ike # 20060127: revert libdisk to static-only OLD_FILES+=usr/lib/libdisk.so # 20060115: sys/pccard includes cleanup OLD_FILES+=usr/include/pccard/driver.h OLD_FILES+=usr/include/pccard/i82365.h OLD_FILES+=usr/include/pccard/meciareg.h OLD_FILES+=usr/include/pccard/pccard_nbk.h OLD_FILES+=usr/include/pccard/pcic_pci.h OLD_FILES+=usr/include/pccard/pcicvar.h OLD_FILES+=usr/include/pccard/slot.h # 20051215: rescue/nextboot.sh renamed to rescue/nextboot OLD_FILES+=rescue/nextboot.sh # 20051214: usbd(8) removed OLD_FILES+=etc/rc.d/usbd OLD_FILES+=etc/usbd.conf OLD_FILES+=usr/sbin/usbd OLD_FILES+=usr/share/man/man8/usbd.8.gz # 20051029: rc.d/ppp-user renamed to rc.d/ppp for convenience OLD_FILES+=etc/rc.d/ppp-user # 20051012: setkey(8) moved to /sbin/ OLD_FILES+=usr/sbin/setkey # 20050930: pccardd(8) removed OLD_FILES+=usr/sbin/pccardd OLD_FILES+=usr/share/man/man5/pccard.conf.5.gz OLD_FILES+=usr/share/man/man8/pccardd.8.gz # 20050927: bridge(4) replaced by if_bridge(4) OLD_FILES+=usr/include/net/bridge.h # 20050831: not implemented OLD_FILES+=usr/share/man/man3/getino.3.gz OLD_FILES+=usr/share/man/man3/putino.3.gz # 20050825: T/TCP retired several months ago OLD_FILES+=usr/share/man/man4/ttcp.4.gz # 20050805 tn3270 retired long ago OLD_FILES+=usr/share/misc/map3270 # 20050801: too old to be interesting here OLD_FILES+=usr/share/doc/papers/px.ps.gz # 20050721: moved to ports OLD_FILES+=usr/sbin/vttest OLD_FILES+=usr/share/man/man1/vttest.1.gz # 20050617: wpa man pages moved to section 8 OLD_FILES+=usr/share/man/man1/hostapd.1.gz OLD_FILES+=usr/share/man/man1/hostapd_cli.1.gz OLD_FILES+=usr/share/man/man1/wpa_cli.1.gz OLD_FILES+=usr/share/man/man1/wpa_supplicant.1.gz # 20050610: rexecd (insecure by design) OLD_FILES+=etc/pam.d/rexecd OLD_FILES+=usr/share/man/man8/rexecd.8.gz OLD_FILES+=usr/libexec/rexecd # 20050606: OpenBSD dhclient replaces ISC one OLD_FILES+=bin/omshell OLD_FILES+=sbin/omshell OLD_FILES+=usr/share/man/man1/omshell.1.gz OLD_FILES+=usr/share/man/man5/dhcp-eval.5.gz # 200504XX: ipf tools moved from /usr to / OLD_FILES+=rescue/ipfs OLD_FILES+=rescue/ipfstat OLD_FILES+=rescue/ipmon OLD_FILES+=rescue/ipnat OLD_FILES+=usr/sbin/ipftest OLD_FILES+=usr/sbin/ipresend OLD_FILES+=usr/sbin/ipsend OLD_FILES+=usr/sbin/iptest OLD_FILES+=usr/share/man/man1/ipnat.1.gz OLD_FILES+=usr/share/man/man1/ipsend.1.gz OLD_FILES+=usr/share/man/man1/iptest.1.gz OLD_FILES+=usr/share/man/man5/ipsend.5.gz # 200503XX: bsdtar takes over gtar OLD_FILES+=usr/bin/gtar OLD_FILES+=usr/share/man/man1/gtar.1.gz # 200503XX OLD_FILES+=usr/share/man/man3/exp10.3.gz OLD_FILES+=usr/share/man/man3/exp10f.3.gz OLD_FILES+=usr/share/man/man3/fpsetsticky.3.gz # 20050324: updated release infrastructure OLD_FILES+=usr/share/man/man5/drivers.conf.5.gz # 20050317: removed from BIND 9 distribution OLD_FILES+=usr/share/doc/bind9/KNOWN_DEFECTS # 2005XXXX: OLD_FILES+=sbin/mount_autofs OLD_FILES+=usr/lib/libautofs.a OLD_FILES+=usr/lib/libautofs.so OLD_FILES+=usr/share/man/man8/mount_autofs.8.gz # 20050203: Merged with fortunes OLD_FILES+=usr/share/games/fortune/fortunes2 OLD_FILES+=usr/share/games/fortune/fortunes2.dat # 200501XX: OLD_FILES+=usr/libexec/getNAME # 200411XX: gvinum replaces vinum OLD_FILES+=bin/vinum OLD_FILES+=rescue/vinum OLD_FILES+=sbin/vinum OLD_FILES+=usr/share/man/man8/vinum.8.gz # 200411XX: libxpg4 removal OLD_FILES+=usr/lib/libxpg4.a OLD_FILES+=usr/lib/libxpg4.so OLD_FILES+=usr/lib/libxpg4_p.a # 20041109: replaced by em(4) OLD_FILES+=usr/share/man/man4/gx.4.gz OLD_FILES+=usr/share/man/man4/if_gx.4.gz # 20041017: rune interface removed OLD_FILES+=usr/include/rune.h OLD_FILES+=usr/share/man/man3/fgetrune.3.gz OLD_FILES+=usr/share/man/man3/fputrune.3.gz OLD_FILES+=usr/share/man/man3/fungetrune.3.gz OLD_FILES+=usr/share/man/man3/mbrrune.3.gz OLD_FILES+=usr/share/man/man3/mbrune.3.gz OLD_FILES+=usr/share/man/man3/rune.3.gz OLD_FILES+=usr/share/man/man3/setinvalidrune.3.gz OLD_FILES+=usr/share/man/man3/sgetrune.3.gz OLD_FILES+=usr/share/man/man3/sputrune.3.gz # 20040925: bind9 import OLD_FILES+=usr/bin/dnskeygen OLD_FILES+=usr/bin/dnsquery OLD_FILES+=usr/lib/libisc.a OLD_FILES+=usr/lib/libisc.so OLD_FILES+=usr/lib/libisc_p.a OLD_FILES+=usr/libexec/named-xfer OLD_FILES+=usr/sbin/named.restart OLD_FILES+=usr/sbin/ndc OLD_FILES+=usr/sbin/nslookup OLD_FILES+=usr/sbin/nsupdate OLD_FILES+=usr/share/doc/bind/html/acl.html OLD_FILES+=usr/share/doc/bind/html/address_list.html OLD_FILES+=usr/share/doc/bind/html/comments.html OLD_FILES+=usr/share/doc/bind/html/config.html OLD_FILES+=usr/share/doc/bind/html/controls.html OLD_FILES+=usr/share/doc/bind/html/docdef.html OLD_FILES+=usr/share/doc/bind/html/example.html OLD_FILES+=usr/share/doc/bind/html/include.html OLD_FILES+=usr/share/doc/bind/html/index.html OLD_FILES+=usr/share/doc/bind/html/key.html OLD_FILES+=usr/share/doc/bind/html/logging.html OLD_FILES+=usr/share/doc/bind/html/master.html OLD_FILES+=usr/share/doc/bind/html/options.html OLD_FILES+=usr/share/doc/bind/html/server.html OLD_FILES+=usr/share/doc/bind/html/trusted-keys.html OLD_FILES+=usr/share/doc/bind/html/zone.html OLD_FILES+=usr/share/doc/bind/misc/DynamicUpdate OLD_FILES+=usr/share/doc/bind/misc/FAQ.1of2 OLD_FILES+=usr/share/doc/bind/misc/FAQ.2of2 OLD_FILES+=usr/share/doc/bind/misc/rfc2317-notes.txt OLD_FILES+=usr/share/doc/bind/misc/style.txt OLD_FILES+=usr/share/man/man1/dnskeygen.1.gz OLD_FILES+=usr/share/man/man1/dnsquery.1.gz OLD_FILES+=usr/share/man/man8/named-bootconf.8.gz OLD_FILES+=usr/share/man/man8/named-xfer.8.gz OLD_FILES+=usr/share/man/man8/named.restart.8.gz OLD_FILES+=usr/share/man/man8/ndc.8.gz OLD_FILES+=usr/share/man/man8/nslookup.8.gz # 200409XX OLD_FILES+=usr/share/man/man3/ENSURE.3.gz OLD_FILES+=usr/share/man/man3/ENSURE_ERR.3.gz OLD_FILES+=usr/share/man/man3/INSIST.3.gz OLD_FILES+=usr/share/man/man3/INSIST_ERR.3.gz OLD_FILES+=usr/share/man/man3/INVARIANT.3.gz OLD_FILES+=usr/share/man/man3/INVARIANT_ERR.3.gz OLD_FILES+=usr/share/man/man3/REQUIRE.3.gz OLD_FILES+=usr/share/man/man3/REQUIRE_ERR.3.gz OLD_FILES+=usr/share/man/man3/assertion_type_to_text.3.gz OLD_FILES+=usr/share/man/man3/assertions.3.gz OLD_FILES+=usr/share/man/man3/bitncmp.3.gz OLD_FILES+=usr/share/man/man3/evAddTime.3.gz OLD_FILES+=usr/share/man/man3/evCancelConn.3.gz OLD_FILES+=usr/share/man/man3/evCancelRW.3.gz OLD_FILES+=usr/share/man/man3/evClearIdleTimer.3.gz OLD_FILES+=usr/share/man/man3/evClearTimer.3.gz OLD_FILES+=usr/share/man/man3/evCmpTime.3.gz OLD_FILES+=usr/share/man/man3/evConnFunc.3.gz OLD_FILES+=usr/share/man/man3/evConnect.3.gz OLD_FILES+=usr/share/man/man3/evConsIovec.3.gz OLD_FILES+=usr/share/man/man3/evConsTime.3.gz OLD_FILES+=usr/share/man/man3/evCreate.3.gz OLD_FILES+=usr/share/man/man3/evDefer.3.gz OLD_FILES+=usr/share/man/man3/evDeselectFD.3.gz OLD_FILES+=usr/share/man/man3/evDestroy.3.gz OLD_FILES+=usr/share/man/man3/evDispatch.3.gz OLD_FILES+=usr/share/man/man3/evDo.3.gz OLD_FILES+=usr/share/man/man3/evDrop.3.gz OLD_FILES+=usr/share/man/man3/evFileFunc.3.gz OLD_FILES+=usr/share/man/man3/evGetNext.3.gz OLD_FILES+=usr/share/man/man3/evHold.3.gz OLD_FILES+=usr/share/man/man3/evInitID.3.gz OLD_FILES+=usr/share/man/man3/evLastEventTime.3.gz OLD_FILES+=usr/share/man/man3/evListen.3.gz OLD_FILES+=usr/share/man/man3/evMainLoop.3.gz OLD_FILES+=usr/share/man/man3/evNowTime.3.gz OLD_FILES+=usr/share/man/man3/evPrintf.3.gz OLD_FILES+=usr/share/man/man3/evRead.3.gz OLD_FILES+=usr/share/man/man3/evResetTimer.3.gz OLD_FILES+=usr/share/man/man3/evSelectFD.3.gz OLD_FILES+=usr/share/man/man3/evSetDebug.3.gz OLD_FILES+=usr/share/man/man3/evSetIdleTimer.3.gz OLD_FILES+=usr/share/man/man3/evSetTimer.3.gz OLD_FILES+=usr/share/man/man3/evStreamFunc.3.gz OLD_FILES+=usr/share/man/man3/evSubTime.3.gz OLD_FILES+=usr/share/man/man3/evTestID.3.gz OLD_FILES+=usr/share/man/man3/evTimeRW.3.gz OLD_FILES+=usr/share/man/man3/evTimeSpec.3.gz OLD_FILES+=usr/share/man/man3/evTimeVal.3.gz OLD_FILES+=usr/share/man/man3/evTimerFunc.3.gz OLD_FILES+=usr/share/man/man3/evTouchIdleTimer.3.gz OLD_FILES+=usr/share/man/man3/evTryAccept.3.gz OLD_FILES+=usr/share/man/man3/evUnhold.3.gz OLD_FILES+=usr/share/man/man3/evUntimeRW.3.gz OLD_FILES+=usr/share/man/man3/evUnwait.3.gz OLD_FILES+=usr/share/man/man3/evWaitFor.3.gz OLD_FILES+=usr/share/man/man3/evWaitFunc.3.gz OLD_FILES+=usr/share/man/man3/evWrite.3.gz OLD_FILES+=usr/share/man/man3/eventlib.3.gz OLD_FILES+=usr/share/man/man3/heap.3.gz OLD_FILES+=usr/share/man/man3/heap_decreased.3.gz OLD_FILES+=usr/share/man/man3/heap_delete.3.gz OLD_FILES+=usr/share/man/man3/heap_element.3.gz OLD_FILES+=usr/share/man/man3/heap_for_each.3.gz OLD_FILES+=usr/share/man/man3/heap_free.3.gz OLD_FILES+=usr/share/man/man3/heap_increased.3.gz OLD_FILES+=usr/share/man/man3/heap_insert.3.gz OLD_FILES+=usr/share/man/man3/heap_new.3.gz OLD_FILES+=usr/share/man/man3/log_add_channel.3.gz OLD_FILES+=usr/share/man/man3/log_category_is_active.3.gz OLD_FILES+=usr/share/man/man3/log_close_stream.3.gz OLD_FILES+=usr/share/man/man3/log_dec_references.3.gz OLD_FILES+=usr/share/man/man3/log_free_channel.3.gz OLD_FILES+=usr/share/man/man3/log_free_context.3.gz OLD_FILES+=usr/share/man/man3/log_get_filename.3.gz OLD_FILES+=usr/share/man/man3/log_get_stream.3.gz OLD_FILES+=usr/share/man/man3/log_inc_references.3.gz OLD_FILES+=usr/share/man/man3/log_new_context.3.gz OLD_FILES+=usr/share/man/man3/log_new_file_channel.3.gz OLD_FILES+=usr/share/man/man3/log_new_null_channel.3.gz OLD_FILES+=usr/share/man/man3/log_new_syslog_channel.3.gz OLD_FILES+=usr/share/man/man3/log_open_stream.3.gz OLD_FILES+=usr/share/man/man3/log_option.3.gz OLD_FILES+=usr/share/man/man3/log_remove_channel.3.gz OLD_FILES+=usr/share/man/man3/log_set_file_owner.3.gz OLD_FILES+=usr/share/man/man3/log_vwrite.3.gz OLD_FILES+=usr/share/man/man3/log_write.3.gz OLD_FILES+=usr/share/man/man3/logging.3.gz OLD_FILES+=usr/share/man/man3/memcluster.3.gz OLD_FILES+=usr/share/man/man3/memget.3.gz OLD_FILES+=usr/share/man/man3/memput.3.gz OLD_FILES+=usr/share/man/man3/memstats.3.gz OLD_FILES+=usr/share/man/man3/set_assertion_failure_callback.3. OLD_FILES+=usr/share/man/man3/sigwait.3.gz OLD_FILES+=usr/share/man/man3/tree_add.3.gz OLD_FILES+=usr/share/man/man3/tree_delete.3.gz OLD_FILES+=usr/share/man/man3/tree_init.3.gz OLD_FILES+=usr/share/man/man3/tree_mung.3.gz OLD_FILES+=usr/share/man/man3/tree_srch.3.gz OLD_FILES+=usr/share/man/man3/tree_trav.3.gz # 2004XXYY: OS internal libs, no ports use them, no need to use OLD_LIBS OLD_LIBS+=lib/geom/geom_concat.so.1 OLD_LIBS+=lib/geom/geom_label.so.1 OLD_LIBS+=lib/geom/geom_nop.so.1 OLD_LIBS+=lib/geom/geom_stripe.so.1 # 20040728: GCC 3.4.2 OLD_DIRS+=usr/include/c++/3.3 OLD_FILES+=usr/include/c++/3.3/FlexLexer.h OLD_FILES+=usr/include/c++/3.3/algorithm OLD_FILES+=usr/include/c++/3.3/backward/algo.h OLD_FILES+=usr/include/c++/3.3/backward/algobase.h OLD_FILES+=usr/include/c++/3.3/backward/alloc.h OLD_FILES+=usr/include/c++/3.3/backward/backward_warning.h OLD_FILES+=usr/include/c++/3.3/backward/bvector.h OLD_FILES+=usr/include/c++/3.3/backward/complex.h OLD_FILES+=usr/include/c++/3.3/backward/defalloc.h OLD_FILES+=usr/include/c++/3.3/backward/deque.h OLD_FILES+=usr/include/c++/3.3/backward/fstream.h OLD_FILES+=usr/include/c++/3.3/backward/function.h OLD_FILES+=usr/include/c++/3.3/backward/hash_map.h OLD_FILES+=usr/include/c++/3.3/backward/hash_set.h OLD_FILES+=usr/include/c++/3.3/backward/hashtable.h OLD_FILES+=usr/include/c++/3.3/backward/heap.h OLD_FILES+=usr/include/c++/3.3/backward/iomanip.h OLD_FILES+=usr/include/c++/3.3/backward/iostream.h OLD_FILES+=usr/include/c++/3.3/backward/istream.h OLD_FILES+=usr/include/c++/3.3/backward/iterator.h OLD_FILES+=usr/include/c++/3.3/backward/list.h OLD_FILES+=usr/include/c++/3.3/backward/map.h OLD_FILES+=usr/include/c++/3.3/backward/multimap.h OLD_FILES+=usr/include/c++/3.3/backward/multiset.h OLD_FILES+=usr/include/c++/3.3/backward/new.h OLD_FILES+=usr/include/c++/3.3/backward/ostream.h OLD_FILES+=usr/include/c++/3.3/backward/pair.h OLD_FILES+=usr/include/c++/3.3/backward/queue.h OLD_FILES+=usr/include/c++/3.3/backward/rope.h OLD_FILES+=usr/include/c++/3.3/backward/set.h OLD_FILES+=usr/include/c++/3.3/backward/slist.h OLD_FILES+=usr/include/c++/3.3/backward/stack.h OLD_FILES+=usr/include/c++/3.3/backward/stream.h OLD_FILES+=usr/include/c++/3.3/backward/streambuf.h OLD_FILES+=usr/include/c++/3.3/backward/strstream OLD_FILES+=usr/include/c++/3.3/backward/strstream.h OLD_FILES+=usr/include/c++/3.3/backward/tempbuf.h OLD_FILES+=usr/include/c++/3.3/backward/tree.h OLD_FILES+=usr/include/c++/3.3/backward/vector.h OLD_DIRS+=usr/include/c++/3.3/backward OLD_FILES+=usr/include/c++/3.3/bits/atomicity.h OLD_FILES+=usr/include/c++/3.3/bits/basic_file.h OLD_FILES+=usr/include/c++/3.3/bits/basic_ios.h OLD_FILES+=usr/include/c++/3.3/bits/basic_ios.tcc OLD_FILES+=usr/include/c++/3.3/bits/basic_string.h OLD_FILES+=usr/include/c++/3.3/bits/basic_string.tcc OLD_FILES+=usr/include/c++/3.3/bits/boost_concept_check.h OLD_FILES+=usr/include/c++/3.3/bits/c++config.h OLD_FILES+=usr/include/c++/3.3/bits/c++io.h OLD_FILES+=usr/include/c++/3.3/bits/c++locale.h OLD_FILES+=usr/include/c++/3.3/bits/c++locale_internal.h OLD_FILES+=usr/include/c++/3.3/bits/char_traits.h OLD_FILES+=usr/include/c++/3.3/bits/cmath.tcc OLD_FILES+=usr/include/c++/3.3/bits/codecvt.h OLD_FILES+=usr/include/c++/3.3/bits/codecvt_specializations.h OLD_FILES+=usr/include/c++/3.3/bits/concept_check.h OLD_FILES+=usr/include/c++/3.3/bits/cpp_type_traits.h OLD_FILES+=usr/include/c++/3.3/bits/ctype_base.h OLD_FILES+=usr/include/c++/3.3/bits/ctype_inline.h OLD_FILES+=usr/include/c++/3.3/bits/ctype_noninline.h OLD_FILES+=usr/include/c++/3.3/bits/deque.tcc OLD_FILES+=usr/include/c++/3.3/bits/fpos.h OLD_FILES+=usr/include/c++/3.3/bits/fstream.tcc OLD_FILES+=usr/include/c++/3.3/bits/functexcept.h OLD_FILES+=usr/include/c++/3.3/bits/generic_shadow.h OLD_FILES+=usr/include/c++/3.3/bits/gslice.h OLD_FILES+=usr/include/c++/3.3/bits/gslice_array.h OLD_FILES+=usr/include/c++/3.3/bits/gthr-default.h OLD_FILES+=usr/include/c++/3.3/bits/gthr-posix.h OLD_FILES+=usr/include/c++/3.3/bits/gthr-single.h OLD_FILES+=usr/include/c++/3.3/bits/gthr.h OLD_FILES+=usr/include/c++/3.3/bits/indirect_array.h OLD_FILES+=usr/include/c++/3.3/bits/ios_base.h OLD_FILES+=usr/include/c++/3.3/bits/istream.tcc OLD_FILES+=usr/include/c++/3.3/bits/list.tcc OLD_FILES+=usr/include/c++/3.3/bits/locale_classes.h OLD_FILES+=usr/include/c++/3.3/bits/locale_facets.h OLD_FILES+=usr/include/c++/3.3/bits/locale_facets.tcc OLD_FILES+=usr/include/c++/3.3/bits/localefwd.h OLD_FILES+=usr/include/c++/3.3/bits/mask_array.h OLD_FILES+=usr/include/c++/3.3/bits/messages_members.h OLD_FILES+=usr/include/c++/3.3/bits/os_defines.h OLD_FILES+=usr/include/c++/3.3/bits/ostream.tcc OLD_FILES+=usr/include/c++/3.3/bits/pthread_allocimpl.h OLD_FILES+=usr/include/c++/3.3/bits/slice.h OLD_FILES+=usr/include/c++/3.3/bits/slice_array.h OLD_FILES+=usr/include/c++/3.3/bits/sstream.tcc OLD_FILES+=usr/include/c++/3.3/bits/stl_algo.h OLD_FILES+=usr/include/c++/3.3/bits/stl_algobase.h OLD_FILES+=usr/include/c++/3.3/bits/stl_alloc.h OLD_FILES+=usr/include/c++/3.3/bits/stl_bvector.h OLD_FILES+=usr/include/c++/3.3/bits/stl_construct.h OLD_FILES+=usr/include/c++/3.3/bits/stl_deque.h OLD_FILES+=usr/include/c++/3.3/bits/stl_function.h OLD_FILES+=usr/include/c++/3.3/bits/stl_heap.h OLD_FILES+=usr/include/c++/3.3/bits/stl_iterator.h OLD_FILES+=usr/include/c++/3.3/bits/stl_iterator_base_funcs.h OLD_FILES+=usr/include/c++/3.3/bits/stl_iterator_base_types.h OLD_FILES+=usr/include/c++/3.3/bits/stl_list.h OLD_FILES+=usr/include/c++/3.3/bits/stl_map.h OLD_FILES+=usr/include/c++/3.3/bits/stl_multimap.h OLD_FILES+=usr/include/c++/3.3/bits/stl_multiset.h OLD_FILES+=usr/include/c++/3.3/bits/stl_numeric.h OLD_FILES+=usr/include/c++/3.3/bits/stl_pair.h OLD_FILES+=usr/include/c++/3.3/bits/stl_pthread_alloc.h OLD_FILES+=usr/include/c++/3.3/bits/stl_queue.h OLD_FILES+=usr/include/c++/3.3/bits/stl_raw_storage_iter.h OLD_FILES+=usr/include/c++/3.3/bits/stl_relops.h OLD_FILES+=usr/include/c++/3.3/bits/stl_set.h OLD_FILES+=usr/include/c++/3.3/bits/stl_stack.h OLD_FILES+=usr/include/c++/3.3/bits/stl_tempbuf.h OLD_FILES+=usr/include/c++/3.3/bits/stl_threads.h OLD_FILES+=usr/include/c++/3.3/bits/stl_tree.h OLD_FILES+=usr/include/c++/3.3/bits/stl_uninitialized.h OLD_FILES+=usr/include/c++/3.3/bits/stl_vector.h OLD_FILES+=usr/include/c++/3.3/bits/stream_iterator.h OLD_FILES+=usr/include/c++/3.3/bits/streambuf.tcc OLD_FILES+=usr/include/c++/3.3/bits/streambuf_iterator.h OLD_FILES+=usr/include/c++/3.3/bits/stringfwd.h OLD_FILES+=usr/include/c++/3.3/bits/time_members.h OLD_FILES+=usr/include/c++/3.3/bits/type_traits.h OLD_FILES+=usr/include/c++/3.3/bits/valarray_array.h OLD_FILES+=usr/include/c++/3.3/bits/valarray_array.tcc OLD_FILES+=usr/include/c++/3.3/bits/valarray_meta.h OLD_FILES+=usr/include/c++/3.3/bits/vector.tcc OLD_DIRS+=usr/include/c++/3.3/bits OLD_FILES+=usr/include/c++/3.3/bitset OLD_FILES+=usr/include/c++/3.3/cassert OLD_FILES+=usr/include/c++/3.3/cctype OLD_FILES+=usr/include/c++/3.3/cerrno OLD_FILES+=usr/include/c++/3.3/cfloat OLD_FILES+=usr/include/c++/3.3/ciso646 OLD_FILES+=usr/include/c++/3.3/climits OLD_FILES+=usr/include/c++/3.3/clocale OLD_FILES+=usr/include/c++/3.3/cmath OLD_FILES+=usr/include/c++/3.3/complex OLD_FILES+=usr/include/c++/3.3/csetjmp OLD_FILES+=usr/include/c++/3.3/csignal OLD_FILES+=usr/include/c++/3.3/cstdarg OLD_FILES+=usr/include/c++/3.3/cstddef OLD_FILES+=usr/include/c++/3.3/cstdio OLD_FILES+=usr/include/c++/3.3/cstdlib OLD_FILES+=usr/include/c++/3.3/cstring OLD_FILES+=usr/include/c++/3.3/ctime OLD_FILES+=usr/include/c++/3.3/cwchar OLD_FILES+=usr/include/c++/3.3/cwctype OLD_FILES+=usr/include/c++/3.3/cxxabi.h OLD_FILES+=usr/include/c++/3.3/deque OLD_FILES+=usr/include/c++/3.3/exception OLD_FILES+=usr/include/c++/3.3/exception_defines.h OLD_FILES+=usr/include/c++/3.3/ext/algorithm OLD_FILES+=usr/include/c++/3.3/ext/enc_filebuf.h OLD_FILES+=usr/include/c++/3.3/ext/functional OLD_FILES+=usr/include/c++/3.3/ext/hash_map OLD_FILES+=usr/include/c++/3.3/ext/hash_set OLD_FILES+=usr/include/c++/3.3/ext/iterator OLD_FILES+=usr/include/c++/3.3/ext/memory OLD_FILES+=usr/include/c++/3.3/ext/numeric OLD_FILES+=usr/include/c++/3.3/ext/rb_tree OLD_FILES+=usr/include/c++/3.3/ext/rope OLD_FILES+=usr/include/c++/3.3/ext/ropeimpl.h OLD_FILES+=usr/include/c++/3.3/ext/slist OLD_FILES+=usr/include/c++/3.3/ext/stdio_filebuf.h OLD_FILES+=usr/include/c++/3.3/ext/stl_hash_fun.h OLD_FILES+=usr/include/c++/3.3/ext/stl_hashtable.h OLD_FILES+=usr/include/c++/3.3/ext/stl_rope.h OLD_DIRS+=usr/include/c++/3.3/ext OLD_FILES+=usr/include/c++/3.3/fstream OLD_FILES+=usr/include/c++/3.3/functional OLD_FILES+=usr/include/c++/3.3/iomanip OLD_FILES+=usr/include/c++/3.3/ios OLD_FILES+=usr/include/c++/3.3/iosfwd OLD_FILES+=usr/include/c++/3.3/iostream OLD_FILES+=usr/include/c++/3.3/istream OLD_FILES+=usr/include/c++/3.3/iterator OLD_FILES+=usr/include/c++/3.3/limits OLD_FILES+=usr/include/c++/3.3/list OLD_FILES+=usr/include/c++/3.3/locale OLD_FILES+=usr/include/c++/3.3/map OLD_FILES+=usr/include/c++/3.3/memory OLD_FILES+=usr/include/c++/3.3/new OLD_FILES+=usr/include/c++/3.3/numeric OLD_FILES+=usr/include/c++/3.3/ostream OLD_FILES+=usr/include/c++/3.3/queue OLD_FILES+=usr/include/c++/3.3/set OLD_FILES+=usr/include/c++/3.3/sstream OLD_FILES+=usr/include/c++/3.3/stack OLD_FILES+=usr/include/c++/3.3/stdexcept OLD_FILES+=usr/include/c++/3.3/streambuf OLD_FILES+=usr/include/c++/3.3/string OLD_FILES+=usr/include/c++/3.3/typeinfo OLD_FILES+=usr/include/c++/3.3/utility OLD_FILES+=usr/include/c++/3.3/valarray OLD_FILES+=usr/include/c++/3.3/vector # 20040713: fla(4) removed OLD_FILES+=usr/share/man/man4/fla.4.gz # 200407XX OLD_FILES+=usr/sbin/kernbb OLD_FILES+=usr/sbin/ntp-genkeys OLD_FILES+=usr/sbin/ntptimeset OLD_FILES+=usr/share/man/man8/kernbb.8.gz OLD_FILES+=usr/share/man/man8/ntp-genkeys.8.gz # 20040627: usbdevs.h and usbdevs_data.h removal OLD_FILES+=usr/include/dev/usb/usbdevs.h OLD_FILES+=usr/include/dev/usb/usbdevs_data.h # 200406XX OLD_FILES+=usr/bin/gasp OLD_FILES+=usr/bin/gdbreplay OLD_FILES+=usr/share/man/man1/gasp.1.gz OLD_FILES+=sbin/mountd OLD_FILES+=sbin/mount_fdesc OLD_FILES+=sbin/mount_umap OLD_FILES+=sbin/mount_union OLD_FILES+=sbin/mount_msdos OLD_FILES+=sbin/mount_null OLD_FILES+=sbin/mount_kernfs # 200405XX: arl OLD_FILES+=usr/sbin/arlconfig OLD_FILES+=usr/share/man/man8/arlconfig.8.gz # 200403XX OLD_FILES+=bin/raidctl OLD_FILES+=sbin/raidctl OLD_FILES+=usr/bin/sasc OLD_FILES+=usr/sbin/sgsc OLD_FILES+=usr/sbin/stlload OLD_FILES+=usr/sbin/stlstats OLD_FILES+=usr/share/man/man1/sasc.1.gz OLD_FILES+=usr/share/man/man1/sgsc.1.gz OLD_FILES+=usr/share/man/man4/i386/stl.4.gz OLD_FILES+=usr/share/man/man8/raidctl.8.gz # 20040229: clean_environment() was removed after 3 days OLD_FILES+=usr/share/man/man3/clean_environment.3.gz # 20040119: installed as `isdntel' in newer systems OLD_FILES+=etc/isdn/isdntel.sh # 200XYYZZ: /lib transition clitches OLD_FILES+=lib/libalias.so OLD_FILES+=lib/libatm.so OLD_FILES+=lib/libbsdxml.so OLD_FILES+=lib/libc.so OLD_FILES+=lib/libcam.so OLD_FILES+=lib/libcrypt.so OLD_FILES+=lib/libcrypto.so OLD_FILES+=lib/libdevstat.so OLD_FILES+=lib/libedit.so OLD_FILES+=lib/libgeom.so OLD_FILES+=lib/libipsec.so OLD_FILES+=lib/libipx.so OLD_FILES+=lib/libkvm.so OLD_FILES+=lib/libm.so OLD_FILES+=lib/libmd.so OLD_FILES+=lib/libncurses.so OLD_FILES+=lib/libreadline.so OLD_FILES+=lib/libsbuf.so OLD_FILES+=lib/libufs.so OLD_FILES+=lib/libz.so # 200312XX OLD_FILES+=bin/cxconfig OLD_FILES+=sbin/cxconfig OLD_FILES+=usr/share/man/man8/cxconfig.8.gz # 20031016: MULTI_DRIVER_MODULE macro removed OLD_FILES+=usr/share/man/man9/MULTI_DRIVER_MODULE.9.gz # 200309XX OLD_FILES+=usr/bin/symorder OLD_FILES+=usr/share/man/man1/symorder.1.gz # 200308XX OLD_FILES+=usr/sbin/amldb OLD_FILES+=usr/share/man/man8/amldb.8.gz # 200307XX OLD_FILES+=sbin/mount_nwfs OLD_FILES+=sbin/mount_portalfs OLD_FILES+=sbin/mount_smbfs # 200306XX OLD_FILES+=usr/sbin/dev_mkdb OLD_FILES+=usr/share/man/man8/dev_mkdb.8.gz # 200304XX OLD_FILES+=usr/lib/libcipher.a OLD_FILES+=usr/lib/libcipher.so OLD_FILES+=usr/lib/libcipher_p.a OLD_FILES+=usr/lib/libgmp.a OLD_FILES+=usr/lib/libgmp.so OLD_FILES+=usr/lib/libgmp_p.a OLD_FILES+=usr/lib/libperl.a OLD_FILES+=usr/lib/libperl.so OLD_FILES+=usr/lib/libperl_p.a OLD_FILES+=usr/lib/libposix1e.a OLD_FILES+=usr/lib/libposix1e.so OLD_FILES+=usr/lib/libposix1e_p.a OLD_FILES+=usr/lib/libskey.a OLD_FILES+=usr/lib/libskey.so OLD_FILES+=usr/lib/libskey_p.a OLD_FILES+=usr/libexec/tradcpp0 OLD_FILES+=usr/libexec/cpp0 # 200304XX: removal of xten OLD_FILES+=usr/libexec/xtend OLD_FILES+=usr/sbin/xten OLD_FILES+=usr/share/man/man1/xten.1.gz OLD_FILES+=usr/share/man/man8/xtend.8.gz # 200303XX OLD_FILES+=usr/lib/libacl.so OLD_FILES+=usr/lib/libdescrypt.so OLD_FILES+=usr/lib/libf2c.so OLD_FILES+=usr/lib/libg++.so OLD_FILES+=usr/lib/libkdb.so OLD_FILES+=usr/lib/librsaINTL.so OLD_FILES+=usr/lib/libscrypt.so OLD_FILES+=usr/lib/libss.so # 200302XX OLD_FILES+=usr/lib/libacl.a OLD_FILES+=usr/lib/libacl_p.a OLD_FILES+=usr/lib/libkadm.a OLD_FILES+=usr/lib/libkadm.so OLD_FILES+=usr/lib/libkadm_p.a OLD_FILES+=usr/lib/libkafs.a OLD_FILES+=usr/lib/libkafs.so OLD_FILES+=usr/lib/libkafs_p.a OLD_FILES+=usr/lib/libkdb.a OLD_FILES+=usr/lib/libkdb_p.a OLD_FILES+=usr/lib/libkrb.a OLD_FILES+=usr/lib/libkrb.so OLD_FILES+=usr/lib/libkrb_p.a OLD_FILES+=usr/share/man/man3/SSL_CIPHER_get_name.3.gz OLD_FILES+=usr/share/man/man3/SSL_COMP_add_compression_method.3 OLD_FILES+=usr/share/man/man3/SSL_CTX_add_extra_chain_cert.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_add_session.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_ctrl.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_flush_sessions.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_free.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_get_verify_mode.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_load_verify_locations.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_new.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_sess_number.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_sess_set_cache_size.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_sess_set_get_cb.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_sessions.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_cert_store.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_cert_verify_callback.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_cipher_list.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_client_CA_list.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_client_cert_cb.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_default_passwd_cb.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_generate_session_id.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_info_callback.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_max_cert_list.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_mode.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_msg_callback.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_options.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_quiet_shutdown.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_session_cache_mode.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_session_id_context.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_ssl_version.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_timeout.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_tmp_dh_callback.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_tmp_rsa_callback.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_set_verify.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_use_certificate.3.gz OLD_FILES+=usr/share/man/man3/SSL_SESSION_free.3.gz OLD_FILES+=usr/share/man/man3/SSL_SESSION_get_ex_new_index.3.gz OLD_FILES+=usr/share/man/man3/SSL_SESSION_get_time.3.gz OLD_FILES+=usr/share/man/man3/SSL_accept.3.gz OLD_FILES+=usr/share/man/man3/SSL_alert_type_string.3.gz OLD_FILES+=usr/share/man/man3/SSL_clear.3.gz OLD_FILES+=usr/share/man/man3/SSL_connect.3.gz OLD_FILES+=usr/share/man/man3/SSL_do_handshake.3.gz OLD_FILES+=usr/share/man/man3/SSL_free.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_SSL_CTX.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_ciphers.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_client_CA_list.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_current_cipher.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_default_timeout.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_error.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_ex_data_X509_STORE_CTX_idx.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_ex_new_index.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_fd.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_peer_cert_chain.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_peer_certificate.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_rbio.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_session.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_verify_result.3.gz OLD_FILES+=usr/share/man/man3/SSL_get_version.3.gz OLD_FILES+=usr/share/man/man3/SSL_library_init.3.gz OLD_FILES+=usr/share/man/man3/SSL_load_client_CA_file.3.gz OLD_FILES+=usr/share/man/man3/SSL_new.3.gz OLD_FILES+=usr/share/man/man3/SSL_pending.3.gz OLD_FILES+=usr/share/man/man3/SSL_read.3.gz OLD_FILES+=usr/share/man/man3/SSL_rstate_string.3.gz OLD_FILES+=usr/share/man/man3/SSL_session_reused.3.gz OLD_FILES+=usr/share/man/man3/SSL_set_bio.3.gz OLD_FILES+=usr/share/man/man3/SSL_set_connect_state.3.gz OLD_FILES+=usr/share/man/man3/SSL_set_fd.3.gz OLD_FILES+=usr/share/man/man3/SSL_set_session.3.gz OLD_FILES+=usr/share/man/man3/SSL_set_shutdown.3.gz OLD_FILES+=usr/share/man/man3/SSL_set_verify_result.3.gz OLD_FILES+=usr/share/man/man3/SSL_shutdown.3.gz OLD_FILES+=usr/share/man/man3/SSL_state_string.3.gz OLD_FILES+=usr/share/man/man3/SSL_want.3.gz OLD_FILES+=usr/share/man/man3/SSL_write.3.gz OLD_FILES+=usr/share/man/man3/d2i_SSL_SESSION.3.gz # 200301XX OLD_FILES+=usr/share/man/man3/des_3cbc_encrypt.3.gz OLD_FILES+=usr/share/man/man3/des_3ecb_encrypt.3.gz OLD_FILES+=usr/share/man/man3/des_cbc_cksum.3.gz OLD_FILES+=usr/share/man/man3/des_cbc_encrypt.3.gz OLD_FILES+=usr/share/man/man3/des_cfb_encrypt.3.gz OLD_FILES+=usr/share/man/man3/des_ecb_encrypt.3.gz OLD_FILES+=usr/share/man/man3/des_enc_read.3.gz OLD_FILES+=usr/share/man/man3/des_enc_write.3.gz OLD_FILES+=usr/share/man/man3/des_is_weak_key.3.gz OLD_FILES+=usr/share/man/man3/des_key_sched.3.gz OLD_FILES+=usr/share/man/man3/des_ofb_encrypt.3.gz OLD_FILES+=usr/share/man/man3/des_pcbc_encrypt.3.gz OLD_FILES+=usr/share/man/man3/des_quad_cksum.3.gz OLD_FILES+=usr/share/man/man3/des_random_key.3.gz OLD_FILES+=usr/share/man/man3/des_read_2password.3.gz OLD_FILES+=usr/share/man/man3/des_read_password.3.gz OLD_FILES+=usr/share/man/man3/des_read_pw_string.3.gz OLD_FILES+=usr/share/man/man3/des_set_key.3.gz OLD_FILES+=usr/share/man/man3/des_set_odd_parity.3.gz OLD_FILES+=usr/share/man/man3/des_string_to_2key.3.gz OLD_FILES+=usr/share/man/man3/des_string_to_key.3.gz # 200212XX OLD_FILES+=usr/sbin/kenv OLD_FILES+=usr/bin/kenv OLD_FILES+=usr/sbin/elf2aout # 200210XX OLD_FILES+=usr/include/libusbhid.h OLD_FILES+=usr/share/man/man3/All_FreeBSD.3.gz OLD_FILES+=usr/share/man/man3/CheckRules.3.gz OLD_FILES+=usr/share/man/man3/ChunkCanBeRoot.3.gz OLD_FILES+=usr/share/man/man3/Clone_Disk.3.gz OLD_FILES+=usr/share/man/man3/Collapse_Chunk.3.gz OLD_FILES+=usr/share/man/man3/Collapse_Disk.3.gz OLD_FILES+=usr/share/man/man3/Create_Chunk.3.gz OLD_FILES+=usr/share/man/man3/Create_Chunk_DWIM.3.gz OLD_FILES+=usr/share/man/man3/Cyl_Aligned.3.gz OLD_FILES+=usr/share/man/man3/Debug_Disk.3.gz OLD_FILES+=usr/share/man/man3/Delete_Chunk.3.gz OLD_FILES+=usr/share/man/man3/Disk_Names.3.gz OLD_FILES+=usr/share/man/man3/Free_Disk.3.gz OLD_FILES+=usr/share/man/man3/MakeDev.3.gz OLD_FILES+=usr/share/man/man3/MakeDevDisk.3.gz OLD_FILES+=usr/share/man/man3/Next_Cyl_Aligned.3.gz OLD_FILES+=usr/share/man/man3/Next_Track_Aligned.3.gz OLD_FILES+=usr/share/man/man3/Open_Disk.3.gz OLD_FILES+=usr/share/man/man3/Prev_Cyl_Aligned.3.gz OLD_FILES+=usr/share/man/man3/Prev_Track_Aligned.3.gz OLD_FILES+=usr/share/man/man3/Set_Bios_Geom.3.gz OLD_FILES+=usr/share/man/man3/Set_Boot_Blocks.3.gz OLD_FILES+=usr/share/man/man3/Set_Boot_Mgr.3.gz OLD_FILES+=usr/share/man/man3/ShowChunkFlags.3.gz OLD_FILES+=usr/share/man/man3/Track_Aligned.3.gz OLD_FILES+=usr/share/man/man3/Write_Disk.3.gz OLD_FILES+=usr/share/man/man3/slice_type_name.3.gz # 200210XX: most games moved to ports OLD_FILES+=usr/share/man/man6/adventure.6.gz OLD_FILES+=usr/share/man/man6/arithmetic.6.gz OLD_FILES+=usr/share/man/man6/atc.6.gz OLD_FILES+=usr/share/man/man6/backgammon.6.gz OLD_FILES+=usr/share/man/man6/battlestar.6.gz OLD_FILES+=usr/share/man/man6/bs.6.gz OLD_FILES+=usr/share/man/man6/canfield.6.gz OLD_FILES+=usr/share/man/man6/cfscores.6.gz OLD_FILES+=usr/share/man/man6/cribbage.6.gz OLD_FILES+=usr/share/man/man6/fish.6.gz OLD_FILES+=usr/share/man/man6/hack.6.gz OLD_FILES+=usr/share/man/man6/hangman.6.gz OLD_FILES+=usr/share/man/man6/larn.6.gz OLD_FILES+=usr/share/man/man6/mille.6.gz OLD_FILES+=usr/share/man/man6/phantasia.6.gz OLD_FILES+=usr/share/man/man6/piano.6.gz OLD_FILES+=usr/share/man/man6/pig.6.gz OLD_FILES+=usr/share/man/man6/quiz.6.gz OLD_FILES+=usr/share/man/man6/rain.6.gz OLD_FILES+=usr/share/man/man6/robots.6.gz OLD_FILES+=usr/share/man/man6/rogue.6.gz OLD_FILES+=usr/share/man/man6/sail.6.gz OLD_FILES+=usr/share/man/man6/snake.6.gz OLD_FILES+=usr/share/man/man6/snscore.6.gz OLD_FILES+=usr/share/man/man6/trek.6.gz OLD_FILES+=usr/share/man/man6/wargames.6.gz OLD_FILES+=usr/share/man/man6/worm.6.gz OLD_FILES+=usr/share/man/man6/worms.6.gz OLD_FILES+=usr/share/man/man6/wump.6.gz # 200207XX OLD_FILES+=usr/share/man/man1aout/ar.1aout.gz OLD_FILES+=usr/share/man/man1aout/as.1aout.gz OLD_FILES+=usr/share/man/man1aout/ld.1aout.gz OLD_FILES+=usr/share/man/man1aout/nm.1aout.gz OLD_FILES+=usr/share/man/man1aout/ranlib.1aout.gz OLD_FILES+=usr/share/man/man1aout/size.1aout.gz OLD_FILES+=usr/share/man/man1aout/strings.1aout.gz OLD_FILES+=usr/share/man/man1aout/strip.1aout.gz OLD_FILES+=bin/mountd OLD_FILES+=bin/nfsd # 20020707 sbin/nfsd -> usr.sbin/nfsd OLD_FILES+=sbin/nfsd # 200206XX OLD_FILES+=usr/lib/libpam_ssh.a OLD_FILES+=usr/lib/libpam_ssh_p.a OLD_FILES+=usr/bin/help OLD_FILES+=usr/bin/sccs .if ${TARGET_ARCH} != "amd64" && ${TARGET} != "arm" && ${TARGET_ARCH} != "i386" && ${TARGET} != "powerpc" OLD_FILES+=usr/bin/gdbserver .endif OLD_FILES+=usr/bin/ssh-keysign OLD_FILES+=usr/sbin/gifconfig OLD_FILES+=usr/sbin/prefix # 200205XX OLD_FILES+=usr/bin/doscmd # 200204XX OLD_FILES+=usr/bin/a2p OLD_FILES+=usr/bin/ptx OLD_FILES+=usr/bin/pod2text OLD_FILES+=usr/bin/pod2man OLD_FILES+=usr/bin/pod2latex OLD_FILES+=usr/bin/pod2html OLD_FILES+=usr/bin/h2ph OLD_FILES+=usr/bin/dprofpp OLD_FILES+=usr/bin/c2ph OLD_FILES+=usr/bin/h2xs OLD_FILES+=usr/bin/pl2pm OLD_FILES+=usr/bin/splain OLD_FILES+=usr/bin/s2p OLD_FILES+=usr/bin/find2perl OLD_FILES+=usr/sbin/pkg_update OLD_FILES+=usr/sbin/scriptdump # 20020409 GC kget(1), userconfig is long dead. OLD_FILES+=sbin/kget OLD_FILES+=usr/share/man/man8/kget.8.gz # 200203XX OLD_FILES+=usr/lib/libss.a OLD_FILES+=usr/lib/libss_p.a OLD_FILES+=usr/lib/libtelnet.a OLD_FILES+=usr/lib/libtelnet_p.a OLD_FILES+=usr/sbin/diskpart # 200202XX OLD_FILES+=usr/bin/gprof4 # 200201XX OLD_FILES+=usr/sbin/linux # 2001XXXX OLD_FILES+=usr/bin/joy OLD_FILES+=usr/sbin/ibcs2 OLD_FILES+=usr/sbin/svr4 OLD_FILES+=usr/bin/chflags OLD_FILES+=usr/sbin/uuconv OLD_FILES+=usr/sbin/uuchk OLD_FILES+=usr/sbin/portmap OLD_FILES+=usr/sbin/pmap_set OLD_FILES+=usr/sbin/pmap_dump OLD_FILES+=usr/sbin/mcon OLD_FILES+=usr/sbin/stlstty OLD_FILES+=usr/sbin/ispppcontrol OLD_FILES+=usr/sbin/rndcontrol # 20011001: UUCP migration to ports OLD_FILES+=usr/bin/uucp OLD_FILES+=usr/bin/uulog OLD_FILES+=usr/bin/uuname OLD_FILES+=usr/bin/uupick OLD_FILES+=usr/bin/uusched OLD_FILES+=usr/bin/uustat OLD_FILES+=usr/bin/uuto OLD_FILES+=usr/bin/uux OLD_FILES+=usr/libexec/uucp/uucico OLD_FILES+=usr/libexec/uucp/uuxqt OLD_FILES+=usr/libexec/uucpd OLD_FILES+=usr/share/man/man1/uuconv.1.gz OLD_FILES+=usr/share/man/man1/uucp.1.gz OLD_FILES+=usr/share/man/man1/uulog.1.gz OLD_FILES+=usr/share/man/man1/uuname.1.gz OLD_FILES+=usr/share/man/man1/uupick.1.gz OLD_FILES+=usr/share/man/man1/uustat.1.gz OLD_FILES+=usr/share/man/man1/uuto.1.gz OLD_FILES+=usr/share/man/man1/uux.1.gz OLD_FILES+=usr/share/man/man8/uuchk.8.gz OLD_FILES+=usr/share/man/man8/uucico.8.gz OLD_FILES+=usr/share/man/man8/uucpd.8.gz OLD_FILES+=usr/share/man/man8/uusched.8.gz OLD_FILES+=usr/share/man/man8/uuxqt.8.gz # 20010523 mount_portal -> mount_portalfs OLD_FILES+=sbin/mount_portal OLD_FILES+=usr/share/man/man8/mount_portal.8.gz # 200104XX OLD_FILES+=usr/lib/libdescrypt.a OLD_FILES+=usr/lib/libscrypt.a OLD_FILES+=usr/lib/libscrypt_p.a OLD_FILES+=usr/sbin/pim6stat OLD_FILES+=usr/sbin/pim6sd OLD_FILES+=usr/sbin/pim6dd # 20010217 OLD_FILES+=usr/share/doc/bind/misc/dns-setup # 20001200 OLD_FILES+=usr/lib/libgcc_r_pic.a # 200009XX OLD_FILES+=usr/lib/libRSAglue.a OLD_FILES+=usr/lib/libRSAglue.so OLD_FILES+=usr/lib/librsaINTL.a OLD_FILES+=usr/lib/librsaUSA.a OLD_FILES+=usr/lib/librsaUSA.so # 200002XX ? OLD_FILES+=usr/lib/libf2c.a OLD_FILES+=usr/lib/libf2c_p.a OLD_FILES+=usr/lib/libg++.a OLD_FILES+=usr/lib/libg++_p.a # 20001006 OLD_FILES+=usr/bin/miniperl # 20000810 OLD_FILES+=usr/bin/sperl # 200001XX OLD_FILES+=usr/sbin/apmconf ## unsorted # do we still support aout builds? #OLD_FILES+=usr/lib/aout/c++rt0.o #OLD_FILES+=usr/lib/aout/crt0.o #OLD_FILES+=usr/lib/aout/gcrt0.o #OLD_FILES+=usr/lib/aout/scrt0.o #OLD_FILES+=usr/lib/aout/sgcrt0.o OLD_FILES+=usr/lib/pam_ftp.so OLD_FILES+=usr/share/man/man1/CA.pl.1.gz OLD_FILES+=usr/share/man/man1/asn1parse.1.gz OLD_FILES+=usr/share/man/man1/ca.1.gz OLD_FILES+=usr/share/man/man1/ciphers.1.gz OLD_FILES+=usr/share/man/man1/config.1.gz OLD_FILES+=usr/share/man/man1/crl.1.gz OLD_FILES+=usr/share/man/man1/crl2pkcs7.1.gz OLD_FILES+=usr/share/man/man1/dgst.1.gz OLD_FILES+=usr/share/man/man1/dhparam.1.gz OLD_FILES+=usr/share/man/man1/doscmd.1.gz OLD_FILES+=usr/share/man/man1/dsa.1.gz OLD_FILES+=usr/share/man/man1/dsaparam.1.gz OLD_FILES+=usr/share/man/man1/enc.1.gz OLD_FILES+=usr/share/man/man1/gendsa.1.gz OLD_FILES+=usr/share/man/man1/genrsa.1.gz OLD_FILES+=usr/share/man/man1/getNAME.1.gz OLD_FILES+=usr/share/man/man1/nseq.1.gz OLD_FILES+=usr/share/man/man1/ocsp.1.gz OLD_FILES+=usr/share/man/man1/openssl.1.gz OLD_FILES+=usr/share/man/man1/pkcs12.1.gz OLD_FILES+=usr/share/man/man1/pkcs7.1.gz OLD_FILES+=usr/share/man/man1/pkcs8.1.gz OLD_FILES+=usr/share/man/man1/rand.1.gz OLD_FILES+=usr/share/man/man1/req.1.gz OLD_FILES+=usr/share/man/man1/rsa.1.gz OLD_FILES+=usr/share/man/man1/rsautl.1.gz OLD_FILES+=usr/share/man/man1/s_client.1.gz OLD_FILES+=usr/share/man/man1/s_server.1.gz OLD_FILES+=usr/share/man/man1/sess_id.1.gz OLD_FILES+=usr/share/man/man1/smime.1.gz OLD_FILES+=usr/share/man/man1/speed.1.gz OLD_FILES+=usr/share/man/man1/spkac.1.gz OLD_FILES+=usr/share/man/man1/verify.1.gz OLD_FILES+=usr/share/man/man1/version.1.gz OLD_FILES+=usr/share/man/man1/x509.1.gz OLD_FILES+=usr/share/man/man3/SSL_COMP_add_compression_method.3.gz OLD_FILES+=usr/share/man/man3/SSL_CTX_get_ex_new_index.3.gz OLD_FILES+=usr/share/man/man3/archive_entry_dup.3.gz OLD_FILES+=usr/share/man/man3/archive_entry_set_tartype.3.gz OLD_FILES+=usr/share/man/man3/archive_entry_tartype.3.gz OLD_FILES+=usr/share/man/man3/archive_read_data_into_file.3.gz OLD_FILES+=usr/share/man/man3/archive_read_open_tar.3.gz OLD_FILES+=usr/share/man/man3/archive_read_support_format_gnutar.3.gz OLD_FILES+=usr/share/man/man3/cipher.3.gz OLD_FILES+=usr/share/man/man3/des_cipher.3.gz OLD_FILES+=usr/share/man/man3/des_setkey.3.gz OLD_FILES+=usr/share/man/man3/encrypt.3.gz OLD_FILES+=usr/share/man/man3/endvfsent.3.gz OLD_FILES+=usr/share/man/man3/getvfsbytype.3.gz OLD_FILES+=usr/share/man/man3/getvfsent.3.gz OLD_FILES+=usr/share/man/man3/isnanf.3.gz OLD_FILES+=usr/share/man/man3/libautofs.3.gz OLD_FILES+=usr/share/man/man3/pthread_attr_setsstack.3.gz OLD_FILES+=usr/share/man/man3/pthread_getcancelstate.3.gz OLD_FILES+=usr/share/man/man3/set_assertion_failure_callback.3.gz OLD_FILES+=usr/share/man/man3/setkey.3.gz OLD_FILES+=usr/share/man/man3/setvfsent.3.gz OLD_FILES+=usr/share/man/man3/ssl.3.gz OLD_FILES+=usr/share/man/man3/vfsisloadable.3.gz OLD_FILES+=usr/share/man/man3/vfsload.3.gz OLD_FILES+=usr/share/man/man4/als4000.4.gz OLD_FILES+=usr/share/man/man4/csa.4.gz OLD_FILES+=usr/share/man/man4/emu10k1.4.gz OLD_FILES+=usr/share/man/man4/euc.4.gz OLD_FILES+=usr/share/man/man4/gusc.4.gz OLD_FILES+=usr/share/man/man4/if_fwp.4.gz OLD_FILES+=usr/share/man/man4/lomac.4.gz OLD_FILES+=usr/share/man/man4/maestro3.4.gz OLD_FILES+=usr/share/man/man4/raid.4.gz OLD_FILES+=usr/share/man/man4/sbc.4.gz OLD_FILES+=usr/share/man/man4/sd.4.gz OLD_FILES+=usr/share/man/man4/snc.4.gz OLD_FILES+=usr/share/man/man4/st.4.gz OLD_FILES+=usr/share/man/man4/uaudio.4.gz OLD_FILES+=usr/share/man/man4/utf2.4.gz OLD_FILES+=usr/share/man/man4/vinumdebug.4.gz OLD_FILES+=usr/share/man/man5/disklabel.5.gz OLD_FILES+=usr/share/man/man5/dm.conf.5.gz OLD_FILES+=usr/share/man/man5/ranlib.5.gz OLD_FILES+=usr/share/man/man5/utf2.5.gz OLD_FILES+=usr/share/man/man7/groff_mwww.7.gz OLD_FILES+=usr/share/man/man7/mmroff.7.gz OLD_FILES+=usr/share/man/man7/mwww.7.gz OLD_FILES+=usr/share/man/man8/dm.8.gz OLD_FILES+=usr/share/man/man8/pam_ftp.8.gz OLD_FILES+=usr/share/man/man8/pam_wheel.8.gz OLD_FILES+=usr/share/man/man8/ssl.8.gz OLD_FILES+=usr/share/man/man8/wlconfig.8.gz OLD_FILES+=usr/share/man/man9/CURSIG.9.gz OLD_FILES+=usr/share/man/man9/VFS_INIT.9.gz OLD_FILES+=usr/share/man/man9/at_exit.9.gz OLD_FILES+=usr/share/man/man9/at_fork.9.gz OLD_FILES+=usr/share/man/man9/cdevsw_add.9.gz OLD_FILES+=usr/share/man/man9/cdevsw_remove.9.gz OLD_FILES+=usr/share/man/man9/cv_waitq_empty.9.gz OLD_FILES+=usr/share/man/man9/cv_waitq_remove.9.gz OLD_FILES+=usr/share/man/man9/endtsleep.9.gz OLD_FILES+=usr/share/man/man9/jumbo.9.gz OLD_FILES+=usr/share/man/man9/jumbo_freem.9.gz OLD_FILES+=usr/share/man/man9/jumbo_pg_alloc.9.gz OLD_FILES+=usr/share/man/man9/jumbo_pg_free.9.gz OLD_FILES+=usr/share/man/man9/jumbo_pg_steal.9.gz OLD_FILES+=usr/share/man/man9/jumbo_phys_to_kva.9.gz OLD_FILES+=usr/share/man/man9/jumbo_vm_init.9.gz OLD_FILES+=usr/share/man/man9/mac_biba.9.gz OLD_FILES+=usr/share/man/man9/mac_bsdextended.9.gz OLD_FILES+=usr/share/man/man9/mono_time.9.gz OLD_FILES+=usr/share/man/man9/p1003_1b.9.gz OLD_FILES+=usr/share/man/man9/pmap_prefault.9.gz OLD_FILES+=usr/share/man/man9/posix4.9.gz OLD_FILES+=usr/share/man/man9/resource_query_name.9.gz OLD_FILES+=usr/share/man/man9/resource_query_string.9.gz OLD_FILES+=usr/share/man/man9/resource_query_unit.9.gz OLD_FILES+=usr/share/man/man9/rm_at_exit.9.gz OLD_FILES+=usr/share/man/man9/rm_at_fork.9.gz OLD_FILES+=usr/share/man/man9/runtime.9.gz OLD_FILES+=usr/share/man/man9/sleepinit.9.gz OLD_FILES+=usr/share/man/man9/unsleep.9.gz OLD_FILES+=usr/share/games/atc/Game_List OLD_FILES+=usr/share/games/atc/Killer OLD_FILES+=usr/share/games/atc/crossover OLD_FILES+=usr/share/games/atc/default OLD_FILES+=usr/share/games/atc/easy OLD_FILES+=usr/share/games/atc/game_2 OLD_FILES+=usr/share/games/larn/larnmaze OLD_FILES+=usr/share/games/larn/larnopts OLD_FILES+=usr/share/games/larn/larn.help OLD_FILES+=usr/share/games/quiz.db/africa OLD_FILES+=usr/share/games/quiz.db/america OLD_FILES+=usr/share/games/quiz.db/areas OLD_FILES+=usr/share/games/quiz.db/arith OLD_FILES+=usr/share/games/quiz.db/asia OLD_FILES+=usr/share/games/quiz.db/babies OLD_FILES+=usr/share/games/quiz.db/bard OLD_FILES+=usr/share/games/quiz.db/chinese OLD_FILES+=usr/share/games/quiz.db/collectives OLD_FILES+=usr/share/games/quiz.db/ed OLD_FILES+=usr/share/games/quiz.db/elements OLD_FILES+=usr/share/games/quiz.db/europe OLD_FILES+=usr/share/games/quiz.db/flowers OLD_FILES+=usr/share/games/quiz.db/greek OLD_FILES+=usr/share/games/quiz.db/inca OLD_FILES+=usr/share/games/quiz.db/index OLD_FILES+=usr/share/games/quiz.db/latin OLD_FILES+=usr/share/games/quiz.db/locomotive OLD_FILES+=usr/share/games/quiz.db/midearth OLD_FILES+=usr/share/games/quiz.db/morse OLD_FILES+=usr/share/games/quiz.db/murders OLD_FILES+=usr/share/games/quiz.db/poetry OLD_FILES+=usr/share/games/quiz.db/posneg OLD_FILES+=usr/share/games/quiz.db/pres OLD_FILES+=usr/share/games/quiz.db/province OLD_FILES+=usr/share/games/quiz.db/seq-easy OLD_FILES+=usr/share/games/quiz.db/seq-hard OLD_FILES+=usr/share/games/quiz.db/sexes OLD_FILES+=usr/share/games/quiz.db/sov OLD_FILES+=usr/share/games/quiz.db/spell OLD_FILES+=usr/share/games/quiz.db/state OLD_FILES+=usr/share/games/quiz.db/trek OLD_FILES+=usr/share/games/quiz.db/ucc OLD_FILES+=usr/share/games/cribbage.instr OLD_FILES+=usr/share/games/fish.instr OLD_FILES+=usr/share/games/wump.info OLD_FILES+=usr/games/hide/adventure OLD_FILES+=usr/games/hide/arithmetic OLD_FILES+=usr/games/hide/atc OLD_FILES+=usr/games/hide/backgammon OLD_FILES+=usr/games/hide/teachgammon OLD_FILES+=usr/games/hide/battlestar OLD_FILES+=usr/games/hide/bs OLD_FILES+=usr/games/hide/canfield OLD_FILES+=usr/games/hide/cribbage OLD_FILES+=usr/games/hide/fish OLD_FILES+=usr/games/hide/hack OLD_FILES+=usr/games/hide/hangman OLD_FILES+=usr/games/hide/larn OLD_FILES+=usr/games/hide/mille OLD_FILES+=usr/games/hide/phantasia OLD_FILES+=usr/games/hide/quiz OLD_FILES+=usr/games/hide/robots OLD_FILES+=usr/games/hide/rogue OLD_FILES+=usr/games/hide/sail OLD_FILES+=usr/games/hide/snake OLD_FILES+=usr/games/hide/trek OLD_FILES+=usr/games/hide/worm OLD_FILES+=usr/games/hide/wump OLD_FILES+=usr/games/adventure OLD_FILES+=usr/games/arithmetic OLD_FILES+=usr/games/atc OLD_FILES+=usr/games/backgammon OLD_FILES+=usr/games/teachgammon OLD_FILES+=usr/games/battlestar OLD_FILES+=usr/games/bs OLD_FILES+=usr/games/canfield OLD_FILES+=usr/games/cfscores OLD_FILES+=usr/games/cribbage OLD_FILES+=usr/games/dm OLD_FILES+=usr/games/fish OLD_FILES+=usr/games/hack OLD_FILES+=usr/games/hangman OLD_FILES+=usr/games/larn OLD_FILES+=usr/games/mille OLD_FILES+=usr/games/phantasia OLD_FILES+=usr/games/piano OLD_FILES+=usr/games/pig OLD_FILES+=usr/games/quiz OLD_FILES+=usr/games/rain OLD_FILES+=usr/games/robots OLD_FILES+=usr/games/rogue OLD_FILES+=usr/games/sail OLD_FILES+=usr/games/snake OLD_FILES+=usr/games/snscore OLD_FILES+=usr/games/trek OLD_FILES+=usr/games/wargames OLD_FILES+=usr/games/worm OLD_FILES+=usr/games/worms OLD_FILES+=usr/games/wump OLD_FILES+=sbin/mount_reiserfs OLD_FILES+=usr/include/cam/cam_extend.h OLD_FILES+=usr/include/dev/wi/wi_hostap.h OLD_FILES+=usr/include/disktab.h OLD_FILES+=usr/include/g++/FlexLexer.h OLD_FILES+=usr/include/g++/PlotFile.h OLD_FILES+=usr/include/g++/SFile.h OLD_FILES+=usr/include/g++/_G_config.h OLD_FILES+=usr/include/g++/algo.h OLD_FILES+=usr/include/g++/algobase.h OLD_FILES+=usr/include/g++/algorithm OLD_FILES+=usr/include/g++/alloc.h OLD_FILES+=usr/include/g++/bitset OLD_FILES+=usr/include/g++/builtinbuf.h OLD_FILES+=usr/include/g++/bvector.h OLD_FILES+=usr/include/g++/cassert OLD_FILES+=usr/include/g++/cctype OLD_FILES+=usr/include/g++/cerrno OLD_FILES+=usr/include/g++/cfloat OLD_FILES+=usr/include/g++/ciso646 OLD_FILES+=usr/include/g++/climits OLD_FILES+=usr/include/g++/clocale OLD_FILES+=usr/include/g++/cmath OLD_FILES+=usr/include/g++/complex OLD_FILES+=usr/include/g++/complex.h OLD_FILES+=usr/include/g++/csetjmp OLD_FILES+=usr/include/g++/csignal OLD_FILES+=usr/include/g++/cstdarg OLD_FILES+=usr/include/g++/cstddef OLD_FILES+=usr/include/g++/cstdio OLD_FILES+=usr/include/g++/cstdlib OLD_FILES+=usr/include/g++/cstring OLD_FILES+=usr/include/g++/ctime OLD_FILES+=usr/include/g++/cwchar OLD_FILES+=usr/include/g++/cwctype OLD_FILES+=usr/include/g++/defalloc.h OLD_FILES+=usr/include/g++/deque OLD_FILES+=usr/include/g++/deque.h OLD_FILES+=usr/include/g++/editbuf.h OLD_FILES+=usr/include/g++/exception OLD_FILES+=usr/include/g++/floatio.h OLD_FILES+=usr/include/g++/fstream OLD_FILES+=usr/include/g++/fstream.h OLD_FILES+=usr/include/g++/function.h OLD_FILES+=usr/include/g++/functional OLD_FILES+=usr/include/g++/hash_map OLD_FILES+=usr/include/g++/hash_map.h OLD_FILES+=usr/include/g++/hash_set OLD_FILES+=usr/include/g++/hash_set.h OLD_FILES+=usr/include/g++/hashtable.h OLD_FILES+=usr/include/g++/heap.h OLD_FILES+=usr/include/g++/indstream.h OLD_FILES+=usr/include/g++/iolibio.h OLD_FILES+=usr/include/g++/iomanip OLD_FILES+=usr/include/g++/iomanip.h OLD_FILES+=usr/include/g++/iosfwd OLD_FILES+=usr/include/g++/iostdio.h OLD_FILES+=usr/include/g++/iostream OLD_FILES+=usr/include/g++/iostream.h OLD_FILES+=usr/include/g++/iostreamP.h OLD_FILES+=usr/include/g++/istream.h OLD_FILES+=usr/include/g++/iterator OLD_FILES+=usr/include/g++/iterator.h OLD_FILES+=usr/include/g++/libio.h OLD_FILES+=usr/include/g++/libioP.h OLD_FILES+=usr/include/g++/list OLD_FILES+=usr/include/g++/list.h OLD_FILES+=usr/include/g++/map OLD_FILES+=usr/include/g++/map.h OLD_FILES+=usr/include/g++/memory OLD_FILES+=usr/include/g++/multimap.h OLD_FILES+=usr/include/g++/multiset.h OLD_FILES+=usr/include/g++/new OLD_FILES+=usr/include/g++/new.h OLD_FILES+=usr/include/g++/numeric OLD_FILES+=usr/include/g++/ostream.h OLD_FILES+=usr/include/g++/pair.h OLD_FILES+=usr/include/g++/parsestream.h OLD_FILES+=usr/include/g++/pfstream.h OLD_FILES+=usr/include/g++/procbuf.h OLD_FILES+=usr/include/g++/pthread_alloc OLD_FILES+=usr/include/g++/pthread_alloc.h OLD_FILES+=usr/include/g++/queue OLD_FILES+=usr/include/g++/rope OLD_FILES+=usr/include/g++/rope.h OLD_FILES+=usr/include/g++/ropeimpl.h OLD_FILES+=usr/include/g++/set OLD_FILES+=usr/include/g++/set.h OLD_FILES+=usr/include/g++/slist OLD_FILES+=usr/include/g++/slist.h OLD_FILES+=usr/include/g++/sstream OLD_FILES+=usr/include/g++/stack OLD_FILES+=usr/include/g++/stack.h OLD_FILES+=usr/include/g++/std/bastring.cc OLD_FILES+=usr/include/g++/std/bastring.h OLD_FILES+=usr/include/g++/std/complext.cc OLD_FILES+=usr/include/g++/std/complext.h OLD_FILES+=usr/include/g++/std/dcomplex.h OLD_FILES+=usr/include/g++/std/fcomplex.h OLD_FILES+=usr/include/g++/std/gslice.h OLD_FILES+=usr/include/g++/std/gslice_array.h OLD_FILES+=usr/include/g++/std/indirect_array.h OLD_FILES+=usr/include/g++/std/ldcomplex.h OLD_FILES+=usr/include/g++/std/mask_array.h OLD_FILES+=usr/include/g++/std/slice.h OLD_FILES+=usr/include/g++/std/slice_array.h OLD_FILES+=usr/include/g++/std/std_valarray.h OLD_FILES+=usr/include/g++/std/straits.h OLD_FILES+=usr/include/g++/std/valarray_array.h OLD_FILES+=usr/include/g++/std/valarray_array.tcc OLD_FILES+=usr/include/g++/std/valarray_meta.h OLD_FILES+=usr/include/g++/stdexcept OLD_FILES+=usr/include/g++/stdiostream.h OLD_FILES+=usr/include/g++/stl.h OLD_FILES+=usr/include/g++/stl_algo.h OLD_FILES+=usr/include/g++/stl_algobase.h OLD_FILES+=usr/include/g++/stl_alloc.h OLD_FILES+=usr/include/g++/stl_bvector.h OLD_FILES+=usr/include/g++/stl_config.h OLD_FILES+=usr/include/g++/stl_construct.h OLD_FILES+=usr/include/g++/stl_deque.h OLD_FILES+=usr/include/g++/stl_function.h OLD_FILES+=usr/include/g++/stl_hash_fun.h OLD_FILES+=usr/include/g++/stl_hash_map.h OLD_FILES+=usr/include/g++/stl_hash_set.h OLD_FILES+=usr/include/g++/stl_hashtable.h OLD_FILES+=usr/include/g++/stl_heap.h OLD_FILES+=usr/include/g++/stl_iterator.h OLD_FILES+=usr/include/g++/stl_list.h OLD_FILES+=usr/include/g++/stl_map.h OLD_FILES+=usr/include/g++/stl_multimap.h OLD_FILES+=usr/include/g++/stl_multiset.h OLD_FILES+=usr/include/g++/stl_numeric.h OLD_FILES+=usr/include/g++/stl_pair.h OLD_FILES+=usr/include/g++/stl_queue.h OLD_FILES+=usr/include/g++/stl_raw_storage_iter.h OLD_FILES+=usr/include/g++/stl_relops.h OLD_FILES+=usr/include/g++/stl_rope.h OLD_FILES+=usr/include/g++/stl_set.h OLD_FILES+=usr/include/g++/stl_slist.h OLD_FILES+=usr/include/g++/stl_stack.h OLD_FILES+=usr/include/g++/stl_tempbuf.h OLD_FILES+=usr/include/g++/stl_tree.h OLD_FILES+=usr/include/g++/stl_uninitialized.h OLD_FILES+=usr/include/g++/stl_vector.h OLD_FILES+=usr/include/g++/stream.h OLD_FILES+=usr/include/g++/streambuf.h OLD_FILES+=usr/include/g++/strfile.h OLD_FILES+=usr/include/g++/string OLD_FILES+=usr/include/g++/strstream OLD_FILES+=usr/include/g++/strstream.h OLD_FILES+=usr/include/g++/tempbuf.h OLD_FILES+=usr/include/g++/tree.h OLD_FILES+=usr/include/g++/type_traits.h OLD_FILES+=usr/include/g++/typeinfo OLD_FILES+=usr/include/g++/utility OLD_FILES+=usr/include/g++/valarray OLD_FILES+=usr/include/g++/vector OLD_FILES+=usr/include/g++/vector.h OLD_FILES+=usr/include/gmp.h OLD_FILES+=usr/include/isc/assertions.h OLD_FILES+=usr/include/isc/ctl.h OLD_FILES+=usr/include/isc/dst.h OLD_FILES+=usr/include/isc/eventlib.h OLD_FILES+=usr/include/isc/heap.h OLD_FILES+=usr/include/isc/irpmarshall.h OLD_FILES+=usr/include/isc/list.h OLD_FILES+=usr/include/isc/logging.h OLD_FILES+=usr/include/isc/memcluster.h OLD_FILES+=usr/include/isc/misc.h OLD_FILES+=usr/include/isc/tree.h OLD_FILES+=usr/include/machine/ansi.h OLD_FILES+=usr/include/machine/apic.h OLD_FILES+=usr/include/machine/asc_ioctl.h OLD_FILES+=usr/include/machine/asnames.h OLD_FILES+=usr/include/machine/bus_at386.h OLD_FILES+=usr/include/machine/bus_memio.h OLD_FILES+=usr/include/machine/bus_pc98.h OLD_FILES+=usr/include/machine/bus_pio.h OLD_FILES+=usr/include/machine/cdk.h OLD_FILES+=usr/include/machine/comstats.h OLD_FILES+=usr/include/machine/console.h OLD_FILES+=usr/include/machine/critical.h OLD_FILES+=usr/include/machine/cronyx.h OLD_FILES+=usr/include/machine/dvcfg.h OLD_FILES+=usr/include/machine/globaldata.h OLD_FILES+=usr/include/machine/globals.h OLD_FILES+=usr/include/machine/gsc.h OLD_FILES+=usr/include/machine/i4b_isppp.h OLD_FILES+=usr/include/machine/if_wavelan_ieee.h OLD_FILES+=usr/include/machine/iic.h OLD_FILES+=usr/include/machine/ioctl_ctx.h OLD_FILES+=usr/include/machine/ioctl_fd.h OLD_FILES+=usr/include/machine/ipl.h OLD_FILES+=usr/include/machine/lock.h OLD_FILES+=usr/include/machine/mouse.h OLD_FILES+=usr/include/machine/mpapic.h OLD_FILES+=usr/include/machine/mtpr.h OLD_FILES+=usr/include/machine/pc/msdos.h OLD_FILES+=usr/include/machine/physio_proc.h OLD_FILES+=usr/include/machine/smb.h OLD_FILES+=usr/include/machine/spigot.h OLD_FILES+=usr/include/machine/types.h OLD_FILES+=usr/include/machine/uc_device.h OLD_FILES+=usr/include/machine/ultrasound.h OLD_FILES+=usr/include/machine/wtio.h OLD_FILES+=usr/include/msdosfs/bootsect.h OLD_FILES+=usr/include/msdosfs/bpb.h OLD_FILES+=usr/include/msdosfs/denode.h OLD_FILES+=usr/include/msdosfs/direntry.h OLD_FILES+=usr/include/msdosfs/fat.h OLD_FILES+=usr/include/msdosfs/msdosfsmount.h OLD_FILES+=usr/include/net/hostcache.h OLD_FILES+=usr/include/net/if_faith.h OLD_FILES+=usr/include/net/if_ieee80211.h OLD_FILES+=usr/include/net/if_tunvar.h OLD_FILES+=usr/include/net/intrq.h OLD_FILES+=usr/include/netatm/kern_include.h OLD_FILES+=usr/include/netinet/if_fddi.h OLD_FILES+=usr/include/netinet/in_hostcache.h OLD_FILES+=usr/include/netinet/ip_flow.h OLD_FILES+=usr/include/netinet/ip_fw2.h OLD_FILES+=usr/include/netinet6/in6_prefix.h OLD_FILES+=usr/include/netns/idp.h OLD_FILES+=usr/include/netns/idp_var.h OLD_FILES+=usr/include/netns/ns.h OLD_FILES+=usr/include/netns/ns_error.h OLD_FILES+=usr/include/netns/ns_if.h OLD_FILES+=usr/include/netns/ns_pcb.h OLD_FILES+=usr/include/netns/sp.h OLD_FILES+=usr/include/netns/spidp.h OLD_FILES+=usr/include/netns/spp_debug.h OLD_FILES+=usr/include/netns/spp_timer.h OLD_FILES+=usr/include/netns/spp_var.h OLD_FILES+=usr/include/nfs/nfs.h OLD_FILES+=usr/include/nfs/nfsm_subs.h OLD_FILES+=usr/include/nfs/nfsmount.h OLD_FILES+=usr/include/nfs/nfsnode.h OLD_FILES+=usr/include/nfs/nfsrtt.h OLD_FILES+=usr/include/nfs/nfsrvcache.h OLD_FILES+=usr/include/nfs/nfsv2.h OLD_FILES+=usr/include/nfs/nqnfs.h OLD_FILES+=usr/include/ntfs/ntfs.h OLD_FILES+=usr/include/ntfs/ntfs_compr.h OLD_FILES+=usr/include/ntfs/ntfs_ihash.h OLD_FILES+=usr/include/ntfs/ntfs_inode.h OLD_FILES+=usr/include/ntfs/ntfs_subr.h OLD_FILES+=usr/include/ntfs/ntfs_vfsops.h OLD_FILES+=usr/include/ntfs/ntfsmount.h OLD_FILES+=usr/include/nwfs/nwfs.h OLD_FILES+=usr/include/nwfs/nwfs_mount.h OLD_FILES+=usr/include/nwfs/nwfs_node.h OLD_FILES+=usr/include/nwfs/nwfs_subr.h OLD_FILES+=usr/include/posix4/_semaphore.h OLD_FILES+=usr/include/posix4/aio.h OLD_FILES+=usr/include/posix4/ksem.h OLD_FILES+=usr/include/posix4/mqueue.h OLD_FILES+=usr/include/posix4/posix4.h OLD_FILES+=usr/include/posix4/sched.h OLD_FILES+=usr/include/posix4/semaphore.h OLD_DIRS+=usr/include/posix4 OLD_FILES+=usr/include/security/_pam_compat.h OLD_FILES+=usr/include/security/_pam_macros.h OLD_FILES+=usr/include/security/_pam_types.h OLD_FILES+=usr/include/security/pam_malloc.h OLD_FILES+=usr/include/security/pam_misc.h OLD_FILES+=usr/include/skey.h OLD_FILES+=usr/include/strhash.h OLD_FILES+=usr/include/struct.h OLD_FILES+=usr/include/sys/_label.h OLD_FILES+=usr/include/sys/_posix.h OLD_FILES+=usr/include/sys/bus_private.h OLD_FILES+=usr/include/sys/ccdvar.h OLD_FILES+=usr/include/sys/diskslice.h OLD_FILES+=usr/include/sys/dmap.h OLD_FILES+=usr/include/sys/inttypes.h OLD_FILES+=usr/include/sys/jumbo.h OLD_FILES+=usr/include/sys/mac_policy.h OLD_FILES+=usr/include/sys/pbioio.h OLD_FILES+=usr/include/sys/syscall-hide.h OLD_FILES+=usr/include/sys/tprintf.h OLD_FILES+=usr/include/sys/vnioctl.h OLD_FILES+=usr/include/sys/wormio.h OLD_FILES+=usr/include/telnet.h OLD_FILES+=usr/include/ufs/mfs/mfs_extern.h OLD_FILES+=usr/include/ufs/mfs/mfsnode.h OLD_FILES+=usr/include/values.h OLD_FILES+=usr/include/vm/vm_zone.h OLD_FILES+=usr/share/examples/etc/usbd.conf OLD_FILES+=usr/share/examples/meteor/README OLD_FILES+=usr/share/examples/meteor/rgb16.c OLD_FILES+=usr/share/examples/meteor/rgb24.c OLD_FILES+=usr/share/examples/meteor/test-n.c OLD_FILES+=usr/share/examples/meteor/yuvpk.c OLD_FILES+=usr/share/examples/meteor/yuvpl.c OLD_FILES+=usr/share/examples/worm/README OLD_FILES+=usr/share/examples/worm/makecdfs.sh OLD_FILES+=usr/share/groff_font/devlj4/Makefile OLD_FILES+=usr/share/groff_font/devlj4/text.map OLD_FILES+=usr/share/groff_font/devlj4/special.map OLD_FILES+=usr/share/misc/nslookup.help OLD_FILES+=usr/share/sendmail/cf/feature/nodns.m4 OLD_FILES+=usr/share/syscons/keymaps/lat-amer.kbd OLD_FILES+=usr/share/vi/catalog/ru_SU.KOI8-R OLD_FILES+=usr/share/zoneinfo/SystemV/YST9 OLD_FILES+=usr/share/zoneinfo/SystemV/PST8 OLD_FILES+=usr/share/zoneinfo/SystemV/EST5EDT OLD_FILES+=usr/share/zoneinfo/SystemV/CST6CDT OLD_FILES+=usr/share/zoneinfo/SystemV/MST7MDT OLD_FILES+=usr/share/zoneinfo/SystemV/PST8PDT OLD_FILES+=usr/share/zoneinfo/SystemV/YST9YDT OLD_FILES+=usr/share/zoneinfo/SystemV/HST10 OLD_FILES+=usr/share/zoneinfo/SystemV/MST7 OLD_FILES+=usr/share/zoneinfo/SystemV/EST5 OLD_FILES+=usr/share/zoneinfo/SystemV/AST4ADT OLD_FILES+=usr/share/zoneinfo/SystemV/CST6 OLD_FILES+=usr/share/zoneinfo/SystemV/AST4 OLD_DIRS+=usr/share/zoneinfo/SystemV OLD_FILES+=usr/share/doc/ntp/accopt.htm OLD_FILES+=usr/share/doc/ntp/assoc.htm OLD_FILES+=usr/share/doc/ntp/audio.htm OLD_FILES+=usr/share/doc/ntp/authopt.htm OLD_FILES+=usr/share/doc/ntp/biblio.htm OLD_FILES+=usr/share/doc/ntp/build.htm OLD_FILES+=usr/share/doc/ntp/clockopt.htm OLD_FILES+=usr/share/doc/ntp/config.htm OLD_FILES+=usr/share/doc/ntp/confopt.htm OLD_FILES+=usr/share/doc/ntp/copyright.htm OLD_FILES+=usr/share/doc/ntp/debug.htm OLD_FILES+=usr/share/doc/ntp/driver1.htm OLD_FILES+=usr/share/doc/ntp/driver10.htm OLD_FILES+=usr/share/doc/ntp/driver11.htm OLD_FILES+=usr/share/doc/ntp/driver12.htm OLD_FILES+=usr/share/doc/ntp/driver16.htm OLD_FILES+=usr/share/doc/ntp/driver18.htm OLD_FILES+=usr/share/doc/ntp/driver19.htm OLD_FILES+=usr/share/doc/ntp/driver2.htm OLD_FILES+=usr/share/doc/ntp/driver20.htm OLD_FILES+=usr/share/doc/ntp/driver22.htm OLD_FILES+=usr/share/doc/ntp/driver23.htm OLD_FILES+=usr/share/doc/ntp/driver24.htm OLD_FILES+=usr/share/doc/ntp/driver26.htm OLD_FILES+=usr/share/doc/ntp/driver27.htm OLD_FILES+=usr/share/doc/ntp/driver28.htm OLD_FILES+=usr/share/doc/ntp/driver29.htm OLD_FILES+=usr/share/doc/ntp/driver3.htm OLD_FILES+=usr/share/doc/ntp/driver30.htm OLD_FILES+=usr/share/doc/ntp/driver32.htm OLD_FILES+=usr/share/doc/ntp/driver33.htm OLD_FILES+=usr/share/doc/ntp/driver34.htm OLD_FILES+=usr/share/doc/ntp/driver35.htm OLD_FILES+=usr/share/doc/ntp/driver36.htm OLD_FILES+=usr/share/doc/ntp/driver37.htm OLD_FILES+=usr/share/doc/ntp/driver4.htm OLD_FILES+=usr/share/doc/ntp/driver5.htm OLD_FILES+=usr/share/doc/ntp/driver6.htm OLD_FILES+=usr/share/doc/ntp/driver7.htm OLD_FILES+=usr/share/doc/ntp/driver8.htm OLD_FILES+=usr/share/doc/ntp/driver9.htm OLD_FILES+=usr/share/doc/ntp/exec.htm OLD_FILES+=usr/share/doc/ntp/extern.htm OLD_FILES+=usr/share/doc/ntp/gadget.htm OLD_FILES+=usr/share/doc/ntp/hints.htm OLD_FILES+=usr/share/doc/ntp/howto.htm OLD_FILES+=usr/share/doc/ntp/htmlprimer.htm OLD_FILES+=usr/share/doc/ntp/index.htm OLD_FILES+=usr/share/doc/ntp/kern.htm OLD_FILES+=usr/share/doc/ntp/kernpps.htm OLD_FILES+=usr/share/doc/ntp/ldisc.htm OLD_FILES+=usr/share/doc/ntp/measure.htm OLD_FILES+=usr/share/doc/ntp/miscopt.htm OLD_FILES+=usr/share/doc/ntp/monopt.htm OLD_FILES+=usr/share/doc/ntp/mx4200data.htm OLD_FILES+=usr/share/doc/ntp/notes.htm OLD_FILES+=usr/share/doc/ntp/ntpd.htm OLD_FILES+=usr/share/doc/ntp/ntpdate.htm OLD_FILES+=usr/share/doc/ntp/ntpdc.htm OLD_FILES+=usr/share/doc/ntp/ntpq.htm OLD_FILES+=usr/share/doc/ntp/ntptime.htm OLD_FILES+=usr/share/doc/ntp/ntptrace.htm OLD_FILES+=usr/share/doc/ntp/parsedata.htm OLD_FILES+=usr/share/doc/ntp/parsenew.htm OLD_FILES+=usr/share/doc/ntp/patches.htm OLD_FILES+=usr/share/doc/ntp/porting.htm OLD_FILES+=usr/share/doc/ntp/pps.htm OLD_FILES+=usr/share/doc/ntp/prefer.htm OLD_FILES+=usr/share/doc/ntp/qth.htm OLD_FILES+=usr/share/doc/ntp/quick.htm OLD_FILES+=usr/share/doc/ntp/rdebug.htm OLD_FILES+=usr/share/doc/ntp/refclock.htm OLD_FILES+=usr/share/doc/ntp/release.htm OLD_FILES+=usr/share/doc/ntp/tickadj.htm OLD_FILES+=usr/share/doc/papers/nqnfs.ascii.gz OLD_FILES+=usr/share/doc/papers/px.ascii.gz OLD_FILES+=usr/share/man/man3/exp10.3.gz OLD_FILES+=usr/share/man/man3/exp10f.3.gz OLD_FILES+=usr/share/man/man3/fpsetsticky.3.gz OLD_FILES+=usr/share/man/man3/gss_krb5_compat_des3_mic.3.gz OLD_FILES+=usr/share/man/man3/gss_krb5_copy_ccache.3.gz OLD_FILES+=usr/share/man/man3/mac_is_present_np.3.gz OLD_FILES+=usr/share/man/man3/mbmb.3.gz OLD_FILES+=usr/share/man/man3/setrunelocale.3.gz OLD_FILES+=usr/share/man/man5/usbd.conf.5.gz .if ${TARGET_ARCH} != "i386" && ${TARGET_ARCH} != "amd64" OLD_FILES+=usr/share/man/man8/boot_i386.8.gz .endif .if ${TARGET_ARCH} != "aarch64" && ${TARGET} != "arm" && \ ${TARGET_ARCH} != "powerpc" && ${TARGET_ARCH} != "powerpc64" && \ ${TARGET_ARCH} != "sparc64" && ${TARGET} != "mips" OLD_FILES+=usr/share/man/man8/ofwdump.8.gz .endif OLD_FILES+=usr/share/man/man8/mount_reiserfs.8.gz OLD_FILES+=usr/share/man/man9/VFS_START.9.gz OLD_FILES+=usr/share/man/man9/cpu_critical_exit.9.gz OLD_FILES+=usr/share/man/man9/cpu_critical_enter.9.gz OLD_FILES+=usr/share/info/annotate.info.gz OLD_FILES+=usr/share/info/tar.info.gz OLD_FILES+=usr/share/bsnmp/defs/tree.def OLD_FILES+=usr/share/bsnmp/defs/mibII_tree.def OLD_FILES+=usr/share/bsnmp/defs/netgraph_tree.def OLD_FILES+=usr/share/bsnmp/mibs/FOKUS-MIB.txt OLD_FILES+=usr/share/bsnmp/mibs/BEGEMOT-MIB.txt OLD_FILES+=usr/share/bsnmp/mibs/BEGEMOT-SNMPD.txt OLD_FILES+=usr/share/bsnmp/mibs/BEGEMOT-NETGRAPH.txt OLD_FILES+=usr/libdata/msdosfs/iso22dos OLD_FILES+=usr/libdata/msdosfs/iso72dos OLD_FILES+=usr/libdata/msdosfs/koi2dos OLD_FILES+=usr/libdata/msdosfs/koi8u2dos # The following files are *not* obsolete, they just don't get touched at # install, so don't add them: # - boot/loader.rc # - usr/share/tmac/man.local # - usr/share/tmac/mm/locale # - usr/share/tmac/mm/se_locale # - var/yp/Makefile # Early entries split OLD_FILES, OLD_LIBS, and OLD_DIRS into separate sections # in this file, but this practice was abandoned in the mid-2000s. # # 20071120: shared library version bump OLD_LIBS+=usr/lib/libasn1.so.8 OLD_LIBS+=usr/lib/libgssapi.so.8 OLD_LIBS+=usr/lib/libgssapi_krb5.so.8 OLD_LIBS+=usr/lib/libhdb.so.8 OLD_LIBS+=usr/lib/libkadm5clnt.so.8 OLD_LIBS+=usr/lib/libkadm5srv.so.8 OLD_LIBS+=usr/lib/libkafs5.so.8 OLD_LIBS+=usr/lib/libkrb5.so.8 OLD_LIBS+=usr/lib/libobjc.so.2 # 20070519: GCC 4.2 OLD_FILES+=usr/lib/libg2c.a OLD_FILES+=usr/lib/libg2c.so OLD_LIBS+=usr/lib/libg2c.so.2 OLD_FILES+=usr/lib/libg2c_p.a OLD_FILES+=usr/lib/libgcc_pic.a # 20060729: OpenSSL 0.9.7e -> 0.9.8b upgrade OLD_LIBS+=lib/libcrypto.so.4 OLD_LIBS+=usr/lib/libssl.so.4 # 20060521: gethostbyaddr(3) ABI change OLD_LIBS+=usr/lib/libroken.so.8 OLD_LIBS+=lib/libatm.so.3 OLD_LIBS+=lib/libc.so.6 OLD_LIBS+=lib/libutil.so.5 # 20060413: shared library moved to /usr/lib MOVED_LIBS+=lib/libgpib.so.1 # 20060413: libpcap.so.4 moved to /lib/ MOVED_LIBS+=usr/lib/libpcap.so.4 # 20060412: libpthread.so.2 moved to /lib/ MOVED_LIBS+=usr/lib/libpthread.so.2 # 20060127: revert libdisk to static-only OLD_LIBS+=usr/lib/libdisk.so.3 # 20051027: libc_r discontinued (removed 20101113) OLD_FILES+=usr/lib/libc_r.a OLD_FILES+=usr/lib/libc_r.so OLD_LIBS+=usr/lib/libc_r.so.7 OLD_FILES+=usr/lib/libc_r_p.a # 20050722: bump for 6.0-RELEASE OLD_LIBS+=lib/libalias.so.4 OLD_LIBS+=lib/libatm.so.2 OLD_LIBS+=lib/libbegemot.so.1 OLD_LIBS+=lib/libbsdxml.so.1 OLD_LIBS+=lib/libbsnmp.so.2 OLD_LIBS+=lib/libc.so.5 OLD_LIBS+=lib/libcam.so.2 OLD_LIBS+=lib/libcrypt.so.2 OLD_LIBS+=lib/libcrypto.so.3 OLD_LIBS+=lib/libdevstat.so.4 OLD_LIBS+=lib/libedit.so.4 OLD_LIBS+=lib/libgeom.so.2 OLD_LIBS+=lib/libgpib.so.0 OLD_LIBS+=lib/libipsec.so.1 OLD_LIBS+=lib/libipx.so.2 OLD_LIBS+=lib/libkiconv.so.1 OLD_LIBS+=lib/libkvm.so.2 OLD_LIBS+=lib/libm.so.3 OLD_LIBS+=lib/libmd.so.2 OLD_LIBS+=lib/libncurses.so.5 OLD_LIBS+=lib/libreadline.so.5 OLD_LIBS+=lib/libsbuf.so.2 OLD_LIBS+=lib/libufs.so.2 OLD_LIBS+=lib/libutil.so.4 OLD_LIBS+=lib/libz.so.2 OLD_LIBS+=usr/lib/libarchive.so.1 OLD_LIBS+=usr/lib/libasn1.so.7 OLD_LIBS+=usr/lib/libbluetooth.so.1 OLD_LIBS+=usr/lib/libbz2.so.1 OLD_LIBS+=usr/lib/libc_r.so.5 OLD_LIBS+=usr/lib/libcalendar.so.2 OLD_LIBS+=usr/lib/libcom_err.so.2 OLD_LIBS+=usr/lib/libdevinfo.so.2 OLD_LIBS+=usr/lib/libdialog.so.4 OLD_LIBS+=usr/lib/libfetch.so.3 OLD_LIBS+=usr/lib/libform.so.2 OLD_LIBS+=usr/lib/libftpio.so.5 OLD_LIBS+=usr/lib/libg2c.so.1 OLD_LIBS+=usr/lib/libgnuregex.so.2 OLD_LIBS+=usr/lib/libgssapi.so.7 OLD_LIBS+=usr/lib/libhdb.so.7 OLD_LIBS+=usr/lib/libhistory.so.5 OLD_LIBS+=usr/lib/libkadm5clnt.so.7 OLD_LIBS+=usr/lib/libkadm5srv.so.7 OLD_LIBS+=usr/lib/libkafs5.so.7 OLD_LIBS+=usr/lib/libkrb5.so.7 OLD_LIBS+=usr/lib/libmagic.so.1 OLD_LIBS+=usr/lib/libmenu.so.2 OLD_LIBS+=usr/lib/libmilter.so.2 OLD_LIBS+=usr/lib/libmp.so.4 OLD_LIBS+=usr/lib/libncp.so.1 OLD_LIBS+=usr/lib/libnetgraph.so.1 OLD_LIBS+=usr/lib/libngatm.so.1 OLD_LIBS+=usr/lib/libobjc.so.1 OLD_LIBS+=usr/lib/libopie.so.3 OLD_LIBS+=usr/lib/libpam.so.2 OLD_LIBS+=usr/lib/libpanel.so.2 OLD_LIBS+=usr/lib/libpcap.so.3 OLD_LIBS+=usr/lib/libpmc.so.2 OLD_LIBS+=usr/lib/libpthread.so.1 OLD_LIBS+=usr/lib/libradius.so.1 OLD_LIBS+=usr/lib/libroken.so.7 OLD_LIBS+=usr/lib/librpcsvc.so.2 OLD_LIBS+=usr/lib/libsdp.so.1 OLD_LIBS+=usr/lib/libsmb.so.1 OLD_LIBS+=usr/lib/libssh.so.2 OLD_LIBS+=usr/lib/libssl.so.3 OLD_LIBS+=usr/lib/libstdc++.so.4 OLD_LIBS+=usr/lib/libtacplus.so.1 OLD_LIBS+=usr/lib/libthr.so.1 OLD_LIBS+=usr/lib/libthread_db.so.1 OLD_LIBS+=usr/lib/libugidfw.so.1 OLD_LIBS+=usr/lib/libusbhid.so.1 OLD_LIBS+=usr/lib/libvgl.so.3 OLD_LIBS+=usr/lib/libwrap.so.3 OLD_LIBS+=usr/lib/libypclnt.so.1 OLD_LIBS+=usr/lib/pam_chroot.so.2 OLD_LIBS+=usr/lib/pam_deny.so.2 OLD_LIBS+=usr/lib/pam_echo.so.2 OLD_LIBS+=usr/lib/pam_exec.so.2 OLD_LIBS+=usr/lib/pam_ftpusers.so.2 OLD_LIBS+=usr/lib/pam_group.so.2 OLD_LIBS+=usr/lib/pam_guest.so.2 OLD_LIBS+=usr/lib/pam_krb5.so.2 OLD_LIBS+=usr/lib/pam_ksu.so.2 OLD_LIBS+=usr/lib/pam_lastlog.so.2 OLD_LIBS+=usr/lib/pam_login_access.so.2 OLD_LIBS+=usr/lib/pam_nologin.so.2 OLD_LIBS+=usr/lib/pam_opie.so.2 OLD_LIBS+=usr/lib/pam_opieaccess.so.2 OLD_LIBS+=usr/lib/pam_passwdqc.so.2 OLD_LIBS+=usr/lib/pam_permit.so.2 OLD_LIBS+=usr/lib/pam_radius.so.2 OLD_LIBS+=usr/lib/pam_rhosts.so.2 OLD_LIBS+=usr/lib/pam_rootok.so.2 OLD_LIBS+=usr/lib/pam_securetty.so.2 OLD_LIBS+=usr/lib/pam_self.so.2 OLD_LIBS+=usr/lib/pam_ssh.so.2 OLD_LIBS+=usr/lib/pam_tacplus.so.2 OLD_LIBS+=usr/lib/pam_unix.so.2 OLD_LIBS+=usr/lib/snmp_atm.so.3 OLD_LIBS+=usr/lib/snmp_mibII.so.3 OLD_LIBS+=usr/lib/snmp_netgraph.so.3 OLD_LIBS+=usr/lib/snmp_pf.so.3 # 200505XX: ? OLD_LIBS+=usr/lib/snmp_atm.so.2 OLD_LIBS+=usr/lib/snmp_mibII.so.2 OLD_LIBS+=usr/lib/snmp_netgraph.so.2 OLD_LIBS+=usr/lib/snmp_pf.so.2 # 2005XXXX: not ready for primetime yet OLD_LIBS+=usr/lib/libautofs.so.1 # 200411XX: libxpg4 removal OLD_LIBS+=usr/lib/libxpg4.so.3 # 200410XX: libm compatibility fix OLD_LIBS+=lib/libm.so.2 # 20041001: version bump OLD_LIBS+=lib/libreadline.so.4 OLD_LIBS+=usr/lib/libhistory.so.4 OLD_LIBS+=usr/lib/libopie.so.2 OLD_LIBS+=usr/lib/libpcap.so.2 # 20040925: bind9 import OLD_LIBS+=usr/lib/libisc.so.1 # 200408XX OLD_LIBS+=usr/lib/snmp_netgraph.so.1 # 200404XX OLD_LIBS+=usr/lib/libsnmp.so.1 OLD_LIBS+=usr/lib/snmp_mibII.so.1 # 200309XX OLD_LIBS+=usr/lib/libasn1.so.6 OLD_LIBS+=usr/lib/libhdb.so.6 OLD_LIBS+=usr/lib/libkadm5clnt.so.6 OLD_LIBS+=usr/lib/libkadm5srv.so.6 OLD_LIBS+=usr/lib/libkrb5.so.6 OLD_LIBS+=usr/lib/libroken.so.6 # 200304XX OLD_LIBS+=usr/lib/libc.so.4 OLD_LIBS+=usr/lib/libc_r.so.4 OLD_LIBS+=usr/lib/libdevstat.so.2 OLD_LIBS+=usr/lib/libedit.so.3 OLD_LIBS+=usr/lib/libgmp.so.3 OLD_LIBS+=usr/lib/libmp.so.3 OLD_LIBS+=usr/lib/libpam.so.1 OLD_LIBS+=usr/lib/libposix1e.so.2 OLD_LIBS+=usr/lib/libskey.so.2 OLD_LIBS+=usr/lib/libusbhid.so.0 OLD_LIBS+=usr/lib/libvgl.so.2 # 20030218: OpenSSL 0.9.7 import OLD_FILES+=usr/include/des.h OLD_FILES+=usr/lib/libdes.a OLD_FILES+=usr/lib/libdes.so OLD_LIBS+=usr/lib/libdes.so.3 OLD_FILES+=usr/lib/libdes_p.a # 200302XX OLD_LIBS+=usr/lib/libacl.so.3 OLD_LIBS+=usr/lib/libasn1.so.5 OLD_LIBS+=usr/lib/libcrypto.so.2 OLD_LIBS+=usr/lib/libgssapi.so.5 OLD_LIBS+=usr/lib/libhdb.so.5 OLD_LIBS+=usr/lib/libkadm.so.3 OLD_LIBS+=usr/lib/libkadm5clnt.so.5 OLD_LIBS+=usr/lib/libkadm5srv.so.5 OLD_LIBS+=usr/lib/libkafs.so.3 OLD_LIBS+=usr/lib/libkafs5.so.5 OLD_LIBS+=usr/lib/libkdb.so.3 OLD_LIBS+=usr/lib/libkrb.so.3 OLD_LIBS+=usr/lib/libroken.so.5 OLD_LIBS+=usr/lib/libssl.so.2 OLD_LIBS+=usr/lib/pam_kerberosIV.so # 200208XX OLD_LIBS+=usr/lib/libgssapi.so.4 # 200203XX OLD_LIBS+=usr/lib/libss.so.3 OLD_LIBS+=usr/lib/libusb.so.0 # 200112XX OLD_LIBS+=usr/lib/libfetch.so.2 # 200110XX OLD_LIBS+=usr/lib/libgssapi.so.3 # 200104XX OLD_LIBS+=usr/lib/libdescrypt.so.2 OLD_LIBS+=usr/lib/libscrypt.so.2 # 200102XX OLD_LIBS+=usr/lib/libcrypto.so.1 OLD_LIBS+=usr/lib/libssl.so.1 # 200009XX OLD_LIBS+=usr/lib/libRSAglue.so.1 OLD_LIBS+=usr/lib/librsaINTL.so.1 OLD_LIBS+=usr/lib/librsaUSA.so.1 # 200006XX OLD_LIBS+=usr/lib/libalias.so.3 OLD_LIBS+=usr/lib/libfetch.so.1 OLD_LIBS+=usr/lib/libipsec.so.0 # 200005XX OLD_LIBS+=usr/lib/libxpg4.so.2 # 200002XX OLD_LIBS+=usr/lib/libc.so.3 OLD_LIBS+=usr/lib/libcurses.so.2 OLD_LIBS+=usr/lib/libdialog.so.3 OLD_LIBS+=usr/lib/libedit.so.2 OLD_LIBS+=usr/lib/libf2c.so.2 OLD_LIBS+=usr/lib/libftpio.so.4 OLD_LIBS+=usr/lib/libg++.so.4 OLD_LIBS+=usr/lib/libhistory.so.3 OLD_LIBS+=usr/lib/libmytinfo.so.2 OLD_LIBS+=usr/lib/libncurses.so.3 OLD_LIBS+=usr/lib/libreadline.so.3 OLD_LIBS+=usr/lib/libss.so.2 OLD_LIBS+=usr/lib/libtermcap.so.2 OLD_LIBS+=usr/lib/libutil.so.2 OLD_LIBS+=usr/lib/libvgl.so.1 OLD_LIBS+=usr/lib/libwrap.so.2 # ??? OLD_LIBS+=usr/lib/libarchive.so.2 OLD_LIBS+=usr/lib/libbsnmp.so.1 OLD_LIBS+=usr/lib/libc_r.so.6 OLD_LIBS+=usr/lib/libcipher.so.2 OLD_LIBS+=usr/lib/libgssapi.so.6 OLD_LIBS+=usr/lib/libkse.so.1 OLD_LIBS+=usr/lib/liblwres.so.3 OLD_LIBS+=usr/lib/pam_ftp.so.2 # 20040925: bind9 import OLD_DIRS+=usr/share/doc/bind/html OLD_DIRS+=usr/share/doc/bind/misc OLD_DIRS+=usr/share/doc/bind/ # ??? OLD_DIRS+=usr/include/g++/std OLD_DIRS+=usr/include/msdosfs OLD_DIRS+=usr/include/ntfs OLD_DIRS+=usr/include/nwfs OLD_DIRS+=usr/include/ufs/mfs # 20011001: UUCP migration to ports OLD_DIRS+=usr/libexec/uucp .include "tools/build/mk/OptionalObsoleteFiles.inc" diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 1c763b2a2ceb..dede651eaf9f 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1,2814 +1,2809 @@ # $FreeBSD$ # # NOTES -- Lines that can be cut/pasted into kernel and hints configs. # # Lines that begin with 'device', 'options', 'machine', 'ident', 'maxusers', # 'makeoptions', 'hints', etc. go into the kernel configuration that you # run config(8) with. # # Lines that begin with 'envvar hint.' should go into your hints file. # See /boot/device.hints and/or the 'hints' config(8) directive. # # Please use ``make LINT'' to create an old-style LINT file if you want to # do kernel test-builds. # # This file contains machine independent kernel configuration notes. For # machine dependent notes, look in /sys//conf/NOTES. # # # NOTES conventions and style guide: # # Large block comments should begin and end with a line containing only a # comment character. # # To describe a particular object, a block comment (if it exists) should # come first. Next should come device, options, and hints lines in that # order. All device and option lines must be described by a comment that # doesn't just expand the device or option name. Use only a concise # comment on the same line if possible. Very detailed descriptions of # devices and subsystems belong in man pages. # # A space followed by a tab separates 'options' from an option name. Two # spaces followed by a tab separate 'device' from a device name. Comments # after an option or device should use one space after the comment character. # To comment out a negative option that disables code and thus should not be # enabled for LINT builds, precede 'options' with "#!". # # # This is the ``identification'' of the kernel. Usually this should # be the same as the name of your kernel. # ident LINT # # The `maxusers' parameter controls the static sizing of a number of # internal system tables by a formula defined in subr_param.c. # Omitting this parameter or setting it to 0 will cause the system to # auto-size based on physical memory. # maxusers 10 # To statically compile in device wiring instead of /boot/device.hints #hints "LINT.hints" # Default places to look for devices. # Use the following to compile in values accessible to the kernel # through getenv() (or kenv(1) in userland). The format of the file # is 'variable=value', see kenv(1) # #env "LINT.env" # # The `makeoptions' parameter allows variables to be passed to the # generated Makefile in the build area. # # CONF_CFLAGS gives some extra compiler flags that are added to ${CFLAGS} # after most other flags. Here we use it to inhibit use of non-optimal # gcc built-in functions (e.g., memcmp). # # DEBUG happens to be magic. # The following is equivalent to 'config -g KERNELNAME' and creates # 'kernel.debug' compiled with -g debugging as well as a normal # 'kernel'. Use 'make install.debug' to install the debug kernel # but that isn't normally necessary as the debug symbols are not loaded # by the kernel and are not useful there anyway. # # KERNEL can be overridden so that you can change the default name of your # kernel. # # MODULES_OVERRIDE can be used to limit modules built to a specific list. # makeoptions CONF_CFLAGS=-fno-builtin #Don't allow use of memcmp, etc. #makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols #makeoptions KERNEL=foo #Build kernel "foo" and install "/foo" # Only build ext2fs module plus those parts of the sound system I need. #makeoptions MODULES_OVERRIDE="ext2fs sound/sound sound/driver/maestro3" makeoptions DESTDIR=/tmp # # FreeBSD processes are subject to certain limits to their consumption # of system resources. See getrlimit(2) for more details. Each # resource limit has two values, a "soft" limit and a "hard" limit. # The soft limits can be modified during normal system operation, but # the hard limits are set at boot time. Their default values are # in sys//include/vmparam.h. There are two ways to change them: # # 1. Set the values at kernel build time. The options below are one # way to allow that limit to grow to 1GB. They can be increased # further by changing the parameters: # # 2. In /boot/loader.conf, set the tunables kern.maxswzone, # kern.maxbcache, kern.maxtsiz, kern.dfldsiz, kern.maxdsiz, # kern.dflssiz, kern.maxssiz and kern.sgrowsiz. # # The options in /boot/loader.conf override anything in the kernel # configuration file. See the function init_param1 in # sys/kern/subr_param.c for more details. # options MAXDSIZ=(1024UL*1024*1024) options MAXSSIZ=(128UL*1024*1024) options DFLDSIZ=(1024UL*1024*1024) # # BLKDEV_IOSIZE sets the default block size used in user block # device I/O. Note that this value will be overridden by the label # when specifying a block device from a label with a non-0 # partition blocksize. The default is PAGE_SIZE. # options BLKDEV_IOSIZE=8192 # # MAXPHYS and DFLTPHYS # # These are the maximal and safe 'raw' I/O block device access sizes. # Reads and writes will be split into MAXPHYS chunks for known good # devices and DFLTPHYS for the rest. Some applications have better # performance with larger raw I/O access sizes. Note that certain VM # parameters are derived from these values and making them too large # can make an unbootable kernel. # # The defaults are 64K and 128K respectively. options DFLTPHYS=(64*1024) options MAXPHYS=(128*1024) # This allows you to actually store this configuration file into # the kernel binary itself. See config(8) for more details. # options INCLUDE_CONFIG_FILE # Include this file in kernel # # Compile-time defaults for various boot parameters # options BOOTVERBOSE=1 options BOOTHOWTO=RB_MULTIPLE # # Compile-time defaults for dmesg boot tagging # # Default boot tag; may use 'kern.boot_tag' loader tunable to override. The # current boot's tag is also exposed via the 'kern.boot_tag' sysctl. options BOOT_TAG=\"\" # Maximum boot tag size the kernel's static buffer should accommodate. Maximum # size for both BOOT_TAG and the assocated tunable. options BOOT_TAG_SZ=32 options GEOM_BDE # Disk encryption. options GEOM_CACHE # Disk cache. options GEOM_CONCAT # Disk concatenation. options GEOM_ELI # Disk encryption. options GEOM_GATE # Userland services. options GEOM_JOURNAL # Journaling. options GEOM_LABEL # Providers labelization. options GEOM_LINUX_LVM # Linux LVM2 volumes options GEOM_MAP # Map based partitioning options GEOM_MIRROR # Disk mirroring. options GEOM_MULTIPATH # Disk multipath options GEOM_NOP # Test class. options GEOM_PART_APM # Apple partitioning options GEOM_PART_BSD # BSD disklabel options GEOM_PART_BSD64 # BSD disklabel64 options GEOM_PART_EBR # Extended Boot Records options GEOM_PART_GPT # GPT partitioning options GEOM_PART_LDM # Logical Disk Manager options GEOM_PART_MBR # MBR partitioning options GEOM_PART_VTOC8 # SMI VTOC8 disk label options GEOM_RAID # Soft RAID functionality. options GEOM_RAID3 # RAID3 functionality. options GEOM_SHSEC # Shared secret. options GEOM_STRIPE # Disk striping. options GEOM_UZIP # Read-only compressed disks options GEOM_VINUM # Vinum logical volume manager options GEOM_VIRSTOR # Virtual storage. options GEOM_ZERO # Performance testing helper. # # The root device and filesystem type can be compiled in; # this provides a fallback option if the root device cannot # be correctly guessed by the bootstrap code, or an override if # the RB_DFLTROOT flag (-r) is specified when booting the kernel. # options ROOTDEVNAME=\"ufs:da0s2e\" ##################################################################### # Scheduler options: # # Specifying one of SCHED_4BSD or SCHED_ULE is mandatory. These options # select which scheduler is compiled in. # # SCHED_4BSD is the historical, proven, BSD scheduler. It has a global run # queue and no CPU affinity which makes it suboptimal for SMP. It has very # good interactivity and priority selection. # # SCHED_ULE provides significant performance advantages over 4BSD on many # workloads on SMP machines. It supports cpu-affinity, per-cpu runqueues # and scheduler locks. It also has a stronger notion of interactivity # which leads to better responsiveness even on uniprocessor machines. This # is the default scheduler. # # SCHED_STATS is a debugging option which keeps some stats in the sysctl # tree at 'kern.sched.stats' and is useful for debugging scheduling decisions. # options SCHED_4BSD options SCHED_STATS #options SCHED_ULE ##################################################################### # SMP OPTIONS: # # SMP enables building of a Symmetric MultiProcessor Kernel. # Mandatory: options SMP # Symmetric MultiProcessor Kernel # EARLY_AP_STARTUP releases the Application Processors earlier in the # kernel startup process (before devices are probed) rather than at the # end. This is a temporary option for use during the transition from # late to early AP startup. options EARLY_AP_STARTUP # MAXCPU defines the maximum number of CPUs that can boot in the system. # A default value should be already present, for every architecture. options MAXCPU=32 # NUMA enables use of Non-Uniform Memory Access policies in various kernel # subsystems. options NUMA # MAXMEMDOM defines the maximum number of memory domains that can boot in the # system. A default value should already be defined by every architecture. options MAXMEMDOM=2 # ADAPTIVE_MUTEXES changes the behavior of blocking mutexes to spin # if the thread that currently owns the mutex is executing on another # CPU. This behavior is enabled by default, so this option can be used # to disable it. options NO_ADAPTIVE_MUTEXES # ADAPTIVE_RWLOCKS changes the behavior of reader/writer locks to spin # if the thread that currently owns the rwlock is executing on another # CPU. This behavior is enabled by default, so this option can be used # to disable it. options NO_ADAPTIVE_RWLOCKS # ADAPTIVE_SX changes the behavior of sx locks to spin if the thread that # currently owns the sx lock is executing on another CPU. # This behavior is enabled by default, so this option can be used to # disable it. options NO_ADAPTIVE_SX # MUTEX_NOINLINE forces mutex operations to call functions to perform each # operation rather than inlining the simple cases. This can be used to # shrink the size of the kernel text segment. Note that this behavior is # already implied by the INVARIANT_SUPPORT, INVARIANTS, KTR, LOCK_PROFILING, # and WITNESS options. options MUTEX_NOINLINE # RWLOCK_NOINLINE forces rwlock operations to call functions to perform each # operation rather than inlining the simple cases. This can be used to # shrink the size of the kernel text segment. Note that this behavior is # already implied by the INVARIANT_SUPPORT, INVARIANTS, KTR, LOCK_PROFILING, # and WITNESS options. options RWLOCK_NOINLINE # SX_NOINLINE forces sx lock operations to call functions to perform each # operation rather than inlining the simple cases. This can be used to # shrink the size of the kernel text segment. Note that this behavior is # already implied by the INVARIANT_SUPPORT, INVARIANTS, KTR, LOCK_PROFILING, # and WITNESS options. options SX_NOINLINE # SMP Debugging Options: # # CALLOUT_PROFILING enables rudimentary profiling of the callwheel data # structure used as backend in callout(9). # PREEMPTION allows the threads that are in the kernel to be preempted by # higher priority [interrupt] threads. It helps with interactivity # and allows interrupt threads to run sooner rather than waiting. # FULL_PREEMPTION instructs the kernel to preempt non-realtime kernel # threads. Its sole use is to expose race conditions and other # bugs during development. Enabling this option will reduce # performance and increase the frequency of kernel panics by # design. If you aren't sure that you need it then you don't. # Relies on the PREEMPTION option. DON'T TURN THIS ON. # SLEEPQUEUE_PROFILING enables rudimentary profiling of the hash table # used to hold active sleep queues as well as sleep wait message # frequency. # TURNSTILE_PROFILING enables rudimentary profiling of the hash table # used to hold active lock queues. # UMTX_PROFILING enables rudimentary profiling of the hash table used # to hold active lock queues. # WITNESS enables the witness code which detects deadlocks and cycles # during locking operations. # WITNESS_KDB causes the witness code to drop into the kernel debugger if # a lock hierarchy violation occurs or if locks are held when going to # sleep. # WITNESS_SKIPSPIN disables the witness checks on spin mutexes. options PREEMPTION options FULL_PREEMPTION options WITNESS options WITNESS_KDB options WITNESS_SKIPSPIN # LOCK_PROFILING - Profiling locks. See LOCK_PROFILING(9) for details. options LOCK_PROFILING # Set the number of buffers and the hash size. The hash size MUST be larger # than the number of buffers. Hash size should be prime. options MPROF_BUFFERS="1536" options MPROF_HASH_SIZE="1543" # Profiling for the callout(9) backend. options CALLOUT_PROFILING # Profiling for internal hash tables. options SLEEPQUEUE_PROFILING options TURNSTILE_PROFILING options UMTX_PROFILING # Debugging traces for epoch(9) misuse options EPOCH_TRACE ##################################################################### # COMPATIBILITY OPTIONS # Old tty interface. options COMPAT_43TTY # Note that as a general rule, COMPAT_FREEBSD depends on # COMPAT_FREEBSD, COMPAT_FREEBSD, etc. # Enable FreeBSD4 compatibility syscalls options COMPAT_FREEBSD4 # Enable FreeBSD5 compatibility syscalls options COMPAT_FREEBSD5 # Enable FreeBSD6 compatibility syscalls options COMPAT_FREEBSD6 # Enable FreeBSD7 compatibility syscalls options COMPAT_FREEBSD7 # Enable FreeBSD9 compatibility syscalls options COMPAT_FREEBSD9 # Enable FreeBSD10 compatibility syscalls options COMPAT_FREEBSD10 # Enable FreeBSD11 compatibility syscalls options COMPAT_FREEBSD11 # Enable FreeBSD12 compatibility syscalls options COMPAT_FREEBSD12 # Enable FreeBSD13 compatibility syscalls options COMPAT_FREEBSD13 # Enable Linux Kernel Programming Interface options COMPAT_LINUXKPI # # These three options provide support for System V Interface # Definition-style interprocess communication, in the form of shared # memory, semaphores, and message queues, respectively. # options SYSVSHM options SYSVSEM options SYSVMSG ##################################################################### # DEBUGGING OPTIONS # # Compile with kernel debugger related code. # options KDB # # Print a stack trace of the current thread on the console for a panic. # options KDB_TRACE # # Don't enter the debugger for a panic. Intended for unattended operation # where you may want to enter the debugger from the console, but still want # the machine to recover from a panic. # options KDB_UNATTENDED # # Enable the ddb debugger backend. # options DDB # # Print the numerical value of symbols in addition to the symbolic # representation. # options DDB_NUMSYM # # Enable the remote gdb debugger backend. # options GDB # # Trashes list pointers when they become invalid (i.e., the element is # removed from a list). Relatively inexpensive to enable. # options QUEUE_MACRO_DEBUG_TRASH # # Stores information about the last caller to modify the list object # in the list object. Requires additional memory overhead. # #options QUEUE_MACRO_DEBUG_TRACE # # SYSCTL_DEBUG enables a 'sysctl' debug tree that can be used to dump the # contents of the registered sysctl nodes on the console. It is disabled by # default because it generates excessively verbose console output that can # interfere with serial console operation. # options SYSCTL_DEBUG # # Enable textdump by default, this disables kernel core dumps. # options TEXTDUMP_PREFERRED # # Enable extra debug messages while performing textdumps. # options TEXTDUMP_VERBOSE # # NO_SYSCTL_DESCR omits the sysctl node descriptions to save space in the # resulting kernel. options NO_SYSCTL_DESCR # # MALLOC_DEBUG_MAXZONES enables multiple uma zones for malloc(9) # allocations that are smaller than a page. The purpose is to isolate # different malloc types into hash classes, so that any buffer # overruns or use-after-free will usually only affect memory from # malloc types in that hash class. This is purely a debugging tool; # by varying the hash function and tracking which hash class was # corrupted, the intersection of the hash classes from each instance # will point to a single malloc type that is being misused. At this # point inspection or memguard(9) can be used to catch the offending # code. # options MALLOC_DEBUG_MAXZONES=8 # # DEBUG_MEMGUARD builds and enables memguard(9), a replacement allocator # for the kernel used to detect modify-after-free scenarios. See the # memguard(9) man page for more information on usage. # options DEBUG_MEMGUARD # # DEBUG_REDZONE enables buffer underflows and buffer overflows detection for # malloc(9). # options DEBUG_REDZONE # # EARLY_PRINTF enables support for calling a special printf (eprintf) # very early in the kernel (before cn_init() has been called). This # should only be used for debugging purposes early in boot. Normally, # it is not defined. It is commented out here because this feature # isn't generally available. And the required eputc() isn't defined. # #options EARLY_PRINTF # # KTRACE enables the system-call tracing facility ktrace(2). To be more # SMP-friendly, KTRACE uses a worker thread to process most trace events # asynchronously to the thread generating the event. This requires a # pre-allocated store of objects representing trace events. The # KTRACE_REQUEST_POOL option specifies the initial size of this store. # The size of the pool can be adjusted both at boottime and runtime via # the kern.ktrace_request_pool tunable and sysctl. # options KTRACE #kernel tracing options KTRACE_REQUEST_POOL=101 # # KTR is a kernel tracing facility imported from BSD/OS. It is # enabled with the KTR option. KTR_ENTRIES defines the number of # entries in the circular trace buffer; it may be an arbitrary number. # KTR_BOOT_ENTRIES defines the number of entries during the early boot, # before malloc(9) is functional. # KTR_COMPILE defines the mask of events to compile into the kernel as # defined by the KTR_* constants in . KTR_MASK defines the # initial value of the ktr_mask variable which determines at runtime # what events to trace. KTR_CPUMASK determines which CPU's log # events, with bit X corresponding to CPU X. The layout of the string # passed as KTR_CPUMASK must match a series of bitmasks each of them # separated by the "," character (ie: # KTR_CPUMASK=0xAF,0xFFFFFFFFFFFFFFFF). KTR_VERBOSE enables # dumping of KTR events to the console by default. This functionality # can be toggled via the debug.ktr_verbose sysctl and defaults to off # if KTR_VERBOSE is not defined. See ktr(4) and ktrdump(8) for details. # options KTR options KTR_BOOT_ENTRIES=1024 options KTR_ENTRIES=(128*1024) options KTR_COMPILE=(KTR_ALL) options KTR_MASK=KTR_INTR options KTR_CPUMASK=0x3 options KTR_VERBOSE # # ALQ(9) is a facility for the asynchronous queuing of records from the kernel # to a vnode, and is employed by services such as ktr(4) to produce trace # files based on a kernel event stream. Records are written asynchronously # in a worker thread. # options ALQ options KTR_ALQ # # The INVARIANTS option is used in a number of source files to enable # extra sanity checking of internal structures. This support is not # enabled by default because of the extra time it would take to check # for these conditions, which can only occur as a result of # programming errors. # options INVARIANTS # # The INVARIANT_SUPPORT option makes us compile in support for # verifying some of the internal structures. It is a prerequisite for # 'INVARIANTS', as enabling 'INVARIANTS' will make these functions be # called. The intent is that you can set 'INVARIANTS' for single # source files (by changing the source file or specifying it on the # command line) if you have 'INVARIANT_SUPPORT' enabled. Also, if you # wish to build a kernel module with 'INVARIANTS', then adding # 'INVARIANT_SUPPORT' to your kernel will provide all the necessary # infrastructure without the added overhead. # options INVARIANT_SUPPORT # # The KASSERT_PANIC_OPTIONAL option allows kasserts to fire without # necessarily inducing a panic. Panic is the default behavior, but # runtime options can configure it either entirely off, or off with a # limit. # options KASSERT_PANIC_OPTIONAL # # The DIAGNOSTIC option is used to enable extra debugging information # and invariants checking. The added checks are too expensive or noisy # for an INVARIANTS kernel and thus are disabled by default. It is # expected that a kernel configured with DIAGNOSTIC will also have the # INVARIANTS option enabled. # options DIAGNOSTIC # # REGRESSION causes optional kernel interfaces necessary only for regression # testing to be enabled. These interfaces may constitute security risks # when enabled, as they permit processes to easily modify aspects of the # run-time environment to reproduce unlikely or unusual (possibly normally # impossible) scenarios. # options REGRESSION # # This option lets some drivers co-exist that can't co-exist in a running # system. This is used to be able to compile all kernel code in one go for # quality assurance purposes (like this file, which the option takes it name # from.) # options COMPILING_LINT # # STACK enables the stack(9) facility, allowing the capture of kernel stack # for the purpose of procinfo(1), etc. stack(9) will also be compiled in # automatically if DDB(4) is compiled into the kernel. # options STACK # # The NUM_CORE_FILES option specifies the limit for the number of core # files generated by a particular process, when the core file format # specifier includes the %I pattern. Since we only have 1 character for # the core count in the format string, meaning the range will be 0-9, the # maximum value allowed for this option is 10. # This core file limit can be adjusted at runtime via the debug.ncores # sysctl. # options NUM_CORE_FILES=5 # # The TSLOG option enables timestamped logging of events, especially # function entries/exits, in order to track the time spent by the kernel. # In particular, this is useful when investigating the early boot process, # before it is possible to use more sophisticated tools like DTrace. # The TSLOGSIZE option controls the size of the (preallocated, fixed # length) buffer used for storing these events (default: 262144 records). # # For security reasons the TSLOG option should not be enabled on systems # used in production. # options TSLOG options TSLOGSIZE=262144 ##################################################################### # PERFORMANCE MONITORING OPTIONS # # The hwpmc driver that allows the use of in-CPU performance monitoring # counters for performance monitoring. The base kernel needs to be configured # with the 'options' line, while the hwpmc device can be either compiled # in or loaded as a loadable kernel module. # # Additional configuration options may be required on specific architectures, # please see hwpmc(4). device hwpmc # Driver (also a loadable module) options HWPMC_DEBUG options HWPMC_HOOKS # Other necessary kernel hooks ##################################################################### # NETWORKING OPTIONS # # Protocol families # options INET #Internet communications protocols options INET6 #IPv6 communications protocols # # Note if you include INET/INET6 or both options # You *must* define at least one of the congestion control # options or the compile will fail. GENERIC defines # options CC_CUBIC. You may want to specify a default # if multiple congestion controls are compiled in. # The string in default is the name of the # cc module as it would appear in the sysctl for # setting the default. The code defines CUBIC # as default, or the sole cc_module compiled in. # options CC_CDG options CC_CHD options CC_CUBIC options CC_DCTCP options CC_HD options CC_HTCP options CC_NEWRENO options CC_VEGAS options CC_DEFAULT=\"cubic\" options RATELIMIT # TX rate limiting support options ROUTETABLES=2 # allocated fibs up to 65536. default is 1. # but that would be a bad idea as they are large. options TCP_OFFLOAD # TCP offload support. options TCP_RFC7413 # TCP Fast Open options TCPHPTS # In order to enable IPSEC you MUST also add device crypto to # your kernel configuration options IPSEC #IP security (requires device crypto) # Option IPSEC_SUPPORT does not enable IPsec, but makes it possible to # load it as a kernel module. You still MUST add device crypto to your kernel # configuration. options IPSEC_SUPPORT #options IPSEC_DEBUG #debug for IP security # TLS framing and encryption/decryption of data over TCP sockets. options KERN_TLS # TLS transmit and receive offload # # SMB/CIFS requester # NETSMB enables support for SMB protocol, it requires LIBMCHAIN and LIBICONV # options. options NETSMB #SMB/CIFS requester # mchain library. It can be either loaded as KLD or compiled into kernel options LIBMCHAIN # libalias library, performing NAT options LIBALIAS # # SCTP is a NEW transport protocol defined by # RFC2960 updated by RFC3309 and RFC3758.. and # soon to have a new base RFC and many many more # extensions. This release supports all the extensions # including many drafts (most about to become RFC's). # It is the reference implementation of SCTP # and is quite well tested. # # Note YOU MUST have both INET and INET6 defined. # You don't have to enable V6, but SCTP is # dual stacked and so far we have not torn apart # the V6 and V4.. since an association can span # both a V6 and V4 address at the SAME time :-) # # The SCTP_SUPPORT option does not enable SCTP, but provides the necessary # support for loading SCTP as a loadable kernel module. # options SCTP options SCTP_SUPPORT # There are bunches of options: # this one turns on all sorts of # nastily printing that you can # do. It's all controlled by a # bit mask (settable by socket opt and # by sysctl). Including will not cause # logging until you set the bits.. but it # can be quite verbose.. so without this # option we don't do any of the tests for # bits and prints.. which makes the code run # faster.. if you are not debugging don't use. options SCTP_DEBUG # # All that options after that turn on specific types of # logging. You can monitor CWND growth, flight size # and all sorts of things. Go look at the code and # see. I have used this to produce interesting # charts and graphs as well :-> # # I have not yet committed the tools to get and print # the logs, I will do that eventually .. before then # if you want them send me an email rrs@freebsd.org # You basically must have ktr(4) enabled for these # and you then set the sysctl to turn on/off various # logging bits. Use ktrdump(8) to pull the log and run # it through a display program.. and graphs and other # things too. # options SCTP_LOCK_LOGGING options SCTP_MBUF_LOGGING options SCTP_MBCNT_LOGGING options SCTP_PACKET_LOGGING options SCTP_LTRACE_CHUNKS options SCTP_LTRACE_ERRORS # altq(9). Enable the base part of the hooks with the ALTQ option. # Individual disciplines must be built into the base system and can not be # loaded as modules at this point. ALTQ requires a stable TSC so if yours is # broken or changes with CPU throttling then you must also have the ALTQ_NOPCC # option. options ALTQ options ALTQ_CBQ # Class Based Queueing options ALTQ_RED # Random Early Detection options ALTQ_RIO # RED In/Out options ALTQ_CODEL # CoDel Active Queueing options ALTQ_HFSC # Hierarchical Packet Scheduler options ALTQ_FAIRQ # Fair Packet Scheduler options ALTQ_CDNR # Traffic conditioner options ALTQ_PRIQ # Priority Queueing options ALTQ_NOPCC # Required if the TSC is unusable options ALTQ_DEBUG # netgraph(4). Enable the base netgraph code with the NETGRAPH option. # Individual node types can be enabled with the corresponding option # listed below; however, this is not strictly necessary as netgraph # will automatically load the corresponding KLD module if the node type # is not already compiled into the kernel. Each type below has a # corresponding man page, e.g., ng_async(8). options NETGRAPH # netgraph(4) system options NETGRAPH_DEBUG # enable extra debugging, this # affects netgraph(4) and nodes # Node types options NETGRAPH_ASYNC options NETGRAPH_ATMLLC options NETGRAPH_ATM_ATMPIF options NETGRAPH_BLUETOOTH # ng_bluetooth(4) options NETGRAPH_BLUETOOTH_HCI # ng_hci(4) options NETGRAPH_BLUETOOTH_L2CAP # ng_l2cap(4) options NETGRAPH_BLUETOOTH_SOCKET # ng_btsocket(4) options NETGRAPH_BLUETOOTH_UBT # ng_ubt(4) options NETGRAPH_BLUETOOTH_UBTBCMFW # ubtbcmfw(4) options NETGRAPH_BPF options NETGRAPH_BRIDGE options NETGRAPH_CAR options NETGRAPH_CHECKSUM options NETGRAPH_CISCO options NETGRAPH_DEFLATE options NETGRAPH_DEVICE options NETGRAPH_ECHO options NETGRAPH_EIFACE options NETGRAPH_ETHER options NETGRAPH_FRAME_RELAY options NETGRAPH_GIF options NETGRAPH_GIF_DEMUX options NETGRAPH_HOLE options NETGRAPH_IFACE options NETGRAPH_IP_INPUT options NETGRAPH_IPFW options NETGRAPH_KSOCKET options NETGRAPH_L2TP options NETGRAPH_LMI options NETGRAPH_MPPC_COMPRESSION options NETGRAPH_MPPC_ENCRYPTION options NETGRAPH_NETFLOW options NETGRAPH_NAT options NETGRAPH_ONE2MANY options NETGRAPH_PATCH options NETGRAPH_PIPE options NETGRAPH_PPP options NETGRAPH_PPPOE options NETGRAPH_PPTPGRE options NETGRAPH_PRED1 options NETGRAPH_RFC1490 options NETGRAPH_SOCKET options NETGRAPH_SPLIT options NETGRAPH_TAG options NETGRAPH_TCPMSS options NETGRAPH_TEE options NETGRAPH_UI options NETGRAPH_VJC options NETGRAPH_VLAN # NgATM - Netgraph ATM options NGATM_ATM options NGATM_ATMBASE options NGATM_SSCOP options NGATM_SSCFU options NGATM_UNI options NGATM_CCATM # Network stack virtualization. options VIMAGE options VNET_DEBUG # debug for VIMAGE # # Network interfaces: # The `loop' device is MANDATORY when networking is enabled. device loop # The `ether' device provides generic code to handle # Ethernets; it is MANDATORY when an Ethernet device driver is # configured. device ether # The `vlan' device implements the VLAN tagging of Ethernet frames # according to IEEE 802.1Q. device vlan # The `vxlan' device implements the VXLAN encapsulation of Ethernet # frames in UDP packets according to RFC7348. device vxlan # The `wlan' device provides generic code to support 802.11 # drivers, including host AP mode; it is MANDATORY for the wi, # and ath drivers and will eventually be required by all 802.11 drivers. device wlan options IEEE80211_DEBUG #enable debugging msgs options IEEE80211_SUPPORT_MESH #enable 802.11s D3.0 support options IEEE80211_SUPPORT_TDMA #enable TDMA support # The `wlan_wep', `wlan_tkip', and `wlan_ccmp' devices provide # support for WEP, TKIP, and AES-CCMP crypto protocols optionally # used with 802.11 devices that depend on the `wlan' module. device wlan_wep device wlan_ccmp device wlan_tkip # The `wlan_xauth' device provides support for external (i.e. user-mode) # authenticators for use with 802.11 drivers that use the `wlan' # module and support 802.1x and/or WPA security protocols. device wlan_xauth # The `wlan_acl' device provides a MAC-based access control mechanism # for use with 802.11 drivers operating in ap mode and using the # `wlan' module. # The 'wlan_amrr' device provides AMRR transmit rate control algorithm device wlan_acl device wlan_amrr # The `bpf' device enables the Berkeley Packet Filter. Be # aware of the legal and administrative consequences of enabling this # option. DHCP requires bpf. device bpf # The `netmap' device implements memory-mapped access to network # devices from userspace, enabling wire-speed packet capture and # generation even at 10Gbit/s. Requires support in the device # driver. Supported drivers are ixgbe, e1000, re. device netmap # The `disc' device implements a minimal network interface, # which throws away all packets sent and never receives any. It is # included for testing and benchmarking purposes. device disc # The `epair' device implements a virtual back-to-back connected Ethernet # like interface pair. device epair # The `edsc' device implements a minimal Ethernet interface, # which discards all packets sent and receives none. device edsc # The `tuntap' device implements (user-)ppp, nos-tun(8) and a pty-like virtual # Ethernet interface device tuntap # The `gif' device implements IPv6 over IP4 tunneling, # IPv4 over IPv6 tunneling, IPv4 over IPv4 tunneling and # IPv6 over IPv6 tunneling. # The `gre' device implements GRE (Generic Routing Encapsulation) tunneling, # as specified in the RFC 2784 and RFC 2890. # The `me' device implements Minimal Encapsulation within IPv4 as # specified in the RFC 2004. # The XBONEHACK option allows the same pair of addresses to be configured on # multiple gif interfaces. device gif device gre device me options XBONEHACK # The `stf' device implements 6to4 encapsulation. device stf # The pf packet filter consists of three devices: # The `pf' device provides /dev/pf and the firewall code itself. # The `pflog' device provides the pflog0 interface which logs packets. # The `pfsync' device provides the pfsync0 interface used for # synchronization of firewall state tables (over the net). device pf device pflog device pfsync # Bridge interface. device if_bridge # Common Address Redundancy Protocol. See carp(4) for more details. device carp # IPsec interface. device enc # Link aggregation interface. device lagg # WireGuard interface. device wg # # Internet family options: # # MROUTING enables the kernel multicast packet forwarder, which works # with mrouted and XORP. # # IPFIREWALL enables support for IP firewall construction, in # conjunction with the `ipfw' program. IPFIREWALL_VERBOSE sends # logged packets to the system logger. IPFIREWALL_VERBOSE_LIMIT # limits the number of times a matching entry can be logged. # # WARNING: IPFIREWALL defaults to a policy of "deny ip from any to any" # and if you do not add other rules during startup to allow access, # YOU WILL LOCK YOURSELF OUT. It is suggested that you set firewall_type=open # in /etc/rc.conf when first enabling this feature, then refining the # firewall rules in /etc/rc.firewall after you've tested that the new kernel # feature works properly. # # IPFIREWALL_DEFAULT_TO_ACCEPT causes the default rule (at boot) to # allow everything. Use with care, if a cracker can crash your # firewall machine, they can get to your protected machines. However, # if you are using it as an as-needed filter for specific problems as # they arise, then this may be for you. Changing the default to 'allow' # means that you won't get stuck if the kernel and /sbin/ipfw binary get # out of sync. # # IPDIVERT enables the divert IP sockets, used by ``ipfw divert''. It # depends on IPFIREWALL if compiled into the kernel. # # IPFIREWALL_NAT adds support for in kernel nat in ipfw, and it requires # LIBALIAS. # # IPFIREWALL_NAT64 adds support for in kernel NAT64 in ipfw. # # IPFIREWALL_NPTV6 adds support for in kernel NPTv6 in ipfw. # # IPFIREWALL_PMOD adds support for protocols modification module. Currently # it supports only TCP MSS modification. # # IPSTEALTH enables code to support stealth forwarding (i.e., forwarding # packets without touching the TTL). This can be useful to hide firewalls # from traceroute and similar tools. # # PF_DEFAULT_TO_DROP causes the default pf(4) rule to deny everything. # -# TCPDEBUG enables code which keeps traces of the TCP state machine -# for sockets with the SO_DEBUG option set, which can then be examined -# using the trpt(8) utility. -# # TCPPCAP enables code which keeps the last n packets sent and received # on a TCP socket. # # TCP_BLACKBOX enables enhanced TCP event logging. # # TCP_HHOOK enables the hhook(9) framework hooks for the TCP stack. # # ROUTE_MPATH provides support for multipath routing. # options MROUTING # Multicast routing options IPFIREWALL #firewall options IPFIREWALL_VERBOSE #enable logging to syslogd(8) options IPFIREWALL_VERBOSE_LIMIT=100 #limit verbosity options IPFIREWALL_DEFAULT_TO_ACCEPT #allow everything by default options IPFIREWALL_NAT #ipfw kernel nat support options IPFIREWALL_NAT64 #ipfw kernel NAT64 support options IPFIREWALL_NPTV6 #ipfw kernel IPv6 NPT support options IPDIVERT #divert sockets options IPFILTER #ipfilter support options IPFILTER_LOG #ipfilter logging options IPFILTER_LOOKUP #ipfilter pools options IPFILTER_DEFAULT_BLOCK #block all packets by default options IPSTEALTH #support for stealth forwarding options PF_DEFAULT_TO_DROP #drop everything by default -options TCPDEBUG options TCPPCAP options TCP_BLACKBOX options TCP_HHOOK options ROUTE_MPATH # The MBUF_STRESS_TEST option enables options which create # various random failures / extreme cases related to mbuf # functions. See mbuf(9) for a list of available test cases. # MBUF_PROFILING enables code to profile the mbuf chains # exiting the system (via participating interfaces) and # return a logarithmic histogram of monitored parameters # (e.g. packet size, wasted space, number of mbufs in chain). options MBUF_STRESS_TEST options MBUF_PROFILING # Statically link in accept filters options ACCEPT_FILTER_DATA options ACCEPT_FILTER_DNS options ACCEPT_FILTER_HTTP # TCP_SIGNATURE adds support for RFC 2385 (TCP-MD5) digests. These are # carried in TCP option 19. This option is commonly used to protect # TCP sessions (e.g. BGP) where IPSEC is not available nor desirable. # This is enabled on a per-socket basis using the TCP_MD5SIG socket option. # This requires the use of 'device crypto' and either 'options IPSEC' or # 'options IPSEC_SUPPORT'. options TCP_SIGNATURE #include support for RFC 2385 # DUMMYNET enables the "dummynet" bandwidth limiter. You need IPFIREWALL # as well. See dummynet(4) and ipfw(8) for more info. When you run # DUMMYNET, HZ/kern.hz should be at least 1000 for adequate response. options DUMMYNET # The DEBUGNET option enables a basic debug/panic-time networking API. It # is used by NETDUMP and NETGDB. options DEBUGNET # The NETDUMP option enables netdump(4) client support in the kernel. # This allows a panicking kernel to transmit a kernel dump to a remote host. options NETDUMP # The NETGDB option enables netgdb(4) support in the kernel. This allows a # panicking kernel to be debugged as a GDB remote over the network. options NETGDB ##################################################################### # FILESYSTEM OPTIONS # # Only the root filesystem needs to be statically compiled or preloaded # as module; everything else will be automatically loaded at mount # time. Some people still prefer to statically compile other # filesystems as well. # # NB: The UNION filesystem was known to be buggy in the past. It is now # being actively maintained, although there are still some issues being # resolved. # # One of these is mandatory: options FFS #Fast filesystem options NFSCL #Network File System client # The rest are optional: options AUTOFS #Automounter filesystem options CD9660 #ISO 9660 filesystem options FDESCFS #File descriptor filesystem options FUSEFS #FUSEFS support module options MSDOSFS #MS DOS File System (FAT, FAT32) options NFSLOCKD #Network Lock Manager options NFSD #Network Filesystem Server options KGSSAPI #Kernel GSSAPI implementation options NULLFS #NULL filesystem options PROCFS #Process filesystem (requires PSEUDOFS) options PSEUDOFS #Pseudo-filesystem framework options PSEUDOFS_TRACE #Debugging support for PSEUDOFS options SMBFS #SMB/CIFS filesystem options TMPFS #Efficient memory filesystem options UDF #Universal Disk Format options UNIONFS #Union filesystem # The xFS_ROOT options REQUIRE the associated ``options xFS'' options NFS_ROOT #NFS usable as root device # Soft updates is a technique for improving filesystem speed and # making abrupt shutdown less risky. # options SOFTUPDATES # Extended attributes allow additional data to be associated with files, # and is used for ACLs, Capabilities, and MAC labels. # See src/sys/ufs/ufs/README.extattr for more information. options UFS_EXTATTR options UFS_EXTATTR_AUTOSTART # Access Control List support for UFS filesystems. The current ACL # implementation requires extended attribute support, UFS_EXTATTR, # for the underlying filesystem. # See src/sys/ufs/ufs/README.acls for more information. options UFS_ACL # Directory hashing improves the speed of operations on very large # directories at the expense of some memory. options UFS_DIRHASH # Gjournal-based UFS journaling support. options UFS_GJOURNAL # Make space in the kernel for a root filesystem on a md device. # Define to the number of kilobytes to reserve for the filesystem. # This is now optional. # If not defined, the root filesystem passed in as the MFS_IMAGE makeoption # will be automatically embedded in the kernel during linking. Its exact size # will be consumed within the kernel. # If defined, the old way of embedding the filesystem in the kernel will be # used. That is to say MD_ROOT_SIZE KB will be allocated in the kernel and # later, the filesystem image passed in as the MFS_IMAGE makeoption will be # dd'd into the reserved space if it fits. options MD_ROOT_SIZE=10 # Make the md device a potential root device, either with preloaded # images of type mfs_root or md_root. options MD_ROOT # Write-protect the md root device so that it may not be mounted writeable. options MD_ROOT_READONLY # Allow to read MD image from external memory regions options MD_ROOT_MEM # Disk quotas are supported when this option is enabled. options QUOTA #enable disk quotas # If you are running a machine just as a fileserver for PC and MAC # users, using SAMBA, you may consider setting this option # and keeping all those users' directories on a filesystem that is # mounted with the suiddir option. This gives new files the same # ownership as the directory (similar to group). It's a security hole # if you let these users run programs, so confine it to file-servers # (but it'll save you lots of headaches in those cases). Root owned # directories are exempt and X bits are cleared. The suid bit must be # set on the directory as well; see chmod(1). PC owners can't see/set # ownerships so they keep getting their toes trodden on. This saves # you all the support calls as the filesystem it's used on will act as # they expect: "It's my dir so it must be my file". # options SUIDDIR # NFS options: options NFS_MINATTRTIMO=3 # VREG attrib cache timeout in sec options NFS_MAXATTRTIMO=60 options NFS_MINDIRATTRTIMO=30 # VDIR attrib cache timeout in sec options NFS_MAXDIRATTRTIMO=60 options NFS_DEBUG # Enable NFS Debugging # # Add support for the EXT2FS filesystem of Linux fame. Be a bit # careful with this - the ext2fs code has a tendency to lag behind # changes and not be exercised very much, so mounting read/write could # be dangerous (and even mounting read only could result in panics.) # options EXT2FS # The system memory devices; /dev/mem, /dev/kmem device mem # The kernel symbol table device; /dev/ksyms device ksyms # Optional character code conversion support with LIBICONV. # Each option requires their base file system and LIBICONV. options CD9660_ICONV options MSDOSFS_ICONV options UDF_ICONV ##################################################################### # POSIX P1003.1B # Real time extensions added in the 1993 POSIX # _KPOSIX_PRIORITY_SCHEDULING: Build in _POSIX_PRIORITY_SCHEDULING options _KPOSIX_PRIORITY_SCHEDULING # p1003_1b_semaphores are very experimental, # user should be ready to assist in debugging if problems arise. options P1003_1B_SEMAPHORES # POSIX message queue options P1003_1B_MQUEUE ##################################################################### # SECURITY POLICY PARAMETERS # Support for BSM audit options AUDIT # Support for Mandatory Access Control (MAC): options MAC options MAC_BIBA options MAC_BSDEXTENDED options MAC_DDB options MAC_IFOFF options MAC_LOMAC options MAC_MLS options MAC_NONE options MAC_NTPD options MAC_PARTITION options MAC_PORTACL options MAC_PRIORITY options MAC_SEEOTHERUIDS options MAC_STUB options MAC_TEST options MAC_VERIEXEC options MAC_VERIEXEC_SHA1 options MAC_VERIEXEC_SHA256 options MAC_VERIEXEC_SHA384 options MAC_VERIEXEC_SHA512 device mac_veriexec_parser # Support for Capsicum options CAPABILITIES # fine-grained rights on file descriptors options CAPABILITY_MODE # sandboxes with no global namespace access ##################################################################### # CLOCK OPTIONS # The granularity of operation is controlled by the kernel option HZ (default # frequency of 1000 Hz or a period 1ms between calls). Virtual machine guests # use a value of 100. Lower values may lower overhead at the expense of accuracy # of scheduling, though the adaptive tick code reduces that overhead. options HZ=100 # Enable support for the kernel PLL to use an external PPS signal, # under supervision of [x]ntpd(8) # More info in ntpd documentation: http://www.eecis.udel.edu/~ntp options PPS_SYNC # Enable support for generic feed-forward clocks in the kernel. # The feed-forward clock support is an alternative to the feedback oriented # ntpd/system clock approach, and is to be used with a feed-forward # synchronization algorithm such as the RADclock: # More info here: http://www.synclab.org/radclock options FFCLOCK ##################################################################### # SCSI DEVICES # SCSI DEVICE CONFIGURATION # The SCSI subsystem consists of the `base' SCSI code, a number of # high-level SCSI device `type' drivers, and the low-level host-adapter # device drivers. The host adapters are listed in the ISA and PCI # device configuration sections below. # # It is possible to wire down your SCSI devices so that a given bus, # target, and LUN always come on line as the same device unit. In # earlier versions the unit numbers were assigned in the order that # the devices were probed on the SCSI bus. This means that if you # removed a disk drive, you may have had to rewrite your /etc/fstab # file, and also that you had to be careful when adding a new disk # as it may have been probed earlier and moved your device configuration # around. # This old behavior is maintained as the default behavior. The unit # assignment begins with the first non-wired down unit for a device # type. For example, if you wire a disk as "da3" then the first # non-wired disk will be assigned da4. # The syntax for wiring down devices is: envvar hint.scbus.0.at="ahc0" envvar hint.scbus.1.at="ahc1" envvar hint.scbus.1.bus="0" envvar hint.scbus.3.at="ahc2" envvar hint.scbus.3.bus="0" envvar hint.scbus.2.at="ahc2" envvar hint.scbus.2.bus="1" envvar hint.da.0.at="scbus0" envvar hint.da.0.target="0" envvar hint.da.0.unit="0" envvar hint.da.1.at="scbus3" envvar hint.da.1.target="1" envvar hint.da.2.at="scbus2" envvar hint.da.2.target="3" envvar hint.sa.1.at="scbus1" envvar hint.sa.1.target="6" # "units" (SCSI logical unit number) that are not specified are # treated as if specified as LUN 0. # All SCSI devices allocate as many units as are required. # The ch driver drives SCSI Media Changer ("jukebox") devices. # # The da driver drives SCSI Direct Access ("disk") and Optical Media # ("WORM") devices. # # The sa driver drives SCSI Sequential Access ("tape") devices. # # The cd driver drives SCSI Read Only Direct Access ("cd") devices. # # The ses driver drives SCSI Environment Services ("ses") and # SAF-TE ("SCSI Accessible Fault-Tolerant Enclosure") devices. # # The pt driver drives SCSI Processor devices. # # The sg driver provides a passthrough API that is compatible with the # Linux SG driver. It will work in conjunction with the Linuxulator # to run linux SG apps. It can also stand on its own and provide # source level API compatibility for porting apps to FreeBSD. # # Target Mode support is provided here but also requires that a SIM # (SCSI Host Adapter Driver) provide support as well. # # The targ driver provides target mode support as a Processor type device. # It exists to give the minimal context necessary to respond to Inquiry # commands. There is a sample user application that shows how the rest # of the command support might be done in /usr/share/examples/scsi_target. # # The targbh driver provides target mode support and exists to respond # to incoming commands that do not otherwise have a logical unit assigned # to them. # # The pass driver provides a passthrough API to access the CAM subsystem. device scbus #base SCSI code device ch #SCSI media changers device da #SCSI direct access devices (aka disks) device sa #SCSI tapes device cd #SCSI CD-ROMs device ses #Enclosure Services (SES and SAF-TE) device pt #SCSI processor device targ #SCSI Target Mode Code device targbh #SCSI Target Mode Blackhole Device device pass #CAM passthrough driver device sg #Linux SCSI passthrough device ctl #CAM Target Layer # CAM OPTIONS: # debugging options: # CAMDEBUG Compile in all possible debugging. # CAM_DEBUG_COMPILE Debug levels to compile in. # CAM_DEBUG_FLAGS Debug levels to enable on boot. # CAM_DEBUG_BUS Limit debugging to the given bus. # CAM_DEBUG_TARGET Limit debugging to the given target. # CAM_DEBUG_LUN Limit debugging to the given lun. # CAM_DEBUG_DELAY Delay in us after printing each debug line. # CAM_IO_STATS Publish additional CAM device statics by sysctl # # CAM_MAX_HIGHPOWER: Maximum number of concurrent high power (start unit) cmds # SCSI_NO_SENSE_STRINGS: When defined disables sense descriptions # SCSI_NO_OP_STRINGS: When defined disables opcode descriptions # SCSI_DELAY: The number of MILLISECONDS to freeze the SIM (scsi adapter) # queue after a bus reset, and the number of milliseconds to # freeze the device queue after a bus device reset. This # can be changed at boot and runtime with the # kern.cam.scsi_delay tunable/sysctl. options CAMDEBUG options CAM_DEBUG_COMPILE=-1 options CAM_DEBUG_FLAGS=(CAM_DEBUG_INFO|CAM_DEBUG_PROBE|CAM_DEBUG_PERIPH) options CAM_DEBUG_BUS=-1 options CAM_DEBUG_TARGET=-1 options CAM_DEBUG_LUN=-1 options CAM_DEBUG_DELAY=1 options CAM_MAX_HIGHPOWER=4 options SCSI_NO_SENSE_STRINGS options SCSI_NO_OP_STRINGS options SCSI_DELAY=5000 # Be pessimistic about Joe SCSI device options CAM_IOSCHED_DYNAMIC options CAM_IO_STATS options CAM_TEST_FAILURE # Options for the CAM CDROM driver: # CHANGER_MIN_BUSY_SECONDS: Guaranteed minimum time quantum for a changer LUN # CHANGER_MAX_BUSY_SECONDS: Maximum time quantum per changer LUN, only # enforced if there is I/O waiting for another LUN # The compiled in defaults for these variables are 2 and 10 seconds, # respectively. # # These can also be changed on the fly with the following sysctl variables: # kern.cam.cd.changer.min_busy_seconds # kern.cam.cd.changer.max_busy_seconds # options CHANGER_MIN_BUSY_SECONDS=2 options CHANGER_MAX_BUSY_SECONDS=10 # Options for the CAM sequential access driver: # SA_IO_TIMEOUT: Timeout for read/write/wfm operations, in minutes # SA_SPACE_TIMEOUT: Timeout for space operations, in minutes # SA_REWIND_TIMEOUT: Timeout for rewind operations, in minutes # SA_ERASE_TIMEOUT: Timeout for erase operations, in minutes # SA_1FM_AT_EOD: Default to model which only has a default one filemark at EOT. options SA_IO_TIMEOUT=4 options SA_SPACE_TIMEOUT=60 options SA_REWIND_TIMEOUT=(2*60) options SA_ERASE_TIMEOUT=(4*60) options SA_1FM_AT_EOD # Optional timeout for the CAM processor target (pt) device # This is specified in seconds. The default is 60 seconds. options SCSI_PT_DEFAULT_TIMEOUT=60 # Optional enable of doing SES passthrough on other devices (e.g., disks) # # Normally disabled because a lot of newer SCSI disks report themselves # as having SES capabilities, but this can then clot up attempts to build # a topology with the SES device that's on the box these drives are in.... options SES_ENABLE_PASSTHROUGH ##################################################################### # MISCELLANEOUS DEVICES AND OPTIONS device pty #BSD-style compatibility pseudo ttys device nmdm #back-to-back tty devices device md #Memory/malloc disk device snp #Snoop device - to look at pty/vty/etc.. device ccd #Concatenated disk driver device firmware #firmware(9) support # Kernel side iconv library options LIBICONV # Size of the kernel message buffer. Should be N * pagesize. options MSGBUF_SIZE=40960 ##################################################################### # HARDWARE BUS CONFIGURATION # # PCI bus & PCI options: # device pci options PCI_HP # PCI-Express native HotPlug options PCI_IOV # PCI SR-IOV support ##################################################################### # HARDWARE DEVICE CONFIGURATION # For ISA the required hints are listed. # PCI, CardBus, and SD/MMC are self identifying buses, so # no hints are needed. # # Mandatory devices: # # These options are valid for other keyboard drivers as well. options KBD_DISABLE_KEYMAP_LOAD # refuse to load a keymap options KBD_INSTALL_CDEV # install a CDEV entry in /dev device kbdmux # keyboard multiplexer options KBDMUX_DFLT_KEYMAP # specify the built-in keymap makeoptions KBDMUX_DFLT_KEYMAP=it.iso options FB_DEBUG # Frame buffer debugging # Enable experimental features of the syscons terminal emulator (teken). options TEKEN_CONS25 # cons25-style terminal emulation options TEKEN_UTF8 # UTF-8 output handling # The vt video console driver. device vt options VT_ALT_TO_ESC_HACK=1 # Prepend ESC sequence to ALT keys options VT_MAXWINDOWS=16 # Number of virtual consoles options VT_TWOBUTTON_MOUSE # Use right mouse button to paste # The following options set the maximum framebuffer size. options VT_FB_MAX_HEIGHT=480 options VT_FB_MAX_WIDTH=640 # The following options will let you change the default vt terminal colors. options TERMINAL_NORM_ATTR=(FG_GREEN|BG_BLACK) options TERMINAL_KERN_ATTR=(FG_LIGHTRED|BG_BLACK) # # Optional devices: # # # SCSI host adapters: # # aacraid: Adaptec by PMC RAID controllers, Series 6/7/8 and upcoming # families. Container interface, CAM required. # ahc: Adaptec 274x/284x/2910/293x/294x/394x/3950x/3960x/398X/4944/ # 19160x/29160x, aic7770/aic78xx # ahd: Adaptec 29320/39320 Controllers. # isp: Qlogic ISP 1020, 1040 and 1040B PCI SCSI host adapters, # ISP 1240 Dual Ultra SCSI, ISP 1080 and 1280 (Dual) Ultra2, # ISP 12160 Ultra3 SCSI, # Qlogic ISP 2100 and ISP 2200 1Gb Fibre Channel host adapters. # Qlogic ISP 2300 and ISP 2312 2Gb Fibre Channel host adapters. # Qlogic ISP 2322 and ISP 6322 2Gb Fibre Channel host adapters. # ispfw: Firmware module for Qlogic host adapters # mpr: LSI-Logic MPT/Fusion Gen 3 # mps: LSI-Logic MPT/Fusion Gen 2 # mpt: LSI-Logic MPT/Fusion 53c1020 or 53c1030 Ultra4 # or FC9x9 Fibre Channel host adapters. # sym: Symbios/Logic 53C8XX family of PCI-SCSI I/O processors: # 53C810, 53C810A, 53C815, 53C825, 53C825A, 53C860, 53C875, # 53C876, 53C885, 53C895, 53C895A, 53C896, 53C897, 53C1510D, # 53C1010-33, 53C1010-66. device aacraid device ahc device ahd device isp envvar hint.isp.0.disable="1" envvar hint.isp.0.role="3" envvar hint.isp.0.prefer_iomap="1" envvar hint.isp.0.prefer_memmap="1" envvar hint.isp.0.fwload_disable="1" envvar hint.isp.0.ignore_nvram="1" envvar hint.isp.0.fullduplex="1" envvar hint.isp.0.topology="lport" envvar hint.isp.0.topology="nport" envvar hint.isp.0.topology="lport-only" envvar hint.isp.0.topology="nport-only" # we can't get u_int64_t types, nor can we get strings if it's got # a leading 0x, hence this silly dodge. envvar hint.isp.0.portwnn="w50000000aaaa0000" envvar hint.isp.0.nodewnn="w50000000aaaa0001" device ispfw device mpr # LSI-Logic MPT-Fusion 3 device mps # LSI-Logic MPT-Fusion 2 device mpt # LSI-Logic MPT-Fusion device sym # The aic7xxx driver will attempt to use memory mapped I/O for all PCI # controllers that have it configured only if this option is set. Unfortunately, # this doesn't work on some motherboards, which prevents it from being the # default. options AHC_ALLOW_MEMIO # Dump the contents of the ahc controller configuration PROM. options AHC_DUMP_EEPROM # Bitmap of units to enable targetmode operations. options AHC_TMODE_ENABLE # Compile in Aic7xxx Debugging code. options AHC_DEBUG # Aic7xxx driver debugging options. See sys/dev/aic7xxx/aic7xxx.h options AHC_DEBUG_OPTS # Print register bitfields in debug output. Adds ~128k to driver # See ahc(4). options AHC_REG_PRETTY_PRINT # Compile in aic79xx debugging code. options AHD_DEBUG # Aic79xx driver debugging options. Adds ~215k to driver. See ahd(4). options AHD_DEBUG_OPTS=0xFFFFFFFF # Print human-readable register definitions when debugging options AHD_REG_PRETTY_PRINT # Bitmap of units to enable targetmode operations. options AHD_TMODE_ENABLE # Options used in dev/iscsi (Software iSCSI stack) # options ISCSI_INITIATOR_DEBUG=9 # Options used in dev/isp/ (Qlogic SCSI/FC driver). # # ISP_TARGET_MODE - enable target mode operation # options ISP_TARGET_MODE=1 # # ISP_DEFAULT_ROLES - default role # none=0 # target=1 # initiator=2 # both=3 (not supported currently) # # ISP_INTERNAL_TARGET (trivial internal disk target, for testing) # options ISP_DEFAULT_ROLES=0 #options SYM_SETUP_SCSI_DIFF #-HVD support for 825a, 875, 885 # disabled:0 (default), enabled:1 #options SYM_SETUP_PCI_PARITY #-PCI parity checking # disabled:0, enabled:1 (default) #options SYM_SETUP_MAX_LUN #-Number of LUNs supported # default:8, range:[1..64] # # Compaq "CISS" RAID controllers (SmartRAID 5* series) # These controllers have a SCSI-like interface, and require the # CAM infrastructure. # device ciss # # Compaq Smart RAID, Mylex DAC960 and AMI MegaRAID controllers. Only # one entry is needed; the code will find and configure all supported # controllers. # device ida # Compaq Smart RAID device mlx # Mylex DAC960 device mfi # LSI MegaRAID SAS device mfip # LSI MegaRAID SAS passthrough, requires CAM options MFI_DEBUG device mrsas # LSI/Avago MegaRAID SAS/SATA, 6Gb/s and 12Gb/s # # 3ware ATA RAID # device twe # 3ware ATA RAID # # Serial ATA host controllers: # # ahci: Advanced Host Controller Interface (AHCI) compatible # mvs: Marvell 88SX50XX/88SX60XX/88SX70XX/SoC controllers # siis: SiliconImage SiI3124/SiI3132/SiI3531 controllers # # These drivers are part of cam(4) subsystem. They supersede less featured # ata(4) subsystem drivers, supporting same hardware. device ahci device mvs device siis # # The 'ATA' driver supports all legacy ATA/ATAPI controllers, including # PC Card devices. You only need one "device ata" for it to find all # PCI and PC Card ATA/ATAPI devices on modern machines. # Alternatively, individual bus and chipset drivers may be chosen by using # the 'atacore' driver then selecting the drivers on a per vendor basis. # For example to build a system which only supports a VIA chipset, # omit 'ata' and include the 'atacore', 'atapci' and 'atavia' drivers. device ata # Modular ATA #device atacore # Core ATA functionality #device ataisa # ISA bus support #device atapci # PCI bus support; only generic chipset support # PCI ATA chipsets #device ataacard # ACARD #device ataacerlabs # Acer Labs Inc. (ALI) #device ataamd # American Micro Devices (AMD) #device ataati # ATI #device atacenatek # Cenatek #device atacypress # Cypress #device atacyrix # Cyrix #device atahighpoint # HighPoint #device ataintel # Intel #device ataite # Integrated Technology Inc. (ITE) #device atajmicron # JMicron #device atamarvell # Marvell #device atamicron # Micron #device atanational # National #device atanetcell # NetCell #device atanvidia # nVidia #device atapromise # Promise #device ataserverworks # ServerWorks #device atasiliconimage # Silicon Image Inc. (SiI) (formerly CMD) #device atasis # Silicon Integrated Systems Corp.(SiS) #device atavia # VIA Technologies Inc. # # For older non-PCI, non-PnPBIOS systems, these are the hints lines to add: envvar hint.ata.0.at="isa" envvar hint.ata.0.port="0x1f0" envvar hint.ata.0.irq="14" envvar hint.ata.1.at="isa" envvar hint.ata.1.port="0x170" envvar hint.ata.1.irq="15" # # uart: generic driver for serial interfaces. # device uart # Options for uart(4) options UART_PPS_ON_CTS # Do time pulse capturing using CTS # instead of DCD. options UART_POLL_FREQ # Set polling rate, used when hw has # no interrupt support (50 Hz default). # The following hint should only be used for pure ISA devices. It is not # needed otherwise. Use of hints is strongly discouraged. envvar hint.uart.0.at="isa" # The following 3 hints are used when the UART is a system device (i.e., a # console or debug port), but only on platforms that don't have any other # means to pass the information to the kernel. The unit number of the hint # is only used to bundle the hints together. There is no relation to the # unit number of the probed UART. envvar hint.uart.0.port="0x3f8" envvar hint.uart.0.flags="0x10" envvar hint.uart.0.baud="115200" # `flags' for serial drivers that support consoles, like uart(4): # 0x10 enable console support for this unit. Other console flags # (if applicable) are ignored unless this is set. Enabling # console support does not make the unit the preferred console. # Boot with -h or set boot_serial=YES in the loader. # Currently, at most one unit can have console support; the # first one (in config file order) with this flag set is # preferred. # 0x80 use this port for serial line gdb support in ddb. Also known # as debug port. # # Options for serial drivers that support consoles: options BREAK_TO_DEBUGGER # A BREAK/DBG on the console goes to # ddb, if available. # Solaris implements a new BREAK which is initiated by a character # sequence CR ~ ^b which is similar to a familiar pattern used on # Sun servers by the Remote Console. There are FreeBSD extensions: # CR ~ ^p requests force panic and CR ~ ^r requests a clean reboot. options ALT_BREAK_TO_DEBUGGER # Serial Communications Controller # Supports the Freescale/NXP QUad Integrated and Zilog Z8530 multi-channel # communications controllers. device scc # PCI Universal Communications driver # Supports various multi port PCI I/O cards. device puc # # Network interfaces: # # MII bus support is required for many PCI Ethernet NICs, # namely those which use MII-compliant transceivers or implement # transceiver control interfaces that operate like an MII. Adding # "device miibus" to the kernel config pulls in support for the generic # miibus API, the common support for bit-bang'ing the MII and all # of the PHY drivers, including a generic one for PHYs that aren't # specifically handled by an individual driver. Support for specific # PHYs may be built by adding "device mii", "device mii_bitbang" if # needed by the NIC driver and then adding the appropriate PHY driver. device mii # Minimal MII support device mii_bitbang # Common module for bit-bang'ing the MII device miibus # MII support w/ bit-bang'ing and all PHYs device acphy # Altima Communications AC101 device amphy # AMD AM79c873 / Davicom DM910{1,2} device atphy # Attansic/Atheros F1 device axphy # Asix Semiconductor AX88x9x device bmtphy # Broadcom BCM5201/BCM5202 and 3Com 3c905C device bnxt # Broadcom NetXtreme-C/NetXtreme-E device brgphy # Broadcom BCM54xx/57xx 1000baseTX device cgem # Cadence GEM Gigabit Ethernet device ciphy # Cicada/Vitesse CS/VSC8xxx device e1000phy # Marvell 88E1000 1000/100/10-BT device gentbi # Generic 10-bit 1000BASE-{LX,SX} fiber ifaces device icsphy # ICS ICS1889-1893 device ip1000phy # IC Plus IP1000A/IP1001 device jmphy # JMicron JMP211/JMP202 device lxtphy # Level One LXT-970 device nsgphy # NatSemi DP8361/DP83865/DP83891 device nsphy # NatSemi DP83840A device nsphyter # NatSemi DP83843/DP83815 device pnaphy # HomePNA device qsphy # Quality Semiconductor QS6612 device rdcphy # RDC Semiconductor R6040 device rgephy # RealTek 8169S/8110S/8211B/8211C device rlphy # RealTek 8139 device rlswitch # RealTek 8305 device smcphy # SMSC LAN91C111 device tdkphy # TDK 89Q2120 device truephy # LSI TruePHY device xmphy # XaQti XMAC II # ae: Support for gigabit ethernet adapters based on the Attansic/Atheros # L2 PCI-Express FastEthernet controllers. # age: Support for gigabit ethernet adapters based on the Attansic/Atheros # L1 PCI express gigabit ethernet controllers. # alc: Support for Atheros AR8131/AR8132 PCIe ethernet controllers. # ale: Support for Atheros AR8121/AR8113/AR8114 PCIe ethernet controllers. # ath: Atheros a/b/g WiFi adapters (requires ath_hal and wlan) # bce: Broadcom NetXtreme II (BCM5706/BCM5708) PCI/PCIe Gigabit Ethernet # adapters. # bfe: Broadcom BCM4401 Ethernet adapter. # bge: Support for gigabit ethernet adapters based on the Broadcom # BCM570x family of controllers, including the 3Com 3c996-T, # the Netgear GA302T, the SysKonnect SK-9D21 and SK-9D41, and # the embedded gigE NICs on Dell PowerEdge 2550 servers. # bnxt: Broadcom NetXtreme-C and NetXtreme-E PCIe 10/25/50G Ethernet adapters. # bxe: Broadcom NetXtreme II (BCM5771X/BCM578XX) PCIe 10Gb Ethernet # adapters. # bwi: Broadcom BCM430* and BCM431* family of wireless adapters. # bwn: Broadcom BCM43xx family of wireless adapters. # cas: Sun Cassini/Cassini+ and National Semiconductor DP83065 Saturn # cxgb: Chelsio T3 based 1GbE/10GbE PCIe Ethernet adapters. # cxgbe:Chelsio T4, T5, and T6-based 1/10/25/40/100GbE PCIe Ethernet # adapters. # cxgbev: Chelsio T4, T5, and T6-based PCIe Virtual Functions. # dc: Support for PCI fast ethernet adapters based on the DEC/Intel 21143 # and various workalikes including: # the ADMtek AL981 Comet and AN985 Centaur, the ASIX Electronics # AX88140A and AX88141, the Davicom DM9100 and DM9102, the Lite-On # 82c168 and 82c169 PNIC, the Lite-On/Macronix LC82C115 PNIC II # and the Macronix 98713/98713A/98715/98715A/98725 PMAC. This driver # replaces the old al, ax, dm, pn and mx drivers. List of brands: # Digital DE500-BA, Kingston KNE100TX, D-Link DFE-570TX, SOHOware SFA110, # SVEC PN102-TX, CNet Pro110B, 120A, and 120B, Compex RL100-TX, # LinkSys LNE100TX, LNE100TX V2.0, Jaton XpressNet, Alfa Inc GFC2204, # KNE110TX. # em: Intel Pro/1000 Gigabit Ethernet 82542, 82543, 82544 based adapters. # fxp: Intel EtherExpress Pro/100B # (hint of prefer_iomap can be done to prefer I/O instead of Mem mapping) # gem: Apple GMAC/Sun ERI/Sun GEM # jme: JMicron JMC260 Fast Ethernet/JMC250 Gigabit Ethernet based adapters. # le: AMD Am7900 LANCE and Am79C9xx PCnet # lge: Support for PCI gigabit ethernet adapters based on the Level 1 # LXT1001 NetCellerator chipset. This includes the D-Link DGE-500SX, # SMC TigerCard 1000 (SMC9462SX), and some Addtron cards. # lio: Support for Cavium 23XX Ethernet adapters # malo: Marvell Libertas wireless NICs. # mwl: Marvell 88W8363 802.11n wireless NICs. # Requires the mwl firmware module # mwlfw: Marvell 88W8363 firmware # msk: Support for gigabit ethernet adapters based on the Marvell/SysKonnect # Yukon II Gigabit controllers, including 88E8021, 88E8022, 88E8061, # 88E8062, 88E8035, 88E8036, 88E8038, 88E8050, 88E8052, 88E8053, # 88E8055, 88E8056 and D-Link 560T/550SX. # mlxfw: Mellanox firmware update module. # mlx5: Mellanox ConnectX-4 and ConnectX-4 LX IB and Eth shared code module. # mlx5en:Mellanox ConnectX-4 and ConnectX-4 LX PCIe Ethernet adapters. # my: Myson Fast Ethernet (MTD80X, MTD89X) # nge: Support for PCI gigabit ethernet adapters based on the National # Semiconductor DP83820 and DP83821 chipset. This includes the # SMC EZ Card 1000 (SMC9462TX), D-Link DGE-500T, Asante FriendlyNet # GigaNIX 1000TA and 1000TPC, the Addtron AEG320T, the Surecom # EP-320G-TX and the Netgear GA622T. # oce: Emulex 10 Gbit adapters (OneConnect Ethernet) # ral: Ralink Technology IEEE 802.11 wireless adapter # re: RealTek 8139C+/8169/816xS/811xS/8101E PCI/PCIe Ethernet adapter # rl: Support for PCI fast ethernet adapters based on the RealTek 8129/8139 # chipset. Note that the RealTek driver defaults to using programmed # I/O to do register accesses because memory mapped mode seems to cause # severe lockups on SMP hardware. This driver also supports the # Accton EN1207D `Cheetah' adapter, which uses a chip called # the MPX 5030/5038, which is either a RealTek in disguise or a # RealTek workalike. Note that the D-Link DFE-530TX+ uses the RealTek # chipset and is supported by this driver, not the 'vr' driver. # rtwn: RealTek wireless adapters. # rtwnfw: RealTek wireless firmware. # sge: Silicon Integrated Systems SiS190/191 Fast/Gigabit Ethernet adapter # sis: Support for NICs based on the Silicon Integrated Systems SiS 900, # SiS 7016 and NS DP83815 PCI fast ethernet controller chips. # sk: Support for the SysKonnect SK-984x series PCI gigabit ethernet NICs. # This includes the SK-9841 and SK-9842 single port cards (single mode # and multimode fiber) and the SK-9843 and SK-9844 dual port cards # (also single mode and multimode). # The driver will autodetect the number of ports on the card and # attach each one as a separate network interface. # ste: Sundance Technologies ST201 PCI fast ethernet controller, includes # the D-Link DFE-550TX. # stge: Support for gigabit ethernet adapters based on the Sundance/Tamarack # TC9021 family of controllers, including the Sundance ST2021/ST2023, # the Sundance/Tamarack TC9021, the D-Link DL-4000 and ASUS NX1101. # ti: Support for PCI gigabit ethernet NICs based on the Alteon Networks # Tigon 1 and Tigon 2 chipsets. This includes the Alteon AceNIC, the # 3Com 3c985, the Netgear GA620 and various others. Note that you will # probably want to bump up kern.ipc.nmbclusters a lot to use this driver. # vr: Support for various fast ethernet adapters based on the VIA # Technologies VT3043 `Rhine I' and VT86C100A `Rhine II' chips, # including the D-Link DFE520TX and D-Link DFE530TX (see 'rl' for # DFE530TX+), the Hawking Technologies PN102TX, and the AOpen/Acer ALN-320. # vte: DM&P Vortex86 RDC R6040 Fast Ethernet # xl: Support for the 3Com 3c900, 3c905, 3c905B and 3c905C (Fast) # Etherlink XL cards and integrated controllers. This includes the # integrated 3c905B-TX chips in certain Dell Optiplex and Dell # Precision desktop machines and the integrated 3c905-TX chips # in Dell Latitude laptop docking stations. # Also supported: 3Com 3c980(C)-TX, 3Com 3cSOHO100-TX, 3Com 3c450-TX # PCI Ethernet NICs that use the common MII bus controller code. device ae # Attansic/Atheros L2 FastEthernet device age # Attansic/Atheros L1 Gigabit Ethernet device alc # Atheros AR8131/AR8132 Ethernet device ale # Atheros AR8121/AR8113/AR8114 Ethernet device bce # Broadcom BCM5706/BCM5708 Gigabit Ethernet device bfe # Broadcom BCM440x 10/100 Ethernet device bge # Broadcom BCM570xx Gigabit Ethernet device cas # Sun Cassini/Cassini+ and NS DP83065 Saturn device dc # DEC/Intel 21143 and various workalikes device et # Agere ET1310 10/100/Gigabit Ethernet device fxp # Intel EtherExpress PRO/100B (82557, 82558) envvar hint.fxp.0.prefer_iomap="0" device gem # Apple GMAC/Sun ERI/Sun GEM device jme # JMicron JMC250 Gigabit/JMC260 Fast Ethernet device lge # Level 1 LXT1001 gigabit Ethernet device lio # Support for Cavium 23XX Ethernet adapters device mlxfw # Mellanox firmware update module device mlx5 # Shared code module between IB and Ethernet device mlx5en # Mellanox ConnectX-4 and ConnectX-4 LX device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet device my # Myson Fast Ethernet (MTD80X, MTD89X) device nge # NatSemi DP83820 gigabit Ethernet device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 device sge # Silicon Integrated Systems SiS190/191 device sis # Silicon Integrated Systems SiS 900/SiS 7016 device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet device ste # Sundance ST201 (D-Link DFE-550TX) device stge # Sundance/Tamarack TC9021 gigabit Ethernet device vr # VIA Rhine, Rhine II device vte # DM&P Vortex86 RDC R6040 Fast Ethernet device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') # PCI/PCI-X/PCIe Ethernet NICs that use iflib infrastructure device iflib device em # Intel Pro/1000 Gigabit Ethernet device ix # Intel Pro/10Gbe PCIE Ethernet device ixv # Intel Pro/10Gbe PCIE Ethernet VF # PCI Ethernet NICs. device cxgb # Chelsio T3 10 Gigabit Ethernet device cxgb_t3fw # Chelsio T3 10 Gigabit Ethernet firmware device cxgbe # Chelsio T4-T6 1/10/25/40/100 Gigabit Ethernet device cxgbev # Chelsio T4-T6 Virtual Functions device le # AMD Am7900 LANCE and Am79C9xx PCnet device mxge # Myricom Myri-10G 10GbE NIC device oce # Emulex 10 GbE (OneConnect Ethernet) device ti # Alteon Networks Tigon I/II gigabit Ethernet # PCI IEEE 802.11 Wireless NICs device ath # Atheros pci/cardbus NIC's device ath_hal # pci/cardbus chip support #device ath_ar5210 # AR5210 chips #device ath_ar5211 # AR5211 chips #device ath_ar5212 # AR5212 chips #device ath_rf2413 #device ath_rf2417 #device ath_rf2425 #device ath_rf5111 #device ath_rf5112 #device ath_rf5413 #device ath_ar5416 # AR5416 chips # All of the AR5212 parts have a problem when paired with the AR71xx # CPUS. These parts have a bug that triggers a fatal bus error on the AR71xx # only. Details of the exact nature of the bug are sketchy, but some can be # found at https://forum.openwrt.org/viewtopic.php?pid=70060 on pages 4, 5 and # 6. This option enables this workaround. There is a performance penalty # for this work around, but without it things don't work at all. The DMA # from the card usually bursts 128 bytes, but on the affected CPUs, only # 4 are safe. options AH_RXCFG_SDMAMW_4BYTES #device ath_ar9160 # AR9160 chips #device ath_ar9280 # AR9280 chips #device ath_ar9285 # AR9285 chips device ath_rate_sample # SampleRate tx rate control for ath device bwi # Broadcom BCM430* BCM431* device bwn # Broadcom BCM43xx device malo # Marvell Libertas wireless NICs. device mwl # Marvell 88W8363 802.11n wireless NICs. device mwlfw device ral # Ralink Technology RT2500 wireless NICs. device rtwn # Realtek wireless NICs device rtwnfw # Use sf_buf(9) interface for jumbo buffers on ti(4) controllers. #options TI_SF_BUF_JUMBO # Turn on the header splitting option for the ti(4) driver firmware. This # only works for Tigon II chips, and has no effect for Tigon I chips. # This option requires the TI_SF_BUF_JUMBO option above. #options TI_JUMBO_HDRSPLIT # These two options allow manipulating the mbuf cluster size and mbuf size, # respectively. Be very careful with NIC driver modules when changing # these from their default values, because that can potentially cause a # mismatch between the mbuf size assumed by the kernel and the mbuf size # assumed by a module. The only driver that currently has the ability to # detect a mismatch is ti(4). options MCLSHIFT=11 # mbuf cluster shift in bits, 11 == 2KB options MSIZE=256 # mbuf size in bytes # # Sound drivers # # sound: The generic sound driver. # device sound # # snd_*: Device-specific drivers. # # The flags of the device tell the device a bit more info about the # device that normally is obtained through the PnP interface. # bit 2..0 secondary DMA channel; # bit 4 set if the board uses two dma channels; # bit 15..8 board type, overrides autodetection; leave it # zero if don't know what to put in (and you don't, # since this is unsupported at the moment...). # # snd_als4000: Avance Logic ALS4000 PCI. # snd_atiixp: ATI IXP 200/300/400 PCI. # snd_cmi: CMedia CMI8338/CMI8738 PCI. # snd_cs4281: Crystal Semiconductor CS4281 PCI. # snd_csa: Crystal Semiconductor CS461x/428x PCI. (except # 4281) # snd_emu10k1: Creative EMU10K1 PCI and EMU10K2 (Audigy) PCI. # snd_emu10kx: Creative SoundBlaster Live! and Audigy # snd_envy24: VIA Envy24 and compatible, needs snd_spicds. # snd_envy24ht: VIA Envy24HT and compatible, needs snd_spicds. # snd_es137x: Ensoniq AudioPCI ES137x PCI. # snd_fm801: Forte Media FM801 PCI. # snd_hda: Intel High Definition Audio (Controller) and # compatible. # snd_hdspe: RME HDSPe AIO and RayDAT. # snd_ich: Intel ICH AC'97 and some more audio controllers # embedded in a chipset, for example nVidia # nForce controllers. # snd_maestro3: ESS Technology Maestro-3/Allegro PCI. # snd_neomagic: Neomagic 256 AV/ZX PCI. # snd_solo: ESS Solo-1x PCI. # snd_spicds: SPI codec driver, needed by Envy24/Envy24HT drivers. # snd_t4dwave: Trident 4DWave DX/NX PCI, Sis 7018 PCI and Acer Labs # M5451 PCI. # snd_uaudio: USB audio. # snd_via8233: VIA VT8233x PCI. # snd_via82c686: VIA VT82C686A PCI. # snd_vibes: S3 Sonicvibes PCI. device snd_als4000 device snd_atiixp device snd_cmi device snd_cs4281 device snd_csa device snd_emu10k1 device snd_emu10kx device snd_envy24 device snd_envy24ht device snd_es137x device snd_fm801 device snd_hda device snd_hdspe device snd_ich device snd_maestro3 device snd_neomagic device snd_solo device snd_spicds device snd_t4dwave device snd_uaudio device snd_via8233 device snd_via82c686 device snd_vibes # For non-PnP sound cards: envvar hint.pcm.0.at="isa" envvar hint.pcm.0.irq="10" envvar hint.pcm.0.drq="1" envvar hint.pcm.0.flags="0x0" envvar hint.sbc.0.at="isa" envvar hint.sbc.0.port="0x220" envvar hint.sbc.0.irq="5" envvar hint.sbc.0.drq="1" envvar hint.sbc.0.flags="0x15" envvar hint.gusc.0.at="isa" envvar hint.gusc.0.port="0x220" envvar hint.gusc.0.irq="5" envvar hint.gusc.0.drq="1" envvar hint.gusc.0.flags="0x13" # # Following options are intended for debugging/testing purposes: # # SND_DEBUG Enable extra debugging code that includes # sanity checking and possible increase of # verbosity. # # SND_DIAGNOSTIC Similar in a spirit of INVARIANTS/DIAGNOSTIC, # zero tolerance against inconsistencies. # # SND_FEEDER_MULTIFORMAT By default, only 16/32 bit feeders are compiled # in. This options enable most feeder converters # except for 8bit. WARNING: May bloat the kernel. # # SND_FEEDER_FULL_MULTIFORMAT Ditto, but includes 8bit feeders as well. # # SND_FEEDER_RATE_HP (feeder_rate) High precision 64bit arithmetic # as much as possible (the default trying to # avoid it). Possible slowdown. # # SND_PCM_64 (Only applicable for i386/32bit arch) # Process 32bit samples through 64bit # integer/arithmetic. Slight increase of dynamic # range at a cost of possible slowdown. # # SND_OLDSTEREO Only 2 channels are allowed, effectively # disabling multichannel processing. # options SND_DEBUG options SND_DIAGNOSTIC options SND_FEEDER_MULTIFORMAT options SND_FEEDER_FULL_MULTIFORMAT options SND_FEEDER_RATE_HP options SND_PCM_64 options SND_OLDSTEREO # # Cardbus # # cbb: pci/CardBus bridge implementing YENTA interface # cardbus: CardBus slots device cbb device cardbus # # MMC/SD # # mmc MMC/SD bus # mmcsd MMC/SD memory card # sdhci Generic PCI SD Host Controller # rtsx Realtek SD card reader (RTS5209, RTS5227, ...) device mmc device mmcsd device sdhci device rtsx # # SMB bus # # System Management Bus support is provided by the 'smbus' device. # Access to the SMBus device is via the 'smb' device (/dev/smb*), # which is a child of the 'smbus' device. # # Supported devices: # smb standard I/O through /dev/smb* # # Supported SMB interfaces: # iicsmb I2C to SMB bridge with any iicbus interface # intpm Intel PIIX4 (82371AB, 82443MX) Power Management Unit # alpm Acer Aladdin-IV/V/Pro2 Power Management Unit # ichsmb Intel ICH SMBus controller chips (82801AA, 82801AB, 82801BA) # viapm VIA VT82C586B/596B/686A and VT8233 Power Management Unit # amdpm AMD 756 Power Management Unit # amdsmb AMD 8111 SMBus 2.0 Controller # nfpm NVIDIA nForce Power Management Unit # nfsmb NVIDIA nForce2/3/4 MCP SMBus 2.0 Controller # ismt Intel SMBus 2.0 controller chips (on Atom S1200, C2000) # device smbus # Bus support, required for smb below. device intpm device alpm device ichsmb device viapm device amdpm device amdsmb device nfpm device nfsmb device ismt device smb # SMBus peripheral devices # # jedec_dimm Asset and temperature reporting for DDR3 and DDR4 DIMMs # device jedec_dimm # I2C Bus # # Philips i2c bus support is provided by the `iicbus' device. # # Supported devices: # ic i2c network interface # iic i2c standard io # iicsmb i2c to smb bridge. Allow i2c i/o with smb commands. # iicoc simple polling driver for OpenCores I2C controller # # Other: # iicbb generic I2C bit-banging code (needed by lpbb) # device iicbus # Bus support, required for ic/iic/iicsmb below. device iicbb # bitbang driver; implements i2c on a pair of gpio pins device ic device iic # userland access to i2c slave devices via ioctl(8) device iicsmb # smb over i2c bridge device iicoc # OpenCores I2C controller support # I2C bus multiplexer (mux) devices device iicmux # i2c mux core driver device iic_gpiomux # i2c mux hardware controlled via gpio pins device ltc430x # LTC4305 and LTC4306 i2c mux chips # I2C peripheral devices # device ad7418 # Analog Devices temp and voltage sensor device ads111x # Texas Instruments ADS101x and ADS111x ADCs device ds1307 # Dallas DS1307 RTC and compatible device ds13rtc # All Dallas/Maxim ds13xx chips device ds1672 # Dallas DS1672 RTC device ds3231 # Dallas DS3231 RTC + temperature device fan53555 # Fairchild Semi FAN53555/SYR82x Regulator device icee # AT24Cxxx and compatible EEPROMs device isl12xx # Intersil ISL12xx RTC device lm75 # LM75 compatible temperature sensor device nxprtc # NXP RTCs: PCA/PFC212x PCA/PCF85xx device rtc8583 # Epson RTC-8583 device s35390a # Seiko Instruments S-35390A RTC device sy8106a # Silergy Corp. SY8106A buck regulator # Parallel-Port Bus # # Parallel port bus support is provided by the `ppbus' device. # Multiple devices may be attached to the parallel port, devices # are automatically probed and attached when found. # # Supported devices: # lpt Parallel Printer # plip Parallel network interface # ppi General-purpose I/O ("Geek Port") + IEEE1284 I/O # pps Pulse per second Timing Interface # lpbb Philips official parallel port I2C bit-banging interface # pcfclock Parallel port clock driver. # # Supported interfaces: # ppc ISA-bus parallel port interfaces. # options PPC_PROBE_CHIPSET # Enable chipset specific detection # (see flags in ppc(4)) options DEBUG_1284 # IEEE1284 signaling protocol debug options PERIPH_1284 # Makes your computer act as an IEEE1284 # compliant peripheral options DONTPROBE_1284 # Avoid boot detection of PnP parallel devices options LPT_DEBUG # Printer driver debug options PPC_DEBUG # Parallel chipset level debug options PLIP_DEBUG # Parallel network IP interface debug options PCFCLOCK_VERBOSE # Verbose pcfclock driver options PCFCLOCK_MAX_RETRIES=5 # Maximum read tries (default 10) device ppc envvar hint.ppc.0.at="isa" envvar hint.ppc.0.irq="7" device ppbus device lpt device plip device ppi device pps device lpbb device pcfclock # General Purpose I/O pins device dwgpio # Synopsys DesignWare APB GPIO Controller device gpio # gpio interfaces and bus support device gpiobacklight # sysctl control of gpio-based backlight device gpioiic # i2c via gpio bitbang device gpiokeys # kbd(4) glue for gpio-based key input device gpioled # led(4) gpio glue device gpiopower # event handler for gpio-based powerdown device gpiopps # Pulse per second input from gpio pin device gpioregulator # extres/regulator glue for gpio pin device gpiospi # SPI via gpio bitbang device gpioths # 1-wire temp/humidity sensor on gpio pin # Pulse width modulation device pwmbus # pwm interface and bus support device pwmc # userland control access to pwm outputs # # Etherswitch framework and drivers # # etherswitch The etherswitch(4) framework # miiproxy Proxy device for miibus(4) functionality # # Switch hardware support: # arswitch Atheros switches # ip17x IC+ 17x family switches # rtl8366r Realtek RTL8366 switches # ukswitch Multi-PHY switches # device etherswitch device miiproxy device arswitch device ip17x device rtl8366rb device ukswitch # Kernel BOOTP support options BOOTP # Use BOOTP to obtain IP address/hostname # Requires NFSCL and NFS_ROOT options BOOTP_NFSROOT # NFS mount root filesystem using BOOTP info options BOOTP_NFSV3 # Use NFS v3 to NFS mount root options BOOTP_COMPAT # Workaround for broken bootp daemons. options BOOTP_WIRED_TO=fxp0 # Use interface fxp0 for BOOTP options BOOTP_BLOCKSIZE=8192 # Override NFS block size # # Enable software watchdog routines, even if hardware watchdog is present. # By default, software watchdog timer is enabled only if no hardware watchdog # is present. # options SW_WATCHDOG # # Add the software deadlock resolver thread. # options DEADLKRES # # Disable swapping of stack pages. This option removes all # code which actually performs swapping, so it's not possible to turn # it back on at run-time. # # This is sometimes usable for systems which don't have any swap space # (see also sysctl "vm.disable_swapspace_pageouts") # #options NO_SWAPPING # Set the number of sf_bufs to allocate. sf_bufs are virtual buffers # for sendfile(2) that are used to map file VM pages, and normally # default to a quantity that is roughly 16*MAXUSERS+512. You would # typically want about 4 of these for each simultaneous file send. # options NSFBUFS=1024 # # Enable extra debugging code for locks. This stores the filename and # line of whatever acquired the lock in the lock itself, and changes a # number of function calls to pass around the relevant data. This is # not at all useful unless you are debugging lock code. Note that # modules should be recompiled as this option modifies KBI. # options DEBUG_LOCKS ##################################################################### # HID support device hid # Generic HID support options HID_DEBUG # enable debug msgs device hidbus # HID bus device hidmap # HID to evdev mapping device hidraw # Raw access driver options HIDRAW_MAKE_UHID_ALIAS # install /dev/uhid alias device hconf # Multitouch configuration TLC device hcons # Consumer controls device hgame # Generic game controllers device hkbd # HID keyboard device hms # HID mouse device hmt # HID multitouch (MS-compatible) device hpen # Generic pen driver device hsctrl # System controls device ps4dshock # Sony PS4 DualShock 4 gamepad driver device xb360gp # XBox 360 gamepad driver ##################################################################### # USB support # UHCI controller device uhci # OHCI controller device ohci # EHCI controller device ehci # XHCI controller device xhci # SL811 Controller #device slhci # General USB code (mandatory for USB) device usb # # USB Double Bulk Pipe devices device udbp # USB temperature meter device ugold # USB LED device uled # Human Interface Device (anything with buttons and dials) device uhid # USB keyboard device ukbd # USB printer device ulpt # USB mass storage driver (Requires scbus and da) device umass # USB mass storage driver for device-side mode device usfs # USB support for Belkin F5U109 and Magic Control Technology serial adapters device umct # USB modem support device umodem # USB mouse device ums # USB touchpad(s) device atp device wsp # eGalax USB touch screen device uep # Diamond Rio 500 MP3 player device urio # HID-over-USB driver device usbhid # # USB serial support device ucom # USB support for 3G modem cards by Option, Novatel, Huawei and Sierra device u3g # USB support for Technologies ARK3116 based serial adapters device uark # USB support for Belkin F5U103 and compatible serial adapters device ubsa # USB support for serial adapters based on the FT8U100AX and FT8U232AM device uftdi # USB support for some Windows CE based serial communication. device uipaq # USB support for Prolific PL-2303 serial adapters device uplcom # USB support for Silicon Laboratories CP2101/CP2102 based USB serial adapters device uslcom # USB Visor and Palm devices device uvisor # USB serial support for DDI pocket's PHS device uvscom # # USB ethernet support device uether # ADMtek USB ethernet. Supports the LinkSys USB100TX, # the Billionton USB100, the Melco LU-ATX, the D-Link DSB-650TX # and the SMC 2202USB. Also works with the ADMtek AN986 Pegasus # eval board. device aue # ASIX Electronics AX88172 USB 2.0 ethernet driver. Used in the # LinkSys USB200M and various other adapters. device axe # ASIX Electronics AX88178A/AX88179 USB 2.0/3.0 gigabit ethernet driver. device axge # # Devices which communicate using Ethernet over USB, particularly # Communication Device Class (CDC) Ethernet specification. Supports # Sharp Zaurus PDAs, some DOCSIS cable modems and so on. device cdce # # CATC USB-EL1201A USB ethernet. Supports the CATC Netmate # and Netmate II, and the Belkin F5U111. device cue # # Kawasaki LSI ethernet. Supports the LinkSys USB10T, # Entrega USB-NET-E45, Peracom Ethernet Adapter, the # 3Com 3c19250, the ADS Technologies USB-10BT, the ATen UC10T, # the Netgear EA101, the D-Link DSB-650, the SMC 2102USB # and 2104USB, and the Corega USB-T. device kue # # RealTek RTL8150 USB to fast ethernet. Supports the Melco LUA-KTX # and the GREEN HOUSE GH-USB100B. device rue # # Davicom DM9601E USB to fast ethernet. Supports the Corega FEther USB-TXC. device udav # # RealTek RTL8152/RTL8153 USB Ethernet driver device ure # # Moschip MCS7730/MCS7840 USB to fast ethernet. Supports the Sitecom LN030. device mos # # HSxPA devices from Option N.V device uhso # Realtek RTL8188SU/RTL8191SU/RTL8192SU wireless driver device rsu # # Ralink Technology RT2501USB/RT2601USB wireless driver device rum # Ralink Technology RT2700U/RT2800U/RT3000U wireless driver device run # # Atheros AR5523 wireless driver device uath # # Conexant/Intersil PrismGT wireless driver device upgt # # Ralink Technology RT2500USB wireless driver device ural # # RNDIS USB ethernet driver device urndis # Realtek RTL8187B/L wireless driver device urtw # # ZyDas ZD1211/ZD1211B wireless driver device zyd # # Sierra USB wireless driver device usie # # debugging options for the USB subsystem # options USB_DEBUG options U3G_DEBUG # options for ukbd: options UKBD_DFLT_KEYMAP # specify the built-in keymap makeoptions UKBD_DFLT_KEYMAP=jp.106 # options for uplcom: options UPLCOM_INTR_INTERVAL=100 # interrupt pipe interval # in milliseconds # options for uvscom: options UVSCOM_DEFAULT_OPKTSIZE=8 # default output packet size options UVSCOM_INTR_INTERVAL=100 # interrupt pipe interval # in milliseconds ##################################################################### # FireWire support device firewire # FireWire bus code device sbp # SCSI over Firewire (Requires scbus and da) device sbp_targ # SBP-2 Target mode (Requires scbus and targ) device fwe # Ethernet over FireWire (non-standard!) device fwip # IP over FireWire (RFC2734 and RFC3146) ##################################################################### # dcons support (Dumb Console Device) device dcons # dumb console driver device dcons_crom # FireWire attachment options DCONS_BUF_SIZE=16384 # buffer size options DCONS_POLL_HZ=100 # polling rate options DCONS_FORCE_CONSOLE=0 # force to be the primary console options DCONS_FORCE_GDB=1 # force to be the gdb device ##################################################################### # crypto subsystem # # This is a port of the OpenBSD crypto framework. Include this when # configuring IPSEC and when you have a h/w crypto device to accelerate # user applications that link to OpenSSL. # # Drivers are ports from OpenBSD with some simple enhancements that have # been fed back to OpenBSD. device crypto # core crypto support # Only install the cryptodev device if you are running tests, or know # specifically why you need it. In most cases, it is not needed and # will make things slower. device cryptodev # /dev/crypto for access to h/w device rndtest # FIPS 140-2 entropy tester device ccr # Chelsio T6 device hifn # Hifn 7951, 7781, etc. options HIFN_DEBUG # enable debugging support: hw.hifn.debug options HIFN_RNDTEST # enable rndtest support ##################################################################### # # Embedded system options: # # An embedded system might want to run something other than init. options INIT_PATH=/sbin/init:/rescue/init # Debug options options BUS_DEBUG # enable newbus debugging options DEBUG_VFS_LOCKS # enable VFS lock debugging options SOCKBUF_DEBUG # enable sockbuf last record/mb tail checking options IFMEDIA_DEBUG # enable debugging in net/if_media.c # # Verbose SYSINIT # # Make the SYSINIT process performed by mi_startup() verbose. This is very # useful when porting to a new architecture. If DDB is also enabled, this # will print function names instead of addresses. If defined with a value # of zero, the verbose code is compiled-in but disabled by default, and can # be enabled with the debug.verbose_sysinit=1 tunable. options VERBOSE_SYSINIT ##################################################################### # SYSV IPC KERNEL PARAMETERS # # Maximum number of System V semaphores that can be used on the system at # one time. options SEMMNI=11 # Total number of semaphores system wide options SEMMNS=61 # Total number of undo structures in system options SEMMNU=31 # Maximum number of System V semaphores that can be used by a single process # at one time. options SEMMSL=61 # Maximum number of operations that can be outstanding on a single System V # semaphore at one time. options SEMOPM=101 # Maximum number of undo operations that can be outstanding on a single # System V semaphore at one time. options SEMUME=11 # Maximum number of shared memory pages system wide. options SHMALL=1025 # Maximum size, in bytes, of a single System V shared memory region. options SHMMAX=(SHMMAXPGS*PAGE_SIZE+1) options SHMMAXPGS=1025 # Minimum size, in bytes, of a single System V shared memory region. options SHMMIN=2 # Maximum number of shared memory regions that can be used on the system # at one time. options SHMMNI=33 # Maximum number of System V shared memory regions that can be attached to # a single process at one time. options SHMSEG=9 # Set the amount of time (in seconds) the system will wait before # rebooting automatically when a kernel panic occurs. If set to (-1), # the system will wait indefinitely until a key is pressed on the # console. options PANIC_REBOOT_WAIT_TIME=16 # Attempt to bypass the buffer cache and put data directly into the # userland buffer for read operation when O_DIRECT flag is set on the # file. Both offset and length of the read operation must be # multiples of the physical media sector size. # options DIRECTIO # Specify a lower limit for the number of swap I/O buffers. They are # (among other things) used when bypassing the buffer cache due to # DIRECTIO kernel option enabled and O_DIRECT flag set on file. # options NSWBUF_MIN=120 ##################################################################### # More undocumented options for linting. # Note that documenting these is not considered an affront. options CAM_DEBUG_DELAY options DEBUG # Kernel filelock debugging. options LOCKF_DEBUG # System V compatible message queues # Please note that the values provided here are used to test kernel # building. The defaults in the sources provide almost the same numbers. # MSGSSZ must be a power of 2 between 8 and 1024. options MSGMNB=2049 # Max number of chars in queue options MSGMNI=41 # Max number of message queue identifiers options MSGSEG=2049 # Max number of message segments options MSGSSZ=16 # Size of a message segment options MSGTQL=41 # Max number of messages in system options NBUF=512 # Number of buffer headers options SC_DEBUG_LEVEL=5 # Syscons debug level options SC_RENDER_DEBUG # syscons rendering debugging options VFS_BIO_DEBUG # VFS buffer I/O debugging options KSTACK_MAX_PAGES=32 # Maximum pages to give the kernel stack options KSTACK_USAGE_PROF # Adaptec Array Controller driver options options AAC_DEBUG # Debugging levels: # 0 - quiet, only emit warnings # 1 - noisy, emit major function # points and things done # 2 - extremely noisy, emit trace # items in loops, etc. # Resource Accounting options RACCT # Resource Limits options RCTL # Yet more undocumented options for linting. options MAXFILES=999 # Random number generator # Alternative algorithm. #options RANDOM_FENESTRASX # Allow the CSPRNG algorithm to be loaded as a module. #options RANDOM_LOADABLE # Select this to allow high-rate but potentially expensive # harvesting of Slab-Allocator entropy. In very high-rate # situations the value of doing this is dubious at best. options RANDOM_ENABLE_UMA # slab allocator # Select this to allow high-rate but potentially expensive # harvesting of of the m_next pointer in the mbuf. Note that # the m_next pointer is NULL except when receiving > 4K # jumbo frames or sustained bursts by way of LRO. Thus in # the common case it is stirring zero in to the entropy # pool. In cases where it is not NULL it is pointing to one # of a small (in the thousands to 10s of thousands) number # of 256 byte aligned mbufs. Hence it is, even in the best # case, a poor source of entropy. And in the absence of actual # runtime analysis of entropy collection may mislead the user in # to believe that substantially more entropy is being collected # than in fact is - leading to a different class of security # risk. In high packet rate situations ethernet entropy # collection is also very expensive, possibly leading to as # much as a 50% drop in packets received. # This option is present to maintain backwards compatibility # if desired, however it cannot be recommended for use in any # environment. options RANDOM_ENABLE_ETHER # ether_input # Module to enable execution of application via emulators like QEMU options IMGACT_BINMISC # zlib I/O stream support # This enables support for compressed core dumps. options GZIO # zstd support # This enables support for Zstd compressed core dumps, GEOM_UZIP images, # and is required by zfs if statically linked. options ZSTDIO # BHND(4) drivers options BHND_LOGLEVEL # Logging threshold level # evdev interface device evdev # input event device support options EVDEV_SUPPORT # evdev support in legacy drivers options EVDEV_DEBUG # enable event debug msgs device uinput # install /dev/uinput cdev options UINPUT_DEBUG # enable uinput debug msgs # Encrypted kernel crash dumps. options EKCD # Serial Peripheral Interface (SPI) support. device spibus # Bus support. device at45d # DataFlash driver device cqspi # device mx25l # SPIFlash driver device n25q # device spigen # Generic access to SPI devices from userland. # Enable legacy /dev/spigenN name aliases for /dev/spigenX.Y devices. options SPIGEN_LEGACY_CDEVNAME # legacy device names for spigen # Compression supports. device zlib # gzip/zlib compression/decompression library device xz # xz_embedded LZMA de-compression library # Kernel support for stats(3). options STATS diff --git a/sys/conf/files b/sys/conf/files index 60c5c749c40b..943817f282aa 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,5244 +1,5243 @@ # $FreeBSD$ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # acpi_quirks.h optional acpi \ dependency "$S/tools/acpi_quirks2h.awk $S/dev/acpica/acpi_quirks" \ compile-with "${AWK} -f $S/tools/acpi_quirks2h.awk $S/dev/acpica/acpi_quirks" \ no-obj no-implicit-rule before-depend \ clean "acpi_quirks.h" bhnd_nvram_map.h optional bhnd \ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \ compile-with "sh $S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -h" \ no-obj no-implicit-rule before-depend \ clean "bhnd_nvram_map.h" bhnd_nvram_map_data.h optional bhnd \ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \ compile-with "sh $S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -d" \ no-obj no-implicit-rule before-depend \ clean "bhnd_nvram_map_data.h" fdt_static_dtb.h optional fdt fdt_dtb_static \ compile-with "sh -c 'MACHINE=${MACHINE} $S/tools/fdt/make_dtbh.sh ${FDT_DTS_FILE} ${.CURDIR}'" \ dependency "${FDT_DTS_FILE:T:R}.dtb" \ no-obj no-implicit-rule before-depend \ clean "fdt_static_dtb.h" feeder_eq_gen.h optional sound \ dependency "$S/tools/sound/feeder_eq_mkfilter.awk" \ compile-with "${AWK} -f $S/tools/sound/feeder_eq_mkfilter.awk -- ${FEEDER_EQ_PRESETS} > feeder_eq_gen.h" \ no-obj no-implicit-rule before-depend \ clean "feeder_eq_gen.h" feeder_rate_gen.h optional sound \ dependency "$S/tools/sound/feeder_rate_mkfilter.awk" \ compile-with "${AWK} -f $S/tools/sound/feeder_rate_mkfilter.awk -- ${FEEDER_RATE_PRESETS} > feeder_rate_gen.h" \ no-obj no-implicit-rule before-depend \ clean "feeder_rate_gen.h" font.h optional sc_dflt_font \ compile-with "uudecode < ${SRCTOP}/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < ${SRCTOP}/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < ${SRCTOP}/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \ no-obj no-implicit-rule before-depend \ clean "font.h ${SC_DFLT_FONT}-8x14 ${SC_DFLT_FONT}-8x16 ${SC_DFLT_FONT}-8x8" snd_fxdiv_gen.h optional sound \ dependency "$S/tools/sound/snd_fxdiv_gen.awk" \ compile-with "${AWK} -f $S/tools/sound/snd_fxdiv_gen.awk -- > snd_fxdiv_gen.h" \ no-obj no-implicit-rule before-depend \ clean "snd_fxdiv_gen.h" miidevs.h optional miibus | mii \ dependency "$S/tools/miidevs2h.awk $S/dev/mii/miidevs" \ compile-with "${AWK} -f $S/tools/miidevs2h.awk $S/dev/mii/miidevs" \ no-obj no-implicit-rule before-depend \ clean "miidevs.h" kbdmuxmap.h optional kbdmux_dflt_keymap \ compile-with "${KEYMAP} -L ${KBDMUX_DFLT_KEYMAP} | ${KEYMAP_FIX} > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "kbdmuxmap.h" teken_state.h optional sc | vt \ dependency "$S/teken/gensequences $S/teken/sequences" \ compile-with "${AWK} -f $S/teken/gensequences $S/teken/sequences > teken_state.h" \ no-obj no-implicit-rule before-depend \ clean "teken_state.h" ukbdmap.h optional ukbd_dflt_keymap \ compile-with "${KEYMAP} -L ${UKBD_DFLT_KEYMAP} | ${KEYMAP_FIX} > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "ukbdmap.h" usbdevs.h optional usb | hid \ dependency "$S/tools/usbdevs2h.awk $S/dev/usb/usbdevs" \ compile-with "${AWK} -f $S/tools/usbdevs2h.awk $S/dev/usb/usbdevs -h" \ no-obj no-implicit-rule before-depend \ clean "usbdevs.h" usbdevs_data.h optional usb \ dependency "$S/tools/usbdevs2h.awk $S/dev/usb/usbdevs" \ compile-with "${AWK} -f $S/tools/usbdevs2h.awk $S/dev/usb/usbdevs -d" \ no-obj no-implicit-rule before-depend \ clean "usbdevs_data.h" sdiodevs.h optional mmccam \ dependency "$S/tools/sdiodevs2h.awk $S/dev/sdio/sdiodevs" \ compile-with "${AWK} -f $S/tools/sdiodevs2h.awk $S/dev/sdio/sdiodevs -h" \ no-obj no-implicit-rule before-depend \ clean "sdiodevs.h" sdiodevs_data.h optional mmccam \ dependency "$S/tools/sdiodevs2h.awk $S/dev/sdio/sdiodevs" \ compile-with "${AWK} -f $S/tools/sdiodevs2h.awk $S/dev/sdio/sdiodevs -d" \ no-obj no-implicit-rule before-depend \ clean "sdiodevs_data.h" cam/cam.c optional scbus cam/cam_compat.c optional scbus cam/cam_iosched.c optional scbus cam/cam_periph.c optional scbus cam/cam_queue.c optional scbus cam/cam_sim.c optional scbus cam/cam_xpt.c optional scbus cam/ata/ata_all.c optional scbus cam/ata/ata_xpt.c optional scbus cam/ata/ata_pmp.c optional scbus cam/nvme/nvme_all.c optional scbus cam/nvme/nvme_da.c optional nda | da cam/nvme/nvme_xpt.c optional scbus cam/scsi/scsi_xpt.c optional scbus cam/scsi/scsi_all.c optional scbus cam/scsi/scsi_cd.c optional cd cam/scsi/scsi_ch.c optional ch cam/ata/ata_da.c optional ada | da cam/ctl/ctl.c optional ctl cam/ctl/ctl_backend.c optional ctl cam/ctl/ctl_backend_block.c optional ctl cam/ctl/ctl_backend_ramdisk.c optional ctl cam/ctl/ctl_cmd_table.c optional ctl cam/ctl/ctl_frontend.c optional ctl cam/ctl/ctl_frontend_cam_sim.c optional ctl cam/ctl/ctl_frontend_ioctl.c optional ctl cam/ctl/ctl_frontend_iscsi.c optional ctl cfiscsi cam/ctl/ctl_ha.c optional ctl cam/ctl/ctl_scsi_all.c optional ctl cam/ctl/ctl_tpc.c optional ctl cam/ctl/ctl_tpc_local.c optional ctl cam/ctl/ctl_error.c optional ctl cam/ctl/ctl_util.c optional ctl cam/ctl/scsi_ctl.c optional ctl cam/mmc/mmc_xpt.c optional scbus mmccam cam/mmc/mmc_sim.c optional scbus mmccam cam/mmc/mmc_sim_if.m optional scbus mmccam cam/mmc/mmc_da.c optional scbus mmccam da cam/scsi/scsi_da.c optional da cam/scsi/scsi_pass.c optional pass cam/scsi/scsi_pt.c optional pt cam/scsi/scsi_sa.c optional sa cam/scsi/scsi_enc.c optional ses cam/scsi/scsi_enc_ses.c optional ses cam/scsi/scsi_enc_safte.c optional ses cam/scsi/scsi_sg.c optional sg cam/scsi/scsi_targ_bh.c optional targbh cam/scsi/scsi_target.c optional targ cam/scsi/smp_all.c optional scbus # shared between zfs and dtrace cddl/compat/opensolaris/kern/opensolaris.c optional dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_proc.c optional zfs | dtrace compile-with "${CDDL_C}" contrib/openzfs/module/os/freebsd/spl/spl_misc.c optional zfs | dtrace compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_cmn_err.c optional zfs | dtrace compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_taskq.c optional zfs | dtrace compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_kmem.c optional zfs | dtrace compile-with "${ZFS_C}" #zfs solaris portability layer contrib/openzfs/module/os/freebsd/spl/acl_common.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/callb.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/list.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_acl.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_dtrace.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_kstat.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_policy.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_string.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_sunddi.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_sysevent.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_uio.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_vfs.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_vm.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_zone.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_procfs_list.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/spl/spl_zlib.c optional zfs compile-with "${ZFS_C}" # zfs specific #zfs avl contrib/openzfs/module/avl/avl.c optional zfs compile-with "${ZFS_C}" # zfs lua support contrib/openzfs/module/lua/lapi.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lauxlib.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lbaselib.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lcode.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lcompat.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lcorolib.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lctype.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/ldebug.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/ldo.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lfunc.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lgc.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/llex.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lmem.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lobject.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lopcodes.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lparser.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lstate.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lstring.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lstrlib.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/ltable.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/ltablib.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/ltm.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lvm.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/lua/lzio.c optional zfs compile-with "${ZFS_C}" # zfs nvpair support contrib/openzfs/module/nvpair/fnvpair.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/nvpair/nvpair.c optional zfs compile-with "${ZFS_RPC_C}" contrib/openzfs/module/nvpair/nvpair_alloc_fixed.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/nvpair/nvpair_alloc_spl.c optional zfs compile-with "${ZFS_C}" #zfs platform compatibility code contrib/openzfs/module/os/freebsd/zfs/abd_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/arc_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/crypto_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/dmu_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/event_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/hkdf.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/kmod_core.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/spa_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/sysctl_os.c optional zfs compile-with "${ZFS_C} -include $S/modules/zfs/zfs_config.h" contrib/openzfs/module/os/freebsd/zfs/vdev_file.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/vdev_label_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/vdev_geom.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_acl.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_debug.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_file_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_compat.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_ioctl_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_racct.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zio_crypt.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/os/freebsd/zfs/zvol_os.c optional zfs compile-with "${ZFS_C}" #zfs unicode support contrib/openzfs/module/unicode/uconv.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/unicode/u8_textprep.c optional zfs compile-with "${ZFS_C}" #zfs checksums / zcommon contrib/openzfs/module/zcommon/cityhash.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfeature_common.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_comutil.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_deleg.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_fletcher.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_fletcher_superscalar.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_fletcher_superscalar4.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_namecheck.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_prop.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zpool_prop.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zprop_common.c optional zfs compile-with "${ZFS_C}" # zfs edon-r hash support contrib/openzfs/module/icp/algs/edonr/edonr.c optional zfs compile-with "${ZFS_C}" # zfs blake3 hash support contrib/openzfs/module/icp/algs/blake3/blake3.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/icp/algs/blake3/blake3_generic.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/icp/algs/blake3/blake3_impl.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/icp/algs/blake3/blake3_x86-64.c optional zfs compile-with "${ZFS_C}" #zfs core common code contrib/openzfs/module/zfs/abd.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/aggsum.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/arc.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/blake3_zfs.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/blkptr.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/bplist.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/bpobj.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/bptree.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/btree.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/bqueue.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dbuf.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dbuf_stats.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dataset_kstats.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/ddt.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/ddt_zap.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_diff.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_object.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_objset.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_recv.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_redact.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_send.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_traverse.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_tx.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dmu_zfetch.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dnode.c optional zfs compile-with "${ZFS_C} ${NO_WUNUSED_BUT_SET_VARIABLE}" \ warning "kernel contains CDDL licensed ZFS filesystem" contrib/openzfs/module/zfs/dnode_sync.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_bookmark.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_crypt.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_dataset.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_deadlist.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_deleg.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_destroy.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_dir.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_pool.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_prop.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_scan.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_synctask.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/dsl_userhold.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/edonr_zfs.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/fm.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/gzip.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/lzjb.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/lz4.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/lz4_zfs.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/metaslab.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/mmp.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/multilist.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/objlist.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/pathname.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/range_tree.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/refcount.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/rrwlock.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/sa.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/sha256.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/skein_zfs.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_checkpoint.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_config.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_errlog.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_history.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_log_spacemap.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_misc.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/spa_stats.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/space_map.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/space_reftree.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/txg.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/uberblock.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/unique.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_cache.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_draid.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_draid_rand.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_indirect.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_indirect_births.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_indirect_mapping.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_initialize.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_label.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_mirror.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_missing.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_queue.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_raidz.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_raidz_math.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_raidz_math_scalar.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_rebuild.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_removal.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_root.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/vdev_trim.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zap.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zap_leaf.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zap_micro.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zcp.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zcp_get.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zcp_global.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zcp_iter.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zcp_set.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zcp_synctask.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfeature.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_byteswap.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_chksum.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_fm.c optional zfs compile-with "${ZFS_C} ${NO_WUNUSED_BUT_SET_VARIABLE}" contrib/openzfs/module/zfs/zfs_fuid.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_ioctl.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_log.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_onexit.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_quota.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_ratelimit.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_replay.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_rlock.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_sa.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zfs_vnops.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zstd/zfs_zstd.c optional zfs zstdio compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zil.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zio.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zio_checksum.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zio_compress.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zio_inject.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zle.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zrlock.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zthr.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zfs/zvol.c optional zfs compile-with "${ZFS_C}" # dtrace specific cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c optional dtrace compile-with "${DTRACE_C}" \ warning "kernel contains CDDL licensed DTRACE" cddl/contrib/opensolaris/uts/common/dtrace/dtrace_xoroshiro128_plus.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/dtmalloc/dtmalloc.c optional dtmalloc | dtraceall compile-with "${CDDL_C}" cddl/dev/profile/profile.c optional dtrace_profile | dtraceall compile-with "${CDDL_C}" cddl/dev/sdt/sdt.c optional dtrace_sdt | dtraceall compile-with "${CDDL_C}" cddl/dev/fbt/fbt.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" cddl/dev/systrace/systrace.c optional dtrace_systrace | dtraceall compile-with "${CDDL_C}" cddl/dev/prototype.c optional dtrace_prototype | dtraceall compile-with "${CDDL_C}" fs/nfsclient/nfs_clkdtrace.c optional dtnfscl nfscl | dtraceall nfscl compile-with "${CDDL_C}" compat/freebsd32/freebsd32_abort2.c optional compat_freebsd32 compat/freebsd32/freebsd32_capability.c optional compat_freebsd32 compat/freebsd32/freebsd32_ioctl.c optional compat_freebsd32 compat/freebsd32/freebsd32_misc.c optional compat_freebsd32 compat/freebsd32/freebsd32_syscalls.c optional compat_freebsd32 compat/freebsd32/freebsd32_sysent.c optional compat_freebsd32 contrib/ck/src/ck_array.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_centralized.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_combining.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_dissemination.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_mcs.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_tournament.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_epoch.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_hp.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_hs.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_ht.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_rhs.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/dev/acpica/common/ahids.c optional acpi acpi_debug contrib/dev/acpica/common/ahuuids.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbcmds.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbconvert.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbdisply.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbexec.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbhistry.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbinput.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbmethod.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbnames.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbobject.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbstats.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbtest.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbutils.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbxface.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmbuffer.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmcstyle.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmdeferred.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmnames.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmopcode.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrc.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrcl.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrcl2.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrcs.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmutils.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmwalk.c optional acpi acpi_debug contrib/dev/acpica/components/dispatcher/dsargs.c optional acpi contrib/dev/acpica/components/dispatcher/dscontrol.c optional acpi contrib/dev/acpica/components/dispatcher/dsdebug.c optional acpi contrib/dev/acpica/components/dispatcher/dsfield.c optional acpi contrib/dev/acpica/components/dispatcher/dsinit.c optional acpi contrib/dev/acpica/components/dispatcher/dsmethod.c optional acpi contrib/dev/acpica/components/dispatcher/dsmthdat.c optional acpi contrib/dev/acpica/components/dispatcher/dsobject.c optional acpi contrib/dev/acpica/components/dispatcher/dsopcode.c optional acpi contrib/dev/acpica/components/dispatcher/dspkginit.c optional acpi contrib/dev/acpica/components/dispatcher/dsutils.c optional acpi contrib/dev/acpica/components/dispatcher/dswexec.c optional acpi contrib/dev/acpica/components/dispatcher/dswload.c optional acpi contrib/dev/acpica/components/dispatcher/dswload2.c optional acpi contrib/dev/acpica/components/dispatcher/dswscope.c optional acpi contrib/dev/acpica/components/dispatcher/dswstate.c optional acpi contrib/dev/acpica/components/events/evevent.c optional acpi contrib/dev/acpica/components/events/evglock.c optional acpi contrib/dev/acpica/components/events/evgpe.c optional acpi contrib/dev/acpica/components/events/evgpeblk.c optional acpi contrib/dev/acpica/components/events/evgpeinit.c optional acpi contrib/dev/acpica/components/events/evgpeutil.c optional acpi contrib/dev/acpica/components/events/evhandler.c optional acpi contrib/dev/acpica/components/events/evmisc.c optional acpi contrib/dev/acpica/components/events/evregion.c optional acpi contrib/dev/acpica/components/events/evrgnini.c optional acpi contrib/dev/acpica/components/events/evsci.c optional acpi contrib/dev/acpica/components/events/evxface.c optional acpi contrib/dev/acpica/components/events/evxfevnt.c optional acpi contrib/dev/acpica/components/events/evxfgpe.c optional acpi contrib/dev/acpica/components/events/evxfregn.c optional acpi contrib/dev/acpica/components/executer/exconcat.c optional acpi contrib/dev/acpica/components/executer/exconfig.c optional acpi contrib/dev/acpica/components/executer/exconvrt.c optional acpi contrib/dev/acpica/components/executer/excreate.c optional acpi contrib/dev/acpica/components/executer/exdebug.c optional acpi contrib/dev/acpica/components/executer/exdump.c optional acpi contrib/dev/acpica/components/executer/exfield.c optional acpi contrib/dev/acpica/components/executer/exfldio.c optional acpi contrib/dev/acpica/components/executer/exmisc.c optional acpi contrib/dev/acpica/components/executer/exmutex.c optional acpi contrib/dev/acpica/components/executer/exnames.c optional acpi contrib/dev/acpica/components/executer/exoparg1.c optional acpi contrib/dev/acpica/components/executer/exoparg2.c optional acpi contrib/dev/acpica/components/executer/exoparg3.c optional acpi contrib/dev/acpica/components/executer/exoparg6.c optional acpi contrib/dev/acpica/components/executer/exprep.c optional acpi contrib/dev/acpica/components/executer/exregion.c optional acpi contrib/dev/acpica/components/executer/exresnte.c optional acpi contrib/dev/acpica/components/executer/exresolv.c optional acpi contrib/dev/acpica/components/executer/exresop.c optional acpi contrib/dev/acpica/components/executer/exserial.c optional acpi contrib/dev/acpica/components/executer/exstore.c optional acpi contrib/dev/acpica/components/executer/exstoren.c optional acpi contrib/dev/acpica/components/executer/exstorob.c optional acpi contrib/dev/acpica/components/executer/exsystem.c optional acpi contrib/dev/acpica/components/executer/extrace.c optional acpi contrib/dev/acpica/components/executer/exutils.c optional acpi contrib/dev/acpica/components/hardware/hwacpi.c optional acpi contrib/dev/acpica/components/hardware/hwesleep.c optional acpi contrib/dev/acpica/components/hardware/hwgpe.c optional acpi contrib/dev/acpica/components/hardware/hwpci.c optional acpi contrib/dev/acpica/components/hardware/hwregs.c optional acpi contrib/dev/acpica/components/hardware/hwsleep.c optional acpi contrib/dev/acpica/components/hardware/hwtimer.c optional acpi contrib/dev/acpica/components/hardware/hwvalid.c optional acpi contrib/dev/acpica/components/hardware/hwxface.c optional acpi contrib/dev/acpica/components/hardware/hwxfsleep.c optional acpi contrib/dev/acpica/components/namespace/nsaccess.c optional acpi \ compile-with "${NORMAL_C} ${NO_WUNUSED_BUT_SET_VARIABLE}" contrib/dev/acpica/components/namespace/nsalloc.c optional acpi contrib/dev/acpica/components/namespace/nsarguments.c optional acpi contrib/dev/acpica/components/namespace/nsconvert.c optional acpi contrib/dev/acpica/components/namespace/nsdump.c optional acpi contrib/dev/acpica/components/namespace/nseval.c optional acpi contrib/dev/acpica/components/namespace/nsinit.c optional acpi contrib/dev/acpica/components/namespace/nsload.c optional acpi contrib/dev/acpica/components/namespace/nsnames.c optional acpi contrib/dev/acpica/components/namespace/nsobject.c optional acpi contrib/dev/acpica/components/namespace/nsparse.c optional acpi contrib/dev/acpica/components/namespace/nspredef.c optional acpi contrib/dev/acpica/components/namespace/nsprepkg.c optional acpi contrib/dev/acpica/components/namespace/nsrepair.c optional acpi contrib/dev/acpica/components/namespace/nsrepair2.c optional acpi contrib/dev/acpica/components/namespace/nssearch.c optional acpi contrib/dev/acpica/components/namespace/nsutils.c optional acpi contrib/dev/acpica/components/namespace/nswalk.c optional acpi contrib/dev/acpica/components/namespace/nsxfeval.c optional acpi contrib/dev/acpica/components/namespace/nsxfname.c optional acpi contrib/dev/acpica/components/namespace/nsxfobj.c optional acpi contrib/dev/acpica/components/parser/psargs.c optional acpi contrib/dev/acpica/components/parser/psloop.c optional acpi contrib/dev/acpica/components/parser/psobject.c optional acpi contrib/dev/acpica/components/parser/psopcode.c optional acpi contrib/dev/acpica/components/parser/psopinfo.c optional acpi contrib/dev/acpica/components/parser/psparse.c optional acpi contrib/dev/acpica/components/parser/psscope.c optional acpi contrib/dev/acpica/components/parser/pstree.c optional acpi contrib/dev/acpica/components/parser/psutils.c optional acpi contrib/dev/acpica/components/parser/pswalk.c optional acpi contrib/dev/acpica/components/parser/psxface.c optional acpi contrib/dev/acpica/components/resources/rsaddr.c optional acpi contrib/dev/acpica/components/resources/rscalc.c optional acpi contrib/dev/acpica/components/resources/rscreate.c optional acpi contrib/dev/acpica/components/resources/rsdump.c optional acpi acpi_debug contrib/dev/acpica/components/resources/rsdumpinfo.c optional acpi contrib/dev/acpica/components/resources/rsinfo.c optional acpi contrib/dev/acpica/components/resources/rsio.c optional acpi contrib/dev/acpica/components/resources/rsirq.c optional acpi contrib/dev/acpica/components/resources/rslist.c optional acpi contrib/dev/acpica/components/resources/rsmemory.c optional acpi contrib/dev/acpica/components/resources/rsmisc.c optional acpi contrib/dev/acpica/components/resources/rsserial.c optional acpi contrib/dev/acpica/components/resources/rsutils.c optional acpi contrib/dev/acpica/components/resources/rsxface.c optional acpi contrib/dev/acpica/components/tables/tbdata.c optional acpi contrib/dev/acpica/components/tables/tbfadt.c optional acpi contrib/dev/acpica/components/tables/tbfind.c optional acpi contrib/dev/acpica/components/tables/tbinstal.c optional acpi contrib/dev/acpica/components/tables/tbprint.c optional acpi contrib/dev/acpica/components/tables/tbutils.c optional acpi contrib/dev/acpica/components/tables/tbxface.c optional acpi contrib/dev/acpica/components/tables/tbxfload.c optional acpi contrib/dev/acpica/components/tables/tbxfroot.c optional acpi contrib/dev/acpica/components/utilities/utaddress.c optional acpi contrib/dev/acpica/components/utilities/utalloc.c optional acpi contrib/dev/acpica/components/utilities/utascii.c optional acpi contrib/dev/acpica/components/utilities/utbuffer.c optional acpi contrib/dev/acpica/components/utilities/utcache.c optional acpi contrib/dev/acpica/components/utilities/utcksum.c optional acpi contrib/dev/acpica/components/utilities/utcopy.c optional acpi contrib/dev/acpica/components/utilities/utdebug.c optional acpi contrib/dev/acpica/components/utilities/utdecode.c optional acpi contrib/dev/acpica/components/utilities/utdelete.c optional acpi contrib/dev/acpica/components/utilities/uterror.c optional acpi contrib/dev/acpica/components/utilities/uteval.c optional acpi contrib/dev/acpica/components/utilities/utexcep.c optional acpi contrib/dev/acpica/components/utilities/utglobal.c optional acpi contrib/dev/acpica/components/utilities/uthex.c optional acpi contrib/dev/acpica/components/utilities/utids.c optional acpi contrib/dev/acpica/components/utilities/utinit.c optional acpi contrib/dev/acpica/components/utilities/utlock.c optional acpi contrib/dev/acpica/components/utilities/utmath.c optional acpi contrib/dev/acpica/components/utilities/utmisc.c optional acpi contrib/dev/acpica/components/utilities/utmutex.c optional acpi contrib/dev/acpica/components/utilities/utnonansi.c optional acpi contrib/dev/acpica/components/utilities/utobject.c optional acpi contrib/dev/acpica/components/utilities/utosi.c optional acpi contrib/dev/acpica/components/utilities/utownerid.c optional acpi contrib/dev/acpica/components/utilities/utpredef.c optional acpi contrib/dev/acpica/components/utilities/utresdecode.c optional acpi acpi_debug contrib/dev/acpica/components/utilities/utresrc.c optional acpi contrib/dev/acpica/components/utilities/utstate.c optional acpi contrib/dev/acpica/components/utilities/utstring.c optional acpi contrib/dev/acpica/components/utilities/utstrsuppt.c optional acpi contrib/dev/acpica/components/utilities/utstrtoul64.c optional acpi contrib/dev/acpica/components/utilities/utuuid.c optional acpi acpi_debug contrib/dev/acpica/components/utilities/utxface.c optional acpi contrib/dev/acpica/components/utilities/utxferror.c optional acpi contrib/dev/acpica/components/utilities/utxfinit.c optional acpi contrib/dev/acpica/os_specific/service_layers/osgendbg.c optional acpi acpi_debug netpfil/ipfilter/netinet/fil.c optional ipfilter inet \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_auth.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_fil_freebsd.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_frag.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_log.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_nat.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_proxy.c optional ipfilter inet \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_state.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_lookup.c optional ipfilter inet \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN} -Wno-unused -Wno-error -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_pool.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_htable.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter ${NO_WTAUTOLOGICAL_POINTER_COMPARE}" netpfil/ipfilter/netinet/ip_sync.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/mlfk_ipl.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_nat6.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_rules.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_scan.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/ip_dstlist.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/netpfil/ipfilter" netpfil/ipfilter/netinet/radix_ipf.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/netpfil/ipfilter" contrib/libfdt/fdt.c optional fdt contrib/libfdt/fdt_ro.c optional fdt contrib/libfdt/fdt_rw.c optional fdt contrib/libfdt/fdt_strerror.c optional fdt contrib/libfdt/fdt_sw.c optional fdt contrib/libfdt/fdt_wip.c optional fdt contrib/libnv/cnvlist.c standard contrib/libnv/dnvlist.c standard contrib/libnv/nvlist.c standard contrib/libnv/bsd_nvpair.c standard contrib/ngatm/netnatm/api/cc_conn.c optional ngatm_ccatm \ compile-with "${NORMAL_C_NOWERROR} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_data.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_dump.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_port.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_sig.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_user.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/unisap.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/misc/straddr.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/misc/unimsg_common.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/msg/traffic.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/msg/uni_ie.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/msg/uni_msg.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/saal/saal_sscfu.c optional ngatm_sscfu \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/saal/saal_sscop.c optional ngatm_sscop \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_call.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_coord.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_party.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_print.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_reset.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_uni.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_unimsgcpy.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_verify.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" # xz dev/xz/xz_mod.c optional xz \ compile-with "${NORMAL_C} -DXZ_USE_CRC64 -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_crc32.c optional xz \ compile-with "${NORMAL_C} -DXZ_USE_CRC64 -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_crc64.c optional xz \ compile-with "${NORMAL_C} -DXZ_USE_CRC64 -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_dec_bcj.c optional xz \ compile-with "${NORMAL_C} -DXZ_USE_CRC64 -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_dec_lzma2.c optional xz \ compile-with "${NORMAL_C} -DXZ_USE_CRC64 -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_dec_stream.c optional xz \ compile-with "${NORMAL_C} -DXZ_USE_CRC64 -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" # Zstd contrib/zstd/lib/freebsd/zstd_kmalloc.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/zstd_common.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/fse_decompress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/entropy_common.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/error_private.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/xxhash.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_compress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_compress_literals.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_compress_sequences.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_compress_superblock.c optional zstdio compile-with "${ZSTD_C} ${NO_WUNUSED_BUT_SET_VARIABLE}" contrib/zstd/lib/compress/fse_compress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/hist.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/huf_compress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_double_fast.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_fast.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_lazy.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_ldm.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_opt.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/decompress/zstd_ddict.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/decompress/zstd_decompress.c optional zstdio compile-with ${ZSTD_C} # See comment in sys/conf/kern.pre.mk contrib/zstd/lib/decompress/zstd_decompress_block.c optional zstdio \ compile-with "${ZSTD_C} ${ZSTD_DECOMPRESS_BLOCK_FLAGS}" contrib/zstd/lib/decompress/huf_decompress.c optional zstdio compile-with "${ZSTD_C} ${NO_WBITWISE_INSTEAD_OF_LOGICAL}" # Blake 2 contrib/libb2/blake2b-ref.c optional crypto | !random_loadable random_fenestrasx \ compile-with "${NORMAL_C} -I$S/crypto/blake2 -Wno-cast-qual -DSUFFIX=_ref -Wno-unused-function" contrib/libb2/blake2s-ref.c optional crypto \ compile-with "${NORMAL_C} -I$S/crypto/blake2 -Wno-cast-qual -DSUFFIX=_ref -Wno-unused-function" crypto/blake2/blake2-sw.c optional crypto \ compile-with "${NORMAL_C} -I$S/crypto/blake2 -Wno-cast-qual" crypto/camellia/camellia.c optional crypto crypto/camellia/camellia-api.c optional crypto crypto/chacha20/chacha.c standard crypto/chacha20/chacha-sw.c optional crypto crypto/chacha20_poly1305.c optional crypto crypto/curve25519.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" crypto/des/des_ecb.c optional netsmb crypto/des/des_setkey.c optional netsmb crypto/openssl/ossl.c optional ossl crypto/openssl/ossl_aes.c optional ossl crypto/openssl/ossl_chacha20.c optional ossl crypto/openssl/ossl_poly1305.c optional ossl crypto/openssl/ossl_sha1.c optional ossl crypto/openssl/ossl_sha256.c optional ossl crypto/openssl/ossl_sha512.c optional ossl crypto/rc4/rc4.c optional netgraph_mppc_encryption crypto/rijndael/rijndael-alg-fst.c optional crypto | ekcd | geom_bde | \ !random_loadable | wlan_ccmp crypto/rijndael/rijndael-api-fst.c optional ekcd | geom_bde | !random_loadable crypto/rijndael/rijndael-api.c optional crypto | wlan_ccmp crypto/sha1.c optional carp | crypto | ether | \ netgraph_mppc_encryption | sctp crypto/sha2/sha256c.c optional crypto | ekcd | geom_bde | \ !random_loadable | sctp | zfs crypto/sha2/sha512c.c optional crypto | geom_bde | zfs crypto/skein/skein.c optional crypto | zfs crypto/skein/skein_block.c optional crypto | zfs crypto/siphash/siphash.c optional inet | inet6 | wg crypto/siphash/siphash_test.c optional inet | inet6 | wg ddb/db_access.c optional ddb ddb/db_break.c optional ddb ddb/db_capture.c optional ddb ddb/db_command.c optional ddb ddb/db_examine.c optional ddb ddb/db_expr.c optional ddb ddb/db_input.c optional ddb ddb/db_lex.c optional ddb ddb/db_main.c optional ddb ddb/db_output.c optional ddb ddb/db_print.c optional ddb ddb/db_ps.c optional ddb ddb/db_run.c optional ddb ddb/db_script.c optional ddb ddb/db_sym.c optional ddb ddb/db_thread.c optional ddb ddb/db_textdump.c optional ddb ddb/db_variables.c optional ddb ddb/db_watch.c optional ddb ddb/db_write_cmd.c optional ddb dev/aac/aac.c optional aac dev/aac/aac_cam.c optional aacp aac dev/aac/aac_debug.c optional aac dev/aac/aac_disk.c optional aac dev/aac/aac_pci.c optional aac pci dev/aacraid/aacraid.c optional aacraid dev/aacraid/aacraid_cam.c optional aacraid scbus dev/aacraid/aacraid_debug.c optional aacraid dev/aacraid/aacraid_pci.c optional aacraid pci dev/acpi_support/acpi_wmi.c optional acpi_wmi acpi dev/acpi_support/acpi_asus.c optional acpi_asus acpi dev/acpi_support/acpi_asus_wmi.c optional acpi_asus_wmi acpi dev/acpi_support/acpi_fujitsu.c optional acpi_fujitsu acpi dev/acpi_support/acpi_hp.c optional acpi_hp acpi dev/acpi_support/acpi_ibm.c optional acpi_ibm acpi dev/acpi_support/acpi_panasonic.c optional acpi_panasonic acpi dev/acpi_support/acpi_sony.c optional acpi_sony acpi dev/acpi_support/acpi_toshiba.c optional acpi_toshiba acpi dev/acpi_support/atk0110.c optional aibs acpi dev/acpica/Osd/OsdDebug.c optional acpi dev/acpica/Osd/OsdHardware.c optional acpi dev/acpica/Osd/OsdInterrupt.c optional acpi dev/acpica/Osd/OsdMemory.c optional acpi dev/acpica/Osd/OsdSchedule.c optional acpi dev/acpica/Osd/OsdStream.c optional acpi dev/acpica/Osd/OsdSynch.c optional acpi dev/acpica/Osd/OsdTable.c optional acpi dev/acpica/acpi.c optional acpi dev/acpica/acpi_acad.c optional acpi dev/acpica/acpi_apei.c optional acpi dev/acpica/acpi_battery.c optional acpi dev/acpica/acpi_button.c optional acpi dev/acpica/acpi_cmbat.c optional acpi dev/acpica/acpi_cpu.c optional acpi dev/acpica/acpi_ec.c optional acpi dev/acpica/acpi_ged.c optional acpi_ged acpi dev/acpica/acpi_isab.c optional acpi isa dev/acpica/acpi_lid.c optional acpi dev/acpica/acpi_package.c optional acpi dev/acpica/acpi_perf.c optional acpi dev/acpica/acpi_powerres.c optional acpi dev/acpica/acpi_quirk.c optional acpi dev/acpica/acpi_resource.c optional acpi dev/acpica/acpi_container.c optional acpi dev/acpica/acpi_smbat.c optional acpi dev/acpica/acpi_thermal.c optional acpi dev/acpica/acpi_throttle.c optional acpi dev/acpica/acpi_video.c optional acpi_video acpi dev/acpica/acpi_dock.c optional acpi_dock acpi dev/adlink/adlink.c optional adlink dev/ae/if_ae.c optional ae pci dev/age/if_age.c optional age pci dev/agp/agp.c optional agp pci dev/agp/agp_if.m optional agp pci dev/ahci/ahci.c optional ahci dev/ahci/ahciem.c optional ahci dev/ahci/ahci_pci.c optional ahci pci dev/aic7xxx/ahc_isa.c optional ahc isa dev/aic7xxx/ahc_pci.c optional ahc pci \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" dev/aic7xxx/ahd_pci.c optional ahd pci \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" dev/aic7xxx/aic7770.c optional ahc dev/aic7xxx/aic79xx.c optional ahd pci dev/aic7xxx/aic79xx_osm.c optional ahd pci dev/aic7xxx/aic79xx_pci.c optional ahd pci dev/aic7xxx/aic79xx_reg_print.c optional ahd pci ahd_reg_pretty_print dev/aic7xxx/aic7xxx.c optional ahc dev/aic7xxx/aic7xxx_93cx6.c optional ahc dev/aic7xxx/aic7xxx_osm.c optional ahc dev/aic7xxx/aic7xxx_pci.c optional ahc pci dev/aic7xxx/aic7xxx_reg_print.c optional ahc ahc_reg_pretty_print dev/al_eth/al_eth.c optional al_eth fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" dev/al_eth/al_init_eth_lm.c optional al_eth fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" dev/al_eth/al_init_eth_kr.c optional al_eth fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_iofic.c optional al_iofic \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_serdes_25g.c optional al_serdes \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_serdes_hssp.c optional al_serdes \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_config.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_debug.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_iofic.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_main.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/al_serdes.c optional al_serdes \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/eth/al_hal_eth_kr.c optional al_eth \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" contrib/alpine-hal/eth/al_hal_eth_main.c optional al_eth \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" dev/alc/if_alc.c optional alc pci dev/ale/if_ale.c optional ale pci dev/alpm/alpm.c optional alpm pci dev/altera/avgen/altera_avgen.c optional altera_avgen dev/altera/avgen/altera_avgen_fdt.c optional altera_avgen fdt dev/altera/avgen/altera_avgen_nexus.c optional altera_avgen dev/altera/msgdma/msgdma.c optional altera_msgdma xdma dev/altera/sdcard/altera_sdcard.c optional altera_sdcard dev/altera/sdcard/altera_sdcard_disk.c optional altera_sdcard dev/altera/sdcard/altera_sdcard_io.c optional altera_sdcard dev/altera/sdcard/altera_sdcard_fdt.c optional altera_sdcard fdt dev/altera/sdcard/altera_sdcard_nexus.c optional altera_sdcard dev/altera/softdma/softdma.c optional altera_softdma xdma fdt dev/altera/pio/pio.c optional altera_pio dev/altera/pio/pio_if.m optional altera_pio dev/amdpm/amdpm.c optional amdpm pci | nfpm pci dev/amdsmb/amdsmb.c optional amdsmb pci # dev/ata/ata_if.m optional ata | atacore dev/ata/ata-all.c optional ata | atacore dev/ata/ata-dma.c optional ata | atacore dev/ata/ata-lowlevel.c optional ata | atacore dev/ata/ata-sata.c optional ata | atacore dev/ata/ata-isa.c optional ata isa | ataisa dev/ata/ata-pci.c optional ata pci | atapci dev/ata/chipsets/ata-acard.c optional ata pci | ataacard dev/ata/chipsets/ata-acerlabs.c optional ata pci | ataacerlabs dev/ata/chipsets/ata-amd.c optional ata pci | ataamd dev/ata/chipsets/ata-ati.c optional ata pci | ataati dev/ata/chipsets/ata-cenatek.c optional ata pci | atacenatek dev/ata/chipsets/ata-cypress.c optional ata pci | atacypress dev/ata/chipsets/ata-cyrix.c optional ata pci | atacyrix dev/ata/chipsets/ata-highpoint.c optional ata pci | atahighpoint dev/ata/chipsets/ata-intel.c optional ata pci | ataintel dev/ata/chipsets/ata-ite.c optional ata pci | ataite dev/ata/chipsets/ata-jmicron.c optional ata pci | atajmicron dev/ata/chipsets/ata-marvell.c optional ata pci | atamarvell dev/ata/chipsets/ata-micron.c optional ata pci | atamicron dev/ata/chipsets/ata-national.c optional ata pci | atanational dev/ata/chipsets/ata-netcell.c optional ata pci | atanetcell dev/ata/chipsets/ata-nvidia.c optional ata pci | atanvidia dev/ata/chipsets/ata-promise.c optional ata pci | atapromise dev/ata/chipsets/ata-serverworks.c optional ata pci | ataserverworks dev/ata/chipsets/ata-siliconimage.c optional ata pci | atasiliconimage | ataati dev/ata/chipsets/ata-sis.c optional ata pci | atasis dev/ata/chipsets/ata-via.c optional ata pci | atavia # dev/ath/if_ath_pci.c optional ath_pci pci \ compile-with "${ATH_C}" # dev/ath/if_ath_ahb.c optional ath_ahb \ compile-with "${ATH_C}" # dev/ath/if_ath.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_alq.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_beacon.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_btcoex.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_btcoex_mci.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_debug.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_descdma.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_keycache.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_ioctl.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_led.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_lna_div.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_tx.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_tx_edma.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_tx_ht.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_tdma.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_sysctl.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_rx.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_rx_edma.c optional ath \ compile-with "${ATH_C}" dev/ath/if_ath_spectral.c optional ath \ compile-with "${ATH_C}" dev/ath/ah_osdep.c optional ath \ compile-with "${ATH_C}" # dev/ath/ath_hal/ah.c optional ath \ compile-with "${ATH_C}" dev/ath/ath_hal/ah_eeprom_v1.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C}" dev/ath/ath_hal/ah_eeprom_v3.c optional ath_hal | ath_ar5211 | ath_ar5212 \ compile-with "${ATH_C}" dev/ath/ath_hal/ah_eeprom_v14.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \ compile-with "${ATH_C}" dev/ath/ath_hal/ah_eeprom_v4k.c \ optional ath_hal | ath_ar9285 \ compile-with "${ATH_C}" dev/ath/ath_hal/ah_eeprom_9287.c \ optional ath_hal | ath_ar9287 \ compile-with "${ATH_C}" dev/ath/ath_hal/ah_regdomain.c optional ath \ compile-with "${ATH_C} ${NO_WSHIFT_COUNT_NEGATIVE} ${NO_WSHIFT_COUNT_OVERFLOW}" # ar5210 dev/ath/ath_hal/ar5210/ar5210_attach.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_beacon.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_interrupts.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_keycache.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_misc.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_phy.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_power.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_recv.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_reset.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_xmit.c optional ath_hal | ath_ar5210 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar5211 dev/ath/ath_hal/ar5211/ar5211_attach.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_beacon.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_interrupts.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_keycache.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_misc.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_phy.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_power.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_recv.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_reset.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_xmit.c optional ath_hal | ath_ar5211 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar5212 dev/ath/ath_hal/ar5212/ar5212_ani.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_attach.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_beacon.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_eeprom.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_gpio.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_interrupts.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_keycache.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_misc.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_phy.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_power.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_recv.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_reset.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_rfgain.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_xmit.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar5416 (depends on ar5212) dev/ath/ath_hal/ar5416/ar5416_ani.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_attach.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_beacon.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_btcoex.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal_iq.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal_adcgain.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal_adcdc.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_eeprom.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_gpio.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_interrupts.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_keycache.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_misc.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_phy.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_power.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_radar.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_recv.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_reset.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_spectral.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_xmit.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar9130 (depends upon ar5416) - also requires AH_SUPPORT_AR9130 # # Since this is an embedded MAC SoC, there's no need to compile it into the # default HAL. dev/ath/ath_hal/ar9001/ar9130_attach.c optional ath_ar9130 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9001/ar9130_phy.c optional ath_ar9130 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9001/ar9130_eeprom.c optional ath_ar9130 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar9160 (depends on ar5416) dev/ath/ath_hal/ar9001/ar9160_attach.c optional ath_hal | ath_ar9160 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar9280 (depends on ar5416) dev/ath/ath_hal/ar9002/ar9280_attach.c optional ath_hal | ath_ar9280 | \ ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9280_olc.c optional ath_hal | ath_ar9280 | \ ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar9285 (depends on ar5416 and ar9280) dev/ath/ath_hal/ar9002/ar9285_attach.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_btcoex.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_reset.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_cal.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_phy.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_diversity.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar9287 (depends on ar5416) dev/ath/ath_hal/ar9002/ar9287_attach.c optional ath_hal | ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287_reset.c optional ath_hal | ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287_cal.c optional ath_hal | ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287_olc.c optional ath_hal | ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ar9300 contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_beacon.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal ${NO_WCONSTANT_CONVERSION}" contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_gpio.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_interrupts.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_keycache.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_mci.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_paprd.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_phy.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_power.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_radar.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_radio.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_recv.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_recv_ds.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal ${NO_WSOMETIMES_UNINITIALIZED} -Wno-unused-function" contrib/dev/ath/ath_hal/ar9300/ar9300_stub.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_spectral.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_timer.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_xmit.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_xmit_ds.c optional ath_hal | ath_ar9300 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" # rf backends dev/ath/ath_hal/ar5212/ar2316.c optional ath_rf2316 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar2317.c optional ath_rf2317 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar2413.c optional ath_hal | ath_rf2413 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar2425.c optional ath_hal | ath_rf2425 | ath_rf2417 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5111.c optional ath_hal | ath_rf5111 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5112.c optional ath_hal | ath_rf5112 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5413.c optional ath_hal | ath_rf5413 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar2133.c optional ath_hal | ath_ar5416 | \ ath_ar9130 | ath_ar9160 | ath_ar9280 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9280.c optional ath_hal | ath_ar9280 | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285.c optional ath_hal | ath_ar9285 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287.c optional ath_hal | ath_ar9287 \ compile-with "${ATH_C} -I$S/dev/ath/ath_hal" # ath rate control algorithms dev/ath/ath_rate/amrr/amrr.c optional ath_rate_amrr \ compile-with "${ATH_C}" dev/ath/ath_rate/onoe/onoe.c optional ath_rate_onoe \ compile-with "${ATH_C}" dev/ath/ath_rate/sample/sample.c optional ath_rate_sample \ compile-with "${ATH_C}" # ath DFS modules dev/ath/ath_dfs/null/dfs_null.c optional ath \ compile-with "${ATH_C}" # dev/backlight/backlight_if.m optional backlight | compat_linuxkpi dev/backlight/backlight.c optional backlight | compat_linuxkpi dev/bce/if_bce.c optional bce dev/bfe/if_bfe.c optional bfe dev/bge/if_bge.c optional bge dev/bhnd/bhnd.c optional bhnd dev/bhnd/bhnd_erom.c optional bhnd dev/bhnd/bhnd_erom_if.m optional bhnd dev/bhnd/bhnd_subr.c optional bhnd dev/bhnd/bhnd_bus_if.m optional bhnd dev/bhnd/bhndb/bhnd_bhndb.c optional bhndb bhnd dev/bhnd/bhndb/bhndb.c optional bhndb bhnd dev/bhnd/bhndb/bhndb_bus_if.m optional bhndb bhnd dev/bhnd/bhndb/bhndb_hwdata.c optional bhndb bhnd dev/bhnd/bhndb/bhndb_if.m optional bhndb bhnd dev/bhnd/bhndb/bhndb_pci.c optional bhndb_pci bhndb bhnd pci dev/bhnd/bhndb/bhndb_pci_hwdata.c optional bhndb_pci bhndb bhnd pci dev/bhnd/bhndb/bhndb_pci_sprom.c optional bhndb_pci bhndb bhnd pci dev/bhnd/bhndb/bhndb_subr.c optional bhndb bhnd dev/bhnd/bcma/bcma.c optional bcma bhnd dev/bhnd/bcma/bcma_bhndb.c optional bcma bhnd bhndb dev/bhnd/bcma/bcma_erom.c optional bcma bhnd dev/bhnd/bcma/bcma_subr.c optional bcma bhnd dev/bhnd/cores/chipc/bhnd_chipc_if.m optional bhnd dev/bhnd/cores/chipc/bhnd_sprom_chipc.c optional bhnd dev/bhnd/cores/chipc/bhnd_pmu_chipc.c optional bhnd dev/bhnd/cores/chipc/chipc.c optional bhnd dev/bhnd/cores/chipc/chipc_cfi.c optional bhnd cfi dev/bhnd/cores/chipc/chipc_gpio.c optional bhnd gpio dev/bhnd/cores/chipc/chipc_slicer.c optional bhnd cfi | bhnd spibus dev/bhnd/cores/chipc/chipc_spi.c optional bhnd spibus dev/bhnd/cores/chipc/chipc_subr.c optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_if.m optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_hostb_if.m optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_subr.c optional bhnd dev/bhnd/cores/pci/bhnd_pci.c optional bhnd pci dev/bhnd/cores/pci/bhnd_pci_hostb.c optional bhndb bhnd pci dev/bhnd/cores/pci/bhnd_pcib.c optional bhnd_pcib bhnd pci dev/bhnd/cores/pcie2/bhnd_pcie2.c optional bhnd pci dev/bhnd/cores/pcie2/bhnd_pcie2_hostb.c optional bhndb bhnd pci dev/bhnd/cores/pcie2/bhnd_pcie2b.c optional bhnd_pcie2b bhnd pci dev/bhnd/cores/pmu/bhnd_pmu.c optional bhnd dev/bhnd/cores/pmu/bhnd_pmu_core.c optional bhnd dev/bhnd/cores/pmu/bhnd_pmu_if.m optional bhnd dev/bhnd/cores/pmu/bhnd_pmu_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_bcm.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_bcmraw.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_btxt.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_sprom.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_sprom_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_tlv.c optional bhnd dev/bhnd/nvram/bhnd_nvram_if.m optional bhnd dev/bhnd/nvram/bhnd_nvram_io.c optional bhnd dev/bhnd/nvram/bhnd_nvram_iobuf.c optional bhnd dev/bhnd/nvram/bhnd_nvram_ioptr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_iores.c optional bhnd dev/bhnd/nvram/bhnd_nvram_plist.c optional bhnd dev/bhnd/nvram/bhnd_nvram_store.c optional bhnd dev/bhnd/nvram/bhnd_nvram_store_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value_fmts.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value_prf.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value_subr.c optional bhnd dev/bhnd/nvram/bhnd_sprom.c optional bhnd dev/bhnd/siba/siba.c optional siba bhnd dev/bhnd/siba/siba_bhndb.c optional siba bhnd bhndb dev/bhnd/siba/siba_erom.c optional siba bhnd dev/bhnd/siba/siba_subr.c optional siba bhnd # dev/bnxt/bnxt_hwrm.c optional bnxt iflib pci dev/bnxt/bnxt_mgmt.c optional bnxt iflib pci dev/bnxt/bnxt_sysctl.c optional bnxt iflib pci dev/bnxt/bnxt_txrx.c optional bnxt iflib pci dev/bnxt/if_bnxt.c optional bnxt iflib pci dev/bwi/bwimac.c optional bwi dev/bwi/bwiphy.c optional bwi dev/bwi/bwirf.c optional bwi dev/bwi/if_bwi.c optional bwi dev/bwi/if_bwi_pci.c optional bwi pci dev/bwn/if_bwn.c optional bwn bhnd dev/bwn/if_bwn_pci.c optional bwn pci bhnd bhndb bhndb_pci dev/bwn/if_bwn_phy_common.c optional bwn bhnd dev/bwn/if_bwn_phy_g.c optional bwn bhnd dev/bwn/if_bwn_phy_lp.c optional bwn bhnd dev/bwn/if_bwn_phy_n.c optional bwn bhnd dev/bwn/if_bwn_util.c optional bwn bhnd dev/cadence/if_cgem.c optional cgem fdt dev/cardbus/card_if.m standard dev/cardbus/cardbus.c optional cardbus dev/cardbus/cardbus_cis.c optional cardbus dev/cardbus/cardbus_device.c optional cardbus dev/cardbus/power_if.m standard dev/cas/if_cas.c optional cas dev/cfi/cfi_bus_fdt.c optional cfi fdt dev/cfi/cfi_bus_nexus.c optional cfi dev/cfi/cfi_core.c optional cfi dev/cfi/cfi_dev.c optional cfi dev/cfi/cfi_disk.c optional cfid dev/chromebook_platform/chromebook_platform.c optional chromebook_platform dev/ciss/ciss.c optional ciss dev/cpufreq/ichss.c optional cpufreq pci dev/cxgb/cxgb_main.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/cxgb_sge.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_mc5.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_vsc7323.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_vsc8211.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_ael1002.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_aq100x.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_mv88e1xxx.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_xgmac.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_t3_hw.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_tn1010.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/sys/uipc_mvec.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/cxgb_t3fw.c optional cxgb cxgb_t3fw \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgbe/t4_clip.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_filter.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_if.m optional cxgbe pci dev/cxgbe/t4_iov.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_mp_ring.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_main.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_netmap.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_sched.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_sge.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_smt.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_l2t.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_tracer.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_vf.c optional cxgbev pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/common/t4_hw.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/common/t4vf_hw.c optional cxgbev pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/crypto/t6_kern_tls.c optional cxgbe pci kern_tls \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/crypto/t4_keyctx.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/cudbg_common.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/cudbg_flash_utils.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/cudbg_lib.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/cudbg_wtp.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/fastlz.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/fastlz_api.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" t4fw_cfg.c optional cxgbe \ compile-with "${AWK} -f $S/tools/fw_stub.awk t4fw_cfg.fw:t4fw_cfg t4fw_cfg_uwire.fw:t4fw_cfg_uwire t4fw.fw:t4fw -mt4fw_cfg -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "t4fw_cfg.c" t4fw_cfg.fwo optional cxgbe \ dependency "t4fw_cfg.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t4fw_cfg.fwo" t4fw_cfg.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t4fw_cfg.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t4fw_cfg.fw" t4fw_cfg_uwire.fwo optional cxgbe \ dependency "t4fw_cfg_uwire.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t4fw_cfg_uwire.fwo" t4fw_cfg_uwire.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t4fw_cfg_uwire.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t4fw_cfg_uwire.fw" t4fw.fwo optional cxgbe \ dependency "t4fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t4fw.fwo" t4fw.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t4fw-1.27.0.0.bin" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t4fw.fw" t5fw_cfg.c optional cxgbe \ compile-with "${AWK} -f $S/tools/fw_stub.awk t5fw_cfg.fw:t5fw_cfg t5fw_cfg_uwire.fw:t5fw_cfg_uwire t5fw.fw:t5fw -mt5fw_cfg -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "t5fw_cfg.c" t5fw_cfg.fwo optional cxgbe \ dependency "t5fw_cfg.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t5fw_cfg.fwo" t5fw_cfg.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t5fw_cfg.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t5fw_cfg.fw" t5fw_cfg_uwire.fwo optional cxgbe \ dependency "t5fw_cfg_uwire.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t5fw_cfg_uwire.fwo" t5fw_cfg_uwire.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t5fw_cfg_uwire.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t5fw_cfg_uwire.fw" t5fw.fwo optional cxgbe \ dependency "t5fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t5fw.fwo" t5fw.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t5fw-1.27.0.0.bin" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t5fw.fw" t6fw_cfg.c optional cxgbe \ compile-with "${AWK} -f $S/tools/fw_stub.awk t6fw_cfg.fw:t6fw_cfg t6fw_cfg_uwire.fw:t6fw_cfg_uwire t6fw.fw:t6fw -mt6fw_cfg -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "t6fw_cfg.c" t6fw_cfg.fwo optional cxgbe \ dependency "t6fw_cfg.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t6fw_cfg.fwo" t6fw_cfg.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t6fw_cfg.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t6fw_cfg.fw" t6fw_cfg_uwire.fwo optional cxgbe \ dependency "t6fw_cfg_uwire.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t6fw_cfg_uwire.fwo" t6fw_cfg_uwire.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t6fw_cfg_uwire.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t6fw_cfg_uwire.fw" t6fw.fwo optional cxgbe \ dependency "t6fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t6fw.fwo" t6fw.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t6fw-1.27.0.0.bin" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t6fw.fw" dev/cxgbe/crypto/t4_crypto.c optional ccr \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cyapa/cyapa.c optional cyapa iicbus dev/dc/if_dc.c optional dc pci dev/dc/dcphy.c optional dc pci dev/dc/pnphy.c optional dc pci dev/dcons/dcons.c optional dcons dev/dcons/dcons_crom.c optional dcons_crom dev/dcons/dcons_os.c optional dcons dev/dialog/da9063/da9063_if.m optional da9063_pmic dev/dialog/da9063/da9063_iic.c optional da9063_pmic iicbus fdt dev/dialog/da9063/da9063_rtc.c optional da9063_rtc fdt dev/dme/if_dme.c optional dme dev/drm2/drm_agpsupport.c optional drm2 dev/drm2/drm_auth.c optional drm2 dev/drm2/drm_bufs.c optional drm2 dev/drm2/drm_buffer.c optional drm2 dev/drm2/drm_context.c optional drm2 dev/drm2/drm_crtc.c optional drm2 dev/drm2/drm_crtc_helper.c optional drm2 dev/drm2/drm_dma.c optional drm2 dev/drm2/drm_dp_helper.c optional drm2 dev/drm2/drm_dp_iic_helper.c optional drm2 dev/drm2/drm_drv.c optional drm2 dev/drm2/drm_edid.c optional drm2 dev/drm2/drm_fb_helper.c optional drm2 dev/drm2/drm_fops.c optional drm2 dev/drm2/drm_gem.c optional drm2 dev/drm2/drm_gem_names.c optional drm2 dev/drm2/drm_global.c optional drm2 dev/drm2/drm_hashtab.c optional drm2 dev/drm2/drm_ioctl.c optional drm2 dev/drm2/drm_irq.c optional drm2 dev/drm2/drm_linux_list_sort.c optional drm2 dev/drm2/drm_lock.c optional drm2 dev/drm2/drm_memory.c optional drm2 dev/drm2/drm_mm.c optional drm2 dev/drm2/drm_modes.c optional drm2 dev/drm2/drm_pci.c optional drm2 dev/drm2/drm_platform.c optional drm2 dev/drm2/drm_scatter.c optional drm2 dev/drm2/drm_stub.c optional drm2 dev/drm2/drm_sysctl.c optional drm2 dev/drm2/drm_vm.c optional drm2 dev/drm2/drm_os_freebsd.c optional drm2 dev/drm2/ttm/ttm_agp_backend.c optional drm2 dev/drm2/ttm/ttm_lock.c optional drm2 dev/drm2/ttm/ttm_object.c optional drm2 dev/drm2/ttm/ttm_tt.c optional drm2 dev/drm2/ttm/ttm_bo_util.c optional drm2 dev/drm2/ttm/ttm_bo.c optional drm2 dev/drm2/ttm/ttm_bo_manager.c optional drm2 dev/drm2/ttm/ttm_execbuf_util.c optional drm2 dev/drm2/ttm/ttm_memory.c optional drm2 dev/drm2/ttm/ttm_page_alloc.c optional drm2 dev/drm2/ttm/ttm_bo_vm.c optional drm2 dev/efidev/efidev.c optional efirt dev/efidev/efirt.c optional efirt dev/efidev/efirtc.c optional efirt dev/e1000/if_em.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/em_txrx.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/igb_txrx.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_80003es2lan.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82540.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82541.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82542.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82543.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82571.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82575.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_ich8lan.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_i210.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_api.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_base.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_mac.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_manage.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_nvm.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_phy.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_vf.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_mbx.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_osdep.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/et/if_et.c optional et dev/ena/ena.c optional ena \ compile-with "${NORMAL_C} -I$S/contrib" dev/ena/ena_datapath.c optional ena \ compile-with "${NORMAL_C} -I$S/contrib" dev/ena/ena_netmap.c optional ena \ compile-with "${NORMAL_C} -I$S/contrib" dev/ena/ena_rss.c optional ena \ compile-with "${NORMAL_C} -I$S/contrib" dev/ena/ena_sysctl.c optional ena \ compile-with "${NORMAL_C} -I$S/contrib" contrib/ena-com/ena_com.c optional ena contrib/ena-com/ena_eth_com.c optional ena dev/etherswitch/arswitch/arswitch.c optional arswitch dev/etherswitch/arswitch/arswitch_reg.c optional arswitch dev/etherswitch/arswitch/arswitch_phy.c optional arswitch dev/etherswitch/arswitch/arswitch_8216.c optional arswitch dev/etherswitch/arswitch/arswitch_8226.c optional arswitch dev/etherswitch/arswitch/arswitch_8316.c optional arswitch dev/etherswitch/arswitch/arswitch_8327.c optional arswitch dev/etherswitch/arswitch/arswitch_7240.c optional arswitch dev/etherswitch/arswitch/arswitch_9340.c optional arswitch dev/etherswitch/arswitch/arswitch_vlans.c optional arswitch dev/etherswitch/etherswitch.c optional etherswitch dev/etherswitch/etherswitch_if.m optional etherswitch dev/etherswitch/ip17x/ip17x.c optional ip17x dev/etherswitch/ip17x/ip175c.c optional ip17x dev/etherswitch/ip17x/ip175d.c optional ip17x dev/etherswitch/ip17x/ip17x_phy.c optional ip17x dev/etherswitch/ip17x/ip17x_vlans.c optional ip17x dev/etherswitch/miiproxy.c optional miiproxy dev/etherswitch/rtl8366/rtl8366rb.c optional rtl8366rb dev/etherswitch/e6000sw/e6000sw.c optional e6000sw fdt dev/etherswitch/e6000sw/e6060sw.c optional e6060sw dev/etherswitch/infineon/adm6996fc.c optional adm6996fc dev/etherswitch/micrel/ksz8995ma.c optional ksz8995ma dev/etherswitch/ukswitch/ukswitch.c optional ukswitch dev/evdev/cdev.c optional evdev dev/evdev/evdev.c optional evdev dev/evdev/evdev_mt.c optional evdev dev/evdev/evdev_utils.c optional evdev dev/evdev/uinput.c optional evdev uinput dev/exca/exca.c optional cbb dev/extres/clk/clk.c optional clk dev/extres/clk/clkdev_if.m optional clk dev/extres/clk/clknode_if.m optional clk dev/extres/clk/clk_bus.c optional clk fdt dev/extres/clk/clk_div.c optional clk dev/extres/clk/clk_fixed.c optional clk dev/extres/clk/clk_gate.c optional clk dev/extres/clk/clk_link.c optional clk dev/extres/clk/clk_mux.c optional clk dev/extres/phy/phy.c optional phy dev/extres/phy/phydev_if.m optional phy fdt dev/extres/phy/phynode_if.m optional phy dev/extres/phy/phy_usb.c optional phy dev/extres/phy/phynode_usb_if.m optional phy dev/extres/hwreset/hwreset.c optional hwreset dev/extres/hwreset/hwreset_if.m optional hwreset dev/extres/nvmem/nvmem.c optional nvmem fdt dev/extres/nvmem/nvmem_if.m optional nvmem dev/extres/regulator/regdev_if.m optional regulator fdt dev/extres/regulator/regnode_if.m optional regulator dev/extres/regulator/regulator.c optional regulator dev/extres/regulator/regulator_bus.c optional regulator fdt dev/extres/regulator/regulator_fixed.c optional regulator dev/extres/syscon/syscon.c optional syscon dev/extres/syscon/syscon_generic.c optional syscon fdt dev/extres/syscon/syscon_if.m optional syscon dev/extres/syscon/syscon_power.c optional syscon syscon_power dev/fb/fbd.c optional fbd | vt dev/fb/fb_if.m standard dev/fb/splash.c optional sc splash dev/fdt/fdt_clock.c optional fdt fdt_clock dev/fdt/fdt_clock_if.m optional fdt fdt_clock dev/fdt/fdt_common.c optional fdt dev/fdt/fdt_pinctrl.c optional fdt fdt_pinctrl dev/fdt/fdt_pinctrl_if.m optional fdt fdt_pinctrl dev/fdt/fdt_slicer.c optional fdt cfi | fdt mx25l | fdt n25q | fdt at45d dev/fdt/fdt_static_dtb.S optional fdt fdt_dtb_static \ dependency "${FDT_DTS_FILE:T:R}.dtb" dev/fdt/simplebus.c optional fdt dev/fdt/simple_mfd.c optional syscon fdt dev/filemon/filemon.c optional filemon dev/firewire/firewire.c optional firewire dev/firewire/fwcrom.c optional firewire dev/firewire/fwdev.c optional firewire dev/firewire/fwdma.c optional firewire dev/firewire/fwmem.c optional firewire dev/firewire/fwohci.c optional firewire dev/firewire/fwohci_pci.c optional firewire pci dev/firewire/if_fwe.c optional fwe dev/firewire/if_fwip.c optional fwip dev/firewire/sbp.c optional sbp dev/firewire/sbp_targ.c optional sbp_targ dev/flash/at45d.c optional at45d dev/flash/cqspi.c optional cqspi fdt xdma dev/flash/mx25l.c optional mx25l dev/flash/n25q.c optional n25q fdt dev/flash/qspi_if.m optional cqspi fdt | n25q fdt dev/fxp/if_fxp.c optional fxp dev/fxp/inphy.c optional fxp dev/gem/if_gem.c optional gem dev/gem/if_gem_pci.c optional gem pci dev/goldfish/goldfish_rtc.c optional goldfish_rtc fdt dev/gpio/dwgpio/dwgpio.c optional gpio dwgpio fdt dev/gpio/dwgpio/dwgpio_bus.c optional gpio dwgpio fdt dev/gpio/dwgpio/dwgpio_if.m optional gpio dwgpio fdt dev/gpio/gpiobacklight.c optional gpiobacklight fdt dev/gpio/gpiokeys.c optional gpiokeys fdt dev/gpio/gpiokeys_codes.c optional gpiokeys fdt dev/gpio/gpiobus.c optional gpio \ dependency "gpiobus_if.h" dev/gpio/gpioc.c optional gpio \ dependency "gpio_if.h" dev/gpio/gpioiic.c optional gpioiic dev/gpio/gpioled.c optional gpioled !fdt dev/gpio/gpioled_fdt.c optional gpioled fdt dev/gpio/gpiomdio.c optional gpiomdio mii_bitbang dev/gpio/gpiopower.c optional gpiopower fdt dev/gpio/gpioregulator.c optional gpioregulator fdt dev/gpio/gpiospi.c optional gpiospi dev/gpio/gpioths.c optional gpioths dev/gpio/gpio_if.m optional gpio dev/gpio/gpiobus_if.m optional gpio dev/gpio/gpiopps.c optional gpiopps fdt dev/gpio/ofw_gpiobus.c optional fdt gpio dev/hid/bcm5974.c optional bcm5974 dev/hid/hconf.c optional hconf dev/hid/hcons.c optional hcons dev/hid/hgame.c optional hgame dev/hid/hid.c optional hid dev/hid/hid_if.m optional hid dev/hid/hidbus.c optional hidbus dev/hid/hidmap.c optional hidmap dev/hid/hidquirk.c optional hid dev/hid/hidraw.c optional hidraw dev/hid/hkbd.c optional hkbd dev/hid/hms.c optional hms dev/hid/hmt.c optional hmt hconf dev/hid/hpen.c optional hpen dev/hid/hsctrl.c optional hsctrl dev/hid/ietp.c optional ietp dev/hid/ps4dshock.c optional ps4dshock dev/hid/xb360gp.c optional xb360gp dev/hifn/hifn7751.c optional hifn dev/hptiop/hptiop.c optional hptiop scbus dev/hwpmc/hwpmc_logging.c optional hwpmc dev/hwpmc/hwpmc_mod.c optional hwpmc dev/hwpmc/hwpmc_soft.c optional hwpmc dev/ichiic/ig4_acpi.c optional ig4 acpi iicbus dev/ichiic/ig4_iic.c optional ig4 iicbus dev/ichiic/ig4_pci.c optional ig4 pci iicbus dev/ichsmb/ichsmb.c optional ichsmb dev/ichsmb/ichsmb_pci.c optional ichsmb pci dev/ida/ida.c optional ida dev/ida/ida_disk.c optional ida dev/ida/ida_pci.c optional ida pci dev/iicbus/acpi_iicbus.c optional acpi iicbus | acpi compat_linuxkpi dev/iicbus/ad7418.c optional ad7418 dev/iicbus/ads111x.c optional ads111x dev/iicbus/ds1307.c optional ds1307 dev/iicbus/ds13rtc.c optional ds13rtc | ds133x | ds1374 dev/iicbus/ds1672.c optional ds1672 dev/iicbus/ds3231.c optional ds3231 dev/iicbus/htu21.c optional htu21 dev/iicbus/icee.c optional icee dev/iicbus/if_ic.c optional ic dev/iicbus/iic.c optional iic dev/iicbus/iic_recover_bus.c optional iicbus | compat_linuxkpi dev/iicbus/iicbb.c optional iicbb | compat_linuxkpi dev/iicbus/iicbb_if.m optional iicbb | compat_linuxkpi dev/iicbus/iicbus.c optional iicbus | compat_linuxkpi dev/iicbus/iicbus_if.m optional iicbus | compat_linuxkpi dev/iicbus/iichid.c optional iichid acpi hid iicbus dev/iicbus/iiconf.c optional iicbus | compat_linuxkpi dev/iicbus/iicsmb.c optional iicsmb \ dependency "iicbus_if.h" dev/iicbus/iicoc.c optional iicoc dev/iicbus/iicoc_fdt.c optional iicoc fdt dev/iicbus/iicoc_pci.c optional iicoc pci dev/iicbus/isl12xx.c optional isl12xx dev/iicbus/lm75.c optional lm75 dev/iicbus/max44009.c optional max44009 dev/iicbus/mux/iicmux.c optional iicmux dev/iicbus/mux/iicmux_if.m optional iicmux dev/iicbus/mux/iic_gpiomux.c optional iic_gpiomux fdt dev/iicbus/mux/ltc430x.c optional ltc430x dev/iicbus/mux/pca954x.c optional pca954x iicbus iicmux dev/iicbus/nxprtc.c optional nxprtc | pcf8563 dev/iicbus/ofw_iicbus.c optional fdt iicbus dev/iicbus/ofw_iicbus_if.m optional fdt iicbus dev/iicbus/pcf8574.c optional pcf8574 dev/iicbus/pcf8591.c optional pcf8591 dev/iicbus/rtc8583.c optional rtc8583 dev/iicbus/rtc/pcf85063.c optional pcf85063 iicbus fdt dev/iicbus/rtc/rx8803.c optional rx8803 iicbus fdt dev/iicbus/s35390a.c optional s35390a dev/iicbus/sy8106a.c optional sy8106a fdt dev/iicbus/syr827.c optional syr827 fdt dev/iicbus/gpio/tca64xx.c optional tca64xx fdt gpio dev/iicbus/pmic/fan53555.c optional fan53555 fdt dev/igc/if_igc.c optional igc iflib pci dev/igc/igc_api.c optional igc iflib pci dev/igc/igc_base.c optional igc iflib pci dev/igc/igc_i225.c optional igc iflib pci dev/igc/igc_mac.c optional igc iflib pci dev/igc/igc_nvm.c optional igc iflib pci dev/igc/igc_phy.c optional igc iflib pci dev/igc/igc_txrx.c optional igc iflib pci dev/intpm/intpm.c optional intpm pci # XXX Work around clang warning, until maintainer approves fix. dev/ips/ips.c optional ips \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/ips/ips_commands.c optional ips dev/ips/ips_disk.c optional ips dev/ips/ips_ioctl.c optional ips dev/ips/ips_pci.c optional ips pci dev/ipw/if_ipw.c optional ipw ipwbssfw.c optional ipwbssfw | ipwfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk ipw_bss.fw:ipw_bss:130 -lintel_ipw -mipw_bss -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "ipwbssfw.c" ipw_bss.fwo optional ipwbssfw | ipwfw \ dependency "ipw_bss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ipw_bss.fwo" ipw_bss.fw optional ipwbssfw | ipwfw \ dependency "$S/contrib/dev/ipw/ipw2100-1.3.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "ipw_bss.fw" ipwibssfw.c optional ipwibssfw | ipwfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk ipw_ibss.fw:ipw_ibss:130 -lintel_ipw -mipw_ibss -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "ipwibssfw.c" ipw_ibss.fwo optional ipwibssfw | ipwfw \ dependency "ipw_ibss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ipw_ibss.fwo" ipw_ibss.fw optional ipwibssfw | ipwfw \ dependency "$S/contrib/dev/ipw/ipw2100-1.3-i.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "ipw_ibss.fw" ipwmonitorfw.c optional ipwmonitorfw | ipwfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk ipw_monitor.fw:ipw_monitor:130 -lintel_ipw -mipw_monitor -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "ipwmonitorfw.c" ipw_monitor.fwo optional ipwmonitorfw | ipwfw \ dependency "ipw_monitor.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ipw_monitor.fwo" ipw_monitor.fw optional ipwmonitorfw | ipwfw \ dependency "$S/contrib/dev/ipw/ipw2100-1.3-p.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "ipw_monitor.fw" dev/iscsi/icl.c optional iscsi dev/iscsi/icl_conn_if.m optional cfiscsi | iscsi dev/iscsi/icl_soft.c optional iscsi dev/iscsi/icl_soft_proxy.c optional iscsi dev/iscsi/iscsi.c optional iscsi scbus dev/ismt/ismt.c optional ismt dev/isl/isl.c optional isl iicbus dev/isp/isp.c optional isp dev/isp/isp_freebsd.c optional isp dev/isp/isp_library.c optional isp dev/isp/isp_pci.c optional isp pci dev/isp/isp_target.c optional isp dev/ispfw/ispfw.c optional ispfw dev/iwi/if_iwi.c optional iwi iwibssfw.c optional iwibssfw | iwifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwi_bss.fw:iwi_bss:300 -lintel_iwi -miwi_bss -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwibssfw.c" iwi_bss.fwo optional iwibssfw | iwifw \ dependency "iwi_bss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwi_bss.fwo" iwi_bss.fw optional iwibssfw | iwifw \ dependency "$S/contrib/dev/iwi/ipw2200-bss.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwi_bss.fw" iwiibssfw.c optional iwiibssfw | iwifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwi_ibss.fw:iwi_ibss:300 -lintel_iwi -miwi_ibss -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwiibssfw.c" iwi_ibss.fwo optional iwiibssfw | iwifw \ dependency "iwi_ibss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwi_ibss.fwo" iwi_ibss.fw optional iwiibssfw | iwifw \ dependency "$S/contrib/dev/iwi/ipw2200-ibss.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwi_ibss.fw" iwimonitorfw.c optional iwimonitorfw | iwifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwi_monitor.fw:iwi_monitor:300 -lintel_iwi -miwi_monitor -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwimonitorfw.c" iwi_monitor.fwo optional iwimonitorfw | iwifw \ dependency "iwi_monitor.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwi_monitor.fwo" iwi_monitor.fw optional iwimonitorfw | iwifw \ dependency "$S/contrib/dev/iwi/ipw2200-sniffer.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwi_monitor.fw" dev/iwm/if_iwm.c optional iwm dev/iwm/if_iwm_7000.c optional iwm dev/iwm/if_iwm_8000.c optional iwm dev/iwm/if_iwm_9000.c optional iwm dev/iwm/if_iwm_9260.c optional iwm dev/iwm/if_iwm_binding.c optional iwm dev/iwm/if_iwm_fw.c optional iwm dev/iwm/if_iwm_led.c optional iwm dev/iwm/if_iwm_mac_ctxt.c optional iwm dev/iwm/if_iwm_notif_wait.c optional iwm dev/iwm/if_iwm_pcie_trans.c optional iwm dev/iwm/if_iwm_phy_ctxt.c optional iwm dev/iwm/if_iwm_phy_db.c optional iwm dev/iwm/if_iwm_power.c optional iwm dev/iwm/if_iwm_scan.c optional iwm dev/iwm/if_iwm_sf.c optional iwm dev/iwm/if_iwm_sta.c optional iwm dev/iwm/if_iwm_time_event.c optional iwm dev/iwm/if_iwm_util.c optional iwm iwm3160fw.c optional iwm3160fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm3160.fw:iwm3160fw -miwm3160fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm3160fw.c" iwm3160fw.fwo optional iwm3160fw | iwmfw \ dependency "iwm3160.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm3160fw.fwo" iwm3160.fw optional iwm3160fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-3160-17.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm3160.fw" iwm3168fw.c optional iwm3168fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm3168.fw:iwm3168fw -miwm3168fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm3168fw.c" iwm3168fw.fwo optional iwm3168fw | iwmfw \ dependency "iwm3168.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm3168fw.fwo" iwm3168.fw optional iwm3168fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-3168-22.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm3168.fw" iwm7260fw.c optional iwm7260fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm7260.fw:iwm7260fw -miwm7260fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm7260fw.c" iwm7260fw.fwo optional iwm7260fw | iwmfw \ dependency "iwm7260.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm7260fw.fwo" iwm7260.fw optional iwm7260fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-7260-17.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm7260.fw" iwm7265fw.c optional iwm7265fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm7265.fw:iwm7265fw -miwm7265fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm7265fw.c" iwm7265fw.fwo optional iwm7265fw | iwmfw \ dependency "iwm7265.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm7265fw.fwo" iwm7265.fw optional iwm7265fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-7265-17.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm7265.fw" iwm7265Dfw.c optional iwm7265Dfw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm7265D.fw:iwm7265Dfw -miwm7265Dfw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm7265Dfw.c" iwm7265Dfw.fwo optional iwm7265Dfw | iwmfw \ dependency "iwm7265D.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm7265Dfw.fwo" iwm7265D.fw optional iwm7265Dfw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-7265D-17.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm7265D.fw" iwm8000Cfw.c optional iwm8000Cfw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm8000C.fw:iwm8000Cfw -miwm8000Cfw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm8000Cfw.c" iwm8000Cfw.fwo optional iwm8000Cfw | iwmfw \ dependency "iwm8000C.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm8000Cfw.fwo" iwm8000C.fw optional iwm8000Cfw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-8000C-16.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm8000C.fw" iwm8265.fw optional iwm8265fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-8265-22.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm8265.fw" iwm8265fw.c optional iwm8265fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm8265.fw:iwm8265fw -miwm8265fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwm8265fw.c" iwm8265fw.fwo optional iwm8265fw | iwmfw \ dependency "iwm8265.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm8265fw.fwo" dev/iwn/if_iwn.c optional iwn iwn1000fw.c optional iwn1000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn1000.fw:iwn1000fw -miwn1000fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn1000fw.c" iwn1000fw.fwo optional iwn1000fw | iwnfw \ dependency "iwn1000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn1000fw.fwo" iwn1000.fw optional iwn1000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-1000-39.31.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn1000.fw" iwn100fw.c optional iwn100fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn100.fw:iwn100fw -miwn100fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn100fw.c" iwn100fw.fwo optional iwn100fw | iwnfw \ dependency "iwn100.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn100fw.fwo" iwn100.fw optional iwn100fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-100-39.31.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn100.fw" iwn105fw.c optional iwn105fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn105.fw:iwn105fw -miwn105fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn105fw.c" iwn105fw.fwo optional iwn105fw | iwnfw \ dependency "iwn105.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn105fw.fwo" iwn105.fw optional iwn105fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-105-6-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn105.fw" iwn135fw.c optional iwn135fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn135.fw:iwn135fw -miwn135fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn135fw.c" iwn135fw.fwo optional iwn135fw | iwnfw \ dependency "iwn135.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn135fw.fwo" iwn135.fw optional iwn135fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-135-6-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn135.fw" iwn2000fw.c optional iwn2000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn2000.fw:iwn2000fw -miwn2000fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn2000fw.c" iwn2000fw.fwo optional iwn2000fw | iwnfw \ dependency "iwn2000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn2000fw.fwo" iwn2000.fw optional iwn2000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-2000-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn2000.fw" iwn2030fw.c optional iwn2030fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn2030.fw:iwn2030fw -miwn2030fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn2030fw.c" iwn2030fw.fwo optional iwn2030fw | iwnfw \ dependency "iwn2030.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn2030fw.fwo" iwn2030.fw optional iwn2030fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwnwifi-2030-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn2030.fw" iwn4965fw.c optional iwn4965fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn4965.fw:iwn4965fw -miwn4965fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn4965fw.c" iwn4965fw.fwo optional iwn4965fw | iwnfw \ dependency "iwn4965.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn4965fw.fwo" iwn4965.fw optional iwn4965fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-4965-228.61.2.24.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn4965.fw" iwn5000fw.c optional iwn5000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn5000.fw:iwn5000fw -miwn5000fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn5000fw.c" iwn5000fw.fwo optional iwn5000fw | iwnfw \ dependency "iwn5000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn5000fw.fwo" iwn5000.fw optional iwn5000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-5000-8.83.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn5000.fw" iwn5150fw.c optional iwn5150fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn5150.fw:iwn5150fw -miwn5150fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn5150fw.c" iwn5150fw.fwo optional iwn5150fw | iwnfw \ dependency "iwn5150.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn5150fw.fwo" iwn5150.fw optional iwn5150fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-5150-8.24.2.2.fw.uu"\ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn5150.fw" iwn6000fw.c optional iwn6000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6000.fw:iwn6000fw -miwn6000fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn6000fw.c" iwn6000fw.fwo optional iwn6000fw | iwnfw \ dependency "iwn6000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6000fw.fwo" iwn6000.fw optional iwn6000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6000-9.221.4.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6000.fw" iwn6000g2afw.c optional iwn6000g2afw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6000g2a.fw:iwn6000g2afw -miwn6000g2afw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn6000g2afw.c" iwn6000g2afw.fwo optional iwn6000g2afw | iwnfw \ dependency "iwn6000g2a.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6000g2afw.fwo" iwn6000g2a.fw optional iwn6000g2afw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6000g2a-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6000g2a.fw" iwn6000g2bfw.c optional iwn6000g2bfw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6000g2b.fw:iwn6000g2bfw -miwn6000g2bfw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn6000g2bfw.c" iwn6000g2bfw.fwo optional iwn6000g2bfw | iwnfw \ dependency "iwn6000g2b.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6000g2bfw.fwo" iwn6000g2b.fw optional iwn6000g2bfw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6000g2b-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6000g2b.fw" iwn6050fw.c optional iwn6050fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6050.fw:iwn6050fw -miwn6050fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "iwn6050fw.c" iwn6050fw.fwo optional iwn6050fw | iwnfw \ dependency "iwn6050.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6050fw.fwo" iwn6050.fw optional iwn6050fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6050-41.28.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6050.fw" dev/ixgbe/if_ix.c optional ix inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe -DSMP" dev/ixgbe/if_ixv.c optional ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe -DSMP" dev/ixgbe/if_bypass.c optional ix inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/if_fdir.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/if_sriov.c optional ix inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ix_txrx.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_osdep.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_phy.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_api.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_common.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_mbx.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_vf.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_82598.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_82599.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_x540.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_x550.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb_82598.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb_82599.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/jedec_dimm/jedec_dimm.c optional jedec_dimm smbus dev/jme/if_jme.c optional jme pci dev/kbd/kbd.c optional atkbd | pckbd | sc | ukbd | vt | hkbd dev/kbdmux/kbdmux.c optional kbdmux dev/ksyms/ksyms.c optional ksyms dev/le/am7990.c optional le dev/le/am79900.c optional le dev/le/if_le_pci.c optional le pci dev/le/lance.c optional le dev/led/led.c standard dev/lge/if_lge.c optional lge dev/liquidio/base/cn23xx_pf_device.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_console.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_ctrl.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_device.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_droq.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_mem_ops.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_request_manager.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_response_manager.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_core.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_ioctl.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_main.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_rss.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_rxtx.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_sysctl.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" lio.c optional lio \ compile-with "${AWK} -f $S/tools/fw_stub.awk lio_23xx_nic.bin.fw:lio_23xx_nic.bin -mlio_23xx_nic.bin -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "lio.c" lio_23xx_nic.bin.fw.fwo optional lio \ dependency "lio_23xx_nic.bin.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "lio_23xx_nic.bin.fw.fwo" lio_23xx_nic.bin.fw optional lio \ dependency "$S/contrib/dev/liquidio/lio_23xx_nic.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "lio_23xx_nic.bin.fw" dev/malo/if_malo.c optional malo dev/malo/if_malohal.c optional malo dev/malo/if_malo_pci.c optional malo pci dev/md/md.c optional md dev/mdio/mdio_if.m optional miiproxy | mdio dev/mdio/mdio.c optional miiproxy | mdio dev/mem/memdev.c optional mem dev/mem/memutil.c optional mem dev/mfi/mfi.c optional mfi dev/mfi/mfi_debug.c optional mfi dev/mfi/mfi_pci.c optional mfi pci dev/mfi/mfi_disk.c optional mfi dev/mfi/mfi_syspd.c optional mfi dev/mfi/mfi_tbolt.c optional mfi dev/mfi/mfi_cam.c optional mfip scbus dev/mii/acphy.c optional miibus | acphy dev/mii/amphy.c optional miibus | amphy dev/mii/atphy.c optional miibus | atphy dev/mii/axphy.c optional miibus | axphy dev/mii/bmtphy.c optional miibus | bmtphy dev/mii/brgphy.c optional miibus | brgphy dev/mii/ciphy.c optional miibus | ciphy dev/mii/dp83822phy.c optional miibus | dp83822phy dev/mii/dp83867phy.c optional miibus | dp83867phy dev/mii/e1000phy.c optional miibus | e1000phy dev/mii/gentbi.c optional miibus | gentbi dev/mii/icsphy.c optional miibus | icsphy dev/mii/ip1000phy.c optional miibus | ip1000phy dev/mii/jmphy.c optional miibus | jmphy dev/mii/lxtphy.c optional miibus | lxtphy dev/mii/micphy.c optional miibus fdt | micphy fdt dev/mii/mii.c optional miibus | mii dev/mii/mii_bitbang.c optional miibus | mii_bitbang dev/mii/mii_physubr.c optional miibus | mii dev/mii/mii_fdt.c optional miibus fdt | mii fdt dev/mii/miibus_if.m optional miibus | mii dev/mii/mv88e151x.c optional miibus | mv88e151x dev/mii/nsgphy.c optional miibus | nsgphy dev/mii/nsphy.c optional miibus | nsphy dev/mii/nsphyter.c optional miibus | nsphyter dev/mii/pnaphy.c optional miibus | pnaphy dev/mii/qsphy.c optional miibus | qsphy dev/mii/rdcphy.c optional miibus | rdcphy dev/mii/rgephy.c optional miibus | rgephy dev/mii/rlphy.c optional miibus | rlphy dev/mii/rlswitch.c optional rlswitch dev/mii/smcphy.c optional miibus | smcphy dev/mii/smscphy.c optional miibus | smscphy dev/mii/tdkphy.c optional miibus | tdkphy dev/mii/truephy.c optional miibus | truephy dev/mii/ukphy.c optional miibus | mii dev/mii/ukphy_subr.c optional miibus | mii dev/mii/vscphy.c optional miibus | vscphy dev/mii/xmphy.c optional miibus | xmphy dev/mlxfw/mlxfw_fsm.c optional mlxfw \ compile-with "${MLXFW_C}" dev/mlxfw/mlxfw_mfa2.c optional mlxfw \ compile-with "${MLXFW_C}" dev/mlxfw/mlxfw_mfa2_tlv_multi.c optional mlxfw \ compile-with "${MLXFW_C}" dev/mlx/mlx.c optional mlx dev/mlx/mlx_disk.c optional mlx dev/mlx/mlx_pci.c optional mlx pci dev/mmc/mmc_subr.c optional mmc | mmcsd !mmccam dev/mmc/mmc.c optional mmc !mmccam dev/mmc/mmcbr_if.m standard dev/mmc/mmcbus_if.m standard dev/mmc/mmcsd.c optional mmcsd !mmccam dev/mmc/mmc_fdt_helpers.c optional mmc regulator clk fdt | mmccam regulator clk fdt dev/mmc/mmc_helpers.c optional mmc gpio regulator clk | mmccam gpio regulator clk dev/mmc/mmc_pwrseq.c optional mmc clk regulator fdt | mmccam clk regulator fdt dev/mmc/mmc_pwrseq_if.m optional mmc clk regulator fdt | mmccam clk regulator fdt dev/mmcnull/mmcnull.c optional mmcnull dev/mpr/mpr.c optional mpr dev/mpr/mpr_config.c optional mpr # XXX Work around clang warning, until maintainer approves fix. dev/mpr/mpr_mapping.c optional mpr \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/mpr/mpr_pci.c optional mpr pci dev/mpr/mpr_sas.c optional mpr \ compile-with "${NORMAL_C} ${NO_WUNNEEDED_INTERNAL_DECL}" dev/mpr/mpr_sas_lsi.c optional mpr dev/mpr/mpr_table.c optional mpr dev/mpr/mpr_user.c optional mpr dev/mps/mps.c optional mps dev/mps/mps_config.c optional mps # XXX Work around clang warning, until maintainer approves fix. dev/mps/mps_mapping.c optional mps \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/mps/mps_pci.c optional mps pci dev/mps/mps_sas.c optional mps \ compile-with "${NORMAL_C} ${NO_WUNNEEDED_INTERNAL_DECL}" dev/mps/mps_sas_lsi.c optional mps dev/mps/mps_table.c optional mps dev/mps/mps_user.c optional mps dev/mpt/mpt.c optional mpt dev/mpt/mpt_cam.c optional mpt dev/mpt/mpt_debug.c optional mpt dev/mpt/mpt_pci.c optional mpt pci dev/mpt/mpt_raid.c optional mpt dev/mpt/mpt_user.c optional mpt dev/mrsas/mrsas.c optional mrsas dev/mrsas/mrsas_cam.c optional mrsas dev/mrsas/mrsas_ioctl.c optional mrsas dev/mrsas/mrsas_fp.c optional mrsas dev/msk/if_msk.c optional msk dev/mvs/mvs.c optional mvs dev/mvs/mvs_if.m optional mvs dev/mvs/mvs_pci.c optional mvs pci dev/mwl/if_mwl.c optional mwl dev/mwl/if_mwl_pci.c optional mwl pci dev/mwl/mwlhal.c optional mwl mwlfw.c optional mwlfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk mw88W8363.fw:mw88W8363fw mwlboot.fw:mwlboot -mmwl -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "mwlfw.c" mw88W8363.fwo optional mwlfw \ dependency "mw88W8363.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "mw88W8363.fwo" mw88W8363.fw optional mwlfw \ dependency "$S/contrib/dev/mwl/mw88W8363.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "mw88W8363.fw" mwlboot.fwo optional mwlfw \ dependency "mwlboot.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "mwlboot.fwo" mwlboot.fw optional mwlfw \ dependency "$S/contrib/dev/mwl/mwlboot.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "mwlboot.fw" dev/mxge/if_mxge.c optional mxge pci dev/mxge/mxge_eth_z8e.c optional mxge pci dev/mxge/mxge_ethp_z8e.c optional mxge pci dev/mxge/mxge_rss_eth_z8e.c optional mxge pci dev/mxge/mxge_rss_ethp_z8e.c optional mxge pci dev/my/if_my.c optional my dev/netmap/if_ptnet.c optional netmap inet dev/netmap/netmap.c optional netmap dev/netmap/netmap_bdg.c optional netmap dev/netmap/netmap_freebsd.c optional netmap dev/netmap/netmap_generic.c optional netmap dev/netmap/netmap_kloop.c optional netmap dev/netmap/netmap_legacy.c optional netmap dev/netmap/netmap_mbq.c optional netmap dev/netmap/netmap_mem2.c optional netmap dev/netmap/netmap_monitor.c optional netmap dev/netmap/netmap_null.c optional netmap dev/netmap/netmap_offloadings.c optional netmap dev/netmap/netmap_pipe.c optional netmap dev/netmap/netmap_vale.c optional netmap # compile-with "${NORMAL_C} -Wconversion -Wextra" dev/nfsmb/nfsmb.c optional nfsmb pci dev/nge/if_nge.c optional nge dev/nmdm/nmdm.c optional nmdm dev/null/null.c standard dev/nvd/nvd.c optional nvd nvme dev/nvme/nvme.c optional nvme dev/nvme/nvme_ahci.c optional nvme ahci dev/nvme/nvme_ctrlr.c optional nvme dev/nvme/nvme_ctrlr_cmd.c optional nvme dev/nvme/nvme_ns.c optional nvme dev/nvme/nvme_ns_cmd.c optional nvme dev/nvme/nvme_pci.c optional nvme pci dev/nvme/nvme_qpair.c optional nvme dev/nvme/nvme_sim.c optional nvme scbus dev/nvme/nvme_sysctl.c optional nvme dev/nvme/nvme_test.c optional nvme dev/nvme/nvme_util.c optional nvme dev/oce/oce_hw.c optional oce pci dev/oce/oce_if.c optional oce pci dev/oce/oce_mbox.c optional oce pci dev/oce/oce_queue.c optional oce pci dev/oce/oce_sysctl.c optional oce pci dev/oce/oce_util.c optional oce pci dev/ocs_fc/ocs_gendump.c optional ocs_fc pci dev/ocs_fc/ocs_pci.c optional ocs_fc pci dev/ocs_fc/ocs_ioctl.c optional ocs_fc pci dev/ocs_fc/ocs_os.c optional ocs_fc pci dev/ocs_fc/ocs_utils.c optional ocs_fc pci dev/ocs_fc/ocs_hw.c optional ocs_fc pci dev/ocs_fc/ocs_hw_queues.c optional ocs_fc pci dev/ocs_fc/sli4.c optional ocs_fc pci dev/ocs_fc/ocs_sm.c optional ocs_fc pci dev/ocs_fc/ocs_device.c optional ocs_fc pci dev/ocs_fc/ocs_xport.c optional ocs_fc pci dev/ocs_fc/ocs_domain.c optional ocs_fc pci dev/ocs_fc/ocs_sport.c optional ocs_fc pci dev/ocs_fc/ocs_els.c optional ocs_fc pci dev/ocs_fc/ocs_fabric.c optional ocs_fc pci dev/ocs_fc/ocs_io.c optional ocs_fc pci dev/ocs_fc/ocs_node.c optional ocs_fc pci dev/ocs_fc/ocs_scsi.c optional ocs_fc pci dev/ocs_fc/ocs_unsol.c optional ocs_fc pci dev/ocs_fc/ocs_ddump.c optional ocs_fc pci dev/ocs_fc/ocs_mgmt.c optional ocs_fc pci dev/ocs_fc/ocs_cam.c optional ocs_fc pci dev/ofw/ofw_bus_if.m optional fdt dev/ofw/ofw_bus_subr.c optional fdt dev/ofw/ofw_cpu.c optional fdt dev/ofw/ofw_fdt.c optional fdt dev/ofw/ofw_if.m optional fdt dev/ofw/ofw_graph.c optional fdt dev/ofw/ofw_subr.c optional fdt dev/ofw/ofwbus.c optional fdt dev/ofw/openfirm.c optional fdt dev/ofw/openfirmio.c optional fdt dev/ow/ow.c optional ow \ dependency "owll_if.h" \ dependency "own_if.h" dev/ow/owll_if.m optional ow dev/ow/own_if.m optional ow dev/ow/ow_temp.c optional ow_temp dev/ow/owc_gpiobus.c optional owc gpio dev/pbio/pbio.c optional pbio isa dev/pccbb/pccbb.c optional cbb dev/pccbb/pccbb_pci.c optional cbb pci dev/pcf/pcf.c optional pcf dev/pci/fixup_pci.c optional pci dev/pci/hostb_pci.c optional pci dev/pci/ignore_pci.c optional pci dev/pci/isa_pci.c optional pci isa dev/pci/pci.c optional pci dev/pci/pci_if.m standard dev/pci/pci_iov.c optional pci pci_iov dev/pci/pci_iov_if.m standard dev/pci/pci_iov_schema.c optional pci pci_iov dev/pci/pci_pci.c optional pci dev/pci/pci_subr.c optional pci dev/pci/pci_user.c optional pci dev/pci/pcib_if.m standard dev/pci/pcib_support.c standard dev/pci/vga_pci.c optional pci dev/pms/freebsd/driver/ini/src/agtiapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sadisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/mpi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saframe.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sahw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sainit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saint.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sampicmd.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sampirsp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saphy.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saport.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sasata.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sasmp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sassp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/satimer.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sautil.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saioctlcmd.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/mpidebug.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dminit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmsmp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmdisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmport.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmtimer.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmmisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/sminit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smmisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smsat.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smsatcb.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smsathw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smtimer.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdinit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdmisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdesgl.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdport.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdint.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdioctl.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdhw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/ossacmnapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tddmcmnapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdsmcmnapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdtimers.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itdio.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itdcb.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itdinit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itddisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sata/host/sat.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sata/host/ossasat.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sata/host/sathw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/ppbus/if_plip.c optional plip dev/ppbus/lpbb.c optional lpbb dev/ppbus/lpt.c optional lpt dev/ppbus/pcfclock.c optional pcfclock dev/ppbus/ppb_1284.c optional ppbus dev/ppbus/ppb_base.c optional ppbus dev/ppbus/ppb_msq.c optional ppbus dev/ppbus/ppbconf.c optional ppbus dev/ppbus/ppbus_if.m optional ppbus dev/ppbus/ppi.c optional ppi dev/ppbus/pps.c optional pps dev/ppc/ppc.c optional ppc dev/ppc/ppc_acpi.c optional ppc acpi dev/ppc/ppc_isa.c optional ppc isa dev/ppc/ppc_pci.c optional ppc pci dev/ppc/ppc_puc.c optional ppc puc dev/proto/proto_bus_isa.c optional proto acpi | proto isa dev/proto/proto_bus_pci.c optional proto pci dev/proto/proto_busdma.c optional proto dev/proto/proto_core.c optional proto dev/pst/pst-iop.c optional pst dev/pst/pst-pci.c optional pst pci dev/pst/pst-raid.c optional pst dev/pty/pty.c optional pty dev/puc/puc.c optional puc dev/puc/puc_cfg.c optional puc dev/puc/puc_pci.c optional puc pci dev/pwm/pwmc.c optional pwm | pwmc dev/pwm/pwmbus.c optional pwm | pwmbus dev/pwm/pwmbus_if.m optional pwm | pwmbus dev/pwm/ofw_pwm.c optional pwm fdt | pwmbus fdt dev/pwm/ofw_pwmbus.c optional pwm fdt | pwmbus fdt dev/pwm/pwm_backlight.c optional pwm pwm_backlight fdt dev/quicc/quicc_core.c optional quicc dev/ral/rt2560.c optional ral dev/ral/rt2661.c optional ral dev/ral/rt2860.c optional ral dev/ral/if_ral_pci.c optional ral pci rt2561fw.c optional rt2561fw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2561.fw:rt2561fw -mrt2561 -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rt2561fw.c" rt2561fw.fwo optional rt2561fw | ralfw \ dependency "rt2561.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2561fw.fwo" rt2561.fw optional rt2561fw | ralfw \ dependency "$S/contrib/dev/ral/rt2561.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2561.fw" rt2561sfw.c optional rt2561sfw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2561s.fw:rt2561sfw -mrt2561s -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rt2561sfw.c" rt2561sfw.fwo optional rt2561sfw | ralfw \ dependency "rt2561s.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2561sfw.fwo" rt2561s.fw optional rt2561sfw | ralfw \ dependency "$S/contrib/dev/ral/rt2561s.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2561s.fw" rt2661fw.c optional rt2661fw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2661.fw:rt2661fw -mrt2661 -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rt2661fw.c" rt2661fw.fwo optional rt2661fw | ralfw \ dependency "rt2661.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2661fw.fwo" rt2661.fw optional rt2661fw | ralfw \ dependency "$S/contrib/dev/ral/rt2661.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2661.fw" rt2860fw.c optional rt2860fw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2860.fw:rt2860fw -mrt2860 -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rt2860fw.c" rt2860fw.fwo optional rt2860fw | ralfw \ dependency "rt2860.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2860fw.fwo" rt2860.fw optional rt2860fw | ralfw \ dependency "$S/contrib/dev/ral/rt2860.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2860.fw" dev/random/random_infra.c standard dev/random/random_harvestq.c standard dev/random/randomdev.c optional !random_loadable dev/random/fenestrasX/fx_brng.c optional !random_loadable random_fenestrasx dev/random/fenestrasX/fx_main.c optional !random_loadable random_fenestrasx \ compile-with "${NORMAL_C} -I$S/crypto/blake2" dev/random/fenestrasX/fx_pool.c optional !random_loadable random_fenestrasx \ compile-with "${NORMAL_C} -I$S/crypto/blake2" dev/random/fenestrasX/fx_rng.c optional !random_loadable random_fenestrasx \ compile-with "${NORMAL_C} -I$S/crypto/blake2" dev/random/fortuna.c optional !random_loadable !random_fenestrasx dev/random/hash.c optional !random_loadable dev/rccgpio/rccgpio.c optional rccgpio gpio dev/re/if_re.c optional re dev/rl/if_rl.c optional rl pci dev/rndtest/rndtest.c optional rndtest # dev/rtsx/rtsx.c optional rtsx pci # dev/rtwn/if_rtwn.c optional rtwn dev/rtwn/if_rtwn_beacon.c optional rtwn dev/rtwn/if_rtwn_calib.c optional rtwn dev/rtwn/if_rtwn_cam.c optional rtwn dev/rtwn/if_rtwn_efuse.c optional rtwn dev/rtwn/if_rtwn_fw.c optional rtwn dev/rtwn/if_rtwn_rx.c optional rtwn dev/rtwn/if_rtwn_task.c optional rtwn dev/rtwn/if_rtwn_tx.c optional rtwn # dev/rtwn/pci/rtwn_pci_attach.c optional rtwn_pci pci dev/rtwn/pci/rtwn_pci_reg.c optional rtwn_pci pci dev/rtwn/pci/rtwn_pci_rx.c optional rtwn_pci pci dev/rtwn/pci/rtwn_pci_tx.c optional rtwn_pci pci # dev/rtwn/usb/rtwn_usb_attach.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_ep.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_reg.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_rx.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_tx.c optional rtwn_usb # RTL8188E dev/rtwn/rtl8188e/r88e_beacon.c optional rtwn dev/rtwn/rtl8188e/r88e_calib.c optional rtwn dev/rtwn/rtl8188e/r88e_chan.c optional rtwn dev/rtwn/rtl8188e/r88e_fw.c optional rtwn dev/rtwn/rtl8188e/r88e_init.c optional rtwn dev/rtwn/rtl8188e/r88e_led.c optional rtwn dev/rtwn/rtl8188e/r88e_tx.c optional rtwn dev/rtwn/rtl8188e/r88e_rf.c optional rtwn dev/rtwn/rtl8188e/r88e_rom.c optional rtwn dev/rtwn/rtl8188e/r88e_rx.c optional rtwn dev/rtwn/rtl8188e/pci/r88ee_attach.c optional rtwn_pci pci dev/rtwn/rtl8188e/pci/r88ee_init.c optional rtwn_pci pci dev/rtwn/rtl8188e/pci/r88ee_rx.c optional rtwn_pci pci dev/rtwn/rtl8188e/usb/r88eu_attach.c optional rtwn_usb dev/rtwn/rtl8188e/usb/r88eu_init.c optional rtwn_usb # RTL8192C dev/rtwn/rtl8192c/r92c_attach.c optional rtwn dev/rtwn/rtl8192c/r92c_beacon.c optional rtwn dev/rtwn/rtl8192c/r92c_calib.c optional rtwn dev/rtwn/rtl8192c/r92c_chan.c optional rtwn dev/rtwn/rtl8192c/r92c_fw.c optional rtwn dev/rtwn/rtl8192c/r92c_init.c optional rtwn dev/rtwn/rtl8192c/r92c_llt.c optional rtwn dev/rtwn/rtl8192c/r92c_rf.c optional rtwn dev/rtwn/rtl8192c/r92c_rom.c optional rtwn dev/rtwn/rtl8192c/r92c_rx.c optional rtwn dev/rtwn/rtl8192c/r92c_tx.c optional rtwn dev/rtwn/rtl8192c/pci/r92ce_attach.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_calib.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_fw.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_init.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_led.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_rx.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_tx.c optional rtwn_pci pci dev/rtwn/rtl8192c/usb/r92cu_attach.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_init.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_led.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_rx.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_tx.c optional rtwn_usb # RTL8192E dev/rtwn/rtl8192e/r92e_chan.c optional rtwn dev/rtwn/rtl8192e/r92e_fw.c optional rtwn dev/rtwn/rtl8192e/r92e_init.c optional rtwn dev/rtwn/rtl8192e/r92e_led.c optional rtwn dev/rtwn/rtl8192e/r92e_rf.c optional rtwn dev/rtwn/rtl8192e/r92e_rom.c optional rtwn dev/rtwn/rtl8192e/r92e_rx.c optional rtwn dev/rtwn/rtl8192e/usb/r92eu_attach.c optional rtwn_usb dev/rtwn/rtl8192e/usb/r92eu_init.c optional rtwn_usb # RTL8812A dev/rtwn/rtl8812a/r12a_beacon.c optional rtwn dev/rtwn/rtl8812a/r12a_calib.c optional rtwn dev/rtwn/rtl8812a/r12a_caps.c optional rtwn dev/rtwn/rtl8812a/r12a_chan.c optional rtwn dev/rtwn/rtl8812a/r12a_fw.c optional rtwn dev/rtwn/rtl8812a/r12a_init.c optional rtwn dev/rtwn/rtl8812a/r12a_led.c optional rtwn dev/rtwn/rtl8812a/r12a_rf.c optional rtwn dev/rtwn/rtl8812a/r12a_rom.c optional rtwn dev/rtwn/rtl8812a/r12a_rx.c optional rtwn dev/rtwn/rtl8812a/r12a_tx.c optional rtwn dev/rtwn/rtl8812a/usb/r12au_attach.c optional rtwn_usb dev/rtwn/rtl8812a/usb/r12au_init.c optional rtwn_usb dev/rtwn/rtl8812a/usb/r12au_rx.c optional rtwn_usb dev/rtwn/rtl8812a/usb/r12au_tx.c optional rtwn_usb # RTL8821A dev/rtwn/rtl8821a/r21a_beacon.c optional rtwn dev/rtwn/rtl8821a/r21a_calib.c optional rtwn dev/rtwn/rtl8821a/r21a_chan.c optional rtwn dev/rtwn/rtl8821a/r21a_fw.c optional rtwn dev/rtwn/rtl8821a/r21a_init.c optional rtwn dev/rtwn/rtl8821a/r21a_led.c optional rtwn dev/rtwn/rtl8821a/r21a_rom.c optional rtwn dev/rtwn/rtl8821a/r21a_rx.c optional rtwn dev/rtwn/rtl8821a/usb/r21au_attach.c optional rtwn_usb dev/rtwn/rtl8821a/usb/r21au_dfs.c optional rtwn_usb dev/rtwn/rtl8821a/usb/r21au_init.c optional rtwn_usb rtwn-rtl8188eefw.c optional rtwn-rtl8188eefw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8188eefw.fw:rtwn-rtl8188eefw:111 -mrtwn-rtl8188eefw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8188eefw.c" rtwn-rtl8188eefw.fwo optional rtwn-rtl8188eefw | rtwnfw \ dependency "rtwn-rtl8188eefw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8188eefw.fwo" rtwn-rtl8188eefw.fw optional rtwn-rtl8188eefw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8188eefw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8188eefw.fw" rtwn-rtl8188eufw.c optional rtwn-rtl8188eufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8188eufw.fw:rtwn-rtl8188eufw:111 -mrtwn-rtl8188eufw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8188eufw.c" rtwn-rtl8188eufw.fwo optional rtwn-rtl8188eufw | rtwnfw \ dependency "rtwn-rtl8188eufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8188eufw.fwo" rtwn-rtl8188eufw.fw optional rtwn-rtl8188eufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8188eufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8188eufw.fw" rtwn-rtl8192cfwE.c optional rtwn-rtl8192cfwE | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwE.fw:rtwn-rtl8192cfwE:111 -mrtwn-rtl8192cfwE -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwE.c" rtwn-rtl8192cfwE.fwo optional rtwn-rtl8192cfwE | rtwnfw \ dependency "rtwn-rtl8192cfwE.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwE.fwo" rtwn-rtl8192cfwE.fw optional rtwn-rtl8192cfwE | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwE.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwE.fw" rtwn-rtl8192cfwE_B.c optional rtwn-rtl8192cfwE_B | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwE_B.fw:rtwn-rtl8192cfwE_B:111 -mrtwn-rtl8192cfwE_B -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwE_B.c" rtwn-rtl8192cfwE_B.fwo optional rtwn-rtl8192cfwE_B | rtwnfw \ dependency "rtwn-rtl8192cfwE_B.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwE_B.fwo" rtwn-rtl8192cfwE_B.fw optional rtwn-rtl8192cfwE_B | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwE_B.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwE_B.fw" rtwn-rtl8192cfwT.c optional rtwn-rtl8192cfwT | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwT.fw:rtwn-rtl8192cfwT:111 -mrtwn-rtl8192cfwT -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwT.c" rtwn-rtl8192cfwT.fwo optional rtwn-rtl8192cfwT | rtwnfw \ dependency "rtwn-rtl8192cfwT.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwT.fwo" rtwn-rtl8192cfwT.fw optional rtwn-rtl8192cfwT | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwT.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwT.fw" rtwn-rtl8192cfwU.c optional rtwn-rtl8192cfwU | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwU.fw:rtwn-rtl8192cfwU:111 -mrtwn-rtl8192cfwU -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwU.c" rtwn-rtl8192cfwU.fwo optional rtwn-rtl8192cfwU | rtwnfw \ dependency "rtwn-rtl8192cfwU.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwU.fwo" rtwn-rtl8192cfwU.fw optional rtwn-rtl8192cfwU | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwU.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwU.fw" rtwn-rtl8192eufw.c optional rtwn-rtl8192eufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192eufw.fw:rtwn-rtl8192eufw:111 -mrtwn-rtl8192eufw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8192eufw.c" rtwn-rtl8192eufw.fwo optional rtwn-rtl8192eufw | rtwnfw \ dependency "rtwn-rtl8192eufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192eufw.fwo" rtwn-rtl8192eufw.fw optional rtwn-rtl8192eufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192eufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192eufw.fw" rtwn-rtl8812aufw.c optional rtwn-rtl8812aufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8812aufw.fw:rtwn-rtl8812aufw:111 -mrtwn-rtl8812aufw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8812aufw.c" rtwn-rtl8812aufw.fwo optional rtwn-rtl8812aufw | rtwnfw \ dependency "rtwn-rtl8812aufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8812aufw.fwo" rtwn-rtl8812aufw.fw optional rtwn-rtl8812aufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8812aufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8812aufw.fw" rtwn-rtl8821aufw.c optional rtwn-rtl8821aufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8821aufw.fw:rtwn-rtl8821aufw:111 -mrtwn-rtl8821aufw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rtwn-rtl8821aufw.c" rtwn-rtl8821aufw.fwo optional rtwn-rtl8821aufw | rtwnfw \ dependency "rtwn-rtl8821aufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8821aufw.fwo" rtwn-rtl8821aufw.fw optional rtwn-rtl8821aufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8821aufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8821aufw.fw" dev/safe/safe.c optional safe dev/scc/scc_if.m optional scc dev/scc/scc_bfe_quicc.c optional scc quicc dev/scc/scc_core.c optional scc dev/scc/scc_dev_quicc.c optional scc quicc dev/scc/scc_dev_z8530.c optional scc dev/sdhci/sdhci.c optional sdhci dev/sdhci/sdhci_fdt.c optional sdhci fdt regulator clk dev/sdhci/sdhci_fdt_gpio.c optional sdhci fdt gpio dev/sdhci/sdhci_fsl_fdt.c optional sdhci fdt gpio regulator clk dev/sdhci/sdhci_if.m optional sdhci dev/sdhci/sdhci_acpi.c optional sdhci acpi dev/sdhci/sdhci_pci.c optional sdhci pci dev/sdio/sdio_if.m optional mmccam dev/sdio/sdio_subr.c optional mmccam dev/sdio/sdiob.c optional mmccam dev/sge/if_sge.c optional sge pci dev/siis/siis.c optional siis pci dev/sis/if_sis.c optional sis pci dev/sk/if_sk.c optional sk pci dev/smbios/smbios.c optional smbios dev/smbus/smb.c optional smb dev/smbus/smbconf.c optional smbus dev/smbus/smbus.c optional smbus dev/smbus/smbus_if.m optional smbus dev/smc/if_smc.c optional smc dev/smc/if_smc_acpi.c optional smc acpi dev/smc/if_smc_fdt.c optional smc fdt dev/snp/snp.c optional snp dev/sound/clone.c optional sound dev/sound/unit.c optional sound dev/sound/pci/als4000.c optional snd_als4000 pci dev/sound/pci/atiixp.c optional snd_atiixp pci dev/sound/pci/cmi.c optional snd_cmi pci dev/sound/pci/cs4281.c optional snd_cs4281 pci dev/sound/pci/csa.c optional snd_csa pci dev/sound/pci/csapcm.c optional snd_csa pci dev/sound/pci/emu10k1.c optional snd_emu10k1 pci dev/sound/pci/emu10kx.c optional snd_emu10kx pci dev/sound/pci/emu10kx-pcm.c optional snd_emu10kx pci dev/sound/pci/emu10kx-midi.c optional snd_emu10kx pci dev/sound/pci/envy24.c optional snd_envy24 pci dev/sound/pci/envy24ht.c optional snd_envy24ht pci dev/sound/pci/es137x.c optional snd_es137x pci dev/sound/pci/fm801.c optional snd_fm801 pci dev/sound/pci/ich.c optional snd_ich pci dev/sound/pci/maestro3.c optional snd_maestro3 pci dev/sound/pci/neomagic.c optional snd_neomagic pci dev/sound/pci/solo.c optional snd_solo pci dev/sound/pci/spicds.c optional snd_spicds pci dev/sound/pci/t4dwave.c optional snd_t4dwave pci dev/sound/pci/via8233.c optional snd_via8233 pci dev/sound/pci/via82c686.c optional snd_via82c686 pci dev/sound/pci/vibes.c optional snd_vibes pci dev/sound/pci/hda/hdaa.c optional snd_hda pci dev/sound/pci/hda/hdaa_patches.c optional snd_hda pci dev/sound/pci/hda/hdac.c optional snd_hda pci dev/sound/pci/hda/hdac_if.m optional snd_hda pci dev/sound/pci/hda/hdacc.c optional snd_hda pci dev/sound/pci/hdspe.c optional snd_hdspe pci dev/sound/pci/hdspe-pcm.c optional snd_hdspe pci dev/sound/pcm/ac97.c optional sound dev/sound/pcm/ac97_if.m optional sound dev/sound/pcm/ac97_patch.c optional sound dev/sound/pcm/buffer.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/channel.c optional sound dev/sound/pcm/channel_if.m optional sound dev/sound/pcm/dsp.c optional sound dev/sound/pcm/feeder.c optional sound dev/sound/pcm/feeder_chain.c optional sound dev/sound/pcm/feeder_eq.c optional sound \ dependency "feeder_eq_gen.h" \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_if.m optional sound dev/sound/pcm/feeder_format.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_matrix.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_mixer.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_rate.c optional sound \ dependency "feeder_rate_gen.h" \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_volume.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/mixer.c optional sound dev/sound/pcm/mixer_if.m optional sound dev/sound/pcm/sndstat.c optional sound dev/sound/pcm/sound.c optional sound dev/sound/pcm/vchan.c optional sound dev/sound/usb/uaudio.c optional snd_uaudio usb dev/sound/usb/uaudio_pcm.c optional snd_uaudio usb dev/sound/midi/midi.c optional sound dev/sound/midi/mpu401.c optional sound dev/sound/midi/mpu_if.m optional sound dev/sound/midi/mpufoi_if.m optional sound dev/sound/midi/sequencer.c optional sound dev/sound/midi/synth_if.m optional sound dev/spibus/ofw_spibus.c optional fdt spibus dev/spibus/spibus.c optional spibus \ dependency "spibus_if.h" dev/spibus/spigen.c optional spigen dev/spibus/spibus_if.m optional spibus dev/ste/if_ste.c optional ste pci dev/stge/if_stge.c optional stge dev/sym/sym_hipd.c optional sym \ dependency "$S/dev/sym/sym_{conf,defs}.h" dev/syscons/blank/blank_saver.c optional blank_saver dev/syscons/daemon/daemon_saver.c optional daemon_saver dev/syscons/dragon/dragon_saver.c optional dragon_saver dev/syscons/fade/fade_saver.c optional fade_saver dev/syscons/fire/fire_saver.c optional fire_saver dev/syscons/green/green_saver.c optional green_saver dev/syscons/logo/logo.c optional logo_saver dev/syscons/logo/logo_saver.c optional logo_saver dev/syscons/rain/rain_saver.c optional rain_saver dev/syscons/schistory.c optional sc dev/syscons/scmouse.c optional sc dev/syscons/scterm.c optional sc dev/syscons/scterm-dumb.c optional sc !SC_NO_TERM_DUMB dev/syscons/scterm-sc.c optional sc !SC_NO_TERM_SC dev/syscons/scterm-teken.c optional sc !SC_NO_TERM_TEKEN dev/syscons/scvidctl.c optional sc dev/syscons/scvtb.c optional sc dev/syscons/snake/snake_saver.c optional snake_saver dev/syscons/star/star_saver.c optional star_saver dev/syscons/syscons.c optional sc dev/syscons/sysmouse.c optional sc dev/syscons/warp/warp_saver.c optional warp_saver dev/tcp_log/tcp_log_dev.c optional tcp_blackbox inet | tcp_blackbox inet6 dev/tdfx/tdfx_pci.c optional tdfx pci dev/ti/if_ti.c optional ti pci dev/twe/twe.c optional twe dev/twe/twe_freebsd.c optional twe dev/tws/tws.c optional tws dev/tws/tws_cam.c optional tws dev/tws/tws_hdm.c optional tws dev/tws/tws_services.c optional tws dev/tws/tws_user.c optional tws dev/uart/uart_bus_acpi.c optional uart acpi dev/uart/uart_bus_fdt.c optional uart fdt dev/uart/uart_bus_isa.c optional uart isa dev/uart/uart_bus_pci.c optional uart pci dev/uart/uart_bus_puc.c optional uart puc dev/uart/uart_bus_scc.c optional uart scc dev/uart/uart_core.c optional uart dev/uart/uart_cpu_acpi.c optional uart acpi dev/uart/uart_dbg.c optional uart gdb dev/uart/uart_dev_imx.c optional uart uart_imx fdt dev/uart/uart_dev_msm.c optional uart uart_msm fdt dev/uart/uart_dev_mvebu.c optional uart uart_mvebu fdt dev/uart/uart_dev_ns8250.c optional uart uart_ns8250 | uart uart_snps dev/uart/uart_dev_pl011.c optional uart pl011 dev/uart/uart_dev_quicc.c optional uart quicc dev/uart/uart_dev_snps.c optional uart uart_snps fdt dev/uart/uart_dev_z8530.c optional uart uart_z8530 | uart scc dev/uart/uart_if.m optional uart dev/uart/uart_subr.c optional uart dev/uart/uart_tty.c optional uart # # USB controller drivers # dev/usb/controller/musb_otg.c optional musb dev/usb/controller/dwc_otg.c optional dwcotg dev/usb/controller/dwc_otg_fdt.c optional dwcotg fdt dev/usb/controller/dwc_otg_acpi.c optional dwcotg acpi dev/usb/controller/ehci.c optional ehci dev/usb/controller/ehci_msm.c optional ehci_msm fdt dev/usb/controller/ehci_pci.c optional ehci pci dev/usb/controller/ohci.c optional ohci dev/usb/controller/ohci_pci.c optional ohci pci dev/usb/controller/uhci.c optional uhci dev/usb/controller/uhci_pci.c optional uhci pci dev/usb/controller/xhci.c optional xhci dev/usb/controller/xhci_pci.c optional xhci pci dev/usb/controller/saf1761_otg.c optional saf1761otg dev/usb/controller/saf1761_otg_fdt.c optional saf1761otg fdt dev/usb/controller/uss820dci.c optional uss820dci dev/usb/controller/usb_controller.c optional usb # # USB storage drivers # dev/usb/storage/cfumass.c optional cfumass ctl dev/usb/storage/umass.c optional umass dev/usb/storage/urio.c optional urio dev/usb/storage/ustorage_fs.c optional usfs # # USB core # dev/usb/usb_busdma.c optional usb dev/usb/usb_core.c optional usb dev/usb/usb_debug.c optional usb dev/usb/usb_dev.c optional usb dev/usb/usb_device.c optional usb dev/usb/usb_dynamic.c optional usb dev/usb/usb_error.c optional usb dev/usb/usb_fdt_support.c optional usb fdt dev/usb/usb_generic.c optional usb dev/usb/usb_handle_request.c optional usb dev/usb/usb_hid.c optional usb dev/usb/usb_hub.c optional usb dev/usb/usb_hub_acpi.c optional uacpi acpi dev/usb/usb_if.m optional usb dev/usb/usb_lookup.c optional usb dev/usb/usb_mbuf.c optional usb dev/usb/usb_msctest.c optional usb dev/usb/usb_parse.c optional usb dev/usb/usb_pf.c optional usb dev/usb/usb_process.c optional usb dev/usb/usb_request.c optional usb dev/usb/usb_transfer.c optional usb dev/usb/usb_util.c optional usb # # USB network drivers # dev/usb/net/if_aue.c optional aue dev/usb/net/if_axe.c optional axe dev/usb/net/if_axge.c optional axge dev/usb/net/if_cdce.c optional cdce dev/usb/net/if_cdceem.c optional cdceem dev/usb/net/if_cue.c optional cue dev/usb/net/if_ipheth.c optional ipheth dev/usb/net/if_kue.c optional kue dev/usb/net/if_mos.c optional mos dev/usb/net/if_muge.c optional muge dev/usb/net/if_rue.c optional rue dev/usb/net/if_smsc.c optional smsc dev/usb/net/if_udav.c optional udav dev/usb/net/if_ure.c optional ure dev/usb/net/if_usie.c optional usie dev/usb/net/if_urndis.c optional urndis dev/usb/net/ruephy.c optional rue dev/usb/net/usb_ethernet.c optional uether | aue | axe | axge | cdce | \ cdceem | cue | ipheth | kue | mos | \ rue | smsc | udav | ure | urndis | muge dev/usb/net/uhso.c optional uhso # # USB WLAN drivers # dev/usb/wlan/if_rsu.c optional rsu rsu-rtl8712fw.c optional rsu-rtl8712fw | rsufw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rsu-rtl8712fw.fw:rsu-rtl8712fw:120 -mrsu-rtl8712fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "rsu-rtl8712fw.c" rsu-rtl8712fw.fwo optional rsu-rtl8712fw | rsufw \ dependency "rsu-rtl8712fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rsu-rtl8712fw.fwo" rsu-rtl8712fw.fw optional rsu-rtl8712.fw | rsufw \ dependency "$S/contrib/dev/rsu/rsu-rtl8712fw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rsu-rtl8712fw.fw" dev/usb/wlan/if_rum.c optional rum dev/usb/wlan/if_run.c optional run runfw.c optional runfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk run.fw:runfw -mrunfw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "runfw.c" runfw.fwo optional runfw \ dependency "run.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "runfw.fwo" run.fw optional runfw \ dependency "$S/contrib/dev/run/rt2870.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "run.fw" dev/usb/wlan/if_uath.c optional uath dev/usb/wlan/if_upgt.c optional upgt dev/usb/wlan/if_ural.c optional ural dev/usb/wlan/if_urtw.c optional urtw dev/usb/wlan/if_zyd.c optional zyd # # USB serial and parallel port drivers # dev/usb/serial/u3g.c optional u3g dev/usb/serial/uark.c optional uark dev/usb/serial/ubsa.c optional ubsa dev/usb/serial/ubser.c optional ubser dev/usb/serial/uchcom.c optional uchcom dev/usb/serial/ucycom.c optional ucycom dev/usb/serial/ufoma.c optional ufoma dev/usb/serial/uftdi.c optional uftdi dev/usb/serial/ugensa.c optional ugensa dev/usb/serial/uipaq.c optional uipaq dev/usb/serial/ulpt.c optional ulpt dev/usb/serial/umcs.c optional umcs dev/usb/serial/umct.c optional umct dev/usb/serial/umodem.c optional umodem dev/usb/serial/umoscom.c optional umoscom dev/usb/serial/uplcom.c optional uplcom dev/usb/serial/uslcom.c optional uslcom dev/usb/serial/uvisor.c optional uvisor dev/usb/serial/uvscom.c optional uvscom dev/usb/serial/usb_serial.c optional ucom | u3g | uark | ubsa | ubser | \ uchcom | ucycom | ufoma | uftdi | \ ugensa | uipaq | umcs | umct | \ umodem | umoscom | uplcom | usie | \ uslcom | uvisor | uvscom # # USB misc drivers # dev/usb/misc/cp2112.c optional cp2112 dev/usb/misc/udbp.c optional udbp dev/usb/misc/ugold.c optional ugold dev/usb/misc/uled.c optional uled # # USB input drivers # dev/usb/input/atp.c optional atp dev/usb/input/uep.c optional uep dev/usb/input/uhid.c optional uhid dev/usb/input/uhid_snes.c optional uhid_snes dev/usb/input/ukbd.c optional ukbd dev/usb/input/ums.c optional ums dev/usb/input/usbhid.c optional usbhid dev/usb/input/wmt.c optional wmt dev/usb/input/wsp.c optional wsp # # USB quirks # dev/usb/quirk/usb_quirk.c optional usb # # USB templates # dev/usb/template/usb_template.c optional usb_template dev/usb/template/usb_template_audio.c optional usb_template dev/usb/template/usb_template_cdce.c optional usb_template dev/usb/template/usb_template_kbd.c optional usb_template dev/usb/template/usb_template_modem.c optional usb_template dev/usb/template/usb_template_mouse.c optional usb_template dev/usb/template/usb_template_msc.c optional usb_template dev/usb/template/usb_template_mtp.c optional usb_template dev/usb/template/usb_template_phone.c optional usb_template dev/usb/template/usb_template_serialnet.c optional usb_template dev/usb/template/usb_template_midi.c optional usb_template dev/usb/template/usb_template_multi.c optional usb_template dev/usb/template/usb_template_cdceem.c optional usb_template # # USB video drivers # dev/usb/video/udl.c optional udl # # USB END # dev/videomode/videomode.c optional videomode dev/videomode/edid.c optional videomode dev/videomode/pickmode.c optional videomode dev/videomode/vesagtf.c optional videomode dev/veriexec/verified_exec.c optional mac_veriexec dev/vge/if_vge.c optional vge dev/viapm/viapm.c optional viapm pci dev/virtio/virtio.c optional virtio dev/virtio/virtqueue.c optional virtio dev/virtio/virtio_bus_if.m optional virtio dev/virtio/virtio_if.m optional virtio dev/virtio/pci/virtio_pci.c optional virtio_pci dev/virtio/pci/virtio_pci_if.m optional virtio_pci dev/virtio/pci/virtio_pci_legacy.c optional virtio_pci dev/virtio/pci/virtio_pci_modern.c optional virtio_pci dev/virtio/mmio/virtio_mmio.c optional virtio_mmio dev/virtio/mmio/virtio_mmio_acpi.c optional virtio_mmio acpi dev/virtio/mmio/virtio_mmio_cmdline.c optional virtio_mmio dev/virtio/mmio/virtio_mmio_fdt.c optional virtio_mmio fdt dev/virtio/mmio/virtio_mmio_if.m optional virtio_mmio dev/virtio/network/if_vtnet.c optional vtnet dev/virtio/block/virtio_blk.c optional virtio_blk dev/virtio/balloon/virtio_balloon.c optional virtio_balloon dev/virtio/scsi/virtio_scsi.c optional virtio_scsi dev/virtio/random/virtio_random.c optional virtio_random dev/virtio/console/virtio_console.c optional virtio_console dev/vkbd/vkbd.c optional vkbd dev/vmgenc/vmgenc_acpi.c optional acpi dev/vmware/vmxnet3/if_vmx.c optional vmx dev/vmware/vmci/vmci.c optional vmci dev/vmware/vmci/vmci_datagram.c optional vmci dev/vmware/vmci/vmci_doorbell.c optional vmci dev/vmware/vmci/vmci_driver.c optional vmci dev/vmware/vmci/vmci_event.c optional vmci dev/vmware/vmci/vmci_hashtable.c optional vmci dev/vmware/vmci/vmci_kernel_if.c optional vmci dev/vmware/vmci/vmci_qpair.c optional vmci dev/vmware/vmci/vmci_queue_pair.c optional vmci dev/vmware/vmci/vmci_resource.c optional vmci dev/vmware/pvscsi/pvscsi.c optional pvscsi dev/vr/if_vr.c optional vr pci dev/vt/colors/vt_termcolors.c optional vt dev/vt/font/vt_font_default.c optional vt dev/vt/font/vt_mouse_cursor.c optional vt dev/vt/hw/efifb/efifb.c optional vt_efifb dev/vt/hw/vbefb/vbefb.c optional vt_vbefb dev/vt/hw/fb/vt_fb.c optional vt dev/vt/hw/vga/vt_vga.c optional vt vt_vga dev/vt/logo/logo_freebsd.c optional vt splash dev/vt/logo/logo_beastie.c optional vt splash dev/vt/vt_buf.c optional vt dev/vt/vt_consolectl.c optional vt dev/vt/vt_core.c optional vt dev/vt/vt_cpulogos.c optional vt splash dev/vt/vt_font.c optional vt dev/vt/vt_sysmouse.c optional vt dev/vte/if_vte.c optional vte pci dev/watchdog/watchdog.c standard dev/wg/if_wg.c optional wg \ compile-with "${NORMAL_C} -include $S/dev/wg/compat.h" dev/wg/wg_cookie.c optional wg \ compile-with "${NORMAL_C} -include $S/dev/wg/compat.h" dev/wg/wg_crypto.c optional wg \ compile-with "${NORMAL_C} -include $S/dev/wg/compat.h" dev/wg/wg_noise.c optional wg \ compile-with "${NORMAL_C} -include $S/dev/wg/compat.h" dev/wpi/if_wpi.c optional wpi pci wpifw.c optional wpifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk wpi.fw:wpifw:153229 -mwpi -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "wpifw.c" wpifw.fwo optional wpifw \ dependency "wpi.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "wpifw.fwo" wpi.fw optional wpifw \ dependency "$S/contrib/dev/wpi/iwlwifi-3945-15.32.2.9.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "wpi.fw" dev/xdma/controller/pl330.c optional xdma pl330 fdt dev/xdma/xdma.c optional xdma dev/xdma/xdma_bank.c optional xdma dev/xdma/xdma_bio.c optional xdma dev/xdma/xdma_fdt_test.c optional xdma xdma_test fdt dev/xdma/xdma_if.m optional xdma dev/xdma/xdma_iommu.c optional xdma dev/xdma/xdma_mbuf.c optional xdma dev/xdma/xdma_queue.c optional xdma dev/xdma/xdma_sg.c optional xdma dev/xdma/xdma_sglist.c optional xdma dev/xen/balloon/balloon.c optional xenhvm dev/xen/blkfront/blkfront.c optional xenhvm dev/xen/blkback/blkback.c optional xenhvm dev/xen/bus/xenpv.c optional xenhvm dev/xen/console/xen_console.c optional xenhvm dev/xen/control/control.c optional xenhvm dev/xen/cpu/xen_acpi_cpu.c optional xenhvm dev/xen/efi/pvefi.c optional xenhvm efirt dev/xen/grant_table/grant_table.c optional xenhvm dev/xen/netback/netback.c optional xenhvm dev/xen/netfront/netfront.c optional xenhvm dev/xen/timer/timer.c optional xenhvm xentimer dev/xen/xenpci/xenpci.c optional xenpci dev/xen/xenstore/xenstore.c optional xenhvm dev/xen/xenstore/xenstore_dev.c optional xenhvm dev/xen/xenstore/xenstored_dev.c optional xenhvm dev/xen/evtchn/evtchn_dev.c optional xenhvm dev/xen/privcmd/privcmd.c optional xenhvm dev/xen/gntdev/gntdev.c optional xenhvm dev/xen/debug/debug.c optional xenhvm dev/xl/if_xl.c optional xl pci dev/xl/xlphy.c optional xl pci fs/autofs/autofs.c optional autofs fs/autofs/autofs_vfsops.c optional autofs fs/autofs/autofs_vnops.c optional autofs fs/deadfs/dead_vnops.c standard fs/devfs/devfs_devs.c standard fs/devfs/devfs_dir.c standard fs/devfs/devfs_rule.c standard fs/devfs/devfs_vfsops.c standard fs/devfs/devfs_vnops.c standard fs/fdescfs/fdesc_vfsops.c optional fdescfs fs/fdescfs/fdesc_vnops.c optional fdescfs fs/fifofs/fifo_vnops.c standard fs/cuse/cuse.c optional cuse fs/fuse/fuse_device.c optional fusefs fs/fuse/fuse_file.c optional fusefs fs/fuse/fuse_internal.c optional fusefs fs/fuse/fuse_io.c optional fusefs fs/fuse/fuse_ipc.c optional fusefs fs/fuse/fuse_main.c optional fusefs fs/fuse/fuse_node.c optional fusefs fs/fuse/fuse_vfsops.c optional fusefs fs/fuse/fuse_vnops.c optional fusefs fs/mntfs/mntfs_vnops.c standard fs/msdosfs/msdosfs_conv.c optional msdosfs fs/msdosfs/msdosfs_denode.c optional msdosfs fs/msdosfs/msdosfs_fat.c optional msdosfs fs/msdosfs/msdosfs_iconv.c optional msdosfs_iconv fs/msdosfs/msdosfs_lookup.c optional msdosfs fs/msdosfs/msdosfs_vfsops.c optional msdosfs fs/msdosfs/msdosfs_vnops.c optional msdosfs fs/nfs/nfs_commonkrpc.c optional nfscl | nfslockd | nfsd fs/nfs/nfs_commonsubs.c optional nfscl | nfslockd | nfsd fs/nfs/nfs_commonport.c optional nfscl | nfslockd | nfsd fs/nfs/nfs_commonacl.c optional nfscl | nfslockd | nfsd fs/nfsclient/nfs_clcomsubs.c optional nfscl fs/nfsclient/nfs_clsubs.c optional nfscl fs/nfsclient/nfs_clstate.c optional nfscl fs/nfsclient/nfs_clkrpc.c optional nfscl fs/nfsclient/nfs_clrpcops.c optional nfscl fs/nfsclient/nfs_clvnops.c optional nfscl fs/nfsclient/nfs_clnode.c optional nfscl fs/nfsclient/nfs_clvfsops.c optional nfscl fs/nfsclient/nfs_clport.c optional nfscl fs/nfsclient/nfs_clbio.c optional nfscl fs/nfsclient/nfs_clnfsiod.c optional nfscl fs/nfsserver/nfs_fha_new.c optional nfsd inet fs/nfsserver/nfs_nfsdsocket.c optional nfsd inet fs/nfsserver/nfs_nfsdsubs.c optional nfsd inet fs/nfsserver/nfs_nfsdstate.c optional nfsd inet fs/nfsserver/nfs_nfsdkrpc.c optional nfsd inet fs/nfsserver/nfs_nfsdserv.c optional nfsd inet fs/nfsserver/nfs_nfsdport.c optional nfsd inet fs/nfsserver/nfs_nfsdcache.c optional nfsd inet fs/nullfs/null_subr.c optional nullfs fs/nullfs/null_vfsops.c optional nullfs fs/nullfs/null_vnops.c optional nullfs fs/procfs/procfs.c optional procfs fs/procfs/procfs_dbregs.c optional procfs fs/procfs/procfs_fpregs.c optional procfs fs/procfs/procfs_map.c optional procfs fs/procfs/procfs_mem.c optional procfs fs/procfs/procfs_note.c optional procfs fs/procfs/procfs_osrel.c optional procfs fs/procfs/procfs_regs.c optional procfs fs/procfs/procfs_rlimit.c optional procfs fs/procfs/procfs_status.c optional procfs fs/procfs/procfs_type.c optional procfs fs/pseudofs/pseudofs.c optional pseudofs fs/pseudofs/pseudofs_fileno.c optional pseudofs fs/pseudofs/pseudofs_vncache.c optional pseudofs fs/pseudofs/pseudofs_vnops.c optional pseudofs fs/smbfs/smbfs_io.c optional smbfs fs/smbfs/smbfs_node.c optional smbfs fs/smbfs/smbfs_smb.c optional smbfs fs/smbfs/smbfs_subr.c optional smbfs fs/smbfs/smbfs_vfsops.c optional smbfs fs/smbfs/smbfs_vnops.c optional smbfs fs/udf/osta.c optional udf fs/udf/udf_iconv.c optional udf_iconv fs/udf/udf_vfsops.c optional udf fs/udf/udf_vnops.c optional udf fs/unionfs/union_subr.c optional unionfs fs/unionfs/union_vfsops.c optional unionfs fs/unionfs/union_vnops.c optional unionfs fs/tmpfs/tmpfs_vnops.c optional tmpfs fs/tmpfs/tmpfs_fifoops.c optional tmpfs fs/tmpfs/tmpfs_vfsops.c optional tmpfs fs/tmpfs/tmpfs_subr.c optional tmpfs gdb/gdb_cons.c optional gdb gdb/gdb_main.c optional gdb gdb/gdb_packet.c optional gdb gdb/netgdb.c optional ddb debugnet gdb netgdb inet geom/bde/g_bde.c optional geom_bde geom/bde/g_bde_crypt.c optional geom_bde geom/bde/g_bde_lock.c optional geom_bde geom/bde/g_bde_work.c optional geom_bde geom/cache/g_cache.c optional geom_cache geom/concat/g_concat.c optional geom_concat geom/eli/g_eli.c optional geom_eli geom/eli/g_eli_crypto.c optional geom_eli geom/eli/g_eli_ctl.c optional geom_eli geom/eli/g_eli_hmac.c optional geom_eli geom/eli/g_eli_integrity.c optional geom_eli geom/eli/g_eli_key.c optional geom_eli geom/eli/g_eli_key_cache.c optional geom_eli geom/eli/g_eli_privacy.c optional geom_eli geom/eli/pkcs5v2.c optional geom_eli geom/gate/g_gate.c optional geom_gate geom/geom_bsd_enc.c optional geom_part_bsd geom/geom_ccd.c optional ccd | geom_ccd geom/geom_ctl.c standard geom/geom_dev.c standard geom/geom_disk.c standard geom/geom_dump.c standard geom/geom_event.c standard geom/geom_flashmap.c optional fdt cfi | fdt mx25l | mmcsd | fdt n25q | fdt at45d geom/geom_io.c standard geom/geom_kern.c standard geom/geom_map.c optional geom_map geom/geom_redboot.c optional geom_redboot geom/geom_slice.c standard geom/geom_subr.c standard geom/geom_vfs.c standard geom/journal/g_journal.c optional geom_journal geom/journal/g_journal_ufs.c optional geom_journal geom/label/g_label.c optional geom_label | geom_label_gpt geom/label/g_label_ext2fs.c optional geom_label geom/label/g_label_flashmap.c optional geom_label geom/label/g_label_iso9660.c optional geom_label geom/label/g_label_msdosfs.c optional geom_label geom/label/g_label_ntfs.c optional geom_label geom/label/g_label_reiserfs.c optional geom_label geom/label/g_label_ufs.c optional geom_label geom/label/g_label_gpt.c optional geom_label | geom_label_gpt geom/label/g_label_disk_ident.c optional geom_label geom/linux_lvm/g_linux_lvm.c optional geom_linux_lvm geom/mirror/g_mirror.c optional geom_mirror geom/mirror/g_mirror_ctl.c optional geom_mirror geom/mountver/g_mountver.c optional geom_mountver geom/multipath/g_multipath.c optional geom_multipath geom/nop/g_nop.c optional geom_nop geom/part/g_part.c standard geom/part/g_part_if.m standard geom/part/g_part_apm.c optional geom_part_apm geom/part/g_part_bsd.c optional geom_part_bsd geom/part/g_part_bsd64.c optional geom_part_bsd64 geom/part/g_part_ebr.c optional geom_part_ebr geom/part/g_part_gpt.c optional geom_part_gpt geom/part/g_part_ldm.c optional geom_part_ldm geom/part/g_part_mbr.c optional geom_part_mbr geom/part/g_part_vtoc8.c optional geom_part_vtoc8 geom/raid/g_raid.c optional geom_raid geom/raid/g_raid_ctl.c optional geom_raid geom/raid/g_raid_md_if.m optional geom_raid geom/raid/g_raid_tr_if.m optional geom_raid geom/raid/md_ddf.c optional geom_raid geom/raid/md_intel.c optional geom_raid geom/raid/md_jmicron.c optional geom_raid geom/raid/md_nvidia.c optional geom_raid geom/raid/md_promise.c optional geom_raid geom/raid/md_sii.c optional geom_raid geom/raid/tr_concat.c optional geom_raid geom/raid/tr_raid0.c optional geom_raid geom/raid/tr_raid1.c optional geom_raid geom/raid/tr_raid1e.c optional geom_raid geom/raid/tr_raid5.c optional geom_raid geom/raid3/g_raid3.c optional geom_raid3 geom/raid3/g_raid3_ctl.c optional geom_raid3 geom/shsec/g_shsec.c optional geom_shsec geom/stripe/g_stripe.c optional geom_stripe geom/union/g_union.c optional geom_union geom/uzip/g_uzip.c optional geom_uzip geom/uzip/g_uzip_lzma.c optional geom_uzip geom/uzip/g_uzip_wrkthr.c optional geom_uzip geom/uzip/g_uzip_zlib.c optional geom_uzip geom/uzip/g_uzip_zstd.c optional geom_uzip zstdio \ compile-with "${NORMAL_C} -I$S/contrib/zstd/lib/freebsd" geom/vinum/geom_vinum.c optional geom_vinum geom/vinum/geom_vinum_create.c optional geom_vinum geom/vinum/geom_vinum_drive.c optional geom_vinum geom/vinum/geom_vinum_plex.c optional geom_vinum geom/vinum/geom_vinum_volume.c optional geom_vinum geom/vinum/geom_vinum_subr.c optional geom_vinum geom/vinum/geom_vinum_raid5.c optional geom_vinum geom/vinum/geom_vinum_share.c optional geom_vinum geom/vinum/geom_vinum_list.c optional geom_vinum geom/vinum/geom_vinum_rm.c optional geom_vinum geom/vinum/geom_vinum_init.c optional geom_vinum geom/vinum/geom_vinum_state.c optional geom_vinum geom/vinum/geom_vinum_rename.c optional geom_vinum geom/vinum/geom_vinum_move.c optional geom_vinum geom/vinum/geom_vinum_events.c optional geom_vinum geom/virstor/binstream.c optional geom_virstor geom/virstor/g_virstor.c optional geom_virstor geom/virstor/g_virstor_md.c optional geom_virstor geom/zero/g_zero.c optional geom_zero fs/ext2fs/ext2_acl.c optional ext2fs fs/ext2fs/ext2_alloc.c optional ext2fs fs/ext2fs/ext2_balloc.c optional ext2fs fs/ext2fs/ext2_bmap.c optional ext2fs fs/ext2fs/ext2_csum.c optional ext2fs fs/ext2fs/ext2_extattr.c optional ext2fs fs/ext2fs/ext2_extents.c optional ext2fs fs/ext2fs/ext2_inode.c optional ext2fs fs/ext2fs/ext2_inode_cnv.c optional ext2fs fs/ext2fs/ext2_hash.c optional ext2fs fs/ext2fs/ext2_htree.c optional ext2fs fs/ext2fs/ext2_lookup.c optional ext2fs fs/ext2fs/ext2_subr.c optional ext2fs fs/ext2fs/ext2_vfsops.c optional ext2fs fs/ext2fs/ext2_vnops.c optional ext2fs # isa/isa_if.m standard isa/isa_common.c optional isa isa/isahint.c optional isa isa/pnp.c optional isa isapnp isa/pnpparse.c optional isa isapnp fs/cd9660/cd9660_bmap.c optional cd9660 fs/cd9660/cd9660_lookup.c optional cd9660 fs/cd9660/cd9660_node.c optional cd9660 fs/cd9660/cd9660_rrip.c optional cd9660 fs/cd9660/cd9660_util.c optional cd9660 fs/cd9660/cd9660_vfsops.c optional cd9660 fs/cd9660/cd9660_vnops.c optional cd9660 fs/cd9660/cd9660_iconv.c optional cd9660_iconv gnu/gcov/gcc_4_7.c optional gcov \ warning "kernel contains GPL licensed gcov support" gnu/gcov/gcov_fs.c optional gcov lindebugfs \ compile-with "${LINUXKPI_C}" gnu/gcov/gcov_subr.c optional gcov kern/bus_if.m standard kern/clock_if.m standard kern/cpufreq_if.m standard kern/device_if.m standard kern/imgact_binmisc.c optional imgact_binmisc kern/imgact_elf.c standard kern/imgact_elf32.c optional compat_freebsd32 kern/imgact_shell.c standard kern/init_main.c standard kern/init_sysent.c standard kern/ksched.c optional _kposix_priority_scheduling kern/kern_acct.c standard kern/kern_alq.c optional alq kern/kern_boottrace.c standard kern/kern_clock.c standard kern/kern_clocksource.c standard kern/kern_condvar.c standard kern/kern_conf.c standard kern/kern_cons.c standard kern/kern_cpu.c standard kern/kern_cpuset.c standard kern/kern_context.c standard kern/kern_descrip.c standard kern/kern_devctl.c standard kern/kern_dtrace.c optional kdtrace_hooks kern/kern_dump.c standard kern/kern_environment.c standard kern/kern_et.c standard kern/kern_event.c standard kern/kern_exec.c standard kern/kern_exit.c standard kern/kern_fail.c standard kern/kern_ffclock.c standard kern/kern_fork.c standard kern/kern_hhook.c standard kern/kern_idle.c standard kern/kern_intr.c standard kern/kern_jail.c standard kern/kern_kcov.c optional kcov \ compile-with "${NORMAL_C:N-fsanitize*} ${NORMAL_C:M-fsanitize=kernel-memory}" kern/kern_khelp.c standard kern/kern_kthread.c standard kern/kern_ktr.c optional ktr kern/kern_ktrace.c standard kern/kern_linker.c standard kern/kern_lock.c standard kern/kern_lockf.c standard kern/kern_lockstat.c optional kdtrace_hooks kern/kern_loginclass.c standard kern/kern_malloc.c standard kern/kern_mbuf.c standard kern/kern_mib.c standard kern/kern_module.c standard kern/kern_mtxpool.c standard kern/kern_mutex.c standard kern/kern_ntptime.c standard kern/kern_osd.c standard kern/kern_physio.c standard kern/kern_pmc.c standard kern/kern_poll.c optional device_polling kern/kern_priv.c standard kern/kern_proc.c standard kern/kern_procctl.c standard kern/kern_prot.c standard kern/kern_racct.c standard kern/kern_rangelock.c standard kern/kern_rctl.c standard kern/kern_resource.c standard kern/kern_rmlock.c standard kern/kern_rwlock.c standard kern/kern_sdt.c optional kdtrace_hooks kern/kern_sema.c standard kern/kern_sendfile.c standard kern/kern_sharedpage.c standard kern/kern_shutdown.c standard kern/kern_sig.c standard kern/kern_switch.c standard kern/kern_sx.c standard kern/kern_synch.c standard kern/kern_syscalls.c standard kern/kern_sysctl.c standard kern/kern_tc.c standard kern/kern_thr.c standard kern/kern_thread.c standard kern/kern_time.c standard kern/kern_timeout.c standard kern/kern_tslog.c optional tslog kern/kern_ubsan.c optional kubsan kern/kern_umtx.c standard kern/kern_uuid.c standard kern/kern_vnodedumper.c standard kern/kern_xxx.c standard kern/link_elf.c standard kern/linker_if.m standard kern/md4c.c optional netsmb kern/md5c.c standard kern/p1003_1b.c standard kern/posix4_mib.c standard kern/sched_4bsd.c optional sched_4bsd kern/sched_ule.c optional sched_ule kern/serdev_if.m standard kern/stack_protector.c standard \ compile-with "${NORMAL_C:N-fstack-protector*}" kern/subr_acl_nfs4.c optional ufs_acl | zfs kern/subr_acl_posix1e.c optional ufs_acl kern/subr_asan.c optional kasan \ compile-with "${NORMAL_C:N-fsanitize*:N-fstack-protector*}" kern/subr_autoconf.c standard kern/subr_blist.c standard kern/subr_boot.c standard kern/subr_bus.c standard kern/subr_bus_dma.c standard kern/subr_bufring.c standard kern/subr_capability.c standard kern/subr_clock.c standard kern/subr_compressor.c standard \ compile-with "${NORMAL_C} -I$S/contrib/zstd/lib/freebsd" kern/subr_coverage.c optional coverage \ compile-with "${NORMAL_C:N-fsanitize*}" kern/subr_counter.c standard kern/subr_csan.c optional kcsan \ compile-with "${NORMAL_C:N-fsanitize*:N-fstack-protector*}" kern/subr_devstat.c standard kern/subr_disk.c standard kern/subr_early.c standard kern/subr_epoch.c standard kern/subr_eventhandler.c standard kern/subr_fattime.c standard kern/subr_firmware.c optional firmware kern/subr_filter.c standard kern/subr_gtaskqueue.c standard kern/subr_hash.c standard kern/subr_hints.c standard kern/subr_kdb.c standard kern/subr_kobj.c standard kern/subr_lock.c standard kern/subr_log.c standard kern/subr_mchain.c optional libmchain kern/subr_module.c standard kern/subr_msan.c optional kmsan \ compile-with "${NORMAL_C:N-fsanitize*:N-fstack-protector*}" kern/subr_msgbuf.c standard kern/subr_param.c standard kern/subr_pcpu.c standard kern/subr_pctrie.c standard kern/subr_pidctrl.c standard kern/subr_power.c standard kern/subr_prf.c standard kern/subr_prng.c standard kern/subr_prof.c standard kern/subr_rangeset.c standard kern/subr_rman.c standard kern/subr_rtc.c standard kern/subr_sbuf.c standard kern/subr_scanf.c standard kern/subr_sglist.c standard kern/subr_sleepqueue.c standard kern/subr_smp.c standard kern/subr_smr.c standard kern/subr_stack.c optional ddb | stack | ktr kern/subr_stats.c optional stats kern/subr_taskqueue.c standard kern/subr_terminal.c optional vt kern/subr_trap.c standard kern/subr_turnstile.c standard kern/subr_uio.c standard kern/subr_unit.c standard kern/subr_vmem.c standard kern/subr_witness.c optional witness kern/sys_capability.c standard kern/sys_eventfd.c standard kern/sys_generic.c standard kern/sys_getrandom.c standard kern/sys_pipe.c standard kern/sys_procdesc.c standard kern/sys_process.c standard kern/sys_socket.c standard kern/syscalls.c standard kern/sysv_ipc.c standard kern/sysv_msg.c optional sysvmsg kern/sysv_sem.c optional sysvsem kern/sysv_shm.c optional sysvshm kern/tty.c standard kern/tty_compat.c optional compat_43tty kern/tty_info.c standard kern/tty_inq.c standard kern/tty_outq.c standard kern/tty_pts.c standard kern/tty_tty.c standard kern/tty_ttydisc.c standard kern/uipc_accf.c standard kern/uipc_debug.c optional ddb kern/uipc_domain.c standard kern/uipc_ktls.c optional kern_tls kern/uipc_mbuf.c standard kern/uipc_mbuf2.c standard kern/uipc_mbufhash.c standard kern/uipc_mqueue.c optional p1003_1b_mqueue kern/uipc_sem.c optional p1003_1b_semaphores kern/uipc_shm.c standard kern/uipc_sockbuf.c standard kern/uipc_socket.c standard kern/uipc_syscalls.c standard kern/uipc_usrreq.c standard kern/vfs_acl.c standard kern/vfs_aio.c standard kern/vfs_bio.c standard kern/vfs_cache.c standard kern/vfs_cluster.c standard kern/vfs_default.c standard kern/vfs_export.c standard kern/vfs_extattr.c standard kern/vfs_hash.c standard kern/vfs_init.c standard kern/vfs_lookup.c standard kern/vfs_mount.c standard kern/vfs_mountroot.c standard kern/vfs_subr.c standard kern/vfs_syscalls.c standard kern/vfs_vnops.c standard # # Kernel GSS-API # gssd.h optional kgssapi \ dependency "$S/kgssapi/gssd.x" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -hM $S/kgssapi/gssd.x | grep -v pthread.h > gssd.h" \ no-obj no-implicit-rule before-depend local \ clean "gssd.h" gssd_xdr.c optional kgssapi \ dependency "$S/kgssapi/gssd.x gssd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -c $S/kgssapi/gssd.x -o gssd_xdr.c" \ no-ctfconvert no-implicit-rule before-depend local \ clean "gssd_xdr.c" gssd_clnt.c optional kgssapi \ dependency "$S/kgssapi/gssd.x gssd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -lM $S/kgssapi/gssd.x | grep -v string.h > gssd_clnt.c" \ no-ctfconvert no-implicit-rule before-depend local \ clean "gssd_clnt.c" kgssapi/gss_accept_sec_context.c optional kgssapi kgssapi/gss_add_oid_set_member.c optional kgssapi kgssapi/gss_acquire_cred.c optional kgssapi kgssapi/gss_canonicalize_name.c optional kgssapi kgssapi/gss_create_empty_oid_set.c optional kgssapi kgssapi/gss_delete_sec_context.c optional kgssapi kgssapi/gss_display_status.c optional kgssapi kgssapi/gss_export_name.c optional kgssapi kgssapi/gss_get_mic.c optional kgssapi kgssapi/gss_init_sec_context.c optional kgssapi kgssapi/gss_impl.c optional kgssapi kgssapi/gss_import_name.c optional kgssapi kgssapi/gss_names.c optional kgssapi kgssapi/gss_pname_to_uid.c optional kgssapi kgssapi/gss_release_buffer.c optional kgssapi kgssapi/gss_release_cred.c optional kgssapi kgssapi/gss_release_name.c optional kgssapi kgssapi/gss_release_oid_set.c optional kgssapi kgssapi/gss_set_cred_option.c optional kgssapi kgssapi/gss_test_oid_set_member.c optional kgssapi kgssapi/gss_unwrap.c optional kgssapi kgssapi/gss_verify_mic.c optional kgssapi kgssapi/gss_wrap.c optional kgssapi kgssapi/gss_wrap_size_limit.c optional kgssapi kgssapi/gssd_prot.c optional kgssapi kgssapi/krb5/krb5_mech.c optional kgssapi kgssapi/krb5/kcrypto.c optional kgssapi kgssapi/krb5/kcrypto_aes.c optional kgssapi kgssapi/kgss_if.m optional kgssapi kgssapi/gsstest.c optional kgssapi_debug # These files in libkern/ are those needed by all architectures. Some # of the files in libkern/ are only needed on some architectures, e.g., # libkern/divdi3.c is needed by i386 but not alpha. Also, some of these # routines may be optimized for a particular platform. In either case, # the file should be moved to conf/files. from here. # libkern/arc4random.c standard libkern/arc4random_uniform.c standard libkern/asprintf.c standard libkern/bcd.c standard libkern/bsearch.c standard libkern/explicit_bzero.c standard libkern/fnmatch.c standard libkern/gsb_crc32.c standard libkern/iconv.c optional libiconv libkern/iconv_converter_if.m optional libiconv libkern/iconv_ucs.c optional libiconv libkern/iconv_xlat.c optional libiconv libkern/iconv_xlat16.c optional libiconv libkern/inet_aton.c standard libkern/inet_ntoa.c standard libkern/inet_ntop.c standard libkern/inet_pton.c standard libkern/jenkins_hash.c standard libkern/murmur3_32.c standard libkern/memcchr.c standard libkern/memchr.c standard libkern/memmem.c optional gdb libkern/qsort.c standard libkern/qsort_r.c standard libkern/random.c standard libkern/scanc.c standard libkern/strcasecmp.c standard libkern/strcasestr.c standard libkern/strcat.c standard libkern/strchr.c standard libkern/strchrnul.c optional gdb libkern/strcpy.c standard libkern/strcspn.c standard libkern/strdup.c standard libkern/strndup.c standard libkern/strlcat.c standard libkern/strlcpy.c standard libkern/strncat.c standard libkern/strncpy.c standard libkern/strnlen.c standard libkern/strnstr.c standard libkern/strrchr.c standard libkern/strsep.c standard libkern/strspn.c standard libkern/strstr.c standard libkern/strtol.c standard libkern/strtoq.c standard libkern/strtoul.c standard libkern/strtouq.c standard libkern/strvalid.c standard libkern/timingsafe_bcmp.c standard contrib/zlib/adler32.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib contrib/zlib/compress.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${NORMAL_C} -Wno-cast-qual" contrib/zlib/crc32.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${NORMAL_C} ${NO_WSTRICT_PROTOTYPES}" contrib/zlib/deflate.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${NORMAL_C} -Wno-cast-qual" contrib/zlib/inffast.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib contrib/zlib/inflate.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib contrib/zlib/inftrees.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib contrib/zlib/trees.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${NORMAL_C} ${NO_WSTRICT_PROTOTYPES}" contrib/zlib/uncompr.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${NORMAL_C} -Wno-cast-qual" contrib/zlib/zutil.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib \ compile-with "${NORMAL_C} ${NO_WSTRICT_PROTOTYPES}" dev/zlib/zlib_mod.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib dev/zlib/zcalloc.c optional crypto | geom_uzip | \ mxge | ddb_ctf | gzio | zfs | zlib net/altq/altq_cbq.c optional altq net/altq/altq_codel.c optional altq net/altq/altq_hfsc.c optional altq net/altq/altq_fairq.c optional altq net/altq/altq_priq.c optional altq net/altq/altq_red.c optional altq net/altq/altq_rio.c optional altq net/altq/altq_rmclass.c optional altq net/altq/altq_subr.c optional altq net/bpf.c standard net/bpf_buffer.c optional bpf net/bpf_jitter.c optional bpf_jitter net/bpf_filter.c optional bpf | netgraph_bpf net/bpf_zerocopy.c optional bpf net/bridgestp.c optional bridge | if_bridge net/ieee8023ad_lacp.c optional lagg net/if.c standard net/if_bridge.c optional bridge inet | if_bridge inet net/if_clone.c standard net/if_dead.c standard net/if_disc.c optional disc net/if_edsc.c optional edsc net/if_enc.c optional enc inet | enc inet6 net/if_epair.c optional epair net/if_ethersubr.c optional ether net/if_fwsubr.c optional fwip net/if_gif.c optional gif inet | gif inet6 | \ netgraph_gif inet | netgraph_gif inet6 net/if_gre.c optional gre inet | gre inet6 net/if_ipsec.c optional inet ipsec | inet6 ipsec net/if_lagg.c optional lagg net/if_loop.c optional loop net/if_llatbl.c standard net/if_me.c optional me inet net/if_media.c standard net/if_mib.c standard net/if_ovpn.c optional ovpn inet | ovpn inet6 net/if_stf.c optional stf inet inet6 net/if_tuntap.c optional tuntap net/if_vlan.c optional vlan net/if_vxlan.c optional vxlan inet | vxlan inet6 net/ifdi_if.m optional ether pci iflib net/iflib.c optional ether pci iflib net/iflib_clone.c optional ether pci iflib net/mp_ring.c optional ether iflib net/mppcc.c optional netgraph_mppc_compression net/mppcd.c optional netgraph_mppc_compression net/netisr.c standard net/debugnet.c optional inet debugnet net/debugnet_inet.c optional inet debugnet net/pfil.c optional ether | inet net/radix.c standard net/route.c standard net/route/nhgrp.c optional route_mpath net/route/nhgrp_ctl.c optional route_mpath net/route/nhop.c standard net/route/nhop_ctl.c standard net/route/nhop_utils.c standard net/route/fib_algo.c optional fib_algo net/route/route_ctl.c standard net/route/route_ddb.c optional ddb net/route/route_helpers.c standard net/route/route_ifaddrs.c standard net/route/route_rtentry.c standard net/route/route_subscription.c standard net/route/route_tables.c standard net/route/route_temporal.c standard net/rss_config.c optional inet rss | inet6 rss net/rtsock.c standard net/slcompress.c optional netgraph_vjc net/toeplitz.c optional inet rss | inet6 rss | route_mpath net/vnet.c optional vimage net80211/ieee80211.c optional wlan net80211/ieee80211_acl.c optional wlan wlan_acl net80211/ieee80211_action.c optional wlan net80211/ieee80211_adhoc.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_ageq.c optional wlan net80211/ieee80211_amrr.c optional wlan | wlan_amrr net80211/ieee80211_crypto.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_crypto_ccmp.c optional wlan wlan_ccmp net80211/ieee80211_crypto_none.c optional wlan net80211/ieee80211_crypto_tkip.c optional wlan wlan_tkip net80211/ieee80211_crypto_wep.c optional wlan wlan_wep net80211/ieee80211_ddb.c optional wlan ddb net80211/ieee80211_dfs.c optional wlan net80211/ieee80211_freebsd.c optional wlan net80211/ieee80211_hostap.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_ht.c optional wlan net80211/ieee80211_hwmp.c optional wlan ieee80211_support_mesh net80211/ieee80211_input.c optional wlan net80211/ieee80211_ioctl.c optional wlan net80211/ieee80211_mesh.c optional wlan ieee80211_support_mesh \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_monitor.c optional wlan net80211/ieee80211_node.c optional wlan net80211/ieee80211_output.c optional wlan net80211/ieee80211_phy.c optional wlan net80211/ieee80211_power.c optional wlan net80211/ieee80211_proto.c optional wlan net80211/ieee80211_radiotap.c optional wlan net80211/ieee80211_ratectl.c optional wlan net80211/ieee80211_ratectl_none.c optional wlan net80211/ieee80211_regdomain.c optional wlan net80211/ieee80211_rssadapt.c optional wlan wlan_rssadapt net80211/ieee80211_scan.c optional wlan net80211/ieee80211_scan_sta.c optional wlan net80211/ieee80211_sta.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_superg.c optional wlan ieee80211_support_superg net80211/ieee80211_scan_sw.c optional wlan net80211/ieee80211_tdma.c optional wlan ieee80211_support_tdma net80211/ieee80211_vht.c optional wlan net80211/ieee80211_wds.c optional wlan net80211/ieee80211_xauth.c optional wlan wlan_xauth net80211/ieee80211_alq.c optional wlan ieee80211_alq netgraph/atm/ccatm/ng_ccatm.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/atm/ngatmbase.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/atm/sscfu/ng_sscfu.c optional ngatm_sscfu \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/atm/sscop/ng_sscop.c optional ngatm_sscop \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/atm/uni/ng_uni.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/bluetooth/common/ng_bluetooth.c optional netgraph_bluetooth netgraph/bluetooth/drivers/ubt/ng_ubt.c optional netgraph_bluetooth_ubt usb netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c optional netgraph_bluetooth_ubt usb netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c optional netgraph_bluetooth_ubtbcmfw usb netgraph/bluetooth/hci/ng_hci_cmds.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_evnt.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_main.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_misc.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_ulpi.c optional netgraph_bluetooth_hci netgraph/bluetooth/l2cap/ng_l2cap_cmds.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_evnt.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_llpi.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_main.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_misc.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_ulpi.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/socket/ng_btsocket.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_hci_raw.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_l2cap.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_rfcomm.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_sco.c optional netgraph_bluetooth_socket netgraph/netflow/netflow.c optional netgraph_netflow netgraph/netflow/netflow_v9.c optional netgraph_netflow netgraph/netflow/ng_netflow.c optional netgraph_netflow netgraph/ng_UI.c optional netgraph_UI netgraph/ng_async.c optional netgraph_async netgraph/ng_atmllc.c optional netgraph_atmllc netgraph/ng_base.c optional netgraph netgraph/ng_bpf.c optional netgraph_bpf netgraph/ng_bridge.c optional netgraph_bridge netgraph/ng_car.c optional netgraph_car netgraph/ng_checksum.c optional netgraph_checksum netgraph/ng_cisco.c optional netgraph_cisco netgraph/ng_deflate.c optional netgraph_deflate netgraph/ng_device.c optional netgraph_device netgraph/ng_echo.c optional netgraph_echo netgraph/ng_eiface.c optional netgraph_eiface netgraph/ng_ether.c optional netgraph_ether netgraph/ng_ether_echo.c optional netgraph_ether_echo netgraph/ng_frame_relay.c optional netgraph_frame_relay netgraph/ng_gif.c optional netgraph_gif inet6 | netgraph_gif inet netgraph/ng_gif_demux.c optional netgraph_gif_demux netgraph/ng_hole.c optional netgraph_hole netgraph/ng_iface.c optional netgraph_iface netgraph/ng_ip_input.c optional netgraph_ip_input netgraph/ng_ipfw.c optional netgraph_ipfw inet ipfirewall netgraph/ng_ksocket.c optional netgraph_ksocket netgraph/ng_l2tp.c optional netgraph_l2tp netgraph/ng_lmi.c optional netgraph_lmi netgraph/ng_macfilter.c optional netgraph_macfilter netgraph/ng_mppc.c optional netgraph_mppc_compression | \ netgraph_mppc_encryption netgraph/ng_nat.c optional netgraph_nat inet libalias netgraph/ng_one2many.c optional netgraph_one2many netgraph/ng_parse.c optional netgraph netgraph/ng_patch.c optional netgraph_patch netgraph/ng_pipe.c optional netgraph_pipe netgraph/ng_ppp.c optional netgraph_ppp netgraph/ng_pppoe.c optional netgraph_pppoe netgraph/ng_pptpgre.c optional netgraph_pptpgre netgraph/ng_pred1.c optional netgraph_pred1 netgraph/ng_rfc1490.c optional netgraph_rfc1490 netgraph/ng_socket.c optional netgraph_socket netgraph/ng_split.c optional netgraph_split netgraph/ng_tag.c optional netgraph_tag netgraph/ng_tcpmss.c optional netgraph_tcpmss netgraph/ng_tee.c optional netgraph_tee netgraph/ng_tty.c optional netgraph_tty netgraph/ng_vjc.c optional netgraph_vjc netgraph/ng_vlan.c optional netgraph_vlan netgraph/ng_vlan_rotate.c optional netgraph_vlan_rotate netinet/accf_data.c optional accept_filter_data inet netinet/accf_dns.c optional accept_filter_dns inet netinet/accf_http.c optional accept_filter_http inet netinet/if_ether.c optional inet ether netinet/igmp.c optional inet netinet/in.c optional inet netinet/in_cksum.c optional inet | inet6 netinet/in_debug.c optional inet ddb netinet/in_kdtrace.c optional inet | inet6 netinet/ip_carp.c optional inet carp | inet6 carp netinet/in_fib.c optional inet netinet/in_fib_algo.c optional inet fib_algo netinet/in_gif.c optional gif inet | netgraph_gif inet netinet/ip_gre.c optional gre inet netinet/ip_id.c optional inet netinet/in_jail.c optional inet netinet/in_mcast.c optional inet netinet/in_pcb.c optional inet | inet6 netinet/in_prot.c optional inet | inet6 netinet/in_proto.c optional inet | inet6 netinet/in_rmx.c optional inet netinet/in_rss.c optional inet rss netinet/ip_divert.c optional ipdivert inet | ipdivert inet6 netinet/ip_ecn.c optional inet | inet6 netinet/ip_encap.c optional inet | inet6 netinet/ip_fastfwd.c optional inet netinet/ip_icmp.c optional inet | inet6 netinet/ip_input.c optional inet netinet/ip_mroute.c optional mrouting inet netinet/ip_options.c optional inet netinet/ip_output.c optional inet netinet/ip_reass.c optional inet netinet/raw_ip.c optional inet | inet6 netinet/cc/cc.c optional cc_newreno inet | cc_vegas inet | \ cc_htcp inet | cc_hd inet | cc_dctcp inet | cc_cubic inet | \ cc_chd inet | cc_cdg inet | cc_newreno inet6 | cc_vegas inet6 | \ cc_htcp inet6 | cc_hd inet6 |cc_dctcp inet6 | cc_cubic inet6 | \ cc_chd inet6 | cc_cdg inet6 netinet/cc/cc_cdg.c optional inet cc_cdg tcp_hhook netinet/cc/cc_chd.c optional inet cc_chd tcp_hhook netinet/cc/cc_cubic.c optional inet cc_cubic | inet6 cc_cubic netinet/cc/cc_dctcp.c optional inet cc_dctcp | inet6 cc_dctcp netinet/cc/cc_hd.c optional inet cc_hd tcp_hhook netinet/cc/cc_htcp.c optional inet cc_htcp | inet6 cc_htcp netinet/cc/cc_newreno.c optional inet cc_newreno | inet6 cc_newreno netinet/cc/cc_vegas.c optional inet cc_vegas tcp_hhook netinet/khelp/h_ertt.c optional inet tcp_hhook netinet/sctp_asconf.c optional inet sctp | inet6 sctp netinet/sctp_auth.c optional inet sctp | inet6 sctp netinet/sctp_bsd_addr.c optional inet sctp | inet6 sctp netinet/sctp_cc_functions.c optional inet sctp | inet6 sctp netinet/sctp_crc32.c optional inet | inet6 netinet/sctp_indata.c optional inet sctp | inet6 sctp netinet/sctp_input.c optional inet sctp | inet6 sctp netinet/sctp_kdtrace.c optional inet sctp | inet6 sctp netinet/sctp_output.c optional inet sctp | inet6 sctp netinet/sctp_pcb.c optional inet sctp | inet6 sctp netinet/sctp_peeloff.c optional inet sctp | inet6 sctp netinet/sctp_ss_functions.c optional inet sctp | inet6 sctp netinet/sctp_syscalls.c optional inet sctp | inet6 sctp netinet/sctp_sysctl.c optional inet sctp | inet6 sctp netinet/sctp_timer.c optional inet sctp | inet6 sctp netinet/sctp_usrreq.c optional inet sctp | inet6 sctp netinet/sctputil.c optional inet sctp | inet6 sctp netinet/siftr.c optional inet siftr alq | inet6 siftr alq -netinet/tcp_debug.c optional tcpdebug netinet/tcp_ecn.c optional inet | inet6 netinet/tcp_fastopen.c optional inet tcp_rfc7413 | inet6 tcp_rfc7413 netinet/tcp_hostcache.c optional inet | inet6 netinet/tcp_input.c optional inet | inet6 netinet/tcp_log_buf.c optional tcp_blackbox inet | tcp_blackbox inet6 netinet/tcp_lro.c optional inet | inet6 netinet/tcp_output.c optional inet | inet6 netinet/tcp_offload.c optional tcp_offload inet | tcp_offload inet6 netinet/tcp_hpts.c optional tcphpts inet | tcphpts inet6 netinet/tcp_ratelimit.c optional ratelimit inet | ratelimit inet6 netinet/tcp_pcap.c optional inet tcppcap | inet6 tcppcap \ compile-with "${NORMAL_C} ${NO_WNONNULL}" netinet/tcp_reass.c optional inet | inet6 netinet/tcp_sack.c optional inet | inet6 netinet/tcp_stats.c optional stats inet | stats inet6 netinet/tcp_subr.c optional inet | inet6 netinet/tcp_syncache.c optional inet | inet6 netinet/tcp_timer.c optional inet | inet6 netinet/tcp_timewait.c optional inet | inet6 netinet/tcp_usrreq.c optional inet | inet6 netinet/udp_usrreq.c optional inet | inet6 netinet/libalias/alias.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_db.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_mod.c optional libalias | netgraph_nat netinet/libalias/alias_proxy.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_util.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_sctp.c optional libalias inet | netgraph_nat inet netinet/netdump/netdump_client.c optional inet debugnet netdump netinet6/dest6.c optional inet6 netinet6/frag6.c optional inet6 netinet6/icmp6.c optional inet6 netinet6/in6.c optional inet6 netinet6/in6_cksum.c optional inet6 netinet6/in6_fib.c optional inet6 netinet6/in6_fib_algo.c optional inet6 fib_algo netinet6/in6_gif.c optional gif inet6 | netgraph_gif inet6 netinet6/in6_ifattach.c optional inet6 netinet6/in6_jail.c optional inet6 netinet6/in6_mcast.c optional inet6 netinet6/in6_pcb.c optional inet6 netinet6/in6_proto.c optional inet6 netinet6/in6_rmx.c optional inet6 netinet6/in6_rss.c optional inet6 rss netinet6/in6_src.c optional inet6 netinet6/ip6_fastfwd.c optional inet6 netinet6/ip6_forward.c optional inet6 netinet6/ip6_gre.c optional gre inet6 netinet6/ip6_id.c optional inet6 netinet6/ip6_input.c optional inet6 netinet6/ip6_mroute.c optional mrouting inet6 netinet6/ip6_output.c optional inet6 netinet6/mld6.c optional inet6 netinet6/nd6.c optional inet6 netinet6/nd6_nbr.c optional inet6 netinet6/nd6_rtr.c optional inet6 netinet6/raw_ip6.c optional inet6 netinet6/route6.c optional inet6 netinet6/scope6.c optional inet6 netinet6/sctp6_usrreq.c optional inet6 sctp netinet6/udp6_usrreq.c optional inet6 netipsec/ipsec.c optional ipsec inet | ipsec inet6 netipsec/ipsec_input.c optional ipsec inet | ipsec inet6 netipsec/ipsec_mbuf.c optional ipsec inet | ipsec inet6 netipsec/ipsec_mod.c optional ipsec inet | ipsec inet6 netipsec/ipsec_output.c optional ipsec inet | ipsec inet6 netipsec/ipsec_pcb.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/key.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/key_debug.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/keysock.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/subr_ipsec.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/udpencap.c optional ipsec inet netipsec/xform_ah.c optional ipsec inet | ipsec inet6 netipsec/xform_esp.c optional ipsec inet | ipsec inet6 netipsec/xform_ipcomp.c optional ipsec inet | ipsec inet6 netipsec/xform_tcp.c optional ipsec inet tcp_signature | \ ipsec inet6 tcp_signature | ipsec_support inet tcp_signature | \ ipsec_support inet6 tcp_signature netpfil/ipfw/dn_aqm_codel.c optional inet dummynet netpfil/ipfw/dn_aqm_pie.c optional inet dummynet netpfil/ipfw/dn_heap.c optional inet dummynet netpfil/ipfw/dn_sched_fifo.c optional inet dummynet netpfil/ipfw/dn_sched_fq_codel.c optional inet dummynet netpfil/ipfw/dn_sched_fq_pie.c optional inet dummynet netpfil/ipfw/dn_sched_prio.c optional inet dummynet netpfil/ipfw/dn_sched_qfq.c optional inet dummynet netpfil/ipfw/dn_sched_rr.c optional inet dummynet netpfil/ipfw/dn_sched_wf2q.c optional inet dummynet netpfil/ipfw/ip_dummynet.c optional inet dummynet netpfil/ipfw/ip_dn_io.c optional inet dummynet netpfil/ipfw/ip_dn_glue.c optional inet dummynet netpfil/ipfw/ip_fw2.c optional inet ipfirewall netpfil/ipfw/ip_fw_bpf.c optional inet ipfirewall netpfil/ipfw/ip_fw_dynamic.c optional inet ipfirewall \ compile-with "${NORMAL_C} -I$S/contrib/ck/include" netpfil/ipfw/ip_fw_eaction.c optional inet ipfirewall netpfil/ipfw/ip_fw_log.c optional inet ipfirewall netpfil/ipfw/ip_fw_pfil.c optional inet ipfirewall netpfil/ipfw/ip_fw_sockopt.c optional inet ipfirewall netpfil/ipfw/ip_fw_table.c optional inet ipfirewall netpfil/ipfw/ip_fw_table_algo.c optional inet ipfirewall netpfil/ipfw/ip_fw_table_value.c optional inet ipfirewall netpfil/ipfw/ip_fw_iface.c optional inet ipfirewall netpfil/ipfw/ip_fw_nat.c optional inet ipfirewall_nat netpfil/ipfw/nat64/ip_fw_nat64.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64clat.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64clat_control.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64lsn.c optional inet inet6 ipfirewall \ ipfirewall_nat64 compile-with "${NORMAL_C} -I$S/contrib/ck/include" netpfil/ipfw/nat64/nat64lsn_control.c optional inet inet6 ipfirewall \ ipfirewall_nat64 compile-with "${NORMAL_C} -I$S/contrib/ck/include" netpfil/ipfw/nat64/nat64stl.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64stl_control.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64_translate.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nptv6/ip_fw_nptv6.c optional inet inet6 ipfirewall \ ipfirewall_nptv6 netpfil/ipfw/nptv6/nptv6.c optional inet inet6 ipfirewall \ ipfirewall_nptv6 netpfil/ipfw/pmod/ip_fw_pmod.c optional inet ipfirewall_pmod netpfil/ipfw/pmod/tcpmod.c optional inet ipfirewall_pmod netpfil/pf/if_pflog.c optional pflog pf inet netpfil/pf/if_pfsync.c optional pfsync pf inet netpfil/pf/pf.c optional pf inet netpfil/pf/pf_if.c optional pf inet netpfil/pf/pf_ioctl.c optional pf inet netpfil/pf/pf_lb.c optional pf inet netpfil/pf/pf_norm.c optional pf inet netpfil/pf/pf_nv.c optional pf inet netpfil/pf/pf_osfp.c optional pf inet netpfil/pf/pf_ruleset.c optional pf inet netpfil/pf/pf_syncookies.c optional pf inet netpfil/pf/pf_table.c optional pf inet netpfil/pf/pfsync_nv.c optional pfsync pf inet netpfil/pf/in4_cksum.c optional pf inet netsmb/smb_conn.c optional netsmb netsmb/smb_crypt.c optional netsmb netsmb/smb_dev.c optional netsmb netsmb/smb_iod.c optional netsmb netsmb/smb_rq.c optional netsmb netsmb/smb_smb.c optional netsmb netsmb/smb_subr.c optional netsmb netsmb/smb_trantcp.c optional netsmb netsmb/smb_usr.c optional netsmb nfs/bootp_subr.c optional bootp nfscl nfs/krpc_subr.c optional bootp nfscl nfs/nfs_diskless.c optional nfscl nfs_root nfs/nfs_nfssvc.c optional nfscl | nfslockd | nfsd nlm/nlm_advlock.c optional nfslockd | nfsd nlm/nlm_prot_clnt.c optional nfslockd | nfsd nlm/nlm_prot_impl.c optional nfslockd | nfsd nlm/nlm_prot_server.c optional nfslockd | nfsd nlm/nlm_prot_svc.c optional nfslockd | nfsd nlm/nlm_prot_xdr.c optional nfslockd | nfsd nlm/sm_inter_xdr.c optional nfslockd | nfsd # Linux Kernel Programming Interface compat/linuxkpi/common/src/linux_80211.c optional compat_linuxkpi wlan \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_80211_macops.c optional compat_linuxkpi wlan \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_kmod.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_acpi.c optional compat_linuxkpi acpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_compat.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_current.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_devres.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_dmi.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_domain.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_firmware.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_fpu.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_hrtimer.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_i2c.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_i2cbb.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_interrupt.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_kthread.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_lock.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_netdev.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_page.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_pci.c optional compat_linuxkpi pci \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_tasklet.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_idr.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_radix.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_rcu.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C} -I$S/contrib/ck/include" compat/linuxkpi/common/src/linux_schedule.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_shmemfs.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_shrinker.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_skbuff.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_slab.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_usb.c optional compat_linuxkpi usb \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_work.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_xarray.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/lkpi_iic_if.m optional compat_linuxkpi compat/linuxkpi/common/src/linux_seq_file.c optional compat_linuxkpi | lindebugfs \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_simple_attr.c optional compat_linuxkpi | lindebugfs \ compile-with "${LINUXKPI_C}" compat/lindebugfs/lindebugfs.c optional lindebugfs \ compile-with "${LINUXKPI_C}" # OpenFabrics Enterprise Distribution (Infiniband) net/if_infiniband.c optional ofed | lagg ofed/drivers/infiniband/core/ib_addr.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_agent.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_cache.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_cm.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_cma.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_core_uverbs.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_cq.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_device.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_fmr_pool.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_iwcm.c optional ofed \ compile-with "${OFED_C} ${NO_WUNUSED_BUT_SET_VARIABLE}" ofed/drivers/infiniband/core/ib_iwpm_msg.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_iwpm_util.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_mad.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_mad_rmpp.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_multicast.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_packer.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_rdma_core.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_sa_query.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_smi.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_sysfs.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_ucm.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_ucma.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_ud_header.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_umem.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_user_mad.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_cmd.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_ioctl.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_main.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_marshall.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_async_fd.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_counters.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_cq.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_device.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_dm.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_flow_action.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_std_types_mr.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_uapi.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_verbs.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/ulp/ipoib/ipoib_cm.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" #ofed/drivers/infiniband/ulp/ipoib/ipoib_fs.c optional ipoib \ # compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_multicast.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_verbs.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" #ofed/drivers/infiniband/ulp/ipoib/ipoib_vlan.c optional ipoib \ # compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/sdp/sdp_bcopy.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_main.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_rx.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/ ${NO_WUNUSED_BUT_SET_VARIABLE}" ofed/drivers/infiniband/ulp/sdp/sdp_cma.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_tx.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/ ${NO_WUNUSED_BUT_SET_VARIABLE}" dev/irdma/icrdma.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_cm.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_ctrl.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_hmc.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_hw.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/icrdma_hw.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/fbsd_kcompat.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_kcompat.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_pble.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_puda.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_uda.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_uk.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_utils.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_verbs.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/irdma/irdma_ws.c optional irdma ice inet inet6 pci ofed \ compile-with "${OFED_C} -I$S/dev/ice/" dev/mthca/mthca_allocator.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_av.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_catas.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_cmd.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_cq.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_eq.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_mad.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_main.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_mcg.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_memfree.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_mr.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_pd.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_profile.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_provider.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_qp.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_reset.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_srq.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_uar.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_alias_GUID.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_mcg.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_sysfs.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_cm.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_ah.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_cq.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_doorbell.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_mad.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_main.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_mr.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_qp.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_srq.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_wc.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_alloc.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_catas.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_cmd.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_cq.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_eq.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_fw.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_fw_qos.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_icm.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_intf.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_main.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_mcg.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_mr.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_pd.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_port.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_profile.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_qp.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_reset.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_sense.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_srq.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_resource_tracker.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_cq.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_main.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_netdev.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_port.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_resources.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_rx.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_tx.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_ah.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_cong.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_cq.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_devx.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_doorbell.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_gsi.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_mad.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_main.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_mem.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_mr.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_qp.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_srq.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_virt.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_alloc.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_cmd.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_cq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_diagnostics.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_eq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_eswitch.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fs_cmd.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fs_tcp.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fs_tree.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fw.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fwdump.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_health.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mad.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_main.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mcg.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mpfs.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mr.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_pagealloc.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_pd.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_port.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_qp.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_rl.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_srq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_tls.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_transobj.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_uar.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_vport.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_vsc.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_wq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_lib/mlx5_gid.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_dim.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_ethtool.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_main.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_tx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_flow_table.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_hw_tls.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_hw_tls_rx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_iq.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_rx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_rl.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_txrx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_port_buffer.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" # crypto support opencrypto/cbc_mac.c optional crypto opencrypto/criov.c optional crypto opencrypto/crypto.c optional crypto opencrypto/cryptodev.c optional cryptodev opencrypto/cryptodev_if.m optional crypto opencrypto/cryptosoft.c optional crypto opencrypto/cryptodeflate.c optional crypto opencrypto/gmac.c optional crypto opencrypto/gfmult.c optional crypto opencrypto/ktls_ocf.c optional kern_tls opencrypto/rmd160.c optional crypto opencrypto/xform_aes_cbc.c optional crypto opencrypto/xform_aes_icm.c optional crypto opencrypto/xform_aes_xts.c optional crypto opencrypto/xform_cbc_mac.c optional crypto opencrypto/xform_chacha20_poly1305.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" opencrypto/xform_cml.c optional crypto opencrypto/xform_deflate.c optional crypto opencrypto/xform_gmac.c optional crypto opencrypto/xform_null.c optional crypto opencrypto/xform_poly1305.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" opencrypto/xform_rmd160.c optional crypto opencrypto/xform_sha1.c optional crypto opencrypto/xform_sha2.c optional crypto contrib/libsodium/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium -Wno-unused-function" contrib/libsodium/src/libsodium/crypto_core/hchacha20/core_hchacha20.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_scalarmult/curve25519/scalarmult_curve25519.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium -Wno-unused-function" contrib/libsodium/src/libsodium/crypto_stream/chacha20/stream_chacha20.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_stream/chacha20/ref/chacha20_ref.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_verify/sodium/verify.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" crypto/libsodium/randombytes.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" crypto/libsodium/utils.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" rpc/auth_none.c optional krpc | nfslockd | nfscl | nfsd rpc/auth_unix.c optional krpc | nfslockd | nfscl | nfsd rpc/authunix_prot.c optional krpc | nfslockd | nfscl | nfsd rpc/clnt_bck.c optional krpc | nfslockd | nfscl | nfsd rpc/clnt_dg.c optional krpc | nfslockd | nfscl | nfsd rpc/clnt_rc.c optional krpc | nfslockd | nfscl | nfsd rpc/clnt_vc.c optional krpc | nfslockd | nfscl | nfsd rpc/getnetconfig.c optional krpc | nfslockd | nfscl | nfsd rpc/replay.c optional krpc | nfslockd | nfscl | nfsd rpc/rpc_callmsg.c optional krpc | nfslockd | nfscl | nfsd rpc/rpc_generic.c optional krpc | nfslockd | nfscl | nfsd rpc/rpc_prot.c optional krpc | nfslockd | nfscl | nfsd rpc/rpcb_clnt.c optional krpc | nfslockd | nfscl | nfsd rpc/rpcb_prot.c optional krpc | nfslockd | nfscl | nfsd rpc/svc.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_auth.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_auth_unix.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_dg.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_generic.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_vc.c optional krpc | nfslockd | nfscl | nfsd # # Kernel RPC-over-TLS # rpctlscd.h optional krpc | nfslockd | nfscl | nfsd \ dependency "$S/rpc/rpcsec_tls/rpctlscd.x" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -hM $S/rpc/rpcsec_tls/rpctlscd.x | grep -v pthread.h > rpctlscd.h" \ no-obj no-implicit-rule before-depend local \ clean "rpctlscd.h" rpctlscd_xdr.c optional krpc | nfslockd | nfscl | nfsd \ dependency "$S/rpc/rpcsec_tls/rpctlscd.x rpctlscd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -c $S/rpc/rpcsec_tls/rpctlscd.x -o rpctlscd_xdr.c" no-ctfconvert \ no-implicit-rule before-depend local \ clean "rpctlscd_xdr.c" rpctlscd_clnt.c optional krpc | nfslockd | nfscl | nfsd \ dependency "$S/rpc/rpcsec_tls/rpctlscd.x rpctlscd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -lM $S/rpc/rpcsec_tls/rpctlscd.x | grep -v string.h > rpctlscd_clnt.c" no-ctfconvert \ no-implicit-rule before-depend local \ clean "rpctlscd_clnt.c" rpctlssd.h optional krpc | nfslockd | nfscl | nfsd \ dependency "$S/rpc/rpcsec_tls/rpctlssd.x" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -hM $S/rpc/rpcsec_tls/rpctlssd.x | grep -v pthread.h > rpctlssd.h" \ no-obj no-implicit-rule before-depend local \ clean "rpctlssd.h" rpctlssd_xdr.c optional krpc | nfslockd | nfscl | nfsd \ dependency "$S/rpc/rpcsec_tls/rpctlssd.x rpctlssd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -c $S/rpc/rpcsec_tls/rpctlssd.x -o rpctlssd_xdr.c" no-ctfconvert \ no-implicit-rule before-depend local \ clean "rpctlssd_xdr.c" rpctlssd_clnt.c optional krpc | nfslockd | nfscl | nfsd \ dependency "$S/rpc/rpcsec_tls/rpctlssd.x rpctlssd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -lM $S/rpc/rpcsec_tls/rpctlssd.x | grep -v string.h > rpctlssd_clnt.c" no-ctfconvert \ no-implicit-rule before-depend local \ clean "rpctlssd_clnt.c" rpc/rpcsec_tls/rpctls_impl.c optional krpc | nfslockd | nfscl | nfsd rpc/rpcsec_tls/auth_tls.c optional krpc | nfslockd | nfscl | nfsd rpc/rpcsec_gss/rpcsec_gss.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/rpcsec_gss_conf.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/rpcsec_gss_misc.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/rpcsec_gss_prot.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/svc_rpcsec_gss.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi security/audit/audit.c optional audit security/audit/audit_arg.c optional audit security/audit/audit_bsm.c optional audit security/audit/audit_bsm_db.c optional audit security/audit/audit_bsm_klib.c optional audit security/audit/audit_dtrace.c optional dtaudit audit | dtraceall audit compile-with "${CDDL_C}" security/audit/audit_pipe.c optional audit security/audit/audit_syscalls.c standard security/audit/audit_trigger.c optional audit security/audit/audit_worker.c optional audit security/audit/bsm_domain.c optional audit security/audit/bsm_errno.c optional audit security/audit/bsm_fcntl.c optional audit security/audit/bsm_socket_type.c optional audit security/audit/bsm_token.c optional audit security/mac/mac_audit.c optional mac audit security/mac/mac_cred.c optional mac security/mac/mac_kdb.c optional mac security/mac/mac_framework.c optional mac security/mac/mac_inet.c optional mac inet | mac inet6 security/mac/mac_inet6.c optional mac inet6 security/mac/mac_label.c optional mac security/mac/mac_net.c optional mac security/mac/mac_pipe.c optional mac security/mac/mac_posix_sem.c optional mac security/mac/mac_posix_shm.c optional mac security/mac/mac_priv.c optional mac security/mac/mac_process.c optional mac security/mac/mac_socket.c optional mac security/mac/mac_syscalls.c standard security/mac/mac_system.c optional mac security/mac/mac_sysv_msg.c optional mac security/mac/mac_sysv_sem.c optional mac security/mac/mac_sysv_shm.c optional mac security/mac/mac_vfs.c optional mac security/mac_biba/mac_biba.c optional mac_biba security/mac_ddb/mac_ddb.c optional mac_ddb security/mac_bsdextended/mac_bsdextended.c optional mac_bsdextended security/mac_bsdextended/ugidfw_system.c optional mac_bsdextended security/mac_bsdextended/ugidfw_vnode.c optional mac_bsdextended security/mac_ifoff/mac_ifoff.c optional mac_ifoff security/mac_lomac/mac_lomac.c optional mac_lomac security/mac_mls/mac_mls.c optional mac_mls security/mac_none/mac_none.c optional mac_none security/mac_ntpd/mac_ntpd.c optional mac_ntpd security/mac_partition/mac_partition.c optional mac_partition security/mac_portacl/mac_portacl.c optional mac_portacl security/mac_priority/mac_priority.c optional mac_priority security/mac_seeotheruids/mac_seeotheruids.c optional mac_seeotheruids security/mac_stub/mac_stub.c optional mac_stub security/mac_test/mac_test.c optional mac_test security/mac_veriexec/mac_veriexec.c optional mac_veriexec security/mac_veriexec/veriexec_fingerprint.c optional mac_veriexec security/mac_veriexec/veriexec_metadata.c optional mac_veriexec security/mac_veriexec_parser/mac_veriexec_parser.c optional mac_veriexec mac_veriexec_parser security/mac_veriexec/mac_veriexec_rmd160.c optional mac_veriexec_rmd160 security/mac_veriexec/mac_veriexec_sha1.c optional mac_veriexec_sha1 security/mac_veriexec/mac_veriexec_sha256.c optional mac_veriexec_sha256 security/mac_veriexec/mac_veriexec_sha384.c optional mac_veriexec_sha384 security/mac_veriexec/mac_veriexec_sha512.c optional mac_veriexec_sha512 teken/teken.c optional sc !SC_NO_TERM_TEKEN | vt ufs/ffs/ffs_alloc.c optional ffs ufs/ffs/ffs_balloc.c optional ffs ufs/ffs/ffs_inode.c optional ffs ufs/ffs/ffs_snapshot.c optional ffs ufs/ffs/ffs_softdep.c optional ffs ufs/ffs/ffs_subr.c optional ffs | geom_label ufs/ffs/ffs_tables.c optional ffs | geom_label ufs/ffs/ffs_vfsops.c optional ffs ufs/ffs/ffs_vnops.c optional ffs ufs/ffs/ffs_rawread.c optional ffs directio ufs/ffs/ffs_suspend.c optional ffs ufs/ufs/ufs_acl.c optional ffs ufs/ufs/ufs_bmap.c optional ffs ufs/ufs/ufs_dirhash.c optional ffs ufs/ufs/ufs_extattr.c optional ffs ufs/ufs/ufs_gjournal.c optional ffs UFS_GJOURNAL ufs/ufs/ufs_inode.c optional ffs ufs/ufs/ufs_lookup.c optional ffs ufs/ufs/ufs_quota.c optional ffs ufs/ufs/ufs_vfsops.c optional ffs ufs/ufs/ufs_vnops.c optional ffs vm/device_pager.c standard vm/phys_pager.c standard vm/redzone.c optional DEBUG_REDZONE vm/sg_pager.c standard vm/swap_pager.c standard vm/uma_core.c standard vm/uma_dbg.c standard vm/memguard.c optional DEBUG_MEMGUARD vm/vm_domainset.c standard vm/vm_fault.c standard vm/vm_glue.c standard vm/vm_init.c standard vm/vm_kern.c standard vm/vm_map.c standard vm/vm_meter.c standard vm/vm_mmap.c standard vm/vm_object.c standard vm/vm_page.c standard vm/vm_pageout.c standard vm/vm_pager.c standard vm/vm_phys.c standard vm/vm_radix.c standard vm/vm_reserv.c standard vm/vm_swapout.c optional !NO_SWAPPING vm/vm_swapout_dummy.c optional NO_SWAPPING vm/vm_unix.c standard vm/vnode_pager.c standard xen/features.c optional xenhvm xen/xenbus/xenbus_if.m optional xenhvm xen/xenbus/xenbus.c optional xenhvm xen/xenbus/xenbusb_if.m optional xenhvm xen/xenbus/xenbusb.c optional xenhvm xen/xenbus/xenbusb_front.c optional xenhvm xen/xenbus/xenbusb_back.c optional xenhvm xen/xenmem/xenmem_if.m optional xenhvm xdr/xdr.c optional xdr | krpc | nfslockd | nfscl | nfsd xdr/xdr_array.c optional xdr | krpc | nfslockd | nfscl | nfsd xdr/xdr_mbuf.c optional xdr | krpc | nfslockd | nfscl | nfsd xdr/xdr_mem.c optional xdr | krpc | nfslockd | nfscl | nfsd xdr/xdr_reference.c optional xdr | krpc | nfslockd | nfscl | nfsd xdr/xdr_sizeof.c optional xdr | krpc | nfslockd | nfscl | nfsd diff --git a/sys/conf/options b/sys/conf/options index 00019b1c2e5c..85f456555447 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -1,1032 +1,1031 @@ # $FreeBSD$ # # On the handling of kernel options # # All kernel options should be listed in NOTES, with suitable # descriptions. Negative options (options that make some code not # compile) should be commented out; LINT (generated from NOTES) should # compile as much code as possible. Try to structure option-using # code so that a single option only switch code on, or only switch # code off, to make it possible to have a full compile-test. If # necessary, you can check for COMPILING_LINT to get maximum code # coverage. # # All new options shall also be listed in either "conf/options" or # "conf/options.". Options that affect a single source-file # .[c|s] should be directed into "opt_.h", while options # that affect multiple files should either go in "opt_global.h" if # this is a kernel-wide option (used just about everywhere), or in # "opt_.h" if it affects only some files. # Note that the effect of listing only an option without a # header-file-name in conf/options (and cousins) is that the last # convention is followed. # # This handling scheme is not yet fully implemented. # # # Format of this file: # Option name filename # # If filename is missing, the default is # opt_.h AAC_DEBUG opt_aac.h AACRAID_DEBUG opt_aacraid.h AHC_ALLOW_MEMIO opt_aic7xxx.h AHC_TMODE_ENABLE opt_aic7xxx.h AHC_DUMP_EEPROM opt_aic7xxx.h AHC_DEBUG opt_aic7xxx.h AHC_DEBUG_OPTS opt_aic7xxx.h AHC_REG_PRETTY_PRINT opt_aic7xxx.h AHD_DEBUG opt_aic79xx.h AHD_DEBUG_OPTS opt_aic79xx.h AHD_TMODE_ENABLE opt_aic79xx.h AHD_REG_PRETTY_PRINT opt_aic79xx.h # Debugging options. ALT_BREAK_TO_DEBUGGER opt_kdb.h BREAK_TO_DEBUGGER opt_kdb.h BUF_TRACKING opt_global.h DDB DDB_BUFR_SIZE opt_ddb.h DDB_CAPTURE_DEFAULTBUFSIZE opt_ddb.h DDB_CAPTURE_MAXBUFSIZE opt_ddb.h DDB_CTF opt_ddb.h DDB_NUMSYM opt_ddb.h EARLY_PRINTF opt_global.h FULL_BUF_TRACKING opt_global.h GDB KDB opt_global.h KDB_TRACE opt_kdb.h KDB_UNATTENDED opt_kdb.h KLD_DEBUG opt_kld.h NUM_CORE_FILES opt_global.h QUEUE_MACRO_DEBUG_TRACE opt_global.h QUEUE_MACRO_DEBUG_TRASH opt_global.h SYSCTL_DEBUG opt_sysctl.h TEXTDUMP_PREFERRED opt_ddb.h TEXTDUMP_VERBOSE opt_ddb.h TSLOG opt_global.h TSLOGSIZE opt_global.h # Miscellaneous options. ALQ ALTERA_SDCARD_FAST_SIM opt_altera_sdcard.h ATSE_CFI_HACK opt_cfi.h AUDIT opt_global.h BOOTHOWTO opt_global.h BOOTVERBOSE opt_global.h CALLOUT_PROFILING CAPABILITIES opt_capsicum.h CAPABILITY_MODE opt_capsicum.h CC_CDG opt_global.h CC_CHD opt_global.h CC_CUBIC opt_global.h CC_DEFAULT opt_cc.h CC_DCTCP opt_global.h CC_HD opt_global.h CC_HTCP opt_global.h CC_NEWRENO opt_global.h CC_VEGAS opt_global.h COMPAT_43 opt_global.h COMPAT_43TTY opt_global.h COMPAT_FREEBSD4 opt_global.h COMPAT_FREEBSD5 opt_global.h COMPAT_FREEBSD6 opt_global.h COMPAT_FREEBSD7 opt_global.h COMPAT_FREEBSD9 opt_global.h COMPAT_FREEBSD10 opt_global.h COMPAT_FREEBSD11 opt_global.h COMPAT_FREEBSD12 opt_global.h COMPAT_FREEBSD13 opt_global.h COMPAT_LINUXKPI opt_dontuse.h _COMPAT_LINUX32 opt_compat.h # XXX: make sure opt_compat.h exists COMPILING_LINT opt_global.h CY_PCI_FASTINTR DEADLKRES opt_watchdog.h EXPERIMENTAL opt_global.h DIRECTIO FILEMON opt_dontuse.h FFCLOCK FULL_PREEMPTION opt_sched.h GZIO opt_gzio.h IMGACT_BINMISC opt_dontuse.h IPI_PREEMPTION opt_sched.h GEOM_BDE opt_geom.h GEOM_CACHE opt_geom.h GEOM_CONCAT opt_geom.h GEOM_ELI opt_geom.h GEOM_GATE opt_geom.h GEOM_JOURNAL opt_geom.h GEOM_LABEL opt_geom.h GEOM_LABEL_GPT opt_geom.h GEOM_LINUX_LVM opt_geom.h GEOM_MAP opt_geom.h GEOM_MIRROR opt_geom.h GEOM_MOUNTVER opt_geom.h GEOM_MULTIPATH opt_geom.h GEOM_NOP opt_geom.h GEOM_PART_APM opt_geom.h GEOM_PART_BSD opt_geom.h GEOM_PART_BSD64 opt_geom.h GEOM_PART_EBR opt_geom.h GEOM_PART_GPT opt_geom.h GEOM_PART_LDM opt_geom.h GEOM_PART_MBR opt_geom.h GEOM_PART_VTOC8 opt_geom.h GEOM_RAID opt_geom.h GEOM_RAID3 opt_geom.h GEOM_SHSEC opt_geom.h GEOM_STRIPE opt_geom.h GEOM_UZIP opt_geom.h GEOM_UZIP_DEBUG opt_geom.h GEOM_VINUM opt_geom.h GEOM_VIRSTOR opt_geom.h GEOM_ZERO opt_geom.h IFLIB opt_iflib.h KDTRACE_HOOKS opt_global.h KDTRACE_FRAME opt_kdtrace.h KN_HASHSIZE opt_kqueue.h KSTACK_MAX_PAGES KSTACK_PAGES KSTACK_USAGE_PROF KTRACE KTRACE_REQUEST_POOL opt_ktrace.h LIBICONV MAC opt_global.h MAC_BIBA opt_dontuse.h MAC_BSDEXTENDED opt_dontuse.h MAC_DDB opt_dontuse.h MAC_IFOFF opt_dontuse.h MAC_LOMAC opt_dontuse.h MAC_MLS opt_dontuse.h MAC_NONE opt_dontuse.h MAC_NTPD opt_dontuse.h MAC_PARTITION opt_dontuse.h MAC_PORTACL opt_dontuse.h MAC_PRIORITY opt_dontuse.h MAC_SEEOTHERUIDS opt_dontuse.h MAC_STATIC opt_mac.h MAC_STUB opt_dontuse.h MAC_TEST opt_dontuse.h MAC_VERIEXEC opt_dontuse.h MAC_VERIEXEC_SHA1 opt_dontuse.h MAC_VERIEXEC_SHA256 opt_dontuse.h MAC_VERIEXEC_SHA384 opt_dontuse.h MAC_VERIEXEC_SHA512 opt_dontuse.h MD_ROOT opt_md.h MD_ROOT_FSTYPE opt_md.h MD_ROOT_READONLY opt_md.h MD_ROOT_SIZE opt_md.h MD_ROOT_MEM opt_md.h MFI_DEBUG opt_mfi.h MFI_DECODE_LOG opt_mfi.h MPROF_BUFFERS opt_mprof.h MPROF_HASH_SIZE opt_mprof.h NEW_PCIB opt_global.h NO_ADAPTIVE_MUTEXES opt_adaptive_mutexes.h NO_ADAPTIVE_RWLOCKS NO_ADAPTIVE_SX NO_OBSOLETE_CODE opt_global.h NO_SYSCTL_DESCR opt_global.h NSWBUF_MIN opt_param.h MBUF_PACKET_ZONE_DISABLE opt_global.h PANIC_REBOOT_WAIT_TIME opt_panic.h PCI_HP opt_pci.h PCI_IOV opt_global.h PPC_DEBUG opt_ppc.h PPC_PROBE_CHIPSET opt_ppc.h PPS_SYNC opt_ntp.h PREEMPTION opt_sched.h QUOTA SCHED_4BSD opt_sched.h SCHED_STATS opt_sched.h SCHED_ULE opt_sched.h SLEEPQUEUE_PROFILING SLHCI_DEBUG opt_slhci.h STACK opt_stack.h SUIDDIR MSGMNB opt_sysvipc.h MSGMNI opt_sysvipc.h MSGSEG opt_sysvipc.h MSGSSZ opt_sysvipc.h MSGTQL opt_sysvipc.h SEMMNI opt_sysvipc.h SEMMNS opt_sysvipc.h SEMMNU opt_sysvipc.h SEMMSL opt_sysvipc.h SEMOPM opt_sysvipc.h SEMUME opt_sysvipc.h SHMALL opt_sysvipc.h SHMMAX opt_sysvipc.h SHMMAXPGS opt_sysvipc.h SHMMIN opt_sysvipc.h SHMMNI opt_sysvipc.h SHMSEG opt_sysvipc.h SYSVMSG opt_sysvipc.h SYSVSEM opt_sysvipc.h SYSVSHM opt_sysvipc.h SW_WATCHDOG opt_watchdog.h TCPHPTS opt_inet.h TURNSTILE_PROFILING UMTX_PROFILING UMTX_CHAINS opt_global.h VERBOSE_SYSINIT ZSTDIO opt_zstdio.h # Sanitizers COVERAGE opt_global.h KASAN opt_global.h KCOV KCSAN opt_global.h KMSAN opt_global.h KUBSAN opt_global.h # POSIX kernel options P1003_1B_MQUEUE opt_posix.h P1003_1B_SEMAPHORES opt_posix.h _KPOSIX_PRIORITY_SCHEDULING opt_posix.h # Do we want the config file compiled into the kernel? INCLUDE_CONFIG_FILE opt_config.h # Options for static filesystems. These should only be used at config # time, since the corresponding lkms cannot work if there are any static # dependencies. Unusability is enforced by hiding the defines for the # options in a never-included header. AUTOFS opt_dontuse.h CD9660 opt_dontuse.h EXT2FS opt_dontuse.h FDESCFS opt_dontuse.h FFS opt_dontuse.h FUSEFS opt_dontuse.h MSDOSFS opt_dontuse.h NULLFS opt_dontuse.h PROCFS opt_dontuse.h PSEUDOFS opt_dontuse.h SMBFS opt_dontuse.h TMPFS opt_dontuse.h UDF opt_dontuse.h UNIONFS opt_dontuse.h ZFS opt_dontuse.h # Pseudofs debugging PSEUDOFS_TRACE opt_pseudofs.h # In-kernel GSS-API KGSSAPI opt_kgssapi.h KGSSAPI_DEBUG opt_kgssapi.h # These static filesystems have one slightly bogus static dependency in # sys/i386/i386/autoconf.c. If any of these filesystems are # statically compiled into the kernel, code for mounting them as root # filesystems will be enabled - but look below. # NFSCL - client # NFSD - server NFSCL opt_nfs.h NFSD opt_nfs.h # filesystems and libiconv bridge CD9660_ICONV opt_dontuse.h MSDOSFS_ICONV opt_dontuse.h UDF_ICONV opt_dontuse.h # If you are following the conditions in the copyright, # you can enable soft-updates which will speed up a lot of thigs # and make the system safer from crashes at the same time. # otherwise a STUB module will be compiled in. SOFTUPDATES opt_ffs.h # On small, embedded systems, it can be useful to turn off support for # snapshots. It saves about 30-40k for a feature that would be lightly # used, if it is used at all. NO_FFS_SNAPSHOT opt_ffs.h # Enabling this option turns on support for Access Control Lists in UFS, # which can be used to support high security configurations. Depends on # UFS_EXTATTR. UFS_ACL opt_ufs.h # Enabling this option turns on support for extended attributes in UFS-based # filesystems, which can be used to support high security configurations # as well as new filesystem features. UFS_EXTATTR opt_ufs.h UFS_EXTATTR_AUTOSTART opt_ufs.h # Enable fast hash lookups for large directories on UFS-based filesystems. UFS_DIRHASH opt_ufs.h # Enable gjournal-based UFS journal. UFS_GJOURNAL opt_ufs.h # The below sentence is not in English, and neither is this one. # We plan to remove the static dependences above, with a # _ROOT option to control if it usable as root. This list # allows these options to be present in config files already (though # they won't make any difference yet). NFS_ROOT opt_nfsroot.h # SMB/CIFS requester NETSMB opt_netsmb.h # Enable debugnet(4) networking support. DEBUGNET opt_global.h # Enable netdump(4) client support. NETDUMP opt_global.h # Enable netgdb(4) support. NETGDB opt_global.h # Options used only in subr_param.c. HZ opt_param.h MAXFILES opt_param.h NBUF opt_param.h NSFBUFS opt_param.h VM_BCACHE_SIZE_MAX opt_param.h VM_SWZONE_SIZE_MAX opt_param.h MAXUSERS DFLDSIZ opt_param.h MAXDSIZ opt_param.h MAXSSIZ opt_param.h # Generic SCSI options. CAM_MAX_HIGHPOWER opt_cam.h CAMDEBUG opt_cam.h CAM_DEBUG_COMPILE opt_cam.h CAM_DEBUG_DELAY opt_cam.h CAM_DEBUG_BUS opt_cam.h CAM_DEBUG_TARGET opt_cam.h CAM_DEBUG_LUN opt_cam.h CAM_DEBUG_FLAGS opt_cam.h CAM_BOOT_DELAY opt_cam.h CAM_IOSCHED_DYNAMIC opt_cam.h CAM_IO_STATS opt_cam.h CAM_TEST_FAILURE opt_cam.h SCSI_DELAY opt_scsi.h SCSI_NO_SENSE_STRINGS opt_scsi.h SCSI_NO_OP_STRINGS opt_scsi.h # Options used only in cam/ata/ata_da.c ATA_STATIC_ID opt_ada.h # Options used only in cam/scsi/scsi_cd.c CHANGER_MIN_BUSY_SECONDS opt_cd.h CHANGER_MAX_BUSY_SECONDS opt_cd.h # Options used only in cam/scsi/scsi_da.c DA_TRACK_REFS opt_da.h # Options used only in cam/scsi/scsi_sa.c. SA_IO_TIMEOUT opt_sa.h SA_SPACE_TIMEOUT opt_sa.h SA_REWIND_TIMEOUT opt_sa.h SA_ERASE_TIMEOUT opt_sa.h SA_1FM_AT_EOD opt_sa.h # Options used only in cam/scsi/scsi_pt.c SCSI_PT_DEFAULT_TIMEOUT opt_pt.h # Options used only in cam/scsi/scsi_ses.c SES_ENABLE_PASSTHROUGH opt_ses.h # Options used in dev/sym/ (Symbios SCSI driver). SYM_SETUP_SCSI_DIFF opt_sym.h #-HVD support for 825a, 875, 885 # disabled:0 (default), enabled:1 SYM_SETUP_PCI_PARITY opt_sym.h #-PCI parity checking # disabled:0, enabled:1 (default) SYM_SETUP_MAX_LUN opt_sym.h #-Number of LUNs supported # default:8, range:[1..64] # Options used only in dev/isp/* ISP_TARGET_MODE opt_isp.h ISP_FW_CRASH_DUMP opt_isp.h ISP_DEFAULT_ROLES opt_isp.h ISP_INTERNAL_TARGET opt_isp.h ISP_FCTAPE_OFF opt_isp.h # Options used only in dev/iscsi ISCSI_INITIATOR_DEBUG opt_iscsi_initiator.h # Net stuff. ACCEPT_FILTER_DATA ACCEPT_FILTER_DNS ACCEPT_FILTER_HTTP ALTQ opt_global.h ALTQ_CBQ opt_altq.h ALTQ_CDNR opt_altq.h ALTQ_CODEL opt_altq.h ALTQ_DEBUG opt_altq.h ALTQ_HFSC opt_altq.h ALTQ_FAIRQ opt_altq.h ALTQ_NOPCC opt_altq.h ALTQ_PRIQ opt_altq.h ALTQ_RED opt_altq.h ALTQ_RIO opt_altq.h BOOTP opt_bootp.h BOOTP_BLOCKSIZE opt_bootp.h BOOTP_COMPAT opt_bootp.h BOOTP_NFSROOT opt_bootp.h BOOTP_NFSV3 opt_bootp.h BOOTP_WIRED_TO opt_bootp.h DEVICE_POLLING DUMMYNET opt_ipdn.h RATELIMIT opt_ratelimit.h RATELIMIT_DEBUG opt_ratelimit.h INET opt_inet.h INET6 opt_inet6.h STATS opt_global.h IPDIVERT IPFILTER opt_ipfilter.h IPFILTER_DEFAULT_BLOCK opt_ipfilter.h IPFILTER_LOG opt_ipfilter.h IPFILTER_LOOKUP opt_ipfilter.h IPFIREWALL opt_ipfw.h IPFIREWALL_DEFAULT_TO_ACCEPT opt_ipfw.h IPFIREWALL_NAT opt_ipfw.h IPFIREWALL_NAT64 opt_ipfw.h IPFIREWALL_NPTV6 opt_ipfw.h IPFIREWALL_VERBOSE opt_ipfw.h IPFIREWALL_VERBOSE_LIMIT opt_ipfw.h IPFIREWALL_PMOD opt_ipfw.h IPSEC opt_ipsec.h IPSEC_DEBUG opt_ipsec.h IPSEC_SUPPORT opt_ipsec.h IPSTEALTH KERN_TLS KRPC LIBALIAS LIBMCHAIN MBUF_PROFILING MBUF_STRESS_TEST MROUTING opt_mrouting.h NFSLOCKD PF_DEFAULT_TO_DROP opt_pf.h ROUTE_MPATH opt_route.h ROUTETABLES opt_route.h FIB_ALGO opt_route.h RSS opt_rss.h SLIP_IFF_OPTS opt_slip.h -TCPDEBUG TCPPCAP opt_global.h SIFTR TCP_BLACKBOX opt_global.h TCP_HHOOK opt_global.h TCP_OFFLOAD opt_inet.h # Enable code to dispatch TCP offloading TCP_RFC7413 opt_inet.h TCP_RFC7413_MAX_KEYS opt_inet.h TCP_RFC7413_MAX_PSKS opt_inet.h TCP_SIGNATURE opt_ipsec.h VLAN_ARRAY opt_vlan.h XDR XBONEHACK # # SCTP # SCTP opt_sctp.h SCTP_SUPPORT opt_sctp.h SCTP_DEBUG opt_sctp.h # Enable debug printfs SCTP_LOCK_LOGGING opt_sctp.h # Log to KTR lock activity SCTP_MBUF_LOGGING opt_sctp.h # Log to KTR general mbuf aloc/free SCTP_MBCNT_LOGGING opt_sctp.h # Log to KTR mbcnt activity SCTP_PACKET_LOGGING opt_sctp.h # Log to a packet buffer last N packets SCTP_LTRACE_CHUNKS opt_sctp.h # Log to KTR chunks processed SCTP_LTRACE_ERRORS opt_sctp.h # Log to KTR error returns. SCTP_USE_PERCPU_STAT opt_sctp.h # Use per cpu stats. SCTP_MCORE_INPUT opt_sctp.h # Have multiple input threads for input mbufs SCTP_LOCAL_TRACE_BUF opt_sctp.h # Use tracebuffer exported via sysctl SCTP_DETAILED_STR_STATS opt_sctp.h # Use per PR-SCTP policy stream stats # # # # Netgraph(4). Use option NETGRAPH to enable the base netgraph code. # Each netgraph node type can be either be compiled into the kernel # or loaded dynamically. To get the former, include the corresponding # option below. Each type has its own man page, e.g. ng_async(4). NETGRAPH NETGRAPH_DEBUG opt_netgraph.h NETGRAPH_ASYNC opt_netgraph.h NETGRAPH_ATMLLC opt_netgraph.h NETGRAPH_ATM_ATMPIF opt_netgraph.h NETGRAPH_BLUETOOTH opt_netgraph.h NETGRAPH_BLUETOOTH_BT3C opt_netgraph.h NETGRAPH_BLUETOOTH_H4 opt_netgraph.h NETGRAPH_BLUETOOTH_HCI opt_netgraph.h NETGRAPH_BLUETOOTH_L2CAP opt_netgraph.h NETGRAPH_BLUETOOTH_SOCKET opt_netgraph.h NETGRAPH_BLUETOOTH_UBT opt_netgraph.h NETGRAPH_BLUETOOTH_UBTBCMFW opt_netgraph.h NETGRAPH_BPF opt_netgraph.h NETGRAPH_BRIDGE opt_netgraph.h NETGRAPH_CAR opt_netgraph.h NETGRAPH_CHECKSUM opt_netgraph.h NETGRAPH_CISCO opt_netgraph.h NETGRAPH_DEFLATE opt_netgraph.h NETGRAPH_DEVICE opt_netgraph.h NETGRAPH_ECHO opt_netgraph.h NETGRAPH_EIFACE opt_netgraph.h NETGRAPH_ETHER opt_netgraph.h NETGRAPH_ETHER_ECHO opt_netgraph.h NETGRAPH_FEC opt_netgraph.h NETGRAPH_FRAME_RELAY opt_netgraph.h NETGRAPH_GIF opt_netgraph.h NETGRAPH_GIF_DEMUX opt_netgraph.h NETGRAPH_HOLE opt_netgraph.h NETGRAPH_IFACE opt_netgraph.h NETGRAPH_IP_INPUT opt_netgraph.h NETGRAPH_IPFW opt_netgraph.h NETGRAPH_KSOCKET opt_netgraph.h NETGRAPH_L2TP opt_netgraph.h NETGRAPH_LMI opt_netgraph.h NETGRAPH_MPPC_COMPRESSION opt_netgraph.h NETGRAPH_MPPC_ENCRYPTION opt_netgraph.h NETGRAPH_NAT opt_netgraph.h NETGRAPH_NETFLOW opt_netgraph.h NETGRAPH_ONE2MANY opt_netgraph.h NETGRAPH_PATCH opt_netgraph.h NETGRAPH_PIPE opt_netgraph.h NETGRAPH_PPP opt_netgraph.h NETGRAPH_PPPOE opt_netgraph.h NETGRAPH_PPTPGRE opt_netgraph.h NETGRAPH_PRED1 opt_netgraph.h NETGRAPH_RFC1490 opt_netgraph.h NETGRAPH_SOCKET opt_netgraph.h NETGRAPH_SPLIT opt_netgraph.h NETGRAPH_SPPP opt_netgraph.h NETGRAPH_TAG opt_netgraph.h NETGRAPH_TCPMSS opt_netgraph.h NETGRAPH_TEE opt_netgraph.h NETGRAPH_TTY opt_netgraph.h NETGRAPH_UI opt_netgraph.h NETGRAPH_VJC opt_netgraph.h NETGRAPH_VLAN opt_netgraph.h # NgATM options NGATM_ATM opt_netgraph.h NGATM_ATMBASE opt_netgraph.h NGATM_SSCOP opt_netgraph.h NGATM_SSCFU opt_netgraph.h NGATM_UNI opt_netgraph.h NGATM_CCATM opt_netgraph.h # DRM options DRM_DEBUG opt_drm.h TI_SF_BUF_JUMBO opt_ti.h TI_JUMBO_HDRSPLIT opt_ti.h # Misc debug flags. Most of these should probably be replaced with # 'DEBUG', and then let people recompile just the interesting modules # with 'make CC="cc -DDEBUG"'. DEBUG_1284 opt_ppb_1284.h LPT_DEBUG opt_lpt.h PLIP_DEBUG opt_plip.h LOCKF_DEBUG opt_debug_lockf.h SI_DEBUG opt_debug_si.h IFMEDIA_DEBUG opt_ifmedia.h # Fb options FB_DEBUG opt_fb.h # ppbus related options PERIPH_1284 opt_ppb_1284.h DONTPROBE_1284 opt_ppb_1284.h # smbus related options ENABLE_ALART opt_intpm.h # These cause changes all over the kernel BLKDEV_IOSIZE opt_global.h BURN_BRIDGES opt_global.h DEBUG opt_global.h DEBUG_LOCKS opt_global.h DEBUG_VFS_LOCKS opt_global.h DFLTPHYS opt_global.h DIAGNOSTIC opt_global.h INVARIANT_SUPPORT opt_global.h INVARIANTS opt_global.h KASSERT_PANIC_OPTIONAL opt_global.h MAXCPU opt_global.h MAXMEMDOM opt_global.h MAXPHYS opt_maxphys.h MCLSHIFT opt_global.h MUTEX_NOINLINE opt_global.h LOCK_PROFILING opt_global.h MSIZE opt_global.h REGRESSION opt_global.h RWLOCK_NOINLINE opt_global.h SX_NOINLINE opt_global.h VFS_BIO_DEBUG opt_global.h # These are VM related options VM_KMEM_SIZE opt_vm.h VM_KMEM_SIZE_SCALE opt_vm.h VM_KMEM_SIZE_MAX opt_vm.h VM_NRESERVLEVEL opt_vm.h VM_LEVEL_0_ORDER opt_vm.h NO_SWAPPING opt_vm.h MALLOC_MAKE_FAILURES opt_vm.h MALLOC_PROFILE opt_vm.h MALLOC_DEBUG_MAXZONES opt_vm.h # The MemGuard replacement allocator used for tamper-after-free detection DEBUG_MEMGUARD opt_vm.h # The RedZone malloc(9) protection DEBUG_REDZONE opt_vm.h # Standard SMP options EARLY_AP_STARTUP opt_global.h SMP opt_global.h NUMA opt_global.h # Size of the kernel message buffer MSGBUF_SIZE opt_msgbuf.h # NFS options NFS_MINATTRTIMO opt_nfs.h NFS_MAXATTRTIMO opt_nfs.h NFS_MINDIRATTRTIMO opt_nfs.h NFS_MAXDIRATTRTIMO opt_nfs.h NFS_DEBUG opt_nfs.h # TMPFS options TMPFS_PAGES_MINRESERVED opt_tmpfs.h # Options for uart(4) UART_PPS_ON_CTS opt_uart.h UART_POLL_FREQ opt_uart.h UART_DEV_TOLERANCE_PCT opt_uart.h # options for bus/device framework BUS_DEBUG opt_bus.h # options for USB support USB_DEBUG opt_usb.h USB_HOST_ALIGN opt_usb.h USB_REQ_DEBUG opt_usb.h USB_TEMPLATE opt_usb.h USB_VERBOSE opt_usb.h USB_DMA_SINGLE_ALLOC opt_usb.h USB_EHCI_BIG_ENDIAN_DESC opt_usb.h U3G_DEBUG opt_u3g.h UKBD_DFLT_KEYMAP opt_ukbd.h UPLCOM_INTR_INTERVAL opt_uplcom.h UVSCOM_DEFAULT_OPKTSIZE opt_uvscom.h UVSCOM_INTR_INTERVAL opt_uvscom.h # options for the Realtek rtwn driver RTWN_DEBUG opt_rtwn.h RTWN_WITHOUT_UCODE opt_rtwn.h # Embedded system options INIT_PATH ROOTDEVNAME FDC_DEBUG opt_fdc.h PCFCLOCK_VERBOSE opt_pcfclock.h PCFCLOCK_MAX_RETRIES opt_pcfclock.h KTR opt_global.h KTR_ALQ opt_ktr.h KTR_MASK opt_ktr.h KTR_CPUMASK opt_ktr.h KTR_COMPILE opt_global.h KTR_BOOT_ENTRIES opt_global.h KTR_ENTRIES opt_global.h KTR_VERBOSE opt_ktr.h WITNESS opt_global.h WITNESS_KDB opt_witness.h WITNESS_NO_VNODE opt_witness.h WITNESS_SKIPSPIN opt_witness.h WITNESS_COUNT opt_witness.h OPENSOLARIS_WITNESS opt_global.h EPOCH_TRACE opt_global.h # options for ACPI support ACPI_DEBUG opt_acpi.h ACPI_MAX_TASKS opt_acpi.h ACPI_MAX_THREADS opt_acpi.h DEV_ACPI opt_acpi.h ACPI_EARLY_EPYC_WAR opt_acpi.h # options for IOMMU support IOMMU opt_iommu.h # ISA support DEV_ISA opt_isa.h ISAPNP opt_dontuse.h # various 'device presence' options. DEV_BPF opt_bpf.h DEV_CARP opt_carp.h DEV_NETMAP opt_global.h DEV_PCI opt_pci.h DEV_PF opt_pf.h DEV_PFLOG opt_pf.h DEV_PFSYNC opt_pf.h DEV_SPLASH opt_splash.h DEV_VLAN opt_vlan.h # bce driver BCE_DEBUG opt_bce.h BCE_NVRAM_WRITE_SUPPORT opt_bce.h SOCKBUF_DEBUG opt_global.h # options for hifn driver HIFN_DEBUG opt_hifn.h HIFN_RNDTEST opt_hifn.h # options for safenet driver SAFE_DEBUG opt_safe.h SAFE_NO_RNG opt_safe.h SAFE_RNDTEST opt_safe.h # syscons/vt options MAXCONS opt_syscons.h SC_ALT_MOUSE_IMAGE opt_syscons.h SC_CUT_SPACES2TABS opt_syscons.h SC_CUT_SEPCHARS opt_syscons.h SC_DEBUG_LEVEL opt_syscons.h SC_DFLT_FONT opt_syscons.h SC_DFLT_TERM opt_syscons.h SC_DISABLE_KDBKEY opt_syscons.h SC_DISABLE_REBOOT opt_syscons.h SC_HISTORY_SIZE opt_syscons.h SC_KERNEL_CONS_ATTR opt_syscons.h SC_KERNEL_CONS_ATTRS opt_syscons.h SC_KERNEL_CONS_REV_ATTR opt_syscons.h SC_MOUSE_CHAR opt_syscons.h SC_NO_CUTPASTE opt_syscons.h SC_NO_FONT_LOADING opt_syscons.h SC_NO_HISTORY opt_syscons.h SC_NO_MODE_CHANGE opt_syscons.h SC_NO_SUSPEND_VTYSWITCH opt_syscons.h SC_NO_SYSMOUSE opt_syscons.h SC_NO_TERM_DUMB opt_syscons.h SC_NO_TERM_SC opt_syscons.h SC_NO_TERM_TEKEN opt_syscons.h SC_NORM_ATTR opt_syscons.h SC_NORM_REV_ATTR opt_syscons.h SC_PIXEL_MODE opt_syscons.h SC_RENDER_DEBUG opt_syscons.h SC_TWOBUTTON_MOUSE opt_syscons.h VT_ALT_TO_ESC_HACK opt_syscons.h VT_FB_MAX_WIDTH opt_syscons.h VT_FB_MAX_HEIGHT opt_syscons.h VT_MAXWINDOWS opt_syscons.h VT_TWOBUTTON_MOUSE opt_syscons.h DEV_SC opt_syscons.h DEV_VT opt_syscons.h # teken terminal emulator options TEKEN_CONS25 opt_teken.h TEKEN_UTF8 opt_teken.h TERMINAL_KERN_ATTR opt_teken.h TERMINAL_NORM_ATTR opt_teken.h # options for printf PRINTF_BUFR_SIZE opt_printf.h BOOT_TAG opt_printf.h BOOT_TAG_SZ opt_printf.h # kbd options KBD_DISABLE_KEYMAP_LOAD opt_kbd.h KBD_INSTALL_CDEV opt_kbd.h KBD_MAXRETRY opt_kbd.h KBD_MAXWAIT opt_kbd.h KBD_RESETDELAY opt_kbd.h KBDIO_DEBUG opt_kbd.h KBDMUX_DFLT_KEYMAP opt_kbdmux.h # options for the Atheros driver ATH_DEBUG opt_ath.h ATH_TXBUF opt_ath.h ATH_RXBUF opt_ath.h ATH_DIAGAPI opt_ath.h ATH_TX99_DIAG opt_ath.h ATH_ENABLE_11N opt_ath.h ATH_ENABLE_DFS opt_ath.h ATH_EEPROM_FIRMWARE opt_ath.h ATH_ENABLE_RADIOTAP_VENDOR_EXT opt_ath.h ATH_DEBUG_ALQ opt_ath.h ATH_KTR_INTR_DEBUG opt_ath.h # options for the Atheros hal # XXX For now, this breaks non-AR9130 chipsets, so only use it # XXX when actually targeting AR9130. AH_SUPPORT_AR9130 opt_ah.h # This is required for AR933x SoC support AH_SUPPORT_AR9330 opt_ah.h AH_SUPPORT_AR9340 opt_ah.h AH_SUPPORT_QCA9530 opt_ah.h AH_SUPPORT_QCA9550 opt_ah.h AH_DEBUG opt_ah.h AH_ASSERT opt_ah.h AH_DEBUG_ALQ opt_ah.h AH_REGOPS_FUNC opt_ah.h AH_WRITE_REGDOMAIN opt_ah.h AH_DEBUG_COUNTRY opt_ah.h AH_WRITE_EEPROM opt_ah.h AH_PRIVATE_DIAG opt_ah.h AH_NEED_DESC_SWAP opt_ah.h AH_USE_INIPDGAIN opt_ah.h AH_MAXCHAN opt_ah.h AH_RXCFG_SDMAMW_4BYTES opt_ah.h AH_INTERRUPT_DEBUGGING opt_ah.h # AR5416 and later interrupt mitigation # XXX do not use this for AR9130 AH_AR5416_INTERRUPT_MITIGATION opt_ah.h # options for the Altera mSGDMA driver (altera_msgdma) ALTERA_MSGDMA_DESC_STD opt_altera_msgdma.h ALTERA_MSGDMA_DESC_EXT opt_altera_msgdma.h ALTERA_MSGDMA_DESC_PF_STD opt_altera_msgdma.h ALTERA_MSGDMA_DESC_PF_EXT opt_altera_msgdma.h # options for the Broadcom BCM43xx driver (bwi) BWI_DEBUG opt_bwi.h BWI_DEBUG_VERBOSE opt_bwi.h # options for the Brodacom BCM43xx driver (bwn) BWN_DEBUG opt_bwn.h BWN_GPL_PHY opt_bwn.h BWN_USE_SIBA opt_bwn.h # Options for the SIBA driver SIBA_DEBUG opt_siba.h # options for the Marvell 8335 wireless driver MALO_DEBUG opt_malo.h MALO_TXBUF opt_malo.h MALO_RXBUF opt_malo.h # options for the Marvell wireless driver MWL_DEBUG opt_mwl.h MWL_TXBUF opt_mwl.h MWL_RXBUF opt_mwl.h MWL_DIAGAPI opt_mwl.h MWL_AGGR_SIZE opt_mwl.h MWL_TX_NODROP opt_mwl.h # Options for the Marvell NETA driver MVNETA_MULTIQUEUE opt_mvneta.h MVNETA_KTR opt_mvneta.h # Options for the Intel 802.11ac wireless driver IWM_DEBUG opt_iwm.h # Options for the Intel 802.11n wireless driver IWN_DEBUG opt_iwn.h # Options for the Intel 3945ABG wireless driver WPI_DEBUG opt_wpi.h # dcons options DCONS_BUF_SIZE opt_dcons.h DCONS_POLL_HZ opt_dcons.h DCONS_FORCE_CONSOLE opt_dcons.h DCONS_FORCE_GDB opt_dcons.h # HWPMC options HWPMC_DEBUG opt_global.h HWPMC_HOOKS HWPMC_MIPS_BACKTRACE opt_hwpmc_hooks.h # 802.11 support layer IEEE80211_DEBUG opt_wlan.h IEEE80211_DEBUG_REFCNT opt_wlan.h IEEE80211_SUPPORT_MESH opt_wlan.h IEEE80211_SUPPORT_SUPERG opt_wlan.h IEEE80211_SUPPORT_TDMA opt_wlan.h IEEE80211_ALQ opt_wlan.h IEEE80211_DFS_DEBUG opt_wlan.h # 802.11 TDMA support TDMA_SLOTLEN_DEFAULT opt_tdma.h TDMA_SLOTCNT_DEFAULT opt_tdma.h TDMA_BINTVAL_DEFAULT opt_tdma.h TDMA_TXRATE_11B_DEFAULT opt_tdma.h TDMA_TXRATE_11G_DEFAULT opt_tdma.h TDMA_TXRATE_11A_DEFAULT opt_tdma.h TDMA_TXRATE_TURBO_DEFAULT opt_tdma.h TDMA_TXRATE_HALF_DEFAULT opt_tdma.h TDMA_TXRATE_QUARTER_DEFAULT opt_tdma.h TDMA_TXRATE_11NA_DEFAULT opt_tdma.h TDMA_TXRATE_11NG_DEFAULT opt_tdma.h # VideoMode PICKMODE_DEBUG opt_videomode.h # Network stack virtualization options VIMAGE opt_global.h VNET_DEBUG opt_global.h # Common Flash Interface (CFI) options CFI_SUPPORT_STRATAFLASH opt_cfi.h CFI_ARMEDANDDANGEROUS opt_cfi.h CFI_HARDWAREBYTESWAP opt_cfi.h # Sound options SND_DEBUG opt_snd.h SND_DIAGNOSTIC opt_snd.h SND_FEEDER_MULTIFORMAT opt_snd.h SND_FEEDER_FULL_MULTIFORMAT opt_snd.h SND_FEEDER_RATE_HP opt_snd.h SND_PCM_64 opt_snd.h SND_OLDSTEREO opt_snd.h X86BIOS # Flattened device tree options FDT opt_platform.h FDT_DTB_STATIC opt_platform.h # OFED Infiniband stack OFED opt_ofed.h OFED_DEBUG_INIT opt_ofed.h SDP opt_ofed.h SDP_DEBUG opt_ofed.h IPOIB opt_ofed.h IPOIB_DEBUG opt_ofed.h IPOIB_CM opt_ofed.h # Resource Accounting RACCT opt_global.h RACCT_DEFAULT_TO_DISABLED opt_global.h # Resource Limits RCTL opt_global.h # Random number generator(s) # Alternative RNG algorithm. RANDOM_FENESTRASX opt_global.h # With this, no entropy processor is loaded, but the entropy # harvesting infrastructure is present. This means an entropy # processor may be loaded as a module. RANDOM_LOADABLE opt_global.h # This turns on high-rate and potentially expensive harvesting in # the uma slab allocator. RANDOM_ENABLE_UMA opt_global.h RANDOM_ENABLE_ETHER opt_global.h # This options turns TPM into entropy source. TPM_HARVEST opt_tpm.h # BHND(4) driver BHND_LOGLEVEL opt_global.h # GPIO and child devices GPIO_SPI_DEBUG opt_gpio.h # SPI devices SPIGEN_LEGACY_CDEVNAME opt_spi.h # etherswitch(4) driver RTL8366_SOFT_RESET opt_etherswitch.h # evdev protocol support EVDEV_SUPPORT opt_evdev.h EVDEV_DEBUG opt_evdev.h UINPUT_DEBUG opt_evdev.h # Hyper-V network driver HN_DEBUG opt_hn.h # CAM-based MMC stack MMCCAM # Encrypted kernel crash dumps EKCD opt_ekcd.h # NVME options NVME_USE_NVD opt_nvme.h NVME_2X_RESET opt_nvme.h # amdsbwd options AMDSBWD_DEBUG opt_amdsbwd.h # gcov support GCOV opt_global.h LINDEBUGFS # options for HID support HID_DEBUG opt_hid.h IICHID_DEBUG opt_hid.h IICHID_SAMPLING opt_hid.h HKBD_DFLT_KEYMAP opt_hkbd.h HIDRAW_MAKE_UHID_ALIAS opt_hid.h # kenv options # The early kernel environment (loader environment, config(8)-provided static) # is typically cleared after the dynamic environment comes up to ensure that # we're not inadvertently holding on to 'secret' values in these stale envs. # This option is insecure except in controlled environments where the static # environment's contents are known to be safe. PRESERVE_EARLY_KENV opt_global.h diff --git a/sys/modules/tcp/bbr/Makefile b/sys/modules/tcp/bbr/Makefile index b94ffd0b518e..72c44f22efec 100644 --- a/sys/modules/tcp/bbr/Makefile +++ b/sys/modules/tcp/bbr/Makefile @@ -1,24 +1,23 @@ # # $FreeBSD$ # .PATH: ${.CURDIR}/../../../netinet/tcp_stacks STACKNAME= bbr KMOD= tcp_${STACKNAME} SRCS= bbr.c sack_filter.c rack_bbr_common.c SRCS+= opt_inet.h opt_inet6.h opt_ipsec.h SRCS+= opt_kern_tls.h SRCS+= opt_ratelimit.h -SRCS+= opt_tcpdebug.h # # Enable full debugging # #CFLAGS += -g CFLAGS+= -DMODNAME=${KMOD} CFLAGS+= -DSTACKNAME=${STACKNAME} .include diff --git a/sys/modules/tcp/rack/Makefile b/sys/modules/tcp/rack/Makefile index ba9dca32babe..68ce40cc074e 100644 --- a/sys/modules/tcp/rack/Makefile +++ b/sys/modules/tcp/rack/Makefile @@ -1,24 +1,23 @@ # # $FreeBSD$ # .PATH: ${.CURDIR}/../../../netinet/tcp_stacks STACKNAME= rack KMOD= tcp_${STACKNAME} SRCS= rack.c sack_filter.c rack_bbr_common.c SRCS+= opt_inet.h opt_inet6.h opt_ipsec.h SRCS+= opt_kern_tls.h SRCS+= opt_ratelimit.h -SRCS+= opt_tcpdebug.h # # Enable full debugging # #CFLAGS += -g CFLAGS+= -DMODNAME=${KMOD} CFLAGS+= -DSTACKNAME=${STACKNAME} .include diff --git a/sys/netinet/in_kdtrace.h b/sys/netinet/in_kdtrace.h index ff0430db2faf..fa88dc437fe7 100644 --- a/sys/netinet/in_kdtrace.h +++ b/sys/netinet/in_kdtrace.h @@ -1,81 +1,132 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2013 Mark Johnston * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. * * $FreeBSD$ */ #ifndef _SYS_IN_KDTRACE_H_ #define _SYS_IN_KDTRACE_H_ #define IP_PROBE(probe, arg0, arg1, arg2, arg3, arg4, arg5) \ SDT_PROBE6(ip, , , probe, arg0, arg1, arg2, arg3, arg4, arg5) #define UDP_PROBE(probe, arg0, arg1, arg2, arg3, arg4) \ SDT_PROBE5(udp, , , probe, arg0, arg1, arg2, arg3, arg4) #define UDPLITE_PROBE(probe, arg0, arg1, arg2, arg3, arg4) \ SDT_PROBE5(udplite, , , probe, arg0, arg1, arg2, arg3, arg4) #define TCP_PROBE1(probe, arg0) \ SDT_PROBE1(tcp, , , probe, arg0) #define TCP_PROBE2(probe, arg0, arg1) \ SDT_PROBE2(tcp, , , probe, arg0, arg1) #define TCP_PROBE3(probe, arg0, arg1, arg2) \ SDT_PROBE3(tcp, , , probe, arg0, arg1, arg2) #define TCP_PROBE4(probe, arg0, arg1, arg2, arg3) \ SDT_PROBE4(tcp, , , probe, arg0, arg1, arg2, arg3) #define TCP_PROBE5(probe, arg0, arg1, arg2, arg3, arg4) \ SDT_PROBE5(tcp, , , probe, arg0, arg1, arg2, arg3, arg4) #define TCP_PROBE6(probe, arg0, arg1, arg2, arg3, arg4, arg5) \ SDT_PROBE6(tcp, , , probe, arg0, arg1, arg2, arg3, arg4, arg5) SDT_PROVIDER_DECLARE(ip); SDT_PROVIDER_DECLARE(tcp); SDT_PROVIDER_DECLARE(udp); SDT_PROVIDER_DECLARE(udplite); SDT_PROBE_DECLARE(ip, , , receive); SDT_PROBE_DECLARE(ip, , , send); SDT_PROBE_DECLARE(tcp, , , accept__established); SDT_PROBE_DECLARE(tcp, , , accept__refused); SDT_PROBE_DECLARE(tcp, , , connect__established); SDT_PROBE_DECLARE(tcp, , , connect__refused); SDT_PROBE_DECLARE(tcp, , , connect__request); SDT_PROBE_DECLARE(tcp, , , receive); SDT_PROBE_DECLARE(tcp, , , send); SDT_PROBE_DECLARE(tcp, , , siftr); SDT_PROBE_DECLARE(tcp, , , state__change); SDT_PROBE_DECLARE(tcp, , , debug__input); SDT_PROBE_DECLARE(tcp, , , debug__output); SDT_PROBE_DECLARE(tcp, , , debug__user); SDT_PROBE_DECLARE(tcp, , , debug__drop); SDT_PROBE_DECLARE(tcp, , , receive__autoresize); SDT_PROBE_DECLARE(udp, , , receive); SDT_PROBE_DECLARE(udp, , , send); SDT_PROBE_DECLARE(udplite, , , receive); SDT_PROBE_DECLARE(udplite, , , send); +/* + * These constants originate from the 4.4BSD sys/protosw.h. They lost + * their initial purpose in 2c37256e5a59, when single pr_usrreq method + * was split into multiple methods. However, they were used by TCPDEBUG, + * a feature barely used, but it kept them in the tree for many years. + * In 5d06879adb95 DTrace probes started to use them. Note that they + * are not documented in dtrace_tcp(4), so they are likely to be + * eventually renamed to something better and extended/trimmed. + */ +#define PRU_ATTACH 0 /* attach protocol to up */ +#define PRU_DETACH 1 /* detach protocol from up */ +#define PRU_BIND 2 /* bind socket to address */ +#define PRU_LISTEN 3 /* listen for connection */ +#define PRU_CONNECT 4 /* establish connection to peer */ +#define PRU_ACCEPT 5 /* accept connection from peer */ +#define PRU_DISCONNECT 6 /* disconnect from peer */ +#define PRU_SHUTDOWN 7 /* won't send any more data */ +#define PRU_RCVD 8 /* have taken data; more room now */ +#define PRU_SEND 9 /* send this data */ +#define PRU_ABORT 10 /* abort (fast DISCONNECT, DETATCH) */ +#define PRU_CONTROL 11 /* control operations on protocol */ +#define PRU_SENSE 12 /* return status into m */ +#define PRU_RCVOOB 13 /* retrieve out of band data */ +#define PRU_SENDOOB 14 /* send out of band data */ +#define PRU_SOCKADDR 15 /* fetch socket's address */ +#define PRU_PEERADDR 16 /* fetch peer's address */ +#define PRU_CONNECT2 17 /* connect two sockets */ +/* begin for protocols internal use */ +#define PRU_FASTTIMO 18 /* 200ms timeout */ +#define PRU_SLOWTIMO 19 /* 500ms timeout */ +#define PRU_PROTORCV 20 /* receive from below */ +#define PRU_PROTOSEND 21 /* send to below */ +/* end for protocol's internal use */ +#define PRU_SEND_EOF 22 /* send and close */ +#define PRU_SOSETLABEL 23 /* MAC label change */ +#define PRU_CLOSE 24 /* socket close */ +#define PRU_FLUSH 25 /* flush the socket */ +#define PRU_NREQ 25 + +#ifdef PRUREQUESTS +const char *prurequests[] = { + "ATTACH", "DETACH", "BIND", "LISTEN", + "CONNECT", "ACCEPT", "DISCONNECT", "SHUTDOWN", + "RCVD", "SEND", "ABORT", "CONTROL", + "SENSE", "RCVOOB", "SENDOOB", "SOCKADDR", + "PEERADDR", "CONNECT2", "FASTTIMO", "SLOWTIMO", + "PROTORCV", "PROTOSEND", "SEND_EOF", "SOSETLABEL", + "CLOSE", "FLUSH", +}; +#endif + #endif diff --git a/sys/netinet/tcp_debug.c b/sys/netinet/tcp_debug.c deleted file mode 100644 index e00dc095b01f..000000000000 --- a/sys/netinet/tcp_debug.c +++ /dev/null @@ -1,225 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)tcp_debug.c 8.1 (Berkeley) 6/10/93 - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_inet.h" -#include "opt_inet6.h" -#include "opt_tcpdebug.h" - -#ifdef TCPDEBUG -/* load symbolic names */ -#define PRUREQUESTS -#define TCPSTATES -#define TCPTIMERS -#define TANAMES -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#ifdef INET6 -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -#ifdef TCPDEBUG -static int tcpconsdebug = 0; -#endif - -/* - * Global ring buffer of TCP debugging state. Each entry captures a snapshot - * of TCP connection state at any given moment. tcp_debx addresses at the - * next available slot. There is no explicit export of this data structure; - * it will be read via /dev/kmem by debugging tools. - */ -static struct tcp_debug tcp_debug[TCP_NDEBUG]; -static int tcp_debx; - -/* - * All global state is protected by tcp_debug_mtx; tcp_trace() is split into - * two parts, one of which saves connection and other state into the global - * array (locked by tcp_debug_mtx). - */ -struct mtx tcp_debug_mtx; -MTX_SYSINIT(tcp_debug_mtx, &tcp_debug_mtx, "tcp_debug_mtx", MTX_DEF); - -/* - * Save TCP state at a given moment; optionally, both tcpcb and TCP packet - * header state will be saved. - */ -void -tcp_trace(short act, short ostate, struct tcpcb *tp, void *ipgen, - struct tcphdr *th, int req) -{ -#ifdef INET6 - int isipv6; -#endif /* INET6 */ - tcp_seq seq, ack; - int len, flags; - struct tcp_debug *td; - - mtx_lock(&tcp_debug_mtx); - td = &tcp_debug[tcp_debx++]; - if (tcp_debx == TCP_NDEBUG) - tcp_debx = 0; - bzero(td, sizeof(*td)); -#ifdef INET6 - isipv6 = (ipgen != NULL && ((struct ip *)ipgen)->ip_v == 6) ? 1 : 0; -#endif /* INET6 */ - td->td_family = -#ifdef INET6 - (isipv6 != 0) ? AF_INET6 : -#endif - AF_INET; -#ifdef INET - td->td_time = iptime(); -#endif - td->td_act = act; - td->td_ostate = ostate; - td->td_tcb = (caddr_t)tp; - if (tp != NULL) - td->td_cb = *tp; - if (ipgen != NULL) { - switch (td->td_family) { -#ifdef INET - case AF_INET: - bcopy(ipgen, &td->td_ti.ti_i, sizeof(td->td_ti.ti_i)); - break; -#endif -#ifdef INET6 - case AF_INET6: - bcopy(ipgen, td->td_ip6buf, sizeof(td->td_ip6buf)); - break; -#endif - } - } - if (th != NULL) { - switch (td->td_family) { -#ifdef INET - case AF_INET: - td->td_ti.ti_t = *th; - break; -#endif -#ifdef INET6 - case AF_INET6: - td->td_ti6.th = *th; - break; -#endif - } - } - td->td_req = req; - mtx_unlock(&tcp_debug_mtx); -#ifdef TCPDEBUG - if (tcpconsdebug == 0) - return; - if (tp != NULL) - printf("%p %s:", tp, tcpstates[ostate]); - else - printf("???????? "); - printf("%s ", tanames[act]); - switch (act) { - case TA_INPUT: - case TA_OUTPUT: - case TA_DROP: - if (ipgen == NULL || th == NULL) - break; - seq = th->th_seq; - ack = th->th_ack; - len = -#ifdef INET6 - isipv6 ? ntohs(((struct ip6_hdr *)ipgen)->ip6_plen) : -#endif - ntohs(((struct ip *)ipgen)->ip_len); - if (act == TA_OUTPUT) { - seq = ntohl(seq); - ack = ntohl(ack); - } - if (act == TA_OUTPUT) - len -= sizeof (struct tcphdr); - if (len) - printf("[%x..%x)", seq, seq+len); - else - printf("%x", seq); - printf("@%x, urp=%x", ack, th->th_urp); - flags = tcp_get_flags(th); - if (flags) { - char *cp = "<"; -#define pf(f) { \ - if (tcp_get_flags(th) & TH_##f) { \ - printf("%s%s", cp, #f); \ - cp = ","; \ - } \ -} - pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG); - printf(">"); - } - break; - - case TA_USER: - printf("%s", prurequests[req&0xff]); - if ((req & 0xff) == PRU_SLOWTIMO) - printf("<%s>", tcptimers[req>>8]); - break; - } - if (tp != NULL) - printf(" -> %s", tcpstates[tp->t_state]); - /* print out internal state of tp !?! */ - printf("\n"); - if (tp == NULL) - return; - printf( - "\trcv_(nxt,wnd,up) (%lx,%lx,%lx) snd_(una,nxt,max) (%lx,%lx,%lx)\n", - (u_long)tp->rcv_nxt, (u_long)tp->rcv_wnd, (u_long)tp->rcv_up, - (u_long)tp->snd_una, (u_long)tp->snd_nxt, (u_long)tp->snd_max); - printf("\tsnd_(wl1,wl2,wnd) (%lx,%lx,%lx)\n", - (u_long)tp->snd_wl1, (u_long)tp->snd_wl2, (u_long)tp->snd_wnd); -#endif /* TCPDEBUG */ -} diff --git a/sys/netinet/tcp_debug.h b/sys/netinet/tcp_debug.h deleted file mode 100644 index 6bb296ea0e52..000000000000 --- a/sys/netinet/tcp_debug.h +++ /dev/null @@ -1,119 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)tcp_debug.h 8.1 (Berkeley) 6/10/93 - * $FreeBSD$ - */ - -#ifndef _NETINET_TCP_DEBUG_H_ -#define _NETINET_TCP_DEBUG_H_ - -struct tcp_debug { - uint32_t td_time; /* network format */ - short td_act; - short td_ostate; - caddr_t td_tcb; - int td_family; - /* - * Co-existense of td_ti and td_ti6 below is ugly, but it is necessary - * to achieve backword compatibility to some extent. - */ - struct tcpiphdr td_ti; - struct { -#define IP6_HDR_LEN 40 /* sizeof(struct ip6_hdr) */ -#if !defined(_KERNEL) && defined(INET6) - struct ip6_hdr ip6; -#else - u_char ip6buf[IP6_HDR_LEN]; -#endif - struct tcphdr th; - } td_ti6; -#define td_ip6buf td_ti6.ip6buf - short td_req; - struct tcpcb td_cb; -}; - -#define TA_INPUT 0 -#define TA_OUTPUT 1 -#define TA_USER 2 -#define TA_RESPOND 3 -#define TA_DROP 4 - -#ifdef TANAMES -static const char *tanames[] = - { "input", "output", "user", "respond", "drop" }; -#endif - -#define TCP_NDEBUG 100 - -/* These older constants are still present in order to support TCP debugging. */ -#define PRU_ATTACH 0 /* attach protocol to up */ -#define PRU_DETACH 1 /* detach protocol from up */ -#define PRU_BIND 2 /* bind socket to address */ -#define PRU_LISTEN 3 /* listen for connection */ -#define PRU_CONNECT 4 /* establish connection to peer */ -#define PRU_ACCEPT 5 /* accept connection from peer */ -#define PRU_DISCONNECT 6 /* disconnect from peer */ -#define PRU_SHUTDOWN 7 /* won't send any more data */ -#define PRU_RCVD 8 /* have taken data; more room now */ -#define PRU_SEND 9 /* send this data */ -#define PRU_ABORT 10 /* abort (fast DISCONNECT, DETATCH) */ -#define PRU_CONTROL 11 /* control operations on protocol */ -#define PRU_SENSE 12 /* return status into m */ -#define PRU_RCVOOB 13 /* retrieve out of band data */ -#define PRU_SENDOOB 14 /* send out of band data */ -#define PRU_SOCKADDR 15 /* fetch socket's address */ -#define PRU_PEERADDR 16 /* fetch peer's address */ -#define PRU_CONNECT2 17 /* connect two sockets */ -/* begin for protocols internal use */ -#define PRU_FASTTIMO 18 /* 200ms timeout */ -#define PRU_SLOWTIMO 19 /* 500ms timeout */ -#define PRU_PROTORCV 20 /* receive from below */ -#define PRU_PROTOSEND 21 /* send to below */ -/* end for protocol's internal use */ -#define PRU_SEND_EOF 22 /* send and close */ -#define PRU_SOSETLABEL 23 /* MAC label change */ -#define PRU_CLOSE 24 /* socket close */ -#define PRU_FLUSH 25 /* flush the socket */ -#define PRU_NREQ 25 - -#ifdef PRUREQUESTS -const char *prurequests[] = { - "ATTACH", "DETACH", "BIND", "LISTEN", - "CONNECT", "ACCEPT", "DISCONNECT", "SHUTDOWN", - "RCVD", "SEND", "ABORT", "CONTROL", - "SENSE", "RCVOOB", "SENDOOB", "SOCKADDR", - "PEERADDR", "CONNECT2", "FASTTIMO", "SLOWTIMO", - "PROTORCV", "PROTOSEND", "SEND_EOF", "SOSETLABEL", - "CLOSE", "FLUSH", -}; -#endif - -#endif /* !_NETINET_TCP_DEBUG_H_ */ diff --git a/sys/netinet/tcp_ecn.c b/sys/netinet/tcp_ecn.c index 5b19ed93225f..579c0b407ae1 100644 --- a/sys/netinet/tcp_ecn.c +++ b/sys/netinet/tcp_ecn.c @@ -1,619 +1,618 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995 * The Regents of the University of California. All rights reserved. * Copyright (c) 2007-2008,2010 * Swinburne University of Technology, Melbourne, Australia. * Copyright (c) 2009-2010 Lawrence Stewart * Copyright (c) 2010 The FreeBSD Foundation * Copyright (c) 2010-2011 Juniper Networks, Inc. * Copyright (c) 2019 Richard Scheffenegger * All rights reserved. * * Portions of this software were developed at the Centre for Advanced Internet * Architectures, Swinburne University of Technology, by Lawrence Stewart, * James Healy and David Hayes, made possible in part by a grant from the Cisco * University Research Program Fund at Community Foundation Silicon Valley. * * Portions of this software were developed at the Centre for Advanced * Internet Architectures, Swinburne University of Technology, Melbourne, * Australia by David Hayes under sponsorship from the FreeBSD Foundation. * * Portions of this software were developed by Robert N. M. Watson under * contract to Juniper Networks, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * @(#)tcp_ecn.c 8.12 (Berkeley) 5/24/95 */ /* * Utility functions to deal with Explicit Congestion Notification in TCP * implementing the essential parts of the Accurate ECN extension * https://tools.ietf.org/html/draft-ietf-tcpm-accurate-ecn-09 */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" -#include "opt_tcpdebug.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static SYSCTL_NODE(_net_inet_tcp, OID_AUTO, ecn, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "TCP ECN"); VNET_DEFINE(int, tcp_do_ecn) = 2; SYSCTL_INT(_net_inet_tcp_ecn, OID_AUTO, enable, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_ecn), 0, "TCP ECN support"); VNET_DEFINE(int, tcp_ecn_maxretries) = 1; SYSCTL_INT(_net_inet_tcp_ecn, OID_AUTO, maxretries, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_ecn_maxretries), 0, "Max retries before giving up on ECN"); /* * Process incoming SYN,ACK packet */ void tcp_ecn_input_syn_sent(struct tcpcb *tp, uint16_t thflags, int iptos) { if (V_tcp_do_ecn == 0) return; if ((V_tcp_do_ecn == 1) || (V_tcp_do_ecn == 2)) { /* RFC3168 ECN handling */ if ((thflags & (TH_CWR | TH_ECE)) == (0 | TH_ECE)) { tp->t_flags2 |= TF2_ECN_PERMIT; tp->t_flags2 &= ~TF2_ACE_PERMIT; TCPSTAT_INC(tcps_ecn_shs); } } else /* decoding Accurate ECN according to table in section 3.1.1 */ if ((V_tcp_do_ecn == 3) || (V_tcp_do_ecn == 4)) { /* * on the SYN,ACK, process the AccECN * flags indicating the state the SYN * was delivered. * Reactions to Path ECN mangling can * come here. */ switch (thflags & (TH_AE | TH_CWR | TH_ECE)) { /* RFC3168 SYN */ case (0|0|TH_ECE): tp->t_flags2 |= TF2_ECN_PERMIT; tp->t_flags2 &= ~TF2_ACE_PERMIT; TCPSTAT_INC(tcps_ecn_shs); break; /* non-ECT SYN */ case (0|TH_CWR|0): tp->t_flags2 |= TF2_ACE_PERMIT; tp->t_flags2 &= ~TF2_ECN_PERMIT; tp->t_scep = 5; TCPSTAT_INC(tcps_ecn_shs); TCPSTAT_INC(tcps_ace_nect); break; /* ECT0 SYN */ case (TH_AE|0|0): tp->t_flags2 |= TF2_ACE_PERMIT; tp->t_flags2 &= ~TF2_ECN_PERMIT; tp->t_scep = 5; TCPSTAT_INC(tcps_ecn_shs); TCPSTAT_INC(tcps_ace_ect0); break; /* ECT1 SYN */ case (0|TH_CWR|TH_ECE): tp->t_flags2 |= TF2_ACE_PERMIT; tp->t_flags2 &= ~TF2_ECN_PERMIT; tp->t_scep = 5; TCPSTAT_INC(tcps_ecn_shs); TCPSTAT_INC(tcps_ace_ect1); break; /* CE SYN */ case (TH_AE|TH_CWR|0): tp->t_flags2 |= TF2_ACE_PERMIT; tp->t_flags2 &= ~TF2_ECN_PERMIT; tp->t_scep = 6; /* * reduce the IW to 2 MSS (to * account for delayed acks) if * the SYN,ACK was CE marked */ tp->snd_cwnd = 2 * tcp_maxseg(tp); TCPSTAT_INC(tcps_ecn_shs); TCPSTAT_INC(tcps_ace_nect); break; default: tp->t_flags2 &= ~(TF2_ECN_PERMIT | TF2_ACE_PERMIT); break; } /* * Set the AccECN Codepoints on * the outgoing to the ECN * state of the * according to table 3 in the * AccECN draft */ switch (iptos & IPTOS_ECN_MASK) { case (IPTOS_ECN_NOTECT): tp->t_rcep = 0b010; break; case (IPTOS_ECN_ECT0): tp->t_rcep = 0b100; break; case (IPTOS_ECN_ECT1): tp->t_rcep = 0b011; break; case (IPTOS_ECN_CE): tp->t_rcep = 0b110; break; } } } /* * Handle parallel SYN for ECN */ void tcp_ecn_input_parallel_syn(struct tcpcb *tp, uint16_t thflags, int iptos) { if (thflags & TH_ACK) return; if (V_tcp_do_ecn == 0) return; if ((V_tcp_do_ecn == 1) || (V_tcp_do_ecn == 2)) { /* RFC3168 ECN handling */ if ((thflags & (TH_CWR | TH_ECE)) == (TH_CWR | TH_ECE)) { tp->t_flags2 |= TF2_ECN_PERMIT; tp->t_flags2 &= ~TF2_ACE_PERMIT; tp->t_flags2 |= TF2_ECN_SND_ECE; TCPSTAT_INC(tcps_ecn_shs); } } else if ((V_tcp_do_ecn == 3) || (V_tcp_do_ecn == 4)) { /* AccECN handling */ switch (thflags & (TH_AE | TH_CWR | TH_ECE)) { default: case (0|0|0): tp->t_flags2 &= ~(TF2_ECN_PERMIT | TF2_ACE_PERMIT); break; case (0|TH_CWR|TH_ECE): tp->t_flags2 |= TF2_ECN_PERMIT; tp->t_flags2 &= ~TF2_ACE_PERMIT; tp->t_flags2 |= TF2_ECN_SND_ECE; TCPSTAT_INC(tcps_ecn_shs); break; case (TH_AE|TH_CWR|TH_ECE): tp->t_flags2 |= TF2_ACE_PERMIT; tp->t_flags2 &= ~TF2_ECN_PERMIT; TCPSTAT_INC(tcps_ecn_shs); /* * Set the AccECN Codepoints on * the outgoing to the ECN * state of the * according to table 3 in the * AccECN draft */ switch (iptos & IPTOS_ECN_MASK) { case (IPTOS_ECN_NOTECT): tp->t_rcep = 0b010; break; case (IPTOS_ECN_ECT0): tp->t_rcep = 0b100; break; case (IPTOS_ECN_ECT1): tp->t_rcep = 0b011; break; case (IPTOS_ECN_CE): tp->t_rcep = 0b110; break; } break; } } } /* * TCP ECN processing. */ int tcp_ecn_input_segment(struct tcpcb *tp, uint16_t thflags, int tlen, int pkts, int iptos) { int delta_cep = 0; switch (iptos & IPTOS_ECN_MASK) { case IPTOS_ECN_CE: TCPSTAT_INC(tcps_ecn_rcvce); break; case IPTOS_ECN_ECT0: TCPSTAT_INC(tcps_ecn_rcvect0); break; case IPTOS_ECN_ECT1: TCPSTAT_INC(tcps_ecn_rcvect1); break; } if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) { if (tp->t_flags2 & TF2_ACE_PERMIT) { if ((iptos & IPTOS_ECN_MASK) == IPTOS_ECN_CE) tp->t_rcep += 1; if (tp->t_flags2 & TF2_ECN_PERMIT) { delta_cep = (tcp_ecn_get_ace(thflags) + 8 - (tp->t_scep & 7)) & 7; if (delta_cep < pkts) delta_cep = pkts - ((pkts - delta_cep) & 7); tp->t_scep += delta_cep; } else { /* * process the final ACK of the 3WHS * see table 3 in draft-ietf-tcpm-accurate-ecn */ switch (tcp_ecn_get_ace(thflags)) { case 0b010: /* nonECT SYN or SYN,ACK */ /* Fallthrough */ case 0b011: /* ECT1 SYN or SYN,ACK */ /* Fallthrough */ case 0b100: /* ECT0 SYN or SYN,ACK */ tp->t_scep = 5; break; case 0b110: /* CE SYN or SYN,ACK */ tp->t_scep = 6; tp->snd_cwnd = 2 * tcp_maxseg(tp); break; default: /* mangled AccECN handshake */ tp->t_scep = 5; break; } tp->t_flags2 |= TF2_ECN_PERMIT; } } else { /* RFC3168 ECN handling */ if ((thflags & (TH_SYN | TH_ECE)) == TH_ECE) { delta_cep = 1; tp->t_scep++; } if (thflags & TH_CWR) { tp->t_flags2 &= ~TF2_ECN_SND_ECE; tp->t_flags |= TF_ACKNOW; } if ((iptos & IPTOS_ECN_MASK) == IPTOS_ECN_CE) tp->t_flags2 |= TF2_ECN_SND_ECE; } /* Process a packet differently from RFC3168. */ cc_ecnpkt_handler_flags(tp, thflags, iptos); } return delta_cep; } /* * Send ECN setup packet header flags */ uint16_t tcp_ecn_output_syn_sent(struct tcpcb *tp) { uint16_t thflags = 0; if (V_tcp_do_ecn == 0) return thflags; if (V_tcp_do_ecn == 1) { /* Send a RFC3168 ECN setup packet */ if (tp->t_rxtshift >= 1) { if (tp->t_rxtshift <= V_tcp_ecn_maxretries) thflags = TH_ECE|TH_CWR; } else thflags = TH_ECE|TH_CWR; } else if (V_tcp_do_ecn == 3) { /* Send an Accurate ECN setup packet */ if (tp->t_rxtshift >= 1) { if (tp->t_rxtshift <= V_tcp_ecn_maxretries) thflags = TH_ECE|TH_CWR|TH_AE; } else thflags = TH_ECE|TH_CWR|TH_AE; } return thflags; } /* * output processing of ECN feature * returning IP ECN header codepoint */ int tcp_ecn_output_established(struct tcpcb *tp, uint16_t *thflags, int len, bool rxmit) { int ipecn = IPTOS_ECN_NOTECT; bool newdata; /* * If the peer has ECN, mark data packets with * ECN capable transmission (ECT). * Ignore pure control packets, retransmissions * and window probes. */ newdata = (len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) && !rxmit && !((tp->t_flags & TF_FORCEDATA) && len == 1)); /* RFC3168 ECN marking, only new data segments */ if (newdata) { if (tp->t_flags2 & TF2_ECN_USE_ECT1) { ipecn = IPTOS_ECN_ECT1; TCPSTAT_INC(tcps_ecn_sndect1); } else { ipecn = IPTOS_ECN_ECT0; TCPSTAT_INC(tcps_ecn_sndect0); } } /* * Reply with proper ECN notifications. */ if (tp->t_flags2 & TF2_ACE_PERMIT) { *thflags &= ~(TH_AE|TH_CWR|TH_ECE); if (tp->t_rcep & 0x01) *thflags |= TH_ECE; if (tp->t_rcep & 0x02) *thflags |= TH_CWR; if (tp->t_rcep & 0x04) *thflags |= TH_AE; if (!(tp->t_flags2 & TF2_ECN_PERMIT)) { /* * here we process the final * ACK of the 3WHS */ if (tp->t_rcep == 0b110) { tp->t_rcep = 6; } else { tp->t_rcep = 5; } tp->t_flags2 |= TF2_ECN_PERMIT; } } else { if (newdata && (tp->t_flags2 & TF2_ECN_SND_CWR)) { *thflags |= TH_CWR; tp->t_flags2 &= ~TF2_ECN_SND_CWR; } if (tp->t_flags2 & TF2_ECN_SND_ECE) *thflags |= TH_ECE; } return ipecn; } /* * Set up the ECN related tcpcb fields from * a syncache entry */ void tcp_ecn_syncache_socket(struct tcpcb *tp, struct syncache *sc) { if (sc->sc_flags & SCF_ECN_MASK) { switch (sc->sc_flags & SCF_ECN_MASK) { case SCF_ECN: tp->t_flags2 |= TF2_ECN_PERMIT; break; case SCF_ACE_N: /* Fallthrough */ case SCF_ACE_0: /* Fallthrough */ case SCF_ACE_1: tp->t_flags2 |= TF2_ACE_PERMIT; tp->t_scep = 5; tp->t_rcep = 5; break; case SCF_ACE_CE: tp->t_flags2 |= TF2_ACE_PERMIT; tp->t_scep = 6; tp->t_rcep = 6; break; /* undefined SCF codepoint */ default: break; } } } /* * Process a packets ECN information, and provide the * syncache with the relevant information. */ int tcp_ecn_syncache_add(uint16_t thflags, int iptos) { int scflags = 0; switch (iptos & IPTOS_ECN_MASK) { case IPTOS_ECN_CE: TCPSTAT_INC(tcps_ecn_rcvce); break; case IPTOS_ECN_ECT0: TCPSTAT_INC(tcps_ecn_rcvect0); break; case IPTOS_ECN_ECT1: TCPSTAT_INC(tcps_ecn_rcvect1); break; } switch (thflags & (TH_AE|TH_CWR|TH_ECE)) { /* no ECN */ case (0|0|0): break; /* legacy ECN */ case (0|TH_CWR|TH_ECE): scflags = SCF_ECN; break; /* Accurate ECN */ case (TH_AE|TH_CWR|TH_ECE): if ((V_tcp_do_ecn == 3) || (V_tcp_do_ecn == 4)) { switch (iptos & IPTOS_ECN_MASK) { case IPTOS_ECN_CE: scflags = SCF_ACE_CE; break; case IPTOS_ECN_ECT0: scflags = SCF_ACE_0; break; case IPTOS_ECN_ECT1: scflags = SCF_ACE_1; break; case IPTOS_ECN_NOTECT: scflags = SCF_ACE_N; break; } } else scflags = SCF_ECN; break; /* Default Case (section 3.1.2) */ default: if ((V_tcp_do_ecn == 3) || (V_tcp_do_ecn == 4)) { switch (iptos & IPTOS_ECN_MASK) { case IPTOS_ECN_CE: scflags = SCF_ACE_CE; break; case IPTOS_ECN_ECT0: scflags = SCF_ACE_0; break; case IPTOS_ECN_ECT1: scflags = SCF_ACE_1; break; case IPTOS_ECN_NOTECT: scflags = SCF_ACE_N; break; } } break; } return scflags; } /* * Set up the ECN information for the from * syncache information. */ uint16_t tcp_ecn_syncache_respond(uint16_t thflags, struct syncache *sc) { if ((thflags & TH_SYN) && (sc->sc_flags & SCF_ECN_MASK)) { switch (sc->sc_flags & SCF_ECN_MASK) { case SCF_ECN: thflags |= (0 | 0 | TH_ECE); TCPSTAT_INC(tcps_ecn_shs); break; case SCF_ACE_N: thflags |= (0 | TH_CWR | 0); TCPSTAT_INC(tcps_ecn_shs); TCPSTAT_INC(tcps_ace_nect); break; case SCF_ACE_0: thflags |= (TH_AE | 0 | 0); TCPSTAT_INC(tcps_ecn_shs); TCPSTAT_INC(tcps_ace_ect0); break; case SCF_ACE_1: thflags |= (0 | TH_ECE | TH_CWR); TCPSTAT_INC(tcps_ecn_shs); TCPSTAT_INC(tcps_ace_ect1); break; case SCF_ACE_CE: thflags |= (TH_AE | TH_CWR | 0); TCPSTAT_INC(tcps_ecn_shs); TCPSTAT_INC(tcps_ace_ce); break; /* undefined SCF codepoint */ default: break; } } return thflags; } int tcp_ecn_get_ace(uint16_t thflags) { int ace = 0; if (thflags & TH_ECE) ace += 1; if (thflags & TH_CWR) ace += 2; if (thflags & TH_AE) ace += 4; return ace; } diff --git a/sys/netinet/tcp_hpts.c b/sys/netinet/tcp_hpts.c index d3e923406784..5731e9a81e19 100644 --- a/sys/netinet/tcp_hpts.c +++ b/sys/netinet/tcp_hpts.c @@ -1,2046 +1,2042 @@ /*- * Copyright (c) 2016-2018 Netflix, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_rss.h" -#include "opt_tcpdebug.h" /** * Some notes about usage. * * The tcp_hpts system is designed to provide a high precision timer * system for tcp. Its main purpose is to provide a mechanism for * pacing packets out onto the wire. It can be used in two ways * by a given TCP stack (and those two methods can be used simultaneously). * * First, and probably the main thing its used by Rack and BBR, it can * be used to call tcp_output() of a transport stack at some time in the future. * The normal way this is done is that tcp_output() of the stack schedules * itself to be called again by calling tcp_hpts_insert(tcpcb, slot). The * slot is the time from now that the stack wants to be called but it * must be converted to tcp_hpts's notion of slot. This is done with * one of the macros HPTS_MS_TO_SLOTS or HPTS_USEC_TO_SLOTS. So a typical * call from the tcp_output() routine might look like: * * tcp_hpts_insert(tp, HPTS_USEC_TO_SLOTS(550)); * * The above would schedule tcp_ouput() to be called in 550 useconds. * Note that if using this mechanism the stack will want to add near * its top a check to prevent unwanted calls (from user land or the * arrival of incoming ack's). So it would add something like: * * if (tcp_in_hpts(inp)) * return; * * to prevent output processing until the time alotted has gone by. * Of course this is a bare bones example and the stack will probably * have more consideration then just the above. * * In order to run input queued segments from the HPTS context the * tcp stack must define an input function for * tfb_do_queued_segments(). This function understands * how to dequeue a array of packets that were input and * knows how to call the correct processing routine. * * Locking in this is important as well so most likely the * stack will need to define the tfb_do_segment_nounlock() * splitting tfb_do_segment() into two parts. The main processing * part that does not unlock the INP and returns a value of 1 or 0. * It returns 0 if all is well and the lock was not released. It * returns 1 if we had to destroy the TCB (a reset received etc). * The remains of tfb_do_segment() then become just a simple call * to the tfb_do_segment_nounlock() function and check the return * code and possibly unlock. * * The stack must also set the flag on the INP that it supports this * feature i.e. INP_SUPPORTS_MBUFQ. The LRO code recoginizes * this flag as well and will queue packets when it is set. * There are other flags as well INP_MBUF_QUEUE_READY and * INP_DONT_SACK_QUEUE. The first flag tells the LRO code * that we are in the pacer for output so there is no * need to wake up the hpts system to get immediate * input. The second tells the LRO code that its okay * if a SACK arrives you can still defer input and let * the current hpts timer run (this is usually set when * a rack timer is up so we know SACK's are happening * on the connection already and don't want to wakeup yet). * * There is a common functions within the rack_bbr_common code * version i.e. ctf_do_queued_segments(). This function * knows how to take the input queue of packets from * tp->t_in_pkts and process them digging out * all the arguments, calling any bpf tap and * calling into tfb_do_segment_nounlock(). The common * function (ctf_do_queued_segments()) requires that * you have defined the tfb_do_segment_nounlock() as * described above. */ #include #include #include #include #include #include #include #include #include /* for proc0 declaration */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef RSS #include #include #endif #define TCPSTATES /* for logging */ #include #include #include #include #include /* required for icmp_var.h */ #include /* for ICMP_BANDLIM */ #include #include #include #include #include #include #include #include #include #include #include #include #include -#ifdef tcpdebug -#include -#endif /* tcpdebug */ #ifdef tcp_offload #include #endif /* * The hpts uses a 102400 wheel. The wheel * defines the time in 10 usec increments (102400 x 10). * This gives a range of 10usec - 1024ms to place * an entry within. If the user requests more than * 1.024 second, a remaineder is attached and the hpts * when seeing the remainder will re-insert the * inpcb forward in time from where it is until * the remainder is zero. */ #define NUM_OF_HPTSI_SLOTS 102400 /* Each hpts has its own p_mtx which is used for locking */ #define HPTS_MTX_ASSERT(hpts) mtx_assert(&(hpts)->p_mtx, MA_OWNED) #define HPTS_LOCK(hpts) mtx_lock(&(hpts)->p_mtx) #define HPTS_UNLOCK(hpts) mtx_unlock(&(hpts)->p_mtx) struct tcp_hpts_entry { /* Cache line 0x00 */ struct mtx p_mtx; /* Mutex for hpts */ struct timeval p_mysleep; /* Our min sleep time */ uint64_t syscall_cnt; uint64_t sleeping; /* What the actual sleep was (if sleeping) */ uint16_t p_hpts_active; /* Flag that says hpts is awake */ uint8_t p_wheel_complete; /* have we completed the wheel arc walk? */ uint32_t p_curtick; /* Tick in 10 us the hpts is going to */ uint32_t p_runningslot; /* Current tick we are at if we are running */ uint32_t p_prev_slot; /* Previous slot we were on */ uint32_t p_cur_slot; /* Current slot in wheel hpts is draining */ uint32_t p_nxt_slot; /* The next slot outside the current range of * slots that the hpts is running on. */ int32_t p_on_queue_cnt; /* Count on queue in this hpts */ uint32_t p_lasttick; /* Last tick before the current one */ uint8_t p_direct_wake :1, /* boolean */ p_on_min_sleep:1, /* boolean */ p_hpts_wake_scheduled:1, /* boolean */ p_avail:5; uint8_t p_fill[3]; /* Fill to 32 bits */ /* Cache line 0x40 */ struct hptsh { TAILQ_HEAD(, inpcb) head; uint32_t count; uint32_t gencnt; } *p_hptss; /* Hptsi wheel */ uint32_t p_hpts_sleep_time; /* Current sleep interval having a max * of 255ms */ uint32_t overidden_sleep; /* what was overrided by min-sleep for logging */ uint32_t saved_lasttick; /* for logging */ uint32_t saved_curtick; /* for logging */ uint32_t saved_curslot; /* for logging */ uint32_t saved_prev_slot; /* for logging */ uint32_t p_delayed_by; /* How much were we delayed by */ /* Cache line 0x80 */ struct sysctl_ctx_list hpts_ctx; struct sysctl_oid *hpts_root; struct intr_event *ie; void *ie_cookie; uint16_t p_num; /* The hpts number one per cpu */ uint16_t p_cpu; /* The hpts CPU */ /* There is extra space in here */ /* Cache line 0x100 */ struct callout co __aligned(CACHE_LINE_SIZE); } __aligned(CACHE_LINE_SIZE); static struct tcp_hptsi { struct cpu_group **grps; struct tcp_hpts_entry **rp_ent; /* Array of hptss */ uint32_t *cts_last_ran; uint32_t grp_cnt; uint32_t rp_num_hptss; /* Number of hpts threads */ } tcp_pace; MALLOC_DEFINE(M_TCPHPTS, "tcp_hpts", "TCP hpts"); #ifdef RSS static int tcp_bind_threads = 1; #else static int tcp_bind_threads = 2; #endif static int tcp_use_irq_cpu = 0; static uint32_t *cts_last_ran; static int hpts_does_tp_logging = 0; static int32_t tcp_hptsi(struct tcp_hpts_entry *hpts, int from_callout); static void tcp_hpts_thread(void *ctx); static void tcp_init_hptsi(void *st); int32_t tcp_min_hptsi_time = DEFAULT_MIN_SLEEP; static int conn_cnt_thresh = DEFAULT_CONNECTION_THESHOLD; static int32_t dynamic_min_sleep = DYNAMIC_MIN_SLEEP; static int32_t dynamic_max_sleep = DYNAMIC_MAX_SLEEP; SYSCTL_NODE(_net_inet_tcp, OID_AUTO, hpts, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "TCP Hpts controls"); SYSCTL_NODE(_net_inet_tcp_hpts, OID_AUTO, stats, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "TCP Hpts statistics"); #define timersub(tvp, uvp, vvp) \ do { \ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ if ((vvp)->tv_usec < 0) { \ (vvp)->tv_sec--; \ (vvp)->tv_usec += 1000000; \ } \ } while (0) static int32_t tcp_hpts_precision = 120; static struct hpts_domain_info { int count; int cpu[MAXCPU]; } hpts_domains[MAXMEMDOM]; enum { IHPTS_NONE = 0, IHPTS_ONQUEUE, IHPTS_MOVING, }; counter_u64_t hpts_hopelessly_behind; SYSCTL_COUNTER_U64(_net_inet_tcp_hpts_stats, OID_AUTO, hopeless, CTLFLAG_RD, &hpts_hopelessly_behind, "Number of times hpts could not catch up and was behind hopelessly"); counter_u64_t hpts_loops; SYSCTL_COUNTER_U64(_net_inet_tcp_hpts_stats, OID_AUTO, loops, CTLFLAG_RD, &hpts_loops, "Number of times hpts had to loop to catch up"); counter_u64_t back_tosleep; SYSCTL_COUNTER_U64(_net_inet_tcp_hpts_stats, OID_AUTO, no_tcbsfound, CTLFLAG_RD, &back_tosleep, "Number of times hpts found no tcbs"); counter_u64_t combined_wheel_wrap; SYSCTL_COUNTER_U64(_net_inet_tcp_hpts_stats, OID_AUTO, comb_wheel_wrap, CTLFLAG_RD, &combined_wheel_wrap, "Number of times the wheel lagged enough to have an insert see wrap"); counter_u64_t wheel_wrap; SYSCTL_COUNTER_U64(_net_inet_tcp_hpts_stats, OID_AUTO, wheel_wrap, CTLFLAG_RD, &wheel_wrap, "Number of times the wheel lagged enough to have an insert see wrap"); counter_u64_t hpts_direct_call; SYSCTL_COUNTER_U64(_net_inet_tcp_hpts_stats, OID_AUTO, direct_call, CTLFLAG_RD, &hpts_direct_call, "Number of times hpts was called by syscall/trap or other entry"); counter_u64_t hpts_wake_timeout; SYSCTL_COUNTER_U64(_net_inet_tcp_hpts_stats, OID_AUTO, timeout_wakeup, CTLFLAG_RD, &hpts_wake_timeout, "Number of times hpts threads woke up via the callout expiring"); counter_u64_t hpts_direct_awakening; SYSCTL_COUNTER_U64(_net_inet_tcp_hpts_stats, OID_AUTO, direct_awakening, CTLFLAG_RD, &hpts_direct_awakening, "Number of times hpts threads woke up via the callout expiring"); counter_u64_t hpts_back_tosleep; SYSCTL_COUNTER_U64(_net_inet_tcp_hpts_stats, OID_AUTO, back_tosleep, CTLFLAG_RD, &hpts_back_tosleep, "Number of times hpts threads woke up via the callout expiring and went back to sleep no work"); counter_u64_t cpu_uses_flowid; counter_u64_t cpu_uses_random; SYSCTL_COUNTER_U64(_net_inet_tcp_hpts_stats, OID_AUTO, cpusel_flowid, CTLFLAG_RD, &cpu_uses_flowid, "Number of times when setting cpuid we used the flowid field"); SYSCTL_COUNTER_U64(_net_inet_tcp_hpts_stats, OID_AUTO, cpusel_random, CTLFLAG_RD, &cpu_uses_random, "Number of times when setting cpuid we used the a random value"); TUNABLE_INT("net.inet.tcp.bind_hptss", &tcp_bind_threads); TUNABLE_INT("net.inet.tcp.use_irq", &tcp_use_irq_cpu); SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, bind_hptss, CTLFLAG_RD, &tcp_bind_threads, 2, "Thread Binding tunable"); SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, use_irq, CTLFLAG_RD, &tcp_use_irq_cpu, 0, "Use of irq CPU tunable"); SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, precision, CTLFLAG_RW, &tcp_hpts_precision, 120, "Value for PRE() precision of callout"); SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, cnt_thresh, CTLFLAG_RW, &conn_cnt_thresh, 0, "How many connections (below) make us use the callout based mechanism"); SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, logging, CTLFLAG_RW, &hpts_does_tp_logging, 0, "Do we add to any tp that has logging on pacer logs"); SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, dyn_minsleep, CTLFLAG_RW, &dynamic_min_sleep, 250, "What is the dynamic minsleep value?"); SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, dyn_maxsleep, CTLFLAG_RW, &dynamic_max_sleep, 5000, "What is the dynamic maxsleep value?"); static int32_t max_pacer_loops = 10; SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, loopmax, CTLFLAG_RW, &max_pacer_loops, 10, "What is the maximum number of times the pacer will loop trying to catch up"); #define HPTS_MAX_SLEEP_ALLOWED (NUM_OF_HPTSI_SLOTS/2) static uint32_t hpts_sleep_max = HPTS_MAX_SLEEP_ALLOWED; static int sysctl_net_inet_tcp_hpts_max_sleep(SYSCTL_HANDLER_ARGS) { int error; uint32_t new; new = hpts_sleep_max; error = sysctl_handle_int(oidp, &new, 0, req); if (error == 0 && req->newptr) { if ((new < (dynamic_min_sleep/HPTS_TICKS_PER_SLOT)) || (new > HPTS_MAX_SLEEP_ALLOWED)) error = EINVAL; else hpts_sleep_max = new; } return (error); } static int sysctl_net_inet_tcp_hpts_min_sleep(SYSCTL_HANDLER_ARGS) { int error; uint32_t new; new = tcp_min_hptsi_time; error = sysctl_handle_int(oidp, &new, 0, req); if (error == 0 && req->newptr) { if (new < LOWEST_SLEEP_ALLOWED) error = EINVAL; else tcp_min_hptsi_time = new; } return (error); } SYSCTL_PROC(_net_inet_tcp_hpts, OID_AUTO, maxsleep, CTLTYPE_UINT | CTLFLAG_RW, &hpts_sleep_max, 0, &sysctl_net_inet_tcp_hpts_max_sleep, "IU", "Maximum time hpts will sleep in slots"); SYSCTL_PROC(_net_inet_tcp_hpts, OID_AUTO, minsleep, CTLTYPE_UINT | CTLFLAG_RW, &tcp_min_hptsi_time, 0, &sysctl_net_inet_tcp_hpts_min_sleep, "IU", "The minimum time the hpts must sleep before processing more slots"); static int ticks_indicate_more_sleep = TICKS_INDICATE_MORE_SLEEP; static int ticks_indicate_less_sleep = TICKS_INDICATE_LESS_SLEEP; static int tcp_hpts_no_wake_over_thresh = 1; SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, more_sleep, CTLFLAG_RW, &ticks_indicate_more_sleep, 0, "If we only process this many or less on a timeout, we need longer sleep on the next callout"); SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, less_sleep, CTLFLAG_RW, &ticks_indicate_less_sleep, 0, "If we process this many or more on a timeout, we need less sleep on the next callout"); SYSCTL_INT(_net_inet_tcp_hpts, OID_AUTO, nowake_over_thresh, CTLFLAG_RW, &tcp_hpts_no_wake_over_thresh, 0, "When we are over the threshold on the pacer do we prohibit wakeups?"); static void tcp_hpts_log(struct tcp_hpts_entry *hpts, struct tcpcb *tp, struct timeval *tv, int slots_to_run, int idx, int from_callout) { union tcp_log_stackspecific log; /* * Unused logs are * 64 bit - delRate, rttProp, bw_inuse * 16 bit - cwnd_gain * 8 bit - bbr_state, bbr_substate, inhpts; */ memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.flex1 = hpts->p_nxt_slot; log.u_bbr.flex2 = hpts->p_cur_slot; log.u_bbr.flex3 = hpts->p_prev_slot; log.u_bbr.flex4 = idx; log.u_bbr.flex5 = hpts->p_curtick; log.u_bbr.flex6 = hpts->p_on_queue_cnt; log.u_bbr.flex7 = hpts->p_cpu; log.u_bbr.flex8 = (uint8_t)from_callout; log.u_bbr.inflight = slots_to_run; log.u_bbr.applimited = hpts->overidden_sleep; log.u_bbr.delivered = hpts->saved_curtick; log.u_bbr.timeStamp = tcp_tv_to_usectick(tv); log.u_bbr.epoch = hpts->saved_curslot; log.u_bbr.lt_epoch = hpts->saved_prev_slot; log.u_bbr.pkts_out = hpts->p_delayed_by; log.u_bbr.lost = hpts->p_hpts_sleep_time; log.u_bbr.pacing_gain = hpts->p_cpu; log.u_bbr.pkt_epoch = hpts->p_runningslot; log.u_bbr.use_lt_bw = 1; TCP_LOG_EVENTP(tp, NULL, &tptosocket(tp)->so_rcv, &tptosocket(tp)->so_snd, BBR_LOG_HPTSDIAG, 0, 0, &log, false, tv); } static void tcp_wakehpts(struct tcp_hpts_entry *hpts) { HPTS_MTX_ASSERT(hpts); if (tcp_hpts_no_wake_over_thresh && (hpts->p_on_queue_cnt >= conn_cnt_thresh)) { hpts->p_direct_wake = 0; return; } if (hpts->p_hpts_wake_scheduled == 0) { hpts->p_hpts_wake_scheduled = 1; swi_sched(hpts->ie_cookie, 0); } } static void hpts_timeout_swi(void *arg) { struct tcp_hpts_entry *hpts; hpts = (struct tcp_hpts_entry *)arg; swi_sched(hpts->ie_cookie, 0); } static void inp_hpts_insert(struct inpcb *inp, struct tcp_hpts_entry *hpts) { struct hptsh *hptsh; INP_WLOCK_ASSERT(inp); HPTS_MTX_ASSERT(hpts); MPASS(hpts->p_cpu == inp->inp_hpts_cpu); MPASS(!(inp->inp_flags & INP_DROPPED)); hptsh = &hpts->p_hptss[inp->inp_hptsslot]; if (inp->inp_in_hpts == IHPTS_NONE) { inp->inp_in_hpts = IHPTS_ONQUEUE; in_pcbref(inp); } else if (inp->inp_in_hpts == IHPTS_MOVING) { inp->inp_in_hpts = IHPTS_ONQUEUE; } else MPASS(inp->inp_in_hpts == IHPTS_ONQUEUE); inp->inp_hpts_gencnt = hptsh->gencnt; TAILQ_INSERT_TAIL(&hptsh->head, inp, inp_hpts); hptsh->count++; hpts->p_on_queue_cnt++; } static struct tcp_hpts_entry * tcp_hpts_lock(struct inpcb *inp) { struct tcp_hpts_entry *hpts; INP_LOCK_ASSERT(inp); hpts = tcp_pace.rp_ent[inp->inp_hpts_cpu]; HPTS_LOCK(hpts); return (hpts); } static void inp_hpts_release(struct inpcb *inp) { bool released __diagused; inp->inp_in_hpts = IHPTS_NONE; released = in_pcbrele_wlocked(inp); MPASS(released == false); } /* * Called normally with the INP_LOCKED but it * does not matter, the hpts lock is the key * but the lock order allows us to hold the * INP lock and then get the hpts lock. */ void tcp_hpts_remove(struct inpcb *inp) { struct tcp_hpts_entry *hpts; struct hptsh *hptsh; INP_WLOCK_ASSERT(inp); hpts = tcp_hpts_lock(inp); if (inp->inp_in_hpts == IHPTS_ONQUEUE) { hptsh = &hpts->p_hptss[inp->inp_hptsslot]; inp->inp_hpts_request = 0; if (__predict_true(inp->inp_hpts_gencnt == hptsh->gencnt)) { TAILQ_REMOVE(&hptsh->head, inp, inp_hpts); MPASS(hptsh->count > 0); hptsh->count--; MPASS(hpts->p_on_queue_cnt > 0); hpts->p_on_queue_cnt--; inp_hpts_release(inp); } else { /* * tcp_hptsi() now owns the TAILQ head of this inp. * Can't TAILQ_REMOVE, just mark it. */ #ifdef INVARIANTS struct inpcb *tmp; TAILQ_FOREACH(tmp, &hptsh->head, inp_hpts) MPASS(tmp != inp); #endif inp->inp_in_hpts = IHPTS_MOVING; inp->inp_hptsslot = -1; } } else if (inp->inp_in_hpts == IHPTS_MOVING) { /* * Handle a special race condition: * tcp_hptsi() moves inpcb to detached tailq * tcp_hpts_remove() marks as IHPTS_MOVING, slot = -1 * tcp_hpts_insert() sets slot to a meaningful value * tcp_hpts_remove() again (we are here!), then in_pcbdrop() * tcp_hptsi() finds pcb with meaningful slot and INP_DROPPED */ inp->inp_hptsslot = -1; } HPTS_UNLOCK(hpts); } bool tcp_in_hpts(struct inpcb *inp) { return (inp->inp_in_hpts == IHPTS_ONQUEUE); } static inline int hpts_slot(uint32_t wheel_slot, uint32_t plus) { /* * Given a slot on the wheel, what slot * is that plus ticks out? */ KASSERT(wheel_slot < NUM_OF_HPTSI_SLOTS, ("Invalid tick %u not on wheel", wheel_slot)); return ((wheel_slot + plus) % NUM_OF_HPTSI_SLOTS); } static inline int tick_to_wheel(uint32_t cts_in_wticks) { /* * Given a timestamp in ticks (so by * default to get it to a real time one * would multiply by 10.. i.e the number * of ticks in a slot) map it to our limited * space wheel. */ return (cts_in_wticks % NUM_OF_HPTSI_SLOTS); } static inline int hpts_slots_diff(int prev_slot, int slot_now) { /* * Given two slots that are someplace * on our wheel. How far are they apart? */ if (slot_now > prev_slot) return (slot_now - prev_slot); else if (slot_now == prev_slot) /* * Special case, same means we can go all of our * wheel less one slot. */ return (NUM_OF_HPTSI_SLOTS - 1); else return ((NUM_OF_HPTSI_SLOTS - prev_slot) + slot_now); } /* * Given a slot on the wheel that is the current time * mapped to the wheel (wheel_slot), what is the maximum * distance forward that can be obtained without * wrapping past either prev_slot or running_slot * depending on the htps state? Also if passed * a uint32_t *, fill it with the slot location. * * Note if you do not give this function the current * time (that you think it is) mapped to the wheel slot * then the results will not be what you expect and * could lead to invalid inserts. */ static inline int32_t max_slots_available(struct tcp_hpts_entry *hpts, uint32_t wheel_slot, uint32_t *target_slot) { uint32_t dis_to_travel, end_slot, pacer_to_now, avail_on_wheel; if ((hpts->p_hpts_active == 1) && (hpts->p_wheel_complete == 0)) { end_slot = hpts->p_runningslot; /* Back up one tick */ if (end_slot == 0) end_slot = NUM_OF_HPTSI_SLOTS - 1; else end_slot--; if (target_slot) *target_slot = end_slot; } else { /* * For the case where we are * not active, or we have * completed the pass over * the wheel, we can use the * prev tick and subtract one from it. This puts us * as far out as possible on the wheel. */ end_slot = hpts->p_prev_slot; if (end_slot == 0) end_slot = NUM_OF_HPTSI_SLOTS - 1; else end_slot--; if (target_slot) *target_slot = end_slot; /* * Now we have close to the full wheel left minus the * time it has been since the pacer went to sleep. Note * that wheel_tick, passed in, should be the current time * from the perspective of the caller, mapped to the wheel. */ if (hpts->p_prev_slot != wheel_slot) dis_to_travel = hpts_slots_diff(hpts->p_prev_slot, wheel_slot); else dis_to_travel = 1; /* * dis_to_travel in this case is the space from when the * pacer stopped (p_prev_slot) and where our wheel_slot * is now. To know how many slots we can put it in we * subtract from the wheel size. We would not want * to place something after p_prev_slot or it will * get ran too soon. */ return (NUM_OF_HPTSI_SLOTS - dis_to_travel); } /* * So how many slots are open between p_runningslot -> p_cur_slot * that is what is currently un-available for insertion. Special * case when we are at the last slot, this gets 1, so that * the answer to how many slots are available is all but 1. */ if (hpts->p_runningslot == hpts->p_cur_slot) dis_to_travel = 1; else dis_to_travel = hpts_slots_diff(hpts->p_runningslot, hpts->p_cur_slot); /* * How long has the pacer been running? */ if (hpts->p_cur_slot != wheel_slot) { /* The pacer is a bit late */ pacer_to_now = hpts_slots_diff(hpts->p_cur_slot, wheel_slot); } else { /* The pacer is right on time, now == pacers start time */ pacer_to_now = 0; } /* * To get the number left we can insert into we simply * subract the distance the pacer has to run from how * many slots there are. */ avail_on_wheel = NUM_OF_HPTSI_SLOTS - dis_to_travel; /* * Now how many of those we will eat due to the pacer's * time (p_cur_slot) of start being behind the * real time (wheel_slot)? */ if (avail_on_wheel <= pacer_to_now) { /* * Wheel wrap, we can't fit on the wheel, that * is unusual the system must be way overloaded! * Insert into the assured slot, and return special * "0". */ counter_u64_add(combined_wheel_wrap, 1); *target_slot = hpts->p_nxt_slot; return (0); } else { /* * We know how many slots are open * on the wheel (the reverse of what * is left to run. Take away the time * the pacer started to now (wheel_slot) * and that tells you how many slots are * open that can be inserted into that won't * be touched by the pacer until later. */ return (avail_on_wheel - pacer_to_now); } } #ifdef INVARIANTS static void check_if_slot_would_be_wrong(struct tcp_hpts_entry *hpts, struct inpcb *inp, uint32_t inp_hptsslot, int line) { /* * Sanity checks for the pacer with invariants * on insert. */ KASSERT(inp_hptsslot < NUM_OF_HPTSI_SLOTS, ("hpts:%p inp:%p slot:%d > max", hpts, inp, inp_hptsslot)); if ((hpts->p_hpts_active) && (hpts->p_wheel_complete == 0)) { /* * If the pacer is processing a arc * of the wheel, we need to make * sure we are not inserting within * that arc. */ int distance, yet_to_run; distance = hpts_slots_diff(hpts->p_runningslot, inp_hptsslot); if (hpts->p_runningslot != hpts->p_cur_slot) yet_to_run = hpts_slots_diff(hpts->p_runningslot, hpts->p_cur_slot); else yet_to_run = 0; /* processing last slot */ KASSERT(yet_to_run <= distance, ("hpts:%p inp:%p slot:%d distance:%d yet_to_run:%d rs:%d cs:%d", hpts, inp, inp_hptsslot, distance, yet_to_run, hpts->p_runningslot, hpts->p_cur_slot)); } } #endif uint32_t tcp_hpts_insert_diag(struct inpcb *inp, uint32_t slot, int32_t line, struct hpts_diag *diag) { struct tcp_hpts_entry *hpts; struct timeval tv; uint32_t slot_on, wheel_cts, last_slot, need_new_to = 0; int32_t wheel_slot, maxslots; bool need_wakeup = false; INP_WLOCK_ASSERT(inp); MPASS(!tcp_in_hpts(inp)); MPASS(!(inp->inp_flags & INP_DROPPED)); /* * We now return the next-slot the hpts will be on, beyond its * current run (if up) or where it was when it stopped if it is * sleeping. */ hpts = tcp_hpts_lock(inp); microuptime(&tv); if (diag) { memset(diag, 0, sizeof(struct hpts_diag)); diag->p_hpts_active = hpts->p_hpts_active; diag->p_prev_slot = hpts->p_prev_slot; diag->p_runningslot = hpts->p_runningslot; diag->p_nxt_slot = hpts->p_nxt_slot; diag->p_cur_slot = hpts->p_cur_slot; diag->p_curtick = hpts->p_curtick; diag->p_lasttick = hpts->p_lasttick; diag->slot_req = slot; diag->p_on_min_sleep = hpts->p_on_min_sleep; diag->hpts_sleep_time = hpts->p_hpts_sleep_time; } if (slot == 0) { /* Ok we need to set it on the hpts in the current slot */ inp->inp_hpts_request = 0; if ((hpts->p_hpts_active == 0) || (hpts->p_wheel_complete)) { /* * A sleeping hpts we want in next slot to run * note that in this state p_prev_slot == p_cur_slot */ inp->inp_hptsslot = hpts_slot(hpts->p_prev_slot, 1); if ((hpts->p_on_min_sleep == 0) && (hpts->p_hpts_active == 0)) need_wakeup = true; } else inp->inp_hptsslot = hpts->p_runningslot; if (__predict_true(inp->inp_in_hpts != IHPTS_MOVING)) inp_hpts_insert(inp, hpts); if (need_wakeup) { /* * Activate the hpts if it is sleeping and its * timeout is not 1. */ hpts->p_direct_wake = 1; tcp_wakehpts(hpts); } slot_on = hpts->p_nxt_slot; HPTS_UNLOCK(hpts); return (slot_on); } /* Get the current time relative to the wheel */ wheel_cts = tcp_tv_to_hptstick(&tv); /* Map it onto the wheel */ wheel_slot = tick_to_wheel(wheel_cts); /* Now what's the max we can place it at? */ maxslots = max_slots_available(hpts, wheel_slot, &last_slot); if (diag) { diag->wheel_slot = wheel_slot; diag->maxslots = maxslots; diag->wheel_cts = wheel_cts; } if (maxslots == 0) { /* The pacer is in a wheel wrap behind, yikes! */ if (slot > 1) { /* * Reduce by 1 to prevent a forever loop in * case something else is wrong. Note this * probably does not hurt because the pacer * if its true is so far behind we will be * > 1second late calling anyway. */ slot--; } inp->inp_hptsslot = last_slot; inp->inp_hpts_request = slot; } else if (maxslots >= slot) { /* It all fits on the wheel */ inp->inp_hpts_request = 0; inp->inp_hptsslot = hpts_slot(wheel_slot, slot); } else { /* It does not fit */ inp->inp_hpts_request = slot - maxslots; inp->inp_hptsslot = last_slot; } if (diag) { diag->slot_remaining = inp->inp_hpts_request; diag->inp_hptsslot = inp->inp_hptsslot; } #ifdef INVARIANTS check_if_slot_would_be_wrong(hpts, inp, inp->inp_hptsslot, line); #endif if (__predict_true(inp->inp_in_hpts != IHPTS_MOVING)) inp_hpts_insert(inp, hpts); if ((hpts->p_hpts_active == 0) && (inp->inp_hpts_request == 0) && (hpts->p_on_min_sleep == 0)) { /* * The hpts is sleeping and NOT on a minimum * sleep time, we need to figure out where * it will wake up at and if we need to reschedule * its time-out. */ uint32_t have_slept, yet_to_sleep; /* Now do we need to restart the hpts's timer? */ have_slept = hpts_slots_diff(hpts->p_prev_slot, wheel_slot); if (have_slept < hpts->p_hpts_sleep_time) yet_to_sleep = hpts->p_hpts_sleep_time - have_slept; else { /* We are over-due */ yet_to_sleep = 0; need_wakeup = 1; } if (diag) { diag->have_slept = have_slept; diag->yet_to_sleep = yet_to_sleep; } if (yet_to_sleep && (yet_to_sleep > slot)) { /* * We need to reschedule the hpts's time-out. */ hpts->p_hpts_sleep_time = slot; need_new_to = slot * HPTS_TICKS_PER_SLOT; } } /* * Now how far is the hpts sleeping to? if active is 1, its * up and ticking we do nothing, otherwise we may need to * reschedule its callout if need_new_to is set from above. */ if (need_wakeup) { hpts->p_direct_wake = 1; tcp_wakehpts(hpts); if (diag) { diag->need_new_to = 0; diag->co_ret = 0xffff0000; } } else if (need_new_to) { int32_t co_ret; struct timeval tv; sbintime_t sb; tv.tv_sec = 0; tv.tv_usec = 0; while (need_new_to > HPTS_USEC_IN_SEC) { tv.tv_sec++; need_new_to -= HPTS_USEC_IN_SEC; } tv.tv_usec = need_new_to; sb = tvtosbt(tv); co_ret = callout_reset_sbt_on(&hpts->co, sb, 0, hpts_timeout_swi, hpts, hpts->p_cpu, (C_DIRECT_EXEC | C_PREL(tcp_hpts_precision))); if (diag) { diag->need_new_to = need_new_to; diag->co_ret = co_ret; } } slot_on = hpts->p_nxt_slot; HPTS_UNLOCK(hpts); return (slot_on); } uint16_t hpts_random_cpu(struct inpcb *inp){ /* * No flow type set distribute the load randomly. */ uint16_t cpuid; uint32_t ran; /* * Shortcut if it is already set. XXXGL: does it happen? */ if (inp->inp_hpts_cpu_set) { return (inp->inp_hpts_cpu); } /* Nothing set use a random number */ ran = arc4random(); cpuid = (((ran & 0xffff) % mp_ncpus) % tcp_pace.rp_num_hptss); return (cpuid); } static uint16_t hpts_cpuid(struct inpcb *inp, int *failed) { u_int cpuid; #ifdef NUMA struct hpts_domain_info *di; #endif *failed = 0; if (inp->inp_hpts_cpu_set) { return (inp->inp_hpts_cpu); } /* * If we are using the irq cpu set by LRO or * the driver then it overrides all other domains. */ if (tcp_use_irq_cpu) { if (inp->inp_irq_cpu_set == 0) { *failed = 1; return(0); } return(inp->inp_irq_cpu); } /* If one is set the other must be the same */ #ifdef RSS cpuid = rss_hash2cpuid(inp->inp_flowid, inp->inp_flowtype); if (cpuid == NETISR_CPUID_NONE) return (hpts_random_cpu(inp)); else return (cpuid); #endif /* * We don't have a flowid -> cpuid mapping, so cheat and just map * unknown cpuids to curcpu. Not the best, but apparently better * than defaulting to swi 0. */ if (inp->inp_flowtype == M_HASHTYPE_NONE) { counter_u64_add(cpu_uses_random, 1); return (hpts_random_cpu(inp)); } /* * Hash to a thread based on the flowid. If we are using numa, * then restrict the hash to the numa domain where the inp lives. */ #ifdef NUMA if ((vm_ndomains == 1) || (inp->inp_numa_domain == M_NODOM)) { #endif cpuid = inp->inp_flowid % mp_ncpus; #ifdef NUMA } else { /* Hash into the cpu's that use that domain */ di = &hpts_domains[inp->inp_numa_domain]; cpuid = di->cpu[inp->inp_flowid % di->count]; } #endif counter_u64_add(cpu_uses_flowid, 1); return (cpuid); } #ifdef not_longer_used_gleb static void tcp_drop_in_pkts(struct tcpcb *tp) { struct mbuf *m, *n; m = tp->t_in_pkt; if (m) n = m->m_nextpkt; else n = NULL; tp->t_in_pkt = NULL; while (m) { m_freem(m); m = n; if (m) n = m->m_nextpkt; } } #endif static void tcp_hpts_set_max_sleep(struct tcp_hpts_entry *hpts, int wrap_loop_cnt) { uint32_t t = 0, i; if ((hpts->p_on_queue_cnt) && (wrap_loop_cnt < 2)) { /* * Find next slot that is occupied and use that to * be the sleep time. */ for (i = 0, t = hpts_slot(hpts->p_cur_slot, 1); i < NUM_OF_HPTSI_SLOTS; i++) { if (TAILQ_EMPTY(&hpts->p_hptss[t].head) == 0) { break; } t = (t + 1) % NUM_OF_HPTSI_SLOTS; } KASSERT((i != NUM_OF_HPTSI_SLOTS), ("Hpts:%p cnt:%d but none found", hpts, hpts->p_on_queue_cnt)); hpts->p_hpts_sleep_time = min((i + 1), hpts_sleep_max); } else { /* No one on the wheel sleep for all but 400 slots or sleep max */ hpts->p_hpts_sleep_time = hpts_sleep_max; } } static int32_t tcp_hptsi(struct tcp_hpts_entry *hpts, int from_callout) { struct tcpcb *tp; struct inpcb *inp; struct timeval tv; int32_t slots_to_run, i, error; int32_t loop_cnt = 0; int32_t did_prefetch = 0; int32_t prefetch_ninp = 0; int32_t prefetch_tp = 0; int32_t wrap_loop_cnt = 0; int32_t slot_pos_of_endpoint = 0; int32_t orig_exit_slot; int8_t completed_measure = 0, seen_endpoint = 0; HPTS_MTX_ASSERT(hpts); NET_EPOCH_ASSERT(); /* record previous info for any logging */ hpts->saved_lasttick = hpts->p_lasttick; hpts->saved_curtick = hpts->p_curtick; hpts->saved_curslot = hpts->p_cur_slot; hpts->saved_prev_slot = hpts->p_prev_slot; hpts->p_lasttick = hpts->p_curtick; hpts->p_curtick = tcp_gethptstick(&tv); cts_last_ran[hpts->p_num] = tcp_tv_to_usectick(&tv); orig_exit_slot = hpts->p_cur_slot = tick_to_wheel(hpts->p_curtick); if ((hpts->p_on_queue_cnt == 0) || (hpts->p_lasttick == hpts->p_curtick)) { /* * No time has yet passed, * or nothing to do. */ hpts->p_prev_slot = hpts->p_cur_slot; hpts->p_lasttick = hpts->p_curtick; goto no_run; } again: hpts->p_wheel_complete = 0; HPTS_MTX_ASSERT(hpts); slots_to_run = hpts_slots_diff(hpts->p_prev_slot, hpts->p_cur_slot); if (((hpts->p_curtick - hpts->p_lasttick) > ((NUM_OF_HPTSI_SLOTS-1) * HPTS_TICKS_PER_SLOT)) && (hpts->p_on_queue_cnt != 0)) { /* * Wheel wrap is occuring, basically we * are behind and the distance between * run's has spread so much it has exceeded * the time on the wheel (1.024 seconds). This * is ugly and should NOT be happening. We * need to run the entire wheel. We last processed * p_prev_slot, so that needs to be the last slot * we run. The next slot after that should be our * reserved first slot for new, and then starts * the running position. Now the problem is the * reserved "not to yet" place does not exist * and there may be inp's in there that need * running. We can merge those into the * first slot at the head. */ wrap_loop_cnt++; hpts->p_nxt_slot = hpts_slot(hpts->p_prev_slot, 1); hpts->p_runningslot = hpts_slot(hpts->p_prev_slot, 2); /* * Adjust p_cur_slot to be where we are starting from * hopefully we will catch up (fat chance if something * is broken this bad :( ) */ hpts->p_cur_slot = hpts->p_prev_slot; /* * The next slot has guys to run too, and that would * be where we would normally start, lets move them into * the next slot (p_prev_slot + 2) so that we will * run them, the extra 10usecs of late (by being * put behind) does not really matter in this situation. */ TAILQ_FOREACH(inp, &hpts->p_hptss[hpts->p_nxt_slot].head, inp_hpts) { MPASS(inp->inp_hptsslot == hpts->p_nxt_slot); MPASS(inp->inp_hpts_gencnt == hpts->p_hptss[hpts->p_nxt_slot].gencnt); MPASS(inp->inp_in_hpts == IHPTS_ONQUEUE); /* * Update gencnt and nextslot accordingly to match * the new location. This is safe since it takes both * the INP lock and the pacer mutex to change the * inp_hptsslot and inp_hpts_gencnt. */ inp->inp_hpts_gencnt = hpts->p_hptss[hpts->p_runningslot].gencnt; inp->inp_hptsslot = hpts->p_runningslot; } TAILQ_CONCAT(&hpts->p_hptss[hpts->p_runningslot].head, &hpts->p_hptss[hpts->p_nxt_slot].head, inp_hpts); hpts->p_hptss[hpts->p_runningslot].count += hpts->p_hptss[hpts->p_nxt_slot].count; hpts->p_hptss[hpts->p_nxt_slot].count = 0; hpts->p_hptss[hpts->p_nxt_slot].gencnt++; slots_to_run = NUM_OF_HPTSI_SLOTS - 1; counter_u64_add(wheel_wrap, 1); } else { /* * Nxt slot is always one after p_runningslot though * its not used usually unless we are doing wheel wrap. */ hpts->p_nxt_slot = hpts->p_prev_slot; hpts->p_runningslot = hpts_slot(hpts->p_prev_slot, 1); } if (hpts->p_on_queue_cnt == 0) { goto no_one; } for (i = 0; i < slots_to_run; i++) { struct inpcb *inp, *ninp; TAILQ_HEAD(, inpcb) head = TAILQ_HEAD_INITIALIZER(head); struct hptsh *hptsh; uint32_t runningslot; /* * Calculate our delay, if there are no extra ticks there * was not any (i.e. if slots_to_run == 1, no delay). */ hpts->p_delayed_by = (slots_to_run - (i + 1)) * HPTS_TICKS_PER_SLOT; runningslot = hpts->p_runningslot; hptsh = &hpts->p_hptss[runningslot]; TAILQ_SWAP(&head, &hptsh->head, inpcb, inp_hpts); hpts->p_on_queue_cnt -= hptsh->count; hptsh->count = 0; hptsh->gencnt++; HPTS_UNLOCK(hpts); TAILQ_FOREACH_SAFE(inp, &head, inp_hpts, ninp) { bool set_cpu; if (ninp != NULL) { /* We prefetch the next inp if possible */ kern_prefetch(ninp, &prefetch_ninp); prefetch_ninp = 1; } /* For debugging */ if (seen_endpoint == 0) { seen_endpoint = 1; orig_exit_slot = slot_pos_of_endpoint = runningslot; } else if (completed_measure == 0) { /* Record the new position */ orig_exit_slot = runningslot; } INP_WLOCK(inp); if (inp->inp_hpts_cpu_set == 0) { set_cpu = true; } else { set_cpu = false; } if (__predict_false(inp->inp_in_hpts == IHPTS_MOVING)) { if (inp->inp_hptsslot == -1) { inp->inp_in_hpts = IHPTS_NONE; if (in_pcbrele_wlocked(inp) == false) INP_WUNLOCK(inp); } else { HPTS_LOCK(hpts); inp_hpts_insert(inp, hpts); HPTS_UNLOCK(hpts); INP_WUNLOCK(inp); } continue; } MPASS(inp->inp_in_hpts == IHPTS_ONQUEUE); MPASS(!(inp->inp_flags & INP_DROPPED)); KASSERT(runningslot == inp->inp_hptsslot, ("Hpts:%p inp:%p slot mis-aligned %u vs %u", hpts, inp, runningslot, inp->inp_hptsslot)); if (inp->inp_hpts_request) { /* * This guy is deferred out further in time * then our wheel had available on it. * Push him back on the wheel or run it * depending. */ uint32_t maxslots, last_slot, remaining_slots; remaining_slots = slots_to_run - (i + 1); if (inp->inp_hpts_request > remaining_slots) { HPTS_LOCK(hpts); /* * How far out can we go? */ maxslots = max_slots_available(hpts, hpts->p_cur_slot, &last_slot); if (maxslots >= inp->inp_hpts_request) { /* We can place it finally to * be processed. */ inp->inp_hptsslot = hpts_slot( hpts->p_runningslot, inp->inp_hpts_request); inp->inp_hpts_request = 0; } else { /* Work off some more time */ inp->inp_hptsslot = last_slot; inp->inp_hpts_request -= maxslots; } inp_hpts_insert(inp, hpts); HPTS_UNLOCK(hpts); INP_WUNLOCK(inp); continue; } inp->inp_hpts_request = 0; /* Fall through we will so do it now */ } inp_hpts_release(inp); tp = intotcpcb(inp); MPASS(tp); if (set_cpu) { /* * Setup so the next time we will move to * the right CPU. This should be a rare * event. It will sometimes happens when we * are the client side (usually not the * server). Somehow tcp_output() gets called * before the tcp_do_segment() sets the * intial state. This means the r_cpu and * r_hpts_cpu is 0. We get on the hpts, and * then tcp_input() gets called setting up * the r_cpu to the correct value. The hpts * goes off and sees the mis-match. We * simply correct it here and the CPU will * switch to the new hpts nextime the tcb * gets added to the hpts (not this one) * :-) */ tcp_set_hpts(inp); } CURVNET_SET(inp->inp_vnet); /* Lets do any logging that we might want to */ if (hpts_does_tp_logging && (tp->t_logstate != TCP_LOG_STATE_OFF)) { tcp_hpts_log(hpts, tp, &tv, slots_to_run, i, from_callout); } if (tp->t_fb_ptr != NULL) { kern_prefetch(tp->t_fb_ptr, &did_prefetch); did_prefetch = 1; } if ((inp->inp_flags2 & INP_SUPPORTS_MBUFQ) && tp->t_in_pkt) { error = (*tp->t_fb->tfb_do_queued_segments)(inp->inp_socket, tp, 0); if (error) { /* The input killed the connection */ goto skip_pacing; } } inp->inp_hpts_calls = 1; error = tcp_output(tp); if (error < 0) goto skip_pacing; inp->inp_hpts_calls = 0; if (ninp) { /* * If we have a nxt inp, see if we can * prefetch it. Note this may seem * "risky" since we have no locks (other * than the previous inp) and there no * assurance that ninp was not pulled while * we were processing inp and freed. If this * occurred it could mean that either: * * a) Its NULL (which is fine we won't go * here) b) Its valid (which is cool we * will prefetch it) c) The inp got * freed back to the slab which was * reallocated. Then the piece of memory was * re-used and something else (not an * address) is in inp_ppcb. If that occurs * we don't crash, but take a TLB shootdown * performance hit (same as if it was NULL * and we tried to pre-fetch it). * * Considering that the likelyhood of is * quite rare we will take a risk on doing * this. If performance drops after testing * we can always take this out. NB: the * kern_prefetch on amd64 actually has * protection against a bad address now via * the DMAP_() tests. This will prevent the * TLB hit, and instead if occurs just * cause us to load cache with a useless * address (to us). * * XXXGL: with tcpcb == inpcb, I'm unsure this * prefetch is still correct and useful. */ kern_prefetch(ninp, &prefetch_tp); prefetch_tp = 1; } INP_WUNLOCK(inp); skip_pacing: CURVNET_RESTORE(); } if (seen_endpoint) { /* * We now have a accurate distance between * slot_pos_of_endpoint <-> orig_exit_slot * to tell us how late we were, orig_exit_slot * is where we calculated the end of our cycle to * be when we first entered. */ completed_measure = 1; } HPTS_LOCK(hpts); hpts->p_runningslot++; if (hpts->p_runningslot >= NUM_OF_HPTSI_SLOTS) { hpts->p_runningslot = 0; } } no_one: HPTS_MTX_ASSERT(hpts); hpts->p_delayed_by = 0; /* * Check to see if we took an excess amount of time and need to run * more ticks (if we did not hit eno-bufs). */ hpts->p_prev_slot = hpts->p_cur_slot; hpts->p_lasttick = hpts->p_curtick; if ((from_callout == 0) || (loop_cnt > max_pacer_loops)) { /* * Something is serious slow we have * looped through processing the wheel * and by the time we cleared the * needs to run max_pacer_loops time * we still needed to run. That means * the system is hopelessly behind and * can never catch up :( * * We will just lie to this thread * and let it thing p_curtick is * correct. When it next awakens * it will find itself further behind. */ if (from_callout) counter_u64_add(hpts_hopelessly_behind, 1); goto no_run; } hpts->p_curtick = tcp_gethptstick(&tv); hpts->p_cur_slot = tick_to_wheel(hpts->p_curtick); if (seen_endpoint == 0) { /* We saw no endpoint but we may be looping */ orig_exit_slot = hpts->p_cur_slot; } if ((wrap_loop_cnt < 2) && (hpts->p_lasttick != hpts->p_curtick)) { counter_u64_add(hpts_loops, 1); loop_cnt++; goto again; } no_run: cts_last_ran[hpts->p_num] = tcp_tv_to_usectick(&tv); /* * Set flag to tell that we are done for * any slot input that happens during * input. */ hpts->p_wheel_complete = 1; /* * Now did we spend too long running input and need to run more ticks? * Note that if wrap_loop_cnt < 2 then we should have the conditions * in the KASSERT's true. But if the wheel is behind i.e. wrap_loop_cnt * is greater than 2, then the condtion most likely are *not* true. * Also if we are called not from the callout, we don't run the wheel * multiple times so the slots may not align either. */ KASSERT(((hpts->p_prev_slot == hpts->p_cur_slot) || (wrap_loop_cnt >= 2) || (from_callout == 0)), ("H:%p p_prev_slot:%u not equal to p_cur_slot:%u", hpts, hpts->p_prev_slot, hpts->p_cur_slot)); KASSERT(((hpts->p_lasttick == hpts->p_curtick) || (wrap_loop_cnt >= 2) || (from_callout == 0)), ("H:%p p_lasttick:%u not equal to p_curtick:%u", hpts, hpts->p_lasttick, hpts->p_curtick)); if (from_callout && (hpts->p_lasttick != hpts->p_curtick)) { hpts->p_curtick = tcp_gethptstick(&tv); counter_u64_add(hpts_loops, 1); hpts->p_cur_slot = tick_to_wheel(hpts->p_curtick); goto again; } if (from_callout){ tcp_hpts_set_max_sleep(hpts, wrap_loop_cnt); } if (seen_endpoint) return(hpts_slots_diff(slot_pos_of_endpoint, orig_exit_slot)); else return (0); } void __tcp_set_hpts(struct inpcb *inp, int32_t line) { struct tcp_hpts_entry *hpts; int failed; INP_WLOCK_ASSERT(inp); hpts = tcp_hpts_lock(inp); if ((inp->inp_in_hpts == 0) && (inp->inp_hpts_cpu_set == 0)) { inp->inp_hpts_cpu = hpts_cpuid(inp, &failed); if (failed == 0) inp->inp_hpts_cpu_set = 1; } mtx_unlock(&hpts->p_mtx); } static void __tcp_run_hpts(struct tcp_hpts_entry *hpts) { int ticks_ran; if (hpts->p_hpts_active) { /* Already active */ return; } if (mtx_trylock(&hpts->p_mtx) == 0) { /* Someone else got the lock */ return; } if (hpts->p_hpts_active) goto out_with_mtx; hpts->syscall_cnt++; counter_u64_add(hpts_direct_call, 1); hpts->p_hpts_active = 1; ticks_ran = tcp_hptsi(hpts, 0); /* We may want to adjust the sleep values here */ if (hpts->p_on_queue_cnt >= conn_cnt_thresh) { if (ticks_ran > ticks_indicate_less_sleep) { struct timeval tv; sbintime_t sb; hpts->p_mysleep.tv_usec /= 2; if (hpts->p_mysleep.tv_usec < dynamic_min_sleep) hpts->p_mysleep.tv_usec = dynamic_min_sleep; /* Reschedule with new to value */ tcp_hpts_set_max_sleep(hpts, 0); tv.tv_usec = hpts->p_hpts_sleep_time * HPTS_TICKS_PER_SLOT; /* Validate its in the right ranges */ if (tv.tv_usec < hpts->p_mysleep.tv_usec) { hpts->overidden_sleep = tv.tv_usec; tv.tv_usec = hpts->p_mysleep.tv_usec; } else if (tv.tv_usec > dynamic_max_sleep) { /* Lets not let sleep get above this value */ hpts->overidden_sleep = tv.tv_usec; tv.tv_usec = dynamic_max_sleep; } /* * In this mode the timer is a backstop to * all the userret/lro_flushes so we use * the dynamic value and set the on_min_sleep * flag so we will not be awoken. */ sb = tvtosbt(tv); /* Store off to make visible the actual sleep time */ hpts->sleeping = tv.tv_usec; callout_reset_sbt_on(&hpts->co, sb, 0, hpts_timeout_swi, hpts, hpts->p_cpu, (C_DIRECT_EXEC | C_PREL(tcp_hpts_precision))); } else if (ticks_ran < ticks_indicate_more_sleep) { /* For the further sleep, don't reschedule hpts */ hpts->p_mysleep.tv_usec *= 2; if (hpts->p_mysleep.tv_usec > dynamic_max_sleep) hpts->p_mysleep.tv_usec = dynamic_max_sleep; } hpts->p_on_min_sleep = 1; } hpts->p_hpts_active = 0; out_with_mtx: HPTS_MTX_ASSERT(hpts); mtx_unlock(&hpts->p_mtx); } static struct tcp_hpts_entry * tcp_choose_hpts_to_run(void) { int i, oldest_idx, start, end; uint32_t cts, time_since_ran, calc; cts = tcp_get_usecs(NULL); time_since_ran = 0; /* Default is all one group */ start = 0; end = tcp_pace.rp_num_hptss; /* * If we have more than one L3 group figure out which one * this CPU is in. */ if (tcp_pace.grp_cnt > 1) { for (i = 0; i < tcp_pace.grp_cnt; i++) { if (CPU_ISSET(curcpu, &tcp_pace.grps[i]->cg_mask)) { start = tcp_pace.grps[i]->cg_first; end = (tcp_pace.grps[i]->cg_last + 1); break; } } } oldest_idx = -1; for (i = start; i < end; i++) { if (TSTMP_GT(cts, cts_last_ran[i])) calc = cts - cts_last_ran[i]; else calc = 0; if (calc > time_since_ran) { oldest_idx = i; time_since_ran = calc; } } if (oldest_idx >= 0) return(tcp_pace.rp_ent[oldest_idx]); else return(tcp_pace.rp_ent[(curcpu % tcp_pace.rp_num_hptss)]); } void tcp_run_hpts(void) { static struct tcp_hpts_entry *hpts; struct epoch_tracker et; NET_EPOCH_ENTER(et); hpts = tcp_choose_hpts_to_run(); __tcp_run_hpts(hpts); NET_EPOCH_EXIT(et); } static void tcp_hpts_thread(void *ctx) { struct tcp_hpts_entry *hpts; struct epoch_tracker et; struct timeval tv; sbintime_t sb; int ticks_ran; hpts = (struct tcp_hpts_entry *)ctx; mtx_lock(&hpts->p_mtx); if (hpts->p_direct_wake) { /* Signaled by input or output with low occupancy count. */ callout_stop(&hpts->co); counter_u64_add(hpts_direct_awakening, 1); } else { /* Timed out, the normal case. */ counter_u64_add(hpts_wake_timeout, 1); if (callout_pending(&hpts->co) || !callout_active(&hpts->co)) { mtx_unlock(&hpts->p_mtx); return; } } callout_deactivate(&hpts->co); hpts->p_hpts_wake_scheduled = 0; NET_EPOCH_ENTER(et); if (hpts->p_hpts_active) { /* * We are active already. This means that a syscall * trap or LRO is running in behalf of hpts. In that case * we need to double our timeout since there seems to be * enough activity in the system that we don't need to * run as often (if we were not directly woken). */ if (hpts->p_direct_wake == 0) { counter_u64_add(hpts_back_tosleep, 1); if (hpts->p_on_queue_cnt >= conn_cnt_thresh) { hpts->p_mysleep.tv_usec *= 2; if (hpts->p_mysleep.tv_usec > dynamic_max_sleep) hpts->p_mysleep.tv_usec = dynamic_max_sleep; tv.tv_usec = hpts->p_mysleep.tv_usec; hpts->p_on_min_sleep = 1; } else { /* * Here we have low count on the wheel, but * somehow we still collided with one of the * connections. Lets go back to sleep for a * min sleep time, but clear the flag so we * can be awoken by insert. */ hpts->p_on_min_sleep = 0; tv.tv_usec = tcp_min_hptsi_time; } } else { /* * Directly woken most likely to reset the * callout time. */ tv.tv_sec = 0; tv.tv_usec = hpts->p_mysleep.tv_usec; } goto back_to_sleep; } hpts->sleeping = 0; hpts->p_hpts_active = 1; ticks_ran = tcp_hptsi(hpts, 1); tv.tv_sec = 0; tv.tv_usec = hpts->p_hpts_sleep_time * HPTS_TICKS_PER_SLOT; if (hpts->p_on_queue_cnt >= conn_cnt_thresh) { if(hpts->p_direct_wake == 0) { /* * Only adjust sleep time if we were * called from the callout i.e. direct_wake == 0. */ if (ticks_ran < ticks_indicate_more_sleep) { hpts->p_mysleep.tv_usec *= 2; if (hpts->p_mysleep.tv_usec > dynamic_max_sleep) hpts->p_mysleep.tv_usec = dynamic_max_sleep; } else if (ticks_ran > ticks_indicate_less_sleep) { hpts->p_mysleep.tv_usec /= 2; if (hpts->p_mysleep.tv_usec < dynamic_min_sleep) hpts->p_mysleep.tv_usec = dynamic_min_sleep; } } if (tv.tv_usec < hpts->p_mysleep.tv_usec) { hpts->overidden_sleep = tv.tv_usec; tv.tv_usec = hpts->p_mysleep.tv_usec; } else if (tv.tv_usec > dynamic_max_sleep) { /* Lets not let sleep get above this value */ hpts->overidden_sleep = tv.tv_usec; tv.tv_usec = dynamic_max_sleep; } /* * In this mode the timer is a backstop to * all the userret/lro_flushes so we use * the dynamic value and set the on_min_sleep * flag so we will not be awoken. */ hpts->p_on_min_sleep = 1; } else if (hpts->p_on_queue_cnt == 0) { /* * No one on the wheel, please wake us up * if you insert on the wheel. */ hpts->p_on_min_sleep = 0; hpts->overidden_sleep = 0; } else { /* * We hit here when we have a low number of * clients on the wheel (our else clause). * We may need to go on min sleep, if we set * the flag we will not be awoken if someone * is inserted ahead of us. Clearing the flag * means we can be awoken. This is "old mode" * where the timer is what runs hpts mainly. */ if (tv.tv_usec < tcp_min_hptsi_time) { /* * Yes on min sleep, which means * we cannot be awoken. */ hpts->overidden_sleep = tv.tv_usec; tv.tv_usec = tcp_min_hptsi_time; hpts->p_on_min_sleep = 1; } else { /* Clear the min sleep flag */ hpts->overidden_sleep = 0; hpts->p_on_min_sleep = 0; } } HPTS_MTX_ASSERT(hpts); hpts->p_hpts_active = 0; back_to_sleep: hpts->p_direct_wake = 0; sb = tvtosbt(tv); /* Store off to make visible the actual sleep time */ hpts->sleeping = tv.tv_usec; callout_reset_sbt_on(&hpts->co, sb, 0, hpts_timeout_swi, hpts, hpts->p_cpu, (C_DIRECT_EXEC | C_PREL(tcp_hpts_precision))); NET_EPOCH_EXIT(et); mtx_unlock(&hpts->p_mtx); } #undef timersub static int32_t hpts_count_level(struct cpu_group *cg) { int32_t count_l3, i; count_l3 = 0; if (cg->cg_level == CG_SHARE_L3) count_l3++; /* Walk all the children looking for L3 */ for (i = 0; i < cg->cg_children; i++) { count_l3 += hpts_count_level(&cg->cg_child[i]); } return (count_l3); } static void hpts_gather_grps(struct cpu_group **grps, int32_t *at, int32_t max, struct cpu_group *cg) { int32_t idx, i; idx = *at; if (cg->cg_level == CG_SHARE_L3) { grps[idx] = cg; idx++; if (idx == max) { *at = idx; return; } } *at = idx; /* Walk all the children looking for L3 */ for (i = 0; i < cg->cg_children; i++) { hpts_gather_grps(grps, at, max, &cg->cg_child[i]); } } static void tcp_init_hptsi(void *st) { struct cpu_group *cpu_top; int32_t error __diagused; int32_t i, j, bound = 0, created = 0; size_t sz, asz; struct timeval tv; sbintime_t sb; struct tcp_hpts_entry *hpts; struct pcpu *pc; char unit[16]; uint32_t ncpus = mp_ncpus ? mp_ncpus : MAXCPU; int count, domain; #ifdef SMP cpu_top = smp_topo(); #else cpu_top = NULL; #endif tcp_pace.rp_num_hptss = ncpus; hpts_hopelessly_behind = counter_u64_alloc(M_WAITOK); hpts_loops = counter_u64_alloc(M_WAITOK); back_tosleep = counter_u64_alloc(M_WAITOK); combined_wheel_wrap = counter_u64_alloc(M_WAITOK); wheel_wrap = counter_u64_alloc(M_WAITOK); hpts_wake_timeout = counter_u64_alloc(M_WAITOK); hpts_direct_awakening = counter_u64_alloc(M_WAITOK); hpts_back_tosleep = counter_u64_alloc(M_WAITOK); hpts_direct_call = counter_u64_alloc(M_WAITOK); cpu_uses_flowid = counter_u64_alloc(M_WAITOK); cpu_uses_random = counter_u64_alloc(M_WAITOK); sz = (tcp_pace.rp_num_hptss * sizeof(struct tcp_hpts_entry *)); tcp_pace.rp_ent = malloc(sz, M_TCPHPTS, M_WAITOK | M_ZERO); sz = (sizeof(uint32_t) * tcp_pace.rp_num_hptss); cts_last_ran = malloc(sz, M_TCPHPTS, M_WAITOK); tcp_pace.grp_cnt = 0; if (cpu_top == NULL) { tcp_pace.grp_cnt = 1; } else { /* Find out how many cache level 3 domains we have */ count = 0; tcp_pace.grp_cnt = hpts_count_level(cpu_top); if (tcp_pace.grp_cnt == 0) { tcp_pace.grp_cnt = 1; } sz = (tcp_pace.grp_cnt * sizeof(struct cpu_group *)); tcp_pace.grps = malloc(sz, M_TCPHPTS, M_WAITOK); /* Now populate the groups */ if (tcp_pace.grp_cnt == 1) { /* * All we need is the top level all cpu's are in * the same cache so when we use grp[0]->cg_mask * with the cg_first <-> cg_last it will include * all cpu's in it. The level here is probably * zero which is ok. */ tcp_pace.grps[0] = cpu_top; } else { /* * Here we must find all the level three cache domains * and setup our pointers to them. */ count = 0; hpts_gather_grps(tcp_pace.grps, &count, tcp_pace.grp_cnt, cpu_top); } } asz = sizeof(struct hptsh) * NUM_OF_HPTSI_SLOTS; for (i = 0; i < tcp_pace.rp_num_hptss; i++) { tcp_pace.rp_ent[i] = malloc(sizeof(struct tcp_hpts_entry), M_TCPHPTS, M_WAITOK | M_ZERO); tcp_pace.rp_ent[i]->p_hptss = malloc(asz, M_TCPHPTS, M_WAITOK); hpts = tcp_pace.rp_ent[i]; /* * Init all the hpts structures that are not specifically * zero'd by the allocations. Also lets attach them to the * appropriate sysctl block as well. */ mtx_init(&hpts->p_mtx, "tcp_hpts_lck", "hpts", MTX_DEF | MTX_DUPOK); for (j = 0; j < NUM_OF_HPTSI_SLOTS; j++) { TAILQ_INIT(&hpts->p_hptss[j].head); hpts->p_hptss[j].count = 0; hpts->p_hptss[j].gencnt = 0; } sysctl_ctx_init(&hpts->hpts_ctx); sprintf(unit, "%d", i); hpts->hpts_root = SYSCTL_ADD_NODE(&hpts->hpts_ctx, SYSCTL_STATIC_CHILDREN(_net_inet_tcp_hpts), OID_AUTO, unit, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, ""); SYSCTL_ADD_INT(&hpts->hpts_ctx, SYSCTL_CHILDREN(hpts->hpts_root), OID_AUTO, "out_qcnt", CTLFLAG_RD, &hpts->p_on_queue_cnt, 0, "Count TCB's awaiting output processing"); SYSCTL_ADD_U16(&hpts->hpts_ctx, SYSCTL_CHILDREN(hpts->hpts_root), OID_AUTO, "active", CTLFLAG_RD, &hpts->p_hpts_active, 0, "Is the hpts active"); SYSCTL_ADD_UINT(&hpts->hpts_ctx, SYSCTL_CHILDREN(hpts->hpts_root), OID_AUTO, "curslot", CTLFLAG_RD, &hpts->p_cur_slot, 0, "What the current running pacers goal"); SYSCTL_ADD_UINT(&hpts->hpts_ctx, SYSCTL_CHILDREN(hpts->hpts_root), OID_AUTO, "runtick", CTLFLAG_RD, &hpts->p_runningslot, 0, "What the running pacers current slot is"); SYSCTL_ADD_UINT(&hpts->hpts_ctx, SYSCTL_CHILDREN(hpts->hpts_root), OID_AUTO, "curtick", CTLFLAG_RD, &hpts->p_curtick, 0, "What the running pacers last tick mapped to the wheel was"); SYSCTL_ADD_UINT(&hpts->hpts_ctx, SYSCTL_CHILDREN(hpts->hpts_root), OID_AUTO, "lastran", CTLFLAG_RD, &cts_last_ran[i], 0, "The last usec tick that this hpts ran"); SYSCTL_ADD_LONG(&hpts->hpts_ctx, SYSCTL_CHILDREN(hpts->hpts_root), OID_AUTO, "cur_min_sleep", CTLFLAG_RD, &hpts->p_mysleep.tv_usec, "What the running pacers is using for p_mysleep.tv_usec"); SYSCTL_ADD_U64(&hpts->hpts_ctx, SYSCTL_CHILDREN(hpts->hpts_root), OID_AUTO, "now_sleeping", CTLFLAG_RD, &hpts->sleeping, 0, "What the running pacers is actually sleeping for"); SYSCTL_ADD_U64(&hpts->hpts_ctx, SYSCTL_CHILDREN(hpts->hpts_root), OID_AUTO, "syscall_cnt", CTLFLAG_RD, &hpts->syscall_cnt, 0, "How many times we had syscalls on this hpts"); hpts->p_hpts_sleep_time = hpts_sleep_max; hpts->p_num = i; hpts->p_curtick = tcp_gethptstick(&tv); cts_last_ran[i] = tcp_tv_to_usectick(&tv); hpts->p_prev_slot = hpts->p_cur_slot = tick_to_wheel(hpts->p_curtick); hpts->p_cpu = 0xffff; hpts->p_nxt_slot = hpts_slot(hpts->p_cur_slot, 1); callout_init(&hpts->co, 1); } /* Don't try to bind to NUMA domains if we don't have any */ if (vm_ndomains == 1 && tcp_bind_threads == 2) tcp_bind_threads = 0; /* * Now lets start ithreads to handle the hptss. */ for (i = 0; i < tcp_pace.rp_num_hptss; i++) { hpts = tcp_pace.rp_ent[i]; hpts->p_cpu = i; error = swi_add(&hpts->ie, "hpts", tcp_hpts_thread, (void *)hpts, SWI_NET, INTR_MPSAFE, &hpts->ie_cookie); KASSERT(error == 0, ("Can't add hpts:%p i:%d err:%d", hpts, i, error)); created++; hpts->p_mysleep.tv_sec = 0; hpts->p_mysleep.tv_usec = tcp_min_hptsi_time; if (tcp_bind_threads == 1) { if (intr_event_bind(hpts->ie, i) == 0) bound++; } else if (tcp_bind_threads == 2) { /* Find the group for this CPU (i) and bind into it */ for (j = 0; j < tcp_pace.grp_cnt; j++) { if (CPU_ISSET(i, &tcp_pace.grps[j]->cg_mask)) { if (intr_event_bind_ithread_cpuset(hpts->ie, &tcp_pace.grps[j]->cg_mask) == 0) { bound++; pc = pcpu_find(i); domain = pc->pc_domain; count = hpts_domains[domain].count; hpts_domains[domain].cpu[count] = i; hpts_domains[domain].count++; break; } } } } tv.tv_sec = 0; tv.tv_usec = hpts->p_hpts_sleep_time * HPTS_TICKS_PER_SLOT; hpts->sleeping = tv.tv_usec; sb = tvtosbt(tv); callout_reset_sbt_on(&hpts->co, sb, 0, hpts_timeout_swi, hpts, hpts->p_cpu, (C_DIRECT_EXEC | C_PREL(tcp_hpts_precision))); } /* * If we somehow have an empty domain, fall back to choosing * among all htps threads. */ for (i = 0; i < vm_ndomains; i++) { if (hpts_domains[i].count == 0) { tcp_bind_threads = 0; break; } } printf("TCP Hpts created %d swi interrupt threads and bound %d to %s\n", created, bound, tcp_bind_threads == 2 ? "NUMA domains" : "cpus"); #ifdef INVARIANTS printf("HPTS is in INVARIANT mode!!\n"); #endif } SYSINIT(tcphptsi, SI_SUB_SOFTINTR, SI_ORDER_ANY, tcp_init_hptsi, NULL); MODULE_VERSION(tcphpts, 1); diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 96812afd3b37..5141903522bf 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4103 +1,4040 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995 * The Regents of the University of California. All rights reserved. * Copyright (c) 2007-2008,2010 * Swinburne University of Technology, Melbourne, Australia. * Copyright (c) 2009-2010 Lawrence Stewart * Copyright (c) 2010 The FreeBSD Foundation * Copyright (c) 2010-2011 Juniper Networks, Inc. * All rights reserved. * * Portions of this software were developed at the Centre for Advanced Internet * Architectures, Swinburne University of Technology, by Lawrence Stewart, * James Healy and David Hayes, made possible in part by a grant from the Cisco * University Research Program Fund at Community Foundation Silicon Valley. * * Portions of this software were developed at the Centre for Advanced * Internet Architectures, Swinburne University of Technology, Melbourne, * Australia by David Hayes under sponsorship from the FreeBSD Foundation. * * Portions of this software were developed by Robert N. M. Watson under * contract to Juniper Networks, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * @(#)tcp_input.c 8.12 (Berkeley) 5/24/95 */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" -#include "opt_tcpdebug.h" #include #include #include #ifdef TCP_HHOOK #include #endif #include #include #include /* for proc0 declaration */ #include #include #include #include #include #include #include #include #include #include #include /* before tcp_seq.h, for tcp_random18() */ #include #include #include #include #include #define TCPSTATES /* for logging */ #include #include #include #include #include #include /* required for icmp_var.h */ #include /* for ICMP_BANDLIM */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef TCPPCAP #include #endif #include -#include #ifdef TCP_OFFLOAD #include #endif #include #include #include #include #include const int tcprexmtthresh = 3; VNET_DEFINE(int, tcp_log_in_vain) = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_log_in_vain), 0, "Log all incoming TCP segments to closed ports"); VNET_DEFINE(int, blackhole) = 0; #define V_blackhole VNET(blackhole) SYSCTL_INT(_net_inet_tcp, OID_AUTO, blackhole, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(blackhole), 0, "Do not send RST on segments to closed ports"); VNET_DEFINE(bool, blackhole_local) = false; #define V_blackhole_local VNET(blackhole_local) SYSCTL_BOOL(_net_inet_tcp, OID_AUTO, blackhole_local, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(blackhole_local), false, "Enforce net.inet.tcp.blackhole for locally originated packets"); VNET_DEFINE(int, tcp_delack_enabled) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, delayed_ack, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_delack_enabled), 0, "Delay ACK to try and piggyback it onto a data packet"); VNET_DEFINE(int, drop_synfin) = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(drop_synfin), 0, "Drop TCP packets with SYN+FIN set"); VNET_DEFINE(int, tcp_do_prr_conservative) = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_prr_conservative, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_prr_conservative), 0, "Do conservative Proportional Rate Reduction"); VNET_DEFINE(int, tcp_do_prr) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_prr, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_prr), 1, "Enable Proportional Rate Reduction per RFC 6937"); VNET_DEFINE(int, tcp_do_lrd) = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_lrd, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_lrd), 1, "Perform Lost Retransmission Detection"); VNET_DEFINE(int, tcp_do_newcwv) = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, newcwv, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_newcwv), 0, "Enable New Congestion Window Validation per RFC7661"); VNET_DEFINE(int, tcp_do_rfc3042) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3042, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_rfc3042), 0, "Enable RFC 3042 (Limited Transmit)"); VNET_DEFINE(int, tcp_do_rfc3390) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3390, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_rfc3390), 0, "Enable RFC 3390 (Increasing TCP's Initial Congestion Window)"); VNET_DEFINE(int, tcp_initcwnd_segments) = 10; SYSCTL_INT(_net_inet_tcp, OID_AUTO, initcwnd_segments, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_initcwnd_segments), 0, "Slow-start flight size (initial congestion window) in number of segments"); VNET_DEFINE(int, tcp_do_rfc3465) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3465, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_rfc3465), 0, "Enable RFC 3465 (Appropriate Byte Counting)"); VNET_DEFINE(int, tcp_abc_l_var) = 2; SYSCTL_INT(_net_inet_tcp, OID_AUTO, abc_l_var, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_abc_l_var), 2, "Cap the max cwnd increment during slow-start to this number of segments"); VNET_DEFINE(int, tcp_insecure_syn) = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, insecure_syn, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_insecure_syn), 0, "Follow RFC793 instead of RFC5961 criteria for accepting SYN packets"); VNET_DEFINE(int, tcp_insecure_rst) = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, insecure_rst, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_insecure_rst), 0, "Follow RFC793 instead of RFC5961 criteria for accepting RST packets"); VNET_DEFINE(int, tcp_recvspace) = 1024*64; #define V_tcp_recvspace VNET(tcp_recvspace) SYSCTL_INT(_net_inet_tcp, TCPCTL_RECVSPACE, recvspace, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_recvspace), 0, "Initial receive socket buffer size"); VNET_DEFINE(int, tcp_do_autorcvbuf) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, recvbuf_auto, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_autorcvbuf), 0, "Enable automatic receive buffer sizing"); VNET_DEFINE(int, tcp_autorcvbuf_max) = 2*1024*1024; SYSCTL_INT(_net_inet_tcp, OID_AUTO, recvbuf_max, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_autorcvbuf_max), 0, "Max size of automatic receive buffer"); VNET_DEFINE(struct inpcbinfo, tcbinfo); /* * TCP statistics are stored in an array of counter(9)s, which size matches * size of struct tcpstat. TCP running connection count is a regular array. */ VNET_PCPUSTAT_DEFINE(struct tcpstat, tcpstat); SYSCTL_VNET_PCPUSTAT(_net_inet_tcp, TCPCTL_STATS, stats, struct tcpstat, tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)"); VNET_DEFINE(counter_u64_t, tcps_states[TCP_NSTATES]); SYSCTL_COUNTER_U64_ARRAY(_net_inet_tcp, TCPCTL_STATES, states, CTLFLAG_RD | CTLFLAG_VNET, &VNET_NAME(tcps_states)[0], TCP_NSTATES, "TCP connection counts by TCP state"); /* * Kernel module interface for updating tcpstat. The first argument is an index * into tcpstat treated as an array. */ void kmod_tcpstat_add(int statnum, int val) { counter_u64_add(VNET(tcpstat)[statnum], val); } /* * Make sure that we only start a SACK loss recovery when * receiving a duplicate ACK with a SACK block, and also * complete SACK loss recovery in case the other end * reneges. */ static bool inline tcp_is_sack_recovery(struct tcpcb *tp, struct tcpopt *to) { return ((tp->t_flags & TF_SACK_PERMIT) && ((to->to_flags & TOF_SACK) || (!TAILQ_EMPTY(&tp->snd_holes)))); } #ifdef TCP_HHOOK /* * Wrapper for the TCP established input helper hook. */ void hhook_run_tcp_est_in(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to) { struct tcp_hhook_data hhook_data; if (V_tcp_hhh[HHOOK_TCP_EST_IN]->hhh_nhooks > 0) { hhook_data.tp = tp; hhook_data.th = th; hhook_data.to = to; hhook_run_hooks(V_tcp_hhh[HHOOK_TCP_EST_IN], &hhook_data, &tp->t_osd); } } #endif /* * CC wrapper hook functions */ void cc_ack_received(struct tcpcb *tp, struct tcphdr *th, uint16_t nsegs, uint16_t type) { #ifdef STATS int32_t gput; #endif INP_WLOCK_ASSERT(tptoinpcb(tp)); tp->t_ccv.nsegs = nsegs; tp->t_ccv.bytes_this_ack = BYTES_THIS_ACK(tp, th); if ((!V_tcp_do_newcwv && (tp->snd_cwnd <= tp->snd_wnd)) || (V_tcp_do_newcwv && (tp->snd_cwnd <= tp->snd_wnd) && (tp->snd_cwnd < (tcp_compute_pipe(tp) * 2)))) tp->t_ccv.flags |= CCF_CWND_LIMITED; else tp->t_ccv.flags &= ~CCF_CWND_LIMITED; if (type == CC_ACK) { #ifdef STATS stats_voi_update_abs_s32(tp->t_stats, VOI_TCP_CALCFRWINDIFF, ((int32_t)tp->snd_cwnd) - tp->snd_wnd); if (!IN_RECOVERY(tp->t_flags)) stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_ACKLEN, tp->t_ccv.bytes_this_ack / (tcp_maxseg(tp) * nsegs)); if ((tp->t_flags & TF_GPUTINPROG) && SEQ_GEQ(th->th_ack, tp->gput_ack)) { /* * Compute goodput in bits per millisecond. */ gput = (((int64_t)SEQ_SUB(th->th_ack, tp->gput_seq)) << 3) / max(1, tcp_ts_getticks() - tp->gput_ts); stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_GPUT, gput); /* * XXXLAS: This is a temporary hack, and should be * chained off VOI_TCP_GPUT when stats(9) grows an API * to deal with chained VOIs. */ if (tp->t_stats_gput_prev > 0) stats_voi_update_abs_s32(tp->t_stats, VOI_TCP_GPUT_ND, ((gput - tp->t_stats_gput_prev) * 100) / tp->t_stats_gput_prev); tp->t_flags &= ~TF_GPUTINPROG; tp->t_stats_gput_prev = gput; } #endif /* STATS */ if (tp->snd_cwnd > tp->snd_ssthresh) { tp->t_bytes_acked += tp->t_ccv.bytes_this_ack; if (tp->t_bytes_acked >= tp->snd_cwnd) { tp->t_bytes_acked -= tp->snd_cwnd; tp->t_ccv.flags |= CCF_ABC_SENTAWND; } } else { tp->t_ccv.flags &= ~CCF_ABC_SENTAWND; tp->t_bytes_acked = 0; } } if (CC_ALGO(tp)->ack_received != NULL) { /* XXXLAS: Find a way to live without this */ tp->t_ccv.curack = th->th_ack; CC_ALGO(tp)->ack_received(&tp->t_ccv, type); } #ifdef STATS stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_LCWIN, tp->snd_cwnd); #endif } void cc_conn_init(struct tcpcb *tp) { struct hc_metrics_lite metrics; struct inpcb *inp = tptoinpcb(tp); u_int maxseg; int rtt; INP_WLOCK_ASSERT(inp); tcp_hc_get(&inp->inp_inc, &metrics); maxseg = tcp_maxseg(tp); if (tp->t_srtt == 0 && (rtt = metrics.rmx_rtt)) { tp->t_srtt = rtt; TCPSTAT_INC(tcps_usedrtt); if (metrics.rmx_rttvar) { tp->t_rttvar = metrics.rmx_rttvar; TCPSTAT_INC(tcps_usedrttvar); } else { /* default variation is +- 1 rtt */ tp->t_rttvar = tp->t_srtt * TCP_RTTVAR_SCALE / TCP_RTT_SCALE; } TCPT_RANGESET(tp->t_rxtcur, ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1, tp->t_rttmin, TCPTV_REXMTMAX); } if (metrics.rmx_ssthresh) { /* * There's some sort of gateway or interface * buffer limit on the path. Use this to set * the slow start threshold, but set the * threshold to no less than 2*mss. */ tp->snd_ssthresh = max(2 * maxseg, metrics.rmx_ssthresh); TCPSTAT_INC(tcps_usedssthresh); } /* * Set the initial slow-start flight size. * * If a SYN or SYN/ACK was lost and retransmitted, we have to * reduce the initial CWND to one segment as congestion is likely * requiring us to be cautious. */ if (tp->snd_cwnd == 1) tp->snd_cwnd = maxseg; /* SYN(-ACK) lost */ else tp->snd_cwnd = tcp_compute_initwnd(maxseg); if (CC_ALGO(tp)->conn_init != NULL) CC_ALGO(tp)->conn_init(&tp->t_ccv); } void inline cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type) { INP_WLOCK_ASSERT(tptoinpcb(tp)); #ifdef STATS stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_CSIG, type); #endif switch(type) { case CC_NDUPACK: if (!IN_FASTRECOVERY(tp->t_flags)) { tp->snd_recover = tp->snd_max; if (tp->t_flags2 & TF2_ECN_PERMIT) tp->t_flags2 |= TF2_ECN_SND_CWR; } break; case CC_ECN: if (!IN_CONGRECOVERY(tp->t_flags) || /* * Allow ECN reaction on ACK to CWR, if * that data segment was also CE marked. */ SEQ_GEQ(th->th_ack, tp->snd_recover)) { EXIT_CONGRECOVERY(tp->t_flags); TCPSTAT_INC(tcps_ecn_rcwnd); tp->snd_recover = tp->snd_max + 1; if (tp->t_flags2 & TF2_ECN_PERMIT) tp->t_flags2 |= TF2_ECN_SND_CWR; } break; case CC_RTO: tp->t_dupacks = 0; tp->t_bytes_acked = 0; EXIT_RECOVERY(tp->t_flags); if (tp->t_flags2 & TF2_ECN_PERMIT) tp->t_flags2 |= TF2_ECN_SND_CWR; break; case CC_RTO_ERR: TCPSTAT_INC(tcps_sndrexmitbad); /* RTO was unnecessary, so reset everything. */ tp->snd_cwnd = tp->snd_cwnd_prev; tp->snd_ssthresh = tp->snd_ssthresh_prev; tp->snd_recover = tp->snd_recover_prev; if (tp->t_flags & TF_WASFRECOVERY) ENTER_FASTRECOVERY(tp->t_flags); if (tp->t_flags & TF_WASCRECOVERY) ENTER_CONGRECOVERY(tp->t_flags); tp->snd_nxt = tp->snd_max; tp->t_flags &= ~TF_PREVVALID; tp->t_badrxtwin = 0; break; } if (CC_ALGO(tp)->cong_signal != NULL) { if (th != NULL) tp->t_ccv.curack = th->th_ack; CC_ALGO(tp)->cong_signal(&tp->t_ccv, type); } } void inline cc_post_recovery(struct tcpcb *tp, struct tcphdr *th) { INP_WLOCK_ASSERT(tptoinpcb(tp)); /* XXXLAS: KASSERT that we're in recovery? */ if (CC_ALGO(tp)->post_recovery != NULL) { tp->t_ccv.curack = th->th_ack; CC_ALGO(tp)->post_recovery(&tp->t_ccv); } /* XXXLAS: EXIT_RECOVERY ? */ tp->t_bytes_acked = 0; tp->sackhint.delivered_data = 0; tp->sackhint.prr_out = 0; } /* * Indicate whether this ack should be delayed. We can delay the ack if * following conditions are met: * - There is no delayed ack timer in progress. * - Our last ack wasn't a 0-sized window. We never want to delay * the ack that opens up a 0-sized window. * - LRO wasn't used for this segment. We make sure by checking that the * segment size is not larger than the MSS. */ #define DELAY_ACK(tp, tlen) \ ((!tcp_timer_active(tp, TT_DELACK) && \ (tp->t_flags & TF_RXWIN0SENT) == 0) && \ (tlen <= tp->t_maxseg) && \ (V_tcp_delack_enabled || (tp->t_flags & TF_NEEDSYN))) void inline cc_ecnpkt_handler_flags(struct tcpcb *tp, uint16_t flags, uint8_t iptos) { INP_WLOCK_ASSERT(tptoinpcb(tp)); if (CC_ALGO(tp)->ecnpkt_handler != NULL) { switch (iptos & IPTOS_ECN_MASK) { case IPTOS_ECN_CE: tp->t_ccv.flags |= CCF_IPHDR_CE; break; case IPTOS_ECN_ECT0: /* FALLTHROUGH */ case IPTOS_ECN_ECT1: /* FALLTHROUGH */ case IPTOS_ECN_NOTECT: tp->t_ccv.flags &= ~CCF_IPHDR_CE; break; } if (flags & TH_CWR) tp->t_ccv.flags |= CCF_TCPHDR_CWR; else tp->t_ccv.flags &= ~CCF_TCPHDR_CWR; CC_ALGO(tp)->ecnpkt_handler(&tp->t_ccv); if (tp->t_ccv.flags & CCF_ACKNOW) { tcp_timer_activate(tp, TT_DELACK, tcp_delacktime); tp->t_flags |= TF_ACKNOW; } } } void inline cc_ecnpkt_handler(struct tcpcb *tp, struct tcphdr *th, uint8_t iptos) { cc_ecnpkt_handler_flags(tp, tcp_get_flags(th), iptos); } /* * TCP input handling is split into multiple parts: * tcp6_input is a thin wrapper around tcp_input for the extended * ip6_protox[] call format in ip6_input * tcp_input handles primary segment validation, inpcb lookup and * SYN processing on listen sockets * tcp_do_segment processes the ACK and text of the segment for * establishing, established and closing connections */ #ifdef INET6 int tcp6_input_with_port(struct mbuf **mp, int *offp, int proto, uint16_t port) { struct mbuf *m; struct in6_ifaddr *ia6; struct ip6_hdr *ip6; m = *mp; if (m->m_len < *offp + sizeof(struct tcphdr)) { m = m_pullup(m, *offp + sizeof(struct tcphdr)); if (m == NULL) { *mp = m; TCPSTAT_INC(tcps_rcvshort); return (IPPROTO_DONE); } } /* * draft-itojun-ipv6-tcp-to-anycast * better place to put this in? */ ip6 = mtod(m, struct ip6_hdr *); ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */, false); if (ia6 && (ia6->ia6_flags & IN6_IFF_ANYCAST)) { icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR, (caddr_t)&ip6->ip6_dst - (caddr_t)ip6); *mp = NULL; return (IPPROTO_DONE); } *mp = m; return (tcp_input_with_port(mp, offp, proto, port)); } int tcp6_input(struct mbuf **mp, int *offp, int proto) { return(tcp6_input_with_port(mp, offp, proto, 0)); } #endif /* INET6 */ int tcp_input_with_port(struct mbuf **mp, int *offp, int proto, uint16_t port) { struct mbuf *m = *mp; struct tcphdr *th = NULL; struct ip *ip = NULL; struct inpcb *inp = NULL; struct tcpcb *tp = NULL; struct socket *so = NULL; u_char *optp = NULL; int off0; int optlen = 0; #ifdef INET int len; uint8_t ipttl; #endif int tlen = 0, off; int drop_hdrlen; int thflags; int rstreason = 0; /* For badport_bandlim accounting purposes */ int lookupflag; uint8_t iptos; struct m_tag *fwd_tag = NULL; #ifdef INET6 struct ip6_hdr *ip6 = NULL; int isipv6; #else const void *ip6 = NULL; #endif /* INET6 */ struct tcpopt to; /* options in this segment */ char *s = NULL; /* address and port logging */ -#ifdef TCPDEBUG - /* - * The size of tcp_saveipgen must be the size of the max ip header, - * now IPv6. - */ - u_char tcp_saveipgen[IP6_HDR_LEN]; - struct tcphdr tcp_savetcp; - short ostate = 0; -#endif NET_EPOCH_ASSERT(); #ifdef INET6 isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; #endif off0 = *offp; m = *mp; *mp = NULL; to.to_flags = 0; TCPSTAT_INC(tcps_rcvtotal); #ifdef INET6 if (isipv6) { ip6 = mtod(m, struct ip6_hdr *); th = (struct tcphdr *)((caddr_t)ip6 + off0); tlen = sizeof(*ip6) + ntohs(ip6->ip6_plen) - off0; if (port) goto skip6_csum; if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) { if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) th->th_sum = m->m_pkthdr.csum_data; else th->th_sum = in6_cksum_pseudo(ip6, tlen, IPPROTO_TCP, m->m_pkthdr.csum_data); th->th_sum ^= 0xffff; } else th->th_sum = in6_cksum(m, IPPROTO_TCP, off0, tlen); if (th->th_sum) { TCPSTAT_INC(tcps_rcvbadsum); goto drop; } skip6_csum: /* * Be proactive about unspecified IPv6 address in source. * As we use all-zero to indicate unbounded/unconnected pcb, * unspecified IPv6 address can be used to confuse us. * * Note that packets with unspecified IPv6 destination is * already dropped in ip6_input. */ if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) { /* XXX stat */ goto drop; } iptos = IPV6_TRAFFIC_CLASS(ip6); } #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET { /* * Get IP and TCP header together in first mbuf. * Note: IP leaves IP header in first mbuf. */ if (off0 > sizeof (struct ip)) { ip_stripoptions(m); off0 = sizeof(struct ip); } if (m->m_len < sizeof (struct tcpiphdr)) { if ((m = m_pullup(m, sizeof (struct tcpiphdr))) == NULL) { TCPSTAT_INC(tcps_rcvshort); return (IPPROTO_DONE); } } ip = mtod(m, struct ip *); th = (struct tcphdr *)((caddr_t)ip + off0); tlen = ntohs(ip->ip_len) - off0; iptos = ip->ip_tos; if (port) goto skip_csum; if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) th->th_sum = m->m_pkthdr.csum_data; else th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htonl(m->m_pkthdr.csum_data + tlen + IPPROTO_TCP)); th->th_sum ^= 0xffff; } else { struct ipovly *ipov = (struct ipovly *)ip; /* * Checksum extended TCP header and data. */ len = off0 + tlen; ipttl = ip->ip_ttl; bzero(ipov->ih_x1, sizeof(ipov->ih_x1)); ipov->ih_len = htons(tlen); th->th_sum = in_cksum(m, len); /* Reset length for SDT probes. */ ip->ip_len = htons(len); /* Reset TOS bits */ ip->ip_tos = iptos; /* Re-initialization for later version check */ ip->ip_ttl = ipttl; ip->ip_v = IPVERSION; ip->ip_hl = off0 >> 2; } skip_csum: if (th->th_sum && (port == 0)) { TCPSTAT_INC(tcps_rcvbadsum); goto drop; } } #endif /* INET */ /* * Check that TCP offset makes sense, * pull out TCP options and adjust length. XXX */ off = th->th_off << 2; if (off < sizeof (struct tcphdr) || off > tlen) { TCPSTAT_INC(tcps_rcvbadoff); goto drop; } tlen -= off; /* tlen is used instead of ti->ti_len */ if (off > sizeof (struct tcphdr)) { #ifdef INET6 if (isipv6) { if (m->m_len < off0 + off) { m = m_pullup(m, off0 + off); if (m == NULL) { TCPSTAT_INC(tcps_rcvshort); return (IPPROTO_DONE); } } ip6 = mtod(m, struct ip6_hdr *); th = (struct tcphdr *)((caddr_t)ip6 + off0); } #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET { if (m->m_len < sizeof(struct ip) + off) { if ((m = m_pullup(m, sizeof (struct ip) + off)) == NULL) { TCPSTAT_INC(tcps_rcvshort); return (IPPROTO_DONE); } ip = mtod(m, struct ip *); th = (struct tcphdr *)((caddr_t)ip + off0); } } #endif optlen = off - sizeof (struct tcphdr); optp = (u_char *)(th + 1); } thflags = tcp_get_flags(th); /* * Convert TCP protocol specific fields to host format. */ tcp_fields_to_host(th); /* * Delay dropping TCP, IP headers, IPv6 ext headers, and TCP options. */ drop_hdrlen = off0 + off; /* * Grab info from PACKET_TAG_IPFORWARD tag prepended to the chain. */ if ( #ifdef INET6 (isipv6 && (m->m_flags & M_IP6_NEXTHOP)) #ifdef INET || (!isipv6 && (m->m_flags & M_IP_NEXTHOP)) #endif #endif #if defined(INET) && !defined(INET6) (m->m_flags & M_IP_NEXTHOP) #endif ) fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL); /* * For initial SYN packets we don't need write lock on matching * PCB, be it a listening one or a synchronized one. The packet * shall not modify its state. */ lookupflag = INPLOOKUP_WILDCARD | ((thflags & (TH_ACK|TH_SYN)) == TH_SYN ? INPLOOKUP_RLOCKPCB : INPLOOKUP_WLOCKPCB); findpcb: #ifdef INET6 if (isipv6 && fwd_tag != NULL) { struct sockaddr_in6 *next_hop6; next_hop6 = (struct sockaddr_in6 *)(fwd_tag + 1); /* * Transparently forwarded. Pretend to be the destination. * Already got one like this? */ inp = in6_pcblookup_mbuf(&V_tcbinfo, &ip6->ip6_src, th->th_sport, &ip6->ip6_dst, th->th_dport, lookupflag, m->m_pkthdr.rcvif, m); if (!inp) { /* * It's new. Try to find the ambushing socket. * Because we've rewritten the destination address, * any hardware-generated hash is ignored. */ inp = in6_pcblookup(&V_tcbinfo, &ip6->ip6_src, th->th_sport, &next_hop6->sin6_addr, next_hop6->sin6_port ? ntohs(next_hop6->sin6_port) : th->th_dport, lookupflag, m->m_pkthdr.rcvif); } } else if (isipv6) { inp = in6_pcblookup_mbuf(&V_tcbinfo, &ip6->ip6_src, th->th_sport, &ip6->ip6_dst, th->th_dport, lookupflag, m->m_pkthdr.rcvif, m); } #endif /* INET6 */ #if defined(INET6) && defined(INET) else #endif #ifdef INET if (fwd_tag != NULL) { struct sockaddr_in *next_hop; next_hop = (struct sockaddr_in *)(fwd_tag+1); /* * Transparently forwarded. Pretend to be the destination. * already got one like this? */ inp = in_pcblookup_mbuf(&V_tcbinfo, ip->ip_src, th->th_sport, ip->ip_dst, th->th_dport, lookupflag, m->m_pkthdr.rcvif, m); if (!inp) { /* * It's new. Try to find the ambushing socket. * Because we've rewritten the destination address, * any hardware-generated hash is ignored. */ inp = in_pcblookup(&V_tcbinfo, ip->ip_src, th->th_sport, next_hop->sin_addr, next_hop->sin_port ? ntohs(next_hop->sin_port) : th->th_dport, lookupflag, m->m_pkthdr.rcvif); } } else inp = in_pcblookup_mbuf(&V_tcbinfo, ip->ip_src, th->th_sport, ip->ip_dst, th->th_dport, lookupflag, m->m_pkthdr.rcvif, m); #endif /* INET */ /* * If the INPCB does not exist then all data in the incoming * segment is discarded and an appropriate RST is sent back. * XXX MRT Send RST using which routing table? */ if (inp == NULL) { if (rstreason != 0) { /* We came here after second (safety) lookup. */ MPASS((lookupflag & INPLOOKUP_WILDCARD) == 0); goto dropwithreset; } /* * Log communication attempts to ports that are not * in use. */ if ((V_tcp_log_in_vain == 1 && (thflags & TH_SYN)) || V_tcp_log_in_vain == 2) { if ((s = tcp_log_vain(NULL, th, (void *)ip, ip6))) log(LOG_INFO, "%s; %s: Connection attempt " "to closed port\n", s, __func__); } /* * When blackholing do not respond with a RST but * completely ignore the segment and drop it. */ if (((V_blackhole == 1 && (thflags & TH_SYN)) || V_blackhole == 2) && (V_blackhole_local || ( #ifdef INET6 isipv6 ? !in6_localaddr(&ip6->ip6_src) : #endif #ifdef INET !in_localip(ip->ip_src) #else true #endif ))) goto dropunlock; rstreason = BANDLIM_RST_CLOSEDPORT; goto dropwithreset; } INP_LOCK_ASSERT(inp); if ((inp->inp_flowtype == M_HASHTYPE_NONE) && (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) && !SOLISTENING(inp->inp_socket)) { inp->inp_flowid = m->m_pkthdr.flowid; inp->inp_flowtype = M_HASHTYPE_GET(m); } #if defined(IPSEC) || defined(IPSEC_SUPPORT) #ifdef INET6 if (isipv6 && IPSEC_ENABLED(ipv6) && IPSEC_CHECK_POLICY(ipv6, m, inp) != 0) { goto dropunlock; } #ifdef INET else #endif #endif /* INET6 */ #ifdef INET if (IPSEC_ENABLED(ipv4) && IPSEC_CHECK_POLICY(ipv4, m, inp) != 0) { goto dropunlock; } #endif /* INET */ #endif /* IPSEC */ /* * Check the minimum TTL for socket. */ if (inp->inp_ip_minttl != 0) { #ifdef INET6 if (isipv6) { if (inp->inp_ip_minttl > ip6->ip6_hlim) goto dropunlock; } else #endif if (inp->inp_ip_minttl > ip->ip_ttl) goto dropunlock; } tp = intotcpcb(inp); switch (tp->t_state) { case TCPS_TIME_WAIT: /* * A previous connection in TIMEWAIT state is supposed to catch * stray or duplicate segments arriving late. If this segment * was a legitimate new connection attempt, the old INPCB gets * removed and we can try again to find a listening socket. */ tcp_dooptions(&to, optp, optlen, (thflags & TH_SYN) ? TO_SYN : 0); /* * tcp_twcheck unlocks the inp always, and frees the m if fails. */ if (tcp_twcheck(inp, &to, th, m, tlen)) goto findpcb; return (IPPROTO_DONE); case TCPS_CLOSED: /* * The TCPCB may no longer exist if the connection is winding * down or it is in the CLOSED state. Either way we drop the * segment and send an appropriate response. */ rstreason = BANDLIM_RST_CLOSEDPORT; goto dropwithreset; } if ((tp->t_port != port) && (tp->t_state > TCPS_LISTEN)) { rstreason = BANDLIM_RST_CLOSEDPORT; goto dropwithreset; } #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) { tcp_offload_input(tp, m); m = NULL; /* consumed by the TOE driver */ goto dropunlock; } #endif #ifdef MAC if (mac_inpcb_check_deliver(inp, m)) goto dropunlock; #endif so = inp->inp_socket; KASSERT(so != NULL, ("%s: so == NULL", __func__)); -#ifdef TCPDEBUG - if (so->so_options & SO_DEBUG) { - ostate = tp->t_state; -#ifdef INET6 - if (isipv6) { - bcopy((char *)ip6, (char *)tcp_saveipgen, sizeof(*ip6)); - } else -#endif - bcopy((char *)ip, (char *)tcp_saveipgen, sizeof(*ip)); - tcp_savetcp = *th; - } -#endif /* TCPDEBUG */ /* * When the socket is accepting connections (the INPCB is in LISTEN * state) we look into the SYN cache if this is a new connection * attempt or the completion of a previous one. */ KASSERT(tp->t_state == TCPS_LISTEN || !SOLISTENING(so), ("%s: so accepting but tp %p not listening", __func__, tp)); if (tp->t_state == TCPS_LISTEN && SOLISTENING(so)) { struct in_conninfo inc; bzero(&inc, sizeof(inc)); #ifdef INET6 if (isipv6) { inc.inc_flags |= INC_ISIPV6; if (inp->inp_inc.inc_flags & INC_IPV6MINMTU) inc.inc_flags |= INC_IPV6MINMTU; inc.inc6_faddr = ip6->ip6_src; inc.inc6_laddr = ip6->ip6_dst; } else #endif { inc.inc_faddr = ip->ip_src; inc.inc_laddr = ip->ip_dst; } inc.inc_fport = th->th_sport; inc.inc_lport = th->th_dport; inc.inc_fibnum = so->so_fibnum; /* * Check for an existing connection attempt in syncache if * the flag is only ACK. A successful lookup creates a new * socket appended to the listen queue in SYN_RECEIVED state. */ if ((thflags & (TH_RST|TH_ACK|TH_SYN)) == TH_ACK) { /* * Parse the TCP options here because * syncookies need access to the reflected * timestamp. */ tcp_dooptions(&to, optp, optlen, 0); /* * NB: syncache_expand() doesn't unlock inp. */ rstreason = syncache_expand(&inc, &to, th, &so, m, port); if (rstreason < 0) { /* * A failing TCP MD5 signature comparison * must result in the segment being dropped * and must not produce any response back * to the sender. */ goto dropunlock; } else if (rstreason == 0) { /* * No syncache entry, or ACK was not for our * SYN/ACK. Do our protection against double * ACK. If peer sent us 2 ACKs, then for the * first one syncache_expand() successfully * converted syncache entry into a socket, * while we were waiting on the inpcb lock. We * don't want to sent RST for the second ACK, * so we perform second lookup without wildcard * match, hoping to find the new socket. If * the ACK is stray indeed, rstreason would * hint the above code that the lookup was a * second attempt. * * NB: syncache did its own logging * of the failure cause. */ INP_WUNLOCK(inp); rstreason = BANDLIM_RST_OPENPORT; lookupflag &= ~INPLOOKUP_WILDCARD; goto findpcb; } tfo_socket_result: if (so == NULL) { /* * We completed the 3-way handshake * but could not allocate a socket * either due to memory shortage, * listen queue length limits or * global socket limits. Send RST * or wait and have the remote end * retransmit the ACK for another * try. */ if ((s = tcp_log_addrs(&inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: Listen socket: " "Socket allocation failed due to " "limits or memory shortage, %s\n", s, __func__, V_tcp_sc_rst_sock_fail ? "sending RST" : "try again"); if (V_tcp_sc_rst_sock_fail) { rstreason = BANDLIM_UNLIMITED; goto dropwithreset; } else goto dropunlock; } /* * Socket is created in state SYN_RECEIVED. * Unlock the listen socket, lock the newly * created socket and update the tp variable. * If we came here via jump to tfo_socket_result, * then listening socket is read-locked. */ INP_UNLOCK(inp); /* listen socket */ inp = sotoinpcb(so); /* * New connection inpcb is already locked by * syncache_expand(). */ INP_WLOCK_ASSERT(inp); tp = intotcpcb(inp); KASSERT(tp->t_state == TCPS_SYN_RECEIVED, ("%s: ", __func__)); /* * Process the segment and the data it * contains. tcp_do_segment() consumes * the mbuf chain and unlocks the inpcb. */ TCP_PROBE5(receive, NULL, tp, m, tp, th); tp->t_fb->tfb_tcp_do_segment(m, th, so, tp, drop_hdrlen, tlen, iptos); return (IPPROTO_DONE); } /* * Segment flag validation for new connection attempts: * * Our (SYN|ACK) response was rejected. * Check with syncache and remove entry to prevent * retransmits. * * NB: syncache_chkrst does its own logging of failure * causes. */ if (thflags & TH_RST) { syncache_chkrst(&inc, th, m, port); goto dropunlock; } /* * We can't do anything without SYN. */ if ((thflags & TH_SYN) == 0) { if ((s = tcp_log_addrs(&inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: Listen socket: " "SYN is missing, segment ignored\n", s, __func__); TCPSTAT_INC(tcps_badsyn); goto dropunlock; } /* * (SYN|ACK) is bogus on a listen socket. */ if (thflags & TH_ACK) { if ((s = tcp_log_addrs(&inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: Listen socket: " "SYN|ACK invalid, segment rejected\n", s, __func__); syncache_badack(&inc, port); /* XXX: Not needed! */ TCPSTAT_INC(tcps_badsyn); rstreason = BANDLIM_RST_OPENPORT; goto dropwithreset; } /* * If the drop_synfin option is enabled, drop all * segments with both the SYN and FIN bits set. * This prevents e.g. nmap from identifying the * TCP/IP stack. * XXX: Poor reasoning. nmap has other methods * and is constantly refining its stack detection * strategies. * XXX: This is a violation of the TCP specification * and was used by RFC1644. */ if ((thflags & TH_FIN) && V_drop_synfin) { if ((s = tcp_log_addrs(&inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: Listen socket: " "SYN|FIN segment ignored (based on " "sysctl setting)\n", s, __func__); TCPSTAT_INC(tcps_badsyn); goto dropunlock; } /* * Segment's flags are (SYN) or (SYN|FIN). * * TH_PUSH, TH_URG, TH_ECE, TH_CWR are ignored * as they do not affect the state of the TCP FSM. * The data pointed to by TH_URG and th_urp is ignored. */ KASSERT((thflags & (TH_RST|TH_ACK)) == 0, ("%s: Listen socket: TH_RST or TH_ACK set", __func__)); KASSERT(thflags & (TH_SYN), ("%s: Listen socket: TH_SYN not set", __func__)); INP_RLOCK_ASSERT(inp); #ifdef INET6 /* * If deprecated address is forbidden, * we do not accept SYN to deprecated interface * address to prevent any new inbound connection from * getting established. * When we do not accept SYN, we send a TCP RST, * with deprecated source address (instead of dropping * it). We compromise it as it is much better for peer * to send a RST, and RST will be the final packet * for the exchange. * * If we do not forbid deprecated addresses, we accept * the SYN packet. RFC2462 does not suggest dropping * SYN in this case. * If we decipher RFC2462 5.5.4, it says like this: * 1. use of deprecated addr with existing * communication is okay - "SHOULD continue to be * used" * 2. use of it with new communication: * (2a) "SHOULD NOT be used if alternate address * with sufficient scope is available" * (2b) nothing mentioned otherwise. * Here we fall into (2b) case as we have no choice in * our source address selection - we must obey the peer. * * The wording in RFC2462 is confusing, and there are * multiple description text for deprecated address * handling - worse, they are not exactly the same. * I believe 5.5.4 is the best one, so we follow 5.5.4. */ if (isipv6 && !V_ip6_use_deprecated) { struct in6_ifaddr *ia6; ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */, false); if (ia6 != NULL && (ia6->ia6_flags & IN6_IFF_DEPRECATED)) { if ((s = tcp_log_addrs(&inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: Listen socket: " "Connection attempt to deprecated " "IPv6 address rejected\n", s, __func__); rstreason = BANDLIM_RST_OPENPORT; goto dropwithreset; } } #endif /* INET6 */ /* * Basic sanity checks on incoming SYN requests: * Don't respond if the destination is a link layer * broadcast according to RFC1122 4.2.3.10, p. 104. * If it is from this socket it must be forged. * Don't respond if the source or destination is a * global or subnet broad- or multicast address. * Note that it is quite possible to receive unicast * link-layer packets with a broadcast IP address. Use * in_broadcast() to find them. */ if (m->m_flags & (M_BCAST|M_MCAST)) { if ((s = tcp_log_addrs(&inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: Listen socket: " "Connection attempt from broad- or multicast " "link layer address ignored\n", s, __func__); goto dropunlock; } #ifdef INET6 if (isipv6) { if (th->th_dport == th->th_sport && IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &ip6->ip6_src)) { if ((s = tcp_log_addrs(&inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: Listen socket: " "Connection attempt to/from self " "ignored\n", s, __func__); goto dropunlock; } if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) { if ((s = tcp_log_addrs(&inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: Listen socket: " "Connection attempt from/to multicast " "address ignored\n", s, __func__); goto dropunlock; } } #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET { if (th->th_dport == th->th_sport && ip->ip_dst.s_addr == ip->ip_src.s_addr) { if ((s = tcp_log_addrs(&inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: Listen socket: " "Connection attempt from/to self " "ignored\n", s, __func__); goto dropunlock; } if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || IN_MULTICAST(ntohl(ip->ip_src.s_addr)) || ip->ip_src.s_addr == htonl(INADDR_BROADCAST) || in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) { if ((s = tcp_log_addrs(&inc, th, NULL, NULL))) log(LOG_DEBUG, "%s; %s: Listen socket: " "Connection attempt from/to broad- " "or multicast address ignored\n", s, __func__); goto dropunlock; } } #endif /* * SYN appears to be valid. Create compressed TCP state * for syncache. */ -#ifdef TCPDEBUG - if (so->so_options & SO_DEBUG) - tcp_trace(TA_INPUT, ostate, tp, - (void *)tcp_saveipgen, &tcp_savetcp, 0); -#endif TCP_PROBE3(debug__input, tp, th, m); tcp_dooptions(&to, optp, optlen, TO_SYN); if ((so = syncache_add(&inc, &to, th, inp, so, m, NULL, NULL, iptos, port)) != NULL) goto tfo_socket_result; /* * Entry added to syncache and mbuf consumed. * Only the listen socket is unlocked by syncache_add(). */ return (IPPROTO_DONE); } else if (tp->t_state == TCPS_LISTEN) { /* * When a listen socket is torn down the SO_ACCEPTCONN * flag is removed first while connections are drained * from the accept queue in a unlock/lock cycle of the * ACCEPT_LOCK, opening a race condition allowing a SYN * attempt go through unhandled. */ goto dropunlock; } #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) if (tp->t_flags & TF_SIGNATURE) { tcp_dooptions(&to, optp, optlen, thflags); if ((to.to_flags & TOF_SIGNATURE) == 0) { TCPSTAT_INC(tcps_sig_err_nosigopt); goto dropunlock; } if (!TCPMD5_ENABLED() || TCPMD5_INPUT(m, th, to.to_signature) != 0) goto dropunlock; } #endif TCP_PROBE5(receive, NULL, tp, m, tp, th); /* * Segment belongs to a connection in SYN_SENT, ESTABLISHED or later * state. tcp_do_segment() always consumes the mbuf chain, unlocks * the inpcb, and unlocks pcbinfo. * * XXXGL: in case of a pure SYN arriving on existing connection * TCP stacks won't need to modify the PCB, they would either drop * the segment silently, or send a challenge ACK. However, we try * to upgrade the lock, because calling convention for stacks is * write-lock on PCB. If upgrade fails, drop the SYN. */ if ((lookupflag & INPLOOKUP_RLOCKPCB) && INP_TRY_UPGRADE(inp) == 0) goto dropunlock; tp->t_fb->tfb_tcp_do_segment(m, th, so, tp, drop_hdrlen, tlen, iptos); return (IPPROTO_DONE); dropwithreset: TCP_PROBE5(receive, NULL, tp, m, tp, th); if (inp != NULL) { tcp_dropwithreset(m, th, tp, tlen, rstreason); INP_UNLOCK(inp); } else tcp_dropwithreset(m, th, NULL, tlen, rstreason); m = NULL; /* mbuf chain got consumed. */ goto drop; dropunlock: if (m != NULL) TCP_PROBE5(receive, NULL, tp, m, tp, th); if (inp != NULL) INP_UNLOCK(inp); drop: if (s != NULL) free(s, M_TCPLOG); if (m != NULL) m_freem(m); return (IPPROTO_DONE); } /* * Automatic sizing of receive socket buffer. Often the send * buffer size is not optimally adjusted to the actual network * conditions at hand (delay bandwidth product). Setting the * buffer size too small limits throughput on links with high * bandwidth and high delay (eg. trans-continental/oceanic links). * * On the receive side the socket buffer memory is only rarely * used to any significant extent. This allows us to be much * more aggressive in scaling the receive socket buffer. For * the case that the buffer space is actually used to a large * extent and we run out of kernel memory we can simply drop * the new segments; TCP on the sender will just retransmit it * later. Setting the buffer size too big may only consume too * much kernel memory if the application doesn't read() from * the socket or packet loss or reordering makes use of the * reassembly queue. * * The criteria to step up the receive buffer one notch are: * 1. Application has not set receive buffer size with * SO_RCVBUF. Setting SO_RCVBUF clears SB_AUTOSIZE. * 2. the number of bytes received during 1/2 of an sRTT * is at least 3/8 of the current socket buffer size. * 3. receive buffer size has not hit maximal automatic size; * * If all of the criteria are met we increaset the socket buffer * by a 1/2 (bounded by the max). This allows us to keep ahead * of slow-start but also makes it so our peer never gets limited * by our rwnd which we then open up causing a burst. * * This algorithm does two steps per RTT at most and only if * we receive a bulk stream w/o packet losses or reorderings. * Shrinking the buffer during idle times is not necessary as * it doesn't consume any memory when idle. * * TODO: Only step up if the application is actually serving * the buffer to better manage the socket buffer resources. */ int tcp_autorcvbuf(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int tlen) { int newsize = 0; if (V_tcp_do_autorcvbuf && (so->so_rcv.sb_flags & SB_AUTOSIZE) && tp->t_srtt != 0 && tp->rfbuf_ts != 0 && TCP_TS_TO_TICKS(tcp_ts_getticks() - tp->rfbuf_ts) > ((tp->t_srtt >> TCP_RTT_SHIFT)/2)) { if (tp->rfbuf_cnt > ((so->so_rcv.sb_hiwat / 2)/ 4 * 3) && so->so_rcv.sb_hiwat < V_tcp_autorcvbuf_max) { newsize = min((so->so_rcv.sb_hiwat + (so->so_rcv.sb_hiwat/2)), V_tcp_autorcvbuf_max); } TCP_PROBE6(receive__autoresize, NULL, tp, m, tp, th, newsize); /* Start over with next RTT. */ tp->rfbuf_ts = 0; tp->rfbuf_cnt = 0; } else { tp->rfbuf_cnt += tlen; /* add up */ } return (newsize); } int tcp_input(struct mbuf **mp, int *offp, int proto) { return(tcp_input_with_port(mp, offp, proto, 0)); } static void tcp_handle_wakeup(struct tcpcb *tp) { INP_WLOCK_ASSERT(tptoinpcb(tp)); if (tp->t_flags & TF_WAKESOR) { struct socket *so = tptosocket(tp); tp->t_flags &= ~TF_WAKESOR; SOCKBUF_LOCK_ASSERT(&so->so_rcv); sorwakeup_locked(so); } } void tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int drop_hdrlen, int tlen, uint8_t iptos) { uint16_t thflags; int acked, ourfinisacked, needoutput = 0, sack_changed; int rstreason, todrop, win, incforsyn = 0; uint32_t tiwin; uint16_t nsegs; char *s; struct inpcb *inp = tptoinpcb(tp); struct in_conninfo *inc = &inp->inp_inc; struct mbuf *mfree; struct tcpopt to; int tfo_syn; u_int maxseg; -#ifdef TCPDEBUG - /* - * The size of tcp_saveipgen must be the size of the max ip header, - * now IPv6. - */ - u_char tcp_saveipgen[IP6_HDR_LEN]; - struct tcphdr tcp_savetcp; - short ostate = 0; -#endif thflags = tcp_get_flags(th); tp->sackhint.last_sack_ack = 0; sack_changed = 0; nsegs = max(1, m->m_pkthdr.lro_nsegs); NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(inp); KASSERT(tp->t_state > TCPS_LISTEN, ("%s: TCPS_LISTEN", __func__)); KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT", __func__)); #ifdef TCPPCAP /* Save segment, if requested. */ tcp_pcap_add(th, m, &(tp->t_inpkts)); #endif TCP_LOG_EVENT(tp, th, &so->so_rcv, &so->so_snd, TCP_LOG_IN, 0, tlen, NULL, true); if ((thflags & TH_SYN) && (thflags & TH_FIN) && V_drop_synfin) { if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: " "SYN|FIN segment ignored (based on " "sysctl setting)\n", s, __func__); free(s, M_TCPLOG); } goto drop; } /* * If a segment with the ACK-bit set arrives in the SYN-SENT state * check SEQ.ACK first. */ if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) && (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { rstreason = BANDLIM_UNLIMITED; tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); goto dropwithreset; } /* * Segment received on connection. * Reset idle time and keep-alive timer. * XXX: This should be done after segment * validation to ignore broken/spoofed segs. */ if (tp->t_idle_reduce && (tp->snd_max == tp->snd_una) && ((ticks - tp->t_rcvtime) >= tp->t_rxtcur)) cc_after_idle(tp); tp->t_rcvtime = ticks; if (thflags & TH_FIN) tcp_log_end_status(tp, TCP_EI_STATUS_CLIENT_FIN); /* * Scale up the window into a 32-bit value. * For the SYN_SENT state the scale is zero. */ tiwin = th->th_win << tp->snd_scale; #ifdef STATS stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_FRWIN, tiwin); #endif /* * TCP ECN processing. */ if (tcp_ecn_input_segment(tp, thflags, tlen, tcp_packets_this_ack(tp, th->th_ack), iptos)) cc_cong_signal(tp, th, CC_ECN); /* * Parse options on any incoming segment. */ tcp_dooptions(&to, (u_char *)(th + 1), (th->th_off << 2) - sizeof(struct tcphdr), (thflags & TH_SYN) ? TO_SYN : 0); #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) if ((tp->t_flags & TF_SIGNATURE) != 0 && (to.to_flags & TOF_SIGNATURE) == 0) { TCPSTAT_INC(tcps_sig_err_sigopt); /* XXX: should drop? */ } #endif /* * If echoed timestamp is later than the current time, * fall back to non RFC1323 RTT calculation. Normalize * timestamp if syncookies were used when this connection * was established. */ if ((to.to_flags & TOF_TS) && (to.to_tsecr != 0)) { to.to_tsecr -= tp->ts_offset; if (TSTMP_GT(to.to_tsecr, tcp_ts_getticks())) to.to_tsecr = 0; else if (tp->t_rxtshift == 1 && tp->t_flags & TF_PREVVALID && tp->t_badrxtwin != 0 && TSTMP_LT(to.to_tsecr, tp->t_badrxtwin)) cc_cong_signal(tp, th, CC_RTO_ERR); } /* * Process options only when we get SYN/ACK back. The SYN case * for incoming connections is handled in tcp_syncache. * According to RFC1323 the window field in a SYN (i.e., a * or ) segment itself is never scaled. * XXX this is traditional behavior, may need to be cleaned up. */ if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) { /* Handle parallel SYN for ECN */ tcp_ecn_input_parallel_syn(tp, thflags, iptos); if ((to.to_flags & TOF_SCALE) && (tp->t_flags & TF_REQ_SCALE) && !(tp->t_flags & TF_NOOPT)) { tp->t_flags |= TF_RCVD_SCALE; tp->snd_scale = to.to_wscale; } else tp->t_flags &= ~TF_REQ_SCALE; /* * Initial send window. It will be updated with * the next incoming segment to the scaled value. */ tp->snd_wnd = th->th_win; if ((to.to_flags & TOF_TS) && (tp->t_flags & TF_REQ_TSTMP) && !(tp->t_flags & TF_NOOPT)) { tp->t_flags |= TF_RCVD_TSTMP; tp->ts_recent = to.to_tsval; tp->ts_recent_age = tcp_ts_getticks(); } else tp->t_flags &= ~TF_REQ_TSTMP; if (to.to_flags & TOF_MSS) tcp_mss(tp, to.to_mss); if ((tp->t_flags & TF_SACK_PERMIT) && (!(to.to_flags & TOF_SACKPERM) || (tp->t_flags & TF_NOOPT))) tp->t_flags &= ~TF_SACK_PERMIT; if (IS_FASTOPEN(tp->t_flags)) { if ((to.to_flags & TOF_FASTOPEN) && !(tp->t_flags & TF_NOOPT)) { uint16_t mss; if (to.to_flags & TOF_MSS) mss = to.to_mss; else if ((inp->inp_vflag & INP_IPV6) != 0) mss = TCP6_MSS; else mss = TCP_MSS; tcp_fastopen_update_cache(tp, mss, to.to_tfo_len, to.to_tfo_cookie); } else tcp_fastopen_disable_path(tp); } } /* * If timestamps were negotiated during SYN/ACK and a * segment without a timestamp is received, silently drop * the segment, unless it is a RST segment or missing timestamps are * tolerated. * See section 3.2 of RFC 7323. */ if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS)) { if (((thflags & TH_RST) != 0) || V_tcp_tolerate_missing_ts) { if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: Timestamp missing, " "segment processed normally\n", s, __func__); free(s, M_TCPLOG); } } else { if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: Timestamp missing, " "segment silently dropped\n", s, __func__); free(s, M_TCPLOG); } goto drop; } } /* * If timestamps were not negotiated during SYN/ACK and a * segment with a timestamp is received, ignore the * timestamp and process the packet normally. * See section 3.2 of RFC 7323. */ if (!(tp->t_flags & TF_RCVD_TSTMP) && (to.to_flags & TOF_TS)) { if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: Timestamp not expected, " "segment processed normally\n", s, __func__); free(s, M_TCPLOG); } } /* * Header prediction: check for the two common cases * of a uni-directional data xfer. If the packet has * no control flags, is in-sequence, the window didn't * change and we're not retransmitting, it's a * candidate. If the length is zero and the ack moved * forward, we're the sender side of the xfer. Just * free the data acked & wake any higher level process * that was blocked waiting for space. If the length * is non-zero and the ack didn't move, we're the * receiver side. If we're getting packets in-order * (the reassembly queue is empty), add the data to * the socket buffer and note that we need a delayed ack. * Make sure that the hidden state-flags are also off. * Since we check for TCPS_ESTABLISHED first, it can only * be TH_NEEDSYN. */ if (tp->t_state == TCPS_ESTABLISHED && th->th_seq == tp->rcv_nxt && (thflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK && tp->snd_nxt == tp->snd_max && tiwin && tiwin == tp->snd_wnd && ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) && SEGQ_EMPTY(tp) && ((to.to_flags & TOF_TS) == 0 || TSTMP_GEQ(to.to_tsval, tp->ts_recent)) ) { /* * If last ACK falls within this segment's sequence numbers, * record the timestamp. * NOTE that the test is modified according to the latest * proposal of the tcplw@cray.com list (Braden 1993/04/26). */ if ((to.to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent)) { tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = to.to_tsval; } if (tlen == 0) { if (SEQ_GT(th->th_ack, tp->snd_una) && SEQ_LEQ(th->th_ack, tp->snd_max) && !IN_RECOVERY(tp->t_flags) && (to.to_flags & TOF_SACK) == 0 && TAILQ_EMPTY(&tp->snd_holes)) { /* * This is a pure ack for outstanding data. */ TCPSTAT_INC(tcps_predack); /* * "bad retransmit" recovery without timestamps. */ if ((to.to_flags & TOF_TS) == 0 && tp->t_rxtshift == 1 && tp->t_flags & TF_PREVVALID && tp->t_badrxtwin != 0 && TSTMP_LT(ticks, tp->t_badrxtwin)) { cc_cong_signal(tp, th, CC_RTO_ERR); } /* * Recalculate the transmit timer / rtt. * * Some boxes send broken timestamp replies * during the SYN+ACK phase, ignore * timestamps of 0 or we could calculate a * huge RTT and blow up the retransmit timer. */ if ((to.to_flags & TOF_TS) != 0 && to.to_tsecr) { uint32_t t; t = tcp_ts_getticks() - to.to_tsecr; if (!tp->t_rttlow || tp->t_rttlow > t) tp->t_rttlow = t; tcp_xmit_timer(tp, TCP_TS_TO_TICKS(t) + 1); } else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq)) { if (!tp->t_rttlow || tp->t_rttlow > ticks - tp->t_rtttime) tp->t_rttlow = ticks - tp->t_rtttime; tcp_xmit_timer(tp, ticks - tp->t_rtttime); } acked = BYTES_THIS_ACK(tp, th); #ifdef TCP_HHOOK /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ hhook_run_tcp_est_in(tp, th, &to); #endif TCPSTAT_ADD(tcps_rcvackpack, nsegs); TCPSTAT_ADD(tcps_rcvackbyte, acked); sbdrop(&so->so_snd, acked); if (SEQ_GT(tp->snd_una, tp->snd_recover) && SEQ_LEQ(th->th_ack, tp->snd_recover)) tp->snd_recover = th->th_ack - 1; /* * Let the congestion control algorithm update * congestion control related information. This * typically means increasing the congestion * window. */ cc_ack_received(tp, th, nsegs, CC_ACK); tp->snd_una = th->th_ack; /* * Pull snd_wl2 up to prevent seq wrap relative * to th_ack. */ tp->snd_wl2 = th->th_ack; tp->t_dupacks = 0; m_freem(m); /* * If all outstanding data are acked, stop * retransmit timer, otherwise restart timer * using current (possibly backed-off) value. * If process is waiting for space, * wakeup/selwakeup/signal. If data * are ready to send, let tcp_output * decide between more output or persist. */ -#ifdef TCPDEBUG - if (so->so_options & SO_DEBUG) - tcp_trace(TA_INPUT, ostate, tp, - (void *)tcp_saveipgen, - &tcp_savetcp, 0); -#endif TCP_PROBE3(debug__input, tp, th, m); /* * Clear t_acktime if remote side has ACKd * all data in the socket buffer. * Otherwise, update t_acktime if we received * a sufficiently large ACK. */ if (sbavail(&so->so_snd) == 0) tp->t_acktime = 0; else if (acked > 1) tp->t_acktime = ticks; if (tp->snd_una == tp->snd_max) tcp_timer_activate(tp, TT_REXMT, 0); else if (!tcp_timer_active(tp, TT_PERSIST)) tcp_timer_activate(tp, TT_REXMT, TP_RXTCUR(tp)); sowwakeup(so); if (sbavail(&so->so_snd)) (void) tcp_output(tp); goto check_delack; } } else if (th->th_ack == tp->snd_una && tlen <= sbspace(&so->so_rcv)) { int newsize = 0; /* automatic sockbuf scaling */ /* * This is a pure, in-sequence data packet with * nothing on the reassembly queue and we have enough * buffer space to take it. */ /* Clean receiver SACK report if present */ if ((tp->t_flags & TF_SACK_PERMIT) && tp->rcv_numsacks) tcp_clean_sackreport(tp); TCPSTAT_INC(tcps_preddat); tp->rcv_nxt += tlen; if (tlen && ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && (tp->t_fbyte_in == 0)) { tp->t_fbyte_in = ticks; if (tp->t_fbyte_in == 0) tp->t_fbyte_in = 1; if (tp->t_fbyte_out && tp->t_fbyte_in) tp->t_flags2 |= TF2_FBYTES_COMPLETE; } /* * Pull snd_wl1 up to prevent seq wrap relative to * th_seq. */ tp->snd_wl1 = th->th_seq; /* * Pull rcv_up up to prevent seq wrap relative to * rcv_nxt. */ tp->rcv_up = tp->rcv_nxt; TCPSTAT_ADD(tcps_rcvpack, nsegs); TCPSTAT_ADD(tcps_rcvbyte, tlen); -#ifdef TCPDEBUG - if (so->so_options & SO_DEBUG) - tcp_trace(TA_INPUT, ostate, tp, - (void *)tcp_saveipgen, &tcp_savetcp, 0); -#endif TCP_PROBE3(debug__input, tp, th, m); newsize = tcp_autorcvbuf(m, th, so, tp, tlen); /* Add data to socket buffer. */ SOCKBUF_LOCK(&so->so_rcv); if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { m_freem(m); } else { /* * Set new socket buffer size. * Give up when limit is reached. */ if (newsize) if (!sbreserve_locked(so, SO_RCV, newsize, NULL)) so->so_rcv.sb_flags &= ~SB_AUTOSIZE; m_adj(m, drop_hdrlen); /* delayed header drop */ sbappendstream_locked(&so->so_rcv, m, 0); } /* NB: sorwakeup_locked() does an implicit unlock. */ sorwakeup_locked(so); if (DELAY_ACK(tp, tlen)) { tp->t_flags |= TF_DELACK; } else { tp->t_flags |= TF_ACKNOW; tcp_output(tp); } goto check_delack; } } /* * Calculate amount of space in receive window, * and then do TCP input processing. * Receive window is amount of space in rcv queue, * but not less than advertised window. */ win = sbspace(&so->so_rcv); if (win < 0) win = 0; tp->rcv_wnd = imax(win, (int)(tp->rcv_adv - tp->rcv_nxt)); switch (tp->t_state) { /* * If the state is SYN_RECEIVED: * if seg contains an ACK, but not for our SYN/ACK, send a RST. */ case TCPS_SYN_RECEIVED: if ((thflags & TH_ACK) && (SEQ_LEQ(th->th_ack, tp->snd_una) || SEQ_GT(th->th_ack, tp->snd_max))) { rstreason = BANDLIM_RST_OPENPORT; tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); goto dropwithreset; } if (IS_FASTOPEN(tp->t_flags)) { /* * When a TFO connection is in SYN_RECEIVED, the * only valid packets are the initial SYN, a * retransmit/copy of the initial SYN (possibly with * a subset of the original data), a valid ACK, a * FIN, or a RST. */ if ((thflags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) { rstreason = BANDLIM_RST_OPENPORT; tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); goto dropwithreset; } else if (thflags & TH_SYN) { /* non-initial SYN is ignored */ if ((tcp_timer_active(tp, TT_DELACK) || tcp_timer_active(tp, TT_REXMT))) goto drop; } else if (!(thflags & (TH_ACK|TH_FIN|TH_RST))) { goto drop; } } break; /* * If the state is SYN_SENT: * if seg contains a RST with valid ACK (SEQ.ACK has already * been verified), then drop the connection. * if seg contains a RST without an ACK, drop the seg. * if seg does not contain SYN, then drop the seg. * Otherwise this is an acceptable SYN segment * initialize tp->rcv_nxt and tp->irs * if seg contains ack then advance tp->snd_una * if seg contains an ECE and ECN support is enabled, the stream * is ECN capable. * if SYN has been acked change to ESTABLISHED else SYN_RCVD state * arrange for segment to be acked (eventually) * continue processing rest of data/controls, beginning with URG */ case TCPS_SYN_SENT: if ((thflags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) { TCP_PROBE5(connect__refused, NULL, tp, m, tp, th); tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); tp = tcp_drop(tp, ECONNREFUSED); } if (thflags & TH_RST) goto drop; if (!(thflags & TH_SYN)) goto drop; tp->irs = th->th_seq; tcp_rcvseqinit(tp); if (thflags & TH_ACK) { int tfo_partial_ack = 0; TCPSTAT_INC(tcps_connects); soisconnected(so); #ifdef MAC mac_socketpeer_set_from_mbuf(m, so); #endif /* Do window scaling on this connection? */ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == (TF_RCVD_SCALE|TF_REQ_SCALE)) { tp->rcv_scale = tp->request_r_scale; } tp->rcv_adv += min(tp->rcv_wnd, TCP_MAXWIN << tp->rcv_scale); tp->snd_una++; /* SYN is acked */ /* * If not all the data that was sent in the TFO SYN * has been acked, resend the remainder right away. */ if (IS_FASTOPEN(tp->t_flags) && (tp->snd_una != tp->snd_max)) { tp->snd_nxt = th->th_ack; tfo_partial_ack = 1; } /* * If there's data, delay ACK; if there's also a FIN * ACKNOW will be turned on later. */ if (DELAY_ACK(tp, tlen) && tlen != 0 && !tfo_partial_ack) tcp_timer_activate(tp, TT_DELACK, tcp_delacktime); else tp->t_flags |= TF_ACKNOW; tcp_ecn_input_syn_sent(tp, thflags, iptos); /* * Received in SYN_SENT[*] state. * Transitions: * SYN_SENT --> ESTABLISHED * SYN_SENT* --> FIN_WAIT_1 */ tp->t_starttime = ticks; if (tp->t_flags & TF_NEEDFIN) { tp->t_acktime = ticks; tcp_state_change(tp, TCPS_FIN_WAIT_1); tp->t_flags &= ~TF_NEEDFIN; thflags &= ~TH_SYN; } else { tcp_state_change(tp, TCPS_ESTABLISHED); TCP_PROBE5(connect__established, NULL, tp, m, tp, th); cc_conn_init(tp); tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp)); } } else { /* * Received initial SYN in SYN-SENT[*] state => * simultaneous open. * If it succeeds, connection is * half-synchronized. * Otherwise, do 3-way handshake: * SYN-SENT -> SYN-RECEIVED * SYN-SENT* -> SYN-RECEIVED* */ tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN | TF_SONOTCONN); tcp_timer_activate(tp, TT_REXMT, 0); tcp_state_change(tp, TCPS_SYN_RECEIVED); } /* * Advance th->th_seq to correspond to first data byte. * If data, trim to stay within window, * dropping FIN if necessary. */ th->th_seq++; if (tlen > tp->rcv_wnd) { todrop = tlen - tp->rcv_wnd; m_adj(m, -todrop); tlen = tp->rcv_wnd; thflags &= ~TH_FIN; TCPSTAT_INC(tcps_rcvpackafterwin); TCPSTAT_ADD(tcps_rcvbyteafterwin, todrop); } tp->snd_wl1 = th->th_seq - 1; tp->rcv_up = th->th_seq; /* * Client side of transaction: already sent SYN and data. * If the remote host used T/TCP to validate the SYN, * our data will be ACK'd; if so, enter normal data segment * processing in the middle of step 5, ack processing. * Otherwise, goto step 6. */ if (thflags & TH_ACK) goto process_ACK; goto step6; } /* * States other than LISTEN or SYN_SENT. * First check the RST flag and sequence number since reset segments * are exempt from the timestamp and connection count tests. This * fixes a bug introduced by the Stevens, vol. 2, p. 960 bugfix * below which allowed reset segments in half the sequence space * to fall though and be processed (which gives forged reset * segments with a random sequence number a 50 percent chance of * killing a connection). * Then check timestamp, if present. * Then check the connection count, if present. * Then check that at least some bytes of segment are within * receive window. If segment begins before rcv_nxt, * drop leading data (and SYN); if nothing left, just ack. */ if (thflags & TH_RST) { /* * RFC5961 Section 3.2 * * - RST drops connection only if SEG.SEQ == RCV.NXT. * - If RST is in window, we send challenge ACK. * * Note: to take into account delayed ACKs, we should * test against last_ack_sent instead of rcv_nxt. * Note 2: we handle special case of closed window, not * covered by the RFC. */ if ((SEQ_GEQ(th->th_seq, tp->last_ack_sent) && SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) || (tp->rcv_wnd == 0 && tp->last_ack_sent == th->th_seq)) { KASSERT(tp->t_state != TCPS_SYN_SENT, ("%s: TH_RST for TCPS_SYN_SENT th %p tp %p", __func__, th, tp)); if (V_tcp_insecure_rst || tp->last_ack_sent == th->th_seq) { TCPSTAT_INC(tcps_drops); /* Drop the connection. */ switch (tp->t_state) { case TCPS_SYN_RECEIVED: so->so_error = ECONNREFUSED; goto close; case TCPS_ESTABLISHED: case TCPS_FIN_WAIT_1: case TCPS_FIN_WAIT_2: case TCPS_CLOSE_WAIT: case TCPS_CLOSING: case TCPS_LAST_ACK: so->so_error = ECONNRESET; close: /* FALLTHROUGH */ default: tcp_log_end_status(tp, TCP_EI_STATUS_CLIENT_RST); tp = tcp_close(tp); } } else { TCPSTAT_INC(tcps_badrst); /* Send challenge ACK. */ tcp_respond(tp, mtod(m, void *), th, m, tp->rcv_nxt, tp->snd_nxt, TH_ACK); tp->last_ack_sent = tp->rcv_nxt; m = NULL; } } goto drop; } /* * RFC5961 Section 4.2 * Send challenge ACK for any SYN in synchronized state. */ if ((thflags & TH_SYN) && tp->t_state != TCPS_SYN_SENT && tp->t_state != TCPS_SYN_RECEIVED) { TCPSTAT_INC(tcps_badsyn); if (V_tcp_insecure_syn && SEQ_GEQ(th->th_seq, tp->last_ack_sent) && SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) { tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); tp = tcp_drop(tp, ECONNRESET); rstreason = BANDLIM_UNLIMITED; } else { tcp_ecn_input_syn_sent(tp, thflags, iptos); /* Send challenge ACK. */ tcp_respond(tp, mtod(m, void *), th, m, tp->rcv_nxt, tp->snd_nxt, TH_ACK); tp->last_ack_sent = tp->rcv_nxt; m = NULL; } goto drop; } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment * and it's less than ts_recent, drop it. */ if ((to.to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to.to_tsval, tp->ts_recent)) { /* Check to see if ts_recent is over 24 days old. */ if (tcp_ts_getticks() - tp->ts_recent_age > TCP_PAWS_IDLE) { /* * Invalidate ts_recent. If this segment updates * ts_recent, the age will be reset later and ts_recent * will get a valid value. If it does not, setting * ts_recent to zero will at least satisfy the * requirement that zero be placed in the timestamp * echo reply when ts_recent isn't valid. The * age isn't reset until we get a valid ts_recent * because we don't want out-of-order segments to be * dropped when ts_recent is old. */ tp->ts_recent = 0; } else { TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, tlen); TCPSTAT_INC(tcps_pawsdrop); if (tlen) goto dropafterack; goto drop; } } /* * In the SYN-RECEIVED state, validate that the packet belongs to * this connection before trimming the data to fit the receive * window. Check the sequence number versus IRS since we know * the sequence numbers haven't wrapped. This is a partial fix * for the "LAND" DoS attack. */ if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(th->th_seq, tp->irs)) { rstreason = BANDLIM_RST_OPENPORT; tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); goto dropwithreset; } todrop = tp->rcv_nxt - th->th_seq; if (todrop > 0) { if (thflags & TH_SYN) { thflags &= ~TH_SYN; th->th_seq++; if (th->th_urp > 1) th->th_urp--; else thflags &= ~TH_URG; todrop--; } /* * Following if statement from Stevens, vol. 2, p. 960. */ if (todrop > tlen || (todrop == tlen && (thflags & TH_FIN) == 0)) { /* * Any valid FIN must be to the left of the window. * At this point the FIN must be a duplicate or out * of sequence; drop it. */ thflags &= ~TH_FIN; /* * Send an ACK to resynchronize and drop any data. * But keep on processing for RST or ACK. */ tp->t_flags |= TF_ACKNOW; todrop = tlen; TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, todrop); } else { TCPSTAT_INC(tcps_rcvpartduppack); TCPSTAT_ADD(tcps_rcvpartdupbyte, todrop); } /* * DSACK - add SACK block for dropped range */ if ((todrop > 0) && (tp->t_flags & TF_SACK_PERMIT)) { tcp_update_sack_list(tp, th->th_seq, th->th_seq + todrop); /* * ACK now, as the next in-sequence segment * will clear the DSACK block again */ tp->t_flags |= TF_ACKNOW; } drop_hdrlen += todrop; /* drop from the top afterwards */ th->th_seq += todrop; tlen -= todrop; if (th->th_urp > todrop) th->th_urp -= todrop; else { thflags &= ~TH_URG; th->th_urp = 0; } } /* * If new data are received on a connection after the * user processes are gone, then RST the other end. */ if ((tp->t_flags & TF_CLOSED) && tlen) { if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: %s: Received %d bytes of data " "after socket was closed, " "sending RST and removing tcpcb\n", s, __func__, tcpstates[tp->t_state], tlen); free(s, M_TCPLOG); } tcp_log_end_status(tp, TCP_EI_STATUS_DATA_A_CLOSE); /* tcp_close will kill the inp pre-log the Reset */ tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST); tp = tcp_close(tp); TCPSTAT_INC(tcps_rcvafterclose); rstreason = BANDLIM_UNLIMITED; goto dropwithreset; } /* * If segment ends after window, drop trailing data * (and PUSH and FIN); if nothing left, just ACK. */ todrop = (th->th_seq + tlen) - (tp->rcv_nxt + tp->rcv_wnd); if (todrop > 0) { TCPSTAT_INC(tcps_rcvpackafterwin); if (todrop >= tlen) { TCPSTAT_ADD(tcps_rcvbyteafterwin, tlen); /* * If window is closed can only take segments at * window edge, and have to drop data and PUSH from * incoming segments. Continue processing, but * remember to ack. Otherwise, drop segment * and ack. */ if (tp->rcv_wnd == 0 && th->th_seq == tp->rcv_nxt) { tp->t_flags |= TF_ACKNOW; TCPSTAT_INC(tcps_rcvwinprobe); } else goto dropafterack; } else TCPSTAT_ADD(tcps_rcvbyteafterwin, todrop); m_adj(m, -todrop); tlen -= todrop; thflags &= ~(TH_PUSH|TH_FIN); } /* * If last ACK falls within this segment's sequence numbers, * record its timestamp. * NOTE: * 1) That the test incorporates suggestions from the latest * proposal of the tcplw@cray.com list (Braden 1993/04/26). * 2) That updating only on newer timestamps interferes with * our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. * 3) That we modify the segment boundary check to be * Last.ACK.Sent <= SEG.SEQ + SEG.Len * instead of RFC1323's * Last.ACK.Sent < SEG.SEQ + SEG.Len, * This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated * Vol. 2 p.869. In such cases, we can still calculate the * RTT correctly when RCV.NXT == Last.ACK.Sent. */ if ((to.to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN|TH_FIN)) != 0))) { tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = to.to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN * flag is on (half-synchronized state), then queue data for * later processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_state == TCPS_SYN_RECEIVED || (tp->t_flags & TF_NEEDSYN)) { if (tp->t_state == TCPS_SYN_RECEIVED && IS_FASTOPEN(tp->t_flags)) { tp->snd_wnd = tiwin; cc_conn_init(tp); } goto step6; } else if (tp->t_flags & TF_ACKNOW) goto dropafterack; else goto drop; } /* * Ack processing. */ switch (tp->t_state) { /* * In SYN_RECEIVED state, the ack ACKs our SYN, so enter * ESTABLISHED state and continue processing. * The ACK was checked above. */ case TCPS_SYN_RECEIVED: TCPSTAT_INC(tcps_connects); if (tp->t_flags & TF_SONOTCONN) { /* * Usually SYN_RECEIVED had been created from a LISTEN, * and solisten_enqueue() has already marked the socket * layer as connected. If it didn't, which can happen * only with an accept_filter(9), then the tp is marked * with TF_SONOTCONN. The other reason for this mark * to be set is a simultaneous open, a SYN_RECEIVED * that had been created from SYN_SENT. */ tp->t_flags &= ~TF_SONOTCONN; soisconnected(so); } /* Do window scaling? */ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == (TF_RCVD_SCALE|TF_REQ_SCALE)) { tp->rcv_scale = tp->request_r_scale; } tp->snd_wnd = tiwin; /* * Make transitions: * SYN-RECEIVED -> ESTABLISHED * SYN-RECEIVED* -> FIN-WAIT-1 */ tp->t_starttime = ticks; if (IS_FASTOPEN(tp->t_flags) && tp->t_tfo_pending) { tcp_fastopen_decrement_counter(tp->t_tfo_pending); tp->t_tfo_pending = NULL; } if (tp->t_flags & TF_NEEDFIN) { tp->t_acktime = ticks; tcp_state_change(tp, TCPS_FIN_WAIT_1); tp->t_flags &= ~TF_NEEDFIN; } else { tcp_state_change(tp, TCPS_ESTABLISHED); TCP_PROBE5(accept__established, NULL, tp, m, tp, th); /* * TFO connections call cc_conn_init() during SYN * processing. Calling it again here for such * connections is not harmless as it would undo the * snd_cwnd reduction that occurs when a TFO SYN|ACK * is retransmitted. */ if (!IS_FASTOPEN(tp->t_flags)) cc_conn_init(tp); tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp)); } /* * Account for the ACK of our SYN prior to * regular ACK processing below, except for * simultaneous SYN, which is handled later. */ if (SEQ_GT(th->th_ack, tp->snd_una) && !(tp->t_flags & TF_NEEDSYN)) incforsyn = 1; /* * If segment contains data or ACK, will call tcp_reass() * later; if not, do so now to pass queued data to user. */ if (tlen == 0 && (thflags & TH_FIN) == 0) { (void) tcp_reass(tp, (struct tcphdr *)0, NULL, 0, (struct mbuf *)0); tcp_handle_wakeup(tp); } tp->snd_wl1 = th->th_seq - 1; /* FALLTHROUGH */ /* * In ESTABLISHED state: drop duplicate ACKs; ACK out of range * ACKs. If the ack is in the range * tp->snd_una < th->th_ack <= tp->snd_max * then advance tp->snd_una to th->th_ack and drop * data from the retransmission queue. If this ACK reflects * more up to date window information we update our window information. */ case TCPS_ESTABLISHED: case TCPS_FIN_WAIT_1: case TCPS_FIN_WAIT_2: case TCPS_CLOSE_WAIT: case TCPS_CLOSING: case TCPS_LAST_ACK: if (SEQ_GT(th->th_ack, tp->snd_max)) { TCPSTAT_INC(tcps_rcvacktoomuch); goto dropafterack; } if (tcp_is_sack_recovery(tp, &to)) { if (((sack_changed = tcp_sack_doack(tp, &to, th->th_ack)) != 0) && (tp->t_flags & TF_LRD)) { tcp_sack_lost_retransmission(tp, th); } } else /* * Reset the value so that previous (valid) value * from the last ack with SACK doesn't get used. */ tp->sackhint.sacked_bytes = 0; #ifdef TCP_HHOOK /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ hhook_run_tcp_est_in(tp, th, &to); #endif if (SEQ_LEQ(th->th_ack, tp->snd_una)) { maxseg = tcp_maxseg(tp); if (tlen == 0 && (tiwin == tp->snd_wnd || (tp->t_flags & TF_SACK_PERMIT))) { /* * If this is the first time we've seen a * FIN from the remote, this is not a * duplicate and it needs to be processed * normally. This happens during a * simultaneous close. */ if ((thflags & TH_FIN) && (TCPS_HAVERCVDFIN(tp->t_state) == 0)) { tp->t_dupacks = 0; break; } TCPSTAT_INC(tcps_rcvdupack); /* * If we have outstanding data (other than * a window probe), this is a completely * duplicate ack (ie, window info didn't * change and FIN isn't set), * the ack is the biggest we've * seen and we've seen exactly our rexmt * threshold of them, assume a packet * has been dropped and retransmit it. * Kludge snd_nxt & the congestion * window so we send only this one * packet. * * We know we're losing at the current * window size so do congestion avoidance * (set ssthresh to half the current window * and pull our congestion window back to * the new ssthresh). * * Dup acks mean that packets have left the * network (they're now cached at the receiver) * so bump cwnd by the amount in the receiver * to keep a constant cwnd packets in the * network. * * When using TCP ECN, notify the peer that * we reduced the cwnd. */ /* * Following 2 kinds of acks should not affect * dupack counting: * 1) Old acks * 2) Acks with SACK but without any new SACK * information in them. These could result from * any anomaly in the network like a switch * duplicating packets or a possible DoS attack. */ if (th->th_ack != tp->snd_una || (tcp_is_sack_recovery(tp, &to) && !sack_changed)) break; else if (!tcp_timer_active(tp, TT_REXMT)) tp->t_dupacks = 0; else if (++tp->t_dupacks > tcprexmtthresh || IN_FASTRECOVERY(tp->t_flags)) { cc_ack_received(tp, th, nsegs, CC_DUPACK); if (V_tcp_do_prr && IN_FASTRECOVERY(tp->t_flags)) { tcp_do_prr_ack(tp, th, &to); } else if (tcp_is_sack_recovery(tp, &to) && IN_FASTRECOVERY(tp->t_flags)) { int awnd; /* * Compute the amount of data in flight first. * We can inject new data into the pipe iff * we have less than 1/2 the original window's * worth of data in flight. */ if (V_tcp_do_newsack) awnd = tcp_compute_pipe(tp); else awnd = (tp->snd_nxt - tp->snd_fack) + tp->sackhint.sack_bytes_rexmit; if (awnd < tp->snd_ssthresh) { tp->snd_cwnd += maxseg; if (tp->snd_cwnd > tp->snd_ssthresh) tp->snd_cwnd = tp->snd_ssthresh; } } else tp->snd_cwnd += maxseg; (void) tcp_output(tp); goto drop; } else if (tp->t_dupacks == tcprexmtthresh || (tp->t_flags & TF_SACK_PERMIT && V_tcp_do_newsack && tp->sackhint.sacked_bytes > (tcprexmtthresh - 1) * maxseg)) { enter_recovery: /* * Above is the RFC6675 trigger condition of * more than (dupthresh-1)*maxseg sacked data. * If the count of holes in the * scoreboard is >= dupthresh, we could * also enter loss recovery, but don't * have that value readily available. */ tp->t_dupacks = tcprexmtthresh; tcp_seq onxt = tp->snd_nxt; /* * If we're doing sack, or prr, check * to see if we're already in sack * recovery. If we're not doing sack, * check to see if we're in newreno * recovery. */ if (V_tcp_do_prr || (tp->t_flags & TF_SACK_PERMIT)) { if (IN_FASTRECOVERY(tp->t_flags)) { tp->t_dupacks = 0; break; } } else { if (SEQ_LEQ(th->th_ack, tp->snd_recover)) { tp->t_dupacks = 0; break; } } /* Congestion signal before ack. */ cc_cong_signal(tp, th, CC_NDUPACK); cc_ack_received(tp, th, nsegs, CC_DUPACK); tcp_timer_activate(tp, TT_REXMT, 0); tp->t_rtttime = 0; if (V_tcp_do_prr) { /* * snd_ssthresh is already updated by * cc_cong_signal. */ if (tcp_is_sack_recovery(tp, &to)) { tp->sackhint.prr_delivered = tp->sackhint.sacked_bytes; } else { tp->sackhint.prr_delivered = imin(tp->snd_max - tp->snd_una, imin(INT_MAX / 65536, tp->t_dupacks) * maxseg); } tp->sackhint.recover_fs = max(1, tp->snd_nxt - tp->snd_una); } if (tcp_is_sack_recovery(tp, &to)) { TCPSTAT_INC( tcps_sack_recovery_episode); tp->snd_recover = tp->snd_nxt; tp->snd_cwnd = maxseg; (void) tcp_output(tp); if (SEQ_GT(th->th_ack, tp->snd_una)) goto resume_partialack; goto drop; } tp->snd_nxt = th->th_ack; tp->snd_cwnd = maxseg; (void) tcp_output(tp); KASSERT(tp->snd_limited <= 2, ("%s: tp->snd_limited too big", __func__)); tp->snd_cwnd = tp->snd_ssthresh + maxseg * (tp->t_dupacks - tp->snd_limited); if (SEQ_GT(onxt, tp->snd_nxt)) tp->snd_nxt = onxt; goto drop; } else if (V_tcp_do_rfc3042) { /* * Process first and second duplicate * ACKs. Each indicates a segment * leaving the network, creating room * for more. Make sure we can send a * packet on reception of each duplicate * ACK by increasing snd_cwnd by one * segment. Restore the original * snd_cwnd after packet transmission. */ cc_ack_received(tp, th, nsegs, CC_DUPACK); uint32_t oldcwnd = tp->snd_cwnd; tcp_seq oldsndmax = tp->snd_max; u_int sent; int avail; KASSERT(tp->t_dupacks == 1 || tp->t_dupacks == 2, ("%s: dupacks not 1 or 2", __func__)); if (tp->t_dupacks == 1) tp->snd_limited = 0; tp->snd_cwnd = (tp->snd_nxt - tp->snd_una) + (tp->t_dupacks - tp->snd_limited) * maxseg; /* * Only call tcp_output when there * is new data available to be sent * or we need to send an ACK. */ SOCKBUF_LOCK(&so->so_snd); avail = sbavail(&so->so_snd) - (tp->snd_nxt - tp->snd_una); SOCKBUF_UNLOCK(&so->so_snd); if (avail > 0 || tp->t_flags & TF_ACKNOW) (void) tcp_output(tp); sent = tp->snd_max - oldsndmax; if (sent > maxseg) { KASSERT((tp->t_dupacks == 2 && tp->snd_limited == 0) || (sent == maxseg + 1 && tp->t_flags & TF_SENTFIN), ("%s: sent too much", __func__)); tp->snd_limited = 2; } else if (sent > 0) ++tp->snd_limited; tp->snd_cwnd = oldcwnd; goto drop; } } break; } else { /* * This ack is advancing the left edge, reset the * counter. */ tp->t_dupacks = 0; /* * If this ack also has new SACK info, increment the * counter as per rfc6675. The variable * sack_changed tracks all changes to the SACK * scoreboard, including when partial ACKs without * SACK options are received, and clear the scoreboard * from the left side. Such partial ACKs should not be * counted as dupacks here. */ if (tcp_is_sack_recovery(tp, &to) && sack_changed) { tp->t_dupacks++; /* limit overhead by setting maxseg last */ if (!IN_FASTRECOVERY(tp->t_flags) && (tp->sackhint.sacked_bytes > ((tcprexmtthresh - 1) * (maxseg = tcp_maxseg(tp))))) { goto enter_recovery; } } } resume_partialack: KASSERT(SEQ_GT(th->th_ack, tp->snd_una), ("%s: th_ack <= snd_una", __func__)); /* * If the congestion window was inflated to account * for the other side's cached packets, retract it. */ if (IN_FASTRECOVERY(tp->t_flags)) { if (SEQ_LT(th->th_ack, tp->snd_recover)) { if (tp->t_flags & TF_SACK_PERMIT) if (V_tcp_do_prr && to.to_flags & TOF_SACK) { tcp_timer_activate(tp, TT_REXMT, 0); tp->t_rtttime = 0; tcp_do_prr_ack(tp, th, &to); tp->t_flags |= TF_ACKNOW; (void) tcp_output(tp); } else tcp_sack_partialack(tp, th); else tcp_newreno_partial_ack(tp, th); } else cc_post_recovery(tp, th); } else if (IN_CONGRECOVERY(tp->t_flags)) { if (SEQ_LT(th->th_ack, tp->snd_recover)) { if (V_tcp_do_prr) { tp->sackhint.delivered_data = BYTES_THIS_ACK(tp, th); tp->snd_fack = th->th_ack; tcp_do_prr_ack(tp, th, &to); (void) tcp_output(tp); } } else cc_post_recovery(tp, th); } /* * If we reach this point, ACK is not a duplicate, * i.e., it ACKs something we sent. */ if (tp->t_flags & TF_NEEDSYN) { /* * T/TCP: Connection was half-synchronized, and our * SYN has been ACK'd (so connection is now fully * synchronized). Go to non-starred state, * increment snd_una for ACK of SYN, and check if * we can do window scaling. */ tp->t_flags &= ~TF_NEEDSYN; tp->snd_una++; /* Do window scaling? */ if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == (TF_RCVD_SCALE|TF_REQ_SCALE)) { tp->rcv_scale = tp->request_r_scale; /* Send window already scaled. */ } } process_ACK: INP_WLOCK_ASSERT(inp); /* * Adjust for the SYN bit in sequence space, * but don't account for it in cwnd calculations. * This is for the SYN_RECEIVED, non-simultaneous * SYN case. SYN_SENT and simultaneous SYN are * treated elsewhere. */ if (incforsyn) tp->snd_una++; acked = BYTES_THIS_ACK(tp, th); KASSERT(acked >= 0, ("%s: acked unexepectedly negative " "(tp->snd_una=%u, th->th_ack=%u, tp=%p, m=%p)", __func__, tp->snd_una, th->th_ack, tp, m)); TCPSTAT_ADD(tcps_rcvackpack, nsegs); TCPSTAT_ADD(tcps_rcvackbyte, acked); /* * If we just performed our first retransmit, and the ACK * arrives within our recovery window, then it was a mistake * to do the retransmit in the first place. Recover our * original cwnd and ssthresh, and proceed to transmit where * we left off. */ if (tp->t_rxtshift == 1 && tp->t_flags & TF_PREVVALID && tp->t_badrxtwin != 0 && to.to_flags & TOF_TS && to.to_tsecr != 0 && TSTMP_LT(to.to_tsecr, tp->t_badrxtwin)) cc_cong_signal(tp, th, CC_RTO_ERR); /* * If we have a timestamp reply, update smoothed * round trip time. If no timestamp is present but * transmit timer is running and timed sequence * number was acked, update smoothed round trip time. * Since we now have an rtt measurement, cancel the * timer backoff (cf., Phil Karn's retransmit alg.). * Recompute the initial retransmit timer. * * Some boxes send broken timestamp replies * during the SYN+ACK phase, ignore * timestamps of 0 or we could calculate a * huge RTT and blow up the retransmit timer. */ if ((to.to_flags & TOF_TS) != 0 && to.to_tsecr) { uint32_t t; t = tcp_ts_getticks() - to.to_tsecr; if (!tp->t_rttlow || tp->t_rttlow > t) tp->t_rttlow = t; tcp_xmit_timer(tp, TCP_TS_TO_TICKS(t) + 1); } else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq)) { if (!tp->t_rttlow || tp->t_rttlow > ticks - tp->t_rtttime) tp->t_rttlow = ticks - tp->t_rtttime; tcp_xmit_timer(tp, ticks - tp->t_rtttime); } SOCKBUF_LOCK(&so->so_snd); /* * Clear t_acktime if remote side has ACKd all data in the * socket buffer and FIN (if applicable). * Otherwise, update t_acktime if we received a sufficiently * large ACK. */ if ((tp->t_state <= TCPS_CLOSE_WAIT && acked == sbavail(&so->so_snd)) || acked > sbavail(&so->so_snd)) tp->t_acktime = 0; else if (acked > 1) tp->t_acktime = ticks; /* * If all outstanding data is acked, stop retransmit * timer and remember to restart (more output or persist). * If there is more data to be acked, restart retransmit * timer, using current (possibly backed-off) value. */ if (th->th_ack == tp->snd_max) { tcp_timer_activate(tp, TT_REXMT, 0); needoutput = 1; } else if (!tcp_timer_active(tp, TT_PERSIST)) tcp_timer_activate(tp, TT_REXMT, TP_RXTCUR(tp)); /* * If no data (only SYN) was ACK'd, * skip rest of ACK processing. */ if (acked == 0) { SOCKBUF_UNLOCK(&so->so_snd); goto step6; } /* * Let the congestion control algorithm update congestion * control related information. This typically means increasing * the congestion window. */ cc_ack_received(tp, th, nsegs, CC_ACK); if (acked > sbavail(&so->so_snd)) { if (tp->snd_wnd >= sbavail(&so->so_snd)) tp->snd_wnd -= sbavail(&so->so_snd); else tp->snd_wnd = 0; mfree = sbcut_locked(&so->so_snd, (int)sbavail(&so->so_snd)); ourfinisacked = 1; } else { mfree = sbcut_locked(&so->so_snd, acked); if (tp->snd_wnd >= (uint32_t) acked) tp->snd_wnd -= acked; else tp->snd_wnd = 0; ourfinisacked = 0; } /* NB: sowwakeup_locked() does an implicit unlock. */ sowwakeup_locked(so); m_freem(mfree); /* Detect una wraparound. */ if (!IN_RECOVERY(tp->t_flags) && SEQ_GT(tp->snd_una, tp->snd_recover) && SEQ_LEQ(th->th_ack, tp->snd_recover)) tp->snd_recover = th->th_ack - 1; /* XXXLAS: Can this be moved up into cc_post_recovery? */ if (IN_RECOVERY(tp->t_flags) && SEQ_GEQ(th->th_ack, tp->snd_recover)) { EXIT_RECOVERY(tp->t_flags); } tp->snd_una = th->th_ack; if (tp->t_flags & TF_SACK_PERMIT) { if (SEQ_GT(tp->snd_una, tp->snd_recover)) tp->snd_recover = tp->snd_una; } if (SEQ_LT(tp->snd_nxt, tp->snd_una)) tp->snd_nxt = tp->snd_una; switch (tp->t_state) { /* * In FIN_WAIT_1 STATE in addition to the processing * for the ESTABLISHED state if our FIN is now acknowledged * then enter FIN_WAIT_2. */ case TCPS_FIN_WAIT_1: if (ourfinisacked) { /* * If we can't receive any more * data, then closing user can proceed. * Starting the timer is contrary to the * specification, but if we don't get a FIN * we'll hang forever. */ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { soisdisconnected(so); tcp_timer_activate(tp, TT_2MSL, (tcp_fast_finwait2_recycle ? tcp_finwait2_timeout : TP_MAXIDLE(tp))); } tcp_state_change(tp, TCPS_FIN_WAIT_2); } break; /* * In CLOSING STATE in addition to the processing for * the ESTABLISHED state if the ACK acknowledges our FIN * then enter the TIME-WAIT state, otherwise ignore * the segment. */ case TCPS_CLOSING: if (ourfinisacked) { tcp_twstart(tp); m_freem(m); return; } break; /* * In LAST_ACK, we may still be waiting for data to drain * and/or to be acked, as well as for the ack of our FIN. * If our FIN is now acknowledged, delete the TCB, * enter the closed state and return. */ case TCPS_LAST_ACK: if (ourfinisacked) { tp = tcp_close(tp); goto drop; } break; } } step6: INP_WLOCK_ASSERT(inp); /* * Update window information. * Don't look at window if no ACK: TAC's send garbage on first SYN. */ if ((thflags & TH_ACK) && (SEQ_LT(tp->snd_wl1, th->th_seq) || (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) || (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) { /* keep track of pure window updates */ if (tlen == 0 && tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd) TCPSTAT_INC(tcps_rcvwinupd); tp->snd_wnd = tiwin; tp->snd_wl1 = th->th_seq; tp->snd_wl2 = th->th_ack; if (tp->snd_wnd > tp->max_sndwnd) tp->max_sndwnd = tp->snd_wnd; needoutput = 1; } /* * Process segments with URG. */ if ((thflags & TH_URG) && th->th_urp && TCPS_HAVERCVDFIN(tp->t_state) == 0) { /* * This is a kludge, but if we receive and accept * random urgent pointers, we'll crash in * soreceive. It's hard to imagine someone * actually wanting to send this much urgent data. */ SOCKBUF_LOCK(&so->so_rcv); if (th->th_urp + sbavail(&so->so_rcv) > sb_max) { th->th_urp = 0; /* XXX */ thflags &= ~TH_URG; /* XXX */ SOCKBUF_UNLOCK(&so->so_rcv); /* XXX */ goto dodata; /* XXX */ } /* * If this segment advances the known urgent pointer, * then mark the data stream. This should not happen * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since * a FIN has been received from the remote side. * In these states we ignore the URG. * * According to RFC961 (Assigned Protocols), * the urgent pointer points to the last octet * of urgent data. We continue, however, * to consider it to indicate the first octet * of data past the urgent section as the original * spec states (in one of two places). */ if (SEQ_GT(th->th_seq+th->th_urp, tp->rcv_up)) { tp->rcv_up = th->th_seq + th->th_urp; so->so_oobmark = sbavail(&so->so_rcv) + (tp->rcv_up - tp->rcv_nxt) - 1; if (so->so_oobmark == 0) so->so_rcv.sb_state |= SBS_RCVATMARK; sohasoutofband(so); tp->t_oobflags &= ~(TCPOOB_HAVEDATA | TCPOOB_HADDATA); } SOCKBUF_UNLOCK(&so->so_rcv); /* * Remove out of band data so doesn't get presented to user. * This can happen independent of advancing the URG pointer, * but if two URG's are pending at once, some out-of-band * data may creep in... ick. */ if (th->th_urp <= (uint32_t)tlen && !(so->so_options & SO_OOBINLINE)) { /* hdr drop is delayed */ tcp_pulloutofband(so, th, m, drop_hdrlen); } } else { /* * If no out of band data is expected, * pull receive urgent pointer along * with the receive window. */ if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) tp->rcv_up = tp->rcv_nxt; } dodata: /* XXX */ INP_WLOCK_ASSERT(inp); /* * Process the segment text, merging it into the TCP sequencing queue, * and arranging for acknowledgment of receipt if necessary. * This process logically involves adjusting tp->rcv_wnd as data * is presented to the user (this happens in tcp_usrreq.c, * case PRU_RCVD). If a FIN has already been received on this * connection then we just ignore the text. */ tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) && IS_FASTOPEN(tp->t_flags)); if ((tlen || (thflags & TH_FIN) || (tfo_syn && tlen > 0)) && TCPS_HAVERCVDFIN(tp->t_state) == 0) { tcp_seq save_start = th->th_seq; tcp_seq save_rnxt = tp->rcv_nxt; int save_tlen = tlen; m_adj(m, drop_hdrlen); /* delayed header drop */ /* * Insert segment which includes th into TCP reassembly queue * with control block tp. Set thflags to whether reassembly now * includes a segment with FIN. This handles the common case * inline (segment is the next to be received on an established * connection, and the queue is empty), avoiding linkage into * and removal from the queue and repetition of various * conversions. * Set DELACK for segments received in order, but ack * immediately when segments are out of order (so * fast retransmit can work). */ if (th->th_seq == tp->rcv_nxt && SEGQ_EMPTY(tp) && (TCPS_HAVEESTABLISHED(tp->t_state) || tfo_syn)) { if (DELAY_ACK(tp, tlen) || tfo_syn) tp->t_flags |= TF_DELACK; else tp->t_flags |= TF_ACKNOW; tp->rcv_nxt += tlen; if (tlen && ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && (tp->t_fbyte_in == 0)) { tp->t_fbyte_in = ticks; if (tp->t_fbyte_in == 0) tp->t_fbyte_in = 1; if (tp->t_fbyte_out && tp->t_fbyte_in) tp->t_flags2 |= TF2_FBYTES_COMPLETE; } thflags = tcp_get_flags(th) & TH_FIN; TCPSTAT_INC(tcps_rcvpack); TCPSTAT_ADD(tcps_rcvbyte, tlen); SOCKBUF_LOCK(&so->so_rcv); if (so->so_rcv.sb_state & SBS_CANTRCVMORE) m_freem(m); else sbappendstream_locked(&so->so_rcv, m, 0); tp->t_flags |= TF_WAKESOR; } else { /* * XXX: Due to the header drop above "th" is * theoretically invalid by now. Fortunately * m_adj() doesn't actually frees any mbufs * when trimming from the head. */ tcp_seq temp = save_start; thflags = tcp_reass(tp, th, &temp, &tlen, m); tp->t_flags |= TF_ACKNOW; } if ((tp->t_flags & TF_SACK_PERMIT) && (save_tlen > 0) && TCPS_HAVEESTABLISHED(tp->t_state)) { if ((tlen == 0) && (SEQ_LT(save_start, save_rnxt))) { /* * DSACK actually handled in the fastpath * above. */ tcp_update_sack_list(tp, save_start, save_start + save_tlen); } else if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) { if ((tp->rcv_numsacks >= 1) && (tp->sackblks[0].end == save_start)) { /* * Partial overlap, recorded at todrop * above. */ tcp_update_sack_list(tp, tp->sackblks[0].start, tp->sackblks[0].end); } else { tcp_update_dsack_list(tp, save_start, save_start + save_tlen); } } else if (tlen >= save_tlen) { /* Update of sackblks. */ tcp_update_dsack_list(tp, save_start, save_start + save_tlen); } else if (tlen > 0) { tcp_update_dsack_list(tp, save_start, save_start + tlen); } } tcp_handle_wakeup(tp); #if 0 /* * Note the amount of data that peer has sent into * our window, in order to estimate the sender's * buffer size. * XXX: Unused. */ if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt); else len = so->so_rcv.sb_hiwat; #endif } else { m_freem(m); thflags &= ~TH_FIN; } /* * If FIN is received ACK the FIN and let the user know * that the connection is closing. */ if (thflags & TH_FIN) { if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { /* The socket upcall is handled by socantrcvmore. */ socantrcvmore(so); /* * If connection is half-synchronized * (ie NEEDSYN flag on) then delay ACK, * so it may be piggybacked when SYN is sent. * Otherwise, since we received a FIN then no * more input can be expected, send ACK now. */ if (tp->t_flags & TF_NEEDSYN) tp->t_flags |= TF_DELACK; else tp->t_flags |= TF_ACKNOW; tp->rcv_nxt++; } switch (tp->t_state) { /* * In SYN_RECEIVED and ESTABLISHED STATES * enter the CLOSE_WAIT state. */ case TCPS_SYN_RECEIVED: tp->t_starttime = ticks; /* FALLTHROUGH */ case TCPS_ESTABLISHED: tcp_state_change(tp, TCPS_CLOSE_WAIT); break; /* * If still in FIN_WAIT_1 STATE FIN has not been acked so * enter the CLOSING state. */ case TCPS_FIN_WAIT_1: tcp_state_change(tp, TCPS_CLOSING); break; /* * In FIN_WAIT_2 state enter the TIME_WAIT state, * starting the time-wait timer, turning off the other * standard timers. */ case TCPS_FIN_WAIT_2: tcp_twstart(tp); return; } } -#ifdef TCPDEBUG - if (so->so_options & SO_DEBUG) - tcp_trace(TA_INPUT, ostate, tp, (void *)tcp_saveipgen, - &tcp_savetcp, 0); -#endif TCP_PROBE3(debug__input, tp, th, m); /* * Return any desired output. */ if (needoutput || (tp->t_flags & TF_ACKNOW)) (void) tcp_output(tp); check_delack: INP_WLOCK_ASSERT(inp); if (tp->t_flags & TF_DELACK) { tp->t_flags &= ~TF_DELACK; tcp_timer_activate(tp, TT_DELACK, tcp_delacktime); } INP_WUNLOCK(inp); return; dropafterack: /* * Generate an ACK dropping incoming segment if it occupies * sequence space, where the ACK reflects our state. * * We can now skip the test for the RST flag since all * paths to this code happen after packets containing * RST have been dropped. * * In the SYN-RECEIVED state, don't send an ACK unless the * segment we received passes the SYN-RECEIVED ACK test. * If it fails send a RST. This breaks the loop in the * "LAND" DoS attack, and also prevents an ACK storm * between two listening ports that have been sent forged * SYN segments, each with the source address of the other. */ if (tp->t_state == TCPS_SYN_RECEIVED && (thflags & TH_ACK) && (SEQ_GT(tp->snd_una, th->th_ack) || SEQ_GT(th->th_ack, tp->snd_max)) ) { rstreason = BANDLIM_RST_OPENPORT; tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); goto dropwithreset; } -#ifdef TCPDEBUG - if (so->so_options & SO_DEBUG) - tcp_trace(TA_DROP, ostate, tp, (void *)tcp_saveipgen, - &tcp_savetcp, 0); -#endif TCP_PROBE3(debug__input, tp, th, m); tp->t_flags |= TF_ACKNOW; (void) tcp_output(tp); INP_WUNLOCK(inp); m_freem(m); return; dropwithreset: if (tp != NULL) { tcp_dropwithreset(m, th, tp, tlen, rstreason); INP_WUNLOCK(inp); } else tcp_dropwithreset(m, th, NULL, tlen, rstreason); return; drop: /* * Drop space held by incoming segment and return. */ -#ifdef TCPDEBUG - if (tp == NULL || (inp->inp_socket->so_options & SO_DEBUG)) - tcp_trace(TA_DROP, ostate, tp, (void *)tcp_saveipgen, - &tcp_savetcp, 0); -#endif TCP_PROBE3(debug__input, tp, th, m); if (tp != NULL) { INP_WUNLOCK(inp); } m_freem(m); } /* * Issue RST and make ACK acceptable to originator of segment. * The mbuf must still include the original packet header. * tp may be NULL. */ void tcp_dropwithreset(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, int tlen, int rstreason) { #ifdef INET struct ip *ip; #endif #ifdef INET6 struct ip6_hdr *ip6; #endif if (tp != NULL) { INP_LOCK_ASSERT(tptoinpcb(tp)); } /* Don't bother if destination was broadcast/multicast. */ if ((tcp_get_flags(th) & TH_RST) || m->m_flags & (M_BCAST|M_MCAST)) goto drop; #ifdef INET6 if (mtod(m, struct ip *)->ip_v == 6) { ip6 = mtod(m, struct ip6_hdr *); if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) goto drop; /* IPv6 anycast check is done at tcp6_input() */ } #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET { ip = mtod(m, struct ip *); if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || IN_MULTICAST(ntohl(ip->ip_src.s_addr)) || ip->ip_src.s_addr == htonl(INADDR_BROADCAST) || in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) goto drop; } #endif /* Perform bandwidth limiting. */ if (badport_bandlim(rstreason) < 0) goto drop; /* tcp_respond consumes the mbuf chain. */ if (tcp_get_flags(th) & TH_ACK) { tcp_respond(tp, mtod(m, void *), th, m, (tcp_seq)0, th->th_ack, TH_RST); } else { if (tcp_get_flags(th) & TH_SYN) tlen++; if (tcp_get_flags(th) & TH_FIN) tlen++; tcp_respond(tp, mtod(m, void *), th, m, th->th_seq+tlen, (tcp_seq)0, TH_RST|TH_ACK); } return; drop: m_freem(m); } /* * Parse TCP options and place in tcpopt. */ void tcp_dooptions(struct tcpopt *to, u_char *cp, int cnt, int flags) { int opt, optlen; to->to_flags = 0; for (; cnt > 0; cnt -= optlen, cp += optlen) { opt = cp[0]; if (opt == TCPOPT_EOL) break; if (opt == TCPOPT_NOP) optlen = 1; else { if (cnt < 2) break; optlen = cp[1]; if (optlen < 2 || optlen > cnt) break; } switch (opt) { case TCPOPT_MAXSEG: if (optlen != TCPOLEN_MAXSEG) continue; if (!(flags & TO_SYN)) continue; to->to_flags |= TOF_MSS; bcopy((char *)cp + 2, (char *)&to->to_mss, sizeof(to->to_mss)); to->to_mss = ntohs(to->to_mss); break; case TCPOPT_WINDOW: if (optlen != TCPOLEN_WINDOW) continue; if (!(flags & TO_SYN)) continue; to->to_flags |= TOF_SCALE; to->to_wscale = min(cp[2], TCP_MAX_WINSHIFT); break; case TCPOPT_TIMESTAMP: if (optlen != TCPOLEN_TIMESTAMP) continue; to->to_flags |= TOF_TS; bcopy((char *)cp + 2, (char *)&to->to_tsval, sizeof(to->to_tsval)); to->to_tsval = ntohl(to->to_tsval); bcopy((char *)cp + 6, (char *)&to->to_tsecr, sizeof(to->to_tsecr)); to->to_tsecr = ntohl(to->to_tsecr); break; case TCPOPT_SIGNATURE: /* * In order to reply to a host which has set the * TCP_SIGNATURE option in its initial SYN, we have * to record the fact that the option was observed * here for the syncache code to perform the correct * response. */ if (optlen != TCPOLEN_SIGNATURE) continue; to->to_flags |= TOF_SIGNATURE; to->to_signature = cp + 2; break; case TCPOPT_SACK_PERMITTED: if (optlen != TCPOLEN_SACK_PERMITTED) continue; if (!(flags & TO_SYN)) continue; if (!V_tcp_do_sack) continue; to->to_flags |= TOF_SACKPERM; break; case TCPOPT_SACK: if (optlen <= 2 || (optlen - 2) % TCPOLEN_SACK != 0) continue; if (flags & TO_SYN) continue; to->to_flags |= TOF_SACK; to->to_nsacks = (optlen - 2) / TCPOLEN_SACK; to->to_sacks = cp + 2; TCPSTAT_INC(tcps_sack_rcv_blocks); break; case TCPOPT_FAST_OPEN: /* * Cookie length validation is performed by the * server side cookie checking code or the client * side cookie cache update code. */ if (!(flags & TO_SYN)) continue; if (!V_tcp_fastopen_client_enable && !V_tcp_fastopen_server_enable) continue; to->to_flags |= TOF_FASTOPEN; to->to_tfo_len = optlen - 2; to->to_tfo_cookie = to->to_tfo_len ? cp + 2 : NULL; break; default: continue; } } } /* * Pull out of band byte out of a segment so * it doesn't appear in the user's data queue. * It is still reflected in the segment length for * sequencing purposes. */ void tcp_pulloutofband(struct socket *so, struct tcphdr *th, struct mbuf *m, int off) { int cnt = off + th->th_urp - 1; while (cnt >= 0) { if (m->m_len > cnt) { char *cp = mtod(m, caddr_t) + cnt; struct tcpcb *tp = sototcpcb(so); INP_WLOCK_ASSERT(tptoinpcb(tp)); tp->t_iobc = *cp; tp->t_oobflags |= TCPOOB_HAVEDATA; bcopy(cp+1, cp, (unsigned)(m->m_len - cnt - 1)); m->m_len--; if (m->m_flags & M_PKTHDR) m->m_pkthdr.len--; return; } cnt -= m->m_len; m = m->m_next; if (m == NULL) break; } panic("tcp_pulloutofband"); } /* * Collect new round-trip time estimate * and update averages and current timeout. */ void tcp_xmit_timer(struct tcpcb *tp, int rtt) { int delta; INP_WLOCK_ASSERT(tptoinpcb(tp)); TCPSTAT_INC(tcps_rttupdated); tp->t_rttupdated++; #ifdef STATS stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT, imax(0, rtt * 1000 / hz)); #endif if ((tp->t_srtt != 0) && (tp->t_rxtshift <= TCP_RTT_INVALIDATE)) { /* * srtt is stored as fixed point with 5 bits after the * binary point (i.e., scaled by 8). The following magic * is equivalent to the smoothing algorithm in rfc793 with * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed * point). Adjust rtt to origin 0. */ delta = ((rtt - 1) << TCP_DELTA_SHIFT) - (tp->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT)); if ((tp->t_srtt += delta) <= 0) tp->t_srtt = 1; /* * We accumulate a smoothed rtt variance (actually, a * smoothed mean difference), then set the retransmit * timer to smoothed rtt + 4 times the smoothed variance. * rttvar is stored as fixed point with 4 bits after the * binary point (scaled by 16). The following is * equivalent to rfc793 smoothing with an alpha of .75 * (rttvar = rttvar*3/4 + |delta| / 4). This replaces * rfc793's wired-in beta. */ if (delta < 0) delta = -delta; delta -= tp->t_rttvar >> (TCP_RTTVAR_SHIFT - TCP_DELTA_SHIFT); if ((tp->t_rttvar += delta) <= 0) tp->t_rttvar = 1; } else { /* * No rtt measurement yet - use the unsmoothed rtt. * Set the variance to half the rtt (so our first * retransmit happens at 3*rtt). */ tp->t_srtt = rtt << TCP_RTT_SHIFT; tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1); } tp->t_rtttime = 0; tp->t_rxtshift = 0; /* * the retransmit should happen at rtt + 4 * rttvar. * Because of the way we do the smoothing, srtt and rttvar * will each average +1/2 tick of bias. When we compute * the retransmit timer, we want 1/2 tick of rounding and * 1 extra tick because of +-1/2 tick uncertainty in the * firing of the timer. The bias will give us exactly the * 1.5 tick we need. But, because the bias is * statistical, we have to test that we don't drop below * the minimum feasible timer (which is 2 ticks). */ TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), max(tp->t_rttmin, rtt + 2), TCPTV_REXMTMAX); /* * We received an ack for a packet that wasn't retransmitted; * it is probably safe to discard any error indications we've * received recently. This isn't quite right, but close enough * for now (a route might have failed after we sent a segment, * and the return path might not be symmetrical). */ tp->t_softerror = 0; } /* * Determine a reasonable value for maxseg size. * If the route is known, check route for mtu. * If none, use an mss that can be handled on the outgoing interface * without forcing IP to fragment. If no route is found, route has no mtu, * or the destination isn't local, use a default, hopefully conservative * size (usually 512 or the default IP max size, but no more than the mtu * of the interface), as we can't discover anything about intervening * gateways or networks. We also initialize the congestion/slow start * window to be a single segment if the destination isn't local. * While looking at the routing entry, we also initialize other path-dependent * parameters from pre-set or cached values in the routing entry. * * NOTE that resulting t_maxseg doesn't include space for TCP options or * IP options, e.g. IPSEC data, since length of this data may vary, and * thus it is calculated for every segment separately in tcp_output(). * * NOTE that this routine is only called when we process an incoming * segment, or an ICMP need fragmentation datagram. Outgoing SYN/ACK MSS * settings are handled in tcp_mssopt(). */ void tcp_mss_update(struct tcpcb *tp, int offer, int mtuoffer, struct hc_metrics_lite *metricptr, struct tcp_ifcap *cap) { int mss = 0; uint32_t maxmtu = 0; struct inpcb *inp = tptoinpcb(tp); struct hc_metrics_lite metrics; #ifdef INET6 int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0; size_t min_protoh = isipv6 ? sizeof (struct ip6_hdr) + sizeof (struct tcphdr) : sizeof (struct tcpiphdr); #else size_t min_protoh = sizeof(struct tcpiphdr); #endif INP_WLOCK_ASSERT(inp); if (tp->t_port) min_protoh += V_tcp_udp_tunneling_overhead; if (mtuoffer != -1) { KASSERT(offer == -1, ("%s: conflict", __func__)); offer = mtuoffer - min_protoh; } /* Initialize. */ #ifdef INET6 if (isipv6) { maxmtu = tcp_maxmtu6(&inp->inp_inc, cap); tp->t_maxseg = V_tcp_v6mssdflt; } #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET { maxmtu = tcp_maxmtu(&inp->inp_inc, cap); tp->t_maxseg = V_tcp_mssdflt; } #endif /* * No route to sender, stay with default mss and return. */ if (maxmtu == 0) { /* * In case we return early we need to initialize metrics * to a defined state as tcp_hc_get() would do for us * if there was no cache hit. */ if (metricptr != NULL) bzero(metricptr, sizeof(struct hc_metrics_lite)); return; } /* What have we got? */ switch (offer) { case 0: /* * Offer == 0 means that there was no MSS on the SYN * segment, in this case we use tcp_mssdflt as * already assigned to t_maxseg above. */ offer = tp->t_maxseg; break; case -1: /* * Offer == -1 means that we didn't receive SYN yet. */ /* FALLTHROUGH */ default: /* * Prevent DoS attack with too small MSS. Round up * to at least minmss. */ offer = max(offer, V_tcp_minmss); } /* * rmx information is now retrieved from tcp_hostcache. */ tcp_hc_get(&inp->inp_inc, &metrics); if (metricptr != NULL) bcopy(&metrics, metricptr, sizeof(struct hc_metrics_lite)); /* * If there's a discovered mtu in tcp hostcache, use it. * Else, use the link mtu. */ if (metrics.rmx_mtu) mss = min(metrics.rmx_mtu, maxmtu) - min_protoh; else { #ifdef INET6 if (isipv6) { mss = maxmtu - min_protoh; if (!V_path_mtu_discovery && !in6_localaddr(&inp->in6p_faddr)) mss = min(mss, V_tcp_v6mssdflt); } #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET { mss = maxmtu - min_protoh; if (!V_path_mtu_discovery && !in_localaddr(inp->inp_faddr)) mss = min(mss, V_tcp_mssdflt); } #endif /* * XXX - The above conditional (mss = maxmtu - min_protoh) * probably violates the TCP spec. * The problem is that, since we don't know the * other end's MSS, we are supposed to use a conservative * default. But, if we do that, then MTU discovery will * never actually take place, because the conservative * default is much less than the MTUs typically seen * on the Internet today. For the moment, we'll sweep * this under the carpet. * * The conservative default might not actually be a problem * if the only case this occurs is when sending an initial * SYN with options and data to a host we've never talked * to before. Then, they will reply with an MSS value which * will get recorded and the new parameters should get * recomputed. For Further Study. */ } mss = min(mss, offer); /* * Sanity check: make sure that maxseg will be large * enough to allow some data on segments even if the * all the option space is used (40bytes). Otherwise * funny things may happen in tcp_output. * * XXXGL: shouldn't we reserve space for IP/IPv6 options? */ mss = max(mss, 64); tp->t_maxseg = mss; } void tcp_mss(struct tcpcb *tp, int offer) { int mss; uint32_t bufsize; struct inpcb *inp = tptoinpcb(tp); struct socket *so; struct hc_metrics_lite metrics; struct tcp_ifcap cap; KASSERT(tp != NULL, ("%s: tp == NULL", __func__)); bzero(&cap, sizeof(cap)); tcp_mss_update(tp, offer, -1, &metrics, &cap); mss = tp->t_maxseg; /* * If there's a pipesize, change the socket buffer to that size, * don't change if sb_hiwat is different than default (then it * has been changed on purpose with setsockopt). * Make the socket buffers an integral number of mss units; * if the mss is larger than the socket buffer, decrease the mss. */ so = inp->inp_socket; SOCKBUF_LOCK(&so->so_snd); if ((so->so_snd.sb_hiwat == V_tcp_sendspace) && metrics.rmx_sendpipe) bufsize = metrics.rmx_sendpipe; else bufsize = so->so_snd.sb_hiwat; if (bufsize < mss) mss = bufsize; else { bufsize = roundup(bufsize, mss); if (bufsize > sb_max) bufsize = sb_max; if (bufsize > so->so_snd.sb_hiwat) (void)sbreserve_locked(so, SO_SND, bufsize, NULL); } SOCKBUF_UNLOCK(&so->so_snd); /* * Sanity check: make sure that maxseg will be large * enough to allow some data on segments even if the * all the option space is used (40bytes). Otherwise * funny things may happen in tcp_output. * * XXXGL: shouldn't we reserve space for IP/IPv6 options? */ tp->t_maxseg = max(mss, 64); SOCKBUF_LOCK(&so->so_rcv); if ((so->so_rcv.sb_hiwat == V_tcp_recvspace) && metrics.rmx_recvpipe) bufsize = metrics.rmx_recvpipe; else bufsize = so->so_rcv.sb_hiwat; if (bufsize > mss) { bufsize = roundup(bufsize, mss); if (bufsize > sb_max) bufsize = sb_max; if (bufsize > so->so_rcv.sb_hiwat) (void)sbreserve_locked(so, SO_RCV, bufsize, NULL); } SOCKBUF_UNLOCK(&so->so_rcv); /* Check the interface for TSO capabilities. */ if (cap.ifcap & CSUM_TSO) { tp->t_flags |= TF_TSO; tp->t_tsomax = cap.tsomax; tp->t_tsomaxsegcount = cap.tsomaxsegcount; tp->t_tsomaxsegsize = cap.tsomaxsegsize; } } /* * Determine the MSS option to send on an outgoing SYN. */ int tcp_mssopt(struct in_conninfo *inc) { int mss = 0; uint32_t thcmtu = 0; uint32_t maxmtu = 0; size_t min_protoh; KASSERT(inc != NULL, ("tcp_mssopt with NULL in_conninfo pointer")); #ifdef INET6 if (inc->inc_flags & INC_ISIPV6) { mss = V_tcp_v6mssdflt; maxmtu = tcp_maxmtu6(inc, NULL); min_protoh = sizeof(struct ip6_hdr) + sizeof(struct tcphdr); } #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET { mss = V_tcp_mssdflt; maxmtu = tcp_maxmtu(inc, NULL); min_protoh = sizeof(struct tcpiphdr); } #endif #if defined(INET6) || defined(INET) thcmtu = tcp_hc_getmtu(inc); /* IPv4 and IPv6 */ #endif if (maxmtu && thcmtu) mss = min(maxmtu, thcmtu) - min_protoh; else if (maxmtu || thcmtu) mss = max(maxmtu, thcmtu) - min_protoh; return (mss); } void tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to) { int snd_cnt = 0, limit = 0, del_data = 0, pipe = 0; int maxseg = tcp_maxseg(tp); INP_WLOCK_ASSERT(tptoinpcb(tp)); /* * Compute the amount of data that this ACK is indicating * (del_data) and an estimate of how many bytes are in the * network. */ if (tcp_is_sack_recovery(tp, to) || (IN_CONGRECOVERY(tp->t_flags) && !IN_FASTRECOVERY(tp->t_flags))) { del_data = tp->sackhint.delivered_data; if (V_tcp_do_newsack) pipe = tcp_compute_pipe(tp); else pipe = (tp->snd_nxt - tp->snd_fack) + tp->sackhint.sack_bytes_rexmit; } else { if (tp->sackhint.prr_delivered < (tcprexmtthresh * maxseg + tp->snd_recover - tp->snd_una)) del_data = maxseg; pipe = imax(0, tp->snd_max - tp->snd_una - imin(INT_MAX / 65536, tp->t_dupacks) * maxseg); } tp->sackhint.prr_delivered += del_data; /* * Proportional Rate Reduction */ if (pipe >= tp->snd_ssthresh) { if (tp->sackhint.recover_fs == 0) tp->sackhint.recover_fs = imax(1, tp->snd_nxt - tp->snd_una); snd_cnt = howmany((long)tp->sackhint.prr_delivered * tp->snd_ssthresh, tp->sackhint.recover_fs) - tp->sackhint.prr_out; } else { if (V_tcp_do_prr_conservative || (del_data == 0)) limit = tp->sackhint.prr_delivered - tp->sackhint.prr_out; else limit = imax(tp->sackhint.prr_delivered - tp->sackhint.prr_out, del_data) + maxseg; snd_cnt = imin((tp->snd_ssthresh - pipe), limit); } snd_cnt = imax(snd_cnt, 0) / maxseg; /* * Send snd_cnt new data into the network in response to this ack. * If there is going to be a SACK retransmission, adjust snd_cwnd * accordingly. */ if (IN_FASTRECOVERY(tp->t_flags)) { if (tcp_is_sack_recovery(tp, to)) { tp->snd_cwnd = tp->snd_nxt - tp->snd_recover + tp->sackhint.sack_bytes_rexmit + (snd_cnt * maxseg); } else { tp->snd_cwnd = (tp->snd_max - tp->snd_una) + (snd_cnt * maxseg); } } else if (IN_CONGRECOVERY(tp->t_flags)) tp->snd_cwnd = pipe - del_data + (snd_cnt * maxseg); tp->snd_cwnd = imax(maxseg, tp->snd_cwnd); } /* * On a partial ack arrives, force the retransmission of the * next unacknowledged segment. Do not clear tp->t_dupacks. * By setting snd_nxt to ti_ack, this forces retransmission timer to * be started again. */ void tcp_newreno_partial_ack(struct tcpcb *tp, struct tcphdr *th) { tcp_seq onxt = tp->snd_nxt; uint32_t ocwnd = tp->snd_cwnd; u_int maxseg = tcp_maxseg(tp); INP_WLOCK_ASSERT(tptoinpcb(tp)); tcp_timer_activate(tp, TT_REXMT, 0); tp->t_rtttime = 0; tp->snd_nxt = th->th_ack; /* * Set snd_cwnd to one segment beyond acknowledged offset. * (tp->snd_una has not yet been updated when this function is called.) */ tp->snd_cwnd = maxseg + BYTES_THIS_ACK(tp, th); tp->t_flags |= TF_ACKNOW; (void) tcp_output(tp); tp->snd_cwnd = ocwnd; if (SEQ_GT(onxt, tp->snd_nxt)) tp->snd_nxt = onxt; /* * Partial window deflation. Relies on fact that tp->snd_una * not updated yet. */ if (tp->snd_cwnd > BYTES_THIS_ACK(tp, th)) tp->snd_cwnd -= BYTES_THIS_ACK(tp, th); else tp->snd_cwnd = 0; tp->snd_cwnd += maxseg; } int tcp_compute_pipe(struct tcpcb *tp) { if (tp->t_fb->tfb_compute_pipe == NULL) { return (tp->snd_max - tp->snd_una + tp->sackhint.sack_bytes_rexmit - tp->sackhint.sacked_bytes); } else { return((*tp->t_fb->tfb_compute_pipe)(tp)); } } uint32_t tcp_compute_initwnd(uint32_t maxseg) { /* * Calculate the Initial Window, also used as Restart Window * * RFC5681 Section 3.1 specifies the default conservative values. * RFC3390 specifies slightly more aggressive values. * RFC6928 increases it to ten segments. * Support for user specified value for initial flight size. */ if (V_tcp_initcwnd_segments) return min(V_tcp_initcwnd_segments * maxseg, max(2 * maxseg, V_tcp_initcwnd_segments * 1460)); else if (V_tcp_do_rfc3390) return min(4 * maxseg, max(2 * maxseg, 4380)); else { /* Per RFC5681 Section 3.1 */ if (maxseg > 2190) return (2 * maxseg); else if (maxseg > 1095) return (3 * maxseg); else return (4 * maxseg); } } diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index aa4bfef9a9ff..e0e8dfeb46ef 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1,2207 +1,2177 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * @(#)tcp_output.c 8.4 (Berkeley) 5/24/95 */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" #include "opt_kern_tls.h" -#include "opt_tcpdebug.h" #include #include #include #include #ifdef TCP_HHOOK #include #endif #include #ifdef KERN_TLS #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef INET6 #include #include #include #endif #include #define TCPOUTFLAGS #include #include #include #include #include #include #include #include #include #ifdef TCPPCAP #include #endif -#ifdef TCPDEBUG -#include -#endif #ifdef TCP_OFFLOAD #include #endif #include #include #include #include #include #include VNET_DEFINE(int, path_mtu_discovery) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, path_mtu_discovery, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(path_mtu_discovery), 1, "Enable Path MTU Discovery"); VNET_DEFINE(int, tcp_do_tso) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, tso, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_tso), 0, "Enable TCP Segmentation Offload"); VNET_DEFINE(int, tcp_sendspace) = 1024*32; #define V_tcp_sendspace VNET(tcp_sendspace) SYSCTL_INT(_net_inet_tcp, TCPCTL_SENDSPACE, sendspace, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_sendspace), 0, "Initial send socket buffer size"); VNET_DEFINE(int, tcp_do_autosndbuf) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_auto, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_autosndbuf), 0, "Enable automatic send buffer sizing"); VNET_DEFINE(int, tcp_autosndbuf_inc) = 8*1024; SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_inc, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_autosndbuf_inc), 0, "Incrementor step size of automatic send buffer"); VNET_DEFINE(int, tcp_autosndbuf_max) = 2*1024*1024; SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_max, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_autosndbuf_max), 0, "Max size of automatic send buffer"); VNET_DEFINE(int, tcp_sendbuf_auto_lowat) = 0; #define V_tcp_sendbuf_auto_lowat VNET(tcp_sendbuf_auto_lowat) SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_auto_lowat, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_sendbuf_auto_lowat), 0, "Modify threshold for auto send buffer growth to account for SO_SNDLOWAT"); /* * Make sure that either retransmit or persist timer is set for SYN, FIN and * non-ACK. */ #define TCP_XMIT_TIMER_ASSERT(tp, len, th_flags) \ KASSERT(((len) == 0 && ((th_flags) & (TH_SYN | TH_FIN)) == 0) ||\ tcp_timer_active((tp), TT_REXMT) || \ tcp_timer_active((tp), TT_PERSIST), \ ("neither rexmt nor persist timer is set")) #ifdef TCP_HHOOK /* * Wrapper for the TCP established output helper hook. */ void hhook_run_tcp_est_out(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to, uint32_t len, int tso) { struct tcp_hhook_data hhook_data; if (V_tcp_hhh[HHOOK_TCP_EST_OUT]->hhh_nhooks > 0) { hhook_data.tp = tp; hhook_data.th = th; hhook_data.to = to; hhook_data.len = len; hhook_data.tso = tso; hhook_run_hooks(V_tcp_hhh[HHOOK_TCP_EST_OUT], &hhook_data, &tp->t_osd); } } #endif /* * CC wrapper hook functions */ void cc_after_idle(struct tcpcb *tp) { INP_WLOCK_ASSERT(tptoinpcb(tp)); if (CC_ALGO(tp)->after_idle != NULL) CC_ALGO(tp)->after_idle(&tp->t_ccv); } /* * Tcp output routine: figure out what should be sent and send it. */ int tcp_default_output(struct tcpcb *tp) { struct socket *so = tptosocket(tp); struct inpcb *inp = tptoinpcb(tp); int32_t len; uint32_t recwin, sendwin; uint16_t flags; int off, error = 0; /* Keep compiler happy */ u_int if_hw_tsomaxsegcount = 0; u_int if_hw_tsomaxsegsize = 0; struct mbuf *m; struct ip *ip = NULL; -#ifdef TCPDEBUG - struct ipovly *ipov = NULL; -#endif struct tcphdr *th; u_char opt[TCP_MAXOLEN]; unsigned ipoptlen, optlen, hdrlen, ulen; #if defined(IPSEC) || defined(IPSEC_SUPPORT) unsigned ipsec_optlen = 0; #endif int idle, sendalot, curticks; int sack_rxmit, sack_bytes_rxmt; struct sackhole *p; int tso, mtu; struct tcpopt to; struct udphdr *udp = NULL; struct tcp_log_buffer *lgb; unsigned int wanted_cookie = 0; unsigned int dont_sendalot = 0; #if 0 int maxburst = TCP_MAXBURST; #endif #ifdef INET6 struct ip6_hdr *ip6 = NULL; int isipv6; isipv6 = (inp->inp_vflag & INP_IPV6) != 0; #endif #ifdef KERN_TLS const bool hw_tls = (so->so_snd.sb_flags & SB_TLS_IFNET) != 0; #else const bool hw_tls = false; #endif NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(inp); #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) return (tcp_offload_output(tp)); #endif /* * For TFO connections in SYN_SENT or SYN_RECEIVED, * only allow the initial SYN or SYN|ACK and those sent * by the retransmit timer. */ if (IS_FASTOPEN(tp->t_flags) && ((tp->t_state == TCPS_SYN_SENT) || (tp->t_state == TCPS_SYN_RECEIVED)) && SEQ_GT(tp->snd_max, tp->snd_una) && /* initial SYN or SYN|ACK sent */ (tp->snd_nxt != tp->snd_una)) /* not a retransmit */ return (0); /* * Determine length of data that should be transmitted, * and flags that will be used. * If there is some data or critical controls (SYN, RST) * to send, then transmit; otherwise, investigate further. */ idle = (tp->t_flags & TF_LASTIDLE) || (tp->snd_max == tp->snd_una); if (idle && (((ticks - tp->t_rcvtime) >= tp->t_rxtcur) || (tp->t_sndtime && ((ticks - tp->t_sndtime) >= tp->t_rxtcur)))) cc_after_idle(tp); tp->t_flags &= ~TF_LASTIDLE; if (idle) { if (tp->t_flags & TF_MORETOCOME) { tp->t_flags |= TF_LASTIDLE; idle = 0; } } again: /* * If we've recently taken a timeout, snd_max will be greater than * snd_nxt. There may be SACK information that allows us to avoid * resending already delivered data. Adjust snd_nxt accordingly. */ if ((tp->t_flags & TF_SACK_PERMIT) && SEQ_LT(tp->snd_nxt, tp->snd_max)) tcp_sack_adjust(tp); sendalot = 0; tso = 0; mtu = 0; off = tp->snd_nxt - tp->snd_una; sendwin = min(tp->snd_wnd, tp->snd_cwnd); flags = tcp_outflags[tp->t_state]; /* * Send any SACK-generated retransmissions. If we're explicitly trying * to send out new data (when sendalot is 1), bypass this function. * If we retransmit in fast recovery mode, decrement snd_cwnd, since * we're replacing a (future) new transmission with a retransmission * now, and we previously incremented snd_cwnd in tcp_input(). */ /* * Still in sack recovery , reset rxmit flag to zero. */ sack_rxmit = 0; sack_bytes_rxmt = 0; len = 0; p = NULL; if ((tp->t_flags & TF_SACK_PERMIT) && IN_FASTRECOVERY(tp->t_flags) && (p = tcp_sack_output(tp, &sack_bytes_rxmt))) { uint32_t cwin; cwin = imax(min(tp->snd_wnd, tp->snd_cwnd) - sack_bytes_rxmt, 0); /* Do not retransmit SACK segments beyond snd_recover */ if (SEQ_GT(p->end, tp->snd_recover)) { /* * (At least) part of sack hole extends beyond * snd_recover. Check to see if we can rexmit data * for this hole. */ if (SEQ_GEQ(p->rxmit, tp->snd_recover)) { /* * Can't rexmit any more data for this hole. * That data will be rexmitted in the next * sack recovery episode, when snd_recover * moves past p->rxmit. */ p = NULL; goto after_sack_rexmit; } else { /* Can rexmit part of the current hole */ len = ((int32_t)ulmin(cwin, SEQ_SUB(tp->snd_recover, p->rxmit))); } } else { len = ((int32_t)ulmin(cwin, SEQ_SUB(p->end, p->rxmit))); } if (len > 0) { off = SEQ_SUB(p->rxmit, tp->snd_una); KASSERT(off >= 0,("%s: sack block to the left of una : %d", __func__, off)); sack_rxmit = 1; sendalot = 1; TCPSTAT_INC(tcps_sack_rexmits); TCPSTAT_ADD(tcps_sack_rexmit_bytes, min(len, tcp_maxseg(tp))); } } after_sack_rexmit: /* * Get standard flags, and add SYN or FIN if requested by 'hidden' * state flags. */ if (tp->t_flags & TF_NEEDFIN) flags |= TH_FIN; if (tp->t_flags & TF_NEEDSYN) flags |= TH_SYN; SOCKBUF_LOCK(&so->so_snd); /* * If in persist timeout with window of 0, send 1 byte. * Otherwise, if window is small but nonzero * and timer expired, we will send what we can * and go to transmit state. */ if (tp->t_flags & TF_FORCEDATA) { if (sendwin == 0) { /* * If we still have some data to send, then * clear the FIN bit. Usually this would * happen below when it realizes that we * aren't sending all the data. However, * if we have exactly 1 byte of unsent data, * then it won't clear the FIN bit below, * and if we are in persist state, we wind * up sending the packet without recording * that we sent the FIN bit. * * We can't just blindly clear the FIN bit, * because if we don't have any more data * to send then the probe will be the FIN * itself. */ if (off < sbused(&so->so_snd)) flags &= ~TH_FIN; sendwin = 1; } else { tcp_timer_activate(tp, TT_PERSIST, 0); tp->t_rxtshift = 0; } } /* * If snd_nxt == snd_max and we have transmitted a FIN, the * offset will be > 0 even if so_snd.sb_cc is 0, resulting in * a negative length. This can also occur when TCP opens up * its congestion window while receiving additional duplicate * acks after fast-retransmit because TCP will reset snd_nxt * to snd_max after the fast-retransmit. * * In the normal retransmit-FIN-only case, however, snd_nxt will * be set to snd_una, the offset will be 0, and the length may * wind up 0. * * If sack_rxmit is true we are retransmitting from the scoreboard * in which case len is already set. */ if (sack_rxmit == 0) { if (sack_bytes_rxmt == 0) len = ((int32_t)min(sbavail(&so->so_snd), sendwin) - off); else { int32_t cwin; /* * We are inside of a SACK recovery episode and are * sending new data, having retransmitted all the * data possible in the scoreboard. */ len = ((int32_t)min(sbavail(&so->so_snd), tp->snd_wnd) - off); /* * Don't remove this (len > 0) check ! * We explicitly check for len > 0 here (although it * isn't really necessary), to work around a gcc * optimization issue - to force gcc to compute * len above. Without this check, the computation * of len is bungled by the optimizer. */ if (len > 0) { cwin = tp->snd_cwnd - imax(0, (int32_t) (tp->snd_nxt - tp->snd_recover)) - sack_bytes_rxmt; if (cwin < 0) cwin = 0; len = imin(len, cwin); } } } /* * Lop off SYN bit if it has already been sent. However, if this * is SYN-SENT state and if segment contains data and if we don't * know that foreign host supports TAO, suppress sending segment. */ if ((flags & TH_SYN) && SEQ_GT(tp->snd_nxt, tp->snd_una)) { if (tp->t_state != TCPS_SYN_RECEIVED) flags &= ~TH_SYN; /* * When sending additional segments following a TFO SYN|ACK, * do not include the SYN bit. */ if (IS_FASTOPEN(tp->t_flags) && (tp->t_state == TCPS_SYN_RECEIVED)) flags &= ~TH_SYN; off--, len++; } /* * Be careful not to send data and/or FIN on SYN segments. * This measure is needed to prevent interoperability problems * with not fully conformant TCP implementations. */ if ((flags & TH_SYN) && (tp->t_flags & TF_NOOPT)) { len = 0; flags &= ~TH_FIN; } /* * On TFO sockets, ensure no data is sent in the following cases: * * - When retransmitting SYN|ACK on a passively-created socket * * - When retransmitting SYN on an actively created socket * * - When sending a zero-length cookie (cookie request) on an * actively created socket * * - When the socket is in the CLOSED state (RST is being sent) */ if (IS_FASTOPEN(tp->t_flags) && (((flags & TH_SYN) && (tp->t_rxtshift > 0)) || ((tp->t_state == TCPS_SYN_SENT) && (tp->t_tfo_client_cookie_len == 0)) || (flags & TH_RST))) len = 0; if (len <= 0) { /* * If FIN has been sent but not acked, * but we haven't been called to retransmit, * len will be < 0. Otherwise, window shrank * after we sent into it. If window shrank to 0, * cancel pending retransmit, pull snd_nxt back * to (closed) window, and set the persist timer * if it isn't already going. If the window didn't * close completely, just wait for an ACK. * * We also do a general check here to ensure that * we will set the persist timer when we have data * to send, but a 0-byte window. This makes sure * the persist timer is set even if the packet * hits one of the "goto send" lines below. */ len = 0; if ((sendwin == 0) && (TCPS_HAVEESTABLISHED(tp->t_state)) && (off < (int) sbavail(&so->so_snd)) && !tcp_timer_active(tp, TT_PERSIST)) { tcp_timer_activate(tp, TT_REXMT, 0); tp->t_rxtshift = 0; tp->snd_nxt = tp->snd_una; if (!tcp_timer_active(tp, TT_PERSIST)) tcp_setpersist(tp); } } /* len will be >= 0 after this point. */ KASSERT(len >= 0, ("[%s:%d]: len < 0", __func__, __LINE__)); tcp_sndbuf_autoscale(tp, so, sendwin); /* * Decide if we can use TCP Segmentation Offloading (if supported by * hardware). * * TSO may only be used if we are in a pure bulk sending state. The * presence of TCP-MD5, SACK retransmits, SACK advertizements and * IP options prevent using TSO. With TSO the TCP header is the same * (except for the sequence number) for all generated packets. This * makes it impossible to transmit any options which vary per generated * segment or packet. * * IPv4 handling has a clear separation of ip options and ip header * flags while IPv6 combines both in in6p_outputopts. ip6_optlen() does * the right thing below to provide length of just ip options and thus * checking for ipoptlen is enough to decide if ip options are present. */ #if defined(IPSEC) || defined(IPSEC_SUPPORT) /* * Pre-calculate here as we save another lookup into the darknesses * of IPsec that way and can actually decide if TSO is ok. */ #ifdef INET6 if (isipv6 && IPSEC_ENABLED(ipv6)) ipsec_optlen = IPSEC_HDRSIZE(ipv6, inp); #ifdef INET else #endif #endif /* INET6 */ #ifdef INET if (IPSEC_ENABLED(ipv4)) ipsec_optlen = IPSEC_HDRSIZE(ipv4, inp); #endif /* INET */ #endif /* IPSEC */ #ifdef INET6 if (isipv6) ipoptlen = ip6_optlen(inp); else #endif if (inp->inp_options) ipoptlen = inp->inp_options->m_len - offsetof(struct ipoption, ipopt_list); else ipoptlen = 0; #if defined(IPSEC) || defined(IPSEC_SUPPORT) ipoptlen += ipsec_optlen; #endif if ((tp->t_flags & TF_TSO) && V_tcp_do_tso && len > tp->t_maxseg && (tp->t_port == 0) && ((tp->t_flags & TF_SIGNATURE) == 0) && tp->rcv_numsacks == 0 && sack_rxmit == 0 && ipoptlen == 0 && !(flags & TH_SYN)) tso = 1; if (sack_rxmit) { if (SEQ_LT(p->rxmit + len, tp->snd_una + sbused(&so->so_snd))) flags &= ~TH_FIN; } else { if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + sbused(&so->so_snd))) flags &= ~TH_FIN; } recwin = lmin(lmax(sbspace(&so->so_rcv), 0), (long)TCP_MAXWIN << tp->rcv_scale); /* * Sender silly window avoidance. We transmit under the following * conditions when len is non-zero: * * - We have a full segment (or more with TSO) * - This is the last buffer in a write()/send() and we are * either idle or running NODELAY * - we've timed out (e.g. persist timer) * - we have more then 1/2 the maximum send window's worth of * data (receiver may be limited the window size) * - we need to retransmit */ if (len) { if (len >= tp->t_maxseg) goto send; /* * As the TCP header options are now * considered when setting up the initial * window, we would not send the last segment * if we skip considering the option length here. * Note: this may not work when tcp headers change * very dynamically in the future. */ if ((((tp->t_flags & TF_SIGNATURE) ? PADTCPOLEN(TCPOLEN_SIGNATURE) : 0) + ((tp->t_flags & TF_RCVD_TSTMP) ? PADTCPOLEN(TCPOLEN_TIMESTAMP) : 0) + len) >= tp->t_maxseg) goto send; /* * NOTE! on localhost connections an 'ack' from the remote * end may occur synchronously with the output and cause * us to flush a buffer queued with moretocome. XXX * * note: the len + off check is almost certainly unnecessary. */ if (!(tp->t_flags & TF_MORETOCOME) && /* normal case */ (idle || (tp->t_flags & TF_NODELAY)) && (uint32_t)len + (uint32_t)off >= sbavail(&so->so_snd) && (tp->t_flags & TF_NOPUSH) == 0) { goto send; } if (tp->t_flags & TF_FORCEDATA) /* typ. timeout case */ goto send; if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0) goto send; if (SEQ_LT(tp->snd_nxt, tp->snd_max)) /* retransmit case */ goto send; if (sack_rxmit) goto send; } /* * Sending of standalone window updates. * * Window updates are important when we close our window due to a * full socket buffer and are opening it again after the application * reads data from it. Once the window has opened again and the * remote end starts to send again the ACK clock takes over and * provides the most current window information. * * We must avoid the silly window syndrome whereas every read * from the receive buffer, no matter how small, causes a window * update to be sent. We also should avoid sending a flurry of * window updates when the socket buffer had queued a lot of data * and the application is doing small reads. * * Prevent a flurry of pointless window updates by only sending * an update when we can increase the advertized window by more * than 1/4th of the socket buffer capacity. When the buffer is * getting full or is very small be more aggressive and send an * update whenever we can increase by two mss sized segments. * In all other situations the ACK's to new incoming data will * carry further window increases. * * Don't send an independent window update if a delayed * ACK is pending (it will get piggy-backed on it) or the * remote side already has done a half-close and won't send * more data. Skip this if the connection is in T/TCP * half-open state. */ if (recwin > 0 && !(tp->t_flags & TF_NEEDSYN) && !(tp->t_flags & TF_DELACK) && !TCPS_HAVERCVDFIN(tp->t_state)) { /* * "adv" is the amount we could increase the window, * taking into account that we are limited by * TCP_MAXWIN << tp->rcv_scale. */ int32_t adv; int oldwin; adv = recwin; if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) { oldwin = (tp->rcv_adv - tp->rcv_nxt); if (adv > oldwin) adv -= oldwin; else adv = 0; } else oldwin = 0; /* * If the new window size ends up being the same as or less * than the old size when it is scaled, then don't force * a window update. */ if (oldwin >> tp->rcv_scale >= (adv + oldwin) >> tp->rcv_scale) goto dontupdate; if (adv >= (int32_t)(2 * tp->t_maxseg) && (adv >= (int32_t)(so->so_rcv.sb_hiwat / 4) || recwin <= (so->so_rcv.sb_hiwat / 8) || so->so_rcv.sb_hiwat <= 8 * tp->t_maxseg || adv >= TCP_MAXWIN << tp->rcv_scale)) goto send; if (2 * adv >= (int32_t)so->so_rcv.sb_hiwat) goto send; } dontupdate: /* * Send if we owe the peer an ACK, RST, SYN, or urgent data. ACKNOW * is also a catch-all for the retransmit timer timeout case. */ if (tp->t_flags & TF_ACKNOW) goto send; if ((flags & TH_RST) || ((flags & TH_SYN) && (tp->t_flags & TF_NEEDSYN) == 0)) goto send; if (SEQ_GT(tp->snd_up, tp->snd_una)) goto send; /* * If our state indicates that FIN should be sent * and we have not yet done so, then we need to send. */ if (flags & TH_FIN && ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una)) goto send; /* * In SACK, it is possible for tcp_output to fail to send a segment * after the retransmission timer has been turned off. Make sure * that the retransmission timer is set. */ if ((tp->t_flags & TF_SACK_PERMIT) && SEQ_GT(tp->snd_max, tp->snd_una) && !tcp_timer_active(tp, TT_REXMT) && !tcp_timer_active(tp, TT_PERSIST)) { tcp_timer_activate(tp, TT_REXMT, TP_RXTCUR(tp)); goto just_return; } /* * TCP window updates are not reliable, rather a polling protocol * using ``persist'' packets is used to insure receipt of window * updates. The three ``states'' for the output side are: * idle not doing retransmits or persists * persisting to move a small or zero window * (re)transmitting and thereby not persisting * * tcp_timer_active(tp, TT_PERSIST) * is true when we are in persist state. * (tp->t_flags & TF_FORCEDATA) * is set when we are called to send a persist packet. * tcp_timer_active(tp, TT_REXMT) * is set when we are retransmitting * The output side is idle when both timers are zero. * * If send window is too small, there is data to transmit, and no * retransmit or persist is pending, then go to persist state. * If nothing happens soon, send when timer expires: * if window is nonzero, transmit what we can, * otherwise force out a byte. */ if (sbavail(&so->so_snd) && !tcp_timer_active(tp, TT_REXMT) && !tcp_timer_active(tp, TT_PERSIST)) { tp->t_rxtshift = 0; tcp_setpersist(tp); } /* * No reason to send a segment, just return. */ just_return: SOCKBUF_UNLOCK(&so->so_snd); return (0); send: SOCKBUF_LOCK_ASSERT(&so->so_snd); if (len > 0) { if (len >= tp->t_maxseg) tp->t_flags2 |= TF2_PLPMTU_MAXSEGSNT; else tp->t_flags2 &= ~TF2_PLPMTU_MAXSEGSNT; } /* * Before ESTABLISHED, force sending of initial options * unless TCP set not to do any options. * NOTE: we assume that the IP/TCP header plus TCP options * always fit in a single mbuf, leaving room for a maximum * link header, i.e. * max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MCLBYTES */ optlen = 0; #ifdef INET6 if (isipv6) hdrlen = sizeof (struct ip6_hdr) + sizeof (struct tcphdr); else #endif hdrlen = sizeof (struct tcpiphdr); if (flags & TH_SYN) { tp->snd_nxt = tp->iss; } /* * Compute options for segment. * We only have to care about SYN and established connection * segments. Options for SYN-ACK segments are handled in TCP * syncache. */ to.to_flags = 0; if ((tp->t_flags & TF_NOOPT) == 0) { /* Maximum segment size. */ if (flags & TH_SYN) { to.to_mss = tcp_mssopt(&inp->inp_inc); if (tp->t_port) to.to_mss -= V_tcp_udp_tunneling_overhead; to.to_flags |= TOF_MSS; /* * On SYN or SYN|ACK transmits on TFO connections, * only include the TFO option if it is not a * retransmit, as the presence of the TFO option may * have caused the original SYN or SYN|ACK to have * been dropped by a middlebox. */ if (IS_FASTOPEN(tp->t_flags) && (tp->t_rxtshift == 0)) { if (tp->t_state == TCPS_SYN_RECEIVED) { to.to_tfo_len = TCP_FASTOPEN_COOKIE_LEN; to.to_tfo_cookie = (u_int8_t *)&tp->t_tfo_cookie.server; to.to_flags |= TOF_FASTOPEN; wanted_cookie = 1; } else if (tp->t_state == TCPS_SYN_SENT) { to.to_tfo_len = tp->t_tfo_client_cookie_len; to.to_tfo_cookie = tp->t_tfo_cookie.client; to.to_flags |= TOF_FASTOPEN; wanted_cookie = 1; /* * If we wind up having more data to * send with the SYN than can fit in * one segment, don't send any more * until the SYN|ACK comes back from * the other end. */ dont_sendalot = 1; } } } /* Window scaling. */ if ((flags & TH_SYN) && (tp->t_flags & TF_REQ_SCALE)) { to.to_wscale = tp->request_r_scale; to.to_flags |= TOF_SCALE; } /* Timestamps. */ if ((tp->t_flags & TF_RCVD_TSTMP) || ((flags & TH_SYN) && (tp->t_flags & TF_REQ_TSTMP))) { curticks = tcp_ts_getticks(); to.to_tsval = curticks + tp->ts_offset; to.to_tsecr = tp->ts_recent; to.to_flags |= TOF_TS; if (tp->t_rxtshift == 1) tp->t_badrxtwin = curticks; } /* Set receive buffer autosizing timestamp. */ if (tp->rfbuf_ts == 0 && (so->so_rcv.sb_flags & SB_AUTOSIZE)) tp->rfbuf_ts = tcp_ts_getticks(); /* Selective ACK's. */ if (tp->t_flags & TF_SACK_PERMIT) { if (flags & TH_SYN) to.to_flags |= TOF_SACKPERM; else if (TCPS_HAVEESTABLISHED(tp->t_state) && tp->rcv_numsacks > 0) { to.to_flags |= TOF_SACK; to.to_nsacks = tp->rcv_numsacks; to.to_sacks = (u_char *)tp->sackblks; } } #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) /* TCP-MD5 (RFC2385). */ /* * Check that TCP_MD5SIG is enabled in tcpcb to * account the size needed to set this TCP option. */ if (tp->t_flags & TF_SIGNATURE) to.to_flags |= TOF_SIGNATURE; #endif /* TCP_SIGNATURE */ /* Processing the options. */ hdrlen += optlen = tcp_addoptions(&to, opt); /* * If we wanted a TFO option to be added, but it was unable * to fit, ensure no data is sent. */ if (IS_FASTOPEN(tp->t_flags) && wanted_cookie && !(to.to_flags & TOF_FASTOPEN)) len = 0; } if (tp->t_port) { if (V_tcp_udp_tunneling_port == 0) { /* The port was removed?? */ SOCKBUF_UNLOCK(&so->so_snd); return (EHOSTUNREACH); } hdrlen += sizeof(struct udphdr); } /* * Adjust data length if insertion of options will * bump the packet length beyond the t_maxseg length. * Clear the FIN bit because we cut off the tail of * the segment. */ if (len + optlen + ipoptlen > tp->t_maxseg) { flags &= ~TH_FIN; if (tso) { u_int if_hw_tsomax; u_int moff; int max_len; /* extract TSO information */ if_hw_tsomax = tp->t_tsomax; if_hw_tsomaxsegcount = tp->t_tsomaxsegcount; if_hw_tsomaxsegsize = tp->t_tsomaxsegsize; /* * Limit a TSO burst to prevent it from * overflowing or exceeding the maximum length * allowed by the network interface: */ KASSERT(ipoptlen == 0, ("%s: TSO can't do IP options", __func__)); /* * Check if we should limit by maximum payload * length: */ if (if_hw_tsomax != 0) { /* compute maximum TSO length */ max_len = (if_hw_tsomax - hdrlen - max_linkhdr); if (max_len <= 0) { len = 0; } else if (len > max_len) { sendalot = 1; len = max_len; } } /* * Prevent the last segment from being * fractional unless the send sockbuf can be * emptied: */ max_len = (tp->t_maxseg - optlen); if (((uint32_t)off + (uint32_t)len) < sbavail(&so->so_snd)) { moff = len % max_len; if (moff != 0) { len -= moff; sendalot = 1; } } /* * In case there are too many small fragments * don't use TSO: */ if (len <= max_len) { len = max_len; sendalot = 1; tso = 0; } /* * Send the FIN in a separate segment * after the bulk sending is done. * We don't trust the TSO implementations * to clear the FIN flag on all but the * last segment. */ if (tp->t_flags & TF_NEEDFIN) sendalot = 1; } else { if (optlen + ipoptlen >= tp->t_maxseg) { /* * Since we don't have enough space to put * the IP header chain and the TCP header in * one packet as required by RFC 7112, don't * send it. Also ensure that at least one * byte of the payload can be put into the * TCP segment. */ SOCKBUF_UNLOCK(&so->so_snd); error = EMSGSIZE; sack_rxmit = 0; goto out; } len = tp->t_maxseg - optlen - ipoptlen; sendalot = 1; if (dont_sendalot) sendalot = 0; } } else tso = 0; KASSERT(len + hdrlen + ipoptlen <= IP_MAXPACKET, ("%s: len > IP_MAXPACKET", __func__)); /*#ifdef DIAGNOSTIC*/ #ifdef INET6 if (max_linkhdr + hdrlen > MCLBYTES) #else if (max_linkhdr + hdrlen > MHLEN) #endif panic("tcphdr too big"); /*#endif*/ /* * This KASSERT is here to catch edge cases at a well defined place. * Before, those had triggered (random) panic conditions further down. */ KASSERT(len >= 0, ("[%s:%d]: len < 0", __func__, __LINE__)); /* * Grab a header mbuf, attaching a copy of data to * be transmitted, and initialize the header from * the template for sends on this connection. */ if (len) { struct mbuf *mb; struct sockbuf *msb; u_int moff; if ((tp->t_flags & TF_FORCEDATA) && len == 1) { TCPSTAT_INC(tcps_sndprobe); #ifdef STATS if (SEQ_LT(tp->snd_nxt, tp->snd_max)) stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RETXPB, len); else stats_voi_update_abs_u64(tp->t_stats, VOI_TCP_TXPB, len); #endif /* STATS */ } else if (SEQ_LT(tp->snd_nxt, tp->snd_max) || sack_rxmit) { tp->t_sndrexmitpack++; TCPSTAT_INC(tcps_sndrexmitpack); TCPSTAT_ADD(tcps_sndrexmitbyte, len); #ifdef STATS stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RETXPB, len); #endif /* STATS */ } else { TCPSTAT_INC(tcps_sndpack); TCPSTAT_ADD(tcps_sndbyte, len); #ifdef STATS stats_voi_update_abs_u64(tp->t_stats, VOI_TCP_TXPB, len); #endif /* STATS */ } #ifdef INET6 if (MHLEN < hdrlen + max_linkhdr) m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); else #endif m = m_gethdr(M_NOWAIT, MT_DATA); if (m == NULL) { SOCKBUF_UNLOCK(&so->so_snd); error = ENOBUFS; sack_rxmit = 0; goto out; } m->m_data += max_linkhdr; m->m_len = hdrlen; /* * Start the m_copy functions from the closest mbuf * to the offset in the socket buffer chain. */ mb = sbsndptr_noadv(&so->so_snd, off, &moff); if (len <= MHLEN - hdrlen - max_linkhdr && !hw_tls) { m_copydata(mb, moff, len, mtod(m, caddr_t) + hdrlen); if (SEQ_LT(tp->snd_nxt, tp->snd_max)) sbsndptr_adv(&so->so_snd, mb, len); m->m_len += len; } else { if (SEQ_LT(tp->snd_nxt, tp->snd_max)) msb = NULL; else msb = &so->so_snd; m->m_next = tcp_m_copym(mb, moff, &len, if_hw_tsomaxsegcount, if_hw_tsomaxsegsize, msb, hw_tls); if (len <= (tp->t_maxseg - optlen)) { /* * Must have ran out of mbufs for the copy * shorten it to no longer need tso. Lets * not put on sendalot since we are low on * mbufs. */ tso = 0; } if (m->m_next == NULL) { SOCKBUF_UNLOCK(&so->so_snd); (void) m_free(m); error = ENOBUFS; sack_rxmit = 0; goto out; } } /* * If we're sending everything we've got, set PUSH. * (This will keep happy those implementations which only * give data to the user when a buffer fills or * a PUSH comes in.) */ if (((uint32_t)off + (uint32_t)len == sbused(&so->so_snd)) && !(flags & TH_SYN)) flags |= TH_PUSH; SOCKBUF_UNLOCK(&so->so_snd); } else { SOCKBUF_UNLOCK(&so->so_snd); if (tp->t_flags & TF_ACKNOW) TCPSTAT_INC(tcps_sndacks); else if (flags & (TH_SYN|TH_FIN|TH_RST)) TCPSTAT_INC(tcps_sndctrl); else if (SEQ_GT(tp->snd_up, tp->snd_una)) TCPSTAT_INC(tcps_sndurg); else TCPSTAT_INC(tcps_sndwinup); m = m_gethdr(M_NOWAIT, MT_DATA); if (m == NULL) { error = ENOBUFS; sack_rxmit = 0; goto out; } #ifdef INET6 if (isipv6 && (MHLEN < hdrlen + max_linkhdr) && MHLEN >= hdrlen) { M_ALIGN(m, hdrlen); } else #endif m->m_data += max_linkhdr; m->m_len = hdrlen; } SOCKBUF_UNLOCK_ASSERT(&so->so_snd); m->m_pkthdr.rcvif = (struct ifnet *)0; #ifdef MAC mac_inpcb_create_mbuf(inp, m); #endif #ifdef INET6 if (isipv6) { ip6 = mtod(m, struct ip6_hdr *); if (tp->t_port) { udp = (struct udphdr *)((caddr_t)ip6 + sizeof(struct ip6_hdr)); udp->uh_sport = htons(V_tcp_udp_tunneling_port); udp->uh_dport = tp->t_port; ulen = hdrlen + len - sizeof(struct ip6_hdr); udp->uh_ulen = htons(ulen); th = (struct tcphdr *)(udp + 1); } else { th = (struct tcphdr *)(ip6 + 1); } tcpip_fillheaders(inp, tp->t_port, ip6, th); } else #endif /* INET6 */ { ip = mtod(m, struct ip *); -#ifdef TCPDEBUG - ipov = (struct ipovly *)ip; -#endif if (tp->t_port) { udp = (struct udphdr *)((caddr_t)ip + sizeof(struct ip)); udp->uh_sport = htons(V_tcp_udp_tunneling_port); udp->uh_dport = tp->t_port; ulen = hdrlen + len - sizeof(struct ip); udp->uh_ulen = htons(ulen); th = (struct tcphdr *)(udp + 1); } else th = (struct tcphdr *)(ip + 1); tcpip_fillheaders(inp, tp->t_port, ip, th); } /* * Fill in fields, remembering maximum advertised * window for use in delaying messages about window sizes. * If resending a FIN, be sure not to use a new sequence number. */ if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && tp->snd_nxt == tp->snd_max) tp->snd_nxt--; /* * If we are starting a connection, send ECN setup * SYN packet. If we are on a retransmit, we may * resend those bits a number of times as per * RFC 3168. */ if (tp->t_state == TCPS_SYN_SENT && V_tcp_do_ecn) { flags |= tcp_ecn_output_syn_sent(tp); } /* Also handle parallel SYN for ECN */ if ((TCPS_HAVERCVDSYN(tp->t_state)) && (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT))) { int ect = tcp_ecn_output_established(tp, &flags, len, sack_rxmit); if ((tp->t_state == TCPS_SYN_RECEIVED) && (tp->t_flags2 & TF2_ECN_SND_ECE)) tp->t_flags2 &= ~TF2_ECN_SND_ECE; #ifdef INET6 if (isipv6) { ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20); ip6->ip6_flow |= htonl(ect << 20); } else #endif { ip->ip_tos &= ~IPTOS_ECN_MASK; ip->ip_tos |= ect; } } /* * If we are doing retransmissions, then snd_nxt will * not reflect the first unsent octet. For ACK only * packets, we do not want the sequence number of the * retransmitted packet, we want the sequence number * of the next unsent octet. So, if there is no data * (and no SYN or FIN), use snd_max instead of snd_nxt * when filling in ti_seq. But if we are in persist * state, snd_max might reflect one byte beyond the * right edge of the window, so use snd_nxt in that * case, since we know we aren't doing a retransmission. * (retransmit and persist are mutually exclusive...) */ if (sack_rxmit == 0) { if (len || (flags & (TH_SYN|TH_FIN)) || tcp_timer_active(tp, TT_PERSIST)) th->th_seq = htonl(tp->snd_nxt); else th->th_seq = htonl(tp->snd_max); } else { th->th_seq = htonl(p->rxmit); p->rxmit += len; /* * Lost Retransmission Detection * trigger resending of a (then * still existing) hole, when * fack acks recoverypoint. */ if ((tp->t_flags & TF_LRD) && SEQ_GEQ(p->rxmit, p->end)) p->rxmit = tp->snd_recover; tp->sackhint.sack_bytes_rexmit += len; } if (IN_RECOVERY(tp->t_flags)) { /* * Account all bytes transmitted while * IN_RECOVERY, simplifying PRR and * Lost Retransmit Detection */ tp->sackhint.prr_out += len; } th->th_ack = htonl(tp->rcv_nxt); if (optlen) { bcopy(opt, th + 1, optlen); th->th_off = (sizeof (struct tcphdr) + optlen) >> 2; } tcp_set_flags(th, flags); /* * Calculate receive window. Don't shrink window, * but avoid silly window syndrome. * If a RST segment is sent, advertise a window of zero. */ if (flags & TH_RST) { recwin = 0; } else { if (recwin < (so->so_rcv.sb_hiwat / 4) && recwin < tp->t_maxseg) recwin = 0; if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt) && recwin < (tp->rcv_adv - tp->rcv_nxt)) recwin = (tp->rcv_adv - tp->rcv_nxt); } /* * According to RFC1323 the window field in a SYN (i.e., a * or ) segment itself is never scaled. The * case is handled in syncache. */ if (flags & TH_SYN) th->th_win = htons((u_short) (min(sbspace(&so->so_rcv), TCP_MAXWIN))); else { /* Avoid shrinking window with window scaling. */ recwin = roundup2(recwin, 1 << tp->rcv_scale); th->th_win = htons((u_short)(recwin >> tp->rcv_scale)); } /* * Adjust the RXWIN0SENT flag - indicate that we have advertised * a 0 window. This may cause the remote transmitter to stall. This * flag tells soreceive() to disable delayed acknowledgements when * draining the buffer. This can occur if the receiver is attempting * to read more data than can be buffered prior to transmitting on * the connection. */ if (th->th_win == 0) { tp->t_sndzerowin++; tp->t_flags |= TF_RXWIN0SENT; } else tp->t_flags &= ~TF_RXWIN0SENT; if (SEQ_GT(tp->snd_up, tp->snd_nxt)) { th->th_urp = htons((u_short)(tp->snd_up - tp->snd_nxt)); th->th_flags |= TH_URG; } else /* * If no urgent pointer to send, then we pull * the urgent pointer to the left edge of the send window * so that it doesn't drift into the send window on sequence * number wraparound. */ tp->snd_up = tp->snd_una; /* drag it along */ /* * Put TCP length in extended header, and then * checksum extended header and data. */ m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */ #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) if (to.to_flags & TOF_SIGNATURE) { /* * Calculate MD5 signature and put it into the place * determined before. * NOTE: since TCP options buffer doesn't point into * mbuf's data, calculate offset and use it. */ if (!TCPMD5_ENABLED() || (error = TCPMD5_OUTPUT(m, th, (u_char *)(th + 1) + (to.to_signature - opt))) != 0) { /* * Do not send segment if the calculation of MD5 * digest has failed. */ m_freem(m); goto out; } } #endif #ifdef INET6 if (isipv6) { /* * There is no need to fill in ip6_plen right now. * It will be filled later by ip6_output. */ if (tp->t_port) { m->m_pkthdr.csum_flags = CSUM_UDP_IPV6; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); udp->uh_sum = in6_cksum_pseudo(ip6, ulen, IPPROTO_UDP, 0); th->th_sum = htons(0); UDPSTAT_INC(udps_opackets); } else { m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); th->th_sum = in6_cksum_pseudo(ip6, sizeof(struct tcphdr) + optlen + len, IPPROTO_TCP, 0); } } #endif #if defined(INET6) && defined(INET) else #endif #ifdef INET { if (tp->t_port) { m->m_pkthdr.csum_flags = CSUM_UDP; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(ulen + IPPROTO_UDP)); th->th_sum = htons(0); UDPSTAT_INC(udps_opackets); } else { m->m_pkthdr.csum_flags = CSUM_TCP; m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(sizeof(struct tcphdr) + IPPROTO_TCP + len + optlen)); } /* IP version must be set here for ipv4/ipv6 checking later */ KASSERT(ip->ip_v == IPVERSION, ("%s: IP version incorrect: %d", __func__, ip->ip_v)); } #endif /* * Enable TSO and specify the size of the segments. * The TCP pseudo header checksum is always provided. */ if (tso) { KASSERT(len > tp->t_maxseg - optlen, ("%s: len <= tso_segsz", __func__)); m->m_pkthdr.csum_flags |= CSUM_TSO; m->m_pkthdr.tso_segsz = tp->t_maxseg - optlen; } KASSERT(len + hdrlen == m_length(m, NULL), ("%s: mbuf chain shorter than expected: %d + %u != %u", __func__, len, hdrlen, m_length(m, NULL))); #ifdef TCP_HHOOK /* Run HHOOK_TCP_ESTABLISHED_OUT helper hooks. */ hhook_run_tcp_est_out(tp, th, &to, len, tso); #endif -#ifdef TCPDEBUG - /* - * Trace. - */ - if (so->so_options & SO_DEBUG) { - u_short save = 0; -#ifdef INET6 - if (!isipv6) -#endif - { - save = ipov->ih_len; - ipov->ih_len = htons(m->m_pkthdr.len /* - hdrlen + (th->th_off << 2) */); - } - tcp_trace(TA_OUTPUT, tp->t_state, tp, mtod(m, void *), th, 0); -#ifdef INET6 - if (!isipv6) -#endif - ipov->ih_len = save; - } -#endif /* TCPDEBUG */ TCP_PROBE3(debug__output, tp, th, m); /* We're getting ready to send; log now. */ /* XXXMT: We are not honoring verbose logging. */ if (tp->t_logstate != TCP_LOG_STATE_OFF) lgb = tcp_log_event_(tp, th, &so->so_rcv, &so->so_snd, TCP_LOG_OUT, ERRNO_UNK, len, NULL, false, NULL, NULL, 0, NULL); else lgb = NULL; /* * Fill in IP length and desired time to live and * send to IP level. There should be a better way * to handle ttl and tos; we could keep them in * the template, but need a way to checksum without them. */ /* * m->m_pkthdr.len should have been set before checksum calculation, * because in6_cksum() need it. */ #ifdef INET6 if (isipv6) { /* * we separately set hoplimit for every segment, since the * user might want to change the value via setsockopt. * Also, desired default hop limit might be changed via * Neighbor Discovery. */ ip6->ip6_hlim = in6_selecthlim(inp, NULL); /* * Set the packet size here for the benefit of DTrace probes. * ip6_output() will set it properly; it's supposed to include * the option header lengths as well. */ ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); if (V_path_mtu_discovery && tp->t_maxseg > V_tcp_minmss) tp->t_flags2 |= TF2_PLPMTU_PMTUD; else tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; if (tp->t_state == TCPS_SYN_SENT) TCP_PROBE5(connect__request, NULL, tp, ip6, tp, th); TCP_PROBE5(send, NULL, tp, ip6, tp, th); #ifdef TCPPCAP /* Save packet, if requested. */ tcp_pcap_add(th, m, &(tp->t_outpkts)); #endif /* TODO: IPv6 IP6TOS_ECT bit on */ error = ip6_output(m, inp->in6p_outputopts, &inp->inp_route6, ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), NULL, NULL, inp); if (error == EMSGSIZE && inp->inp_route6.ro_nh != NULL) mtu = inp->inp_route6.ro_nh->nh_mtu; } #endif /* INET6 */ #if defined(INET) && defined(INET6) else #endif #ifdef INET { ip->ip_len = htons(m->m_pkthdr.len); #ifdef INET6 if (inp->inp_vflag & INP_IPV6PROTO) ip->ip_ttl = in6_selecthlim(inp, NULL); #endif /* INET6 */ /* * If we do path MTU discovery, then we set DF on every packet. * This might not be the best thing to do according to RFC3390 * Section 2. However the tcp hostcache migitates the problem * so it affects only the first tcp connection with a host. * * NB: Don't set DF on small MTU/MSS to have a safe fallback. */ if (V_path_mtu_discovery && tp->t_maxseg > V_tcp_minmss) { tp->t_flags2 |= TF2_PLPMTU_PMTUD; if (tp->t_port == 0 || len < V_tcp_minmss) { ip->ip_off |= htons(IP_DF); } } else { tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; } if (tp->t_state == TCPS_SYN_SENT) TCP_PROBE5(connect__request, NULL, tp, ip, tp, th); TCP_PROBE5(send, NULL, tp, ip, tp, th); #ifdef TCPPCAP /* Save packet, if requested. */ tcp_pcap_add(th, m, &(tp->t_outpkts)); #endif error = ip_output(m, inp->inp_options, &inp->inp_route, ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), 0, inp); if (error == EMSGSIZE && inp->inp_route.ro_nh != NULL) mtu = inp->inp_route.ro_nh->nh_mtu; } #endif /* INET */ if (lgb != NULL) { lgb->tlb_errno = error; lgb = NULL; } out: if (error == 0) tcp_account_for_send(tp, len, (tp->snd_nxt != tp->snd_max), 0, hw_tls); /* * In transmit state, time the transmission and arrange for * the retransmit. In persist state, just set snd_max. */ if ((tp->t_flags & TF_FORCEDATA) == 0 || !tcp_timer_active(tp, TT_PERSIST)) { tcp_seq startseq = tp->snd_nxt; /* * Advance snd_nxt over sequence space of this segment. */ if (flags & (TH_SYN|TH_FIN)) { if (flags & TH_SYN) tp->snd_nxt++; if (flags & TH_FIN) { tp->snd_nxt++; tp->t_flags |= TF_SENTFIN; } } if (sack_rxmit) goto timer; tp->snd_nxt += len; if (SEQ_GT(tp->snd_nxt, tp->snd_max)) { /* * Update "made progress" indication if we just * added new data to an empty socket buffer. */ if (tp->snd_una == tp->snd_max) tp->t_acktime = ticks; tp->snd_max = tp->snd_nxt; /* * Time this transmission if not a retransmission and * not currently timing anything. */ tp->t_sndtime = ticks; if (tp->t_rtttime == 0) { tp->t_rtttime = ticks; tp->t_rtseq = startseq; TCPSTAT_INC(tcps_segstimed); } #ifdef STATS if (!(tp->t_flags & TF_GPUTINPROG) && len) { tp->t_flags |= TF_GPUTINPROG; tp->gput_seq = startseq; tp->gput_ack = startseq + ulmin(sbavail(&so->so_snd) - off, sendwin); tp->gput_ts = tcp_ts_getticks(); } #endif /* STATS */ } /* * Set retransmit timer if not currently set, * and not doing a pure ack or a keep-alive probe. * Initial value for retransmit timer is smoothed * round-trip time + 2 * round-trip time variance. * Initialize shift counter which is used for backoff * of retransmit time. */ timer: if (!tcp_timer_active(tp, TT_REXMT) && ((sack_rxmit && tp->snd_nxt != tp->snd_max) || (tp->snd_nxt != tp->snd_una))) { if (tcp_timer_active(tp, TT_PERSIST)) { tcp_timer_activate(tp, TT_PERSIST, 0); tp->t_rxtshift = 0; } tcp_timer_activate(tp, TT_REXMT, TP_RXTCUR(tp)); } else if (len == 0 && sbavail(&so->so_snd) && !tcp_timer_active(tp, TT_REXMT) && !tcp_timer_active(tp, TT_PERSIST)) { /* * Avoid a situation where we do not set persist timer * after a zero window condition. For example: * 1) A -> B: packet with enough data to fill the window * 2) B -> A: ACK for #1 + new data (0 window * advertisement) * 3) A -> B: ACK for #2, 0 len packet * * In this case, A will not activate the persist timer, * because it chose to send a packet. Unless tcp_output * is called for some other reason (delayed ack timer, * another input packet from B, socket syscall), A will * not send zero window probes. * * So, if you send a 0-length packet, but there is data * in the socket buffer, and neither the rexmt or * persist timer is already set, then activate the * persist timer. */ tp->t_rxtshift = 0; tcp_setpersist(tp); } } else { /* * Persist case, update snd_max but since we are in * persist mode (no window) we do not update snd_nxt. */ int xlen = len; if (flags & TH_SYN) ++xlen; if (flags & TH_FIN) { ++xlen; tp->t_flags |= TF_SENTFIN; } if (SEQ_GT(tp->snd_nxt + xlen, tp->snd_max)) tp->snd_max = tp->snd_nxt + xlen; } if ((error == 0) && (TCPS_HAVEESTABLISHED(tp->t_state) && (tp->t_flags & TF_SACK_PERMIT) && tp->rcv_numsacks > 0)) { /* Clean up any DSACK's sent */ tcp_clean_dsack_blocks(tp); } if (error) { /* * We know that the packet was lost, so back out the * sequence number advance, if any. * * If the error is EPERM the packet got blocked by the * local firewall. Normally we should terminate the * connection but the blocking may have been spurious * due to a firewall reconfiguration cycle. So we treat * it like a packet loss and let the retransmit timer and * timeouts do their work over time. * XXX: It is a POLA question whether calling tcp_drop right * away would be the really correct behavior instead. */ if (((tp->t_flags & TF_FORCEDATA) == 0 || !tcp_timer_active(tp, TT_PERSIST)) && ((flags & TH_SYN) == 0) && (error != EPERM)) { if (sack_rxmit) { p->rxmit -= len; tp->sackhint.sack_bytes_rexmit -= len; KASSERT(tp->sackhint.sack_bytes_rexmit >= 0, ("sackhint bytes rtx >= 0")); KASSERT((flags & TH_FIN) == 0, ("error while FIN with SACK rxmit")); } else { tp->snd_nxt -= len; if (flags & TH_FIN) tp->snd_nxt--; } } SOCKBUF_UNLOCK_ASSERT(&so->so_snd); /* Check gotos. */ switch (error) { case EACCES: case EPERM: tp->t_softerror = error; return (error); case ENOBUFS: TCP_XMIT_TIMER_ASSERT(tp, len, flags); tp->snd_cwnd = tp->t_maxseg; return (0); case EMSGSIZE: /* * For some reason the interface we used initially * to send segments changed to another or lowered * its MTU. * If TSO was active we either got an interface * without TSO capabilits or TSO was turned off. * If we obtained mtu from ip_output() then update * it and try again. */ if (tso) tp->t_flags &= ~TF_TSO; if (mtu != 0) { tcp_mss_update(tp, -1, mtu, NULL, NULL); goto again; } return (error); case EHOSTDOWN: case EHOSTUNREACH: case ENETDOWN: case ENETUNREACH: if (TCPS_HAVERCVDSYN(tp->t_state)) { tp->t_softerror = error; return (0); } /* FALLTHROUGH */ default: return (error); } } TCPSTAT_INC(tcps_sndtotal); /* * Data sent (as far as we can tell). * If this advertises a larger window than any other segment, * then remember the size of the advertised window. * Any pending ACK has now been sent. */ if (SEQ_GT(tp->rcv_nxt + recwin, tp->rcv_adv)) tp->rcv_adv = tp->rcv_nxt + recwin; tp->last_ack_sent = tp->rcv_nxt; tp->t_flags &= ~(TF_ACKNOW | TF_DELACK); if (tcp_timer_active(tp, TT_DELACK)) tcp_timer_activate(tp, TT_DELACK, 0); #if 0 /* * This completely breaks TCP if newreno is turned on. What happens * is that if delayed-acks are turned on on the receiver, this code * on the transmitter effectively destroys the TCP window, forcing * it to four packets (1.5Kx4 = 6K window). */ if (sendalot && --maxburst) goto again; #endif if (sendalot) goto again; return (0); } void tcp_setpersist(struct tcpcb *tp) { int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1; int tt; int maxunacktime; tp->t_flags &= ~TF_PREVVALID; if (tcp_timer_active(tp, TT_REXMT)) panic("tcp_setpersist: retransmit pending"); /* * If the state is already closed, don't bother. */ if (tp->t_state == TCPS_CLOSED) return; /* * Start/restart persistence timer. */ TCPT_RANGESET(tt, t * tcp_backoff[tp->t_rxtshift], tcp_persmin, tcp_persmax); if (TP_MAXUNACKTIME(tp) && tp->t_acktime) { maxunacktime = tp->t_acktime + TP_MAXUNACKTIME(tp) - ticks; if (maxunacktime < 1) maxunacktime = 1; if (maxunacktime < tt) tt = maxunacktime; } tcp_timer_activate(tp, TT_PERSIST, tt); if (tp->t_rxtshift < TCP_MAXRXTSHIFT) tp->t_rxtshift++; } /* * Insert TCP options according to the supplied parameters to the place * optp in a consistent way. Can handle unaligned destinations. * * The order of the option processing is crucial for optimal packing and * alignment for the scarce option space. * * The optimal order for a SYN/SYN-ACK segment is: * MSS (4) + NOP (1) + Window scale (3) + SACK permitted (2) + * Timestamp (10) + Signature (18) = 38 bytes out of a maximum of 40. * * The SACK options should be last. SACK blocks consume 8*n+2 bytes. * So a full size SACK blocks option is 34 bytes (with 4 SACK blocks). * At minimum we need 10 bytes (to generate 1 SACK block). If both * TCP Timestamps (12 bytes) and TCP Signatures (18 bytes) are present, * we only have 10 bytes for SACK options (40 - (12 + 18)). */ int tcp_addoptions(struct tcpopt *to, u_char *optp) { u_int32_t mask, optlen = 0; for (mask = 1; mask < TOF_MAXOPT; mask <<= 1) { if ((to->to_flags & mask) != mask) continue; if (optlen == TCP_MAXOLEN) break; switch (to->to_flags & mask) { case TOF_MSS: while (optlen % 4) { optlen += TCPOLEN_NOP; *optp++ = TCPOPT_NOP; } if (TCP_MAXOLEN - optlen < TCPOLEN_MAXSEG) continue; optlen += TCPOLEN_MAXSEG; *optp++ = TCPOPT_MAXSEG; *optp++ = TCPOLEN_MAXSEG; to->to_mss = htons(to->to_mss); bcopy((u_char *)&to->to_mss, optp, sizeof(to->to_mss)); optp += sizeof(to->to_mss); break; case TOF_SCALE: while (!optlen || optlen % 2 != 1) { optlen += TCPOLEN_NOP; *optp++ = TCPOPT_NOP; } if (TCP_MAXOLEN - optlen < TCPOLEN_WINDOW) continue; optlen += TCPOLEN_WINDOW; *optp++ = TCPOPT_WINDOW; *optp++ = TCPOLEN_WINDOW; *optp++ = to->to_wscale; break; case TOF_SACKPERM: while (optlen % 2) { optlen += TCPOLEN_NOP; *optp++ = TCPOPT_NOP; } if (TCP_MAXOLEN - optlen < TCPOLEN_SACK_PERMITTED) continue; optlen += TCPOLEN_SACK_PERMITTED; *optp++ = TCPOPT_SACK_PERMITTED; *optp++ = TCPOLEN_SACK_PERMITTED; break; case TOF_TS: while (!optlen || optlen % 4 != 2) { optlen += TCPOLEN_NOP; *optp++ = TCPOPT_NOP; } if (TCP_MAXOLEN - optlen < TCPOLEN_TIMESTAMP) continue; optlen += TCPOLEN_TIMESTAMP; *optp++ = TCPOPT_TIMESTAMP; *optp++ = TCPOLEN_TIMESTAMP; to->to_tsval = htonl(to->to_tsval); to->to_tsecr = htonl(to->to_tsecr); bcopy((u_char *)&to->to_tsval, optp, sizeof(to->to_tsval)); optp += sizeof(to->to_tsval); bcopy((u_char *)&to->to_tsecr, optp, sizeof(to->to_tsecr)); optp += sizeof(to->to_tsecr); break; case TOF_SIGNATURE: { int siglen = TCPOLEN_SIGNATURE - 2; while (!optlen || optlen % 4 != 2) { optlen += TCPOLEN_NOP; *optp++ = TCPOPT_NOP; } if (TCP_MAXOLEN - optlen < TCPOLEN_SIGNATURE) { to->to_flags &= ~TOF_SIGNATURE; continue; } optlen += TCPOLEN_SIGNATURE; *optp++ = TCPOPT_SIGNATURE; *optp++ = TCPOLEN_SIGNATURE; to->to_signature = optp; while (siglen--) *optp++ = 0; break; } case TOF_SACK: { int sackblks = 0; struct sackblk *sack = (struct sackblk *)to->to_sacks; tcp_seq sack_seq; while (!optlen || optlen % 4 != 2) { optlen += TCPOLEN_NOP; *optp++ = TCPOPT_NOP; } if (TCP_MAXOLEN - optlen < TCPOLEN_SACKHDR + TCPOLEN_SACK) continue; optlen += TCPOLEN_SACKHDR; *optp++ = TCPOPT_SACK; sackblks = min(to->to_nsacks, (TCP_MAXOLEN - optlen) / TCPOLEN_SACK); *optp++ = TCPOLEN_SACKHDR + sackblks * TCPOLEN_SACK; while (sackblks--) { sack_seq = htonl(sack->start); bcopy((u_char *)&sack_seq, optp, sizeof(sack_seq)); optp += sizeof(sack_seq); sack_seq = htonl(sack->end); bcopy((u_char *)&sack_seq, optp, sizeof(sack_seq)); optp += sizeof(sack_seq); optlen += TCPOLEN_SACK; sack++; } TCPSTAT_INC(tcps_sack_send_blocks); break; } case TOF_FASTOPEN: { int total_len; /* XXX is there any point to aligning this option? */ total_len = TCPOLEN_FAST_OPEN_EMPTY + to->to_tfo_len; if (TCP_MAXOLEN - optlen < total_len) { to->to_flags &= ~TOF_FASTOPEN; continue; } *optp++ = TCPOPT_FAST_OPEN; *optp++ = total_len; if (to->to_tfo_len > 0) { bcopy(to->to_tfo_cookie, optp, to->to_tfo_len); optp += to->to_tfo_len; } optlen += total_len; break; } default: panic("%s: unknown TCP option type", __func__); break; } } /* Terminate and pad TCP options to a 4 byte boundary. */ if (optlen % 4) { optlen += TCPOLEN_EOL; *optp++ = TCPOPT_EOL; } /* * According to RFC 793 (STD0007): * "The content of the header beyond the End-of-Option option * must be header padding (i.e., zero)." * and later: "The padding is composed of zeros." */ while (optlen % 4) { optlen += TCPOLEN_PAD; *optp++ = TCPOPT_PAD; } KASSERT(optlen <= TCP_MAXOLEN, ("%s: TCP options too long", __func__)); return (optlen); } /* * This is a copy of m_copym(), taking the TSO segment size/limit * constraints into account, and advancing the sndptr as it goes. */ struct mbuf * tcp_m_copym(struct mbuf *m, int32_t off0, int32_t *plen, int32_t seglimit, int32_t segsize, struct sockbuf *sb, bool hw_tls) { #ifdef KERN_TLS struct ktls_session *tls, *ntls; struct mbuf *start __diagused; #endif struct mbuf *n, **np; struct mbuf *top; int32_t off = off0; int32_t len = *plen; int32_t fragsize; int32_t len_cp = 0; int32_t *pkthdrlen; uint32_t mlen, frags; bool copyhdr; KASSERT(off >= 0, ("tcp_m_copym, negative off %d", off)); KASSERT(len >= 0, ("tcp_m_copym, negative len %d", len)); if (off == 0 && m->m_flags & M_PKTHDR) copyhdr = true; else copyhdr = false; while (off > 0) { KASSERT(m != NULL, ("tcp_m_copym, offset > size of mbuf chain")); if (off < m->m_len) break; off -= m->m_len; if ((sb) && (m == sb->sb_sndptr)) { sb->sb_sndptroff += m->m_len; sb->sb_sndptr = m->m_next; } m = m->m_next; } np = ⊤ top = NULL; pkthdrlen = NULL; #ifdef KERN_TLS if (hw_tls && (m->m_flags & M_EXTPG)) tls = m->m_epg_tls; else tls = NULL; start = m; #endif while (len > 0) { if (m == NULL) { KASSERT(len == M_COPYALL, ("tcp_m_copym, length > size of mbuf chain")); *plen = len_cp; if (pkthdrlen != NULL) *pkthdrlen = len_cp; break; } #ifdef KERN_TLS if (hw_tls) { if (m->m_flags & M_EXTPG) ntls = m->m_epg_tls; else ntls = NULL; /* * Avoid mixing TLS records with handshake * data or TLS records from different * sessions. */ if (tls != ntls) { MPASS(m != start); *plen = len_cp; if (pkthdrlen != NULL) *pkthdrlen = len_cp; break; } } #endif mlen = min(len, m->m_len - off); if (seglimit) { /* * For M_EXTPG mbufs, add 3 segments * + 1 in case we are crossing page boundaries * + 2 in case the TLS hdr/trailer are used * It is cheaper to just add the segments * than it is to take the cache miss to look * at the mbuf ext_pgs state in detail. */ if (m->m_flags & M_EXTPG) { fragsize = min(segsize, PAGE_SIZE); frags = 3; } else { fragsize = segsize; frags = 0; } /* Break if we really can't fit anymore. */ if ((frags + 1) >= seglimit) { *plen = len_cp; if (pkthdrlen != NULL) *pkthdrlen = len_cp; break; } /* * Reduce size if you can't copy the whole * mbuf. If we can't copy the whole mbuf, also * adjust len so the loop will end after this * mbuf. */ if ((frags + howmany(mlen, fragsize)) >= seglimit) { mlen = (seglimit - frags - 1) * fragsize; len = mlen; *plen = len_cp + len; if (pkthdrlen != NULL) *pkthdrlen = *plen; } frags += howmany(mlen, fragsize); if (frags == 0) frags++; seglimit -= frags; KASSERT(seglimit > 0, ("%s: seglimit went too low", __func__)); } if (copyhdr) n = m_gethdr(M_NOWAIT, m->m_type); else n = m_get(M_NOWAIT, m->m_type); *np = n; if (n == NULL) goto nospace; if (copyhdr) { if (!m_dup_pkthdr(n, m, M_NOWAIT)) goto nospace; if (len == M_COPYALL) n->m_pkthdr.len -= off0; else n->m_pkthdr.len = len; pkthdrlen = &n->m_pkthdr.len; copyhdr = false; } n->m_len = mlen; len_cp += n->m_len; if (m->m_flags & (M_EXT|M_EXTPG)) { n->m_data = m->m_data + off; mb_dupcl(n, m); } else bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t), (u_int)n->m_len); if (sb && (sb->sb_sndptr == m) && ((n->m_len + off) >= m->m_len) && m->m_next) { sb->sb_sndptroff += m->m_len; sb->sb_sndptr = m->m_next; } off = 0; if (len != M_COPYALL) { len -= n->m_len; } m = m->m_next; np = &n->m_next; } return (top); nospace: m_freem(top); return (NULL); } void tcp_sndbuf_autoscale(struct tcpcb *tp, struct socket *so, uint32_t sendwin) { /* * Automatic sizing of send socket buffer. Often the send buffer * size is not optimally adjusted to the actual network conditions * at hand (delay bandwidth product). Setting the buffer size too * small limits throughput on links with high bandwidth and high * delay (eg. trans-continental/oceanic links). Setting the * buffer size too big consumes too much real kernel memory, * especially with many connections on busy servers. * * The criteria to step up the send buffer one notch are: * 1. receive window of remote host is larger than send buffer * (with a fudge factor of 5/4th); * 2. send buffer is filled to 7/8th with data (so we actually * have data to make use of it); * 3. send buffer fill has not hit maximal automatic size; * 4. our send window (slow start and cogestion controlled) is * larger than sent but unacknowledged data in send buffer. * * The remote host receive window scaling factor may limit the * growing of the send buffer before it reaches its allowed * maximum. * * It scales directly with slow start or congestion window * and does at most one step per received ACK. This fast * scaling has the drawback of growing the send buffer beyond * what is strictly necessary to make full use of a given * delay*bandwidth product. However testing has shown this not * to be much of an problem. At worst we are trading wasting * of available bandwidth (the non-use of it) for wasting some * socket buffer memory. * * TODO: Shrink send buffer during idle periods together * with congestion window. Requires another timer. Has to * wait for upcoming tcp timer rewrite. * * XXXGL: should there be used sbused() or sbavail()? */ if (V_tcp_do_autosndbuf && so->so_snd.sb_flags & SB_AUTOSIZE) { int lowat; lowat = V_tcp_sendbuf_auto_lowat ? so->so_snd.sb_lowat : 0; if ((tp->snd_wnd / 4 * 5) >= so->so_snd.sb_hiwat - lowat && sbused(&so->so_snd) >= (so->so_snd.sb_hiwat / 8 * 7) - lowat && sbused(&so->so_snd) < V_tcp_autosndbuf_max && sendwin >= (sbused(&so->so_snd) - (tp->snd_nxt - tp->snd_una))) { if (!sbreserve_locked(so, SO_SND, min(so->so_snd.sb_hiwat + V_tcp_autosndbuf_inc, V_tcp_autosndbuf_max), curthread)) so->so_snd.sb_flags &= ~SB_AUTOSIZE; } } } diff --git a/sys/netinet/tcp_ratelimit.c b/sys/netinet/tcp_ratelimit.c index f6567d159b36..dc207d10311c 100644 --- a/sys/netinet/tcp_ratelimit.c +++ b/sys/netinet/tcp_ratelimit.c @@ -1,1765 +1,1764 @@ /*- * * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 2018-2020 * Netflix Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * */ /** * Author: Randall Stewart */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" -#include "opt_tcpdebug.h" #include "opt_ratelimit.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define TCPSTATES /* for logging */ #include #include #include #include #ifndef USECS_IN_SECOND #define USECS_IN_SECOND 1000000 #endif /* * For the purposes of each send, what is the size * of an ethernet frame. */ MALLOC_DEFINE(M_TCPPACE, "tcp_hwpace", "TCP Hardware pacing memory"); #ifdef RATELIMIT /* * The following preferred table will seem weird to * the casual viewer. Why do we not have any rates below * 1Mbps? Why do we have a rate at 1.44Mbps called common? * Why do the rates cluster in the 1-100Mbps range more * than others? Why does the table jump around at the beginnign * and then be more consistently raising? * * Let me try to answer those questions. A lot of * this is dependant on the hardware. We have three basic * supporters of rate limiting * * Chelsio - Supporting 16 configurable rates. * Mlx - c4 supporting 13 fixed rates. * Mlx - c5 & c6 supporting 127 configurable rates. * * The c4 is why we have a common rate that is available * in all rate tables. This is a selected rate from the * c4 table and we assure its available in all ratelimit * tables. This way the tcp_ratelimit code has an assured * rate it should always be able to get. This answers a * couple of the questions above. * * So what about the rest, well the table is built to * try to get the most out of a joint hardware/software * pacing system. The software pacer will always pick * a rate higher than the b/w that it is estimating * * on the path. This is done for two reasons. * a) So we can discover more b/w * and * b) So we can send a block of MSS's down and then * have the software timer go off after the previous * send is completely out of the hardware. * * But when we do we don't want to have the delay * between the last packet sent by the hardware be * excessively long (to reach our desired rate). * * So let me give an example for clarity. * * Lets assume that the tcp stack sees that 29,110,000 bps is * what the bw of the path is. The stack would select the * rate 31Mbps. 31Mbps means that each send that is done * by the hardware will cause a 390 micro-second gap between * the packets sent at that rate. For 29,110,000 bps we * would need 416 micro-seconds gap between each send. * * Note that are calculating a complete time for pacing * which includes the ethernet, IP and TCP overhead. So * a full 1514 bytes is used for the above calculations. * My testing has shown that both cards are also using this * as their basis i.e. full payload size of the ethernet frame. * The TCP stack caller needs to be aware of this and make the * appropriate overhead calculations be included in its choices. * * Now, continuing our example, we pick a MSS size based on the * delta between the two rates (416 - 390) divided into the rate * we really wish to send at rounded up. That results in a MSS * send of 17 mss's at once. The hardware then will * run out of data in a single 17MSS send in 6,630 micro-seconds. * * On the other hand the software pacer will send more data * in 7,072 micro-seconds. This means that we will refill * the hardware 52 microseconds after it would have sent * next if it had not ran out of data. This is a win since we are * only sending every 7ms or so and yet all the packets are spaced on * the wire with 94% of what they should be and only * the last packet is delayed extra to make up for the * difference. * * Note that the above formula has two important caveat. * If we are above (b/w wise) over 100Mbps we double the result * of the MSS calculation. The second caveat is if we are 500Mbps * or more we just send the maximum MSS at once i.e. 45MSS. At * the higher b/w's even the cards have limits to what times (timer granularity) * they can insert between packets and start to send more than one * packet at a time on the wire. * */ #define COMMON_RATE 180500 const uint64_t desired_rates[] = { 122500, /* 1Mbps - rate 1 */ 180500, /* 1.44Mpbs - rate 2 common rate */ 375000, /* 3Mbps - rate 3 */ 625000, /* 5Mbps - rate 4 */ 1250000, /* 10Mbps - rate 5 */ 1875000, /* 15Mbps - rate 6 */ 2500000, /* 20Mbps - rate 7 */ 3125000, /* 25Mbps - rate 8 */ 3750000, /* 30Mbps - rate 9 */ 4375000, /* 35Mbps - rate 10 */ 5000000, /* 40Meg - rate 11 */ 6250000, /* 50Mbps - rate 12 */ 12500000, /* 100Mbps - rate 13 */ 25000000, /* 200Mbps - rate 14 */ 50000000, /* 400Mbps - rate 15 */ 100000000, /* 800Mbps - rate 16 */ 5625000, /* 45Mbps - rate 17 */ 6875000, /* 55Mbps - rate 19 */ 7500000, /* 60Mbps - rate 20 */ 8125000, /* 65Mbps - rate 21 */ 8750000, /* 70Mbps - rate 22 */ 9375000, /* 75Mbps - rate 23 */ 10000000, /* 80Mbps - rate 24 */ 10625000, /* 85Mbps - rate 25 */ 11250000, /* 90Mbps - rate 26 */ 11875000, /* 95Mbps - rate 27 */ 12500000, /* 100Mbps - rate 28 */ 13750000, /* 110Mbps - rate 29 */ 15000000, /* 120Mbps - rate 30 */ 16250000, /* 130Mbps - rate 31 */ 17500000, /* 140Mbps - rate 32 */ 18750000, /* 150Mbps - rate 33 */ 20000000, /* 160Mbps - rate 34 */ 21250000, /* 170Mbps - rate 35 */ 22500000, /* 180Mbps - rate 36 */ 23750000, /* 190Mbps - rate 37 */ 26250000, /* 210Mbps - rate 38 */ 27500000, /* 220Mbps - rate 39 */ 28750000, /* 230Mbps - rate 40 */ 30000000, /* 240Mbps - rate 41 */ 31250000, /* 250Mbps - rate 42 */ 34375000, /* 275Mbps - rate 43 */ 37500000, /* 300Mbps - rate 44 */ 40625000, /* 325Mbps - rate 45 */ 43750000, /* 350Mbps - rate 46 */ 46875000, /* 375Mbps - rate 47 */ 53125000, /* 425Mbps - rate 48 */ 56250000, /* 450Mbps - rate 49 */ 59375000, /* 475Mbps - rate 50 */ 62500000, /* 500Mbps - rate 51 */ 68750000, /* 550Mbps - rate 52 */ 75000000, /* 600Mbps - rate 53 */ 81250000, /* 650Mbps - rate 54 */ 87500000, /* 700Mbps - rate 55 */ 93750000, /* 750Mbps - rate 56 */ 106250000, /* 850Mbps - rate 57 */ 112500000, /* 900Mbps - rate 58 */ 125000000, /* 1Gbps - rate 59 */ 156250000, /* 1.25Gps - rate 60 */ 187500000, /* 1.5Gps - rate 61 */ 218750000, /* 1.75Gps - rate 62 */ 250000000, /* 2Gbps - rate 63 */ 281250000, /* 2.25Gps - rate 64 */ 312500000, /* 2.5Gbps - rate 65 */ 343750000, /* 2.75Gbps - rate 66 */ 375000000, /* 3Gbps - rate 67 */ 500000000, /* 4Gbps - rate 68 */ 625000000, /* 5Gbps - rate 69 */ 750000000, /* 6Gbps - rate 70 */ 875000000, /* 7Gbps - rate 71 */ 1000000000, /* 8Gbps - rate 72 */ 1125000000, /* 9Gbps - rate 73 */ 1250000000, /* 10Gbps - rate 74 */ 1875000000, /* 15Gbps - rate 75 */ 2500000000 /* 20Gbps - rate 76 */ }; #define MAX_HDWR_RATES (sizeof(desired_rates)/sizeof(uint64_t)) #define RS_ORDERED_COUNT 16 /* * Number that are in order * at the beginning of the table, * over this a sort is required. */ #define RS_NEXT_ORDER_GROUP 16 /* * The point in our table where * we come fill in a second ordered * group (index wise means -1). */ #define ALL_HARDWARE_RATES 1004 /* * 1Meg - 1Gig in 1 Meg steps * plus 100, 200k and 500k and * 10Gig */ #define RS_ONE_MEGABIT_PERSEC 1000000 #define RS_ONE_GIGABIT_PERSEC 1000000000 #define RS_TEN_GIGABIT_PERSEC 10000000000 static struct head_tcp_rate_set int_rs; static struct mtx rs_mtx; uint32_t rs_number_alive; uint32_t rs_number_dead; static uint32_t rs_floor_mss = 0; static uint32_t wait_time_floor = 8000; /* 8 ms */ static uint32_t rs_hw_floor_mss = 16; static uint32_t num_of_waits_allowed = 1; /* How many time blocks are we willing to wait */ SYSCTL_NODE(_net_inet_tcp, OID_AUTO, rl, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "TCP Ratelimit stats"); SYSCTL_UINT(_net_inet_tcp_rl, OID_AUTO, alive, CTLFLAG_RW, &rs_number_alive, 0, "Number of interfaces initialized for ratelimiting"); SYSCTL_UINT(_net_inet_tcp_rl, OID_AUTO, dead, CTLFLAG_RW, &rs_number_dead, 0, "Number of interfaces departing from ratelimiting"); SYSCTL_UINT(_net_inet_tcp_rl, OID_AUTO, floor_mss, CTLFLAG_RW, &rs_floor_mss, 0, "Number of MSS that will override the normal minimums (0 means don't enforce)"); SYSCTL_UINT(_net_inet_tcp_rl, OID_AUTO, wait_floor, CTLFLAG_RW, &wait_time_floor, 2000, "Has b/w increases what is the wait floor we are willing to wait at the end?"); SYSCTL_UINT(_net_inet_tcp_rl, OID_AUTO, time_blocks, CTLFLAG_RW, &num_of_waits_allowed, 1, "How many time blocks on the end should software pacing be willing to wait?"); SYSCTL_UINT(_net_inet_tcp_rl, OID_AUTO, hw_floor_mss, CTLFLAG_RW, &rs_hw_floor_mss, 16, "Number of mss that are a minum for hardware pacing?"); static void rl_add_syctl_entries(struct sysctl_oid *rl_sysctl_root, struct tcp_rate_set *rs) { /* * Add sysctl entries for thus interface. */ if (rs->rs_flags & RS_INTF_NO_SUP) { SYSCTL_ADD_S32(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_sysctl_root), OID_AUTO, "disable", CTLFLAG_RD, &rs->rs_disable, 0, "Disable this interface from new hdwr limiting?"); } else { SYSCTL_ADD_S32(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_sysctl_root), OID_AUTO, "disable", CTLFLAG_RW, &rs->rs_disable, 0, "Disable this interface from new hdwr limiting?"); } SYSCTL_ADD_S32(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_sysctl_root), OID_AUTO, "minseg", CTLFLAG_RW, &rs->rs_min_seg, 0, "What is the minimum we need to send on this interface?"); SYSCTL_ADD_U64(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_sysctl_root), OID_AUTO, "flow_limit", CTLFLAG_RW, &rs->rs_flow_limit, 0, "What is the limit for number of flows (0=unlimited)?"); SYSCTL_ADD_S32(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_sysctl_root), OID_AUTO, "highest", CTLFLAG_RD, &rs->rs_highest_valid, 0, "Highest valid rate"); SYSCTL_ADD_S32(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_sysctl_root), OID_AUTO, "lowest", CTLFLAG_RD, &rs->rs_lowest_valid, 0, "Lowest valid rate"); SYSCTL_ADD_S32(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_sysctl_root), OID_AUTO, "flags", CTLFLAG_RD, &rs->rs_flags, 0, "What lags are on the entry?"); SYSCTL_ADD_S32(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_sysctl_root), OID_AUTO, "numrates", CTLFLAG_RD, &rs->rs_rate_cnt, 0, "How many rates re there?"); SYSCTL_ADD_U64(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_sysctl_root), OID_AUTO, "flows_using", CTLFLAG_RD, &rs->rs_flows_using, 0, "How many flows are using this interface now?"); #ifdef DETAILED_RATELIMIT_SYSCTL if (rs->rs_rlt && rs->rs_rate_cnt > 0) { /* Lets display the rates */ int i; struct sysctl_oid *rl_rates; struct sysctl_oid *rl_rate_num; char rate_num[16]; rl_rates = SYSCTL_ADD_NODE(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_sysctl_root), OID_AUTO, "rate", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Ratelist"); for( i = 0; i < rs->rs_rate_cnt; i++) { sprintf(rate_num, "%d", i); rl_rate_num = SYSCTL_ADD_NODE(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_rates), OID_AUTO, rate_num, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Individual Rate"); SYSCTL_ADD_U32(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_rate_num), OID_AUTO, "flags", CTLFLAG_RD, &rs->rs_rlt[i].flags, 0, "Flags on this rate"); SYSCTL_ADD_U32(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_rate_num), OID_AUTO, "pacetime", CTLFLAG_RD, &rs->rs_rlt[i].time_between, 0, "Time hardware inserts between 1500 byte sends"); SYSCTL_ADD_LONG(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_rate_num), OID_AUTO, "rate", CTLFLAG_RD, &rs->rs_rlt[i].rate, "Rate in bytes per second"); SYSCTL_ADD_LONG(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_rate_num), OID_AUTO, "using", CTLFLAG_RD, &rs->rs_rlt[i].using, "Number of flows using"); SYSCTL_ADD_LONG(&rs->sysctl_ctx, SYSCTL_CHILDREN(rl_rate_num), OID_AUTO, "enobufs", CTLFLAG_RD, &rs->rs_rlt[i].rs_num_enobufs, "Number of enobufs logged on this rate"); } } #endif } static void rs_destroy(epoch_context_t ctx) { struct tcp_rate_set *rs; bool do_free_rs; rs = __containerof(ctx, struct tcp_rate_set, rs_epoch_ctx); mtx_lock(&rs_mtx); rs->rs_flags &= ~RS_FUNERAL_SCHD; /* * In theory its possible (but unlikely) * that while the delete was occuring * and we were applying the DEAD flag * someone slipped in and found the * interface in a lookup. While we * decided rs_flows_using were 0 and * scheduling the epoch_call, the other * thread incremented rs_flow_using. This * is because users have a pointer and * we only use the rs_flows_using in an * atomic fashion, i.e. the other entities * are not protected. To assure this did * not occur, we check rs_flows_using here * before deleting. */ do_free_rs = (rs->rs_flows_using == 0); rs_number_dead--; mtx_unlock(&rs_mtx); if (do_free_rs) { sysctl_ctx_free(&rs->sysctl_ctx); free(rs->rs_rlt, M_TCPPACE); free(rs, M_TCPPACE); } } static void rs_defer_destroy(struct tcp_rate_set *rs) { mtx_assert(&rs_mtx, MA_OWNED); /* Check if already pending. */ if (rs->rs_flags & RS_FUNERAL_SCHD) return; rs_number_dead++; /* Set flag to only defer once. */ rs->rs_flags |= RS_FUNERAL_SCHD; NET_EPOCH_CALL(rs_destroy, &rs->rs_epoch_ctx); } #ifdef INET extern counter_u64_t rate_limit_new; extern counter_u64_t rate_limit_chg; extern counter_u64_t rate_limit_set_ok; extern counter_u64_t rate_limit_active; extern counter_u64_t rate_limit_alloc_fail; #endif static int rl_attach_txrtlmt(struct ifnet *ifp, uint32_t flowtype, int flowid, uint64_t cfg_rate, struct m_snd_tag **tag) { int error; union if_snd_tag_alloc_params params = { .rate_limit.hdr.type = IF_SND_TAG_TYPE_RATE_LIMIT, .rate_limit.hdr.flowid = flowid, .rate_limit.hdr.flowtype = flowtype, .rate_limit.max_rate = cfg_rate, .rate_limit.flags = M_NOWAIT, }; error = m_snd_tag_alloc(ifp, ¶ms, tag); #ifdef INET if (error == 0) { counter_u64_add(rate_limit_set_ok, 1); counter_u64_add(rate_limit_active, 1); } else if (error != EOPNOTSUPP) counter_u64_add(rate_limit_alloc_fail, 1); #endif return (error); } static void populate_canned_table(struct tcp_rate_set *rs, const uint64_t *rate_table_act) { /* * The internal table is "special", it * is two seperate ordered tables that * must be merged. We get here when the * adapter specifies a number of rates that * covers both ranges in the table in some * form. */ int i, at_low, at_high; uint8_t low_disabled = 0, high_disabled = 0; for(i = 0, at_low = 0, at_high = RS_NEXT_ORDER_GROUP; i < rs->rs_rate_cnt; i++) { rs->rs_rlt[i].flags = 0; rs->rs_rlt[i].time_between = 0; if ((low_disabled == 0) && (high_disabled || (rate_table_act[at_low] < rate_table_act[at_high]))) { rs->rs_rlt[i].rate = rate_table_act[at_low]; at_low++; if (at_low == RS_NEXT_ORDER_GROUP) low_disabled = 1; } else if (high_disabled == 0) { rs->rs_rlt[i].rate = rate_table_act[at_high]; at_high++; if (at_high == MAX_HDWR_RATES) high_disabled = 1; } } } static struct tcp_rate_set * rt_setup_new_rs(struct ifnet *ifp, int *error) { struct tcp_rate_set *rs; const uint64_t *rate_table_act; uint64_t lentim, res; size_t sz; uint32_t hash_type; int i; struct if_ratelimit_query_results rl; struct sysctl_oid *rl_sysctl_root; struct epoch_tracker et; /* * We expect to enter with the * mutex locked. */ if (ifp->if_ratelimit_query == NULL) { /* * We can do nothing if we cannot * get a query back from the driver. */ printf("Warning:No query functions for %s:%d-- failed\n", ifp->if_dname, ifp->if_dunit); return (NULL); } rs = malloc(sizeof(struct tcp_rate_set), M_TCPPACE, M_NOWAIT | M_ZERO); if (rs == NULL) { if (error) *error = ENOMEM; printf("Warning:No memory for malloc of tcp_rate_set\n"); return (NULL); } memset(&rl, 0, sizeof(rl)); rl.flags = RT_NOSUPPORT; ifp->if_ratelimit_query(ifp, &rl); if (rl.flags & RT_IS_UNUSABLE) { /* * The interface does not really support * the rate-limiting. */ memset(rs, 0, sizeof(struct tcp_rate_set)); rs->rs_ifp = ifp; rs->rs_if_dunit = ifp->if_dunit; rs->rs_flags = RS_INTF_NO_SUP; rs->rs_disable = 1; rs_number_alive++; sysctl_ctx_init(&rs->sysctl_ctx); rl_sysctl_root = SYSCTL_ADD_NODE(&rs->sysctl_ctx, SYSCTL_STATIC_CHILDREN(_net_inet_tcp_rl), OID_AUTO, rs->rs_ifp->if_xname, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, ""); rl_add_syctl_entries(rl_sysctl_root, rs); NET_EPOCH_ENTER(et); mtx_lock(&rs_mtx); CK_LIST_INSERT_HEAD(&int_rs, rs, next); mtx_unlock(&rs_mtx); NET_EPOCH_EXIT(et); return (rs); } else if ((rl.flags & RT_IS_INDIRECT) == RT_IS_INDIRECT) { memset(rs, 0, sizeof(struct tcp_rate_set)); rs->rs_ifp = ifp; rs->rs_if_dunit = ifp->if_dunit; rs->rs_flags = RS_IS_DEFF; rs_number_alive++; sysctl_ctx_init(&rs->sysctl_ctx); rl_sysctl_root = SYSCTL_ADD_NODE(&rs->sysctl_ctx, SYSCTL_STATIC_CHILDREN(_net_inet_tcp_rl), OID_AUTO, rs->rs_ifp->if_xname, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, ""); rl_add_syctl_entries(rl_sysctl_root, rs); NET_EPOCH_ENTER(et); mtx_lock(&rs_mtx); CK_LIST_INSERT_HEAD(&int_rs, rs, next); mtx_unlock(&rs_mtx); NET_EPOCH_EXIT(et); return (rs); } else if ((rl.flags & RT_IS_FIXED_TABLE) == RT_IS_FIXED_TABLE) { /* Mellanox C4 likely */ rs->rs_ifp = ifp; rs->rs_if_dunit = ifp->if_dunit; rs->rs_rate_cnt = rl.number_of_rates; rs->rs_min_seg = rl.min_segment_burst; rs->rs_highest_valid = 0; rs->rs_flow_limit = rl.max_flows; rs->rs_flags = RS_IS_INTF | RS_NO_PRE; rs->rs_disable = 0; rate_table_act = rl.rate_table; } else if ((rl.flags & RT_IS_SELECTABLE) == RT_IS_SELECTABLE) { /* Chelsio, C5 and C6 of Mellanox? */ rs->rs_ifp = ifp; rs->rs_if_dunit = ifp->if_dunit; rs->rs_rate_cnt = rl.number_of_rates; rs->rs_min_seg = rl.min_segment_burst; rs->rs_disable = 0; rs->rs_flow_limit = rl.max_flows; rate_table_act = desired_rates; if ((rs->rs_rate_cnt > MAX_HDWR_RATES) && (rs->rs_rate_cnt < ALL_HARDWARE_RATES)) { /* * Our desired table is not big * enough, do what we can. */ rs->rs_rate_cnt = MAX_HDWR_RATES; } if (rs->rs_rate_cnt <= RS_ORDERED_COUNT) rs->rs_flags = RS_IS_INTF; else rs->rs_flags = RS_IS_INTF | RS_INT_TBL; if (rs->rs_rate_cnt >= ALL_HARDWARE_RATES) rs->rs_rate_cnt = ALL_HARDWARE_RATES; } else { free(rs, M_TCPPACE); return (NULL); } sz = sizeof(struct tcp_hwrate_limit_table) * rs->rs_rate_cnt; rs->rs_rlt = malloc(sz, M_TCPPACE, M_NOWAIT); if (rs->rs_rlt == NULL) { if (error) *error = ENOMEM; bail: free(rs, M_TCPPACE); return (NULL); } if (rs->rs_rate_cnt >= ALL_HARDWARE_RATES) { /* * The interface supports all * the rates we could possibly want. */ uint64_t rat; rs->rs_rlt[0].rate = 12500; /* 100k */ rs->rs_rlt[1].rate = 25000; /* 200k */ rs->rs_rlt[2].rate = 62500; /* 500k */ /* Note 125000 == 1Megabit * populate 1Meg - 1000meg. */ for(i = 3, rat = 125000; i< (ALL_HARDWARE_RATES-1); i++) { rs->rs_rlt[i].rate = rat; rat += 125000; } rs->rs_rlt[(ALL_HARDWARE_RATES-1)].rate = 1250000000; } else if (rs->rs_flags & RS_INT_TBL) { /* We populate this in a special way */ populate_canned_table(rs, rate_table_act); } else { /* * Just copy in the rates from * the table, it is in order. */ for (i=0; irs_rate_cnt; i++) { rs->rs_rlt[i].rate = rate_table_act[i]; rs->rs_rlt[i].time_between = 0; rs->rs_rlt[i].flags = 0; } } for (i = (rs->rs_rate_cnt - 1); i >= 0; i--) { /* * We go backwards through the list so that if we can't get * a rate and fail to init one, we have at least a chance of * getting the highest one. */ rs->rs_rlt[i].ptbl = rs; rs->rs_rlt[i].tag = NULL; rs->rs_rlt[i].using = 0; rs->rs_rlt[i].rs_num_enobufs = 0; /* * Calculate the time between. */ lentim = ETHERNET_SEGMENT_SIZE * USECS_IN_SECOND; res = lentim / rs->rs_rlt[i].rate; if (res > 0) rs->rs_rlt[i].time_between = res; else rs->rs_rlt[i].time_between = 1; if (rs->rs_flags & RS_NO_PRE) { rs->rs_rlt[i].flags = HDWRPACE_INITED; rs->rs_lowest_valid = i; } else { int err; if ((rl.flags & RT_IS_SETUP_REQ) && (ifp->if_ratelimit_query)) { err = ifp->if_ratelimit_setup(ifp, rs->rs_rlt[i].rate, i); if (err) goto handle_err; } #ifdef RSS hash_type = M_HASHTYPE_RSS_TCP_IPV4; #else hash_type = M_HASHTYPE_OPAQUE_HASH; #endif err = rl_attach_txrtlmt(ifp, hash_type, (i + 1), rs->rs_rlt[i].rate, &rs->rs_rlt[i].tag); if (err) { handle_err: if (i == (rs->rs_rate_cnt - 1)) { /* * Huh - first rate and we can't get * it? */ free(rs->rs_rlt, M_TCPPACE); if (error) *error = err; goto bail; } else { if (error) *error = err; } break; } else { rs->rs_rlt[i].flags = HDWRPACE_INITED | HDWRPACE_TAGPRESENT; rs->rs_lowest_valid = i; } } } /* Did we get at least 1 rate? */ if (rs->rs_rlt[(rs->rs_rate_cnt - 1)].flags & HDWRPACE_INITED) rs->rs_highest_valid = rs->rs_rate_cnt - 1; else { free(rs->rs_rlt, M_TCPPACE); goto bail; } rs_number_alive++; sysctl_ctx_init(&rs->sysctl_ctx); rl_sysctl_root = SYSCTL_ADD_NODE(&rs->sysctl_ctx, SYSCTL_STATIC_CHILDREN(_net_inet_tcp_rl), OID_AUTO, rs->rs_ifp->if_xname, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, ""); rl_add_syctl_entries(rl_sysctl_root, rs); NET_EPOCH_ENTER(et); mtx_lock(&rs_mtx); CK_LIST_INSERT_HEAD(&int_rs, rs, next); mtx_unlock(&rs_mtx); NET_EPOCH_EXIT(et); return (rs); } /* * For an explanation of why the argument is volatile please * look at the comments around rt_setup_rate(). */ static const struct tcp_hwrate_limit_table * tcp_int_find_suitable_rate(const volatile struct tcp_rate_set *rs, uint64_t bytes_per_sec, uint32_t flags, uint64_t *lower_rate) { struct tcp_hwrate_limit_table *arte = NULL, *rte = NULL; uint64_t mbits_per_sec, ind_calc, previous_rate = 0; int i; mbits_per_sec = (bytes_per_sec * 8); if (flags & RS_PACING_LT) { if ((mbits_per_sec < RS_ONE_MEGABIT_PERSEC) && (rs->rs_lowest_valid <= 2)){ /* * Smaller than 1Meg, only * 3 entries can match it. */ previous_rate = 0; for(i = rs->rs_lowest_valid; i < 3; i++) { if (bytes_per_sec <= rs->rs_rlt[i].rate) { rte = &rs->rs_rlt[i]; break; } else if (rs->rs_rlt[i].flags & HDWRPACE_INITED) { arte = &rs->rs_rlt[i]; } previous_rate = rs->rs_rlt[i].rate; } goto done; } else if ((mbits_per_sec > RS_ONE_GIGABIT_PERSEC) && (rs->rs_rlt[(ALL_HARDWARE_RATES-1)].flags & HDWRPACE_INITED)){ /* * Larger than 1G (the majority of * our table. */ if (mbits_per_sec < RS_TEN_GIGABIT_PERSEC) rte = &rs->rs_rlt[(ALL_HARDWARE_RATES-1)]; else arte = &rs->rs_rlt[(ALL_HARDWARE_RATES-1)]; previous_rate = rs->rs_rlt[(ALL_HARDWARE_RATES-2)].rate; goto done; } /* * If we reach here its in our table (between 1Meg - 1000Meg), * just take the rounded down mbits per second, and add * 1Megabit to it, from this we can calculate * the index in the table. */ ind_calc = mbits_per_sec/RS_ONE_MEGABIT_PERSEC; if ((ind_calc * RS_ONE_MEGABIT_PERSEC) != mbits_per_sec) ind_calc++; /* our table is offset by 3, we add 2 */ ind_calc += 2; if (ind_calc > (ALL_HARDWARE_RATES-1)) { /* This should not happen */ ind_calc = ALL_HARDWARE_RATES-1; } if ((ind_calc >= rs->rs_lowest_valid) && (ind_calc <= rs->rs_highest_valid)) { rte = &rs->rs_rlt[ind_calc]; if (ind_calc >= 1) previous_rate = rs->rs_rlt[(ind_calc-1)].rate; } } else if (flags & RS_PACING_EXACT_MATCH) { if ((mbits_per_sec < RS_ONE_MEGABIT_PERSEC) && (rs->rs_lowest_valid <= 2)){ for(i = rs->rs_lowest_valid; i < 3; i++) { if (bytes_per_sec == rs->rs_rlt[i].rate) { rte = &rs->rs_rlt[i]; break; } } } else if ((mbits_per_sec > RS_ONE_GIGABIT_PERSEC) && (rs->rs_rlt[(ALL_HARDWARE_RATES-1)].flags & HDWRPACE_INITED)) { /* > 1Gbps only one rate */ if (bytes_per_sec == rs->rs_rlt[(ALL_HARDWARE_RATES-1)].rate) { /* Its 10G wow */ rte = &rs->rs_rlt[(ALL_HARDWARE_RATES-1)]; } } else { /* Ok it must be a exact meg (its between 1G and 1Meg) */ ind_calc = mbits_per_sec/RS_ONE_MEGABIT_PERSEC; if ((ind_calc * RS_ONE_MEGABIT_PERSEC) == mbits_per_sec) { /* its an exact Mbps */ ind_calc += 2; if (ind_calc > (ALL_HARDWARE_RATES-1)) { /* This should not happen */ ind_calc = ALL_HARDWARE_RATES-1; } if (rs->rs_rlt[ind_calc].flags & HDWRPACE_INITED) rte = &rs->rs_rlt[ind_calc]; } } } else { /* we want greater than the requested rate */ if ((mbits_per_sec < RS_ONE_MEGABIT_PERSEC) && (rs->rs_lowest_valid <= 2)){ arte = &rs->rs_rlt[3]; /* set alternate to 1Meg */ for (i=2; i>=rs->rs_lowest_valid; i--) { if (bytes_per_sec < rs->rs_rlt[i].rate) { rte = &rs->rs_rlt[i]; if (i >= 1) { previous_rate = rs->rs_rlt[(i-1)].rate; } break; } else if ((flags & RS_PACING_GEQ) && (bytes_per_sec == rs->rs_rlt[i].rate)) { rte = &rs->rs_rlt[i]; if (i >= 1) { previous_rate = rs->rs_rlt[(i-1)].rate; } break; } else { arte = &rs->rs_rlt[i]; /* new alternate */ } } } else if (mbits_per_sec > RS_ONE_GIGABIT_PERSEC) { if ((bytes_per_sec < rs->rs_rlt[(ALL_HARDWARE_RATES-1)].rate) && (rs->rs_rlt[(ALL_HARDWARE_RATES-1)].flags & HDWRPACE_INITED)){ /* Our top rate is larger than the request */ rte = &rs->rs_rlt[(ALL_HARDWARE_RATES-1)]; } else if ((flags & RS_PACING_GEQ) && (bytes_per_sec == rs->rs_rlt[(ALL_HARDWARE_RATES-1)].rate) && (rs->rs_rlt[(ALL_HARDWARE_RATES-1)].flags & HDWRPACE_INITED)) { /* It matches our top rate */ rte = &rs->rs_rlt[(ALL_HARDWARE_RATES-1)]; } else if (rs->rs_rlt[(ALL_HARDWARE_RATES-1)].flags & HDWRPACE_INITED) { /* The top rate is an alternative */ arte = &rs->rs_rlt[(ALL_HARDWARE_RATES-1)]; } previous_rate = rs->rs_rlt[(ALL_HARDWARE_RATES-2)].rate; } else { /* Its in our range 1Meg - 1Gig */ if (flags & RS_PACING_GEQ) { ind_calc = mbits_per_sec/RS_ONE_MEGABIT_PERSEC; if ((ind_calc * RS_ONE_MEGABIT_PERSEC) == mbits_per_sec) { if (ind_calc > (ALL_HARDWARE_RATES-1)) { /* This should not happen */ ind_calc = (ALL_HARDWARE_RATES-1); } rte = &rs->rs_rlt[ind_calc]; if (ind_calc >= 1) previous_rate = rs->rs_rlt[(ind_calc-1)].rate; } goto done; } ind_calc = (mbits_per_sec + (RS_ONE_MEGABIT_PERSEC-1))/RS_ONE_MEGABIT_PERSEC; ind_calc += 2; if (ind_calc > (ALL_HARDWARE_RATES-1)) { /* This should not happen */ ind_calc = ALL_HARDWARE_RATES-1; } if (rs->rs_rlt[ind_calc].flags & HDWRPACE_INITED) { rte = &rs->rs_rlt[ind_calc]; if (ind_calc >= 1) previous_rate = rs->rs_rlt[(ind_calc-1)].rate; } } } done: if ((rte == NULL) && (arte != NULL) && (flags & RS_PACING_SUB_OK)) { /* We can use the substitute */ rte = arte; } if (lower_rate) *lower_rate = previous_rate; return (rte); } /* * For an explanation of why the argument is volatile please * look at the comments around rt_setup_rate(). */ static const struct tcp_hwrate_limit_table * tcp_find_suitable_rate(const volatile struct tcp_rate_set *rs, uint64_t bytes_per_sec, uint32_t flags, uint64_t *lower_rate) { /** * Hunt the rate table with the restrictions in flags and find a * suitable rate if possible. * RS_PACING_EXACT_MATCH - look for an exact match to rate. * RS_PACING_GT - must be greater than. * RS_PACING_GEQ - must be greater than or equal. * RS_PACING_LT - must be less than. * RS_PACING_SUB_OK - If we don't meet criteria a * substitute is ok. */ int i, matched; struct tcp_hwrate_limit_table *rte = NULL; uint64_t previous_rate = 0; if ((rs->rs_flags & RS_INT_TBL) && (rs->rs_rate_cnt >= ALL_HARDWARE_RATES)) { /* * Here we don't want to paw thru * a big table, we have everything * from 1Meg - 1000Meg in 1Meg increments. * Use an alternate method to "lookup". */ return (tcp_int_find_suitable_rate(rs, bytes_per_sec, flags, lower_rate)); } if ((flags & RS_PACING_LT) || (flags & RS_PACING_EXACT_MATCH)) { /* * For exact and less than we go forward through the table. * This way when we find one larger we stop (exact was a * toss up). */ for (i = rs->rs_lowest_valid, matched = 0; i <= rs->rs_highest_valid; i++) { if ((flags & RS_PACING_EXACT_MATCH) && (bytes_per_sec == rs->rs_rlt[i].rate)) { rte = &rs->rs_rlt[i]; matched = 1; if (lower_rate != NULL) *lower_rate = previous_rate; break; } else if ((flags & RS_PACING_LT) && (bytes_per_sec <= rs->rs_rlt[i].rate)) { rte = &rs->rs_rlt[i]; matched = 1; if (lower_rate != NULL) *lower_rate = previous_rate; break; } previous_rate = rs->rs_rlt[i].rate; if (bytes_per_sec > rs->rs_rlt[i].rate) break; } if ((matched == 0) && (flags & RS_PACING_LT) && (flags & RS_PACING_SUB_OK)) { /* Kick in a substitute (the lowest) */ rte = &rs->rs_rlt[rs->rs_lowest_valid]; } } else { /* * Here we go backward through the table so that we can find * the one greater in theory faster (but its probably a * wash). */ for (i = rs->rs_highest_valid, matched = 0; i >= rs->rs_lowest_valid; i--) { if (rs->rs_rlt[i].rate > bytes_per_sec) { /* A possible candidate */ rte = &rs->rs_rlt[i]; } if ((flags & RS_PACING_GEQ) && (bytes_per_sec == rs->rs_rlt[i].rate)) { /* An exact match and we want equal */ matched = 1; rte = &rs->rs_rlt[i]; break; } else if (rte) { /* * Found one that is larger than but don't * stop, there may be a more closer match. */ matched = 1; } if (rs->rs_rlt[i].rate < bytes_per_sec) { /* * We found a table entry that is smaller, * stop there will be none greater or equal. */ if (lower_rate != NULL) *lower_rate = rs->rs_rlt[i].rate; break; } } if ((matched == 0) && (flags & RS_PACING_SUB_OK)) { /* Kick in a substitute (the highest) */ rte = &rs->rs_rlt[rs->rs_highest_valid]; } } return (rte); } static struct ifnet * rt_find_real_interface(struct ifnet *ifp, struct inpcb *inp, int *error) { struct ifnet *tifp; struct m_snd_tag *tag, *ntag; union if_snd_tag_alloc_params params = { .rate_limit.hdr.type = IF_SND_TAG_TYPE_RATE_LIMIT, .rate_limit.hdr.flowid = inp->inp_flowid, .rate_limit.hdr.numa_domain = inp->inp_numa_domain, .rate_limit.max_rate = COMMON_RATE, .rate_limit.flags = M_NOWAIT, }; int err; #ifdef RSS params.rate_limit.hdr.flowtype = ((inp->inp_vflag & INP_IPV6) ? M_HASHTYPE_RSS_TCP_IPV6 : M_HASHTYPE_RSS_TCP_IPV4); #else params.rate_limit.hdr.flowtype = M_HASHTYPE_OPAQUE_HASH; #endif err = m_snd_tag_alloc(ifp, ¶ms, &tag); if (err) { /* Failed to setup a tag? */ if (error) *error = err; return (NULL); } ntag = tag; while (ntag->sw->next_snd_tag != NULL) { ntag = ntag->sw->next_snd_tag(ntag); } tifp = ntag->ifp; m_snd_tag_rele(tag); return (tifp); } static void rl_increment_using(const struct tcp_hwrate_limit_table *rte) { struct tcp_hwrate_limit_table *decon_rte; decon_rte = __DECONST(struct tcp_hwrate_limit_table *, rte); atomic_add_long(&decon_rte->using, 1); } static void rl_decrement_using(const struct tcp_hwrate_limit_table *rte) { struct tcp_hwrate_limit_table *decon_rte; decon_rte = __DECONST(struct tcp_hwrate_limit_table *, rte); atomic_subtract_long(&decon_rte->using, 1); } void tcp_rl_log_enobuf(const struct tcp_hwrate_limit_table *rte) { struct tcp_hwrate_limit_table *decon_rte; decon_rte = __DECONST(struct tcp_hwrate_limit_table *, rte); atomic_add_long(&decon_rte->rs_num_enobufs, 1); } /* * Do NOT take the __noinline out of the * find_rs_for_ifp() function. If you do the inline * of it for the rt_setup_rate() will show you a * compiler bug. For some reason the compiler thinks * the list can never be empty. The consequence of * this will be a crash when we dereference NULL * if an ifp is removed just has a hw rate limit * is attempted. If you are working on the compiler * and want to "test" this go ahead and take the noinline * out otherwise let sleeping dogs ly until such time * as we get a compiler fix 10/2/20 -- RRS */ static __noinline struct tcp_rate_set * find_rs_for_ifp(struct ifnet *ifp) { struct tcp_rate_set *rs; CK_LIST_FOREACH(rs, &int_rs, next) { if ((rs->rs_ifp == ifp) && (rs->rs_if_dunit == ifp->if_dunit)) { /* Ok we found it */ return (rs); } } return (NULL); } static const struct tcp_hwrate_limit_table * rt_setup_rate(struct inpcb *inp, struct ifnet *ifp, uint64_t bytes_per_sec, uint32_t flags, int *error, uint64_t *lower_rate) { /* First lets find the interface if it exists */ const struct tcp_hwrate_limit_table *rte; /* * So why is rs volatile? This is to defeat a * compiler bug where in the compiler is convinced * that rs can never be NULL (which is not true). Because * of its conviction it nicely optimizes out the if ((rs == NULL * below which means if you get a NULL back you dereference it. */ volatile struct tcp_rate_set *rs; struct epoch_tracker et; struct ifnet *oifp = ifp; int err; NET_EPOCH_ENTER(et); use_real_interface: rs = find_rs_for_ifp(ifp); if ((rs == NULL) || (rs->rs_flags & RS_INTF_NO_SUP) || (rs->rs_flags & RS_IS_DEAD)) { /* * This means we got a packet *before* * the IF-UP was processed below, * while or after we already received an interface * departed event. In either case we really don't * want to do anything with pacing, in * the departing case the packet is not * going to go very far. The new case * might be arguable, but its impossible * to tell from the departing case. */ if (error) *error = ENODEV; NET_EPOCH_EXIT(et); return (NULL); } if ((rs == NULL) || (rs->rs_disable != 0)) { if (error) *error = ENOSPC; NET_EPOCH_EXIT(et); return (NULL); } if (rs->rs_flags & RS_IS_DEFF) { /* We need to find the real interface */ struct ifnet *tifp; tifp = rt_find_real_interface(ifp, inp, error); if (tifp == NULL) { if (rs->rs_disable && error) *error = ENOTSUP; NET_EPOCH_EXIT(et); return (NULL); } KASSERT((tifp != ifp), ("Lookup failure ifp:%p inp:%p rt_find_real_interface() returns the same interface tifp:%p?\n", ifp, inp, tifp)); ifp = tifp; goto use_real_interface; } if (rs->rs_flow_limit && ((rs->rs_flows_using + 1) > rs->rs_flow_limit)) { if (error) *error = ENOSPC; NET_EPOCH_EXIT(et); return (NULL); } rte = tcp_find_suitable_rate(rs, bytes_per_sec, flags, lower_rate); if (rte) { err = in_pcbattach_txrtlmt(inp, oifp, inp->inp_flowtype, inp->inp_flowid, rte->rate, &inp->inp_snd_tag); if (err) { /* Failed to attach */ if (error) *error = err; rte = NULL; } else { KASSERT((inp->inp_snd_tag != NULL) , ("Setup rate has no snd_tag inp:%p rte:%p rate:%llu rs:%p", inp, rte, (unsigned long long)rte->rate, rs)); #ifdef INET counter_u64_add(rate_limit_new, 1); #endif } } if (rte) { /* * We use an atomic here for accounting so we don't have to * use locks when freeing. */ atomic_add_64(&rs->rs_flows_using, 1); } NET_EPOCH_EXIT(et); return (rte); } static void tcp_rl_ifnet_link(void *arg __unused, struct ifnet *ifp, int link_state) { int error; struct tcp_rate_set *rs; struct epoch_tracker et; if (((ifp->if_capenable & IFCAP_TXRTLMT) == 0) || (link_state != LINK_STATE_UP)) { /* * We only care on an interface going up that is rate-limit * capable. */ return; } NET_EPOCH_ENTER(et); mtx_lock(&rs_mtx); rs = find_rs_for_ifp(ifp); if (rs) { /* We already have initialized this guy */ mtx_unlock(&rs_mtx); NET_EPOCH_EXIT(et); return; } mtx_unlock(&rs_mtx); NET_EPOCH_EXIT(et); rt_setup_new_rs(ifp, &error); } static void tcp_rl_ifnet_departure(void *arg __unused, struct ifnet *ifp) { struct tcp_rate_set *rs; struct epoch_tracker et; int i; NET_EPOCH_ENTER(et); mtx_lock(&rs_mtx); rs = find_rs_for_ifp(ifp); if (rs) { CK_LIST_REMOVE(rs, next); rs_number_alive--; rs->rs_flags |= RS_IS_DEAD; for (i = 0; i < rs->rs_rate_cnt; i++) { if (rs->rs_rlt[i].flags & HDWRPACE_TAGPRESENT) { in_pcbdetach_tag(rs->rs_rlt[i].tag); rs->rs_rlt[i].tag = NULL; } rs->rs_rlt[i].flags = HDWRPACE_IFPDEPARTED; } if (rs->rs_flows_using == 0) rs_defer_destroy(rs); } mtx_unlock(&rs_mtx); NET_EPOCH_EXIT(et); } static void tcp_rl_shutdown(void *arg __unused, int howto __unused) { struct tcp_rate_set *rs, *nrs; struct epoch_tracker et; int i; NET_EPOCH_ENTER(et); mtx_lock(&rs_mtx); CK_LIST_FOREACH_SAFE(rs, &int_rs, next, nrs) { CK_LIST_REMOVE(rs, next); rs_number_alive--; rs->rs_flags |= RS_IS_DEAD; for (i = 0; i < rs->rs_rate_cnt; i++) { if (rs->rs_rlt[i].flags & HDWRPACE_TAGPRESENT) { in_pcbdetach_tag(rs->rs_rlt[i].tag); rs->rs_rlt[i].tag = NULL; } rs->rs_rlt[i].flags = HDWRPACE_IFPDEPARTED; } if (rs->rs_flows_using == 0) rs_defer_destroy(rs); } mtx_unlock(&rs_mtx); NET_EPOCH_EXIT(et); } const struct tcp_hwrate_limit_table * tcp_set_pacing_rate(struct tcpcb *tp, struct ifnet *ifp, uint64_t bytes_per_sec, int flags, int *error, uint64_t *lower_rate) { struct inpcb *inp = tptoinpcb(tp); const struct tcp_hwrate_limit_table *rte; #ifdef KERN_TLS struct ktls_session *tls; #endif INP_WLOCK_ASSERT(inp); if (inp->inp_snd_tag == NULL) { /* * We are setting up a rate for the first time. */ if ((ifp->if_capenable & IFCAP_TXRTLMT) == 0) { /* Not supported by the egress */ if (error) *error = ENODEV; return (NULL); } #ifdef KERN_TLS tls = NULL; if (tptosocket(tp)->so_snd.sb_flags & SB_TLS_IFNET) { tls = tptosocket(tp)->so_snd.sb_tls_info; if ((ifp->if_capenable & IFCAP_TXTLS_RTLMT) == 0 || tls->mode != TCP_TLS_MODE_IFNET) { if (error) *error = ENODEV; return (NULL); } } #endif rte = rt_setup_rate(inp, ifp, bytes_per_sec, flags, error, lower_rate); if (rte) rl_increment_using(rte); #ifdef KERN_TLS if (rte != NULL && tls != NULL && tls->snd_tag != NULL) { /* * Fake a route change error to reset the TLS * send tag. This will convert the existing * tag to a TLS ratelimit tag. */ MPASS(tls->snd_tag->sw->type == IF_SND_TAG_TYPE_TLS); ktls_output_eagain(inp, tls); } #endif } else { /* * We are modifying a rate, wrong interface? */ if (error) *error = EINVAL; rte = NULL; } if (rte != NULL) { tp->t_pacing_rate = rte->rate; *error = 0; } return (rte); } const struct tcp_hwrate_limit_table * tcp_chg_pacing_rate(const struct tcp_hwrate_limit_table *crte, struct tcpcb *tp, struct ifnet *ifp, uint64_t bytes_per_sec, int flags, int *error, uint64_t *lower_rate) { struct inpcb *inp = tptoinpcb(tp); const struct tcp_hwrate_limit_table *nrte; const struct tcp_rate_set *rs; #ifdef KERN_TLS struct ktls_session *tls = NULL; #endif int err; INP_WLOCK_ASSERT(inp); if (crte == NULL) { /* Wrong interface */ if (error) *error = EINVAL; return (NULL); } #ifdef KERN_TLS if (tptosocket(tp)->so_snd.sb_flags & SB_TLS_IFNET) { tls = tptosocket(tp)->so_snd.sb_tls_info; if (tls->mode != TCP_TLS_MODE_IFNET) tls = NULL; else if (tls->snd_tag != NULL && tls->snd_tag->sw->type != IF_SND_TAG_TYPE_TLS_RATE_LIMIT) { if (!tls->reset_pending) { /* * NIC probably doesn't support * ratelimit TLS tags if it didn't * allocate one when an existing rate * was present, so ignore. */ tcp_rel_pacing_rate(crte, tp); if (error) *error = EOPNOTSUPP; return (NULL); } /* * The send tag is being converted, so set the * rate limit on the inpcb tag. There is a * race that the new NIC send tag might use * the current rate instead of this one. */ tls = NULL; } } #endif if (inp->inp_snd_tag == NULL) { /* Wrong interface */ tcp_rel_pacing_rate(crte, tp); if (error) *error = EINVAL; return (NULL); } rs = crte->ptbl; if ((rs->rs_flags & RS_IS_DEAD) || (crte->flags & HDWRPACE_IFPDEPARTED)) { /* Release the rate, and try anew */ tcp_rel_pacing_rate(crte, tp); nrte = tcp_set_pacing_rate(tp, ifp, bytes_per_sec, flags, error, lower_rate); return (nrte); } nrte = tcp_find_suitable_rate(rs, bytes_per_sec, flags, lower_rate); if (nrte == crte) { /* No change */ if (error) *error = 0; return (crte); } if (nrte == NULL) { /* Release the old rate */ if (error) *error = ENOENT; tcp_rel_pacing_rate(crte, tp); return (NULL); } rl_decrement_using(crte); rl_increment_using(nrte); /* Change rates to our new entry */ #ifdef KERN_TLS if (tls != NULL) err = ktls_modify_txrtlmt(tls, nrte->rate); else #endif err = in_pcbmodify_txrtlmt(inp, nrte->rate); if (err) { struct tcp_rate_set *lrs; uint64_t pre; rl_decrement_using(nrte); lrs = __DECONST(struct tcp_rate_set *, rs); pre = atomic_fetchadd_64(&lrs->rs_flows_using, -1); /* Do we still have a snd-tag attached? */ if (inp->inp_snd_tag) in_pcbdetach_txrtlmt(inp); if (pre == 1) { struct epoch_tracker et; NET_EPOCH_ENTER(et); mtx_lock(&rs_mtx); /* * Is it dead? */ if (lrs->rs_flags & RS_IS_DEAD) rs_defer_destroy(lrs); mtx_unlock(&rs_mtx); NET_EPOCH_EXIT(et); } if (error) *error = err; return (NULL); } else { #ifdef INET counter_u64_add(rate_limit_chg, 1); #endif } if (error) *error = 0; tp->t_pacing_rate = nrte->rate; return (nrte); } void tcp_rel_pacing_rate(const struct tcp_hwrate_limit_table *crte, struct tcpcb *tp) { struct inpcb *inp = tptoinpcb(tp); const struct tcp_rate_set *crs; struct tcp_rate_set *rs; uint64_t pre; INP_WLOCK_ASSERT(inp); tp->t_pacing_rate = -1; crs = crte->ptbl; /* * Now we must break the const * in order to release our refcount. */ rs = __DECONST(struct tcp_rate_set *, crs); rl_decrement_using(crte); pre = atomic_fetchadd_64(&rs->rs_flows_using, -1); if (pre == 1) { struct epoch_tracker et; NET_EPOCH_ENTER(et); mtx_lock(&rs_mtx); /* * Is it dead? */ if (rs->rs_flags & RS_IS_DEAD) rs_defer_destroy(rs); mtx_unlock(&rs_mtx); NET_EPOCH_EXIT(et); } /* * XXX: If this connection is using ifnet TLS, should we * switch it to using an unlimited rate, or perhaps use * ktls_output_eagain() to reset the send tag to a plain * TLS tag? */ in_pcbdetach_txrtlmt(inp); } #define ONE_POINT_TWO_MEG 150000 /* 1.2 megabits in bytes */ #define ONE_HUNDRED_MBPS 12500000 /* 100Mbps in bytes per second */ #define FIVE_HUNDRED_MBPS 62500000 /* 500Mbps in bytes per second */ #define MAX_MSS_SENT 43 /* 43 mss = 43 x 1500 = 64,500 bytes */ static void tcp_log_pacing_size(struct tcpcb *tp, uint64_t bw, uint32_t segsiz, uint32_t new_tso, uint64_t hw_rate, uint32_t time_between, uint32_t calc_time_between, uint32_t segs, uint32_t res_div, uint16_t mult, uint8_t mod) { if (tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log, 0, sizeof(log)); log.u_bbr.flex1 = segsiz; log.u_bbr.flex2 = new_tso; log.u_bbr.flex3 = time_between; log.u_bbr.flex4 = calc_time_between; log.u_bbr.flex5 = segs; log.u_bbr.flex6 = res_div; log.u_bbr.flex7 = mult; log.u_bbr.flex8 = mod; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.cur_del_rate = bw; log.u_bbr.delRate = hw_rate; TCP_LOG_EVENTP(tp, NULL, &tptosocket(tp)->so_rcv, &tptosocket(tp)->so_snd, TCP_HDWR_PACE_SIZE, 0, 0, &log, false, &tv); } } uint32_t tcp_get_pacing_burst_size (struct tcpcb *tp, uint64_t bw, uint32_t segsiz, int can_use_1mss, const struct tcp_hwrate_limit_table *te, int *err) { /* * We use the google formula to calculate the * TSO size. I.E. * bw < 24Meg * tso = 2mss * else * tso = min(bw/1000, 64k) * * Note for these calculations we ignore the * packet overhead (enet hdr, ip hdr and tcp hdr). */ uint64_t lentim, res, bytes; uint32_t new_tso, min_tso_segs; bytes = bw / 1000; if (bytes > (64 * 1000)) bytes = 64 * 1000; /* Round up */ new_tso = (bytes + segsiz - 1) / segsiz; if (can_use_1mss && (bw < ONE_POINT_TWO_MEG)) min_tso_segs = 1; else min_tso_segs = 2; if (rs_floor_mss && (new_tso < rs_floor_mss)) new_tso = rs_floor_mss; else if (new_tso < min_tso_segs) new_tso = min_tso_segs; if (new_tso > MAX_MSS_SENT) new_tso = MAX_MSS_SENT; new_tso *= segsiz; tcp_log_pacing_size(tp, bw, segsiz, new_tso, 0, 0, 0, 0, 0, 0, 1); /* * If we are not doing hardware pacing * then we are done. */ if (te == NULL) { if (err) *err = 0; return(new_tso); } /* * For hardware pacing we look at the * rate you are sending at and compare * that to the rate you have in hardware. * * If the hardware rate is slower than your * software rate then you are in error and * we will build a queue in our hardware whic * is probably not desired, in such a case * just return the non-hardware TSO size. * * If the rate in hardware is faster (which * it should be) then look at how long it * takes to send one ethernet segment size at * your b/w and compare that to the time it * takes to send at the rate you had selected. * * If your time is greater (which we hope it is) * we get the delta between the two, and then * divide that into your pacing time. This tells * us how many MSS you can send down at once (rounded up). * * Note we also double this value if the b/w is over * 100Mbps. If its over 500meg we just set you to the * max (43 segments). */ if (te->rate > FIVE_HUNDRED_MBPS) goto max; if (te->rate == bw) { /* We are pacing at exactly the hdwr rate */ max: tcp_log_pacing_size(tp, bw, segsiz, new_tso, te->rate, te->time_between, (uint32_t)0, (segsiz * MAX_MSS_SENT), 0, 0, 3); return (segsiz * MAX_MSS_SENT); } lentim = ETHERNET_SEGMENT_SIZE * USECS_IN_SECOND; res = lentim / bw; if (res > te->time_between) { uint32_t delta, segs, res_div; res_div = ((res * num_of_waits_allowed) + wait_time_floor); delta = res - te->time_between; segs = (res_div + delta - 1)/delta; if (segs < min_tso_segs) segs = min_tso_segs; if (segs < rs_hw_floor_mss) segs = rs_hw_floor_mss; if (segs > MAX_MSS_SENT) segs = MAX_MSS_SENT; segs *= segsiz; tcp_log_pacing_size(tp, bw, segsiz, new_tso, te->rate, te->time_between, (uint32_t)res, segs, res_div, 1, 3); if (err) *err = 0; if (segs < new_tso) { /* unexpected ? */ return(new_tso); } else { return (segs); } } else { /* * Your time is smaller which means * we will grow a queue on our * hardware. Send back the non-hardware * rate. */ tcp_log_pacing_size(tp, bw, segsiz, new_tso, te->rate, te->time_between, (uint32_t)res, 0, 0, 0, 4); if (err) *err = -1; return (new_tso); } } uint64_t tcp_hw_highest_rate_ifp(struct ifnet *ifp, struct inpcb *inp) { struct epoch_tracker et; struct tcp_rate_set *rs; uint64_t rate_ret; NET_EPOCH_ENTER(et); use_next_interface: rs = find_rs_for_ifp(ifp); if (rs == NULL) { /* This interface does not do ratelimiting */ rate_ret = 0; } else if (rs->rs_flags & RS_IS_DEFF) { /* We need to find the real interface */ struct ifnet *tifp; tifp = rt_find_real_interface(ifp, inp, NULL); if (tifp == NULL) { NET_EPOCH_EXIT(et); return (0); } ifp = tifp; goto use_next_interface; } else { /* Lets return the highest rate this guy has */ rate_ret = rs->rs_rlt[rs->rs_highest_valid].rate; } NET_EPOCH_EXIT(et); return(rate_ret); } static eventhandler_tag rl_ifnet_departs; static eventhandler_tag rl_ifnet_arrives; static eventhandler_tag rl_shutdown_start; static void tcp_rs_init(void *st __unused) { CK_LIST_INIT(&int_rs); rs_number_alive = 0; rs_number_dead = 0; mtx_init(&rs_mtx, "tcp_rs_mtx", "rsmtx", MTX_DEF); rl_ifnet_departs = EVENTHANDLER_REGISTER(ifnet_departure_event, tcp_rl_ifnet_departure, NULL, EVENTHANDLER_PRI_ANY); rl_ifnet_arrives = EVENTHANDLER_REGISTER(ifnet_link_event, tcp_rl_ifnet_link, NULL, EVENTHANDLER_PRI_ANY); rl_shutdown_start = EVENTHANDLER_REGISTER(shutdown_pre_sync, tcp_rl_shutdown, NULL, SHUTDOWN_PRI_FIRST); printf("TCP_ratelimit: Is now initialized\n"); } SYSINIT(tcp_rl_init, SI_SUB_SMP + 1, SI_ORDER_ANY, tcp_rs_init, NULL); #endif diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 0a620d173d88..77d1d9fa31bf 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -1,1123 +1,1119 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * @(#)tcp_input.c 8.12 (Berkeley) 5/24/95 */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" -#include "opt_tcpdebug.h" /* For debugging we want counters and BB logging */ /* #define TCP_REASS_COUNTERS 1 */ /* #define TCP_REASS_LOGGING 1 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef TCP_REASS_LOGGING #include #include #endif #include -#ifdef TCPDEBUG -#include -#endif /* TCPDEBUG */ #define TCP_R_LOG_ADD 1 #define TCP_R_LOG_LIMIT_REACHED 2 #define TCP_R_LOG_APPEND 3 #define TCP_R_LOG_PREPEND 4 #define TCP_R_LOG_REPLACE 5 #define TCP_R_LOG_MERGE_INTO 6 #define TCP_R_LOG_NEW_ENTRY 7 #define TCP_R_LOG_READ 8 #define TCP_R_LOG_ZERO 9 #define TCP_R_LOG_DUMP 10 #define TCP_R_LOG_TRIM 11 static SYSCTL_NODE(_net_inet_tcp, OID_AUTO, reass, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "TCP Segment Reassembly Queue"); static SYSCTL_NODE(_net_inet_tcp_reass, OID_AUTO, stats, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "TCP Segment Reassembly stats"); static int tcp_reass_maxseg = 0; SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLFLAG_RDTUN, &tcp_reass_maxseg, 0, "Global maximum number of TCP Segments in Reassembly Queue"); static uma_zone_t tcp_reass_zone; SYSCTL_UMA_CUR(_net_inet_tcp_reass, OID_AUTO, cursegments, 0, &tcp_reass_zone, "Global number of TCP Segments currently in Reassembly Queue"); static u_int tcp_reass_maxqueuelen = 100; SYSCTL_UINT(_net_inet_tcp_reass, OID_AUTO, maxqueuelen, CTLFLAG_RWTUN, &tcp_reass_maxqueuelen, 0, "Maximum number of TCP Segments per Reassembly Queue"); static int tcp_new_limits = 0; SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, new_limit, CTLFLAG_RWTUN, &tcp_new_limits, 0, "Do we use the new limit method we are discussing?"); static u_int tcp_reass_queue_guard = 16; SYSCTL_UINT(_net_inet_tcp_reass, OID_AUTO, queueguard, CTLFLAG_RWTUN, &tcp_reass_queue_guard, 16, "Number of TCP Segments in Reassembly Queue where we flip over to guard mode"); #ifdef TCP_REASS_COUNTERS counter_u64_t reass_entry; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, entry, CTLFLAG_RD, &reass_entry, "A segment entered reassembly "); counter_u64_t reass_path1; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, path1, CTLFLAG_RD, &reass_path1, "Took path 1"); counter_u64_t reass_path2; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, path2, CTLFLAG_RD, &reass_path2, "Took path 2"); counter_u64_t reass_path3; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, path3, CTLFLAG_RD, &reass_path3, "Took path 3"); counter_u64_t reass_path4; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, path4, CTLFLAG_RD, &reass_path4, "Took path 4"); counter_u64_t reass_path5; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, path5, CTLFLAG_RD, &reass_path5, "Took path 5"); counter_u64_t reass_path6; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, path6, CTLFLAG_RD, &reass_path6, "Took path 6"); counter_u64_t reass_path7; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, path7, CTLFLAG_RD, &reass_path7, "Took path 7"); counter_u64_t reass_fullwalk; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, fullwalk, CTLFLAG_RD, &reass_fullwalk, "Took a full walk "); counter_u64_t reass_nospace; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, nospace, CTLFLAG_RD, &reass_nospace, "Had no mbuf capacity "); counter_u64_t merge_fwd; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, merge_fwd, CTLFLAG_RD, &merge_fwd, "Ran merge fwd"); counter_u64_t merge_into; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, merge_into, CTLFLAG_RD, &merge_into, "Ran merge into"); counter_u64_t tcp_zero_input; SYSCTL_COUNTER_U64(_net_inet_tcp_reass_stats, OID_AUTO, zero_input, CTLFLAG_RD, &tcp_zero_input, "The reassembly buffer saw a zero len segment etc"); #endif /* Initialize TCP reassembly queue */ static void tcp_reass_zone_change(void *tag) { /* Set the zone limit and read back the effective value. */ tcp_reass_maxseg = nmbclusters / 16; tcp_reass_maxseg = uma_zone_set_max(tcp_reass_zone, tcp_reass_maxseg); } #ifdef TCP_REASS_LOGGING static void tcp_log_reassm(struct tcpcb *tp, struct tseg_qent *q, struct tseg_qent *p, tcp_seq seq, int len, uint8_t action, int instance) { struct socket *so = tptosocket(tp); uint32_t cts; struct timeval tv; if (tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; memset(&log, 0, sizeof(log)); cts = tcp_get_usecs(&tv); log.u_bbr.flex1 = seq; log.u_bbr.cur_del_rate = (uint64_t)q; log.u_bbr.delRate = (uint64_t)p; if (q != NULL) { log.u_bbr.flex2 = q->tqe_start; log.u_bbr.flex3 = q->tqe_len; log.u_bbr.flex4 = q->tqe_mbuf_cnt; log.u_bbr.hptsi_gain = q->tqe_flags; } if (p != NULL) { log.u_bbr.flex5 = p->tqe_start; log.u_bbr.pkts_out = p->tqe_len; log.u_bbr.epoch = p->tqe_mbuf_cnt; log.u_bbr.cwnd_gain = p->tqe_flags; } log.u_bbr.flex6 = tp->t_segqmbuflen; log.u_bbr.flex7 = instance; log.u_bbr.flex8 = action; log.u_bbr.timeStamp = cts; TCP_LOG_EVENTP(tp, NULL, &so->so_rcv, &so->so_snd, TCP_LOG_REASS, 0, len, &log, false, &tv); } } static void tcp_reass_log_dump(struct tcpcb *tp) { struct tseg_qent *q; if (tp->t_logstate != TCP_LOG_STATE_OFF) { TAILQ_FOREACH(q, &tp->t_segq, tqe_q) { tcp_log_reassm(tp, q, NULL, q->tqe_start, q->tqe_len, TCP_R_LOG_DUMP, 0); } }; } static void tcp_reass_log_new_in(struct tcpcb *tp, tcp_seq seq, int len, struct mbuf *m, int logval, struct tseg_qent *q) { int cnt; struct mbuf *t; cnt = 0; t = m; while (t) { cnt += t->m_len; t = t->m_next; } tcp_log_reassm(tp, q, NULL, seq, len, logval, cnt); } #endif void tcp_reass_global_init(void) { tcp_reass_maxseg = nmbclusters / 16; TUNABLE_INT_FETCH("net.inet.tcp.reass.maxsegments", &tcp_reass_maxseg); tcp_reass_zone = uma_zcreate("tcpreass", sizeof (struct tseg_qent), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); /* Set the zone limit and read back the effective value. */ tcp_reass_maxseg = uma_zone_set_max(tcp_reass_zone, tcp_reass_maxseg); #ifdef TCP_REASS_COUNTERS reass_path1 = counter_u64_alloc(M_WAITOK); reass_path2 = counter_u64_alloc(M_WAITOK); reass_path3 = counter_u64_alloc(M_WAITOK); reass_path4 = counter_u64_alloc(M_WAITOK); reass_path5 = counter_u64_alloc(M_WAITOK); reass_path6 = counter_u64_alloc(M_WAITOK); reass_path7 = counter_u64_alloc(M_WAITOK); reass_fullwalk = counter_u64_alloc(M_WAITOK); reass_nospace = counter_u64_alloc(M_WAITOK); reass_entry = counter_u64_alloc(M_WAITOK); merge_fwd = counter_u64_alloc(M_WAITOK); merge_into = counter_u64_alloc(M_WAITOK); tcp_zero_input = counter_u64_alloc(M_WAITOK); #endif EVENTHANDLER_REGISTER(nmbclusters_change, tcp_reass_zone_change, NULL, EVENTHANDLER_PRI_ANY); } void tcp_reass_flush(struct tcpcb *tp) { struct tseg_qent *qe; INP_WLOCK_ASSERT(tptoinpcb(tp)); while ((qe = TAILQ_FIRST(&tp->t_segq)) != NULL) { TAILQ_REMOVE(&tp->t_segq, qe, tqe_q); m_freem(qe->tqe_m); uma_zfree(tcp_reass_zone, qe); tp->t_segqlen--; } tp->t_segqmbuflen = 0; KASSERT((tp->t_segqlen == 0), ("TCP reass queue %p segment count is %d instead of 0 after flush.", tp, tp->t_segqlen)); } static void tcp_reass_append(struct tcpcb *tp, struct tseg_qent *last, struct mbuf *m, struct tcphdr *th, int tlen, struct mbuf *mlast, int lenofoh) { #ifdef TCP_REASS_LOGGING tcp_log_reassm(tp, last, NULL, th->th_seq, tlen, TCP_R_LOG_APPEND, 0); #endif last->tqe_len += tlen; last->tqe_m->m_pkthdr.len += tlen; /* Preserve the FIN bit if its there */ last->tqe_flags |= (tcp_get_flags(th) & TH_FIN); last->tqe_last->m_next = m; last->tqe_last = mlast; last->tqe_mbuf_cnt += lenofoh; tp->t_rcvoopack++; TCPSTAT_INC(tcps_rcvoopack); TCPSTAT_ADD(tcps_rcvoobyte, tlen); #ifdef TCP_REASS_LOGGING tcp_reass_log_new_in(tp, last->tqe_start, lenofoh, last->tqe_m, TCP_R_LOG_APPEND, last); #endif } static void tcp_reass_prepend(struct tcpcb *tp, struct tseg_qent *first, struct mbuf *m, struct tcphdr *th, int tlen, struct mbuf *mlast, int lenofoh) { int i; #ifdef TCP_REASS_LOGGING tcp_log_reassm(tp, first, NULL, th->th_seq, tlen, TCP_R_LOG_PREPEND, 0); #endif if (SEQ_GT((th->th_seq + tlen), first->tqe_start)) { /* The new data overlaps into the old */ i = (th->th_seq + tlen) - first->tqe_start; #ifdef TCP_REASS_LOGGING tcp_log_reassm(tp, first, NULL, 0, i, TCP_R_LOG_TRIM, 1); #endif m_adj(first->tqe_m, i); first->tqe_len -= i; first->tqe_start += i; } /* Ok now setup our chain to point to the old first */ mlast->m_next = first->tqe_m; first->tqe_m = m; first->tqe_len += tlen; first->tqe_start = th->th_seq; first->tqe_m->m_pkthdr.len = first->tqe_len; first->tqe_mbuf_cnt += lenofoh; tp->t_rcvoopack++; TCPSTAT_INC(tcps_rcvoopack); TCPSTAT_ADD(tcps_rcvoobyte, tlen); #ifdef TCP_REASS_LOGGING tcp_reass_log_new_in(tp, first->tqe_start, lenofoh, first->tqe_m, TCP_R_LOG_PREPEND, first); #endif } static void tcp_reass_replace(struct tcpcb *tp, struct tseg_qent *q, struct mbuf *m, tcp_seq seq, int len, struct mbuf *mlast, int mbufoh, uint16_t flags) { /* * Free the data in q, and replace * it with the new segment. */ int len_dif; #ifdef TCP_REASS_LOGGING tcp_log_reassm(tp, q, NULL, seq, len, TCP_R_LOG_REPLACE, 0); #endif m_freem(q->tqe_m); KASSERT(tp->t_segqmbuflen >= q->tqe_mbuf_cnt, ("Tp:%p seg queue goes negative", tp)); tp->t_segqmbuflen -= q->tqe_mbuf_cnt; q->tqe_mbuf_cnt = mbufoh; q->tqe_m = m; q->tqe_last = mlast; q->tqe_start = seq; if (len > q->tqe_len) len_dif = len - q->tqe_len; else len_dif = 0; tp->t_rcvoopack++; TCPSTAT_INC(tcps_rcvoopack); TCPSTAT_ADD(tcps_rcvoobyte, len_dif); q->tqe_len = len; q->tqe_flags = (flags & TH_FIN); q->tqe_m->m_pkthdr.len = q->tqe_len; tp->t_segqmbuflen += mbufoh; } static void tcp_reass_merge_into(struct tcpcb *tp, struct tseg_qent *ent, struct tseg_qent *q) { /* * Merge q into ent and free q from the list. */ #ifdef TCP_REASS_LOGGING tcp_log_reassm(tp, q, ent, 0, 0, TCP_R_LOG_MERGE_INTO, 0); #endif #ifdef TCP_REASS_COUNTERS counter_u64_add(merge_into, 1); #endif ent->tqe_last->m_next = q->tqe_m; ent->tqe_last = q->tqe_last; ent->tqe_len += q->tqe_len; ent->tqe_mbuf_cnt += q->tqe_mbuf_cnt; ent->tqe_m->m_pkthdr.len += q->tqe_len; ent->tqe_flags |= (q->tqe_flags & TH_FIN); TAILQ_REMOVE(&tp->t_segq, q, tqe_q); uma_zfree(tcp_reass_zone, q); tp->t_segqlen--; } static void tcp_reass_merge_forward(struct tcpcb *tp, struct tseg_qent *ent) { struct tseg_qent *q, *qtmp; int i; tcp_seq max; /* * Given an entry merge forward anyplace * that ent overlaps forward. */ max = ent->tqe_start + ent->tqe_len; q = TAILQ_NEXT(ent, tqe_q); if (q == NULL) { /* Nothing left */ return; } TAILQ_FOREACH_FROM_SAFE(q, &tp->t_segq, tqe_q, qtmp) { if (SEQ_GT(q->tqe_start, max)) { /* Beyond q */ break; } /* We have some or all that are overlapping */ if (SEQ_GEQ(max, (q->tqe_start + q->tqe_len))) { /* It consumes it all */ tp->t_segqmbuflen -= q->tqe_mbuf_cnt; m_freem(q->tqe_m); TAILQ_REMOVE(&tp->t_segq, q, tqe_q); uma_zfree(tcp_reass_zone, q); tp->t_segqlen--; continue; } /* * Trim the q entry to dovetail to this one * and then merge q into ent updating max * in the process. */ i = max - q->tqe_start; #ifdef TCP_REASS_LOGGING tcp_log_reassm(tp, q, NULL, 0, i, TCP_R_LOG_TRIM, 2); #endif m_adj(q->tqe_m, i); q->tqe_len -= i; q->tqe_start += i; tcp_reass_merge_into(tp, ent, q); max = ent->tqe_start + ent->tqe_len; } #ifdef TCP_REASS_COUNTERS counter_u64_add(merge_fwd, 1); #endif } static int tcp_reass_overhead_of_chain(struct mbuf *m, struct mbuf **mlast) { int len = MSIZE; if (m->m_flags & M_EXT) len += m->m_ext.ext_size; while (m->m_next != NULL) { m = m->m_next; len += MSIZE; if (m->m_flags & M_EXT) len += m->m_ext.ext_size; } *mlast = m; return (len); } /* * NOTE!!! the new tcp-reassembly code *must not* use * m_adj() with a negative index. That alters the chain * of mbufs (by possibly chopping trailing mbufs). At * the front of tcp_reass we count the mbuf overhead * and setup the tail pointer. If we use m_adj(m, -5) * we could corrupt the tail pointer. Currently the * code only uses m_adj(m, postive-num). If this * changes appropriate changes to update mlast would * be needed. */ int tcp_reass(struct tcpcb *tp, struct tcphdr *th, tcp_seq *seq_start, int *tlenp, struct mbuf *m) { struct tseg_qent *q, *last, *first; struct tseg_qent *p = NULL; struct tseg_qent *nq = NULL; struct tseg_qent *te = NULL; struct mbuf *mlast = NULL; struct inpcb *inp = tptoinpcb(tp); struct socket *so = tptosocket(tp); struct sockbuf *sb = &so->so_rcv; char *s = NULL; int flags, i, lenofoh; INP_WLOCK_ASSERT(inp); /* * XXX: tcp_reass() is rather inefficient with its data structures * and should be rewritten (see NetBSD for optimizations). */ KASSERT(th == NULL || (seq_start != NULL && tlenp != NULL), ("tcp_reass called with illegal parameter combination " "(tp=%p, th=%p, seq_start=%p, tlenp=%p, m=%p)", tp, th, seq_start, tlenp, m)); /* * Call with th==NULL after become established to * force pre-ESTABLISHED data up to user socket. */ if (th == NULL) goto present; KASSERT(SEQ_GEQ(th->th_seq, tp->rcv_nxt), ("Attempt to add old entry to reassembly queue (th=%p, tp=%p)", th, tp)); #ifdef TCP_REASS_LOGGING tcp_reass_log_new_in(tp, th->th_seq, *tlenp, m, TCP_R_LOG_ADD, NULL); #endif #ifdef TCP_REASS_COUNTERS counter_u64_add(reass_entry, 1); #endif /* * Check for zero length data. */ if ((*tlenp == 0) && ((tcp_get_flags(th) & TH_FIN) == 0)) { /* * A zero length segment does no * one any good. We could check * the rcv_nxt <-> rcv_wnd but thats * already done for us by the caller. */ strip_fin: #ifdef TCP_REASS_COUNTERS counter_u64_add(tcp_zero_input, 1); #endif m_freem(m); #ifdef TCP_REASS_LOGGING tcp_reass_log_dump(tp); #endif return (0); } else if ((*tlenp == 0) && (tcp_get_flags(th) & TH_FIN) && !TCPS_HAVEESTABLISHED(tp->t_state)) { /* * We have not established, and we * have a FIN and no data. Lets treat * this as the same as if the FIN were * not present. We don't want to save * the FIN bit in a reassembly buffer * we want to get established first before * we do that (the peer will retransmit). */ goto strip_fin; } /* * Will it fit? */ lenofoh = tcp_reass_overhead_of_chain(m, &mlast); if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && (sb->sb_mbcnt + tp->t_segqmbuflen + lenofoh) > sb->sb_mbmax) { /* No room */ TCPSTAT_INC(tcps_rcvreassfull); #ifdef TCP_REASS_COUNTERS counter_u64_add(reass_nospace, 1); #endif #ifdef TCP_REASS_LOGGING tcp_log_reassm(tp, NULL, NULL, th->th_seq, lenofoh, TCP_R_LOG_LIMIT_REACHED, 0); #endif if ((s = tcp_log_addrs(&inp->inp_inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: mbuf count limit reached, " "segment dropped\n", s, __func__); free(s, M_TCPLOG); } m_freem(m); *tlenp = 0; #ifdef TCP_REASS_LOGGING tcp_reass_log_dump(tp); #endif return (0); } /* * First lets deal with two common cases, the * segment appends to the back of our collected * segments. Or the segment is the next in line. */ last = TAILQ_LAST_FAST(&tp->t_segq, tseg_qent, tqe_q); if (last != NULL) { if ((tcp_get_flags(th) & TH_FIN) && SEQ_LT((th->th_seq + *tlenp), (last->tqe_start + last->tqe_len))) { /* * Someone is trying to game us, dump * the segment. */ *tlenp = 0; m_freem(m); return (0); } if ((SEQ_GEQ(th->th_seq, last->tqe_start)) && (SEQ_GEQ((last->tqe_start + last->tqe_len), th->th_seq))) { /* Common case, trailing segment is added */ /** * +--last * v * reassembly buffer |---| |---| |---| * new segment |---| */ #ifdef TCP_REASS_COUNTERS counter_u64_add(reass_path1, 1); #endif if (SEQ_GT((last->tqe_start + last->tqe_len), th->th_seq)) { i = (last->tqe_start + last->tqe_len) - th->th_seq; if (i < *tlenp) { #ifdef TCP_REASS_LOGGING tcp_log_reassm(tp, last, NULL, 0, i, TCP_R_LOG_TRIM, 3); th->th_seq += i; #endif m_adj(m, i); *tlenp -= i; } else { /* Complete overlap */ TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); *tlenp = last->tqe_len; *seq_start = last->tqe_start; return (0); } } if (last->tqe_flags & TH_FIN) { /* * We have data after the FIN on the last? */ *tlenp = 0; m_freem(m); return(0); } tcp_reass_append(tp, last, m, th, *tlenp, mlast, lenofoh); tp->t_segqmbuflen += lenofoh; *seq_start = last->tqe_start; *tlenp = last->tqe_len; return (0); } else if (SEQ_GT(th->th_seq, (last->tqe_start + last->tqe_len))) { /* * Second common case, we missed * another one and have something more * for the end. */ /** * +--last * v * reassembly buffer |---| |---| |---| * new segment |---| */ if (last->tqe_flags & TH_FIN) { /* * We have data after the FIN on the last? */ *tlenp = 0; m_freem(m); return(0); } #ifdef TCP_REASS_COUNTERS counter_u64_add(reass_path2, 1); #endif p = last; goto new_entry; } } else { /* First segment (it's NULL). */ goto new_entry; } first = TAILQ_FIRST(&tp->t_segq); if (SEQ_LT(th->th_seq, first->tqe_start) && SEQ_GEQ((th->th_seq + *tlenp),first->tqe_start) && SEQ_LT((th->th_seq + *tlenp), (first->tqe_start + first->tqe_len))) { /* * The head of the queue is prepended by this and * it may be the one I want most. */ /** * first-------+ * v * rea: |---| |---| |---| * new: |---| * Note the case we do not deal with here is: * rea= |---| |---| |---| * new= |----| * Due to the fact that it could be * new |--------------------| * And we might need to merge forward. */ #ifdef INVARIANTS struct mbuf *firstmbuf; #endif #ifdef TCP_REASS_COUNTERS counter_u64_add(reass_path3, 1); #endif if (SEQ_LT(th->th_seq, tp->rcv_nxt)) { /* * The resend was even before * what we have. We need to trim it. * Note TSNH (it should be trimmed * before the call to tcp_reass()). */ #ifdef INVARIANTS panic("th->th_seq:%u rcv_nxt:%u tp:%p not pre-trimmed", th->th_seq, tp->rcv_nxt, tp); #else i = tp->rcv_nxt - th->th_seq; #ifdef TCP_REASS_LOGGING tcp_log_reassm(tp, first, NULL, 0, i, TCP_R_LOG_TRIM, 4); #endif m_adj(m, i); th->th_seq += i; *tlenp -= i; #endif } #ifdef INVARIANTS firstmbuf = first->tqe_m; #endif tcp_reass_prepend(tp, first, m, th, *tlenp, mlast, lenofoh); #ifdef INVARIANTS if (firstmbuf == first->tqe_m) { panic("First stayed same m:%p foobar:%p first->tqe_m:%p tp:%p first:%p", m, firstmbuf, first->tqe_m, tp, first); } else if (first->tqe_m != m) { panic("First did not change to m:%p foobar:%p first->tqe_m:%p tp:%p first:%p", m, firstmbuf, first->tqe_m, tp, first); } #endif tp->t_segqmbuflen += lenofoh; *seq_start = first->tqe_start; *tlenp = first->tqe_len; goto present; } else if (SEQ_LT((th->th_seq + *tlenp), first->tqe_start)) { /* New segment is before our earliest segment. */ /** * first---->+ * v * rea= |---| .... * new" |---| * */ goto new_entry; } /* * Find a segment which begins after this one does. */ #ifdef TCP_REASS_COUNTERS counter_u64_add(reass_fullwalk, 1); #endif TAILQ_FOREACH(q, &tp->t_segq, tqe_q) { if (SEQ_GT(q->tqe_start, th->th_seq)) break; } p = TAILQ_PREV(q, tsegqe_head, tqe_q); /** * Now is this fit just in-between only? * i.e.: * p---+ +----q * v v * res= |--| |--| |--| * nee |-| */ if (SEQ_LT((th->th_seq + *tlenp), q->tqe_start) && ((p == NULL) || (SEQ_GT(th->th_seq, (p->tqe_start + p->tqe_len))))) { /* Yep no overlap */ goto new_entry; } /** * If we reach here we have some (possibly all) overlap * such as: * res= |--| |--| |--| * new= |----| * or new= |-----------------| * or new= |--------| * or new= |---| * or new= |-----------| */ if ((p != NULL) && (SEQ_LEQ(th->th_seq, (p->tqe_start + p->tqe_len)))) { /* conversion to int (in i) handles seq wraparound */ #ifdef TCP_REASS_COUNTERS counter_u64_add(reass_path4, 1); #endif i = p->tqe_start + p->tqe_len - th->th_seq; if (i >= 0) { if (i >= *tlenp) { /** * prev seg---->+ * v * reassembly buffer |---| * new segment |-| */ TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); *tlenp = p->tqe_len; *seq_start = p->tqe_start; m_freem(m); /* * Try to present any queued data * at the left window edge to the user. * This is needed after the 3-WHS * completes. Note this probably * will not work and we will return. */ return (0); } if (i > 0) { /** * prev seg---->+ * v * reassembly buffer |---| * new segment |-----| */ #ifdef TCP_REASS_COUNTERS counter_u64_add(reass_path5, 1); #endif #ifdef TCP_REASS_LOGGING tcp_log_reassm(tp, p, NULL, 0, i, TCP_R_LOG_TRIM, 5); #endif m_adj(m, i); *tlenp -= i; th->th_seq += i; } } if (th->th_seq == (p->tqe_start + p->tqe_len)) { /* * If dovetails in with this one * append it. */ /** * prev seg---->+ * v * reassembly buffer |--| |---| * new segment |--| * (note: it was trimmed above if it overlapped) */ tcp_reass_append(tp, p, m, th, *tlenp, mlast, lenofoh); tp->t_segqmbuflen += lenofoh; } else { #ifdef INVARIANTS panic("Impossible cut th_seq:%u p->seq:%u(%d) p:%p tp:%p", th->th_seq, p->tqe_start, p->tqe_len, p, tp); #endif *tlenp = 0; m_freem(m); return (0); } q = p; } else { /* * The new data runs over the * top of previously sack'd data (in q). * It may be partially overlapping, or * it may overlap the entire segment. */ #ifdef TCP_REASS_COUNTERS counter_u64_add(reass_path6, 1); #endif if (SEQ_GEQ((th->th_seq + *tlenp), (q->tqe_start + q->tqe_len))) { /* It consumes it all */ /** * next seg---->+ * v * reassembly buffer |--| |---| * new segment |----------| */ #ifdef TCP_REASS_COUNTERS counter_u64_add(reass_path7, 1); #endif tcp_reass_replace(tp, q, m, th->th_seq, *tlenp, mlast, lenofoh, tcp_get_flags(th)); } else { /* * We just need to prepend the data * to this. It does not overrun * the end. */ /** * next seg---->+ * v * reassembly buffer |--| |---| * new segment |----------| */ tcp_reass_prepend(tp, q, m, th, *tlenp, mlast, lenofoh); tp->t_segqmbuflen += lenofoh; } } /* Now does it go further than that? */ tcp_reass_merge_forward(tp, q); *seq_start = q->tqe_start; *tlenp = q->tqe_len; goto present; /* * When we reach here we can't combine it * with any existing segment. * * Limit the number of segments that can be queued to reduce the * potential for mbuf exhaustion. For best performance, we want to be * able to queue a full window's worth of segments. The size of the * socket receive buffer determines our advertised window and grows * automatically when socket buffer autotuning is enabled. Use it as the * basis for our queue limit. * * However, allow the user to specify a ceiling for the number of * segments in each queue. * * Always let the missing segment through which caused this queue. * NB: Access to the socket buffer is left intentionally unlocked as we * can tolerate stale information here. * * XXXLAS: Using sbspace(so->so_rcv) instead of so->so_rcv.sb_hiwat * should work but causes packets to be dropped when they shouldn't. * Investigate why and re-evaluate the below limit after the behaviour * is understood. */ new_entry: if (th->th_seq == tp->rcv_nxt && TCPS_HAVEESTABLISHED(tp->t_state)) { tp->rcv_nxt += *tlenp; flags = tcp_get_flags(th) & TH_FIN; TCPSTAT_INC(tcps_rcvoopack); TCPSTAT_ADD(tcps_rcvoobyte, *tlenp); SOCKBUF_LOCK(&so->so_rcv); if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { m_freem(m); } else { sbappendstream_locked(&so->so_rcv, m, 0); } tp->t_flags |= TF_WAKESOR; return (flags); } if (tcp_new_limits) { if ((tp->t_segqlen > tcp_reass_queue_guard) && (*tlenp < MSIZE)) { /* * This is really a lie, we are not full but * are getting a segment that is above * guard threshold. If it is and its below * a mbuf size (256) we drop it if it * can't fill in some place. */ TCPSTAT_INC(tcps_rcvreassfull); *tlenp = 0; if ((s = tcp_log_addrs(&inp->inp_inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: queue limit reached, " "segment dropped\n", s, __func__); free(s, M_TCPLOG); } m_freem(m); #ifdef TCP_REASS_LOGGING tcp_reass_log_dump(tp); #endif return (0); } } else { if (tp->t_segqlen >= min((so->so_rcv.sb_hiwat / tp->t_maxseg) + 1, tcp_reass_maxqueuelen)) { TCPSTAT_INC(tcps_rcvreassfull); *tlenp = 0; if ((s = tcp_log_addrs(&inp->inp_inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: queue limit reached, " "segment dropped\n", s, __func__); free(s, M_TCPLOG); } m_freem(m); #ifdef TCP_REASS_LOGGING tcp_reass_log_dump(tp); #endif return (0); } } /* * Allocate a new queue entry. If we can't, or hit the zone limit * just drop the pkt. */ te = uma_zalloc(tcp_reass_zone, M_NOWAIT); if (te == NULL) { TCPSTAT_INC(tcps_rcvmemdrop); m_freem(m); *tlenp = 0; if ((s = tcp_log_addrs(&inp->inp_inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: global zone limit " "reached, segment dropped\n", s, __func__); free(s, M_TCPLOG); } return (0); } tp->t_segqlen++; tp->t_rcvoopack++; TCPSTAT_INC(tcps_rcvoopack); TCPSTAT_ADD(tcps_rcvoobyte, *tlenp); /* Insert the new segment queue entry into place. */ te->tqe_m = m; te->tqe_flags = tcp_get_flags(th); te->tqe_len = *tlenp; te->tqe_start = th->th_seq; te->tqe_last = mlast; te->tqe_mbuf_cnt = lenofoh; tp->t_segqmbuflen += te->tqe_mbuf_cnt; if (p == NULL) { TAILQ_INSERT_HEAD(&tp->t_segq, te, tqe_q); } else { TAILQ_INSERT_AFTER(&tp->t_segq, p, te, tqe_q); } #ifdef TCP_REASS_LOGGING tcp_reass_log_new_in(tp, th->th_seq, *tlenp, m, TCP_R_LOG_NEW_ENTRY, te); #endif present: /* * Present data to user, advancing rcv_nxt through * completed sequence space. */ if (!TCPS_HAVEESTABLISHED(tp->t_state)) return (0); q = TAILQ_FIRST(&tp->t_segq); KASSERT(q == NULL || SEQ_GEQ(q->tqe_start, tp->rcv_nxt), ("Reassembly queue for %p has stale entry at head", tp)); if (!q || q->tqe_start != tp->rcv_nxt) { #ifdef TCP_REASS_LOGGING tcp_reass_log_dump(tp); #endif return (0); } SOCKBUF_LOCK(&so->so_rcv); do { tp->rcv_nxt += q->tqe_len; flags = q->tqe_flags & TH_FIN; nq = TAILQ_NEXT(q, tqe_q); TAILQ_REMOVE(&tp->t_segq, q, tqe_q); if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { m_freem(q->tqe_m); } else { #ifdef TCP_REASS_LOGGING tcp_reass_log_new_in(tp, q->tqe_start, q->tqe_len, q->tqe_m, TCP_R_LOG_READ, q); if (th != NULL) { tcp_log_reassm(tp, q, NULL, th->th_seq, *tlenp, TCP_R_LOG_READ, 1); } else { tcp_log_reassm(tp, q, NULL, 0, 0, TCP_R_LOG_READ, 1); } #endif sbappendstream_locked(&so->so_rcv, q->tqe_m, 0); } #ifdef TCP_REASS_LOGGING if (th != NULL) { tcp_log_reassm(tp, q, NULL, th->th_seq, *tlenp, TCP_R_LOG_READ, 2); } else { tcp_log_reassm(tp, q, NULL, 0, 0, TCP_R_LOG_READ, 2); } #endif KASSERT(tp->t_segqmbuflen >= q->tqe_mbuf_cnt, ("tp:%p seg queue goes negative", tp)); tp->t_segqmbuflen -= q->tqe_mbuf_cnt; uma_zfree(tcp_reass_zone, q); tp->t_segqlen--; q = nq; } while (q && q->tqe_start == tp->rcv_nxt); if (TAILQ_EMPTY(&tp->t_segq) && (tp->t_segqmbuflen != 0)) { #ifdef INVARIANTS panic("tp:%p segq:%p len:%d queue empty", tp, &tp->t_segq, tp->t_segqmbuflen); #else #ifdef TCP_REASS_LOGGING if (th != NULL) { tcp_log_reassm(tp, NULL, NULL, th->th_seq, *tlenp, TCP_R_LOG_ZERO, 0); } else { tcp_log_reassm(tp, NULL, NULL, 0, 0, TCP_R_LOG_ZERO, 0); } #endif tp->t_segqmbuflen = 0; #endif } #ifdef TCP_REASS_LOGGING tcp_reass_log_dump(tp); #endif tp->t_flags |= TF_WAKESOR; return (flags); } diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c index 23ebb346ff5e..558773f91228 100644 --- a/sys/netinet/tcp_sack.c +++ b/sys/netinet/tcp_sack.c @@ -1,1074 +1,1070 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995 * The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * @(#)tcp_sack.c 8.12 (Berkeley) 5/24/95 */ /*- * @@(#)COPYRIGHT 1.1 (NRL) 17 January 1995 * * NRL grants permission for redistribution and use in source and binary * forms, with or without modification, of the software and documentation * created at NRL provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgements: * This product includes software developed by the University of * California, Berkeley and its contributors. * This product includes software developed at the Information * Technology Division, US Naval Research Laboratory. * 4. Neither the name of the NRL nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL 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 NRL 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. * * The views and conclusions contained in the software and documentation * are those of the authors and should not be interpreted as representing * official policies, either expressed or implied, of the US Naval * Research Laboratory (NRL). */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" -#include "opt_tcpdebug.h" #include #include #include #include #include #include #include /* for proc0 declaration */ #include #include #include #include #include #include /* before tcp_seq.h, for tcp_random18() */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#ifdef TCPDEBUG -#include -#endif /* TCPDEBUG */ #include VNET_DECLARE(struct uma_zone *, sack_hole_zone); #define V_sack_hole_zone VNET(sack_hole_zone) SYSCTL_NODE(_net_inet_tcp, OID_AUTO, sack, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "TCP SACK"); VNET_DEFINE(int, tcp_do_sack) = 1; SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO, enable, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_sack), 0, "Enable/Disable TCP SACK support"); VNET_DEFINE(int, tcp_do_newsack) = 1; SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO, revised, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_newsack), 0, "Use revised SACK loss recovery per RFC 6675"); VNET_DEFINE(int, tcp_sack_maxholes) = 128; SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO, maxholes, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_sack_maxholes), 0, "Maximum number of TCP SACK holes allowed per connection"); VNET_DEFINE(int, tcp_sack_globalmaxholes) = 65536; SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO, globalmaxholes, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_sack_globalmaxholes), 0, "Global maximum number of TCP SACK holes"); VNET_DEFINE(int, tcp_sack_globalholes) = 0; SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO, globalholes, CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(tcp_sack_globalholes), 0, "Global number of TCP SACK holes currently allocated"); int tcp_dsack_block_exists(struct tcpcb *tp) { /* Return true if a DSACK block exists */ if (tp->rcv_numsacks == 0) return (0); if (SEQ_LEQ(tp->sackblks[0].end, tp->rcv_nxt)) return(1); return (0); } /* * This function will find overlaps with the currently stored sackblocks * and add any overlap as a dsack block upfront */ void tcp_update_dsack_list(struct tcpcb *tp, tcp_seq rcv_start, tcp_seq rcv_end) { struct sackblk head_blk,mid_blk,saved_blks[MAX_SACK_BLKS]; int i, j, n, identical; tcp_seq start, end; INP_WLOCK_ASSERT(tptoinpcb(tp)); KASSERT(SEQ_LT(rcv_start, rcv_end), ("rcv_start < rcv_end")); if (SEQ_LT(rcv_end, tp->rcv_nxt) || ((rcv_end == tp->rcv_nxt) && (tp->rcv_numsacks > 0 ) && (tp->sackblks[0].end == tp->rcv_nxt))) { saved_blks[0].start = rcv_start; saved_blks[0].end = rcv_end; } else { saved_blks[0].start = saved_blks[0].end = 0; } head_blk.start = head_blk.end = 0; mid_blk.start = rcv_start; mid_blk.end = rcv_end; identical = 0; for (i = 0; i < tp->rcv_numsacks; i++) { start = tp->sackblks[i].start; end = tp->sackblks[i].end; if (SEQ_LT(rcv_end, start)) { /* pkt left to sack blk */ continue; } if (SEQ_GT(rcv_start, end)) { /* pkt right to sack blk */ continue; } if (SEQ_GT(tp->rcv_nxt, end)) { if ((SEQ_MAX(rcv_start, start) != SEQ_MIN(rcv_end, end)) && (SEQ_GT(head_blk.start, SEQ_MAX(rcv_start, start)) || (head_blk.start == head_blk.end))) { head_blk.start = SEQ_MAX(rcv_start, start); head_blk.end = SEQ_MIN(rcv_end, end); } continue; } if (((head_blk.start == head_blk.end) || SEQ_LT(start, head_blk.start)) && (SEQ_GT(end, rcv_start) && SEQ_LEQ(start, rcv_end))) { head_blk.start = start; head_blk.end = end; } mid_blk.start = SEQ_MIN(mid_blk.start, start); mid_blk.end = SEQ_MAX(mid_blk.end, end); if ((mid_blk.start == start) && (mid_blk.end == end)) identical = 1; } if (SEQ_LT(head_blk.start, head_blk.end)) { /* store overlapping range */ saved_blks[0].start = SEQ_MAX(rcv_start, head_blk.start); saved_blks[0].end = SEQ_MIN(rcv_end, head_blk.end); } n = 1; /* * Second, if not ACKed, store the SACK block that * overlaps with the DSACK block unless it is identical */ if ((SEQ_LT(tp->rcv_nxt, mid_blk.end) && !((mid_blk.start == saved_blks[0].start) && (mid_blk.end == saved_blks[0].end))) || identical == 1) { saved_blks[n].start = mid_blk.start; saved_blks[n++].end = mid_blk.end; } for (j = 0; (j < tp->rcv_numsacks) && (n < MAX_SACK_BLKS); j++) { if (((SEQ_LT(tp->sackblks[j].end, mid_blk.start) || SEQ_GT(tp->sackblks[j].start, mid_blk.end)) && (SEQ_GT(tp->sackblks[j].start, tp->rcv_nxt)))) saved_blks[n++] = tp->sackblks[j]; } j = 0; for (i = 0; i < n; i++) { /* we can end up with a stale initial entry */ if (SEQ_LT(saved_blks[i].start, saved_blks[i].end)) { tp->sackblks[j++] = saved_blks[i]; } } tp->rcv_numsacks = j; } /* * This function is called upon receipt of new valid data (while not in * header prediction mode), and it updates the ordered list of sacks. */ void tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_start, tcp_seq rcv_end) { /* * First reported block MUST be the most recent one. Subsequent * blocks SHOULD be in the order in which they arrived at the * receiver. These two conditions make the implementation fully * compliant with RFC 2018. */ struct sackblk head_blk, saved_blks[MAX_SACK_BLKS]; int num_head, num_saved, i; INP_WLOCK_ASSERT(tptoinpcb(tp)); /* Check arguments. */ KASSERT(SEQ_LEQ(rcv_start, rcv_end), ("rcv_start <= rcv_end")); if ((rcv_start == rcv_end) && (tp->rcv_numsacks >= 1) && (rcv_end == tp->sackblks[0].end)) { /* retaining DSACK block below rcv_nxt (todrop) */ head_blk = tp->sackblks[0]; } else { /* SACK block for the received segment. */ head_blk.start = rcv_start; head_blk.end = rcv_end; } /* * Merge updated SACK blocks into head_blk, and save unchanged SACK * blocks into saved_blks[]. num_saved will have the number of the * saved SACK blocks. */ num_saved = 0; for (i = 0; i < tp->rcv_numsacks; i++) { tcp_seq start = tp->sackblks[i].start; tcp_seq end = tp->sackblks[i].end; if (SEQ_GEQ(start, end) || SEQ_LEQ(start, tp->rcv_nxt)) { /* * Discard this SACK block. */ } else if (SEQ_LEQ(head_blk.start, end) && SEQ_GEQ(head_blk.end, start)) { /* * Merge this SACK block into head_blk. This SACK * block itself will be discarded. */ /* * |-| * |---| merge * * |-| * |---| merge * * |-----| * |-| DSACK smaller * * |-| * |-----| DSACK smaller */ if (head_blk.start == end) head_blk.start = start; else if (head_blk.end == start) head_blk.end = end; else { if (SEQ_LT(head_blk.start, start)) { tcp_seq temp = start; start = head_blk.start; head_blk.start = temp; } if (SEQ_GT(head_blk.end, end)) { tcp_seq temp = end; end = head_blk.end; head_blk.end = temp; } if ((head_blk.start != start) || (head_blk.end != end)) { if ((num_saved >= 1) && SEQ_GEQ(saved_blks[num_saved-1].start, start) && SEQ_LEQ(saved_blks[num_saved-1].end, end)) num_saved--; saved_blks[num_saved].start = start; saved_blks[num_saved].end = end; num_saved++; } } } else { /* * This block supercedes the prior block */ if ((num_saved >= 1) && SEQ_GEQ(saved_blks[num_saved-1].start, start) && SEQ_LEQ(saved_blks[num_saved-1].end, end)) num_saved--; /* * Save this SACK block. */ saved_blks[num_saved].start = start; saved_blks[num_saved].end = end; num_saved++; } } /* * Update SACK list in tp->sackblks[]. */ num_head = 0; if (SEQ_LT(rcv_start, rcv_end)) { /* * The received data segment is an out-of-order segment. Put * head_blk at the top of SACK list. */ tp->sackblks[0] = head_blk; num_head = 1; /* * If the number of saved SACK blocks exceeds its limit, * discard the last SACK block. */ if (num_saved >= MAX_SACK_BLKS) num_saved--; } if ((rcv_start == rcv_end) && (rcv_start == tp->sackblks[0].end)) { num_head = 1; } if (num_saved > 0) { /* * Copy the saved SACK blocks back. */ bcopy(saved_blks, &tp->sackblks[num_head], sizeof(struct sackblk) * num_saved); } /* Save the number of SACK blocks. */ tp->rcv_numsacks = num_head + num_saved; } void tcp_clean_dsack_blocks(struct tcpcb *tp) { struct sackblk saved_blks[MAX_SACK_BLKS]; int num_saved, i; INP_WLOCK_ASSERT(tptoinpcb(tp)); /* * Clean up any DSACK blocks that * are in our queue of sack blocks. * */ num_saved = 0; for (i = 0; i < tp->rcv_numsacks; i++) { tcp_seq start = tp->sackblks[i].start; tcp_seq end = tp->sackblks[i].end; if (SEQ_GEQ(start, end) || SEQ_LEQ(start, tp->rcv_nxt)) { /* * Discard this D-SACK block. */ continue; } /* * Save this SACK block. */ saved_blks[num_saved].start = start; saved_blks[num_saved].end = end; num_saved++; } if (num_saved > 0) { /* * Copy the saved SACK blocks back. */ bcopy(saved_blks, &tp->sackblks[0], sizeof(struct sackblk) * num_saved); } tp->rcv_numsacks = num_saved; } /* * Delete all receiver-side SACK information. */ void tcp_clean_sackreport(struct tcpcb *tp) { int i; INP_WLOCK_ASSERT(tptoinpcb(tp)); tp->rcv_numsacks = 0; for (i = 0; i < MAX_SACK_BLKS; i++) tp->sackblks[i].start = tp->sackblks[i].end=0; } /* * Allocate struct sackhole. */ static struct sackhole * tcp_sackhole_alloc(struct tcpcb *tp, tcp_seq start, tcp_seq end) { struct sackhole *hole; if (tp->snd_numholes >= V_tcp_sack_maxholes || V_tcp_sack_globalholes >= V_tcp_sack_globalmaxholes) { TCPSTAT_INC(tcps_sack_sboverflow); return NULL; } hole = (struct sackhole *)uma_zalloc(V_sack_hole_zone, M_NOWAIT); if (hole == NULL) return NULL; hole->start = start; hole->end = end; hole->rxmit = start; tp->snd_numholes++; atomic_add_int(&V_tcp_sack_globalholes, 1); return hole; } /* * Free struct sackhole. */ static void tcp_sackhole_free(struct tcpcb *tp, struct sackhole *hole) { uma_zfree(V_sack_hole_zone, hole); tp->snd_numholes--; atomic_subtract_int(&V_tcp_sack_globalholes, 1); KASSERT(tp->snd_numholes >= 0, ("tp->snd_numholes >= 0")); KASSERT(V_tcp_sack_globalholes >= 0, ("tcp_sack_globalholes >= 0")); } /* * Insert new SACK hole into scoreboard. */ static struct sackhole * tcp_sackhole_insert(struct tcpcb *tp, tcp_seq start, tcp_seq end, struct sackhole *after) { struct sackhole *hole; /* Allocate a new SACK hole. */ hole = tcp_sackhole_alloc(tp, start, end); if (hole == NULL) return NULL; /* Insert the new SACK hole into scoreboard. */ if (after != NULL) TAILQ_INSERT_AFTER(&tp->snd_holes, after, hole, scblink); else TAILQ_INSERT_TAIL(&tp->snd_holes, hole, scblink); /* Update SACK hint. */ if (tp->sackhint.nexthole == NULL) tp->sackhint.nexthole = hole; return hole; } /* * Remove SACK hole from scoreboard. */ static void tcp_sackhole_remove(struct tcpcb *tp, struct sackhole *hole) { /* Update SACK hint. */ if (tp->sackhint.nexthole == hole) tp->sackhint.nexthole = TAILQ_NEXT(hole, scblink); /* Remove this SACK hole. */ TAILQ_REMOVE(&tp->snd_holes, hole, scblink); /* Free this SACK hole. */ tcp_sackhole_free(tp, hole); } /* * Process cumulative ACK and the TCP SACK option to update the scoreboard. * tp->snd_holes is an ordered list of holes (oldest to newest, in terms of * the sequence space). * Returns 1 if incoming ACK has previously unknown SACK information, * 0 otherwise. */ int tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) { struct sackhole *cur, *temp; struct sackblk sack, sack_blocks[TCP_MAX_SACK + 1], *sblkp; int i, j, num_sack_blks, sack_changed; int delivered_data, left_edge_delta; INP_WLOCK_ASSERT(tptoinpcb(tp)); num_sack_blks = 0; sack_changed = 0; delivered_data = 0; left_edge_delta = 0; /* * If SND.UNA will be advanced by SEG.ACK, and if SACK holes exist, * treat [SND.UNA, SEG.ACK) as if it is a SACK block. * Account changes to SND.UNA always in delivered data. */ if (SEQ_LT(tp->snd_una, th_ack) && !TAILQ_EMPTY(&tp->snd_holes)) { left_edge_delta = th_ack - tp->snd_una; sack_blocks[num_sack_blks].start = tp->snd_una; sack_blocks[num_sack_blks++].end = th_ack; /* * Pulling snd_fack forward if we got here * due to DSACK blocks */ if (SEQ_LT(tp->snd_fack, th_ack)) { delivered_data += th_ack - tp->snd_una; tp->snd_fack = th_ack; sack_changed = 1; } } /* * Append received valid SACK blocks to sack_blocks[], but only if we * received new blocks from the other side. */ if (to->to_flags & TOF_SACK) { for (i = 0; i < to->to_nsacks; i++) { bcopy((to->to_sacks + i * TCPOLEN_SACK), &sack, sizeof(sack)); sack.start = ntohl(sack.start); sack.end = ntohl(sack.end); if (SEQ_GT(sack.end, sack.start) && SEQ_GT(sack.start, tp->snd_una) && SEQ_GT(sack.start, th_ack) && SEQ_LT(sack.start, tp->snd_max) && SEQ_GT(sack.end, tp->snd_una) && SEQ_LEQ(sack.end, tp->snd_max)) { sack_blocks[num_sack_blks++] = sack; } else if (SEQ_LEQ(sack.start, th_ack) && SEQ_LEQ(sack.end, th_ack)) { /* * Its a D-SACK block. */ tcp_record_dsack(tp, sack.start, sack.end, 0); } } } /* * Return if SND.UNA is not advanced and no valid SACK block is * received. */ if (num_sack_blks == 0) return (sack_changed); /* * Sort the SACK blocks so we can update the scoreboard with just one * pass. The overhead of sorting up to 4+1 elements is less than * making up to 4+1 passes over the scoreboard. */ for (i = 0; i < num_sack_blks; i++) { for (j = i + 1; j < num_sack_blks; j++) { if (SEQ_GT(sack_blocks[i].end, sack_blocks[j].end)) { sack = sack_blocks[i]; sack_blocks[i] = sack_blocks[j]; sack_blocks[j] = sack; } } } if (TAILQ_EMPTY(&tp->snd_holes)) { /* * Empty scoreboard. Need to initialize snd_fack (it may be * uninitialized or have a bogus value). Scoreboard holes * (from the sack blocks received) are created later below * (in the logic that adds holes to the tail of the * scoreboard). */ tp->snd_fack = SEQ_MAX(tp->snd_una, th_ack); tp->sackhint.sacked_bytes = 0; /* reset */ } /* * In the while-loop below, incoming SACK blocks (sack_blocks[]) and * SACK holes (snd_holes) are traversed from their tails with just * one pass in order to reduce the number of compares especially when * the bandwidth-delay product is large. * * Note: Typically, in the first RTT of SACK recovery, the highest * three or four SACK blocks with the same ack number are received. * In the second RTT, if retransmitted data segments are not lost, * the highest three or four SACK blocks with ack number advancing * are received. */ sblkp = &sack_blocks[num_sack_blks - 1]; /* Last SACK block */ tp->sackhint.last_sack_ack = sblkp->end; if (SEQ_LT(tp->snd_fack, sblkp->start)) { /* * The highest SACK block is beyond fack. First, * check if there was a successful Rescue Retransmission, * and move this hole left. With normal holes, snd_fack * is always to the right of the end. */ if (((temp = TAILQ_LAST(&tp->snd_holes, sackhole_head)) != NULL) && SEQ_LEQ(tp->snd_fack,temp->end)) { temp->start = SEQ_MAX(tp->snd_fack, SEQ_MAX(tp->snd_una, th_ack)); temp->end = sblkp->start; temp->rxmit = temp->start; delivered_data += sblkp->end - sblkp->start; tp->snd_fack = sblkp->end; sblkp--; sack_changed = 1; } else { /* * Append a new SACK hole at the tail. If the * second or later highest SACK blocks are also * beyond the current fack, they will be inserted * by way of hole splitting in the while-loop below. */ temp = tcp_sackhole_insert(tp, tp->snd_fack,sblkp->start,NULL); if (temp != NULL) { delivered_data += sblkp->end - sblkp->start; tp->snd_fack = sblkp->end; /* Go to the previous sack block. */ sblkp--; sack_changed = 1; } else { /* * We failed to add a new hole based on the current * sack block. Skip over all the sack blocks that * fall completely to the right of snd_fack and * proceed to trim the scoreboard based on the * remaining sack blocks. This also trims the * scoreboard for th_ack (which is sack_blocks[0]). */ while (sblkp >= sack_blocks && SEQ_LT(tp->snd_fack, sblkp->start)) sblkp--; if (sblkp >= sack_blocks && SEQ_LT(tp->snd_fack, sblkp->end)) { delivered_data += sblkp->end - tp->snd_fack; tp->snd_fack = sblkp->end; sack_changed = 1; } } } } else if (SEQ_LT(tp->snd_fack, sblkp->end)) { /* fack is advanced. */ delivered_data += sblkp->end - tp->snd_fack; tp->snd_fack = sblkp->end; sack_changed = 1; } cur = TAILQ_LAST(&tp->snd_holes, sackhole_head); /* Last SACK hole. */ /* * Since the incoming sack blocks are sorted, we can process them * making one sweep of the scoreboard. */ while (sblkp >= sack_blocks && cur != NULL) { if (SEQ_GEQ(sblkp->start, cur->end)) { /* * SACKs data beyond the current hole. Go to the * previous sack block. */ sblkp--; continue; } if (SEQ_LEQ(sblkp->end, cur->start)) { /* * SACKs data before the current hole. Go to the * previous hole. */ cur = TAILQ_PREV(cur, sackhole_head, scblink); continue; } tp->sackhint.sack_bytes_rexmit -= (SEQ_MIN(cur->rxmit, cur->end) - cur->start); KASSERT(tp->sackhint.sack_bytes_rexmit >= 0, ("sackhint bytes rtx >= 0")); sack_changed = 1; if (SEQ_LEQ(sblkp->start, cur->start)) { /* Data acks at least the beginning of hole. */ if (SEQ_GEQ(sblkp->end, cur->end)) { /* Acks entire hole, so delete hole. */ delivered_data += (cur->end - cur->start); temp = cur; cur = TAILQ_PREV(cur, sackhole_head, scblink); tcp_sackhole_remove(tp, temp); /* * The sack block may ack all or part of the * next hole too, so continue onto the next * hole. */ continue; } else { /* Move start of hole forward. */ delivered_data += (sblkp->end - cur->start); cur->start = sblkp->end; cur->rxmit = SEQ_MAX(cur->rxmit, cur->start); } } else { /* Data acks at least the end of hole. */ if (SEQ_GEQ(sblkp->end, cur->end)) { /* Move end of hole backward. */ delivered_data += (cur->end - sblkp->start); cur->end = sblkp->start; cur->rxmit = SEQ_MIN(cur->rxmit, cur->end); if ((tp->t_flags & TF_LRD) && SEQ_GEQ(cur->rxmit, cur->end)) cur->rxmit = tp->snd_recover; } else { /* * ACKs some data in middle of a hole; need * to split current hole */ temp = tcp_sackhole_insert(tp, sblkp->end, cur->end, cur); if (temp != NULL) { if (SEQ_GT(cur->rxmit, temp->rxmit)) { temp->rxmit = cur->rxmit; tp->sackhint.sack_bytes_rexmit += (SEQ_MIN(temp->rxmit, temp->end) - temp->start); } cur->end = sblkp->start; cur->rxmit = SEQ_MIN(cur->rxmit, cur->end); if ((tp->t_flags & TF_LRD) && SEQ_GEQ(cur->rxmit, cur->end)) cur->rxmit = tp->snd_recover; delivered_data += (sblkp->end - sblkp->start); } } } tp->sackhint.sack_bytes_rexmit += (SEQ_MIN(cur->rxmit, cur->end) - cur->start); /* * Testing sblkp->start against cur->start tells us whether * we're done with the sack block or the sack hole. * Accordingly, we advance one or the other. */ if (SEQ_LEQ(sblkp->start, cur->start)) cur = TAILQ_PREV(cur, sackhole_head, scblink); else sblkp--; } if (!(to->to_flags & TOF_SACK)) /* * If this ACK did not contain any * SACK blocks, any only moved the * left edge right, it is a pure * cumulative ACK. Do not count * DupAck for this. Also required * for RFC6675 rescue retransmission. */ sack_changed = 0; tp->sackhint.delivered_data = delivered_data; tp->sackhint.sacked_bytes += delivered_data - left_edge_delta; KASSERT((delivered_data >= 0), ("delivered_data < 0")); KASSERT((tp->sackhint.sacked_bytes >= 0), ("sacked_bytes < 0")); return (sack_changed); } /* * Free all SACK holes to clear the scoreboard. */ void tcp_free_sackholes(struct tcpcb *tp) { struct sackhole *q; INP_WLOCK_ASSERT(tptoinpcb(tp)); while ((q = TAILQ_FIRST(&tp->snd_holes)) != NULL) tcp_sackhole_remove(tp, q); tp->sackhint.sack_bytes_rexmit = 0; KASSERT(tp->snd_numholes == 0, ("tp->snd_numholes == 0")); KASSERT(tp->sackhint.nexthole == NULL, ("tp->sackhint.nexthole == NULL")); } /* * Partial ack handling within a sack recovery episode. Keeping this very * simple for now. When a partial ack is received, force snd_cwnd to a value * that will allow the sender to transmit no more than 2 segments. If * necessary, a better scheme can be adopted at a later point, but for now, * the goal is to prevent the sender from bursting a large amount of data in * the midst of sack recovery. */ void tcp_sack_partialack(struct tcpcb *tp, struct tcphdr *th) { int num_segs = 1; u_int maxseg = tcp_maxseg(tp); INP_WLOCK_ASSERT(tptoinpcb(tp)); tcp_timer_activate(tp, TT_REXMT, 0); tp->t_rtttime = 0; /* Send one or 2 segments based on how much new data was acked. */ if ((BYTES_THIS_ACK(tp, th) / maxseg) >= 2) num_segs = 2; tp->snd_cwnd = (tp->sackhint.sack_bytes_rexmit + (tp->snd_nxt - tp->snd_recover) + num_segs * maxseg); if (tp->snd_cwnd > tp->snd_ssthresh) tp->snd_cwnd = tp->snd_ssthresh; tp->t_flags |= TF_ACKNOW; /* * RFC6675 rescue retransmission * Add a hole between th_ack (snd_una is not yet set) and snd_max, * if this was a pure cumulative ACK and no data was send beyond * recovery point. Since the data in the socket has not been freed * at this point, we check if the scoreboard is empty, and the ACK * delivered some new data, indicating a full ACK. Also, if the * recovery point is still at snd_max, we are probably application * limited. However, this inference might not always be true. The * rescue retransmission may rarely be slightly premature * compared to RFC6675. * The corresponding ACK+SACK will cause any further outstanding * segments to be retransmitted. This addresses a corner case, when * the trailing packets of a window are lost and no further data * is available for sending. */ if ((V_tcp_do_newsack) && SEQ_LT(th->th_ack, tp->snd_recover) && (tp->snd_recover == tp->snd_max) && TAILQ_EMPTY(&tp->snd_holes) && (tp->sackhint.delivered_data > 0)) { /* * Exclude FIN sequence space in * the hole for the rescue retransmission, * and also don't create a hole, if only * the ACK for a FIN is outstanding. */ tcp_seq highdata = tp->snd_max; if (tp->t_flags & TF_SENTFIN) highdata--; if (th->th_ack != highdata) { tp->snd_fack = th->th_ack; (void)tcp_sackhole_insert(tp, SEQ_MAX(th->th_ack, highdata - maxseg), highdata, NULL); } } (void) tcp_output(tp); } #if 0 /* * Debug version of tcp_sack_output() that walks the scoreboard. Used for * now to sanity check the hint. */ static struct sackhole * tcp_sack_output_debug(struct tcpcb *tp, int *sack_bytes_rexmt) { struct sackhole *p; INP_WLOCK_ASSERT(tptoinpcb(tp)); *sack_bytes_rexmt = 0; TAILQ_FOREACH(p, &tp->snd_holes, scblink) { if (SEQ_LT(p->rxmit, p->end)) { if (SEQ_LT(p->rxmit, tp->snd_una)) {/* old SACK hole */ continue; } *sack_bytes_rexmt += (p->rxmit - p->start); break; } *sack_bytes_rexmt += (SEQ_MIN(p->rxmit, p->end) - p->start); } return (p); } #endif /* * Returns the next hole to retransmit and the number of retransmitted bytes * from the scoreboard. We store both the next hole and the number of * retransmitted bytes as hints (and recompute these on the fly upon SACK/ACK * reception). This avoids scoreboard traversals completely. * * The loop here will traverse *at most* one link. Here's the argument. For * the loop to traverse more than 1 link before finding the next hole to * retransmit, we would need to have at least 1 node following the current * hint with (rxmit == end). But, for all holes following the current hint, * (start == rxmit), since we have not yet retransmitted from them. * Therefore, in order to traverse more 1 link in the loop below, we need to * have at least one node following the current hint with (start == rxmit == * end). But that can't happen, (start == end) means that all the data in * that hole has been sacked, in which case, the hole would have been removed * from the scoreboard. */ struct sackhole * tcp_sack_output(struct tcpcb *tp, int *sack_bytes_rexmt) { struct sackhole *hole = NULL; INP_WLOCK_ASSERT(tptoinpcb(tp)); *sack_bytes_rexmt = tp->sackhint.sack_bytes_rexmit; hole = tp->sackhint.nexthole; if (hole == NULL) return (hole); if (SEQ_GEQ(hole->rxmit, hole->end)) { for (;;) { hole = TAILQ_NEXT(hole, scblink); if (hole == NULL) return (hole); if (SEQ_LT(hole->rxmit, hole->end)) { tp->sackhint.nexthole = hole; break; } } } KASSERT(SEQ_LT(hole->start, hole->end), ("%s: hole.start >= hole.end", __func__)); if (!(V_tcp_do_newsack)) { KASSERT(SEQ_LT(hole->start, tp->snd_fack), ("%s: hole.start >= snd.fack", __func__)); KASSERT(SEQ_LT(hole->end, tp->snd_fack), ("%s: hole.end >= snd.fack", __func__)); KASSERT(SEQ_LT(hole->rxmit, tp->snd_fack), ("%s: hole.rxmit >= snd.fack", __func__)); if (SEQ_GEQ(hole->start, hole->end) || SEQ_GEQ(hole->start, tp->snd_fack) || SEQ_GEQ(hole->end, tp->snd_fack) || SEQ_GEQ(hole->rxmit, tp->snd_fack)) { log(LOG_CRIT,"tcp: invalid SACK hole (%u-%u,%u) vs fwd ack %u, ignoring.\n", hole->start, hole->end, hole->rxmit, tp->snd_fack); return (NULL); } } return (hole); } /* * After a timeout, the SACK list may be rebuilt. This SACK information * should be used to avoid retransmitting SACKed data. This function * traverses the SACK list to see if snd_nxt should be moved forward. */ void tcp_sack_adjust(struct tcpcb *tp) { struct sackhole *p, *cur = TAILQ_FIRST(&tp->snd_holes); INP_WLOCK_ASSERT(tptoinpcb(tp)); if (cur == NULL) return; /* No holes */ if (SEQ_GEQ(tp->snd_nxt, tp->snd_fack)) return; /* We're already beyond any SACKed blocks */ /*- * Two cases for which we want to advance snd_nxt: * i) snd_nxt lies between end of one hole and beginning of another * ii) snd_nxt lies between end of last hole and snd_fack */ while ((p = TAILQ_NEXT(cur, scblink)) != NULL) { if (SEQ_LT(tp->snd_nxt, cur->end)) return; if (SEQ_GEQ(tp->snd_nxt, p->start)) cur = p; else { tp->snd_nxt = p->start; return; } } if (SEQ_LT(tp->snd_nxt, cur->end)) return; tp->snd_nxt = tp->snd_fack; } /* * Lost Retransmission Detection * Check is FACK is beyond the rexmit of the leftmost hole. * If yes, we restart sending from still existing holes, * and adjust cwnd via the congestion control module. */ void tcp_sack_lost_retransmission(struct tcpcb *tp, struct tcphdr *th) { struct sackhole *temp; if (IN_RECOVERY(tp->t_flags) && SEQ_GT(tp->snd_fack, tp->snd_recover) && ((temp = TAILQ_FIRST(&tp->snd_holes)) != NULL) && SEQ_GEQ(temp->rxmit, temp->end) && SEQ_GEQ(tp->snd_fack, temp->rxmit)) { TCPSTAT_INC(tcps_sack_lostrexmt); /* * Start retransmissions from the first hole, and * subsequently all other remaining holes, including * those, which had been sent completely before. */ tp->sackhint.nexthole = temp; TAILQ_FOREACH(temp, &tp->snd_holes, scblink) { if (SEQ_GEQ(tp->snd_fack, temp->rxmit) && SEQ_GEQ(temp->rxmit, temp->end)) temp->rxmit = temp->start; } /* * Remember the old ssthresh, to deduct the beta factor used * by the CC module. Finally, set cwnd to ssthresh just * prior to invoking another cwnd reduction by the CC * module, to not shrink it excessively. */ tp->snd_cwnd = tp->snd_ssthresh; /* * Formally exit recovery, and let the CC module adjust * ssthresh as intended. */ EXIT_RECOVERY(tp->t_flags); cc_cong_signal(tp, th, CC_NDUPACK); /* * For PRR, adjust recover_fs as if this new reduction * initialized this variable. * cwnd will be adjusted by SACK or PRR processing * subsequently, only set it to a safe value here. */ tp->snd_cwnd = tcp_maxseg(tp); tp->sackhint.recover_fs = (tp->snd_max - tp->snd_una) - tp->sackhint.recover_fs; } } diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c index 5a1e3de4c416..4f74fdd1dd76 100644 --- a/sys/netinet/tcp_stacks/bbr.c +++ b/sys/netinet/tcp_stacks/bbr.c @@ -1,14832 +1,14770 @@ /*- * Copyright (c) 2016-2020 Netflix, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * */ /** * Author: Randall Stewart * This work is based on the ACM Queue paper * BBR - Congestion Based Congestion Control * and also numerous discussions with Neal, Yuchung and Van. */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" -#include "opt_tcpdebug.h" #include "opt_ratelimit.h" #include #include #include #include #include #ifdef TCP_HHOOK #include #endif #include #include #include #include #include #include #include #ifdef STATS #include #include #include /* Must come after qmath.h and tree.h */ #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define TCPSTATES /* for logging */ #include #include #include #include #include /* required for icmp_var.h */ #include /* for ICMP_BANDLIM */ #include #include #include #include #define TCPOUTFLAGS #include #include #include #include #include #include #include #include #include #include #include -#ifdef TCPDEBUG -#include -#endif /* TCPDEBUG */ #ifdef TCP_OFFLOAD #include #endif #ifdef INET6 #include #endif #include #include #include #include #include #if defined(IPSEC) || defined(IPSEC_SUPPORT) #include #include #endif /* IPSEC */ #include #include #include #ifdef MAC #include #endif #include "sack_filter.h" #include "tcp_bbr.h" #include "rack_bbr_common.h" uma_zone_t bbr_zone; uma_zone_t bbr_pcb_zone; struct sysctl_ctx_list bbr_sysctl_ctx; struct sysctl_oid *bbr_sysctl_root; #define TCPT_RANGESET_NOSLOP(tv, value, tvmin, tvmax) do { \ (tv) = (value); \ if ((u_long)(tv) < (u_long)(tvmin)) \ (tv) = (tvmin); \ if ((u_long)(tv) > (u_long)(tvmax)) \ (tv) = (tvmax); \ } while(0) /*#define BBR_INVARIANT 1*/ /* * initial window */ static uint32_t bbr_def_init_win = 10; static int32_t bbr_persist_min = 250000; /* 250ms */ static int32_t bbr_persist_max = 1000000; /* 1 Second */ static int32_t bbr_cwnd_may_shrink = 0; static int32_t bbr_cwndtarget_rtt_touse = BBR_RTT_PROP; static int32_t bbr_num_pktepo_for_del_limit = BBR_NUM_RTTS_FOR_DEL_LIMIT; static int32_t bbr_hardware_pacing_limit = 8000; static int32_t bbr_quanta = 3; /* How much extra quanta do we get? */ static int32_t bbr_no_retran = 0; static int32_t bbr_error_base_paceout = 10000; /* usec to pace */ static int32_t bbr_max_net_error_cnt = 10; /* Should the following be dynamic too -- loss wise */ static int32_t bbr_rtt_gain_thresh = 0; /* Measurement controls */ static int32_t bbr_use_google_algo = 1; static int32_t bbr_ts_limiting = 1; static int32_t bbr_ts_can_raise = 0; static int32_t bbr_do_red = 600; static int32_t bbr_red_scale = 20000; static int32_t bbr_red_mul = 1; static int32_t bbr_red_div = 2; static int32_t bbr_red_growth_restrict = 1; static int32_t bbr_target_is_bbunit = 0; static int32_t bbr_drop_limit = 0; /* * How much gain do we need to see to * stay in startup? */ static int32_t bbr_marks_rxt_sack_passed = 0; static int32_t bbr_start_exit = 25; static int32_t bbr_low_start_exit = 25; /* When we are in reduced gain */ static int32_t bbr_startup_loss_thresh = 2000; /* 20.00% loss */ static int32_t bbr_hptsi_max_mul = 1; /* These two mul/div assure a min pacing */ static int32_t bbr_hptsi_max_div = 2; /* time, 0 means turned off. We need this * if we go back ever to where the pacer * has priority over timers. */ static int32_t bbr_policer_call_from_rack_to = 0; static int32_t bbr_policer_detection_enabled = 1; static int32_t bbr_min_measurements_req = 1; /* We need at least 2 * measurements before we are * "good" note that 2 == 1. * This is because we use a > * comparison. This means if * min_measure was 0, it takes * num-measures > min(0) and * you get 1 measurement and * you are good. Set to 1, you * have to have two * measurements (this is done * to prevent it from being ok * to have no measurements). */ static int32_t bbr_no_pacing_until = 4; static int32_t bbr_min_usec_delta = 20000; /* 20,000 usecs */ static int32_t bbr_min_peer_delta = 20; /* 20 units */ static int32_t bbr_delta_percent = 150; /* 15.0 % */ static int32_t bbr_target_cwnd_mult_limit = 8; /* * bbr_cwnd_min_val is the number of * segments we hold to in the RTT probe * state typically 4. */ static int32_t bbr_cwnd_min_val = BBR_PROBERTT_NUM_MSS; static int32_t bbr_cwnd_min_val_hs = BBR_HIGHSPEED_NUM_MSS; static int32_t bbr_gain_to_target = 1; static int32_t bbr_gain_gets_extra_too = 1; /* * bbr_high_gain is the 2/ln(2) value we need * to double the sending rate in startup. This * is used for both cwnd and hptsi gain's. */ static int32_t bbr_high_gain = BBR_UNIT * 2885 / 1000 + 1; static int32_t bbr_startup_lower = BBR_UNIT * 1500 / 1000 + 1; static int32_t bbr_use_lower_gain_in_startup = 1; /* thresholds for reduction on drain in sub-states/drain */ static int32_t bbr_drain_rtt = BBR_SRTT; static int32_t bbr_drain_floor = 88; static int32_t google_allow_early_out = 1; static int32_t google_consider_lost = 1; static int32_t bbr_drain_drop_mul = 4; static int32_t bbr_drain_drop_div = 5; static int32_t bbr_rand_ot = 50; static int32_t bbr_can_force_probertt = 0; static int32_t bbr_can_adjust_probertt = 1; static int32_t bbr_probertt_sets_rtt = 0; static int32_t bbr_can_use_ts_for_rtt = 1; static int32_t bbr_is_ratio = 0; static int32_t bbr_sub_drain_app_limit = 1; static int32_t bbr_prtt_slam_cwnd = 1; static int32_t bbr_sub_drain_slam_cwnd = 1; static int32_t bbr_slam_cwnd_in_main_drain = 1; static int32_t bbr_filter_len_sec = 6; /* How long does the rttProp filter * hold */ static uint32_t bbr_rtt_probe_limit = (USECS_IN_SECOND * 4); /* * bbr_drain_gain is the reverse of the high_gain * designed to drain back out the standing queue * that is formed in startup by causing a larger * hptsi gain and thus drainging the packets * in flight. */ static int32_t bbr_drain_gain = BBR_UNIT * 1000 / 2885; static int32_t bbr_rttprobe_gain = 192; /* * The cwnd_gain is the default cwnd gain applied when * calculating a target cwnd. Note that the cwnd is * a secondary factor in the way BBR works (see the * paper and think about it, it will take some time). * Basically the hptsi_gain spreads the packets out * so you never get more than BDP to the peer even * if the cwnd is high. In our implemenation that * means in non-recovery/retransmission scenarios * cwnd will never be reached by the flight-size. */ static int32_t bbr_cwnd_gain = BBR_UNIT * 2; static int32_t bbr_tlp_type_to_use = BBR_SRTT; static int32_t bbr_delack_time = 100000; /* 100ms in useconds */ static int32_t bbr_sack_not_required = 0; /* set to one to allow non-sack to use bbr */ static int32_t bbr_initial_bw_bps = 62500; /* 500kbps in bytes ps */ static int32_t bbr_ignore_data_after_close = 1; static int16_t bbr_hptsi_gain[] = { (BBR_UNIT *5 / 4), (BBR_UNIT * 3 / 4), BBR_UNIT, BBR_UNIT, BBR_UNIT, BBR_UNIT, BBR_UNIT, BBR_UNIT }; int32_t bbr_use_rack_resend_cheat = 1; int32_t bbr_sends_full_iwnd = 1; #define BBR_HPTSI_GAIN_MAX 8 /* * The BBR module incorporates a number of * TCP ideas that have been put out into the IETF * over the last few years: * - Yuchung Cheng's RACK TCP (for which its named) that * will stop us using the number of dup acks and instead * use time as the gage of when we retransmit. * - Reorder Detection of RFC4737 and the Tail-Loss probe draft * of Dukkipati et.al. * - Van Jacobson's et.al BBR. * * RACK depends on SACK, so if an endpoint arrives that * cannot do SACK the state machine below will shuttle the * connection back to using the "default" TCP stack that is * in FreeBSD. * * To implement BBR and RACK the original TCP stack was first decomposed * into a functional state machine with individual states * for each of the possible TCP connection states. The do_segment * functions role in life is to mandate the connection supports SACK * initially and then assure that the RACK state matches the conenction * state before calling the states do_segment function. Data processing * of inbound segments also now happens in the hpts_do_segment in general * with only one exception. This is so we can keep the connection on * a single CPU. * * Each state is simplified due to the fact that the original do_segment * has been decomposed and we *know* what state we are in (no * switches on the state) and all tests for SACK are gone. This * greatly simplifies what each state does. * * TCP output is also over-written with a new version since it * must maintain the new rack scoreboard and has had hptsi * integrated as a requirment. Still todo is to eliminate the * use of the callout_() system and use the hpts for all * timers as well. */ static uint32_t bbr_rtt_probe_time = 200000; /* 200ms in micro seconds */ static uint32_t bbr_rtt_probe_cwndtarg = 4; /* How many mss's outstanding */ static const int32_t bbr_min_req_free = 2; /* The min we must have on the * free list */ static int32_t bbr_tlp_thresh = 1; static int32_t bbr_reorder_thresh = 2; static int32_t bbr_reorder_fade = 60000000; /* 0 - never fade, def * 60,000,000 - 60 seconds */ static int32_t bbr_pkt_delay = 1000; static int32_t bbr_min_to = 1000; /* Number of usec's minimum timeout */ static int32_t bbr_incr_timers = 1; static int32_t bbr_tlp_min = 10000; /* 10ms in usecs */ static int32_t bbr_delayed_ack_time = 200000; /* 200ms in usecs */ static int32_t bbr_exit_startup_at_loss = 1; /* * bbr_lt_bw_ratio is 1/8th * bbr_lt_bw_diff is < 4 Kbit/sec */ static uint64_t bbr_lt_bw_diff = 4000 / 8; /* In bytes per second */ static uint64_t bbr_lt_bw_ratio = 8; /* For 1/8th */ static uint32_t bbr_lt_bw_max_rtts = 48; /* How many rtt's do we use * the lt_bw for */ static uint32_t bbr_lt_intvl_min_rtts = 4; /* Min num of RTT's to measure * lt_bw */ static int32_t bbr_lt_intvl_fp = 0; /* False positive epoch diff */ static int32_t bbr_lt_loss_thresh = 196; /* Lost vs delivered % */ static int32_t bbr_lt_fd_thresh = 100; /* false detection % */ static int32_t bbr_verbose_logging = 0; /* * Currently regular tcp has a rto_min of 30ms * the backoff goes 12 times so that ends up * being a total of 122.850 seconds before a * connection is killed. */ static int32_t bbr_rto_min_ms = 30; /* 30ms same as main freebsd */ static int32_t bbr_rto_max_sec = 4; /* 4 seconds */ /****************************************************/ /* DEFAULT TSO SIZING (cpu performance impacting) */ /****************************************************/ /* What amount is our formula using to get TSO size */ static int32_t bbr_hptsi_per_second = 1000; /* * For hptsi under bbr_cross_over connections what is delay * target 7ms (in usec) combined with a seg_max of 2 * gets us close to identical google behavior in * TSO size selection (possibly more 1MSS sends). */ static int32_t bbr_hptsi_segments_delay_tar = 7000; /* Does pacing delay include overhead's in its time calculations? */ static int32_t bbr_include_enet_oh = 0; static int32_t bbr_include_ip_oh = 1; static int32_t bbr_include_tcp_oh = 1; static int32_t bbr_google_discount = 10; /* Do we use (nf mode) pkt-epoch to drive us or rttProp? */ static int32_t bbr_state_is_pkt_epoch = 0; static int32_t bbr_state_drain_2_tar = 1; /* What is the max the 0 - bbr_cross_over MBPS TSO target * can reach using our delay target. Note that this * value becomes the floor for the cross over * algorithm. */ static int32_t bbr_hptsi_segments_max = 2; static int32_t bbr_hptsi_segments_floor = 1; static int32_t bbr_hptsi_utter_max = 0; /* What is the min the 0 - bbr_cross-over MBPS TSO target can be */ static int32_t bbr_hptsi_bytes_min = 1460; static int32_t bbr_all_get_min = 0; /* Cross over point from algo-a to algo-b */ static uint32_t bbr_cross_over = TWENTY_THREE_MBPS; /* Do we deal with our restart state? */ static int32_t bbr_uses_idle_restart = 0; static int32_t bbr_idle_restart_threshold = 100000; /* 100ms in useconds */ /* Do we allow hardware pacing? */ static int32_t bbr_allow_hdwr_pacing = 0; static int32_t bbr_hdwr_pace_adjust = 2; /* multipler when we calc the tso size */ static int32_t bbr_hdwr_pace_floor = 1; static int32_t bbr_hdwr_pacing_delay_cnt = 10; /****************************************************/ static int32_t bbr_resends_use_tso = 0; static int32_t bbr_tlp_max_resend = 2; static int32_t bbr_sack_block_limit = 128; #define BBR_MAX_STAT 19 counter_u64_t bbr_state_time[BBR_MAX_STAT]; counter_u64_t bbr_state_lost[BBR_MAX_STAT]; counter_u64_t bbr_state_resend[BBR_MAX_STAT]; counter_u64_t bbr_stat_arry[BBR_STAT_SIZE]; counter_u64_t bbr_opts_arry[BBR_OPTS_SIZE]; counter_u64_t bbr_out_size[TCP_MSS_ACCT_SIZE]; counter_u64_t bbr_flows_whdwr_pacing; counter_u64_t bbr_flows_nohdwr_pacing; counter_u64_t bbr_nohdwr_pacing_enobuf; counter_u64_t bbr_hdwr_pacing_enobuf; static inline uint64_t bbr_get_bw(struct tcp_bbr *bbr); /* * Static defintions we need for forward declarations. */ static uint32_t bbr_get_pacing_length(struct tcp_bbr *bbr, uint16_t gain, uint32_t useconds_time, uint64_t bw); static uint32_t bbr_get_a_state_target(struct tcp_bbr *bbr, uint32_t gain); static void bbr_set_state(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t win); static void bbr_set_probebw_gains(struct tcp_bbr *bbr, uint32_t cts, uint32_t losses); static void bbr_substate_change(struct tcp_bbr *bbr, uint32_t cts, int line, int dolog); static uint32_t bbr_get_target_cwnd(struct tcp_bbr *bbr, uint64_t bw, uint32_t gain); static void bbr_state_change(struct tcp_bbr *bbr, uint32_t cts, int32_t epoch, int32_t pkt_epoch, uint32_t losses); static uint32_t bbr_calc_thresh_rack(struct tcp_bbr *bbr, uint32_t srtt, uint32_t cts, struct bbr_sendmap *rsm); static uint32_t bbr_initial_cwnd(struct tcp_bbr *bbr, struct tcpcb *tp); static uint32_t bbr_calc_thresh_tlp(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t srtt, uint32_t cts); static void bbr_exit_persist(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts, int32_t line); static void bbr_set_state_target(struct tcp_bbr *bbr, int line); static void bbr_enter_probe_rtt(struct tcp_bbr *bbr, uint32_t cts, int32_t line); static void bbr_log_progress_event(struct tcp_bbr *bbr, struct tcpcb *tp, uint32_t tick, int event, int line); static void tcp_bbr_tso_size_check(struct tcp_bbr *bbr, uint32_t cts); static void bbr_setup_red_bw(struct tcp_bbr *bbr, uint32_t cts); static void bbr_log_rtt_shrinks(struct tcp_bbr *bbr, uint32_t cts, uint32_t applied, uint32_t rtt, uint32_t line, uint8_t is_start, uint16_t set); static struct bbr_sendmap * bbr_find_lowest_rsm(struct tcp_bbr *bbr); static __inline uint32_t bbr_get_rtt(struct tcp_bbr *bbr, int32_t rtt_type); static void bbr_log_to_start(struct tcp_bbr *bbr, uint32_t cts, uint32_t to, int32_t slot, uint8_t which); static void bbr_log_timer_var(struct tcp_bbr *bbr, int mode, uint32_t cts, uint32_t time_since_sent, uint32_t srtt, uint32_t thresh, uint32_t to); static void bbr_log_hpts_diag(struct tcp_bbr *bbr, uint32_t cts, struct hpts_diag *diag); static void bbr_log_type_bbrsnd(struct tcp_bbr *bbr, uint32_t len, uint32_t slot, uint32_t del_by, uint32_t cts, uint32_t sloton, uint32_t prev_delay); static void bbr_enter_persist(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts, int32_t line); static void bbr_stop_all_timers(struct tcpcb *tp); static void bbr_exit_probe_rtt(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts); static void bbr_check_probe_rtt_limits(struct tcp_bbr *bbr, uint32_t cts); static void bbr_timer_cancel(struct tcp_bbr *bbr, int32_t line, uint32_t cts); static void bbr_log_pacing_delay_calc(struct tcp_bbr *bbr, uint16_t gain, uint32_t len, uint32_t cts, uint32_t usecs, uint64_t bw, uint32_t override, int mod); static int bbr_ctloutput(struct inpcb *inp, struct sockopt *sopt); static inline uint8_t bbr_state_val(struct tcp_bbr *bbr) { return(bbr->rc_bbr_substate); } static inline uint32_t get_min_cwnd(struct tcp_bbr *bbr) { int mss; mss = min((bbr->rc_tp->t_maxseg - bbr->rc_last_options), bbr->r_ctl.rc_pace_max_segs); if (bbr_get_rtt(bbr, BBR_RTT_PROP) < BBR_HIGH_SPEED) return (bbr_cwnd_min_val_hs * mss); else return (bbr_cwnd_min_val * mss); } static uint32_t bbr_get_persists_timer_val(struct tcpcb *tp, struct tcp_bbr *bbr) { uint64_t srtt, var; uint64_t ret_val; bbr->r_ctl.rc_hpts_flags |= PACE_TMR_PERSIT; if (tp->t_srtt == 0) { srtt = (uint64_t)BBR_INITIAL_RTO; var = 0; } else { srtt = ((uint64_t)TICKS_2_USEC(tp->t_srtt) >> TCP_RTT_SHIFT); var = ((uint64_t)TICKS_2_USEC(tp->t_rttvar) >> TCP_RTT_SHIFT); } TCPT_RANGESET_NOSLOP(ret_val, ((srtt + var) * tcp_backoff[tp->t_rxtshift]), bbr_persist_min, bbr_persist_max); return ((uint32_t)ret_val); } static uint32_t bbr_timer_start(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts) { /* * Start the FR timer, we do this based on getting the first one in * the rc_tmap. Note that if its NULL we must stop the timer. in all * events we need to stop the running timer (if its running) before * starting the new one. */ uint32_t thresh, exp, to, srtt, time_since_sent, tstmp_touse; int32_t idx; int32_t is_tlp_timer = 0; struct bbr_sendmap *rsm; if (bbr->rc_all_timers_stopped) { /* All timers have been stopped none are to run */ return (0); } if (bbr->rc_in_persist) { /* We can't start any timer in persists */ return (bbr_get_persists_timer_val(tp, bbr)); } rsm = TAILQ_FIRST(&bbr->r_ctl.rc_tmap); if ((rsm == NULL) || ((tp->t_flags & TF_SACK_PERMIT) == 0) || (tp->t_state < TCPS_ESTABLISHED)) { /* Nothing on the send map */ activate_rxt: if (SEQ_LT(tp->snd_una, tp->snd_max) || sbavail(&tptosocket(tp)->so_snd)) { uint64_t tov; time_since_sent = 0; rsm = TAILQ_FIRST(&bbr->r_ctl.rc_tmap); if (rsm) { idx = rsm->r_rtr_cnt - 1; if (TSTMP_GEQ(rsm->r_tim_lastsent[idx], bbr->r_ctl.rc_tlp_rxt_last_time)) tstmp_touse = rsm->r_tim_lastsent[idx]; else tstmp_touse = bbr->r_ctl.rc_tlp_rxt_last_time; if (TSTMP_GT(tstmp_touse, cts)) time_since_sent = cts - tstmp_touse; } bbr->r_ctl.rc_hpts_flags |= PACE_TMR_RXT; if (tp->t_srtt == 0) tov = BBR_INITIAL_RTO; else tov = ((uint64_t)(TICKS_2_USEC(tp->t_srtt) + ((uint64_t)TICKS_2_USEC(tp->t_rttvar) * (uint64_t)4)) >> TCP_RTT_SHIFT); if (tp->t_rxtshift) tov *= tcp_backoff[tp->t_rxtshift]; if (tov > time_since_sent) tov -= time_since_sent; else tov = bbr->r_ctl.rc_min_to; TCPT_RANGESET_NOSLOP(to, tov, (bbr->r_ctl.rc_min_rto_ms * MS_IN_USEC), (bbr->rc_max_rto_sec * USECS_IN_SECOND)); bbr_log_timer_var(bbr, 2, cts, 0, srtt, 0, to); return (to); } return (0); } if (rsm->r_flags & BBR_ACKED) { rsm = bbr_find_lowest_rsm(bbr); if (rsm == NULL) { /* No lowest? */ goto activate_rxt; } } /* Convert from ms to usecs */ if (rsm->r_flags & BBR_SACK_PASSED) { if ((tp->t_flags & TF_SENTFIN) && ((tp->snd_max - tp->snd_una) == 1) && (rsm->r_flags & BBR_HAS_FIN)) { /* * We don't start a bbr rack timer if all we have is * a FIN outstanding. */ goto activate_rxt; } srtt = bbr_get_rtt(bbr, BBR_RTT_RACK); thresh = bbr_calc_thresh_rack(bbr, srtt, cts, rsm); idx = rsm->r_rtr_cnt - 1; exp = rsm->r_tim_lastsent[idx] + thresh; if (SEQ_GEQ(exp, cts)) { to = exp - cts; if (to < bbr->r_ctl.rc_min_to) { to = bbr->r_ctl.rc_min_to; } } else { to = bbr->r_ctl.rc_min_to; } } else { /* Ok we need to do a TLP not RACK */ if (bbr->rc_tlp_in_progress != 0) { /* * The previous send was a TLP. */ goto activate_rxt; } rsm = TAILQ_LAST_FAST(&bbr->r_ctl.rc_tmap, bbr_sendmap, r_tnext); if (rsm == NULL) { /* We found no rsm to TLP with. */ goto activate_rxt; } if (rsm->r_flags & BBR_HAS_FIN) { /* If its a FIN we don't do TLP */ rsm = NULL; goto activate_rxt; } time_since_sent = 0; idx = rsm->r_rtr_cnt - 1; if (TSTMP_GEQ(rsm->r_tim_lastsent[idx], bbr->r_ctl.rc_tlp_rxt_last_time)) tstmp_touse = rsm->r_tim_lastsent[idx]; else tstmp_touse = bbr->r_ctl.rc_tlp_rxt_last_time; if (TSTMP_GT(tstmp_touse, cts)) time_since_sent = cts - tstmp_touse; is_tlp_timer = 1; srtt = bbr_get_rtt(bbr, bbr_tlp_type_to_use); thresh = bbr_calc_thresh_tlp(tp, bbr, rsm, srtt, cts); if (thresh > time_since_sent) to = thresh - time_since_sent; else to = bbr->r_ctl.rc_min_to; if (to > (((uint32_t)bbr->rc_max_rto_sec) * USECS_IN_SECOND)) { /* * If the TLP time works out to larger than the max * RTO lets not do TLP.. just RTO. */ goto activate_rxt; } if ((bbr->rc_tlp_rtx_out == 1) && (rsm->r_start == bbr->r_ctl.rc_last_tlp_seq)) { /* * Second retransmit of the same TLP * lets not. */ bbr->rc_tlp_rtx_out = 0; goto activate_rxt; } if (rsm->r_start != bbr->r_ctl.rc_last_tlp_seq) { /* * The tail is no longer the last one I did a probe * on */ bbr->r_ctl.rc_tlp_seg_send_cnt = 0; bbr->r_ctl.rc_last_tlp_seq = rsm->r_start; } } if (is_tlp_timer == 0) { BBR_STAT_INC(bbr_to_arm_rack); bbr->r_ctl.rc_hpts_flags |= PACE_TMR_RACK; } else { bbr_log_timer_var(bbr, 1, cts, time_since_sent, srtt, thresh, to); if (bbr->r_ctl.rc_tlp_seg_send_cnt > bbr_tlp_max_resend) { /* * We have exceeded how many times we can retran the * current TLP timer, switch to the RTO timer. */ goto activate_rxt; } else { BBR_STAT_INC(bbr_to_arm_tlp); bbr->r_ctl.rc_hpts_flags |= PACE_TMR_TLP; } } return (to); } static inline int32_t bbr_minseg(struct tcp_bbr *bbr) { return (bbr->r_ctl.rc_pace_min_segs - bbr->rc_last_options); } static void bbr_start_hpts_timer(struct tcp_bbr *bbr, struct tcpcb *tp, uint32_t cts, int32_t frm, int32_t slot, uint32_t tot_len) { struct inpcb *inp = tptoinpcb(tp); struct hpts_diag diag; uint32_t delayed_ack = 0; uint32_t left = 0; uint32_t hpts_timeout; uint8_t stopped; int32_t delay_calc = 0; uint32_t prev_delay = 0; if (tcp_in_hpts(inp)) { /* A previous call is already set up */ return; } if ((tp->t_state == TCPS_CLOSED) || (tp->t_state == TCPS_LISTEN)) { return; } stopped = bbr->rc_tmr_stopped; if (stopped && TSTMP_GT(bbr->r_ctl.rc_timer_exp, cts)) { left = bbr->r_ctl.rc_timer_exp - cts; } bbr->r_ctl.rc_hpts_flags = 0; bbr->r_ctl.rc_timer_exp = 0; prev_delay = bbr->r_ctl.rc_last_delay_val; if (bbr->r_ctl.rc_last_delay_val && (slot == 0)) { /* * If a previous pacer delay was in place we * are not coming from the output side (where * we calculate a delay, more likely a timer). */ slot = bbr->r_ctl.rc_last_delay_val; if (TSTMP_GT(cts, bbr->rc_pacer_started)) { /* Compensate for time passed */ delay_calc = cts - bbr->rc_pacer_started; if (delay_calc <= slot) slot -= delay_calc; } } /* Do we have early to make up for by pushing out the pacing time? */ if (bbr->r_agg_early_set) { bbr_log_pacing_delay_calc(bbr, 0, bbr->r_ctl.rc_agg_early, cts, slot, 0, bbr->r_agg_early_set, 2); slot += bbr->r_ctl.rc_agg_early; bbr->r_ctl.rc_agg_early = 0; bbr->r_agg_early_set = 0; } /* Are we running a total debt that needs to be compensated for? */ if (bbr->r_ctl.rc_hptsi_agg_delay) { if (slot > bbr->r_ctl.rc_hptsi_agg_delay) { /* We nuke the delay */ slot -= bbr->r_ctl.rc_hptsi_agg_delay; bbr->r_ctl.rc_hptsi_agg_delay = 0; } else { /* We nuke some of the delay, put in a minimal 100usecs */ bbr->r_ctl.rc_hptsi_agg_delay -= slot; bbr->r_ctl.rc_last_delay_val = slot = 100; } } bbr->r_ctl.rc_last_delay_val = slot; hpts_timeout = bbr_timer_start(tp, bbr, cts); if (tp->t_flags & TF_DELACK) { if (bbr->rc_in_persist == 0) { delayed_ack = bbr_delack_time; } else { /* * We are in persists and have * gotten a new data element. */ if (hpts_timeout > bbr_delack_time) { /* * Lets make the persists timer (which acks) * be the smaller of hpts_timeout and bbr_delack_time. */ hpts_timeout = bbr_delack_time; } } } if (delayed_ack && ((hpts_timeout == 0) || (delayed_ack < hpts_timeout))) { /* We need a Delayed ack timer */ bbr->r_ctl.rc_hpts_flags = PACE_TMR_DELACK; hpts_timeout = delayed_ack; } if (slot) { /* Mark that we have a pacing timer up */ BBR_STAT_INC(bbr_paced_segments); bbr->r_ctl.rc_hpts_flags |= PACE_PKT_OUTPUT; } /* * If no timers are going to run and we will fall off thfe hptsi * wheel, we resort to a keep-alive timer if its configured. */ if ((hpts_timeout == 0) && (slot == 0)) { if ((V_tcp_always_keepalive || inp->inp_socket->so_options & SO_KEEPALIVE) && (tp->t_state <= TCPS_CLOSING)) { /* * Ok we have no timer (persists, rack, tlp, rxt or * del-ack), we don't have segments being paced. So * all that is left is the keepalive timer. */ if (TCPS_HAVEESTABLISHED(tp->t_state)) { hpts_timeout = TICKS_2_USEC(TP_KEEPIDLE(tp)); } else { hpts_timeout = TICKS_2_USEC(TP_KEEPINIT(tp)); } bbr->r_ctl.rc_hpts_flags |= PACE_TMR_KEEP; } } if (left && (stopped & (PACE_TMR_KEEP | PACE_TMR_DELACK)) == (bbr->r_ctl.rc_hpts_flags & PACE_TMR_MASK)) { /* * RACK, TLP, persists and RXT timers all are restartable * based on actions input .. i.e we received a packet (ack * or sack) and that changes things (rw, or snd_una etc). * Thus we can restart them with a new value. For * keep-alive, delayed_ack we keep track of what was left * and restart the timer with a smaller value. */ if (left < hpts_timeout) hpts_timeout = left; } if (bbr->r_ctl.rc_incr_tmrs && slot && (bbr->r_ctl.rc_hpts_flags & (PACE_TMR_TLP|PACE_TMR_RXT))) { /* * If configured to do so, and the timer is either * the TLP or RXT timer, we need to increase the timeout * by the pacing time. Consider the bottleneck at my * machine as an example, we are sending something * to start a TLP on. The last packet won't be emitted * fully until the pacing time (the bottleneck will hold * the data in place). Once the packet is emitted that * is when we want to start waiting for the TLP. This * is most evident with hardware pacing (where the nic * is holding the packet(s) before emitting). But it * can also show up in the network so we do it for all * cases. Technically we would take off one packet from * this extra delay but this is easier and being more * conservative is probably better. */ hpts_timeout += slot; } if (hpts_timeout) { /* * Hack alert for now we can't time-out over 2147 seconds (a * bit more than 35min) */ if (hpts_timeout > 0x7ffffffe) hpts_timeout = 0x7ffffffe; bbr->r_ctl.rc_timer_exp = cts + hpts_timeout; } else bbr->r_ctl.rc_timer_exp = 0; if ((slot) && (bbr->rc_use_google || bbr->output_error_seen || (slot <= hpts_timeout)) ) { /* * Tell LRO that it can queue packets while * we pace. */ bbr->rc_inp->inp_flags2 |= INP_MBUF_QUEUE_READY; if ((bbr->r_ctl.rc_hpts_flags & PACE_TMR_RACK) && (bbr->rc_cwnd_limited == 0)) { /* * If we are not cwnd limited and we * are running a rack timer we put on * the do not disturbe even for sack. */ inp->inp_flags2 |= INP_DONT_SACK_QUEUE; } else inp->inp_flags2 &= ~INP_DONT_SACK_QUEUE; bbr->rc_pacer_started = cts; (void)tcp_hpts_insert_diag(inp, HPTS_USEC_TO_SLOTS(slot), __LINE__, &diag); bbr->rc_timer_first = 0; bbr->bbr_timer_src = frm; bbr_log_to_start(bbr, cts, hpts_timeout, slot, 1); bbr_log_hpts_diag(bbr, cts, &diag); } else if (hpts_timeout) { (void)tcp_hpts_insert_diag(inp, HPTS_USEC_TO_SLOTS(hpts_timeout), __LINE__, &diag); /* * We add the flag here as well if the slot is set, * since hpts will call in to clear the queue first before * calling the output routine (which does our timers). * We don't want to set the flag if its just a timer * else the arrival of data might (that causes us * to send more) might get delayed. Imagine being * on a keep-alive timer and a request comes in for * more data. */ if (slot) bbr->rc_pacer_started = cts; if ((bbr->r_ctl.rc_hpts_flags & PACE_TMR_RACK) && (bbr->rc_cwnd_limited == 0)) { /* * For a rack timer, don't wake us even * if a sack arrives as long as we are * not cwnd limited. */ bbr->rc_inp->inp_flags2 |= INP_MBUF_QUEUE_READY; inp->inp_flags2 |= INP_DONT_SACK_QUEUE; } else { /* All other timers wake us up */ bbr->rc_inp->inp_flags2 &= ~INP_MBUF_QUEUE_READY; inp->inp_flags2 &= ~INP_DONT_SACK_QUEUE; } bbr->bbr_timer_src = frm; bbr_log_to_start(bbr, cts, hpts_timeout, slot, 0); bbr_log_hpts_diag(bbr, cts, &diag); bbr->rc_timer_first = 1; } bbr->rc_tmr_stopped = 0; bbr_log_type_bbrsnd(bbr, tot_len, slot, delay_calc, cts, frm, prev_delay); } static void bbr_timer_audit(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts, struct sockbuf *sb) { /* * We received an ack, and then did not call send or were bounced * out due to the hpts was running. Now a timer is up as well, is it * the right timer? */ struct inpcb *inp; struct bbr_sendmap *rsm; uint32_t hpts_timeout; int tmr_up; tmr_up = bbr->r_ctl.rc_hpts_flags & PACE_TMR_MASK; if (bbr->rc_in_persist && (tmr_up == PACE_TMR_PERSIT)) return; rsm = TAILQ_FIRST(&bbr->r_ctl.rc_tmap); if (((rsm == NULL) || (tp->t_state < TCPS_ESTABLISHED)) && (tmr_up == PACE_TMR_RXT)) { /* Should be an RXT */ return; } inp = bbr->rc_inp; if (rsm == NULL) { /* Nothing outstanding? */ if (tp->t_flags & TF_DELACK) { if (tmr_up == PACE_TMR_DELACK) /* * We are supposed to have delayed ack up * and we do */ return; } else if (sbavail(&inp->inp_socket->so_snd) && (tmr_up == PACE_TMR_RXT)) { /* * if we hit enobufs then we would expect the * possibility of nothing outstanding and the RXT up * (and the hptsi timer). */ return; } else if (((V_tcp_always_keepalive || inp->inp_socket->so_options & SO_KEEPALIVE) && (tp->t_state <= TCPS_CLOSING)) && (tmr_up == PACE_TMR_KEEP) && (tp->snd_max == tp->snd_una)) { /* We should have keep alive up and we do */ return; } } if (rsm && (rsm->r_flags & BBR_SACK_PASSED)) { if ((tp->t_flags & TF_SENTFIN) && ((tp->snd_max - tp->snd_una) == 1) && (rsm->r_flags & BBR_HAS_FIN)) { /* needs to be a RXT */ if (tmr_up == PACE_TMR_RXT) return; else goto wrong_timer; } else if (tmr_up == PACE_TMR_RACK) return; else goto wrong_timer; } else if (rsm && (tmr_up == PACE_TMR_RACK)) { /* Rack timer has priority if we have data out */ return; } else if (SEQ_GT(tp->snd_max, tp->snd_una) && ((tmr_up == PACE_TMR_TLP) || (tmr_up == PACE_TMR_RXT))) { /* * Either a TLP or RXT is fine if no sack-passed is in place * and data is outstanding. */ return; } else if (tmr_up == PACE_TMR_DELACK) { /* * If the delayed ack was going to go off before the * rtx/tlp/rack timer were going to expire, then that would * be the timer in control. Note we don't check the time * here trusting the code is correct. */ return; } if (SEQ_GT(tp->snd_max, tp->snd_una) && ((tmr_up == PACE_TMR_RXT) || (tmr_up == PACE_TMR_TLP) || (tmr_up == PACE_TMR_RACK))) { /* * We have outstanding data and * we *do* have a RACK, TLP or RXT * timer running. We won't restart * anything here since thats probably ok we * will get called with some timer here shortly. */ return; } /* * Ok the timer originally started is not what we want now. We will * force the hpts to be stopped if any, and restart with the slot * set to what was in the saved slot. */ wrong_timer: if ((bbr->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) == 0) { if (tcp_in_hpts(inp)) tcp_hpts_remove(inp); bbr_timer_cancel(bbr, __LINE__, cts); bbr_start_hpts_timer(bbr, tp, cts, 1, bbr->r_ctl.rc_last_delay_val, 0); } else { /* * Output is hptsi so we just need to switch the type of * timer. We don't bother with keep-alive, since when we * jump through the output, it will start the keep-alive if * nothing is sent. * * We only need a delayed-ack added and or the hpts_timeout. */ hpts_timeout = bbr_timer_start(tp, bbr, cts); if (tp->t_flags & TF_DELACK) { if (hpts_timeout == 0) { hpts_timeout = bbr_delack_time; bbr->r_ctl.rc_hpts_flags = PACE_TMR_DELACK; } else if (hpts_timeout > bbr_delack_time) { hpts_timeout = bbr_delack_time; bbr->r_ctl.rc_hpts_flags = PACE_TMR_DELACK; } } if (hpts_timeout) { if (hpts_timeout > 0x7ffffffe) hpts_timeout = 0x7ffffffe; bbr->r_ctl.rc_timer_exp = cts + hpts_timeout; } } } int32_t bbr_clear_lost = 0; /* * Considers the two time values now (cts) and earlier. * If cts is smaller than earlier, we could have * had a sequence wrap (our counter wraps every * 70 min or so) or it could be just clock skew * getting us two different time values. Clock skew * will show up within 10ms or so. So in such * a case (where cts is behind earlier time by * less than 10ms) we return 0. Otherwise we * return the true difference between them. */ static inline uint32_t bbr_calc_time(uint32_t cts, uint32_t earlier_time) { /* * Given two timestamps, the current time stamp cts, and some other * time-stamp taken in theory earlier return the difference. The * trick is here sometimes locking will get the other timestamp * after the cts. If this occurs we need to return 0. */ if (TSTMP_GEQ(cts, earlier_time)) return (cts - earlier_time); /* * cts is behind earlier_time if its less than 10ms consider it 0. * If its more than 10ms difference then we had a time wrap. Else * its just the normal locking foo. I wonder if we should not go to * 64bit TS and get rid of this issue. */ if (TSTMP_GEQ((cts + 10000), earlier_time)) return (0); /* * Ok the time must have wrapped. So we need to answer a large * amount of time, which the normal subtraction should do. */ return (cts - earlier_time); } static int sysctl_bbr_clear_lost(SYSCTL_HANDLER_ARGS) { uint32_t stat; int32_t error; error = SYSCTL_OUT(req, &bbr_clear_lost, sizeof(uint32_t)); if (error || req->newptr == NULL) return error; error = SYSCTL_IN(req, &stat, sizeof(uint32_t)); if (error) return (error); if (stat == 1) { #ifdef BBR_INVARIANTS printf("Clearing BBR lost counters\n"); #endif COUNTER_ARRAY_ZERO(bbr_state_lost, BBR_MAX_STAT); COUNTER_ARRAY_ZERO(bbr_state_time, BBR_MAX_STAT); COUNTER_ARRAY_ZERO(bbr_state_resend, BBR_MAX_STAT); } else if (stat == 2) { #ifdef BBR_INVARIANTS printf("Clearing BBR option counters\n"); #endif COUNTER_ARRAY_ZERO(bbr_opts_arry, BBR_OPTS_SIZE); } else if (stat == 3) { #ifdef BBR_INVARIANTS printf("Clearing BBR stats counters\n"); #endif COUNTER_ARRAY_ZERO(bbr_stat_arry, BBR_STAT_SIZE); } else if (stat == 4) { #ifdef BBR_INVARIANTS printf("Clearing BBR out-size counters\n"); #endif COUNTER_ARRAY_ZERO(bbr_out_size, TCP_MSS_ACCT_SIZE); } bbr_clear_lost = 0; return (0); } static void bbr_init_sysctls(void) { struct sysctl_oid *bbr_probertt; struct sysctl_oid *bbr_hptsi; struct sysctl_oid *bbr_measure; struct sysctl_oid *bbr_cwnd; struct sysctl_oid *bbr_timeout; struct sysctl_oid *bbr_states; struct sysctl_oid *bbr_startup; struct sysctl_oid *bbr_policer; /* Probe rtt controls */ bbr_probertt = SYSCTL_ADD_NODE(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "probertt", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, ""); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_probertt), OID_AUTO, "gain", CTLFLAG_RW, &bbr_rttprobe_gain, 192, "What is the filter gain drop in probe_rtt (0=disable)?"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_probertt), OID_AUTO, "cwnd", CTLFLAG_RW, &bbr_rtt_probe_cwndtarg, 4, "How many mss's are outstanding during probe-rtt"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_probertt), OID_AUTO, "int", CTLFLAG_RW, &bbr_rtt_probe_limit, 4000000, "If RTT has not shrank in this many micro-seconds enter probe-rtt"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_probertt), OID_AUTO, "mintime", CTLFLAG_RW, &bbr_rtt_probe_time, 200000, "How many microseconds in probe-rtt"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_probertt), OID_AUTO, "filter_len_sec", CTLFLAG_RW, &bbr_filter_len_sec, 6, "How long in seconds does the rttProp filter run?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_probertt), OID_AUTO, "drain_rtt", CTLFLAG_RW, &bbr_drain_rtt, BBR_SRTT, "What is the drain rtt to use in probeRTT (rtt_prop=0, rtt_rack=1, rtt_pkt=2, rtt_srtt=3?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_probertt), OID_AUTO, "can_force", CTLFLAG_RW, &bbr_can_force_probertt, 0, "If we keep setting new low rtt's but delay going in probe-rtt can we force in??"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_probertt), OID_AUTO, "enter_sets_force", CTLFLAG_RW, &bbr_probertt_sets_rtt, 0, "In NF mode, do we imitate google_mode and set the rttProp on entry to probe-rtt?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_probertt), OID_AUTO, "can_adjust", CTLFLAG_RW, &bbr_can_adjust_probertt, 1, "Can we dynamically adjust the probe-rtt limits and times?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_probertt), OID_AUTO, "is_ratio", CTLFLAG_RW, &bbr_is_ratio, 0, "is the limit to filter a ratio?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_probertt), OID_AUTO, "use_cwnd", CTLFLAG_RW, &bbr_prtt_slam_cwnd, 0, "Should we set/recover cwnd?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_probertt), OID_AUTO, "can_use_ts", CTLFLAG_RW, &bbr_can_use_ts_for_rtt, 1, "Can we use the ms timestamp if available for retransmistted rtt calculations?"); /* Pacing controls */ bbr_hptsi = SYSCTL_ADD_NODE(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "pacing", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, ""); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "hw_pacing", CTLFLAG_RW, &bbr_allow_hdwr_pacing, 1, "Do we allow hardware pacing?"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "hw_pacing_limit", CTLFLAG_RW, &bbr_hardware_pacing_limit, 4000, "Do we have a limited number of connections for pacing chelsio (0=no limit)?"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "hw_pacing_adj", CTLFLAG_RW, &bbr_hdwr_pace_adjust, 2, "Multiplier to calculated tso size?"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "hw_pacing_floor", CTLFLAG_RW, &bbr_hdwr_pace_floor, 1, "Do we invoke the hardware pacing floor?"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "hw_pacing_delay_cnt", CTLFLAG_RW, &bbr_hdwr_pacing_delay_cnt, 10, "How many packets must be sent after hdwr pacing is enabled"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "bw_cross", CTLFLAG_RW, &bbr_cross_over, 3000000, "What is the point where we cross over to linux like TSO size set"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "seg_deltarg", CTLFLAG_RW, &bbr_hptsi_segments_delay_tar, 7000, "What is the worse case delay target for hptsi < 48Mbp connections"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "enet_oh", CTLFLAG_RW, &bbr_include_enet_oh, 0, "Do we include the ethernet overhead in calculating pacing delay?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "ip_oh", CTLFLAG_RW, &bbr_include_ip_oh, 1, "Do we include the IP overhead in calculating pacing delay?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "tcp_oh", CTLFLAG_RW, &bbr_include_tcp_oh, 0, "Do we include the TCP overhead in calculating pacing delay?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "google_discount", CTLFLAG_RW, &bbr_google_discount, 10, "What is the default google discount percentage wise for pacing (11 = 1.1%%)?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "all_get_min", CTLFLAG_RW, &bbr_all_get_min, 0, "If you are less than a MSS do you just get the min?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "tso_min", CTLFLAG_RW, &bbr_hptsi_bytes_min, 1460, "For 0 -> 24Mbps what is floor number of segments for TSO"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "seg_tso_max", CTLFLAG_RW, &bbr_hptsi_segments_max, 6, "For 0 -> 24Mbps what is top number of segments for TSO"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "seg_floor", CTLFLAG_RW, &bbr_hptsi_segments_floor, 1, "Minimum TSO size we will fall too in segments"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "utter_max", CTLFLAG_RW, &bbr_hptsi_utter_max, 0, "The absolute maximum that any pacing (outside of hardware) can be"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "seg_divisor", CTLFLAG_RW, &bbr_hptsi_per_second, 100, "What is the divisor in our hptsi TSO calculation 512Mbps < X > 24Mbps "); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "srtt_mul", CTLFLAG_RW, &bbr_hptsi_max_mul, 1, "The multiplier for pace len max"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_hptsi), OID_AUTO, "srtt_div", CTLFLAG_RW, &bbr_hptsi_max_div, 2, "The divisor for pace len max"); /* Measurement controls */ bbr_measure = SYSCTL_ADD_NODE(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "measure", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Measurement controls"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_measure), OID_AUTO, "min_i_bw", CTLFLAG_RW, &bbr_initial_bw_bps, 62500, "Minimum initial b/w in bytes per second"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_measure), OID_AUTO, "no_sack_needed", CTLFLAG_RW, &bbr_sack_not_required, 0, "Do we allow bbr to run on connections not supporting SACK?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_measure), OID_AUTO, "use_google", CTLFLAG_RW, &bbr_use_google_algo, 0, "Use has close to google V1.0 has possible?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_measure), OID_AUTO, "ts_limiting", CTLFLAG_RW, &bbr_ts_limiting, 1, "Do we attempt to use the peers timestamp to limit b/w caculations?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_measure), OID_AUTO, "ts_can_raise", CTLFLAG_RW, &bbr_ts_can_raise, 0, "Can we raise the b/w via timestamp b/w calculation?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_measure), OID_AUTO, "ts_delta", CTLFLAG_RW, &bbr_min_usec_delta, 20000, "How long in usec between ts of our sends in ts validation code?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_measure), OID_AUTO, "ts_peer_delta", CTLFLAG_RW, &bbr_min_peer_delta, 20, "What min numerical value should be between the peer deltas?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_measure), OID_AUTO, "ts_delta_percent", CTLFLAG_RW, &bbr_delta_percent, 150, "What percentage (150 = 15.0) do we allow variance for?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_measure), OID_AUTO, "min_measure_good_bw", CTLFLAG_RW, &bbr_min_measurements_req, 1, "What is the minimum measurement count we need before we switch to our b/w estimate"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_measure), OID_AUTO, "min_measure_before_pace", CTLFLAG_RW, &bbr_no_pacing_until, 4, "How many pkt-epoch's (0 is off) do we need before pacing is on?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_measure), OID_AUTO, "quanta", CTLFLAG_RW, &bbr_quanta, 2, "Extra quanta to add when calculating the target (ID section 4.2.3.2)."); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_measure), OID_AUTO, "noretran", CTLFLAG_RW, &bbr_no_retran, 0, "Should google mode not use retransmission measurements for the b/w estimation?"); /* State controls */ bbr_states = SYSCTL_ADD_NODE(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "states", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "State controls"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "idle_restart", CTLFLAG_RW, &bbr_uses_idle_restart, 0, "Do we use a new special idle_restart state to ramp back up quickly?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "idle_restart_threshold", CTLFLAG_RW, &bbr_idle_restart_threshold, 100000, "How long must we be idle before we restart??"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "use_pkt_epoch", CTLFLAG_RW, &bbr_state_is_pkt_epoch, 0, "Do we use a pkt-epoch for substate if 0 rttProp?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "startup_rtt_gain", CTLFLAG_RW, &bbr_rtt_gain_thresh, 0, "What increase in RTT triggers us to stop ignoring no-loss and possibly exit startup?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "drain_floor", CTLFLAG_RW, &bbr_drain_floor, 88, "What is the lowest we can drain (pg) too?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "drain_2_target", CTLFLAG_RW, &bbr_state_drain_2_tar, 1, "Do we drain to target in drain substate?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "gain_2_target", CTLFLAG_RW, &bbr_gain_to_target, 1, "Does probe bw gain to target??"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "gain_extra_time", CTLFLAG_RW, &bbr_gain_gets_extra_too, 1, "Does probe bw gain get the extra time too?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "ld_div", CTLFLAG_RW, &bbr_drain_drop_div, 5, "Long drain drop divider?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "ld_mul", CTLFLAG_RW, &bbr_drain_drop_mul, 4, "Long drain drop multiplier?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "rand_ot_disc", CTLFLAG_RW, &bbr_rand_ot, 50, "Random discount of the ot?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "dr_filter_life", CTLFLAG_RW, &bbr_num_pktepo_for_del_limit, BBR_NUM_RTTS_FOR_DEL_LIMIT, "How many packet-epochs does the b/w delivery rate last?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "subdrain_applimited", CTLFLAG_RW, &bbr_sub_drain_app_limit, 0, "Does our sub-state drain invoke app limited if its long?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "use_cwnd_subdrain", CTLFLAG_RW, &bbr_sub_drain_slam_cwnd, 0, "Should we set/recover cwnd for sub-state drain?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "use_cwnd_maindrain", CTLFLAG_RW, &bbr_slam_cwnd_in_main_drain, 0, "Should we set/recover cwnd for main-state drain?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "google_gets_earlyout", CTLFLAG_RW, &google_allow_early_out, 1, "Should we allow google probe-bw/drain to exit early at flight target?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_states), OID_AUTO, "google_exit_loss", CTLFLAG_RW, &google_consider_lost, 1, "Should we have losses exit gain of probebw in google mode??"); /* Startup controls */ bbr_startup = SYSCTL_ADD_NODE(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "startup", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Startup controls"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_startup), OID_AUTO, "cheat_iwnd", CTLFLAG_RW, &bbr_sends_full_iwnd, 1, "Do we not pace but burst out initial windows has our TSO size?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_startup), OID_AUTO, "loss_threshold", CTLFLAG_RW, &bbr_startup_loss_thresh, 2000, "In startup what is the loss threshold in a pe that will exit us from startup?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_startup), OID_AUTO, "use_lowerpg", CTLFLAG_RW, &bbr_use_lower_gain_in_startup, 1, "Should we use a lower hptsi gain if we see loss in startup?"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_startup), OID_AUTO, "gain", CTLFLAG_RW, &bbr_start_exit, 25, "What gain percent do we need to see to stay in startup??"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_startup), OID_AUTO, "low_gain", CTLFLAG_RW, &bbr_low_start_exit, 15, "What gain percent do we need to see to stay in the lower gain startup??"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_startup), OID_AUTO, "loss_exit", CTLFLAG_RW, &bbr_exit_startup_at_loss, 1, "Should we exit startup at loss in an epoch if we are not gaining?"); /* CWND controls */ bbr_cwnd = SYSCTL_ADD_NODE(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "cwnd", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Cwnd controls"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "tar_rtt", CTLFLAG_RW, &bbr_cwndtarget_rtt_touse, 0, "Target cwnd rtt measurement to use (0=rtt_prop, 1=rtt_rack, 2=pkt_rtt, 3=srtt)?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "may_shrink", CTLFLAG_RW, &bbr_cwnd_may_shrink, 0, "Can the cwnd shrink if it would grow to more than the target?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "max_target_limit", CTLFLAG_RW, &bbr_target_cwnd_mult_limit, 8, "Do we limit the cwnd to some multiple of the cwnd target if cwnd can't shrink 0=no?"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "highspeed_min", CTLFLAG_RW, &bbr_cwnd_min_val_hs, BBR_HIGHSPEED_NUM_MSS, "What is the high-speed min cwnd (rttProp under 1ms)"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "lowspeed_min", CTLFLAG_RW, &bbr_cwnd_min_val, BBR_PROBERTT_NUM_MSS, "What is the min cwnd (rttProp > 1ms)"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "initwin", CTLFLAG_RW, &bbr_def_init_win, 10, "What is the BBR initial window, if 0 use tcp version"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "do_loss_red", CTLFLAG_RW, &bbr_do_red, 600, "Do we reduce the b/w at exit from recovery based on ratio of prop/srtt (800=80.0, 0=off)?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "red_scale", CTLFLAG_RW, &bbr_red_scale, 20000, "What RTT do we scale with?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "red_growslow", CTLFLAG_RW, &bbr_red_growth_restrict, 1, "Do we restrict cwnd growth for whats in flight?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "red_div", CTLFLAG_RW, &bbr_red_div, 2, "If we reduce whats the divisor?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "red_mul", CTLFLAG_RW, &bbr_red_mul, 1, "If we reduce whats the mulitiplier?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "target_is_unit", CTLFLAG_RW, &bbr_target_is_bbunit, 0, "Is the state target the pacing_gain or BBR_UNIT?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_cwnd), OID_AUTO, "drop_limit", CTLFLAG_RW, &bbr_drop_limit, 0, "Number of segments limit for drop (0=use min_cwnd w/flight)?"); /* Timeout controls */ bbr_timeout = SYSCTL_ADD_NODE(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "timeout", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Time out controls"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_timeout), OID_AUTO, "delack", CTLFLAG_RW, &bbr_delack_time, 100000, "BBR's delayed ack time"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_timeout), OID_AUTO, "tlp_uses", CTLFLAG_RW, &bbr_tlp_type_to_use, 3, "RTT that TLP uses in its calculations, 0=rttProp, 1=Rack_rtt, 2=pkt_rtt and 3=srtt"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_timeout), OID_AUTO, "persmin", CTLFLAG_RW, &bbr_persist_min, 250000, "What is the minimum time in microseconds between persists"); SYSCTL_ADD_U32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_timeout), OID_AUTO, "persmax", CTLFLAG_RW, &bbr_persist_max, 1000000, "What is the largest delay in microseconds between persists"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_timeout), OID_AUTO, "tlp_minto", CTLFLAG_RW, &bbr_tlp_min, 10000, "TLP Min timeout in usecs"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_timeout), OID_AUTO, "tlp_dack_time", CTLFLAG_RW, &bbr_delayed_ack_time, 200000, "TLP delayed ack compensation value"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "minrto", CTLFLAG_RW, &bbr_rto_min_ms, 30, "Minimum RTO in ms"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_timeout), OID_AUTO, "maxrto", CTLFLAG_RW, &bbr_rto_max_sec, 4, "Maximum RTO in seconds -- should be at least as large as min_rto"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_timeout), OID_AUTO, "tlp_retry", CTLFLAG_RW, &bbr_tlp_max_resend, 2, "How many times does TLP retry a single segment or multiple with no ACK"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_timeout), OID_AUTO, "minto", CTLFLAG_RW, &bbr_min_to, 1000, "Minimum rack timeout in useconds"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_timeout), OID_AUTO, "pktdelay", CTLFLAG_RW, &bbr_pkt_delay, 1000, "Extra RACK time (in useconds) besides reordering thresh"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_timeout), OID_AUTO, "incr_tmrs", CTLFLAG_RW, &bbr_incr_timers, 1, "Increase the RXT/TLP timer by the pacing time used?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_timeout), OID_AUTO, "rxtmark_sackpassed", CTLFLAG_RW, &bbr_marks_rxt_sack_passed, 0, "Mark sack passed on all those not ack'd when a RXT hits?"); /* Policer controls */ bbr_policer = SYSCTL_ADD_NODE(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "policer", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Policer controls"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_policer), OID_AUTO, "detect_enable", CTLFLAG_RW, &bbr_policer_detection_enabled, 1, "Is policer detection enabled??"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_policer), OID_AUTO, "min_pes", CTLFLAG_RW, &bbr_lt_intvl_min_rtts, 4, "Minimum number of PE's?"); SYSCTL_ADD_U64(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_policer), OID_AUTO, "bwdiff", CTLFLAG_RW, &bbr_lt_bw_diff, (4000/8), "Minimal bw diff?"); SYSCTL_ADD_U64(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_policer), OID_AUTO, "bwratio", CTLFLAG_RW, &bbr_lt_bw_ratio, 8, "Minimal bw diff?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_policer), OID_AUTO, "from_rack_rxt", CTLFLAG_RW, &bbr_policer_call_from_rack_to, 0, "Do we call the policer detection code from a rack-timeout?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_policer), OID_AUTO, "false_postive", CTLFLAG_RW, &bbr_lt_intvl_fp, 0, "What packet epoch do we do false-positive detection at (0=no)?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_policer), OID_AUTO, "loss_thresh", CTLFLAG_RW, &bbr_lt_loss_thresh, 196, "Loss threshold 196 = 19.6%?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_policer), OID_AUTO, "false_postive_thresh", CTLFLAG_RW, &bbr_lt_fd_thresh, 100, "What percentage is the false detection threshold (150=15.0)?"); /* All the rest */ SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "cheat_rxt", CTLFLAG_RW, &bbr_use_rack_resend_cheat, 0, "Do we burst 1ms between sends on retransmissions (like rack)?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "error_paceout", CTLFLAG_RW, &bbr_error_base_paceout, 10000, "When we hit an error what is the min to pace out in usec's?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "kill_paceout", CTLFLAG_RW, &bbr_max_net_error_cnt, 10, "When we hit this many errors in a row, kill the session?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "data_after_close", CTLFLAG_RW, &bbr_ignore_data_after_close, 1, "Do we hold off sending a RST until all pending data is ack'd"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "resend_use_tso", CTLFLAG_RW, &bbr_resends_use_tso, 0, "Can resends use TSO?"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "sblklimit", CTLFLAG_RW, &bbr_sack_block_limit, 128, "When do we start ignoring small sack blocks"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "bb_verbose", CTLFLAG_RW, &bbr_verbose_logging, 0, "Should BBR black box logging be verbose"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "reorder_thresh", CTLFLAG_RW, &bbr_reorder_thresh, 2, "What factor for rack will be added when seeing reordering (shift right)"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "reorder_fade", CTLFLAG_RW, &bbr_reorder_fade, 0, "Does reorder detection fade, if so how many ms (0 means never)"); SYSCTL_ADD_S32(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "rtt_tlp_thresh", CTLFLAG_RW, &bbr_tlp_thresh, 1, "what divisor for TLP rtt/retran will be added (1=rtt, 2=1/2 rtt etc)"); /* Stats and counters */ /* The pacing counters for hdwr/software can't be in the array */ bbr_nohdwr_pacing_enobuf = counter_u64_alloc(M_WAITOK); bbr_hdwr_pacing_enobuf = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "enob_hdwr_pacing", CTLFLAG_RD, &bbr_hdwr_pacing_enobuf, "Total number of enobufs for hardware paced flows"); SYSCTL_ADD_COUNTER_U64(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "enob_no_hdwr_pacing", CTLFLAG_RD, &bbr_nohdwr_pacing_enobuf, "Total number of enobufs for non-hardware paced flows"); bbr_flows_whdwr_pacing = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "hdwr_pacing", CTLFLAG_RD, &bbr_flows_whdwr_pacing, "Total number of hardware paced flows"); bbr_flows_nohdwr_pacing = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "software_pacing", CTLFLAG_RD, &bbr_flows_nohdwr_pacing, "Total number of software paced flows"); COUNTER_ARRAY_ALLOC(bbr_stat_arry, BBR_STAT_SIZE, M_WAITOK); SYSCTL_ADD_COUNTER_U64_ARRAY(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "stats", CTLFLAG_RD, bbr_stat_arry, BBR_STAT_SIZE, "BBR Stats"); COUNTER_ARRAY_ALLOC(bbr_opts_arry, BBR_OPTS_SIZE, M_WAITOK); SYSCTL_ADD_COUNTER_U64_ARRAY(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "opts", CTLFLAG_RD, bbr_opts_arry, BBR_OPTS_SIZE, "BBR Option Stats"); COUNTER_ARRAY_ALLOC(bbr_state_lost, BBR_MAX_STAT, M_WAITOK); SYSCTL_ADD_COUNTER_U64_ARRAY(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "lost", CTLFLAG_RD, bbr_state_lost, BBR_MAX_STAT, "Stats of when losses occur"); COUNTER_ARRAY_ALLOC(bbr_state_resend, BBR_MAX_STAT, M_WAITOK); SYSCTL_ADD_COUNTER_U64_ARRAY(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "stateresend", CTLFLAG_RD, bbr_state_resend, BBR_MAX_STAT, "Stats of what states resend"); COUNTER_ARRAY_ALLOC(bbr_state_time, BBR_MAX_STAT, M_WAITOK); SYSCTL_ADD_COUNTER_U64_ARRAY(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "statetime", CTLFLAG_RD, bbr_state_time, BBR_MAX_STAT, "Stats of time spent in the states"); COUNTER_ARRAY_ALLOC(bbr_out_size, TCP_MSS_ACCT_SIZE, M_WAITOK); SYSCTL_ADD_COUNTER_U64_ARRAY(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "outsize", CTLFLAG_RD, bbr_out_size, TCP_MSS_ACCT_SIZE, "Size of output calls"); SYSCTL_ADD_PROC(&bbr_sysctl_ctx, SYSCTL_CHILDREN(bbr_sysctl_root), OID_AUTO, "clrlost", CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, &bbr_clear_lost, 0, sysctl_bbr_clear_lost, "IU", "Clear lost counters"); } static void bbr_counter_destroy(void) { COUNTER_ARRAY_FREE(bbr_stat_arry, BBR_STAT_SIZE); COUNTER_ARRAY_FREE(bbr_opts_arry, BBR_OPTS_SIZE); COUNTER_ARRAY_FREE(bbr_out_size, TCP_MSS_ACCT_SIZE); COUNTER_ARRAY_FREE(bbr_state_lost, BBR_MAX_STAT); COUNTER_ARRAY_FREE(bbr_state_time, BBR_MAX_STAT); COUNTER_ARRAY_FREE(bbr_state_resend, BBR_MAX_STAT); counter_u64_free(bbr_nohdwr_pacing_enobuf); counter_u64_free(bbr_hdwr_pacing_enobuf); counter_u64_free(bbr_flows_whdwr_pacing); counter_u64_free(bbr_flows_nohdwr_pacing); } static __inline void bbr_fill_in_logging_data(struct tcp_bbr *bbr, struct tcp_log_bbr *l, uint32_t cts) { memset(l, 0, sizeof(union tcp_log_stackspecific)); l->cur_del_rate = bbr->r_ctl.rc_bbr_cur_del_rate; l->delRate = get_filter_value(&bbr->r_ctl.rc_delrate); l->rttProp = get_filter_value_small(&bbr->r_ctl.rc_rttprop); l->bw_inuse = bbr_get_bw(bbr); l->inflight = ctf_flight_size(bbr->rc_tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); l->applimited = bbr->r_ctl.r_app_limited_until; l->delivered = bbr->r_ctl.rc_delivered; l->timeStamp = cts; l->lost = bbr->r_ctl.rc_lost; l->bbr_state = bbr->rc_bbr_state; l->bbr_substate = bbr_state_val(bbr); l->epoch = bbr->r_ctl.rc_rtt_epoch; l->lt_epoch = bbr->r_ctl.rc_lt_epoch; l->pacing_gain = bbr->r_ctl.rc_bbr_hptsi_gain; l->cwnd_gain = bbr->r_ctl.rc_bbr_cwnd_gain; l->inhpts = tcp_in_hpts(bbr->rc_inp); l->use_lt_bw = bbr->rc_lt_use_bw; l->pkts_out = bbr->r_ctl.rc_flight_at_input; l->pkt_epoch = bbr->r_ctl.rc_pkt_epoch; } static void bbr_log_type_bw_reduce(struct tcp_bbr *bbr, int reason) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, bbr->r_ctl.rc_rcvtime); log.u_bbr.flex1 = 0; log.u_bbr.flex2 = 0; log.u_bbr.flex5 = 0; log.u_bbr.flex3 = 0; log.u_bbr.flex4 = bbr->r_ctl.rc_pkt_epoch_loss_rate; log.u_bbr.flex7 = reason; log.u_bbr.flex6 = bbr->r_ctl.rc_bbr_enters_probertt; log.u_bbr.flex8 = 0; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_BW_RED_EV, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_type_rwnd_collapse(struct tcp_bbr *bbr, int seq, int mode, uint32_t count) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, bbr->r_ctl.rc_rcvtime); log.u_bbr.flex1 = seq; log.u_bbr.flex2 = count; log.u_bbr.flex8 = mode; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_LOWGAIN, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_type_just_return(struct tcp_bbr *bbr, uint32_t cts, uint32_t tlen, uint8_t hpts_calling, uint8_t reason, uint32_t p_maxseg, int len) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = p_maxseg; log.u_bbr.flex2 = bbr->r_ctl.rc_hpts_flags; log.u_bbr.flex3 = bbr->r_ctl.rc_timer_exp; log.u_bbr.flex4 = reason; log.u_bbr.flex5 = bbr->rc_in_persist; log.u_bbr.flex6 = bbr->r_ctl.rc_last_delay_val; log.u_bbr.flex7 = p_maxseg; log.u_bbr.flex8 = bbr->rc_in_persist; log.u_bbr.pkts_out = 0; log.u_bbr.applimited = len; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_JUSTRET, 0, tlen, &log, false, &bbr->rc_tv); } } static void bbr_log_type_enter_rec(struct tcp_bbr *bbr, uint32_t seq) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, bbr->r_ctl.rc_rcvtime); log.u_bbr.flex1 = seq; log.u_bbr.flex2 = bbr->r_ctl.rc_cwnd_on_ent; log.u_bbr.flex3 = bbr->r_ctl.rc_recovery_start; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_ENTREC, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_msgsize_fail(struct tcp_bbr *bbr, struct tcpcb *tp, uint32_t len, uint32_t maxseg, uint32_t mtu, int32_t csum_flags, int32_t tso, uint32_t cts) { if (tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = tso; log.u_bbr.flex2 = maxseg; log.u_bbr.flex3 = mtu; log.u_bbr.flex4 = csum_flags; TCP_LOG_EVENTP(tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_MSGSIZE, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_flowend(struct tcp_bbr *bbr) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct sockbuf *r, *s; struct timeval tv; if (bbr->rc_inp->inp_socket) { r = &bbr->rc_inp->inp_socket->so_rcv; s = &bbr->rc_inp->inp_socket->so_snd; } else { r = s = NULL; } bbr_fill_in_logging_data(bbr, &log.u_bbr, tcp_get_usecs(&tv)); TCP_LOG_EVENTP(bbr->rc_tp, NULL, r, s, TCP_LOG_FLOWEND, 0, 0, &log, false, &tv); } } static void bbr_log_pkt_epoch(struct tcp_bbr *bbr, uint32_t cts, uint32_t line, uint32_t lost, uint32_t del) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = lost; log.u_bbr.flex2 = del; log.u_bbr.flex3 = bbr->r_ctl.rc_bbr_lastbtlbw; log.u_bbr.flex4 = bbr->r_ctl.rc_pkt_epoch_rtt; log.u_bbr.flex5 = bbr->r_ctl.rc_bbr_last_startup_epoch; log.u_bbr.flex6 = bbr->r_ctl.rc_lost_at_startup; log.u_bbr.flex7 = line; log.u_bbr.flex8 = 0; log.u_bbr.inflight = bbr->r_ctl.r_measurement_count; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_PKT_EPOCH, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_time_epoch(struct tcp_bbr *bbr, uint32_t cts, uint32_t line, uint32_t epoch_time) { if (bbr_verbose_logging && (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = bbr->r_ctl.rc_lost; log.u_bbr.flex2 = bbr->rc_inp->inp_socket->so_snd.sb_lowat; log.u_bbr.flex3 = bbr->rc_inp->inp_socket->so_snd.sb_hiwat; log.u_bbr.flex7 = line; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_TIME_EPOCH, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_set_of_state_target(struct tcp_bbr *bbr, uint32_t new_tar, int line, int meth) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, bbr->r_ctl.rc_rcvtime); log.u_bbr.flex1 = bbr->r_ctl.rc_target_at_state; log.u_bbr.flex2 = new_tar; log.u_bbr.flex3 = line; log.u_bbr.flex4 = bbr->r_ctl.rc_pace_max_segs; log.u_bbr.flex5 = bbr_quanta; log.u_bbr.flex6 = bbr->r_ctl.rc_pace_min_segs; log.u_bbr.flex7 = bbr->rc_last_options; log.u_bbr.flex8 = meth; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_STATE_TARGET, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_type_statechange(struct tcp_bbr *bbr, uint32_t cts, int32_t line) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = line; log.u_bbr.flex2 = bbr->r_ctl.rc_rtt_shrinks; log.u_bbr.flex3 = bbr->r_ctl.rc_probertt_int; if (bbr_state_is_pkt_epoch) log.u_bbr.flex4 = bbr_get_rtt(bbr, BBR_RTT_PKTRTT); else log.u_bbr.flex4 = bbr_get_rtt(bbr, BBR_RTT_PROP); log.u_bbr.flex5 = bbr->r_ctl.rc_bbr_last_startup_epoch; log.u_bbr.flex6 = bbr->r_ctl.rc_lost_at_startup; log.u_bbr.flex7 = (bbr->r_ctl.rc_target_at_state/1000); log.u_bbr.lt_epoch = bbr->r_ctl.rc_level_state_extra; log.u_bbr.pkts_out = bbr->r_ctl.rc_target_at_state; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_STATE, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_rtt_shrinks(struct tcp_bbr *bbr, uint32_t cts, uint32_t applied, uint32_t rtt, uint32_t line, uint8_t reas, uint16_t cond) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = line; log.u_bbr.flex2 = bbr->r_ctl.rc_rtt_shrinks; log.u_bbr.flex3 = bbr->r_ctl.last_in_probertt; log.u_bbr.flex4 = applied; log.u_bbr.flex5 = rtt; log.u_bbr.flex6 = bbr->r_ctl.rc_target_at_state; log.u_bbr.flex7 = cond; log.u_bbr.flex8 = reas; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_RTT_SHRINKS, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_type_exit_rec(struct tcp_bbr *bbr) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, bbr->r_ctl.rc_rcvtime); log.u_bbr.flex1 = bbr->r_ctl.rc_recovery_start; log.u_bbr.flex2 = bbr->r_ctl.rc_cwnd_on_ent; log.u_bbr.flex5 = bbr->r_ctl.rc_target_at_state; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_EXITREC, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_type_cwndupd(struct tcp_bbr *bbr, uint32_t bytes_this_ack, uint32_t chg, uint32_t prev_acked, int32_t meth, uint32_t target, uint32_t th_ack, int32_t line) { if (bbr_verbose_logging && (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, bbr->r_ctl.rc_rcvtime); log.u_bbr.flex1 = line; log.u_bbr.flex2 = prev_acked; log.u_bbr.flex3 = bytes_this_ack; log.u_bbr.flex4 = chg; log.u_bbr.flex5 = th_ack; log.u_bbr.flex6 = target; log.u_bbr.flex8 = meth; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_CWND, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_rtt_sample(struct tcp_bbr *bbr, uint32_t rtt, uint32_t tsin) { /* * Log the rtt sample we are applying to the srtt algorithm in * useconds. */ if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, bbr->r_ctl.rc_rcvtime); log.u_bbr.flex1 = rtt; log.u_bbr.flex2 = bbr->r_ctl.rc_bbr_state_time; log.u_bbr.flex3 = bbr->r_ctl.rc_ack_hdwr_delay; log.u_bbr.flex4 = bbr->rc_tp->ts_offset; log.u_bbr.flex5 = bbr->r_ctl.rc_target_at_state; log.u_bbr.pkts_out = tcp_tv_to_mssectick(&bbr->rc_tv); log.u_bbr.flex6 = tsin; log.u_bbr.flex7 = 0; log.u_bbr.flex8 = bbr->rc_ack_was_delayed; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, TCP_LOG_RTT, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_type_pesist(struct tcp_bbr *bbr, uint32_t cts, uint32_t time_in, int32_t line, uint8_t enter_exit) { if (bbr_verbose_logging && (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = time_in; log.u_bbr.flex2 = line; log.u_bbr.flex8 = enter_exit; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_PERSIST, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_ack_clear(struct tcp_bbr *bbr, uint32_t cts) { if (bbr_verbose_logging && (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = bbr->rc_tp->ts_recent_age; log.u_bbr.flex2 = bbr->r_ctl.rc_rtt_shrinks; log.u_bbr.flex3 = bbr->r_ctl.rc_probertt_int; log.u_bbr.flex4 = bbr->r_ctl.rc_went_idle_time; log.u_bbr.flex5 = bbr->r_ctl.rc_target_at_state; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_ACKCLEAR, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_ack_event(struct tcp_bbr *bbr, struct tcphdr *th, struct tcpopt *to, uint32_t tlen, uint16_t nsegs, uint32_t cts, int32_t nxt_pkt, struct mbuf *m) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = nsegs; log.u_bbr.flex2 = bbr->r_ctl.rc_lost_bytes; if (m) { struct timespec ts; log.u_bbr.flex3 = m->m_flags; if (m->m_flags & M_TSTMP) { mbuf_tstmp2timespec(m, &ts); tv.tv_sec = ts.tv_sec; tv.tv_usec = ts.tv_nsec / 1000; log.u_bbr.lt_epoch = tcp_tv_to_usectick(&tv); } else { log.u_bbr.lt_epoch = 0; } if (m->m_flags & M_TSTMP_LRO) { mbuf_tstmp2timeval(m, &tv); log.u_bbr.flex5 = tcp_tv_to_usectick(&tv); } else { /* No arrival timestamp */ log.u_bbr.flex5 = 0; } log.u_bbr.pkts_out = tcp_get_usecs(&tv); } else { log.u_bbr.flex3 = 0; log.u_bbr.flex5 = 0; log.u_bbr.flex6 = 0; log.u_bbr.pkts_out = 0; } log.u_bbr.flex4 = bbr->r_ctl.rc_target_at_state; log.u_bbr.flex7 = bbr->r_wanted_output; log.u_bbr.flex8 = bbr->rc_in_persist; TCP_LOG_EVENTP(bbr->rc_tp, th, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, TCP_LOG_IN, 0, tlen, &log, true, &bbr->rc_tv); } } static void bbr_log_doseg_done(struct tcp_bbr *bbr, uint32_t cts, int32_t nxt_pkt, int32_t did_out) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = did_out; log.u_bbr.flex2 = nxt_pkt; log.u_bbr.flex3 = bbr->r_ctl.rc_last_delay_val; log.u_bbr.flex4 = bbr->r_ctl.rc_hpts_flags; log.u_bbr.flex5 = bbr->r_ctl.rc_timer_exp; log.u_bbr.flex6 = bbr->r_ctl.rc_lost_bytes; log.u_bbr.flex7 = bbr->r_wanted_output; log.u_bbr.flex8 = bbr->rc_in_persist; log.u_bbr.pkts_out = bbr->r_ctl.highest_hdwr_delay; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_DOSEG_DONE, 0, 0, &log, true, &bbr->rc_tv); } } static void bbr_log_enobuf_jmp(struct tcp_bbr *bbr, uint32_t len, uint32_t cts, int32_t line, uint32_t o_len, uint32_t segcnt, uint32_t segsiz) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = line; log.u_bbr.flex2 = o_len; log.u_bbr.flex3 = segcnt; log.u_bbr.flex4 = segsiz; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_ENOBUF_JMP, ENOBUFS, len, &log, true, &bbr->rc_tv); } } static void bbr_log_to_processing(struct tcp_bbr *bbr, uint32_t cts, int32_t ret, int32_t timers, uint8_t hpts_calling) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = timers; log.u_bbr.flex2 = ret; log.u_bbr.flex3 = bbr->r_ctl.rc_timer_exp; log.u_bbr.flex4 = bbr->r_ctl.rc_hpts_flags; log.u_bbr.flex5 = cts; log.u_bbr.flex6 = bbr->r_ctl.rc_target_at_state; log.u_bbr.flex8 = hpts_calling; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_TO_PROCESS, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_to_event(struct tcp_bbr *bbr, uint32_t cts, int32_t to_num) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; uint64_t ar; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = bbr->bbr_timer_src; log.u_bbr.flex2 = 0; log.u_bbr.flex3 = bbr->r_ctl.rc_hpts_flags; ar = (uint64_t)(bbr->r_ctl.rc_resend); ar >>= 32; ar &= 0x00000000ffffffff; log.u_bbr.flex4 = (uint32_t)ar; ar = (uint64_t)bbr->r_ctl.rc_resend; ar &= 0x00000000ffffffff; log.u_bbr.flex5 = (uint32_t)ar; log.u_bbr.flex6 = TICKS_2_USEC(bbr->rc_tp->t_rxtcur); log.u_bbr.flex8 = to_num; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_RTO, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_startup_event(struct tcp_bbr *bbr, uint32_t cts, uint32_t flex1, uint32_t flex2, uint32_t flex3, uint8_t reason) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = flex1; log.u_bbr.flex2 = flex2; log.u_bbr.flex3 = flex3; log.u_bbr.flex4 = 0; log.u_bbr.flex5 = bbr->r_ctl.rc_target_at_state; log.u_bbr.flex6 = bbr->r_ctl.rc_lost_at_startup; log.u_bbr.flex8 = reason; log.u_bbr.cur_del_rate = bbr->r_ctl.rc_bbr_lastbtlbw; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_REDUCE, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_hpts_diag(struct tcp_bbr *bbr, uint32_t cts, struct hpts_diag *diag) { if (bbr_verbose_logging && (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = diag->p_nxt_slot; log.u_bbr.flex2 = diag->p_cur_slot; log.u_bbr.flex3 = diag->slot_req; log.u_bbr.flex4 = diag->inp_hptsslot; log.u_bbr.flex5 = diag->slot_remaining; log.u_bbr.flex6 = diag->need_new_to; log.u_bbr.flex7 = diag->p_hpts_active; log.u_bbr.flex8 = diag->p_on_min_sleep; /* Hijack other fields as needed */ log.u_bbr.epoch = diag->have_slept; log.u_bbr.lt_epoch = diag->yet_to_sleep; log.u_bbr.pkts_out = diag->co_ret; log.u_bbr.applimited = diag->hpts_sleep_time; log.u_bbr.delivered = diag->p_prev_slot; log.u_bbr.inflight = diag->p_runningslot; log.u_bbr.bw_inuse = diag->wheel_slot; log.u_bbr.rttProp = diag->wheel_cts; log.u_bbr.delRate = diag->maxslots; log.u_bbr.cur_del_rate = diag->p_curtick; log.u_bbr.cur_del_rate <<= 32; log.u_bbr.cur_del_rate |= diag->p_lasttick; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_HPTSDIAG, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_timer_var(struct tcp_bbr *bbr, int mode, uint32_t cts, uint32_t time_since_sent, uint32_t srtt, uint32_t thresh, uint32_t to) { if (bbr_verbose_logging && (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = bbr->rc_tp->t_rttvar; log.u_bbr.flex2 = time_since_sent; log.u_bbr.flex3 = srtt; log.u_bbr.flex4 = thresh; log.u_bbr.flex5 = to; log.u_bbr.flex6 = bbr->rc_tp->t_srtt; log.u_bbr.flex8 = mode; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_TIMERPREP, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_pacing_delay_calc(struct tcp_bbr *bbr, uint16_t gain, uint32_t len, uint32_t cts, uint32_t usecs, uint64_t bw, uint32_t override, int mod) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = usecs; log.u_bbr.flex2 = len; log.u_bbr.flex3 = (uint32_t)((bw >> 32) & 0x00000000ffffffff); log.u_bbr.flex4 = (uint32_t)(bw & 0x00000000ffffffff); if (override) log.u_bbr.flex5 = (1 << 2); else log.u_bbr.flex5 = 0; log.u_bbr.flex6 = override; log.u_bbr.flex7 = gain; log.u_bbr.flex8 = mod; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_HPTSI_CALC, 0, len, &log, false, &bbr->rc_tv); } } static void bbr_log_to_start(struct tcp_bbr *bbr, uint32_t cts, uint32_t to, int32_t slot, uint8_t which) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = bbr->bbr_timer_src; log.u_bbr.flex2 = to; log.u_bbr.flex3 = bbr->r_ctl.rc_hpts_flags; log.u_bbr.flex4 = slot; log.u_bbr.flex5 = bbr->rc_inp->inp_hptsslot; log.u_bbr.flex6 = TICKS_2_USEC(bbr->rc_tp->t_rxtcur); log.u_bbr.pkts_out = bbr->rc_inp->inp_flags2; log.u_bbr.flex8 = which; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_TIMERSTAR, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_thresh_choice(struct tcp_bbr *bbr, uint32_t cts, uint32_t thresh, uint32_t lro, uint32_t srtt, struct bbr_sendmap *rsm, uint8_t frm) { if (bbr_verbose_logging && (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = thresh; log.u_bbr.flex2 = lro; log.u_bbr.flex3 = bbr->r_ctl.rc_reorder_ts; log.u_bbr.flex4 = rsm->r_tim_lastsent[(rsm->r_rtr_cnt - 1)]; log.u_bbr.flex5 = TICKS_2_USEC(bbr->rc_tp->t_rxtcur); log.u_bbr.flex6 = srtt; log.u_bbr.flex7 = bbr->r_ctl.rc_reorder_shift; log.u_bbr.flex8 = frm; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_THRESH_CALC, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_to_cancel(struct tcp_bbr *bbr, int32_t line, uint32_t cts, uint8_t hpts_removed) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = line; log.u_bbr.flex2 = bbr->bbr_timer_src; log.u_bbr.flex3 = bbr->r_ctl.rc_hpts_flags; log.u_bbr.flex4 = bbr->rc_in_persist; log.u_bbr.flex5 = bbr->r_ctl.rc_target_at_state; log.u_bbr.flex6 = TICKS_2_USEC(bbr->rc_tp->t_rxtcur); log.u_bbr.flex8 = hpts_removed; log.u_bbr.pkts_out = bbr->rc_pacer_started; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_TIMERCANC, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_tstmp_validation(struct tcp_bbr *bbr, uint64_t peer_delta, uint64_t delta) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, bbr->r_ctl.rc_rcvtime); log.u_bbr.flex1 = bbr->r_ctl.bbr_peer_tsratio; log.u_bbr.flex2 = (peer_delta >> 32); log.u_bbr.flex3 = (peer_delta & 0x00000000ffffffff); log.u_bbr.flex4 = (delta >> 32); log.u_bbr.flex5 = (delta & 0x00000000ffffffff); log.u_bbr.flex7 = bbr->rc_ts_clock_set; log.u_bbr.flex8 = bbr->rc_ts_cant_be_used; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_TSTMP_VAL, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_type_tsosize(struct tcp_bbr *bbr, uint32_t cts, uint32_t tsosz, uint32_t tls, uint32_t old_val, uint32_t maxseg, int hdwr) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = tsosz; log.u_bbr.flex2 = tls; log.u_bbr.flex3 = tcp_min_hptsi_time; log.u_bbr.flex4 = bbr->r_ctl.bbr_hptsi_bytes_min; log.u_bbr.flex5 = old_val; log.u_bbr.flex6 = maxseg; log.u_bbr.flex7 = bbr->rc_no_pacing; log.u_bbr.flex7 <<= 1; log.u_bbr.flex7 |= bbr->rc_past_init_win; if (hdwr) log.u_bbr.flex8 = 0x80 | bbr->rc_use_google; else log.u_bbr.flex8 = bbr->rc_use_google; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_BBRTSO, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_type_rsmclear(struct tcp_bbr *bbr, uint32_t cts, struct bbr_sendmap *rsm, uint32_t flags, uint32_t line) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = line; log.u_bbr.flex2 = rsm->r_start; log.u_bbr.flex3 = rsm->r_end; log.u_bbr.flex4 = rsm->r_delivered; log.u_bbr.flex5 = rsm->r_rtr_cnt; log.u_bbr.flex6 = rsm->r_dupack; log.u_bbr.flex7 = rsm->r_tim_lastsent[0]; log.u_bbr.flex8 = rsm->r_flags; /* Hijack the pkts_out fids */ log.u_bbr.applimited = flags; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_RSM_CLEARED, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_type_bbrupd(struct tcp_bbr *bbr, uint8_t flex8, uint32_t cts, uint32_t flex3, uint32_t flex2, uint32_t flex5, uint32_t flex6, uint32_t pkts_out, int flex7, uint32_t flex4, uint32_t flex1) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = flex1; log.u_bbr.flex2 = flex2; log.u_bbr.flex3 = flex3; log.u_bbr.flex4 = flex4; log.u_bbr.flex5 = flex5; log.u_bbr.flex6 = flex6; log.u_bbr.flex7 = flex7; /* Hijack the pkts_out fids */ log.u_bbr.pkts_out = pkts_out; log.u_bbr.flex8 = flex8; if (bbr->rc_ack_was_delayed) log.u_bbr.epoch = bbr->r_ctl.rc_ack_hdwr_delay; else log.u_bbr.epoch = 0; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_BBRUPD, 0, flex2, &log, false, &bbr->rc_tv); } } static void bbr_log_type_ltbw(struct tcp_bbr *bbr, uint32_t cts, int32_t reason, uint32_t newbw, uint32_t obw, uint32_t diff, uint32_t tim) { if (/*bbr_verbose_logging && */(bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = reason; log.u_bbr.flex2 = newbw; log.u_bbr.flex3 = obw; log.u_bbr.flex4 = diff; log.u_bbr.flex5 = bbr->r_ctl.rc_lt_lost; log.u_bbr.flex6 = bbr->r_ctl.rc_lt_del; log.u_bbr.flex7 = bbr->rc_lt_is_sampling; log.u_bbr.pkts_out = tim; log.u_bbr.bw_inuse = bbr->r_ctl.rc_lt_bw; if (bbr->rc_lt_use_bw == 0) log.u_bbr.epoch = bbr->r_ctl.rc_pkt_epoch - bbr->r_ctl.rc_lt_epoch; else log.u_bbr.epoch = bbr->r_ctl.rc_pkt_epoch - bbr->r_ctl.rc_lt_epoch_use; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_BWSAMP, 0, 0, &log, false, &bbr->rc_tv); } } static inline void bbr_log_progress_event(struct tcp_bbr *bbr, struct tcpcb *tp, uint32_t tick, int event, int line) { if (bbr_verbose_logging && (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, bbr->r_ctl.rc_rcvtime); log.u_bbr.flex1 = line; log.u_bbr.flex2 = tick; log.u_bbr.flex3 = tp->t_maxunacktime; log.u_bbr.flex4 = tp->t_acktime; log.u_bbr.flex8 = event; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_PROGRESS, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_type_log_hdwr_pacing(struct tcp_bbr *bbr, const struct ifnet *ifp, uint64_t rate, uint64_t hw_rate, int line, uint32_t cts, int error) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = ((hw_rate >> 32) & 0x00000000ffffffff); log.u_bbr.flex2 = (hw_rate & 0x00000000ffffffff); log.u_bbr.flex3 = (((uint64_t)ifp >> 32) & 0x00000000ffffffff); log.u_bbr.flex4 = ((uint64_t)ifp & 0x00000000ffffffff); log.u_bbr.bw_inuse = rate; log.u_bbr.flex5 = line; log.u_bbr.flex6 = error; log.u_bbr.flex8 = bbr->skip_gain; log.u_bbr.flex8 <<= 1; log.u_bbr.flex8 |= bbr->gain_is_limited; log.u_bbr.flex8 <<= 1; log.u_bbr.flex8 |= bbr->bbr_hdrw_pacing; log.u_bbr.pkts_out = bbr->rc_tp->t_maxseg; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_HDWR_PACE, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_type_bbrsnd(struct tcp_bbr *bbr, uint32_t len, uint32_t slot, uint32_t del_by, uint32_t cts, uint32_t line, uint32_t prev_delay) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = slot; log.u_bbr.flex2 = del_by; log.u_bbr.flex3 = prev_delay; log.u_bbr.flex4 = line; log.u_bbr.flex5 = bbr->r_ctl.rc_last_delay_val; log.u_bbr.flex6 = bbr->r_ctl.rc_hptsi_agg_delay; log.u_bbr.flex7 = (0x0000ffff & bbr->r_ctl.rc_hpts_flags); log.u_bbr.flex8 = bbr->rc_in_persist; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_BBRSND, 0, len, &log, false, &bbr->rc_tv); } } static void bbr_log_type_bbrrttprop(struct tcp_bbr *bbr, uint32_t t, uint32_t end, uint32_t tsconv, uint32_t cts, int32_t match, uint32_t seq, uint8_t flags) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = bbr->r_ctl.rc_delivered; log.u_bbr.flex2 = 0; log.u_bbr.flex3 = bbr->r_ctl.rc_lowest_rtt; log.u_bbr.flex4 = end; log.u_bbr.flex5 = seq; log.u_bbr.flex6 = t; log.u_bbr.flex7 = match; log.u_bbr.flex8 = flags; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_BBRRTT, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_exit_gain(struct tcp_bbr *bbr, uint32_t cts, int32_t entry_method) { if (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); log.u_bbr.flex1 = bbr->r_ctl.rc_target_at_state; log.u_bbr.flex2 = (bbr->rc_tp->t_maxseg - bbr->rc_last_options); log.u_bbr.flex3 = bbr->r_ctl.gain_epoch; log.u_bbr.flex4 = bbr->r_ctl.rc_pace_max_segs; log.u_bbr.flex5 = bbr->r_ctl.rc_pace_min_segs; log.u_bbr.flex6 = bbr->r_ctl.rc_bbr_state_atflight; log.u_bbr.flex7 = 0; log.u_bbr.flex8 = entry_method; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_EXIT_GAIN, 0, 0, &log, false, &bbr->rc_tv); } } static void bbr_log_settings_change(struct tcp_bbr *bbr, int settings_desired) { if (bbr_verbose_logging && (bbr->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, bbr->r_ctl.rc_rcvtime); /* R-HU */ log.u_bbr.flex1 = 0; log.u_bbr.flex2 = 0; log.u_bbr.flex3 = 0; log.u_bbr.flex4 = 0; log.u_bbr.flex7 = 0; log.u_bbr.flex8 = settings_desired; TCP_LOG_EVENTP(bbr->rc_tp, NULL, &bbr->rc_inp->inp_socket->so_rcv, &bbr->rc_inp->inp_socket->so_snd, BBR_LOG_SETTINGS_CHG, 0, 0, &log, false, &bbr->rc_tv); } } /* * Returns the bw from the our filter. */ static inline uint64_t bbr_get_full_bw(struct tcp_bbr *bbr) { uint64_t bw; bw = get_filter_value(&bbr->r_ctl.rc_delrate); return (bw); } static inline void bbr_set_pktepoch(struct tcp_bbr *bbr, uint32_t cts, int32_t line) { uint64_t calclr; uint32_t lost, del; if (bbr->r_ctl.rc_lost > bbr->r_ctl.rc_lost_at_pktepoch) lost = bbr->r_ctl.rc_lost - bbr->r_ctl.rc_lost_at_pktepoch; else lost = 0; del = bbr->r_ctl.rc_delivered - bbr->r_ctl.rc_pkt_epoch_del; if (lost == 0) { calclr = 0; } else if (del) { calclr = lost; calclr *= (uint64_t)1000; calclr /= (uint64_t)del; } else { /* Nothing delivered? 100.0% loss */ calclr = 1000; } bbr->r_ctl.rc_pkt_epoch_loss_rate = (uint32_t)calclr; if (IN_RECOVERY(bbr->rc_tp->t_flags)) bbr->r_ctl.recovery_lr += (uint32_t)calclr; bbr->r_ctl.rc_pkt_epoch++; if (bbr->rc_no_pacing && (bbr->r_ctl.rc_pkt_epoch >= bbr->no_pacing_until)) { bbr->rc_no_pacing = 0; tcp_bbr_tso_size_check(bbr, cts); } bbr->r_ctl.rc_pkt_epoch_rtt = bbr_calc_time(cts, bbr->r_ctl.rc_pkt_epoch_time); bbr->r_ctl.rc_pkt_epoch_time = cts; /* What was our loss rate */ bbr_log_pkt_epoch(bbr, cts, line, lost, del); bbr->r_ctl.rc_pkt_epoch_del = bbr->r_ctl.rc_delivered; bbr->r_ctl.rc_lost_at_pktepoch = bbr->r_ctl.rc_lost; } static inline void bbr_set_epoch(struct tcp_bbr *bbr, uint32_t cts, int32_t line) { uint32_t epoch_time; /* Tick the RTT clock */ bbr->r_ctl.rc_rtt_epoch++; epoch_time = cts - bbr->r_ctl.rc_rcv_epoch_start; bbr_log_time_epoch(bbr, cts, line, epoch_time); bbr->r_ctl.rc_rcv_epoch_start = cts; } static inline void bbr_isit_a_pkt_epoch(struct tcp_bbr *bbr, uint32_t cts, struct bbr_sendmap *rsm, int32_t line, int32_t cum_acked) { if (SEQ_GEQ(rsm->r_delivered, bbr->r_ctl.rc_pkt_epoch_del)) { bbr->rc_is_pkt_epoch_now = 1; } } /* * Returns the bw from either the b/w filter * or from the lt_bw (if the connection is being * policed). */ static inline uint64_t __bbr_get_bw(struct tcp_bbr *bbr) { uint64_t bw, min_bw; uint64_t rtt; int gm_measure_cnt = 1; /* * For startup we make, like google, a * minimum b/w. This is generated from the * IW and the rttProp. We do fall back to srtt * if for some reason (initial handshake) we don't * have a rttProp. We, in the worst case, fall back * to the configured min_bw (rc_initial_hptsi_bw). */ if (bbr->rc_bbr_state == BBR_STATE_STARTUP) { /* Attempt first to use rttProp */ rtt = (uint64_t)get_filter_value_small(&bbr->r_ctl.rc_rttprop); if (rtt && (rtt < 0xffffffff)) { measure: min_bw = (uint64_t)(bbr_initial_cwnd(bbr, bbr->rc_tp)) * ((uint64_t)1000000); min_bw /= rtt; if (min_bw < bbr->r_ctl.rc_initial_hptsi_bw) { min_bw = bbr->r_ctl.rc_initial_hptsi_bw; } } else if (bbr->rc_tp->t_srtt != 0) { /* No rttProp, use srtt? */ rtt = bbr_get_rtt(bbr, BBR_SRTT); goto measure; } else { min_bw = bbr->r_ctl.rc_initial_hptsi_bw; } } else min_bw = 0; if ((bbr->rc_past_init_win == 0) && (bbr->r_ctl.rc_delivered > bbr_initial_cwnd(bbr, bbr->rc_tp))) bbr->rc_past_init_win = 1; if ((bbr->rc_use_google) && (bbr->r_ctl.r_measurement_count >= 1)) gm_measure_cnt = 0; if (gm_measure_cnt && ((bbr->r_ctl.r_measurement_count < bbr_min_measurements_req) || (bbr->rc_past_init_win == 0))) { /* For google we use our guess rate until we get 1 measurement */ use_initial_window: rtt = (uint64_t)get_filter_value_small(&bbr->r_ctl.rc_rttprop); if (rtt && (rtt < 0xffffffff)) { /* * We have an RTT measurement. Use that in * combination with our initial window to calculate * a b/w. */ bw = (uint64_t)(bbr_initial_cwnd(bbr, bbr->rc_tp)) * ((uint64_t)1000000); bw /= rtt; if (bw < bbr->r_ctl.rc_initial_hptsi_bw) { bw = bbr->r_ctl.rc_initial_hptsi_bw; } } else { /* Drop back to the 40 and punt to a default */ bw = bbr->r_ctl.rc_initial_hptsi_bw; } if (bw < 1) /* Probably should panic */ bw = 1; if (bw > min_bw) return (bw); else return (min_bw); } if (bbr->rc_lt_use_bw) bw = bbr->r_ctl.rc_lt_bw; else if (bbr->r_recovery_bw && (bbr->rc_use_google == 0)) bw = bbr->r_ctl.red_bw; else bw = get_filter_value(&bbr->r_ctl.rc_delrate); if (bbr->rc_tp->t_peakrate_thr && (bbr->rc_use_google == 0)) { /* * Enforce user set rate limit, keep in mind that * t_peakrate_thr is in B/s already */ bw = uqmin((uint64_t)bbr->rc_tp->t_peakrate_thr, bw); } if (bw == 0) { /* We should not be at 0, go to the initial window then */ goto use_initial_window; } if (bw < 1) /* Probably should panic */ bw = 1; if (bw < min_bw) bw = min_bw; return (bw); } static inline uint64_t bbr_get_bw(struct tcp_bbr *bbr) { uint64_t bw; bw = __bbr_get_bw(bbr); return (bw); } static inline void bbr_reset_lt_bw_interval(struct tcp_bbr *bbr, uint32_t cts) { bbr->r_ctl.rc_lt_epoch = bbr->r_ctl.rc_pkt_epoch; bbr->r_ctl.rc_lt_time = bbr->r_ctl.rc_del_time; bbr->r_ctl.rc_lt_del = bbr->r_ctl.rc_delivered; bbr->r_ctl.rc_lt_lost = bbr->r_ctl.rc_lost; } static inline void bbr_reset_lt_bw_sampling(struct tcp_bbr *bbr, uint32_t cts) { bbr->rc_lt_is_sampling = 0; bbr->rc_lt_use_bw = 0; bbr->r_ctl.rc_lt_bw = 0; bbr_reset_lt_bw_interval(bbr, cts); } static inline void bbr_lt_bw_samp_done(struct tcp_bbr *bbr, uint64_t bw, uint32_t cts, uint32_t timin) { uint64_t diff; /* Do we have a previous sample? */ if (bbr->r_ctl.rc_lt_bw) { /* Get the diff in bytes per second */ if (bbr->r_ctl.rc_lt_bw > bw) diff = bbr->r_ctl.rc_lt_bw - bw; else diff = bw - bbr->r_ctl.rc_lt_bw; if ((diff <= bbr_lt_bw_diff) || (diff <= (bbr->r_ctl.rc_lt_bw / bbr_lt_bw_ratio))) { /* Consider us policed */ uint32_t saved_bw; saved_bw = (uint32_t)bbr->r_ctl.rc_lt_bw; bbr->r_ctl.rc_lt_bw = (bw + bbr->r_ctl.rc_lt_bw) / 2; /* average of two */ bbr->rc_lt_use_bw = 1; bbr->r_ctl.rc_bbr_hptsi_gain = BBR_UNIT; /* * Use pkt based epoch for measuring length of * policer up */ bbr->r_ctl.rc_lt_epoch_use = bbr->r_ctl.rc_pkt_epoch; /* * reason 4 is we need to start consider being * policed */ bbr_log_type_ltbw(bbr, cts, 4, (uint32_t)bw, saved_bw, (uint32_t)diff, timin); return; } } bbr->r_ctl.rc_lt_bw = bw; bbr_reset_lt_bw_interval(bbr, cts); bbr_log_type_ltbw(bbr, cts, 5, 0, (uint32_t)bw, 0, timin); } static void bbr_randomize_extra_state_time(struct tcp_bbr *bbr) { uint32_t ran, deduct; ran = arc4random_uniform(bbr_rand_ot); if (ran) { deduct = bbr->r_ctl.rc_level_state_extra / ran; bbr->r_ctl.rc_level_state_extra -= deduct; } } /* * Return randomly the starting state * to use in probebw. */ static uint8_t bbr_pick_probebw_substate(struct tcp_bbr *bbr, uint32_t cts) { uint32_t ran; uint8_t ret_val; /* Initialize the offset to 0 */ bbr->r_ctl.rc_exta_time_gd = 0; bbr->rc_hit_state_1 = 0; bbr->r_ctl.rc_level_state_extra = 0; ran = arc4random_uniform((BBR_SUBSTATE_COUNT-1)); /* * The math works funny here :) the return value is used to set the * substate and then the state change is called which increments by * one. So if we return 1 (DRAIN) we will increment to 2 (LEVEL1) when * we fully enter the state. Note that the (8 - 1 - ran) assures that * we return 1 - 7, so we dont return 0 and end up starting in * state 1 (DRAIN). */ ret_val = BBR_SUBSTATE_COUNT - 1 - ran; /* Set an epoch */ if ((cts - bbr->r_ctl.rc_rcv_epoch_start) >= bbr_get_rtt(bbr, BBR_RTT_PROP)) bbr_set_epoch(bbr, cts, __LINE__); bbr->r_ctl.bbr_lost_at_state = bbr->r_ctl.rc_lost; return (ret_val); } static void bbr_lt_bw_sampling(struct tcp_bbr *bbr, uint32_t cts, int32_t loss_detected) { uint32_t diff, d_time; uint64_t del_time, bw, lost, delivered; if (bbr->r_use_policer == 0) return; if (bbr->rc_lt_use_bw) { /* We are using lt bw do we stop yet? */ diff = bbr->r_ctl.rc_pkt_epoch - bbr->r_ctl.rc_lt_epoch_use; if (diff > bbr_lt_bw_max_rtts) { /* Reset it all */ reset_all: bbr_reset_lt_bw_sampling(bbr, cts); if (bbr->rc_filled_pipe) { bbr_set_epoch(bbr, cts, __LINE__); bbr->rc_bbr_substate = bbr_pick_probebw_substate(bbr, cts); bbr_substate_change(bbr, cts, __LINE__, 0); bbr->rc_bbr_state = BBR_STATE_PROBE_BW; bbr_log_type_statechange(bbr, cts, __LINE__); } else { /* * This should not happen really * unless we remove the startup/drain * restrictions above. */ bbr->rc_bbr_state = BBR_STATE_STARTUP; bbr_set_epoch(bbr, cts, __LINE__); bbr->r_ctl.rc_bbr_state_time = cts; bbr->r_ctl.rc_lost_at_startup = bbr->r_ctl.rc_lost; bbr->r_ctl.rc_bbr_hptsi_gain = bbr->r_ctl.rc_startup_pg; bbr->r_ctl.rc_bbr_cwnd_gain = bbr->r_ctl.rc_startup_pg; bbr_set_state_target(bbr, __LINE__); bbr_log_type_statechange(bbr, cts, __LINE__); } /* reason 0 is to stop using lt-bw */ bbr_log_type_ltbw(bbr, cts, 0, 0, 0, 0, 0); return; } if (bbr_lt_intvl_fp == 0) { /* Not doing false-positive detection */ return; } /* False positive detection */ if (diff == bbr_lt_intvl_fp) { /* At bbr_lt_intvl_fp we record the lost */ bbr->r_ctl.rc_lt_del = bbr->r_ctl.rc_delivered; bbr->r_ctl.rc_lt_lost = bbr->r_ctl.rc_lost; } else if (diff > (bbr_lt_intvl_min_rtts + bbr_lt_intvl_fp)) { /* Now is our loss rate still high? */ lost = bbr->r_ctl.rc_lost - bbr->r_ctl.rc_lt_lost; delivered = bbr->r_ctl.rc_delivered - bbr->r_ctl.rc_lt_del; if ((delivered == 0) || (((lost * 1000)/delivered) < bbr_lt_fd_thresh)) { /* No still below our threshold */ bbr_log_type_ltbw(bbr, cts, 7, lost, delivered, 0, 0); } else { /* Yikes its still high, it must be a false positive */ bbr_log_type_ltbw(bbr, cts, 8, lost, delivered, 0, 0); goto reset_all; } } return; } /* * Wait for the first loss before sampling, to let the policer * exhaust its tokens and estimate the steady-state rate allowed by * the policer. Starting samples earlier includes bursts that * over-estimate the bw. */ if (bbr->rc_lt_is_sampling == 0) { /* reason 1 is to begin doing the sampling */ if (loss_detected == 0) return; bbr_reset_lt_bw_interval(bbr, cts); bbr->rc_lt_is_sampling = 1; bbr_log_type_ltbw(bbr, cts, 1, 0, 0, 0, 0); return; } /* Now how long were we delivering long term last> */ if (TSTMP_GEQ(bbr->r_ctl.rc_del_time, bbr->r_ctl.rc_lt_time)) d_time = bbr->r_ctl.rc_del_time - bbr->r_ctl.rc_lt_time; else d_time = 0; /* To avoid underestimates, reset sampling if we run out of data. */ if (bbr->r_ctl.r_app_limited_until) { /* Can not measure in app-limited state */ bbr_reset_lt_bw_sampling(bbr, cts); /* reason 2 is to reset sampling due to app limits */ bbr_log_type_ltbw(bbr, cts, 2, 0, 0, 0, d_time); return; } diff = bbr->r_ctl.rc_pkt_epoch - bbr->r_ctl.rc_lt_epoch; if (diff < bbr_lt_intvl_min_rtts) { /* * need more samples (we don't * start on a round like linux so * we need 1 more). */ /* 6 is not_enough time or no-loss */ bbr_log_type_ltbw(bbr, cts, 6, 0, 0, 0, d_time); return; } if (diff > (4 * bbr_lt_intvl_min_rtts)) { /* * For now if we wait too long, reset all sampling. We need * to do some research here, its possible that we should * base this on how much loss as occurred.. something like * if its under 10% (or some thresh) reset all otherwise * don't. Thats for phase II I guess. */ bbr_reset_lt_bw_sampling(bbr, cts); /* reason 3 is to reset sampling due too long of sampling */ bbr_log_type_ltbw(bbr, cts, 3, 0, 0, 0, d_time); return; } /* * End sampling interval when a packet is lost, so we estimate the * policer tokens were exhausted. Stopping the sampling before the * tokens are exhausted under-estimates the policed rate. */ if (loss_detected == 0) { /* 6 is not_enough time or no-loss */ bbr_log_type_ltbw(bbr, cts, 6, 0, 0, 0, d_time); return; } /* Calculate packets lost and delivered in sampling interval. */ lost = bbr->r_ctl.rc_lost - bbr->r_ctl.rc_lt_lost; delivered = bbr->r_ctl.rc_delivered - bbr->r_ctl.rc_lt_del; if ((delivered == 0) || (((lost * 1000)/delivered) < bbr_lt_loss_thresh)) { bbr_log_type_ltbw(bbr, cts, 6, lost, delivered, 0, d_time); return; } if (d_time < 1000) { /* Not enough time. wait */ /* 6 is not_enough time or no-loss */ bbr_log_type_ltbw(bbr, cts, 6, 0, 0, 0, d_time); return; } if (d_time >= (0xffffffff / USECS_IN_MSEC)) { /* Too long */ bbr_reset_lt_bw_sampling(bbr, cts); /* reason 3 is to reset sampling due too long of sampling */ bbr_log_type_ltbw(bbr, cts, 3, 0, 0, 0, d_time); return; } del_time = d_time; bw = delivered; bw *= (uint64_t)USECS_IN_SECOND; bw /= del_time; bbr_lt_bw_samp_done(bbr, bw, cts, d_time); } /* * Allocate a sendmap from our zone. */ static struct bbr_sendmap * bbr_alloc(struct tcp_bbr *bbr) { struct bbr_sendmap *rsm; BBR_STAT_INC(bbr_to_alloc); rsm = uma_zalloc(bbr_zone, (M_NOWAIT | M_ZERO)); if (rsm) { bbr->r_ctl.rc_num_maps_alloced++; return (rsm); } if (bbr->r_ctl.rc_free_cnt) { BBR_STAT_INC(bbr_to_alloc_emerg); rsm = TAILQ_FIRST(&bbr->r_ctl.rc_free); TAILQ_REMOVE(&bbr->r_ctl.rc_free, rsm, r_next); bbr->r_ctl.rc_free_cnt--; return (rsm); } BBR_STAT_INC(bbr_to_alloc_failed); return (NULL); } static struct bbr_sendmap * bbr_alloc_full_limit(struct tcp_bbr *bbr) { if ((V_tcp_map_entries_limit > 0) && (bbr->r_ctl.rc_num_maps_alloced >= V_tcp_map_entries_limit)) { BBR_STAT_INC(bbr_alloc_limited); if (!bbr->alloc_limit_reported) { bbr->alloc_limit_reported = 1; BBR_STAT_INC(bbr_alloc_limited_conns); } return (NULL); } return (bbr_alloc(bbr)); } /* wrapper to allocate a sendmap entry, subject to a specific limit */ static struct bbr_sendmap * bbr_alloc_limit(struct tcp_bbr *bbr, uint8_t limit_type) { struct bbr_sendmap *rsm; if (limit_type) { /* currently there is only one limit type */ if (V_tcp_map_split_limit > 0 && bbr->r_ctl.rc_num_split_allocs >= V_tcp_map_split_limit) { BBR_STAT_INC(bbr_split_limited); if (!bbr->alloc_limit_reported) { bbr->alloc_limit_reported = 1; BBR_STAT_INC(bbr_alloc_limited_conns); } return (NULL); } } /* allocate and mark in the limit type, if set */ rsm = bbr_alloc(bbr); if (rsm != NULL && limit_type) { rsm->r_limit_type = limit_type; bbr->r_ctl.rc_num_split_allocs++; } return (rsm); } static void bbr_free(struct tcp_bbr *bbr, struct bbr_sendmap *rsm) { if (rsm->r_limit_type) { /* currently there is only one limit type */ bbr->r_ctl.rc_num_split_allocs--; } if (rsm->r_is_smallmap) bbr->r_ctl.rc_num_small_maps_alloced--; if (bbr->r_ctl.rc_tlp_send == rsm) bbr->r_ctl.rc_tlp_send = NULL; if (bbr->r_ctl.rc_resend == rsm) { bbr->r_ctl.rc_resend = NULL; } if (bbr->r_ctl.rc_next == rsm) bbr->r_ctl.rc_next = NULL; if (bbr->r_ctl.rc_sacklast == rsm) bbr->r_ctl.rc_sacklast = NULL; if (bbr->r_ctl.rc_free_cnt < bbr_min_req_free) { memset(rsm, 0, sizeof(struct bbr_sendmap)); TAILQ_INSERT_TAIL(&bbr->r_ctl.rc_free, rsm, r_next); rsm->r_limit_type = 0; bbr->r_ctl.rc_free_cnt++; return; } bbr->r_ctl.rc_num_maps_alloced--; uma_zfree(bbr_zone, rsm); } /* * Returns the BDP. */ static uint64_t bbr_get_bw_delay_prod(uint64_t rtt, uint64_t bw) { /* * Calculate the bytes in flight needed given the bw (in bytes per * second) and the specifyed rtt in useconds. We need to put out the * returned value per RTT to match that rate. Gain will normally * raise it up from there. * * This should not overflow as long as the bandwidth is below 1 * TByte per second (bw < 10**12 = 2**40) and the rtt is smaller * than 1000 seconds (rtt < 10**3 * 10**6 = 10**9 = 2**30). */ uint64_t usec_per_sec; usec_per_sec = USECS_IN_SECOND; return ((rtt * bw) / usec_per_sec); } /* * Return the initial cwnd. */ static uint32_t bbr_initial_cwnd(struct tcp_bbr *bbr, struct tcpcb *tp) { uint32_t i_cwnd; if (bbr->rc_init_win) { i_cwnd = bbr->rc_init_win * tp->t_maxseg; } else if (V_tcp_initcwnd_segments) i_cwnd = min((V_tcp_initcwnd_segments * tp->t_maxseg), max(2 * tp->t_maxseg, 14600)); else if (V_tcp_do_rfc3390) i_cwnd = min(4 * tp->t_maxseg, max(2 * tp->t_maxseg, 4380)); else { /* Per RFC5681 Section 3.1 */ if (tp->t_maxseg > 2190) i_cwnd = 2 * tp->t_maxseg; else if (tp->t_maxseg > 1095) i_cwnd = 3 * tp->t_maxseg; else i_cwnd = 4 * tp->t_maxseg; } return (i_cwnd); } /* * Given a specified gain, return the target * cwnd based on that gain. */ static uint32_t bbr_get_raw_target_cwnd(struct tcp_bbr *bbr, uint32_t gain, uint64_t bw) { uint64_t bdp, rtt; uint32_t cwnd; if ((get_filter_value_small(&bbr->r_ctl.rc_rttprop) == 0xffffffff) || (bbr_get_full_bw(bbr) == 0)) { /* No measurements yet */ return (bbr_initial_cwnd(bbr, bbr->rc_tp)); } /* * Get bytes per RTT needed (rttProp is normally in * bbr_cwndtarget_rtt_touse) */ rtt = bbr_get_rtt(bbr, bbr_cwndtarget_rtt_touse); /* Get the bdp from the two values */ bdp = bbr_get_bw_delay_prod(rtt, bw); /* Now apply the gain */ cwnd = (uint32_t)(((bdp * ((uint64_t)gain)) + (uint64_t)(BBR_UNIT - 1)) / ((uint64_t)BBR_UNIT)); return (cwnd); } static uint32_t bbr_get_target_cwnd(struct tcp_bbr *bbr, uint64_t bw, uint32_t gain) { uint32_t cwnd, mss; mss = min((bbr->rc_tp->t_maxseg - bbr->rc_last_options), bbr->r_ctl.rc_pace_max_segs); /* Get the base cwnd with gain rounded to a mss */ cwnd = roundup(bbr_get_raw_target_cwnd(bbr, bw, gain), mss); /* * Add in N (2 default since we do not have a * fq layer to trap packets in) quanta's per the I-D * section 4.2.3.2 quanta adjust. */ cwnd += (bbr_quanta * bbr->r_ctl.rc_pace_max_segs); if (bbr->rc_use_google) { if((bbr->rc_bbr_state == BBR_STATE_PROBE_BW) && (bbr_state_val(bbr) == BBR_SUB_GAIN)) { /* * The linux implementation adds * an extra 2 x mss in gain cycle which * is documented no-where except in the code. * so we add more for Neal undocumented feature */ cwnd += 2 * mss; } if ((cwnd / mss) & 0x1) { /* Round up for odd num mss */ cwnd += mss; } } /* Are we below the min cwnd? */ if (cwnd < get_min_cwnd(bbr)) return (get_min_cwnd(bbr)); return (cwnd); } static uint16_t bbr_gain_adjust(struct tcp_bbr *bbr, uint16_t gain) { if (gain < 1) gain = 1; return (gain); } static uint32_t bbr_get_header_oh(struct tcp_bbr *bbr) { int seg_oh; seg_oh = 0; if (bbr->r_ctl.rc_inc_tcp_oh) { /* Do we include TCP overhead? */ seg_oh = (bbr->rc_last_options + sizeof(struct tcphdr)); } if (bbr->r_ctl.rc_inc_ip_oh) { /* Do we include IP overhead? */ #ifdef INET6 if (bbr->r_is_v6) { seg_oh += sizeof(struct ip6_hdr); } else #endif { #ifdef INET seg_oh += sizeof(struct ip); #endif } } if (bbr->r_ctl.rc_inc_enet_oh) { /* Do we include the ethernet overhead? */ seg_oh += sizeof(struct ether_header); } return(seg_oh); } static uint32_t bbr_get_pacing_length(struct tcp_bbr *bbr, uint16_t gain, uint32_t useconds_time, uint64_t bw) { uint64_t divor, res, tim; if (useconds_time == 0) return (0); gain = bbr_gain_adjust(bbr, gain); divor = (uint64_t)USECS_IN_SECOND * (uint64_t)BBR_UNIT; tim = useconds_time; res = (tim * bw * gain) / divor; if (res == 0) res = 1; return ((uint32_t)res); } /* * Given a gain and a length return the delay in useconds that * should be used to evenly space out packets * on the connection (based on the gain factor). */ static uint32_t bbr_get_pacing_delay(struct tcp_bbr *bbr, uint16_t gain, int32_t len, uint32_t cts, int nolog) { uint64_t bw, lentim, res; uint32_t usecs, srtt, over = 0; uint32_t seg_oh, num_segs, maxseg; if (len == 0) return (0); maxseg = bbr->rc_tp->t_maxseg - bbr->rc_last_options; num_segs = (len + maxseg - 1) / maxseg; if (bbr->rc_use_google == 0) { seg_oh = bbr_get_header_oh(bbr); len += (num_segs * seg_oh); } gain = bbr_gain_adjust(bbr, gain); bw = bbr_get_bw(bbr); if (bbr->rc_use_google) { uint64_t cbw; /* * Reduce the b/w by the google discount * factor 10 = 1%. */ cbw = bw * (uint64_t)(1000 - bbr->r_ctl.bbr_google_discount); cbw /= (uint64_t)1000; /* We don't apply a discount if it results in 0 */ if (cbw > 0) bw = cbw; } lentim = ((uint64_t)len * (uint64_t)USECS_IN_SECOND * (uint64_t)BBR_UNIT); res = lentim / ((uint64_t)gain * bw); if (res == 0) res = 1; usecs = (uint32_t)res; srtt = bbr_get_rtt(bbr, BBR_SRTT); if (bbr_hptsi_max_mul && bbr_hptsi_max_div && (bbr->rc_use_google == 0) && (usecs > ((srtt * bbr_hptsi_max_mul) / bbr_hptsi_max_div))) { /* * We cannot let the delay be more than 1/2 the srtt time. * Otherwise we cannot pace out or send properly. */ over = usecs = (srtt * bbr_hptsi_max_mul) / bbr_hptsi_max_div; BBR_STAT_INC(bbr_hpts_min_time); } if (!nolog) bbr_log_pacing_delay_calc(bbr, gain, len, cts, usecs, bw, over, 1); return (usecs); } static void bbr_ack_received(struct tcpcb *tp, struct tcp_bbr *bbr, struct tcphdr *th, uint32_t bytes_this_ack, uint32_t sack_changed, uint32_t prev_acked, int32_t line, uint32_t losses) { uint64_t bw; uint32_t cwnd, target_cwnd, saved_bytes, maxseg; int32_t meth; INP_WLOCK_ASSERT(tptoinpcb(tp)); #ifdef STATS if ((tp->t_flags & TF_GPUTINPROG) && SEQ_GEQ(th->th_ack, tp->gput_ack)) { /* * Strech acks and compressed acks will cause this to * oscillate but we are doing it the same way as the main * stack so it will be compariable (though possibly not * ideal). */ int32_t cgput; int64_t gput, time_stamp; gput = (int64_t) (th->th_ack - tp->gput_seq) * 8; time_stamp = max(1, ((bbr->r_ctl.rc_rcvtime - tp->gput_ts) / 1000)); cgput = gput / time_stamp; stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_GPUT, cgput); if (tp->t_stats_gput_prev > 0) stats_voi_update_abs_s32(tp->t_stats, VOI_TCP_GPUT_ND, ((gput - tp->t_stats_gput_prev) * 100) / tp->t_stats_gput_prev); tp->t_flags &= ~TF_GPUTINPROG; tp->t_stats_gput_prev = cgput; } #endif if ((bbr->rc_bbr_state == BBR_STATE_PROBE_RTT) && ((bbr->r_ctl.bbr_rttprobe_gain_val == 0) || bbr->rc_use_google)) { /* We don't change anything in probe-rtt */ return; } maxseg = tp->t_maxseg - bbr->rc_last_options; saved_bytes = bytes_this_ack; bytes_this_ack += sack_changed; if (bytes_this_ack > prev_acked) { bytes_this_ack -= prev_acked; /* * A byte ack'd gives us a full mss * to be like linux i.e. they count packets. */ if ((bytes_this_ack < maxseg) && bbr->rc_use_google) bytes_this_ack = maxseg; } else { /* Unlikely */ bytes_this_ack = 0; } cwnd = tp->snd_cwnd; bw = get_filter_value(&bbr->r_ctl.rc_delrate); if (bw) target_cwnd = bbr_get_target_cwnd(bbr, bw, (uint32_t)bbr->r_ctl.rc_bbr_cwnd_gain); else target_cwnd = bbr_initial_cwnd(bbr, bbr->rc_tp); if (IN_RECOVERY(tp->t_flags) && (bbr->bbr_prev_in_rec == 0)) { /* * We are entering recovery and * thus packet conservation. */ bbr->pkt_conservation = 1; bbr->r_ctl.rc_recovery_start = bbr->r_ctl.rc_rcvtime; cwnd = ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)) + bytes_this_ack; } if (IN_RECOVERY(tp->t_flags)) { uint32_t flight; bbr->bbr_prev_in_rec = 1; if (cwnd > losses) { cwnd -= losses; if (cwnd < maxseg) cwnd = maxseg; } else cwnd = maxseg; flight = ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); bbr_log_type_cwndupd(bbr, flight, 0, losses, 10, 0, 0, line); if (bbr->pkt_conservation) { uint32_t time_in; if (TSTMP_GEQ(bbr->r_ctl.rc_rcvtime, bbr->r_ctl.rc_recovery_start)) time_in = bbr->r_ctl.rc_rcvtime - bbr->r_ctl.rc_recovery_start; else time_in = 0; if (time_in >= bbr_get_rtt(bbr, BBR_RTT_PROP)) { /* Clear packet conservation after an rttProp */ bbr->pkt_conservation = 0; } else { if ((flight + bytes_this_ack) > cwnd) cwnd = flight + bytes_this_ack; if (cwnd < get_min_cwnd(bbr)) cwnd = get_min_cwnd(bbr); tp->snd_cwnd = cwnd; bbr_log_type_cwndupd(bbr, saved_bytes, sack_changed, prev_acked, 1, target_cwnd, th->th_ack, line); return; } } } else bbr->bbr_prev_in_rec = 0; if ((bbr->rc_use_google == 0) && bbr->r_ctl.restrict_growth) { bbr->r_ctl.restrict_growth--; if (bytes_this_ack > maxseg) bytes_this_ack = maxseg; } if (bbr->rc_filled_pipe) { /* * Here we have exited startup and filled the pipe. We will * thus allow the cwnd to shrink to the target. We hit here * mostly. */ uint32_t s_cwnd; meth = 2; s_cwnd = min((cwnd + bytes_this_ack), target_cwnd); if (s_cwnd > cwnd) cwnd = s_cwnd; else if (bbr_cwnd_may_shrink || bbr->rc_use_google || bbr->rc_no_pacing) cwnd = s_cwnd; } else { /* * Here we are still in startup, we increase cwnd by what * has been acked. */ if ((cwnd < target_cwnd) || (bbr->rc_past_init_win == 0)) { meth = 3; cwnd += bytes_this_ack; } else { /* * Method 4 means we are at target so no gain in * startup and past the initial window. */ meth = 4; } } tp->snd_cwnd = max(cwnd, get_min_cwnd(bbr)); bbr_log_type_cwndupd(bbr, saved_bytes, sack_changed, prev_acked, meth, target_cwnd, th->th_ack, line); } static void tcp_bbr_partialack(struct tcpcb *tp) { struct tcp_bbr *bbr; bbr = (struct tcp_bbr *)tp->t_fb_ptr; INP_WLOCK_ASSERT(tptoinpcb(tp)); if (ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)) <= tp->snd_cwnd) { bbr->r_wanted_output = 1; } } static void bbr_post_recovery(struct tcpcb *tp) { struct tcp_bbr *bbr; uint32_t flight; INP_WLOCK_ASSERT(tptoinpcb(tp)); bbr = (struct tcp_bbr *)tp->t_fb_ptr; /* * Here we just exit recovery. */ EXIT_RECOVERY(tp->t_flags); /* Lock in our b/w reduction for the specified number of pkt-epochs */ bbr->r_recovery_bw = 0; tp->snd_recover = tp->snd_una; tcp_bbr_tso_size_check(bbr, bbr->r_ctl.rc_rcvtime); bbr->pkt_conservation = 0; if (bbr->rc_use_google == 0) { /* * For non-google mode lets * go ahead and make sure we clear * the recovery state so if we * bounce back in to recovery we * will do PC. */ bbr->bbr_prev_in_rec = 0; } bbr_log_type_exit_rec(bbr); if (bbr->rc_bbr_state != BBR_STATE_PROBE_RTT) { tp->snd_cwnd = max(tp->snd_cwnd, bbr->r_ctl.rc_cwnd_on_ent); bbr_log_type_cwndupd(bbr, 0, 0, 0, 15, 0, 0, __LINE__); } else { /* For probe-rtt case lets fix up its saved_cwnd */ if (bbr->r_ctl.rc_saved_cwnd < bbr->r_ctl.rc_cwnd_on_ent) { bbr->r_ctl.rc_saved_cwnd = bbr->r_ctl.rc_cwnd_on_ent; bbr_log_type_cwndupd(bbr, 0, 0, 0, 16, 0, 0, __LINE__); } } flight = ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); if ((bbr->rc_use_google == 0) && bbr_do_red) { uint64_t val, lr2use; uint32_t maxseg, newcwnd, acks_inflight, ratio, cwnd; uint32_t *cwnd_p; if (bbr_get_rtt(bbr, BBR_SRTT)) { val = ((uint64_t)bbr_get_rtt(bbr, BBR_RTT_PROP) * (uint64_t)1000); val /= bbr_get_rtt(bbr, BBR_SRTT); ratio = (uint32_t)val; } else ratio = 1000; bbr_log_type_cwndupd(bbr, bbr_red_mul, bbr_red_div, bbr->r_ctl.recovery_lr, 21, ratio, bbr->r_ctl.rc_red_cwnd_pe, __LINE__); if ((ratio < bbr_do_red) || (bbr_do_red == 0)) goto done; if (((bbr->rc_bbr_state == BBR_STATE_PROBE_RTT) && bbr_prtt_slam_cwnd) || (bbr_sub_drain_slam_cwnd && (bbr->rc_bbr_state == BBR_STATE_PROBE_BW) && bbr->rc_hit_state_1 && (bbr_state_val(bbr) == BBR_SUB_DRAIN)) || ((bbr->rc_bbr_state == BBR_STATE_DRAIN) && bbr_slam_cwnd_in_main_drain)) { /* * Here we must poke at the saved cwnd * as well as the cwnd. */ cwnd = bbr->r_ctl.rc_saved_cwnd; cwnd_p = &bbr->r_ctl.rc_saved_cwnd; } else { cwnd = tp->snd_cwnd; cwnd_p = &tp->snd_cwnd; } maxseg = tp->t_maxseg - bbr->rc_last_options; /* Add the overall lr with the recovery lr */ if (bbr->r_ctl.rc_lost == 0) lr2use = 0; else if (bbr->r_ctl.rc_delivered == 0) lr2use = 1000; else { lr2use = bbr->r_ctl.rc_lost * 1000; lr2use /= bbr->r_ctl.rc_delivered; } lr2use += bbr->r_ctl.recovery_lr; acks_inflight = (flight / (maxseg * 2)); if (bbr_red_scale) { lr2use *= bbr_get_rtt(bbr, BBR_SRTT); lr2use /= bbr_red_scale; if ((bbr_red_growth_restrict) && ((bbr_get_rtt(bbr, BBR_SRTT)/bbr_red_scale) > 1)) bbr->r_ctl.restrict_growth += acks_inflight; } if (lr2use) { val = (uint64_t)cwnd * lr2use; val /= 1000; if (cwnd > val) newcwnd = roundup((cwnd - val), maxseg); else newcwnd = maxseg; } else { val = (uint64_t)cwnd * (uint64_t)bbr_red_mul; val /= (uint64_t)bbr_red_div; newcwnd = roundup((uint32_t)val, maxseg); } /* with standard delayed acks how many acks can I expect? */ if (bbr_drop_limit == 0) { /* * Anticpate how much we will * raise the cwnd based on the acks. */ if ((newcwnd + (acks_inflight * maxseg)) < get_min_cwnd(bbr)) { /* We do enforce the min (with the acks) */ newcwnd = (get_min_cwnd(bbr) - acks_inflight); } } else { /* * A strict drop limit of N is inplace */ if (newcwnd < (bbr_drop_limit * maxseg)) { newcwnd = bbr_drop_limit * maxseg; } } /* For the next N acks do we restrict the growth */ *cwnd_p = newcwnd; if (tp->snd_cwnd > newcwnd) tp->snd_cwnd = newcwnd; bbr_log_type_cwndupd(bbr, bbr_red_mul, bbr_red_div, val, 22, (uint32_t)lr2use, bbr_get_rtt(bbr, BBR_SRTT), __LINE__); bbr->r_ctl.rc_red_cwnd_pe = bbr->r_ctl.rc_pkt_epoch; } done: bbr->r_ctl.recovery_lr = 0; if (flight <= tp->snd_cwnd) { bbr->r_wanted_output = 1; } tcp_bbr_tso_size_check(bbr, bbr->r_ctl.rc_rcvtime); } static void bbr_setup_red_bw(struct tcp_bbr *bbr, uint32_t cts) { bbr->r_ctl.red_bw = get_filter_value(&bbr->r_ctl.rc_delrate); /* Limit the drop in b/w to 1/2 our current filter. */ if (bbr->r_ctl.red_bw > bbr->r_ctl.rc_bbr_cur_del_rate) bbr->r_ctl.red_bw = bbr->r_ctl.rc_bbr_cur_del_rate; if (bbr->r_ctl.red_bw < (get_filter_value(&bbr->r_ctl.rc_delrate) / 2)) bbr->r_ctl.red_bw = get_filter_value(&bbr->r_ctl.rc_delrate) / 2; tcp_bbr_tso_size_check(bbr, cts); } static void bbr_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type, struct bbr_sendmap *rsm) { struct tcp_bbr *bbr; INP_WLOCK_ASSERT(tptoinpcb(tp)); #ifdef STATS stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_CSIG, type); #endif bbr = (struct tcp_bbr *)tp->t_fb_ptr; switch (type) { case CC_NDUPACK: if (!IN_RECOVERY(tp->t_flags)) { tp->snd_recover = tp->snd_max; /* Start a new epoch */ bbr_set_pktepoch(bbr, bbr->r_ctl.rc_rcvtime, __LINE__); if (bbr->rc_lt_is_sampling || bbr->rc_lt_use_bw) { /* * Move forward the lt epoch * so it won't count the truncated * epoch. */ bbr->r_ctl.rc_lt_epoch++; } if (bbr->rc_bbr_state == BBR_STATE_STARTUP) { /* * Just like the policer detection code * if we are in startup we must push * forward the last startup epoch * to hide the truncated PE. */ bbr->r_ctl.rc_bbr_last_startup_epoch++; } bbr->r_ctl.rc_cwnd_on_ent = tp->snd_cwnd; ENTER_RECOVERY(tp->t_flags); bbr->rc_tlp_rtx_out = 0; bbr->r_ctl.recovery_lr = bbr->r_ctl.rc_pkt_epoch_loss_rate; tcp_bbr_tso_size_check(bbr, bbr->r_ctl.rc_rcvtime); if (tcp_in_hpts(bbr->rc_inp) && ((bbr->r_ctl.rc_hpts_flags & PACE_TMR_RACK) == 0)) { /* * When we enter recovery, we need to restart * any timers. This may mean we gain an agg * early, which will be made up for at the last * rxt out. */ bbr->rc_timer_first = 1; bbr_timer_cancel(bbr, __LINE__, bbr->r_ctl.rc_rcvtime); } /* * Calculate a new cwnd based on to the current * delivery rate with no gain. We get the bdp * without gaining it up like we normally would and * we use the last cur_del_rate. */ if ((bbr->rc_use_google == 0) && (bbr->r_ctl.bbr_rttprobe_gain_val || (bbr->rc_bbr_state != BBR_STATE_PROBE_RTT))) { tp->snd_cwnd = ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)) + (tp->t_maxseg - bbr->rc_last_options); if (tp->snd_cwnd < get_min_cwnd(bbr)) { /* We always gate to min cwnd */ tp->snd_cwnd = get_min_cwnd(bbr); } bbr_log_type_cwndupd(bbr, 0, 0, 0, 14, 0, 0, __LINE__); } bbr_log_type_enter_rec(bbr, rsm->r_start); } break; case CC_RTO_ERR: KMOD_TCPSTAT_INC(tcps_sndrexmitbad); /* RTO was unnecessary, so reset everything. */ bbr_reset_lt_bw_sampling(bbr, bbr->r_ctl.rc_rcvtime); if (bbr->rc_bbr_state != BBR_STATE_PROBE_RTT) { tp->snd_cwnd = tp->snd_cwnd_prev; tp->snd_ssthresh = tp->snd_ssthresh_prev; tp->snd_recover = tp->snd_recover_prev; tp->snd_cwnd = max(tp->snd_cwnd, bbr->r_ctl.rc_cwnd_on_ent); bbr_log_type_cwndupd(bbr, 0, 0, 0, 13, 0, 0, __LINE__); } tp->t_badrxtwin = 0; break; } } /* * Indicate whether this ack should be delayed. We can delay the ack if * following conditions are met: * - There is no delayed ack timer in progress. * - Our last ack wasn't a 0-sized window. We never want to delay * the ack that opens up a 0-sized window. * - LRO wasn't used for this segment. We make sure by checking that the * segment size is not larger than the MSS. * - Delayed acks are enabled or this is a half-synchronized T/TCP * connection. * - The data being acked is less than a full segment (a stretch ack * of more than a segment we should ack. * - nsegs is 1 (if its more than that we received more than 1 ack). */ #define DELAY_ACK(tp, bbr, nsegs) \ (((tp->t_flags & TF_RXWIN0SENT) == 0) && \ ((tp->t_flags & TF_DELACK) == 0) && \ ((bbr->bbr_segs_rcvd + nsegs) < tp->t_delayed_ack) && \ (tp->t_delayed_ack || (tp->t_flags & TF_NEEDSYN))) /* * Return the lowest RSM in the map of * packets still in flight that is not acked. * This should normally find on the first one * since we remove packets from the send * map after they are marked ACKED. */ static struct bbr_sendmap * bbr_find_lowest_rsm(struct tcp_bbr *bbr) { struct bbr_sendmap *rsm; /* * Walk the time-order transmitted list looking for an rsm that is * not acked. This will be the one that was sent the longest time * ago that is still outstanding. */ TAILQ_FOREACH(rsm, &bbr->r_ctl.rc_tmap, r_tnext) { if (rsm->r_flags & BBR_ACKED) { continue; } goto finish; } finish: return (rsm); } static struct bbr_sendmap * bbr_find_high_nonack(struct tcp_bbr *bbr, struct bbr_sendmap *rsm) { struct bbr_sendmap *prsm; /* * Walk the sequence order list backward until we hit and arrive at * the highest seq not acked. In theory when this is called it * should be the last segment (which it was not). */ prsm = rsm; TAILQ_FOREACH_REVERSE_FROM(prsm, &bbr->r_ctl.rc_map, bbr_head, r_next) { if (prsm->r_flags & (BBR_ACKED | BBR_HAS_FIN)) { continue; } return (prsm); } return (NULL); } /* * Returns to the caller the number of microseconds that * the packet can be outstanding before we think we * should have had an ack returned. */ static uint32_t bbr_calc_thresh_rack(struct tcp_bbr *bbr, uint32_t srtt, uint32_t cts, struct bbr_sendmap *rsm) { /* * lro is the flag we use to determine if we have seen reordering. * If it gets set we have seen reordering. The reorder logic either * works in one of two ways: * * If reorder-fade is configured, then we track the last time we saw * re-ordering occur. If we reach the point where enough time as * passed we no longer consider reordering has occuring. * * Or if reorder-face is 0, then once we see reordering we consider * the connection to alway be subject to reordering and just set lro * to 1. * * In the end if lro is non-zero we add the extra time for * reordering in. */ int32_t lro; uint32_t thresh, t_rxtcur; if (srtt == 0) srtt = 1; if (bbr->r_ctl.rc_reorder_ts) { if (bbr->r_ctl.rc_reorder_fade) { if (SEQ_GEQ(cts, bbr->r_ctl.rc_reorder_ts)) { lro = cts - bbr->r_ctl.rc_reorder_ts; if (lro == 0) { /* * No time as passed since the last * reorder, mark it as reordering. */ lro = 1; } } else { /* Negative time? */ lro = 0; } if (lro > bbr->r_ctl.rc_reorder_fade) { /* Turn off reordering seen too */ bbr->r_ctl.rc_reorder_ts = 0; lro = 0; } } else { /* Reodering does not fade */ lro = 1; } } else { lro = 0; } thresh = srtt + bbr->r_ctl.rc_pkt_delay; if (lro) { /* It must be set, if not you get 1/4 rtt */ if (bbr->r_ctl.rc_reorder_shift) thresh += (srtt >> bbr->r_ctl.rc_reorder_shift); else thresh += (srtt >> 2); } else { thresh += 1000; } /* We don't let the rack timeout be above a RTO */ if ((bbr->rc_tp)->t_srtt == 0) t_rxtcur = BBR_INITIAL_RTO; else t_rxtcur = TICKS_2_USEC(bbr->rc_tp->t_rxtcur); if (thresh > t_rxtcur) { thresh = t_rxtcur; } /* And we don't want it above the RTO max either */ if (thresh > (((uint32_t)bbr->rc_max_rto_sec) * USECS_IN_SECOND)) { thresh = (((uint32_t)bbr->rc_max_rto_sec) * USECS_IN_SECOND); } bbr_log_thresh_choice(bbr, cts, thresh, lro, srtt, rsm, BBR_TO_FRM_RACK); return (thresh); } /* * Return to the caller the amount of time in mico-seconds * that should be used for the TLP timer from the last * send time of this packet. */ static uint32_t bbr_calc_thresh_tlp(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t srtt, uint32_t cts) { uint32_t thresh, len, maxseg, t_rxtcur; struct bbr_sendmap *prsm; if (srtt == 0) srtt = 1; if (bbr->rc_tlp_threshold) thresh = srtt + (srtt / bbr->rc_tlp_threshold); else thresh = (srtt * 2); maxseg = tp->t_maxseg - bbr->rc_last_options; /* Get the previous sent packet, if any */ len = rsm->r_end - rsm->r_start; /* 2.1 behavior */ prsm = TAILQ_PREV(rsm, bbr_head, r_tnext); if (prsm && (len <= maxseg)) { /* * Two packets outstanding, thresh should be (2*srtt) + * possible inter-packet delay (if any). */ uint32_t inter_gap = 0; int idx, nidx; idx = rsm->r_rtr_cnt - 1; nidx = prsm->r_rtr_cnt - 1; if (TSTMP_GEQ(rsm->r_tim_lastsent[nidx], prsm->r_tim_lastsent[idx])) { /* Yes it was sent later (or at the same time) */ inter_gap = rsm->r_tim_lastsent[idx] - prsm->r_tim_lastsent[nidx]; } thresh += inter_gap; } else if (len <= maxseg) { /* * Possibly compensate for delayed-ack. */ uint32_t alt_thresh; alt_thresh = srtt + (srtt / 2) + bbr_delayed_ack_time; if (alt_thresh > thresh) thresh = alt_thresh; } /* Not above the current RTO */ if (tp->t_srtt == 0) t_rxtcur = BBR_INITIAL_RTO; else t_rxtcur = TICKS_2_USEC(tp->t_rxtcur); bbr_log_thresh_choice(bbr, cts, thresh, t_rxtcur, srtt, rsm, BBR_TO_FRM_TLP); /* Not above an RTO */ if (thresh > t_rxtcur) { thresh = t_rxtcur; } /* Not above a RTO max */ if (thresh > (((uint32_t)bbr->rc_max_rto_sec) * USECS_IN_SECOND)) { thresh = (((uint32_t)bbr->rc_max_rto_sec) * USECS_IN_SECOND); } /* And now apply the user TLP min */ if (thresh < bbr_tlp_min) { thresh = bbr_tlp_min; } return (thresh); } /* * Return one of three RTTs to use (in microseconds). */ static __inline uint32_t bbr_get_rtt(struct tcp_bbr *bbr, int32_t rtt_type) { uint32_t f_rtt; uint32_t srtt; f_rtt = get_filter_value_small(&bbr->r_ctl.rc_rttprop); if (get_filter_value_small(&bbr->r_ctl.rc_rttprop) == 0xffffffff) { /* We have no rtt at all */ if (bbr->rc_tp->t_srtt == 0) f_rtt = BBR_INITIAL_RTO; else f_rtt = (TICKS_2_USEC(bbr->rc_tp->t_srtt) >> TCP_RTT_SHIFT); /* * Since we don't know how good the rtt is apply a * delayed-ack min */ if (f_rtt < bbr_delayed_ack_time) { f_rtt = bbr_delayed_ack_time; } } /* Take the filter version or last measured pkt-rtt */ if (rtt_type == BBR_RTT_PROP) { srtt = f_rtt; } else if (rtt_type == BBR_RTT_PKTRTT) { if (bbr->r_ctl.rc_pkt_epoch_rtt) { srtt = bbr->r_ctl.rc_pkt_epoch_rtt; } else { /* No pkt rtt yet */ srtt = f_rtt; } } else if (rtt_type == BBR_RTT_RACK) { srtt = bbr->r_ctl.rc_last_rtt; /* We need to add in any internal delay for our timer */ if (bbr->rc_ack_was_delayed) srtt += bbr->r_ctl.rc_ack_hdwr_delay; } else if (rtt_type == BBR_SRTT) { srtt = (TICKS_2_USEC(bbr->rc_tp->t_srtt) >> TCP_RTT_SHIFT); } else { /* TSNH */ srtt = f_rtt; #ifdef BBR_INVARIANTS panic("Unknown rtt request type %d", rtt_type); #endif } return (srtt); } static int bbr_is_lost(struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t cts) { uint32_t thresh; thresh = bbr_calc_thresh_rack(bbr, bbr_get_rtt(bbr, BBR_RTT_RACK), cts, rsm); if ((cts - rsm->r_tim_lastsent[(rsm->r_rtr_cnt - 1)]) >= thresh) { /* It is lost (past time) */ return (1); } return (0); } /* * Return a sendmap if we need to retransmit something. */ static struct bbr_sendmap * bbr_check_recovery_mode(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts) { /* * Check to see that we don't need to fall into recovery. We will * need to do so if our oldest transmit is past the time we should * have had an ack. */ struct bbr_sendmap *rsm; int32_t idx; if (TAILQ_EMPTY(&bbr->r_ctl.rc_map)) { /* Nothing outstanding that we know of */ return (NULL); } rsm = TAILQ_FIRST(&bbr->r_ctl.rc_tmap); if (rsm == NULL) { /* Nothing in the transmit map */ return (NULL); } if (tp->t_flags & TF_SENTFIN) { /* Fin restricted, don't find anything once a fin is sent */ return (NULL); } if (rsm->r_flags & BBR_ACKED) { /* * Ok the first one is acked (this really should not happen * since we remove the from the tmap once they are acked) */ rsm = bbr_find_lowest_rsm(bbr); if (rsm == NULL) return (NULL); } idx = rsm->r_rtr_cnt - 1; if (SEQ_LEQ(cts, rsm->r_tim_lastsent[idx])) { /* Send timestamp is the same or less? can't be ready */ return (NULL); } /* Get our RTT time */ if (bbr_is_lost(bbr, rsm, cts) && ((rsm->r_dupack >= DUP_ACK_THRESHOLD) || (rsm->r_flags & BBR_SACK_PASSED))) { if ((rsm->r_flags & BBR_MARKED_LOST) == 0) { rsm->r_flags |= BBR_MARKED_LOST; bbr->r_ctl.rc_lost += rsm->r_end - rsm->r_start; bbr->r_ctl.rc_lost_bytes += rsm->r_end - rsm->r_start; } bbr_cong_signal(tp, NULL, CC_NDUPACK, rsm); #ifdef BBR_INVARIANTS if ((rsm->r_end - rsm->r_start) == 0) panic("tp:%p bbr:%p rsm:%p length is 0?", tp, bbr, rsm); #endif return (rsm); } return (NULL); } /* * RACK Timer, here we simply do logging and house keeping. * the normal bbr_output_wtime() function will call the * appropriate thing to check if we need to do a RACK retransmit. * We return 1, saying don't proceed with bbr_output_wtime only * when all timers have been stopped (destroyed PCB?). */ static int bbr_timeout_rack(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts) { /* * This timer simply provides an internal trigger to send out data. * The check_recovery_mode call will see if there are needed * retransmissions, if so we will enter fast-recovery. The output * call may or may not do the same thing depending on sysctl * settings. */ uint32_t lost; if (bbr->rc_all_timers_stopped) { return (1); } if (TSTMP_LT(cts, bbr->r_ctl.rc_timer_exp)) { /* Its not time yet */ return (0); } BBR_STAT_INC(bbr_to_tot); lost = bbr->r_ctl.rc_lost; if (bbr->r_state && (bbr->r_state != tp->t_state)) bbr_set_state(tp, bbr, 0); bbr_log_to_event(bbr, cts, BBR_TO_FRM_RACK); if (bbr->r_ctl.rc_resend == NULL) { /* Lets do the check here */ bbr->r_ctl.rc_resend = bbr_check_recovery_mode(tp, bbr, cts); } if (bbr_policer_call_from_rack_to) bbr_lt_bw_sampling(bbr, cts, (bbr->r_ctl.rc_lost > lost)); bbr->r_ctl.rc_hpts_flags &= ~PACE_TMR_RACK; return (0); } static __inline void bbr_clone_rsm(struct tcp_bbr *bbr, struct bbr_sendmap *nrsm, struct bbr_sendmap *rsm, uint32_t start) { int idx; nrsm->r_start = start; nrsm->r_end = rsm->r_end; nrsm->r_rtr_cnt = rsm->r_rtr_cnt; nrsm-> r_rtt_not_allowed = rsm->r_rtt_not_allowed; nrsm->r_flags = rsm->r_flags; /* We don't transfer forward the SYN flag */ nrsm->r_flags &= ~BBR_HAS_SYN; /* We move forward the FIN flag, not that this should happen */ rsm->r_flags &= ~BBR_HAS_FIN; nrsm->r_dupack = rsm->r_dupack; nrsm->r_rtr_bytes = 0; nrsm->r_is_gain = rsm->r_is_gain; nrsm->r_is_drain = rsm->r_is_drain; nrsm->r_delivered = rsm->r_delivered; nrsm->r_ts_valid = rsm->r_ts_valid; nrsm->r_del_ack_ts = rsm->r_del_ack_ts; nrsm->r_del_time = rsm->r_del_time; nrsm->r_app_limited = rsm->r_app_limited; nrsm->r_first_sent_time = rsm->r_first_sent_time; nrsm->r_flight_at_send = rsm->r_flight_at_send; /* We split a piece the lower section looses any just_ret flag. */ nrsm->r_bbr_state = rsm->r_bbr_state; for (idx = 0; idx < nrsm->r_rtr_cnt; idx++) { nrsm->r_tim_lastsent[idx] = rsm->r_tim_lastsent[idx]; } rsm->r_end = nrsm->r_start; idx = min((bbr->rc_tp->t_maxseg - bbr->rc_last_options), bbr->r_ctl.rc_pace_max_segs); idx /= 8; /* Check if we got too small */ if ((rsm->r_is_smallmap == 0) && ((rsm->r_end - rsm->r_start) <= idx)) { bbr->r_ctl.rc_num_small_maps_alloced++; rsm->r_is_smallmap = 1; } /* Check the new one as well */ if ((nrsm->r_end - nrsm->r_start) <= idx) { bbr->r_ctl.rc_num_small_maps_alloced++; nrsm->r_is_smallmap = 1; } } static int bbr_sack_mergable(struct bbr_sendmap *at, uint32_t start, uint32_t end) { /* * Given a sack block defined by * start and end, and a current position * at. Return 1 if either side of at * would show that the block is mergable * to that side. A block to be mergable * must have overlap with the start/end * and be in the SACK'd state. */ struct bbr_sendmap *l_rsm; struct bbr_sendmap *r_rsm; /* first get the either side blocks */ l_rsm = TAILQ_PREV(at, bbr_head, r_next); r_rsm = TAILQ_NEXT(at, r_next); if (l_rsm && (l_rsm->r_flags & BBR_ACKED)) { /* Potentially mergeable */ if ((l_rsm->r_end == start) || (SEQ_LT(start, l_rsm->r_end) && SEQ_GT(end, l_rsm->r_end))) { /* * map blk |------| * sack blk |------| * * map blk |------| * sack blk |------| */ return (1); } } if (r_rsm && (r_rsm->r_flags & BBR_ACKED)) { /* Potentially mergeable */ if ((r_rsm->r_start == end) || (SEQ_LT(start, r_rsm->r_start) && SEQ_GT(end, r_rsm->r_start))) { /* * map blk |---------| * sack blk |----| * * map blk |---------| * sack blk |-------| */ return (1); } } return (0); } static struct bbr_sendmap * bbr_merge_rsm(struct tcp_bbr *bbr, struct bbr_sendmap *l_rsm, struct bbr_sendmap *r_rsm) { /* * We are merging two ack'd RSM's, * the l_rsm is on the left (lower seq * values) and the r_rsm is on the right * (higher seq value). The simplest way * to merge these is to move the right * one into the left. I don't think there * is any reason we need to try to find * the oldest (or last oldest retransmitted). */ l_rsm->r_end = r_rsm->r_end; if (l_rsm->r_dupack < r_rsm->r_dupack) l_rsm->r_dupack = r_rsm->r_dupack; if (r_rsm->r_rtr_bytes) l_rsm->r_rtr_bytes += r_rsm->r_rtr_bytes; if (r_rsm->r_in_tmap) { /* This really should not happen */ TAILQ_REMOVE(&bbr->r_ctl.rc_tmap, r_rsm, r_tnext); } if (r_rsm->r_app_limited) l_rsm->r_app_limited = r_rsm->r_app_limited; /* Now the flags */ if (r_rsm->r_flags & BBR_HAS_FIN) l_rsm->r_flags |= BBR_HAS_FIN; if (r_rsm->r_flags & BBR_TLP) l_rsm->r_flags |= BBR_TLP; if (r_rsm->r_flags & BBR_RWND_COLLAPSED) l_rsm->r_flags |= BBR_RWND_COLLAPSED; if (r_rsm->r_flags & BBR_MARKED_LOST) { /* This really should not happen */ bbr->r_ctl.rc_lost_bytes -= r_rsm->r_end - r_rsm->r_start; } TAILQ_REMOVE(&bbr->r_ctl.rc_map, r_rsm, r_next); if ((r_rsm->r_limit_type == 0) && (l_rsm->r_limit_type != 0)) { /* Transfer the split limit to the map we free */ r_rsm->r_limit_type = l_rsm->r_limit_type; l_rsm->r_limit_type = 0; } bbr_free(bbr, r_rsm); return(l_rsm); } /* * TLP Timer, here we simply setup what segment we want to * have the TLP expire on, the normal bbr_output_wtime() will then * send it out. * * We return 1, saying don't proceed with bbr_output_wtime only * when all timers have been stopped (destroyed PCB?). */ static int bbr_timeout_tlp(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts) { /* * Tail Loss Probe. */ struct bbr_sendmap *rsm = NULL; struct socket *so; uint32_t amm; uint32_t out, avail; uint32_t maxseg; int collapsed_win = 0; if (bbr->rc_all_timers_stopped) { return (1); } if (TSTMP_LT(cts, bbr->r_ctl.rc_timer_exp)) { /* Its not time yet */ return (0); } if (ctf_progress_timeout_check(tp, true)) { bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__); return (-ETIMEDOUT); /* tcp_drop() */ } /* Did we somehow get into persists? */ if (bbr->rc_in_persist) { return (0); } if (bbr->r_state && (bbr->r_state != tp->t_state)) bbr_set_state(tp, bbr, 0); BBR_STAT_INC(bbr_tlp_tot); maxseg = tp->t_maxseg - bbr->rc_last_options; /* * A TLP timer has expired. We have been idle for 2 rtts. So we now * need to figure out how to force a full MSS segment out. */ so = tptosocket(tp); avail = sbavail(&so->so_snd); out = ctf_outstanding(tp); if (out > tp->snd_wnd) { /* special case, we need a retransmission */ collapsed_win = 1; goto need_retran; } if (avail > out) { /* New data is available */ amm = avail - out; if (amm > maxseg) { amm = maxseg; } else if ((amm < maxseg) && ((tp->t_flags & TF_NODELAY) == 0)) { /* not enough to fill a MTU and no-delay is off */ goto need_retran; } /* Set the send-new override */ if ((out + amm) <= tp->snd_wnd) { bbr->rc_tlp_new_data = 1; } else { goto need_retran; } bbr->r_ctl.rc_tlp_seg_send_cnt = 0; bbr->r_ctl.rc_last_tlp_seq = tp->snd_max; bbr->r_ctl.rc_tlp_send = NULL; /* cap any slots */ BBR_STAT_INC(bbr_tlp_newdata); goto send; } need_retran: /* * Ok we need to arrange the last un-acked segment to be re-sent, or * optionally the first un-acked segment. */ if (collapsed_win == 0) { rsm = TAILQ_LAST_FAST(&bbr->r_ctl.rc_map, bbr_sendmap, r_next); if (rsm && (BBR_ACKED | BBR_HAS_FIN)) { rsm = bbr_find_high_nonack(bbr, rsm); } if (rsm == NULL) { goto restore; } } else { /* * We must find the last segment * that was acceptable by the client. */ TAILQ_FOREACH_REVERSE(rsm, &bbr->r_ctl.rc_map, bbr_head, r_next) { if ((rsm->r_flags & BBR_RWND_COLLAPSED) == 0) { /* Found one */ break; } } if (rsm == NULL) { /* None? if so send the first */ rsm = TAILQ_FIRST(&bbr->r_ctl.rc_map); if (rsm == NULL) goto restore; } } if ((rsm->r_end - rsm->r_start) > maxseg) { /* * We need to split this the last segment in two. */ struct bbr_sendmap *nrsm; nrsm = bbr_alloc_full_limit(bbr); if (nrsm == NULL) { /* * We can't get memory to split, we can either just * not split it. Or retransmit the whole piece, lets * do the large send (BTLP :-) ). */ goto go_for_it; } bbr_clone_rsm(bbr, nrsm, rsm, (rsm->r_end - maxseg)); TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_map, rsm, nrsm, r_next); if (rsm->r_in_tmap) { TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_tmap, rsm, nrsm, r_tnext); nrsm->r_in_tmap = 1; } rsm->r_flags &= (~BBR_HAS_FIN); rsm = nrsm; } go_for_it: bbr->r_ctl.rc_tlp_send = rsm; bbr->rc_tlp_rtx_out = 1; if (rsm->r_start == bbr->r_ctl.rc_last_tlp_seq) { bbr->r_ctl.rc_tlp_seg_send_cnt++; tp->t_rxtshift++; } else { bbr->r_ctl.rc_last_tlp_seq = rsm->r_start; bbr->r_ctl.rc_tlp_seg_send_cnt = 1; } send: if (bbr->r_ctl.rc_tlp_seg_send_cnt > bbr_tlp_max_resend) { /* * Can't [re]/transmit a segment we have retransmitted the * max times. We need the retransmit timer to take over. */ restore: bbr->rc_tlp_new_data = 0; bbr->r_ctl.rc_tlp_send = NULL; if (rsm) rsm->r_flags &= ~BBR_TLP; BBR_STAT_INC(bbr_tlp_retran_fail); return (0); } else if (rsm) { rsm->r_flags |= BBR_TLP; } if (rsm && (rsm->r_start == bbr->r_ctl.rc_last_tlp_seq) && (bbr->r_ctl.rc_tlp_seg_send_cnt > bbr_tlp_max_resend)) { /* * We have retransmitted to many times for TLP. Switch to * the regular RTO timer */ goto restore; } bbr_log_to_event(bbr, cts, BBR_TO_FRM_TLP); bbr->r_ctl.rc_hpts_flags &= ~PACE_TMR_TLP; return (0); } /* * Delayed ack Timer, here we simply need to setup the * ACK_NOW flag and remove the DELACK flag. From there * the output routine will send the ack out. * * We only return 1, saying don't proceed, if all timers * are stopped (destroyed PCB?). */ static int bbr_timeout_delack(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts) { if (bbr->rc_all_timers_stopped) { return (1); } bbr_log_to_event(bbr, cts, BBR_TO_FRM_DELACK); tp->t_flags &= ~TF_DELACK; tp->t_flags |= TF_ACKNOW; KMOD_TCPSTAT_INC(tcps_delack); bbr->r_ctl.rc_hpts_flags &= ~PACE_TMR_DELACK; return (0); } /* * Here we send a KEEP-ALIVE like probe to the * peer, we do not send data. * * We only return 1, saying don't proceed, if all timers * are stopped (destroyed PCB?). */ static int bbr_timeout_persist(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts) { struct tcptemp *t_template; int32_t retval = 1; if (bbr->rc_all_timers_stopped) { return (1); } if (bbr->rc_in_persist == 0) return (0); /* * Persistence timer into zero window. Force a byte to be output, if * possible. */ bbr_log_to_event(bbr, cts, BBR_TO_FRM_PERSIST); bbr->r_ctl.rc_hpts_flags &= ~PACE_TMR_PERSIT; KMOD_TCPSTAT_INC(tcps_persisttimeo); /* * Have we exceeded the user specified progress time? */ if (ctf_progress_timeout_check(tp, true)) { bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__); return (-ETIMEDOUT); /* tcp_drop() */ } /* * Hack: if the peer is dead/unreachable, we do not time out if the * window is closed. After a full backoff, drop the connection if * the idle time (no responses to probes) reaches the maximum * backoff that we would use if retransmitting. */ if (tp->t_rxtshift == TCP_MAXRXTSHIFT && (ticks - tp->t_rcvtime >= tcp_maxpersistidle || ticks - tp->t_rcvtime >= TCP_REXMTVAL(tp) * tcp_totbackoff)) { KMOD_TCPSTAT_INC(tcps_persistdrop); tcp_log_end_status(tp, TCP_EI_STATUS_PERSIST_MAX); return (-ETIMEDOUT); /* tcp_drop() */ } if ((sbavail(&bbr->rc_inp->inp_socket->so_snd) == 0) && tp->snd_una == tp->snd_max) { bbr_exit_persist(tp, bbr, cts, __LINE__); retval = 0; goto out; } /* * If the user has closed the socket then drop a persisting * connection after a much reduced timeout. */ if (tp->t_state > TCPS_CLOSE_WAIT && (ticks - tp->t_rcvtime) >= TCPTV_PERSMAX) { KMOD_TCPSTAT_INC(tcps_persistdrop); tcp_log_end_status(tp, TCP_EI_STATUS_PERSIST_MAX); return (-ETIMEDOUT); /* tcp_drop() */ } t_template = tcpip_maketemplate(bbr->rc_inp); if (t_template) { tcp_respond(tp, t_template->tt_ipgen, &t_template->tt_t, (struct mbuf *)NULL, tp->rcv_nxt, tp->snd_una - 1, 0); /* This sends an ack */ if (tp->t_flags & TF_DELACK) tp->t_flags &= ~TF_DELACK; free(t_template, M_TEMP); } if (tp->t_rxtshift < TCP_MAXRXTSHIFT) tp->t_rxtshift++; bbr_start_hpts_timer(bbr, tp, cts, 3, 0, 0); out: return (retval); } /* * If a keepalive goes off, we had no other timers * happening. We always return 1 here since this * routine either drops the connection or sends * out a segment with respond. */ static int bbr_timeout_keepalive(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts) { struct tcptemp *t_template; struct inpcb *inp = tptoinpcb(tp); if (bbr->rc_all_timers_stopped) { return (1); } bbr->r_ctl.rc_hpts_flags &= ~PACE_TMR_KEEP; bbr_log_to_event(bbr, cts, BBR_TO_FRM_KEEP); /* * Keep-alive timer went off; send something or drop connection if * idle for too long. */ KMOD_TCPSTAT_INC(tcps_keeptimeo); if (tp->t_state < TCPS_ESTABLISHED) goto dropit; if ((V_tcp_always_keepalive || inp->inp_socket->so_options & SO_KEEPALIVE) && tp->t_state <= TCPS_CLOSING) { if (ticks - tp->t_rcvtime >= TP_KEEPIDLE(tp) + TP_MAXIDLE(tp)) goto dropit; /* * Send a packet designed to force a response if the peer is * up and reachable: either an ACK if the connection is * still alive, or an RST if the peer has closed the * connection due to timeout or reboot. Using sequence * number tp->snd_una-1 causes the transmitted zero-length * segment to lie outside the receive window; by the * protocol spec, this requires the correspondent TCP to * respond. */ KMOD_TCPSTAT_INC(tcps_keepprobe); t_template = tcpip_maketemplate(inp); if (t_template) { tcp_respond(tp, t_template->tt_ipgen, &t_template->tt_t, (struct mbuf *)NULL, tp->rcv_nxt, tp->snd_una - 1, 0); free(t_template, M_TEMP); } } bbr_start_hpts_timer(bbr, tp, cts, 4, 0, 0); return (1); dropit: KMOD_TCPSTAT_INC(tcps_keepdrops); tcp_log_end_status(tp, TCP_EI_STATUS_KEEP_MAX); return (-ETIMEDOUT); /* tcp_drop() */ } /* * Retransmit helper function, clear up all the ack * flags and take care of important book keeping. */ static void bbr_remxt_tmr(struct tcpcb *tp) { /* * The retransmit timer went off, all sack'd blocks must be * un-acked. */ struct bbr_sendmap *rsm, *trsm = NULL; struct tcp_bbr *bbr; uint32_t cts, lost; bbr = (struct tcp_bbr *)tp->t_fb_ptr; cts = tcp_get_usecs(&bbr->rc_tv); lost = bbr->r_ctl.rc_lost; if (bbr->r_state && (bbr->r_state != tp->t_state)) bbr_set_state(tp, bbr, 0); TAILQ_FOREACH(rsm, &bbr->r_ctl.rc_map, r_next) { if (rsm->r_flags & BBR_ACKED) { uint32_t old_flags; rsm->r_dupack = 0; if (rsm->r_in_tmap == 0) { /* We must re-add it back to the tlist */ if (trsm == NULL) { TAILQ_INSERT_HEAD(&bbr->r_ctl.rc_tmap, rsm, r_tnext); } else { TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_tmap, trsm, rsm, r_tnext); } rsm->r_in_tmap = 1; } old_flags = rsm->r_flags; rsm->r_flags |= BBR_RXT_CLEARED; rsm->r_flags &= ~(BBR_ACKED | BBR_SACK_PASSED | BBR_WAS_SACKPASS); bbr_log_type_rsmclear(bbr, cts, rsm, old_flags, __LINE__); } else { if ((tp->t_state < TCPS_ESTABLISHED) && (rsm->r_start == tp->snd_una)) { /* * Special case for TCP FO. Where * we sent more data beyond the snd_max. * We don't mark that as lost and stop here. */ break; } if ((rsm->r_flags & BBR_MARKED_LOST) == 0) { bbr->r_ctl.rc_lost += rsm->r_end - rsm->r_start; bbr->r_ctl.rc_lost_bytes += rsm->r_end - rsm->r_start; } if (bbr_marks_rxt_sack_passed) { /* * With this option, we will rack out * in 1ms increments the rest of the packets. */ rsm->r_flags |= BBR_SACK_PASSED | BBR_MARKED_LOST; rsm->r_flags &= ~BBR_WAS_SACKPASS; } else { /* * With this option we only mark them lost * and remove all sack'd markings. We will run * another RXT or a TLP. This will cause * us to eventually send more based on what * ack's come in. */ rsm->r_flags |= BBR_MARKED_LOST; rsm->r_flags &= ~BBR_WAS_SACKPASS; rsm->r_flags &= ~BBR_SACK_PASSED; } } trsm = rsm; } bbr->r_ctl.rc_resend = TAILQ_FIRST(&bbr->r_ctl.rc_map); /* Clear the count (we just un-acked them) */ bbr_log_to_event(bbr, cts, BBR_TO_FRM_TMR); bbr->rc_tlp_new_data = 0; bbr->r_ctl.rc_tlp_seg_send_cnt = 0; /* zap the behindness on a rxt */ bbr->r_ctl.rc_hptsi_agg_delay = 0; bbr->r_agg_early_set = 0; bbr->r_ctl.rc_agg_early = 0; bbr->rc_tlp_rtx_out = 0; bbr->r_ctl.rc_sacked = 0; bbr->r_ctl.rc_sacklast = NULL; bbr->r_timer_override = 1; bbr_lt_bw_sampling(bbr, cts, (bbr->r_ctl.rc_lost > lost)); } /* * Re-transmit timeout! If we drop the PCB we will return 1, otherwise * we will setup to retransmit the lowest seq number outstanding. */ static int bbr_timeout_rxt(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts) { struct inpcb *inp = tptoinpcb(tp); int32_t rexmt; int32_t retval = 0; bool isipv6; bbr->r_ctl.rc_hpts_flags &= ~PACE_TMR_RXT; if (bbr->rc_all_timers_stopped) { return (1); } if (TCPS_HAVEESTABLISHED(tp->t_state) && (tp->snd_una == tp->snd_max)) { /* Nothing outstanding .. nothing to do */ return (0); } /* * Retransmission timer went off. Message has not been acked within * retransmit interval. Back off to a longer retransmit interval * and retransmit one segment. */ if (ctf_progress_timeout_check(tp, true)) { bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__); return (-ETIMEDOUT); /* tcp_drop() */ } bbr_remxt_tmr(tp); if ((bbr->r_ctl.rc_resend == NULL) || ((bbr->r_ctl.rc_resend->r_flags & BBR_RWND_COLLAPSED) == 0)) { /* * If the rwnd collapsed on * the one we are retransmitting * it does not count against the * rxt count. */ tp->t_rxtshift++; } if (tp->t_rxtshift > TCP_MAXRXTSHIFT) { tp->t_rxtshift = TCP_MAXRXTSHIFT; KMOD_TCPSTAT_INC(tcps_timeoutdrop); tcp_log_end_status(tp, TCP_EI_STATUS_RETRAN); /* XXXGL: previously t_softerror was casted to uint16_t */ MPASS(tp->t_softerror >= 0); retval = tp->t_softerror ? -tp->t_softerror : -ETIMEDOUT; return (retval); /* tcp_drop() */ } if (tp->t_state == TCPS_SYN_SENT) { /* * If the SYN was retransmitted, indicate CWND to be limited * to 1 segment in cc_conn_init(). */ tp->snd_cwnd = 1; } else if (tp->t_rxtshift == 1) { /* * first retransmit; record ssthresh and cwnd so they can be * recovered if this turns out to be a "bad" retransmit. A * retransmit is considered "bad" if an ACK for this segment * is received within RTT/2 interval; the assumption here is * that the ACK was already in flight. See "On Estimating * End-to-End Network Path Properties" by Allman and Paxson * for more details. */ tp->snd_cwnd = tp->t_maxseg - bbr->rc_last_options; if (!IN_RECOVERY(tp->t_flags)) { tp->snd_cwnd_prev = tp->snd_cwnd; tp->snd_ssthresh_prev = tp->snd_ssthresh; tp->snd_recover_prev = tp->snd_recover; tp->t_badrxtwin = ticks + (tp->t_srtt >> (TCP_RTT_SHIFT + 1)); tp->t_flags |= TF_PREVVALID; } else { tp->t_flags &= ~TF_PREVVALID; } tp->snd_cwnd = tp->t_maxseg - bbr->rc_last_options; } else { tp->snd_cwnd = tp->t_maxseg - bbr->rc_last_options; tp->t_flags &= ~TF_PREVVALID; } KMOD_TCPSTAT_INC(tcps_rexmttimeo); if ((tp->t_state == TCPS_SYN_SENT) || (tp->t_state == TCPS_SYN_RECEIVED)) rexmt = USEC_2_TICKS(BBR_INITIAL_RTO) * tcp_backoff[tp->t_rxtshift]; else rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift]; TCPT_RANGESET(tp->t_rxtcur, rexmt, MSEC_2_TICKS(bbr->r_ctl.rc_min_rto_ms), MSEC_2_TICKS(((uint32_t)bbr->rc_max_rto_sec) * 1000)); /* * We enter the path for PLMTUD if connection is established or, if * connection is FIN_WAIT_1 status, reason for the last is that if * amount of data we send is very small, we could send it in couple * of packets and process straight to FIN. In that case we won't * catch ESTABLISHED state. */ #ifdef INET6 isipv6 = (inp->inp_vflag & INP_IPV6) ? true : false; #else isipv6 = false; #endif if (((V_tcp_pmtud_blackhole_detect == 1) || (V_tcp_pmtud_blackhole_detect == 2 && !isipv6) || (V_tcp_pmtud_blackhole_detect == 3 && isipv6)) && ((tp->t_state == TCPS_ESTABLISHED) || (tp->t_state == TCPS_FIN_WAIT_1))) { /* * Idea here is that at each stage of mtu probe (usually, * 1448 -> 1188 -> 524) should be given 2 chances to recover * before further clamping down. 'tp->t_rxtshift % 2 == 0' * should take care of that. */ if (((tp->t_flags2 & (TF2_PLPMTU_PMTUD | TF2_PLPMTU_MAXSEGSNT)) == (TF2_PLPMTU_PMTUD | TF2_PLPMTU_MAXSEGSNT)) && (tp->t_rxtshift >= 2 && tp->t_rxtshift < 6 && tp->t_rxtshift % 2 == 0)) { /* * Enter Path MTU Black-hole Detection mechanism: - * Disable Path MTU Discovery (IP "DF" bit). - * Reduce MTU to lower value than what we negotiated * with peer. */ if ((tp->t_flags2 & TF2_PLPMTU_BLACKHOLE) == 0) { /* * Record that we may have found a black * hole. */ tp->t_flags2 |= TF2_PLPMTU_BLACKHOLE; /* Keep track of previous MSS. */ tp->t_pmtud_saved_maxseg = tp->t_maxseg; } /* * Reduce the MSS to blackhole value or to the * default in an attempt to retransmit. */ #ifdef INET6 isipv6 = bbr->r_is_v6; if (isipv6 && tp->t_maxseg > V_tcp_v6pmtud_blackhole_mss) { /* Use the sysctl tuneable blackhole MSS. */ tp->t_maxseg = V_tcp_v6pmtud_blackhole_mss; KMOD_TCPSTAT_INC(tcps_pmtud_blackhole_activated); } else if (isipv6) { /* Use the default MSS. */ tp->t_maxseg = V_tcp_v6mssdflt; /* * Disable Path MTU Discovery when we switch * to minmss. */ tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; KMOD_TCPSTAT_INC(tcps_pmtud_blackhole_activated_min_mss); } #endif #if defined(INET6) && defined(INET) else #endif #ifdef INET if (tp->t_maxseg > V_tcp_pmtud_blackhole_mss) { /* Use the sysctl tuneable blackhole MSS. */ tp->t_maxseg = V_tcp_pmtud_blackhole_mss; KMOD_TCPSTAT_INC(tcps_pmtud_blackhole_activated); } else { /* Use the default MSS. */ tp->t_maxseg = V_tcp_mssdflt; /* * Disable Path MTU Discovery when we switch * to minmss. */ tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; KMOD_TCPSTAT_INC(tcps_pmtud_blackhole_activated_min_mss); } #endif } else { /* * If further retransmissions are still unsuccessful * with a lowered MTU, maybe this isn't a blackhole * and we restore the previous MSS and blackhole * detection flags. The limit '6' is determined by * giving each probe stage (1448, 1188, 524) 2 * chances to recover. */ if ((tp->t_flags2 & TF2_PLPMTU_BLACKHOLE) && (tp->t_rxtshift >= 6)) { tp->t_flags2 |= TF2_PLPMTU_PMTUD; tp->t_flags2 &= ~TF2_PLPMTU_BLACKHOLE; tp->t_maxseg = tp->t_pmtud_saved_maxseg; KMOD_TCPSTAT_INC(tcps_pmtud_blackhole_failed); } } } /* * Disable RFC1323 and SACK if we haven't got any response to our * third SYN to work-around some broken terminal servers (most of * which have hopefully been retired) that have bad VJ header * compression code which trashes TCP segments containing * unknown-to-them TCP options. */ if (tcp_rexmit_drop_options && (tp->t_state == TCPS_SYN_SENT) && (tp->t_rxtshift == 3)) tp->t_flags &= ~(TF_REQ_SCALE | TF_REQ_TSTMP | TF_SACK_PERMIT); /* * If we backed off this far, our srtt estimate is probably bogus. * Clobber it so we'll take the next rtt measurement as our srtt; * move the current srtt into rttvar to keep the current retransmit * times until then. */ if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) { #ifdef INET6 if (bbr->r_is_v6) in6_losing(inp); else #endif in_losing(inp); tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT); tp->t_srtt = 0; } sack_filter_clear(&bbr->r_ctl.bbr_sf, tp->snd_una); tp->snd_recover = tp->snd_max; tp->t_flags |= TF_ACKNOW; tp->t_rtttime = 0; return (retval); } static int bbr_process_timers(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts, uint8_t hpts_calling) { int32_t ret = 0; int32_t timers = (bbr->r_ctl.rc_hpts_flags & PACE_TMR_MASK); if (timers == 0) { return (0); } if (tp->t_state == TCPS_LISTEN) { /* no timers on listen sockets */ if (bbr->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) return (0); return (1); } if (TSTMP_LT(cts, bbr->r_ctl.rc_timer_exp)) { uint32_t left; if (bbr->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) { ret = -1; bbr_log_to_processing(bbr, cts, ret, 0, hpts_calling); return (0); } if (hpts_calling == 0) { ret = -2; bbr_log_to_processing(bbr, cts, ret, 0, hpts_calling); return (0); } /* * Ok our timer went off early and we are not paced false * alarm, go back to sleep. */ left = bbr->r_ctl.rc_timer_exp - cts; ret = -3; bbr_log_to_processing(bbr, cts, ret, left, hpts_calling); tcp_hpts_insert(tptoinpcb(tp), HPTS_USEC_TO_SLOTS(left)); return (1); } bbr->rc_tmr_stopped = 0; bbr->r_ctl.rc_hpts_flags &= ~PACE_TMR_MASK; if (timers & PACE_TMR_DELACK) { ret = bbr_timeout_delack(tp, bbr, cts); } else if (timers & PACE_TMR_PERSIT) { ret = bbr_timeout_persist(tp, bbr, cts); } else if (timers & PACE_TMR_RACK) { bbr->r_ctl.rc_tlp_rxt_last_time = cts; ret = bbr_timeout_rack(tp, bbr, cts); } else if (timers & PACE_TMR_TLP) { bbr->r_ctl.rc_tlp_rxt_last_time = cts; ret = bbr_timeout_tlp(tp, bbr, cts); } else if (timers & PACE_TMR_RXT) { bbr->r_ctl.rc_tlp_rxt_last_time = cts; ret = bbr_timeout_rxt(tp, bbr, cts); } else if (timers & PACE_TMR_KEEP) { ret = bbr_timeout_keepalive(tp, bbr, cts); } bbr_log_to_processing(bbr, cts, ret, timers, hpts_calling); return (ret); } static void bbr_timer_cancel(struct tcp_bbr *bbr, int32_t line, uint32_t cts) { if (bbr->r_ctl.rc_hpts_flags & PACE_TMR_MASK) { uint8_t hpts_removed = 0; if (tcp_in_hpts(bbr->rc_inp) && (bbr->rc_timer_first == 1)) { /* * If we are canceling timer's when we have the * timer ahead of the output being paced. We also * must remove ourselves from the hpts. */ hpts_removed = 1; tcp_hpts_remove(bbr->rc_inp); if (bbr->r_ctl.rc_last_delay_val) { /* Update the last hptsi delay too */ uint32_t time_since_send; if (TSTMP_GT(cts, bbr->rc_pacer_started)) time_since_send = cts - bbr->rc_pacer_started; else time_since_send = 0; if (bbr->r_ctl.rc_last_delay_val > time_since_send) { /* Cut down our slot time */ bbr->r_ctl.rc_last_delay_val -= time_since_send; } else { bbr->r_ctl.rc_last_delay_val = 0; } bbr->rc_pacer_started = cts; } } bbr->rc_timer_first = 0; bbr_log_to_cancel(bbr, line, cts, hpts_removed); bbr->rc_tmr_stopped = bbr->r_ctl.rc_hpts_flags & PACE_TMR_MASK; bbr->r_ctl.rc_hpts_flags &= ~(PACE_TMR_MASK); } } static int bbr_stopall(struct tcpcb *tp) { struct tcp_bbr *bbr; bbr = (struct tcp_bbr *)tp->t_fb_ptr; bbr->rc_all_timers_stopped = 1; return (0); } static uint32_t bbr_get_earliest_send_outstanding(struct tcp_bbr *bbr, struct bbr_sendmap *u_rsm, uint32_t cts) { struct bbr_sendmap *rsm; rsm = TAILQ_FIRST(&bbr->r_ctl.rc_tmap); if ((rsm == NULL) || (u_rsm == rsm)) return (cts); return(rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]); } static void bbr_update_rsm(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t cts, uint32_t pacing_time) { int32_t idx; rsm->r_rtr_cnt++; rsm->r_dupack = 0; if (rsm->r_rtr_cnt > BBR_NUM_OF_RETRANS) { rsm->r_rtr_cnt = BBR_NUM_OF_RETRANS; rsm->r_flags |= BBR_OVERMAX; } if (rsm->r_flags & BBR_RWND_COLLAPSED) { /* Take off the collapsed flag at rxt */ rsm->r_flags &= ~BBR_RWND_COLLAPSED; } if (rsm->r_flags & BBR_MARKED_LOST) { /* We have retransmitted, its no longer lost */ rsm->r_flags &= ~BBR_MARKED_LOST; bbr->r_ctl.rc_lost_bytes -= rsm->r_end - rsm->r_start; } if (rsm->r_flags & BBR_RXT_CLEARED) { /* * We hit a RXT timer on it and * we cleared the "acked" flag. * We now have it going back into * flight, we can remove the cleared * flag and possibly do accounting on * this piece. */ rsm->r_flags &= ~BBR_RXT_CLEARED; } if ((rsm->r_rtr_cnt > 1) && ((rsm->r_flags & BBR_TLP) == 0)) { bbr->r_ctl.rc_holes_rxt += (rsm->r_end - rsm->r_start); rsm->r_rtr_bytes += (rsm->r_end - rsm->r_start); } idx = rsm->r_rtr_cnt - 1; rsm->r_tim_lastsent[idx] = cts; rsm->r_pacing_delay = pacing_time; rsm->r_delivered = bbr->r_ctl.rc_delivered; rsm->r_ts_valid = bbr->rc_ts_valid; if (bbr->rc_ts_valid) rsm->r_del_ack_ts = bbr->r_ctl.last_inbound_ts; if (bbr->r_ctl.r_app_limited_until) rsm->r_app_limited = 1; else rsm->r_app_limited = 0; if (bbr->rc_bbr_state == BBR_STATE_PROBE_BW) rsm->r_bbr_state = bbr_state_val(bbr); else rsm->r_bbr_state = 8; if (rsm->r_flags & BBR_ACKED) { /* Problably MTU discovery messing with us */ uint32_t old_flags; old_flags = rsm->r_flags; rsm->r_flags &= ~BBR_ACKED; bbr_log_type_rsmclear(bbr, cts, rsm, old_flags, __LINE__); bbr->r_ctl.rc_sacked -= (rsm->r_end - rsm->r_start); if (bbr->r_ctl.rc_sacked == 0) bbr->r_ctl.rc_sacklast = NULL; } if (rsm->r_in_tmap) { TAILQ_REMOVE(&bbr->r_ctl.rc_tmap, rsm, r_tnext); } TAILQ_INSERT_TAIL(&bbr->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 1; if (rsm->r_flags & BBR_SACK_PASSED) { /* We have retransmitted due to the SACK pass */ rsm->r_flags &= ~BBR_SACK_PASSED; rsm->r_flags |= BBR_WAS_SACKPASS; } rsm->r_first_sent_time = bbr_get_earliest_send_outstanding(bbr, rsm, cts); rsm->r_flight_at_send = ctf_flight_size(bbr->rc_tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); bbr->r_ctl.rc_next = TAILQ_NEXT(rsm, r_next); if (bbr->r_ctl.rc_bbr_hptsi_gain > BBR_UNIT) { rsm->r_is_gain = 1; rsm->r_is_drain = 0; } else if (bbr->r_ctl.rc_bbr_hptsi_gain < BBR_UNIT) { rsm->r_is_drain = 1; rsm->r_is_gain = 0; } else { rsm->r_is_drain = 0; rsm->r_is_gain = 0; } rsm->r_del_time = bbr->r_ctl.rc_del_time; /* TEMP GOOGLE CODE */ } /* * Returns 0, or the sequence where we stopped * updating. We also update the lenp to be the amount * of data left. */ static uint32_t bbr_update_entry(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t cts, int32_t *lenp, uint32_t pacing_time) { /* * We (re-)transmitted starting at rsm->r_start for some length * (possibly less than r_end. */ struct bbr_sendmap *nrsm; uint32_t c_end; int32_t len; len = *lenp; c_end = rsm->r_start + len; if (SEQ_GEQ(c_end, rsm->r_end)) { /* * We retransmitted the whole piece or more than the whole * slopping into the next rsm. */ bbr_update_rsm(tp, bbr, rsm, cts, pacing_time); if (c_end == rsm->r_end) { *lenp = 0; return (0); } else { int32_t act_len; /* Hangs over the end return whats left */ act_len = rsm->r_end - rsm->r_start; *lenp = (len - act_len); return (rsm->r_end); } /* We don't get out of this block. */ } /* * Here we retransmitted less than the whole thing which means we * have to split this into what was transmitted and what was not. */ nrsm = bbr_alloc_full_limit(bbr); if (nrsm == NULL) { *lenp = 0; return (0); } /* * So here we are going to take the original rsm and make it what we * retransmitted. nrsm will be the tail portion we did not * retransmit. For example say the chunk was 1, 11 (10 bytes). And * we retransmitted 5 bytes i.e. 1, 5. The original piece shrinks to * 1, 6 and the new piece will be 6, 11. */ bbr_clone_rsm(bbr, nrsm, rsm, c_end); TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_map, rsm, nrsm, r_next); nrsm->r_dupack = 0; if (rsm->r_in_tmap) { TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_tmap, rsm, nrsm, r_tnext); nrsm->r_in_tmap = 1; } rsm->r_flags &= (~BBR_HAS_FIN); bbr_update_rsm(tp, bbr, rsm, cts, pacing_time); *lenp = 0; return (0); } static uint64_t bbr_get_hardware_rate(struct tcp_bbr *bbr) { uint64_t bw; bw = bbr_get_bw(bbr); bw *= (uint64_t)bbr_hptsi_gain[BBR_SUB_GAIN]; bw /= (uint64_t)BBR_UNIT; return(bw); } static void bbr_setup_less_of_rate(struct tcp_bbr *bbr, uint32_t cts, uint64_t act_rate, uint64_t rate_wanted) { /* * We could not get a full gains worth * of rate. */ if (get_filter_value(&bbr->r_ctl.rc_delrate) >= act_rate) { /* we can't even get the real rate */ uint64_t red; bbr->skip_gain = 1; bbr->gain_is_limited = 0; red = get_filter_value(&bbr->r_ctl.rc_delrate) - act_rate; if (red) filter_reduce_by(&bbr->r_ctl.rc_delrate, red, cts); } else { /* We can use a lower gain */ bbr->skip_gain = 0; bbr->gain_is_limited = 1; } } static void bbr_update_hardware_pacing_rate(struct tcp_bbr *bbr, uint32_t cts) { const struct tcp_hwrate_limit_table *nrte; int error, rate = -1; if (bbr->r_ctl.crte == NULL) return; if ((bbr->rc_inp->inp_route.ro_nh == NULL) || (bbr->rc_inp->inp_route.ro_nh->nh_ifp == NULL)) { /* Lost our routes? */ /* Clear the way for a re-attempt */ bbr->bbr_attempt_hdwr_pace = 0; lost_rate: bbr->gain_is_limited = 0; bbr->skip_gain = 0; bbr->bbr_hdrw_pacing = 0; counter_u64_add(bbr_flows_whdwr_pacing, -1); counter_u64_add(bbr_flows_nohdwr_pacing, 1); tcp_bbr_tso_size_check(bbr, cts); return; } rate = bbr_get_hardware_rate(bbr); nrte = tcp_chg_pacing_rate(bbr->r_ctl.crte, bbr->rc_tp, bbr->rc_inp->inp_route.ro_nh->nh_ifp, rate, (RS_PACING_GEQ|RS_PACING_SUB_OK), &error, NULL); if (nrte == NULL) { goto lost_rate; } if (nrte != bbr->r_ctl.crte) { bbr->r_ctl.crte = nrte; if (error == 0) { BBR_STAT_INC(bbr_hdwr_rl_mod_ok); if (bbr->r_ctl.crte->rate < rate) { /* We have a problem */ bbr_setup_less_of_rate(bbr, cts, bbr->r_ctl.crte->rate, rate); } else { /* We are good */ bbr->gain_is_limited = 0; bbr->skip_gain = 0; } } else { /* A failure should release the tag */ BBR_STAT_INC(bbr_hdwr_rl_mod_fail); bbr->gain_is_limited = 0; bbr->skip_gain = 0; bbr->bbr_hdrw_pacing = 0; } bbr_type_log_hdwr_pacing(bbr, bbr->r_ctl.crte->ptbl->rs_ifp, rate, ((bbr->r_ctl.crte == NULL) ? 0 : bbr->r_ctl.crte->rate), __LINE__, cts, error); } } static void bbr_adjust_for_hw_pacing(struct tcp_bbr *bbr, uint32_t cts) { /* * If we have hardware pacing support * we need to factor that in for our * TSO size. */ const struct tcp_hwrate_limit_table *rlp; uint32_t cur_delay, seg_sz, maxseg, new_tso, delta, hdwr_delay; if ((bbr->bbr_hdrw_pacing == 0) || (IN_RECOVERY(bbr->rc_tp->t_flags)) || (bbr->r_ctl.crte == NULL)) return; if (bbr->hw_pacing_set == 0) { /* Not yet by the hdwr pacing count delay */ return; } if (bbr_hdwr_pace_adjust == 0) { /* No adjustment */ return; } rlp = bbr->r_ctl.crte; if (bbr->rc_tp->t_maxseg > bbr->rc_last_options) maxseg = bbr->rc_tp->t_maxseg - bbr->rc_last_options; else maxseg = BBR_MIN_SEG - bbr->rc_last_options; /* * So lets first get the * time we will take between * TSO sized sends currently without * hardware help. */ cur_delay = bbr_get_pacing_delay(bbr, BBR_UNIT, bbr->r_ctl.rc_pace_max_segs, cts, 1); hdwr_delay = bbr->r_ctl.rc_pace_max_segs / maxseg; hdwr_delay *= rlp->time_between; if (cur_delay > hdwr_delay) delta = cur_delay - hdwr_delay; else delta = 0; bbr_log_type_tsosize(bbr, cts, delta, cur_delay, hdwr_delay, (bbr->r_ctl.rc_pace_max_segs / maxseg), 1); if (delta && (delta < (max(rlp->time_between, bbr->r_ctl.bbr_hptsi_segments_delay_tar)))) { /* * Now lets divide by the pacing * time between each segment the * hardware sends rounding up and * derive a bytes from that. We multiply * that by bbr_hdwr_pace_adjust to get * more bang for our buck. * * The goal is to have the software pacer * waiting no more than an additional * pacing delay if we can (without the * compensation i.e. x bbr_hdwr_pace_adjust). */ seg_sz = max(((cur_delay + rlp->time_between)/rlp->time_between), (bbr->r_ctl.rc_pace_max_segs/maxseg)); seg_sz *= bbr_hdwr_pace_adjust; if (bbr_hdwr_pace_floor && (seg_sz < bbr->r_ctl.crte->ptbl->rs_min_seg)) { /* Currently hardware paces * out rs_min_seg segments at a time. * We need to make sure we always send at least * a full burst of bbr_hdwr_pace_floor down. */ seg_sz = bbr->r_ctl.crte->ptbl->rs_min_seg; } seg_sz *= maxseg; } else if (delta == 0) { /* * The highest pacing rate is * above our b/w gained. This means * we probably are going quite fast at * the hardware highest rate. Lets just multiply * the calculated TSO size by the * multiplier factor (its probably * 4 segments in the default config for * mlx). */ seg_sz = bbr->r_ctl.rc_pace_max_segs * bbr_hdwr_pace_adjust; if (bbr_hdwr_pace_floor && (seg_sz < bbr->r_ctl.crte->ptbl->rs_min_seg)) { /* Currently hardware paces * out rs_min_seg segments at a time. * We need to make sure we always send at least * a full burst of bbr_hdwr_pace_floor down. */ seg_sz = bbr->r_ctl.crte->ptbl->rs_min_seg; } } else { /* * The pacing time difference is so * big that the hardware will * pace out more rapidly then we * really want and then we * will have a long delay. Lets just keep * the same TSO size so its as if * we were not using hdwr pacing (we * just gain a bit of spacing from the * hardware if seg_sz > 1). */ seg_sz = bbr->r_ctl.rc_pace_max_segs; } if (seg_sz > bbr->r_ctl.rc_pace_max_segs) new_tso = seg_sz; else new_tso = bbr->r_ctl.rc_pace_max_segs; if (new_tso >= (PACE_MAX_IP_BYTES-maxseg)) new_tso = PACE_MAX_IP_BYTES - maxseg; if (new_tso != bbr->r_ctl.rc_pace_max_segs) { bbr_log_type_tsosize(bbr, cts, new_tso, 0, bbr->r_ctl.rc_pace_max_segs, maxseg, 0); bbr->r_ctl.rc_pace_max_segs = new_tso; } } static void tcp_bbr_tso_size_check(struct tcp_bbr *bbr, uint32_t cts) { uint64_t bw; uint32_t old_tso = 0, new_tso; uint32_t maxseg, bytes; uint32_t tls_seg=0; /* * Google/linux uses the following algorithm to determine * the TSO size based on the b/w of the link (from Neal Cardwell email 9/27/18): * * bytes = bw_in_bytes_per_second / 1000 * bytes = min(bytes, 64k) * tso_segs = bytes / MSS * if (bw < 1.2Mbs) * min_tso_segs = 1 * else * min_tso_segs = 2 * tso_segs = max(tso_segs, min_tso_segs) * * * Note apply a device specific limit (we apply this in the * tcp_m_copym). * Note that before the initial measurement is made google bursts out * a full iwnd just like new-reno/cubic. * * We do not use this algorithm. Instead we * use a two phased approach: * * if ( bw <= per-tcb-cross-over) * goal_tso = calculate how much with this bw we * can send in goal-time seconds. * if (goal_tso > mss) * seg = goal_tso / mss * tso = seg * mss * else * tso = mss * if (tso > per-tcb-max) * tso = per-tcb-max * else if ( bw > 512Mbps) * tso = max-tso (64k/mss) * else * goal_tso = bw / per-tcb-divsor * seg = (goal_tso + mss-1)/mss * tso = seg * mss * * if (tso < per-tcb-floor) * tso = per-tcb-floor * if (tso > per-tcb-utter_max) * tso = per-tcb-utter_max * * Note the default per-tcb-divisor is 1000 (same as google). * the goal cross over is 30Mbps however. To recreate googles * algorithm you need to set: * * cross-over = 23,168,000 bps * goal-time = 18000 * per-tcb-max = 2 * per-tcb-divisor = 1000 * per-tcb-floor = 1 * * This will get you "google bbr" behavior with respect to tso size. * * Note we do set anything TSO size until we are past the initial * window. Before that we gnerally use either a single MSS * or we use the full IW size (so we burst a IW at a time) */ if (bbr->rc_tp->t_maxseg > bbr->rc_last_options) { maxseg = bbr->rc_tp->t_maxseg - bbr->rc_last_options; } else { maxseg = BBR_MIN_SEG - bbr->rc_last_options; } old_tso = bbr->r_ctl.rc_pace_max_segs; if (bbr->rc_past_init_win == 0) { /* * Not enough data has been acknowledged to make a * judgement. Set up the initial TSO based on if we * are sending a full IW at once or not. */ if (bbr->rc_use_google) bbr->r_ctl.rc_pace_max_segs = ((bbr->rc_tp->t_maxseg - bbr->rc_last_options) * 2); else if (bbr->bbr_init_win_cheat) bbr->r_ctl.rc_pace_max_segs = bbr_initial_cwnd(bbr, bbr->rc_tp); else bbr->r_ctl.rc_pace_max_segs = bbr->rc_tp->t_maxseg - bbr->rc_last_options; if (bbr->r_ctl.rc_pace_min_segs != bbr->rc_tp->t_maxseg) bbr->r_ctl.rc_pace_min_segs = bbr->rc_tp->t_maxseg; if (bbr->r_ctl.rc_pace_max_segs == 0) { bbr->r_ctl.rc_pace_max_segs = maxseg; } bbr_log_type_tsosize(bbr, cts, bbr->r_ctl.rc_pace_max_segs, tls_seg, old_tso, maxseg, 0); bbr_adjust_for_hw_pacing(bbr, cts); return; } /** * Now lets set the TSO goal based on our delivery rate in * bytes per second. Note we only do this if * we have acked at least the initial cwnd worth of data. */ bw = bbr_get_bw(bbr); if (IN_RECOVERY(bbr->rc_tp->t_flags) && (bbr->rc_use_google == 0)) { /* We clamp to one MSS in recovery */ new_tso = maxseg; } else if (bbr->rc_use_google) { int min_tso_segs; /* Google considers the gain too */ if (bbr->r_ctl.rc_bbr_hptsi_gain != BBR_UNIT) { bw *= bbr->r_ctl.rc_bbr_hptsi_gain; bw /= BBR_UNIT; } bytes = bw / 1024; if (bytes > (64 * 1024)) bytes = 64 * 1024; new_tso = bytes / maxseg; if (bw < ONE_POINT_TWO_MEG) min_tso_segs = 1; else min_tso_segs = 2; if (new_tso < min_tso_segs) new_tso = min_tso_segs; new_tso *= maxseg; } else if (bbr->rc_no_pacing) { new_tso = (PACE_MAX_IP_BYTES / maxseg) * maxseg; } else if (bw <= bbr->r_ctl.bbr_cross_over) { /* * Calculate the worse case b/w TSO if we are inserting no * more than a delay_target number of TSO's. */ uint32_t tso_len, min_tso; tso_len = bbr_get_pacing_length(bbr, BBR_UNIT, bbr->r_ctl.bbr_hptsi_segments_delay_tar, bw); if (tso_len > maxseg) { new_tso = tso_len / maxseg; if (new_tso > bbr->r_ctl.bbr_hptsi_segments_max) new_tso = bbr->r_ctl.bbr_hptsi_segments_max; new_tso *= maxseg; } else { /* * less than a full sized frame yikes.. long rtt or * low bw? */ min_tso = bbr_minseg(bbr); if ((tso_len > min_tso) && (bbr_all_get_min == 0)) new_tso = rounddown(tso_len, min_tso); else new_tso = min_tso; } } else if (bw > FIVETWELVE_MBPS) { /* * This guy is so fast b/w wise that we can TSO as large as * possible of segments that the NIC will allow. */ new_tso = rounddown(PACE_MAX_IP_BYTES, maxseg); } else { /* * This formula is based on attempting to send a segment or * more every bbr_hptsi_per_second. The default is 1000 * which means you are targeting what you can send every 1ms * based on the peers bw. * * If the number drops to say 500, then you are looking more * at 2ms and you will raise how much we send in a single * TSO thus saving CPU (less bbr_output_wtime() calls). The * trade off of course is you will send more at once and * thus tend to clump up the sends into larger "bursts" * building a queue. */ bw /= bbr->r_ctl.bbr_hptsi_per_second; new_tso = roundup(bw, (uint64_t)maxseg); /* * Gate the floor to match what our lower than 48Mbps * algorithm does. The ceiling (bbr_hptsi_segments_max) thus * becomes the floor for this calculation. */ if (new_tso < (bbr->r_ctl.bbr_hptsi_segments_max * maxseg)) new_tso = (bbr->r_ctl.bbr_hptsi_segments_max * maxseg); } if (bbr->r_ctl.bbr_hptsi_segments_floor && (new_tso < (maxseg * bbr->r_ctl.bbr_hptsi_segments_floor))) new_tso = maxseg * bbr->r_ctl.bbr_hptsi_segments_floor; if (new_tso > PACE_MAX_IP_BYTES) new_tso = rounddown(PACE_MAX_IP_BYTES, maxseg); /* Enforce an utter maximum. */ if (bbr->r_ctl.bbr_utter_max && (new_tso > (bbr->r_ctl.bbr_utter_max * maxseg))) { new_tso = bbr->r_ctl.bbr_utter_max * maxseg; } if (old_tso != new_tso) { /* Only log changes */ bbr_log_type_tsosize(bbr, cts, new_tso, tls_seg, old_tso, maxseg, 0); bbr->r_ctl.rc_pace_max_segs = new_tso; } /* We have hardware pacing! */ bbr_adjust_for_hw_pacing(bbr, cts); } static void bbr_log_output(struct tcp_bbr *bbr, struct tcpcb *tp, struct tcpopt *to, int32_t len, uint32_t seq_out, uint16_t th_flags, int32_t err, uint32_t cts, struct mbuf *mb, int32_t * abandon, struct bbr_sendmap *hintrsm, uint32_t delay_calc, struct sockbuf *sb) { struct bbr_sendmap *rsm, *nrsm; register uint32_t snd_max, snd_una; uint32_t pacing_time; /* * Add to the RACK log of packets in flight or retransmitted. If * there is a TS option we will use the TS echoed, if not we will * grab a TS. * * Retransmissions will increment the count and move the ts to its * proper place. Note that if options do not include TS's then we * won't be able to effectively use the ACK for an RTT on a retran. * * Notes about r_start and r_end. Lets consider a send starting at * sequence 1 for 10 bytes. In such an example the r_start would be * 1 (starting sequence) but the r_end would be r_start+len i.e. 11. * This means that r_end is actually the first sequence for the next * slot (11). * */ INP_WLOCK_ASSERT(tptoinpcb(tp)); if (err) { /* * We don't log errors -- we could but snd_max does not * advance in this case either. */ return; } if (th_flags & TH_RST) { /* * We don't log resets and we return immediately from * sending */ *abandon = 1; return; } snd_una = tp->snd_una; if (th_flags & (TH_SYN | TH_FIN) && (hintrsm == NULL)) { /* * The call to bbr_log_output is made before bumping * snd_max. This means we can record one extra byte on a SYN * or FIN if seq_out is adding more on and a FIN is present * (and we are not resending). */ if ((th_flags & TH_SYN) && (tp->iss == seq_out)) len++; if (th_flags & TH_FIN) len++; } if (SEQ_LEQ((seq_out + len), snd_una)) { /* Are sending an old segment to induce an ack (keep-alive)? */ return; } if (SEQ_LT(seq_out, snd_una)) { /* huh? should we panic? */ uint32_t end; end = seq_out + len; seq_out = snd_una; len = end - seq_out; } snd_max = tp->snd_max; if (len == 0) { /* We don't log zero window probes */ return; } pacing_time = bbr_get_pacing_delay(bbr, bbr->r_ctl.rc_bbr_hptsi_gain, len, cts, 1); /* First question is it a retransmission? */ if (seq_out == snd_max) { again: rsm = bbr_alloc(bbr); if (rsm == NULL) { return; } rsm->r_flags = 0; if (th_flags & TH_SYN) rsm->r_flags |= BBR_HAS_SYN; if (th_flags & TH_FIN) rsm->r_flags |= BBR_HAS_FIN; rsm->r_tim_lastsent[0] = cts; rsm->r_rtr_cnt = 1; rsm->r_rtr_bytes = 0; rsm->r_start = seq_out; rsm->r_end = rsm->r_start + len; rsm->r_dupack = 0; rsm->r_delivered = bbr->r_ctl.rc_delivered; rsm->r_pacing_delay = pacing_time; rsm->r_ts_valid = bbr->rc_ts_valid; if (bbr->rc_ts_valid) rsm->r_del_ack_ts = bbr->r_ctl.last_inbound_ts; rsm->r_del_time = bbr->r_ctl.rc_del_time; if (bbr->r_ctl.r_app_limited_until) rsm->r_app_limited = 1; else rsm->r_app_limited = 0; rsm->r_first_sent_time = bbr_get_earliest_send_outstanding(bbr, rsm, cts); rsm->r_flight_at_send = ctf_flight_size(bbr->rc_tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); /* * Here we must also add in this rsm since snd_max * is updated after we return from a new send. */ rsm->r_flight_at_send += len; TAILQ_INSERT_TAIL(&bbr->r_ctl.rc_map, rsm, r_next); TAILQ_INSERT_TAIL(&bbr->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 1; if (bbr->rc_bbr_state == BBR_STATE_PROBE_BW) rsm->r_bbr_state = bbr_state_val(bbr); else rsm->r_bbr_state = 8; if (bbr->r_ctl.rc_bbr_hptsi_gain > BBR_UNIT) { rsm->r_is_gain = 1; rsm->r_is_drain = 0; } else if (bbr->r_ctl.rc_bbr_hptsi_gain < BBR_UNIT) { rsm->r_is_drain = 1; rsm->r_is_gain = 0; } else { rsm->r_is_drain = 0; rsm->r_is_gain = 0; } return; } /* * If we reach here its a retransmission and we need to find it. */ more: if (hintrsm && (hintrsm->r_start == seq_out)) { rsm = hintrsm; hintrsm = NULL; } else if (bbr->r_ctl.rc_next) { /* We have a hint from a previous run */ rsm = bbr->r_ctl.rc_next; } else { /* No hints sorry */ rsm = NULL; } if ((rsm) && (rsm->r_start == seq_out)) { /* * We used rc_next or hintrsm to retransmit, hopefully the * likely case. */ seq_out = bbr_update_entry(tp, bbr, rsm, cts, &len, pacing_time); if (len == 0) { return; } else { goto more; } } /* Ok it was not the last pointer go through it the hard way. */ TAILQ_FOREACH(rsm, &bbr->r_ctl.rc_map, r_next) { if (rsm->r_start == seq_out) { seq_out = bbr_update_entry(tp, bbr, rsm, cts, &len, pacing_time); bbr->r_ctl.rc_next = TAILQ_NEXT(rsm, r_next); if (len == 0) { return; } else { continue; } } if (SEQ_GEQ(seq_out, rsm->r_start) && SEQ_LT(seq_out, rsm->r_end)) { /* Transmitted within this piece */ /* * Ok we must split off the front and then let the * update do the rest */ nrsm = bbr_alloc_full_limit(bbr); if (nrsm == NULL) { bbr_update_rsm(tp, bbr, rsm, cts, pacing_time); return; } /* * copy rsm to nrsm and then trim the front of rsm * to not include this part. */ bbr_clone_rsm(bbr, nrsm, rsm, seq_out); TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_map, rsm, nrsm, r_next); if (rsm->r_in_tmap) { TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_tmap, rsm, nrsm, r_tnext); nrsm->r_in_tmap = 1; } rsm->r_flags &= (~BBR_HAS_FIN); seq_out = bbr_update_entry(tp, bbr, nrsm, cts, &len, pacing_time); if (len == 0) { return; } } } /* * Hmm not found in map did they retransmit both old and on into the * new? */ if (seq_out == tp->snd_max) { goto again; } else if (SEQ_LT(seq_out, tp->snd_max)) { #ifdef BBR_INVARIANTS printf("seq_out:%u len:%d snd_una:%u snd_max:%u -- but rsm not found?\n", seq_out, len, tp->snd_una, tp->snd_max); printf("Starting Dump of all rack entries\n"); TAILQ_FOREACH(rsm, &bbr->r_ctl.rc_map, r_next) { printf("rsm:%p start:%u end:%u\n", rsm, rsm->r_start, rsm->r_end); } printf("Dump complete\n"); panic("seq_out not found rack:%p tp:%p", bbr, tp); #endif } else { #ifdef BBR_INVARIANTS /* * Hmm beyond sndmax? (only if we are using the new rtt-pack * flag) */ panic("seq_out:%u(%d) is beyond snd_max:%u tp:%p", seq_out, len, tp->snd_max, tp); #endif } } static void bbr_collapse_rtt(struct tcpcb *tp, struct tcp_bbr *bbr, int32_t rtt) { /* * Collapse timeout back the cum-ack moved. */ tp->t_rxtshift = 0; tp->t_softerror = 0; } static void tcp_bbr_xmit_timer(struct tcp_bbr *bbr, uint32_t rtt_usecs, uint32_t rsm_send_time, uint32_t r_start, uint32_t tsin) { bbr->rtt_valid = 1; bbr->r_ctl.cur_rtt = rtt_usecs; bbr->r_ctl.ts_in = tsin; if (rsm_send_time) bbr->r_ctl.cur_rtt_send_time = rsm_send_time; } static void bbr_make_timestamp_determination(struct tcp_bbr *bbr) { /** * We have in our bbr control: * 1) The timestamp we started observing cum-acks (bbr->r_ctl.bbr_ts_check_tstmp). * 2) Our timestamp indicating when we sent that packet (bbr->r_ctl.rsm->bbr_ts_check_our_cts). * 3) The current timestamp that just came in (bbr->r_ctl.last_inbound_ts) * 4) The time that the packet that generated that ack was sent (bbr->r_ctl.cur_rtt_send_time) * * Now we can calculate the time between the sends by doing: * * delta = bbr->r_ctl.cur_rtt_send_time - bbr->r_ctl.bbr_ts_check_our_cts * * And the peer's time between receiving them by doing: * * peer_delta = bbr->r_ctl.last_inbound_ts - bbr->r_ctl.bbr_ts_check_tstmp * * We want to figure out if the timestamp values are in msec, 10msec or usec. * We also may find that we can't use the timestamps if say we see * that the peer_delta indicates that though we may have taken 10ms to * pace out the data, it only saw 1ms between the two packets. This would * indicate that somewhere on the path is a batching entity that is giving * out time-slices of the actual b/w. This would mean we could not use * reliably the peers timestamps. * * We expect delta > peer_delta initially. Until we figure out the * timestamp difference which we will store in bbr->r_ctl.bbr_peer_tsratio. * If we place 1000 there then its a ms vs our usec. If we place 10000 there * then its 10ms vs our usec. If the peer is running a usec clock we would * put a 1 there. If the value is faster then ours, we will disable the * use of timestamps (though we could revist this later if we find it to be not * just an isolated one or two flows)). * * To detect the batching middle boxes we will come up with our compensation and * if with it in place, we find the peer is drastically off (by some margin) in * the smaller direction, then we will assume the worst case and disable use of timestamps. * */ uint64_t delta, peer_delta, delta_up; delta = bbr->r_ctl.cur_rtt_send_time - bbr->r_ctl.bbr_ts_check_our_cts; if (delta < bbr_min_usec_delta) { /* * Have not seen a min amount of time * between our send times so we can * make a determination of the timestamp * yet. */ return; } peer_delta = bbr->r_ctl.last_inbound_ts - bbr->r_ctl.bbr_ts_check_tstmp; if (peer_delta < bbr_min_peer_delta) { /* * We may have enough in the form of * our delta but the peers number * has not changed that much. It could * be its clock ratio is such that * we need more data (10ms tick) or * there may be other compression scenarios * going on. In any event we need the * spread to be larger. */ return; } /* Ok lets first see which way our delta is going */ if (peer_delta > delta) { /* Very unlikely, the peer without * compensation shows that it saw * the two sends arrive further apart * then we saw then in micro-seconds. */ if (peer_delta < (delta + ((delta * (uint64_t)1000)/ (uint64_t)bbr_delta_percent))) { /* well it looks like the peer is a micro-second clock. */ bbr->rc_ts_clock_set = 1; bbr->r_ctl.bbr_peer_tsratio = 1; } else { bbr->rc_ts_cant_be_used = 1; bbr->rc_ts_clock_set = 1; } return; } /* Ok we know that the peer_delta is smaller than our send distance */ bbr->rc_ts_clock_set = 1; /* First question is it within the percentage that they are using usec time? */ delta_up = (peer_delta * 1000) / (uint64_t)bbr_delta_percent; if ((peer_delta + delta_up) >= delta) { /* Its a usec clock */ bbr->r_ctl.bbr_peer_tsratio = 1; bbr_log_tstmp_validation(bbr, peer_delta, delta); return; } /* Ok if not usec, what about 10usec (though unlikely)? */ delta_up = (peer_delta * 1000 * 10) / (uint64_t)bbr_delta_percent; if (((peer_delta * 10) + delta_up) >= delta) { bbr->r_ctl.bbr_peer_tsratio = 10; bbr_log_tstmp_validation(bbr, peer_delta, delta); return; } /* And what about 100usec (though again unlikely)? */ delta_up = (peer_delta * 1000 * 100) / (uint64_t)bbr_delta_percent; if (((peer_delta * 100) + delta_up) >= delta) { bbr->r_ctl.bbr_peer_tsratio = 100; bbr_log_tstmp_validation(bbr, peer_delta, delta); return; } /* And how about 1 msec (the most likely one)? */ delta_up = (peer_delta * 1000 * 1000) / (uint64_t)bbr_delta_percent; if (((peer_delta * 1000) + delta_up) >= delta) { bbr->r_ctl.bbr_peer_tsratio = 1000; bbr_log_tstmp_validation(bbr, peer_delta, delta); return; } /* Ok if not msec could it be 10 msec? */ delta_up = (peer_delta * 1000 * 10000) / (uint64_t)bbr_delta_percent; if (((peer_delta * 10000) + delta_up) >= delta) { bbr->r_ctl.bbr_peer_tsratio = 10000; return; } /* If we fall down here the clock tick so slowly we can't use it */ bbr->rc_ts_cant_be_used = 1; bbr->r_ctl.bbr_peer_tsratio = 0; bbr_log_tstmp_validation(bbr, peer_delta, delta); } /* * Collect new round-trip time estimate * and update averages and current timeout. */ static void tcp_bbr_xmit_timer_commit(struct tcp_bbr *bbr, struct tcpcb *tp, uint32_t cts) { int32_t delta; uint32_t rtt, tsin; int32_t rtt_ticks; if (bbr->rtt_valid == 0) /* No valid sample */ return; rtt = bbr->r_ctl.cur_rtt; tsin = bbr->r_ctl.ts_in; if (bbr->rc_prtt_set_ts) { /* * We are to force feed the rttProp filter due * to an entry into PROBE_RTT. This assures * that the times are sync'd between when we * go into PROBE_RTT and the filter expiration. * * Google does not use a true filter, so they do * this implicitly since they only keep one value * and when they enter probe-rtt they update the * value to the newest rtt. */ uint32_t rtt_prop; bbr->rc_prtt_set_ts = 0; rtt_prop = get_filter_value_small(&bbr->r_ctl.rc_rttprop); if (rtt > rtt_prop) filter_increase_by_small(&bbr->r_ctl.rc_rttprop, (rtt - rtt_prop), cts); else apply_filter_min_small(&bbr->r_ctl.rc_rttprop, rtt, cts); } if (bbr->rc_ack_was_delayed) rtt += bbr->r_ctl.rc_ack_hdwr_delay; if (rtt < bbr->r_ctl.rc_lowest_rtt) bbr->r_ctl.rc_lowest_rtt = rtt; bbr_log_rtt_sample(bbr, rtt, tsin); if (bbr->r_init_rtt) { /* * The initial rtt is not-trusted, nuke it and lets get * our first valid measurement in. */ bbr->r_init_rtt = 0; tp->t_srtt = 0; } if ((bbr->rc_ts_clock_set == 0) && bbr->rc_ts_valid) { /* * So we have not yet figured out * what the peers TSTMP value is * in (most likely ms). We need a * series of cum-ack's to determine * this reliably. */ if (bbr->rc_ack_is_cumack) { if (bbr->rc_ts_data_set) { /* Lets attempt to determine the timestamp granularity. */ bbr_make_timestamp_determination(bbr); } else { bbr->rc_ts_data_set = 1; bbr->r_ctl.bbr_ts_check_tstmp = bbr->r_ctl.last_inbound_ts; bbr->r_ctl.bbr_ts_check_our_cts = bbr->r_ctl.cur_rtt_send_time; } } else { /* * We have to have consecutive acks * reset any "filled" state to none. */ bbr->rc_ts_data_set = 0; } } /* Round it up */ rtt_ticks = USEC_2_TICKS((rtt + (USECS_IN_MSEC - 1))); if (rtt_ticks == 0) rtt_ticks = 1; if (tp->t_srtt != 0) { /* * srtt is stored as fixed point with 5 bits after the * binary point (i.e., scaled by 8). The following magic is * equivalent to the smoothing algorithm in rfc793 with an * alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed point). * Adjust rtt to origin 0. */ delta = ((rtt_ticks - 1) << TCP_DELTA_SHIFT) - (tp->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT)); tp->t_srtt += delta; if (tp->t_srtt <= 0) tp->t_srtt = 1; /* * We accumulate a smoothed rtt variance (actually, a * smoothed mean difference), then set the retransmit timer * to smoothed rtt + 4 times the smoothed variance. rttvar * is stored as fixed point with 4 bits after the binary * point (scaled by 16). The following is equivalent to * rfc793 smoothing with an alpha of .75 (rttvar = * rttvar*3/4 + |delta| / 4). This replaces rfc793's * wired-in beta. */ if (delta < 0) delta = -delta; delta -= tp->t_rttvar >> (TCP_RTTVAR_SHIFT - TCP_DELTA_SHIFT); tp->t_rttvar += delta; if (tp->t_rttvar <= 0) tp->t_rttvar = 1; } else { /* * No rtt measurement yet - use the unsmoothed rtt. Set the * variance to half the rtt (so our first retransmit happens * at 3*rtt). */ tp->t_srtt = rtt_ticks << TCP_RTT_SHIFT; tp->t_rttvar = rtt_ticks << (TCP_RTTVAR_SHIFT - 1); } KMOD_TCPSTAT_INC(tcps_rttupdated); tp->t_rttupdated++; #ifdef STATS stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT, imax(0, rtt_ticks)); #endif /* * the retransmit should happen at rtt + 4 * rttvar. Because of the * way we do the smoothing, srtt and rttvar will each average +1/2 * tick of bias. When we compute the retransmit timer, we want 1/2 * tick of rounding and 1 extra tick because of +-1/2 tick * uncertainty in the firing of the timer. The bias will give us * exactly the 1.5 tick we need. But, because the bias is * statistical, we have to test that we don't drop below the minimum * feasible timer (which is 2 ticks). */ TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), max(MSEC_2_TICKS(bbr->r_ctl.rc_min_rto_ms), rtt_ticks + 2), MSEC_2_TICKS(((uint32_t)bbr->rc_max_rto_sec) * 1000)); /* * We received an ack for a packet that wasn't retransmitted; it is * probably safe to discard any error indications we've received * recently. This isn't quite right, but close enough for now (a * route might have failed after we sent a segment, and the return * path might not be symmetrical). */ tp->t_softerror = 0; rtt = (TICKS_2_USEC(bbr->rc_tp->t_srtt) >> TCP_RTT_SHIFT); if (bbr->r_ctl.bbr_smallest_srtt_this_state > rtt) bbr->r_ctl.bbr_smallest_srtt_this_state = rtt; } static void bbr_set_reduced_rtt(struct tcp_bbr *bbr, uint32_t cts, uint32_t line) { bbr->r_ctl.rc_rtt_shrinks = cts; if (bbr_can_force_probertt && (TSTMP_GT(cts, bbr->r_ctl.last_in_probertt)) && ((cts - bbr->r_ctl.last_in_probertt) > bbr->r_ctl.rc_probertt_int)) { /* * We should enter probe-rtt its been too long * since we have been there. */ bbr_enter_probe_rtt(bbr, cts, __LINE__); } else bbr_check_probe_rtt_limits(bbr, cts); } static void tcp_bbr_commit_bw(struct tcp_bbr *bbr, uint32_t cts) { uint64_t orig_bw; if (bbr->r_ctl.rc_bbr_cur_del_rate == 0) { /* We never apply a zero measurement */ bbr_log_type_bbrupd(bbr, 20, cts, 0, 0, 0, 0, 0, 0, 0, 0); return; } if (bbr->r_ctl.r_measurement_count < 0xffffffff) bbr->r_ctl.r_measurement_count++; orig_bw = get_filter_value(&bbr->r_ctl.rc_delrate); apply_filter_max(&bbr->r_ctl.rc_delrate, bbr->r_ctl.rc_bbr_cur_del_rate, bbr->r_ctl.rc_pkt_epoch); bbr_log_type_bbrupd(bbr, 21, cts, (uint32_t)orig_bw, (uint32_t)get_filter_value(&bbr->r_ctl.rc_delrate), 0, 0, 0, 0, 0, 0); if (orig_bw && (orig_bw != get_filter_value(&bbr->r_ctl.rc_delrate))) { if (bbr->bbr_hdrw_pacing) { /* * Apply a new rate to the hardware * possibly. */ bbr_update_hardware_pacing_rate(bbr, cts); } bbr_set_state_target(bbr, __LINE__); tcp_bbr_tso_size_check(bbr, cts); if (bbr->r_recovery_bw) { bbr_setup_red_bw(bbr, cts); bbr_log_type_bw_reduce(bbr, BBR_RED_BW_USELRBW); } } else if ((orig_bw == 0) && get_filter_value(&bbr->r_ctl.rc_delrate)) tcp_bbr_tso_size_check(bbr, cts); } static void bbr_nf_measurement(struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t rtt, uint32_t cts) { if (bbr->rc_in_persist == 0) { /* We log only when not in persist */ /* Translate to a Bytes Per Second */ uint64_t tim, bw, ts_diff, ts_bw; uint32_t delivered; if (TSTMP_GT(bbr->r_ctl.rc_del_time, rsm->r_del_time)) tim = (uint64_t)(bbr->r_ctl.rc_del_time - rsm->r_del_time); else tim = 1; /* * Now that we have processed the tim (skipping the sample * or possibly updating the time, go ahead and * calculate the cdr. */ delivered = (bbr->r_ctl.rc_delivered - rsm->r_delivered); bw = (uint64_t)delivered; bw *= (uint64_t)USECS_IN_SECOND; bw /= tim; if (bw == 0) { /* We must have a calculatable amount */ return; } /* * If we are using this b/w shove it in now so we * can see in the trace viewer if it gets over-ridden. */ if (rsm->r_ts_valid && bbr->rc_ts_valid && bbr->rc_ts_clock_set && (bbr->rc_ts_cant_be_used == 0) && bbr->rc_use_ts_limit) { ts_diff = max((bbr->r_ctl.last_inbound_ts - rsm->r_del_ack_ts), 1); ts_diff *= bbr->r_ctl.bbr_peer_tsratio; if ((delivered == 0) || (rtt < 1000)) { /* Can't use the ts */ bbr_log_type_bbrupd(bbr, 61, cts, ts_diff, bbr->r_ctl.last_inbound_ts, rsm->r_del_ack_ts, 0, 0, 0, 0, delivered); } else { ts_bw = (uint64_t)delivered; ts_bw *= (uint64_t)USECS_IN_SECOND; ts_bw /= ts_diff; bbr_log_type_bbrupd(bbr, 62, cts, (ts_bw >> 32), (ts_bw & 0xffffffff), 0, 0, 0, 0, ts_diff, delivered); if ((bbr->ts_can_raise) && (ts_bw > bw)) { bbr_log_type_bbrupd(bbr, 8, cts, delivered, ts_diff, (bw >> 32), (bw & 0x00000000ffffffff), 0, 0, 0, 0); bw = ts_bw; } else if (ts_bw && (ts_bw < bw)) { bbr_log_type_bbrupd(bbr, 7, cts, delivered, ts_diff, (bw >> 32), (bw & 0x00000000ffffffff), 0, 0, 0, 0); bw = ts_bw; } } } if (rsm->r_first_sent_time && TSTMP_GT(rsm->r_tim_lastsent[(rsm->r_rtr_cnt -1)],rsm->r_first_sent_time)) { uint64_t sbw, sti; /* * We use what was in flight at the time of our * send and the size of this send to figure * out what we have been sending at (amount). * For the time we take from the time of * the send of the first send outstanding * until this send plus this sends pacing * time. This gives us a good calculation * as to the rate we have been sending at. */ sbw = (uint64_t)(rsm->r_flight_at_send); sbw *= (uint64_t)USECS_IN_SECOND; sti = rsm->r_tim_lastsent[(rsm->r_rtr_cnt -1)] - rsm->r_first_sent_time; sti += rsm->r_pacing_delay; sbw /= sti; if (sbw < bw) { bbr_log_type_bbrupd(bbr, 6, cts, delivered, (uint32_t)sti, (bw >> 32), (uint32_t)bw, rsm->r_first_sent_time, 0, (sbw >> 32), (uint32_t)sbw); bw = sbw; } } /* Use the google algorithm for b/w measurements */ bbr->r_ctl.rc_bbr_cur_del_rate = bw; if ((rsm->r_app_limited == 0) || (bw > get_filter_value(&bbr->r_ctl.rc_delrate))) { tcp_bbr_commit_bw(bbr, cts); bbr_log_type_bbrupd(bbr, 10, cts, (uint32_t)tim, delivered, 0, 0, 0, 0, bbr->r_ctl.rc_del_time, rsm->r_del_time); } } } static void bbr_google_measurement(struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t rtt, uint32_t cts) { if (bbr->rc_in_persist == 0) { /* We log only when not in persist */ /* Translate to a Bytes Per Second */ uint64_t tim, bw; uint32_t delivered; int no_apply = 0; if (TSTMP_GT(bbr->r_ctl.rc_del_time, rsm->r_del_time)) tim = (uint64_t)(bbr->r_ctl.rc_del_time - rsm->r_del_time); else tim = 1; /* * Now that we have processed the tim (skipping the sample * or possibly updating the time, go ahead and * calculate the cdr. */ delivered = (bbr->r_ctl.rc_delivered - rsm->r_delivered); bw = (uint64_t)delivered; bw *= (uint64_t)USECS_IN_SECOND; bw /= tim; if (tim < bbr->r_ctl.rc_lowest_rtt) { bbr_log_type_bbrupd(bbr, 99, cts, (uint32_t)tim, delivered, tim, bbr->r_ctl.rc_lowest_rtt, 0, 0, 0, 0); no_apply = 1; } /* * If we are using this b/w shove it in now so we * can see in the trace viewer if it gets over-ridden. */ bbr->r_ctl.rc_bbr_cur_del_rate = bw; /* Gate by the sending rate */ if (rsm->r_first_sent_time && TSTMP_GT(rsm->r_tim_lastsent[(rsm->r_rtr_cnt -1)],rsm->r_first_sent_time)) { uint64_t sbw, sti; /* * We use what was in flight at the time of our * send and the size of this send to figure * out what we have been sending at (amount). * For the time we take from the time of * the send of the first send outstanding * until this send plus this sends pacing * time. This gives us a good calculation * as to the rate we have been sending at. */ sbw = (uint64_t)(rsm->r_flight_at_send); sbw *= (uint64_t)USECS_IN_SECOND; sti = rsm->r_tim_lastsent[(rsm->r_rtr_cnt -1)] - rsm->r_first_sent_time; sti += rsm->r_pacing_delay; sbw /= sti; if (sbw < bw) { bbr_log_type_bbrupd(bbr, 6, cts, delivered, (uint32_t)sti, (bw >> 32), (uint32_t)bw, rsm->r_first_sent_time, 0, (sbw >> 32), (uint32_t)sbw); bw = sbw; } if ((sti > tim) && (sti < bbr->r_ctl.rc_lowest_rtt)) { bbr_log_type_bbrupd(bbr, 99, cts, (uint32_t)tim, delivered, (uint32_t)sti, bbr->r_ctl.rc_lowest_rtt, 0, 0, 0, 0); no_apply = 1; } else no_apply = 0; } bbr->r_ctl.rc_bbr_cur_del_rate = bw; if ((no_apply == 0) && ((rsm->r_app_limited == 0) || (bw > get_filter_value(&bbr->r_ctl.rc_delrate)))) { tcp_bbr_commit_bw(bbr, cts); bbr_log_type_bbrupd(bbr, 10, cts, (uint32_t)tim, delivered, 0, 0, 0, 0, bbr->r_ctl.rc_del_time, rsm->r_del_time); } } } static void bbr_update_bbr_info(struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t rtt, uint32_t cts, uint32_t tsin, uint32_t uts, int32_t match, uint32_t rsm_send_time, int32_t ack_type, struct tcpopt *to) { uint64_t old_rttprop; /* Update our delivery time and amount */ bbr->r_ctl.rc_delivered += (rsm->r_end - rsm->r_start); bbr->r_ctl.rc_del_time = cts; if (rtt == 0) { /* * 0 means its a retransmit, for now we don't use these for * the rest of BBR. */ return; } if ((bbr->rc_use_google == 0) && (match != BBR_RTT_BY_EXACTMATCH) && (match != BBR_RTT_BY_TIMESTAMP)){ /* * We get a lot of rtt updates, lets not pay attention to * any that are not an exact match. That way we don't have * to worry about timestamps and the whole nonsense of * unsure if its a retransmission etc (if we ever had the * timestamp fixed to always have the last thing sent this * would not be a issue). */ return; } if ((bbr_no_retran && bbr->rc_use_google) && (match != BBR_RTT_BY_EXACTMATCH) && (match != BBR_RTT_BY_TIMESTAMP)){ /* * We only do measurements in google mode * with bbr_no_retran on for sure things. */ return; } /* Only update srtt if we know by exact match */ tcp_bbr_xmit_timer(bbr, rtt, rsm_send_time, rsm->r_start, tsin); if (ack_type == BBR_CUM_ACKED) bbr->rc_ack_is_cumack = 1; else bbr->rc_ack_is_cumack = 0; old_rttprop = bbr_get_rtt(bbr, BBR_RTT_PROP); /* * Note the following code differs to the original * BBR spec. It calls for <= not <. However after a * long discussion in email with Neal, he acknowledged * that it should be < than so that we will have flows * going into probe-rtt (we were seeing cases where that * did not happen and caused ugly things to occur). We * have added this agreed upon fix to our code base. */ if (rtt < old_rttprop) { /* Update when we last saw a rtt drop */ bbr_log_rtt_shrinks(bbr, cts, 0, rtt, __LINE__, BBR_RTTS_NEWRTT, 0); bbr_set_reduced_rtt(bbr, cts, __LINE__); } bbr_log_type_bbrrttprop(bbr, rtt, (rsm ? rsm->r_end : 0), uts, cts, match, rsm->r_start, rsm->r_flags); apply_filter_min_small(&bbr->r_ctl.rc_rttprop, rtt, cts); if (old_rttprop != bbr_get_rtt(bbr, BBR_RTT_PROP)) { /* * The RTT-prop moved, reset the target (may be a * nop for some states). */ bbr_set_state_target(bbr, __LINE__); if (bbr->rc_bbr_state == BBR_STATE_PROBE_RTT) bbr_log_rtt_shrinks(bbr, cts, 0, 0, __LINE__, BBR_RTTS_NEW_TARGET, 0); else if (old_rttprop < bbr_get_rtt(bbr, BBR_RTT_PROP)) /* It went up */ bbr_check_probe_rtt_limits(bbr, cts); } if ((bbr->rc_use_google == 0) && (match == BBR_RTT_BY_TIMESTAMP)) { /* * We don't do b/w update with * these since they are not really * reliable. */ return; } if (bbr->r_ctl.r_app_limited_until && (bbr->r_ctl.rc_delivered >= bbr->r_ctl.r_app_limited_until)) { /* We are no longer app-limited */ bbr->r_ctl.r_app_limited_until = 0; } if (bbr->rc_use_google) { bbr_google_measurement(bbr, rsm, rtt, cts); } else { bbr_nf_measurement(bbr, rsm, rtt, cts); } } /* * Convert a timestamp that the main stack * uses (milliseconds) into one that bbr uses * (microseconds). Return that converted timestamp. */ static uint32_t bbr_ts_convert(uint32_t cts) { uint32_t sec, msec; sec = cts / MS_IN_USEC; msec = cts - (MS_IN_USEC * sec); return ((sec * USECS_IN_SECOND) + (msec * MS_IN_USEC)); } /* * Return 0 if we did not update the RTT time, return * 1 if we did. */ static int bbr_update_rtt(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, struct tcpopt *to, uint32_t cts, int32_t ack_type, uint32_t th_ack) { int32_t i; uint32_t t, uts = 0; if ((rsm->r_flags & BBR_ACKED) || (rsm->r_flags & BBR_WAS_RENEGED) || (rsm->r_flags & BBR_RXT_CLEARED)) { /* Already done */ return (0); } if (rsm->r_rtt_not_allowed) { /* Not allowed */ return (0); } if (rsm->r_rtr_cnt == 1) { /* * Only one transmit. Hopefully the normal case. */ if (TSTMP_GT(cts, rsm->r_tim_lastsent[0])) t = cts - rsm->r_tim_lastsent[0]; else t = 1; if ((int)t <= 0) t = 1; bbr->r_ctl.rc_last_rtt = t; bbr_update_bbr_info(bbr, rsm, t, cts, to->to_tsecr, 0, BBR_RTT_BY_EXACTMATCH, rsm->r_tim_lastsent[0], ack_type, to); return (1); } /* Convert to usecs */ if ((bbr_can_use_ts_for_rtt == 1) && (bbr->rc_use_google == 1) && (ack_type == BBR_CUM_ACKED) && (to->to_flags & TOF_TS) && (to->to_tsecr != 0)) { t = tcp_tv_to_mssectick(&bbr->rc_tv) - to->to_tsecr; if (t < 1) t = 1; t *= MS_IN_USEC; bbr_update_bbr_info(bbr, rsm, t, cts, to->to_tsecr, 0, BBR_RTT_BY_TIMESTAMP, rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)], ack_type, to); return (1); } uts = bbr_ts_convert(to->to_tsecr); if ((to->to_flags & TOF_TS) && (to->to_tsecr != 0) && (ack_type == BBR_CUM_ACKED) && ((rsm->r_flags & BBR_OVERMAX) == 0)) { /* * Now which timestamp does it match? In this block the ACK * may be coming from a previous transmission. */ uint32_t fudge; fudge = BBR_TIMER_FUDGE; for (i = 0; i < rsm->r_rtr_cnt; i++) { if ((SEQ_GEQ(uts, (rsm->r_tim_lastsent[i] - fudge))) && (SEQ_LEQ(uts, (rsm->r_tim_lastsent[i] + fudge)))) { if (TSTMP_GT(cts, rsm->r_tim_lastsent[i])) t = cts - rsm->r_tim_lastsent[i]; else t = 1; if ((int)t <= 0) t = 1; bbr->r_ctl.rc_last_rtt = t; bbr_update_bbr_info(bbr, rsm, t, cts, to->to_tsecr, uts, BBR_RTT_BY_TSMATCHING, rsm->r_tim_lastsent[i], ack_type, to); if ((i + 1) < rsm->r_rtr_cnt) { /* Likely */ return (0); } else if (rsm->r_flags & BBR_TLP) { bbr->rc_tlp_rtx_out = 0; } return (1); } } /* Fall through if we can't find a matching timestamp */ } /* * Ok its a SACK block that we retransmitted. or a windows * machine without timestamps. We can tell nothing from the * time-stamp since its not there or the time the peer last * recieved a segment that moved forward its cum-ack point. * * Lets look at the last retransmit and see what we can tell * (with BBR for space we only keep 2 note we have to keep * at least 2 so the map can not be condensed more). */ i = rsm->r_rtr_cnt - 1; if (TSTMP_GT(cts, rsm->r_tim_lastsent[i])) t = cts - rsm->r_tim_lastsent[i]; else goto not_sure; if (t < bbr->r_ctl.rc_lowest_rtt) { /* * We retransmitted and the ack came back in less * than the smallest rtt we have observed in the * windowed rtt. We most likey did an improper * retransmit as outlined in 4.2 Step 3 point 2 in * the rack-draft. * * Use the prior transmission to update all the * information as long as there is only one prior * transmission. */ if ((rsm->r_flags & BBR_OVERMAX) == 0) { #ifdef BBR_INVARIANTS if (rsm->r_rtr_cnt == 1) panic("rsm:%p bbr:%p rsm has overmax and only 1 retranmit flags:%x?", rsm, bbr, rsm->r_flags); #endif i = rsm->r_rtr_cnt - 2; if (TSTMP_GT(cts, rsm->r_tim_lastsent[i])) t = cts - rsm->r_tim_lastsent[i]; else t = 1; bbr_update_bbr_info(bbr, rsm, t, cts, to->to_tsecr, uts, BBR_RTT_BY_EARLIER_RET, rsm->r_tim_lastsent[i], ack_type, to); return (0); } else { /* * Too many prior transmissions, just * updated BBR delivered */ not_sure: bbr_update_bbr_info(bbr, rsm, 0, cts, to->to_tsecr, uts, BBR_RTT_BY_SOME_RETRAN, 0, ack_type, to); } } else { /* * We retransmitted it and the retransmit did the * job. */ if (rsm->r_flags & BBR_TLP) bbr->rc_tlp_rtx_out = 0; if ((rsm->r_flags & BBR_OVERMAX) == 0) bbr_update_bbr_info(bbr, rsm, t, cts, to->to_tsecr, uts, BBR_RTT_BY_THIS_RETRAN, 0, ack_type, to); else bbr_update_bbr_info(bbr, rsm, 0, cts, to->to_tsecr, uts, BBR_RTT_BY_SOME_RETRAN, 0, ack_type, to); return (1); } return (0); } /* * Mark the SACK_PASSED flag on all entries prior to rsm send wise. */ static void bbr_log_sack_passed(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm) { struct bbr_sendmap *nrsm; nrsm = rsm; TAILQ_FOREACH_REVERSE_FROM(nrsm, &bbr->r_ctl.rc_tmap, bbr_head, r_tnext) { if (nrsm == rsm) { /* Skip orginal segment he is acked */ continue; } if (nrsm->r_flags & BBR_ACKED) { /* Skip ack'd segments */ continue; } if (nrsm->r_flags & BBR_SACK_PASSED) { /* * We found one that is already marked * passed, we have been here before and * so all others below this are marked. */ break; } BBR_STAT_INC(bbr_sack_passed); nrsm->r_flags |= BBR_SACK_PASSED; if (((nrsm->r_flags & BBR_MARKED_LOST) == 0) && bbr_is_lost(bbr, nrsm, bbr->r_ctl.rc_rcvtime)) { bbr->r_ctl.rc_lost += nrsm->r_end - nrsm->r_start; bbr->r_ctl.rc_lost_bytes += nrsm->r_end - nrsm->r_start; nrsm->r_flags |= BBR_MARKED_LOST; } nrsm->r_flags &= ~BBR_WAS_SACKPASS; } } /* * Returns the number of bytes that were * newly ack'd by sack blocks. */ static uint32_t bbr_proc_sack_blk(struct tcpcb *tp, struct tcp_bbr *bbr, struct sackblk *sack, struct tcpopt *to, struct bbr_sendmap **prsm, uint32_t cts) { int32_t times = 0; uint32_t start, end, changed = 0; struct bbr_sendmap *rsm, *nrsm; int32_t used_ref = 1; uint8_t went_back = 0, went_fwd = 0; start = sack->start; end = sack->end; rsm = *prsm; if (rsm == NULL) used_ref = 0; /* Do we locate the block behind where we last were? */ if (rsm && SEQ_LT(start, rsm->r_start)) { went_back = 1; TAILQ_FOREACH_REVERSE_FROM(rsm, &bbr->r_ctl.rc_map, bbr_head, r_next) { if (SEQ_GEQ(start, rsm->r_start) && SEQ_LT(start, rsm->r_end)) { goto do_rest_ofb; } } } start_at_beginning: went_fwd = 1; /* * Ok lets locate the block where this guy is fwd from rsm (if its * set) */ TAILQ_FOREACH_FROM(rsm, &bbr->r_ctl.rc_map, r_next) { if (SEQ_GEQ(start, rsm->r_start) && SEQ_LT(start, rsm->r_end)) { break; } } do_rest_ofb: if (rsm == NULL) { /* * This happens when we get duplicate sack blocks with the * same end. For example SACK 4: 100 SACK 3: 100 The sort * will not change there location so we would just start at * the end of the first one and get lost. */ if (tp->t_flags & TF_SENTFIN) { /* * Check to see if we have not logged the FIN that * went out. */ nrsm = TAILQ_LAST_FAST(&bbr->r_ctl.rc_map, bbr_sendmap, r_next); if (nrsm && (nrsm->r_end + 1) == tp->snd_max) { /* * Ok we did not get the FIN logged. */ nrsm->r_end++; rsm = nrsm; goto do_rest_ofb; } } if (times == 1) { #ifdef BBR_INVARIANTS panic("tp:%p bbr:%p sack:%p to:%p prsm:%p", tp, bbr, sack, to, prsm); #else goto out; #endif } times++; BBR_STAT_INC(bbr_sack_proc_restart); rsm = NULL; goto start_at_beginning; } /* Ok we have an ACK for some piece of rsm */ if (rsm->r_start != start) { /* * Need to split this in two pieces the before and after. */ if (bbr_sack_mergable(rsm, start, end)) nrsm = bbr_alloc_full_limit(bbr); else nrsm = bbr_alloc_limit(bbr, BBR_LIMIT_TYPE_SPLIT); if (nrsm == NULL) { /* We could not allocate ignore the sack */ struct sackblk blk; blk.start = start; blk.end = end; sack_filter_reject(&bbr->r_ctl.bbr_sf, &blk); goto out; } bbr_clone_rsm(bbr, nrsm, rsm, start); TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_map, rsm, nrsm, r_next); if (rsm->r_in_tmap) { TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_tmap, rsm, nrsm, r_tnext); nrsm->r_in_tmap = 1; } rsm->r_flags &= (~BBR_HAS_FIN); rsm = nrsm; } if (SEQ_GEQ(end, rsm->r_end)) { /* * The end of this block is either beyond this guy or right * at this guy. */ if ((rsm->r_flags & BBR_ACKED) == 0) { bbr_update_rtt(tp, bbr, rsm, to, cts, BBR_SACKED, 0); changed += (rsm->r_end - rsm->r_start); bbr->r_ctl.rc_sacked += (rsm->r_end - rsm->r_start); bbr_log_sack_passed(tp, bbr, rsm); if (rsm->r_flags & BBR_MARKED_LOST) { bbr->r_ctl.rc_lost_bytes -= rsm->r_end - rsm->r_start; } /* Is Reordering occuring? */ if (rsm->r_flags & BBR_SACK_PASSED) { BBR_STAT_INC(bbr_reorder_seen); bbr->r_ctl.rc_reorder_ts = cts; if (rsm->r_flags & BBR_MARKED_LOST) { bbr->r_ctl.rc_lost -= rsm->r_end - rsm->r_start; if (SEQ_GT(bbr->r_ctl.rc_lt_lost, bbr->r_ctl.rc_lost)) /* LT sampling also needs adjustment */ bbr->r_ctl.rc_lt_lost = bbr->r_ctl.rc_lost; } } rsm->r_flags |= BBR_ACKED; rsm->r_flags &= ~(BBR_TLP|BBR_WAS_RENEGED|BBR_RXT_CLEARED|BBR_MARKED_LOST); if (rsm->r_in_tmap) { TAILQ_REMOVE(&bbr->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 0; } } bbr_isit_a_pkt_epoch(bbr, cts, rsm, __LINE__, BBR_SACKED); if (end == rsm->r_end) { /* This block only - done */ goto out; } /* There is more not coverend by this rsm move on */ start = rsm->r_end; nrsm = TAILQ_NEXT(rsm, r_next); rsm = nrsm; times = 0; goto do_rest_ofb; } if (rsm->r_flags & BBR_ACKED) { /* Been here done that */ goto out; } /* Ok we need to split off this one at the tail */ if (bbr_sack_mergable(rsm, start, end)) nrsm = bbr_alloc_full_limit(bbr); else nrsm = bbr_alloc_limit(bbr, BBR_LIMIT_TYPE_SPLIT); if (nrsm == NULL) { /* failed XXXrrs what can we do but loose the sack info? */ struct sackblk blk; blk.start = start; blk.end = end; sack_filter_reject(&bbr->r_ctl.bbr_sf, &blk); goto out; } /* Clone it */ bbr_clone_rsm(bbr, nrsm, rsm, end); /* The sack block does not cover this guy fully */ rsm->r_flags &= (~BBR_HAS_FIN); TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_map, rsm, nrsm, r_next); if (rsm->r_in_tmap) { TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_tmap, rsm, nrsm, r_tnext); nrsm->r_in_tmap = 1; } nrsm->r_dupack = 0; bbr_update_rtt(tp, bbr, rsm, to, cts, BBR_SACKED, 0); bbr_isit_a_pkt_epoch(bbr, cts, rsm, __LINE__, BBR_SACKED); changed += (rsm->r_end - rsm->r_start); bbr->r_ctl.rc_sacked += (rsm->r_end - rsm->r_start); bbr_log_sack_passed(tp, bbr, rsm); /* Is Reordering occuring? */ if (rsm->r_flags & BBR_MARKED_LOST) { bbr->r_ctl.rc_lost_bytes -= rsm->r_end - rsm->r_start; } if (rsm->r_flags & BBR_SACK_PASSED) { BBR_STAT_INC(bbr_reorder_seen); bbr->r_ctl.rc_reorder_ts = cts; if (rsm->r_flags & BBR_MARKED_LOST) { bbr->r_ctl.rc_lost -= rsm->r_end - rsm->r_start; if (SEQ_GT(bbr->r_ctl.rc_lt_lost, bbr->r_ctl.rc_lost)) /* LT sampling also needs adjustment */ bbr->r_ctl.rc_lt_lost = bbr->r_ctl.rc_lost; } } rsm->r_flags &= ~(BBR_TLP|BBR_WAS_RENEGED|BBR_RXT_CLEARED|BBR_MARKED_LOST); rsm->r_flags |= BBR_ACKED; if (rsm->r_in_tmap) { TAILQ_REMOVE(&bbr->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 0; } out: if (rsm && (rsm->r_flags & BBR_ACKED)) { /* * Now can we merge this newly acked * block with either the previous or * next block? */ nrsm = TAILQ_NEXT(rsm, r_next); if (nrsm && (nrsm->r_flags & BBR_ACKED)) { /* yep this and next can be merged */ rsm = bbr_merge_rsm(bbr, rsm, nrsm); } /* Now what about the previous? */ nrsm = TAILQ_PREV(rsm, bbr_head, r_next); if (nrsm && (nrsm->r_flags & BBR_ACKED)) { /* yep the previous and this can be merged */ rsm = bbr_merge_rsm(bbr, nrsm, rsm); } } if (used_ref == 0) { BBR_STAT_INC(bbr_sack_proc_all); } else { BBR_STAT_INC(bbr_sack_proc_short); } if (went_fwd && went_back) { BBR_STAT_INC(bbr_sack_search_both); } else if (went_fwd) { BBR_STAT_INC(bbr_sack_search_fwd); } else if (went_back) { BBR_STAT_INC(bbr_sack_search_back); } /* Save off where the next seq is */ if (rsm) bbr->r_ctl.rc_sacklast = TAILQ_NEXT(rsm, r_next); else bbr->r_ctl.rc_sacklast = NULL; *prsm = rsm; return (changed); } static void inline bbr_peer_reneges(struct tcp_bbr *bbr, struct bbr_sendmap *rsm, tcp_seq th_ack) { struct bbr_sendmap *tmap; BBR_STAT_INC(bbr_reneges_seen); tmap = NULL; while (rsm && (rsm->r_flags & BBR_ACKED)) { /* Its no longer sacked, mark it so */ uint32_t oflags; bbr->r_ctl.rc_sacked -= (rsm->r_end - rsm->r_start); #ifdef BBR_INVARIANTS if (rsm->r_in_tmap) { panic("bbr:%p rsm:%p flags:0x%x in tmap?", bbr, rsm, rsm->r_flags); } #endif oflags = rsm->r_flags; if (rsm->r_flags & BBR_MARKED_LOST) { bbr->r_ctl.rc_lost -= rsm->r_end - rsm->r_start; bbr->r_ctl.rc_lost_bytes -= rsm->r_end - rsm->r_start; if (SEQ_GT(bbr->r_ctl.rc_lt_lost, bbr->r_ctl.rc_lost)) /* LT sampling also needs adjustment */ bbr->r_ctl.rc_lt_lost = bbr->r_ctl.rc_lost; } rsm->r_flags &= ~(BBR_ACKED | BBR_SACK_PASSED | BBR_WAS_SACKPASS | BBR_MARKED_LOST); rsm->r_flags |= BBR_WAS_RENEGED; rsm->r_flags |= BBR_RXT_CLEARED; bbr_log_type_rsmclear(bbr, bbr->r_ctl.rc_rcvtime, rsm, oflags, __LINE__); /* Rebuild it into our tmap */ if (tmap == NULL) { TAILQ_INSERT_HEAD(&bbr->r_ctl.rc_tmap, rsm, r_tnext); tmap = rsm; } else { TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_tmap, tmap, rsm, r_tnext); tmap = rsm; } tmap->r_in_tmap = 1; /* * XXXrrs Delivered? Should we do anything here? * * Of course we don't on a rxt timeout so maybe its ok that * we don't? * * For now lets not. */ rsm = TAILQ_NEXT(rsm, r_next); } /* * Now lets possibly clear the sack filter so we start recognizing * sacks that cover this area. */ sack_filter_clear(&bbr->r_ctl.bbr_sf, th_ack); } static void bbr_log_syn(struct tcpcb *tp, struct tcpopt *to) { struct tcp_bbr *bbr; struct bbr_sendmap *rsm; uint32_t cts; bbr = (struct tcp_bbr *)tp->t_fb_ptr; cts = bbr->r_ctl.rc_rcvtime; rsm = TAILQ_FIRST(&bbr->r_ctl.rc_map); if (rsm && (rsm->r_flags & BBR_HAS_SYN)) { if ((rsm->r_end - rsm->r_start) <= 1) { /* Log out the SYN completely */ bbr->r_ctl.rc_holes_rxt -= rsm->r_rtr_bytes; rsm->r_rtr_bytes = 0; TAILQ_REMOVE(&bbr->r_ctl.rc_map, rsm, r_next); if (rsm->r_in_tmap) { TAILQ_REMOVE(&bbr->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 0; } if (bbr->r_ctl.rc_next == rsm) { /* scoot along the marker */ bbr->r_ctl.rc_next = TAILQ_FIRST(&bbr->r_ctl.rc_map); } if (to != NULL) bbr_update_rtt(tp, bbr, rsm, to, cts, BBR_CUM_ACKED, 0); bbr_free(bbr, rsm); } else { /* There is more (Fast open)? strip out SYN. */ rsm->r_flags &= ~BBR_HAS_SYN; rsm->r_start++; } } } /* * Returns the number of bytes that were * acknowledged by SACK blocks. */ static uint32_t bbr_log_ack(struct tcpcb *tp, struct tcpopt *to, struct tcphdr *th, uint32_t *prev_acked) { uint32_t changed, last_seq, entered_recovery = 0; struct tcp_bbr *bbr; struct bbr_sendmap *rsm; struct sackblk sack, sack_blocks[TCP_MAX_SACK + 1]; register uint32_t th_ack; int32_t i, j, k, new_sb, num_sack_blks = 0; uint32_t cts, acked, ack_point, sack_changed = 0; uint32_t p_maxseg, maxseg, p_acked = 0; INP_WLOCK_ASSERT(tptoinpcb(tp)); if (tcp_get_flags(th) & TH_RST) { /* We don't log resets */ return (0); } bbr = (struct tcp_bbr *)tp->t_fb_ptr; cts = bbr->r_ctl.rc_rcvtime; rsm = TAILQ_FIRST(&bbr->r_ctl.rc_map); changed = 0; maxseg = tp->t_maxseg - bbr->rc_last_options; p_maxseg = min(bbr->r_ctl.rc_pace_max_segs, maxseg); th_ack = th->th_ack; if (SEQ_GT(th_ack, tp->snd_una)) { acked = th_ack - tp->snd_una; bbr_log_progress_event(bbr, tp, ticks, PROGRESS_UPDATE, __LINE__); bbr->rc_tp->t_acktime = ticks; } else acked = 0; if (SEQ_LEQ(th_ack, tp->snd_una)) { /* Only sent here for sack processing */ goto proc_sack; } if (rsm && SEQ_GT(th_ack, rsm->r_start)) { changed = th_ack - rsm->r_start; } else if ((rsm == NULL) && ((th_ack - 1) == tp->iss)) { /* * For the SYN incoming case we will not have called * tcp_output for the sending of the SYN, so there will be * no map. All other cases should probably be a panic. */ if ((to->to_flags & TOF_TS) && (to->to_tsecr != 0)) { /* * We have a timestamp that can be used to generate * an initial RTT. */ uint32_t ts, now, rtt; ts = bbr_ts_convert(to->to_tsecr); now = bbr_ts_convert(tcp_tv_to_mssectick(&bbr->rc_tv)); rtt = now - ts; if (rtt < 1) rtt = 1; bbr_log_type_bbrrttprop(bbr, rtt, tp->iss, 0, cts, BBR_RTT_BY_TIMESTAMP, tp->iss, 0); apply_filter_min_small(&bbr->r_ctl.rc_rttprop, rtt, cts); changed = 1; bbr->r_wanted_output = 1; goto out; } goto proc_sack; } else if (rsm == NULL) { goto out; } if (changed) { /* * The ACK point is advancing to th_ack, we must drop off * the packets in the rack log and calculate any eligble * RTT's. */ bbr->r_wanted_output = 1; more: if (rsm == NULL) { if (tp->t_flags & TF_SENTFIN) { /* if we send a FIN we will not hav a map */ goto proc_sack; } #ifdef BBR_INVARIANTS panic("No rack map tp:%p for th:%p state:%d bbr:%p snd_una:%u snd_max:%u chg:%d\n", tp, th, tp->t_state, bbr, tp->snd_una, tp->snd_max, changed); #endif goto proc_sack; } } if (SEQ_LT(th_ack, rsm->r_start)) { /* Huh map is missing this */ #ifdef BBR_INVARIANTS printf("Rack map starts at r_start:%u for th_ack:%u huh? ts:%d rs:%d bbr:%p\n", rsm->r_start, th_ack, tp->t_state, bbr->r_state, bbr); panic("th-ack is bad bbr:%p tp:%p", bbr, tp); #endif goto proc_sack; } else if (th_ack == rsm->r_start) { /* None here to ack */ goto proc_sack; } /* * Clear the dup ack counter, it will * either be freed or if there is some * remaining we need to start it at zero. */ rsm->r_dupack = 0; /* Now do we consume the whole thing? */ if (SEQ_GEQ(th_ack, rsm->r_end)) { /* Its all consumed. */ uint32_t left; if (rsm->r_flags & BBR_ACKED) { /* * It was acked on the scoreboard -- remove it from * total */ p_acked += (rsm->r_end - rsm->r_start); bbr->r_ctl.rc_sacked -= (rsm->r_end - rsm->r_start); if (bbr->r_ctl.rc_sacked == 0) bbr->r_ctl.rc_sacklast = NULL; } else { bbr_update_rtt(tp, bbr, rsm, to, cts, BBR_CUM_ACKED, th_ack); if (rsm->r_flags & BBR_MARKED_LOST) { bbr->r_ctl.rc_lost_bytes -= rsm->r_end - rsm->r_start; } if (rsm->r_flags & BBR_SACK_PASSED) { /* * There are acked segments ACKED on the * scoreboard further up. We are seeing * reordering. */ BBR_STAT_INC(bbr_reorder_seen); bbr->r_ctl.rc_reorder_ts = cts; if (rsm->r_flags & BBR_MARKED_LOST) { bbr->r_ctl.rc_lost -= rsm->r_end - rsm->r_start; if (SEQ_GT(bbr->r_ctl.rc_lt_lost, bbr->r_ctl.rc_lost)) /* LT sampling also needs adjustment */ bbr->r_ctl.rc_lt_lost = bbr->r_ctl.rc_lost; } } rsm->r_flags &= ~BBR_MARKED_LOST; } bbr->r_ctl.rc_holes_rxt -= rsm->r_rtr_bytes; rsm->r_rtr_bytes = 0; TAILQ_REMOVE(&bbr->r_ctl.rc_map, rsm, r_next); if (rsm->r_in_tmap) { TAILQ_REMOVE(&bbr->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 0; } if (bbr->r_ctl.rc_next == rsm) { /* scoot along the marker */ bbr->r_ctl.rc_next = TAILQ_FIRST(&bbr->r_ctl.rc_map); } bbr_isit_a_pkt_epoch(bbr, cts, rsm, __LINE__, BBR_CUM_ACKED); /* Adjust the packet counts */ left = th_ack - rsm->r_end; /* Free back to zone */ bbr_free(bbr, rsm); if (left) { rsm = TAILQ_FIRST(&bbr->r_ctl.rc_map); goto more; } goto proc_sack; } if (rsm->r_flags & BBR_ACKED) { /* * It was acked on the scoreboard -- remove it from total * for the part being cum-acked. */ p_acked += (rsm->r_end - rsm->r_start); bbr->r_ctl.rc_sacked -= (th_ack - rsm->r_start); if (bbr->r_ctl.rc_sacked == 0) bbr->r_ctl.rc_sacklast = NULL; } else { /* * It was acked up to th_ack point for the first time */ struct bbr_sendmap lrsm; memcpy(&lrsm, rsm, sizeof(struct bbr_sendmap)); lrsm.r_end = th_ack; bbr_update_rtt(tp, bbr, &lrsm, to, cts, BBR_CUM_ACKED, th_ack); } if ((rsm->r_flags & BBR_MARKED_LOST) && ((rsm->r_flags & BBR_ACKED) == 0)) { /* * It was marked lost and partly ack'd now * for the first time. We lower the rc_lost_bytes * and still leave it MARKED. */ bbr->r_ctl.rc_lost_bytes -= th_ack - rsm->r_start; } bbr_isit_a_pkt_epoch(bbr, cts, rsm, __LINE__, BBR_CUM_ACKED); bbr->r_ctl.rc_holes_rxt -= rsm->r_rtr_bytes; rsm->r_rtr_bytes = 0; /* adjust packet count */ rsm->r_start = th_ack; proc_sack: /* Check for reneging */ rsm = TAILQ_FIRST(&bbr->r_ctl.rc_map); if (rsm && (rsm->r_flags & BBR_ACKED) && (th_ack == rsm->r_start)) { /* * The peer has moved snd_una up to the edge of this send, * i.e. one that it had previously acked. The only way that * can be true if the peer threw away data (space issues) * that it had previously sacked (else it would have given * us snd_una up to (rsm->r_end). We need to undo the acked * markings here. * * Note we have to look to make sure th_ack is our * rsm->r_start in case we get an old ack where th_ack is * behind snd_una. */ bbr_peer_reneges(bbr, rsm, th->th_ack); } if ((to->to_flags & TOF_SACK) == 0) { /* We are done nothing left to log */ goto out; } rsm = TAILQ_LAST_FAST(&bbr->r_ctl.rc_map, bbr_sendmap, r_next); if (rsm) { last_seq = rsm->r_end; } else { last_seq = tp->snd_max; } /* Sack block processing */ if (SEQ_GT(th_ack, tp->snd_una)) ack_point = th_ack; else ack_point = tp->snd_una; for (i = 0; i < to->to_nsacks; i++) { bcopy((to->to_sacks + i * TCPOLEN_SACK), &sack, sizeof(sack)); sack.start = ntohl(sack.start); sack.end = ntohl(sack.end); if (SEQ_GT(sack.end, sack.start) && SEQ_GT(sack.start, ack_point) && SEQ_LT(sack.start, tp->snd_max) && SEQ_GT(sack.end, ack_point) && SEQ_LEQ(sack.end, tp->snd_max)) { if ((bbr->r_ctl.rc_num_small_maps_alloced > bbr_sack_block_limit) && (SEQ_LT(sack.end, last_seq)) && ((sack.end - sack.start) < (p_maxseg / 8))) { /* * Not the last piece and its smaller than * 1/8th of a p_maxseg. We ignore this. */ BBR_STAT_INC(bbr_runt_sacks); continue; } sack_blocks[num_sack_blks] = sack; num_sack_blks++; } else if (SEQ_LEQ(sack.start, th_ack) && SEQ_LEQ(sack.end, th_ack)) { /* * Its a D-SACK block. */ tcp_record_dsack(tp, sack.start, sack.end, 0); } } if (num_sack_blks == 0) goto out; /* * Sort the SACK blocks so we can update the rack scoreboard with * just one pass. */ new_sb = sack_filter_blks(&bbr->r_ctl.bbr_sf, sack_blocks, num_sack_blks, th->th_ack); ctf_log_sack_filter(bbr->rc_tp, new_sb, sack_blocks); BBR_STAT_ADD(bbr_sack_blocks, num_sack_blks); BBR_STAT_ADD(bbr_sack_blocks_skip, (num_sack_blks - new_sb)); num_sack_blks = new_sb; if (num_sack_blks < 2) { goto do_sack_work; } /* Sort the sacks */ for (i = 0; i < num_sack_blks; i++) { for (j = i + 1; j < num_sack_blks; j++) { if (SEQ_GT(sack_blocks[i].end, sack_blocks[j].end)) { sack = sack_blocks[i]; sack_blocks[i] = sack_blocks[j]; sack_blocks[j] = sack; } } } /* * Now are any of the sack block ends the same (yes some * implememtations send these)? */ again: if (num_sack_blks > 1) { for (i = 0; i < num_sack_blks; i++) { for (j = i + 1; j < num_sack_blks; j++) { if (sack_blocks[i].end == sack_blocks[j].end) { /* * Ok these two have the same end we * want the smallest end and then * throw away the larger and start * again. */ if (SEQ_LT(sack_blocks[j].start, sack_blocks[i].start)) { /* * The second block covers * more area use that */ sack_blocks[i].start = sack_blocks[j].start; } /* * Now collapse out the dup-sack and * lower the count */ for (k = (j + 1); k < num_sack_blks; k++) { sack_blocks[j].start = sack_blocks[k].start; sack_blocks[j].end = sack_blocks[k].end; j++; } num_sack_blks--; goto again; } } } } do_sack_work: rsm = bbr->r_ctl.rc_sacklast; for (i = 0; i < num_sack_blks; i++) { acked = bbr_proc_sack_blk(tp, bbr, &sack_blocks[i], to, &rsm, cts); if (acked) { bbr->r_wanted_output = 1; changed += acked; sack_changed += acked; } } out: *prev_acked = p_acked; if ((sack_changed) && (!IN_RECOVERY(tp->t_flags))) { /* * Ok we have a high probability that we need to go in to * recovery since we have data sack'd */ struct bbr_sendmap *rsm; rsm = bbr_check_recovery_mode(tp, bbr, cts); if (rsm) { /* Enter recovery */ entered_recovery = 1; bbr->r_wanted_output = 1; /* * When we enter recovery we need to assure we send * one packet. */ if (bbr->r_ctl.rc_resend == NULL) { bbr->r_ctl.rc_resend = rsm; } } } if (IN_RECOVERY(tp->t_flags) && (entered_recovery == 0)) { /* * See if we need to rack-retransmit anything if so set it * up as the thing to resend assuming something else is not * already in that position. */ if (bbr->r_ctl.rc_resend == NULL) { bbr->r_ctl.rc_resend = bbr_check_recovery_mode(tp, bbr, cts); } } /* * We return the amount that changed via sack, this is used by the * ack-received code to augment what was changed between th_ack <-> * snd_una. */ return (sack_changed); } static void bbr_strike_dupack(struct tcp_bbr *bbr) { struct bbr_sendmap *rsm; rsm = TAILQ_FIRST(&bbr->r_ctl.rc_tmap); if (rsm && (rsm->r_dupack < 0xff)) { rsm->r_dupack++; if (rsm->r_dupack >= DUP_ACK_THRESHOLD) bbr->r_wanted_output = 1; } } /* * Return value of 1, we do not need to call bbr_process_data(). * return value of 0, bbr_process_data can be called. * For ret_val if its 0 the TCB is locked and valid, if its non-zero * its unlocked and probably unsafe to touch the TCB. */ static int bbr_process_ack(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, uint32_t tiwin, int32_t tlen, int32_t * ofia, int32_t thflags, int32_t * ret_val) { int32_t ourfinisacked = 0; int32_t acked_amount; uint16_t nsegs; int32_t acked; uint32_t lost, sack_changed = 0; struct mbuf *mfree; struct tcp_bbr *bbr; uint32_t prev_acked = 0; bbr = (struct tcp_bbr *)tp->t_fb_ptr; lost = bbr->r_ctl.rc_lost; nsegs = max(1, m->m_pkthdr.lro_nsegs); if (SEQ_GT(th->th_ack, tp->snd_max)) { ctf_do_dropafterack(m, tp, th, thflags, tlen, ret_val); bbr->r_wanted_output = 1; return (1); } if (SEQ_GEQ(th->th_ack, tp->snd_una) || to->to_nsacks) { /* Process the ack */ if (bbr->rc_in_persist) tp->t_rxtshift = 0; if ((th->th_ack == tp->snd_una) && (tiwin == tp->snd_wnd)) bbr_strike_dupack(bbr); sack_changed = bbr_log_ack(tp, to, th, &prev_acked); } bbr_lt_bw_sampling(bbr, bbr->r_ctl.rc_rcvtime, (bbr->r_ctl.rc_lost > lost)); if (__predict_false(SEQ_LEQ(th->th_ack, tp->snd_una))) { /* * Old ack, behind the last one rcv'd or a duplicate ack * with SACK info. */ if (th->th_ack == tp->snd_una) { bbr_ack_received(tp, bbr, th, 0, sack_changed, prev_acked, __LINE__, 0); if (bbr->r_state == TCPS_SYN_SENT) { /* * Special case on where we sent SYN. When * the SYN-ACK is processed in syn_sent * state it bumps the snd_una. This causes * us to hit here even though we did ack 1 * byte. * * Go through the nothing left case so we * send data. */ goto nothing_left; } } return (0); } /* * If we reach this point, ACK is not a duplicate, i.e., it ACKs * something we sent. */ if (tp->t_flags & TF_NEEDSYN) { /* * T/TCP: Connection was half-synchronized, and our SYN has * been ACK'd (so connection is now fully synchronized). Go * to non-starred state, increment snd_una for ACK of SYN, * and check if we can do window scaling. */ tp->t_flags &= ~TF_NEEDSYN; tp->snd_una++; /* Do window scaling? */ if ((tp->t_flags & (TF_RCVD_SCALE | TF_REQ_SCALE)) == (TF_RCVD_SCALE | TF_REQ_SCALE)) { tp->rcv_scale = tp->request_r_scale; /* Send window already scaled. */ } } INP_WLOCK_ASSERT(tptoinpcb(tp)); acked = BYTES_THIS_ACK(tp, th); KMOD_TCPSTAT_ADD(tcps_rcvackpack, (int)nsegs); KMOD_TCPSTAT_ADD(tcps_rcvackbyte, acked); /* * If we just performed our first retransmit, and the ACK arrives * within our recovery window, then it was a mistake to do the * retransmit in the first place. Recover our original cwnd and * ssthresh, and proceed to transmit where we left off. */ if (tp->t_flags & TF_PREVVALID) { tp->t_flags &= ~TF_PREVVALID; if (tp->t_rxtshift == 1 && (int)(ticks - tp->t_badrxtwin) < 0) bbr_cong_signal(tp, th, CC_RTO_ERR, NULL); } SOCKBUF_LOCK(&so->so_snd); acked_amount = min(acked, (int)sbavail(&so->so_snd)); tp->snd_wnd -= acked_amount; mfree = sbcut_locked(&so->so_snd, acked_amount); /* NB: sowwakeup_locked() does an implicit unlock. */ sowwakeup_locked(so); m_freem(mfree); if (SEQ_GT(th->th_ack, tp->snd_una)) { bbr_collapse_rtt(tp, bbr, TCP_REXMTVAL(tp)); } tp->snd_una = th->th_ack; bbr_ack_received(tp, bbr, th, acked, sack_changed, prev_acked, __LINE__, (bbr->r_ctl.rc_lost - lost)); if (IN_RECOVERY(tp->t_flags)) { if (SEQ_LT(th->th_ack, tp->snd_recover) && (SEQ_LT(th->th_ack, tp->snd_max))) { tcp_bbr_partialack(tp); } else { bbr_post_recovery(tp); } } if (SEQ_GT(tp->snd_una, tp->snd_recover)) { tp->snd_recover = tp->snd_una; } if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { tp->snd_nxt = tp->snd_max; } if (tp->snd_una == tp->snd_max) { /* Nothing left outstanding */ nothing_left: bbr_log_progress_event(bbr, tp, ticks, PROGRESS_CLEAR, __LINE__); if (sbavail(&so->so_snd) == 0) bbr->rc_tp->t_acktime = 0; if ((sbused(&so->so_snd) == 0) && (tp->t_flags & TF_SENTFIN)) { ourfinisacked = 1; } bbr_timer_cancel(bbr, __LINE__, bbr->r_ctl.rc_rcvtime); if (bbr->rc_in_persist == 0) { bbr->r_ctl.rc_went_idle_time = bbr->r_ctl.rc_rcvtime; } sack_filter_clear(&bbr->r_ctl.bbr_sf, tp->snd_una); bbr_log_ack_clear(bbr, bbr->r_ctl.rc_rcvtime); /* * We invalidate the last ack here since we * don't want to transfer forward the time * for our sum's calculations. */ if ((tp->t_state >= TCPS_FIN_WAIT_1) && (sbavail(&so->so_snd) == 0) && (tp->t_flags2 & TF2_DROP_AF_DATA)) { /* * The socket was gone and the peer sent data, time * to reset him. */ *ret_val = 1; tcp_log_end_status(tp, TCP_EI_STATUS_DATA_A_CLOSE); /* tcp_close will kill the inp pre-log the Reset */ tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST); tp = tcp_close(tp); ctf_do_dropwithreset(m, tp, th, BANDLIM_UNLIMITED, tlen); BBR_STAT_INC(bbr_dropped_af_data); return (1); } /* Set need output so persist might get set */ bbr->r_wanted_output = 1; } if (ofia) *ofia = ourfinisacked; return (0); } static void bbr_enter_persist(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts, int32_t line) { if (bbr->rc_in_persist == 0) { bbr_timer_cancel(bbr, __LINE__, cts); bbr->r_ctl.rc_last_delay_val = 0; tp->t_rxtshift = 0; bbr->rc_in_persist = 1; bbr->r_ctl.rc_went_idle_time = cts; /* We should be capped when rw went to 0 but just in case */ bbr_log_type_pesist(bbr, cts, 0, line, 1); /* Time freezes for the state, so do the accounting now */ if (SEQ_GT(cts, bbr->r_ctl.rc_bbr_state_time)) { uint32_t time_in; time_in = cts - bbr->r_ctl.rc_bbr_state_time; if (bbr->rc_bbr_state == BBR_STATE_PROBE_BW) { int32_t idx; idx = bbr_state_val(bbr); counter_u64_add(bbr_state_time[(idx + 5)], time_in); } else { counter_u64_add(bbr_state_time[bbr->rc_bbr_state], time_in); } } bbr->r_ctl.rc_bbr_state_time = cts; } } static void bbr_restart_after_idle(struct tcp_bbr *bbr, uint32_t cts, uint32_t idle_time) { /* * Note that if idle time does not exceed our * threshold, we do nothing continuing the state * transitions we were last walking through. */ if (idle_time >= bbr_idle_restart_threshold) { if (bbr->rc_use_idle_restart) { bbr->rc_bbr_state = BBR_STATE_IDLE_EXIT; /* * Set our target using BBR_UNIT, so * we increase at a dramatic rate but * we stop when we get the pipe * full again for our current b/w estimate. */ bbr->r_ctl.rc_bbr_hptsi_gain = BBR_UNIT; bbr->r_ctl.rc_bbr_cwnd_gain = BBR_UNIT; bbr_set_state_target(bbr, __LINE__); /* Now setup our gains to ramp up */ bbr->r_ctl.rc_bbr_hptsi_gain = bbr->r_ctl.rc_startup_pg; bbr->r_ctl.rc_bbr_cwnd_gain = bbr->r_ctl.rc_startup_pg; bbr_log_type_statechange(bbr, cts, __LINE__); } else if (bbr->rc_bbr_state == BBR_STATE_PROBE_BW) { bbr_substate_change(bbr, cts, __LINE__, 1); } } } static void bbr_exit_persist(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts, int32_t line) { uint32_t idle_time; if (bbr->rc_in_persist == 0) return; idle_time = bbr_calc_time(cts, bbr->r_ctl.rc_went_idle_time); bbr->rc_in_persist = 0; bbr->rc_hit_state_1 = 0; bbr->r_ctl.rc_del_time = cts; /* * We invalidate the last ack here since we * don't want to transfer forward the time * for our sum's calculations. */ if (tcp_in_hpts(bbr->rc_inp)) { tcp_hpts_remove(bbr->rc_inp); bbr->rc_timer_first = 0; bbr->r_ctl.rc_hpts_flags = 0; bbr->r_ctl.rc_last_delay_val = 0; bbr->r_ctl.rc_hptsi_agg_delay = 0; bbr->r_agg_early_set = 0; bbr->r_ctl.rc_agg_early = 0; } bbr_log_type_pesist(bbr, cts, idle_time, line, 0); if (idle_time >= bbr_rtt_probe_time) { /* * This qualifies as a RTT_PROBE session since we drop the * data outstanding to nothing and waited more than * bbr_rtt_probe_time. */ bbr_log_rtt_shrinks(bbr, cts, 0, 0, __LINE__, BBR_RTTS_PERSIST, 0); bbr->r_ctl.last_in_probertt = bbr->r_ctl.rc_rtt_shrinks = cts; } tp->t_rxtshift = 0; /* * If in probeBW and we have persisted more than an RTT lets do * special handling. */ /* Force a time based epoch */ bbr_set_epoch(bbr, cts, __LINE__); /* * Setup the lost so we don't count anything against the guy * we have been stuck with during persists. */ bbr->r_ctl.bbr_lost_at_state = bbr->r_ctl.rc_lost; /* Time un-freezes for the state */ bbr->r_ctl.rc_bbr_state_time = cts; if ((bbr->rc_bbr_state == BBR_STATE_PROBE_BW) || (bbr->rc_bbr_state == BBR_STATE_PROBE_RTT)) { /* * If we are going back to probe-bw * or probe_rtt, we may need to possibly * do a fast restart. */ bbr_restart_after_idle(bbr, cts, idle_time); } } static void bbr_collapsed_window(struct tcp_bbr *bbr) { /* * Now we must walk the * send map and divide the * ones left stranded. These * guys can't cause us to abort * the connection and are really * "unsent". However if a buggy * client actually did keep some * of the data i.e. collapsed the win * and refused to ack and then opened * the win and acked that data. We would * get into an ack war, the simplier * method then of just pretending we * did not send those segments something * won't work. */ struct bbr_sendmap *rsm, *nrsm; tcp_seq max_seq; uint32_t maxseg; int can_split = 0; int fnd = 0; maxseg = bbr->rc_tp->t_maxseg - bbr->rc_last_options; max_seq = bbr->rc_tp->snd_una + bbr->rc_tp->snd_wnd; bbr_log_type_rwnd_collapse(bbr, max_seq, 1, 0); TAILQ_FOREACH(rsm, &bbr->r_ctl.rc_map, r_next) { /* Find the first seq past or at maxseq */ if (rsm->r_flags & BBR_RWND_COLLAPSED) rsm->r_flags &= ~BBR_RWND_COLLAPSED; if (SEQ_GEQ(max_seq, rsm->r_start) && SEQ_GEQ(rsm->r_end, max_seq)) { fnd = 1; break; } } bbr->rc_has_collapsed = 0; if (!fnd) { /* Nothing to do strange */ return; } /* * Now can we split? * * We don't want to split if splitting * would generate too many small segments * less we let an attacker fragment our * send_map and leave us out of memory. */ if ((max_seq != rsm->r_start) && (max_seq != rsm->r_end)){ /* can we split? */ int res1, res2; res1 = max_seq - rsm->r_start; res2 = rsm->r_end - max_seq; if ((res1 >= (maxseg/8)) && (res2 >= (maxseg/8))) { /* No small pieces here */ can_split = 1; } else if (bbr->r_ctl.rc_num_small_maps_alloced < bbr_sack_block_limit) { /* We are under the limit */ can_split = 1; } } /* Ok do we need to split this rsm? */ if (max_seq == rsm->r_start) { /* It's this guy no split required */ nrsm = rsm; } else if (max_seq == rsm->r_end) { /* It's the next one no split required. */ nrsm = TAILQ_NEXT(rsm, r_next); if (nrsm == NULL) { /* Huh? */ return; } } else if (can_split && SEQ_LT(max_seq, rsm->r_end)) { /* yep we need to split it */ nrsm = bbr_alloc_limit(bbr, BBR_LIMIT_TYPE_SPLIT); if (nrsm == NULL) { /* failed XXXrrs what can we do mark the whole? */ nrsm = rsm; goto no_split; } /* Clone it */ bbr_log_type_rwnd_collapse(bbr, max_seq, 3, 0); bbr_clone_rsm(bbr, nrsm, rsm, max_seq); TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_map, rsm, nrsm, r_next); if (rsm->r_in_tmap) { TAILQ_INSERT_AFTER(&bbr->r_ctl.rc_tmap, rsm, nrsm, r_tnext); nrsm->r_in_tmap = 1; } } else { /* * Split not allowed just start here just * use this guy. */ nrsm = rsm; } no_split: BBR_STAT_INC(bbr_collapsed_win); /* reuse fnd as a count */ fnd = 0; TAILQ_FOREACH_FROM(nrsm, &bbr->r_ctl.rc_map, r_next) { nrsm->r_flags |= BBR_RWND_COLLAPSED; fnd++; bbr->rc_has_collapsed = 1; } bbr_log_type_rwnd_collapse(bbr, max_seq, 4, fnd); } static void bbr_un_collapse_window(struct tcp_bbr *bbr) { struct bbr_sendmap *rsm; int cleared = 0; TAILQ_FOREACH_REVERSE(rsm, &bbr->r_ctl.rc_map, bbr_head, r_next) { if (rsm->r_flags & BBR_RWND_COLLAPSED) { /* Clear the flag */ rsm->r_flags &= ~BBR_RWND_COLLAPSED; cleared++; } else break; } bbr_log_type_rwnd_collapse(bbr, (bbr->rc_tp->snd_una + bbr->rc_tp->snd_wnd), 0, cleared); bbr->rc_has_collapsed = 0; } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCB is still * locked. */ static int bbr_process_data(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt) { /* * Update window information. Don't look at window if no ACK: TAC's * send garbage on first SYN. */ uint16_t nsegs; int32_t tfo_syn; struct tcp_bbr *bbr; bbr = (struct tcp_bbr *)tp->t_fb_ptr; INP_WLOCK_ASSERT(tptoinpcb(tp)); nsegs = max(1, m->m_pkthdr.lro_nsegs); if ((thflags & TH_ACK) && (SEQ_LT(tp->snd_wl1, th->th_seq) || (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) || (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) { /* keep track of pure window updates */ if (tlen == 0 && tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd) KMOD_TCPSTAT_INC(tcps_rcvwinupd); tp->snd_wnd = tiwin; tp->snd_wl1 = th->th_seq; tp->snd_wl2 = th->th_ack; if (tp->snd_wnd > tp->max_sndwnd) tp->max_sndwnd = tp->snd_wnd; bbr->r_wanted_output = 1; } else if (thflags & TH_ACK) { if ((tp->snd_wl2 == th->th_ack) && (tiwin < tp->snd_wnd)) { tp->snd_wnd = tiwin; tp->snd_wl1 = th->th_seq; tp->snd_wl2 = th->th_ack; } } if (tp->snd_wnd < ctf_outstanding(tp)) /* The peer collapsed its window on us */ bbr_collapsed_window(bbr); else if (bbr->rc_has_collapsed) bbr_un_collapse_window(bbr); /* Was persist timer active and now we have window space? */ if ((bbr->rc_in_persist != 0) && (tp->snd_wnd >= min((bbr->r_ctl.rc_high_rwnd/2), bbr_minseg(bbr)))) { /* * Make the rate persist at end of persist mode if idle long * enough */ bbr_exit_persist(tp, bbr, bbr->r_ctl.rc_rcvtime, __LINE__); /* Make sure we output to start the timer */ bbr->r_wanted_output = 1; } /* Do we need to enter persist? */ if ((bbr->rc_in_persist == 0) && (tp->snd_wnd < min((bbr->r_ctl.rc_high_rwnd/2), bbr_minseg(bbr))) && TCPS_HAVEESTABLISHED(tp->t_state) && (tp->snd_max == tp->snd_una) && sbavail(&so->so_snd) && (sbavail(&so->so_snd) > tp->snd_wnd)) { /* No send window.. we must enter persist */ bbr_enter_persist(tp, bbr, bbr->r_ctl.rc_rcvtime, __LINE__); } if (tp->t_flags2 & TF2_DROP_AF_DATA) { m_freem(m); return (0); } /* * We don't support urgent data but * drag along the up just to make sure * if there is a stack switch no one * is surprised. */ tp->rcv_up = tp->rcv_nxt; /* * Process the segment text, merging it into the TCP sequencing * queue, and arranging for acknowledgment of receipt if necessary. * This process logically involves adjusting tp->rcv_wnd as data is * presented to the user (this happens in tcp_usrreq.c, case * PRU_RCVD). If a FIN has already been received on this connection * then we just ignore the text. */ tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) && IS_FASTOPEN(tp->t_flags)); if ((tlen || (thflags & TH_FIN) || (tfo_syn && tlen > 0)) && TCPS_HAVERCVDFIN(tp->t_state) == 0) { tcp_seq save_start = th->th_seq; tcp_seq save_rnxt = tp->rcv_nxt; int save_tlen = tlen; m_adj(m, drop_hdrlen); /* delayed header drop */ /* * Insert segment which includes th into TCP reassembly * queue with control block tp. Set thflags to whether * reassembly now includes a segment with FIN. This handles * the common case inline (segment is the next to be * received on an established connection, and the queue is * empty), avoiding linkage into and removal from the queue * and repetition of various conversions. Set DELACK for * segments received in order, but ack immediately when * segments are out of order (so fast retransmit can work). */ if (th->th_seq == tp->rcv_nxt && SEGQ_EMPTY(tp) && (TCPS_HAVEESTABLISHED(tp->t_state) || tfo_syn)) { #ifdef NETFLIX_SB_LIMITS u_int mcnt, appended; if (so->so_rcv.sb_shlim) { mcnt = m_memcnt(m); appended = 0; if (counter_fo_get(so->so_rcv.sb_shlim, mcnt, CFO_NOSLEEP, NULL) == false) { counter_u64_add(tcp_sb_shlim_fails, 1); m_freem(m); return (0); } } #endif if (DELAY_ACK(tp, bbr, nsegs) || tfo_syn) { bbr->bbr_segs_rcvd += max(1, nsegs); tp->t_flags |= TF_DELACK; bbr_timer_cancel(bbr, __LINE__, bbr->r_ctl.rc_rcvtime); } else { bbr->r_wanted_output = 1; tp->t_flags |= TF_ACKNOW; } tp->rcv_nxt += tlen; if (tlen && ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && (tp->t_fbyte_in == 0)) { tp->t_fbyte_in = ticks; if (tp->t_fbyte_in == 0) tp->t_fbyte_in = 1; if (tp->t_fbyte_out && tp->t_fbyte_in) tp->t_flags2 |= TF2_FBYTES_COMPLETE; } thflags = tcp_get_flags(th) & TH_FIN; KMOD_TCPSTAT_ADD(tcps_rcvpack, (int)nsegs); KMOD_TCPSTAT_ADD(tcps_rcvbyte, tlen); SOCKBUF_LOCK(&so->so_rcv); if (so->so_rcv.sb_state & SBS_CANTRCVMORE) m_freem(m); else #ifdef NETFLIX_SB_LIMITS appended = #endif sbappendstream_locked(&so->so_rcv, m, 0); /* NB: sorwakeup_locked() does an implicit unlock. */ sorwakeup_locked(so); #ifdef NETFLIX_SB_LIMITS if (so->so_rcv.sb_shlim && appended != mcnt) counter_fo_release(so->so_rcv.sb_shlim, mcnt - appended); #endif } else { /* * XXX: Due to the header drop above "th" is * theoretically invalid by now. Fortunately * m_adj() doesn't actually frees any mbufs when * trimming from the head. */ tcp_seq temp = save_start; thflags = tcp_reass(tp, th, &temp, &tlen, m); tp->t_flags |= TF_ACKNOW; if (tp->t_flags & TF_WAKESOR) { tp->t_flags &= ~TF_WAKESOR; /* NB: sorwakeup_locked() does an implicit unlock. */ sorwakeup_locked(so); } } if ((tp->t_flags & TF_SACK_PERMIT) && (save_tlen > 0) && TCPS_HAVEESTABLISHED(tp->t_state)) { if ((tlen == 0) && (SEQ_LT(save_start, save_rnxt))) { /* * DSACK actually handled in the fastpath * above. */ tcp_update_sack_list(tp, save_start, save_start + save_tlen); } else if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) { if ((tp->rcv_numsacks >= 1) && (tp->sackblks[0].end == save_start)) { /* * Partial overlap, recorded at todrop * above. */ tcp_update_sack_list(tp, tp->sackblks[0].start, tp->sackblks[0].end); } else { tcp_update_dsack_list(tp, save_start, save_start + save_tlen); } } else if (tlen >= save_tlen) { /* Update of sackblks. */ tcp_update_dsack_list(tp, save_start, save_start + save_tlen); } else if (tlen > 0) { tcp_update_dsack_list(tp, save_start, save_start + tlen); } } } else { m_freem(m); thflags &= ~TH_FIN; } /* * If FIN is received ACK the FIN and let the user know that the * connection is closing. */ if (thflags & TH_FIN) { if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { /* The socket upcall is handled by socantrcvmore. */ socantrcvmore(so); /* * If connection is half-synchronized (ie NEEDSYN * flag on) then delay ACK, so it may be piggybacked * when SYN is sent. Otherwise, since we received a * FIN then no more input can be expected, send ACK * now. */ if (tp->t_flags & TF_NEEDSYN) { tp->t_flags |= TF_DELACK; bbr_timer_cancel(bbr, __LINE__, bbr->r_ctl.rc_rcvtime); } else { tp->t_flags |= TF_ACKNOW; } tp->rcv_nxt++; } switch (tp->t_state) { /* * In SYN_RECEIVED and ESTABLISHED STATES enter the * CLOSE_WAIT state. */ case TCPS_SYN_RECEIVED: tp->t_starttime = ticks; /* FALLTHROUGH */ case TCPS_ESTABLISHED: tcp_state_change(tp, TCPS_CLOSE_WAIT); break; /* * If still in FIN_WAIT_1 STATE FIN has not been * acked so enter the CLOSING state. */ case TCPS_FIN_WAIT_1: tcp_state_change(tp, TCPS_CLOSING); break; /* * In FIN_WAIT_2 state enter the TIME_WAIT state, * starting the time-wait timer, turning off the * other standard timers. */ case TCPS_FIN_WAIT_2: bbr->rc_timer_first = 1; bbr_timer_cancel(bbr, __LINE__, bbr->r_ctl.rc_rcvtime); tcp_twstart(tp); return (1); } } /* * Return any desired output. */ if ((tp->t_flags & TF_ACKNOW) || (sbavail(&so->so_snd) > ctf_outstanding(tp))) { bbr->r_wanted_output = 1; } return (0); } /* * Here nothing is really faster, its just that we * have broken out the fast-data path also just like * the fast-ack. Return 1 if we processed the packet * return 0 if you need to take the "slow-path". */ static int bbr_do_fastnewdata(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t nxt_pkt) { uint16_t nsegs; int32_t newsize = 0; /* automatic sockbuf scaling */ struct tcp_bbr *bbr; #ifdef NETFLIX_SB_LIMITS u_int mcnt, appended; #endif -#ifdef TCPDEBUG - /* - * The size of tcp_saveipgen must be the size of the max ip header, - * now IPv6. - */ - u_char tcp_saveipgen[IP6_HDR_LEN]; - struct tcphdr tcp_savetcp; - short ostate = 0; -#endif /* On the hpts and we would have called output */ bbr = (struct tcp_bbr *)tp->t_fb_ptr; /* * If last ACK falls within this segment's sequence numbers, record * the timestamp. NOTE that the test is modified according to the * latest proposal of the tcplw@cray.com list (Braden 1993/04/26). */ if (bbr->r_ctl.rc_resend != NULL) { return (0); } if (tiwin && tiwin != tp->snd_wnd) { return (0); } if (__predict_false((tp->t_flags & (TF_NEEDSYN | TF_NEEDFIN)))) { return (0); } if (__predict_false((to->to_flags & TOF_TS) && (TSTMP_LT(to->to_tsval, tp->ts_recent)))) { return (0); } if (__predict_false((th->th_ack != tp->snd_una))) { return (0); } if (__predict_false(tlen > sbspace(&so->so_rcv))) { return (0); } if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent)) { tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* * This is a pure, in-sequence data packet with nothing on the * reassembly queue and we have enough buffer space to take it. */ nsegs = max(1, m->m_pkthdr.lro_nsegs); #ifdef NETFLIX_SB_LIMITS if (so->so_rcv.sb_shlim) { mcnt = m_memcnt(m); appended = 0; if (counter_fo_get(so->so_rcv.sb_shlim, mcnt, CFO_NOSLEEP, NULL) == false) { counter_u64_add(tcp_sb_shlim_fails, 1); m_freem(m); return (1); } } #endif /* Clean receiver SACK report if present */ if (tp->rcv_numsacks) tcp_clean_sackreport(tp); KMOD_TCPSTAT_INC(tcps_preddat); tp->rcv_nxt += tlen; if (tlen && ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && (tp->t_fbyte_in == 0)) { tp->t_fbyte_in = ticks; if (tp->t_fbyte_in == 0) tp->t_fbyte_in = 1; if (tp->t_fbyte_out && tp->t_fbyte_in) tp->t_flags2 |= TF2_FBYTES_COMPLETE; } /* * Pull snd_wl1 up to prevent seq wrap relative to th_seq. */ tp->snd_wl1 = th->th_seq; /* * Pull rcv_up up to prevent seq wrap relative to rcv_nxt. */ tp->rcv_up = tp->rcv_nxt; KMOD_TCPSTAT_ADD(tcps_rcvpack, (int)nsegs); KMOD_TCPSTAT_ADD(tcps_rcvbyte, tlen); -#ifdef TCPDEBUG - if (so->so_options & SO_DEBUG) - tcp_trace(TA_INPUT, ostate, tp, - (void *)tcp_saveipgen, &tcp_savetcp, 0); -#endif newsize = tcp_autorcvbuf(m, th, so, tp, tlen); /* Add data to socket buffer. */ SOCKBUF_LOCK(&so->so_rcv); if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { m_freem(m); } else { /* * Set new socket buffer size. Give up when limit is * reached. */ if (newsize) if (!sbreserve_locked(so, SO_RCV, newsize, NULL)) so->so_rcv.sb_flags &= ~SB_AUTOSIZE; m_adj(m, drop_hdrlen); /* delayed header drop */ #ifdef NETFLIX_SB_LIMITS appended = #endif sbappendstream_locked(&so->so_rcv, m, 0); ctf_calc_rwin(so, tp); } /* NB: sorwakeup_locked() does an implicit unlock. */ sorwakeup_locked(so); #ifdef NETFLIX_SB_LIMITS if (so->so_rcv.sb_shlim && mcnt != appended) counter_fo_release(so->so_rcv.sb_shlim, mcnt - appended); #endif if (DELAY_ACK(tp, bbr, nsegs)) { bbr->bbr_segs_rcvd += max(1, nsegs); tp->t_flags |= TF_DELACK; bbr_timer_cancel(bbr, __LINE__, bbr->r_ctl.rc_rcvtime); } else { bbr->r_wanted_output = 1; tp->t_flags |= TF_ACKNOW; } return (1); } /* * This subfunction is used to try to highly optimize the * fast path. We again allow window updates that are * in sequence to remain in the fast-path. We also add * in the __predict's to attempt to help the compiler. * Note that if we return a 0, then we can *not* process * it and the caller should push the packet into the * slow-path. If we return 1, then all is well and * the packet is fully processed. */ static int bbr_fastack(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t nxt_pkt, uint8_t iptos) { int32_t acked; uint16_t nsegs; uint32_t sack_changed; -#ifdef TCPDEBUG - /* - * The size of tcp_saveipgen must be the size of the max ip header, - * now IPv6. - */ - u_char tcp_saveipgen[IP6_HDR_LEN]; - struct tcphdr tcp_savetcp; - short ostate = 0; - -#endif uint32_t prev_acked = 0; struct tcp_bbr *bbr; if (__predict_false(SEQ_LEQ(th->th_ack, tp->snd_una))) { /* Old ack, behind (or duplicate to) the last one rcv'd */ return (0); } if (__predict_false(SEQ_GT(th->th_ack, tp->snd_max))) { /* Above what we have sent? */ return (0); } if (__predict_false(tiwin == 0)) { /* zero window */ return (0); } if (__predict_false(tp->t_flags & (TF_NEEDSYN | TF_NEEDFIN))) { /* We need a SYN or a FIN, unlikely.. */ return (0); } if ((to->to_flags & TOF_TS) && __predict_false(TSTMP_LT(to->to_tsval, tp->ts_recent))) { /* Timestamp is behind .. old ack with seq wrap? */ return (0); } if (__predict_false(IN_RECOVERY(tp->t_flags))) { /* Still recovering */ return (0); } bbr = (struct tcp_bbr *)tp->t_fb_ptr; if (__predict_false(bbr->r_ctl.rc_resend != NULL)) { /* We are retransmitting */ return (0); } if (__predict_false(bbr->rc_in_persist != 0)) { /* In persist mode */ return (0); } if (bbr->r_ctl.rc_sacked) { /* We have sack holes on our scoreboard */ return (0); } /* Ok if we reach here, we can process a fast-ack */ nsegs = max(1, m->m_pkthdr.lro_nsegs); sack_changed = bbr_log_ack(tp, to, th, &prev_acked); /* * We never detect loss in fast ack [we can't * have a sack and can't be in recovery so * we always pass 0 (nothing detected)]. */ bbr_lt_bw_sampling(bbr, bbr->r_ctl.rc_rcvtime, 0); /* Did the window get updated? */ if (tiwin != tp->snd_wnd) { tp->snd_wnd = tiwin; tp->snd_wl1 = th->th_seq; if (tp->snd_wnd > tp->max_sndwnd) tp->max_sndwnd = tp->snd_wnd; } /* Do we need to exit persists? */ if ((bbr->rc_in_persist != 0) && (tp->snd_wnd >= min((bbr->r_ctl.rc_high_rwnd/2), bbr_minseg(bbr)))) { bbr_exit_persist(tp, bbr, bbr->r_ctl.rc_rcvtime, __LINE__); bbr->r_wanted_output = 1; } /* Do we need to enter persists? */ if ((bbr->rc_in_persist == 0) && (tp->snd_wnd < min((bbr->r_ctl.rc_high_rwnd/2), bbr_minseg(bbr))) && TCPS_HAVEESTABLISHED(tp->t_state) && (tp->snd_max == tp->snd_una) && sbavail(&so->so_snd) && (sbavail(&so->so_snd) > tp->snd_wnd)) { /* No send window.. we must enter persist */ bbr_enter_persist(tp, bbr, bbr->r_ctl.rc_rcvtime, __LINE__); } /* * If last ACK falls within this segment's sequence numbers, record * the timestamp. NOTE that the test is modified according to the * latest proposal of the tcplw@cray.com list (Braden 1993/04/26). */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent)) { tp->ts_recent_age = bbr->r_ctl.rc_rcvtime; tp->ts_recent = to->to_tsval; } /* * This is a pure ack for outstanding data. */ KMOD_TCPSTAT_INC(tcps_predack); /* * "bad retransmit" recovery. */ if (tp->t_flags & TF_PREVVALID) { tp->t_flags &= ~TF_PREVVALID; if (tp->t_rxtshift == 1 && (int)(ticks - tp->t_badrxtwin) < 0) bbr_cong_signal(tp, th, CC_RTO_ERR, NULL); } /* * Recalculate the transmit timer / rtt. * * Some boxes send broken timestamp replies during the SYN+ACK * phase, ignore timestamps of 0 or we could calculate a huge RTT * and blow up the retransmit timer. */ acked = BYTES_THIS_ACK(tp, th); #ifdef TCP_HHOOK /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ hhook_run_tcp_est_in(tp, th, to); #endif KMOD_TCPSTAT_ADD(tcps_rcvackpack, (int)nsegs); KMOD_TCPSTAT_ADD(tcps_rcvackbyte, acked); sbdrop(&so->so_snd, acked); if (SEQ_GT(th->th_ack, tp->snd_una)) bbr_collapse_rtt(tp, bbr, TCP_REXMTVAL(tp)); tp->snd_una = th->th_ack; if (tp->snd_wnd < ctf_outstanding(tp)) /* The peer collapsed its window on us */ bbr_collapsed_window(bbr); else if (bbr->rc_has_collapsed) bbr_un_collapse_window(bbr); if (SEQ_GT(tp->snd_una, tp->snd_recover)) { tp->snd_recover = tp->snd_una; } bbr_ack_received(tp, bbr, th, acked, sack_changed, prev_acked, __LINE__, 0); /* * Pull snd_wl2 up to prevent seq wrap relative to th_ack. */ tp->snd_wl2 = th->th_ack; m_freem(m); /* * If all outstanding data are acked, stop retransmit timer, * otherwise restart timer using current (possibly backed-off) * value. If process is waiting for space, wakeup/selwakeup/signal. * If data are ready to send, let tcp_output decide between more * output or persist. + * Wake up the socket if we have room to write more. */ -#ifdef TCPDEBUG - if (so->so_options & SO_DEBUG) - tcp_trace(TA_INPUT, ostate, tp, - (void *)tcp_saveipgen, - &tcp_savetcp, 0); -#endif - /* Wake up the socket if we have room to write more */ sowwakeup(so); if (tp->snd_una == tp->snd_max) { /* Nothing left outstanding */ bbr_log_progress_event(bbr, tp, ticks, PROGRESS_CLEAR, __LINE__); if (sbavail(&so->so_snd) == 0) bbr->rc_tp->t_acktime = 0; bbr_timer_cancel(bbr, __LINE__, bbr->r_ctl.rc_rcvtime); if (bbr->rc_in_persist == 0) { bbr->r_ctl.rc_went_idle_time = bbr->r_ctl.rc_rcvtime; } sack_filter_clear(&bbr->r_ctl.bbr_sf, tp->snd_una); bbr_log_ack_clear(bbr, bbr->r_ctl.rc_rcvtime); /* * We invalidate the last ack here since we * don't want to transfer forward the time * for our sum's calculations. */ bbr->r_wanted_output = 1; } if (sbavail(&so->so_snd)) { bbr->r_wanted_output = 1; } return (1); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCB is still * locked. */ static int bbr_do_syn_sent(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t todrop; int32_t ourfinisacked = 0; struct tcp_bbr *bbr; int32_t ret_val = 0; INP_WLOCK_ASSERT(tptoinpcb(tp)); bbr = (struct tcp_bbr *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); /* * If the state is SYN_SENT: if seg contains an ACK, but not for our * SYN, drop the input. if seg contains a RST, then drop the * connection. if seg does not contain SYN, then drop it. Otherwise * this is an acceptable SYN segment initialize tp->rcv_nxt and * tp->irs if seg contains ack then advance tp->snd_una. BRR does * not support ECN so we will not say we are capable. if SYN has * been acked change to ESTABLISHED else SYN_RCVD state arrange for * segment to be acked (eventually) continue processing rest of * data/controls, beginning with URG */ if ((thflags & TH_ACK) && (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); ctf_do_dropwithreset(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } if ((thflags & (TH_ACK | TH_RST)) == (TH_ACK | TH_RST)) { TCP_PROBE5(connect__refused, NULL, tp, mtod(m, const char *), tp, th); tp = tcp_drop(tp, ECONNREFUSED); ctf_do_drop(m, tp); return (1); } if (thflags & TH_RST) { ctf_do_drop(m, tp); return (1); } if (!(thflags & TH_SYN)) { ctf_do_drop(m, tp); return (1); } tp->irs = th->th_seq; tcp_rcvseqinit(tp); if (thflags & TH_ACK) { int tfo_partial = 0; KMOD_TCPSTAT_INC(tcps_connects); soisconnected(so); #ifdef MAC mac_socketpeer_set_from_mbuf(m, so); #endif /* Do window scaling on this connection? */ if ((tp->t_flags & (TF_RCVD_SCALE | TF_REQ_SCALE)) == (TF_RCVD_SCALE | TF_REQ_SCALE)) { tp->rcv_scale = tp->request_r_scale; } tp->rcv_adv += min(tp->rcv_wnd, TCP_MAXWIN << tp->rcv_scale); /* * If not all the data that was sent in the TFO SYN * has been acked, resend the remainder right away. */ if (IS_FASTOPEN(tp->t_flags) && (tp->snd_una != tp->snd_max)) { tp->snd_nxt = th->th_ack; tfo_partial = 1; } /* * If there's data, delay ACK; if there's also a FIN ACKNOW * will be turned on later. */ if (DELAY_ACK(tp, bbr, 1) && tlen != 0 && !tfo_partial) { bbr->bbr_segs_rcvd += 1; tp->t_flags |= TF_DELACK; bbr_timer_cancel(bbr, __LINE__, bbr->r_ctl.rc_rcvtime); } else { bbr->r_wanted_output = 1; tp->t_flags |= TF_ACKNOW; } if (SEQ_GT(th->th_ack, tp->iss)) { /* * The SYN is acked * handle it specially. */ bbr_log_syn(tp, to); } if (SEQ_GT(th->th_ack, tp->snd_una)) { /* * We advance snd_una for the * fast open case. If th_ack is * acknowledging data beyond * snd_una we can't just call * ack-processing since the * data stream in our send-map * will start at snd_una + 1 (one * beyond the SYN). If its just * equal we don't need to do that * and there is no send_map. */ tp->snd_una++; } /* * Received in SYN_SENT[*] state. Transitions: * SYN_SENT --> ESTABLISHED SYN_SENT* --> FIN_WAIT_1 */ tp->t_starttime = ticks; if (tp->t_flags & TF_NEEDFIN) { tcp_state_change(tp, TCPS_FIN_WAIT_1); tp->t_flags &= ~TF_NEEDFIN; thflags &= ~TH_SYN; } else { tcp_state_change(tp, TCPS_ESTABLISHED); TCP_PROBE5(connect__established, NULL, tp, mtod(m, const char *), tp, th); cc_conn_init(tp); } } else { /* * Received initial SYN in SYN-SENT[*] state => simultaneous * open. If segment contains CC option and there is a * cached CC, apply TAO test. If it succeeds, connection is * * half-synchronized. Otherwise, do 3-way handshake: * SYN-SENT -> SYN-RECEIVED SYN-SENT* -> SYN-RECEIVED* If * there was no CC option, clear cached CC value. */ tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN | TF_SONOTCONN); tcp_state_change(tp, TCPS_SYN_RECEIVED); } /* * Advance th->th_seq to correspond to first data byte. If data, * trim to stay within window, dropping FIN if necessary. */ th->th_seq++; if (tlen > tp->rcv_wnd) { todrop = tlen - tp->rcv_wnd; m_adj(m, -todrop); tlen = tp->rcv_wnd; thflags &= ~TH_FIN; KMOD_TCPSTAT_INC(tcps_rcvpackafterwin); KMOD_TCPSTAT_ADD(tcps_rcvbyteafterwin, todrop); } tp->snd_wl1 = th->th_seq - 1; tp->rcv_up = th->th_seq; /* * Client side of transaction: already sent SYN and data. If the * remote host used T/TCP to validate the SYN, our data will be * ACK'd; if so, enter normal data segment processing in the middle * of step 5, ack processing. Otherwise, goto step 6. */ if (thflags & TH_ACK) { if ((to->to_flags & TOF_TS) != 0) { uint32_t t, rtt; t = tcp_tv_to_mssectick(&bbr->rc_tv); if (TSTMP_GEQ(t, to->to_tsecr)) { rtt = t - to->to_tsecr; if (rtt == 0) { rtt = 1; } rtt *= MS_IN_USEC; tcp_bbr_xmit_timer(bbr, rtt, 0, 0, 0); apply_filter_min_small(&bbr->r_ctl.rc_rttprop, rtt, bbr->r_ctl.rc_rcvtime); } } if (bbr_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) return (ret_val); /* We may have changed to FIN_WAIT_1 above */ if (tp->t_state == TCPS_FIN_WAIT_1) { /* * In FIN_WAIT_1 STATE in addition to the processing * for the ESTABLISHED state if our FIN is now * acknowledged then enter FIN_WAIT_2. */ if (ourfinisacked) { /* * If we can't receive any more data, then * closing user can proceed. Starting the * timer is contrary to the specification, * but if we don't get a FIN we'll hang * forever. * * XXXjl: we should release the tp also, and * use a compressed state. */ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { soisdisconnected(so); tcp_timer_activate(tp, TT_2MSL, (tcp_fast_finwait2_recycle ? tcp_finwait2_timeout : TP_MAXIDLE(tp))); } tcp_state_change(tp, TCPS_FIN_WAIT_2); } } } return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCB is still * locked. */ static int bbr_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t ourfinisacked = 0; int32_t ret_val; struct tcp_bbr *bbr; INP_WLOCK_ASSERT(tptoinpcb(tp)); bbr = (struct tcp_bbr *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_ACK) && (SEQ_LEQ(th->th_ack, tp->snd_una) || SEQ_GT(th->th_ack, tp->snd_max))) { tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); ctf_do_dropwithreset(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } if (IS_FASTOPEN(tp->t_flags)) { /* * When a TFO connection is in SYN_RECEIVED, the only valid * packets are the initial SYN, a retransmit/copy of the * initial SYN (possibly with a subset of the original * data), a valid ACK, a FIN, or a RST. */ if ((thflags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) { tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); ctf_do_dropwithreset(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } else if (thflags & TH_SYN) { /* non-initial SYN is ignored */ if ((bbr->r_ctl.rc_hpts_flags & PACE_TMR_RXT) || (bbr->r_ctl.rc_hpts_flags & PACE_TMR_TLP) || (bbr->r_ctl.rc_hpts_flags & PACE_TMR_RACK)) { ctf_do_drop(m, NULL); return (0); } } else if (!(thflags & (TH_ACK | TH_FIN | TH_RST))) { ctf_do_drop(m, NULL); return (0); } } if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (ctf_process_rst(m, th, so, tp)); /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } /* * In the SYN-RECEIVED state, validate that the packet belongs to * this connection before trimming the data to fit the receive * window. Check the sequence number versus IRS since we know the * sequence numbers haven't wrapped. This is a partial fix for the * "LAND" DoS attack. */ if (SEQ_LT(th->th_seq, tp->irs)) { tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); ctf_do_dropwithreset(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } tp->snd_wnd = tiwin; /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (IS_FASTOPEN(tp->t_flags)) { cc_conn_init(tp); } return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } KMOD_TCPSTAT_INC(tcps_connects); if (tp->t_flags & TF_SONOTCONN) { tp->t_flags &= ~TF_SONOTCONN; soisconnected(so); } /* Do window scaling? */ if ((tp->t_flags & (TF_RCVD_SCALE | TF_REQ_SCALE)) == (TF_RCVD_SCALE | TF_REQ_SCALE)) { tp->rcv_scale = tp->request_r_scale; } /* * ok for the first time in lets see if we can use the ts to figure * out what the initial RTT was. */ if ((to->to_flags & TOF_TS) != 0) { uint32_t t, rtt; t = tcp_tv_to_mssectick(&bbr->rc_tv); if (TSTMP_GEQ(t, to->to_tsecr)) { rtt = t - to->to_tsecr; if (rtt == 0) { rtt = 1; } rtt *= MS_IN_USEC; tcp_bbr_xmit_timer(bbr, rtt, 0, 0, 0); apply_filter_min_small(&bbr->r_ctl.rc_rttprop, rtt, bbr->r_ctl.rc_rcvtime); } } /* Drop off any SYN in the send map (probably not there) */ if (thflags & TH_ACK) bbr_log_syn(tp, to); if (IS_FASTOPEN(tp->t_flags) && tp->t_tfo_pending) { tcp_fastopen_decrement_counter(tp->t_tfo_pending); tp->t_tfo_pending = NULL; } /* * Make transitions: SYN-RECEIVED -> ESTABLISHED SYN-RECEIVED* -> * FIN-WAIT-1 */ tp->t_starttime = ticks; if (tp->t_flags & TF_NEEDFIN) { tcp_state_change(tp, TCPS_FIN_WAIT_1); tp->t_flags &= ~TF_NEEDFIN; } else { tcp_state_change(tp, TCPS_ESTABLISHED); TCP_PROBE5(accept__established, NULL, tp, mtod(m, const char *), tp, th); /* * TFO connections call cc_conn_init() during SYN * processing. Calling it again here for such connections * is not harmless as it would undo the snd_cwnd reduction * that occurs when a TFO SYN|ACK is retransmitted. */ if (!IS_FASTOPEN(tp->t_flags)) cc_conn_init(tp); } /* * Account for the ACK of our SYN prior to * regular ACK processing below, except for * simultaneous SYN, which is handled later. */ if (SEQ_GT(th->th_ack, tp->snd_una) && !(tp->t_flags & TF_NEEDSYN)) tp->snd_una++; /* * If segment contains data or ACK, will call tcp_reass() later; if * not, do so now to pass queued data to user. */ if (tlen == 0 && (thflags & TH_FIN) == 0) { (void)tcp_reass(tp, (struct tcphdr *)0, NULL, 0, (struct mbuf *)0); if (tp->t_flags & TF_WAKESOR) { tp->t_flags &= ~TF_WAKESOR; /* NB: sorwakeup_locked() does an implicit unlock. */ sorwakeup_locked(so); } } tp->snd_wl1 = th->th_seq - 1; if (bbr_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) { return (ret_val); } if (tp->t_state == TCPS_FIN_WAIT_1) { /* We could have went to FIN_WAIT_1 (or EST) above */ /* * In FIN_WAIT_1 STATE in addition to the processing for the * ESTABLISHED state if our FIN is now acknowledged then * enter FIN_WAIT_2. */ if (ourfinisacked) { /* * If we can't receive any more data, then closing * user can proceed. Starting the timer is contrary * to the specification, but if we don't get a FIN * we'll hang forever. * * XXXjl: we should release the tp also, and use a * compressed state. */ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { soisdisconnected(so); tcp_timer_activate(tp, TT_2MSL, (tcp_fast_finwait2_recycle ? tcp_finwait2_timeout : TP_MAXIDLE(tp))); } tcp_state_change(tp, TCPS_FIN_WAIT_2); } } return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCB is still * locked. */ static int bbr_do_established(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { struct tcp_bbr *bbr; int32_t ret_val; INP_WLOCK_ASSERT(tptoinpcb(tp)); /* * Header prediction: check for the two common cases of a * uni-directional data xfer. If the packet has no control flags, * is in-sequence, the window didn't change and we're not * retransmitting, it's a candidate. If the length is zero and the * ack moved forward, we're the sender side of the xfer. Just free * the data acked & wake any higher level process that was blocked * waiting for space. If the length is non-zero and the ack didn't * move, we're the receiver side. If we're getting packets in-order * (the reassembly queue is empty), add the data toc The socket * buffer and note that we need a delayed ack. Make sure that the * hidden state-flags are also off. Since we check for * TCPS_ESTABLISHED first, it can only be TH_NEEDSYN. */ bbr = (struct tcp_bbr *)tp->t_fb_ptr; if (bbr->r_ctl.rc_delivered < (4 * tp->t_maxseg)) { /* * If we have delived under 4 segments increase the initial * window if raised by the peer. We use this to determine * dynamic and static rwnd's at the end of a connection. */ bbr->r_ctl.rc_init_rwnd = max(tiwin, tp->snd_wnd); } if (__predict_true(((to->to_flags & TOF_SACK) == 0)) && __predict_true((thflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) == TH_ACK) && __predict_true(SEGQ_EMPTY(tp)) && __predict_true(th->th_seq == tp->rcv_nxt)) { if (tlen == 0) { if (bbr_fastack(m, th, so, tp, to, drop_hdrlen, tlen, tiwin, nxt_pkt, iptos)) { return (0); } } else { if (bbr_do_fastnewdata(m, th, so, tp, to, drop_hdrlen, tlen, tiwin, nxt_pkt)) { return (0); } } } ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (ctf_process_rst(m, th, so, tp)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. */ if (thflags & TH_SYN) { ctf_challenge_ack(m, th, tp, iptos, &ret_val); return (ret_val); } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_flags & TF_NEEDSYN) { return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } else if (tp->t_flags & TF_ACKNOW) { ctf_do_dropafterack(m, tp, th, thflags, tlen, &ret_val); bbr->r_wanted_output = 1; return (ret_val); } else { ctf_do_drop(m, NULL); return (0); } } /* * Ack processing. */ if (bbr_process_ack(m, th, so, tp, to, tiwin, tlen, NULL, thflags, &ret_val)) { return (ret_val); } if (sbavail(&so->so_snd)) { if (ctf_progress_timeout_check(tp, true)) { bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } } /* State changes only happen in bbr_process_data() */ return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCB is still * locked. */ static int bbr_do_close_wait(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { struct tcp_bbr *bbr; int32_t ret_val; INP_WLOCK_ASSERT(tptoinpcb(tp)); bbr = (struct tcp_bbr *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (ctf_process_rst(m, th, so, tp)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. */ if (thflags & TH_SYN) { ctf_challenge_ack(m, th, tp, iptos, &ret_val); return (ret_val); } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_flags & TF_NEEDSYN) { return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } else if (tp->t_flags & TF_ACKNOW) { ctf_do_dropafterack(m, tp, th, thflags, tlen, &ret_val); bbr->r_wanted_output = 1; return (ret_val); } else { ctf_do_drop(m, NULL); return (0); } } /* * Ack processing. */ if (bbr_process_ack(m, th, so, tp, to, tiwin, tlen, NULL, thflags, &ret_val)) { return (ret_val); } if (sbavail(&so->so_snd)) { if (ctf_progress_timeout_check(tp, true)) { bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } } return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } static int bbr_check_data_after_close(struct mbuf *m, struct tcp_bbr *bbr, struct tcpcb *tp, int32_t * tlen, struct tcphdr *th, struct socket *so) { if (bbr->rc_allow_data_af_clo == 0) { close_now: tcp_log_end_status(tp, TCP_EI_STATUS_DATA_A_CLOSE); /* tcp_close will kill the inp pre-log the Reset */ tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST); tp = tcp_close(tp); KMOD_TCPSTAT_INC(tcps_rcvafterclose); ctf_do_dropwithreset(m, tp, th, BANDLIM_UNLIMITED, (*tlen)); return (1); } if (sbavail(&so->so_snd) == 0) goto close_now; /* Ok we allow data that is ignored and a followup reset */ tp->rcv_nxt = th->th_seq + *tlen; tp->t_flags2 |= TF2_DROP_AF_DATA; bbr->r_wanted_output = 1; *tlen = 0; return (0); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCB is still * locked. */ static int bbr_do_fin_wait_1(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t ourfinisacked = 0; int32_t ret_val; struct tcp_bbr *bbr; INP_WLOCK_ASSERT(tptoinpcb(tp)); bbr = (struct tcp_bbr *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (ctf_process_rst(m, th, so, tp)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. */ if (thflags & TH_SYN) { ctf_challenge_ack(m, th, tp, iptos, &ret_val); return (ret_val); } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* * If new data are received on a connection after the user processes * are gone, then RST the other end. * We call a new function now so we might continue and setup * to reset at all data being ack'd. */ if ((tp->t_flags & TF_CLOSED) && tlen && bbr_check_data_after_close(m, bbr, tp, &tlen, th, so)) return (1); /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_flags & TF_NEEDSYN) { return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } else if (tp->t_flags & TF_ACKNOW) { ctf_do_dropafterack(m, tp, th, thflags, tlen, &ret_val); bbr->r_wanted_output = 1; return (ret_val); } else { ctf_do_drop(m, NULL); return (0); } } /* * Ack processing. */ if (bbr_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) { return (ret_val); } if (ourfinisacked) { /* * If we can't receive any more data, then closing user can * proceed. Starting the timer is contrary to the * specification, but if we don't get a FIN we'll hang * forever. * * XXXjl: we should release the tp also, and use a * compressed state. */ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { soisdisconnected(so); tcp_timer_activate(tp, TT_2MSL, (tcp_fast_finwait2_recycle ? tcp_finwait2_timeout : TP_MAXIDLE(tp))); } tcp_state_change(tp, TCPS_FIN_WAIT_2); } if (sbavail(&so->so_snd)) { if (ctf_progress_timeout_check(tp, true)) { bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } } return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCB is still * locked. */ static int bbr_do_closing(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t ourfinisacked = 0; int32_t ret_val; struct tcp_bbr *bbr; INP_WLOCK_ASSERT(tptoinpcb(tp)); bbr = (struct tcp_bbr *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (ctf_process_rst(m, th, so, tp)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. */ if (thflags & TH_SYN) { ctf_challenge_ack(m, th, tp, iptos, &ret_val); return (ret_val); } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* * If new data are received on a connection after the user processes * are gone, then RST the other end. * We call a new function now so we might continue and setup * to reset at all data being ack'd. */ if ((tp->t_flags & TF_CLOSED) && tlen && bbr_check_data_after_close(m, bbr, tp, &tlen, th, so)) return (1); /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_flags & TF_NEEDSYN) { return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } else if (tp->t_flags & TF_ACKNOW) { ctf_do_dropafterack(m, tp, th, thflags, tlen, &ret_val); bbr->r_wanted_output = 1; return (ret_val); } else { ctf_do_drop(m, NULL); return (0); } } /* * Ack processing. */ if (bbr_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) { return (ret_val); } if (ourfinisacked) { tcp_twstart(tp); m_freem(m); return (1); } if (sbavail(&so->so_snd)) { if (ctf_progress_timeout_check(tp, true)) { bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } } return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCB is still * locked. */ static int bbr_do_lastack(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t ourfinisacked = 0; int32_t ret_val; struct tcp_bbr *bbr; INP_WLOCK_ASSERT(tptoinpcb(tp)); bbr = (struct tcp_bbr *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (ctf_process_rst(m, th, so, tp)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. */ if (thflags & TH_SYN) { ctf_challenge_ack(m, th, tp, iptos, &ret_val); return (ret_val); } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* * If new data are received on a connection after the user processes * are gone, then RST the other end. * We call a new function now so we might continue and setup * to reset at all data being ack'd. */ if ((tp->t_flags & TF_CLOSED) && tlen && bbr_check_data_after_close(m, bbr, tp, &tlen, th, so)) return (1); /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_flags & TF_NEEDSYN) { return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } else if (tp->t_flags & TF_ACKNOW) { ctf_do_dropafterack(m, tp, th, thflags, tlen, &ret_val); bbr->r_wanted_output = 1; return (ret_val); } else { ctf_do_drop(m, NULL); return (0); } } /* * case TCPS_LAST_ACK: Ack processing. */ if (bbr_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) { return (ret_val); } if (ourfinisacked) { tp = tcp_close(tp); ctf_do_drop(m, tp); return (1); } if (sbavail(&so->so_snd)) { if (ctf_progress_timeout_check(tp, true)) { bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } } return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCB is still * locked. */ static int bbr_do_fin_wait_2(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t ourfinisacked = 0; int32_t ret_val; struct tcp_bbr *bbr; INP_WLOCK_ASSERT(tptoinpcb(tp)); bbr = (struct tcp_bbr *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); /* Reset receive buffer auto scaling when not in bulk receive mode. */ if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (ctf_process_rst(m, th, so, tp)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. */ if (thflags & TH_SYN) { ctf_challenge_ack(m, th, tp, iptos, &ret_val); return (ret_val); } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } if (ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) { return (ret_val); } /* * If new data are received on a connection after the user processes * are gone, then we may RST the other end depending on the outcome * of bbr_check_data_after_close. * We call a new function now so we might continue and setup * to reset at all data being ack'd. */ if ((tp->t_flags & TF_CLOSED) && tlen && bbr_check_data_after_close(m, bbr, tp, &tlen, th, so)) return (1); /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); tp->ts_recent = to->to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_flags & TF_NEEDSYN) { return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } else if (tp->t_flags & TF_ACKNOW) { ctf_do_dropafterack(m, tp, th, thflags, tlen, &ret_val); bbr->r_wanted_output = 1; return (ret_val); } else { ctf_do_drop(m, NULL); return (0); } } /* * Ack processing. */ if (bbr_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) { return (ret_val); } if (sbavail(&so->so_snd)) { if (ctf_progress_timeout_check(tp, true)) { bbr_log_progress_event(bbr, tp, tick, PROGRESS_DROP, __LINE__); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } } return (bbr_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } static void bbr_stop_all_timers(struct tcpcb *tp) { struct tcp_bbr *bbr; /* * Assure no timers are running. */ if (tcp_timer_active(tp, TT_PERSIST)) { /* We enter in persists, set the flag appropriately */ bbr = (struct tcp_bbr *)tp->t_fb_ptr; bbr->rc_in_persist = 1; } } static void bbr_google_mode_on(struct tcp_bbr *bbr) { bbr->rc_use_google = 1; bbr->rc_no_pacing = 0; bbr->r_ctl.bbr_google_discount = bbr_google_discount; bbr->r_use_policer = bbr_policer_detection_enabled; bbr->r_ctl.rc_probertt_int = (USECS_IN_SECOND * 10); bbr->bbr_use_rack_cheat = 0; bbr->r_ctl.rc_incr_tmrs = 0; bbr->r_ctl.rc_inc_tcp_oh = 0; bbr->r_ctl.rc_inc_ip_oh = 0; bbr->r_ctl.rc_inc_enet_oh = 0; reset_time(&bbr->r_ctl.rc_delrate, BBR_NUM_RTTS_FOR_GOOG_DEL_LIMIT); reset_time_small(&bbr->r_ctl.rc_rttprop, (11 * USECS_IN_SECOND)); tcp_bbr_tso_size_check(bbr, tcp_get_usecs(&bbr->rc_tv)); } static void bbr_google_mode_off(struct tcp_bbr *bbr) { bbr->rc_use_google = 0; bbr->r_ctl.bbr_google_discount = 0; bbr->no_pacing_until = bbr_no_pacing_until; bbr->r_use_policer = 0; if (bbr->no_pacing_until) bbr->rc_no_pacing = 1; else bbr->rc_no_pacing = 0; if (bbr_use_rack_resend_cheat) bbr->bbr_use_rack_cheat = 1; else bbr->bbr_use_rack_cheat = 0; if (bbr_incr_timers) bbr->r_ctl.rc_incr_tmrs = 1; else bbr->r_ctl.rc_incr_tmrs = 0; if (bbr_include_tcp_oh) bbr->r_ctl.rc_inc_tcp_oh = 1; else bbr->r_ctl.rc_inc_tcp_oh = 0; if (bbr_include_ip_oh) bbr->r_ctl.rc_inc_ip_oh = 1; else bbr->r_ctl.rc_inc_ip_oh = 0; if (bbr_include_enet_oh) bbr->r_ctl.rc_inc_enet_oh = 1; else bbr->r_ctl.rc_inc_enet_oh = 0; bbr->r_ctl.rc_probertt_int = bbr_rtt_probe_limit; reset_time(&bbr->r_ctl.rc_delrate, bbr_num_pktepo_for_del_limit); reset_time_small(&bbr->r_ctl.rc_rttprop, (bbr_filter_len_sec * USECS_IN_SECOND)); tcp_bbr_tso_size_check(bbr, tcp_get_usecs(&bbr->rc_tv)); } /* * Return 0 on success, non-zero on failure * which indicates the error (usually no memory). */ static int bbr_init(struct tcpcb *tp) { struct inpcb *inp = tptoinpcb(tp); struct tcp_bbr *bbr = NULL; uint32_t cts; tp->t_fb_ptr = uma_zalloc(bbr_pcb_zone, (M_NOWAIT | M_ZERO)); if (tp->t_fb_ptr == NULL) { /* * We need to allocate memory but cant. The INP and INP_INFO * locks and they are recursive (happens during setup. So a * scheme to drop the locks fails :( * */ return (ENOMEM); } bbr = (struct tcp_bbr *)tp->t_fb_ptr; bbr->rtt_valid = 0; inp->inp_flags2 |= INP_CANNOT_DO_ECN; inp->inp_flags2 |= INP_SUPPORTS_MBUFQ; TAILQ_INIT(&bbr->r_ctl.rc_map); TAILQ_INIT(&bbr->r_ctl.rc_free); TAILQ_INIT(&bbr->r_ctl.rc_tmap); bbr->rc_tp = tp; bbr->rc_inp = inp; cts = tcp_get_usecs(&bbr->rc_tv); tp->t_acktime = 0; bbr->rc_allow_data_af_clo = bbr_ignore_data_after_close; bbr->r_ctl.rc_reorder_fade = bbr_reorder_fade; bbr->rc_tlp_threshold = bbr_tlp_thresh; bbr->r_ctl.rc_reorder_shift = bbr_reorder_thresh; bbr->r_ctl.rc_pkt_delay = bbr_pkt_delay; bbr->r_ctl.rc_min_to = bbr_min_to; bbr->rc_bbr_state = BBR_STATE_STARTUP; bbr->r_ctl.bbr_lost_at_state = 0; bbr->r_ctl.rc_lost_at_startup = 0; bbr->rc_all_timers_stopped = 0; bbr->r_ctl.rc_bbr_lastbtlbw = 0; bbr->r_ctl.rc_pkt_epoch_del = 0; bbr->r_ctl.rc_pkt_epoch = 0; bbr->r_ctl.rc_lowest_rtt = 0xffffffff; bbr->r_ctl.rc_bbr_hptsi_gain = bbr_high_gain; bbr->r_ctl.rc_bbr_cwnd_gain = bbr_high_gain; bbr->r_ctl.rc_went_idle_time = cts; bbr->rc_pacer_started = cts; bbr->r_ctl.rc_pkt_epoch_time = cts; bbr->r_ctl.rc_rcvtime = cts; bbr->r_ctl.rc_bbr_state_time = cts; bbr->r_ctl.rc_del_time = cts; bbr->r_ctl.rc_tlp_rxt_last_time = cts; bbr->r_ctl.last_in_probertt = cts; bbr->skip_gain = 0; bbr->gain_is_limited = 0; bbr->no_pacing_until = bbr_no_pacing_until; if (bbr->no_pacing_until) bbr->rc_no_pacing = 1; if (bbr_use_google_algo) { bbr->rc_no_pacing = 0; bbr->rc_use_google = 1; bbr->r_ctl.bbr_google_discount = bbr_google_discount; bbr->r_use_policer = bbr_policer_detection_enabled; } else { bbr->rc_use_google = 0; bbr->r_ctl.bbr_google_discount = 0; bbr->r_use_policer = 0; } if (bbr_ts_limiting) bbr->rc_use_ts_limit = 1; else bbr->rc_use_ts_limit = 0; if (bbr_ts_can_raise) bbr->ts_can_raise = 1; else bbr->ts_can_raise = 0; if (V_tcp_delack_enabled == 1) tp->t_delayed_ack = 2; else if (V_tcp_delack_enabled == 0) tp->t_delayed_ack = 0; else if (V_tcp_delack_enabled < 100) tp->t_delayed_ack = V_tcp_delack_enabled; else tp->t_delayed_ack = 2; if (bbr->rc_use_google == 0) bbr->r_ctl.rc_probertt_int = bbr_rtt_probe_limit; else bbr->r_ctl.rc_probertt_int = (USECS_IN_SECOND * 10); bbr->r_ctl.rc_min_rto_ms = bbr_rto_min_ms; bbr->rc_max_rto_sec = bbr_rto_max_sec; bbr->rc_init_win = bbr_def_init_win; if (tp->t_flags & TF_REQ_TSTMP) bbr->rc_last_options = TCP_TS_OVERHEAD; bbr->r_ctl.rc_pace_max_segs = tp->t_maxseg - bbr->rc_last_options; bbr->r_ctl.rc_high_rwnd = tp->snd_wnd; bbr->r_init_rtt = 1; counter_u64_add(bbr_flows_nohdwr_pacing, 1); if (bbr_allow_hdwr_pacing) bbr->bbr_hdw_pace_ena = 1; else bbr->bbr_hdw_pace_ena = 0; if (bbr_sends_full_iwnd) bbr->bbr_init_win_cheat = 1; else bbr->bbr_init_win_cheat = 0; bbr->r_ctl.bbr_utter_max = bbr_hptsi_utter_max; bbr->r_ctl.rc_drain_pg = bbr_drain_gain; bbr->r_ctl.rc_startup_pg = bbr_high_gain; bbr->rc_loss_exit = bbr_exit_startup_at_loss; bbr->r_ctl.bbr_rttprobe_gain_val = bbr_rttprobe_gain; bbr->r_ctl.bbr_hptsi_per_second = bbr_hptsi_per_second; bbr->r_ctl.bbr_hptsi_segments_delay_tar = bbr_hptsi_segments_delay_tar; bbr->r_ctl.bbr_hptsi_segments_max = bbr_hptsi_segments_max; bbr->r_ctl.bbr_hptsi_segments_floor = bbr_hptsi_segments_floor; bbr->r_ctl.bbr_hptsi_bytes_min = bbr_hptsi_bytes_min; bbr->r_ctl.bbr_cross_over = bbr_cross_over; bbr->r_ctl.rc_rtt_shrinks = cts; if (bbr->rc_use_google) { setup_time_filter(&bbr->r_ctl.rc_delrate, FILTER_TYPE_MAX, BBR_NUM_RTTS_FOR_GOOG_DEL_LIMIT); setup_time_filter_small(&bbr->r_ctl.rc_rttprop, FILTER_TYPE_MIN, (11 * USECS_IN_SECOND)); } else { setup_time_filter(&bbr->r_ctl.rc_delrate, FILTER_TYPE_MAX, bbr_num_pktepo_for_del_limit); setup_time_filter_small(&bbr->r_ctl.rc_rttprop, FILTER_TYPE_MIN, (bbr_filter_len_sec * USECS_IN_SECOND)); } bbr_log_rtt_shrinks(bbr, cts, 0, 0, __LINE__, BBR_RTTS_INIT, 0); if (bbr_uses_idle_restart) bbr->rc_use_idle_restart = 1; else bbr->rc_use_idle_restart = 0; bbr->r_ctl.rc_bbr_cur_del_rate = 0; bbr->r_ctl.rc_initial_hptsi_bw = bbr_initial_bw_bps; if (bbr_resends_use_tso) bbr->rc_resends_use_tso = 1; #ifdef NETFLIX_PEAKRATE tp->t_peakrate_thr = tp->t_maxpeakrate; #endif if (tp->snd_una != tp->snd_max) { /* Create a send map for the current outstanding data */ struct bbr_sendmap *rsm; rsm = bbr_alloc(bbr); if (rsm == NULL) { uma_zfree(bbr_pcb_zone, tp->t_fb_ptr); tp->t_fb_ptr = NULL; return (ENOMEM); } rsm->r_rtt_not_allowed = 1; rsm->r_tim_lastsent[0] = cts; rsm->r_rtr_cnt = 1; rsm->r_rtr_bytes = 0; rsm->r_start = tp->snd_una; rsm->r_end = tp->snd_max; rsm->r_dupack = 0; rsm->r_delivered = bbr->r_ctl.rc_delivered; rsm->r_ts_valid = 0; rsm->r_del_ack_ts = tp->ts_recent; rsm->r_del_time = cts; if (bbr->r_ctl.r_app_limited_until) rsm->r_app_limited = 1; else rsm->r_app_limited = 0; TAILQ_INSERT_TAIL(&bbr->r_ctl.rc_map, rsm, r_next); TAILQ_INSERT_TAIL(&bbr->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 1; if (bbr->rc_bbr_state == BBR_STATE_PROBE_BW) rsm->r_bbr_state = bbr_state_val(bbr); else rsm->r_bbr_state = 8; } if (bbr_use_rack_resend_cheat && (bbr->rc_use_google == 0)) bbr->bbr_use_rack_cheat = 1; if (bbr_incr_timers && (bbr->rc_use_google == 0)) bbr->r_ctl.rc_incr_tmrs = 1; if (bbr_include_tcp_oh && (bbr->rc_use_google == 0)) bbr->r_ctl.rc_inc_tcp_oh = 1; if (bbr_include_ip_oh && (bbr->rc_use_google == 0)) bbr->r_ctl.rc_inc_ip_oh = 1; if (bbr_include_enet_oh && (bbr->rc_use_google == 0)) bbr->r_ctl.rc_inc_enet_oh = 1; bbr_log_type_statechange(bbr, cts, __LINE__); if (TCPS_HAVEESTABLISHED(tp->t_state) && (tp->t_srtt)) { uint32_t rtt; rtt = (TICKS_2_USEC(tp->t_srtt) >> TCP_RTT_SHIFT); apply_filter_min_small(&bbr->r_ctl.rc_rttprop, rtt, cts); } /* announce the settings and state */ bbr_log_settings_change(bbr, BBR_RECOVERY_LOWRTT); tcp_bbr_tso_size_check(bbr, cts); /* * Now call the generic function to start a timer. This will place * the TCB on the hptsi wheel if a timer is needed with appropriate * flags. */ bbr_stop_all_timers(tp); bbr_start_hpts_timer(bbr, tp, cts, 5, 0, 0); return (0); } /* * Return 0 if we can accept the connection. Return * non-zero if we can't handle the connection. A EAGAIN * means you need to wait until the connection is up. * a EADDRNOTAVAIL means we can never handle the connection * (no SACK). */ static int bbr_handoff_ok(struct tcpcb *tp) { if ((tp->t_state == TCPS_CLOSED) || (tp->t_state == TCPS_LISTEN)) { /* Sure no problem though it may not stick */ return (0); } if ((tp->t_state == TCPS_SYN_SENT) || (tp->t_state == TCPS_SYN_RECEIVED)) { /* * We really don't know you have to get to ESTAB or beyond * to tell. */ return (EAGAIN); } if (tp->t_flags & TF_SENTFIN) return (EINVAL); if ((tp->t_flags & TF_SACK_PERMIT) || bbr_sack_not_required) { return (0); } /* * If we reach here we don't do SACK on this connection so we can * never do rack. */ return (EINVAL); } static void bbr_fini(struct tcpcb *tp, int32_t tcb_is_purged) { if (tp->t_fb_ptr) { struct inpcb *inp = tptoinpcb(tp); uint32_t calc; struct tcp_bbr *bbr; struct bbr_sendmap *rsm; bbr = (struct tcp_bbr *)tp->t_fb_ptr; if (bbr->r_ctl.crte) tcp_rel_pacing_rate(bbr->r_ctl.crte, bbr->rc_tp); bbr_log_flowend(bbr); bbr->rc_tp = NULL; /* Backout any flags2 we applied */ inp->inp_flags2 &= ~INP_CANNOT_DO_ECN; inp->inp_flags2 &= ~INP_SUPPORTS_MBUFQ; inp->inp_flags2 &= ~INP_MBUF_QUEUE_READY; if (bbr->bbr_hdrw_pacing) counter_u64_add(bbr_flows_whdwr_pacing, -1); else counter_u64_add(bbr_flows_nohdwr_pacing, -1); if (bbr->r_ctl.crte != NULL) { tcp_rel_pacing_rate(bbr->r_ctl.crte, tp); bbr->r_ctl.crte = NULL; } rsm = TAILQ_FIRST(&bbr->r_ctl.rc_map); while (rsm) { TAILQ_REMOVE(&bbr->r_ctl.rc_map, rsm, r_next); uma_zfree(bbr_zone, rsm); rsm = TAILQ_FIRST(&bbr->r_ctl.rc_map); } rsm = TAILQ_FIRST(&bbr->r_ctl.rc_free); while (rsm) { TAILQ_REMOVE(&bbr->r_ctl.rc_free, rsm, r_next); uma_zfree(bbr_zone, rsm); rsm = TAILQ_FIRST(&bbr->r_ctl.rc_free); } calc = bbr->r_ctl.rc_high_rwnd - bbr->r_ctl.rc_init_rwnd; if (calc > (bbr->r_ctl.rc_init_rwnd / 10)) BBR_STAT_INC(bbr_dynamic_rwnd); else BBR_STAT_INC(bbr_static_rwnd); bbr->r_ctl.rc_free_cnt = 0; uma_zfree(bbr_pcb_zone, tp->t_fb_ptr); tp->t_fb_ptr = NULL; } /* Make sure snd_nxt is correctly set */ tp->snd_nxt = tp->snd_max; } static void bbr_set_state(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t win) { switch (tp->t_state) { case TCPS_SYN_SENT: bbr->r_state = TCPS_SYN_SENT; bbr->r_substate = bbr_do_syn_sent; break; case TCPS_SYN_RECEIVED: bbr->r_state = TCPS_SYN_RECEIVED; bbr->r_substate = bbr_do_syn_recv; break; case TCPS_ESTABLISHED: bbr->r_ctl.rc_init_rwnd = max(win, bbr->rc_tp->snd_wnd); bbr->r_state = TCPS_ESTABLISHED; bbr->r_substate = bbr_do_established; break; case TCPS_CLOSE_WAIT: bbr->r_state = TCPS_CLOSE_WAIT; bbr->r_substate = bbr_do_close_wait; break; case TCPS_FIN_WAIT_1: bbr->r_state = TCPS_FIN_WAIT_1; bbr->r_substate = bbr_do_fin_wait_1; break; case TCPS_CLOSING: bbr->r_state = TCPS_CLOSING; bbr->r_substate = bbr_do_closing; break; case TCPS_LAST_ACK: bbr->r_state = TCPS_LAST_ACK; bbr->r_substate = bbr_do_lastack; break; case TCPS_FIN_WAIT_2: bbr->r_state = TCPS_FIN_WAIT_2; bbr->r_substate = bbr_do_fin_wait_2; break; case TCPS_LISTEN: case TCPS_CLOSED: case TCPS_TIME_WAIT: default: break; }; } static void bbr_substate_change(struct tcp_bbr *bbr, uint32_t cts, int32_t line, int dolog) { /* * Now what state are we going into now? Is there adjustments * needed? */ int32_t old_state; old_state = bbr_state_val(bbr); if (bbr_state_val(bbr) == BBR_SUB_LEVEL1) { /* Save the lowest srtt we saw in our end of the sub-state */ bbr->rc_hit_state_1 = 0; if (bbr->r_ctl.bbr_smallest_srtt_this_state != 0xffffffff) bbr->r_ctl.bbr_smallest_srtt_state2 = bbr->r_ctl.bbr_smallest_srtt_this_state; } bbr->rc_bbr_substate++; if (bbr->rc_bbr_substate >= BBR_SUBSTATE_COUNT) { /* Cycle back to first state-> gain */ bbr->rc_bbr_substate = 0; } if (bbr_state_val(bbr) == BBR_SUB_GAIN) { /* * We enter the gain(5/4) cycle (possibly less if * shallow buffer detection is enabled) */ if (bbr->skip_gain) { /* * Hardware pacing has set our rate to * the max and limited our b/w just * do level i.e. no gain. */ bbr->r_ctl.rc_bbr_hptsi_gain = bbr_hptsi_gain[BBR_SUB_LEVEL1]; } else if (bbr->gain_is_limited && bbr->bbr_hdrw_pacing && bbr->r_ctl.crte) { /* * We can't gain above the hardware pacing * rate which is less than our rate + the gain * calculate the gain needed to reach the hardware * pacing rate.. */ uint64_t bw, rate, gain_calc; bw = bbr_get_bw(bbr); rate = bbr->r_ctl.crte->rate; if ((rate > bw) && (((bw * (uint64_t)bbr_hptsi_gain[BBR_SUB_GAIN]) / (uint64_t)BBR_UNIT) > rate)) { gain_calc = (rate * BBR_UNIT) / bw; if (gain_calc < BBR_UNIT) gain_calc = BBR_UNIT; bbr->r_ctl.rc_bbr_hptsi_gain = (uint16_t)gain_calc; } else { bbr->r_ctl.rc_bbr_hptsi_gain = bbr_hptsi_gain[BBR_SUB_GAIN]; } } else bbr->r_ctl.rc_bbr_hptsi_gain = bbr_hptsi_gain[BBR_SUB_GAIN]; if ((bbr->rc_use_google == 0) && (bbr_gain_to_target == 0)) { bbr->r_ctl.rc_bbr_state_atflight = cts; } else bbr->r_ctl.rc_bbr_state_atflight = 0; } else if (bbr_state_val(bbr) == BBR_SUB_DRAIN) { bbr->rc_hit_state_1 = 1; bbr->r_ctl.rc_exta_time_gd = 0; bbr->r_ctl.flightsize_at_drain = ctf_flight_size(bbr->rc_tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); if (bbr_state_drain_2_tar) { bbr->r_ctl.rc_bbr_state_atflight = 0; } else bbr->r_ctl.rc_bbr_state_atflight = cts; bbr->r_ctl.rc_bbr_hptsi_gain = bbr_hptsi_gain[BBR_SUB_DRAIN]; } else { /* All other cycles hit here 2-7 */ if ((old_state == BBR_SUB_DRAIN) && bbr->rc_hit_state_1) { if (bbr_sub_drain_slam_cwnd && (bbr->rc_use_google == 0) && (bbr->rc_tp->snd_cwnd < bbr->r_ctl.rc_saved_cwnd)) { bbr->rc_tp->snd_cwnd = bbr->r_ctl.rc_saved_cwnd; bbr_log_type_cwndupd(bbr, 0, 0, 0, 12, 0, 0, __LINE__); } if ((cts - bbr->r_ctl.rc_bbr_state_time) > bbr_get_rtt(bbr, BBR_RTT_PROP)) bbr->r_ctl.rc_exta_time_gd += ((cts - bbr->r_ctl.rc_bbr_state_time) - bbr_get_rtt(bbr, BBR_RTT_PROP)); else bbr->r_ctl.rc_exta_time_gd = 0; if (bbr->r_ctl.rc_exta_time_gd) { bbr->r_ctl.rc_level_state_extra = bbr->r_ctl.rc_exta_time_gd; /* Now chop up the time for each state (div by 7) */ bbr->r_ctl.rc_level_state_extra /= 7; if (bbr_rand_ot && bbr->r_ctl.rc_level_state_extra) { /* Add a randomization */ bbr_randomize_extra_state_time(bbr); } } } bbr->r_ctl.rc_bbr_state_atflight = max(1, cts); bbr->r_ctl.rc_bbr_hptsi_gain = bbr_hptsi_gain[bbr_state_val(bbr)]; } if (bbr->rc_use_google) { bbr->r_ctl.rc_bbr_state_atflight = max(1, cts); } bbr->r_ctl.bbr_lost_at_state = bbr->r_ctl.rc_lost; bbr->r_ctl.rc_bbr_cwnd_gain = bbr_cwnd_gain; if (dolog) bbr_log_type_statechange(bbr, cts, line); if (SEQ_GT(cts, bbr->r_ctl.rc_bbr_state_time)) { uint32_t time_in; time_in = cts - bbr->r_ctl.rc_bbr_state_time; if (bbr->rc_bbr_state == BBR_STATE_PROBE_BW) { counter_u64_add(bbr_state_time[(old_state + 5)], time_in); } else { counter_u64_add(bbr_state_time[bbr->rc_bbr_state], time_in); } } bbr->r_ctl.bbr_smallest_srtt_this_state = 0xffffffff; bbr_set_state_target(bbr, __LINE__); if (bbr_sub_drain_slam_cwnd && (bbr->rc_use_google == 0) && (bbr_state_val(bbr) == BBR_SUB_DRAIN)) { /* Slam down the cwnd */ bbr->r_ctl.rc_saved_cwnd = bbr->rc_tp->snd_cwnd; bbr->rc_tp->snd_cwnd = bbr->r_ctl.rc_target_at_state; if (bbr_sub_drain_app_limit) { /* Go app limited if we are on a long drain */ bbr->r_ctl.r_app_limited_until = (bbr->r_ctl.rc_delivered + ctf_flight_size(bbr->rc_tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes))); } bbr_log_type_cwndupd(bbr, 0, 0, 0, 12, 0, 0, __LINE__); } if (bbr->rc_lt_use_bw) { /* In policed mode we clamp pacing_gain to BBR_UNIT */ bbr->r_ctl.rc_bbr_hptsi_gain = BBR_UNIT; } /* Google changes TSO size every cycle */ if (bbr->rc_use_google) tcp_bbr_tso_size_check(bbr, cts); bbr->r_ctl.gain_epoch = cts; bbr->r_ctl.rc_bbr_state_time = cts; bbr->r_ctl.substate_pe = bbr->r_ctl.rc_pkt_epoch; } static void bbr_set_probebw_google_gains(struct tcp_bbr *bbr, uint32_t cts, uint32_t losses) { if ((bbr_state_val(bbr) == BBR_SUB_DRAIN) && (google_allow_early_out == 1) && (bbr->r_ctl.rc_flight_at_input <= bbr->r_ctl.rc_target_at_state)) { /* We have reached out target flight size possibly early */ goto change_state; } if (TSTMP_LT(cts, bbr->r_ctl.rc_bbr_state_time)) { return; } if ((cts - bbr->r_ctl.rc_bbr_state_time) < bbr_get_rtt(bbr, BBR_RTT_PROP)) { /* * Must be a rttProp movement forward before * we can change states. */ return; } if (bbr_state_val(bbr) == BBR_SUB_GAIN) { /* * The needed time has passed but for * the gain cycle extra rules apply: * 1) If we have seen loss, we exit * 2) If we have not reached the target * we stay in GAIN (gain-to-target). */ if (google_consider_lost && losses) goto change_state; if (bbr->r_ctl.rc_target_at_state > bbr->r_ctl.rc_flight_at_input) { return; } } change_state: /* For gain we must reach our target, all others last 1 rttProp */ bbr_substate_change(bbr, cts, __LINE__, 1); } static void bbr_set_probebw_gains(struct tcp_bbr *bbr, uint32_t cts, uint32_t losses) { uint32_t flight, bbr_cur_cycle_time; if (bbr->rc_use_google) { bbr_set_probebw_google_gains(bbr, cts, losses); return; } if (cts == 0) { /* * Never alow cts to be 0 we * do this so we can judge if * we have set a timestamp. */ cts = 1; } if (bbr_state_is_pkt_epoch) bbr_cur_cycle_time = bbr_get_rtt(bbr, BBR_RTT_PKTRTT); else bbr_cur_cycle_time = bbr_get_rtt(bbr, BBR_RTT_PROP); if (bbr->r_ctl.rc_bbr_state_atflight == 0) { if (bbr_state_val(bbr) == BBR_SUB_DRAIN) { flight = ctf_flight_size(bbr->rc_tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); if (bbr_sub_drain_slam_cwnd && bbr->rc_hit_state_1) { /* Keep it slam down */ if (bbr->rc_tp->snd_cwnd > bbr->r_ctl.rc_target_at_state) { bbr->rc_tp->snd_cwnd = bbr->r_ctl.rc_target_at_state; bbr_log_type_cwndupd(bbr, 0, 0, 0, 12, 0, 0, __LINE__); } if (bbr_sub_drain_app_limit) { /* Go app limited if we are on a long drain */ bbr->r_ctl.r_app_limited_until = (bbr->r_ctl.rc_delivered + flight); } } if (TSTMP_GT(cts, bbr->r_ctl.gain_epoch) && (((cts - bbr->r_ctl.gain_epoch) > bbr_get_rtt(bbr, BBR_RTT_PROP)) || (flight >= bbr->r_ctl.flightsize_at_drain))) { /* * Still here after the same time as * the gain. We need to drain harder * for the next srtt. Reduce by a set amount * the gain drop is capped at DRAIN states * value (88). */ bbr->r_ctl.flightsize_at_drain = flight; if (bbr_drain_drop_mul && bbr_drain_drop_div && (bbr_drain_drop_mul < bbr_drain_drop_div)) { /* Use your specific drop value (def 4/5 = 20%) */ bbr->r_ctl.rc_bbr_hptsi_gain *= bbr_drain_drop_mul; bbr->r_ctl.rc_bbr_hptsi_gain /= bbr_drain_drop_div; } else { /* You get drop of 20% */ bbr->r_ctl.rc_bbr_hptsi_gain *= 4; bbr->r_ctl.rc_bbr_hptsi_gain /= 5; } if (bbr->r_ctl.rc_bbr_hptsi_gain <= bbr_drain_floor) { /* Reduce our gain again to the bottom */ bbr->r_ctl.rc_bbr_hptsi_gain = max(bbr_drain_floor, 1); } bbr_log_exit_gain(bbr, cts, 4); /* * Extend out so we wait another * epoch before dropping again. */ bbr->r_ctl.gain_epoch = cts; } if (flight <= bbr->r_ctl.rc_target_at_state) { if (bbr_sub_drain_slam_cwnd && (bbr->rc_use_google == 0) && (bbr->rc_tp->snd_cwnd < bbr->r_ctl.rc_saved_cwnd)) { bbr->rc_tp->snd_cwnd = bbr->r_ctl.rc_saved_cwnd; bbr_log_type_cwndupd(bbr, 0, 0, 0, 12, 0, 0, __LINE__); } bbr->r_ctl.rc_bbr_state_atflight = max(cts, 1); bbr_log_exit_gain(bbr, cts, 3); } } else { /* Its a gain */ if (bbr->r_ctl.rc_lost > bbr->r_ctl.bbr_lost_at_state) { bbr->r_ctl.rc_bbr_state_atflight = max(cts, 1); goto change_state; } if ((ctf_outstanding(bbr->rc_tp) >= bbr->r_ctl.rc_target_at_state) || ((ctf_outstanding(bbr->rc_tp) + bbr->rc_tp->t_maxseg - 1) >= bbr->rc_tp->snd_wnd)) { bbr->r_ctl.rc_bbr_state_atflight = max(cts, 1); bbr_log_exit_gain(bbr, cts, 2); } } /** * We fall through and return always one of two things has * occurred. * 1) We are still not at target * * 2) We reached the target and set rc_bbr_state_atflight * which means we no longer hit this block * next time we are called. */ return; } change_state: if (TSTMP_LT(cts, bbr->r_ctl.rc_bbr_state_time)) return; if ((cts - bbr->r_ctl.rc_bbr_state_time) < bbr_cur_cycle_time) { /* Less than a full time-period has passed */ return; } if (bbr->r_ctl.rc_level_state_extra && (bbr_state_val(bbr) > BBR_SUB_DRAIN) && ((cts - bbr->r_ctl.rc_bbr_state_time) < (bbr_cur_cycle_time + bbr->r_ctl.rc_level_state_extra))) { /* Less than a full time-period + extra has passed */ return; } if (bbr_gain_gets_extra_too && bbr->r_ctl.rc_level_state_extra && (bbr_state_val(bbr) == BBR_SUB_GAIN) && ((cts - bbr->r_ctl.rc_bbr_state_time) < (bbr_cur_cycle_time + bbr->r_ctl.rc_level_state_extra))) { /* Less than a full time-period + extra has passed */ return; } bbr_substate_change(bbr, cts, __LINE__, 1); } static uint32_t bbr_get_a_state_target(struct tcp_bbr *bbr, uint32_t gain) { uint32_t mss, tar; if (bbr->rc_use_google) { /* Google just uses the cwnd target */ tar = bbr_get_target_cwnd(bbr, bbr_get_bw(bbr), gain); } else { mss = min((bbr->rc_tp->t_maxseg - bbr->rc_last_options), bbr->r_ctl.rc_pace_max_segs); /* Get the base cwnd with gain rounded to a mss */ tar = roundup(bbr_get_raw_target_cwnd(bbr, bbr_get_bw(bbr), gain), mss); /* Make sure it is within our min */ if (tar < get_min_cwnd(bbr)) return (get_min_cwnd(bbr)); } return (tar); } static void bbr_set_state_target(struct tcp_bbr *bbr, int line) { uint32_t tar, meth; if ((bbr->rc_bbr_state == BBR_STATE_PROBE_RTT) && ((bbr->r_ctl.bbr_rttprobe_gain_val == 0) || bbr->rc_use_google)) { /* Special case using old probe-rtt method */ tar = bbr_rtt_probe_cwndtarg * (bbr->rc_tp->t_maxseg - bbr->rc_last_options); meth = 1; } else { /* Non-probe-rtt case and reduced probe-rtt */ if ((bbr->rc_bbr_state == BBR_STATE_PROBE_BW) && (bbr->r_ctl.rc_bbr_hptsi_gain > BBR_UNIT)) { /* For gain cycle we use the hptsi gain */ tar = bbr_get_a_state_target(bbr, bbr->r_ctl.rc_bbr_hptsi_gain); meth = 2; } else if ((bbr_target_is_bbunit) || bbr->rc_use_google) { /* * If configured, or for google all other states * get BBR_UNIT. */ tar = bbr_get_a_state_target(bbr, BBR_UNIT); meth = 3; } else { /* * Or we set a target based on the pacing gain * for non-google mode and default (non-configured). * Note we don't set a target goal below drain (192). */ if (bbr->r_ctl.rc_bbr_hptsi_gain < bbr_hptsi_gain[BBR_SUB_DRAIN]) { tar = bbr_get_a_state_target(bbr, bbr_hptsi_gain[BBR_SUB_DRAIN]); meth = 4; } else { tar = bbr_get_a_state_target(bbr, bbr->r_ctl.rc_bbr_hptsi_gain); meth = 5; } } } bbr_log_set_of_state_target(bbr, tar, line, meth); bbr->r_ctl.rc_target_at_state = tar; } static void bbr_enter_probe_rtt(struct tcp_bbr *bbr, uint32_t cts, int32_t line) { /* Change to probe_rtt */ uint32_t time_in; bbr->r_ctl.bbr_lost_at_state = bbr->r_ctl.rc_lost; bbr->r_ctl.flightsize_at_drain = ctf_flight_size(bbr->rc_tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); bbr->r_ctl.r_app_limited_until = (bbr->r_ctl.flightsize_at_drain + bbr->r_ctl.rc_delivered); /* Setup so we force feed the filter */ if (bbr->rc_use_google || bbr_probertt_sets_rtt) bbr->rc_prtt_set_ts = 1; if (SEQ_GT(cts, bbr->r_ctl.rc_bbr_state_time)) { time_in = cts - bbr->r_ctl.rc_bbr_state_time; counter_u64_add(bbr_state_time[bbr->rc_bbr_state], time_in); } bbr_log_rtt_shrinks(bbr, cts, 0, 0, __LINE__, BBR_RTTS_ENTERPROBE, 0); bbr->r_ctl.rc_rtt_shrinks = cts; bbr->r_ctl.last_in_probertt = cts; bbr->r_ctl.rc_probertt_srttchktim = cts; bbr->r_ctl.rc_bbr_state_time = cts; bbr->rc_bbr_state = BBR_STATE_PROBE_RTT; /* We need to force the filter to update */ if ((bbr_sub_drain_slam_cwnd) && bbr->rc_hit_state_1 && (bbr->rc_use_google == 0) && (bbr_state_val(bbr) == BBR_SUB_DRAIN)) { if (bbr->rc_tp->snd_cwnd > bbr->r_ctl.rc_saved_cwnd) bbr->r_ctl.rc_saved_cwnd = bbr->rc_tp->snd_cwnd; } else bbr->r_ctl.rc_saved_cwnd = bbr->rc_tp->snd_cwnd; /* Update the lost */ bbr->r_ctl.rc_lost_at_startup = bbr->r_ctl.rc_lost; if ((bbr->r_ctl.bbr_rttprobe_gain_val == 0) || bbr->rc_use_google){ /* Set to the non-configurable default of 4 (PROBE_RTT_MIN) */ bbr->rc_tp->snd_cwnd = bbr_rtt_probe_cwndtarg * (bbr->rc_tp->t_maxseg - bbr->rc_last_options); bbr_log_type_cwndupd(bbr, 0, 0, 0, 12, 0, 0, __LINE__); bbr->r_ctl.rc_bbr_hptsi_gain = BBR_UNIT; bbr->r_ctl.rc_bbr_cwnd_gain = BBR_UNIT; bbr_log_set_of_state_target(bbr, bbr->rc_tp->snd_cwnd, __LINE__, 6); bbr->r_ctl.rc_target_at_state = bbr->rc_tp->snd_cwnd; } else { /* * We bring it down slowly by using a hptsi gain that is * probably 75%. This will slowly float down our outstanding * without tampering with the cwnd. */ bbr->r_ctl.rc_bbr_hptsi_gain = bbr->r_ctl.bbr_rttprobe_gain_val; bbr->r_ctl.rc_bbr_cwnd_gain = BBR_UNIT; bbr_set_state_target(bbr, __LINE__); if (bbr_prtt_slam_cwnd && (bbr->rc_tp->snd_cwnd > bbr->r_ctl.rc_target_at_state)) { bbr->rc_tp->snd_cwnd = bbr->r_ctl.rc_target_at_state; bbr_log_type_cwndupd(bbr, 0, 0, 0, 12, 0, 0, __LINE__); } } if (ctf_flight_size(bbr->rc_tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)) <= bbr->r_ctl.rc_target_at_state) { /* We are at target */ bbr->r_ctl.rc_bbr_enters_probertt = cts; } else { /* We need to come down to reach target before our time begins */ bbr->r_ctl.rc_bbr_enters_probertt = 0; } bbr->r_ctl.rc_pe_of_prtt = bbr->r_ctl.rc_pkt_epoch; BBR_STAT_INC(bbr_enter_probertt); bbr_log_exit_gain(bbr, cts, 0); bbr_log_type_statechange(bbr, cts, line); } static void bbr_check_probe_rtt_limits(struct tcp_bbr *bbr, uint32_t cts) { /* * Sanity check on probe-rtt intervals. * In crazy situations where we are competing * against new-reno flows with huge buffers * our rtt-prop interval could come to dominate * things if we can't get through a full set * of cycles, we need to adjust it. */ if (bbr_can_adjust_probertt && (bbr->rc_use_google == 0)) { uint16_t val = 0; uint32_t cur_rttp, fval, newval, baseval; /* Are we to small and go into probe-rtt to often? */ baseval = (bbr_get_rtt(bbr, BBR_RTT_PROP) * (BBR_SUBSTATE_COUNT + 1)); cur_rttp = roundup(baseval, USECS_IN_SECOND); fval = bbr_filter_len_sec * USECS_IN_SECOND; if (bbr_is_ratio == 0) { if (fval > bbr_rtt_probe_limit) newval = cur_rttp + (fval - bbr_rtt_probe_limit); else newval = cur_rttp; } else { int mul; mul = fval / bbr_rtt_probe_limit; newval = cur_rttp * mul; } if (cur_rttp > bbr->r_ctl.rc_probertt_int) { bbr->r_ctl.rc_probertt_int = cur_rttp; reset_time_small(&bbr->r_ctl.rc_rttprop, newval); val = 1; } else { /* * No adjustments were made * do we need to shrink it? */ if (bbr->r_ctl.rc_probertt_int > bbr_rtt_probe_limit) { if (cur_rttp <= bbr_rtt_probe_limit) { /* * Things have calmed down lets * shrink all the way to default */ bbr->r_ctl.rc_probertt_int = bbr_rtt_probe_limit; reset_time_small(&bbr->r_ctl.rc_rttprop, (bbr_filter_len_sec * USECS_IN_SECOND)); cur_rttp = bbr_rtt_probe_limit; newval = (bbr_filter_len_sec * USECS_IN_SECOND); val = 2; } else { /* * Well does some adjustment make sense? */ if (cur_rttp < bbr->r_ctl.rc_probertt_int) { /* We can reduce interval time some */ bbr->r_ctl.rc_probertt_int = cur_rttp; reset_time_small(&bbr->r_ctl.rc_rttprop, newval); val = 3; } } } } if (val) bbr_log_rtt_shrinks(bbr, cts, cur_rttp, newval, __LINE__, BBR_RTTS_RESETS_VALUES, val); } } static void bbr_exit_probe_rtt(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts) { /* Exit probe-rtt */ if (tp->snd_cwnd < bbr->r_ctl.rc_saved_cwnd) { tp->snd_cwnd = bbr->r_ctl.rc_saved_cwnd; bbr_log_type_cwndupd(bbr, 0, 0, 0, 12, 0, 0, __LINE__); } bbr_log_exit_gain(bbr, cts, 1); bbr->rc_hit_state_1 = 0; bbr->r_ctl.rc_rtt_shrinks = cts; bbr->r_ctl.last_in_probertt = cts; bbr_log_rtt_shrinks(bbr, cts, 0, 0, __LINE__, BBR_RTTS_RTTPROBE, 0); bbr->r_ctl.bbr_lost_at_state = bbr->r_ctl.rc_lost; bbr->r_ctl.r_app_limited_until = (ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)) + bbr->r_ctl.rc_delivered); if (SEQ_GT(cts, bbr->r_ctl.rc_bbr_state_time)) { uint32_t time_in; time_in = cts - bbr->r_ctl.rc_bbr_state_time; counter_u64_add(bbr_state_time[bbr->rc_bbr_state], time_in); } if (bbr->rc_filled_pipe) { /* Switch to probe_bw */ bbr->rc_bbr_state = BBR_STATE_PROBE_BW; bbr->rc_bbr_substate = bbr_pick_probebw_substate(bbr, cts); bbr->r_ctl.rc_bbr_cwnd_gain = bbr_cwnd_gain; bbr_substate_change(bbr, cts, __LINE__, 0); bbr_log_type_statechange(bbr, cts, __LINE__); } else { /* Back to startup */ bbr->rc_bbr_state = BBR_STATE_STARTUP; bbr->r_ctl.rc_bbr_state_time = cts; /* * We don't want to give a complete free 3 * measurements until we exit, so we use * the number of pe's we were in probe-rtt * to add to the startup_epoch. That way * we will still retain the old state. */ bbr->r_ctl.rc_bbr_last_startup_epoch += (bbr->r_ctl.rc_pkt_epoch - bbr->r_ctl.rc_pe_of_prtt); bbr->r_ctl.rc_lost_at_startup = bbr->r_ctl.rc_lost; /* Make sure to use the lower pg when shifting back in */ if (bbr->r_ctl.rc_lost && bbr_use_lower_gain_in_startup && (bbr->rc_use_google == 0)) bbr->r_ctl.rc_bbr_hptsi_gain = bbr_startup_lower; else bbr->r_ctl.rc_bbr_hptsi_gain = bbr->r_ctl.rc_startup_pg; bbr->r_ctl.rc_bbr_cwnd_gain = bbr->r_ctl.rc_startup_pg; /* Probably not needed but set it anyway */ bbr_set_state_target(bbr, __LINE__); bbr_log_type_statechange(bbr, cts, __LINE__); bbr_log_startup_event(bbr, cts, bbr->r_ctl.rc_bbr_last_startup_epoch, bbr->r_ctl.rc_lost_at_startup, bbr_start_exit, 0); } bbr_check_probe_rtt_limits(bbr, cts); } static int32_t inline bbr_should_enter_probe_rtt(struct tcp_bbr *bbr, uint32_t cts) { if ((bbr->rc_past_init_win == 1) && (bbr->rc_in_persist == 0) && (bbr_calc_time(cts, bbr->r_ctl.rc_rtt_shrinks) >= bbr->r_ctl.rc_probertt_int)) { return (1); } if (bbr_can_force_probertt && (bbr->rc_in_persist == 0) && (TSTMP_GT(cts, bbr->r_ctl.last_in_probertt)) && ((cts - bbr->r_ctl.last_in_probertt) > bbr->r_ctl.rc_probertt_int)) { return (1); } return (0); } static int32_t bbr_google_startup(struct tcp_bbr *bbr, uint32_t cts, int32_t pkt_epoch) { uint64_t btlbw, gain; if (pkt_epoch == 0) { /* * Need to be on a pkt-epoch to continue. */ return (0); } btlbw = bbr_get_full_bw(bbr); gain = ((bbr->r_ctl.rc_bbr_lastbtlbw * (uint64_t)bbr_start_exit) / (uint64_t)100) + bbr->r_ctl.rc_bbr_lastbtlbw; if (btlbw >= gain) { bbr->r_ctl.rc_bbr_last_startup_epoch = bbr->r_ctl.rc_pkt_epoch; bbr_log_startup_event(bbr, cts, bbr->r_ctl.rc_bbr_last_startup_epoch, bbr->r_ctl.rc_lost_at_startup, bbr_start_exit, 3); bbr->r_ctl.rc_bbr_lastbtlbw = btlbw; } if ((bbr->r_ctl.rc_pkt_epoch - bbr->r_ctl.rc_bbr_last_startup_epoch) >= BBR_STARTUP_EPOCHS) return (1); bbr_log_startup_event(bbr, cts, bbr->r_ctl.rc_bbr_last_startup_epoch, bbr->r_ctl.rc_lost_at_startup, bbr_start_exit, 8); return(0); } static int32_t inline bbr_state_startup(struct tcp_bbr *bbr, uint32_t cts, int32_t epoch, int32_t pkt_epoch) { /* Have we gained 25% in the last 3 packet based epoch's? */ uint64_t btlbw, gain; int do_exit; int delta, rtt_gain; if ((bbr->rc_tp->snd_una == bbr->rc_tp->snd_max) && (bbr_calc_time(cts, bbr->r_ctl.rc_went_idle_time) >= bbr_rtt_probe_time)) { /* * This qualifies as a RTT_PROBE session since we drop the * data outstanding to nothing and waited more than * bbr_rtt_probe_time. */ bbr_log_rtt_shrinks(bbr, cts, 0, 0, __LINE__, BBR_RTTS_WASIDLE, 0); bbr_set_reduced_rtt(bbr, cts, __LINE__); } if (bbr_should_enter_probe_rtt(bbr, cts)) { bbr_enter_probe_rtt(bbr, cts, __LINE__); return (0); } if (bbr->rc_use_google) return (bbr_google_startup(bbr, cts, pkt_epoch)); if ((bbr->r_ctl.rc_lost > bbr->r_ctl.rc_lost_at_startup) && (bbr_use_lower_gain_in_startup)) { /* Drop to a lower gain 1.5 x since we saw loss */ bbr->r_ctl.rc_bbr_hptsi_gain = bbr_startup_lower; } if (pkt_epoch == 0) { /* * Need to be on a pkt-epoch to continue. */ return (0); } if (bbr_rtt_gain_thresh) { /* * Do we allow a flow to stay * in startup with no loss and no * gain in rtt over a set threshold? */ if (bbr->r_ctl.rc_pkt_epoch_rtt && bbr->r_ctl.startup_last_srtt && (bbr->r_ctl.rc_pkt_epoch_rtt > bbr->r_ctl.startup_last_srtt)) { delta = bbr->r_ctl.rc_pkt_epoch_rtt - bbr->r_ctl.startup_last_srtt; rtt_gain = (delta * 100) / bbr->r_ctl.startup_last_srtt; } else rtt_gain = 0; if ((bbr->r_ctl.startup_last_srtt == 0) || (bbr->r_ctl.rc_pkt_epoch_rtt < bbr->r_ctl.startup_last_srtt)) /* First time or new lower value */ bbr->r_ctl.startup_last_srtt = bbr->r_ctl.rc_pkt_epoch_rtt; if ((bbr->r_ctl.rc_lost == 0) && (rtt_gain < bbr_rtt_gain_thresh)) { /* * No loss, and we are under * our gain threhold for * increasing RTT. */ if (bbr->r_ctl.rc_bbr_last_startup_epoch < bbr->r_ctl.rc_pkt_epoch) bbr->r_ctl.rc_bbr_last_startup_epoch++; bbr_log_startup_event(bbr, cts, rtt_gain, delta, bbr->r_ctl.startup_last_srtt, 10); return (0); } } if ((bbr->r_ctl.r_measurement_count == bbr->r_ctl.last_startup_measure) && (bbr->r_ctl.rc_lost_at_startup == bbr->r_ctl.rc_lost) && (!IN_RECOVERY(bbr->rc_tp->t_flags))) { /* * We only assess if we have a new measurement when * we have no loss and are not in recovery. * Drag up by one our last_startup epoch so we will hold * the number of non-gain we have already accumulated. */ if (bbr->r_ctl.rc_bbr_last_startup_epoch < bbr->r_ctl.rc_pkt_epoch) bbr->r_ctl.rc_bbr_last_startup_epoch++; bbr_log_startup_event(bbr, cts, bbr->r_ctl.rc_bbr_last_startup_epoch, bbr->r_ctl.rc_lost_at_startup, bbr_start_exit, 9); return (0); } /* Case where we reduced the lost (bad retransmit) */ if (bbr->r_ctl.rc_lost_at_startup > bbr->r_ctl.rc_lost) bbr->r_ctl.rc_lost_at_startup = bbr->r_ctl.rc_lost; bbr->r_ctl.last_startup_measure = bbr->r_ctl.r_measurement_count; btlbw = bbr_get_full_bw(bbr); if (bbr->r_ctl.rc_bbr_hptsi_gain == bbr_startup_lower) gain = ((bbr->r_ctl.rc_bbr_lastbtlbw * (uint64_t)bbr_low_start_exit) / (uint64_t)100) + bbr->r_ctl.rc_bbr_lastbtlbw; else gain = ((bbr->r_ctl.rc_bbr_lastbtlbw * (uint64_t)bbr_start_exit) / (uint64_t)100) + bbr->r_ctl.rc_bbr_lastbtlbw; do_exit = 0; if (btlbw > bbr->r_ctl.rc_bbr_lastbtlbw) bbr->r_ctl.rc_bbr_lastbtlbw = btlbw; if (btlbw >= gain) { bbr->r_ctl.rc_bbr_last_startup_epoch = bbr->r_ctl.rc_pkt_epoch; /* Update the lost so we won't exit in next set of tests */ bbr->r_ctl.rc_lost_at_startup = bbr->r_ctl.rc_lost; bbr_log_startup_event(bbr, cts, bbr->r_ctl.rc_bbr_last_startup_epoch, bbr->r_ctl.rc_lost_at_startup, bbr_start_exit, 3); } if ((bbr->rc_loss_exit && (bbr->r_ctl.rc_lost > bbr->r_ctl.rc_lost_at_startup) && (bbr->r_ctl.rc_pkt_epoch_loss_rate > bbr_startup_loss_thresh)) && ((bbr->r_ctl.rc_pkt_epoch - bbr->r_ctl.rc_bbr_last_startup_epoch) >= BBR_STARTUP_EPOCHS)) { /* * If we had no gain, we had loss and that loss was above * our threshould, the rwnd is not constrained, and we have * had at least 3 packet epochs exit. Note that this is * switched off by sysctl. Google does not do this by the * way. */ if ((ctf_flight_size(bbr->rc_tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)) + (2 * max(bbr->r_ctl.rc_pace_max_segs, bbr->rc_tp->t_maxseg))) <= bbr->rc_tp->snd_wnd) { do_exit = 1; bbr_log_startup_event(bbr, cts, bbr->r_ctl.rc_bbr_last_startup_epoch, bbr->r_ctl.rc_lost_at_startup, bbr_start_exit, 4); } else { /* Just record an updated loss value */ bbr->r_ctl.rc_lost_at_startup = bbr->r_ctl.rc_lost; bbr_log_startup_event(bbr, cts, bbr->r_ctl.rc_bbr_last_startup_epoch, bbr->r_ctl.rc_lost_at_startup, bbr_start_exit, 5); } } else bbr->r_ctl.rc_lost_at_startup = bbr->r_ctl.rc_lost; if (((bbr->r_ctl.rc_pkt_epoch - bbr->r_ctl.rc_bbr_last_startup_epoch) >= BBR_STARTUP_EPOCHS) || do_exit) { /* Return 1 to exit the startup state. */ return (1); } /* Stay in startup */ bbr_log_startup_event(bbr, cts, bbr->r_ctl.rc_bbr_last_startup_epoch, bbr->r_ctl.rc_lost_at_startup, bbr_start_exit, 8); return (0); } static void bbr_state_change(struct tcp_bbr *bbr, uint32_t cts, int32_t epoch, int32_t pkt_epoch, uint32_t losses) { /* * A tick occurred in the rtt epoch do we need to do anything? */ #ifdef BBR_INVARIANTS if ((bbr->rc_bbr_state != BBR_STATE_STARTUP) && (bbr->rc_bbr_state != BBR_STATE_DRAIN) && (bbr->rc_bbr_state != BBR_STATE_PROBE_RTT) && (bbr->rc_bbr_state != BBR_STATE_IDLE_EXIT) && (bbr->rc_bbr_state != BBR_STATE_PROBE_BW)) { /* Debug code? */ panic("Unknown BBR state %d?\n", bbr->rc_bbr_state); } #endif if (bbr->rc_bbr_state == BBR_STATE_STARTUP) { /* Do we exit the startup state? */ if (bbr_state_startup(bbr, cts, epoch, pkt_epoch)) { uint32_t time_in; bbr_log_startup_event(bbr, cts, bbr->r_ctl.rc_bbr_last_startup_epoch, bbr->r_ctl.rc_lost_at_startup, bbr_start_exit, 6); bbr->rc_filled_pipe = 1; bbr->r_ctl.bbr_lost_at_state = bbr->r_ctl.rc_lost; if (SEQ_GT(cts, bbr->r_ctl.rc_bbr_state_time)) { time_in = cts - bbr->r_ctl.rc_bbr_state_time; counter_u64_add(bbr_state_time[bbr->rc_bbr_state], time_in); } else time_in = 0; if (bbr->rc_no_pacing) bbr->rc_no_pacing = 0; bbr->r_ctl.rc_bbr_state_time = cts; bbr->r_ctl.rc_bbr_hptsi_gain = bbr->r_ctl.rc_drain_pg; bbr->rc_bbr_state = BBR_STATE_DRAIN; bbr_set_state_target(bbr, __LINE__); if ((bbr->rc_use_google == 0) && bbr_slam_cwnd_in_main_drain) { /* Here we don't have to worry about probe-rtt */ bbr->r_ctl.rc_saved_cwnd = bbr->rc_tp->snd_cwnd; bbr->rc_tp->snd_cwnd = bbr->r_ctl.rc_target_at_state; bbr_log_type_cwndupd(bbr, 0, 0, 0, 12, 0, 0, __LINE__); } bbr->r_ctl.rc_bbr_cwnd_gain = bbr_high_gain; bbr_log_type_statechange(bbr, cts, __LINE__); if (ctf_flight_size(bbr->rc_tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)) <= bbr->r_ctl.rc_target_at_state) { /* * Switch to probe_bw if we are already * there */ bbr->rc_bbr_substate = bbr_pick_probebw_substate(bbr, cts); bbr_substate_change(bbr, cts, __LINE__, 0); bbr->rc_bbr_state = BBR_STATE_PROBE_BW; bbr_log_type_statechange(bbr, cts, __LINE__); } } } else if (bbr->rc_bbr_state == BBR_STATE_IDLE_EXIT) { uint32_t inflight; struct tcpcb *tp; tp = bbr->rc_tp; inflight = ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); if (inflight >= bbr->r_ctl.rc_target_at_state) { /* We have reached a flight of the cwnd target */ bbr->rc_bbr_state = BBR_STATE_PROBE_BW; bbr->r_ctl.rc_bbr_hptsi_gain = BBR_UNIT; bbr->r_ctl.rc_bbr_cwnd_gain = BBR_UNIT; bbr_set_state_target(bbr, __LINE__); /* * Rig it so we don't do anything crazy and * start fresh with a new randomization. */ bbr->r_ctl.bbr_smallest_srtt_this_state = 0xffffffff; bbr->rc_bbr_substate = BBR_SUB_LEVEL6; bbr_substate_change(bbr, cts, __LINE__, 1); } } else if (bbr->rc_bbr_state == BBR_STATE_DRAIN) { /* Has in-flight reached the bdp (or less)? */ uint32_t inflight; struct tcpcb *tp; tp = bbr->rc_tp; inflight = ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); if ((bbr->rc_use_google == 0) && bbr_slam_cwnd_in_main_drain && (bbr->rc_tp->snd_cwnd > bbr->r_ctl.rc_target_at_state)) { /* * Here we don't have to worry about probe-rtt * re-slam it, but keep it slammed down. */ bbr->rc_tp->snd_cwnd = bbr->r_ctl.rc_target_at_state; bbr_log_type_cwndupd(bbr, 0, 0, 0, 12, 0, 0, __LINE__); } if (inflight <= bbr->r_ctl.rc_target_at_state) { /* We have drained */ bbr->rc_bbr_state = BBR_STATE_PROBE_BW; bbr->r_ctl.bbr_lost_at_state = bbr->r_ctl.rc_lost; if (SEQ_GT(cts, bbr->r_ctl.rc_bbr_state_time)) { uint32_t time_in; time_in = cts - bbr->r_ctl.rc_bbr_state_time; counter_u64_add(bbr_state_time[bbr->rc_bbr_state], time_in); } if ((bbr->rc_use_google == 0) && bbr_slam_cwnd_in_main_drain && (tp->snd_cwnd < bbr->r_ctl.rc_saved_cwnd)) { /* Restore the cwnd */ tp->snd_cwnd = bbr->r_ctl.rc_saved_cwnd; bbr_log_type_cwndupd(bbr, 0, 0, 0, 12, 0, 0, __LINE__); } /* Setup probe-rtt has being done now RRS-HERE */ bbr->r_ctl.rc_rtt_shrinks = cts; bbr->r_ctl.last_in_probertt = cts; bbr_log_rtt_shrinks(bbr, cts, 0, 0, __LINE__, BBR_RTTS_LEAVE_DRAIN, 0); /* Randomly pick a sub-state */ bbr->rc_bbr_substate = bbr_pick_probebw_substate(bbr, cts); bbr_substate_change(bbr, cts, __LINE__, 0); bbr_log_type_statechange(bbr, cts, __LINE__); } } else if (bbr->rc_bbr_state == BBR_STATE_PROBE_RTT) { uint32_t flight; flight = ctf_flight_size(bbr->rc_tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); bbr->r_ctl.r_app_limited_until = (flight + bbr->r_ctl.rc_delivered); if (((bbr->r_ctl.bbr_rttprobe_gain_val == 0) || bbr->rc_use_google) && (bbr->rc_tp->snd_cwnd > bbr->r_ctl.rc_target_at_state)) { /* * We must keep cwnd at the desired MSS. */ bbr->rc_tp->snd_cwnd = bbr_rtt_probe_cwndtarg * (bbr->rc_tp->t_maxseg - bbr->rc_last_options); bbr_log_type_cwndupd(bbr, 0, 0, 0, 12, 0, 0, __LINE__); } else if ((bbr_prtt_slam_cwnd) && (bbr->rc_tp->snd_cwnd > bbr->r_ctl.rc_target_at_state)) { /* Re-slam it */ bbr->rc_tp->snd_cwnd = bbr->r_ctl.rc_target_at_state; bbr_log_type_cwndupd(bbr, 0, 0, 0, 12, 0, 0, __LINE__); } if (bbr->r_ctl.rc_bbr_enters_probertt == 0) { /* Has outstanding reached our target? */ if (flight <= bbr->r_ctl.rc_target_at_state) { bbr_log_rtt_shrinks(bbr, cts, 0, 0, __LINE__, BBR_RTTS_REACHTAR, 0); bbr->r_ctl.rc_bbr_enters_probertt = cts; /* If time is exactly 0, be 1usec off */ if (bbr->r_ctl.rc_bbr_enters_probertt == 0) bbr->r_ctl.rc_bbr_enters_probertt = 1; if (bbr->rc_use_google == 0) { /* * Restore any lowering that as occurred to * reach here */ if (bbr->r_ctl.bbr_rttprobe_gain_val) bbr->r_ctl.rc_bbr_hptsi_gain = bbr->r_ctl.bbr_rttprobe_gain_val; else bbr->r_ctl.rc_bbr_hptsi_gain = BBR_UNIT; } } if ((bbr->r_ctl.rc_bbr_enters_probertt == 0) && (bbr->rc_use_google == 0) && bbr->r_ctl.bbr_rttprobe_gain_val && (((cts - bbr->r_ctl.rc_probertt_srttchktim) > bbr_get_rtt(bbr, bbr_drain_rtt)) || (flight >= bbr->r_ctl.flightsize_at_drain))) { /* * We have doddled with our current hptsi * gain an srtt and have still not made it * to target, or we have increased our flight. * Lets reduce the gain by xx% * flooring the reduce at DRAIN (based on * mul/div) */ int red; bbr->r_ctl.flightsize_at_drain = flight; bbr->r_ctl.rc_probertt_srttchktim = cts; red = max((bbr->r_ctl.bbr_rttprobe_gain_val / 10), 1); if ((bbr->r_ctl.rc_bbr_hptsi_gain - red) > max(bbr_drain_floor, 1)) { /* Reduce our gain again */ bbr->r_ctl.rc_bbr_hptsi_gain -= red; bbr_log_rtt_shrinks(bbr, cts, 0, 0, __LINE__, BBR_RTTS_SHRINK_PG, 0); } else if (bbr->r_ctl.rc_bbr_hptsi_gain > max(bbr_drain_floor, 1)) { /* one more chance before we give up */ bbr->r_ctl.rc_bbr_hptsi_gain = max(bbr_drain_floor, 1); bbr_log_rtt_shrinks(bbr, cts, 0, 0, __LINE__, BBR_RTTS_SHRINK_PG_FINAL, 0); } else { /* At the very bottom */ bbr->r_ctl.rc_bbr_hptsi_gain = max((bbr_drain_floor-1), 1); } } } if (bbr->r_ctl.rc_bbr_enters_probertt && (TSTMP_GT(cts, bbr->r_ctl.rc_bbr_enters_probertt)) && ((cts - bbr->r_ctl.rc_bbr_enters_probertt) >= bbr_rtt_probe_time)) { /* Time to exit probe RTT normally */ bbr_exit_probe_rtt(bbr->rc_tp, bbr, cts); } } else if (bbr->rc_bbr_state == BBR_STATE_PROBE_BW) { if ((bbr->rc_tp->snd_una == bbr->rc_tp->snd_max) && (bbr_calc_time(cts, bbr->r_ctl.rc_went_idle_time) >= bbr_rtt_probe_time)) { /* * This qualifies as a RTT_PROBE session since we * drop the data outstanding to nothing and waited * more than bbr_rtt_probe_time. */ bbr_log_rtt_shrinks(bbr, cts, 0, 0, __LINE__, BBR_RTTS_WASIDLE, 0); bbr_set_reduced_rtt(bbr, cts, __LINE__); } if (bbr_should_enter_probe_rtt(bbr, cts)) { bbr_enter_probe_rtt(bbr, cts, __LINE__); } else { bbr_set_probebw_gains(bbr, cts, losses); } } } static void bbr_check_bbr_for_state(struct tcp_bbr *bbr, uint32_t cts, int32_t line, uint32_t losses) { int32_t epoch = 0; if ((cts - bbr->r_ctl.rc_rcv_epoch_start) >= bbr_get_rtt(bbr, BBR_RTT_PROP)) { bbr_set_epoch(bbr, cts, line); /* At each epoch doe lt bw sampling */ epoch = 1; } bbr_state_change(bbr, cts, epoch, bbr->rc_is_pkt_epoch_now, losses); } static int bbr_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, uint8_t iptos, int32_t nxt_pkt, struct timeval *tv) { struct inpcb *inp = tptoinpcb(tp); int32_t thflags, retval; uint32_t cts, lcts; uint32_t tiwin; struct tcpopt to; struct tcp_bbr *bbr; struct bbr_sendmap *rsm; struct timeval ltv; int32_t did_out = 0; uint16_t nsegs; int32_t prev_state; uint32_t lost; nsegs = max(1, m->m_pkthdr.lro_nsegs); bbr = (struct tcp_bbr *)tp->t_fb_ptr; /* add in our stats */ kern_prefetch(bbr, &prev_state); prev_state = 0; thflags = tcp_get_flags(th); /* * If this is either a state-changing packet or current state isn't * established, we require a write lock on tcbinfo. Otherwise, we * allow the tcbinfo to be in either alocked or unlocked, as the * caller may have unnecessarily acquired a write lock due to a * race. */ INP_WLOCK_ASSERT(tptoinpcb(tp)); KASSERT(tp->t_state > TCPS_LISTEN, ("%s: TCPS_LISTEN", __func__)); KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT", __func__)); tp->t_rcvtime = ticks; /* * Unscale the window into a 32-bit value. For the SYN_SENT state * the scale is zero. */ tiwin = th->th_win << tp->snd_scale; #ifdef STATS stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_FRWIN, tiwin); #endif if (m->m_flags & M_TSTMP) { /* Prefer the hardware timestamp if present */ struct timespec ts; mbuf_tstmp2timespec(m, &ts); bbr->rc_tv.tv_sec = ts.tv_sec; bbr->rc_tv.tv_usec = ts.tv_nsec / 1000; bbr->r_ctl.rc_rcvtime = cts = tcp_tv_to_usectick(&bbr->rc_tv); } else if (m->m_flags & M_TSTMP_LRO) { /* Next the arrival timestamp */ struct timespec ts; mbuf_tstmp2timespec(m, &ts); bbr->rc_tv.tv_sec = ts.tv_sec; bbr->rc_tv.tv_usec = ts.tv_nsec / 1000; bbr->r_ctl.rc_rcvtime = cts = tcp_tv_to_usectick(&bbr->rc_tv); } else { /* * Ok just get the current time. */ bbr->r_ctl.rc_rcvtime = lcts = cts = tcp_get_usecs(&bbr->rc_tv); } /* * Parse options on any incoming segment. */ tcp_dooptions(&to, (u_char *)(th + 1), (th->th_off << 2) - sizeof(struct tcphdr), (thflags & TH_SYN) ? TO_SYN : 0); /* * If timestamps were negotiated during SYN/ACK and a * segment without a timestamp is received, silently drop * the segment, unless it is a RST segment or missing timestamps are * tolerated. * See section 3.2 of RFC 7323. */ if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS) && ((thflags & TH_RST) == 0) && (V_tcp_tolerate_missing_ts == 0)) { retval = 0; m_freem(m); goto done_with_input; } /* * If echoed timestamp is later than the current time, fall back to * non RFC1323 RTT calculation. Normalize timestamp if syncookies * were used when this connection was established. */ if ((to.to_flags & TOF_TS) && (to.to_tsecr != 0)) { to.to_tsecr -= tp->ts_offset; if (TSTMP_GT(to.to_tsecr, tcp_tv_to_mssectick(&bbr->rc_tv))) to.to_tsecr = 0; } /* * If its the first time in we need to take care of options and * verify we can do SACK for rack! */ if (bbr->r_state == 0) { /* * Process options only when we get SYN/ACK back. The SYN * case for incoming connections is handled in tcp_syncache. * According to RFC1323 the window field in a SYN (i.e., a * or ) segment itself is never scaled. XXX * this is traditional behavior, may need to be cleaned up. */ if (bbr->rc_inp == NULL) { bbr->rc_inp = inp; } /* * We need to init rc_inp here since its not init'd when * bbr_init is called */ if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) { if ((to.to_flags & TOF_SCALE) && (tp->t_flags & TF_REQ_SCALE)) { tp->t_flags |= TF_RCVD_SCALE; tp->snd_scale = to.to_wscale; } else tp->t_flags &= ~TF_REQ_SCALE; /* * Initial send window. It will be updated with the * next incoming segment to the scaled value. */ tp->snd_wnd = th->th_win; if ((to.to_flags & TOF_TS) && (tp->t_flags & TF_REQ_TSTMP)) { tp->t_flags |= TF_RCVD_TSTMP; tp->ts_recent = to.to_tsval; tp->ts_recent_age = tcp_tv_to_mssectick(&bbr->rc_tv); } else tp->t_flags &= ~TF_REQ_TSTMP; if (to.to_flags & TOF_MSS) tcp_mss(tp, to.to_mss); if ((tp->t_flags & TF_SACK_PERMIT) && (to.to_flags & TOF_SACKPERM) == 0) tp->t_flags &= ~TF_SACK_PERMIT; if (IS_FASTOPEN(tp->t_flags)) { if (to.to_flags & TOF_FASTOPEN) { uint16_t mss; if (to.to_flags & TOF_MSS) mss = to.to_mss; else if ((inp->inp_vflag & INP_IPV6) != 0) mss = TCP6_MSS; else mss = TCP_MSS; tcp_fastopen_update_cache(tp, mss, to.to_tfo_len, to.to_tfo_cookie); } else tcp_fastopen_disable_path(tp); } } /* * At this point we are at the initial call. Here we decide * if we are doing RACK or not. We do this by seeing if * TF_SACK_PERMIT is set, if not rack is *not* possible and * we switch to the default code. */ if ((tp->t_flags & TF_SACK_PERMIT) == 0) { /* Bail */ tcp_switch_back_to_default(tp); (*tp->t_fb->tfb_tcp_do_segment) (m, th, so, tp, drop_hdrlen, tlen, iptos); return (1); } /* Set the flag */ bbr->r_is_v6 = (inp->inp_vflag & INP_IPV6) != 0; tcp_set_hpts(inp); sack_filter_clear(&bbr->r_ctl.bbr_sf, th->th_ack); } if (thflags & TH_ACK) { /* Track ack types */ if (to.to_flags & TOF_SACK) BBR_STAT_INC(bbr_acks_with_sacks); else BBR_STAT_INC(bbr_plain_acks); } /* * This is the one exception case where we set the rack state * always. All other times (timers etc) we must have a rack-state * set (so we assure we have done the checks above for SACK). */ if (thflags & TH_FIN) tcp_log_end_status(tp, TCP_EI_STATUS_CLIENT_FIN); if (bbr->r_state != tp->t_state) bbr_set_state(tp, bbr, tiwin); if (SEQ_GT(th->th_ack, tp->snd_una) && (rsm = TAILQ_FIRST(&bbr->r_ctl.rc_map)) != NULL) kern_prefetch(rsm, &prev_state); prev_state = bbr->r_state; bbr->rc_ack_was_delayed = 0; lost = bbr->r_ctl.rc_lost; bbr->rc_is_pkt_epoch_now = 0; if (m->m_flags & (M_TSTMP|M_TSTMP_LRO)) { /* Get the real time into lcts and figure the real delay */ lcts = tcp_get_usecs(<v); if (TSTMP_GT(lcts, cts)) { bbr->r_ctl.rc_ack_hdwr_delay = lcts - cts; bbr->rc_ack_was_delayed = 1; if (TSTMP_GT(bbr->r_ctl.rc_ack_hdwr_delay, bbr->r_ctl.highest_hdwr_delay)) bbr->r_ctl.highest_hdwr_delay = bbr->r_ctl.rc_ack_hdwr_delay; } else { bbr->r_ctl.rc_ack_hdwr_delay = 0; bbr->rc_ack_was_delayed = 0; } } else { bbr->r_ctl.rc_ack_hdwr_delay = 0; bbr->rc_ack_was_delayed = 0; } bbr_log_ack_event(bbr, th, &to, tlen, nsegs, cts, nxt_pkt, m); if ((thflags & TH_SYN) && (thflags & TH_FIN) && V_drop_synfin) { retval = 0; m_freem(m); goto done_with_input; } /* * If a segment with the ACK-bit set arrives in the SYN-SENT state * check SEQ.ACK first as described on page 66 of RFC 793, section 3.9. */ if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) && (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } if (tiwin > bbr->r_ctl.rc_high_rwnd) bbr->r_ctl.rc_high_rwnd = tiwin; bbr->r_ctl.rc_flight_at_input = ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); bbr->rtt_valid = 0; if (to.to_flags & TOF_TS) { bbr->rc_ts_valid = 1; bbr->r_ctl.last_inbound_ts = to.to_tsval; } else { bbr->rc_ts_valid = 0; bbr->r_ctl.last_inbound_ts = 0; } retval = (*bbr->r_substate) (m, th, so, tp, &to, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt, iptos); if (nxt_pkt == 0) BBR_STAT_INC(bbr_rlock_left_ret0); else BBR_STAT_INC(bbr_rlock_left_ret1); if (retval == 0) { /* * If retval is 1 the tcb is unlocked and most likely the tp * is gone. */ INP_WLOCK_ASSERT(inp); tcp_bbr_xmit_timer_commit(bbr, tp, cts); if (bbr->rc_is_pkt_epoch_now) bbr_set_pktepoch(bbr, cts, __LINE__); bbr_check_bbr_for_state(bbr, cts, __LINE__, (bbr->r_ctl.rc_lost - lost)); if (nxt_pkt == 0) { if (bbr->r_wanted_output != 0) { bbr->rc_output_starts_timer = 0; did_out = 1; if (tcp_output(tp) < 0) return (1); } else bbr_start_hpts_timer(bbr, tp, cts, 6, 0, 0); } if ((nxt_pkt == 0) && ((bbr->r_ctl.rc_hpts_flags & PACE_TMR_MASK) == 0) && (SEQ_GT(tp->snd_max, tp->snd_una) || (tp->t_flags & TF_DELACK) || ((V_tcp_always_keepalive || bbr->rc_inp->inp_socket->so_options & SO_KEEPALIVE) && (tp->t_state <= TCPS_CLOSING)))) { /* * We could not send (probably in the hpts but * stopped the timer)? */ if ((tp->snd_max == tp->snd_una) && ((tp->t_flags & TF_DELACK) == 0) && (tcp_in_hpts(bbr->rc_inp)) && (bbr->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT)) { /* * keep alive not needed if we are hptsi * output yet */ ; } else { if (tcp_in_hpts(bbr->rc_inp)) { tcp_hpts_remove(bbr->rc_inp); if ((bbr->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) && (TSTMP_GT(lcts, bbr->rc_pacer_started))) { uint32_t del; del = lcts - bbr->rc_pacer_started; if (bbr->r_ctl.rc_last_delay_val > del) { BBR_STAT_INC(bbr_force_timer_start); bbr->r_ctl.rc_last_delay_val -= del; bbr->rc_pacer_started = lcts; } else { /* We are late */ bbr->r_ctl.rc_last_delay_val = 0; BBR_STAT_INC(bbr_force_output); if (tcp_output(tp) < 0) return (1); } } } bbr_start_hpts_timer(bbr, tp, cts, 8, bbr->r_ctl.rc_last_delay_val, 0); } } else if ((bbr->rc_output_starts_timer == 0) && (nxt_pkt == 0)) { /* Do we have the correct timer running? */ bbr_timer_audit(tp, bbr, lcts, &so->so_snd); } /* Do we have a new state */ if (bbr->r_state != tp->t_state) bbr_set_state(tp, bbr, tiwin); done_with_input: bbr_log_doseg_done(bbr, cts, nxt_pkt, did_out); if (did_out) bbr->r_wanted_output = 0; } return (retval); } static void bbr_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, uint8_t iptos) { struct timeval tv; int retval; /* First lets see if we have old packets */ if (tp->t_in_pkt) { if (ctf_do_queued_segments(so, tp, 1)) { m_freem(m); return; } } if (m->m_flags & M_TSTMP_LRO) { mbuf_tstmp2timeval(m, &tv); } else { /* Should not be should we kassert instead? */ tcp_get_usecs(&tv); } retval = bbr_do_segment_nounlock(m, th, so, tp, drop_hdrlen, tlen, iptos, 0, &tv); if (retval == 0) { INP_WUNLOCK(tptoinpcb(tp)); } } /* * Return how much data can be sent without violating the * cwnd or rwnd. */ static inline uint32_t bbr_what_can_we_send(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t sendwin, uint32_t avail, int32_t sb_offset, uint32_t cts) { uint32_t len; if (ctf_outstanding(tp) >= tp->snd_wnd) { /* We never want to go over our peers rcv-window */ len = 0; } else { uint32_t flight; flight = ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)); if (flight >= sendwin) { /* * We have in flight what we are allowed by cwnd (if * it was rwnd blocking it would have hit above out * >= tp->snd_wnd). */ return (0); } len = sendwin - flight; if ((len + ctf_outstanding(tp)) > tp->snd_wnd) { /* We would send too much (beyond the rwnd) */ len = tp->snd_wnd - ctf_outstanding(tp); } if ((len + sb_offset) > avail) { /* * We don't have that much in the SB, how much is * there? */ len = avail - sb_offset; } } return (len); } static inline void bbr_do_error_accounting(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, int32_t len, int32_t error) { #ifdef NETFLIX_STATS KMOD_TCPSTAT_INC(tcps_sndpack_error); KMOD_TCPSTAT_ADD(tcps_sndbyte_error, len); #endif } static inline void bbr_do_send_accounting(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, int32_t len, int32_t error) { if (error) { bbr_do_error_accounting(tp, bbr, rsm, len, error); return; } if (rsm) { if (rsm->r_flags & BBR_TLP) { /* * TLP should not count in retran count, but in its * own bin */ #ifdef NETFLIX_STATS KMOD_TCPSTAT_INC(tcps_tlpresends); KMOD_TCPSTAT_ADD(tcps_tlpresend_bytes, len); #endif } else { /* Retransmit */ tp->t_sndrexmitpack++; KMOD_TCPSTAT_INC(tcps_sndrexmitpack); KMOD_TCPSTAT_ADD(tcps_sndrexmitbyte, len); #ifdef STATS stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RETXPB, len); #endif } /* * Logs in 0 - 8, 8 is all non probe_bw states 0-7 is * sub-state */ counter_u64_add(bbr_state_lost[rsm->r_bbr_state], len); if (bbr->rc_bbr_state != BBR_STATE_PROBE_BW) { /* Non probe_bw log in 1, 2, or 4. */ counter_u64_add(bbr_state_resend[bbr->rc_bbr_state], len); } else { /* * Log our probe state 3, and log also 5-13 to show * us the recovery sub-state for the send. This * means that 3 == (5+6+7+8+9+10+11+12+13) */ counter_u64_add(bbr_state_resend[BBR_STATE_PROBE_BW], len); counter_u64_add(bbr_state_resend[(bbr_state_val(bbr) + 5)], len); } /* Place in both 16's the totals of retransmitted */ counter_u64_add(bbr_state_lost[16], len); counter_u64_add(bbr_state_resend[16], len); /* Place in 17's the total sent */ counter_u64_add(bbr_state_resend[17], len); counter_u64_add(bbr_state_lost[17], len); } else { /* New sends */ KMOD_TCPSTAT_INC(tcps_sndpack); KMOD_TCPSTAT_ADD(tcps_sndbyte, len); /* Place in 17's the total sent */ counter_u64_add(bbr_state_resend[17], len); counter_u64_add(bbr_state_lost[17], len); #ifdef STATS stats_voi_update_abs_u64(tp->t_stats, VOI_TCP_TXPB, len); #endif } } static void bbr_cwnd_limiting(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t in_level) { if (bbr->rc_filled_pipe && bbr_target_cwnd_mult_limit && (bbr->rc_use_google == 0)) { /* * Limit the cwnd to not be above N x the target plus whats * is outstanding. The target is based on the current b/w * estimate. */ uint32_t target; target = bbr_get_target_cwnd(bbr, bbr_get_bw(bbr), BBR_UNIT); target += ctf_outstanding(tp); target *= bbr_target_cwnd_mult_limit; if (tp->snd_cwnd > target) tp->snd_cwnd = target; bbr_log_type_cwndupd(bbr, 0, 0, 0, 10, 0, 0, __LINE__); } } static int bbr_window_update_needed(struct tcpcb *tp, struct socket *so, uint32_t recwin, int32_t maxseg) { /* * "adv" is the amount we could increase the window, taking into * account that we are limited by TCP_MAXWIN << tp->rcv_scale. */ int32_t adv; int32_t oldwin; adv = recwin; if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) { oldwin = (tp->rcv_adv - tp->rcv_nxt); if (adv > oldwin) adv -= oldwin; else { /* We can't increase the window */ adv = 0; } } else oldwin = 0; /* * If the new window size ends up being the same as or less * than the old size when it is scaled, then don't force * a window update. */ if (oldwin >> tp->rcv_scale >= (adv + oldwin) >> tp->rcv_scale) return (0); if (adv >= (2 * maxseg) && (adv >= (so->so_rcv.sb_hiwat / 4) || recwin <= (so->so_rcv.sb_hiwat / 8) || so->so_rcv.sb_hiwat <= 8 * maxseg)) { return (1); } if (2 * adv >= (int32_t) so->so_rcv.sb_hiwat) return (1); return (0); } /* * Return 0 on success and a errno on failure to send. * Note that a 0 return may not mean we sent anything * if the TCB was on the hpts. A non-zero return * does indicate the error we got from ip[6]_output. */ static int bbr_output_wtime(struct tcpcb *tp, const struct timeval *tv) { struct socket *so; int32_t len; uint32_t cts; uint32_t recwin, sendwin; int32_t sb_offset; int32_t flags, abandon, error = 0; struct tcp_log_buffer *lgb = NULL; struct mbuf *m; struct mbuf *mb; uint32_t if_hw_tsomaxsegcount = 0; uint32_t if_hw_tsomaxsegsize = 0; uint32_t if_hw_tsomax = 0; struct ip *ip = NULL; -#ifdef TCPDEBUG - struct ipovly *ipov = NULL; -#endif struct tcp_bbr *bbr; struct tcphdr *th; struct udphdr *udp = NULL; u_char opt[TCP_MAXOLEN]; unsigned ipoptlen, optlen, hdrlen; unsigned ulen; uint32_t bbr_seq; uint32_t delay_calc=0; uint8_t doing_tlp = 0; uint8_t local_options; #ifdef BBR_INVARIANTS uint8_t doing_retran_from = 0; uint8_t picked_up_retran = 0; #endif uint8_t wanted_cookie = 0; uint8_t more_to_rxt=0; int32_t prefetch_so_done = 0; int32_t prefetch_rsm = 0; uint32_t tot_len = 0; uint32_t maxseg, pace_max_segs, p_maxseg; int32_t csum_flags = 0; int32_t hw_tls; #if defined(IPSEC) || defined(IPSEC_SUPPORT) unsigned ipsec_optlen = 0; #endif volatile int32_t sack_rxmit; struct bbr_sendmap *rsm = NULL; int32_t tso, mtu; struct tcpopt to; int32_t slot = 0; struct inpcb *inp; struct sockbuf *sb; uint32_t hpts_calling; #ifdef INET6 struct ip6_hdr *ip6 = NULL; int32_t isipv6; #endif uint8_t app_limited = BBR_JR_SENT_DATA; uint8_t filled_all = 0; bbr = (struct tcp_bbr *)tp->t_fb_ptr; /* We take a cache hit here */ memcpy(&bbr->rc_tv, tv, sizeof(struct timeval)); cts = tcp_tv_to_usectick(&bbr->rc_tv); inp = bbr->rc_inp; so = inp->inp_socket; sb = &so->so_snd; if (sb->sb_flags & SB_TLS_IFNET) hw_tls = 1; else hw_tls = 0; kern_prefetch(sb, &maxseg); maxseg = tp->t_maxseg - bbr->rc_last_options; if (bbr_minseg(bbr) < maxseg) { tcp_bbr_tso_size_check(bbr, cts); } /* Remove any flags that indicate we are pacing on the inp */ pace_max_segs = bbr->r_ctl.rc_pace_max_segs; p_maxseg = min(maxseg, pace_max_segs); INP_WLOCK_ASSERT(inp); #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) return (tcp_offload_output(tp)); #endif #ifdef INET6 if (bbr->r_state) { /* Use the cache line loaded if possible */ isipv6 = bbr->r_is_v6; } else { isipv6 = (inp->inp_vflag & INP_IPV6) != 0; } #endif if (((bbr->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) == 0) && tcp_in_hpts(inp)) { /* * We are on the hpts for some timer but not hptsi output. * Possibly remove from the hpts so we can send/recv etc. */ if ((tp->t_flags & TF_ACKNOW) == 0) { /* * No immediate demand right now to send an ack, but * the user may have read, making room for new data * (a window update). If so we may want to cancel * whatever timer is running (KEEP/DEL-ACK?) and * continue to send out a window update. Or we may * have gotten more data into the socket buffer to * send. */ recwin = lmin(lmax(sbspace(&so->so_rcv), 0), (long)TCP_MAXWIN << tp->rcv_scale); if ((bbr_window_update_needed(tp, so, recwin, maxseg) == 0) && ((tcp_outflags[tp->t_state] & TH_RST) == 0) && ((sbavail(sb) + ((tcp_outflags[tp->t_state] & TH_FIN) ? 1 : 0)) <= (tp->snd_max - tp->snd_una))) { /* * Nothing new to send and no window update * is needed to send. Lets just return and * let the timer-run off. */ return (0); } } tcp_hpts_remove(inp); bbr_timer_cancel(bbr, __LINE__, cts); } if (bbr->r_ctl.rc_last_delay_val) { /* Calculate a rough delay for early escape to sending */ if (SEQ_GT(cts, bbr->rc_pacer_started)) delay_calc = cts - bbr->rc_pacer_started; if (delay_calc >= bbr->r_ctl.rc_last_delay_val) delay_calc -= bbr->r_ctl.rc_last_delay_val; else delay_calc = 0; } /* Mark that we have called bbr_output(). */ if ((bbr->r_timer_override) || (tp->t_state < TCPS_ESTABLISHED)) { /* Timeouts or early states are exempt */ if (tcp_in_hpts(inp)) tcp_hpts_remove(inp); } else if (tcp_in_hpts(inp)) { if ((bbr->r_ctl.rc_last_delay_val) && (bbr->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) && delay_calc) { /* * We were being paced for output and the delay has * already exceeded when we were supposed to be * called, lets go ahead and pull out of the hpts * and call output. */ counter_u64_add(bbr_out_size[TCP_MSS_ACCT_LATE], 1); bbr->r_ctl.rc_last_delay_val = 0; tcp_hpts_remove(inp); } else if (tp->t_state == TCPS_CLOSED) { bbr->r_ctl.rc_last_delay_val = 0; tcp_hpts_remove(inp); } else { /* * On the hpts, you shall not pass! even if ACKNOW * is on, we will when the hpts fires, unless of * course we are overdue. */ counter_u64_add(bbr_out_size[TCP_MSS_ACCT_INPACE], 1); return (0); } } bbr->rc_cwnd_limited = 0; if (bbr->r_ctl.rc_last_delay_val) { /* recalculate the real delay and deal with over/under */ if (SEQ_GT(cts, bbr->rc_pacer_started)) delay_calc = cts - bbr->rc_pacer_started; else delay_calc = 0; if (delay_calc >= bbr->r_ctl.rc_last_delay_val) /* Setup the delay which will be added in */ delay_calc -= bbr->r_ctl.rc_last_delay_val; else { /* * We are early setup to adjust * our slot time. */ uint64_t merged_val; bbr->r_ctl.rc_agg_early += (bbr->r_ctl.rc_last_delay_val - delay_calc); bbr->r_agg_early_set = 1; if (bbr->r_ctl.rc_hptsi_agg_delay) { if (bbr->r_ctl.rc_hptsi_agg_delay >= bbr->r_ctl.rc_agg_early) { /* Nope our previous late cancels out the early */ bbr->r_ctl.rc_hptsi_agg_delay -= bbr->r_ctl.rc_agg_early; bbr->r_agg_early_set = 0; bbr->r_ctl.rc_agg_early = 0; } else { bbr->r_ctl.rc_agg_early -= bbr->r_ctl.rc_hptsi_agg_delay; bbr->r_ctl.rc_hptsi_agg_delay = 0; } } merged_val = bbr->rc_pacer_started; merged_val <<= 32; merged_val |= bbr->r_ctl.rc_last_delay_val; bbr_log_pacing_delay_calc(bbr, inp->inp_hpts_calls, bbr->r_ctl.rc_agg_early, cts, delay_calc, merged_val, bbr->r_agg_early_set, 3); bbr->r_ctl.rc_last_delay_val = 0; BBR_STAT_INC(bbr_early); delay_calc = 0; } } else { /* We were not delayed due to hptsi */ if (bbr->r_agg_early_set) bbr->r_ctl.rc_agg_early = 0; bbr->r_agg_early_set = 0; delay_calc = 0; } if (delay_calc) { /* * We had a hptsi delay which means we are falling behind on * sending at the expected rate. Calculate an extra amount * of data we can send, if any, to put us back on track. */ if ((bbr->r_ctl.rc_hptsi_agg_delay + delay_calc) < bbr->r_ctl.rc_hptsi_agg_delay) bbr->r_ctl.rc_hptsi_agg_delay = 0xffffffff; else bbr->r_ctl.rc_hptsi_agg_delay += delay_calc; } sendwin = min(tp->snd_wnd, tp->snd_cwnd); if ((tp->snd_una == tp->snd_max) && (bbr->rc_bbr_state != BBR_STATE_IDLE_EXIT) && (sbavail(sb))) { /* * Ok we have been idle with nothing outstanding * we possibly need to start fresh with either a new * suite of states or a fast-ramp up. */ bbr_restart_after_idle(bbr, cts, bbr_calc_time(cts, bbr->r_ctl.rc_went_idle_time)); } /* * Now was there a hptsi delay where we are behind? We only count * being behind if: a) We are not in recovery. b) There was a delay. * c) We had room to send something. * */ hpts_calling = inp->inp_hpts_calls; inp->inp_hpts_calls = 0; if (bbr->r_ctl.rc_hpts_flags & PACE_TMR_MASK) { int retval; retval = bbr_process_timers(tp, bbr, cts, hpts_calling); if (retval != 0) { counter_u64_add(bbr_out_size[TCP_MSS_ACCT_ATIMER], 1); /* * If timers want tcp_drop(), then pass error out, * otherwise suppress it. */ return (retval < 0 ? retval : 0); } } bbr->rc_inp->inp_flags2 &= ~INP_MBUF_QUEUE_READY; if (hpts_calling && (bbr->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT)) { bbr->r_ctl.rc_last_delay_val = 0; } bbr->r_timer_override = 0; bbr->r_wanted_output = 0; /* * For TFO connections in SYN_RECEIVED, only allow the initial * SYN|ACK and those sent by the retransmit timer. */ if (IS_FASTOPEN(tp->t_flags) && ((tp->t_state == TCPS_SYN_RECEIVED) || (tp->t_state == TCPS_SYN_SENT)) && SEQ_GT(tp->snd_max, tp->snd_una) && /* initial SYN or SYN|ACK sent */ (tp->t_rxtshift == 0)) { /* not a retransmit */ len = 0; goto just_return_nolock; } /* * Before sending anything check for a state update. For hpts * calling without input this is important. If its input calling * then this was already done. */ if (bbr->rc_use_google == 0) bbr_check_bbr_for_state(bbr, cts, __LINE__, 0); again: /* * If we've recently taken a timeout, snd_max will be greater than * snd_max. BBR in general does not pay much attention to snd_nxt * for historic reasons the persist timer still uses it. This means * we have to look at it. All retransmissions that are not persits * use the rsm that needs to be sent so snd_nxt is ignored. At the * end of this routine we pull snd_nxt always up to snd_max. */ doing_tlp = 0; #ifdef BBR_INVARIANTS doing_retran_from = picked_up_retran = 0; #endif error = 0; tso = 0; slot = 0; mtu = 0; sendwin = min(tp->snd_wnd, tp->snd_cwnd); sb_offset = tp->snd_max - tp->snd_una; flags = tcp_outflags[tp->t_state]; sack_rxmit = 0; len = 0; rsm = NULL; if (flags & TH_RST) { SOCKBUF_LOCK(sb); goto send; } recheck_resend: while (bbr->r_ctl.rc_free_cnt < bbr_min_req_free) { /* We need to always have one in reserve */ rsm = bbr_alloc(bbr); if (rsm == NULL) { error = ENOMEM; /* Lie to get on the hpts */ tot_len = tp->t_maxseg; if (hpts_calling) /* Retry in a ms */ slot = 1001; goto just_return_nolock; } TAILQ_INSERT_TAIL(&bbr->r_ctl.rc_free, rsm, r_next); bbr->r_ctl.rc_free_cnt++; rsm = NULL; } /* What do we send, a resend? */ if (bbr->r_ctl.rc_resend == NULL) { /* Check for rack timeout */ bbr->r_ctl.rc_resend = bbr_check_recovery_mode(tp, bbr, cts); if (bbr->r_ctl.rc_resend) { #ifdef BBR_INVARIANTS picked_up_retran = 1; #endif bbr_cong_signal(tp, NULL, CC_NDUPACK, bbr->r_ctl.rc_resend); } } if (bbr->r_ctl.rc_resend) { rsm = bbr->r_ctl.rc_resend; #ifdef BBR_INVARIANTS doing_retran_from = 1; #endif /* Remove any TLP flags its a RACK or T-O */ rsm->r_flags &= ~BBR_TLP; bbr->r_ctl.rc_resend = NULL; if (SEQ_LT(rsm->r_start, tp->snd_una)) { #ifdef BBR_INVARIANTS panic("Huh, tp:%p bbr:%p rsm:%p start:%u < snd_una:%u\n", tp, bbr, rsm, rsm->r_start, tp->snd_una); goto recheck_resend; #else /* TSNH */ rsm = NULL; goto recheck_resend; #endif } if (rsm->r_flags & BBR_HAS_SYN) { /* Only retransmit a SYN by itself */ len = 0; if ((flags & TH_SYN) == 0) { /* Huh something is wrong */ rsm->r_start++; if (rsm->r_start == rsm->r_end) { /* Clean it up, somehow we missed the ack? */ bbr_log_syn(tp, NULL); } else { /* TFO with data? */ rsm->r_flags &= ~BBR_HAS_SYN; len = rsm->r_end - rsm->r_start; } } else { /* Retransmitting SYN */ rsm = NULL; SOCKBUF_LOCK(sb); goto send; } } else len = rsm->r_end - rsm->r_start; if ((bbr->rc_resends_use_tso == 0) && (len > maxseg)) { len = maxseg; more_to_rxt = 1; } sb_offset = rsm->r_start - tp->snd_una; if (len > 0) { sack_rxmit = 1; KMOD_TCPSTAT_INC(tcps_sack_rexmits); KMOD_TCPSTAT_ADD(tcps_sack_rexmit_bytes, min(len, maxseg)); } else { /* I dont think this can happen */ rsm = NULL; goto recheck_resend; } BBR_STAT_INC(bbr_resends_set); } else if (bbr->r_ctl.rc_tlp_send) { /* * Tail loss probe */ doing_tlp = 1; rsm = bbr->r_ctl.rc_tlp_send; bbr->r_ctl.rc_tlp_send = NULL; sack_rxmit = 1; len = rsm->r_end - rsm->r_start; if ((bbr->rc_resends_use_tso == 0) && (len > maxseg)) len = maxseg; if (SEQ_GT(tp->snd_una, rsm->r_start)) { #ifdef BBR_INVARIANTS panic("tp:%p bbc:%p snd_una:%u rsm:%p r_start:%u", tp, bbr, tp->snd_una, rsm, rsm->r_start); #else /* TSNH */ rsm = NULL; goto recheck_resend; #endif } sb_offset = rsm->r_start - tp->snd_una; BBR_STAT_INC(bbr_tlp_set); } /* * Enforce a connection sendmap count limit if set * as long as we are not retransmiting. */ if ((rsm == NULL) && (V_tcp_map_entries_limit > 0) && (bbr->r_ctl.rc_num_maps_alloced >= V_tcp_map_entries_limit)) { BBR_STAT_INC(bbr_alloc_limited); if (!bbr->alloc_limit_reported) { bbr->alloc_limit_reported = 1; BBR_STAT_INC(bbr_alloc_limited_conns); } goto just_return_nolock; } #ifdef BBR_INVARIANTS if (rsm && SEQ_LT(rsm->r_start, tp->snd_una)) { panic("tp:%p bbr:%p rsm:%p sb_offset:%u len:%u", tp, bbr, rsm, sb_offset, len); } #endif /* * Get standard flags, and add SYN or FIN if requested by 'hidden' * state flags. */ if (tp->t_flags & TF_NEEDFIN && (rsm == NULL)) flags |= TH_FIN; if (tp->t_flags & TF_NEEDSYN) flags |= TH_SYN; if (rsm && (rsm->r_flags & BBR_HAS_FIN)) { /* we are retransmitting the fin */ len--; if (len) { /* * When retransmitting data do *not* include the * FIN. This could happen from a TLP probe if we * allowed data with a FIN. */ flags &= ~TH_FIN; } } else if (rsm) { if (flags & TH_FIN) flags &= ~TH_FIN; } if ((sack_rxmit == 0) && (prefetch_rsm == 0)) { void *end_rsm; end_rsm = TAILQ_LAST_FAST(&bbr->r_ctl.rc_tmap, bbr_sendmap, r_tnext); if (end_rsm) kern_prefetch(end_rsm, &prefetch_rsm); prefetch_rsm = 1; } SOCKBUF_LOCK(sb); /* * If snd_nxt == snd_max and we have transmitted a FIN, the * sb_offset will be > 0 even if so_snd.sb_cc is 0, resulting in a * negative length. This can also occur when TCP opens up its * congestion window while receiving additional duplicate acks after * fast-retransmit because TCP will reset snd_nxt to snd_max after * the fast-retransmit. * * In the normal retransmit-FIN-only case, however, snd_nxt will be * set to snd_una, the sb_offset will be 0, and the length may wind * up 0. * * If sack_rxmit is true we are retransmitting from the scoreboard * in which case len is already set. */ if (sack_rxmit == 0) { uint32_t avail; avail = sbavail(sb); if (SEQ_GT(tp->snd_max, tp->snd_una)) sb_offset = tp->snd_max - tp->snd_una; else sb_offset = 0; if (bbr->rc_tlp_new_data) { /* TLP is forcing out new data */ uint32_t tlplen; doing_tlp = 1; tlplen = maxseg; if (tlplen > (uint32_t)(avail - sb_offset)) { tlplen = (uint32_t)(avail - sb_offset); } if (tlplen > tp->snd_wnd) { len = tp->snd_wnd; } else { len = tlplen; } bbr->rc_tlp_new_data = 0; } else { len = bbr_what_can_we_send(tp, bbr, sendwin, avail, sb_offset, cts); if ((len < p_maxseg) && (bbr->rc_in_persist == 0) && (ctf_outstanding(tp) >= (2 * p_maxseg)) && ((avail - sb_offset) >= p_maxseg)) { /* * We are not completing whats in the socket * buffer (i.e. there is at least a segment * waiting to send) and we have 2 or more * segments outstanding. There is no sense * of sending a little piece. Lets defer and * and wait until we can send a whole * segment. */ len = 0; } if (bbr->rc_in_persist) { /* * We are in persists, figure out if * a retransmit is available (maybe the previous * persists we sent) or if we have to send new * data. */ rsm = TAILQ_FIRST(&bbr->r_ctl.rc_map); if (rsm) { len = rsm->r_end - rsm->r_start; if (rsm->r_flags & BBR_HAS_FIN) len--; if ((bbr->rc_resends_use_tso == 0) && (len > maxseg)) len = maxseg; if (len > 1) BBR_STAT_INC(bbr_persist_reneg); /* * XXXrrs we could force the len to * 1 byte here to cause the chunk to * split apart.. but that would then * mean we always retransmit it as * one byte even after the window * opens. */ sack_rxmit = 1; sb_offset = rsm->r_start - tp->snd_una; } else { /* * First time through in persists or peer * acked our one byte. Though we do have * to have something in the sb. */ len = 1; sb_offset = 0; if (avail == 0) len = 0; } } } } if (prefetch_so_done == 0) { kern_prefetch(so, &prefetch_so_done); prefetch_so_done = 1; } /* * Lop off SYN bit if it has already been sent. However, if this is * SYN-SENT state and if segment contains data and if we don't know * that foreign host supports TAO, suppress sending segment. */ if ((flags & TH_SYN) && (rsm == NULL) && SEQ_GT(tp->snd_max, tp->snd_una)) { if (tp->t_state != TCPS_SYN_RECEIVED) flags &= ~TH_SYN; /* * When sending additional segments following a TFO SYN|ACK, * do not include the SYN bit. */ if (IS_FASTOPEN(tp->t_flags) && (tp->t_state == TCPS_SYN_RECEIVED)) flags &= ~TH_SYN; sb_offset--, len++; if (sbavail(sb) == 0) len = 0; } else if ((flags & TH_SYN) && rsm) { /* * Subtract one from the len for the SYN being * retransmitted. */ len--; } /* * Be careful not to send data and/or FIN on SYN segments. This * measure is needed to prevent interoperability problems with not * fully conformant TCP implementations. */ if ((flags & TH_SYN) && (tp->t_flags & TF_NOOPT)) { len = 0; flags &= ~TH_FIN; } /* * On TFO sockets, ensure no data is sent in the following cases: * * - When retransmitting SYN|ACK on a passively-created socket * - When retransmitting SYN on an actively created socket * - When sending a zero-length cookie (cookie request) on an * actively created socket * - When the socket is in the CLOSED state (RST is being sent) */ if (IS_FASTOPEN(tp->t_flags) && (((flags & TH_SYN) && (tp->t_rxtshift > 0)) || ((tp->t_state == TCPS_SYN_SENT) && (tp->t_tfo_client_cookie_len == 0)) || (flags & TH_RST))) { len = 0; sack_rxmit = 0; rsm = NULL; } /* Without fast-open there should never be data sent on a SYN */ if ((flags & TH_SYN) && (!IS_FASTOPEN(tp->t_flags))) len = 0; if (len <= 0) { /* * If FIN has been sent but not acked, but we haven't been * called to retransmit, len will be < 0. Otherwise, window * shrank after we sent into it. If window shrank to 0, * cancel pending retransmit, pull snd_nxt back to (closed) * window, and set the persist timer if it isn't already * going. If the window didn't close completely, just wait * for an ACK. * * We also do a general check here to ensure that we will * set the persist timer when we have data to send, but a * 0-byte window. This makes sure the persist timer is set * even if the packet hits one of the "goto send" lines * below. */ len = 0; if ((tp->snd_wnd == 0) && (TCPS_HAVEESTABLISHED(tp->t_state)) && (tp->snd_una == tp->snd_max) && (sb_offset < (int)sbavail(sb))) { /* * Not enough room in the rwnd to send * a paced segment out. */ bbr_enter_persist(tp, bbr, cts, __LINE__); } } else if ((rsm == NULL) && (doing_tlp == 0) && (len < bbr->r_ctl.rc_pace_max_segs)) { /* * We are not sending a full segment for * some reason. Should we not send anything (think * sws or persists)? */ if ((tp->snd_wnd < min((bbr->r_ctl.rc_high_rwnd/2), bbr_minseg(bbr))) && (TCPS_HAVEESTABLISHED(tp->t_state)) && (len < (int)(sbavail(sb) - sb_offset))) { /* * Here the rwnd is less than * the pacing size, this is not a retransmit, * we are established and * the send is not the last in the socket buffer * lets not send, and possibly enter persists. */ len = 0; if (tp->snd_max == tp->snd_una) bbr_enter_persist(tp, bbr, cts, __LINE__); } else if ((tp->snd_cwnd >= bbr->r_ctl.rc_pace_max_segs) && (ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)) > (2 * maxseg)) && (len < (int)(sbavail(sb) - sb_offset)) && (len < bbr_minseg(bbr))) { /* * Here we are not retransmitting, and * the cwnd is not so small that we could * not send at least a min size (rxt timer * not having gone off), We have 2 segments or * more already in flight, its not the tail end * of the socket buffer and the cwnd is blocking * us from sending out minimum pacing segment size. * Lets not send anything. */ bbr->rc_cwnd_limited = 1; len = 0; } else if (((tp->snd_wnd - ctf_outstanding(tp)) < min((bbr->r_ctl.rc_high_rwnd/2), bbr_minseg(bbr))) && (ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)) > (2 * maxseg)) && (len < (int)(sbavail(sb) - sb_offset)) && (TCPS_HAVEESTABLISHED(tp->t_state))) { /* * Here we have a send window but we have * filled it up and we can't send another pacing segment. * We also have in flight more than 2 segments * and we are not completing the sb i.e. we allow * the last bytes of the sb to go out even if * its not a full pacing segment. */ len = 0; } } /* len will be >= 0 after this point. */ KASSERT(len >= 0, ("[%s:%d]: len < 0", __func__, __LINE__)); tcp_sndbuf_autoscale(tp, so, sendwin); /* * */ if (bbr->rc_in_persist && len && (rsm == NULL) && (len < min((bbr->r_ctl.rc_high_rwnd/2), bbr->r_ctl.rc_pace_max_segs))) { /* * We are in persist, not doing a retransmit and don't have enough space * yet to send a full TSO. So is it at the end of the sb * if so we need to send else nuke to 0 and don't send. */ int sbleft; if (sbavail(sb) > sb_offset) sbleft = sbavail(sb) - sb_offset; else sbleft = 0; if (sbleft >= min((bbr->r_ctl.rc_high_rwnd/2), bbr->r_ctl.rc_pace_max_segs)) { /* not at end of sb lets not send */ len = 0; } } /* * Decide if we can use TCP Segmentation Offloading (if supported by * hardware). * * TSO may only be used if we are in a pure bulk sending state. The * presence of TCP-MD5, SACK retransmits, SACK advertizements and IP * options prevent using TSO. With TSO the TCP header is the same * (except for the sequence number) for all generated packets. This * makes it impossible to transmit any options which vary per * generated segment or packet. * * IPv4 handling has a clear separation of ip options and ip header * flags while IPv6 combines both in in6p_outputopts. ip6_optlen() * does the right thing below to provide length of just ip options * and thus checking for ipoptlen is enough to decide if ip options * are present. */ #ifdef INET6 if (isipv6) ipoptlen = ip6_optlen(inp); else #endif if (inp->inp_options) ipoptlen = inp->inp_options->m_len - offsetof(struct ipoption, ipopt_list); else ipoptlen = 0; #if defined(IPSEC) || defined(IPSEC_SUPPORT) /* * Pre-calculate here as we save another lookup into the darknesses * of IPsec that way and can actually decide if TSO is ok. */ #ifdef INET6 if (isipv6 && IPSEC_ENABLED(ipv6)) ipsec_optlen = IPSEC_HDRSIZE(ipv6, inp); #ifdef INET else #endif #endif /* INET6 */ #ifdef INET if (IPSEC_ENABLED(ipv4)) ipsec_optlen = IPSEC_HDRSIZE(ipv4, inp); #endif /* INET */ #endif /* IPSEC */ #if defined(IPSEC) || defined(IPSEC_SUPPORT) ipoptlen += ipsec_optlen; #endif if ((tp->t_flags & TF_TSO) && V_tcp_do_tso && (len > maxseg) && (tp->t_port == 0) && ((tp->t_flags & TF_SIGNATURE) == 0) && tp->rcv_numsacks == 0 && ipoptlen == 0) tso = 1; recwin = lmin(lmax(sbspace(&so->so_rcv), 0), (long)TCP_MAXWIN << tp->rcv_scale); /* * Sender silly window avoidance. We transmit under the following * conditions when len is non-zero: * * - We have a full segment (or more with TSO) - This is the last * buffer in a write()/send() and we are either idle or running * NODELAY - we've timed out (e.g. persist timer) - we have more * then 1/2 the maximum send window's worth of data (receiver may be * limited the window size) - we need to retransmit */ if (rsm) goto send; if (len) { if (sack_rxmit) goto send; if (len >= p_maxseg) goto send; /* * NOTE! on localhost connections an 'ack' from the remote * end may occur synchronously with the output and cause us * to flush a buffer queued with moretocome. XXX * */ if (((tp->t_flags & TF_MORETOCOME) == 0) && /* normal case */ ((tp->t_flags & TF_NODELAY) || ((uint32_t)len + (uint32_t)sb_offset) >= sbavail(&so->so_snd)) && (tp->t_flags & TF_NOPUSH) == 0) { goto send; } if ((tp->snd_una == tp->snd_max) && len) { /* Nothing outstanding */ goto send; } if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0) { goto send; } } /* * Sending of standalone window updates. * * Window updates are important when we close our window due to a * full socket buffer and are opening it again after the application * reads data from it. Once the window has opened again and the * remote end starts to send again the ACK clock takes over and * provides the most current window information. * * We must avoid the silly window syndrome whereas every read from * the receive buffer, no matter how small, causes a window update * to be sent. We also should avoid sending a flurry of window * updates when the socket buffer had queued a lot of data and the * application is doing small reads. * * Prevent a flurry of pointless window updates by only sending an * update when we can increase the advertized window by more than * 1/4th of the socket buffer capacity. When the buffer is getting * full or is very small be more aggressive and send an update * whenever we can increase by two mss sized segments. In all other * situations the ACK's to new incoming data will carry further * window increases. * * Don't send an independent window update if a delayed ACK is * pending (it will get piggy-backed on it) or the remote side * already has done a half-close and won't send more data. Skip * this if the connection is in T/TCP half-open state. */ if (recwin > 0 && !(tp->t_flags & TF_NEEDSYN) && !(tp->t_flags & TF_DELACK) && !TCPS_HAVERCVDFIN(tp->t_state)) { /* Check to see if we should do a window update */ if (bbr_window_update_needed(tp, so, recwin, maxseg)) goto send; } /* * Send if we owe the peer an ACK, RST, SYN. ACKNOW * is also a catch-all for the retransmit timer timeout case. */ if (tp->t_flags & TF_ACKNOW) { goto send; } if (flags & TH_RST) { /* Always send a RST if one is due */ goto send; } if ((flags & TH_SYN) && (tp->t_flags & TF_NEEDSYN) == 0) { goto send; } /* * If our state indicates that FIN should be sent and we have not * yet done so, then we need to send. */ if (flags & TH_FIN && ((tp->t_flags & TF_SENTFIN) == 0)) { goto send; } /* * No reason to send a segment, just return. */ just_return: SOCKBUF_UNLOCK(sb); just_return_nolock: if (tot_len) slot = bbr_get_pacing_delay(bbr, bbr->r_ctl.rc_bbr_hptsi_gain, tot_len, cts, 0); if (bbr->rc_no_pacing) slot = 0; if (tot_len == 0) { if ((ctf_outstanding(tp) + min((bbr->r_ctl.rc_high_rwnd/2), bbr_minseg(bbr))) >= tp->snd_wnd) { BBR_STAT_INC(bbr_rwnd_limited); app_limited = BBR_JR_RWND_LIMITED; bbr_cwnd_limiting(tp, bbr, ctf_outstanding(tp)); if ((bbr->rc_in_persist == 0) && TCPS_HAVEESTABLISHED(tp->t_state) && (tp->snd_max == tp->snd_una) && sbavail(&so->so_snd)) { /* No send window.. we must enter persist */ bbr_enter_persist(tp, bbr, bbr->r_ctl.rc_rcvtime, __LINE__); } } else if (ctf_outstanding(tp) >= sbavail(sb)) { BBR_STAT_INC(bbr_app_limited); app_limited = BBR_JR_APP_LIMITED; bbr_cwnd_limiting(tp, bbr, ctf_outstanding(tp)); } else if ((ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)) + p_maxseg) >= tp->snd_cwnd) { BBR_STAT_INC(bbr_cwnd_limited); app_limited = BBR_JR_CWND_LIMITED; bbr_cwnd_limiting(tp, bbr, ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes))); bbr->rc_cwnd_limited = 1; } else { BBR_STAT_INC(bbr_app_limited); app_limited = BBR_JR_APP_LIMITED; bbr_cwnd_limiting(tp, bbr, ctf_outstanding(tp)); } bbr->r_ctl.rc_hptsi_agg_delay = 0; bbr->r_agg_early_set = 0; bbr->r_ctl.rc_agg_early = 0; bbr->r_ctl.rc_last_delay_val = 0; } else if (bbr->rc_use_google == 0) bbr_check_bbr_for_state(bbr, cts, __LINE__, 0); /* Are we app limited? */ if ((app_limited == BBR_JR_APP_LIMITED) || (app_limited == BBR_JR_RWND_LIMITED)) { /** * We are application limited. */ bbr->r_ctl.r_app_limited_until = (ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)) + bbr->r_ctl.rc_delivered); } if (tot_len == 0) counter_u64_add(bbr_out_size[TCP_MSS_ACCT_JUSTRET], 1); /* Dont update the time if we did not send */ bbr->r_ctl.rc_last_delay_val = 0; bbr->rc_output_starts_timer = 1; bbr_start_hpts_timer(bbr, tp, cts, 9, slot, tot_len); bbr_log_type_just_return(bbr, cts, tot_len, hpts_calling, app_limited, p_maxseg, len); if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { /* Make sure snd_nxt is drug up */ tp->snd_nxt = tp->snd_max; } return (error); send: if (doing_tlp == 0) { /* * Data not a TLP, and its not the rxt firing. If it is the * rxt firing, we want to leave the tlp_in_progress flag on * so we don't send another TLP. It has to be a rack timer * or normal send (response to acked data) to clear the tlp * in progress flag. */ bbr->rc_tlp_in_progress = 0; bbr->rc_tlp_rtx_out = 0; } else { /* * Its a TLP. */ bbr->rc_tlp_in_progress = 1; } bbr_timer_cancel(bbr, __LINE__, cts); if (rsm == NULL) { if (sbused(sb) > 0) { /* * This is sub-optimal. We only send a stand alone * FIN on its own segment. */ if (flags & TH_FIN) { flags &= ~TH_FIN; if ((len == 0) && ((tp->t_flags & TF_ACKNOW) == 0)) { /* Lets not send this */ slot = 0; goto just_return; } } } } else { /* * We do *not* send a FIN on a retransmit if it has data. * The if clause here where len > 1 should never come true. */ if ((len > 0) && (((rsm->r_flags & BBR_HAS_FIN) == 0) && (flags & TH_FIN))) { flags &= ~TH_FIN; len--; } } SOCKBUF_LOCK_ASSERT(sb); if (len > 0) { if ((tp->snd_una == tp->snd_max) && (bbr_calc_time(cts, bbr->r_ctl.rc_went_idle_time) >= bbr_rtt_probe_time)) { /* * This qualifies as a RTT_PROBE session since we * drop the data outstanding to nothing and waited * more than bbr_rtt_probe_time. */ bbr_log_rtt_shrinks(bbr, cts, 0, 0, __LINE__, BBR_RTTS_WASIDLE, 0); bbr_set_reduced_rtt(bbr, cts, __LINE__); } if (len >= maxseg) tp->t_flags2 |= TF2_PLPMTU_MAXSEGSNT; else tp->t_flags2 &= ~TF2_PLPMTU_MAXSEGSNT; } /* * Before ESTABLISHED, force sending of initial options unless TCP * set not to do any options. NOTE: we assume that the IP/TCP header * plus TCP options always fit in a single mbuf, leaving room for a * maximum link header, i.e. max_linkhdr + sizeof (struct tcpiphdr) * + optlen <= MCLBYTES */ optlen = 0; #ifdef INET6 if (isipv6) hdrlen = sizeof(struct ip6_hdr) + sizeof(struct tcphdr); else #endif hdrlen = sizeof(struct tcpiphdr); /* * Compute options for segment. We only have to care about SYN and * established connection segments. Options for SYN-ACK segments * are handled in TCP syncache. */ to.to_flags = 0; local_options = 0; if ((tp->t_flags & TF_NOOPT) == 0) { /* Maximum segment size. */ if (flags & TH_SYN) { to.to_mss = tcp_mssopt(&inp->inp_inc); if (tp->t_port) to.to_mss -= V_tcp_udp_tunneling_overhead; to.to_flags |= TOF_MSS; /* * On SYN or SYN|ACK transmits on TFO connections, * only include the TFO option if it is not a * retransmit, as the presence of the TFO option may * have caused the original SYN or SYN|ACK to have * been dropped by a middlebox. */ if (IS_FASTOPEN(tp->t_flags) && (tp->t_rxtshift == 0)) { if (tp->t_state == TCPS_SYN_RECEIVED) { to.to_tfo_len = TCP_FASTOPEN_COOKIE_LEN; to.to_tfo_cookie = (u_int8_t *)&tp->t_tfo_cookie.server; to.to_flags |= TOF_FASTOPEN; wanted_cookie = 1; } else if (tp->t_state == TCPS_SYN_SENT) { to.to_tfo_len = tp->t_tfo_client_cookie_len; to.to_tfo_cookie = tp->t_tfo_cookie.client; to.to_flags |= TOF_FASTOPEN; wanted_cookie = 1; } } } /* Window scaling. */ if ((flags & TH_SYN) && (tp->t_flags & TF_REQ_SCALE)) { to.to_wscale = tp->request_r_scale; to.to_flags |= TOF_SCALE; } /* Timestamps. */ if ((tp->t_flags & TF_RCVD_TSTMP) || ((flags & TH_SYN) && (tp->t_flags & TF_REQ_TSTMP))) { to.to_tsval = tcp_tv_to_mssectick(&bbr->rc_tv) + tp->ts_offset; to.to_tsecr = tp->ts_recent; to.to_flags |= TOF_TS; local_options += TCPOLEN_TIMESTAMP + 2; } /* Set receive buffer autosizing timestamp. */ if (tp->rfbuf_ts == 0 && (so->so_rcv.sb_flags & SB_AUTOSIZE)) tp->rfbuf_ts = tcp_tv_to_mssectick(&bbr->rc_tv); /* Selective ACK's. */ if (flags & TH_SYN) to.to_flags |= TOF_SACKPERM; else if (TCPS_HAVEESTABLISHED(tp->t_state) && tp->rcv_numsacks > 0) { to.to_flags |= TOF_SACK; to.to_nsacks = tp->rcv_numsacks; to.to_sacks = (u_char *)tp->sackblks; } #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) /* TCP-MD5 (RFC2385). */ if (tp->t_flags & TF_SIGNATURE) to.to_flags |= TOF_SIGNATURE; #endif /* TCP_SIGNATURE */ /* Processing the options. */ hdrlen += (optlen = tcp_addoptions(&to, opt)); /* * If we wanted a TFO option to be added, but it was unable * to fit, ensure no data is sent. */ if (IS_FASTOPEN(tp->t_flags) && wanted_cookie && !(to.to_flags & TOF_FASTOPEN)) len = 0; } if (tp->t_port) { if (V_tcp_udp_tunneling_port == 0) { /* The port was removed?? */ SOCKBUF_UNLOCK(&so->so_snd); return (EHOSTUNREACH); } hdrlen += sizeof(struct udphdr); } #ifdef INET6 if (isipv6) ipoptlen = ip6_optlen(inp); else #endif if (inp->inp_options) ipoptlen = inp->inp_options->m_len - offsetof(struct ipoption, ipopt_list); else ipoptlen = 0; ipoptlen = 0; #if defined(IPSEC) || defined(IPSEC_SUPPORT) ipoptlen += ipsec_optlen; #endif if (bbr->rc_last_options != local_options) { /* * Cache the options length this generally does not change * on a connection. We use this to calculate TSO. */ bbr->rc_last_options = local_options; } maxseg = tp->t_maxseg - (ipoptlen + optlen); p_maxseg = min(maxseg, pace_max_segs); /* * Adjust data length if insertion of options will bump the packet * length beyond the t_maxseg length. Clear the FIN bit because we * cut off the tail of the segment. */ if (len > maxseg) { if (len != 0 && (flags & TH_FIN)) { flags &= ~TH_FIN; } if (tso) { uint32_t moff; int32_t max_len; /* extract TSO information */ if_hw_tsomax = tp->t_tsomax; if_hw_tsomaxsegcount = tp->t_tsomaxsegcount; if_hw_tsomaxsegsize = tp->t_tsomaxsegsize; KASSERT(ipoptlen == 0, ("%s: TSO can't do IP options", __func__)); /* * Check if we should limit by maximum payload * length: */ if (if_hw_tsomax != 0) { /* compute maximum TSO length */ max_len = (if_hw_tsomax - hdrlen - max_linkhdr); if (max_len <= 0) { len = 0; } else if (len > max_len) { len = max_len; } } /* * Prevent the last segment from being fractional * unless the send sockbuf can be emptied: */ if ((sb_offset + len) < sbavail(sb)) { moff = len % (uint32_t)maxseg; if (moff != 0) { len -= moff; } } /* * In case there are too many small fragments don't * use TSO: */ if (len <= maxseg) { len = maxseg; tso = 0; } } else { /* Not doing TSO */ if (optlen + ipoptlen >= tp->t_maxseg) { /* * Since we don't have enough space to put * the IP header chain and the TCP header in * one packet as required by RFC 7112, don't * send it. Also ensure that at least one * byte of the payload can be put into the * TCP segment. */ SOCKBUF_UNLOCK(&so->so_snd); error = EMSGSIZE; sack_rxmit = 0; goto out; } len = maxseg; } } else { /* Not doing TSO */ if_hw_tsomaxsegcount = 0; tso = 0; } KASSERT(len + hdrlen + ipoptlen <= IP_MAXPACKET, ("%s: len > IP_MAXPACKET", __func__)); #ifdef DIAGNOSTIC #ifdef INET6 if (max_linkhdr + hdrlen > MCLBYTES) #else if (max_linkhdr + hdrlen > MHLEN) #endif panic("tcphdr too big"); #endif /* * This KASSERT is here to catch edge cases at a well defined place. * Before, those had triggered (random) panic conditions further * down. */ #ifdef BBR_INVARIANTS if (sack_rxmit) { if (SEQ_LT(rsm->r_start, tp->snd_una)) { panic("RSM:%p TP:%p bbr:%p start:%u is < snd_una:%u", rsm, tp, bbr, rsm->r_start, tp->snd_una); } } #endif KASSERT(len >= 0, ("[%s:%d]: len < 0", __func__, __LINE__)); if ((len == 0) && (flags & TH_FIN) && (sbused(sb))) { /* * We have outstanding data, don't send a fin by itself!. */ slot = 0; goto just_return; } /* * Grab a header mbuf, attaching a copy of data to be transmitted, * and initialize the header from the template for sends on this * connection. */ if (len) { uint32_t moff; /* * We place a limit on sending with hptsi. */ if ((rsm == NULL) && len > pace_max_segs) len = pace_max_segs; if (len <= maxseg) tso = 0; #ifdef INET6 if (MHLEN < hdrlen + max_linkhdr) m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); else #endif m = m_gethdr(M_NOWAIT, MT_DATA); if (m == NULL) { BBR_STAT_INC(bbr_failed_mbuf_aloc); bbr_log_enobuf_jmp(bbr, len, cts, __LINE__, len, 0, 0); SOCKBUF_UNLOCK(sb); error = ENOBUFS; sack_rxmit = 0; goto out; } m->m_data += max_linkhdr; m->m_len = hdrlen; /* * Start the m_copy functions from the closest mbuf to the * sb_offset in the socket buffer chain. */ if ((sb_offset > sbavail(sb)) || ((len + sb_offset) > sbavail(sb))) { #ifdef BBR_INVARIANTS if ((len + sb_offset) > (sbavail(sb) + ((flags & (TH_FIN | TH_SYN)) ? 1 : 0))) panic("tp:%p bbr:%p len:%u sb_offset:%u sbavail:%u rsm:%p %u:%u:%u", tp, bbr, len, sb_offset, sbavail(sb), rsm, doing_retran_from, picked_up_retran, doing_tlp); #endif /* * In this messed up situation we have two choices, * a) pretend the send worked, and just start timers * and what not (not good since that may lead us * back here a lot). b) Send the lowest segment * in the map. c) Drop the connection. Lets do * which if it continues to happen will lead to * via timeouts. */ BBR_STAT_INC(bbr_offset_recovery); rsm = TAILQ_FIRST(&bbr->r_ctl.rc_map); sb_offset = 0; if (rsm == NULL) { sack_rxmit = 0; len = sbavail(sb); } else { sack_rxmit = 1; if (rsm->r_start != tp->snd_una) { /* * Things are really messed up, * is the only thing to do. */ BBR_STAT_INC(bbr_offset_drop); SOCKBUF_UNLOCK(sb); (void)m_free(m); return (-EFAULT); /* tcp_drop() */ } len = rsm->r_end - rsm->r_start; } if (len > sbavail(sb)) len = sbavail(sb); if (len > maxseg) len = maxseg; } mb = sbsndptr_noadv(sb, sb_offset, &moff); if (len <= MHLEN - hdrlen - max_linkhdr && !hw_tls) { m_copydata(mb, moff, (int)len, mtod(m, caddr_t)+hdrlen); if (rsm == NULL) sbsndptr_adv(sb, mb, len); m->m_len += len; } else { struct sockbuf *msb; if (rsm) msb = NULL; else msb = sb; #ifdef BBR_INVARIANTS if ((len + moff) > (sbavail(sb) + ((flags & (TH_FIN | TH_SYN)) ? 1 : 0))) { if (rsm) { panic("tp:%p bbr:%p len:%u moff:%u sbavail:%u rsm:%p snd_una:%u rsm_start:%u flg:%x %u:%u:%u sr:%d ", tp, bbr, len, moff, sbavail(sb), rsm, tp->snd_una, rsm->r_flags, rsm->r_start, doing_retran_from, picked_up_retran, doing_tlp, sack_rxmit); } else { panic("tp:%p bbr:%p len:%u moff:%u sbavail:%u sb_offset:%u snd_una:%u", tp, bbr, len, moff, sbavail(sb), sb_offset, tp->snd_una); } } #endif m->m_next = tcp_m_copym( mb, moff, &len, if_hw_tsomaxsegcount, if_hw_tsomaxsegsize, msb, ((rsm == NULL) ? hw_tls : 0) #ifdef NETFLIX_COPY_ARGS , &filled_all #endif ); if (len <= maxseg) { /* * Must have ran out of mbufs for the copy * shorten it to no longer need tso. Lets * not put on sendalot since we are low on * mbufs. */ tso = 0; } if (m->m_next == NULL) { SOCKBUF_UNLOCK(sb); (void)m_free(m); error = ENOBUFS; sack_rxmit = 0; goto out; } } #ifdef BBR_INVARIANTS if (tso && len < maxseg) { panic("tp:%p tso on, but len:%d < maxseg:%d", tp, len, maxseg); } if (tso && if_hw_tsomaxsegcount) { int32_t seg_cnt = 0; struct mbuf *foo; foo = m; while (foo) { seg_cnt++; foo = foo->m_next; } if (seg_cnt > if_hw_tsomaxsegcount) { panic("seg_cnt:%d > max:%d", seg_cnt, if_hw_tsomaxsegcount); } } #endif /* * If we're sending everything we've got, set PUSH. (This * will keep happy those implementations which only give * data to the user when a buffer fills or a PUSH comes in.) */ if (sb_offset + len == sbused(sb) && sbused(sb) && !(flags & TH_SYN)) { flags |= TH_PUSH; } SOCKBUF_UNLOCK(sb); } else { SOCKBUF_UNLOCK(sb); if (tp->t_flags & TF_ACKNOW) KMOD_TCPSTAT_INC(tcps_sndacks); else if (flags & (TH_SYN | TH_FIN | TH_RST)) KMOD_TCPSTAT_INC(tcps_sndctrl); else KMOD_TCPSTAT_INC(tcps_sndwinup); m = m_gethdr(M_NOWAIT, MT_DATA); if (m == NULL) { BBR_STAT_INC(bbr_failed_mbuf_aloc); bbr_log_enobuf_jmp(bbr, len, cts, __LINE__, len, 0, 0); error = ENOBUFS; /* Fudge the send time since we could not send */ sack_rxmit = 0; goto out; } #ifdef INET6 if (isipv6 && (MHLEN < hdrlen + max_linkhdr) && MHLEN >= hdrlen) { M_ALIGN(m, hdrlen); } else #endif m->m_data += max_linkhdr; m->m_len = hdrlen; } SOCKBUF_UNLOCK_ASSERT(sb); m->m_pkthdr.rcvif = (struct ifnet *)0; #ifdef MAC mac_inpcb_create_mbuf(inp, m); #endif #ifdef INET6 if (isipv6) { ip6 = mtod(m, struct ip6_hdr *); if (tp->t_port) { udp = (struct udphdr *)((caddr_t)ip6 + sizeof(struct ip6_hdr)); udp->uh_sport = htons(V_tcp_udp_tunneling_port); udp->uh_dport = tp->t_port; ulen = hdrlen + len - sizeof(struct ip6_hdr); udp->uh_ulen = htons(ulen); th = (struct tcphdr *)(udp + 1); } else { th = (struct tcphdr *)(ip6 + 1); } tcpip_fillheaders(inp, tp->t_port, ip6, th); } else #endif /* INET6 */ { ip = mtod(m, struct ip *); -#ifdef TCPDEBUG - ipov = (struct ipovly *)ip; -#endif if (tp->t_port) { udp = (struct udphdr *)((caddr_t)ip + sizeof(struct ip)); udp->uh_sport = htons(V_tcp_udp_tunneling_port); udp->uh_dport = tp->t_port; ulen = hdrlen + len - sizeof(struct ip); udp->uh_ulen = htons(ulen); th = (struct tcphdr *)(udp + 1); } else { th = (struct tcphdr *)(ip + 1); } tcpip_fillheaders(inp, tp->t_port, ip, th); } /* * If we are doing retransmissions, then snd_nxt will not reflect * the first unsent octet. For ACK only packets, we do not want the * sequence number of the retransmitted packet, we want the sequence * number of the next unsent octet. So, if there is no data (and no * SYN or FIN), use snd_max instead of snd_nxt when filling in * ti_seq. But if we are in persist state, snd_max might reflect * one byte beyond the right edge of the window, so use snd_nxt in * that case, since we know we aren't doing a retransmission. * (retransmit and persist are mutually exclusive...) */ if (sack_rxmit == 0) { if (len && ((flags & (TH_FIN | TH_SYN | TH_RST)) == 0)) { /* New data (including new persists) */ th->th_seq = htonl(tp->snd_max); bbr_seq = tp->snd_max; } else if (flags & TH_SYN) { /* Syn's always send from iss */ th->th_seq = htonl(tp->iss); bbr_seq = tp->iss; } else if (flags & TH_FIN) { if (flags & TH_FIN && tp->t_flags & TF_SENTFIN) { /* * If we sent the fin already its 1 minus * snd_max */ th->th_seq = (htonl(tp->snd_max - 1)); bbr_seq = (tp->snd_max - 1); } else { /* First time FIN use snd_max */ th->th_seq = htonl(tp->snd_max); bbr_seq = tp->snd_max; } } else { /* * len == 0 and not persist we use snd_max, sending * an ack unless we have sent the fin then its 1 * minus. */ /* * XXXRRS Question if we are in persists and we have * nothing outstanding to send and we have not sent * a FIN, we will send an ACK. In such a case it * might be better to send (tp->snd_una - 1) which * would force the peer to ack. */ if (tp->t_flags & TF_SENTFIN) { th->th_seq = htonl(tp->snd_max - 1); bbr_seq = (tp->snd_max - 1); } else { th->th_seq = htonl(tp->snd_max); bbr_seq = tp->snd_max; } } } else { /* All retransmits use the rsm to guide the send */ th->th_seq = htonl(rsm->r_start); bbr_seq = rsm->r_start; } th->th_ack = htonl(tp->rcv_nxt); if (optlen) { bcopy(opt, th + 1, optlen); th->th_off = (sizeof(struct tcphdr) + optlen) >> 2; } tcp_set_flags(th, flags); /* * Calculate receive window. Don't shrink window, but avoid silly * window syndrome. */ if ((flags & TH_RST) || ((recwin < (so->so_rcv.sb_hiwat / 4) && recwin < maxseg))) recwin = 0; if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt) && recwin < (tp->rcv_adv - tp->rcv_nxt)) recwin = (tp->rcv_adv - tp->rcv_nxt); if (recwin > TCP_MAXWIN << tp->rcv_scale) recwin = TCP_MAXWIN << tp->rcv_scale; /* * According to RFC1323 the window field in a SYN (i.e., a or * ) segment itself is never scaled. The case is * handled in syncache. */ if (flags & TH_SYN) th->th_win = htons((u_short) (min(sbspace(&so->so_rcv), TCP_MAXWIN))); else { /* Avoid shrinking window with window scaling. */ recwin = roundup2(recwin, 1 << tp->rcv_scale); th->th_win = htons((u_short)(recwin >> tp->rcv_scale)); } /* * Adjust the RXWIN0SENT flag - indicate that we have advertised a 0 * window. This may cause the remote transmitter to stall. This * flag tells soreceive() to disable delayed acknowledgements when * draining the buffer. This can occur if the receiver is * attempting to read more data than can be buffered prior to * transmitting on the connection. */ if (th->th_win == 0) { tp->t_sndzerowin++; tp->t_flags |= TF_RXWIN0SENT; } else tp->t_flags &= ~TF_RXWIN0SENT; /* * We don't support urgent data, but drag along * the pointer in case of a stack switch. */ tp->snd_up = tp->snd_una; #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) if (to.to_flags & TOF_SIGNATURE) { /* * Calculate MD5 signature and put it into the place * determined before. NOTE: since TCP options buffer doesn't * point into mbuf's data, calculate offset and use it. */ if (!TCPMD5_ENABLED() || TCPMD5_OUTPUT(m, th, (u_char *)(th + 1) + (to.to_signature - opt)) != 0) { /* * Do not send segment if the calculation of MD5 * digest has failed. */ goto out; } } #endif /* * Put TCP length in extended header, and then checksum extended * header and data. */ m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */ #ifdef INET6 if (isipv6) { /* * ip6_plen is not need to be filled now, and will be filled * in ip6_output. */ if (tp->t_port) { m->m_pkthdr.csum_flags = CSUM_UDP_IPV6; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); udp->uh_sum = in6_cksum_pseudo(ip6, ulen, IPPROTO_UDP, 0); th->th_sum = htons(0); UDPSTAT_INC(udps_opackets); } else { csum_flags = m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); th->th_sum = in6_cksum_pseudo(ip6, sizeof(struct tcphdr) + optlen + len, IPPROTO_TCP, 0); } } #endif #if defined(INET6) && defined(INET) else #endif #ifdef INET { if (tp->t_port) { m->m_pkthdr.csum_flags = CSUM_UDP; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(ulen + IPPROTO_UDP)); th->th_sum = htons(0); UDPSTAT_INC(udps_opackets); } else { csum_flags = m->m_pkthdr.csum_flags = CSUM_TCP; m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(sizeof(struct tcphdr) + IPPROTO_TCP + len + optlen)); } /* IP version must be set here for ipv4/ipv6 checking later */ KASSERT(ip->ip_v == IPVERSION, ("%s: IP version incorrect: %d", __func__, ip->ip_v)); } #endif /* * Enable TSO and specify the size of the segments. The TCP pseudo * header checksum is always provided. XXX: Fixme: This is currently * not the case for IPv6. */ if (tso) { KASSERT(len > maxseg, ("%s: len:%d <= tso_segsz:%d", __func__, len, maxseg)); m->m_pkthdr.csum_flags |= CSUM_TSO; csum_flags |= CSUM_TSO; m->m_pkthdr.tso_segsz = maxseg; } KASSERT(len + hdrlen == m_length(m, NULL), ("%s: mbuf chain different than expected: %d + %u != %u", __func__, len, hdrlen, m_length(m, NULL))); #ifdef TCP_HHOOK /* Run HHOOK_TC_ESTABLISHED_OUT helper hooks. */ hhook_run_tcp_est_out(tp, th, &to, len, tso); #endif -#ifdef TCPDEBUG - /* - * Trace. - */ - if (so->so_options & SO_DEBUG) { - u_short save = 0; - -#ifdef INET6 - if (!isipv6) -#endif - { - save = ipov->ih_len; - ipov->ih_len = htons(m->m_pkthdr.len /* - hdrlen + - * (th->th_off << 2) */ ); - } - tcp_trace(TA_OUTPUT, tp->t_state, tp, mtod(m, void *), th, 0); -#ifdef INET6 - if (!isipv6) -#endif - ipov->ih_len = save; - } -#endif /* TCPDEBUG */ /* Log to the black box */ if (tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; bbr_fill_in_logging_data(bbr, &log.u_bbr, cts); /* Record info on type of transmission */ log.u_bbr.flex1 = bbr->r_ctl.rc_hptsi_agg_delay; log.u_bbr.flex2 = (bbr->r_recovery_bw << 3); log.u_bbr.flex3 = maxseg; log.u_bbr.flex4 = delay_calc; /* Encode filled_all into the upper flex5 bit */ log.u_bbr.flex5 = bbr->rc_past_init_win; log.u_bbr.flex5 <<= 1; log.u_bbr.flex5 |= bbr->rc_no_pacing; log.u_bbr.flex5 <<= 29; if (filled_all) log.u_bbr.flex5 |= 0x80000000; log.u_bbr.flex5 |= tp->t_maxseg; log.u_bbr.flex6 = bbr->r_ctl.rc_pace_max_segs; log.u_bbr.flex7 = (bbr->rc_bbr_state << 8) | bbr_state_val(bbr); /* lets poke in the low and the high here for debugging */ log.u_bbr.pkts_out = bbr->rc_tp->t_maxseg; if (rsm || sack_rxmit) { if (doing_tlp) log.u_bbr.flex8 = 2; else log.u_bbr.flex8 = 1; } else { log.u_bbr.flex8 = 0; } lgb = tcp_log_event_(tp, th, &so->so_rcv, &so->so_snd, TCP_LOG_OUT, ERRNO_UNK, len, &log, false, NULL, NULL, 0, tv); } else { lgb = NULL; } /* * Fill in IP length and desired time to live and send to IP level. * There should be a better way to handle ttl and tos; we could keep * them in the template, but need a way to checksum without them. */ /* * m->m_pkthdr.len should have been set before cksum calcuration, * because in6_cksum() need it. */ #ifdef INET6 if (isipv6) { /* * we separately set hoplimit for every segment, since the * user might want to change the value via setsockopt. Also, * desired default hop limit might be changed via Neighbor * Discovery. */ ip6->ip6_hlim = in6_selecthlim(inp, NULL); /* * Set the packet size here for the benefit of DTrace * probes. ip6_output() will set it properly; it's supposed * to include the option header lengths as well. */ ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); if (V_path_mtu_discovery && maxseg > V_tcp_minmss) tp->t_flags2 |= TF2_PLPMTU_PMTUD; else tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; if (tp->t_state == TCPS_SYN_SENT) TCP_PROBE5(connect__request, NULL, tp, ip6, tp, th); TCP_PROBE5(send, NULL, tp, ip6, tp, th); /* TODO: IPv6 IP6TOS_ECT bit on */ error = ip6_output(m, inp->in6p_outputopts, &inp->inp_route6, ((rsm || sack_rxmit) ? IP_NO_SND_TAG_RL : 0), NULL, NULL, inp); if (error == EMSGSIZE && inp->inp_route6.ro_nh != NULL) mtu = inp->inp_route6.ro_nh->nh_mtu; } #endif /* INET6 */ #if defined(INET) && defined(INET6) else #endif #ifdef INET { ip->ip_len = htons(m->m_pkthdr.len); #ifdef INET6 if (isipv6) ip->ip_ttl = in6_selecthlim(inp, NULL); #endif /* INET6 */ /* * If we do path MTU discovery, then we set DF on every * packet. This might not be the best thing to do according * to RFC3390 Section 2. However the tcp hostcache migitates * the problem so it affects only the first tcp connection * with a host. * * NB: Don't set DF on small MTU/MSS to have a safe * fallback. */ if (V_path_mtu_discovery && tp->t_maxseg > V_tcp_minmss) { tp->t_flags2 |= TF2_PLPMTU_PMTUD; if (tp->t_port == 0 || len < V_tcp_minmss) { ip->ip_off |= htons(IP_DF); } } else { tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; } if (tp->t_state == TCPS_SYN_SENT) TCP_PROBE5(connect__request, NULL, tp, ip, tp, th); TCP_PROBE5(send, NULL, tp, ip, tp, th); error = ip_output(m, inp->inp_options, &inp->inp_route, ((rsm || sack_rxmit) ? IP_NO_SND_TAG_RL : 0), 0, inp); if (error == EMSGSIZE && inp->inp_route.ro_nh != NULL) mtu = inp->inp_route.ro_nh->nh_mtu; } #endif /* INET */ out: if (lgb) { lgb->tlb_errno = error; lgb = NULL; } /* * In transmit state, time the transmission and arrange for the * retransmit. In persist state, just set snd_max. */ if (error == 0) { tcp_account_for_send(tp, len, (rsm != NULL), doing_tlp, hw_tls); if (TCPS_HAVEESTABLISHED(tp->t_state) && (tp->t_flags & TF_SACK_PERMIT) && tp->rcv_numsacks > 0) tcp_clean_dsack_blocks(tp); /* We sent an ack clear the bbr_segs_rcvd count */ bbr->output_error_seen = 0; bbr->oerror_cnt = 0; bbr->bbr_segs_rcvd = 0; if (len == 0) counter_u64_add(bbr_out_size[TCP_MSS_ACCT_SNDACK], 1); /* Do accounting for new sends */ if ((len > 0) && (rsm == NULL)) { int idx; if (tp->snd_una == tp->snd_max) { /* * Special case to match google, when * nothing is in flight the delivered * time does get updated to the current * time (see tcp_rate_bsd.c). */ bbr->r_ctl.rc_del_time = cts; } if (len >= maxseg) { idx = (len / maxseg) + 3; if (idx >= TCP_MSS_ACCT_ATIMER) counter_u64_add(bbr_out_size[(TCP_MSS_ACCT_ATIMER - 1)], 1); else counter_u64_add(bbr_out_size[idx], 1); } else { /* smaller than a MSS */ idx = len / (bbr_hptsi_bytes_min - bbr->rc_last_options); if (idx >= TCP_MSS_SMALL_MAX_SIZE_DIV) idx = (TCP_MSS_SMALL_MAX_SIZE_DIV - 1); counter_u64_add(bbr_out_size[(idx + TCP_MSS_SMALL_SIZE_OFF)], 1); } } } abandon = 0; /* * We must do the send accounting before we log the output, * otherwise the state of the rsm could change and we account to the * wrong bucket. */ if (len > 0) { bbr_do_send_accounting(tp, bbr, rsm, len, error); if (error == 0) { if (tp->snd_una == tp->snd_max) bbr->r_ctl.rc_tlp_rxt_last_time = cts; } } bbr_log_output(bbr, tp, &to, len, bbr_seq, (uint8_t) flags, error, cts, mb, &abandon, rsm, 0, sb); if (abandon) { /* * If bbr_log_output destroys the TCB or sees a TH_RST being * sent we should hit this condition. */ return (0); } if (bbr->rc_in_persist == 0) { /* * Advance snd_nxt over sequence space of this segment. */ if (error) /* We don't log or do anything with errors */ goto skip_upd; if (tp->snd_una == tp->snd_max && (len || (flags & (TH_SYN | TH_FIN)))) { /* * Update the time we just added data since none was * outstanding. */ bbr_log_progress_event(bbr, tp, ticks, PROGRESS_START, __LINE__); bbr->rc_tp->t_acktime = ticks; } if (flags & (TH_SYN | TH_FIN) && (rsm == NULL)) { if (flags & TH_SYN) { /* * Smack the snd_max to iss + 1 * if its a FO we will add len below. */ tp->snd_max = tp->iss + 1; } if ((flags & TH_FIN) && ((tp->t_flags & TF_SENTFIN) == 0)) { tp->snd_max++; tp->t_flags |= TF_SENTFIN; } } if (sack_rxmit == 0) tp->snd_max += len; skip_upd: if ((error == 0) && len) tot_len += len; } else { /* Persists case */ int32_t xlen = len; if (error) goto nomore; if (flags & TH_SYN) ++xlen; if ((flags & TH_FIN) && ((tp->t_flags & TF_SENTFIN) == 0)) { ++xlen; tp->t_flags |= TF_SENTFIN; } if (xlen && (tp->snd_una == tp->snd_max)) { /* * Update the time we just added data since none was * outstanding. */ bbr_log_progress_event(bbr, tp, ticks, PROGRESS_START, __LINE__); bbr->rc_tp->t_acktime = ticks; } if (sack_rxmit == 0) tp->snd_max += xlen; tot_len += (len + optlen + ipoptlen); } nomore: if (error) { /* * Failures do not advance the seq counter above. For the * case of ENOBUFS we will fall out and become ack-clocked. * capping the cwnd at the current flight. * Everything else will just have to retransmit with the timer * (no pacer). */ SOCKBUF_UNLOCK_ASSERT(sb); BBR_STAT_INC(bbr_saw_oerr); /* Clear all delay/early tracks */ bbr->r_ctl.rc_hptsi_agg_delay = 0; bbr->r_ctl.rc_agg_early = 0; bbr->r_agg_early_set = 0; bbr->output_error_seen = 1; if (bbr->oerror_cnt < 0xf) bbr->oerror_cnt++; if (bbr_max_net_error_cnt && (bbr->oerror_cnt >= bbr_max_net_error_cnt)) { /* drop the session */ return (-ENETDOWN); } switch (error) { case ENOBUFS: /* * Make this guy have to get ack's to send * more but lets make sure we don't * slam him below a T-O (1MSS). */ if (bbr->rc_bbr_state != BBR_STATE_PROBE_RTT) { tp->snd_cwnd = ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes)) - maxseg; if (tp->snd_cwnd < maxseg) tp->snd_cwnd = maxseg; } slot = (bbr_error_base_paceout + 1) << bbr->oerror_cnt; BBR_STAT_INC(bbr_saw_enobuf); if (bbr->bbr_hdrw_pacing) counter_u64_add(bbr_hdwr_pacing_enobuf, 1); else counter_u64_add(bbr_nohdwr_pacing_enobuf, 1); /* * Here even in the enobuf's case we want to do our * state update. The reason being we may have been * called by the input function. If so we have had * things change. */ error = 0; goto enobufs; case EMSGSIZE: /* * For some reason the interface we used initially * to send segments changed to another or lowered * its MTU. If TSO was active we either got an * interface without TSO capabilits or TSO was * turned off. If we obtained mtu from ip_output() * then update it and try again. */ /* Turn on tracing (or try to) */ { int old_maxseg; old_maxseg = tp->t_maxseg; BBR_STAT_INC(bbr_saw_emsgsiz); bbr_log_msgsize_fail(bbr, tp, len, maxseg, mtu, csum_flags, tso, cts); if (mtu != 0) tcp_mss_update(tp, -1, mtu, NULL, NULL); if (old_maxseg <= tp->t_maxseg) { /* Huh it did not shrink? */ tp->t_maxseg = old_maxseg - 40; bbr_log_msgsize_fail(bbr, tp, len, maxseg, mtu, 0, tso, cts); } /* * Nuke all other things that can interfere * with slot */ if ((tot_len + len) && (len >= tp->t_maxseg)) { slot = bbr_get_pacing_delay(bbr, bbr->r_ctl.rc_bbr_hptsi_gain, (tot_len + len), cts, 0); if (slot < bbr_error_base_paceout) slot = (bbr_error_base_paceout + 2) << bbr->oerror_cnt; } else slot = (bbr_error_base_paceout + 2) << bbr->oerror_cnt; bbr->rc_output_starts_timer = 1; bbr_start_hpts_timer(bbr, tp, cts, 10, slot, tot_len); return (error); } case EPERM: tp->t_softerror = error; /* Fall through */ case EHOSTDOWN: case EHOSTUNREACH: case ENETDOWN: case ENETUNREACH: if (TCPS_HAVERCVDSYN(tp->t_state)) { tp->t_softerror = error; } /* FALLTHROUGH */ default: slot = (bbr_error_base_paceout + 3) << bbr->oerror_cnt; bbr->rc_output_starts_timer = 1; bbr_start_hpts_timer(bbr, tp, cts, 11, slot, 0); return (error); } #ifdef STATS } else if (((tp->t_flags & TF_GPUTINPROG) == 0) && len && (rsm == NULL) && (bbr->rc_in_persist == 0)) { tp->gput_seq = bbr_seq; tp->gput_ack = bbr_seq + min(sbavail(&so->so_snd) - sb_offset, sendwin); tp->gput_ts = cts; tp->t_flags |= TF_GPUTINPROG; #endif } KMOD_TCPSTAT_INC(tcps_sndtotal); if ((bbr->bbr_hdw_pace_ena) && (bbr->bbr_attempt_hdwr_pace == 0) && (bbr->rc_past_init_win) && (bbr->rc_bbr_state != BBR_STATE_STARTUP) && (get_filter_value(&bbr->r_ctl.rc_delrate)) && (inp->inp_route.ro_nh && inp->inp_route.ro_nh->nh_ifp)) { /* * We are past the initial window and * have at least one measurement so we * could use hardware pacing if its available. * We have an interface and we have not attempted * to setup hardware pacing, lets try to now. */ uint64_t rate_wanted; int err = 0; rate_wanted = bbr_get_hardware_rate(bbr); bbr->bbr_attempt_hdwr_pace = 1; bbr->r_ctl.crte = tcp_set_pacing_rate(bbr->rc_tp, inp->inp_route.ro_nh->nh_ifp, rate_wanted, (RS_PACING_GEQ|RS_PACING_SUB_OK), &err, NULL); if (bbr->r_ctl.crte) { bbr_type_log_hdwr_pacing(bbr, bbr->r_ctl.crte->ptbl->rs_ifp, rate_wanted, bbr->r_ctl.crte->rate, __LINE__, cts, err); BBR_STAT_INC(bbr_hdwr_rl_add_ok); counter_u64_add(bbr_flows_nohdwr_pacing, -1); counter_u64_add(bbr_flows_whdwr_pacing, 1); bbr->bbr_hdrw_pacing = 1; /* Now what is our gain status? */ if (bbr->r_ctl.crte->rate < rate_wanted) { /* We have a problem */ bbr_setup_less_of_rate(bbr, cts, bbr->r_ctl.crte->rate, rate_wanted); } else { /* We are good */ bbr->gain_is_limited = 0; bbr->skip_gain = 0; } tcp_bbr_tso_size_check(bbr, cts); } else { bbr_type_log_hdwr_pacing(bbr, inp->inp_route.ro_nh->nh_ifp, rate_wanted, 0, __LINE__, cts, err); BBR_STAT_INC(bbr_hdwr_rl_add_fail); } } if (bbr->bbr_hdrw_pacing) { /* * Worry about cases where the route * changes or something happened that we * lost our hardware pacing possibly during * the last ip_output call. */ if (inp->inp_snd_tag == NULL) { /* A change during ip output disabled hw pacing? */ bbr->bbr_hdrw_pacing = 0; } else if ((inp->inp_route.ro_nh == NULL) || (inp->inp_route.ro_nh->nh_ifp != inp->inp_snd_tag->ifp)) { /* * We had an interface or route change, * detach from the current hdwr pacing * and setup to re-attempt next go * round. */ bbr->bbr_hdrw_pacing = 0; bbr->bbr_attempt_hdwr_pace = 0; tcp_rel_pacing_rate(bbr->r_ctl.crte, bbr->rc_tp); tcp_bbr_tso_size_check(bbr, cts); } } /* * Data sent (as far as we can tell). If this advertises a larger * window than any other segment, then remember the size of the * advertised window. Any pending ACK has now been sent. */ if (SEQ_GT(tp->rcv_nxt + recwin, tp->rcv_adv)) tp->rcv_adv = tp->rcv_nxt + recwin; tp->last_ack_sent = tp->rcv_nxt; if ((error == 0) && (bbr->r_ctl.rc_pace_max_segs > tp->t_maxseg) && (doing_tlp == 0) && (tso == 0) && (len > 0) && ((flags & TH_RST) == 0) && ((flags & TH_SYN) == 0) && (IN_RECOVERY(tp->t_flags) == 0) && (bbr->rc_in_persist == 0) && (tot_len < bbr->r_ctl.rc_pace_max_segs)) { /* * For non-tso we need to goto again until we have sent out * enough data to match what we are hptsi out every hptsi * interval. */ if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { /* Make sure snd_nxt is drug up */ tp->snd_nxt = tp->snd_max; } if (rsm != NULL) { rsm = NULL; goto skip_again; } rsm = NULL; sack_rxmit = 0; tp->t_flags &= ~(TF_ACKNOW | TF_DELACK); goto again; } skip_again: if ((error == 0) && (flags & TH_FIN)) tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_FIN); if ((error == 0) && (flags & TH_RST)) tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST); if (((flags & (TH_RST | TH_SYN | TH_FIN)) == 0) && tot_len) { /* * Calculate/Re-Calculate the hptsi slot in usecs based on * what we have sent so far */ slot = bbr_get_pacing_delay(bbr, bbr->r_ctl.rc_bbr_hptsi_gain, tot_len, cts, 0); if (bbr->rc_no_pacing) slot = 0; } tp->t_flags &= ~(TF_ACKNOW | TF_DELACK); enobufs: if (bbr->rc_use_google == 0) bbr_check_bbr_for_state(bbr, cts, __LINE__, 0); bbr_cwnd_limiting(tp, bbr, ctf_flight_size(tp, (bbr->r_ctl.rc_sacked + bbr->r_ctl.rc_lost_bytes))); bbr->rc_output_starts_timer = 1; if (bbr->bbr_use_rack_cheat && (more_to_rxt || ((bbr->r_ctl.rc_resend = bbr_check_recovery_mode(tp, bbr, cts)) != NULL))) { /* Rack cheats and shotguns out all rxt's 1ms apart */ if (slot > 1000) slot = 1000; } if (bbr->bbr_hdrw_pacing && (bbr->hw_pacing_set == 0)) { /* * We don't change the tso size until some number of sends * to give the hardware commands time to get down * to the interface. */ bbr->r_ctl.bbr_hdwr_cnt_noset_snt++; if (bbr->r_ctl.bbr_hdwr_cnt_noset_snt >= bbr_hdwr_pacing_delay_cnt) { bbr->hw_pacing_set = 1; tcp_bbr_tso_size_check(bbr, cts); } } bbr_start_hpts_timer(bbr, tp, cts, 12, slot, tot_len); if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { /* Make sure snd_nxt is drug up */ tp->snd_nxt = tp->snd_max; } return (error); } /* * See bbr_output_wtime() for return values. */ static int bbr_output(struct tcpcb *tp) { int32_t ret; struct timeval tv; NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(tptoinpcb(tp)); (void)tcp_get_usecs(&tv); ret = bbr_output_wtime(tp, &tv); return (ret); } static void bbr_mtu_chg(struct tcpcb *tp) { struct tcp_bbr *bbr; struct bbr_sendmap *rsm, *frsm = NULL; uint32_t maxseg; /* * The MTU has changed. a) Clear the sack filter. b) Mark everything * over the current size as SACK_PASS so a retransmit will occur. */ bbr = (struct tcp_bbr *)tp->t_fb_ptr; maxseg = tp->t_maxseg - bbr->rc_last_options; sack_filter_clear(&bbr->r_ctl.bbr_sf, tp->snd_una); TAILQ_FOREACH(rsm, &bbr->r_ctl.rc_map, r_next) { /* Don't mess with ones acked (by sack?) */ if (rsm->r_flags & BBR_ACKED) continue; if ((rsm->r_end - rsm->r_start) > maxseg) { /* * We mark sack-passed on all the previous large * sends we did. This will force them to retransmit. */ rsm->r_flags |= BBR_SACK_PASSED; if (((rsm->r_flags & BBR_MARKED_LOST) == 0) && bbr_is_lost(bbr, rsm, bbr->r_ctl.rc_rcvtime)) { bbr->r_ctl.rc_lost_bytes += rsm->r_end - rsm->r_start; bbr->r_ctl.rc_lost += rsm->r_end - rsm->r_start; rsm->r_flags |= BBR_MARKED_LOST; } if (frsm == NULL) frsm = rsm; } } if (frsm) { bbr->r_ctl.rc_resend = frsm; } } static int bbr_pru_options(struct tcpcb *tp, int flags) { if (flags & PRUS_OOB) return (EOPNOTSUPP); return (0); } struct tcp_function_block __tcp_bbr = { .tfb_tcp_block_name = __XSTRING(STACKNAME), .tfb_tcp_output = bbr_output, .tfb_do_queued_segments = ctf_do_queued_segments, .tfb_do_segment_nounlock = bbr_do_segment_nounlock, .tfb_tcp_do_segment = bbr_do_segment, .tfb_tcp_ctloutput = bbr_ctloutput, .tfb_tcp_fb_init = bbr_init, .tfb_tcp_fb_fini = bbr_fini, .tfb_tcp_timer_stop_all = bbr_stopall, .tfb_tcp_rexmit_tmr = bbr_remxt_tmr, .tfb_tcp_handoff_ok = bbr_handoff_ok, .tfb_tcp_mtu_chg = bbr_mtu_chg, .tfb_pru_options = bbr_pru_options, .tfb_flags = TCP_FUNC_OUTPUT_CANDROP, }; /* * bbr_ctloutput() must drop the inpcb lock before performing copyin on * socket option arguments. When it re-acquires the lock after the copy, it * has to revalidate that the connection is still valid for the socket * option. */ static int bbr_set_sockopt(struct inpcb *inp, struct sockopt *sopt) { struct epoch_tracker et; struct tcpcb *tp; struct tcp_bbr *bbr; int32_t error = 0, optval; switch (sopt->sopt_level) { case IPPROTO_IPV6: case IPPROTO_IP: return (tcp_default_ctloutput(inp, sopt)); } switch (sopt->sopt_name) { case TCP_RACK_PACE_MAX_SEG: case TCP_RACK_MIN_TO: case TCP_RACK_REORD_THRESH: case TCP_RACK_REORD_FADE: case TCP_RACK_TLP_THRESH: case TCP_RACK_PKT_DELAY: case TCP_BBR_ALGORITHM: case TCP_BBR_TSLIMITS: case TCP_BBR_IWINTSO: case TCP_BBR_RECFORCE: case TCP_BBR_STARTUP_PG: case TCP_BBR_DRAIN_PG: case TCP_BBR_RWND_IS_APP: case TCP_BBR_PROBE_RTT_INT: case TCP_BBR_PROBE_RTT_GAIN: case TCP_BBR_PROBE_RTT_LEN: case TCP_BBR_STARTUP_LOSS_EXIT: case TCP_BBR_USEDEL_RATE: case TCP_BBR_MIN_RTO: case TCP_BBR_MAX_RTO: case TCP_BBR_PACE_PER_SEC: case TCP_DELACK: case TCP_BBR_PACE_DEL_TAR: case TCP_BBR_SEND_IWND_IN_TSO: case TCP_BBR_EXTRA_STATE: case TCP_BBR_UTTER_MAX_TSO: case TCP_BBR_MIN_TOPACEOUT: case TCP_BBR_FLOOR_MIN_TSO: case TCP_BBR_TSTMP_RAISES: case TCP_BBR_POLICER_DETECT: case TCP_BBR_USE_RACK_CHEAT: case TCP_DATA_AFTER_CLOSE: case TCP_BBR_HDWR_PACE: case TCP_BBR_PACE_SEG_MAX: case TCP_BBR_PACE_SEG_MIN: case TCP_BBR_PACE_CROSS: case TCP_BBR_PACE_OH: #ifdef NETFLIX_PEAKRATE case TCP_MAXPEAKRATE: #endif case TCP_BBR_TMR_PACE_OH: case TCP_BBR_RACK_RTT_USE: case TCP_BBR_RETRAN_WTSO: break; default: return (tcp_default_ctloutput(inp, sopt)); break; } INP_WUNLOCK(inp); error = sooptcopyin(sopt, &optval, sizeof(optval), sizeof(optval)); if (error) return (error); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { INP_WUNLOCK(inp); return (ECONNRESET); } tp = intotcpcb(inp); if (tp->t_fb != &__tcp_bbr) { INP_WUNLOCK(inp); return (ENOPROTOOPT); } bbr = (struct tcp_bbr *)tp->t_fb_ptr; switch (sopt->sopt_name) { case TCP_BBR_PACE_PER_SEC: BBR_OPTS_INC(tcp_bbr_pace_per_sec); bbr->r_ctl.bbr_hptsi_per_second = optval; break; case TCP_BBR_PACE_DEL_TAR: BBR_OPTS_INC(tcp_bbr_pace_del_tar); bbr->r_ctl.bbr_hptsi_segments_delay_tar = optval; break; case TCP_BBR_PACE_SEG_MAX: BBR_OPTS_INC(tcp_bbr_pace_seg_max); bbr->r_ctl.bbr_hptsi_segments_max = optval; break; case TCP_BBR_PACE_SEG_MIN: BBR_OPTS_INC(tcp_bbr_pace_seg_min); bbr->r_ctl.bbr_hptsi_bytes_min = optval; break; case TCP_BBR_PACE_CROSS: BBR_OPTS_INC(tcp_bbr_pace_cross); bbr->r_ctl.bbr_cross_over = optval; break; case TCP_BBR_ALGORITHM: BBR_OPTS_INC(tcp_bbr_algorithm); if (optval && (bbr->rc_use_google == 0)) { /* Turn on the google mode */ bbr_google_mode_on(bbr); if ((optval > 3) && (optval < 500)) { /* * Must be at least greater than .3% * and must be less than 50.0%. */ bbr->r_ctl.bbr_google_discount = optval; } } else if ((optval == 0) && (bbr->rc_use_google == 1)) { /* Turn off the google mode */ bbr_google_mode_off(bbr); } break; case TCP_BBR_TSLIMITS: BBR_OPTS_INC(tcp_bbr_tslimits); if (optval == 1) bbr->rc_use_ts_limit = 1; else if (optval == 0) bbr->rc_use_ts_limit = 0; else error = EINVAL; break; case TCP_BBR_IWINTSO: BBR_OPTS_INC(tcp_bbr_iwintso); if ((optval >= 0) && (optval < 128)) { uint32_t twin; bbr->rc_init_win = optval; twin = bbr_initial_cwnd(bbr, tp); if ((bbr->rc_past_init_win == 0) && (twin > tp->snd_cwnd)) tp->snd_cwnd = twin; else error = EBUSY; } else error = EINVAL; break; case TCP_BBR_STARTUP_PG: BBR_OPTS_INC(tcp_bbr_startup_pg); if ((optval > 0) && (optval < BBR_MAX_GAIN_VALUE)) { bbr->r_ctl.rc_startup_pg = optval; if (bbr->rc_bbr_state == BBR_STATE_STARTUP) { bbr->r_ctl.rc_bbr_hptsi_gain = optval; } } else error = EINVAL; break; case TCP_BBR_DRAIN_PG: BBR_OPTS_INC(tcp_bbr_drain_pg); if ((optval > 0) && (optval < BBR_MAX_GAIN_VALUE)) bbr->r_ctl.rc_drain_pg = optval; else error = EINVAL; break; case TCP_BBR_PROBE_RTT_LEN: BBR_OPTS_INC(tcp_bbr_probertt_len); if (optval <= 1) reset_time_small(&bbr->r_ctl.rc_rttprop, (optval * USECS_IN_SECOND)); else error = EINVAL; break; case TCP_BBR_PROBE_RTT_GAIN: BBR_OPTS_INC(tcp_bbr_probertt_gain); if (optval <= BBR_UNIT) bbr->r_ctl.bbr_rttprobe_gain_val = optval; else error = EINVAL; break; case TCP_BBR_PROBE_RTT_INT: BBR_OPTS_INC(tcp_bbr_probe_rtt_int); if (optval > 1000) bbr->r_ctl.rc_probertt_int = optval; else error = EINVAL; break; case TCP_BBR_MIN_TOPACEOUT: BBR_OPTS_INC(tcp_bbr_topaceout); if (optval == 0) { bbr->no_pacing_until = 0; bbr->rc_no_pacing = 0; } else if (optval <= 0x00ff) { bbr->no_pacing_until = optval; if ((bbr->r_ctl.rc_pkt_epoch < bbr->no_pacing_until) && (bbr->rc_bbr_state == BBR_STATE_STARTUP)){ /* Turn on no pacing */ bbr->rc_no_pacing = 1; } } else error = EINVAL; break; case TCP_BBR_STARTUP_LOSS_EXIT: BBR_OPTS_INC(tcp_bbr_startup_loss_exit); bbr->rc_loss_exit = optval; break; case TCP_BBR_USEDEL_RATE: error = EINVAL; break; case TCP_BBR_MIN_RTO: BBR_OPTS_INC(tcp_bbr_min_rto); bbr->r_ctl.rc_min_rto_ms = optval; break; case TCP_BBR_MAX_RTO: BBR_OPTS_INC(tcp_bbr_max_rto); bbr->rc_max_rto_sec = optval; break; case TCP_RACK_MIN_TO: /* Minimum time between rack t-o's in ms */ BBR_OPTS_INC(tcp_rack_min_to); bbr->r_ctl.rc_min_to = optval; break; case TCP_RACK_REORD_THRESH: /* RACK reorder threshold (shift amount) */ BBR_OPTS_INC(tcp_rack_reord_thresh); if ((optval > 0) && (optval < 31)) bbr->r_ctl.rc_reorder_shift = optval; else error = EINVAL; break; case TCP_RACK_REORD_FADE: /* Does reordering fade after ms time */ BBR_OPTS_INC(tcp_rack_reord_fade); bbr->r_ctl.rc_reorder_fade = optval; break; case TCP_RACK_TLP_THRESH: /* RACK TLP theshold i.e. srtt+(srtt/N) */ BBR_OPTS_INC(tcp_rack_tlp_thresh); if (optval) bbr->rc_tlp_threshold = optval; else error = EINVAL; break; case TCP_BBR_USE_RACK_CHEAT: BBR_OPTS_INC(tcp_use_rackcheat); if (bbr->rc_use_google) { error = EINVAL; break; } BBR_OPTS_INC(tcp_rack_cheat); if (optval) bbr->bbr_use_rack_cheat = 1; else bbr->bbr_use_rack_cheat = 0; break; case TCP_BBR_FLOOR_MIN_TSO: BBR_OPTS_INC(tcp_utter_max_tso); if ((optval >= 0) && (optval < 40)) bbr->r_ctl.bbr_hptsi_segments_floor = optval; else error = EINVAL; break; case TCP_BBR_UTTER_MAX_TSO: BBR_OPTS_INC(tcp_utter_max_tso); if ((optval >= 0) && (optval < 0xffff)) bbr->r_ctl.bbr_utter_max = optval; else error = EINVAL; break; case TCP_BBR_EXTRA_STATE: BBR_OPTS_INC(tcp_extra_state); if (optval) bbr->rc_use_idle_restart = 1; else bbr->rc_use_idle_restart = 0; break; case TCP_BBR_SEND_IWND_IN_TSO: BBR_OPTS_INC(tcp_iwnd_tso); if (optval) { bbr->bbr_init_win_cheat = 1; if (bbr->rc_past_init_win == 0) { uint32_t cts; cts = tcp_get_usecs(&bbr->rc_tv); tcp_bbr_tso_size_check(bbr, cts); } } else bbr->bbr_init_win_cheat = 0; break; case TCP_BBR_HDWR_PACE: BBR_OPTS_INC(tcp_hdwr_pacing); if (optval){ bbr->bbr_hdw_pace_ena = 1; bbr->bbr_attempt_hdwr_pace = 0; } else { bbr->bbr_hdw_pace_ena = 0; #ifdef RATELIMIT if (bbr->r_ctl.crte != NULL) { tcp_rel_pacing_rate(bbr->r_ctl.crte, tp); bbr->r_ctl.crte = NULL; } #endif } break; case TCP_DELACK: BBR_OPTS_INC(tcp_delack); if (optval < 100) { if (optval == 0) /* off */ tp->t_delayed_ack = 0; else if (optval == 1) /* on which is 2 */ tp->t_delayed_ack = 2; else /* higher than 2 and less than 100 */ tp->t_delayed_ack = optval; if (tp->t_flags & TF_DELACK) { tp->t_flags &= ~TF_DELACK; tp->t_flags |= TF_ACKNOW; NET_EPOCH_ENTER(et); bbr_output(tp); NET_EPOCH_EXIT(et); } } else error = EINVAL; break; case TCP_RACK_PKT_DELAY: /* RACK added ms i.e. rack-rtt + reord + N */ BBR_OPTS_INC(tcp_rack_pkt_delay); bbr->r_ctl.rc_pkt_delay = optval; break; #ifdef NETFLIX_PEAKRATE case TCP_MAXPEAKRATE: BBR_OPTS_INC(tcp_maxpeak); error = tcp_set_maxpeakrate(tp, optval); if (!error) tp->t_peakrate_thr = tp->t_maxpeakrate; break; #endif case TCP_BBR_RETRAN_WTSO: BBR_OPTS_INC(tcp_retran_wtso); if (optval) bbr->rc_resends_use_tso = 1; else bbr->rc_resends_use_tso = 0; break; case TCP_DATA_AFTER_CLOSE: BBR_OPTS_INC(tcp_data_ac); if (optval) bbr->rc_allow_data_af_clo = 1; else bbr->rc_allow_data_af_clo = 0; break; case TCP_BBR_POLICER_DETECT: BBR_OPTS_INC(tcp_policer_det); if (bbr->rc_use_google == 0) error = EINVAL; else if (optval) bbr->r_use_policer = 1; else bbr->r_use_policer = 0; break; case TCP_BBR_TSTMP_RAISES: BBR_OPTS_INC(tcp_ts_raises); if (optval) bbr->ts_can_raise = 1; else bbr->ts_can_raise = 0; break; case TCP_BBR_TMR_PACE_OH: BBR_OPTS_INC(tcp_pacing_oh_tmr); if (bbr->rc_use_google) { error = EINVAL; } else { if (optval) bbr->r_ctl.rc_incr_tmrs = 1; else bbr->r_ctl.rc_incr_tmrs = 0; } break; case TCP_BBR_PACE_OH: BBR_OPTS_INC(tcp_pacing_oh); if (bbr->rc_use_google) { error = EINVAL; } else { if (optval > (BBR_INCL_TCP_OH| BBR_INCL_IP_OH| BBR_INCL_ENET_OH)) { error = EINVAL; break; } if (optval & BBR_INCL_TCP_OH) bbr->r_ctl.rc_inc_tcp_oh = 1; else bbr->r_ctl.rc_inc_tcp_oh = 0; if (optval & BBR_INCL_IP_OH) bbr->r_ctl.rc_inc_ip_oh = 1; else bbr->r_ctl.rc_inc_ip_oh = 0; if (optval & BBR_INCL_ENET_OH) bbr->r_ctl.rc_inc_enet_oh = 1; else bbr->r_ctl.rc_inc_enet_oh = 0; } break; default: return (tcp_default_ctloutput(inp, sopt)); break; } #ifdef NETFLIX_STATS tcp_log_socket_option(tp, sopt->sopt_name, optval, error); #endif INP_WUNLOCK(inp); return (error); } /* * return 0 on success, error-num on failure */ static int bbr_get_sockopt(struct inpcb *inp, struct sockopt *sopt) { struct tcpcb *tp; struct tcp_bbr *bbr; int32_t error, optval; tp = intotcpcb(inp); bbr = (struct tcp_bbr *)tp->t_fb_ptr; if (bbr == NULL) { INP_WUNLOCK(inp); return (EINVAL); } /* * Because all our options are either boolean or an int, we can just * pull everything into optval and then unlock and copy. If we ever * add a option that is not a int, then this will have quite an * impact to this routine. */ switch (sopt->sopt_name) { case TCP_BBR_PACE_PER_SEC: optval = bbr->r_ctl.bbr_hptsi_per_second; break; case TCP_BBR_PACE_DEL_TAR: optval = bbr->r_ctl.bbr_hptsi_segments_delay_tar; break; case TCP_BBR_PACE_SEG_MAX: optval = bbr->r_ctl.bbr_hptsi_segments_max; break; case TCP_BBR_MIN_TOPACEOUT: optval = bbr->no_pacing_until; break; case TCP_BBR_PACE_SEG_MIN: optval = bbr->r_ctl.bbr_hptsi_bytes_min; break; case TCP_BBR_PACE_CROSS: optval = bbr->r_ctl.bbr_cross_over; break; case TCP_BBR_ALGORITHM: optval = bbr->rc_use_google; break; case TCP_BBR_TSLIMITS: optval = bbr->rc_use_ts_limit; break; case TCP_BBR_IWINTSO: optval = bbr->rc_init_win; break; case TCP_BBR_STARTUP_PG: optval = bbr->r_ctl.rc_startup_pg; break; case TCP_BBR_DRAIN_PG: optval = bbr->r_ctl.rc_drain_pg; break; case TCP_BBR_PROBE_RTT_INT: optval = bbr->r_ctl.rc_probertt_int; break; case TCP_BBR_PROBE_RTT_LEN: optval = (bbr->r_ctl.rc_rttprop.cur_time_limit / USECS_IN_SECOND); break; case TCP_BBR_PROBE_RTT_GAIN: optval = bbr->r_ctl.bbr_rttprobe_gain_val; break; case TCP_BBR_STARTUP_LOSS_EXIT: optval = bbr->rc_loss_exit; break; case TCP_BBR_USEDEL_RATE: error = EINVAL; break; case TCP_BBR_MIN_RTO: optval = bbr->r_ctl.rc_min_rto_ms; break; case TCP_BBR_MAX_RTO: optval = bbr->rc_max_rto_sec; break; case TCP_RACK_PACE_MAX_SEG: /* Max segments in a pace */ optval = bbr->r_ctl.rc_pace_max_segs; break; case TCP_RACK_MIN_TO: /* Minimum time between rack t-o's in ms */ optval = bbr->r_ctl.rc_min_to; break; case TCP_RACK_REORD_THRESH: /* RACK reorder threshold (shift amount) */ optval = bbr->r_ctl.rc_reorder_shift; break; case TCP_RACK_REORD_FADE: /* Does reordering fade after ms time */ optval = bbr->r_ctl.rc_reorder_fade; break; case TCP_BBR_USE_RACK_CHEAT: /* Do we use the rack cheat for rxt */ optval = bbr->bbr_use_rack_cheat; break; case TCP_BBR_FLOOR_MIN_TSO: optval = bbr->r_ctl.bbr_hptsi_segments_floor; break; case TCP_BBR_UTTER_MAX_TSO: optval = bbr->r_ctl.bbr_utter_max; break; case TCP_BBR_SEND_IWND_IN_TSO: /* Do we send TSO size segments initially */ optval = bbr->bbr_init_win_cheat; break; case TCP_BBR_EXTRA_STATE: optval = bbr->rc_use_idle_restart; break; case TCP_RACK_TLP_THRESH: /* RACK TLP theshold i.e. srtt+(srtt/N) */ optval = bbr->rc_tlp_threshold; break; case TCP_RACK_PKT_DELAY: /* RACK added ms i.e. rack-rtt + reord + N */ optval = bbr->r_ctl.rc_pkt_delay; break; case TCP_BBR_RETRAN_WTSO: optval = bbr->rc_resends_use_tso; break; case TCP_DATA_AFTER_CLOSE: optval = bbr->rc_allow_data_af_clo; break; case TCP_DELACK: optval = tp->t_delayed_ack; break; case TCP_BBR_HDWR_PACE: optval = bbr->bbr_hdw_pace_ena; break; case TCP_BBR_POLICER_DETECT: optval = bbr->r_use_policer; break; case TCP_BBR_TSTMP_RAISES: optval = bbr->ts_can_raise; break; case TCP_BBR_TMR_PACE_OH: optval = bbr->r_ctl.rc_incr_tmrs; break; case TCP_BBR_PACE_OH: optval = 0; if (bbr->r_ctl.rc_inc_tcp_oh) optval |= BBR_INCL_TCP_OH; if (bbr->r_ctl.rc_inc_ip_oh) optval |= BBR_INCL_IP_OH; if (bbr->r_ctl.rc_inc_enet_oh) optval |= BBR_INCL_ENET_OH; break; default: return (tcp_default_ctloutput(inp, sopt)); break; } INP_WUNLOCK(inp); error = sooptcopyout(sopt, &optval, sizeof optval); return (error); } /* * return 0 on success, error-num on failure */ static int bbr_ctloutput(struct inpcb *inp, struct sockopt *sopt) { if (sopt->sopt_dir == SOPT_SET) { return (bbr_set_sockopt(inp, sopt)); } else if (sopt->sopt_dir == SOPT_GET) { return (bbr_get_sockopt(inp, sopt)); } else { panic("%s: sopt_dir $%d", __func__, sopt->sopt_dir); } } static const char *bbr_stack_names[] = { __XSTRING(STACKNAME), #ifdef STACKALIAS __XSTRING(STACKALIAS), #endif }; static bool bbr_mod_inited = false; static int tcp_addbbr(module_t mod, int32_t type, void *data) { int32_t err = 0; int num_stacks; switch (type) { case MOD_LOAD: printf("Attempting to load " __XSTRING(MODNAME) "\n"); bbr_zone = uma_zcreate(__XSTRING(MODNAME) "_map", sizeof(struct bbr_sendmap), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); bbr_pcb_zone = uma_zcreate(__XSTRING(MODNAME) "_pcb", sizeof(struct tcp_bbr), NULL, NULL, NULL, NULL, UMA_ALIGN_CACHE, 0); sysctl_ctx_init(&bbr_sysctl_ctx); bbr_sysctl_root = SYSCTL_ADD_NODE(&bbr_sysctl_ctx, SYSCTL_STATIC_CHILDREN(_net_inet_tcp), OID_AUTO, #ifdef STACKALIAS __XSTRING(STACKALIAS), #else __XSTRING(STACKNAME), #endif CTLFLAG_RW | CTLFLAG_MPSAFE, 0, ""); if (bbr_sysctl_root == NULL) { printf("Failed to add sysctl node\n"); err = EFAULT; goto free_uma; } bbr_init_sysctls(); num_stacks = nitems(bbr_stack_names); err = register_tcp_functions_as_names(&__tcp_bbr, M_WAITOK, bbr_stack_names, &num_stacks); if (err) { printf("Failed to register %s stack name for " "%s module\n", bbr_stack_names[num_stacks], __XSTRING(MODNAME)); sysctl_ctx_free(&bbr_sysctl_ctx); free_uma: uma_zdestroy(bbr_zone); uma_zdestroy(bbr_pcb_zone); bbr_counter_destroy(); printf("Failed to register " __XSTRING(MODNAME) " module err:%d\n", err); return (err); } tcp_lro_reg_mbufq(); bbr_mod_inited = true; printf(__XSTRING(MODNAME) " is now available\n"); break; case MOD_QUIESCE: err = deregister_tcp_functions(&__tcp_bbr, true, false); break; case MOD_UNLOAD: err = deregister_tcp_functions(&__tcp_bbr, false, true); if (err == EBUSY) break; if (bbr_mod_inited) { uma_zdestroy(bbr_zone); uma_zdestroy(bbr_pcb_zone); sysctl_ctx_free(&bbr_sysctl_ctx); bbr_counter_destroy(); printf(__XSTRING(MODNAME) " is now no longer available\n"); bbr_mod_inited = false; } tcp_lro_dereg_mbufq(); err = 0; break; default: return (EOPNOTSUPP); } return (err); } static moduledata_t tcp_bbr = { .name = __XSTRING(MODNAME), .evhand = tcp_addbbr, .priv = 0 }; MODULE_VERSION(MODNAME, 1); DECLARE_MODULE(MODNAME, tcp_bbr, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY); MODULE_DEPEND(MODNAME, tcphpts, 1, 1, 1); diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c index 784d97c7d945..0aa3d0910562 100644 --- a/sys/netinet/tcp_stacks/rack.c +++ b/sys/netinet/tcp_stacks/rack.c @@ -1,20898 +1,20865 @@ /*- * Copyright (c) 2016-2020 Netflix, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" -#include "opt_tcpdebug.h" #include "opt_ratelimit.h" #include "opt_kern_tls.h" #include #include #include #include #ifdef TCP_HHOOK #include #endif #include #include #include #include #include #include /* for proc0 declaration */ #include #include #include #include #ifdef STATS #include #include #include /* Must come after qmath.h and tree.h */ #else #include #endif #include #include #include #include #include #include #include #ifdef TCP_ACCOUNTING #include #include #endif #include #include #include #include #define TCPSTATES /* for logging */ #include #include #include #include #include /* required for icmp_var.h */ #include /* for ICMP_BANDLIM */ #include #include #include #include #include #define TCPOUTFLAGS #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef NETFLIX_SHARED_CWND #include #endif -#ifdef TCPDEBUG -#include -#endif /* TCPDEBUG */ #ifdef TCP_OFFLOAD #include #endif #ifdef INET6 #include #endif #include #include #if defined(IPSEC) || defined(IPSEC_SUPPORT) #include #include #endif /* IPSEC */ #include #include #include #ifdef MAC #include #endif #include "sack_filter.h" #include "tcp_rack.h" #include "rack_bbr_common.h" uma_zone_t rack_zone; uma_zone_t rack_pcb_zone; #ifndef TICKS2SBT #define TICKS2SBT(__t) (tick_sbt * ((sbintime_t)(__t))) #endif VNET_DECLARE(uint32_t, newreno_beta); VNET_DECLARE(uint32_t, newreno_beta_ecn); #define V_newreno_beta VNET(newreno_beta) #define V_newreno_beta_ecn VNET(newreno_beta_ecn) MALLOC_DEFINE(M_TCPFSB, "tcp_fsb", "TCP fast send block"); MALLOC_DEFINE(M_TCPDO, "tcp_do", "TCP deferred options"); struct sysctl_ctx_list rack_sysctl_ctx; struct sysctl_oid *rack_sysctl_root; #define CUM_ACKED 1 #define SACKED 2 /* * The RACK module incorporates a number of * TCP ideas that have been put out into the IETF * over the last few years: * - Matt Mathis's Rate Halving which slowly drops * the congestion window so that the ack clock can * be maintained during a recovery. * - Yuchung Cheng's RACK TCP (for which its named) that * will stop us using the number of dup acks and instead * use time as the gage of when we retransmit. * - Reorder Detection of RFC4737 and the Tail-Loss probe draft * of Dukkipati et.al. * RACK depends on SACK, so if an endpoint arrives that * cannot do SACK the state machine below will shuttle the * connection back to using the "default" TCP stack that is * in FreeBSD. * * To implement RACK the original TCP stack was first decomposed * into a functional state machine with individual states * for each of the possible TCP connection states. The do_segment * functions role in life is to mandate the connection supports SACK * initially and then assure that the RACK state matches the conenction * state before calling the states do_segment function. Each * state is simplified due to the fact that the original do_segment * has been decomposed and we *know* what state we are in (no * switches on the state) and all tests for SACK are gone. This * greatly simplifies what each state does. * * TCP output is also over-written with a new version since it * must maintain the new rack scoreboard. * */ static int32_t rack_tlp_thresh = 1; static int32_t rack_tlp_limit = 2; /* No more than 2 TLPs w-out new data */ static int32_t rack_tlp_use_greater = 1; static int32_t rack_reorder_thresh = 2; static int32_t rack_reorder_fade = 60000000; /* 0 - never fade, def 60,000,000 * - 60 seconds */ static uint8_t rack_req_measurements = 1; /* Attack threshold detections */ static uint32_t rack_highest_sack_thresh_seen = 0; static uint32_t rack_highest_move_thresh_seen = 0; static int32_t rack_enable_hw_pacing = 0; /* Due to CCSP keep it off by default */ static int32_t rack_hw_pace_extra_slots = 2; /* 2 extra MSS time betweens */ static int32_t rack_hw_rate_caps = 1; /* 1; */ static int32_t rack_hw_rate_min = 0; /* 1500000;*/ static int32_t rack_hw_rate_to_low = 0; /* 1200000; */ static int32_t rack_hw_up_only = 1; static int32_t rack_stats_gets_ms_rtt = 1; static int32_t rack_prr_addbackmax = 2; static int32_t rack_do_hystart = 0; static int32_t rack_apply_rtt_with_reduced_conf = 0; static int32_t rack_pkt_delay = 1000; static int32_t rack_send_a_lot_in_prr = 1; static int32_t rack_min_to = 1000; /* Number of microsecond min timeout */ static int32_t rack_verbose_logging = 0; static int32_t rack_ignore_data_after_close = 1; static int32_t rack_enable_shared_cwnd = 1; static int32_t rack_use_cmp_acks = 1; static int32_t rack_use_fsb = 1; static int32_t rack_use_rfo = 1; static int32_t rack_use_rsm_rfo = 1; static int32_t rack_max_abc_post_recovery = 2; static int32_t rack_client_low_buf = 0; static int32_t rack_dsack_std_based = 0x3; /* bit field bit 1 sets rc_rack_tmr_std_based and bit 2 sets rc_rack_use_dsack */ #ifdef TCP_ACCOUNTING static int32_t rack_tcp_accounting = 0; #endif static int32_t rack_limits_scwnd = 1; static int32_t rack_enable_mqueue_for_nonpaced = 0; static int32_t rack_disable_prr = 0; static int32_t use_rack_rr = 1; static int32_t rack_non_rxt_use_cr = 0; /* does a non-rxt in recovery use the configured rate (ss/ca)? */ static int32_t rack_persist_min = 250000; /* 250usec */ static int32_t rack_persist_max = 2000000; /* 2 Second in usec's */ static int32_t rack_sack_not_required = 1; /* set to one to allow non-sack to use rack */ static int32_t rack_default_init_window = 0; /* Use system default */ static int32_t rack_limit_time_with_srtt = 0; static int32_t rack_autosndbuf_inc = 20; /* In percentage form */ static int32_t rack_enobuf_hw_boost_mult = 2; /* How many times the hw rate we boost slot using time_between */ static int32_t rack_enobuf_hw_max = 12000; /* 12 ms in usecs */ static int32_t rack_enobuf_hw_min = 10000; /* 10 ms in usecs */ static int32_t rack_hw_rwnd_factor = 2; /* How many max_segs the rwnd must be before we hold off sending */ /* * Currently regular tcp has a rto_min of 30ms * the backoff goes 12 times so that ends up * being a total of 122.850 seconds before a * connection is killed. */ static uint32_t rack_def_data_window = 20; static uint32_t rack_goal_bdp = 2; static uint32_t rack_min_srtts = 1; static uint32_t rack_min_measure_usec = 0; static int32_t rack_tlp_min = 10000; /* 10ms */ static int32_t rack_rto_min = 30000; /* 30,000 usec same as main freebsd */ static int32_t rack_rto_max = 4000000; /* 4 seconds in usec's */ static const int32_t rack_free_cache = 2; static int32_t rack_hptsi_segments = 40; static int32_t rack_rate_sample_method = USE_RTT_LOW; static int32_t rack_pace_every_seg = 0; static int32_t rack_delayed_ack_time = 40000; /* 40ms in usecs */ static int32_t rack_slot_reduction = 4; static int32_t rack_wma_divisor = 8; /* For WMA calculation */ static int32_t rack_cwnd_block_ends_measure = 0; static int32_t rack_rwnd_block_ends_measure = 0; static int32_t rack_def_profile = 0; static int32_t rack_lower_cwnd_at_tlp = 0; static int32_t rack_limited_retran = 0; static int32_t rack_always_send_oldest = 0; static int32_t rack_tlp_threshold_use = TLP_USE_TWO_ONE; static uint16_t rack_per_of_gp_ss = 250; /* 250 % slow-start */ static uint16_t rack_per_of_gp_ca = 200; /* 200 % congestion-avoidance */ static uint16_t rack_per_of_gp_rec = 200; /* 200 % of bw */ /* Probertt */ static uint16_t rack_per_of_gp_probertt = 60; /* 60% of bw */ static uint16_t rack_per_of_gp_lowthresh = 40; /* 40% is bottom */ static uint16_t rack_per_of_gp_probertt_reduce = 10; /* 10% reduction */ static uint16_t rack_atexit_prtt_hbp = 130; /* Clamp to 130% on exit prtt if highly buffered path */ static uint16_t rack_atexit_prtt = 130; /* Clamp to 100% on exit prtt if non highly buffered path */ static uint32_t rack_max_drain_wait = 2; /* How man gp srtt's before we give up draining */ static uint32_t rack_must_drain = 1; /* How many GP srtt's we *must* wait */ static uint32_t rack_probertt_use_min_rtt_entry = 1; /* Use the min to calculate the goal else gp_srtt */ static uint32_t rack_probertt_use_min_rtt_exit = 0; static uint32_t rack_probe_rtt_sets_cwnd = 0; static uint32_t rack_probe_rtt_safety_val = 2000000; /* No more than 2 sec in probe-rtt */ static uint32_t rack_time_between_probertt = 9600000; /* 9.6 sec in usecs */ static uint32_t rack_probertt_gpsrtt_cnt_mul = 0; /* How many srtt periods does probe-rtt last top fraction */ static uint32_t rack_probertt_gpsrtt_cnt_div = 0; /* How many srtt periods does probe-rtt last bottom fraction */ static uint32_t rack_min_probertt_hold = 40000; /* Equal to delayed ack time */ static uint32_t rack_probertt_filter_life = 10000000; static uint32_t rack_probertt_lower_within = 10; static uint32_t rack_min_rtt_movement = 250000; /* Must move at least 250ms (in microseconds) to count as a lowering */ static int32_t rack_pace_one_seg = 0; /* Shall we pace for less than 1.4Meg 1MSS at a time */ static int32_t rack_probertt_clear_is = 1; static int32_t rack_max_drain_hbp = 1; /* Extra drain times gpsrtt for highly buffered paths */ static int32_t rack_hbp_thresh = 3; /* what is the divisor max_rtt/min_rtt to decided a hbp */ /* Part of pacing */ static int32_t rack_max_per_above = 30; /* When we go to increment stop if above 100+this% */ /* Timely information */ /* Combine these two gives the range of 'no change' to bw */ /* ie the up/down provide the upper and lower bound */ static int32_t rack_gp_per_bw_mul_up = 2; /* 2% */ static int32_t rack_gp_per_bw_mul_down = 4; /* 4% */ static int32_t rack_gp_rtt_maxmul = 3; /* 3 x maxmin */ static int32_t rack_gp_rtt_minmul = 1; /* minrtt + (minrtt/mindiv) is lower rtt */ static int32_t rack_gp_rtt_mindiv = 4; /* minrtt + (minrtt * minmul/mindiv) is lower rtt */ static int32_t rack_gp_decrease_per = 20; /* 20% decrease in multiplier */ static int32_t rack_gp_increase_per = 2; /* 2% increase in multiplier */ static int32_t rack_per_lower_bound = 50; /* Don't allow to drop below this multiplier */ static int32_t rack_per_upper_bound_ss = 0; /* Don't allow SS to grow above this */ static int32_t rack_per_upper_bound_ca = 0; /* Don't allow CA to grow above this */ static int32_t rack_do_dyn_mul = 0; /* Are the rack gp multipliers dynamic */ static int32_t rack_gp_no_rec_chg = 1; /* Prohibit recovery from reducing it's multiplier */ static int32_t rack_timely_dec_clear = 6; /* Do we clear decrement count at a value (6)? */ static int32_t rack_timely_max_push_rise = 3; /* One round of pushing */ static int32_t rack_timely_max_push_drop = 3; /* Three round of pushing */ static int32_t rack_timely_min_segs = 4; /* 4 segment minimum */ static int32_t rack_use_max_for_nobackoff = 0; static int32_t rack_timely_int_timely_only = 0; /* do interim timely's only use the timely algo (no b/w changes)? */ static int32_t rack_timely_no_stopping = 0; static int32_t rack_down_raise_thresh = 100; static int32_t rack_req_segs = 1; static uint64_t rack_bw_rate_cap = 0; static uint32_t rack_trace_point_config = 0; static uint32_t rack_trace_point_bb_mode = 4; static int32_t rack_trace_point_count = 0; /* Weird delayed ack mode */ static int32_t rack_use_imac_dack = 0; /* Rack specific counters */ counter_u64_t rack_saw_enobuf; counter_u64_t rack_saw_enobuf_hw; counter_u64_t rack_saw_enetunreach; counter_u64_t rack_persists_sends; counter_u64_t rack_persists_acks; counter_u64_t rack_persists_loss; counter_u64_t rack_persists_lost_ends; #ifdef INVARIANTS counter_u64_t rack_adjust_map_bw; #endif /* Tail loss probe counters */ counter_u64_t rack_tlp_tot; counter_u64_t rack_tlp_newdata; counter_u64_t rack_tlp_retran; counter_u64_t rack_tlp_retran_bytes; counter_u64_t rack_to_tot; counter_u64_t rack_hot_alloc; counter_u64_t rack_to_alloc; counter_u64_t rack_to_alloc_hard; counter_u64_t rack_to_alloc_emerg; counter_u64_t rack_to_alloc_limited; counter_u64_t rack_alloc_limited_conns; counter_u64_t rack_split_limited; counter_u64_t rack_multi_single_eq; counter_u64_t rack_proc_non_comp_ack; counter_u64_t rack_fto_send; counter_u64_t rack_fto_rsm_send; counter_u64_t rack_nfto_resend; counter_u64_t rack_non_fto_send; counter_u64_t rack_extended_rfo; counter_u64_t rack_sack_proc_all; counter_u64_t rack_sack_proc_short; counter_u64_t rack_sack_proc_restart; counter_u64_t rack_sack_attacks_detected; counter_u64_t rack_sack_attacks_reversed; counter_u64_t rack_sack_used_next_merge; counter_u64_t rack_sack_splits; counter_u64_t rack_sack_used_prev_merge; counter_u64_t rack_sack_skipped_acked; counter_u64_t rack_ack_total; counter_u64_t rack_express_sack; counter_u64_t rack_sack_total; counter_u64_t rack_move_none; counter_u64_t rack_move_some; counter_u64_t rack_input_idle_reduces; counter_u64_t rack_collapsed_win; counter_u64_t rack_collapsed_win_seen; counter_u64_t rack_collapsed_win_rxt; counter_u64_t rack_collapsed_win_rxt_bytes; counter_u64_t rack_try_scwnd; counter_u64_t rack_hw_pace_init_fail; counter_u64_t rack_hw_pace_lost; counter_u64_t rack_out_size[TCP_MSS_ACCT_SIZE]; counter_u64_t rack_opts_arry[RACK_OPTS_SIZE]; #define RACK_REXMTVAL(tp) max(rack_rto_min, ((tp)->t_srtt + ((tp)->t_rttvar << 2))) #define RACK_TCPT_RANGESET(tv, value, tvmin, tvmax, slop) do { \ (tv) = (value) + slop; \ if ((u_long)(tv) < (u_long)(tvmin)) \ (tv) = (tvmin); \ if ((u_long)(tv) > (u_long)(tvmax)) \ (tv) = (tvmax); \ } while (0) static void rack_log_progress_event(struct tcp_rack *rack, struct tcpcb *tp, uint32_t tick, int event, int line); static int rack_process_ack(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, uint32_t tiwin, int32_t tlen, int32_t * ofia, int32_t thflags, int32_t * ret_val); static int rack_process_data(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt); static void rack_ack_received(struct tcpcb *tp, struct tcp_rack *rack, uint32_t th_ack, uint16_t nsegs, uint16_t type, int32_t recovery); static struct rack_sendmap *rack_alloc(struct tcp_rack *rack); static struct rack_sendmap *rack_alloc_limit(struct tcp_rack *rack, uint8_t limit_type); static struct rack_sendmap * rack_check_recovery_mode(struct tcpcb *tp, uint32_t tsused); static void rack_cong_signal(struct tcpcb *tp, uint32_t type, uint32_t ack, int ); static void rack_counter_destroy(void); static int rack_ctloutput(struct inpcb *inp, struct sockopt *sopt); static int32_t rack_ctor(void *mem, int32_t size, void *arg, int32_t how); static void rack_set_pace_segments(struct tcpcb *tp, struct tcp_rack *rack, uint32_t line, uint64_t *fill_override); static void rack_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, uint8_t iptos); static void rack_dtor(void *mem, int32_t size, void *arg); static void rack_log_alt_to_to_cancel(struct tcp_rack *rack, uint32_t flex1, uint32_t flex2, uint32_t flex3, uint32_t flex4, uint32_t flex5, uint32_t flex6, uint16_t flex7, uint8_t mod); static void rack_log_pacing_delay_calc(struct tcp_rack *rack, uint32_t len, uint32_t slot, uint64_t bw_est, uint64_t bw, uint64_t len_time, int method, int line, struct rack_sendmap *rsm, uint8_t quality); static struct rack_sendmap * rack_find_high_nonack(struct tcp_rack *rack, struct rack_sendmap *rsm); static struct rack_sendmap *rack_find_lowest_rsm(struct tcp_rack *rack); static void rack_free(struct tcp_rack *rack, struct rack_sendmap *rsm); static void rack_fini(struct tcpcb *tp, int32_t tcb_is_purged); static int rack_get_sockopt(struct inpcb *inp, struct sockopt *sopt); static void rack_do_goodput_measurement(struct tcpcb *tp, struct tcp_rack *rack, tcp_seq th_ack, int line, uint8_t quality); static uint32_t rack_get_pacing_len(struct tcp_rack *rack, uint64_t bw, uint32_t mss); static int32_t rack_handoff_ok(struct tcpcb *tp); static int32_t rack_init(struct tcpcb *tp); static void rack_init_sysctls(void); static void rack_log_ack(struct tcpcb *tp, struct tcpopt *to, struct tcphdr *th, int entered_rec, int dup_ack_struck); static void rack_log_output(struct tcpcb *tp, struct tcpopt *to, int32_t len, uint32_t seq_out, uint16_t th_flags, int32_t err, uint64_t ts, struct rack_sendmap *hintrsm, uint16_t add_flags, struct mbuf *s_mb, uint32_t s_moff, int hw_tls); static void rack_log_sack_passed(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendmap *rsm); static void rack_log_to_event(struct tcp_rack *rack, int32_t to_num, struct rack_sendmap *rsm); static int32_t rack_output(struct tcpcb *tp); static uint32_t rack_proc_sack_blk(struct tcpcb *tp, struct tcp_rack *rack, struct sackblk *sack, struct tcpopt *to, struct rack_sendmap **prsm, uint32_t cts, int *moved_two); static void rack_post_recovery(struct tcpcb *tp, uint32_t th_seq); static void rack_remxt_tmr(struct tcpcb *tp); static int rack_set_sockopt(struct inpcb *inp, struct sockopt *sopt); static void rack_set_state(struct tcpcb *tp, struct tcp_rack *rack); static int32_t rack_stopall(struct tcpcb *tp); static void rack_timer_cancel(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts, int line); static uint32_t rack_update_entry(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendmap *rsm, uint64_t ts, int32_t * lenp, uint16_t add_flag); static void rack_update_rsm(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendmap *rsm, uint64_t ts, uint16_t add_flag); static int rack_update_rtt(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendmap *rsm, struct tcpopt *to, uint32_t cts, int32_t ack_type, tcp_seq th_ack); static int32_t tcp_addrack(module_t mod, int32_t type, void *data); static int rack_do_close_wait(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos); static int rack_do_closing(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos); static int rack_do_established(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos); static int rack_do_fastnewdata(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t nxt_pkt, uint8_t iptos); static int rack_do_fin_wait_1(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos); static int rack_do_fin_wait_2(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos); static int rack_do_lastack(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos); static int rack_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos); static int rack_do_syn_sent(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos); struct rack_sendmap * tcp_rack_output(struct tcpcb *tp, struct tcp_rack *rack, uint32_t tsused); static void tcp_rack_xmit_timer(struct tcp_rack *rack, int32_t rtt, uint32_t len, uint32_t us_tim, int confidence, struct rack_sendmap *rsm, uint16_t rtrcnt); static void tcp_rack_partialack(struct tcpcb *tp); static int rack_set_profile(struct tcp_rack *rack, int prof); static void rack_apply_deferred_options(struct tcp_rack *rack); int32_t rack_clear_counter=0; static inline void rack_trace_point(struct tcp_rack *rack, int num) { if (((rack_trace_point_config == num) || (rack_trace_point_config = 0xffffffff)) && (rack_trace_point_bb_mode != 0) && (rack_trace_point_count > 0) && (rack->rc_tp->t_logstate == 0)) { int res; res = atomic_fetchadd_int(&rack_trace_point_count, -1); if (res > 0) { rack->rc_tp->t_logstate = rack_trace_point_bb_mode; } else { /* Loss a race assure its zero now */ rack_trace_point_count = 0; } } } static void rack_set_cc_pacing(struct tcp_rack *rack) { struct sockopt sopt; struct cc_newreno_opts opt; struct newreno old, *ptr; struct tcpcb *tp; int error; if (rack->rc_pacing_cc_set) return; tp = rack->rc_tp; if (tp->t_cc == NULL) { /* Tcb is leaving */ return; } rack->rc_pacing_cc_set = 1; if (strcmp(tp->t_cc->name, CCALGONAME_NEWRENO) != 0) { /* Not new-reno we can't play games with beta! */ goto out; } ptr = ((struct newreno *)tp->t_ccv.cc_data); if (CC_ALGO(tp)->ctl_output == NULL) { /* Huh, why does new_reno no longer have a set function? */ goto out; } if (ptr == NULL) { /* Just the default values */ old.beta = V_newreno_beta_ecn; old.beta_ecn = V_newreno_beta_ecn; old.newreno_flags = 0; } else { old.beta = ptr->beta; old.beta_ecn = ptr->beta_ecn; old.newreno_flags = ptr->newreno_flags; } sopt.sopt_valsize = sizeof(struct cc_newreno_opts); sopt.sopt_dir = SOPT_SET; opt.name = CC_NEWRENO_BETA; opt.val = rack->r_ctl.rc_saved_beta.beta; error = CC_ALGO(tp)->ctl_output(&tp->t_ccv, &sopt, &opt); if (error) { goto out; } /* * Hack alert we need to set in our newreno_flags * so that Abe behavior is also applied. */ ((struct newreno *)tp->t_ccv.cc_data)->newreno_flags |= CC_NEWRENO_BETA_ECN_ENABLED; opt.name = CC_NEWRENO_BETA_ECN; opt.val = rack->r_ctl.rc_saved_beta.beta_ecn; error = CC_ALGO(tp)->ctl_output(&tp->t_ccv, &sopt, &opt); if (error) { goto out; } /* Save off the original values for restoral */ memcpy(&rack->r_ctl.rc_saved_beta, &old, sizeof(struct newreno)); out: if (rack_verbose_logging && (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; struct timeval tv; ptr = ((struct newreno *)tp->t_ccv.cc_data); memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.timeStamp = tcp_get_usecs(&tv); if (ptr) { log.u_bbr.flex1 = ptr->beta; log.u_bbr.flex2 = ptr->beta_ecn; log.u_bbr.flex3 = ptr->newreno_flags; } log.u_bbr.flex4 = rack->r_ctl.rc_saved_beta.beta; log.u_bbr.flex5 = rack->r_ctl.rc_saved_beta.beta_ecn; log.u_bbr.flex6 = rack->r_ctl.rc_saved_beta.newreno_flags; log.u_bbr.flex7 = rack->gp_ready; log.u_bbr.flex7 <<= 1; log.u_bbr.flex7 |= rack->use_fixed_rate; log.u_bbr.flex7 <<= 1; log.u_bbr.flex7 |= rack->rc_pacing_cc_set; log.u_bbr.pkts_out = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.flex8 = 3; tcp_log_event_(tp, NULL, NULL, NULL, BBR_LOG_CWND, error, 0, &log, false, NULL, NULL, 0, &tv); } } static void rack_undo_cc_pacing(struct tcp_rack *rack) { struct newreno old, *ptr; struct tcpcb *tp; if (rack->rc_pacing_cc_set == 0) return; tp = rack->rc_tp; rack->rc_pacing_cc_set = 0; if (tp->t_cc == NULL) /* Tcb is leaving */ return; if (strcmp(tp->t_cc->name, CCALGONAME_NEWRENO) != 0) { /* Not new-reno nothing to do! */ return; } ptr = ((struct newreno *)tp->t_ccv.cc_data); if (ptr == NULL) { /* * This happens at rack_fini() if the * cc module gets freed on us. In that * case we loose our "new" settings but * thats ok, since the tcb is going away anyway. */ return; } /* Grab out our set values */ memcpy(&old, ptr, sizeof(struct newreno)); /* Copy back in the original values */ memcpy(ptr, &rack->r_ctl.rc_saved_beta, sizeof(struct newreno)); /* Now save back the values we had set in (for when pacing is restored) */ memcpy(&rack->r_ctl.rc_saved_beta, &old, sizeof(struct newreno)); if (rack_verbose_logging && (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; struct timeval tv; ptr = ((struct newreno *)tp->t_ccv.cc_data); memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.flex1 = ptr->beta; log.u_bbr.flex2 = ptr->beta_ecn; log.u_bbr.flex3 = ptr->newreno_flags; log.u_bbr.flex4 = rack->r_ctl.rc_saved_beta.beta; log.u_bbr.flex5 = rack->r_ctl.rc_saved_beta.beta_ecn; log.u_bbr.flex6 = rack->r_ctl.rc_saved_beta.newreno_flags; log.u_bbr.flex7 = rack->gp_ready; log.u_bbr.flex7 <<= 1; log.u_bbr.flex7 |= rack->use_fixed_rate; log.u_bbr.flex7 <<= 1; log.u_bbr.flex7 |= rack->rc_pacing_cc_set; log.u_bbr.pkts_out = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.flex8 = 4; tcp_log_event_(tp, NULL, NULL, NULL, BBR_LOG_CWND, 0, 0, &log, false, NULL, NULL, 0, &tv); } } #ifdef NETFLIX_PEAKRATE static inline void rack_update_peakrate_thr(struct tcpcb *tp) { /* Keep in mind that t_maxpeakrate is in B/s. */ uint64_t peak; peak = uqmax((tp->t_maxseg * 2), (((uint64_t)tp->t_maxpeakrate * (uint64_t)(tp->t_srtt)) / (uint64_t)HPTS_USEC_IN_SEC)); tp->t_peakrate_thr = (uint32_t)uqmin(peak, UINT32_MAX); } #endif static int sysctl_rack_clear(SYSCTL_HANDLER_ARGS) { uint32_t stat; int32_t error; error = SYSCTL_OUT(req, &rack_clear_counter, sizeof(uint32_t)); if (error || req->newptr == NULL) return error; error = SYSCTL_IN(req, &stat, sizeof(uint32_t)); if (error) return (error); if (stat == 1) { #ifdef INVARIANTS printf("Clearing RACK counters\n"); #endif counter_u64_zero(rack_tlp_tot); counter_u64_zero(rack_tlp_newdata); counter_u64_zero(rack_tlp_retran); counter_u64_zero(rack_tlp_retran_bytes); counter_u64_zero(rack_to_tot); counter_u64_zero(rack_saw_enobuf); counter_u64_zero(rack_saw_enobuf_hw); counter_u64_zero(rack_saw_enetunreach); counter_u64_zero(rack_persists_sends); counter_u64_zero(rack_persists_acks); counter_u64_zero(rack_persists_loss); counter_u64_zero(rack_persists_lost_ends); #ifdef INVARIANTS counter_u64_zero(rack_adjust_map_bw); #endif counter_u64_zero(rack_to_alloc_hard); counter_u64_zero(rack_to_alloc_emerg); counter_u64_zero(rack_sack_proc_all); counter_u64_zero(rack_fto_send); counter_u64_zero(rack_fto_rsm_send); counter_u64_zero(rack_extended_rfo); counter_u64_zero(rack_hw_pace_init_fail); counter_u64_zero(rack_hw_pace_lost); counter_u64_zero(rack_non_fto_send); counter_u64_zero(rack_nfto_resend); counter_u64_zero(rack_sack_proc_short); counter_u64_zero(rack_sack_proc_restart); counter_u64_zero(rack_to_alloc); counter_u64_zero(rack_to_alloc_limited); counter_u64_zero(rack_alloc_limited_conns); counter_u64_zero(rack_split_limited); counter_u64_zero(rack_multi_single_eq); counter_u64_zero(rack_proc_non_comp_ack); counter_u64_zero(rack_sack_attacks_detected); counter_u64_zero(rack_sack_attacks_reversed); counter_u64_zero(rack_sack_used_next_merge); counter_u64_zero(rack_sack_used_prev_merge); counter_u64_zero(rack_sack_splits); counter_u64_zero(rack_sack_skipped_acked); counter_u64_zero(rack_ack_total); counter_u64_zero(rack_express_sack); counter_u64_zero(rack_sack_total); counter_u64_zero(rack_move_none); counter_u64_zero(rack_move_some); counter_u64_zero(rack_try_scwnd); counter_u64_zero(rack_collapsed_win); counter_u64_zero(rack_collapsed_win_rxt); counter_u64_zero(rack_collapsed_win_seen); counter_u64_zero(rack_collapsed_win_rxt_bytes); } rack_clear_counter = 0; return (0); } static void rack_init_sysctls(void) { struct sysctl_oid *rack_counters; struct sysctl_oid *rack_attack; struct sysctl_oid *rack_pacing; struct sysctl_oid *rack_timely; struct sysctl_oid *rack_timers; struct sysctl_oid *rack_tlp; struct sysctl_oid *rack_misc; struct sysctl_oid *rack_features; struct sysctl_oid *rack_measure; struct sysctl_oid *rack_probertt; struct sysctl_oid *rack_hw_pacing; struct sysctl_oid *rack_tracepoint; rack_attack = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "sack_attack", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Rack Sack Attack Counters and Controls"); rack_counters = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "stats", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Rack Counters"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "rate_sample_method", CTLFLAG_RW, &rack_rate_sample_method , USE_RTT_LOW, "What method should we use for rate sampling 0=high, 1=low "); /* Probe rtt related controls */ rack_probertt = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "probertt", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "ProbeRTT related Controls"); SYSCTL_ADD_U16(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "exit_per_hpb", CTLFLAG_RW, &rack_atexit_prtt_hbp, 130, "What percentage above goodput do we clamp CA/SS to at exit on high-BDP path 110%"); SYSCTL_ADD_U16(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "exit_per_nonhpb", CTLFLAG_RW, &rack_atexit_prtt, 130, "What percentage above goodput do we clamp CA/SS to at exit on a non high-BDP path 100%"); SYSCTL_ADD_U16(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "gp_per_mul", CTLFLAG_RW, &rack_per_of_gp_probertt, 60, "What percentage of goodput do we pace at in probertt"); SYSCTL_ADD_U16(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "gp_per_reduce", CTLFLAG_RW, &rack_per_of_gp_probertt_reduce, 10, "What percentage of goodput do we reduce every gp_srtt"); SYSCTL_ADD_U16(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "gp_per_low", CTLFLAG_RW, &rack_per_of_gp_lowthresh, 40, "What percentage of goodput do we allow the multiplier to fall to"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "time_between", CTLFLAG_RW, & rack_time_between_probertt, 96000000, "How many useconds between the lowest rtt falling must past before we enter probertt"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "safety", CTLFLAG_RW, &rack_probe_rtt_safety_val, 2000000, "If not zero, provides a maximum usecond that you can stay in probertt (2sec = 2000000)"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "sets_cwnd", CTLFLAG_RW, &rack_probe_rtt_sets_cwnd, 0, "Do we set the cwnd too (if always_lower is on)"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "maxdrainsrtts", CTLFLAG_RW, &rack_max_drain_wait, 2, "Maximum number of gp_srtt's to hold in drain waiting for flight to reach goal"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "mustdrainsrtts", CTLFLAG_RW, &rack_must_drain, 1, "We must drain this many gp_srtt's waiting for flight to reach goal"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "goal_use_min_entry", CTLFLAG_RW, &rack_probertt_use_min_rtt_entry, 1, "Should we use the min-rtt to calculate the goal rtt (else gp_srtt) at entry"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "goal_use_min_exit", CTLFLAG_RW, &rack_probertt_use_min_rtt_exit, 0, "How to set cwnd at exit, 0 - dynamic, 1 - use min-rtt, 2 - use curgprtt, 3 - entry gp-rtt"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "length_div", CTLFLAG_RW, &rack_probertt_gpsrtt_cnt_div, 0, "How many recent goodput srtt periods plus hold tim does probertt last (bottom of fraction)"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "length_mul", CTLFLAG_RW, &rack_probertt_gpsrtt_cnt_mul, 0, "How many recent goodput srtt periods plus hold tim does probertt last (top of fraction)"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "holdtim_at_target", CTLFLAG_RW, &rack_min_probertt_hold, 200000, "What is the minimum time we hold probertt at target"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "filter_life", CTLFLAG_RW, &rack_probertt_filter_life, 10000000, "What is the time for the filters life in useconds"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "lower_within", CTLFLAG_RW, &rack_probertt_lower_within, 10, "If the rtt goes lower within this percentage of the time, go into probe-rtt"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "must_move", CTLFLAG_RW, &rack_min_rtt_movement, 250, "How much is the minimum movement in rtt to count as a drop for probertt purposes"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "clear_is_cnts", CTLFLAG_RW, &rack_probertt_clear_is, 1, "Do we clear I/S counts on exiting probe-rtt"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "hbp_extra_drain", CTLFLAG_RW, &rack_max_drain_hbp, 1, "How many extra drain gpsrtt's do we get in highly buffered paths"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "hbp_threshold", CTLFLAG_RW, &rack_hbp_thresh, 3, "We are highly buffered if min_rtt_seen / max_rtt_seen > this-threshold"); rack_tracepoint = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "tp", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Rack tracepoint facility"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tracepoint), OID_AUTO, "number", CTLFLAG_RW, &rack_trace_point_config, 0, "What is the trace point number to activate (0=none, 0xffffffff = all)?"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tracepoint), OID_AUTO, "bbmode", CTLFLAG_RW, &rack_trace_point_bb_mode, 4, "What is BB logging mode that is activated?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tracepoint), OID_AUTO, "count", CTLFLAG_RW, &rack_trace_point_count, 0, "How many connections will have BB logging turned on that hit the tracepoint?"); /* Pacing related sysctls */ rack_pacing = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "pacing", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Pacing related Controls"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_pacing), OID_AUTO, "max_pace_over", CTLFLAG_RW, &rack_max_per_above, 30, "What is the maximum allowable percentage that we can pace above (so 30 = 130% of our goal)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_pacing), OID_AUTO, "pace_to_one", CTLFLAG_RW, &rack_pace_one_seg, 0, "Do we allow low b/w pacing of 1MSS instead of two"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_pacing), OID_AUTO, "limit_wsrtt", CTLFLAG_RW, &rack_limit_time_with_srtt, 0, "Do we limit pacing time based on srtt"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_pacing), OID_AUTO, "init_win", CTLFLAG_RW, &rack_default_init_window, 0, "Do we have a rack initial window 0 = system default"); SYSCTL_ADD_U16(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_pacing), OID_AUTO, "gp_per_ss", CTLFLAG_RW, &rack_per_of_gp_ss, 250, "If non zero, what percentage of goodput to pace at in slow start"); SYSCTL_ADD_U16(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_pacing), OID_AUTO, "gp_per_ca", CTLFLAG_RW, &rack_per_of_gp_ca, 150, "If non zero, what percentage of goodput to pace at in congestion avoidance"); SYSCTL_ADD_U16(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_pacing), OID_AUTO, "gp_per_rec", CTLFLAG_RW, &rack_per_of_gp_rec, 200, "If non zero, what percentage of goodput to pace at in recovery"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_pacing), OID_AUTO, "pace_max_seg", CTLFLAG_RW, &rack_hptsi_segments, 40, "What size is the max for TSO segments in pacing and burst mitigation"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_pacing), OID_AUTO, "burst_reduces", CTLFLAG_RW, &rack_slot_reduction, 4, "When doing only burst mitigation what is the reduce divisor"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "use_pacing", CTLFLAG_RW, &rack_pace_every_seg, 0, "If set we use pacing, if clear we use only the original burst mitigation"); SYSCTL_ADD_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_pacing), OID_AUTO, "rate_cap", CTLFLAG_RW, &rack_bw_rate_cap, 0, "If set we apply this value to the absolute rate cap used by pacing"); SYSCTL_ADD_U8(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "req_measure_cnt", CTLFLAG_RW, &rack_req_measurements, 1, "If doing dynamic pacing, how many measurements must be in before we start pacing?"); /* Hardware pacing */ rack_hw_pacing = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "hdwr_pacing", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Pacing related Controls"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_hw_pacing), OID_AUTO, "rwnd_factor", CTLFLAG_RW, &rack_hw_rwnd_factor, 2, "How many times does snd_wnd need to be bigger than pace_max_seg so we will hold off and get more acks?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_hw_pacing), OID_AUTO, "pace_enobuf_mult", CTLFLAG_RW, &rack_enobuf_hw_boost_mult, 2, "By how many time_betweens should we boost the pacing time if we see a ENOBUFS?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_hw_pacing), OID_AUTO, "pace_enobuf_max", CTLFLAG_RW, &rack_enobuf_hw_max, 2, "What is the max boost the pacing time if we see a ENOBUFS?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_hw_pacing), OID_AUTO, "pace_enobuf_min", CTLFLAG_RW, &rack_enobuf_hw_min, 2, "What is the min boost the pacing time if we see a ENOBUFS?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_hw_pacing), OID_AUTO, "enable", CTLFLAG_RW, &rack_enable_hw_pacing, 0, "Should RACK attempt to use hw pacing?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_hw_pacing), OID_AUTO, "rate_cap", CTLFLAG_RW, &rack_hw_rate_caps, 1, "Does the highest hardware pacing rate cap the rate we will send at??"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_hw_pacing), OID_AUTO, "rate_min", CTLFLAG_RW, &rack_hw_rate_min, 0, "Do we need a minimum estimate of this many bytes per second in order to engage hw pacing?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_hw_pacing), OID_AUTO, "rate_to_low", CTLFLAG_RW, &rack_hw_rate_to_low, 0, "If we fall below this rate, dis-engage hw pacing?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_hw_pacing), OID_AUTO, "up_only", CTLFLAG_RW, &rack_hw_up_only, 1, "Do we allow hw pacing to lower the rate selected?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_hw_pacing), OID_AUTO, "extra_mss_precise", CTLFLAG_RW, &rack_hw_pace_extra_slots, 2, "If the rates between software and hardware match precisely how many extra time_betweens do we get?"); rack_timely = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "timely", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Rack Timely RTT Controls"); /* Timely based GP dynmics */ SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "upper", CTLFLAG_RW, &rack_gp_per_bw_mul_up, 2, "Rack timely upper range for equal b/w (in percentage)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "lower", CTLFLAG_RW, &rack_gp_per_bw_mul_down, 4, "Rack timely lower range for equal b/w (in percentage)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "rtt_max_mul", CTLFLAG_RW, &rack_gp_rtt_maxmul, 3, "Rack timely multiplier of lowest rtt for rtt_max"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "rtt_min_div", CTLFLAG_RW, &rack_gp_rtt_mindiv, 4, "Rack timely divisor used for rtt + (rtt * mul/divisor) for check for lower rtt"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "rtt_min_mul", CTLFLAG_RW, &rack_gp_rtt_minmul, 1, "Rack timely multiplier used for rtt + (rtt * mul/divisor) for check for lower rtt"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "decrease", CTLFLAG_RW, &rack_gp_decrease_per, 20, "Rack timely decrease percentage of our GP multiplication factor"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "increase", CTLFLAG_RW, &rack_gp_increase_per, 2, "Rack timely increase perentage of our GP multiplication factor"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "lowerbound", CTLFLAG_RW, &rack_per_lower_bound, 50, "Rack timely lowest percentage we allow GP multiplier to fall to"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "upperboundss", CTLFLAG_RW, &rack_per_upper_bound_ss, 0, "Rack timely highest percentage we allow GP multiplier in SS to raise to (0 is no upperbound)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "upperboundca", CTLFLAG_RW, &rack_per_upper_bound_ca, 0, "Rack timely highest percentage we allow GP multiplier to CA raise to (0 is no upperbound)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "dynamicgp", CTLFLAG_RW, &rack_do_dyn_mul, 0, "Rack timely do we enable dynmaic timely goodput by default"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "no_rec_red", CTLFLAG_RW, &rack_gp_no_rec_chg, 1, "Rack timely do we prohibit the recovery multiplier from being lowered"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "red_clear_cnt", CTLFLAG_RW, &rack_timely_dec_clear, 6, "Rack timely what threshold do we count to before another boost during b/w decent"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "max_push_rise", CTLFLAG_RW, &rack_timely_max_push_rise, 3, "Rack timely how many times do we push up with b/w increase"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "max_push_drop", CTLFLAG_RW, &rack_timely_max_push_drop, 3, "Rack timely how many times do we push back on b/w decent"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "min_segs", CTLFLAG_RW, &rack_timely_min_segs, 4, "Rack timely when setting the cwnd what is the min num segments"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "noback_max", CTLFLAG_RW, &rack_use_max_for_nobackoff, 0, "Rack timely when deciding if to backoff on a loss, do we use under max rtt else min"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "interim_timely_only", CTLFLAG_RW, &rack_timely_int_timely_only, 0, "Rack timely when doing interim timely's do we only do timely (no b/w consideration)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "nonstop", CTLFLAG_RW, &rack_timely_no_stopping, 0, "Rack timely don't stop increase"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "dec_raise_thresh", CTLFLAG_RW, &rack_down_raise_thresh, 100, "If the CA or SS is below this threshold raise on the first 3 b/w lowers (0=always)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timely), OID_AUTO, "bottom_drag_segs", CTLFLAG_RW, &rack_req_segs, 1, "Bottom dragging if not these many segments outstanding and room"); /* TLP and Rack related parameters */ rack_tlp = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "tlp", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "TLP and Rack related Controls"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "use_rrr", CTLFLAG_RW, &use_rack_rr, 1, "Do we use Rack Rapid Recovery"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "post_rec_labc", CTLFLAG_RW, &rack_max_abc_post_recovery, 2, "Since we do early recovery, do we override the l_abc to a value, if so what?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "nonrxt_use_cr", CTLFLAG_RW, &rack_non_rxt_use_cr, 0, "Do we use ss/ca rate if in recovery we are transmitting a new data chunk"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "tlpmethod", CTLFLAG_RW, &rack_tlp_threshold_use, TLP_USE_TWO_ONE, "What method do we do for TLP time calc 0=no-de-ack-comp, 1=ID, 2=2.1, 3=2.2"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "limit", CTLFLAG_RW, &rack_tlp_limit, 2, "How many TLP's can be sent without sending new data"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "use_greater", CTLFLAG_RW, &rack_tlp_use_greater, 1, "Should we use the rack_rtt time if its greater than srtt"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "tlpminto", CTLFLAG_RW, &rack_tlp_min, 10000, "TLP minimum timeout per the specification (in microseconds)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "send_oldest", CTLFLAG_RW, &rack_always_send_oldest, 0, "Should we always send the oldest TLP and RACK-TLP"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "rack_tlimit", CTLFLAG_RW, &rack_limited_retran, 0, "How many times can a rack timeout drive out sends"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "tlp_cwnd_flag", CTLFLAG_RW, &rack_lower_cwnd_at_tlp, 0, "When a TLP completes a retran should we enter recovery"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "reorder_thresh", CTLFLAG_RW, &rack_reorder_thresh, 2, "What factor for rack will be added when seeing reordering (shift right)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "rtt_tlp_thresh", CTLFLAG_RW, &rack_tlp_thresh, 1, "What divisor for TLP rtt/retran will be added (1=rtt, 2=1/2 rtt etc)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "reorder_fade", CTLFLAG_RW, &rack_reorder_fade, 60000000, "Does reorder detection fade, if so how many microseconds (0 means never)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_tlp), OID_AUTO, "pktdelay", CTLFLAG_RW, &rack_pkt_delay, 1000, "Extra RACK time (in microseconds) besides reordering thresh"); /* Timer related controls */ rack_timers = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "timers", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Timer related controls"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timers), OID_AUTO, "persmin", CTLFLAG_RW, &rack_persist_min, 250000, "What is the minimum time in microseconds between persists"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timers), OID_AUTO, "persmax", CTLFLAG_RW, &rack_persist_max, 2000000, "What is the largest delay in microseconds between persists"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timers), OID_AUTO, "delayed_ack", CTLFLAG_RW, &rack_delayed_ack_time, 40000, "Delayed ack time (40ms in microseconds)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timers), OID_AUTO, "minrto", CTLFLAG_RW, &rack_rto_min, 30000, "Minimum RTO in microseconds -- set with caution below 1000 due to TLP"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timers), OID_AUTO, "maxrto", CTLFLAG_RW, &rack_rto_max, 4000000, "Maximum RTO in microseconds -- should be at least as large as min_rto"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_timers), OID_AUTO, "minto", CTLFLAG_RW, &rack_min_to, 1000, "Minimum rack timeout in microseconds"); /* Measure controls */ rack_measure = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "measure", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Measure related controls"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_measure), OID_AUTO, "wma_divisor", CTLFLAG_RW, &rack_wma_divisor, 8, "When doing b/w calculation what is the divisor for the WMA"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_measure), OID_AUTO, "end_cwnd", CTLFLAG_RW, &rack_cwnd_block_ends_measure, 0, "Does a cwnd just-return end the measurement window (app limited)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_measure), OID_AUTO, "end_rwnd", CTLFLAG_RW, &rack_rwnd_block_ends_measure, 0, "Does an rwnd just-return end the measurement window (app limited -- not persists)"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_measure), OID_AUTO, "min_target", CTLFLAG_RW, &rack_def_data_window, 20, "What is the minimum target window (in mss) for a GP measurements"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_measure), OID_AUTO, "goal_bdp", CTLFLAG_RW, &rack_goal_bdp, 2, "What is the goal BDP to measure"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_measure), OID_AUTO, "min_srtts", CTLFLAG_RW, &rack_min_srtts, 1, "What is the goal BDP to measure"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_measure), OID_AUTO, "min_measure_tim", CTLFLAG_RW, &rack_min_measure_usec, 0, "What is the Minimum time time for a measurement if 0, this is off"); /* Features */ rack_features = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "features", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Feature controls"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_features), OID_AUTO, "cmpack", CTLFLAG_RW, &rack_use_cmp_acks, 1, "Should RACK have LRO send compressed acks"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_features), OID_AUTO, "fsb", CTLFLAG_RW, &rack_use_fsb, 1, "Should RACK use the fast send block?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_features), OID_AUTO, "rfo", CTLFLAG_RW, &rack_use_rfo, 1, "Should RACK use rack_fast_output()?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_features), OID_AUTO, "rsmrfo", CTLFLAG_RW, &rack_use_rsm_rfo, 1, "Should RACK use rack_fast_rsm_output()?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_features), OID_AUTO, "non_paced_lro_queue", CTLFLAG_RW, &rack_enable_mqueue_for_nonpaced, 0, "Should RACK use mbuf queuing for non-paced connections"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_features), OID_AUTO, "hystartplusplus", CTLFLAG_RW, &rack_do_hystart, 0, "Should RACK enable HyStart++ on connections?"); /* Misc rack controls */ rack_misc = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "misc", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Misc related controls"); #ifdef TCP_ACCOUNTING SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "tcp_acct", CTLFLAG_RW, &rack_tcp_accounting, 0, "Should we turn on TCP accounting for all rack sessions?"); #endif SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "apply_rtt_with_low_conf", CTLFLAG_RW, &rack_apply_rtt_with_reduced_conf, 0, "When a persist or keep-alive probe is not answered do we calculate rtt on subsequent answers?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "rack_dsack_ctl", CTLFLAG_RW, &rack_dsack_std_based, 3, "How do we process dsack with respect to rack timers, bit field, 3 is standards based?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "prr_addback_max", CTLFLAG_RW, &rack_prr_addbackmax, 2, "What is the maximum number of MSS we allow to be added back if prr can't send all its data?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "stats_gets_ms", CTLFLAG_RW, &rack_stats_gets_ms_rtt, 1, "What do we feed the stats framework (1 = ms_rtt, 0 = us_rtt, 2 = ms_rtt from hdwr, > 2 usec rtt from hdwr)?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "clientlowbuf", CTLFLAG_RW, &rack_client_low_buf, 0, "Client low buffer level (below this we are more aggressive in DGP exiting recovery (0 = off)?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "defprofile", CTLFLAG_RW, &rack_def_profile, 0, "Should RACK use a default profile (0=no, num == profile num)?"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "shared_cwnd", CTLFLAG_RW, &rack_enable_shared_cwnd, 1, "Should RACK try to use the shared cwnd on connections where allowed"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "limits_on_scwnd", CTLFLAG_RW, &rack_limits_scwnd, 1, "Should RACK place low end time limits on the shared cwnd feature"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "iMac_dack", CTLFLAG_RW, &rack_use_imac_dack, 0, "Should RACK try to emulate iMac delayed ack"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "no_prr", CTLFLAG_RW, &rack_disable_prr, 0, "Should RACK not use prr and only pace (must have pacing on)"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "bb_verbose", CTLFLAG_RW, &rack_verbose_logging, 0, "Should RACK black box logging be verbose"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "data_after_close", CTLFLAG_RW, &rack_ignore_data_after_close, 1, "Do we hold off sending a RST until all pending data is ack'd"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "no_sack_needed", CTLFLAG_RW, &rack_sack_not_required, 1, "Do we allow rack to run on connections not supporting SACK"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "prr_sendalot", CTLFLAG_RW, &rack_send_a_lot_in_prr, 1, "Send a lot in prr"); SYSCTL_ADD_S32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_misc), OID_AUTO, "autoscale", CTLFLAG_RW, &rack_autosndbuf_inc, 20, "What percentage should rack scale up its snd buffer by?"); /* Sack Attacker detection stuff */ SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "detect_highsackratio", CTLFLAG_RW, &rack_highest_sack_thresh_seen, 0, "Highest sack to ack ratio seen"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "detect_highmoveratio", CTLFLAG_RW, &rack_highest_move_thresh_seen, 0, "Highest move to non-move ratio seen"); rack_ack_total = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "acktotal", CTLFLAG_RD, &rack_ack_total, "Total number of Ack's"); rack_express_sack = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "exp_sacktotal", CTLFLAG_RD, &rack_express_sack, "Total expresss number of Sack's"); rack_sack_total = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "sacktotal", CTLFLAG_RD, &rack_sack_total, "Total number of SACKs"); rack_move_none = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "move_none", CTLFLAG_RD, &rack_move_none, "Total number of SACK index reuse of positions under threshold"); rack_move_some = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "move_some", CTLFLAG_RD, &rack_move_some, "Total number of SACK index reuse of positions over threshold"); rack_sack_attacks_detected = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "attacks", CTLFLAG_RD, &rack_sack_attacks_detected, "Total number of SACK attackers that had sack disabled"); rack_sack_attacks_reversed = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "reversed", CTLFLAG_RD, &rack_sack_attacks_reversed, "Total number of SACK attackers that were later determined false positive"); rack_sack_used_next_merge = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "nextmerge", CTLFLAG_RD, &rack_sack_used_next_merge, "Total number of times we used the next merge"); rack_sack_used_prev_merge = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "prevmerge", CTLFLAG_RD, &rack_sack_used_prev_merge, "Total number of times we used the prev merge"); /* Counters */ rack_fto_send = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "fto_send", CTLFLAG_RD, &rack_fto_send, "Total number of rack_fast_output sends"); rack_fto_rsm_send = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "fto_rsm_send", CTLFLAG_RD, &rack_fto_rsm_send, "Total number of rack_fast_rsm_output sends"); rack_nfto_resend = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "nfto_resend", CTLFLAG_RD, &rack_nfto_resend, "Total number of rack_output retransmissions"); rack_non_fto_send = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "nfto_send", CTLFLAG_RD, &rack_non_fto_send, "Total number of rack_output first sends"); rack_extended_rfo = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "rfo_extended", CTLFLAG_RD, &rack_extended_rfo, "Total number of times we extended rfo"); rack_hw_pace_init_fail = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "hwpace_init_fail", CTLFLAG_RD, &rack_hw_pace_init_fail, "Total number of times we failed to initialize hw pacing"); rack_hw_pace_lost = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "hwpace_lost", CTLFLAG_RD, &rack_hw_pace_lost, "Total number of times we failed to initialize hw pacing"); rack_tlp_tot = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "tlp_to_total", CTLFLAG_RD, &rack_tlp_tot, "Total number of tail loss probe expirations"); rack_tlp_newdata = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "tlp_new", CTLFLAG_RD, &rack_tlp_newdata, "Total number of tail loss probe sending new data"); rack_tlp_retran = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "tlp_retran", CTLFLAG_RD, &rack_tlp_retran, "Total number of tail loss probe sending retransmitted data"); rack_tlp_retran_bytes = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "tlp_retran_bytes", CTLFLAG_RD, &rack_tlp_retran_bytes, "Total bytes of tail loss probe sending retransmitted data"); rack_to_tot = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "rack_to_tot", CTLFLAG_RD, &rack_to_tot, "Total number of times the rack to expired"); rack_saw_enobuf = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "saw_enobufs", CTLFLAG_RD, &rack_saw_enobuf, "Total number of times a sends returned enobuf for non-hdwr paced connections"); rack_saw_enobuf_hw = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "saw_enobufs_hw", CTLFLAG_RD, &rack_saw_enobuf_hw, "Total number of times a send returned enobuf for hdwr paced connections"); rack_saw_enetunreach = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "saw_enetunreach", CTLFLAG_RD, &rack_saw_enetunreach, "Total number of times a send received a enetunreachable"); rack_hot_alloc = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "alloc_hot", CTLFLAG_RD, &rack_hot_alloc, "Total allocations from the top of our list"); rack_to_alloc = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "allocs", CTLFLAG_RD, &rack_to_alloc, "Total allocations of tracking structures"); rack_to_alloc_hard = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "allochard", CTLFLAG_RD, &rack_to_alloc_hard, "Total allocations done with sleeping the hard way"); rack_to_alloc_emerg = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "allocemerg", CTLFLAG_RD, &rack_to_alloc_emerg, "Total allocations done from emergency cache"); rack_to_alloc_limited = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "alloc_limited", CTLFLAG_RD, &rack_to_alloc_limited, "Total allocations dropped due to limit"); rack_alloc_limited_conns = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "alloc_limited_conns", CTLFLAG_RD, &rack_alloc_limited_conns, "Connections with allocations dropped due to limit"); rack_split_limited = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "split_limited", CTLFLAG_RD, &rack_split_limited, "Split allocations dropped due to limit"); rack_persists_sends = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "persist_sends", CTLFLAG_RD, &rack_persists_sends, "Number of times we sent a persist probe"); rack_persists_acks = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "persist_acks", CTLFLAG_RD, &rack_persists_acks, "Number of times a persist probe was acked"); rack_persists_loss = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "persist_loss", CTLFLAG_RD, &rack_persists_loss, "Number of times we detected a lost persist probe (no ack)"); rack_persists_lost_ends = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "persist_loss_ends", CTLFLAG_RD, &rack_persists_lost_ends, "Number of lost persist probe (no ack) that the run ended with a PERSIST abort"); #ifdef INVARIANTS rack_adjust_map_bw = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "map_adjust_req", CTLFLAG_RD, &rack_adjust_map_bw, "Number of times we hit the case where the sb went up and down on a sendmap entry"); #endif rack_multi_single_eq = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "cmp_ack_equiv", CTLFLAG_RD, &rack_multi_single_eq, "Number of compressed acks total represented"); rack_proc_non_comp_ack = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "cmp_ack_not", CTLFLAG_RD, &rack_proc_non_comp_ack, "Number of non compresseds acks that we processed"); rack_sack_proc_all = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "sack_long", CTLFLAG_RD, &rack_sack_proc_all, "Total times we had to walk whole list for sack processing"); rack_sack_proc_restart = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "sack_restart", CTLFLAG_RD, &rack_sack_proc_restart, "Total times we had to walk whole list due to a restart"); rack_sack_proc_short = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "sack_short", CTLFLAG_RD, &rack_sack_proc_short, "Total times we took shortcut for sack processing"); rack_sack_skipped_acked = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "skipacked", CTLFLAG_RD, &rack_sack_skipped_acked, "Total number of times we skipped previously sacked"); rack_sack_splits = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_attack), OID_AUTO, "ofsplit", CTLFLAG_RD, &rack_sack_splits, "Total number of times we did the old fashion tree split"); rack_input_idle_reduces = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "idle_reduce_oninput", CTLFLAG_RD, &rack_input_idle_reduces, "Total number of idle reductions on input"); rack_collapsed_win_seen = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "collapsed_win_seen", CTLFLAG_RD, &rack_collapsed_win_seen, "Total number of collapsed window events seen (where our window shrinks)"); rack_collapsed_win = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "collapsed_win", CTLFLAG_RD, &rack_collapsed_win, "Total number of collapsed window events where we mark packets"); rack_collapsed_win_rxt = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "collapsed_win_rxt", CTLFLAG_RD, &rack_collapsed_win_rxt, "Total number of packets that were retransmitted"); rack_collapsed_win_rxt_bytes = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "collapsed_win_bytes", CTLFLAG_RD, &rack_collapsed_win_rxt_bytes, "Total number of bytes that were retransmitted"); rack_try_scwnd = counter_u64_alloc(M_WAITOK); SYSCTL_ADD_COUNTER_U64(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_counters), OID_AUTO, "tried_scwnd", CTLFLAG_RD, &rack_try_scwnd, "Total number of scwnd attempts"); COUNTER_ARRAY_ALLOC(rack_out_size, TCP_MSS_ACCT_SIZE, M_WAITOK); SYSCTL_ADD_COUNTER_U64_ARRAY(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "outsize", CTLFLAG_RD, rack_out_size, TCP_MSS_ACCT_SIZE, "MSS send sizes"); COUNTER_ARRAY_ALLOC(rack_opts_arry, RACK_OPTS_SIZE, M_WAITOK); SYSCTL_ADD_COUNTER_U64_ARRAY(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "opts", CTLFLAG_RD, rack_opts_arry, RACK_OPTS_SIZE, "RACK Option Stats"); SYSCTL_ADD_PROC(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_sysctl_root), OID_AUTO, "clear", CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, &rack_clear_counter, 0, sysctl_rack_clear, "IU", "Clear counters"); } static __inline int rb_map_cmp(struct rack_sendmap *b, struct rack_sendmap *a) { if (SEQ_GEQ(b->r_start, a->r_start) && SEQ_LT(b->r_start, a->r_end)) { /* * The entry b is within the * block a. i.e.: * a -- |-------------| * b -- |----| * * b -- |------| * * b -- |-----------| */ return (0); } else if (SEQ_GEQ(b->r_start, a->r_end)) { /* * b falls as either the next * sequence block after a so a * is said to be smaller than b. * i.e: * a -- |------| * b -- |--------| * or * b -- |-----| */ return (1); } /* * Whats left is where a is * larger than b. i.e: * a -- |-------| * b -- |---| * or even possibly * b -- |--------------| */ return (-1); } RB_PROTOTYPE(rack_rb_tree_head, rack_sendmap, r_next, rb_map_cmp); RB_GENERATE(rack_rb_tree_head, rack_sendmap, r_next, rb_map_cmp); static uint32_t rc_init_window(struct tcp_rack *rack) { uint32_t win; if (rack->rc_init_win == 0) { /* * Nothing set by the user, use the system stack * default. */ return (tcp_compute_initwnd(tcp_maxseg(rack->rc_tp))); } win = ctf_fixed_maxseg(rack->rc_tp) * rack->rc_init_win; return (win); } static uint64_t rack_get_fixed_pacing_bw(struct tcp_rack *rack) { if (IN_FASTRECOVERY(rack->rc_tp->t_flags)) return (rack->r_ctl.rc_fixed_pacing_rate_rec); else if (rack->r_ctl.cwnd_to_use < rack->rc_tp->snd_ssthresh) return (rack->r_ctl.rc_fixed_pacing_rate_ss); else return (rack->r_ctl.rc_fixed_pacing_rate_ca); } static uint64_t rack_get_bw(struct tcp_rack *rack) { if (rack->use_fixed_rate) { /* Return the fixed pacing rate */ return (rack_get_fixed_pacing_bw(rack)); } if (rack->r_ctl.gp_bw == 0) { /* * We have yet no b/w measurement, * if we have a user set initial bw * return it. If we don't have that and * we have an srtt, use the tcp IW (10) to * calculate a fictional b/w over the SRTT * which is more or less a guess. Note * we don't use our IW from rack on purpose * so if we have like IW=30, we are not * calculating a "huge" b/w. */ uint64_t bw, srtt; if (rack->r_ctl.init_rate) return (rack->r_ctl.init_rate); /* Has the user set a max peak rate? */ #ifdef NETFLIX_PEAKRATE if (rack->rc_tp->t_maxpeakrate) return (rack->rc_tp->t_maxpeakrate); #endif /* Ok lets come up with the IW guess, if we have a srtt */ if (rack->rc_tp->t_srtt == 0) { /* * Go with old pacing method * i.e. burst mitigation only. */ return (0); } /* Ok lets get the initial TCP win (not racks) */ bw = tcp_compute_initwnd(tcp_maxseg(rack->rc_tp)); srtt = (uint64_t)rack->rc_tp->t_srtt; bw *= (uint64_t)USECS_IN_SECOND; bw /= srtt; if (rack->r_ctl.bw_rate_cap && (bw > rack->r_ctl.bw_rate_cap)) bw = rack->r_ctl.bw_rate_cap; return (bw); } else { uint64_t bw; if (rack->r_ctl.num_measurements >= RACK_REQ_AVG) { /* Averaging is done, we can return the value */ bw = rack->r_ctl.gp_bw; } else { /* Still doing initial average must calculate */ bw = rack->r_ctl.gp_bw / rack->r_ctl.num_measurements; } #ifdef NETFLIX_PEAKRATE if ((rack->rc_tp->t_maxpeakrate) && (bw > rack->rc_tp->t_maxpeakrate)) { /* The user has set a peak rate to pace at * don't allow us to pace faster than that. */ return (rack->rc_tp->t_maxpeakrate); } #endif if (rack->r_ctl.bw_rate_cap && (bw > rack->r_ctl.bw_rate_cap)) bw = rack->r_ctl.bw_rate_cap; return (bw); } } static uint16_t rack_get_output_gain(struct tcp_rack *rack, struct rack_sendmap *rsm) { if (rack->use_fixed_rate) { return (100); } else if (rack->in_probe_rtt && (rsm == NULL)) return (rack->r_ctl.rack_per_of_gp_probertt); else if ((IN_FASTRECOVERY(rack->rc_tp->t_flags) && rack->r_ctl.rack_per_of_gp_rec)) { if (rsm) { /* a retransmission always use the recovery rate */ return (rack->r_ctl.rack_per_of_gp_rec); } else if (rack->rack_rec_nonrxt_use_cr) { /* Directed to use the configured rate */ goto configured_rate; } else if (rack->rack_no_prr && (rack->r_ctl.rack_per_of_gp_rec > 100)) { /* No PRR, lets just use the b/w estimate only */ return (100); } else { /* * Here we may have a non-retransmit but we * have no overrides, so just use the recovery * rate (prr is in effect). */ return (rack->r_ctl.rack_per_of_gp_rec); } } configured_rate: /* For the configured rate we look at our cwnd vs the ssthresh */ if (rack->r_ctl.cwnd_to_use < rack->rc_tp->snd_ssthresh) return (rack->r_ctl.rack_per_of_gp_ss); else return (rack->r_ctl.rack_per_of_gp_ca); } static void rack_log_dsack_event(struct tcp_rack *rack, uint8_t mod, uint32_t flex4, uint32_t flex5, uint32_t flex6) { /* * Types of logs (mod value) * 1 = dsack_persists reduced by 1 via T-O or fast recovery exit. * 2 = a dsack round begins, persist is reset to 16. * 3 = a dsack round ends * 4 = Dsack option increases rack rtt flex5 is the srtt input, flex6 is thresh * 5 = Socket option set changing the control flags rc_rack_tmr_std_based, rc_rack_use_dsack * 6 = Final rack rtt, flex4 is srtt and flex6 is final limited thresh. */ if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log, 0, sizeof(log)); log.u_bbr.flex1 = rack->rc_rack_tmr_std_based; log.u_bbr.flex1 <<= 1; log.u_bbr.flex1 |= rack->rc_rack_use_dsack; log.u_bbr.flex1 <<= 1; log.u_bbr.flex1 |= rack->rc_dsack_round_seen; log.u_bbr.flex2 = rack->r_ctl.dsack_round_end; log.u_bbr.flex3 = rack->r_ctl.num_dsack; log.u_bbr.flex4 = flex4; log.u_bbr.flex5 = flex5; log.u_bbr.flex6 = flex6; log.u_bbr.flex7 = rack->r_ctl.dsack_persist; log.u_bbr.flex8 = mod; log.u_bbr.timeStamp = tcp_get_usecs(&tv); TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, RACK_DSACK_HANDLING, 0, 0, &log, false, &tv); } } static void rack_log_hdwr_pacing(struct tcp_rack *rack, uint64_t rate, uint64_t hw_rate, int line, int error, uint16_t mod) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; const struct ifnet *ifp; memset(&log, 0, sizeof(log)); log.u_bbr.flex1 = ((hw_rate >> 32) & 0x00000000ffffffff); log.u_bbr.flex2 = (hw_rate & 0x00000000ffffffff); if (rack->r_ctl.crte) { ifp = rack->r_ctl.crte->ptbl->rs_ifp; } else if (rack->rc_inp->inp_route.ro_nh && rack->rc_inp->inp_route.ro_nh->nh_ifp) { ifp = rack->rc_inp->inp_route.ro_nh->nh_ifp; } else ifp = NULL; if (ifp) { log.u_bbr.flex3 = (((uint64_t)ifp >> 32) & 0x00000000ffffffff); log.u_bbr.flex4 = ((uint64_t)ifp & 0x00000000ffffffff); } log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.bw_inuse = rate; log.u_bbr.flex5 = line; log.u_bbr.flex6 = error; log.u_bbr.flex7 = mod; log.u_bbr.applimited = rack->r_ctl.rc_pace_max_segs; log.u_bbr.flex8 = rack->use_fixed_rate; log.u_bbr.flex8 <<= 1; log.u_bbr.flex8 |= rack->rack_hdrw_pacing; log.u_bbr.pkts_out = rack->rc_tp->t_maxseg; log.u_bbr.delRate = rack->r_ctl.crte_prev_rate; if (rack->r_ctl.crte) log.u_bbr.cur_del_rate = rack->r_ctl.crte->rate; else log.u_bbr.cur_del_rate = 0; log.u_bbr.rttProp = rack->r_ctl.last_hw_bw_req; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_HDWR_PACE, 0, 0, &log, false, &tv); } } static uint64_t rack_get_output_bw(struct tcp_rack *rack, uint64_t bw, struct rack_sendmap *rsm, int *capped) { /* * We allow rack_per_of_gp_xx to dictate our bw rate we want. */ uint64_t bw_est, high_rate; uint64_t gain; gain = (uint64_t)rack_get_output_gain(rack, rsm); bw_est = bw * gain; bw_est /= (uint64_t)100; /* Never fall below the minimum (def 64kbps) */ if (bw_est < RACK_MIN_BW) bw_est = RACK_MIN_BW; if (rack->r_rack_hw_rate_caps) { /* Rate caps are in place */ if (rack->r_ctl.crte != NULL) { /* We have a hdwr rate already */ high_rate = tcp_hw_highest_rate(rack->r_ctl.crte); if (bw_est >= high_rate) { /* We are capping bw at the highest rate table entry */ rack_log_hdwr_pacing(rack, bw_est, high_rate, __LINE__, 0, 3); bw_est = high_rate; if (capped) *capped = 1; } } else if ((rack->rack_hdrw_pacing == 0) && (rack->rack_hdw_pace_ena) && (rack->rack_attempt_hdwr_pace == 0) && (rack->rc_inp->inp_route.ro_nh != NULL) && (rack->rc_inp->inp_route.ro_nh->nh_ifp != NULL)) { /* * Special case, we have not yet attempted hardware * pacing, and yet we may, when we do, find out if we are * above the highest rate. We need to know the maxbw for the interface * in question (if it supports ratelimiting). We get back * a 0, if the interface is not found in the RL lists. */ high_rate = tcp_hw_highest_rate_ifp(rack->rc_inp->inp_route.ro_nh->nh_ifp, rack->rc_inp); if (high_rate) { /* Yep, we have a rate is it above this rate? */ if (bw_est > high_rate) { bw_est = high_rate; if (capped) *capped = 1; } } } } return (bw_est); } static void rack_log_retran_reason(struct tcp_rack *rack, struct rack_sendmap *rsm, uint32_t tsused, uint32_t thresh, int mod) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; if ((mod != 1) && (rack_verbose_logging == 0)) { /* * We get 3 values currently for mod * 1 - We are retransmitting and this tells the reason. * 2 - We are clearing a dup-ack count. * 3 - We are incrementing a dup-ack count. * * The clear/increment are only logged * if you have BBverbose on. */ return; } memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.flex1 = tsused; log.u_bbr.flex2 = thresh; log.u_bbr.flex3 = rsm->r_flags; log.u_bbr.flex4 = rsm->r_dupack; log.u_bbr.flex5 = rsm->r_start; log.u_bbr.flex6 = rsm->r_end; log.u_bbr.flex8 = mod; log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.pkts_out = rack->r_ctl.rc_out_at_rto; log.u_bbr.delivered = rack->r_ctl.rc_snd_max_at_rto; log.u_bbr.pacing_gain = rack->r_must_retran; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_SETTINGS_CHG, 0, 0, &log, false, &tv); } } static void rack_log_to_start(struct tcp_rack *rack, uint32_t cts, uint32_t to, int32_t slot, uint8_t which) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.flex1 = rack->rc_tp->t_srtt; log.u_bbr.flex2 = to; log.u_bbr.flex3 = rack->r_ctl.rc_hpts_flags; log.u_bbr.flex4 = slot; log.u_bbr.flex5 = rack->rc_inp->inp_hptsslot; log.u_bbr.flex6 = rack->rc_tp->t_rxtcur; log.u_bbr.flex7 = rack->rc_in_persist; log.u_bbr.flex8 = which; if (rack->rack_no_prr) log.u_bbr.pkts_out = 0; else log.u_bbr.pkts_out = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.pkts_out = rack->r_ctl.rc_out_at_rto; log.u_bbr.delivered = rack->r_ctl.rc_snd_max_at_rto; log.u_bbr.pacing_gain = rack->r_must_retran; log.u_bbr.cwnd_gain = rack->rc_has_collapsed; log.u_bbr.lt_epoch = rack->rc_tp->t_rxtshift; log.u_bbr.lost = rack_rto_min; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_TIMERSTAR, 0, 0, &log, false, &tv); } } static void rack_log_to_event(struct tcp_rack *rack, int32_t to_num, struct rack_sendmap *rsm) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); log.u_bbr.flex8 = to_num; log.u_bbr.flex1 = rack->r_ctl.rc_rack_min_rtt; log.u_bbr.flex2 = rack->rc_rack_rtt; if (rsm == NULL) log.u_bbr.flex3 = 0; else log.u_bbr.flex3 = rsm->r_end - rsm->r_start; if (rack->rack_no_prr) log.u_bbr.flex5 = 0; else log.u_bbr.flex5 = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.pkts_out = rack->r_ctl.rc_out_at_rto; log.u_bbr.delivered = rack->r_ctl.rc_snd_max_at_rto; log.u_bbr.pacing_gain = rack->r_must_retran; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_RTO, 0, 0, &log, false, &tv); } } static void rack_log_map_chg(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendmap *prev, struct rack_sendmap *rsm, struct rack_sendmap *next, int flag, uint32_t th_ack, int line) { if (rack_verbose_logging && (tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.flex8 = flag; log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); log.u_bbr.cur_del_rate = (uint64_t)prev; log.u_bbr.delRate = (uint64_t)rsm; log.u_bbr.rttProp = (uint64_t)next; log.u_bbr.flex7 = 0; if (prev) { log.u_bbr.flex1 = prev->r_start; log.u_bbr.flex2 = prev->r_end; log.u_bbr.flex7 |= 0x4; } if (rsm) { log.u_bbr.flex3 = rsm->r_start; log.u_bbr.flex4 = rsm->r_end; log.u_bbr.flex7 |= 0x2; } if (next) { log.u_bbr.flex5 = next->r_start; log.u_bbr.flex6 = next->r_end; log.u_bbr.flex7 |= 0x1; } log.u_bbr.applimited = line; log.u_bbr.pkts_out = th_ack; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); if (rack->rack_no_prr) log.u_bbr.lost = 0; else log.u_bbr.lost = rack->r_ctl.rc_prr_sndcnt; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, TCP_LOG_MAPCHG, 0, 0, &log, false, &tv); } } static void rack_log_rtt_upd(struct tcpcb *tp, struct tcp_rack *rack, uint32_t t, uint32_t len, struct rack_sendmap *rsm, int conf) { if (tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); log.u_bbr.flex1 = t; log.u_bbr.flex2 = len; log.u_bbr.flex3 = rack->r_ctl.rc_rack_min_rtt; log.u_bbr.flex4 = rack->r_ctl.rack_rs.rs_rtt_lowest; log.u_bbr.flex5 = rack->r_ctl.rack_rs.rs_rtt_highest; log.u_bbr.flex6 = rack->r_ctl.rack_rs.rs_us_rtrcnt; log.u_bbr.flex7 = conf; log.u_bbr.rttProp = (uint64_t)rack->r_ctl.rack_rs.rs_rtt_tot; log.u_bbr.flex8 = rack->r_ctl.rc_rate_sample_method; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.delivered = rack->r_ctl.rack_rs.rs_us_rtrcnt; log.u_bbr.pkts_out = rack->r_ctl.rack_rs.rs_flags; log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); if (rsm) { log.u_bbr.pkt_epoch = rsm->r_start; log.u_bbr.lost = rsm->r_end; log.u_bbr.cwnd_gain = rsm->r_rtr_cnt; /* We loose any upper of the 24 bits */ log.u_bbr.pacing_gain = (uint16_t)rsm->r_flags; } else { /* Its a SYN */ log.u_bbr.pkt_epoch = rack->rc_tp->iss; log.u_bbr.lost = 0; log.u_bbr.cwnd_gain = 0; log.u_bbr.pacing_gain = 0; } /* Write out general bits of interest rrs here */ log.u_bbr.use_lt_bw = rack->rc_highly_buffered; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->forced_ack; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->rc_gp_dyn_mul; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->in_probe_rtt; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->measure_saw_probe_rtt; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->app_limited_needs_set; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->rc_gp_filled; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->rc_dragged_bottom; log.u_bbr.applimited = rack->r_ctl.rc_target_probertt_flight; log.u_bbr.epoch = rack->r_ctl.rc_time_probertt_starts; log.u_bbr.lt_epoch = rack->r_ctl.rc_time_probertt_entered; log.u_bbr.cur_del_rate = rack->r_ctl.rc_lower_rtt_us_cts; log.u_bbr.delRate = rack->r_ctl.rc_gp_srtt; log.u_bbr.bw_inuse = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); log.u_bbr.bw_inuse <<= 32; if (rsm) log.u_bbr.bw_inuse |= ((uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]); TCP_LOG_EVENTP(tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_BBRRTT, 0, 0, &log, false, &tv); } } static void rack_log_rtt_sample(struct tcp_rack *rack, uint32_t rtt) { /* * Log the rtt sample we are * applying to the srtt algorithm in * useconds. */ if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; /* Convert our ms to a microsecond */ memset(&log, 0, sizeof(log)); log.u_bbr.flex1 = rtt; log.u_bbr.flex2 = rack->r_ctl.ack_count; log.u_bbr.flex3 = rack->r_ctl.sack_count; log.u_bbr.flex4 = rack->r_ctl.sack_noextra_move; log.u_bbr.flex5 = rack->r_ctl.sack_moved_extra; log.u_bbr.flex6 = rack->rc_tp->t_rxtcur; log.u_bbr.flex7 = 1; log.u_bbr.flex8 = rack->sack_attack_disable; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.pkts_out = rack->r_ctl.rc_out_at_rto; log.u_bbr.delivered = rack->r_ctl.rc_snd_max_at_rto; log.u_bbr.pacing_gain = rack->r_must_retran; /* * We capture in delRate the upper 32 bits as * the confidence level we had declared, and the * lower 32 bits as the actual RTT using the arrival * timestamp. */ log.u_bbr.delRate = rack->r_ctl.rack_rs.confidence; log.u_bbr.delRate <<= 32; log.u_bbr.delRate |= rack->r_ctl.rack_rs.rs_us_rtt; /* Lets capture all the things that make up t_rtxcur */ log.u_bbr.applimited = rack_rto_min; log.u_bbr.epoch = rack_rto_max; log.u_bbr.lt_epoch = rack->r_ctl.timer_slop; log.u_bbr.lost = rack_rto_min; log.u_bbr.pkt_epoch = TICKS_2_USEC(tcp_rexmit_slop); log.u_bbr.rttProp = RACK_REXMTVAL(rack->rc_tp); log.u_bbr.bw_inuse = rack->r_ctl.act_rcv_time.tv_sec; log.u_bbr.bw_inuse *= HPTS_USEC_IN_SEC; log.u_bbr.bw_inuse += rack->r_ctl.act_rcv_time.tv_usec; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, TCP_LOG_RTT, 0, 0, &log, false, &tv); } } static void rack_log_rtt_sample_calc(struct tcp_rack *rack, uint32_t rtt, uint32_t send_time, uint32_t ack_time, int where) { if (rack_verbose_logging && (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; struct timeval tv; /* Convert our ms to a microsecond */ memset(&log, 0, sizeof(log)); log.u_bbr.flex1 = rtt; log.u_bbr.flex2 = send_time; log.u_bbr.flex3 = ack_time; log.u_bbr.flex4 = where; log.u_bbr.flex7 = 2; log.u_bbr.timeStamp = tcp_get_usecs(&tv); TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, TCP_LOG_RTT, 0, 0, &log, false, &tv); } } static inline void rack_log_progress_event(struct tcp_rack *rack, struct tcpcb *tp, uint32_t tick, int event, int line) { if (rack_verbose_logging && (tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); log.u_bbr.flex1 = line; log.u_bbr.flex2 = tick; log.u_bbr.flex3 = tp->t_maxunacktime; log.u_bbr.flex4 = tp->t_acktime; log.u_bbr.flex8 = event; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.pkts_out = rack->r_ctl.rc_out_at_rto; log.u_bbr.delivered = rack->r_ctl.rc_snd_max_at_rto; log.u_bbr.pacing_gain = rack->r_must_retran; TCP_LOG_EVENTP(tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_PROGRESS, 0, 0, &log, false, &tv); } } static void rack_log_type_bbrsnd(struct tcp_rack *rack, uint32_t len, uint32_t slot, uint32_t cts, struct timeval *tv) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); log.u_bbr.flex1 = slot; if (rack->rack_no_prr) log.u_bbr.flex2 = 0; else log.u_bbr.flex2 = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.flex7 = (0x0000ffff & rack->r_ctl.rc_hpts_flags); log.u_bbr.flex8 = rack->rc_in_persist; log.u_bbr.timeStamp = cts; log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.pkts_out = rack->r_ctl.rc_out_at_rto; log.u_bbr.delivered = rack->r_ctl.rc_snd_max_at_rto; log.u_bbr.pacing_gain = rack->r_must_retran; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_BBRSND, 0, 0, &log, false, tv); } } static void rack_log_doseg_done(struct tcp_rack *rack, uint32_t cts, int32_t nxt_pkt, int32_t did_out, int way_out, int nsegs) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log, 0, sizeof(log)); log.u_bbr.flex1 = did_out; log.u_bbr.flex2 = nxt_pkt; log.u_bbr.flex3 = way_out; log.u_bbr.flex4 = rack->r_ctl.rc_hpts_flags; if (rack->rack_no_prr) log.u_bbr.flex5 = 0; else log.u_bbr.flex5 = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.flex6 = nsegs; log.u_bbr.applimited = rack->r_ctl.rc_pace_min_segs; log.u_bbr.flex7 = rack->rc_ack_can_sendout_data; /* Do we have ack-can-send set */ log.u_bbr.flex7 <<= 1; log.u_bbr.flex7 |= rack->r_fast_output; /* is fast output primed */ log.u_bbr.flex7 <<= 1; log.u_bbr.flex7 |= rack->r_wanted_output; /* Do we want output */ log.u_bbr.flex8 = rack->rc_in_persist; log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.use_lt_bw = rack->r_ent_rec_ns; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->r_might_revert; log.u_bbr.pkts_out = rack->r_ctl.rc_out_at_rto; log.u_bbr.delivered = rack->r_ctl.rc_snd_max_at_rto; log.u_bbr.pacing_gain = rack->r_must_retran; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_DOSEG_DONE, 0, 0, &log, false, &tv); } } static void rack_log_type_pacing_sizes(struct tcpcb *tp, struct tcp_rack *rack, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint8_t frm) { if (tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log, 0, sizeof(log)); log.u_bbr.flex1 = rack->r_ctl.rc_pace_min_segs; log.u_bbr.flex3 = rack->r_ctl.rc_pace_max_segs; log.u_bbr.flex4 = arg1; log.u_bbr.flex5 = arg2; log.u_bbr.flex6 = arg3; log.u_bbr.flex8 = frm; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.pkts_out = rack->r_ctl.rc_out_at_rto; log.u_bbr.applimited = rack->r_ctl.rc_sacked; log.u_bbr.delivered = rack->r_ctl.rc_snd_max_at_rto; log.u_bbr.pacing_gain = rack->r_must_retran; TCP_LOG_EVENTP(tp, NULL, &tptosocket(tp)->so_rcv, &tptosocket(tp)->so_snd, TCP_HDWR_PACE_SIZE, 0, 0, &log, false, &tv); } } static void rack_log_type_just_return(struct tcp_rack *rack, uint32_t cts, uint32_t tlen, uint32_t slot, uint8_t hpts_calling, int reason, uint32_t cwnd_to_use) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); log.u_bbr.flex1 = slot; log.u_bbr.flex2 = rack->r_ctl.rc_hpts_flags; log.u_bbr.flex4 = reason; if (rack->rack_no_prr) log.u_bbr.flex5 = 0; else log.u_bbr.flex5 = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.flex7 = hpts_calling; log.u_bbr.flex8 = rack->rc_in_persist; log.u_bbr.lt_epoch = cwnd_to_use; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.pkts_out = rack->r_ctl.rc_out_at_rto; log.u_bbr.delivered = rack->r_ctl.rc_snd_max_at_rto; log.u_bbr.pacing_gain = rack->r_must_retran; log.u_bbr.cwnd_gain = rack->rc_has_collapsed; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_JUSTRET, 0, tlen, &log, false, &tv); } } static void rack_log_to_cancel(struct tcp_rack *rack, int32_t hpts_removed, int line, uint32_t us_cts, struct timeval *tv, uint32_t flags_on_entry) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); log.u_bbr.flex1 = line; log.u_bbr.flex2 = rack->r_ctl.rc_last_output_to; log.u_bbr.flex3 = flags_on_entry; log.u_bbr.flex4 = us_cts; if (rack->rack_no_prr) log.u_bbr.flex5 = 0; else log.u_bbr.flex5 = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.flex6 = rack->rc_tp->t_rxtcur; log.u_bbr.flex7 = hpts_removed; log.u_bbr.flex8 = 1; log.u_bbr.applimited = rack->r_ctl.rc_hpts_flags; log.u_bbr.timeStamp = us_cts; log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.pkts_out = rack->r_ctl.rc_out_at_rto; log.u_bbr.delivered = rack->r_ctl.rc_snd_max_at_rto; log.u_bbr.pacing_gain = rack->r_must_retran; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_TIMERCANC, 0, 0, &log, false, tv); } } static void rack_log_alt_to_to_cancel(struct tcp_rack *rack, uint32_t flex1, uint32_t flex2, uint32_t flex3, uint32_t flex4, uint32_t flex5, uint32_t flex6, uint16_t flex7, uint8_t mod) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; if (mod == 1) { /* No you can't use 1, its for the real to cancel */ return; } memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.flex1 = flex1; log.u_bbr.flex2 = flex2; log.u_bbr.flex3 = flex3; log.u_bbr.flex4 = flex4; log.u_bbr.flex5 = flex5; log.u_bbr.flex6 = flex6; log.u_bbr.flex7 = flex7; log.u_bbr.flex8 = mod; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_TIMERCANC, 0, 0, &log, false, &tv); } } static void rack_log_to_processing(struct tcp_rack *rack, uint32_t cts, int32_t ret, int32_t timers) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.flex1 = timers; log.u_bbr.flex2 = ret; log.u_bbr.flex3 = rack->r_ctl.rc_timer_exp; log.u_bbr.flex4 = rack->r_ctl.rc_hpts_flags; log.u_bbr.flex5 = cts; if (rack->rack_no_prr) log.u_bbr.flex6 = 0; else log.u_bbr.flex6 = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.pkts_out = rack->r_ctl.rc_out_at_rto; log.u_bbr.delivered = rack->r_ctl.rc_snd_max_at_rto; log.u_bbr.pacing_gain = rack->r_must_retran; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_TO_PROCESS, 0, 0, &log, false, &tv); } } static void rack_log_to_prr(struct tcp_rack *rack, int frm, int orig_cwnd, int line) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.flex1 = rack->r_ctl.rc_prr_out; log.u_bbr.flex2 = rack->r_ctl.rc_prr_recovery_fs; if (rack->rack_no_prr) log.u_bbr.flex3 = 0; else log.u_bbr.flex3 = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.flex4 = rack->r_ctl.rc_prr_delivered; log.u_bbr.flex5 = rack->r_ctl.rc_sacked; log.u_bbr.flex6 = rack->r_ctl.rc_holes_rxt; log.u_bbr.flex7 = line; log.u_bbr.flex8 = frm; log.u_bbr.pkts_out = orig_cwnd; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.use_lt_bw = rack->r_ent_rec_ns; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->r_might_revert; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_BBRUPD, 0, 0, &log, false, &tv); } } #ifdef NETFLIX_EXP_DETECTION static void rack_log_sad(struct tcp_rack *rack, int event) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.flex1 = rack->r_ctl.sack_count; log.u_bbr.flex2 = rack->r_ctl.ack_count; log.u_bbr.flex3 = rack->r_ctl.sack_moved_extra; log.u_bbr.flex4 = rack->r_ctl.sack_noextra_move; log.u_bbr.flex5 = rack->r_ctl.rc_num_maps_alloced; log.u_bbr.flex6 = tcp_sack_to_ack_thresh; log.u_bbr.pkts_out = tcp_sack_to_move_thresh; log.u_bbr.lt_epoch = (tcp_force_detection << 8); log.u_bbr.lt_epoch |= rack->do_detection; log.u_bbr.applimited = tcp_map_minimum; log.u_bbr.flex7 = rack->sack_attack_disable; log.u_bbr.flex8 = event; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.delivered = tcp_sad_decay_val; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, TCP_SAD_DETECTION, 0, 0, &log, false, &tv); } } #endif static void rack_counter_destroy(void) { counter_u64_free(rack_fto_send); counter_u64_free(rack_fto_rsm_send); counter_u64_free(rack_nfto_resend); counter_u64_free(rack_hw_pace_init_fail); counter_u64_free(rack_hw_pace_lost); counter_u64_free(rack_non_fto_send); counter_u64_free(rack_extended_rfo); counter_u64_free(rack_ack_total); counter_u64_free(rack_express_sack); counter_u64_free(rack_sack_total); counter_u64_free(rack_move_none); counter_u64_free(rack_move_some); counter_u64_free(rack_sack_attacks_detected); counter_u64_free(rack_sack_attacks_reversed); counter_u64_free(rack_sack_used_next_merge); counter_u64_free(rack_sack_used_prev_merge); counter_u64_free(rack_tlp_tot); counter_u64_free(rack_tlp_newdata); counter_u64_free(rack_tlp_retran); counter_u64_free(rack_tlp_retran_bytes); counter_u64_free(rack_to_tot); counter_u64_free(rack_saw_enobuf); counter_u64_free(rack_saw_enobuf_hw); counter_u64_free(rack_saw_enetunreach); counter_u64_free(rack_hot_alloc); counter_u64_free(rack_to_alloc); counter_u64_free(rack_to_alloc_hard); counter_u64_free(rack_to_alloc_emerg); counter_u64_free(rack_to_alloc_limited); counter_u64_free(rack_alloc_limited_conns); counter_u64_free(rack_split_limited); counter_u64_free(rack_multi_single_eq); counter_u64_free(rack_proc_non_comp_ack); counter_u64_free(rack_sack_proc_all); counter_u64_free(rack_sack_proc_restart); counter_u64_free(rack_sack_proc_short); counter_u64_free(rack_sack_skipped_acked); counter_u64_free(rack_sack_splits); counter_u64_free(rack_input_idle_reduces); counter_u64_free(rack_collapsed_win); counter_u64_free(rack_collapsed_win_rxt); counter_u64_free(rack_collapsed_win_rxt_bytes); counter_u64_free(rack_collapsed_win_seen); counter_u64_free(rack_try_scwnd); counter_u64_free(rack_persists_sends); counter_u64_free(rack_persists_acks); counter_u64_free(rack_persists_loss); counter_u64_free(rack_persists_lost_ends); #ifdef INVARIANTS counter_u64_free(rack_adjust_map_bw); #endif COUNTER_ARRAY_FREE(rack_out_size, TCP_MSS_ACCT_SIZE); COUNTER_ARRAY_FREE(rack_opts_arry, RACK_OPTS_SIZE); } static struct rack_sendmap * rack_alloc(struct tcp_rack *rack) { struct rack_sendmap *rsm; /* * First get the top of the list it in * theory is the "hottest" rsm we have, * possibly just freed by ack processing. */ if (rack->rc_free_cnt > rack_free_cache) { rsm = TAILQ_FIRST(&rack->r_ctl.rc_free); TAILQ_REMOVE(&rack->r_ctl.rc_free, rsm, r_tnext); counter_u64_add(rack_hot_alloc, 1); rack->rc_free_cnt--; return (rsm); } /* * Once we get under our free cache we probably * no longer have a "hot" one available. Lets * get one from UMA. */ rsm = uma_zalloc(rack_zone, M_NOWAIT); if (rsm) { rack->r_ctl.rc_num_maps_alloced++; counter_u64_add(rack_to_alloc, 1); return (rsm); } /* * Dig in to our aux rsm's (the last two) since * UMA failed to get us one. */ if (rack->rc_free_cnt) { counter_u64_add(rack_to_alloc_emerg, 1); rsm = TAILQ_FIRST(&rack->r_ctl.rc_free); TAILQ_REMOVE(&rack->r_ctl.rc_free, rsm, r_tnext); rack->rc_free_cnt--; return (rsm); } return (NULL); } static struct rack_sendmap * rack_alloc_full_limit(struct tcp_rack *rack) { if ((V_tcp_map_entries_limit > 0) && (rack->do_detection == 0) && (rack->r_ctl.rc_num_maps_alloced >= V_tcp_map_entries_limit)) { counter_u64_add(rack_to_alloc_limited, 1); if (!rack->alloc_limit_reported) { rack->alloc_limit_reported = 1; counter_u64_add(rack_alloc_limited_conns, 1); } return (NULL); } return (rack_alloc(rack)); } /* wrapper to allocate a sendmap entry, subject to a specific limit */ static struct rack_sendmap * rack_alloc_limit(struct tcp_rack *rack, uint8_t limit_type) { struct rack_sendmap *rsm; if (limit_type) { /* currently there is only one limit type */ if (V_tcp_map_split_limit > 0 && (rack->do_detection == 0) && rack->r_ctl.rc_num_split_allocs >= V_tcp_map_split_limit) { counter_u64_add(rack_split_limited, 1); if (!rack->alloc_limit_reported) { rack->alloc_limit_reported = 1; counter_u64_add(rack_alloc_limited_conns, 1); } return (NULL); } } /* allocate and mark in the limit type, if set */ rsm = rack_alloc(rack); if (rsm != NULL && limit_type) { rsm->r_limit_type = limit_type; rack->r_ctl.rc_num_split_allocs++; } return (rsm); } static void rack_free(struct tcp_rack *rack, struct rack_sendmap *rsm) { if (rsm->r_flags & RACK_APP_LIMITED) { if (rack->r_ctl.rc_app_limited_cnt > 0) { rack->r_ctl.rc_app_limited_cnt--; } } if (rsm->r_limit_type) { /* currently there is only one limit type */ rack->r_ctl.rc_num_split_allocs--; } if (rsm == rack->r_ctl.rc_first_appl) { if (rack->r_ctl.rc_app_limited_cnt == 0) rack->r_ctl.rc_first_appl = NULL; else { /* Follow the next one out */ struct rack_sendmap fe; fe.r_start = rsm->r_nseq_appl; rack->r_ctl.rc_first_appl = RB_FIND(rack_rb_tree_head, &rack->r_ctl.rc_mtree, &fe); } } if (rsm == rack->r_ctl.rc_resend) rack->r_ctl.rc_resend = NULL; if (rsm == rack->r_ctl.rc_end_appl) rack->r_ctl.rc_end_appl = NULL; if (rack->r_ctl.rc_tlpsend == rsm) rack->r_ctl.rc_tlpsend = NULL; if (rack->r_ctl.rc_sacklast == rsm) rack->r_ctl.rc_sacklast = NULL; memset(rsm, 0, sizeof(struct rack_sendmap)); TAILQ_INSERT_HEAD(&rack->r_ctl.rc_free, rsm, r_tnext); rack->rc_free_cnt++; } static void rack_free_trim(struct tcp_rack *rack) { struct rack_sendmap *rsm; /* * Free up all the tail entries until * we get our list down to the limit. */ while (rack->rc_free_cnt > rack_free_cache) { rsm = TAILQ_LAST(&rack->r_ctl.rc_free, rack_head); TAILQ_REMOVE(&rack->r_ctl.rc_free, rsm, r_tnext); rack->rc_free_cnt--; uma_zfree(rack_zone, rsm); } } static uint32_t rack_get_measure_window(struct tcpcb *tp, struct tcp_rack *rack) { uint64_t srtt, bw, len, tim; uint32_t segsiz, def_len, minl; segsiz = min(ctf_fixed_maxseg(tp), rack->r_ctl.rc_pace_min_segs); def_len = rack_def_data_window * segsiz; if (rack->rc_gp_filled == 0) { /* * We have no measurement (IW is in flight?) so * we can only guess using our data_window sysctl * value (usually 20MSS). */ return (def_len); } /* * Now we have a number of factors to consider. * * 1) We have a desired BDP which is usually * at least 2. * 2) We have a minimum number of rtt's usually 1 SRTT * but we allow it too to be more. * 3) We want to make sure a measurement last N useconds (if * we have set rack_min_measure_usec. * * We handle the first concern here by trying to create a data * window of max(rack_def_data_window, DesiredBDP). The * second concern we handle in not letting the measurement * window end normally until at least the required SRTT's * have gone by which is done further below in * rack_enough_for_measurement(). Finally the third concern * we also handle here by calculating how long that time * would take at the current BW and then return the * max of our first calculation and that length. Note * that if rack_min_measure_usec is 0, we don't deal * with concern 3. Also for both Concern 1 and 3 an * application limited period could end the measurement * earlier. * * So lets calculate the BDP with the "known" b/w using * the SRTT has our rtt and then multiply it by the * goal. */ bw = rack_get_bw(rack); srtt = (uint64_t)tp->t_srtt; len = bw * srtt; len /= (uint64_t)HPTS_USEC_IN_SEC; len *= max(1, rack_goal_bdp); /* Now we need to round up to the nearest MSS */ len = roundup(len, segsiz); if (rack_min_measure_usec) { /* Now calculate our min length for this b/w */ tim = rack_min_measure_usec; minl = (tim * bw) / (uint64_t)HPTS_USEC_IN_SEC; if (minl == 0) minl = 1; minl = roundup(minl, segsiz); if (len < minl) len = minl; } /* * Now if we have a very small window we want * to attempt to get the window that is * as small as possible. This happens on * low b/w connections and we don't want to * span huge numbers of rtt's between measurements. * * We basically include 2 over our "MIN window" so * that the measurement can be shortened (possibly) by * an ack'ed packet. */ if (len < def_len) return (max((uint32_t)len, ((MIN_GP_WIN+2) * segsiz))); else return (max((uint32_t)len, def_len)); } static int rack_enough_for_measurement(struct tcpcb *tp, struct tcp_rack *rack, tcp_seq th_ack, uint8_t *quality) { uint32_t tim, srtts, segsiz; /* * Has enough time passed for the GP measurement to be valid? */ if ((tp->snd_max == tp->snd_una) || (th_ack == tp->snd_max)){ /* All is acked */ *quality = RACK_QUALITY_ALLACKED; return (1); } if (SEQ_LT(th_ack, tp->gput_seq)) { /* Not enough bytes yet */ return (0); } segsiz = min(ctf_fixed_maxseg(tp), rack->r_ctl.rc_pace_min_segs); if (SEQ_LT(th_ack, tp->gput_ack) && ((th_ack - tp->gput_seq) < max(rc_init_window(rack), (MIN_GP_WIN * segsiz)))) { /* Not enough bytes yet */ return (0); } if (rack->r_ctl.rc_first_appl && (SEQ_GEQ(th_ack, rack->r_ctl.rc_first_appl->r_end))) { /* * We are up to the app limited send point * we have to measure irrespective of the time.. */ *quality = RACK_QUALITY_APPLIMITED; return (1); } /* Now what about time? */ srtts = (rack->r_ctl.rc_gp_srtt * rack_min_srtts); tim = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time) - tp->gput_ts; if (tim >= srtts) { *quality = RACK_QUALITY_HIGH; return (1); } /* Nope not even a full SRTT has passed */ return (0); } static void rack_log_timely(struct tcp_rack *rack, uint32_t logged, uint64_t cur_bw, uint64_t low_bnd, uint64_t up_bnd, int line, uint8_t method) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log, 0, sizeof(log)); log.u_bbr.flex1 = logged; log.u_bbr.flex2 = rack->rc_gp_timely_inc_cnt; log.u_bbr.flex2 <<= 4; log.u_bbr.flex2 |= rack->rc_gp_timely_dec_cnt; log.u_bbr.flex2 <<= 4; log.u_bbr.flex2 |= rack->rc_gp_incr; log.u_bbr.flex2 <<= 4; log.u_bbr.flex2 |= rack->rc_gp_bwred; log.u_bbr.flex3 = rack->rc_gp_incr; log.u_bbr.flex4 = rack->r_ctl.rack_per_of_gp_ss; log.u_bbr.flex5 = rack->r_ctl.rack_per_of_gp_ca; log.u_bbr.flex6 = rack->r_ctl.rack_per_of_gp_rec; log.u_bbr.flex7 = rack->rc_gp_bwred; log.u_bbr.flex8 = method; log.u_bbr.cur_del_rate = cur_bw; log.u_bbr.delRate = low_bnd; log.u_bbr.bw_inuse = up_bnd; log.u_bbr.rttProp = rack_get_bw(rack); log.u_bbr.pkt_epoch = line; log.u_bbr.pkts_out = rack->r_ctl.rc_rtt_diff; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.epoch = rack->r_ctl.rc_gp_srtt; log.u_bbr.lt_epoch = rack->r_ctl.rc_prev_gp_srtt; log.u_bbr.cwnd_gain = rack->rc_dragged_bottom; log.u_bbr.cwnd_gain <<= 1; log.u_bbr.cwnd_gain |= rack->rc_gp_saw_rec; log.u_bbr.cwnd_gain <<= 1; log.u_bbr.cwnd_gain |= rack->rc_gp_saw_ss; log.u_bbr.cwnd_gain <<= 1; log.u_bbr.cwnd_gain |= rack->rc_gp_saw_ca; log.u_bbr.lost = rack->r_ctl.rc_loss_count; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, TCP_TIMELY_WORK, 0, 0, &log, false, &tv); } } static int rack_bw_can_be_raised(struct tcp_rack *rack, uint64_t cur_bw, uint64_t last_bw_est, uint16_t mult) { /* * Before we increase we need to know if * the estimate just made was less than * our pacing goal (i.e. (cur_bw * mult) > last_bw_est) * * If we already are pacing at a fast enough * rate to push us faster there is no sense of * increasing. * * We first caculate our actual pacing rate (ss or ca multiplier * times our cur_bw). * * Then we take the last measured rate and multipy by our * maximum pacing overage to give us a max allowable rate. * * If our act_rate is smaller than our max_allowable rate * then we should increase. Else we should hold steady. * */ uint64_t act_rate, max_allow_rate; if (rack_timely_no_stopping) return (1); if ((cur_bw == 0) || (last_bw_est == 0)) { /* * Initial startup case or * everything is acked case. */ rack_log_timely(rack, mult, cur_bw, 0, 0, __LINE__, 9); return (1); } if (mult <= 100) { /* * We can always pace at or slightly above our rate. */ rack_log_timely(rack, mult, cur_bw, 0, 0, __LINE__, 9); return (1); } act_rate = cur_bw * (uint64_t)mult; act_rate /= 100; max_allow_rate = last_bw_est * ((uint64_t)rack_max_per_above + (uint64_t)100); max_allow_rate /= 100; if (act_rate < max_allow_rate) { /* * Here the rate we are actually pacing at * is smaller than 10% above our last measurement. * This means we are pacing below what we would * like to try to achieve (plus some wiggle room). */ rack_log_timely(rack, mult, cur_bw, act_rate, max_allow_rate, __LINE__, 9); return (1); } else { /* * Here we are already pacing at least rack_max_per_above(10%) * what we are getting back. This indicates most likely * that we are being limited (cwnd/rwnd/app) and can't * get any more b/w. There is no sense of trying to * raise up the pacing rate its not speeding us up * and we already are pacing faster than we are getting. */ rack_log_timely(rack, mult, cur_bw, act_rate, max_allow_rate, __LINE__, 8); return (0); } } static void rack_validate_multipliers_at_or_above100(struct tcp_rack *rack) { /* * When we drag bottom, we want to assure * that no multiplier is below 1.0, if so * we want to restore it to at least that. */ if (rack->r_ctl.rack_per_of_gp_rec < 100) { /* This is unlikely we usually do not touch recovery */ rack->r_ctl.rack_per_of_gp_rec = 100; } if (rack->r_ctl.rack_per_of_gp_ca < 100) { rack->r_ctl.rack_per_of_gp_ca = 100; } if (rack->r_ctl.rack_per_of_gp_ss < 100) { rack->r_ctl.rack_per_of_gp_ss = 100; } } static void rack_validate_multipliers_at_or_below_100(struct tcp_rack *rack) { if (rack->r_ctl.rack_per_of_gp_ca > 100) { rack->r_ctl.rack_per_of_gp_ca = 100; } if (rack->r_ctl.rack_per_of_gp_ss > 100) { rack->r_ctl.rack_per_of_gp_ss = 100; } } static void rack_increase_bw_mul(struct tcp_rack *rack, int timely_says, uint64_t cur_bw, uint64_t last_bw_est, int override) { int32_t calc, logged, plus; logged = 0; if (override) { /* * override is passed when we are * loosing b/w and making one last * gasp at trying to not loose out * to a new-reno flow. */ goto extra_boost; } /* In classic timely we boost by 5x if we have 5 increases in a row, lets not */ if (rack->rc_gp_incr && ((rack->rc_gp_timely_inc_cnt + 1) >= RACK_TIMELY_CNT_BOOST)) { /* * Reset and get 5 strokes more before the boost. Note * that the count is 0 based so we have to add one. */ extra_boost: plus = (uint32_t)rack_gp_increase_per * RACK_TIMELY_CNT_BOOST; rack->rc_gp_timely_inc_cnt = 0; } else plus = (uint32_t)rack_gp_increase_per; /* Must be at least 1% increase for true timely increases */ if ((plus < 1) && ((rack->r_ctl.rc_rtt_diff <= 0) || (timely_says <= 0))) plus = 1; if (rack->rc_gp_saw_rec && (rack->rc_gp_no_rec_chg == 0) && rack_bw_can_be_raised(rack, cur_bw, last_bw_est, rack->r_ctl.rack_per_of_gp_rec)) { /* We have been in recovery ding it too */ calc = rack->r_ctl.rack_per_of_gp_rec + plus; if (calc > 0xffff) calc = 0xffff; logged |= 1; rack->r_ctl.rack_per_of_gp_rec = (uint16_t)calc; if (rack_per_upper_bound_ss && (rack->rc_dragged_bottom == 0) && (rack->r_ctl.rack_per_of_gp_rec > rack_per_upper_bound_ss)) rack->r_ctl.rack_per_of_gp_rec = rack_per_upper_bound_ss; } if (rack->rc_gp_saw_ca && (rack->rc_gp_saw_ss == 0) && rack_bw_can_be_raised(rack, cur_bw, last_bw_est, rack->r_ctl.rack_per_of_gp_ca)) { /* In CA */ calc = rack->r_ctl.rack_per_of_gp_ca + plus; if (calc > 0xffff) calc = 0xffff; logged |= 2; rack->r_ctl.rack_per_of_gp_ca = (uint16_t)calc; if (rack_per_upper_bound_ca && (rack->rc_dragged_bottom == 0) && (rack->r_ctl.rack_per_of_gp_ca > rack_per_upper_bound_ca)) rack->r_ctl.rack_per_of_gp_ca = rack_per_upper_bound_ca; } if (rack->rc_gp_saw_ss && rack_bw_can_be_raised(rack, cur_bw, last_bw_est, rack->r_ctl.rack_per_of_gp_ss)) { /* In SS */ calc = rack->r_ctl.rack_per_of_gp_ss + plus; if (calc > 0xffff) calc = 0xffff; rack->r_ctl.rack_per_of_gp_ss = (uint16_t)calc; if (rack_per_upper_bound_ss && (rack->rc_dragged_bottom == 0) && (rack->r_ctl.rack_per_of_gp_ss > rack_per_upper_bound_ss)) rack->r_ctl.rack_per_of_gp_ss = rack_per_upper_bound_ss; logged |= 4; } if (logged && (rack->rc_gp_incr == 0)){ /* Go into increment mode */ rack->rc_gp_incr = 1; rack->rc_gp_timely_inc_cnt = 0; } if (rack->rc_gp_incr && logged && (rack->rc_gp_timely_inc_cnt < RACK_TIMELY_CNT_BOOST)) { rack->rc_gp_timely_inc_cnt++; } rack_log_timely(rack, logged, plus, 0, 0, __LINE__, 1); } static uint32_t rack_get_decrease(struct tcp_rack *rack, uint32_t curper, int32_t rtt_diff) { /* * norm_grad = rtt_diff / minrtt; * new_per = curper * (1 - B * norm_grad) * * B = rack_gp_decrease_per (default 10%) * rtt_dif = input var current rtt-diff * curper = input var current percentage * minrtt = from rack filter * */ uint64_t perf; perf = (((uint64_t)curper * ((uint64_t)1000000 - ((uint64_t)rack_gp_decrease_per * (uint64_t)10000 * (((uint64_t)rtt_diff * (uint64_t)1000000)/ (uint64_t)get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt)))/ (uint64_t)1000000)) / (uint64_t)1000000); if (perf > curper) { /* TSNH */ perf = curper - 1; } return ((uint32_t)perf); } static uint32_t rack_decrease_highrtt(struct tcp_rack *rack, uint32_t curper, uint32_t rtt) { /* * highrttthresh * result = curper * (1 - (B * ( 1 - ------ )) * gp_srtt * * B = rack_gp_decrease_per (default 10%) * highrttthresh = filter_min * rack_gp_rtt_maxmul */ uint64_t perf; uint32_t highrttthresh; highrttthresh = get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt) * rack_gp_rtt_maxmul; perf = (((uint64_t)curper * ((uint64_t)1000000 - ((uint64_t)rack_gp_decrease_per * ((uint64_t)1000000 - ((uint64_t)highrttthresh * (uint64_t)1000000) / (uint64_t)rtt)) / 100)) /(uint64_t)1000000); return (perf); } static void rack_decrease_bw_mul(struct tcp_rack *rack, int timely_says, uint32_t rtt, int32_t rtt_diff) { uint64_t logvar, logvar2, logvar3; uint32_t logged, new_per, ss_red, ca_red, rec_red, alt, val; if (rack->rc_gp_incr) { /* Turn off increment counting */ rack->rc_gp_incr = 0; rack->rc_gp_timely_inc_cnt = 0; } ss_red = ca_red = rec_red = 0; logged = 0; /* Calculate the reduction value */ if (rtt_diff < 0) { rtt_diff *= -1; } /* Must be at least 1% reduction */ if (rack->rc_gp_saw_rec && (rack->rc_gp_no_rec_chg == 0)) { /* We have been in recovery ding it too */ if (timely_says == 2) { new_per = rack_decrease_highrtt(rack, rack->r_ctl.rack_per_of_gp_rec, rtt); alt = rack_get_decrease(rack, rack->r_ctl.rack_per_of_gp_rec, rtt_diff); if (alt < new_per) val = alt; else val = new_per; } else val = new_per = alt = rack_get_decrease(rack, rack->r_ctl.rack_per_of_gp_rec, rtt_diff); if (rack->r_ctl.rack_per_of_gp_rec > val) { rec_red = (rack->r_ctl.rack_per_of_gp_rec - val); rack->r_ctl.rack_per_of_gp_rec = (uint16_t)val; } else { rack->r_ctl.rack_per_of_gp_rec = rack_per_lower_bound; rec_red = 0; } if (rack_per_lower_bound > rack->r_ctl.rack_per_of_gp_rec) rack->r_ctl.rack_per_of_gp_rec = rack_per_lower_bound; logged |= 1; } if (rack->rc_gp_saw_ss) { /* Sent in SS */ if (timely_says == 2) { new_per = rack_decrease_highrtt(rack, rack->r_ctl.rack_per_of_gp_ss, rtt); alt = rack_get_decrease(rack, rack->r_ctl.rack_per_of_gp_rec, rtt_diff); if (alt < new_per) val = alt; else val = new_per; } else val = new_per = alt = rack_get_decrease(rack, rack->r_ctl.rack_per_of_gp_ss, rtt_diff); if (rack->r_ctl.rack_per_of_gp_ss > new_per) { ss_red = rack->r_ctl.rack_per_of_gp_ss - val; rack->r_ctl.rack_per_of_gp_ss = (uint16_t)val; } else { ss_red = new_per; rack->r_ctl.rack_per_of_gp_ss = rack_per_lower_bound; logvar = new_per; logvar <<= 32; logvar |= alt; logvar2 = (uint32_t)rtt; logvar2 <<= 32; logvar2 |= (uint32_t)rtt_diff; logvar3 = rack_gp_rtt_maxmul; logvar3 <<= 32; logvar3 |= get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt); rack_log_timely(rack, timely_says, logvar2, logvar3, logvar, __LINE__, 10); } if (rack_per_lower_bound > rack->r_ctl.rack_per_of_gp_ss) rack->r_ctl.rack_per_of_gp_ss = rack_per_lower_bound; logged |= 4; } else if (rack->rc_gp_saw_ca) { /* Sent in CA */ if (timely_says == 2) { new_per = rack_decrease_highrtt(rack, rack->r_ctl.rack_per_of_gp_ca, rtt); alt = rack_get_decrease(rack, rack->r_ctl.rack_per_of_gp_rec, rtt_diff); if (alt < new_per) val = alt; else val = new_per; } else val = new_per = alt = rack_get_decrease(rack, rack->r_ctl.rack_per_of_gp_ca, rtt_diff); if (rack->r_ctl.rack_per_of_gp_ca > val) { ca_red = rack->r_ctl.rack_per_of_gp_ca - val; rack->r_ctl.rack_per_of_gp_ca = (uint16_t)val; } else { rack->r_ctl.rack_per_of_gp_ca = rack_per_lower_bound; ca_red = 0; logvar = new_per; logvar <<= 32; logvar |= alt; logvar2 = (uint32_t)rtt; logvar2 <<= 32; logvar2 |= (uint32_t)rtt_diff; logvar3 = rack_gp_rtt_maxmul; logvar3 <<= 32; logvar3 |= get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt); rack_log_timely(rack, timely_says, logvar2, logvar3, logvar, __LINE__, 10); } if (rack_per_lower_bound > rack->r_ctl.rack_per_of_gp_ca) rack->r_ctl.rack_per_of_gp_ca = rack_per_lower_bound; logged |= 2; } if (rack->rc_gp_timely_dec_cnt < 0x7) { rack->rc_gp_timely_dec_cnt++; if (rack_timely_dec_clear && (rack->rc_gp_timely_dec_cnt == rack_timely_dec_clear)) rack->rc_gp_timely_dec_cnt = 0; } logvar = ss_red; logvar <<= 32; logvar |= ca_red; rack_log_timely(rack, logged, rec_red, rack_per_lower_bound, logvar, __LINE__, 2); } static void rack_log_rtt_shrinks(struct tcp_rack *rack, uint32_t us_cts, uint32_t rtt, uint32_t line, uint8_t reas) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.flex1 = line; log.u_bbr.flex2 = rack->r_ctl.rc_time_probertt_starts; log.u_bbr.flex3 = rack->r_ctl.rc_lower_rtt_us_cts; log.u_bbr.flex4 = rack->r_ctl.rack_per_of_gp_ss; log.u_bbr.flex5 = rtt; log.u_bbr.flex6 = rack->rc_highly_buffered; log.u_bbr.flex6 <<= 1; log.u_bbr.flex6 |= rack->forced_ack; log.u_bbr.flex6 <<= 1; log.u_bbr.flex6 |= rack->rc_gp_dyn_mul; log.u_bbr.flex6 <<= 1; log.u_bbr.flex6 |= rack->in_probe_rtt; log.u_bbr.flex6 <<= 1; log.u_bbr.flex6 |= rack->measure_saw_probe_rtt; log.u_bbr.flex7 = rack->r_ctl.rack_per_of_gp_probertt; log.u_bbr.pacing_gain = rack->r_ctl.rack_per_of_gp_ca; log.u_bbr.cwnd_gain = rack->r_ctl.rack_per_of_gp_rec; log.u_bbr.flex8 = reas; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.delRate = rack_get_bw(rack); log.u_bbr.cur_del_rate = rack->r_ctl.rc_highest_us_rtt; log.u_bbr.cur_del_rate <<= 32; log.u_bbr.cur_del_rate |= rack->r_ctl.rc_lowest_us_rtt; log.u_bbr.applimited = rack->r_ctl.rc_time_probertt_entered; log.u_bbr.pkts_out = rack->r_ctl.rc_rtt_diff; log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.epoch = rack->r_ctl.rc_gp_srtt; log.u_bbr.lt_epoch = rack->r_ctl.rc_prev_gp_srtt; log.u_bbr.pkt_epoch = rack->r_ctl.rc_lower_rtt_us_cts; log.u_bbr.delivered = rack->r_ctl.rc_target_probertt_flight; log.u_bbr.lost = get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt); log.u_bbr.rttProp = us_cts; log.u_bbr.rttProp <<= 32; log.u_bbr.rttProp |= rack->r_ctl.rc_entry_gp_rtt; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_RTT_SHRINKS, 0, 0, &log, false, &rack->r_ctl.act_rcv_time); } } static void rack_set_prtt_target(struct tcp_rack *rack, uint32_t segsiz, uint32_t rtt) { uint64_t bwdp; bwdp = rack_get_bw(rack); bwdp *= (uint64_t)rtt; bwdp /= (uint64_t)HPTS_USEC_IN_SEC; rack->r_ctl.rc_target_probertt_flight = roundup((uint32_t)bwdp, segsiz); if (rack->r_ctl.rc_target_probertt_flight < (segsiz * rack_timely_min_segs)) { /* * A window protocol must be able to have 4 packets * outstanding as the floor in order to function * (especially considering delayed ack :D). */ rack->r_ctl.rc_target_probertt_flight = (segsiz * rack_timely_min_segs); } } static void rack_enter_probertt(struct tcp_rack *rack, uint32_t us_cts) { /** * ProbeRTT is a bit different in rack_pacing than in * BBR. It is like BBR in that it uses the lowering of * the RTT as a signal that we saw something new and * counts from there for how long between. But it is * different in that its quite simple. It does not * play with the cwnd and wait until we get down * to N segments outstanding and hold that for * 200ms. Instead it just sets the pacing reduction * rate to a set percentage (70 by default) and hold * that for a number of recent GP Srtt's. */ uint32_t segsiz; if (rack->rc_gp_dyn_mul == 0) return; if (rack->rc_tp->snd_max == rack->rc_tp->snd_una) { /* We are idle */ return; } if ((rack->rc_tp->t_flags & TF_GPUTINPROG) && SEQ_GT(rack->rc_tp->snd_una, rack->rc_tp->gput_seq)) { /* * Stop the goodput now, the idea here is * that future measurements with in_probe_rtt * won't register if they are not greater so * we want to get what info (if any) is available * now. */ rack_do_goodput_measurement(rack->rc_tp, rack, rack->rc_tp->snd_una, __LINE__, RACK_QUALITY_PROBERTT); } rack->r_ctl.rack_per_of_gp_probertt = rack_per_of_gp_probertt; rack->r_ctl.rc_time_probertt_entered = us_cts; segsiz = min(ctf_fixed_maxseg(rack->rc_tp), rack->r_ctl.rc_pace_min_segs); rack->in_probe_rtt = 1; rack->measure_saw_probe_rtt = 1; rack->r_ctl.rc_lower_rtt_us_cts = us_cts; rack->r_ctl.rc_time_probertt_starts = 0; rack->r_ctl.rc_entry_gp_rtt = rack->r_ctl.rc_gp_srtt; if (rack_probertt_use_min_rtt_entry) rack_set_prtt_target(rack, segsiz, get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt)); else rack_set_prtt_target(rack, segsiz, rack->r_ctl.rc_gp_srtt); rack_log_rtt_shrinks(rack, us_cts, get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt), __LINE__, RACK_RTTS_ENTERPROBE); } static void rack_exit_probertt(struct tcp_rack *rack, uint32_t us_cts) { struct rack_sendmap *rsm; uint32_t segsiz; segsiz = min(ctf_fixed_maxseg(rack->rc_tp), rack->r_ctl.rc_pace_min_segs); rack->in_probe_rtt = 0; if ((rack->rc_tp->t_flags & TF_GPUTINPROG) && SEQ_GT(rack->rc_tp->snd_una, rack->rc_tp->gput_seq)) { /* * Stop the goodput now, the idea here is * that future measurements with in_probe_rtt * won't register if they are not greater so * we want to get what info (if any) is available * now. */ rack_do_goodput_measurement(rack->rc_tp, rack, rack->rc_tp->snd_una, __LINE__, RACK_QUALITY_PROBERTT); } else if (rack->rc_tp->t_flags & TF_GPUTINPROG) { /* * We don't have enough data to make a measurement. * So lets just stop and start here after exiting * probe-rtt. We probably are not interested in * the results anyway. */ rack->rc_tp->t_flags &= ~TF_GPUTINPROG; } /* * Measurements through the current snd_max are going * to be limited by the slower pacing rate. * * We need to mark these as app-limited so we * don't collapse the b/w. */ rsm = RB_MAX(rack_rb_tree_head, &rack->r_ctl.rc_mtree); if (rsm && ((rsm->r_flags & RACK_APP_LIMITED) == 0)) { if (rack->r_ctl.rc_app_limited_cnt == 0) rack->r_ctl.rc_end_appl = rack->r_ctl.rc_first_appl = rsm; else { /* * Go out to the end app limited and mark * this new one as next and move the end_appl up * to this guy. */ if (rack->r_ctl.rc_end_appl) rack->r_ctl.rc_end_appl->r_nseq_appl = rsm->r_start; rack->r_ctl.rc_end_appl = rsm; } rsm->r_flags |= RACK_APP_LIMITED; rack->r_ctl.rc_app_limited_cnt++; } /* * Now, we need to examine our pacing rate multipliers. * If its under 100%, we need to kick it back up to * 100%. We also don't let it be over our "max" above * the actual rate i.e. 100% + rack_clamp_atexit_prtt. * Note setting clamp_atexit_prtt to 0 has the effect * of setting CA/SS to 100% always at exit (which is * the default behavior). */ if (rack_probertt_clear_is) { rack->rc_gp_incr = 0; rack->rc_gp_bwred = 0; rack->rc_gp_timely_inc_cnt = 0; rack->rc_gp_timely_dec_cnt = 0; } /* Do we do any clamping at exit? */ if (rack->rc_highly_buffered && rack_atexit_prtt_hbp) { rack->r_ctl.rack_per_of_gp_ca = rack_atexit_prtt_hbp; rack->r_ctl.rack_per_of_gp_ss = rack_atexit_prtt_hbp; } if ((rack->rc_highly_buffered == 0) && rack_atexit_prtt) { rack->r_ctl.rack_per_of_gp_ca = rack_atexit_prtt; rack->r_ctl.rack_per_of_gp_ss = rack_atexit_prtt; } /* * Lets set rtt_diff to 0, so that we will get a "boost" * after exiting. */ rack->r_ctl.rc_rtt_diff = 0; /* Clear all flags so we start fresh */ rack->rc_tp->t_bytes_acked = 0; rack->rc_tp->t_ccv.flags &= ~CCF_ABC_SENTAWND; /* * If configured to, set the cwnd and ssthresh to * our targets. */ if (rack_probe_rtt_sets_cwnd) { uint64_t ebdp; uint32_t setto; /* Set ssthresh so we get into CA once we hit our target */ if (rack_probertt_use_min_rtt_exit == 1) { /* Set to min rtt */ rack_set_prtt_target(rack, segsiz, get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt)); } else if (rack_probertt_use_min_rtt_exit == 2) { /* Set to current gp rtt */ rack_set_prtt_target(rack, segsiz, rack->r_ctl.rc_gp_srtt); } else if (rack_probertt_use_min_rtt_exit == 3) { /* Set to entry gp rtt */ rack_set_prtt_target(rack, segsiz, rack->r_ctl.rc_entry_gp_rtt); } else { uint64_t sum; uint32_t setval; sum = rack->r_ctl.rc_entry_gp_rtt; sum *= 10; sum /= (uint64_t)(max(1, rack->r_ctl.rc_gp_srtt)); if (sum >= 20) { /* * A highly buffered path needs * cwnd space for timely to work. * Lets set things up as if * we are heading back here again. */ setval = rack->r_ctl.rc_entry_gp_rtt; } else if (sum >= 15) { /* * Lets take the smaller of the * two since we are just somewhat * buffered. */ setval = rack->r_ctl.rc_gp_srtt; if (setval > rack->r_ctl.rc_entry_gp_rtt) setval = rack->r_ctl.rc_entry_gp_rtt; } else { /* * Here we are not highly buffered * and should pick the min we can to * keep from causing loss. */ setval = get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt); } rack_set_prtt_target(rack, segsiz, setval); } if (rack_probe_rtt_sets_cwnd > 1) { /* There is a percentage here to boost */ ebdp = rack->r_ctl.rc_target_probertt_flight; ebdp *= rack_probe_rtt_sets_cwnd; ebdp /= 100; setto = rack->r_ctl.rc_target_probertt_flight + ebdp; } else setto = rack->r_ctl.rc_target_probertt_flight; rack->rc_tp->snd_cwnd = roundup(setto, segsiz); if (rack->rc_tp->snd_cwnd < (segsiz * rack_timely_min_segs)) { /* Enforce a min */ rack->rc_tp->snd_cwnd = segsiz * rack_timely_min_segs; } /* If we set in the cwnd also set the ssthresh point so we are in CA */ rack->rc_tp->snd_ssthresh = (rack->rc_tp->snd_cwnd - 1); } rack_log_rtt_shrinks(rack, us_cts, get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt), __LINE__, RACK_RTTS_EXITPROBE); /* Clear times last so log has all the info */ rack->r_ctl.rc_probertt_sndmax_atexit = rack->rc_tp->snd_max; rack->r_ctl.rc_time_probertt_entered = us_cts; rack->r_ctl.rc_time_probertt_starts = rack->r_ctl.rc_lower_rtt_us_cts = us_cts; rack->r_ctl.rc_time_of_last_probertt = us_cts; } static void rack_check_probe_rtt(struct tcp_rack *rack, uint32_t us_cts) { /* Check in on probe-rtt */ if (rack->rc_gp_filled == 0) { /* We do not do p-rtt unless we have gp measurements */ return; } if (rack->in_probe_rtt) { uint64_t no_overflow; uint32_t endtime, must_stay; if (rack->r_ctl.rc_went_idle_time && ((us_cts - rack->r_ctl.rc_went_idle_time) > rack_min_probertt_hold)) { /* * We went idle during prtt, just exit now. */ rack_exit_probertt(rack, us_cts); } else if (rack_probe_rtt_safety_val && TSTMP_GT(us_cts, rack->r_ctl.rc_time_probertt_entered) && ((us_cts - rack->r_ctl.rc_time_probertt_entered) > rack_probe_rtt_safety_val)) { /* * Probe RTT safety value triggered! */ rack_log_rtt_shrinks(rack, us_cts, get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt), __LINE__, RACK_RTTS_SAFETY); rack_exit_probertt(rack, us_cts); } /* Calculate the max we will wait */ endtime = rack->r_ctl.rc_time_probertt_entered + (rack->r_ctl.rc_gp_srtt * rack_max_drain_wait); if (rack->rc_highly_buffered) endtime += (rack->r_ctl.rc_gp_srtt * rack_max_drain_hbp); /* Calculate the min we must wait */ must_stay = rack->r_ctl.rc_time_probertt_entered + (rack->r_ctl.rc_gp_srtt * rack_must_drain); if ((ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked) > rack->r_ctl.rc_target_probertt_flight) && TSTMP_LT(us_cts, endtime)) { uint32_t calc; /* Do we lower more? */ no_exit: if (TSTMP_GT(us_cts, rack->r_ctl.rc_time_probertt_entered)) calc = us_cts - rack->r_ctl.rc_time_probertt_entered; else calc = 0; calc /= max(rack->r_ctl.rc_gp_srtt, 1); if (calc) { /* Maybe */ calc *= rack_per_of_gp_probertt_reduce; rack->r_ctl.rack_per_of_gp_probertt = rack_per_of_gp_probertt - calc; /* Limit it too */ if (rack->r_ctl.rack_per_of_gp_probertt < rack_per_of_gp_lowthresh) rack->r_ctl.rack_per_of_gp_probertt = rack_per_of_gp_lowthresh; } /* We must reach target or the time set */ return; } if (rack->r_ctl.rc_time_probertt_starts == 0) { if ((TSTMP_LT(us_cts, must_stay) && rack->rc_highly_buffered) || (ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked) > rack->r_ctl.rc_target_probertt_flight)) { /* We are not past the must_stay time */ goto no_exit; } rack_log_rtt_shrinks(rack, us_cts, get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt), __LINE__, RACK_RTTS_REACHTARGET); rack->r_ctl.rc_time_probertt_starts = us_cts; if (rack->r_ctl.rc_time_probertt_starts == 0) rack->r_ctl.rc_time_probertt_starts = 1; /* Restore back to our rate we want to pace at in prtt */ rack->r_ctl.rack_per_of_gp_probertt = rack_per_of_gp_probertt; } /* * Setup our end time, some number of gp_srtts plus 200ms. */ no_overflow = ((uint64_t)rack->r_ctl.rc_gp_srtt * (uint64_t)rack_probertt_gpsrtt_cnt_mul); if (rack_probertt_gpsrtt_cnt_div) endtime = (uint32_t)(no_overflow / (uint64_t)rack_probertt_gpsrtt_cnt_div); else endtime = 0; endtime += rack_min_probertt_hold; endtime += rack->r_ctl.rc_time_probertt_starts; if (TSTMP_GEQ(us_cts, endtime)) { /* yes, exit probertt */ rack_exit_probertt(rack, us_cts); } } else if ((us_cts - rack->r_ctl.rc_lower_rtt_us_cts) >= rack_time_between_probertt) { /* Go into probertt, its been too long since we went lower */ rack_enter_probertt(rack, us_cts); } } static void rack_update_multiplier(struct tcp_rack *rack, int32_t timely_says, uint64_t last_bw_est, uint32_t rtt, int32_t rtt_diff) { uint64_t cur_bw, up_bnd, low_bnd, subfr; uint32_t losses; if ((rack->rc_gp_dyn_mul == 0) || (rack->use_fixed_rate) || (rack->in_probe_rtt) || (rack->rc_always_pace == 0)) { /* No dynamic GP multiplier in play */ return; } losses = rack->r_ctl.rc_loss_count - rack->r_ctl.rc_loss_at_start; cur_bw = rack_get_bw(rack); /* Calculate our up and down range */ up_bnd = rack->r_ctl.last_gp_comp_bw * (uint64_t)rack_gp_per_bw_mul_up; up_bnd /= 100; up_bnd += rack->r_ctl.last_gp_comp_bw; subfr = (uint64_t)rack->r_ctl.last_gp_comp_bw * (uint64_t)rack_gp_per_bw_mul_down; subfr /= 100; low_bnd = rack->r_ctl.last_gp_comp_bw - subfr; if ((timely_says == 2) && (rack->r_ctl.rc_no_push_at_mrtt)) { /* * This is the case where our RTT is above * the max target and we have been configured * to just do timely no bonus up stuff in that case. * * There are two configurations, set to 1, and we * just do timely if we are over our max. If its * set above 1 then we slam the multipliers down * to 100 and then decrement per timely. */ rack_log_timely(rack, timely_says, cur_bw, low_bnd, up_bnd, __LINE__, 3); if (rack->r_ctl.rc_no_push_at_mrtt > 1) rack_validate_multipliers_at_or_below_100(rack); rack_decrease_bw_mul(rack, timely_says, rtt, rtt_diff); } else if ((last_bw_est < low_bnd) && !losses) { /* * We are decreasing this is a bit complicated this * means we are loosing ground. This could be * because another flow entered and we are competing * for b/w with it. This will push the RTT up which * makes timely unusable unless we want to get shoved * into a corner and just be backed off (the age * old problem with delay based CC). * * On the other hand if it was a route change we * would like to stay somewhat contained and not * blow out the buffers. */ rack_log_timely(rack, timely_says, cur_bw, low_bnd, up_bnd, __LINE__, 3); rack->r_ctl.last_gp_comp_bw = cur_bw; if (rack->rc_gp_bwred == 0) { /* Go into reduction counting */ rack->rc_gp_bwred = 1; rack->rc_gp_timely_dec_cnt = 0; } if ((rack->rc_gp_timely_dec_cnt < rack_timely_max_push_drop) || (timely_says == 0)) { /* * Push another time with a faster pacing * to try to gain back (we include override to * get a full raise factor). */ if ((rack->rc_gp_saw_ca && rack->r_ctl.rack_per_of_gp_ca <= rack_down_raise_thresh) || (rack->rc_gp_saw_ss && rack->r_ctl.rack_per_of_gp_ss <= rack_down_raise_thresh) || (timely_says == 0) || (rack_down_raise_thresh == 0)) { /* * Do an override up in b/w if we were * below the threshold or if the threshold * is zero we always do the raise. */ rack_increase_bw_mul(rack, timely_says, cur_bw, last_bw_est, 1); } else { /* Log it stays the same */ rack_log_timely(rack, 0, last_bw_est, low_bnd, 0, __LINE__, 11); } rack->rc_gp_timely_dec_cnt++; /* We are not incrementing really no-count */ rack->rc_gp_incr = 0; rack->rc_gp_timely_inc_cnt = 0; } else { /* * Lets just use the RTT * information and give up * pushing. */ goto use_timely; } } else if ((timely_says != 2) && !losses && (last_bw_est > up_bnd)) { /* * We are increasing b/w lets keep going, updating * our b/w and ignoring any timely input, unless * of course we are at our max raise (if there is one). */ rack_log_timely(rack, timely_says, cur_bw, low_bnd, up_bnd, __LINE__, 3); rack->r_ctl.last_gp_comp_bw = cur_bw; if (rack->rc_gp_saw_ss && rack_per_upper_bound_ss && (rack->r_ctl.rack_per_of_gp_ss == rack_per_upper_bound_ss)) { /* * In cases where we can't go higher * we should just use timely. */ goto use_timely; } if (rack->rc_gp_saw_ca && rack_per_upper_bound_ca && (rack->r_ctl.rack_per_of_gp_ca == rack_per_upper_bound_ca)) { /* * In cases where we can't go higher * we should just use timely. */ goto use_timely; } rack->rc_gp_bwred = 0; rack->rc_gp_timely_dec_cnt = 0; /* You get a set number of pushes if timely is trying to reduce */ if ((rack->rc_gp_incr < rack_timely_max_push_rise) || (timely_says == 0)) { rack_increase_bw_mul(rack, timely_says, cur_bw, last_bw_est, 0); } else { /* Log it stays the same */ rack_log_timely(rack, 0, last_bw_est, up_bnd, 0, __LINE__, 12); } return; } else { /* * We are staying between the lower and upper range bounds * so use timely to decide. */ rack_log_timely(rack, timely_says, cur_bw, low_bnd, up_bnd, __LINE__, 3); use_timely: if (timely_says) { rack->rc_gp_incr = 0; rack->rc_gp_timely_inc_cnt = 0; if ((rack->rc_gp_timely_dec_cnt < rack_timely_max_push_drop) && !losses && (last_bw_est < low_bnd)) { /* We are loosing ground */ rack_increase_bw_mul(rack, timely_says, cur_bw, last_bw_est, 0); rack->rc_gp_timely_dec_cnt++; /* We are not incrementing really no-count */ rack->rc_gp_incr = 0; rack->rc_gp_timely_inc_cnt = 0; } else rack_decrease_bw_mul(rack, timely_says, rtt, rtt_diff); } else { rack->rc_gp_bwred = 0; rack->rc_gp_timely_dec_cnt = 0; rack_increase_bw_mul(rack, timely_says, cur_bw, last_bw_est, 0); } } } static int32_t rack_make_timely_judgement(struct tcp_rack *rack, uint32_t rtt, int32_t rtt_diff, uint32_t prev_rtt) { int32_t timely_says; uint64_t log_mult, log_rtt_a_diff; log_rtt_a_diff = rtt; log_rtt_a_diff <<= 32; log_rtt_a_diff |= (uint32_t)rtt_diff; if (rtt >= (get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt) * rack_gp_rtt_maxmul)) { /* Reduce the b/w multiplier */ timely_says = 2; log_mult = get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt) * rack_gp_rtt_maxmul; log_mult <<= 32; log_mult |= prev_rtt; rack_log_timely(rack, timely_says, log_mult, get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt), log_rtt_a_diff, __LINE__, 4); } else if (rtt <= (get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt) + ((get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt) * rack_gp_rtt_minmul) / max(rack_gp_rtt_mindiv , 1)))) { /* Increase the b/w multiplier */ log_mult = get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt) + ((get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt) * rack_gp_rtt_minmul) / max(rack_gp_rtt_mindiv , 1)); log_mult <<= 32; log_mult |= prev_rtt; timely_says = 0; rack_log_timely(rack, timely_says, log_mult , get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt), log_rtt_a_diff, __LINE__, 5); } else { /* * Use a gradient to find it the timely gradient * is: * grad = rc_rtt_diff / min_rtt; * * anything below or equal to 0 will be * a increase indication. Anything above * zero is a decrease. Note we take care * of the actual gradient calculation * in the reduction (its not needed for * increase). */ log_mult = prev_rtt; if (rtt_diff <= 0) { /* * Rttdiff is less than zero, increase the * b/w multiplier (its 0 or negative) */ timely_says = 0; rack_log_timely(rack, timely_says, log_mult, get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt), log_rtt_a_diff, __LINE__, 6); } else { /* Reduce the b/w multiplier */ timely_says = 1; rack_log_timely(rack, timely_says, log_mult, get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt), log_rtt_a_diff, __LINE__, 7); } } return (timely_says); } static void rack_do_goodput_measurement(struct tcpcb *tp, struct tcp_rack *rack, tcp_seq th_ack, int line, uint8_t quality) { uint64_t tim, bytes_ps, ltim, stim, utim; uint32_t segsiz, bytes, reqbytes, us_cts; int32_t gput, new_rtt_diff, timely_says; uint64_t resid_bw, subpart = 0, addpart = 0, srtt; int did_add = 0; us_cts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); segsiz = min(ctf_fixed_maxseg(tp), rack->r_ctl.rc_pace_min_segs); if (TSTMP_GEQ(us_cts, tp->gput_ts)) tim = us_cts - tp->gput_ts; else tim = 0; if (rack->r_ctl.rc_gp_cumack_ts > rack->r_ctl.rc_gp_output_ts) stim = rack->r_ctl.rc_gp_cumack_ts - rack->r_ctl.rc_gp_output_ts; else stim = 0; /* * Use the larger of the send time or ack time. This prevents us * from being influenced by ack artifacts to come up with too * high of measurement. Note that since we are spanning over many more * bytes in most of our measurements hopefully that is less likely to * occur. */ if (tim > stim) utim = max(tim, 1); else utim = max(stim, 1); /* Lets get a msec time ltim too for the old stuff */ ltim = max(1, (utim / HPTS_USEC_IN_MSEC)); gput = (((uint64_t) (th_ack - tp->gput_seq)) << 3) / ltim; reqbytes = min(rc_init_window(rack), (MIN_GP_WIN * segsiz)); if ((tim == 0) && (stim == 0)) { /* * Invalid measurement time, maybe * all on one ack/one send? */ bytes = 0; bytes_ps = 0; rack_log_pacing_delay_calc(rack, bytes_ps, reqbytes, 0, 0, 0, 10, __LINE__, NULL, quality); goto skip_measurement; } if (rack->r_ctl.rc_gp_lowrtt == 0xffffffff) { /* We never made a us_rtt measurement? */ bytes = 0; bytes_ps = 0; rack_log_pacing_delay_calc(rack, bytes_ps, reqbytes, 0, 0, 0, 10, __LINE__, NULL, quality); goto skip_measurement; } /* * Calculate the maximum possible b/w this connection * could have. We base our calculation on the lowest * rtt we have seen during the measurement and the * largest rwnd the client has given us in that time. This * forms a BDP that is the maximum that we could ever * get to the client. Anything larger is not valid. * * I originally had code here that rejected measurements * where the time was less than 1/2 the latest us_rtt. * But after thinking on that I realized its wrong since * say you had a 150Mbps or even 1Gbps link, and you * were a long way away.. example I am in Europe (100ms rtt) * talking to my 1Gbps link in S.C. Now measuring say 150,000 * bytes my time would be 1.2ms, and yet my rtt would say * the measurement was invalid the time was < 50ms. The * same thing is true for 150Mb (8ms of time). * * A better way I realized is to look at what the maximum * the connection could possibly do. This is gated on * the lowest RTT we have seen and the highest rwnd. * We should in theory never exceed that, if we are * then something on the path is storing up packets * and then feeding them all at once to our endpoint * messing up our measurement. */ rack->r_ctl.last_max_bw = rack->r_ctl.rc_gp_high_rwnd; rack->r_ctl.last_max_bw *= HPTS_USEC_IN_SEC; rack->r_ctl.last_max_bw /= rack->r_ctl.rc_gp_lowrtt; if (SEQ_LT(th_ack, tp->gput_seq)) { /* No measurement can be made */ bytes = 0; bytes_ps = 0; rack_log_pacing_delay_calc(rack, bytes_ps, reqbytes, 0, 0, 0, 10, __LINE__, NULL, quality); goto skip_measurement; } else bytes = (th_ack - tp->gput_seq); bytes_ps = (uint64_t)bytes; /* * Don't measure a b/w for pacing unless we have gotten at least * an initial windows worth of data in this measurement interval. * * Small numbers of bytes get badly influenced by delayed ack and * other artifacts. Note we take the initial window or our * defined minimum GP (defaulting to 10 which hopefully is the * IW). */ if (rack->rc_gp_filled == 0) { /* * The initial estimate is special. We * have blasted out an IW worth of packets * without a real valid ack ts results. We * then setup the app_limited_needs_set flag, * this should get the first ack in (probably 2 * MSS worth) to be recorded as the timestamp. * We thus allow a smaller number of bytes i.e. * IW - 2MSS. */ reqbytes -= (2 * segsiz); /* Also lets fill previous for our first measurement to be neutral */ rack->r_ctl.rc_prev_gp_srtt = rack->r_ctl.rc_gp_srtt; } if ((bytes_ps < reqbytes) || rack->app_limited_needs_set) { rack_log_pacing_delay_calc(rack, bytes_ps, reqbytes, rack->r_ctl.rc_app_limited_cnt, 0, 0, 10, __LINE__, NULL, quality); goto skip_measurement; } /* * We now need to calculate the Timely like status so * we can update (possibly) the b/w multipliers. */ new_rtt_diff = (int32_t)rack->r_ctl.rc_gp_srtt - (int32_t)rack->r_ctl.rc_prev_gp_srtt; if (rack->rc_gp_filled == 0) { /* No previous reading */ rack->r_ctl.rc_rtt_diff = new_rtt_diff; } else { if (rack->measure_saw_probe_rtt == 0) { /* * We don't want a probertt to be counted * since it will be negative incorrectly. We * expect to be reducing the RTT when we * pace at a slower rate. */ rack->r_ctl.rc_rtt_diff -= (rack->r_ctl.rc_rtt_diff / 8); rack->r_ctl.rc_rtt_diff += (new_rtt_diff / 8); } } timely_says = rack_make_timely_judgement(rack, rack->r_ctl.rc_gp_srtt, rack->r_ctl.rc_rtt_diff, rack->r_ctl.rc_prev_gp_srtt ); bytes_ps *= HPTS_USEC_IN_SEC; bytes_ps /= utim; if (bytes_ps > rack->r_ctl.last_max_bw) { /* * Something is on path playing * since this b/w is not possible based * on our BDP (highest rwnd and lowest rtt * we saw in the measurement window). * * Another option here would be to * instead skip the measurement. */ rack_log_pacing_delay_calc(rack, bytes, reqbytes, bytes_ps, rack->r_ctl.last_max_bw, 0, 11, __LINE__, NULL, quality); bytes_ps = rack->r_ctl.last_max_bw; } /* We store gp for b/w in bytes per second */ if (rack->rc_gp_filled == 0) { /* Initial measurement */ if (bytes_ps) { rack->r_ctl.gp_bw = bytes_ps; rack->rc_gp_filled = 1; rack->r_ctl.num_measurements = 1; rack_set_pace_segments(rack->rc_tp, rack, __LINE__, NULL); } else { rack_log_pacing_delay_calc(rack, bytes_ps, reqbytes, rack->r_ctl.rc_app_limited_cnt, 0, 0, 10, __LINE__, NULL, quality); } if (tcp_in_hpts(rack->rc_inp) && (rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT)) { /* * Ok we can't trust the pacer in this case * where we transition from un-paced to paced. * Or for that matter when the burst mitigation * was making a wild guess and got it wrong. * Stop the pacer and clear up all the aggregate * delays etc. */ tcp_hpts_remove(rack->rc_inp); rack->r_ctl.rc_hpts_flags = 0; rack->r_ctl.rc_last_output_to = 0; } did_add = 2; } else if (rack->r_ctl.num_measurements < RACK_REQ_AVG) { /* Still a small number run an average */ rack->r_ctl.gp_bw += bytes_ps; addpart = rack->r_ctl.num_measurements; rack->r_ctl.num_measurements++; if (rack->r_ctl.num_measurements >= RACK_REQ_AVG) { /* We have collected enough to move forward */ rack->r_ctl.gp_bw /= (uint64_t)rack->r_ctl.num_measurements; } did_add = 3; } else { /* * We want to take 1/wma of the goodput and add in to 7/8th * of the old value weighted by the srtt. So if your measurement * period is say 2 SRTT's long you would get 1/4 as the * value, if it was like 1/2 SRTT then you would get 1/16th. * * But we must be careful not to take too much i.e. if the * srtt is say 20ms and the measurement is taken over * 400ms our weight would be 400/20 i.e. 20. On the * other hand if we get a measurement over 1ms with a * 10ms rtt we only want to take a much smaller portion. */ if (rack->r_ctl.num_measurements < 0xff) { rack->r_ctl.num_measurements++; } srtt = (uint64_t)tp->t_srtt; if (srtt == 0) { /* * Strange why did t_srtt go back to zero? */ if (rack->r_ctl.rc_rack_min_rtt) srtt = rack->r_ctl.rc_rack_min_rtt; else srtt = HPTS_USEC_IN_MSEC; } /* * XXXrrs: Note for reviewers, in playing with * dynamic pacing I discovered this GP calculation * as done originally leads to some undesired results. * Basically you can get longer measurements contributing * too much to the WMA. Thus I changed it if you are doing * dynamic adjustments to only do the aportioned adjustment * if we have a very small (time wise) measurement. Longer * measurements just get there weight (defaulting to 1/8) * add to the WMA. We may want to think about changing * this to always do that for both sides i.e. dynamic * and non-dynamic... but considering lots of folks * were playing with this I did not want to change the * calculation per.se. without your thoughts.. Lawerence? * Peter?? */ if (rack->rc_gp_dyn_mul == 0) { subpart = rack->r_ctl.gp_bw * utim; subpart /= (srtt * 8); if (subpart < (rack->r_ctl.gp_bw / 2)) { /* * The b/w update takes no more * away then 1/2 our running total * so factor it in. */ addpart = bytes_ps * utim; addpart /= (srtt * 8); } else { /* * Don't allow a single measurement * to account for more than 1/2 of the * WMA. This could happen on a retransmission * where utim becomes huge compared to * srtt (multiple retransmissions when using * the sending rate which factors in all the * transmissions from the first one). */ subpart = rack->r_ctl.gp_bw / 2; addpart = bytes_ps / 2; } resid_bw = rack->r_ctl.gp_bw - subpart; rack->r_ctl.gp_bw = resid_bw + addpart; did_add = 1; } else { if ((utim / srtt) <= 1) { /* * The b/w update was over a small period * of time. The idea here is to prevent a small * measurement time period from counting * too much. So we scale it based on the * time so it attributes less than 1/rack_wma_divisor * of its measurement. */ subpart = rack->r_ctl.gp_bw * utim; subpart /= (srtt * rack_wma_divisor); addpart = bytes_ps * utim; addpart /= (srtt * rack_wma_divisor); } else { /* * The scaled measurement was long * enough so lets just add in the * portion of the measurement i.e. 1/rack_wma_divisor */ subpart = rack->r_ctl.gp_bw / rack_wma_divisor; addpart = bytes_ps / rack_wma_divisor; } if ((rack->measure_saw_probe_rtt == 0) || (bytes_ps > rack->r_ctl.gp_bw)) { /* * For probe-rtt we only add it in * if its larger, all others we just * add in. */ did_add = 1; resid_bw = rack->r_ctl.gp_bw - subpart; rack->r_ctl.gp_bw = resid_bw + addpart; } } } if ((rack->gp_ready == 0) && (rack->r_ctl.num_measurements >= rack->r_ctl.req_measurements)) { /* We have enough measurements now */ rack->gp_ready = 1; rack_set_cc_pacing(rack); if (rack->defer_options) rack_apply_deferred_options(rack); } rack_log_pacing_delay_calc(rack, subpart, addpart, bytes_ps, stim, rack_get_bw(rack), 22, did_add, NULL, quality); /* We do not update any multipliers if we are in or have seen a probe-rtt */ if ((rack->measure_saw_probe_rtt == 0) && rack->rc_gp_rtt_set) rack_update_multiplier(rack, timely_says, bytes_ps, rack->r_ctl.rc_gp_srtt, rack->r_ctl.rc_rtt_diff); rack_log_pacing_delay_calc(rack, bytes, tim, bytes_ps, stim, rack_get_bw(rack), 3, line, NULL, quality); /* reset the gp srtt and setup the new prev */ rack->r_ctl.rc_prev_gp_srtt = rack->r_ctl.rc_gp_srtt; /* Record the lost count for the next measurement */ rack->r_ctl.rc_loss_at_start = rack->r_ctl.rc_loss_count; /* * We restart our diffs based on the gpsrtt in the * measurement window. */ rack->rc_gp_rtt_set = 0; rack->rc_gp_saw_rec = 0; rack->rc_gp_saw_ca = 0; rack->rc_gp_saw_ss = 0; rack->rc_dragged_bottom = 0; skip_measurement: #ifdef STATS stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_GPUT, gput); /* * XXXLAS: This is a temporary hack, and should be * chained off VOI_TCP_GPUT when stats(9) grows an * API to deal with chained VOIs. */ if (tp->t_stats_gput_prev > 0) stats_voi_update_abs_s32(tp->t_stats, VOI_TCP_GPUT_ND, ((gput - tp->t_stats_gput_prev) * 100) / tp->t_stats_gput_prev); #endif tp->t_flags &= ~TF_GPUTINPROG; tp->t_stats_gput_prev = gput; /* * Now are we app limited now and there is space from where we * were to where we want to go? * * We don't do the other case i.e. non-applimited here since * the next send will trigger us picking up the missing data. */ if (rack->r_ctl.rc_first_appl && TCPS_HAVEESTABLISHED(tp->t_state) && rack->r_ctl.rc_app_limited_cnt && (SEQ_GT(rack->r_ctl.rc_first_appl->r_start, th_ack)) && ((rack->r_ctl.rc_first_appl->r_end - th_ack) > max(rc_init_window(rack), (MIN_GP_WIN * segsiz)))) { /* * Yep there is enough outstanding to make a measurement here. */ struct rack_sendmap *rsm, fe; rack->r_ctl.rc_gp_lowrtt = 0xffffffff; rack->r_ctl.rc_gp_high_rwnd = rack->rc_tp->snd_wnd; tp->gput_ts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); rack->app_limited_needs_set = 0; tp->gput_seq = th_ack; if (rack->in_probe_rtt) rack->measure_saw_probe_rtt = 1; else if ((rack->measure_saw_probe_rtt) && (SEQ_GEQ(tp->gput_seq, rack->r_ctl.rc_probertt_sndmax_atexit))) rack->measure_saw_probe_rtt = 0; if ((rack->r_ctl.rc_first_appl->r_end - th_ack) >= rack_get_measure_window(tp, rack)) { /* There is a full window to gain info from */ tp->gput_ack = tp->gput_seq + rack_get_measure_window(tp, rack); } else { /* We can only measure up to the applimited point */ tp->gput_ack = tp->gput_seq + (rack->r_ctl.rc_first_appl->r_end - th_ack); if ((tp->gput_ack - tp->gput_seq) < (MIN_GP_WIN * segsiz)) { /* * We don't have enough to make a measurement. */ tp->t_flags &= ~TF_GPUTINPROG; rack_log_pacing_delay_calc(rack, tp->gput_ack, tp->gput_seq, 0, 0, 0, 6, __LINE__, NULL, quality); return; } } if (tp->t_state >= TCPS_FIN_WAIT_1) { /* * We will get no more data into the SB * this means we need to have the data available * before we start a measurement. */ if (sbavail(&tptosocket(tp)->so_snd) < (tp->gput_ack - tp->gput_seq)) { /* Nope not enough data. */ return; } } tp->t_flags |= TF_GPUTINPROG; /* * Now we need to find the timestamp of the send at tp->gput_seq * for the send based measurement. */ fe.r_start = tp->gput_seq; rsm = RB_FIND(rack_rb_tree_head, &rack->r_ctl.rc_mtree, &fe); if (rsm) { /* Ok send-based limit is set */ if (SEQ_LT(rsm->r_start, tp->gput_seq)) { /* * Move back to include the earlier part * so our ack time lines up right (this may * make an overlapping measurement but thats * ok). */ tp->gput_seq = rsm->r_start; } if (rsm->r_flags & RACK_ACKED) tp->gput_ts = (uint32_t)rsm->r_ack_arrival; else rack->app_limited_needs_set = 1; rack->r_ctl.rc_gp_output_ts = rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]; } else { /* * If we don't find the rsm due to some * send-limit set the current time, which * basically disables the send-limit. */ struct timeval tv; microuptime(&tv); rack->r_ctl.rc_gp_output_ts = rack_to_usec_ts(&tv); } rack_log_pacing_delay_calc(rack, tp->gput_seq, tp->gput_ack, (uint64_t)rsm, tp->gput_ts, rack->r_ctl.rc_app_limited_cnt, 9, __LINE__, NULL, quality); } } /* * CC wrapper hook functions */ static void rack_ack_received(struct tcpcb *tp, struct tcp_rack *rack, uint32_t th_ack, uint16_t nsegs, uint16_t type, int32_t recovery) { uint32_t prior_cwnd, acked; struct tcp_log_buffer *lgb = NULL; uint8_t labc_to_use, quality; INP_WLOCK_ASSERT(tptoinpcb(tp)); tp->t_ccv.nsegs = nsegs; acked = tp->t_ccv.bytes_this_ack = (th_ack - tp->snd_una); if ((recovery) && (rack->r_ctl.rc_early_recovery_segs)) { uint32_t max; max = rack->r_ctl.rc_early_recovery_segs * ctf_fixed_maxseg(tp); if (tp->t_ccv.bytes_this_ack > max) { tp->t_ccv.bytes_this_ack = max; } } #ifdef STATS stats_voi_update_abs_s32(tp->t_stats, VOI_TCP_CALCFRWINDIFF, ((int32_t)rack->r_ctl.cwnd_to_use) - tp->snd_wnd); #endif quality = RACK_QUALITY_NONE; if ((tp->t_flags & TF_GPUTINPROG) && rack_enough_for_measurement(tp, rack, th_ack, &quality)) { /* Measure the Goodput */ rack_do_goodput_measurement(tp, rack, th_ack, __LINE__, quality); #ifdef NETFLIX_PEAKRATE if ((type == CC_ACK) && (tp->t_maxpeakrate)) { /* * We update t_peakrate_thr. This gives us roughly * one update per round trip time. Note * it will only be used if pace_always is off i.e * we don't do this for paced flows. */ rack_update_peakrate_thr(tp); } #endif } /* Which way our we limited, if not cwnd limited no advance in CA */ if (tp->snd_cwnd <= tp->snd_wnd) tp->t_ccv.flags |= CCF_CWND_LIMITED; else tp->t_ccv.flags &= ~CCF_CWND_LIMITED; if (tp->snd_cwnd > tp->snd_ssthresh) { tp->t_bytes_acked += min(tp->t_ccv.bytes_this_ack, nsegs * V_tcp_abc_l_var * ctf_fixed_maxseg(tp)); /* For the setting of a window past use the actual scwnd we are using */ if (tp->t_bytes_acked >= rack->r_ctl.cwnd_to_use) { tp->t_bytes_acked -= rack->r_ctl.cwnd_to_use; tp->t_ccv.flags |= CCF_ABC_SENTAWND; } } else { tp->t_ccv.flags &= ~CCF_ABC_SENTAWND; tp->t_bytes_acked = 0; } prior_cwnd = tp->snd_cwnd; if ((recovery == 0) || (rack_max_abc_post_recovery == 0) || rack->r_use_labc_for_rec || (rack_client_low_buf && (rack->client_bufferlvl < rack_client_low_buf))) labc_to_use = rack->rc_labc; else labc_to_use = rack_max_abc_post_recovery; if (rack_verbose_logging && (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.flex1 = th_ack; log.u_bbr.flex2 = tp->t_ccv.flags; log.u_bbr.flex3 = tp->t_ccv.bytes_this_ack; log.u_bbr.flex4 = tp->t_ccv.nsegs; log.u_bbr.flex5 = labc_to_use; log.u_bbr.flex6 = prior_cwnd; log.u_bbr.flex7 = V_tcp_do_newsack; log.u_bbr.flex8 = 1; lgb = tcp_log_event_(tp, NULL, NULL, NULL, BBR_LOG_CWND, 0, 0, &log, false, NULL, NULL, 0, &tv); } if (CC_ALGO(tp)->ack_received != NULL) { /* XXXLAS: Find a way to live without this */ tp->t_ccv.curack = th_ack; tp->t_ccv.labc = labc_to_use; tp->t_ccv.flags |= CCF_USE_LOCAL_ABC; CC_ALGO(tp)->ack_received(&tp->t_ccv, type); } if (lgb) { lgb->tlb_stackinfo.u_bbr.flex6 = tp->snd_cwnd; } if (rack->r_must_retran) { if (SEQ_GEQ(th_ack, rack->r_ctl.rc_snd_max_at_rto)) { /* * We now are beyond the rxt point so lets disable * the flag. */ rack->r_ctl.rc_out_at_rto = 0; rack->r_must_retran = 0; } else if ((prior_cwnd + ctf_fixed_maxseg(tp)) <= tp->snd_cwnd) { /* * Only decrement the rc_out_at_rto if the cwnd advances * at least a whole segment. Otherwise next time the peer * acks, we won't be able to send this generaly happens * when we are in Congestion Avoidance. */ if (acked <= rack->r_ctl.rc_out_at_rto){ rack->r_ctl.rc_out_at_rto -= acked; } else { rack->r_ctl.rc_out_at_rto = 0; } } } #ifdef STATS stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_LCWIN, rack->r_ctl.cwnd_to_use); #endif if (rack->r_ctl.rc_rack_largest_cwnd < rack->r_ctl.cwnd_to_use) { rack->r_ctl.rc_rack_largest_cwnd = rack->r_ctl.cwnd_to_use; } #ifdef NETFLIX_PEAKRATE /* we enforce max peak rate if it is set and we are not pacing */ if ((rack->rc_always_pace == 0) && tp->t_peakrate_thr && (tp->snd_cwnd > tp->t_peakrate_thr)) { tp->snd_cwnd = tp->t_peakrate_thr; } #endif } static void tcp_rack_partialack(struct tcpcb *tp) { struct tcp_rack *rack; rack = (struct tcp_rack *)tp->t_fb_ptr; INP_WLOCK_ASSERT(tptoinpcb(tp)); /* * If we are doing PRR and have enough * room to send we are pacing and prr * is disabled we will want to see if we * can send data (by setting r_wanted_output to * true). */ if ((rack->r_ctl.rc_prr_sndcnt > 0) || rack->rack_no_prr) rack->r_wanted_output = 1; } static void rack_post_recovery(struct tcpcb *tp, uint32_t th_ack) { struct tcp_rack *rack; uint32_t orig_cwnd; orig_cwnd = tp->snd_cwnd; INP_WLOCK_ASSERT(tptoinpcb(tp)); rack = (struct tcp_rack *)tp->t_fb_ptr; /* only alert CC if we alerted when we entered */ if (CC_ALGO(tp)->post_recovery != NULL) { tp->t_ccv.curack = th_ack; CC_ALGO(tp)->post_recovery(&tp->t_ccv); if (tp->snd_cwnd < tp->snd_ssthresh) { /* * Rack has burst control and pacing * so lets not set this any lower than * snd_ssthresh per RFC-6582 (option 2). */ tp->snd_cwnd = tp->snd_ssthresh; } } if (rack_verbose_logging && (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.flex1 = th_ack; log.u_bbr.flex2 = tp->t_ccv.flags; log.u_bbr.flex3 = tp->t_ccv.bytes_this_ack; log.u_bbr.flex4 = tp->t_ccv.nsegs; log.u_bbr.flex5 = V_tcp_abc_l_var; log.u_bbr.flex6 = orig_cwnd; log.u_bbr.flex7 = V_tcp_do_newsack; log.u_bbr.pkts_out = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.flex8 = 2; tcp_log_event_(tp, NULL, NULL, NULL, BBR_LOG_CWND, 0, 0, &log, false, NULL, NULL, 0, &tv); } if ((rack->rack_no_prr == 0) && (rack->no_prr_addback == 0) && (rack->r_ctl.rc_prr_sndcnt > 0)) { /* * Suck the next prr cnt back into cwnd, but * only do that if we are not application limited. */ if (ctf_outstanding(tp) <= sbavail(&tptosocket(tp)->so_snd)) { /* * We are allowed to add back to the cwnd the amount we did * not get out if: * a) no_prr_addback is off. * b) we are not app limited * c) we are doing prr * * d) it is bounded by rack_prr_addbackmax (if addback is 0, then none). */ tp->snd_cwnd += min((ctf_fixed_maxseg(tp) * rack_prr_addbackmax), rack->r_ctl.rc_prr_sndcnt); } rack->r_ctl.rc_prr_sndcnt = 0; rack_log_to_prr(rack, 1, 0, __LINE__); } rack_log_to_prr(rack, 14, orig_cwnd, __LINE__); tp->snd_recover = tp->snd_una; if (rack->r_ctl.dsack_persist) { rack->r_ctl.dsack_persist--; if (rack->r_ctl.num_dsack && (rack->r_ctl.dsack_persist == 0)) { rack->r_ctl.num_dsack = 0; } rack_log_dsack_event(rack, 1, __LINE__, 0, 0); } EXIT_RECOVERY(tp->t_flags); } static void rack_cong_signal(struct tcpcb *tp, uint32_t type, uint32_t ack, int line) { struct tcp_rack *rack; uint32_t ssthresh_enter, cwnd_enter, in_rec_at_entry, orig_cwnd; INP_WLOCK_ASSERT(tptoinpcb(tp)); #ifdef STATS stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_CSIG, type); #endif if (IN_RECOVERY(tp->t_flags) == 0) { in_rec_at_entry = 0; ssthresh_enter = tp->snd_ssthresh; cwnd_enter = tp->snd_cwnd; } else in_rec_at_entry = 1; rack = (struct tcp_rack *)tp->t_fb_ptr; switch (type) { case CC_NDUPACK: tp->t_flags &= ~TF_WASFRECOVERY; tp->t_flags &= ~TF_WASCRECOVERY; if (!IN_FASTRECOVERY(tp->t_flags)) { rack->r_ctl.rc_prr_delivered = 0; rack->r_ctl.rc_prr_out = 0; if (rack->rack_no_prr == 0) { rack->r_ctl.rc_prr_sndcnt = ctf_fixed_maxseg(tp); rack_log_to_prr(rack, 2, in_rec_at_entry, line); } rack->r_ctl.rc_prr_recovery_fs = tp->snd_max - tp->snd_una; tp->snd_recover = tp->snd_max; if (tp->t_flags2 & TF2_ECN_PERMIT) tp->t_flags2 |= TF2_ECN_SND_CWR; } break; case CC_ECN: if (!IN_CONGRECOVERY(tp->t_flags) || /* * Allow ECN reaction on ACK to CWR, if * that data segment was also CE marked. */ SEQ_GEQ(ack, tp->snd_recover)) { EXIT_CONGRECOVERY(tp->t_flags); KMOD_TCPSTAT_INC(tcps_ecn_rcwnd); tp->snd_recover = tp->snd_max + 1; if (tp->t_flags2 & TF2_ECN_PERMIT) tp->t_flags2 |= TF2_ECN_SND_CWR; } break; case CC_RTO: tp->t_dupacks = 0; tp->t_bytes_acked = 0; EXIT_RECOVERY(tp->t_flags); tp->snd_ssthresh = max(2, min(tp->snd_wnd, rack->r_ctl.cwnd_to_use) / 2 / ctf_fixed_maxseg(tp)) * ctf_fixed_maxseg(tp); orig_cwnd = tp->snd_cwnd; tp->snd_cwnd = ctf_fixed_maxseg(tp); rack_log_to_prr(rack, 16, orig_cwnd, line); if (tp->t_flags2 & TF2_ECN_PERMIT) tp->t_flags2 |= TF2_ECN_SND_CWR; break; case CC_RTO_ERR: KMOD_TCPSTAT_INC(tcps_sndrexmitbad); /* RTO was unnecessary, so reset everything. */ tp->snd_cwnd = tp->snd_cwnd_prev; tp->snd_ssthresh = tp->snd_ssthresh_prev; tp->snd_recover = tp->snd_recover_prev; if (tp->t_flags & TF_WASFRECOVERY) { ENTER_FASTRECOVERY(tp->t_flags); tp->t_flags &= ~TF_WASFRECOVERY; } if (tp->t_flags & TF_WASCRECOVERY) { ENTER_CONGRECOVERY(tp->t_flags); tp->t_flags &= ~TF_WASCRECOVERY; } tp->snd_nxt = tp->snd_max; tp->t_badrxtwin = 0; break; } if ((CC_ALGO(tp)->cong_signal != NULL) && (type != CC_RTO)){ tp->t_ccv.curack = ack; CC_ALGO(tp)->cong_signal(&tp->t_ccv, type); } if ((in_rec_at_entry == 0) && IN_RECOVERY(tp->t_flags)) { rack_log_to_prr(rack, 15, cwnd_enter, line); rack->r_ctl.dsack_byte_cnt = 0; rack->r_ctl.retran_during_recovery = 0; rack->r_ctl.rc_cwnd_at_erec = cwnd_enter; rack->r_ctl.rc_ssthresh_at_erec = ssthresh_enter; rack->r_ent_rec_ns = 1; } } static inline void rack_cc_after_idle(struct tcp_rack *rack, struct tcpcb *tp) { uint32_t i_cwnd; INP_WLOCK_ASSERT(tptoinpcb(tp)); #ifdef NETFLIX_STATS KMOD_TCPSTAT_INC(tcps_idle_restarts); if (tp->t_state == TCPS_ESTABLISHED) KMOD_TCPSTAT_INC(tcps_idle_estrestarts); #endif if (CC_ALGO(tp)->after_idle != NULL) CC_ALGO(tp)->after_idle(&tp->t_ccv); if (tp->snd_cwnd == 1) i_cwnd = tp->t_maxseg; /* SYN(-ACK) lost */ else i_cwnd = rc_init_window(rack); /* * Being idle is no different than the initial window. If the cc * clamps it down below the initial window raise it to the initial * window. */ if (tp->snd_cwnd < i_cwnd) { tp->snd_cwnd = i_cwnd; } } /* * Indicate whether this ack should be delayed. We can delay the ack if * following conditions are met: * - There is no delayed ack timer in progress. * - Our last ack wasn't a 0-sized window. We never want to delay * the ack that opens up a 0-sized window. * - LRO wasn't used for this segment. We make sure by checking that the * segment size is not larger than the MSS. * - Delayed acks are enabled or this is a half-synchronized T/TCP * connection. */ #define DELAY_ACK(tp, tlen) \ (((tp->t_flags & TF_RXWIN0SENT) == 0) && \ ((tp->t_flags & TF_DELACK) == 0) && \ (tlen <= tp->t_maxseg) && \ (tp->t_delayed_ack || (tp->t_flags & TF_NEEDSYN))) static struct rack_sendmap * rack_find_lowest_rsm(struct tcp_rack *rack) { struct rack_sendmap *rsm; /* * Walk the time-order transmitted list looking for an rsm that is * not acked. This will be the one that was sent the longest time * ago that is still outstanding. */ TAILQ_FOREACH(rsm, &rack->r_ctl.rc_tmap, r_tnext) { if (rsm->r_flags & RACK_ACKED) { continue; } goto finish; } finish: return (rsm); } static struct rack_sendmap * rack_find_high_nonack(struct tcp_rack *rack, struct rack_sendmap *rsm) { struct rack_sendmap *prsm; /* * Walk the sequence order list backward until we hit and arrive at * the highest seq not acked. In theory when this is called it * should be the last segment (which it was not). */ prsm = rsm; RB_FOREACH_REVERSE_FROM(prsm, rack_rb_tree_head, rsm) { if (prsm->r_flags & (RACK_ACKED | RACK_HAS_FIN)) { continue; } return (prsm); } return (NULL); } static uint32_t rack_calc_thresh_rack(struct tcp_rack *rack, uint32_t srtt, uint32_t cts) { int32_t lro; uint32_t thresh; /* * lro is the flag we use to determine if we have seen reordering. * If it gets set we have seen reordering. The reorder logic either * works in one of two ways: * * If reorder-fade is configured, then we track the last time we saw * re-ordering occur. If we reach the point where enough time as * passed we no longer consider reordering has occuring. * * Or if reorder-face is 0, then once we see reordering we consider * the connection to alway be subject to reordering and just set lro * to 1. * * In the end if lro is non-zero we add the extra time for * reordering in. */ if (srtt == 0) srtt = 1; if (rack->r_ctl.rc_reorder_ts) { if (rack->r_ctl.rc_reorder_fade) { if (SEQ_GEQ(cts, rack->r_ctl.rc_reorder_ts)) { lro = cts - rack->r_ctl.rc_reorder_ts; if (lro == 0) { /* * No time as passed since the last * reorder, mark it as reordering. */ lro = 1; } } else { /* Negative time? */ lro = 0; } if (lro > rack->r_ctl.rc_reorder_fade) { /* Turn off reordering seen too */ rack->r_ctl.rc_reorder_ts = 0; lro = 0; } } else { /* Reodering does not fade */ lro = 1; } } else { lro = 0; } if (rack->rc_rack_tmr_std_based == 0) { thresh = srtt + rack->r_ctl.rc_pkt_delay; } else { /* Standards based pkt-delay is 1/4 srtt */ thresh = srtt + (srtt >> 2); } if (lro && (rack->rc_rack_tmr_std_based == 0)) { /* It must be set, if not you get 1/4 rtt */ if (rack->r_ctl.rc_reorder_shift) thresh += (srtt >> rack->r_ctl.rc_reorder_shift); else thresh += (srtt >> 2); } if (rack->rc_rack_use_dsack && lro && (rack->r_ctl.num_dsack > 0)) { /* * We only increase the reordering window if we * have seen reordering we have a DSACK count. */ thresh += rack->r_ctl.num_dsack * (srtt >> 2); rack_log_dsack_event(rack, 4, __LINE__, srtt, thresh); } /* SRTT * 2 is the ceiling */ if (thresh > (srtt * 2)) { thresh = srtt * 2; } /* And we don't want it above the RTO max either */ if (thresh > rack_rto_max) { thresh = rack_rto_max; } rack_log_dsack_event(rack, 6, __LINE__, srtt, thresh); return (thresh); } static uint32_t rack_calc_thresh_tlp(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendmap *rsm, uint32_t srtt) { struct rack_sendmap *prsm; uint32_t thresh, len; int segsiz; if (srtt == 0) srtt = 1; if (rack->r_ctl.rc_tlp_threshold) thresh = srtt + (srtt / rack->r_ctl.rc_tlp_threshold); else thresh = (srtt * 2); /* Get the previous sent packet, if any */ segsiz = min(ctf_fixed_maxseg(tp), rack->r_ctl.rc_pace_min_segs); len = rsm->r_end - rsm->r_start; if (rack->rack_tlp_threshold_use == TLP_USE_ID) { /* Exactly like the ID */ if (((tp->snd_max - tp->snd_una) - rack->r_ctl.rc_sacked + rack->r_ctl.rc_holes_rxt) <= segsiz) { uint32_t alt_thresh; /* * Compensate for delayed-ack with the d-ack time. */ alt_thresh = srtt + (srtt / 2) + rack_delayed_ack_time; if (alt_thresh > thresh) thresh = alt_thresh; } } else if (rack->rack_tlp_threshold_use == TLP_USE_TWO_ONE) { /* 2.1 behavior */ prsm = TAILQ_PREV(rsm, rack_head, r_tnext); if (prsm && (len <= segsiz)) { /* * Two packets outstanding, thresh should be (2*srtt) + * possible inter-packet delay (if any). */ uint32_t inter_gap = 0; int idx, nidx; idx = rsm->r_rtr_cnt - 1; nidx = prsm->r_rtr_cnt - 1; if (rsm->r_tim_lastsent[nidx] >= prsm->r_tim_lastsent[idx]) { /* Yes it was sent later (or at the same time) */ inter_gap = rsm->r_tim_lastsent[idx] - prsm->r_tim_lastsent[nidx]; } thresh += inter_gap; } else if (len <= segsiz) { /* * Possibly compensate for delayed-ack. */ uint32_t alt_thresh; alt_thresh = srtt + (srtt / 2) + rack_delayed_ack_time; if (alt_thresh > thresh) thresh = alt_thresh; } } else if (rack->rack_tlp_threshold_use == TLP_USE_TWO_TWO) { /* 2.2 behavior */ if (len <= segsiz) { uint32_t alt_thresh; /* * Compensate for delayed-ack with the d-ack time. */ alt_thresh = srtt + (srtt / 2) + rack_delayed_ack_time; if (alt_thresh > thresh) thresh = alt_thresh; } } /* Not above an RTO */ if (thresh > tp->t_rxtcur) { thresh = tp->t_rxtcur; } /* Not above a RTO max */ if (thresh > rack_rto_max) { thresh = rack_rto_max; } /* Apply user supplied min TLP */ if (thresh < rack_tlp_min) { thresh = rack_tlp_min; } return (thresh); } static uint32_t rack_grab_rtt(struct tcpcb *tp, struct tcp_rack *rack) { /* * We want the rack_rtt which is the * last rtt we measured. However if that * does not exist we fallback to the srtt (which * we probably will never do) and then as a last * resort we use RACK_INITIAL_RTO if no srtt is * yet set. */ if (rack->rc_rack_rtt) return (rack->rc_rack_rtt); else if (tp->t_srtt == 0) return (RACK_INITIAL_RTO); return (tp->t_srtt); } static struct rack_sendmap * rack_check_recovery_mode(struct tcpcb *tp, uint32_t tsused) { /* * Check to see that we don't need to fall into recovery. We will * need to do so if our oldest transmit is past the time we should * have had an ack. */ struct tcp_rack *rack; struct rack_sendmap *rsm; int32_t idx; uint32_t srtt, thresh; rack = (struct tcp_rack *)tp->t_fb_ptr; if (RB_EMPTY(&rack->r_ctl.rc_mtree)) { return (NULL); } rsm = TAILQ_FIRST(&rack->r_ctl.rc_tmap); if (rsm == NULL) return (NULL); if (rsm->r_flags & RACK_ACKED) { rsm = rack_find_lowest_rsm(rack); if (rsm == NULL) return (NULL); } idx = rsm->r_rtr_cnt - 1; srtt = rack_grab_rtt(tp, rack); thresh = rack_calc_thresh_rack(rack, srtt, tsused); if (TSTMP_LT(tsused, ((uint32_t)rsm->r_tim_lastsent[idx]))) { return (NULL); } if ((tsused - ((uint32_t)rsm->r_tim_lastsent[idx])) < thresh) { return (NULL); } /* Ok if we reach here we are over-due and this guy can be sent */ rack_cong_signal(tp, CC_NDUPACK, tp->snd_una, __LINE__); return (rsm); } static uint32_t rack_get_persists_timer_val(struct tcpcb *tp, struct tcp_rack *rack) { int32_t t; int32_t tt; uint32_t ret_val; t = (tp->t_srtt + (tp->t_rttvar << 2)); RACK_TCPT_RANGESET(tt, t * tcp_backoff[tp->t_rxtshift], rack_persist_min, rack_persist_max, rack->r_ctl.timer_slop); rack->r_ctl.rc_hpts_flags |= PACE_TMR_PERSIT; ret_val = (uint32_t)tt; return (ret_val); } static uint32_t rack_timer_start(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts, int sup_rack) { /* * Start the FR timer, we do this based on getting the first one in * the rc_tmap. Note that if its NULL we must stop the timer. in all * events we need to stop the running timer (if its running) before * starting the new one. */ uint32_t thresh, exp, to, srtt, time_since_sent, tstmp_touse; uint32_t srtt_cur; int32_t idx; int32_t is_tlp_timer = 0; struct rack_sendmap *rsm; if (rack->t_timers_stopped) { /* All timers have been stopped none are to run */ return (0); } if (rack->rc_in_persist) { /* We can't start any timer in persists */ return (rack_get_persists_timer_val(tp, rack)); } rack->rc_on_min_to = 0; if ((tp->t_state < TCPS_ESTABLISHED) || ((tp->t_flags & TF_SACK_PERMIT) == 0)) { goto activate_rxt; } rsm = TAILQ_FIRST(&rack->r_ctl.rc_tmap); if ((rsm == NULL) || sup_rack) { /* Nothing on the send map or no rack */ activate_rxt: time_since_sent = 0; rsm = TAILQ_FIRST(&rack->r_ctl.rc_tmap); if (rsm) { /* * Should we discount the RTX timer any? * * We want to discount it the smallest amount. * If a timer (Rack/TLP or RXT) has gone off more * recently thats the discount we want to use (now - timer time). * If the retransmit of the oldest packet was more recent then * we want to use that (now - oldest-packet-last_transmit_time). * */ idx = rsm->r_rtr_cnt - 1; if (TSTMP_GEQ(rack->r_ctl.rc_tlp_rxt_last_time, ((uint32_t)rsm->r_tim_lastsent[idx]))) tstmp_touse = (uint32_t)rack->r_ctl.rc_tlp_rxt_last_time; else tstmp_touse = (uint32_t)rsm->r_tim_lastsent[idx]; if (TSTMP_GT(cts, tstmp_touse)) time_since_sent = cts - tstmp_touse; } if (SEQ_LT(tp->snd_una, tp->snd_max) || sbavail(&tptosocket(tp)->so_snd)) { rack->r_ctl.rc_hpts_flags |= PACE_TMR_RXT; to = tp->t_rxtcur; if (to > time_since_sent) to -= time_since_sent; else to = rack->r_ctl.rc_min_to; if (to == 0) to = 1; /* Special case for KEEPINIT */ if ((TCPS_HAVEESTABLISHED(tp->t_state) == 0) && (TP_KEEPINIT(tp) != 0) && rsm) { /* * We have to put a ceiling on the rxt timer * of the keep-init timeout. */ uint32_t max_time, red; max_time = TICKS_2_USEC(TP_KEEPINIT(tp)); if (TSTMP_GT(cts, (uint32_t)rsm->r_tim_lastsent[0])) { red = (cts - (uint32_t)rsm->r_tim_lastsent[0]); if (red < max_time) max_time -= red; else max_time = 1; } /* Reduce timeout to the keep value if needed */ if (max_time < to) to = max_time; } return (to); } return (0); } if (rsm->r_flags & RACK_ACKED) { rsm = rack_find_lowest_rsm(rack); if (rsm == NULL) { /* No lowest? */ goto activate_rxt; } } if (rack->sack_attack_disable) { /* * We don't want to do * any TLP's if you are an attacker. * Though if you are doing what * is expected you may still have * SACK-PASSED marks. */ goto activate_rxt; } /* Convert from ms to usecs */ if ((rsm->r_flags & RACK_SACK_PASSED) || (rsm->r_flags & RACK_RWND_COLLAPSED) || (rsm->r_dupack >= DUP_ACK_THRESHOLD)) { if ((tp->t_flags & TF_SENTFIN) && ((tp->snd_max - tp->snd_una) == 1) && (rsm->r_flags & RACK_HAS_FIN)) { /* * We don't start a rack timer if all we have is a * FIN outstanding. */ goto activate_rxt; } if ((rack->use_rack_rr == 0) && (IN_FASTRECOVERY(tp->t_flags)) && (rack->rack_no_prr == 0) && (rack->r_ctl.rc_prr_sndcnt < ctf_fixed_maxseg(tp))) { /* * We are not cheating, in recovery and * not enough ack's to yet get our next * retransmission out. * * Note that classified attackers do not * get to use the rack-cheat. */ goto activate_tlp; } srtt = rack_grab_rtt(tp, rack); thresh = rack_calc_thresh_rack(rack, srtt, cts); idx = rsm->r_rtr_cnt - 1; exp = ((uint32_t)rsm->r_tim_lastsent[idx]) + thresh; if (SEQ_GEQ(exp, cts)) { to = exp - cts; if (to < rack->r_ctl.rc_min_to) { to = rack->r_ctl.rc_min_to; if (rack->r_rr_config == 3) rack->rc_on_min_to = 1; } } else { to = rack->r_ctl.rc_min_to; if (rack->r_rr_config == 3) rack->rc_on_min_to = 1; } } else { /* Ok we need to do a TLP not RACK */ activate_tlp: if ((rack->rc_tlp_in_progress != 0) && (rack->r_ctl.rc_tlp_cnt_out >= rack_tlp_limit)) { /* * The previous send was a TLP and we have sent * N TLP's without sending new data. */ goto activate_rxt; } rsm = TAILQ_LAST_FAST(&rack->r_ctl.rc_tmap, rack_sendmap, r_tnext); if (rsm == NULL) { /* We found no rsm to TLP with. */ goto activate_rxt; } if (rsm->r_flags & RACK_HAS_FIN) { /* If its a FIN we dont do TLP */ rsm = NULL; goto activate_rxt; } idx = rsm->r_rtr_cnt - 1; time_since_sent = 0; if (TSTMP_GEQ(((uint32_t)rsm->r_tim_lastsent[idx]), rack->r_ctl.rc_tlp_rxt_last_time)) tstmp_touse = (uint32_t)rsm->r_tim_lastsent[idx]; else tstmp_touse = (uint32_t)rack->r_ctl.rc_tlp_rxt_last_time; if (TSTMP_GT(cts, tstmp_touse)) time_since_sent = cts - tstmp_touse; is_tlp_timer = 1; if (tp->t_srtt) { if ((rack->rc_srtt_measure_made == 0) && (tp->t_srtt == 1)) { /* * If another stack as run and set srtt to 1, * then the srtt was 0, so lets use the initial. */ srtt = RACK_INITIAL_RTO; } else { srtt_cur = tp->t_srtt; srtt = srtt_cur; } } else srtt = RACK_INITIAL_RTO; /* * If the SRTT is not keeping up and the * rack RTT has spiked we want to use * the last RTT not the smoothed one. */ if (rack_tlp_use_greater && tp->t_srtt && (srtt < rack_grab_rtt(tp, rack))) { srtt = rack_grab_rtt(tp, rack); } thresh = rack_calc_thresh_tlp(tp, rack, rsm, srtt); if (thresh > time_since_sent) { to = thresh - time_since_sent; } else { to = rack->r_ctl.rc_min_to; rack_log_alt_to_to_cancel(rack, thresh, /* flex1 */ time_since_sent, /* flex2 */ tstmp_touse, /* flex3 */ rack->r_ctl.rc_tlp_rxt_last_time, /* flex4 */ (uint32_t)rsm->r_tim_lastsent[idx], srtt, idx, 99); } if (to < rack_tlp_min) { to = rack_tlp_min; } if (to > TICKS_2_USEC(TCPTV_REXMTMAX)) { /* * If the TLP time works out to larger than the max * RTO lets not do TLP.. just RTO. */ goto activate_rxt; } } if (is_tlp_timer == 0) { rack->r_ctl.rc_hpts_flags |= PACE_TMR_RACK; } else { rack->r_ctl.rc_hpts_flags |= PACE_TMR_TLP; } if (to == 0) to = 1; return (to); } static void rack_enter_persist(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts) { if (rack->rc_in_persist == 0) { if (tp->t_flags & TF_GPUTINPROG) { /* * Stop the goodput now, the calling of the * measurement function clears the flag. */ rack_do_goodput_measurement(tp, rack, tp->snd_una, __LINE__, RACK_QUALITY_PERSIST); } #ifdef NETFLIX_SHARED_CWND if (rack->r_ctl.rc_scw) { tcp_shared_cwnd_idle(rack->r_ctl.rc_scw, rack->r_ctl.rc_scw_index); rack->rack_scwnd_is_idle = 1; } #endif rack->r_ctl.rc_went_idle_time = tcp_get_usecs(NULL); if (rack->r_ctl.rc_went_idle_time == 0) rack->r_ctl.rc_went_idle_time = 1; rack_timer_cancel(tp, rack, cts, __LINE__); rack->r_ctl.persist_lost_ends = 0; rack->probe_not_answered = 0; rack->forced_ack = 0; tp->t_rxtshift = 0; RACK_TCPT_RANGESET(tp->t_rxtcur, RACK_REXMTVAL(tp), rack_rto_min, rack_rto_max, rack->r_ctl.timer_slop); rack->rc_in_persist = 1; } } static void rack_exit_persist(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts) { if (tcp_in_hpts(rack->rc_inp)) { tcp_hpts_remove(rack->rc_inp); rack->r_ctl.rc_hpts_flags = 0; } #ifdef NETFLIX_SHARED_CWND if (rack->r_ctl.rc_scw) { tcp_shared_cwnd_active(rack->r_ctl.rc_scw, rack->r_ctl.rc_scw_index); rack->rack_scwnd_is_idle = 0; } #endif if (rack->rc_gp_dyn_mul && (rack->use_fixed_rate == 0) && (rack->rc_always_pace)) { /* * Do we count this as if a probe-rtt just * finished? */ uint32_t time_idle, idle_min; time_idle = tcp_get_usecs(NULL) - rack->r_ctl.rc_went_idle_time; idle_min = rack_min_probertt_hold; if (rack_probertt_gpsrtt_cnt_div) { uint64_t extra; extra = (uint64_t)rack->r_ctl.rc_gp_srtt * (uint64_t)rack_probertt_gpsrtt_cnt_mul; extra /= (uint64_t)rack_probertt_gpsrtt_cnt_div; idle_min += (uint32_t)extra; } if (time_idle >= idle_min) { /* Yes, we count it as a probe-rtt. */ uint32_t us_cts; us_cts = tcp_get_usecs(NULL); if (rack->in_probe_rtt == 0) { rack->r_ctl.rc_lower_rtt_us_cts = us_cts; rack->r_ctl.rc_time_probertt_entered = rack->r_ctl.rc_lower_rtt_us_cts; rack->r_ctl.rc_time_probertt_starts = rack->r_ctl.rc_lower_rtt_us_cts; rack->r_ctl.rc_time_of_last_probertt = rack->r_ctl.rc_lower_rtt_us_cts; } else { rack_exit_probertt(rack, us_cts); } } } rack->rc_in_persist = 0; rack->r_ctl.rc_went_idle_time = 0; tp->t_rxtshift = 0; RACK_TCPT_RANGESET(tp->t_rxtcur, RACK_REXMTVAL(tp), rack_rto_min, rack_rto_max, rack->r_ctl.timer_slop); rack->r_ctl.rc_agg_delayed = 0; rack->r_early = 0; rack->r_late = 0; rack->r_ctl.rc_agg_early = 0; } static void rack_log_hpts_diag(struct tcp_rack *rack, uint32_t cts, struct hpts_diag *diag, struct timeval *tv) { if (rack_verbose_logging && rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.flex1 = diag->p_nxt_slot; log.u_bbr.flex2 = diag->p_cur_slot; log.u_bbr.flex3 = diag->slot_req; log.u_bbr.flex4 = diag->inp_hptsslot; log.u_bbr.flex5 = diag->slot_remaining; log.u_bbr.flex6 = diag->need_new_to; log.u_bbr.flex7 = diag->p_hpts_active; log.u_bbr.flex8 = diag->p_on_min_sleep; /* Hijack other fields as needed */ log.u_bbr.epoch = diag->have_slept; log.u_bbr.lt_epoch = diag->yet_to_sleep; log.u_bbr.pkts_out = diag->co_ret; log.u_bbr.applimited = diag->hpts_sleep_time; log.u_bbr.delivered = diag->p_prev_slot; log.u_bbr.inflight = diag->p_runningslot; log.u_bbr.bw_inuse = diag->wheel_slot; log.u_bbr.rttProp = diag->wheel_cts; log.u_bbr.timeStamp = cts; log.u_bbr.delRate = diag->maxslots; log.u_bbr.cur_del_rate = diag->p_curtick; log.u_bbr.cur_del_rate <<= 32; log.u_bbr.cur_del_rate |= diag->p_lasttick; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_HPTSDIAG, 0, 0, &log, false, tv); } } static void rack_log_wakeup(struct tcpcb *tp, struct tcp_rack *rack, struct sockbuf *sb, uint32_t len, int type) { if (rack_verbose_logging && rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.flex1 = sb->sb_flags; log.u_bbr.flex2 = len; log.u_bbr.flex3 = sb->sb_state; log.u_bbr.flex8 = type; log.u_bbr.timeStamp = tcp_get_usecs(&tv); TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, TCP_LOG_SB_WAKE, 0, len, &log, false, &tv); } } static void rack_start_hpts_timer(struct tcp_rack *rack, struct tcpcb *tp, uint32_t cts, int32_t slot, uint32_t tot_len_this_send, int sup_rack) { struct hpts_diag diag; struct inpcb *inp = tptoinpcb(tp); struct timeval tv; uint32_t delayed_ack = 0; uint32_t hpts_timeout; uint32_t entry_slot = slot; uint8_t stopped; uint32_t left = 0; uint32_t us_cts; if ((tp->t_state == TCPS_CLOSED) || (tp->t_state == TCPS_LISTEN)) { return; } if (tcp_in_hpts(inp)) { /* Already on the pacer */ return; } stopped = rack->rc_tmr_stopped; if (stopped && TSTMP_GT(rack->r_ctl.rc_timer_exp, cts)) { left = rack->r_ctl.rc_timer_exp - cts; } rack->r_ctl.rc_timer_exp = 0; rack->r_ctl.rc_hpts_flags = 0; us_cts = tcp_get_usecs(&tv); /* Now early/late accounting */ rack_log_pacing_delay_calc(rack, entry_slot, slot, 0, 0, 0, 26, __LINE__, NULL, 0); if (rack->r_early && (rack->rc_ack_can_sendout_data == 0)) { /* * We have a early carry over set, * we can always add more time so we * can always make this compensation. * * Note if ack's are allowed to wake us do not * penalize the next timer for being awoke * by an ack aka the rc_agg_early (non-paced mode). */ slot += rack->r_ctl.rc_agg_early; rack->r_early = 0; rack->r_ctl.rc_agg_early = 0; } if (rack->r_late) { /* * This is harder, we can * compensate some but it * really depends on what * the current pacing time is. */ if (rack->r_ctl.rc_agg_delayed >= slot) { /* * We can't compensate for it all. * And we have to have some time * on the clock. We always have a min * 10 slots (10 x 10 i.e. 100 usecs). */ if (slot <= HPTS_TICKS_PER_SLOT) { /* We gain delay */ rack->r_ctl.rc_agg_delayed += (HPTS_TICKS_PER_SLOT - slot); slot = HPTS_TICKS_PER_SLOT; } else { /* We take off some */ rack->r_ctl.rc_agg_delayed -= (slot - HPTS_TICKS_PER_SLOT); slot = HPTS_TICKS_PER_SLOT; } } else { slot -= rack->r_ctl.rc_agg_delayed; rack->r_ctl.rc_agg_delayed = 0; /* Make sure we have 100 useconds at minimum */ if (slot < HPTS_TICKS_PER_SLOT) { rack->r_ctl.rc_agg_delayed = HPTS_TICKS_PER_SLOT - slot; slot = HPTS_TICKS_PER_SLOT; } if (rack->r_ctl.rc_agg_delayed == 0) rack->r_late = 0; } } if (slot) { /* We are pacing too */ rack->r_ctl.rc_hpts_flags |= PACE_PKT_OUTPUT; } hpts_timeout = rack_timer_start(tp, rack, cts, sup_rack); #ifdef NETFLIX_EXP_DETECTION if (rack->sack_attack_disable && (slot < tcp_sad_pacing_interval)) { /* * We have a potential attacker on * the line. We have possibly some * (or now) pacing time set. We want to * slow down the processing of sacks by some * amount (if it is an attacker). Set the default * slot for attackers in place (unless the orginal * interval is longer). Its stored in * micro-seconds, so lets convert to msecs. */ slot = tcp_sad_pacing_interval; } #endif if (tp->t_flags & TF_DELACK) { delayed_ack = TICKS_2_USEC(tcp_delacktime); rack->r_ctl.rc_hpts_flags |= PACE_TMR_DELACK; } if (delayed_ack && ((hpts_timeout == 0) || (delayed_ack < hpts_timeout))) hpts_timeout = delayed_ack; else rack->r_ctl.rc_hpts_flags &= ~PACE_TMR_DELACK; /* * If no timers are going to run and we will fall off the hptsi * wheel, we resort to a keep-alive timer if its configured. */ if ((hpts_timeout == 0) && (slot == 0)) { if ((V_tcp_always_keepalive || inp->inp_socket->so_options & SO_KEEPALIVE) && (tp->t_state <= TCPS_CLOSING)) { /* * Ok we have no timer (persists, rack, tlp, rxt or * del-ack), we don't have segments being paced. So * all that is left is the keepalive timer. */ if (TCPS_HAVEESTABLISHED(tp->t_state)) { /* Get the established keep-alive time */ hpts_timeout = TICKS_2_USEC(TP_KEEPIDLE(tp)); } else { /* * Get the initial setup keep-alive time, * note that this is probably not going to * happen, since rack will be running a rxt timer * if a SYN of some sort is outstanding. It is * actually handled in rack_timeout_rxt(). */ hpts_timeout = TICKS_2_USEC(TP_KEEPINIT(tp)); } rack->r_ctl.rc_hpts_flags |= PACE_TMR_KEEP; if (rack->in_probe_rtt) { /* * We want to instead not wake up a long time from * now but to wake up about the time we would * exit probe-rtt and initiate a keep-alive ack. * This will get us out of probe-rtt and update * our min-rtt. */ hpts_timeout = rack_min_probertt_hold; } } } if (left && (stopped & (PACE_TMR_KEEP | PACE_TMR_DELACK)) == (rack->r_ctl.rc_hpts_flags & PACE_TMR_MASK)) { /* * RACK, TLP, persists and RXT timers all are restartable * based on actions input .. i.e we received a packet (ack * or sack) and that changes things (rw, or snd_una etc). * Thus we can restart them with a new value. For * keep-alive, delayed_ack we keep track of what was left * and restart the timer with a smaller value. */ if (left < hpts_timeout) hpts_timeout = left; } if (hpts_timeout) { /* * Hack alert for now we can't time-out over 2,147,483 * seconds (a bit more than 596 hours), which is probably ok * :). */ if (hpts_timeout > 0x7ffffffe) hpts_timeout = 0x7ffffffe; rack->r_ctl.rc_timer_exp = cts + hpts_timeout; } rack_log_pacing_delay_calc(rack, entry_slot, slot, hpts_timeout, 0, 0, 27, __LINE__, NULL, 0); if ((rack->gp_ready == 0) && (rack->use_fixed_rate == 0) && (hpts_timeout < slot) && (rack->r_ctl.rc_hpts_flags & (PACE_TMR_TLP|PACE_TMR_RXT))) { /* * We have no good estimate yet for the * old clunky burst mitigation or the * real pacing. And the tlp or rxt is smaller * than the pacing calculation. Lets not * pace that long since we know the calculation * so far is not accurate. */ slot = hpts_timeout; } /** * Turn off all the flags for queuing by default. The * flags have important meanings to what happens when * LRO interacts with the transport. Most likely (by default now) * mbuf_queueing and ack compression are on. So the transport * has a couple of flags that control what happens (if those * are not on then these flags won't have any effect since it * won't go through the queuing LRO path). * * INP_MBUF_QUEUE_READY - This flags says that I am busy * pacing output, so don't disturb. But * it also means LRO can wake me if there * is a SACK arrival. * * INP_DONT_SACK_QUEUE - This flag is used in conjunction * with the above flag (QUEUE_READY) and * when present it says don't even wake me * if a SACK arrives. * * The idea behind these flags is that if we are pacing we * set the MBUF_QUEUE_READY and only get woken up if * a SACK arrives (which could change things) or if * our pacing timer expires. If, however, we have a rack * timer running, then we don't even want a sack to wake * us since the rack timer has to expire before we can send. * * Other cases should usually have none of the flags set * so LRO can call into us. */ inp->inp_flags2 &= ~(INP_DONT_SACK_QUEUE|INP_MBUF_QUEUE_READY); if (slot) { rack->r_ctl.rc_last_output_to = us_cts + slot; /* * A pacing timer (slot) is being set, in * such a case we cannot send (we are blocked by * the timer). So lets tell LRO that it should not * wake us unless there is a SACK. Note this only * will be effective if mbuf queueing is on or * compressed acks are being processed. */ inp->inp_flags2 |= INP_MBUF_QUEUE_READY; /* * But wait if we have a Rack timer running * even a SACK should not disturb us (with * the exception of r_rr_config 3). */ if ((rack->r_ctl.rc_hpts_flags & PACE_TMR_RACK) && (rack->r_rr_config != 3)) inp->inp_flags2 |= INP_DONT_SACK_QUEUE; if (rack->rc_ack_can_sendout_data) { /* * Ahh but wait, this is that special case * where the pacing timer can be disturbed * backout the changes (used for non-paced * burst limiting). */ inp->inp_flags2 &= ~(INP_DONT_SACK_QUEUE|INP_MBUF_QUEUE_READY); } if ((rack->use_rack_rr) && (rack->r_rr_config < 2) && ((hpts_timeout) && (hpts_timeout < slot))) { /* * Arrange for the hpts to kick back in after the * t-o if the t-o does not cause a send. */ (void)tcp_hpts_insert_diag(inp, HPTS_USEC_TO_SLOTS(hpts_timeout), __LINE__, &diag); rack_log_hpts_diag(rack, us_cts, &diag, &tv); rack_log_to_start(rack, cts, hpts_timeout, slot, 0); } else { (void)tcp_hpts_insert_diag(inp, HPTS_USEC_TO_SLOTS(slot), __LINE__, &diag); rack_log_hpts_diag(rack, us_cts, &diag, &tv); rack_log_to_start(rack, cts, hpts_timeout, slot, 1); } } else if (hpts_timeout) { /* * With respect to inp_flags2 here, lets let any new acks wake * us up here. Since we are not pacing (no pacing timer), output * can happen so we should let it. If its a Rack timer, then any inbound * packet probably won't change the sending (we will be blocked) * but it may change the prr stats so letting it in (the set defaults * at the start of this block) are good enough. */ (void)tcp_hpts_insert_diag(inp, HPTS_USEC_TO_SLOTS(hpts_timeout), __LINE__, &diag); rack_log_hpts_diag(rack, us_cts, &diag, &tv); rack_log_to_start(rack, cts, hpts_timeout, slot, 0); } else { /* No timer starting */ #ifdef INVARIANTS if (SEQ_GT(tp->snd_max, tp->snd_una)) { panic("tp:%p rack:%p tlts:%d cts:%u slot:%u pto:%u -- no timer started?", tp, rack, tot_len_this_send, cts, slot, hpts_timeout); } #endif } rack->rc_tmr_stopped = 0; if (slot) rack_log_type_bbrsnd(rack, tot_len_this_send, slot, us_cts, &tv); } /* * RACK Timer, here we simply do logging and house keeping. * the normal rack_output() function will call the * appropriate thing to check if we need to do a RACK retransmit. * We return 1, saying don't proceed with rack_output only * when all timers have been stopped (destroyed PCB?). */ static int rack_timeout_rack(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts) { /* * This timer simply provides an internal trigger to send out data. * The check_recovery_mode call will see if there are needed * retransmissions, if so we will enter fast-recovery. The output * call may or may not do the same thing depending on sysctl * settings. */ struct rack_sendmap *rsm; counter_u64_add(rack_to_tot, 1); if (rack->r_state && (rack->r_state != tp->t_state)) rack_set_state(tp, rack); rack->rc_on_min_to = 0; rsm = rack_check_recovery_mode(tp, cts); rack_log_to_event(rack, RACK_TO_FRM_RACK, rsm); if (rsm) { rack->r_ctl.rc_resend = rsm; rack->r_timer_override = 1; if (rack->use_rack_rr) { /* * Don't accumulate extra pacing delay * we are allowing the rack timer to * over-ride pacing i.e. rrr takes precedence * if the pacing interval is longer than the rrr * time (in other words we get the min pacing * time versus rrr pacing time). */ rack->r_ctl.rc_hpts_flags &= ~PACE_PKT_OUTPUT; } } rack->r_ctl.rc_hpts_flags &= ~PACE_TMR_RACK; if (rsm == NULL) { /* restart a timer and return 1 */ rack_start_hpts_timer(rack, tp, cts, 0, 0, 0); return (1); } return (0); } static void rack_adjust_orig_mlen(struct rack_sendmap *rsm) { if (rsm->m->m_len > rsm->orig_m_len) { /* * Mbuf grew, caused by sbcompress, our offset does * not change. */ rsm->orig_m_len = rsm->m->m_len; } else if (rsm->m->m_len < rsm->orig_m_len) { /* * Mbuf shrank, trimmed off the top by an ack, our * offset changes. */ rsm->soff -= (rsm->orig_m_len - rsm->m->m_len); rsm->orig_m_len = rsm->m->m_len; } } static void rack_setup_offset_for_rsm(struct rack_sendmap *src_rsm, struct rack_sendmap *rsm) { struct mbuf *m; uint32_t soff; if (src_rsm->m && (src_rsm->orig_m_len != src_rsm->m->m_len)) { /* Fix up the orig_m_len and possibly the mbuf offset */ rack_adjust_orig_mlen(src_rsm); } m = src_rsm->m; soff = src_rsm->soff + (src_rsm->r_end - src_rsm->r_start); while (soff >= m->m_len) { /* Move out past this mbuf */ soff -= m->m_len; m = m->m_next; KASSERT((m != NULL), ("rsm:%p nrsm:%p hit at soff:%u null m", src_rsm, rsm, soff)); } rsm->m = m; rsm->soff = soff; rsm->orig_m_len = m->m_len; } static __inline void rack_clone_rsm(struct tcp_rack *rack, struct rack_sendmap *nrsm, struct rack_sendmap *rsm, uint32_t start) { int idx; nrsm->r_start = start; nrsm->r_end = rsm->r_end; nrsm->r_rtr_cnt = rsm->r_rtr_cnt; nrsm->r_flags = rsm->r_flags; nrsm->r_dupack = rsm->r_dupack; nrsm->r_no_rtt_allowed = rsm->r_no_rtt_allowed; nrsm->r_rtr_bytes = 0; nrsm->r_fas = rsm->r_fas; rsm->r_end = nrsm->r_start; nrsm->r_just_ret = rsm->r_just_ret; for (idx = 0; idx < nrsm->r_rtr_cnt; idx++) { nrsm->r_tim_lastsent[idx] = rsm->r_tim_lastsent[idx]; } /* Now if we have SYN flag we keep it on the left edge */ if (nrsm->r_flags & RACK_HAS_SYN) nrsm->r_flags &= ~RACK_HAS_SYN; /* Now if we have a FIN flag we keep it on the right edge */ if (rsm->r_flags & RACK_HAS_FIN) rsm->r_flags &= ~RACK_HAS_FIN; /* Push bit must go to the right edge as well */ if (rsm->r_flags & RACK_HAD_PUSH) rsm->r_flags &= ~RACK_HAD_PUSH; /* Clone over the state of the hw_tls flag */ nrsm->r_hw_tls = rsm->r_hw_tls; /* * Now we need to find nrsm's new location in the mbuf chain * we basically calculate a new offset, which is soff + * how much is left in original rsm. Then we walk out the mbuf * chain to find the righ position, it may be the same mbuf * or maybe not. */ KASSERT(((rsm->m != NULL) || (rsm->r_flags & (RACK_HAS_SYN|RACK_HAS_FIN))), ("rsm:%p nrsm:%p rack:%p -- rsm->m is NULL?", rsm, nrsm, rack)); if (rsm->m) rack_setup_offset_for_rsm(rsm, nrsm); } static struct rack_sendmap * rack_merge_rsm(struct tcp_rack *rack, struct rack_sendmap *l_rsm, struct rack_sendmap *r_rsm) { /* * We are merging two ack'd RSM's, * the l_rsm is on the left (lower seq * values) and the r_rsm is on the right * (higher seq value). The simplest way * to merge these is to move the right * one into the left. I don't think there * is any reason we need to try to find * the oldest (or last oldest retransmitted). */ #ifdef INVARIANTS struct rack_sendmap *rm; #endif rack_log_map_chg(rack->rc_tp, rack, NULL, l_rsm, r_rsm, MAP_MERGE, r_rsm->r_end, __LINE__); l_rsm->r_end = r_rsm->r_end; if (l_rsm->r_dupack < r_rsm->r_dupack) l_rsm->r_dupack = r_rsm->r_dupack; if (r_rsm->r_rtr_bytes) l_rsm->r_rtr_bytes += r_rsm->r_rtr_bytes; if (r_rsm->r_in_tmap) { /* This really should not happen */ TAILQ_REMOVE(&rack->r_ctl.rc_tmap, r_rsm, r_tnext); r_rsm->r_in_tmap = 0; } /* Now the flags */ if (r_rsm->r_flags & RACK_HAS_FIN) l_rsm->r_flags |= RACK_HAS_FIN; if (r_rsm->r_flags & RACK_TLP) l_rsm->r_flags |= RACK_TLP; if (r_rsm->r_flags & RACK_RWND_COLLAPSED) l_rsm->r_flags |= RACK_RWND_COLLAPSED; if ((r_rsm->r_flags & RACK_APP_LIMITED) && ((l_rsm->r_flags & RACK_APP_LIMITED) == 0)) { /* * If both are app-limited then let the * free lower the count. If right is app * limited and left is not, transfer. */ l_rsm->r_flags |= RACK_APP_LIMITED; r_rsm->r_flags &= ~RACK_APP_LIMITED; if (r_rsm == rack->r_ctl.rc_first_appl) rack->r_ctl.rc_first_appl = l_rsm; } #ifndef INVARIANTS (void)RB_REMOVE(rack_rb_tree_head, &rack->r_ctl.rc_mtree, r_rsm); #else rm = RB_REMOVE(rack_rb_tree_head, &rack->r_ctl.rc_mtree, r_rsm); if (rm != r_rsm) { panic("removing head in rack:%p rsm:%p rm:%p", rack, r_rsm, rm); } #endif if ((r_rsm->r_limit_type == 0) && (l_rsm->r_limit_type != 0)) { /* Transfer the split limit to the map we free */ r_rsm->r_limit_type = l_rsm->r_limit_type; l_rsm->r_limit_type = 0; } rack_free(rack, r_rsm); return (l_rsm); } /* * TLP Timer, here we simply setup what segment we want to * have the TLP expire on, the normal rack_output() will then * send it out. * * We return 1, saying don't proceed with rack_output only * when all timers have been stopped (destroyed PCB?). */ static int rack_timeout_tlp(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts, uint8_t *doing_tlp) { /* * Tail Loss Probe. */ struct rack_sendmap *rsm = NULL; #ifdef INVARIANTS struct rack_sendmap *insret; #endif struct socket *so = tptosocket(tp); uint32_t amm; uint32_t out, avail; int collapsed_win = 0; if (TSTMP_LT(cts, rack->r_ctl.rc_timer_exp)) { /* Its not time yet */ return (0); } if (ctf_progress_timeout_check(tp, true)) { rack_log_progress_event(rack, tp, tick, PROGRESS_DROP, __LINE__); return (-ETIMEDOUT); /* tcp_drop() */ } /* * A TLP timer has expired. We have been idle for 2 rtts. So we now * need to figure out how to force a full MSS segment out. */ rack_log_to_event(rack, RACK_TO_FRM_TLP, NULL); rack->r_ctl.retran_during_recovery = 0; rack->r_ctl.dsack_byte_cnt = 0; counter_u64_add(rack_tlp_tot, 1); if (rack->r_state && (rack->r_state != tp->t_state)) rack_set_state(tp, rack); avail = sbavail(&so->so_snd); out = tp->snd_max - tp->snd_una; if ((out > tp->snd_wnd) || rack->rc_has_collapsed) { /* special case, we need a retransmission */ collapsed_win = 1; goto need_retran; } if (rack->r_ctl.dsack_persist && (rack->r_ctl.rc_tlp_cnt_out >= 1)) { rack->r_ctl.dsack_persist--; if (rack->r_ctl.num_dsack && (rack->r_ctl.dsack_persist == 0)) { rack->r_ctl.num_dsack = 0; } rack_log_dsack_event(rack, 1, __LINE__, 0, 0); } if ((tp->t_flags & TF_GPUTINPROG) && (rack->r_ctl.rc_tlp_cnt_out == 1)) { /* * If this is the second in a row * TLP and we are doing a measurement * its time to abandon the measurement. * Something is likely broken on * the clients network and measuring a * broken network does us no good. */ tp->t_flags &= ~TF_GPUTINPROG; rack_log_pacing_delay_calc(rack, (tp->gput_ack - tp->gput_seq) /*flex2*/, rack->r_ctl.rc_gp_srtt /*flex1*/, tp->gput_seq, 0, 0, 18, __LINE__, NULL, 0); } /* * Check our send oldest always settings, and if * there is an oldest to send jump to the need_retran. */ if (rack_always_send_oldest && (TAILQ_EMPTY(&rack->r_ctl.rc_tmap) == 0)) goto need_retran; if (avail > out) { /* New data is available */ amm = avail - out; if (amm > ctf_fixed_maxseg(tp)) { amm = ctf_fixed_maxseg(tp); if ((amm + out) > tp->snd_wnd) { /* We are rwnd limited */ goto need_retran; } } else if (amm < ctf_fixed_maxseg(tp)) { /* not enough to fill a MTU */ goto need_retran; } if (IN_FASTRECOVERY(tp->t_flags)) { /* Unlikely */ if (rack->rack_no_prr == 0) { if (out + amm <= tp->snd_wnd) { rack->r_ctl.rc_prr_sndcnt = amm; rack->r_ctl.rc_tlp_new_data = amm; rack_log_to_prr(rack, 4, 0, __LINE__); } } else goto need_retran; } else { /* Set the send-new override */ if (out + amm <= tp->snd_wnd) rack->r_ctl.rc_tlp_new_data = amm; else goto need_retran; } rack->r_ctl.rc_tlpsend = NULL; counter_u64_add(rack_tlp_newdata, 1); goto send; } need_retran: /* * Ok we need to arrange the last un-acked segment to be re-sent, or * optionally the first un-acked segment. */ if (collapsed_win == 0) { if (rack_always_send_oldest) rsm = TAILQ_FIRST(&rack->r_ctl.rc_tmap); else { rsm = RB_MAX(rack_rb_tree_head, &rack->r_ctl.rc_mtree); if (rsm && (rsm->r_flags & (RACK_ACKED | RACK_HAS_FIN))) { rsm = rack_find_high_nonack(rack, rsm); } } if (rsm == NULL) { #ifdef TCP_BLACKBOX tcp_log_dump_tp_logbuf(tp, "nada counter trips", M_NOWAIT, true); #endif goto out; } } else { /* * We must find the last segment * that was acceptable by the client. */ RB_FOREACH_REVERSE(rsm, rack_rb_tree_head, &rack->r_ctl.rc_mtree) { if ((rsm->r_flags & RACK_RWND_COLLAPSED) == 0) { /* Found one */ break; } } if (rsm == NULL) { /* None? if so send the first */ rsm = RB_MIN(rack_rb_tree_head, &rack->r_ctl.rc_mtree); if (rsm == NULL) { #ifdef TCP_BLACKBOX tcp_log_dump_tp_logbuf(tp, "nada counter trips", M_NOWAIT, true); #endif goto out; } } } if ((rsm->r_end - rsm->r_start) > ctf_fixed_maxseg(tp)) { /* * We need to split this the last segment in two. */ struct rack_sendmap *nrsm; nrsm = rack_alloc_full_limit(rack); if (nrsm == NULL) { /* * No memory to split, we will just exit and punt * off to the RXT timer. */ goto out; } rack_clone_rsm(rack, nrsm, rsm, (rsm->r_end - ctf_fixed_maxseg(tp))); rack_log_map_chg(tp, rack, NULL, rsm, nrsm, MAP_SPLIT, 0, __LINE__); #ifndef INVARIANTS (void)RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); #else insret = RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); if (insret != NULL) { panic("Insert in rb tree of %p fails ret:%p rack:%p rsm:%p", nrsm, insret, rack, rsm); } #endif if (rsm->r_in_tmap) { TAILQ_INSERT_AFTER(&rack->r_ctl.rc_tmap, rsm, nrsm, r_tnext); nrsm->r_in_tmap = 1; } rsm = nrsm; } rack->r_ctl.rc_tlpsend = rsm; send: /* Make sure output path knows we are doing a TLP */ *doing_tlp = 1; rack->r_timer_override = 1; rack->r_ctl.rc_hpts_flags &= ~PACE_TMR_TLP; return (0); out: rack->r_ctl.rc_hpts_flags &= ~PACE_TMR_TLP; return (0); } /* * Delayed ack Timer, here we simply need to setup the * ACK_NOW flag and remove the DELACK flag. From there * the output routine will send the ack out. * * We only return 1, saying don't proceed, if all timers * are stopped (destroyed PCB?). */ static int rack_timeout_delack(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts) { rack_log_to_event(rack, RACK_TO_FRM_DELACK, NULL); tp->t_flags &= ~TF_DELACK; tp->t_flags |= TF_ACKNOW; KMOD_TCPSTAT_INC(tcps_delack); rack->r_ctl.rc_hpts_flags &= ~PACE_TMR_DELACK; return (0); } /* * Persists timer, here we simply send the * same thing as a keepalive will. * the one byte send. * * We only return 1, saying don't proceed, if all timers * are stopped (destroyed PCB?). */ static int rack_timeout_persist(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts) { struct tcptemp *t_template; int32_t retval = 1; if (rack->rc_in_persist == 0) return (0); if (ctf_progress_timeout_check(tp, false)) { tcp_log_end_status(tp, TCP_EI_STATUS_PERSIST_MAX); rack_log_progress_event(rack, tp, tick, PROGRESS_DROP, __LINE__); counter_u64_add(rack_persists_lost_ends, rack->r_ctl.persist_lost_ends); return (-ETIMEDOUT); /* tcp_drop() */ } /* * Persistence timer into zero window. Force a byte to be output, if * possible. */ KMOD_TCPSTAT_INC(tcps_persisttimeo); /* * Hack: if the peer is dead/unreachable, we do not time out if the * window is closed. After a full backoff, drop the connection if * the idle time (no responses to probes) reaches the maximum * backoff that we would use if retransmitting. */ if (tp->t_rxtshift == TCP_MAXRXTSHIFT && (ticks - tp->t_rcvtime >= tcp_maxpersistidle || TICKS_2_USEC(ticks - tp->t_rcvtime) >= RACK_REXMTVAL(tp) * tcp_totbackoff)) { KMOD_TCPSTAT_INC(tcps_persistdrop); tcp_log_end_status(tp, TCP_EI_STATUS_PERSIST_MAX); counter_u64_add(rack_persists_lost_ends, rack->r_ctl.persist_lost_ends); retval = -ETIMEDOUT; /* tcp_drop() */ goto out; } if ((sbavail(&rack->rc_inp->inp_socket->so_snd) == 0) && tp->snd_una == tp->snd_max) rack_exit_persist(tp, rack, cts); rack->r_ctl.rc_hpts_flags &= ~PACE_TMR_PERSIT; /* * If the user has closed the socket then drop a persisting * connection after a much reduced timeout. */ if (tp->t_state > TCPS_CLOSE_WAIT && (ticks - tp->t_rcvtime) >= TCPTV_PERSMAX) { KMOD_TCPSTAT_INC(tcps_persistdrop); tcp_log_end_status(tp, TCP_EI_STATUS_PERSIST_MAX); counter_u64_add(rack_persists_lost_ends, rack->r_ctl.persist_lost_ends); retval = -ETIMEDOUT; /* tcp_drop() */ goto out; } t_template = tcpip_maketemplate(rack->rc_inp); if (t_template) { /* only set it if we were answered */ if (rack->forced_ack == 0) { rack->forced_ack = 1; rack->r_ctl.forced_ack_ts = tcp_get_usecs(NULL); } else { rack->probe_not_answered = 1; counter_u64_add(rack_persists_loss, 1); rack->r_ctl.persist_lost_ends++; } counter_u64_add(rack_persists_sends, 1); tcp_respond(tp, t_template->tt_ipgen, &t_template->tt_t, (struct mbuf *)NULL, tp->rcv_nxt, tp->snd_una - 1, 0); /* This sends an ack */ if (tp->t_flags & TF_DELACK) tp->t_flags &= ~TF_DELACK; free(t_template, M_TEMP); } if (tp->t_rxtshift < TCP_MAXRXTSHIFT) tp->t_rxtshift++; out: rack_log_to_event(rack, RACK_TO_FRM_PERSIST, NULL); rack_start_hpts_timer(rack, tp, cts, 0, 0, 0); return (retval); } /* * If a keepalive goes off, we had no other timers * happening. We always return 1 here since this * routine either drops the connection or sends * out a segment with respond. */ static int rack_timeout_keepalive(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts) { struct tcptemp *t_template; struct inpcb *inp = tptoinpcb(tp); rack->r_ctl.rc_hpts_flags &= ~PACE_TMR_KEEP; rack_log_to_event(rack, RACK_TO_FRM_KEEP, NULL); /* * Keep-alive timer went off; send something or drop connection if * idle for too long. */ KMOD_TCPSTAT_INC(tcps_keeptimeo); if (tp->t_state < TCPS_ESTABLISHED) goto dropit; if ((V_tcp_always_keepalive || inp->inp_socket->so_options & SO_KEEPALIVE) && tp->t_state <= TCPS_CLOSING) { if (ticks - tp->t_rcvtime >= TP_KEEPIDLE(tp) + TP_MAXIDLE(tp)) goto dropit; /* * Send a packet designed to force a response if the peer is * up and reachable: either an ACK if the connection is * still alive, or an RST if the peer has closed the * connection due to timeout or reboot. Using sequence * number tp->snd_una-1 causes the transmitted zero-length * segment to lie outside the receive window; by the * protocol spec, this requires the correspondent TCP to * respond. */ KMOD_TCPSTAT_INC(tcps_keepprobe); t_template = tcpip_maketemplate(inp); if (t_template) { if (rack->forced_ack == 0) { rack->forced_ack = 1; rack->r_ctl.forced_ack_ts = tcp_get_usecs(NULL); } else { rack->probe_not_answered = 1; } tcp_respond(tp, t_template->tt_ipgen, &t_template->tt_t, (struct mbuf *)NULL, tp->rcv_nxt, tp->snd_una - 1, 0); free(t_template, M_TEMP); } } rack_start_hpts_timer(rack, tp, cts, 0, 0, 0); return (1); dropit: KMOD_TCPSTAT_INC(tcps_keepdrops); tcp_log_end_status(tp, TCP_EI_STATUS_KEEP_MAX); return (-ETIMEDOUT); /* tcp_drop() */ } /* * Retransmit helper function, clear up all the ack * flags and take care of important book keeping. */ static void rack_remxt_tmr(struct tcpcb *tp) { /* * The retransmit timer went off, all sack'd blocks must be * un-acked. */ struct rack_sendmap *rsm, *trsm = NULL; struct tcp_rack *rack; rack = (struct tcp_rack *)tp->t_fb_ptr; rack_timer_cancel(tp, rack, tcp_get_usecs(NULL), __LINE__); rack_log_to_event(rack, RACK_TO_FRM_TMR, NULL); if (rack->r_state && (rack->r_state != tp->t_state)) rack_set_state(tp, rack); /* * Ideally we would like to be able to * mark SACK-PASS on anything not acked here. * * However, if we do that we would burst out * all that data 1ms apart. This would be unwise, * so for now we will just let the normal rxt timer * and tlp timer take care of it. * * Also we really need to stick them back in sequence * order. This way we send in the proper order and any * sacks that come floating in will "re-ack" the data. * To do this we zap the tmap with an INIT and then * walk through and place every rsm in the RB tree * back in its seq ordered place. */ TAILQ_INIT(&rack->r_ctl.rc_tmap); RB_FOREACH(rsm, rack_rb_tree_head, &rack->r_ctl.rc_mtree) { rsm->r_dupack = 0; rack_log_retran_reason(rack, rsm, __LINE__, 0, 2); /* We must re-add it back to the tlist */ if (trsm == NULL) { TAILQ_INSERT_HEAD(&rack->r_ctl.rc_tmap, rsm, r_tnext); } else { TAILQ_INSERT_AFTER(&rack->r_ctl.rc_tmap, trsm, rsm, r_tnext); } rsm->r_in_tmap = 1; trsm = rsm; if (rsm->r_flags & RACK_ACKED) rsm->r_flags |= RACK_WAS_ACKED; rsm->r_flags &= ~(RACK_ACKED | RACK_SACK_PASSED | RACK_WAS_SACKPASS | RACK_RWND_COLLAPSED); rsm->r_flags |= RACK_MUST_RXT; } /* Clear the count (we just un-acked them) */ rack->r_ctl.rc_last_timeout_snduna = tp->snd_una; rack->r_ctl.rc_sacked = 0; rack->r_ctl.rc_sacklast = NULL; rack->r_ctl.rc_agg_delayed = 0; rack->r_early = 0; rack->r_ctl.rc_agg_early = 0; rack->r_late = 0; /* Clear the tlp rtx mark */ rack->r_ctl.rc_resend = RB_MIN(rack_rb_tree_head, &rack->r_ctl.rc_mtree); if (rack->r_ctl.rc_resend != NULL) rack->r_ctl.rc_resend->r_flags |= RACK_TO_REXT; rack->r_ctl.rc_prr_sndcnt = 0; rack_log_to_prr(rack, 6, 0, __LINE__); rack->r_timer_override = 1; if ((((tp->t_flags & TF_SACK_PERMIT) == 0) #ifdef NETFLIX_EXP_DETECTION || (rack->sack_attack_disable != 0) #endif ) && ((tp->t_flags & TF_SENTFIN) == 0)) { /* * For non-sack customers new data * needs to go out as retransmits until * we retransmit up to snd_max. */ rack->r_must_retran = 1; rack->r_ctl.rc_out_at_rto = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); } rack->r_ctl.rc_snd_max_at_rto = tp->snd_max; } static void rack_convert_rtts(struct tcpcb *tp) { if (tp->t_srtt > 1) { uint32_t val, frac; val = tp->t_srtt >> TCP_RTT_SHIFT; frac = tp->t_srtt & 0x1f; tp->t_srtt = TICKS_2_USEC(val); /* * frac is the fractional part of the srtt (if any) * but its in ticks and every bit represents * 1/32nd of a hz. */ if (frac) { if (hz == 1000) { frac = (((uint64_t)frac * (uint64_t)HPTS_USEC_IN_MSEC) / (uint64_t)TCP_RTT_SCALE); } else { frac = (((uint64_t)frac * (uint64_t)HPTS_USEC_IN_SEC) / ((uint64_t)(hz) * (uint64_t)TCP_RTT_SCALE)); } tp->t_srtt += frac; } } if (tp->t_rttvar) { uint32_t val, frac; val = tp->t_rttvar >> TCP_RTTVAR_SHIFT; frac = tp->t_rttvar & 0x1f; tp->t_rttvar = TICKS_2_USEC(val); /* * frac is the fractional part of the srtt (if any) * but its in ticks and every bit represents * 1/32nd of a hz. */ if (frac) { if (hz == 1000) { frac = (((uint64_t)frac * (uint64_t)HPTS_USEC_IN_MSEC) / (uint64_t)TCP_RTT_SCALE); } else { frac = (((uint64_t)frac * (uint64_t)HPTS_USEC_IN_SEC) / ((uint64_t)(hz) * (uint64_t)TCP_RTT_SCALE)); } tp->t_rttvar += frac; } } tp->t_rxtcur = RACK_REXMTVAL(tp); if (TCPS_HAVEESTABLISHED(tp->t_state)) { tp->t_rxtcur += TICKS_2_USEC(tcp_rexmit_slop); } if (tp->t_rxtcur > rack_rto_max) { tp->t_rxtcur = rack_rto_max; } } static void rack_cc_conn_init(struct tcpcb *tp) { struct tcp_rack *rack; uint32_t srtt; rack = (struct tcp_rack *)tp->t_fb_ptr; srtt = tp->t_srtt; cc_conn_init(tp); /* * Now convert to rack's internal format, * if required. */ if ((srtt == 0) && (tp->t_srtt != 0)) rack_convert_rtts(tp); /* * We want a chance to stay in slowstart as * we create a connection. TCP spec says that * initially ssthresh is infinite. For our * purposes that is the snd_wnd. */ if (tp->snd_ssthresh < tp->snd_wnd) { tp->snd_ssthresh = tp->snd_wnd; } /* * We also want to assure a IW worth of * data can get inflight. */ if (rc_init_window(rack) < tp->snd_cwnd) tp->snd_cwnd = rc_init_window(rack); } /* * Re-transmit timeout! If we drop the PCB we will return 1, otherwise * we will setup to retransmit the lowest seq number outstanding. */ static int rack_timeout_rxt(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts) { struct inpcb *inp = tptoinpcb(tp); int32_t rexmt; int32_t retval = 0; bool isipv6; if ((tp->t_flags & TF_GPUTINPROG) && (tp->t_rxtshift)) { /* * We have had a second timeout * measurements on successive rxt's are not profitable. * It is unlikely to be of any use (the network is * broken or the client went away). */ tp->t_flags &= ~TF_GPUTINPROG; rack_log_pacing_delay_calc(rack, (tp->gput_ack - tp->gput_seq) /*flex2*/, rack->r_ctl.rc_gp_srtt /*flex1*/, tp->gput_seq, 0, 0, 18, __LINE__, NULL, 0); } if (ctf_progress_timeout_check(tp, false)) { tcp_log_end_status(tp, TCP_EI_STATUS_RETRAN); rack_log_progress_event(rack, tp, tick, PROGRESS_DROP, __LINE__); return (-ETIMEDOUT); /* tcp_drop() */ } rack->r_ctl.rc_hpts_flags &= ~PACE_TMR_RXT; rack->r_ctl.retran_during_recovery = 0; rack->rc_ack_required = 1; rack->r_ctl.dsack_byte_cnt = 0; if (IN_FASTRECOVERY(tp->t_flags)) tp->t_flags |= TF_WASFRECOVERY; else tp->t_flags &= ~TF_WASFRECOVERY; if (IN_CONGRECOVERY(tp->t_flags)) tp->t_flags |= TF_WASCRECOVERY; else tp->t_flags &= ~TF_WASCRECOVERY; if (TCPS_HAVEESTABLISHED(tp->t_state) && (tp->snd_una == tp->snd_max)) { /* Nothing outstanding .. nothing to do */ return (0); } if (rack->r_ctl.dsack_persist) { rack->r_ctl.dsack_persist--; if (rack->r_ctl.num_dsack && (rack->r_ctl.dsack_persist == 0)) { rack->r_ctl.num_dsack = 0; } rack_log_dsack_event(rack, 1, __LINE__, 0, 0); } /* * Rack can only run one timer at a time, so we cannot * run a KEEPINIT (gating SYN sending) and a retransmit * timer for the SYN. So if we are in a front state and * have a KEEPINIT timer we need to check the first transmit * against now to see if we have exceeded the KEEPINIT time * (if one is set). */ if ((TCPS_HAVEESTABLISHED(tp->t_state) == 0) && (TP_KEEPINIT(tp) != 0)) { struct rack_sendmap *rsm; rsm = RB_MIN(rack_rb_tree_head, &rack->r_ctl.rc_mtree); if (rsm) { /* Ok we have something outstanding to test keepinit with */ if ((TSTMP_GT(cts, (uint32_t)rsm->r_tim_lastsent[0])) && ((cts - (uint32_t)rsm->r_tim_lastsent[0]) >= TICKS_2_USEC(TP_KEEPINIT(tp)))) { /* We have exceeded the KEEPINIT time */ tcp_log_end_status(tp, TCP_EI_STATUS_KEEP_MAX); goto drop_it; } } } /* * Retransmission timer went off. Message has not been acked within * retransmit interval. Back off to a longer retransmit interval * and retransmit one segment. */ rack_remxt_tmr(tp); if ((rack->r_ctl.rc_resend == NULL) || ((rack->r_ctl.rc_resend->r_flags & RACK_RWND_COLLAPSED) == 0)) { /* * If the rwnd collapsed on * the one we are retransmitting * it does not count against the * rxt count. */ tp->t_rxtshift++; } if (tp->t_rxtshift > TCP_MAXRXTSHIFT) { tcp_log_end_status(tp, TCP_EI_STATUS_RETRAN); drop_it: tp->t_rxtshift = TCP_MAXRXTSHIFT; KMOD_TCPSTAT_INC(tcps_timeoutdrop); /* XXXGL: previously t_softerror was casted to uint16_t */ MPASS(tp->t_softerror >= 0); retval = tp->t_softerror ? -tp->t_softerror : -ETIMEDOUT; goto out; /* tcp_drop() */ } if (tp->t_state == TCPS_SYN_SENT) { /* * If the SYN was retransmitted, indicate CWND to be limited * to 1 segment in cc_conn_init(). */ tp->snd_cwnd = 1; } else if (tp->t_rxtshift == 1) { /* * first retransmit; record ssthresh and cwnd so they can be * recovered if this turns out to be a "bad" retransmit. A * retransmit is considered "bad" if an ACK for this segment * is received within RTT/2 interval; the assumption here is * that the ACK was already in flight. See "On Estimating * End-to-End Network Path Properties" by Allman and Paxson * for more details. */ tp->snd_cwnd_prev = tp->snd_cwnd; tp->snd_ssthresh_prev = tp->snd_ssthresh; tp->snd_recover_prev = tp->snd_recover; tp->t_badrxtwin = ticks + (USEC_2_TICKS(tp->t_srtt)/2); tp->t_flags |= TF_PREVVALID; } else if ((tp->t_flags & TF_RCVD_TSTMP) == 0) tp->t_flags &= ~TF_PREVVALID; KMOD_TCPSTAT_INC(tcps_rexmttimeo); if ((tp->t_state == TCPS_SYN_SENT) || (tp->t_state == TCPS_SYN_RECEIVED)) rexmt = RACK_INITIAL_RTO * tcp_backoff[tp->t_rxtshift]; else rexmt = max(rack_rto_min, (tp->t_srtt + (tp->t_rttvar << 2))) * tcp_backoff[tp->t_rxtshift]; RACK_TCPT_RANGESET(tp->t_rxtcur, rexmt, max(rack_rto_min, rexmt), rack_rto_max, rack->r_ctl.timer_slop); /* * We enter the path for PLMTUD if connection is established or, if * connection is FIN_WAIT_1 status, reason for the last is that if * amount of data we send is very small, we could send it in couple * of packets and process straight to FIN. In that case we won't * catch ESTABLISHED state. */ #ifdef INET6 isipv6 = (inp->inp_vflag & INP_IPV6) ? true : false; #else isipv6 = false; #endif if (((V_tcp_pmtud_blackhole_detect == 1) || (V_tcp_pmtud_blackhole_detect == 2 && !isipv6) || (V_tcp_pmtud_blackhole_detect == 3 && isipv6)) && ((tp->t_state == TCPS_ESTABLISHED) || (tp->t_state == TCPS_FIN_WAIT_1))) { /* * Idea here is that at each stage of mtu probe (usually, * 1448 -> 1188 -> 524) should be given 2 chances to recover * before further clamping down. 'tp->t_rxtshift % 2 == 0' * should take care of that. */ if (((tp->t_flags2 & (TF2_PLPMTU_PMTUD | TF2_PLPMTU_MAXSEGSNT)) == (TF2_PLPMTU_PMTUD | TF2_PLPMTU_MAXSEGSNT)) && (tp->t_rxtshift >= 2 && tp->t_rxtshift < 6 && tp->t_rxtshift % 2 == 0)) { /* * Enter Path MTU Black-hole Detection mechanism: - * Disable Path MTU Discovery (IP "DF" bit). - * Reduce MTU to lower value than what we negotiated * with peer. */ if ((tp->t_flags2 & TF2_PLPMTU_BLACKHOLE) == 0) { /* Record that we may have found a black hole. */ tp->t_flags2 |= TF2_PLPMTU_BLACKHOLE; /* Keep track of previous MSS. */ tp->t_pmtud_saved_maxseg = tp->t_maxseg; } /* * Reduce the MSS to blackhole value or to the * default in an attempt to retransmit. */ #ifdef INET6 if (isipv6 && tp->t_maxseg > V_tcp_v6pmtud_blackhole_mss) { /* Use the sysctl tuneable blackhole MSS. */ tp->t_maxseg = V_tcp_v6pmtud_blackhole_mss; KMOD_TCPSTAT_INC(tcps_pmtud_blackhole_activated); } else if (isipv6) { /* Use the default MSS. */ tp->t_maxseg = V_tcp_v6mssdflt; /* * Disable Path MTU Discovery when we switch * to minmss. */ tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; KMOD_TCPSTAT_INC(tcps_pmtud_blackhole_activated_min_mss); } #endif #if defined(INET6) && defined(INET) else #endif #ifdef INET if (tp->t_maxseg > V_tcp_pmtud_blackhole_mss) { /* Use the sysctl tuneable blackhole MSS. */ tp->t_maxseg = V_tcp_pmtud_blackhole_mss; KMOD_TCPSTAT_INC(tcps_pmtud_blackhole_activated); } else { /* Use the default MSS. */ tp->t_maxseg = V_tcp_mssdflt; /* * Disable Path MTU Discovery when we switch * to minmss. */ tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; KMOD_TCPSTAT_INC(tcps_pmtud_blackhole_activated_min_mss); } #endif } else { /* * If further retransmissions are still unsuccessful * with a lowered MTU, maybe this isn't a blackhole * and we restore the previous MSS and blackhole * detection flags. The limit '6' is determined by * giving each probe stage (1448, 1188, 524) 2 * chances to recover. */ if ((tp->t_flags2 & TF2_PLPMTU_BLACKHOLE) && (tp->t_rxtshift >= 6)) { tp->t_flags2 |= TF2_PLPMTU_PMTUD; tp->t_flags2 &= ~TF2_PLPMTU_BLACKHOLE; tp->t_maxseg = tp->t_pmtud_saved_maxseg; KMOD_TCPSTAT_INC(tcps_pmtud_blackhole_failed); } } } /* * Disable RFC1323 and SACK if we haven't got any response to * our third SYN to work-around some broken terminal servers * (most of which have hopefully been retired) that have bad VJ * header compression code which trashes TCP segments containing * unknown-to-them TCP options. */ if (tcp_rexmit_drop_options && (tp->t_state == TCPS_SYN_SENT) && (tp->t_rxtshift == 3)) tp->t_flags &= ~(TF_REQ_SCALE|TF_REQ_TSTMP|TF_SACK_PERMIT); /* * If we backed off this far, our srtt estimate is probably bogus. * Clobber it so we'll take the next rtt measurement as our srtt; * move the current srtt into rttvar to keep the current retransmit * times until then. */ if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) { #ifdef INET6 if ((inp->inp_vflag & INP_IPV6) != 0) in6_losing(inp); else #endif in_losing(inp); tp->t_rttvar += tp->t_srtt; tp->t_srtt = 0; } sack_filter_clear(&rack->r_ctl.rack_sf, tp->snd_una); tp->snd_recover = tp->snd_max; tp->t_flags |= TF_ACKNOW; tp->t_rtttime = 0; rack_cong_signal(tp, CC_RTO, tp->snd_una, __LINE__); out: return (retval); } static int rack_process_timers(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts, uint8_t hpts_calling, uint8_t *doing_tlp) { int32_t ret = 0; int32_t timers = (rack->r_ctl.rc_hpts_flags & PACE_TMR_MASK); if ((tp->t_state >= TCPS_FIN_WAIT_1) && (tp->t_flags & TF_GPUTINPROG)) { /* * We have a goodput in progress * and we have entered a late state. * Do we have enough data in the sb * to handle the GPUT request? */ uint32_t bytes; bytes = tp->gput_ack - tp->gput_seq; if (SEQ_GT(tp->gput_seq, tp->snd_una)) bytes += tp->gput_seq - tp->snd_una; if (bytes > sbavail(&tptosocket(tp)->so_snd)) { /* * There are not enough bytes in the socket * buffer that have been sent to cover this * measurement. Cancel it. */ rack_log_pacing_delay_calc(rack, (tp->gput_ack - tp->gput_seq) /*flex2*/, rack->r_ctl.rc_gp_srtt /*flex1*/, tp->gput_seq, 0, 0, 18, __LINE__, NULL, 0); tp->t_flags &= ~TF_GPUTINPROG; } } if (timers == 0) { return (0); } if (tp->t_state == TCPS_LISTEN) { /* no timers on listen sockets */ if (rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) return (0); return (1); } if ((timers & PACE_TMR_RACK) && rack->rc_on_min_to) { /* * For the rack timer when we * are on a min-timeout (which means rrr_conf = 3) * we don't want to check the timer. It may * be going off for a pace and thats ok we * want to send the retransmit (if its ready). * * If its on a normal rack timer (non-min) then * we will check if its expired. */ goto skip_time_check; } if (TSTMP_LT(cts, rack->r_ctl.rc_timer_exp)) { uint32_t left; if (rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) { ret = -1; rack_log_to_processing(rack, cts, ret, 0); return (0); } if (hpts_calling == 0) { /* * A user send or queued mbuf (sack) has called us? We * return 0 and let the pacing guards * deal with it if they should or * should not cause a send. */ ret = -2; rack_log_to_processing(rack, cts, ret, 0); return (0); } /* * Ok our timer went off early and we are not paced false * alarm, go back to sleep. */ ret = -3; left = rack->r_ctl.rc_timer_exp - cts; tcp_hpts_insert(tptoinpcb(tp), HPTS_MS_TO_SLOTS(left)); rack_log_to_processing(rack, cts, ret, left); return (1); } skip_time_check: rack->rc_tmr_stopped = 0; rack->r_ctl.rc_hpts_flags &= ~PACE_TMR_MASK; if (timers & PACE_TMR_DELACK) { ret = rack_timeout_delack(tp, rack, cts); } else if (timers & PACE_TMR_RACK) { rack->r_ctl.rc_tlp_rxt_last_time = cts; rack->r_fast_output = 0; ret = rack_timeout_rack(tp, rack, cts); } else if (timers & PACE_TMR_TLP) { rack->r_ctl.rc_tlp_rxt_last_time = cts; ret = rack_timeout_tlp(tp, rack, cts, doing_tlp); } else if (timers & PACE_TMR_RXT) { rack->r_ctl.rc_tlp_rxt_last_time = cts; rack->r_fast_output = 0; ret = rack_timeout_rxt(tp, rack, cts); } else if (timers & PACE_TMR_PERSIT) { ret = rack_timeout_persist(tp, rack, cts); } else if (timers & PACE_TMR_KEEP) { ret = rack_timeout_keepalive(tp, rack, cts); } rack_log_to_processing(rack, cts, ret, timers); return (ret); } static void rack_timer_cancel(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cts, int line) { struct timeval tv; uint32_t us_cts, flags_on_entry; uint8_t hpts_removed = 0; flags_on_entry = rack->r_ctl.rc_hpts_flags; us_cts = tcp_get_usecs(&tv); if ((rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) && ((TSTMP_GEQ(us_cts, rack->r_ctl.rc_last_output_to)) || ((tp->snd_max - tp->snd_una) == 0))) { tcp_hpts_remove(rack->rc_inp); hpts_removed = 1; /* If we were not delayed cancel out the flag. */ if ((tp->snd_max - tp->snd_una) == 0) rack->r_ctl.rc_hpts_flags &= ~PACE_PKT_OUTPUT; rack_log_to_cancel(rack, hpts_removed, line, us_cts, &tv, flags_on_entry); } if (rack->r_ctl.rc_hpts_flags & PACE_TMR_MASK) { rack->rc_tmr_stopped = rack->r_ctl.rc_hpts_flags & PACE_TMR_MASK; if (tcp_in_hpts(rack->rc_inp) && ((rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) == 0)) { /* * Canceling timer's when we have no output being * paced. We also must remove ourselves from the * hpts. */ tcp_hpts_remove(rack->rc_inp); hpts_removed = 1; } rack->r_ctl.rc_hpts_flags &= ~(PACE_TMR_MASK); } if (hpts_removed == 0) rack_log_to_cancel(rack, hpts_removed, line, us_cts, &tv, flags_on_entry); } static int rack_stopall(struct tcpcb *tp) { struct tcp_rack *rack; rack = (struct tcp_rack *)tp->t_fb_ptr; rack->t_timers_stopped = 1; return (0); } static void rack_stop_all_timers(struct tcpcb *tp) { struct tcp_rack *rack; /* * Assure no timers are running. */ if (tcp_timer_active(tp, TT_PERSIST)) { /* We enter in persists, set the flag appropriately */ rack = (struct tcp_rack *)tp->t_fb_ptr; rack->rc_in_persist = 1; } } static void rack_update_rsm(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendmap *rsm, uint64_t ts, uint16_t add_flag) { int32_t idx; rsm->r_rtr_cnt++; rack_log_retran_reason(rack, rsm, __LINE__, 0, 2); rsm->r_dupack = 0; if (rsm->r_rtr_cnt > RACK_NUM_OF_RETRANS) { rsm->r_rtr_cnt = RACK_NUM_OF_RETRANS; rsm->r_flags |= RACK_OVERMAX; } if ((rsm->r_rtr_cnt > 1) && ((rsm->r_flags & RACK_TLP) == 0)) { rack->r_ctl.rc_holes_rxt += (rsm->r_end - rsm->r_start); rsm->r_rtr_bytes += (rsm->r_end - rsm->r_start); } idx = rsm->r_rtr_cnt - 1; rsm->r_tim_lastsent[idx] = ts; /* * Here we don't add in the len of send, since its already * in snduna <->snd_max. */ rsm->r_fas = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); if (rsm->r_flags & RACK_ACKED) { /* Problably MTU discovery messing with us */ rsm->r_flags &= ~RACK_ACKED; rack->r_ctl.rc_sacked -= (rsm->r_end - rsm->r_start); } if (rsm->r_in_tmap) { TAILQ_REMOVE(&rack->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 0; } TAILQ_INSERT_TAIL(&rack->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 1; /* Take off the must retransmit flag, if its on */ if (rsm->r_flags & RACK_MUST_RXT) { if (rack->r_must_retran) rack->r_ctl.rc_out_at_rto -= (rsm->r_end - rsm->r_start); if (SEQ_GEQ(rsm->r_end, rack->r_ctl.rc_snd_max_at_rto)) { /* * We have retransmitted all we need. Clear * any must retransmit flags. */ rack->r_must_retran = 0; rack->r_ctl.rc_out_at_rto = 0; } rsm->r_flags &= ~RACK_MUST_RXT; } if (rsm->r_flags & RACK_SACK_PASSED) { /* We have retransmitted due to the SACK pass */ rsm->r_flags &= ~RACK_SACK_PASSED; rsm->r_flags |= RACK_WAS_SACKPASS; } } static uint32_t rack_update_entry(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendmap *rsm, uint64_t ts, int32_t *lenp, uint16_t add_flag) { /* * We (re-)transmitted starting at rsm->r_start for some length * (possibly less than r_end. */ struct rack_sendmap *nrsm; #ifdef INVARIANTS struct rack_sendmap *insret; #endif uint32_t c_end; int32_t len; len = *lenp; c_end = rsm->r_start + len; if (SEQ_GEQ(c_end, rsm->r_end)) { /* * We retransmitted the whole piece or more than the whole * slopping into the next rsm. */ rack_update_rsm(tp, rack, rsm, ts, add_flag); if (c_end == rsm->r_end) { *lenp = 0; return (0); } else { int32_t act_len; /* Hangs over the end return whats left */ act_len = rsm->r_end - rsm->r_start; *lenp = (len - act_len); return (rsm->r_end); } /* We don't get out of this block. */ } /* * Here we retransmitted less than the whole thing which means we * have to split this into what was transmitted and what was not. */ nrsm = rack_alloc_full_limit(rack); if (nrsm == NULL) { /* * We can't get memory, so lets not proceed. */ *lenp = 0; return (0); } /* * So here we are going to take the original rsm and make it what we * retransmitted. nrsm will be the tail portion we did not * retransmit. For example say the chunk was 1, 11 (10 bytes). And * we retransmitted 5 bytes i.e. 1, 5. The original piece shrinks to * 1, 6 and the new piece will be 6, 11. */ rack_clone_rsm(rack, nrsm, rsm, c_end); nrsm->r_dupack = 0; rack_log_retran_reason(rack, nrsm, __LINE__, 0, 2); #ifndef INVARIANTS (void)RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); #else insret = RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); if (insret != NULL) { panic("Insert in rb tree of %p fails ret:%p rack:%p rsm:%p", nrsm, insret, rack, rsm); } #endif if (rsm->r_in_tmap) { TAILQ_INSERT_AFTER(&rack->r_ctl.rc_tmap, rsm, nrsm, r_tnext); nrsm->r_in_tmap = 1; } rsm->r_flags &= (~RACK_HAS_FIN); rack_update_rsm(tp, rack, rsm, ts, add_flag); /* Log a split of rsm into rsm and nrsm */ rack_log_map_chg(tp, rack, NULL, rsm, nrsm, MAP_SPLIT, 0, __LINE__); *lenp = 0; return (0); } static void rack_log_output(struct tcpcb *tp, struct tcpopt *to, int32_t len, uint32_t seq_out, uint16_t th_flags, int32_t err, uint64_t cts, struct rack_sendmap *hintrsm, uint16_t add_flag, struct mbuf *s_mb, uint32_t s_moff, int hw_tls) { struct tcp_rack *rack; struct rack_sendmap *rsm, *nrsm, fe; #ifdef INVARIANTS struct rack_sendmap *insret; #endif register uint32_t snd_max, snd_una; /* * Add to the RACK log of packets in flight or retransmitted. If * there is a TS option we will use the TS echoed, if not we will * grab a TS. * * Retransmissions will increment the count and move the ts to its * proper place. Note that if options do not include TS's then we * won't be able to effectively use the ACK for an RTT on a retran. * * Notes about r_start and r_end. Lets consider a send starting at * sequence 1 for 10 bytes. In such an example the r_start would be * 1 (starting sequence) but the r_end would be r_start+len i.e. 11. * This means that r_end is actually the first sequence for the next * slot (11). * */ /* * If err is set what do we do XXXrrs? should we not add the thing? * -- i.e. return if err != 0 or should we pretend we sent it? -- * i.e. proceed with add ** do this for now. */ INP_WLOCK_ASSERT(tptoinpcb(tp)); if (err) /* * We don't log errors -- we could but snd_max does not * advance in this case either. */ return; if (th_flags & TH_RST) { /* * We don't log resets and we return immediately from * sending */ return; } rack = (struct tcp_rack *)tp->t_fb_ptr; snd_una = tp->snd_una; snd_max = tp->snd_max; if (th_flags & (TH_SYN | TH_FIN)) { /* * The call to rack_log_output is made before bumping * snd_max. This means we can record one extra byte on a SYN * or FIN if seq_out is adding more on and a FIN is present * (and we are not resending). */ if ((th_flags & TH_SYN) && (seq_out == tp->iss)) len++; if (th_flags & TH_FIN) len++; if (SEQ_LT(snd_max, tp->snd_nxt)) { /* * The add/update as not been done for the FIN/SYN * yet. */ snd_max = tp->snd_nxt; } } if (SEQ_LEQ((seq_out + len), snd_una)) { /* Are sending an old segment to induce an ack (keep-alive)? */ return; } if (SEQ_LT(seq_out, snd_una)) { /* huh? should we panic? */ uint32_t end; end = seq_out + len; seq_out = snd_una; if (SEQ_GEQ(end, seq_out)) len = end - seq_out; else len = 0; } if (len == 0) { /* We don't log zero window probes */ return; } if (IN_FASTRECOVERY(tp->t_flags)) { rack->r_ctl.rc_prr_out += len; } /* First question is it a retransmission or new? */ if (seq_out == snd_max) { /* Its new */ again: rsm = rack_alloc(rack); if (rsm == NULL) { /* * Hmm out of memory and the tcb got destroyed while * we tried to wait. */ return; } if (th_flags & TH_FIN) { rsm->r_flags = RACK_HAS_FIN|add_flag; } else { rsm->r_flags = add_flag; } if (hw_tls) rsm->r_hw_tls = 1; rsm->r_tim_lastsent[0] = cts; rsm->r_rtr_cnt = 1; rsm->r_rtr_bytes = 0; if (th_flags & TH_SYN) { /* The data space is one beyond snd_una */ rsm->r_flags |= RACK_HAS_SYN; } rsm->r_start = seq_out; rsm->r_end = rsm->r_start + len; rsm->r_dupack = 0; /* * save off the mbuf location that * sndmbuf_noadv returned (which is * where we started copying from).. */ rsm->m = s_mb; rsm->soff = s_moff; /* * Here we do add in the len of send, since its not yet * reflected in in snduna <->snd_max */ rsm->r_fas = (ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked) + (rsm->r_end - rsm->r_start)); /* rsm->m will be NULL if RACK_HAS_SYN or RACK_HAS_FIN is set */ if (rsm->m) { if (rsm->m->m_len <= rsm->soff) { /* * XXXrrs Question, will this happen? * * If sbsndptr is set at the correct place * then s_moff should always be somewhere * within rsm->m. But if the sbsndptr was * off then that won't be true. If it occurs * we need to walkout to the correct location. */ struct mbuf *lm; lm = rsm->m; while (lm->m_len <= rsm->soff) { rsm->soff -= lm->m_len; lm = lm->m_next; KASSERT(lm != NULL, ("%s rack:%p lm goes null orig_off:%u origmb:%p rsm->soff:%u", __func__, rack, s_moff, s_mb, rsm->soff)); } rsm->m = lm; } rsm->orig_m_len = rsm->m->m_len; } else rsm->orig_m_len = 0; rack_log_retran_reason(rack, rsm, __LINE__, 0, 2); /* Log a new rsm */ rack_log_map_chg(tp, rack, NULL, rsm, NULL, MAP_NEW, 0, __LINE__); #ifndef INVARIANTS (void)RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); #else insret = RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); if (insret != NULL) { panic("Insert in rb tree of %p fails ret:%p rack:%p rsm:%p", nrsm, insret, rack, rsm); } #endif TAILQ_INSERT_TAIL(&rack->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 1; /* * Special case detection, is there just a single * packet outstanding when we are not in recovery? * * If this is true mark it so. */ if ((IN_FASTRECOVERY(tp->t_flags) == 0) && (ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked) == ctf_fixed_maxseg(tp))) { struct rack_sendmap *prsm; prsm = RB_PREV(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); if (prsm) prsm->r_one_out_nr = 1; } return; } /* * If we reach here its a retransmission and we need to find it. */ memset(&fe, 0, sizeof(fe)); more: if (hintrsm && (hintrsm->r_start == seq_out)) { rsm = hintrsm; hintrsm = NULL; } else { /* No hints sorry */ rsm = NULL; } if ((rsm) && (rsm->r_start == seq_out)) { seq_out = rack_update_entry(tp, rack, rsm, cts, &len, add_flag); if (len == 0) { return; } else { goto more; } } /* Ok it was not the last pointer go through it the hard way. */ refind: fe.r_start = seq_out; rsm = RB_FIND(rack_rb_tree_head, &rack->r_ctl.rc_mtree, &fe); if (rsm) { if (rsm->r_start == seq_out) { seq_out = rack_update_entry(tp, rack, rsm, cts, &len, add_flag); if (len == 0) { return; } else { goto refind; } } if (SEQ_GEQ(seq_out, rsm->r_start) && SEQ_LT(seq_out, rsm->r_end)) { /* Transmitted within this piece */ /* * Ok we must split off the front and then let the * update do the rest */ nrsm = rack_alloc_full_limit(rack); if (nrsm == NULL) { rack_update_rsm(tp, rack, rsm, cts, add_flag); return; } /* * copy rsm to nrsm and then trim the front of rsm * to not include this part. */ rack_clone_rsm(rack, nrsm, rsm, seq_out); rack_log_map_chg(tp, rack, NULL, rsm, nrsm, MAP_SPLIT, 0, __LINE__); #ifndef INVARIANTS (void)RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); #else insret = RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); if (insret != NULL) { panic("Insert in rb tree of %p fails ret:%p rack:%p rsm:%p", nrsm, insret, rack, rsm); } #endif if (rsm->r_in_tmap) { TAILQ_INSERT_AFTER(&rack->r_ctl.rc_tmap, rsm, nrsm, r_tnext); nrsm->r_in_tmap = 1; } rsm->r_flags &= (~RACK_HAS_FIN); seq_out = rack_update_entry(tp, rack, nrsm, cts, &len, add_flag); if (len == 0) { return; } else if (len > 0) goto refind; } } /* * Hmm not found in map did they retransmit both old and on into the * new? */ if (seq_out == tp->snd_max) { goto again; } else if (SEQ_LT(seq_out, tp->snd_max)) { #ifdef INVARIANTS printf("seq_out:%u len:%d snd_una:%u snd_max:%u -- but rsm not found?\n", seq_out, len, tp->snd_una, tp->snd_max); printf("Starting Dump of all rack entries\n"); RB_FOREACH(rsm, rack_rb_tree_head, &rack->r_ctl.rc_mtree) { printf("rsm:%p start:%u end:%u\n", rsm, rsm->r_start, rsm->r_end); } printf("Dump complete\n"); panic("seq_out not found rack:%p tp:%p", rack, tp); #endif } else { #ifdef INVARIANTS /* * Hmm beyond sndmax? (only if we are using the new rtt-pack * flag) */ panic("seq_out:%u(%d) is beyond snd_max:%u tp:%p", seq_out, len, tp->snd_max, tp); #endif } } /* * Record one of the RTT updates from an ack into * our sample structure. */ static void tcp_rack_xmit_timer(struct tcp_rack *rack, int32_t rtt, uint32_t len, uint32_t us_rtt, int confidence, struct rack_sendmap *rsm, uint16_t rtrcnt) { if ((rack->r_ctl.rack_rs.rs_flags & RACK_RTT_EMPTY) || (rack->r_ctl.rack_rs.rs_rtt_lowest > rtt)) { rack->r_ctl.rack_rs.rs_rtt_lowest = rtt; } if ((rack->r_ctl.rack_rs.rs_flags & RACK_RTT_EMPTY) || (rack->r_ctl.rack_rs.rs_rtt_highest < rtt)) { rack->r_ctl.rack_rs.rs_rtt_highest = rtt; } if (rack->rc_tp->t_flags & TF_GPUTINPROG) { if (us_rtt < rack->r_ctl.rc_gp_lowrtt) rack->r_ctl.rc_gp_lowrtt = us_rtt; if (rack->rc_tp->snd_wnd > rack->r_ctl.rc_gp_high_rwnd) rack->r_ctl.rc_gp_high_rwnd = rack->rc_tp->snd_wnd; } if ((confidence == 1) && ((rsm == NULL) || (rsm->r_just_ret) || (rsm->r_one_out_nr && len < (ctf_fixed_maxseg(rack->rc_tp) * 2)))) { /* * If the rsm had a just return * hit it then we can't trust the * rtt measurement for buffer deterimination * Note that a confidence of 2, indicates * SACK'd which overrides the r_just_ret or * the r_one_out_nr. If it was a CUM-ACK and * we had only two outstanding, but get an * ack for only 1. Then that also lowers our * confidence. */ confidence = 0; } if ((rack->r_ctl.rack_rs.rs_flags & RACK_RTT_EMPTY) || (rack->r_ctl.rack_rs.rs_us_rtt > us_rtt)) { if (rack->r_ctl.rack_rs.confidence == 0) { /* * We take anything with no current confidence * saved. */ rack->r_ctl.rack_rs.rs_us_rtt = us_rtt; rack->r_ctl.rack_rs.confidence = confidence; rack->r_ctl.rack_rs.rs_us_rtrcnt = rtrcnt; } else if (confidence || rack->r_ctl.rack_rs.confidence) { /* * Once we have a confident number, * we can update it with a smaller * value since this confident number * may include the DSACK time until * the next segment (the second one) arrived. */ rack->r_ctl.rack_rs.rs_us_rtt = us_rtt; rack->r_ctl.rack_rs.confidence = confidence; rack->r_ctl.rack_rs.rs_us_rtrcnt = rtrcnt; } } rack_log_rtt_upd(rack->rc_tp, rack, us_rtt, len, rsm, confidence); rack->r_ctl.rack_rs.rs_flags = RACK_RTT_VALID; rack->r_ctl.rack_rs.rs_rtt_tot += rtt; rack->r_ctl.rack_rs.rs_rtt_cnt++; } /* * Collect new round-trip time estimate * and update averages and current timeout. */ static void tcp_rack_xmit_timer_commit(struct tcp_rack *rack, struct tcpcb *tp) { int32_t delta; int32_t rtt; if (rack->r_ctl.rack_rs.rs_flags & RACK_RTT_EMPTY) /* No valid sample */ return; if (rack->r_ctl.rc_rate_sample_method == USE_RTT_LOW) { /* We are to use the lowest RTT seen in a single ack */ rtt = rack->r_ctl.rack_rs.rs_rtt_lowest; } else if (rack->r_ctl.rc_rate_sample_method == USE_RTT_HIGH) { /* We are to use the highest RTT seen in a single ack */ rtt = rack->r_ctl.rack_rs.rs_rtt_highest; } else if (rack->r_ctl.rc_rate_sample_method == USE_RTT_AVG) { /* We are to use the average RTT seen in a single ack */ rtt = (int32_t)(rack->r_ctl.rack_rs.rs_rtt_tot / (uint64_t)rack->r_ctl.rack_rs.rs_rtt_cnt); } else { #ifdef INVARIANTS panic("Unknown rtt variant %d", rack->r_ctl.rc_rate_sample_method); #endif return; } if (rtt == 0) rtt = 1; if (rack->rc_gp_rtt_set == 0) { /* * With no RTT we have to accept * even one we are not confident of. */ rack->r_ctl.rc_gp_srtt = rack->r_ctl.rack_rs.rs_us_rtt; rack->rc_gp_rtt_set = 1; } else if (rack->r_ctl.rack_rs.confidence) { /* update the running gp srtt */ rack->r_ctl.rc_gp_srtt -= (rack->r_ctl.rc_gp_srtt/8); rack->r_ctl.rc_gp_srtt += rack->r_ctl.rack_rs.rs_us_rtt / 8; } if (rack->r_ctl.rack_rs.confidence) { /* * record the low and high for highly buffered path computation, * we only do this if we are confident (not a retransmission). */ if (rack->r_ctl.rc_highest_us_rtt < rack->r_ctl.rack_rs.rs_us_rtt) { rack->r_ctl.rc_highest_us_rtt = rack->r_ctl.rack_rs.rs_us_rtt; } if (rack->rc_highly_buffered == 0) { /* * Currently once we declare a path has * highly buffered there is no going * back, which may be a problem... */ if ((rack->r_ctl.rc_highest_us_rtt / rack->r_ctl.rc_lowest_us_rtt) > rack_hbp_thresh) { rack_log_rtt_shrinks(rack, rack->r_ctl.rack_rs.rs_us_rtt, rack->r_ctl.rc_highest_us_rtt, rack->r_ctl.rc_lowest_us_rtt, RACK_RTTS_SEEHBP); rack->rc_highly_buffered = 1; } } } if ((rack->r_ctl.rack_rs.confidence) || (rack->r_ctl.rack_rs.rs_us_rtrcnt == 1)) { /* * If we are highly confident of it it was * never retransmitted we accept it as the last us_rtt. */ rack->r_ctl.rc_last_us_rtt = rack->r_ctl.rack_rs.rs_us_rtt; /* The lowest rtt can be set if its was not retransmited */ if (rack->r_ctl.rc_lowest_us_rtt > rack->r_ctl.rack_rs.rs_us_rtt) { rack->r_ctl.rc_lowest_us_rtt = rack->r_ctl.rack_rs.rs_us_rtt; if (rack->r_ctl.rc_lowest_us_rtt == 0) rack->r_ctl.rc_lowest_us_rtt = 1; } } rack = (struct tcp_rack *)tp->t_fb_ptr; if (tp->t_srtt != 0) { /* * We keep a simple srtt in microseconds, like our rtt * measurement. We don't need to do any tricks with shifting * etc. Instead we just add in 1/8th of the new measurement * and subtract out 1/8 of the old srtt. We do the same with * the variance after finding the absolute value of the * difference between this sample and the current srtt. */ delta = tp->t_srtt - rtt; /* Take off 1/8th of the current sRTT */ tp->t_srtt -= (tp->t_srtt >> 3); /* Add in 1/8th of the new RTT just measured */ tp->t_srtt += (rtt >> 3); if (tp->t_srtt <= 0) tp->t_srtt = 1; /* Now lets make the absolute value of the variance */ if (delta < 0) delta = -delta; /* Subtract out 1/8th */ tp->t_rttvar -= (tp->t_rttvar >> 3); /* Add in 1/8th of the new variance we just saw */ tp->t_rttvar += (delta >> 3); if (tp->t_rttvar <= 0) tp->t_rttvar = 1; } else { /* * No rtt measurement yet - use the unsmoothed rtt. Set the * variance to half the rtt (so our first retransmit happens * at 3*rtt). */ tp->t_srtt = rtt; tp->t_rttvar = rtt >> 1; } rack->rc_srtt_measure_made = 1; KMOD_TCPSTAT_INC(tcps_rttupdated); tp->t_rttupdated++; #ifdef STATS if (rack_stats_gets_ms_rtt == 0) { /* Send in the microsecond rtt used for rxt timeout purposes */ stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT, imax(0, rtt)); } else if (rack_stats_gets_ms_rtt == 1) { /* Send in the millisecond rtt used for rxt timeout purposes */ int32_t ms_rtt; /* Round up */ ms_rtt = (rtt + HPTS_USEC_IN_MSEC - 1) / HPTS_USEC_IN_MSEC; stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT, imax(0, ms_rtt)); } else if (rack_stats_gets_ms_rtt == 2) { /* Send in the millisecond rtt has close to the path RTT as we can get */ int32_t ms_rtt; /* Round up */ ms_rtt = (rack->r_ctl.rack_rs.rs_us_rtt + HPTS_USEC_IN_MSEC - 1) / HPTS_USEC_IN_MSEC; stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT, imax(0, ms_rtt)); } else { /* Send in the microsecond rtt has close to the path RTT as we can get */ stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RTT, imax(0, rack->r_ctl.rack_rs.rs_us_rtt)); } #endif /* * the retransmit should happen at rtt + 4 * rttvar. Because of the * way we do the smoothing, srtt and rttvar will each average +1/2 * tick of bias. When we compute the retransmit timer, we want 1/2 * tick of rounding and 1 extra tick because of +-1/2 tick * uncertainty in the firing of the timer. The bias will give us * exactly the 1.5 tick we need. But, because the bias is * statistical, we have to test that we don't drop below the minimum * feasible timer (which is 2 ticks). */ tp->t_rxtshift = 0; RACK_TCPT_RANGESET(tp->t_rxtcur, RACK_REXMTVAL(tp), max(rack_rto_min, rtt + 2), rack_rto_max, rack->r_ctl.timer_slop); rack_log_rtt_sample(rack, rtt); tp->t_softerror = 0; } static void rack_apply_updated_usrtt(struct tcp_rack *rack, uint32_t us_rtt, uint32_t us_cts) { /* * Apply to filter the inbound us-rtt at us_cts. */ uint32_t old_rtt; old_rtt = get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt); apply_filter_min_small(&rack->r_ctl.rc_gp_min_rtt, us_rtt, us_cts); if (old_rtt > us_rtt) { /* We just hit a new lower rtt time */ rack_log_rtt_shrinks(rack, us_cts, old_rtt, __LINE__, RACK_RTTS_NEWRTT); /* * Only count it if its lower than what we saw within our * calculated range. */ if ((old_rtt - us_rtt) > rack_min_rtt_movement) { if (rack_probertt_lower_within && rack->rc_gp_dyn_mul && (rack->use_fixed_rate == 0) && (rack->rc_always_pace)) { /* * We are seeing a new lower rtt very close * to the time that we would have entered probe-rtt. * This is probably due to the fact that a peer flow * has entered probe-rtt. Lets go in now too. */ uint32_t val; val = rack_probertt_lower_within * rack_time_between_probertt; val /= 100; if ((rack->in_probe_rtt == 0) && ((us_cts - rack->r_ctl.rc_lower_rtt_us_cts) >= (rack_time_between_probertt - val))) { rack_enter_probertt(rack, us_cts); } } rack->r_ctl.rc_lower_rtt_us_cts = us_cts; } } } static int rack_update_rtt(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendmap *rsm, struct tcpopt *to, uint32_t cts, int32_t ack_type, tcp_seq th_ack) { uint32_t us_rtt; int32_t i, all; uint32_t t, len_acked; if ((rsm->r_flags & RACK_ACKED) || (rsm->r_flags & RACK_WAS_ACKED)) /* Already done */ return (0); if (rsm->r_no_rtt_allowed) { /* Not allowed */ return (0); } if (ack_type == CUM_ACKED) { if (SEQ_GT(th_ack, rsm->r_end)) { len_acked = rsm->r_end - rsm->r_start; all = 1; } else { len_acked = th_ack - rsm->r_start; all = 0; } } else { len_acked = rsm->r_end - rsm->r_start; all = 0; } if (rsm->r_rtr_cnt == 1) { t = cts - (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt - 1)]; if ((int)t <= 0) t = 1; if (!tp->t_rttlow || tp->t_rttlow > t) tp->t_rttlow = t; if (!rack->r_ctl.rc_rack_min_rtt || SEQ_LT(t, rack->r_ctl.rc_rack_min_rtt)) { rack->r_ctl.rc_rack_min_rtt = t; if (rack->r_ctl.rc_rack_min_rtt == 0) { rack->r_ctl.rc_rack_min_rtt = 1; } } if (TSTMP_GT(tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time), rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)])) us_rtt = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time) - (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]; else us_rtt = tcp_get_usecs(NULL) - (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]; if (us_rtt == 0) us_rtt = 1; if (CC_ALGO(tp)->rttsample != NULL) { /* Kick the RTT to the CC */ CC_ALGO(tp)->rttsample(&tp->t_ccv, us_rtt, 1, rsm->r_fas); } rack_apply_updated_usrtt(rack, us_rtt, tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time)); if (ack_type == SACKED) { rack_log_rtt_sample_calc(rack, t, (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt - 1)], cts, 1); tcp_rack_xmit_timer(rack, t + 1, len_acked, us_rtt, 2 , rsm, rsm->r_rtr_cnt); } else { /* * We need to setup what our confidence * is in this ack. * * If the rsm was app limited and it is * less than a mss in length (the end * of the send) then we have a gap. If we * were app limited but say we were sending * multiple MSS's then we are more confident * int it. * * When we are not app-limited then we see if * the rsm is being included in the current * measurement, we tell this by the app_limited_needs_set * flag. * * Note that being cwnd blocked is not applimited * as well as the pacing delay between packets which * are sending only 1 or 2 MSS's also will show up * in the RTT. We probably need to examine this algorithm * a bit more and enhance it to account for the delay * between rsm's. We could do that by saving off the * pacing delay of each rsm (in an rsm) and then * factoring that in somehow though for now I am * not sure how :) */ int calc_conf = 0; if (rsm->r_flags & RACK_APP_LIMITED) { if (all && (len_acked <= ctf_fixed_maxseg(tp))) calc_conf = 0; else calc_conf = 1; } else if (rack->app_limited_needs_set == 0) { calc_conf = 1; } else { calc_conf = 0; } rack_log_rtt_sample_calc(rack, t, (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt - 1)], cts, 2); tcp_rack_xmit_timer(rack, t + 1, len_acked, us_rtt, calc_conf, rsm, rsm->r_rtr_cnt); } if ((rsm->r_flags & RACK_TLP) && (!IN_FASTRECOVERY(tp->t_flags))) { /* Segment was a TLP and our retrans matched */ if (rack->r_ctl.rc_tlp_cwnd_reduce) { rack_cong_signal(tp, CC_NDUPACK, tp->snd_una, __LINE__); } } if (SEQ_LT(rack->r_ctl.rc_rack_tmit_time, (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt - 1)])) { /* New more recent rack_tmit_time */ rack->r_ctl.rc_rack_tmit_time = (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt - 1)]; rack->rc_rack_rtt = t; } return (1); } /* * We clear the soft/rxtshift since we got an ack. * There is no assurance we will call the commit() function * so we need to clear these to avoid incorrect handling. */ tp->t_rxtshift = 0; RACK_TCPT_RANGESET(tp->t_rxtcur, RACK_REXMTVAL(tp), rack_rto_min, rack_rto_max, rack->r_ctl.timer_slop); tp->t_softerror = 0; if (to && (to->to_flags & TOF_TS) && (ack_type == CUM_ACKED) && (to->to_tsecr) && ((rsm->r_flags & RACK_OVERMAX) == 0)) { /* * Now which timestamp does it match? In this block the ACK * must be coming from a previous transmission. */ for (i = 0; i < rsm->r_rtr_cnt; i++) { if (rack_ts_to_msec(rsm->r_tim_lastsent[i]) == to->to_tsecr) { t = cts - (uint32_t)rsm->r_tim_lastsent[i]; if ((int)t <= 0) t = 1; if (CC_ALGO(tp)->rttsample != NULL) { /* * Kick the RTT to the CC, here * we lie a bit in that we know the * retransmission is correct even though * we retransmitted. This is because * we match the timestamps. */ if (TSTMP_GT(tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time), rsm->r_tim_lastsent[i])) us_rtt = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time) - (uint32_t)rsm->r_tim_lastsent[i]; else us_rtt = tcp_get_usecs(NULL) - (uint32_t)rsm->r_tim_lastsent[i]; CC_ALGO(tp)->rttsample(&tp->t_ccv, us_rtt, 1, rsm->r_fas); } if ((i + 1) < rsm->r_rtr_cnt) { /* * The peer ack'd from our previous * transmission. We have a spurious * retransmission and thus we dont * want to update our rack_rtt. * * Hmm should there be a CC revert here? * */ return (0); } if (!tp->t_rttlow || tp->t_rttlow > t) tp->t_rttlow = t; if (!rack->r_ctl.rc_rack_min_rtt || SEQ_LT(t, rack->r_ctl.rc_rack_min_rtt)) { rack->r_ctl.rc_rack_min_rtt = t; if (rack->r_ctl.rc_rack_min_rtt == 0) { rack->r_ctl.rc_rack_min_rtt = 1; } } if (SEQ_LT(rack->r_ctl.rc_rack_tmit_time, (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt - 1)])) { /* New more recent rack_tmit_time */ rack->r_ctl.rc_rack_tmit_time = (uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt - 1)]; rack->rc_rack_rtt = t; } rack_log_rtt_sample_calc(rack, t, (uint32_t)rsm->r_tim_lastsent[i], cts, 3); tcp_rack_xmit_timer(rack, t + 1, len_acked, t, 0, rsm, rsm->r_rtr_cnt); return (1); } } goto ts_not_found; } else { /* * Ok its a SACK block that we retransmitted. or a windows * machine without timestamps. We can tell nothing from the * time-stamp since its not there or the time the peer last * recieved a segment that moved forward its cum-ack point. */ ts_not_found: i = rsm->r_rtr_cnt - 1; t = cts - (uint32_t)rsm->r_tim_lastsent[i]; if ((int)t <= 0) t = 1; if (rack->r_ctl.rc_rack_min_rtt && SEQ_LT(t, rack->r_ctl.rc_rack_min_rtt)) { /* * We retransmitted and the ack came back in less * than the smallest rtt we have observed. We most * likely did an improper retransmit as outlined in * 6.2 Step 2 point 2 in the rack-draft so we * don't want to update our rack_rtt. We in * theory (in future) might want to think about reverting our * cwnd state but we won't for now. */ return (0); } else if (rack->r_ctl.rc_rack_min_rtt) { /* * We retransmitted it and the retransmit did the * job. */ if (!rack->r_ctl.rc_rack_min_rtt || SEQ_LT(t, rack->r_ctl.rc_rack_min_rtt)) { rack->r_ctl.rc_rack_min_rtt = t; if (rack->r_ctl.rc_rack_min_rtt == 0) { rack->r_ctl.rc_rack_min_rtt = 1; } } if (SEQ_LT(rack->r_ctl.rc_rack_tmit_time, (uint32_t)rsm->r_tim_lastsent[i])) { /* New more recent rack_tmit_time */ rack->r_ctl.rc_rack_tmit_time = (uint32_t)rsm->r_tim_lastsent[i]; rack->rc_rack_rtt = t; } return (1); } } return (0); } /* * Mark the SACK_PASSED flag on all entries prior to rsm send wise. */ static void rack_log_sack_passed(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendmap *rsm) { struct rack_sendmap *nrsm; nrsm = rsm; TAILQ_FOREACH_REVERSE_FROM(nrsm, &rack->r_ctl.rc_tmap, rack_head, r_tnext) { if (nrsm == rsm) { /* Skip orginal segment he is acked */ continue; } if (nrsm->r_flags & RACK_ACKED) { /* * Skip ack'd segments, though we * should not see these, since tmap * should not have ack'd segments. */ continue; } if (nrsm->r_flags & RACK_RWND_COLLAPSED) { /* * If the peer dropped the rwnd on * these then we don't worry about them. */ continue; } if (nrsm->r_flags & RACK_SACK_PASSED) { /* * We found one that is already marked * passed, we have been here before and * so all others below this are marked. */ break; } nrsm->r_flags |= RACK_SACK_PASSED; nrsm->r_flags &= ~RACK_WAS_SACKPASS; } } static void rack_need_set_test(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendmap *rsm, tcp_seq th_ack, int line, int use_which) { if ((tp->t_flags & TF_GPUTINPROG) && SEQ_GEQ(rsm->r_end, tp->gput_seq)) { /* * We were app limited, and this ack * butts up or goes beyond the point where we want * to start our next measurement. We need * to record the new gput_ts as here and * possibly update the start sequence. */ uint32_t seq, ts; if (rsm->r_rtr_cnt > 1) { /* * This is a retransmit, can we * really make any assessment at this * point? We are not really sure of * the timestamp, is it this or the * previous transmission? * * Lets wait for something better that * is not retransmitted. */ return; } seq = tp->gput_seq; ts = tp->gput_ts; rack->app_limited_needs_set = 0; tp->gput_ts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); /* Do we start at a new end? */ if ((use_which == RACK_USE_BEG) && SEQ_GEQ(rsm->r_start, tp->gput_seq)) { /* * When we get an ACK that just eats * up some of the rsm, we set RACK_USE_BEG * since whats at r_start (i.e. th_ack) * is left unacked and thats where the * measurement not starts. */ tp->gput_seq = rsm->r_start; rack->r_ctl.rc_gp_output_ts = rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]; } if ((use_which == RACK_USE_END) && SEQ_GEQ(rsm->r_end, tp->gput_seq)) { /* * We use the end when the cumack * is moving forward and completely * deleting the rsm passed so basically * r_end holds th_ack. * * For SACK's we also want to use the end * since this piece just got sacked and * we want to target anything after that * in our measurement. */ tp->gput_seq = rsm->r_end; rack->r_ctl.rc_gp_output_ts = rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]; } if (use_which == RACK_USE_END_OR_THACK) { /* * special case for ack moving forward, * not a sack, we need to move all the * way up to where this ack cum-ack moves * to. */ if (SEQ_GT(th_ack, rsm->r_end)) tp->gput_seq = th_ack; else tp->gput_seq = rsm->r_end; rack->r_ctl.rc_gp_output_ts = rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]; } if (SEQ_GT(tp->gput_seq, tp->gput_ack)) { /* * We moved beyond this guy's range, re-calculate * the new end point. */ if (rack->rc_gp_filled == 0) { tp->gput_ack = tp->gput_seq + max(rc_init_window(rack), (MIN_GP_WIN * ctf_fixed_maxseg(tp))); } else { tp->gput_ack = tp->gput_seq + rack_get_measure_window(tp, rack); } } /* * We are moving the goal post, we may be able to clear the * measure_saw_probe_rtt flag. */ if ((rack->in_probe_rtt == 0) && (rack->measure_saw_probe_rtt) && (SEQ_GEQ(tp->gput_seq, rack->r_ctl.rc_probertt_sndmax_atexit))) rack->measure_saw_probe_rtt = 0; rack_log_pacing_delay_calc(rack, ts, tp->gput_ts, seq, tp->gput_seq, 0, 5, line, NULL, 0); if (rack->rc_gp_filled && ((tp->gput_ack - tp->gput_seq) < max(rc_init_window(rack), (MIN_GP_WIN * ctf_fixed_maxseg(tp))))) { uint32_t ideal_amount; ideal_amount = rack_get_measure_window(tp, rack); if (ideal_amount > sbavail(&tptosocket(tp)->so_snd)) { /* * There is no sense of continuing this measurement * because its too small to gain us anything we * trust. Skip it and that way we can start a new * measurement quicker. */ tp->t_flags &= ~TF_GPUTINPROG; rack_log_pacing_delay_calc(rack, tp->gput_ack, tp->gput_seq, 0, 0, 0, 6, __LINE__, NULL, 0); } else { /* * Reset the window further out. */ tp->gput_ack = tp->gput_seq + ideal_amount; } } } } static inline int is_rsm_inside_declared_tlp_block(struct tcp_rack *rack, struct rack_sendmap *rsm) { if (SEQ_LT(rsm->r_end, rack->r_ctl.last_tlp_acked_start)) { /* Behind our TLP definition or right at */ return (0); } if (SEQ_GT(rsm->r_start, rack->r_ctl.last_tlp_acked_end)) { /* The start is beyond or right at our end of TLP definition */ return (0); } /* It has to be a sub-part of the original TLP recorded */ return (1); } static uint32_t rack_proc_sack_blk(struct tcpcb *tp, struct tcp_rack *rack, struct sackblk *sack, struct tcpopt *to, struct rack_sendmap **prsm, uint32_t cts, int *moved_two) { uint32_t start, end, changed = 0; struct rack_sendmap stack_map; struct rack_sendmap *rsm, *nrsm, fe, *prev, *next; #ifdef INVARIANTS struct rack_sendmap *insret; #endif int32_t used_ref = 1; int moved = 0; start = sack->start; end = sack->end; rsm = *prsm; memset(&fe, 0, sizeof(fe)); do_rest_ofb: if ((rsm == NULL) || (SEQ_LT(end, rsm->r_start)) || (SEQ_GEQ(start, rsm->r_end)) || (SEQ_LT(start, rsm->r_start))) { /* * We are not in the right spot, * find the correct spot in the tree. */ used_ref = 0; fe.r_start = start; rsm = RB_FIND(rack_rb_tree_head, &rack->r_ctl.rc_mtree, &fe); moved++; } if (rsm == NULL) { /* TSNH */ goto out; } /* Ok we have an ACK for some piece of this rsm */ if (rsm->r_start != start) { if ((rsm->r_flags & RACK_ACKED) == 0) { /* * Before any splitting or hookery is * done is it a TLP of interest i.e. rxt? */ if ((rsm->r_flags & RACK_TLP) && (rsm->r_rtr_cnt > 1)) { /* * We are splitting a rxt TLP, check * if we need to save off the start/end */ if (rack->rc_last_tlp_acked_set && (is_rsm_inside_declared_tlp_block(rack, rsm))) { /* * We already turned this on since we are inside * the previous one was a partially sack now we * are getting another one (maybe all of it). * */ rack_log_dsack_event(rack, 10, __LINE__, rsm->r_start, rsm->r_end); /* * Lets make sure we have all of it though. */ if (SEQ_LT(rsm->r_start, rack->r_ctl.last_tlp_acked_start)) { rack->r_ctl.last_tlp_acked_start = rsm->r_start; rack_log_dsack_event(rack, 11, __LINE__, rack->r_ctl.last_tlp_acked_start, rack->r_ctl.last_tlp_acked_end); } if (SEQ_GT(rsm->r_end, rack->r_ctl.last_tlp_acked_end)) { rack->r_ctl.last_tlp_acked_end = rsm->r_end; rack_log_dsack_event(rack, 11, __LINE__, rack->r_ctl.last_tlp_acked_start, rack->r_ctl.last_tlp_acked_end); } } else { rack->r_ctl.last_tlp_acked_start = rsm->r_start; rack->r_ctl.last_tlp_acked_end = rsm->r_end; rack->rc_last_tlp_past_cumack = 0; rack->rc_last_tlp_acked_set = 1; rack_log_dsack_event(rack, 8, __LINE__, rsm->r_start, rsm->r_end); } } /** * Need to split this in two pieces the before and after, * the before remains in the map, the after must be * added. In other words we have: * rsm |--------------| * sackblk |-------> * rsm will become * rsm |---| * and nrsm will be the sacked piece * nrsm |----------| * * But before we start down that path lets * see if the sack spans over on top of * the next guy and it is already sacked. * */ next = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); if (next && (next->r_flags & RACK_ACKED) && SEQ_GEQ(end, next->r_start)) { /** * So the next one is already acked, and * we can thus by hookery use our stack_map * to reflect the piece being sacked and * then adjust the two tree entries moving * the start and ends around. So we start like: * rsm |------------| (not-acked) * next |-----------| (acked) * sackblk |--------> * We want to end like so: * rsm |------| (not-acked) * next |-----------------| (acked) * nrsm |-----| * Where nrsm is a temporary stack piece we * use to update all the gizmos. */ /* Copy up our fudge block */ nrsm = &stack_map; memcpy(nrsm, rsm, sizeof(struct rack_sendmap)); /* Now adjust our tree blocks */ rsm->r_end = start; next->r_start = start; /* Now we must adjust back where next->m is */ rack_setup_offset_for_rsm(rsm, next); /* We don't need to adjust rsm, it did not change */ /* Clear out the dup ack count of the remainder */ rsm->r_dupack = 0; rsm->r_just_ret = 0; rack_log_retran_reason(rack, rsm, __LINE__, 0, 2); /* Now lets make sure our fudge block is right */ nrsm->r_start = start; /* Now lets update all the stats and such */ rack_update_rtt(tp, rack, nrsm, to, cts, SACKED, 0); if (rack->app_limited_needs_set) rack_need_set_test(tp, rack, nrsm, tp->snd_una, __LINE__, RACK_USE_END); changed += (nrsm->r_end - nrsm->r_start); rack->r_ctl.rc_sacked += (nrsm->r_end - nrsm->r_start); if (nrsm->r_flags & RACK_SACK_PASSED) { rack->r_ctl.rc_reorder_ts = cts; } /* * Now we want to go up from rsm (the * one left un-acked) to the next one * in the tmap. We do this so when * we walk backwards we include marking * sack-passed on rsm (The one passed in * is skipped since it is generally called * on something sacked before removing it * from the tmap). */ if (rsm->r_in_tmap) { nrsm = TAILQ_NEXT(rsm, r_tnext); /* * Now that we have the next * one walk backwards from there. */ if (nrsm && nrsm->r_in_tmap) rack_log_sack_passed(tp, rack, nrsm); } /* Now are we done? */ if (SEQ_LT(end, next->r_end) || (end == next->r_end)) { /* Done with block */ goto out; } rack_log_map_chg(tp, rack, &stack_map, rsm, next, MAP_SACK_M1, end, __LINE__); counter_u64_add(rack_sack_used_next_merge, 1); /* Postion for the next block */ start = next->r_end; rsm = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, next); if (rsm == NULL) goto out; } else { /** * We can't use any hookery here, so we * need to split the map. We enter like * so: * rsm |--------| * sackblk |-----> * We will add the new block nrsm and * that will be the new portion, and then * fall through after reseting rsm. So we * split and look like this: * rsm |----| * sackblk |-----> * nrsm |---| * We then fall through reseting * rsm to nrsm, so the next block * picks it up. */ nrsm = rack_alloc_limit(rack, RACK_LIMIT_TYPE_SPLIT); if (nrsm == NULL) { /* * failed XXXrrs what can we do but loose the sack * info? */ goto out; } counter_u64_add(rack_sack_splits, 1); rack_clone_rsm(rack, nrsm, rsm, start); rsm->r_just_ret = 0; #ifndef INVARIANTS (void)RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); #else insret = RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); if (insret != NULL) { panic("Insert in rb tree of %p fails ret:%p rack:%p rsm:%p", nrsm, insret, rack, rsm); } #endif if (rsm->r_in_tmap) { TAILQ_INSERT_AFTER(&rack->r_ctl.rc_tmap, rsm, nrsm, r_tnext); nrsm->r_in_tmap = 1; } rack_log_map_chg(tp, rack, NULL, rsm, nrsm, MAP_SACK_M2, end, __LINE__); rsm->r_flags &= (~RACK_HAS_FIN); /* Position us to point to the new nrsm that starts the sack blk */ rsm = nrsm; } } else { /* Already sacked this piece */ counter_u64_add(rack_sack_skipped_acked, 1); moved++; if (end == rsm->r_end) { /* Done with block */ rsm = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); goto out; } else if (SEQ_LT(end, rsm->r_end)) { /* A partial sack to a already sacked block */ moved++; rsm = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); goto out; } else { /* * The end goes beyond this guy * reposition the start to the * next block. */ start = rsm->r_end; rsm = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); if (rsm == NULL) goto out; } } } if (SEQ_GEQ(end, rsm->r_end)) { /** * The end of this block is either beyond this guy or right * at this guy. I.e.: * rsm --- |-----| * end |-----| * * end |---------| */ if ((rsm->r_flags & RACK_ACKED) == 0) { /* * Is it a TLP of interest? */ if ((rsm->r_flags & RACK_TLP) && (rsm->r_rtr_cnt > 1)) { /* * We are splitting a rxt TLP, check * if we need to save off the start/end */ if (rack->rc_last_tlp_acked_set && (is_rsm_inside_declared_tlp_block(rack, rsm))) { /* * We already turned this on since we are inside * the previous one was a partially sack now we * are getting another one (maybe all of it). */ rack_log_dsack_event(rack, 10, __LINE__, rsm->r_start, rsm->r_end); /* * Lets make sure we have all of it though. */ if (SEQ_LT(rsm->r_start, rack->r_ctl.last_tlp_acked_start)) { rack->r_ctl.last_tlp_acked_start = rsm->r_start; rack_log_dsack_event(rack, 11, __LINE__, rack->r_ctl.last_tlp_acked_start, rack->r_ctl.last_tlp_acked_end); } if (SEQ_GT(rsm->r_end, rack->r_ctl.last_tlp_acked_end)) { rack->r_ctl.last_tlp_acked_end = rsm->r_end; rack_log_dsack_event(rack, 11, __LINE__, rack->r_ctl.last_tlp_acked_start, rack->r_ctl.last_tlp_acked_end); } } else { rack->r_ctl.last_tlp_acked_start = rsm->r_start; rack->r_ctl.last_tlp_acked_end = rsm->r_end; rack->rc_last_tlp_past_cumack = 0; rack->rc_last_tlp_acked_set = 1; rack_log_dsack_event(rack, 8, __LINE__, rsm->r_start, rsm->r_end); } } rack_update_rtt(tp, rack, rsm, to, cts, SACKED, 0); changed += (rsm->r_end - rsm->r_start); rack->r_ctl.rc_sacked += (rsm->r_end - rsm->r_start); if (rsm->r_in_tmap) /* should be true */ rack_log_sack_passed(tp, rack, rsm); /* Is Reordering occuring? */ if (rsm->r_flags & RACK_SACK_PASSED) { rsm->r_flags &= ~RACK_SACK_PASSED; rack->r_ctl.rc_reorder_ts = cts; } if (rack->app_limited_needs_set) rack_need_set_test(tp, rack, rsm, tp->snd_una, __LINE__, RACK_USE_END); rsm->r_ack_arrival = rack_to_usec_ts(&rack->r_ctl.act_rcv_time); rsm->r_flags |= RACK_ACKED; if (rsm->r_in_tmap) { TAILQ_REMOVE(&rack->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 0; } rack_log_map_chg(tp, rack, NULL, rsm, NULL, MAP_SACK_M3, end, __LINE__); } else { counter_u64_add(rack_sack_skipped_acked, 1); moved++; } if (end == rsm->r_end) { /* This block only - done, setup for next */ goto out; } /* * There is more not coverend by this rsm move on * to the next block in the RB tree. */ nrsm = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); start = rsm->r_end; rsm = nrsm; if (rsm == NULL) goto out; goto do_rest_ofb; } /** * The end of this sack block is smaller than * our rsm i.e.: * rsm --- |-----| * end |--| */ if ((rsm->r_flags & RACK_ACKED) == 0) { /* * Is it a TLP of interest? */ if ((rsm->r_flags & RACK_TLP) && (rsm->r_rtr_cnt > 1)) { /* * We are splitting a rxt TLP, check * if we need to save off the start/end */ if (rack->rc_last_tlp_acked_set && (is_rsm_inside_declared_tlp_block(rack, rsm))) { /* * We already turned this on since we are inside * the previous one was a partially sack now we * are getting another one (maybe all of it). */ rack_log_dsack_event(rack, 10, __LINE__, rsm->r_start, rsm->r_end); /* * Lets make sure we have all of it though. */ if (SEQ_LT(rsm->r_start, rack->r_ctl.last_tlp_acked_start)) { rack->r_ctl.last_tlp_acked_start = rsm->r_start; rack_log_dsack_event(rack, 11, __LINE__, rack->r_ctl.last_tlp_acked_start, rack->r_ctl.last_tlp_acked_end); } if (SEQ_GT(rsm->r_end, rack->r_ctl.last_tlp_acked_end)) { rack->r_ctl.last_tlp_acked_end = rsm->r_end; rack_log_dsack_event(rack, 11, __LINE__, rack->r_ctl.last_tlp_acked_start, rack->r_ctl.last_tlp_acked_end); } } else { rack->r_ctl.last_tlp_acked_start = rsm->r_start; rack->r_ctl.last_tlp_acked_end = rsm->r_end; rack->rc_last_tlp_past_cumack = 0; rack->rc_last_tlp_acked_set = 1; rack_log_dsack_event(rack, 8, __LINE__, rsm->r_start, rsm->r_end); } } prev = RB_PREV(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); if (prev && (prev->r_flags & RACK_ACKED)) { /** * Goal, we want the right remainder of rsm to shrink * in place and span from (rsm->r_start = end) to rsm->r_end. * We want to expand prev to go all the way * to prev->r_end <- end. * so in the tree we have before: * prev |--------| (acked) * rsm |-------| (non-acked) * sackblk |-| * We churn it so we end up with * prev |----------| (acked) * rsm |-----| (non-acked) * nrsm |-| (temporary) * * Note if either prev/rsm is a TLP we don't * do this. */ nrsm = &stack_map; memcpy(nrsm, rsm, sizeof(struct rack_sendmap)); prev->r_end = end; rsm->r_start = end; /* Now adjust nrsm (stack copy) to be * the one that is the small * piece that was "sacked". */ nrsm->r_end = end; rsm->r_dupack = 0; rack_log_retran_reason(rack, rsm, __LINE__, 0, 2); /* * Now that the rsm has had its start moved forward * lets go ahead and get its new place in the world. */ rack_setup_offset_for_rsm(prev, rsm); /* * Now nrsm is our new little piece * that is acked (which was merged * to prev). Update the rtt and changed * based on that. Also check for reordering. */ rack_update_rtt(tp, rack, nrsm, to, cts, SACKED, 0); if (rack->app_limited_needs_set) rack_need_set_test(tp, rack, nrsm, tp->snd_una, __LINE__, RACK_USE_END); changed += (nrsm->r_end - nrsm->r_start); rack->r_ctl.rc_sacked += (nrsm->r_end - nrsm->r_start); if (nrsm->r_flags & RACK_SACK_PASSED) { rack->r_ctl.rc_reorder_ts = cts; } rack_log_map_chg(tp, rack, prev, &stack_map, rsm, MAP_SACK_M4, end, __LINE__); rsm = prev; counter_u64_add(rack_sack_used_prev_merge, 1); } else { /** * This is the case where our previous * block is not acked either, so we must * split the block in two. */ nrsm = rack_alloc_limit(rack, RACK_LIMIT_TYPE_SPLIT); if (nrsm == NULL) { /* failed rrs what can we do but loose the sack info? */ goto out; } if ((rsm->r_flags & RACK_TLP) && (rsm->r_rtr_cnt > 1)) { /* * We are splitting a rxt TLP, check * if we need to save off the start/end */ if (rack->rc_last_tlp_acked_set && (is_rsm_inside_declared_tlp_block(rack, rsm))) { /* * We already turned this on since this block is inside * the previous one was a partially sack now we * are getting another one (maybe all of it). */ rack_log_dsack_event(rack, 10, __LINE__, rsm->r_start, rsm->r_end); /* * Lets make sure we have all of it though. */ if (SEQ_LT(rsm->r_start, rack->r_ctl.last_tlp_acked_start)) { rack->r_ctl.last_tlp_acked_start = rsm->r_start; rack_log_dsack_event(rack, 11, __LINE__, rack->r_ctl.last_tlp_acked_start, rack->r_ctl.last_tlp_acked_end); } if (SEQ_GT(rsm->r_end, rack->r_ctl.last_tlp_acked_end)) { rack->r_ctl.last_tlp_acked_end = rsm->r_end; rack_log_dsack_event(rack, 11, __LINE__, rack->r_ctl.last_tlp_acked_start, rack->r_ctl.last_tlp_acked_end); } } else { rack->r_ctl.last_tlp_acked_start = rsm->r_start; rack->r_ctl.last_tlp_acked_end = rsm->r_end; rack->rc_last_tlp_acked_set = 1; rack->rc_last_tlp_past_cumack = 0; rack_log_dsack_event(rack, 8, __LINE__, rsm->r_start, rsm->r_end); } } /** * In this case nrsm becomes * nrsm->r_start = end; * nrsm->r_end = rsm->r_end; * which is un-acked. * * rsm->r_end = nrsm->r_start; * i.e. the remaining un-acked * piece is left on the left * hand side. * * So we start like this * rsm |----------| (not acked) * sackblk |---| * build it so we have * rsm |---| (acked) * nrsm |------| (not acked) */ counter_u64_add(rack_sack_splits, 1); rack_clone_rsm(rack, nrsm, rsm, end); rsm->r_flags &= (~RACK_HAS_FIN); rsm->r_just_ret = 0; #ifndef INVARIANTS (void)RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); #else insret = RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); if (insret != NULL) { panic("Insert in rb tree of %p fails ret:%p rack:%p rsm:%p", nrsm, insret, rack, rsm); } #endif if (rsm->r_in_tmap) { TAILQ_INSERT_AFTER(&rack->r_ctl.rc_tmap, rsm, nrsm, r_tnext); nrsm->r_in_tmap = 1; } nrsm->r_dupack = 0; rack_log_retran_reason(rack, nrsm, __LINE__, 0, 2); rack_update_rtt(tp, rack, rsm, to, cts, SACKED, 0); changed += (rsm->r_end - rsm->r_start); rack->r_ctl.rc_sacked += (rsm->r_end - rsm->r_start); if (rsm->r_in_tmap) /* should be true */ rack_log_sack_passed(tp, rack, rsm); /* Is Reordering occuring? */ if (rsm->r_flags & RACK_SACK_PASSED) { rsm->r_flags &= ~RACK_SACK_PASSED; rack->r_ctl.rc_reorder_ts = cts; } if (rack->app_limited_needs_set) rack_need_set_test(tp, rack, rsm, tp->snd_una, __LINE__, RACK_USE_END); rsm->r_ack_arrival = rack_to_usec_ts(&rack->r_ctl.act_rcv_time); rsm->r_flags |= RACK_ACKED; rack_log_map_chg(tp, rack, NULL, rsm, nrsm, MAP_SACK_M5, end, __LINE__); if (rsm->r_in_tmap) { TAILQ_REMOVE(&rack->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 0; } } } else if (start != end){ /* * The block was already acked. */ counter_u64_add(rack_sack_skipped_acked, 1); moved++; } out: if (rsm && ((rsm->r_flags & RACK_TLP) == 0) && (rsm->r_flags & RACK_ACKED)) { /* * Now can we merge where we worked * with either the previous or * next block? */ next = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); while (next) { if (next->r_flags & RACK_TLP) break; if (next->r_flags & RACK_ACKED) { /* yep this and next can be merged */ rsm = rack_merge_rsm(rack, rsm, next); next = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); } else break; } /* Now what about the previous? */ prev = RB_PREV(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); while (prev) { if (prev->r_flags & RACK_TLP) break; if (prev->r_flags & RACK_ACKED) { /* yep the previous and this can be merged */ rsm = rack_merge_rsm(rack, prev, rsm); prev = RB_PREV(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); } else break; } } if (used_ref == 0) { counter_u64_add(rack_sack_proc_all, 1); } else { counter_u64_add(rack_sack_proc_short, 1); } /* Save off the next one for quick reference. */ if (rsm) nrsm = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); else nrsm = NULL; *prsm = rack->r_ctl.rc_sacklast = nrsm; /* Pass back the moved. */ *moved_two = moved; return (changed); } static void inline rack_peer_reneges(struct tcp_rack *rack, struct rack_sendmap *rsm, tcp_seq th_ack) { struct rack_sendmap *tmap; tmap = NULL; while (rsm && (rsm->r_flags & RACK_ACKED)) { /* Its no longer sacked, mark it so */ rack->r_ctl.rc_sacked -= (rsm->r_end - rsm->r_start); #ifdef INVARIANTS if (rsm->r_in_tmap) { panic("rack:%p rsm:%p flags:0x%x in tmap?", rack, rsm, rsm->r_flags); } #endif rsm->r_flags &= ~(RACK_ACKED|RACK_SACK_PASSED|RACK_WAS_SACKPASS); /* Rebuild it into our tmap */ if (tmap == NULL) { TAILQ_INSERT_HEAD(&rack->r_ctl.rc_tmap, rsm, r_tnext); tmap = rsm; } else { TAILQ_INSERT_AFTER(&rack->r_ctl.rc_tmap, tmap, rsm, r_tnext); tmap = rsm; } tmap->r_in_tmap = 1; rsm = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); } /* * Now lets possibly clear the sack filter so we start * recognizing sacks that cover this area. */ sack_filter_clear(&rack->r_ctl.rack_sf, th_ack); } static void rack_do_decay(struct tcp_rack *rack) { struct timeval res; #define timersub(tvp, uvp, vvp) \ do { \ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ if ((vvp)->tv_usec < 0) { \ (vvp)->tv_sec--; \ (vvp)->tv_usec += 1000000; \ } \ } while (0) timersub(&rack->r_ctl.act_rcv_time, &rack->r_ctl.rc_last_time_decay, &res); #undef timersub rack->r_ctl.input_pkt++; if ((rack->rc_in_persist) || (res.tv_sec >= 1) || (rack->rc_tp->snd_max == rack->rc_tp->snd_una)) { /* * Check for decay of non-SAD, * we want all SAD detection metrics to * decay 1/4 per second (or more) passed. */ #ifdef NETFLIX_EXP_DETECTION uint32_t pkt_delta; pkt_delta = rack->r_ctl.input_pkt - rack->r_ctl.saved_input_pkt; #endif /* Update our saved tracking values */ rack->r_ctl.saved_input_pkt = rack->r_ctl.input_pkt; rack->r_ctl.rc_last_time_decay = rack->r_ctl.act_rcv_time; /* Now do we escape without decay? */ #ifdef NETFLIX_EXP_DETECTION if (rack->rc_in_persist || (rack->rc_tp->snd_max == rack->rc_tp->snd_una) || (pkt_delta < tcp_sad_low_pps)){ /* * We don't decay idle connections * or ones that have a low input pps. */ return; } /* Decay the counters */ rack->r_ctl.ack_count = ctf_decay_count(rack->r_ctl.ack_count, tcp_sad_decay_val); rack->r_ctl.sack_count = ctf_decay_count(rack->r_ctl.sack_count, tcp_sad_decay_val); rack->r_ctl.sack_moved_extra = ctf_decay_count(rack->r_ctl.sack_moved_extra, tcp_sad_decay_val); rack->r_ctl.sack_noextra_move = ctf_decay_count(rack->r_ctl.sack_noextra_move, tcp_sad_decay_val); #endif } } static void rack_process_to_cumack(struct tcpcb *tp, struct tcp_rack *rack, register uint32_t th_ack, uint32_t cts, struct tcpopt *to) { struct rack_sendmap *rsm; #ifdef INVARIANTS struct rack_sendmap *rm; #endif /* * The ACK point is advancing to th_ack, we must drop off * the packets in the rack log and calculate any eligble * RTT's. */ rack->r_wanted_output = 1; /* Tend any TLP that has been marked for 1/2 the seq space (its old) */ if ((rack->rc_last_tlp_acked_set == 1)&& (rack->rc_last_tlp_past_cumack == 1) && (SEQ_GT(rack->r_ctl.last_tlp_acked_start, th_ack))) { /* * We have reached the point where our last rack * tlp retransmit sequence is ahead of the cum-ack. * This can only happen when the cum-ack moves all * the way around (its been a full 2^^31+1 bytes * or more since we sent a retransmitted TLP). Lets * turn off the valid flag since its not really valid. * * Note since sack's also turn on this event we have * a complication, we have to wait to age it out until * the cum-ack is by the TLP before checking which is * what the next else clause does. */ rack_log_dsack_event(rack, 9, __LINE__, rack->r_ctl.last_tlp_acked_start, rack->r_ctl.last_tlp_acked_end); rack->rc_last_tlp_acked_set = 0; rack->rc_last_tlp_past_cumack = 0; } else if ((rack->rc_last_tlp_acked_set == 1) && (rack->rc_last_tlp_past_cumack == 0) && (SEQ_GEQ(th_ack, rack->r_ctl.last_tlp_acked_end))) { /* * It is safe to start aging TLP's out. */ rack->rc_last_tlp_past_cumack = 1; } /* We do the same for the tlp send seq as well */ if ((rack->rc_last_sent_tlp_seq_valid == 1) && (rack->rc_last_sent_tlp_past_cumack == 1) && (SEQ_GT(rack->r_ctl.last_sent_tlp_seq, th_ack))) { rack_log_dsack_event(rack, 9, __LINE__, rack->r_ctl.last_sent_tlp_seq, (rack->r_ctl.last_sent_tlp_seq + rack->r_ctl.last_sent_tlp_len)); rack->rc_last_sent_tlp_seq_valid = 0; rack->rc_last_sent_tlp_past_cumack = 0; } else if ((rack->rc_last_sent_tlp_seq_valid == 1) && (rack->rc_last_sent_tlp_past_cumack == 0) && (SEQ_GEQ(th_ack, rack->r_ctl.last_sent_tlp_seq))) { /* * It is safe to start aging TLP's send. */ rack->rc_last_sent_tlp_past_cumack = 1; } more: rsm = RB_MIN(rack_rb_tree_head, &rack->r_ctl.rc_mtree); if (rsm == NULL) { if ((th_ack - 1) == tp->iss) { /* * For the SYN incoming case we will not * have called tcp_output for the sending of * the SYN, so there will be no map. All * other cases should probably be a panic. */ return; } if (tp->t_flags & TF_SENTFIN) { /* if we sent a FIN we often will not have map */ return; } #ifdef INVARIANTS panic("No rack map tp:%p for state:%d ack:%u rack:%p snd_una:%u snd_max:%u snd_nxt:%u\n", tp, tp->t_state, th_ack, rack, tp->snd_una, tp->snd_max, tp->snd_nxt); #endif return; } if (SEQ_LT(th_ack, rsm->r_start)) { /* Huh map is missing this */ #ifdef INVARIANTS printf("Rack map starts at r_start:%u for th_ack:%u huh? ts:%d rs:%d\n", rsm->r_start, th_ack, tp->t_state, rack->r_state); #endif return; } rack_update_rtt(tp, rack, rsm, to, cts, CUM_ACKED, th_ack); /* Now was it a retransmitted TLP? */ if ((rsm->r_flags & RACK_TLP) && (rsm->r_rtr_cnt > 1)) { /* * Yes, this rsm was a TLP and retransmitted, remember that * since if a DSACK comes back on this we don't want * to think of it as a reordered segment. This may * get updated again with possibly even other TLPs * in flight, but thats ok. Only when we don't send * a retransmitted TLP for 1/2 the sequences space * will it get turned off (above). */ if (rack->rc_last_tlp_acked_set && (is_rsm_inside_declared_tlp_block(rack, rsm))) { /* * We already turned this on since the end matches, * the previous one was a partially ack now we * are getting another one (maybe all of it). */ rack_log_dsack_event(rack, 10, __LINE__, rsm->r_start, rsm->r_end); /* * Lets make sure we have all of it though. */ if (SEQ_LT(rsm->r_start, rack->r_ctl.last_tlp_acked_start)) { rack->r_ctl.last_tlp_acked_start = rsm->r_start; rack_log_dsack_event(rack, 11, __LINE__, rack->r_ctl.last_tlp_acked_start, rack->r_ctl.last_tlp_acked_end); } if (SEQ_GT(rsm->r_end, rack->r_ctl.last_tlp_acked_end)) { rack->r_ctl.last_tlp_acked_end = rsm->r_end; rack_log_dsack_event(rack, 11, __LINE__, rack->r_ctl.last_tlp_acked_start, rack->r_ctl.last_tlp_acked_end); } } else { rack->rc_last_tlp_past_cumack = 1; rack->r_ctl.last_tlp_acked_start = rsm->r_start; rack->r_ctl.last_tlp_acked_end = rsm->r_end; rack->rc_last_tlp_acked_set = 1; rack_log_dsack_event(rack, 8, __LINE__, rsm->r_start, rsm->r_end); } } /* Now do we consume the whole thing? */ if (SEQ_GEQ(th_ack, rsm->r_end)) { /* Its all consumed. */ uint32_t left; uint8_t newly_acked; rack_log_map_chg(tp, rack, NULL, rsm, NULL, MAP_FREE, rsm->r_end, __LINE__); rack->r_ctl.rc_holes_rxt -= rsm->r_rtr_bytes; rsm->r_rtr_bytes = 0; /* Record the time of highest cumack sent */ rack->r_ctl.rc_gp_cumack_ts = rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]; #ifndef INVARIANTS (void)RB_REMOVE(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); #else rm = RB_REMOVE(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); if (rm != rsm) { panic("removing head in rack:%p rsm:%p rm:%p", rack, rsm, rm); } #endif if (rsm->r_in_tmap) { TAILQ_REMOVE(&rack->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 0; } newly_acked = 1; if (rsm->r_flags & RACK_ACKED) { /* * It was acked on the scoreboard -- remove * it from total */ rack->r_ctl.rc_sacked -= (rsm->r_end - rsm->r_start); newly_acked = 0; } else if (rsm->r_flags & RACK_SACK_PASSED) { /* * There are segments ACKED on the * scoreboard further up. We are seeing * reordering. */ rsm->r_flags &= ~RACK_SACK_PASSED; rsm->r_ack_arrival = rack_to_usec_ts(&rack->r_ctl.act_rcv_time); rsm->r_flags |= RACK_ACKED; rack->r_ctl.rc_reorder_ts = cts; if (rack->r_ent_rec_ns) { /* * We have sent no more, and we saw an sack * then ack arrive. */ rack->r_might_revert = 1; } } if ((rsm->r_flags & RACK_TO_REXT) && (tp->t_flags & TF_RCVD_TSTMP) && (to->to_flags & TOF_TS) && (to->to_tsecr != 0) && (tp->t_flags & TF_PREVVALID)) { /* * We can use the timestamp to see * if this retransmission was from the * first transmit. If so we made a mistake. */ tp->t_flags &= ~TF_PREVVALID; if (to->to_tsecr == rack_ts_to_msec(rsm->r_tim_lastsent[0])) { /* The first transmit is what this ack is for */ rack_cong_signal(tp, CC_RTO_ERR, th_ack, __LINE__); } } left = th_ack - rsm->r_end; if (rack->app_limited_needs_set && newly_acked) rack_need_set_test(tp, rack, rsm, th_ack, __LINE__, RACK_USE_END_OR_THACK); /* Free back to zone */ rack_free(rack, rsm); if (left) { goto more; } /* Check for reneging */ rsm = RB_MIN(rack_rb_tree_head, &rack->r_ctl.rc_mtree); if (rsm && (rsm->r_flags & RACK_ACKED) && (th_ack == rsm->r_start)) { /* * The peer has moved snd_una up to * the edge of this send, i.e. one * that it had previously acked. The only * way that can be true if the peer threw * away data (space issues) that it had * previously sacked (else it would have * given us snd_una up to (rsm->r_end). * We need to undo the acked markings here. * * Note we have to look to make sure th_ack is * our rsm->r_start in case we get an old ack * where th_ack is behind snd_una. */ rack_peer_reneges(rack, rsm, th_ack); } return; } if (rsm->r_flags & RACK_ACKED) { /* * It was acked on the scoreboard -- remove it from * total for the part being cum-acked. */ rack->r_ctl.rc_sacked -= (th_ack - rsm->r_start); } /* * Clear the dup ack count for * the piece that remains. */ rsm->r_dupack = 0; rack_log_retran_reason(rack, rsm, __LINE__, 0, 2); if (rsm->r_rtr_bytes) { /* * It was retransmitted adjust the * sack holes for what was acked. */ int ack_am; ack_am = (th_ack - rsm->r_start); if (ack_am >= rsm->r_rtr_bytes) { rack->r_ctl.rc_holes_rxt -= ack_am; rsm->r_rtr_bytes -= ack_am; } } /* * Update where the piece starts and record * the time of send of highest cumack sent. */ rack->r_ctl.rc_gp_cumack_ts = rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)]; rack_log_map_chg(tp, rack, NULL, rsm, NULL, MAP_TRIM_HEAD, th_ack, __LINE__); /* Now we need to move our offset forward too */ if (rsm->m && (rsm->orig_m_len != rsm->m->m_len)) { /* Fix up the orig_m_len and possibly the mbuf offset */ rack_adjust_orig_mlen(rsm); } rsm->soff += (th_ack - rsm->r_start); rsm->r_start = th_ack; /* Now do we need to move the mbuf fwd too? */ if (rsm->m) { while (rsm->soff >= rsm->m->m_len) { rsm->soff -= rsm->m->m_len; rsm->m = rsm->m->m_next; KASSERT((rsm->m != NULL), (" nrsm:%p hit at soff:%u null m", rsm, rsm->soff)); } rsm->orig_m_len = rsm->m->m_len; } if (rack->app_limited_needs_set) rack_need_set_test(tp, rack, rsm, tp->snd_una, __LINE__, RACK_USE_BEG); } static void rack_handle_might_revert(struct tcpcb *tp, struct tcp_rack *rack) { struct rack_sendmap *rsm; int sack_pass_fnd = 0; if (rack->r_might_revert) { /* * Ok we have reordering, have not sent anything, we * might want to revert the congestion state if nothing * further has SACK_PASSED on it. Lets check. * * We also get here when we have DSACKs come in for * all the data that we FR'd. Note that a rxt or tlp * timer clears this from happening. */ TAILQ_FOREACH(rsm, &rack->r_ctl.rc_tmap, r_tnext) { if (rsm->r_flags & RACK_SACK_PASSED) { sack_pass_fnd = 1; break; } } if (sack_pass_fnd == 0) { /* * We went into recovery * incorrectly due to reordering! */ int orig_cwnd; rack->r_ent_rec_ns = 0; orig_cwnd = tp->snd_cwnd; tp->snd_ssthresh = rack->r_ctl.rc_ssthresh_at_erec; tp->snd_recover = tp->snd_una; rack_log_to_prr(rack, 14, orig_cwnd, __LINE__); EXIT_RECOVERY(tp->t_flags); } rack->r_might_revert = 0; } } #ifdef NETFLIX_EXP_DETECTION static void rack_do_detection(struct tcpcb *tp, struct tcp_rack *rack, uint32_t bytes_this_ack, uint32_t segsiz) { if ((rack->do_detection || tcp_force_detection) && tcp_sack_to_ack_thresh && tcp_sack_to_move_thresh && ((rack->r_ctl.rc_num_maps_alloced > tcp_map_minimum) || rack->sack_attack_disable)) { /* * We have thresholds set to find * possible attackers and disable sack. * Check them. */ uint64_t ackratio, moveratio, movetotal; /* Log detecting */ rack_log_sad(rack, 1); ackratio = (uint64_t)(rack->r_ctl.sack_count); ackratio *= (uint64_t)(1000); if (rack->r_ctl.ack_count) ackratio /= (uint64_t)(rack->r_ctl.ack_count); else { /* We really should not hit here */ ackratio = 1000; } if ((rack->sack_attack_disable == 0) && (ackratio > rack_highest_sack_thresh_seen)) rack_highest_sack_thresh_seen = (uint32_t)ackratio; movetotal = rack->r_ctl.sack_moved_extra; movetotal += rack->r_ctl.sack_noextra_move; moveratio = rack->r_ctl.sack_moved_extra; moveratio *= (uint64_t)1000; if (movetotal) moveratio /= movetotal; else { /* No moves, thats pretty good */ moveratio = 0; } if ((rack->sack_attack_disable == 0) && (moveratio > rack_highest_move_thresh_seen)) rack_highest_move_thresh_seen = (uint32_t)moveratio; if (rack->sack_attack_disable == 0) { if ((ackratio > tcp_sack_to_ack_thresh) && (moveratio > tcp_sack_to_move_thresh)) { /* Disable sack processing */ rack->sack_attack_disable = 1; if (rack->r_rep_attack == 0) { rack->r_rep_attack = 1; counter_u64_add(rack_sack_attacks_detected, 1); } if (tcp_attack_on_turns_on_logging) { /* * Turn on logging, used for debugging * false positives. */ rack->rc_tp->t_logstate = tcp_attack_on_turns_on_logging; } /* Clamp the cwnd at flight size */ rack->r_ctl.rc_saved_cwnd = rack->rc_tp->snd_cwnd; rack->rc_tp->snd_cwnd = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); rack_log_sad(rack, 2); } } else { /* We are sack-disabled check for false positives */ if ((ackratio <= tcp_restoral_thresh) || (rack->r_ctl.rc_num_maps_alloced < tcp_map_minimum)) { rack->sack_attack_disable = 0; rack_log_sad(rack, 3); /* Restart counting */ rack->r_ctl.sack_count = 0; rack->r_ctl.sack_moved_extra = 0; rack->r_ctl.sack_noextra_move = 1; rack->r_ctl.ack_count = max(1, (bytes_this_ack / segsiz)); if (rack->r_rep_reverse == 0) { rack->r_rep_reverse = 1; counter_u64_add(rack_sack_attacks_reversed, 1); } /* Restore the cwnd */ if (rack->r_ctl.rc_saved_cwnd > rack->rc_tp->snd_cwnd) rack->rc_tp->snd_cwnd = rack->r_ctl.rc_saved_cwnd; } } } } #endif static int rack_note_dsack(struct tcp_rack *rack, tcp_seq start, tcp_seq end) { uint32_t am, l_end; int was_tlp = 0; if (SEQ_GT(end, start)) am = end - start; else am = 0; if ((rack->rc_last_tlp_acked_set ) && (SEQ_GEQ(start, rack->r_ctl.last_tlp_acked_start)) && (SEQ_LEQ(end, rack->r_ctl.last_tlp_acked_end))) { /* * The DSACK is because of a TLP which we don't * do anything with the reordering window over since * it was not reordering that caused the DSACK but * our previous retransmit TLP. */ rack_log_dsack_event(rack, 7, __LINE__, start, end); was_tlp = 1; goto skip_dsack_round; } if (rack->rc_last_sent_tlp_seq_valid) { l_end = rack->r_ctl.last_sent_tlp_seq + rack->r_ctl.last_sent_tlp_len; if (SEQ_GEQ(start, rack->r_ctl.last_sent_tlp_seq) && (SEQ_LEQ(end, l_end))) { /* * This dsack is from the last sent TLP, ignore it * for reordering purposes. */ rack_log_dsack_event(rack, 7, __LINE__, start, end); was_tlp = 1; goto skip_dsack_round; } } if (rack->rc_dsack_round_seen == 0) { rack->rc_dsack_round_seen = 1; rack->r_ctl.dsack_round_end = rack->rc_tp->snd_max; rack->r_ctl.num_dsack++; rack->r_ctl.dsack_persist = 16; /* 16 is from the standard */ rack_log_dsack_event(rack, 2, __LINE__, 0, 0); } skip_dsack_round: /* * We keep track of how many DSACK blocks we get * after a recovery incident. */ rack->r_ctl.dsack_byte_cnt += am; if (!IN_FASTRECOVERY(rack->rc_tp->t_flags) && rack->r_ctl.retran_during_recovery && (rack->r_ctl.dsack_byte_cnt >= rack->r_ctl.retran_during_recovery)) { /* * False recovery most likely culprit is reordering. If * nothing else is missing we need to revert. */ rack->r_might_revert = 1; rack_handle_might_revert(rack->rc_tp, rack); rack->r_might_revert = 0; rack->r_ctl.retran_during_recovery = 0; rack->r_ctl.dsack_byte_cnt = 0; } return (was_tlp); } static uint32_t do_rack_compute_pipe(struct tcpcb *tp, struct tcp_rack *rack, uint32_t snd_una) { return (((tp->snd_max - snd_una) - rack->r_ctl.rc_sacked) + rack->r_ctl.rc_holes_rxt); } static int32_t rack_compute_pipe(struct tcpcb *tp) { return ((int32_t)do_rack_compute_pipe(tp, (struct tcp_rack *)tp->t_fb_ptr, tp->snd_una)); } static void rack_update_prr(struct tcpcb *tp, struct tcp_rack *rack, uint32_t changed, tcp_seq th_ack) { /* Deal with changed and PRR here (in recovery only) */ uint32_t pipe, snd_una; rack->r_ctl.rc_prr_delivered += changed; if (sbavail(&rack->rc_inp->inp_socket->so_snd) <= (tp->snd_max - tp->snd_una)) { /* * It is all outstanding, we are application limited * and thus we don't need more room to send anything. * Note we use tp->snd_una here and not th_ack because * the data as yet not been cut from the sb. */ rack->r_ctl.rc_prr_sndcnt = 0; return; } /* Compute prr_sndcnt */ if (SEQ_GT(tp->snd_una, th_ack)) { snd_una = tp->snd_una; } else { snd_una = th_ack; } pipe = do_rack_compute_pipe(tp, rack, snd_una); if (pipe > tp->snd_ssthresh) { long sndcnt; sndcnt = rack->r_ctl.rc_prr_delivered * tp->snd_ssthresh; if (rack->r_ctl.rc_prr_recovery_fs > 0) sndcnt /= (long)rack->r_ctl.rc_prr_recovery_fs; else { rack->r_ctl.rc_prr_sndcnt = 0; rack_log_to_prr(rack, 9, 0, __LINE__); sndcnt = 0; } sndcnt++; if (sndcnt > (long)rack->r_ctl.rc_prr_out) sndcnt -= rack->r_ctl.rc_prr_out; else sndcnt = 0; rack->r_ctl.rc_prr_sndcnt = sndcnt; rack_log_to_prr(rack, 10, 0, __LINE__); } else { uint32_t limit; if (rack->r_ctl.rc_prr_delivered > rack->r_ctl.rc_prr_out) limit = (rack->r_ctl.rc_prr_delivered - rack->r_ctl.rc_prr_out); else limit = 0; if (changed > limit) limit = changed; limit += ctf_fixed_maxseg(tp); if (tp->snd_ssthresh > pipe) { rack->r_ctl.rc_prr_sndcnt = min((tp->snd_ssthresh - pipe), limit); rack_log_to_prr(rack, 11, 0, __LINE__); } else { rack->r_ctl.rc_prr_sndcnt = min(0, limit); rack_log_to_prr(rack, 12, 0, __LINE__); } } } static void rack_log_ack(struct tcpcb *tp, struct tcpopt *to, struct tcphdr *th, int entered_recovery, int dup_ack_struck) { uint32_t changed; struct tcp_rack *rack; struct rack_sendmap *rsm; struct sackblk sack, sack_blocks[TCP_MAX_SACK + 1]; register uint32_t th_ack; int32_t i, j, k, num_sack_blks = 0; uint32_t cts, acked, ack_point; int loop_start = 0, moved_two = 0; uint32_t tsused; INP_WLOCK_ASSERT(tptoinpcb(tp)); if (tcp_get_flags(th) & TH_RST) { /* We don't log resets */ return; } rack = (struct tcp_rack *)tp->t_fb_ptr; cts = tcp_get_usecs(NULL); rsm = RB_MIN(rack_rb_tree_head, &rack->r_ctl.rc_mtree); changed = 0; th_ack = th->th_ack; if (rack->sack_attack_disable == 0) rack_do_decay(rack); if (BYTES_THIS_ACK(tp, th) >= ctf_fixed_maxseg(rack->rc_tp)) { /* * You only get credit for * MSS and greater (and you get extra * credit for larger cum-ack moves). */ int ac; ac = BYTES_THIS_ACK(tp, th) / ctf_fixed_maxseg(rack->rc_tp); rack->r_ctl.ack_count += ac; counter_u64_add(rack_ack_total, ac); } if (rack->r_ctl.ack_count > 0xfff00000) { /* * reduce the number to keep us under * a uint32_t. */ rack->r_ctl.ack_count /= 2; rack->r_ctl.sack_count /= 2; } if (SEQ_GT(th_ack, tp->snd_una)) { rack_log_progress_event(rack, tp, ticks, PROGRESS_UPDATE, __LINE__); tp->t_acktime = ticks; } if (rsm && SEQ_GT(th_ack, rsm->r_start)) changed = th_ack - rsm->r_start; if (changed) { rack_process_to_cumack(tp, rack, th_ack, cts, to); } if ((to->to_flags & TOF_SACK) == 0) { /* We are done nothing left and no sack. */ rack_handle_might_revert(tp, rack); /* * For cases where we struck a dup-ack * with no SACK, add to the changes so * PRR will work right. */ if (dup_ack_struck && (changed == 0)) { changed += ctf_fixed_maxseg(rack->rc_tp); } goto out; } /* Sack block processing */ if (SEQ_GT(th_ack, tp->snd_una)) ack_point = th_ack; else ack_point = tp->snd_una; for (i = 0; i < to->to_nsacks; i++) { bcopy((to->to_sacks + i * TCPOLEN_SACK), &sack, sizeof(sack)); sack.start = ntohl(sack.start); sack.end = ntohl(sack.end); if (SEQ_GT(sack.end, sack.start) && SEQ_GT(sack.start, ack_point) && SEQ_LT(sack.start, tp->snd_max) && SEQ_GT(sack.end, ack_point) && SEQ_LEQ(sack.end, tp->snd_max)) { sack_blocks[num_sack_blks] = sack; num_sack_blks++; } else if (SEQ_LEQ(sack.start, th_ack) && SEQ_LEQ(sack.end, th_ack)) { int was_tlp; was_tlp = rack_note_dsack(rack, sack.start, sack.end); /* * Its a D-SACK block. */ tcp_record_dsack(tp, sack.start, sack.end, was_tlp); } } if (rack->rc_dsack_round_seen) { /* Is the dsack roound over? */ if (SEQ_GEQ(th_ack, rack->r_ctl.dsack_round_end)) { /* Yes it is */ rack->rc_dsack_round_seen = 0; rack_log_dsack_event(rack, 3, __LINE__, 0, 0); } } /* * Sort the SACK blocks so we can update the rack scoreboard with * just one pass. */ num_sack_blks = sack_filter_blks(&rack->r_ctl.rack_sf, sack_blocks, num_sack_blks, th->th_ack); ctf_log_sack_filter(rack->rc_tp, num_sack_blks, sack_blocks); if (num_sack_blks == 0) { /* Nothing to sack (DSACKs?) */ goto out_with_totals; } if (num_sack_blks < 2) { /* Only one, we don't need to sort */ goto do_sack_work; } /* Sort the sacks */ for (i = 0; i < num_sack_blks; i++) { for (j = i + 1; j < num_sack_blks; j++) { if (SEQ_GT(sack_blocks[i].end, sack_blocks[j].end)) { sack = sack_blocks[i]; sack_blocks[i] = sack_blocks[j]; sack_blocks[j] = sack; } } } /* * Now are any of the sack block ends the same (yes some * implementations send these)? */ again: if (num_sack_blks == 0) goto out_with_totals; if (num_sack_blks > 1) { for (i = 0; i < num_sack_blks; i++) { for (j = i + 1; j < num_sack_blks; j++) { if (sack_blocks[i].end == sack_blocks[j].end) { /* * Ok these two have the same end we * want the smallest end and then * throw away the larger and start * again. */ if (SEQ_LT(sack_blocks[j].start, sack_blocks[i].start)) { /* * The second block covers * more area use that */ sack_blocks[i].start = sack_blocks[j].start; } /* * Now collapse out the dup-sack and * lower the count */ for (k = (j + 1); k < num_sack_blks; k++) { sack_blocks[j].start = sack_blocks[k].start; sack_blocks[j].end = sack_blocks[k].end; j++; } num_sack_blks--; goto again; } } } } do_sack_work: /* * First lets look to see if * we have retransmitted and * can use the transmit next? */ rsm = TAILQ_FIRST(&rack->r_ctl.rc_tmap); if (rsm && SEQ_GT(sack_blocks[0].end, rsm->r_start) && SEQ_LT(sack_blocks[0].start, rsm->r_end)) { /* * We probably did the FR and the next * SACK in continues as we would expect. */ acked = rack_proc_sack_blk(tp, rack, &sack_blocks[0], to, &rsm, cts, &moved_two); if (acked) { rack->r_wanted_output = 1; changed += acked; } if (num_sack_blks == 1) { /* * This is what we would expect from * a normal implementation to happen * after we have retransmitted the FR, * i.e the sack-filter pushes down * to 1 block and the next to be retransmitted * is the sequence in the sack block (has more * are acked). Count this as ACK'd data to boost * up the chances of recovering any false positives. */ rack->r_ctl.ack_count += (acked / ctf_fixed_maxseg(rack->rc_tp)); counter_u64_add(rack_ack_total, (acked / ctf_fixed_maxseg(rack->rc_tp))); counter_u64_add(rack_express_sack, 1); if (rack->r_ctl.ack_count > 0xfff00000) { /* * reduce the number to keep us under * a uint32_t. */ rack->r_ctl.ack_count /= 2; rack->r_ctl.sack_count /= 2; } goto out_with_totals; } else { /* * Start the loop through the * rest of blocks, past the first block. */ moved_two = 0; loop_start = 1; } } /* Its a sack of some sort */ rack->r_ctl.sack_count++; if (rack->r_ctl.sack_count > 0xfff00000) { /* * reduce the number to keep us under * a uint32_t. */ rack->r_ctl.ack_count /= 2; rack->r_ctl.sack_count /= 2; } counter_u64_add(rack_sack_total, 1); if (rack->sack_attack_disable) { /* An attacker disablement is in place */ if (num_sack_blks > 1) { rack->r_ctl.sack_count += (num_sack_blks - 1); rack->r_ctl.sack_moved_extra++; counter_u64_add(rack_move_some, 1); if (rack->r_ctl.sack_moved_extra > 0xfff00000) { rack->r_ctl.sack_moved_extra /= 2; rack->r_ctl.sack_noextra_move /= 2; } } goto out; } rsm = rack->r_ctl.rc_sacklast; for (i = loop_start; i < num_sack_blks; i++) { acked = rack_proc_sack_blk(tp, rack, &sack_blocks[i], to, &rsm, cts, &moved_two); if (acked) { rack->r_wanted_output = 1; changed += acked; } if (moved_two) { /* * If we did not get a SACK for at least a MSS and * had to move at all, or if we moved more than our * threshold, it counts against the "extra" move. */ rack->r_ctl.sack_moved_extra += moved_two; counter_u64_add(rack_move_some, 1); } else { /* * else we did not have to move * any more than we would expect. */ rack->r_ctl.sack_noextra_move++; counter_u64_add(rack_move_none, 1); } if (moved_two && (acked < ctf_fixed_maxseg(rack->rc_tp))) { /* * If the SACK was not a full MSS then * we add to sack_count the number of * MSS's (or possibly more than * a MSS if its a TSO send) we had to skip by. */ rack->r_ctl.sack_count += moved_two; counter_u64_add(rack_sack_total, moved_two); } /* * Now we need to setup for the next * round. First we make sure we won't * exceed the size of our uint32_t on * the various counts, and then clear out * moved_two. */ if ((rack->r_ctl.sack_moved_extra > 0xfff00000) || (rack->r_ctl.sack_noextra_move > 0xfff00000)) { rack->r_ctl.sack_moved_extra /= 2; rack->r_ctl.sack_noextra_move /= 2; } if (rack->r_ctl.sack_count > 0xfff00000) { rack->r_ctl.ack_count /= 2; rack->r_ctl.sack_count /= 2; } moved_two = 0; } out_with_totals: if (num_sack_blks > 1) { /* * You get an extra stroke if * you have more than one sack-blk, this * could be where we are skipping forward * and the sack-filter is still working, or * it could be an attacker constantly * moving us. */ rack->r_ctl.sack_moved_extra++; counter_u64_add(rack_move_some, 1); } out: #ifdef NETFLIX_EXP_DETECTION rack_do_detection(tp, rack, BYTES_THIS_ACK(tp, th), ctf_fixed_maxseg(rack->rc_tp)); #endif if (changed) { /* Something changed cancel the rack timer */ rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); } tsused = tcp_get_usecs(NULL); rsm = tcp_rack_output(tp, rack, tsused); if ((!IN_FASTRECOVERY(tp->t_flags)) && rsm && ((rsm->r_flags & RACK_MUST_RXT) == 0)) { /* Enter recovery */ entered_recovery = 1; rack_cong_signal(tp, CC_NDUPACK, tp->snd_una, __LINE__); /* * When we enter recovery we need to assure we send * one packet. */ if (rack->rack_no_prr == 0) { rack->r_ctl.rc_prr_sndcnt = ctf_fixed_maxseg(tp); rack_log_to_prr(rack, 8, 0, __LINE__); } rack->r_timer_override = 1; rack->r_early = 0; rack->r_ctl.rc_agg_early = 0; } else if (IN_FASTRECOVERY(tp->t_flags) && rsm && (rack->r_rr_config == 3)) { /* * Assure we can output and we get no * remembered pace time except the retransmit. */ rack->r_timer_override = 1; rack->r_ctl.rc_hpts_flags &= ~PACE_PKT_OUTPUT; rack->r_ctl.rc_resend = rsm; } if (IN_FASTRECOVERY(tp->t_flags) && (rack->rack_no_prr == 0) && (entered_recovery == 0)) { rack_update_prr(tp, rack, changed, th_ack); if ((rsm && (rack->r_ctl.rc_prr_sndcnt >= ctf_fixed_maxseg(tp)) && ((tcp_in_hpts(rack->rc_inp) == 0) && ((rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) == 0)))) { /* * If you are pacing output you don't want * to override. */ rack->r_early = 0; rack->r_ctl.rc_agg_early = 0; rack->r_timer_override = 1; } } } static void rack_strike_dupack(struct tcp_rack *rack) { struct rack_sendmap *rsm; rsm = TAILQ_FIRST(&rack->r_ctl.rc_tmap); while (rsm && (rsm->r_dupack >= DUP_ACK_THRESHOLD)) { rsm = TAILQ_NEXT(rsm, r_tnext); if (rsm->r_flags & RACK_MUST_RXT) { /* Sendmap entries that are marked to * be retransmitted do not need dupack's * struck. We get these marks for a number * of reasons (rxt timeout with no sack, * mtu change, or rwnd collapses). When * these events occur, we know we must retransmit * them and mark the sendmap entries. Dupack counting * is not needed since we are already set to retransmit * it as soon as we can. */ continue; } } if (rsm && (rsm->r_dupack < 0xff)) { rsm->r_dupack++; if (rsm->r_dupack >= DUP_ACK_THRESHOLD) { struct timeval tv; uint32_t cts; /* * Here we see if we need to retransmit. For * a SACK type connection if enough time has passed * we will get a return of the rsm. For a non-sack * connection we will get the rsm returned if the * dupack value is 3 or more. */ cts = tcp_get_usecs(&tv); rack->r_ctl.rc_resend = tcp_rack_output(rack->rc_tp, rack, cts); if (rack->r_ctl.rc_resend != NULL) { if (!IN_FASTRECOVERY(rack->rc_tp->t_flags)) { rack_cong_signal(rack->rc_tp, CC_NDUPACK, rack->rc_tp->snd_una, __LINE__); } rack->r_wanted_output = 1; rack->r_timer_override = 1; rack_log_retran_reason(rack, rsm, __LINE__, 1, 3); } } else { rack_log_retran_reason(rack, rsm, __LINE__, 0, 3); } } } static void rack_check_bottom_drag(struct tcpcb *tp, struct tcp_rack *rack, struct socket *so, int32_t acked) { uint32_t segsiz, minseg; segsiz = ctf_fixed_maxseg(tp); minseg = segsiz; if (tp->snd_max == tp->snd_una) { /* * We are doing dynamic pacing and we are way * under. Basically everything got acked while * we were still waiting on the pacer to expire. * * This means we need to boost the b/w in * addition to any earlier boosting of * the multiplier. */ rack->rc_dragged_bottom = 1; rack_validate_multipliers_at_or_above100(rack); /* * Lets use the segment bytes acked plus * the lowest RTT seen as the basis to * form a b/w estimate. This will be off * due to the fact that the true estimate * should be around 1/2 the time of the RTT * but we can settle for that. */ if ((rack->r_ctl.rack_rs.rs_flags & RACK_RTT_VALID) && acked) { uint64_t bw, calc_bw, rtt; rtt = rack->r_ctl.rack_rs.rs_us_rtt; if (rtt == 0) { /* no us sample is there a ms one? */ if (rack->r_ctl.rack_rs.rs_rtt_lowest) { rtt = rack->r_ctl.rack_rs.rs_rtt_lowest; } else { goto no_measurement; } } bw = acked; calc_bw = bw * 1000000; calc_bw /= rtt; if (rack->r_ctl.last_max_bw && (rack->r_ctl.last_max_bw < calc_bw)) { /* * If we have a last calculated max bw * enforce it. */ calc_bw = rack->r_ctl.last_max_bw; } /* now plop it in */ if (rack->rc_gp_filled == 0) { if (calc_bw > ONE_POINT_TWO_MEG) { /* * If we have no measurement * don't let us set in more than * 1.2Mbps. If we are still too * low after pacing with this we * will hopefully have a max b/w * available to sanity check things. */ calc_bw = ONE_POINT_TWO_MEG; } rack->r_ctl.rc_rtt_diff = 0; rack->r_ctl.gp_bw = calc_bw; rack->rc_gp_filled = 1; if (rack->r_ctl.num_measurements < RACK_REQ_AVG) rack->r_ctl.num_measurements = RACK_REQ_AVG; rack_set_pace_segments(rack->rc_tp, rack, __LINE__, NULL); } else if (calc_bw > rack->r_ctl.gp_bw) { rack->r_ctl.rc_rtt_diff = 0; if (rack->r_ctl.num_measurements < RACK_REQ_AVG) rack->r_ctl.num_measurements = RACK_REQ_AVG; rack->r_ctl.gp_bw = calc_bw; rack_set_pace_segments(rack->rc_tp, rack, __LINE__, NULL); } else rack_increase_bw_mul(rack, -1, 0, 0, 1); if ((rack->gp_ready == 0) && (rack->r_ctl.num_measurements >= rack->r_ctl.req_measurements)) { /* We have enough measurements now */ rack->gp_ready = 1; rack_set_cc_pacing(rack); if (rack->defer_options) rack_apply_deferred_options(rack); } /* * For acks over 1mss we do a extra boost to simulate * where we would get 2 acks (we want 110 for the mul). */ if (acked > segsiz) rack_increase_bw_mul(rack, -1, 0, 0, 1); } else { /* * zero rtt possibly?, settle for just an old increase. */ no_measurement: rack_increase_bw_mul(rack, -1, 0, 0, 1); } } else if ((IN_FASTRECOVERY(tp->t_flags) == 0) && (sbavail(&so->so_snd) > max((segsiz * (4 + rack_req_segs)), minseg)) && (rack->r_ctl.cwnd_to_use > max((segsiz * (rack_req_segs + 2)), minseg)) && (tp->snd_wnd > max((segsiz * (rack_req_segs + 2)), minseg)) && (ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked) <= (segsiz * rack_req_segs))) { /* * We are doing dynamic GP pacing and * we have everything except 1MSS or less * bytes left out. We are still pacing away. * And there is data that could be sent, This * means we are inserting delayed ack time in * our measurements because we are pacing too slow. */ rack_validate_multipliers_at_or_above100(rack); rack->rc_dragged_bottom = 1; rack_increase_bw_mul(rack, -1, 0, 0, 1); } } static void rack_gain_for_fastoutput(struct tcp_rack *rack, struct tcpcb *tp, struct socket *so, uint32_t acked_amount) { /* * The fast output path is enabled and we * have moved the cumack forward. Lets see if * we can expand forward the fast path length by * that amount. What we would ideally like to * do is increase the number of bytes in the * fast path block (left_to_send) by the * acked amount. However we have to gate that * by two factors: * 1) The amount outstanding and the rwnd of the peer * (i.e. we don't want to exceed the rwnd of the peer). * * 2) The amount of data left in the socket buffer (i.e. * we can't send beyond what is in the buffer). * * Note that this does not take into account any increase * in the cwnd. We will only extend the fast path by * what was acked. */ uint32_t new_total, gating_val; new_total = acked_amount + rack->r_ctl.fsb.left_to_send; gating_val = min((sbavail(&so->so_snd) - (tp->snd_max - tp->snd_una)), (tp->snd_wnd - (tp->snd_max - tp->snd_una))); if (new_total <= gating_val) { /* We can increase left_to_send by the acked amount */ counter_u64_add(rack_extended_rfo, 1); rack->r_ctl.fsb.left_to_send = new_total; KASSERT((rack->r_ctl.fsb.left_to_send <= (sbavail(&rack->rc_inp->inp_socket->so_snd) - (tp->snd_max - tp->snd_una))), ("rack:%p left_to_send:%u sbavail:%u out:%u", rack, rack->r_ctl.fsb.left_to_send, sbavail(&rack->rc_inp->inp_socket->so_snd), (tp->snd_max - tp->snd_una))); } } static void rack_adjust_sendmap(struct tcp_rack *rack, struct sockbuf *sb, tcp_seq snd_una) { /* * Here any sendmap entry that points to the * beginning mbuf must be adjusted to the correct * offset. This must be called with: * 1) The socket buffer locked * 2) snd_una adjusted to its new postion. * * Note that (2) implies rack_ack_received has also * been called. * * We grab the first mbuf in the socket buffer and * then go through the front of the sendmap, recalculating * the stored offset for any sendmap entry that has * that mbuf. We must use the sb functions to do this * since its possible an add was done has well as * the subtraction we may have just completed. This should * not be a penalty though, since we just referenced the sb * to go in and trim off the mbufs that we freed (of course * there will be a penalty for the sendmap references though). */ struct mbuf *m; struct rack_sendmap *rsm; SOCKBUF_LOCK_ASSERT(sb); m = sb->sb_mb; rsm = RB_MIN(rack_rb_tree_head, &rack->r_ctl.rc_mtree); if ((rsm == NULL) || (m == NULL)) { /* Nothing outstanding */ return; } while (rsm->m && (rsm->m == m)) { /* one to adjust */ #ifdef INVARIANTS struct mbuf *tm; uint32_t soff; tm = sbsndmbuf(sb, (rsm->r_start - snd_una), &soff); if (rsm->orig_m_len != m->m_len) { rack_adjust_orig_mlen(rsm); } if (rsm->soff != soff) { /* * This is not a fatal error, we anticipate it * might happen (the else code), so we count it here * so that under invariant we can see that it really * does happen. */ counter_u64_add(rack_adjust_map_bw, 1); } rsm->m = tm; rsm->soff = soff; if (tm) rsm->orig_m_len = rsm->m->m_len; else rsm->orig_m_len = 0; #else rsm->m = sbsndmbuf(sb, (rsm->r_start - snd_una), &rsm->soff); if (rsm->m) rsm->orig_m_len = rsm->m->m_len; else rsm->orig_m_len = 0; #endif rsm = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); if (rsm == NULL) break; } } /* * Return value of 1, we do not need to call rack_process_data(). * return value of 0, rack_process_data can be called. * For ret_val if its 0 the TCP is locked, if its non-zero * its unlocked and probably unsafe to touch the TCB. */ static int rack_process_ack(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, uint32_t tiwin, int32_t tlen, int32_t * ofia, int32_t thflags, int32_t *ret_val) { int32_t ourfinisacked = 0; int32_t nsegs, acked_amount; int32_t acked; struct mbuf *mfree; struct tcp_rack *rack; int32_t under_pacing = 0; int32_t recovery = 0; INP_WLOCK_ASSERT(tptoinpcb(tp)); rack = (struct tcp_rack *)tp->t_fb_ptr; if (SEQ_GT(th->th_ack, tp->snd_max)) { __ctf_do_dropafterack(m, tp, th, thflags, tlen, ret_val, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt); rack->r_wanted_output = 1; return (1); } if (rack->gp_ready && (rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT)) { under_pacing = 1; } if (SEQ_GEQ(th->th_ack, tp->snd_una) || to->to_nsacks) { int in_rec, dup_ack_struck = 0; in_rec = IN_FASTRECOVERY(tp->t_flags); if (rack->rc_in_persist) { tp->t_rxtshift = 0; RACK_TCPT_RANGESET(tp->t_rxtcur, RACK_REXMTVAL(tp), rack_rto_min, rack_rto_max, rack->r_ctl.timer_slop); } if ((th->th_ack == tp->snd_una) && (tiwin == tp->snd_wnd) && ((to->to_flags & TOF_SACK) == 0)) { rack_strike_dupack(rack); dup_ack_struck = 1; } rack_log_ack(tp, to, th, ((in_rec == 0) && IN_FASTRECOVERY(tp->t_flags)), dup_ack_struck); } if (__predict_false(SEQ_LEQ(th->th_ack, tp->snd_una))) { /* * Old ack, behind (or duplicate to) the last one rcv'd * Note: We mark reordering is occuring if its * less than and we have not closed our window. */ if (SEQ_LT(th->th_ack, tp->snd_una) && (sbspace(&so->so_rcv) > ctf_fixed_maxseg(tp))) { rack->r_ctl.rc_reorder_ts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); } return (0); } /* * If we reach this point, ACK is not a duplicate, i.e., it ACKs * something we sent. */ if (tp->t_flags & TF_NEEDSYN) { /* * T/TCP: Connection was half-synchronized, and our SYN has * been ACK'd (so connection is now fully synchronized). Go * to non-starred state, increment snd_una for ACK of SYN, * and check if we can do window scaling. */ tp->t_flags &= ~TF_NEEDSYN; tp->snd_una++; /* Do window scaling? */ if ((tp->t_flags & (TF_RCVD_SCALE | TF_REQ_SCALE)) == (TF_RCVD_SCALE | TF_REQ_SCALE)) { tp->rcv_scale = tp->request_r_scale; /* Send window already scaled. */ } } nsegs = max(1, m->m_pkthdr.lro_nsegs); acked = BYTES_THIS_ACK(tp, th); if (acked) { /* * Any time we move the cum-ack forward clear * keep-alive tied probe-not-answered. The * persists clears its own on entry. */ rack->probe_not_answered = 0; } KMOD_TCPSTAT_ADD(tcps_rcvackpack, nsegs); KMOD_TCPSTAT_ADD(tcps_rcvackbyte, acked); /* * If we just performed our first retransmit, and the ACK arrives * within our recovery window, then it was a mistake to do the * retransmit in the first place. Recover our original cwnd and * ssthresh, and proceed to transmit where we left off. */ if ((tp->t_flags & TF_PREVVALID) && ((tp->t_flags & TF_RCVD_TSTMP) == 0)) { tp->t_flags &= ~TF_PREVVALID; if (tp->t_rxtshift == 1 && (int)(ticks - tp->t_badrxtwin) < 0) rack_cong_signal(tp, CC_RTO_ERR, th->th_ack, __LINE__); } if (acked) { /* assure we are not backed off */ tp->t_rxtshift = 0; RACK_TCPT_RANGESET(tp->t_rxtcur, RACK_REXMTVAL(tp), rack_rto_min, rack_rto_max, rack->r_ctl.timer_slop); rack->rc_tlp_in_progress = 0; rack->r_ctl.rc_tlp_cnt_out = 0; /* * If it is the RXT timer we want to * stop it, so we can restart a TLP. */ if (rack->r_ctl.rc_hpts_flags & PACE_TMR_RXT) rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); #ifdef NETFLIX_HTTP_LOGGING tcp_http_check_for_comp(rack->rc_tp, th->th_ack); #endif } /* * If we have a timestamp reply, update smoothed round trip time. If * no timestamp is present but transmit timer is running and timed * sequence number was acked, update smoothed round trip time. Since * we now have an rtt measurement, cancel the timer backoff (cf., * Phil Karn's retransmit alg.). Recompute the initial retransmit * timer. * * Some boxes send broken timestamp replies during the SYN+ACK * phase, ignore timestamps of 0 or we could calculate a huge RTT * and blow up the retransmit timer. */ /* * If all outstanding data is acked, stop retransmit timer and * remember to restart (more output or persist). If there is more * data to be acked, restart retransmit timer, using current * (possibly backed-off) value. */ if (acked == 0) { if (ofia) *ofia = ourfinisacked; return (0); } if (IN_RECOVERY(tp->t_flags)) { if (SEQ_LT(th->th_ack, tp->snd_recover) && (SEQ_LT(th->th_ack, tp->snd_max))) { tcp_rack_partialack(tp); } else { rack_post_recovery(tp, th->th_ack); recovery = 1; } } /* * Let the congestion control algorithm update congestion control * related information. This typically means increasing the * congestion window. */ rack_ack_received(tp, rack, th->th_ack, nsegs, CC_ACK, recovery); SOCKBUF_LOCK(&so->so_snd); acked_amount = min(acked, (int)sbavail(&so->so_snd)); tp->snd_wnd -= acked_amount; mfree = sbcut_locked(&so->so_snd, acked_amount); if ((sbused(&so->so_snd) == 0) && (acked > acked_amount) && (tp->t_state >= TCPS_FIN_WAIT_1) && (tp->t_flags & TF_SENTFIN)) { /* * We must be sure our fin * was sent and acked (we can be * in FIN_WAIT_1 without having * sent the fin). */ ourfinisacked = 1; } tp->snd_una = th->th_ack; if (acked_amount && sbavail(&so->so_snd)) rack_adjust_sendmap(rack, &so->so_snd, tp->snd_una); rack_log_wakeup(tp,rack, &so->so_snd, acked, 2); /* NB: sowwakeup_locked() does an implicit unlock. */ sowwakeup_locked(so); m_freem(mfree); if (SEQ_GT(tp->snd_una, tp->snd_recover)) tp->snd_recover = tp->snd_una; if (SEQ_LT(tp->snd_nxt, tp->snd_una)) { tp->snd_nxt = tp->snd_una; } if (under_pacing && (rack->use_fixed_rate == 0) && (rack->in_probe_rtt == 0) && rack->rc_gp_dyn_mul && rack->rc_always_pace) { /* Check if we are dragging bottom */ rack_check_bottom_drag(tp, rack, so, acked); } if (tp->snd_una == tp->snd_max) { /* Nothing left outstanding */ tp->t_flags &= ~TF_PREVVALID; rack->r_ctl.rc_went_idle_time = tcp_get_usecs(NULL); rack->r_ctl.retran_during_recovery = 0; rack->r_ctl.dsack_byte_cnt = 0; if (rack->r_ctl.rc_went_idle_time == 0) rack->r_ctl.rc_went_idle_time = 1; rack_log_progress_event(rack, tp, 0, PROGRESS_CLEAR, __LINE__); if (sbavail(&tptosocket(tp)->so_snd) == 0) tp->t_acktime = 0; rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); /* Set need output so persist might get set */ rack->r_wanted_output = 1; sack_filter_clear(&rack->r_ctl.rack_sf, tp->snd_una); if ((tp->t_state >= TCPS_FIN_WAIT_1) && (sbavail(&so->so_snd) == 0) && (tp->t_flags2 & TF2_DROP_AF_DATA)) { /* * The socket was gone and the * peer sent data (now or in the past), time to * reset him. */ *ret_val = 1; /* tcp_close will kill the inp pre-log the Reset */ tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST); tp = tcp_close(tp); ctf_do_dropwithreset(m, tp, th, BANDLIM_UNLIMITED, tlen); return (1); } } if (ofia) *ofia = ourfinisacked; return (0); } static void rack_log_collapse(struct tcp_rack *rack, uint32_t cnt, uint32_t split, uint32_t out, int line, int dir, uint32_t flags, struct rack_sendmap *rsm) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log, 0, sizeof(log)); log.u_bbr.flex1 = cnt; log.u_bbr.flex2 = split; log.u_bbr.flex3 = out; log.u_bbr.flex4 = line; log.u_bbr.flex5 = rack->r_must_retran; log.u_bbr.flex6 = flags; log.u_bbr.flex7 = rack->rc_has_collapsed; log.u_bbr.flex8 = dir; /* * 1 is collapsed, 0 is uncollapsed, * 2 is log of a rsm being marked, 3 is a split. */ if (rsm == NULL) log.u_bbr.rttProp = 0; else log.u_bbr.rttProp = (uint64_t)rsm; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, TCP_RACK_LOG_COLLAPSE, 0, 0, &log, false, &tv); } } static void rack_collapsed_window(struct tcp_rack *rack, uint32_t out, int line) { /* * Here all we do is mark the collapsed point and set the flag. * This may happen again and again, but there is no * sense splitting our map until we know where the * peer finally lands in the collapse. */ rack_trace_point(rack, RACK_TP_COLLAPSED_WND); if ((rack->rc_has_collapsed == 0) || (rack->r_ctl.last_collapse_point != (rack->rc_tp->snd_una + rack->rc_tp->snd_wnd))) counter_u64_add(rack_collapsed_win_seen, 1); rack->r_ctl.last_collapse_point = rack->rc_tp->snd_una + rack->rc_tp->snd_wnd; rack->r_ctl.high_collapse_point = rack->rc_tp->snd_max; rack->rc_has_collapsed = 1; rack->r_collapse_point_valid = 1; rack_log_collapse(rack, 0, 0, rack->r_ctl.last_collapse_point, line, 1, 0, NULL); } static void rack_un_collapse_window(struct tcp_rack *rack, int line) { struct rack_sendmap *nrsm, *rsm, fe; int cnt = 0, split = 0; #ifdef INVARIANTS struct rack_sendmap *insret; #endif memset(&fe, 0, sizeof(fe)); rack->rc_has_collapsed = 0; fe.r_start = rack->r_ctl.last_collapse_point; rsm = RB_FIND(rack_rb_tree_head, &rack->r_ctl.rc_mtree, &fe); if (rsm == NULL) { /* Nothing to do maybe the peer ack'ed it all */ rack_log_collapse(rack, 0, 0, ctf_outstanding(rack->rc_tp), line, 0, 0, NULL); return; } /* Now do we need to split this one? */ if (SEQ_GT(rack->r_ctl.last_collapse_point, rsm->r_start)) { rack_log_collapse(rack, rsm->r_start, rsm->r_end, rack->r_ctl.last_collapse_point, line, 3, rsm->r_flags, rsm); nrsm = rack_alloc_limit(rack, RACK_LIMIT_TYPE_SPLIT); if (nrsm == NULL) { /* We can't get a rsm, mark all? */ nrsm = rsm; goto no_split; } /* Clone it */ split = 1; rack_clone_rsm(rack, nrsm, rsm, rack->r_ctl.last_collapse_point); #ifndef INVARIANTS (void)RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); #else insret = RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); if (insret != NULL) { panic("Insert in rb tree of %p fails ret:%p rack:%p rsm:%p", nrsm, insret, rack, rsm); } #endif rack_log_map_chg(rack->rc_tp, rack, NULL, rsm, nrsm, MAP_SPLIT, rack->r_ctl.last_collapse_point, __LINE__); if (rsm->r_in_tmap) { TAILQ_INSERT_AFTER(&rack->r_ctl.rc_tmap, rsm, nrsm, r_tnext); nrsm->r_in_tmap = 1; } /* * Set in the new RSM as the * collapsed starting point */ rsm = nrsm; } no_split: RB_FOREACH_FROM(nrsm, rack_rb_tree_head, rsm) { nrsm->r_flags |= RACK_RWND_COLLAPSED; rack_log_collapse(rack, nrsm->r_start, nrsm->r_end, 0, line, 4, nrsm->r_flags, nrsm); cnt++; } if (cnt) { counter_u64_add(rack_collapsed_win, 1); } rack_log_collapse(rack, cnt, split, ctf_outstanding(rack->rc_tp), line, 0, 0, NULL); } static void rack_handle_delayed_ack(struct tcpcb *tp, struct tcp_rack *rack, int32_t tlen, int32_t tfo_syn) { if (DELAY_ACK(tp, tlen) || tfo_syn) { if (rack->rc_dack_mode && (tlen > 500) && (rack->rc_dack_toggle == 1)) { goto no_delayed_ack; } rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); tp->t_flags |= TF_DELACK; } else { no_delayed_ack: rack->r_wanted_output = 1; tp->t_flags |= TF_ACKNOW; if (rack->rc_dack_mode) { if (tp->t_flags & TF_DELACK) rack->rc_dack_toggle = 1; else rack->rc_dack_toggle = 0; } } } static void rack_validate_fo_sendwin_up(struct tcpcb *tp, struct tcp_rack *rack) { /* * If fast output is in progress, lets validate that * the new window did not shrink on us and make it * so fast output should end. */ if (rack->r_fast_output) { uint32_t out; /* * Calculate what we will send if left as is * and compare that to our send window. */ out = ctf_outstanding(tp); if ((out + rack->r_ctl.fsb.left_to_send) > tp->snd_wnd) { /* ok we have an issue */ if (out >= tp->snd_wnd) { /* Turn off fast output the window is met or collapsed */ rack->r_fast_output = 0; } else { /* we have some room left */ rack->r_ctl.fsb.left_to_send = tp->snd_wnd - out; if (rack->r_ctl.fsb.left_to_send < ctf_fixed_maxseg(tp)) { /* If not at least 1 full segment never mind */ rack->r_fast_output = 0; } } } } } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCP is still * locked. */ static int rack_process_data(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt) { /* * Update window information. Don't look at window if no ACK: TAC's * send garbage on first SYN. */ int32_t nsegs; int32_t tfo_syn; struct tcp_rack *rack; INP_WLOCK_ASSERT(tptoinpcb(tp)); rack = (struct tcp_rack *)tp->t_fb_ptr; nsegs = max(1, m->m_pkthdr.lro_nsegs); if ((thflags & TH_ACK) && (SEQ_LT(tp->snd_wl1, th->th_seq) || (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) || (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) { /* keep track of pure window updates */ if (tlen == 0 && tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd) KMOD_TCPSTAT_INC(tcps_rcvwinupd); tp->snd_wnd = tiwin; rack_validate_fo_sendwin_up(tp, rack); tp->snd_wl1 = th->th_seq; tp->snd_wl2 = th->th_ack; if (tp->snd_wnd > tp->max_sndwnd) tp->max_sndwnd = tp->snd_wnd; rack->r_wanted_output = 1; } else if (thflags & TH_ACK) { if ((tp->snd_wl2 == th->th_ack) && (tiwin < tp->snd_wnd)) { tp->snd_wnd = tiwin; rack_validate_fo_sendwin_up(tp, rack); tp->snd_wl1 = th->th_seq; tp->snd_wl2 = th->th_ack; } } if (tp->snd_wnd < ctf_outstanding(tp)) /* The peer collapsed the window */ rack_collapsed_window(rack, ctf_outstanding(tp), __LINE__); else if (rack->rc_has_collapsed) rack_un_collapse_window(rack, __LINE__); if ((rack->r_collapse_point_valid) && (SEQ_GT(th->th_ack, rack->r_ctl.high_collapse_point))) rack->r_collapse_point_valid = 0; /* Was persist timer active and now we have window space? */ if ((rack->rc_in_persist != 0) && (tp->snd_wnd >= min((rack->r_ctl.rc_high_rwnd/2), rack->r_ctl.rc_pace_min_segs))) { rack_exit_persist(tp, rack, rack->r_ctl.rc_rcvtime); tp->snd_nxt = tp->snd_max; /* Make sure we output to start the timer */ rack->r_wanted_output = 1; } /* Do we enter persists? */ if ((rack->rc_in_persist == 0) && (tp->snd_wnd < min((rack->r_ctl.rc_high_rwnd/2), rack->r_ctl.rc_pace_min_segs)) && TCPS_HAVEESTABLISHED(tp->t_state) && ((tp->snd_max == tp->snd_una) || rack->rc_has_collapsed) && sbavail(&tptosocket(tp)->so_snd) && (sbavail(&tptosocket(tp)->so_snd) > tp->snd_wnd)) { /* * Here the rwnd is less than * the pacing size, we are established, * nothing is outstanding, and there is * data to send. Enter persists. */ rack_enter_persist(tp, rack, rack->r_ctl.rc_rcvtime); } if (tp->t_flags2 & TF2_DROP_AF_DATA) { m_freem(m); return (0); } /* * don't process the URG bit, ignore them drag * along the up. */ tp->rcv_up = tp->rcv_nxt; /* * Process the segment text, merging it into the TCP sequencing * queue, and arranging for acknowledgment of receipt if necessary. * This process logically involves adjusting tp->rcv_wnd as data is * presented to the user (this happens in tcp_usrreq.c, case * PRU_RCVD). If a FIN has already been received on this connection * then we just ignore the text. */ tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) && IS_FASTOPEN(tp->t_flags)); if ((tlen || (thflags & TH_FIN) || (tfo_syn && tlen > 0)) && TCPS_HAVERCVDFIN(tp->t_state) == 0) { tcp_seq save_start = th->th_seq; tcp_seq save_rnxt = tp->rcv_nxt; int save_tlen = tlen; m_adj(m, drop_hdrlen); /* delayed header drop */ /* * Insert segment which includes th into TCP reassembly * queue with control block tp. Set thflags to whether * reassembly now includes a segment with FIN. This handles * the common case inline (segment is the next to be * received on an established connection, and the queue is * empty), avoiding linkage into and removal from the queue * and repetition of various conversions. Set DELACK for * segments received in order, but ack immediately when * segments are out of order (so fast retransmit can work). */ if (th->th_seq == tp->rcv_nxt && SEGQ_EMPTY(tp) && (TCPS_HAVEESTABLISHED(tp->t_state) || tfo_syn)) { #ifdef NETFLIX_SB_LIMITS u_int mcnt, appended; if (so->so_rcv.sb_shlim) { mcnt = m_memcnt(m); appended = 0; if (counter_fo_get(so->so_rcv.sb_shlim, mcnt, CFO_NOSLEEP, NULL) == false) { counter_u64_add(tcp_sb_shlim_fails, 1); m_freem(m); return (0); } } #endif rack_handle_delayed_ack(tp, rack, tlen, tfo_syn); tp->rcv_nxt += tlen; if (tlen && ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && (tp->t_fbyte_in == 0)) { tp->t_fbyte_in = ticks; if (tp->t_fbyte_in == 0) tp->t_fbyte_in = 1; if (tp->t_fbyte_out && tp->t_fbyte_in) tp->t_flags2 |= TF2_FBYTES_COMPLETE; } thflags = tcp_get_flags(th) & TH_FIN; KMOD_TCPSTAT_ADD(tcps_rcvpack, nsegs); KMOD_TCPSTAT_ADD(tcps_rcvbyte, tlen); SOCKBUF_LOCK(&so->so_rcv); if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { m_freem(m); } else #ifdef NETFLIX_SB_LIMITS appended = #endif sbappendstream_locked(&so->so_rcv, m, 0); rack_log_wakeup(tp,rack, &so->so_rcv, tlen, 1); /* NB: sorwakeup_locked() does an implicit unlock. */ sorwakeup_locked(so); #ifdef NETFLIX_SB_LIMITS if (so->so_rcv.sb_shlim && appended != mcnt) counter_fo_release(so->so_rcv.sb_shlim, mcnt - appended); #endif } else { /* * XXX: Due to the header drop above "th" is * theoretically invalid by now. Fortunately * m_adj() doesn't actually frees any mbufs when * trimming from the head. */ tcp_seq temp = save_start; thflags = tcp_reass(tp, th, &temp, &tlen, m); tp->t_flags |= TF_ACKNOW; if (tp->t_flags & TF_WAKESOR) { tp->t_flags &= ~TF_WAKESOR; /* NB: sorwakeup_locked() does an implicit unlock. */ sorwakeup_locked(so); } } if ((tp->t_flags & TF_SACK_PERMIT) && (save_tlen > 0) && TCPS_HAVEESTABLISHED(tp->t_state)) { if ((tlen == 0) && (SEQ_LT(save_start, save_rnxt))) { /* * DSACK actually handled in the fastpath * above. */ RACK_OPTS_INC(tcp_sack_path_1); tcp_update_sack_list(tp, save_start, save_start + save_tlen); } else if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) { if ((tp->rcv_numsacks >= 1) && (tp->sackblks[0].end == save_start)) { /* * Partial overlap, recorded at todrop * above. */ RACK_OPTS_INC(tcp_sack_path_2a); tcp_update_sack_list(tp, tp->sackblks[0].start, tp->sackblks[0].end); } else { RACK_OPTS_INC(tcp_sack_path_2b); tcp_update_dsack_list(tp, save_start, save_start + save_tlen); } } else if (tlen >= save_tlen) { /* Update of sackblks. */ RACK_OPTS_INC(tcp_sack_path_3); tcp_update_dsack_list(tp, save_start, save_start + save_tlen); } else if (tlen > 0) { RACK_OPTS_INC(tcp_sack_path_4); tcp_update_dsack_list(tp, save_start, save_start + tlen); } } } else { m_freem(m); thflags &= ~TH_FIN; } /* * If FIN is received ACK the FIN and let the user know that the * connection is closing. */ if (thflags & TH_FIN) { if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { /* The socket upcall is handled by socantrcvmore. */ socantrcvmore(so); /* * If connection is half-synchronized (ie NEEDSYN * flag on) then delay ACK, so it may be piggybacked * when SYN is sent. Otherwise, since we received a * FIN then no more input can be expected, send ACK * now. */ if (tp->t_flags & TF_NEEDSYN) { rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); tp->t_flags |= TF_DELACK; } else { tp->t_flags |= TF_ACKNOW; } tp->rcv_nxt++; } switch (tp->t_state) { /* * In SYN_RECEIVED and ESTABLISHED STATES enter the * CLOSE_WAIT state. */ case TCPS_SYN_RECEIVED: tp->t_starttime = ticks; /* FALLTHROUGH */ case TCPS_ESTABLISHED: rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); tcp_state_change(tp, TCPS_CLOSE_WAIT); break; /* * If still in FIN_WAIT_1 STATE FIN has not been * acked so enter the CLOSING state. */ case TCPS_FIN_WAIT_1: rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); tcp_state_change(tp, TCPS_CLOSING); break; /* * In FIN_WAIT_2 state enter the TIME_WAIT state, * starting the time-wait timer, turning off the * other standard timers. */ case TCPS_FIN_WAIT_2: rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); tcp_twstart(tp); return (1); } } /* * Return any desired output. */ if ((tp->t_flags & TF_ACKNOW) || (sbavail(&so->so_snd) > (tp->snd_max - tp->snd_una))) { rack->r_wanted_output = 1; } return (0); } /* * Here nothing is really faster, its just that we * have broken out the fast-data path also just like * the fast-ack. */ static int rack_do_fastnewdata(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t nxt_pkt, uint8_t iptos) { int32_t nsegs; int32_t newsize = 0; /* automatic sockbuf scaling */ struct tcp_rack *rack; #ifdef NETFLIX_SB_LIMITS u_int mcnt, appended; #endif -#ifdef TCPDEBUG - /* - * The size of tcp_saveipgen must be the size of the max ip header, - * now IPv6. - */ - u_char tcp_saveipgen[IP6_HDR_LEN]; - struct tcphdr tcp_savetcp; - short ostate = 0; -#endif /* * If last ACK falls within this segment's sequence numbers, record * the timestamp. NOTE that the test is modified according to the * latest proposal of the tcplw@cray.com list (Braden 1993/04/26). */ if (__predict_false(th->th_seq != tp->rcv_nxt)) { return (0); } if (__predict_false(tp->snd_nxt != tp->snd_max)) { return (0); } if (tiwin && tiwin != tp->snd_wnd) { return (0); } if (__predict_false((tp->t_flags & (TF_NEEDSYN | TF_NEEDFIN)))) { return (0); } if (__predict_false((to->to_flags & TOF_TS) && (TSTMP_LT(to->to_tsval, tp->ts_recent)))) { return (0); } if (__predict_false((th->th_ack != tp->snd_una))) { return (0); } if (__predict_false(tlen > sbspace(&so->so_rcv))) { return (0); } if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent)) { tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = to->to_tsval; } rack = (struct tcp_rack *)tp->t_fb_ptr; /* * This is a pure, in-sequence data packet with nothing on the * reassembly queue and we have enough buffer space to take it. */ nsegs = max(1, m->m_pkthdr.lro_nsegs); #ifdef NETFLIX_SB_LIMITS if (so->so_rcv.sb_shlim) { mcnt = m_memcnt(m); appended = 0; if (counter_fo_get(so->so_rcv.sb_shlim, mcnt, CFO_NOSLEEP, NULL) == false) { counter_u64_add(tcp_sb_shlim_fails, 1); m_freem(m); return (1); } } #endif /* Clean receiver SACK report if present */ if (tp->rcv_numsacks) tcp_clean_sackreport(tp); KMOD_TCPSTAT_INC(tcps_preddat); tp->rcv_nxt += tlen; if (tlen && ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && (tp->t_fbyte_in == 0)) { tp->t_fbyte_in = ticks; if (tp->t_fbyte_in == 0) tp->t_fbyte_in = 1; if (tp->t_fbyte_out && tp->t_fbyte_in) tp->t_flags2 |= TF2_FBYTES_COMPLETE; } /* * Pull snd_wl1 up to prevent seq wrap relative to th_seq. */ tp->snd_wl1 = th->th_seq; /* * Pull rcv_up up to prevent seq wrap relative to rcv_nxt. */ tp->rcv_up = tp->rcv_nxt; KMOD_TCPSTAT_ADD(tcps_rcvpack, nsegs); KMOD_TCPSTAT_ADD(tcps_rcvbyte, tlen); -#ifdef TCPDEBUG - if (so->so_options & SO_DEBUG) - tcp_trace(TA_INPUT, ostate, tp, - (void *)tcp_saveipgen, &tcp_savetcp, 0); -#endif newsize = tcp_autorcvbuf(m, th, so, tp, tlen); /* Add data to socket buffer. */ SOCKBUF_LOCK(&so->so_rcv); if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { m_freem(m); } else { /* * Set new socket buffer size. Give up when limit is * reached. */ if (newsize) if (!sbreserve_locked(so, SO_RCV, newsize, NULL)) so->so_rcv.sb_flags &= ~SB_AUTOSIZE; m_adj(m, drop_hdrlen); /* delayed header drop */ #ifdef NETFLIX_SB_LIMITS appended = #endif sbappendstream_locked(&so->so_rcv, m, 0); ctf_calc_rwin(so, tp); } rack_log_wakeup(tp,rack, &so->so_rcv, tlen, 1); /* NB: sorwakeup_locked() does an implicit unlock. */ sorwakeup_locked(so); #ifdef NETFLIX_SB_LIMITS if (so->so_rcv.sb_shlim && mcnt != appended) counter_fo_release(so->so_rcv.sb_shlim, mcnt - appended); #endif rack_handle_delayed_ack(tp, rack, tlen, 0); if (tp->snd_una == tp->snd_max) sack_filter_clear(&rack->r_ctl.rack_sf, tp->snd_una); return (1); } /* * This subfunction is used to try to highly optimize the * fast path. We again allow window updates that are * in sequence to remain in the fast-path. We also add * in the __predict's to attempt to help the compiler. * Note that if we return a 0, then we can *not* process * it and the caller should push the packet into the * slow-path. */ static int rack_fastack(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t nxt_pkt, uint32_t cts) { int32_t acked; int32_t nsegs; -#ifdef TCPDEBUG - /* - * The size of tcp_saveipgen must be the size of the max ip header, - * now IPv6. - */ - u_char tcp_saveipgen[IP6_HDR_LEN]; - struct tcphdr tcp_savetcp; - short ostate = 0; -#endif int32_t under_pacing = 0; struct tcp_rack *rack; if (__predict_false(SEQ_LEQ(th->th_ack, tp->snd_una))) { /* Old ack, behind (or duplicate to) the last one rcv'd */ return (0); } if (__predict_false(SEQ_GT(th->th_ack, tp->snd_max))) { /* Above what we have sent? */ return (0); } if (__predict_false(tp->snd_nxt != tp->snd_max)) { /* We are retransmitting */ return (0); } if (__predict_false(tiwin == 0)) { /* zero window */ return (0); } if (__predict_false(tp->t_flags & (TF_NEEDSYN | TF_NEEDFIN))) { /* We need a SYN or a FIN, unlikely.. */ return (0); } if ((to->to_flags & TOF_TS) && __predict_false(TSTMP_LT(to->to_tsval, tp->ts_recent))) { /* Timestamp is behind .. old ack with seq wrap? */ return (0); } if (__predict_false(IN_RECOVERY(tp->t_flags))) { /* Still recovering */ return (0); } rack = (struct tcp_rack *)tp->t_fb_ptr; if (rack->r_ctl.rc_sacked) { /* We have sack holes on our scoreboard */ return (0); } /* Ok if we reach here, we can process a fast-ack */ if (rack->gp_ready && (rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT)) { under_pacing = 1; } nsegs = max(1, m->m_pkthdr.lro_nsegs); rack_log_ack(tp, to, th, 0, 0); /* Did the window get updated? */ if (tiwin != tp->snd_wnd) { tp->snd_wnd = tiwin; rack_validate_fo_sendwin_up(tp, rack); tp->snd_wl1 = th->th_seq; if (tp->snd_wnd > tp->max_sndwnd) tp->max_sndwnd = tp->snd_wnd; } /* Do we exit persists? */ if ((rack->rc_in_persist != 0) && (tp->snd_wnd >= min((rack->r_ctl.rc_high_rwnd/2), rack->r_ctl.rc_pace_min_segs))) { rack_exit_persist(tp, rack, cts); } /* Do we enter persists? */ if ((rack->rc_in_persist == 0) && (tp->snd_wnd < min((rack->r_ctl.rc_high_rwnd/2), rack->r_ctl.rc_pace_min_segs)) && TCPS_HAVEESTABLISHED(tp->t_state) && ((tp->snd_max == tp->snd_una) || rack->rc_has_collapsed) && sbavail(&tptosocket(tp)->so_snd) && (sbavail(&tptosocket(tp)->so_snd) > tp->snd_wnd)) { /* * Here the rwnd is less than * the pacing size, we are established, * nothing is outstanding, and there is * data to send. Enter persists. */ rack_enter_persist(tp, rack, rack->r_ctl.rc_rcvtime); } /* * If last ACK falls within this segment's sequence numbers, record * the timestamp. NOTE that the test is modified according to the * latest proposal of the tcplw@cray.com list (Braden 1993/04/26). */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent)) { tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = to->to_tsval; } /* * This is a pure ack for outstanding data. */ KMOD_TCPSTAT_INC(tcps_predack); /* * "bad retransmit" recovery. */ if ((tp->t_flags & TF_PREVVALID) && ((tp->t_flags & TF_RCVD_TSTMP) == 0)) { tp->t_flags &= ~TF_PREVVALID; if (tp->t_rxtshift == 1 && (int)(ticks - tp->t_badrxtwin) < 0) rack_cong_signal(tp, CC_RTO_ERR, th->th_ack, __LINE__); } /* * Recalculate the transmit timer / rtt. * * Some boxes send broken timestamp replies during the SYN+ACK * phase, ignore timestamps of 0 or we could calculate a huge RTT * and blow up the retransmit timer. */ acked = BYTES_THIS_ACK(tp, th); #ifdef TCP_HHOOK /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ hhook_run_tcp_est_in(tp, th, to); #endif KMOD_TCPSTAT_ADD(tcps_rcvackpack, nsegs); KMOD_TCPSTAT_ADD(tcps_rcvackbyte, acked); if (acked) { struct mbuf *mfree; rack_ack_received(tp, rack, th->th_ack, nsegs, CC_ACK, 0); SOCKBUF_LOCK(&so->so_snd); mfree = sbcut_locked(&so->so_snd, acked); tp->snd_una = th->th_ack; /* Note we want to hold the sb lock through the sendmap adjust */ rack_adjust_sendmap(rack, &so->so_snd, tp->snd_una); /* Wake up the socket if we have room to write more */ rack_log_wakeup(tp,rack, &so->so_snd, acked, 2); sowwakeup_locked(so); m_freem(mfree); tp->t_rxtshift = 0; RACK_TCPT_RANGESET(tp->t_rxtcur, RACK_REXMTVAL(tp), rack_rto_min, rack_rto_max, rack->r_ctl.timer_slop); rack->rc_tlp_in_progress = 0; rack->r_ctl.rc_tlp_cnt_out = 0; /* * If it is the RXT timer we want to * stop it, so we can restart a TLP. */ if (rack->r_ctl.rc_hpts_flags & PACE_TMR_RXT) rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); #ifdef NETFLIX_HTTP_LOGGING tcp_http_check_for_comp(rack->rc_tp, th->th_ack); #endif } /* * Let the congestion control algorithm update congestion control * related information. This typically means increasing the * congestion window. */ if (tp->snd_wnd < ctf_outstanding(tp)) { /* The peer collapsed the window */ rack_collapsed_window(rack, ctf_outstanding(tp), __LINE__); } else if (rack->rc_has_collapsed) rack_un_collapse_window(rack, __LINE__); if ((rack->r_collapse_point_valid) && (SEQ_GT(tp->snd_una, rack->r_ctl.high_collapse_point))) rack->r_collapse_point_valid = 0; /* * Pull snd_wl2 up to prevent seq wrap relative to th_ack. */ tp->snd_wl2 = th->th_ack; tp->t_dupacks = 0; m_freem(m); /* ND6_HINT(tp); *//* Some progress has been made. */ /* * If all outstanding data are acked, stop retransmit timer, * otherwise restart timer using current (possibly backed-off) * value. If process is waiting for space, wakeup/selwakeup/signal. * If data are ready to send, let tcp_output decide between more * output or persist. */ -#ifdef TCPDEBUG - if (so->so_options & SO_DEBUG) - tcp_trace(TA_INPUT, ostate, tp, - (void *)tcp_saveipgen, - &tcp_savetcp, 0); -#endif if (under_pacing && (rack->use_fixed_rate == 0) && (rack->in_probe_rtt == 0) && rack->rc_gp_dyn_mul && rack->rc_always_pace) { /* Check if we are dragging bottom */ rack_check_bottom_drag(tp, rack, so, acked); } if (tp->snd_una == tp->snd_max) { tp->t_flags &= ~TF_PREVVALID; rack->r_ctl.retran_during_recovery = 0; rack->r_ctl.dsack_byte_cnt = 0; rack->r_ctl.rc_went_idle_time = tcp_get_usecs(NULL); if (rack->r_ctl.rc_went_idle_time == 0) rack->r_ctl.rc_went_idle_time = 1; rack_log_progress_event(rack, tp, 0, PROGRESS_CLEAR, __LINE__); if (sbavail(&tptosocket(tp)->so_snd) == 0) tp->t_acktime = 0; rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); } if (acked && rack->r_fast_output) rack_gain_for_fastoutput(rack, tp, so, (uint32_t)acked); if (sbavail(&so->so_snd)) { rack->r_wanted_output = 1; } return (1); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCP is still * locked. */ static int rack_do_syn_sent(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t ret_val = 0; int32_t todrop; int32_t ourfinisacked = 0; struct tcp_rack *rack; INP_WLOCK_ASSERT(tptoinpcb(tp)); ctf_calc_rwin(so, tp); /* * If the state is SYN_SENT: if seg contains an ACK, but not for our * SYN, drop the input. if seg contains a RST, then drop the * connection. if seg does not contain SYN, then drop it. Otherwise * this is an acceptable SYN segment initialize tp->rcv_nxt and * tp->irs if seg contains ack then advance tp->snd_una if seg * contains an ECE and ECN support is enabled, the stream is ECN * capable. if SYN has been acked change to ESTABLISHED else * SYN_RCVD state arrange for segment to be acked (eventually) * continue processing rest of data/controls. */ if ((thflags & TH_ACK) && (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); ctf_do_dropwithreset(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } if ((thflags & (TH_ACK | TH_RST)) == (TH_ACK | TH_RST)) { TCP_PROBE5(connect__refused, NULL, tp, mtod(m, const char *), tp, th); tp = tcp_drop(tp, ECONNREFUSED); ctf_do_drop(m, tp); return (1); } if (thflags & TH_RST) { ctf_do_drop(m, tp); return (1); } if (!(thflags & TH_SYN)) { ctf_do_drop(m, tp); return (1); } tp->irs = th->th_seq; tcp_rcvseqinit(tp); rack = (struct tcp_rack *)tp->t_fb_ptr; if (thflags & TH_ACK) { int tfo_partial = 0; KMOD_TCPSTAT_INC(tcps_connects); soisconnected(so); #ifdef MAC mac_socketpeer_set_from_mbuf(m, so); #endif /* Do window scaling on this connection? */ if ((tp->t_flags & (TF_RCVD_SCALE | TF_REQ_SCALE)) == (TF_RCVD_SCALE | TF_REQ_SCALE)) { tp->rcv_scale = tp->request_r_scale; } tp->rcv_adv += min(tp->rcv_wnd, TCP_MAXWIN << tp->rcv_scale); /* * If not all the data that was sent in the TFO SYN * has been acked, resend the remainder right away. */ if (IS_FASTOPEN(tp->t_flags) && (tp->snd_una != tp->snd_max)) { tp->snd_nxt = th->th_ack; tfo_partial = 1; } /* * If there's data, delay ACK; if there's also a FIN ACKNOW * will be turned on later. */ if (DELAY_ACK(tp, tlen) && tlen != 0 && !tfo_partial) { rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); tp->t_flags |= TF_DELACK; } else { rack->r_wanted_output = 1; tp->t_flags |= TF_ACKNOW; rack->rc_dack_toggle = 0; } tcp_ecn_input_syn_sent(tp, thflags, iptos); if (SEQ_GT(th->th_ack, tp->snd_una)) { /* * We advance snd_una for the * fast open case. If th_ack is * acknowledging data beyond * snd_una we can't just call * ack-processing since the * data stream in our send-map * will start at snd_una + 1 (one * beyond the SYN). If its just * equal we don't need to do that * and there is no send_map. */ tp->snd_una++; } /* * Received in SYN_SENT[*] state. Transitions: * SYN_SENT --> ESTABLISHED SYN_SENT* --> FIN_WAIT_1 */ tp->t_starttime = ticks; if (tp->t_flags & TF_NEEDFIN) { tcp_state_change(tp, TCPS_FIN_WAIT_1); tp->t_flags &= ~TF_NEEDFIN; thflags &= ~TH_SYN; } else { tcp_state_change(tp, TCPS_ESTABLISHED); TCP_PROBE5(connect__established, NULL, tp, mtod(m, const char *), tp, th); rack_cc_conn_init(tp); } } else { /* * Received initial SYN in SYN-SENT[*] state => simultaneous * open. If segment contains CC option and there is a * cached CC, apply TAO test. If it succeeds, connection is * * half-synchronized. Otherwise, do 3-way handshake: * SYN-SENT -> SYN-RECEIVED SYN-SENT* -> SYN-RECEIVED* If * there was no CC option, clear cached CC value. */ tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN | TF_SONOTCONN); tcp_state_change(tp, TCPS_SYN_RECEIVED); } /* * Advance th->th_seq to correspond to first data byte. If data, * trim to stay within window, dropping FIN if necessary. */ th->th_seq++; if (tlen > tp->rcv_wnd) { todrop = tlen - tp->rcv_wnd; m_adj(m, -todrop); tlen = tp->rcv_wnd; thflags &= ~TH_FIN; KMOD_TCPSTAT_INC(tcps_rcvpackafterwin); KMOD_TCPSTAT_ADD(tcps_rcvbyteafterwin, todrop); } tp->snd_wl1 = th->th_seq - 1; tp->rcv_up = th->th_seq; /* * Client side of transaction: already sent SYN and data. If the * remote host used T/TCP to validate the SYN, our data will be * ACK'd; if so, enter normal data segment processing in the middle * of step 5, ack processing. Otherwise, goto step 6. */ if (thflags & TH_ACK) { /* For syn-sent we need to possibly update the rtt */ if ((to->to_flags & TOF_TS) != 0 && to->to_tsecr) { uint32_t t, mcts; mcts = tcp_ts_getticks(); t = (mcts - to->to_tsecr) * HPTS_USEC_IN_MSEC; if (!tp->t_rttlow || tp->t_rttlow > t) tp->t_rttlow = t; rack_log_rtt_sample_calc(rack, t, (to->to_tsecr * 1000), (mcts * 1000), 4); tcp_rack_xmit_timer(rack, t + 1, 1, t, 0, NULL, 2); tcp_rack_xmit_timer_commit(rack, tp); } if (rack_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) return (ret_val); /* We may have changed to FIN_WAIT_1 above */ if (tp->t_state == TCPS_FIN_WAIT_1) { /* * In FIN_WAIT_1 STATE in addition to the processing * for the ESTABLISHED state if our FIN is now * acknowledged then enter FIN_WAIT_2. */ if (ourfinisacked) { /* * If we can't receive any more data, then * closing user can proceed. Starting the * timer is contrary to the specification, * but if we don't get a FIN we'll hang * forever. * * XXXjl: we should release the tp also, and * use a compressed state. */ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { soisdisconnected(so); tcp_timer_activate(tp, TT_2MSL, (tcp_fast_finwait2_recycle ? tcp_finwait2_timeout : TP_MAXIDLE(tp))); } tcp_state_change(tp, TCPS_FIN_WAIT_2); } } } return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCP is still * locked. */ static int rack_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { struct tcp_rack *rack; int32_t ret_val = 0; int32_t ourfinisacked = 0; ctf_calc_rwin(so, tp); if ((thflags & TH_ACK) && (SEQ_LEQ(th->th_ack, tp->snd_una) || SEQ_GT(th->th_ack, tp->snd_max))) { tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); ctf_do_dropwithreset(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } rack = (struct tcp_rack *)tp->t_fb_ptr; if (IS_FASTOPEN(tp->t_flags)) { /* * When a TFO connection is in SYN_RECEIVED, the * only valid packets are the initial SYN, a * retransmit/copy of the initial SYN (possibly with * a subset of the original data), a valid ACK, a * FIN, or a RST. */ if ((thflags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) { tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); ctf_do_dropwithreset(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } else if (thflags & TH_SYN) { /* non-initial SYN is ignored */ if ((rack->r_ctl.rc_hpts_flags & PACE_TMR_RXT) || (rack->r_ctl.rc_hpts_flags & PACE_TMR_TLP) || (rack->r_ctl.rc_hpts_flags & PACE_TMR_RACK)) { ctf_do_drop(m, NULL); return (0); } } else if (!(thflags & (TH_ACK | TH_FIN | TH_RST))) { ctf_do_drop(m, NULL); return (0); } } if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (__ctf_process_rst(m, th, so, tp, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)); /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } /* * In the SYN-RECEIVED state, validate that the packet belongs to * this connection before trimming the data to fit the receive * window. Check the sequence number versus IRS since we know the * sequence numbers haven't wrapped. This is a partial fix for the * "LAND" DoS attack. */ if (SEQ_LT(th->th_seq, tp->irs)) { tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); ctf_do_dropwithreset(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)) { return (ret_val); } /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = to->to_tsval; } tp->snd_wnd = tiwin; rack_validate_fo_sendwin_up(tp, rack); /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (IS_FASTOPEN(tp->t_flags)) { rack_cc_conn_init(tp); } return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } KMOD_TCPSTAT_INC(tcps_connects); if (tp->t_flags & TF_SONOTCONN) { tp->t_flags &= ~TF_SONOTCONN; soisconnected(so); } /* Do window scaling? */ if ((tp->t_flags & (TF_RCVD_SCALE | TF_REQ_SCALE)) == (TF_RCVD_SCALE | TF_REQ_SCALE)) { tp->rcv_scale = tp->request_r_scale; } /* * Make transitions: SYN-RECEIVED -> ESTABLISHED SYN-RECEIVED* -> * FIN-WAIT-1 */ tp->t_starttime = ticks; if (IS_FASTOPEN(tp->t_flags) && tp->t_tfo_pending) { tcp_fastopen_decrement_counter(tp->t_tfo_pending); tp->t_tfo_pending = NULL; } if (tp->t_flags & TF_NEEDFIN) { tcp_state_change(tp, TCPS_FIN_WAIT_1); tp->t_flags &= ~TF_NEEDFIN; } else { tcp_state_change(tp, TCPS_ESTABLISHED); TCP_PROBE5(accept__established, NULL, tp, mtod(m, const char *), tp, th); /* * TFO connections call cc_conn_init() during SYN * processing. Calling it again here for such connections * is not harmless as it would undo the snd_cwnd reduction * that occurs when a TFO SYN|ACK is retransmitted. */ if (!IS_FASTOPEN(tp->t_flags)) rack_cc_conn_init(tp); } /* * Account for the ACK of our SYN prior to * regular ACK processing below, except for * simultaneous SYN, which is handled later. */ if (SEQ_GT(th->th_ack, tp->snd_una) && !(tp->t_flags & TF_NEEDSYN)) tp->snd_una++; /* * If segment contains data or ACK, will call tcp_reass() later; if * not, do so now to pass queued data to user. */ if (tlen == 0 && (thflags & TH_FIN) == 0) { (void) tcp_reass(tp, (struct tcphdr *)0, NULL, 0, (struct mbuf *)0); if (tp->t_flags & TF_WAKESOR) { tp->t_flags &= ~TF_WAKESOR; /* NB: sorwakeup_locked() does an implicit unlock. */ sorwakeup_locked(so); } } tp->snd_wl1 = th->th_seq - 1; /* For syn-recv we need to possibly update the rtt */ if ((to->to_flags & TOF_TS) != 0 && to->to_tsecr) { uint32_t t, mcts; mcts = tcp_ts_getticks(); t = (mcts - to->to_tsecr) * HPTS_USEC_IN_MSEC; if (!tp->t_rttlow || tp->t_rttlow > t) tp->t_rttlow = t; rack_log_rtt_sample_calc(rack, t, (to->to_tsecr * 1000), (mcts * 1000), 5); tcp_rack_xmit_timer(rack, t + 1, 1, t, 0, NULL, 2); tcp_rack_xmit_timer_commit(rack, tp); } if (rack_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) { return (ret_val); } if (tp->t_state == TCPS_FIN_WAIT_1) { /* We could have went to FIN_WAIT_1 (or EST) above */ /* * In FIN_WAIT_1 STATE in addition to the processing for the * ESTABLISHED state if our FIN is now acknowledged then * enter FIN_WAIT_2. */ if (ourfinisacked) { /* * If we can't receive any more data, then closing * user can proceed. Starting the timer is contrary * to the specification, but if we don't get a FIN * we'll hang forever. * * XXXjl: we should release the tp also, and use a * compressed state. */ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { soisdisconnected(so); tcp_timer_activate(tp, TT_2MSL, (tcp_fast_finwait2_recycle ? tcp_finwait2_timeout : TP_MAXIDLE(tp))); } tcp_state_change(tp, TCPS_FIN_WAIT_2); } } return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCP is still * locked. */ static int rack_do_established(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t ret_val = 0; struct tcp_rack *rack; /* * Header prediction: check for the two common cases of a * uni-directional data xfer. If the packet has no control flags, * is in-sequence, the window didn't change and we're not * retransmitting, it's a candidate. If the length is zero and the * ack moved forward, we're the sender side of the xfer. Just free * the data acked & wake any higher level process that was blocked * waiting for space. If the length is non-zero and the ack didn't * move, we're the receiver side. If we're getting packets in-order * (the reassembly queue is empty), add the data toc The socket * buffer and note that we need a delayed ack. Make sure that the * hidden state-flags are also off. Since we check for * TCPS_ESTABLISHED first, it can only be TH_NEEDSYN. */ rack = (struct tcp_rack *)tp->t_fb_ptr; if (__predict_true(((to->to_flags & TOF_SACK) == 0)) && __predict_true((thflags & (TH_SYN | TH_FIN | TH_RST | TH_ACK)) == TH_ACK) && __predict_true(SEGQ_EMPTY(tp)) && __predict_true(th->th_seq == tp->rcv_nxt)) { if (tlen == 0) { if (rack_fastack(m, th, so, tp, to, drop_hdrlen, tlen, tiwin, nxt_pkt, rack->r_ctl.rc_rcvtime)) { return (0); } } else { if (rack_do_fastnewdata(m, th, so, tp, to, drop_hdrlen, tlen, tiwin, nxt_pkt, iptos)) { return (0); } } } ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (__ctf_process_rst(m, th, so, tp, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. */ if (thflags & TH_SYN) { ctf_challenge_ack(m, th, tp, iptos, &ret_val); return (ret_val); } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)) { return (ret_val); } /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = to->to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_flags & TF_NEEDSYN) { return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } else if (tp->t_flags & TF_ACKNOW) { ctf_do_dropafterack(m, tp, th, thflags, tlen, &ret_val); ((struct tcp_rack *)tp->t_fb_ptr)->r_wanted_output = 1; return (ret_val); } else { ctf_do_drop(m, NULL); return (0); } } /* * Ack processing. */ if (rack_process_ack(m, th, so, tp, to, tiwin, tlen, NULL, thflags, &ret_val)) { return (ret_val); } if (sbavail(&so->so_snd)) { if (ctf_progress_timeout_check(tp, true)) { rack_log_progress_event(rack, tp, tick, PROGRESS_DROP, __LINE__); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } } /* State changes only happen in rack_process_data() */ return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCP is still * locked. */ static int rack_do_close_wait(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t ret_val = 0; struct tcp_rack *rack; rack = (struct tcp_rack *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (__ctf_process_rst(m, th, so, tp, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. */ if (thflags & TH_SYN) { ctf_challenge_ack(m, th, tp, iptos, &ret_val); return (ret_val); } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)) { return (ret_val); } /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = to->to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_flags & TF_NEEDSYN) { return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } else if (tp->t_flags & TF_ACKNOW) { ctf_do_dropafterack(m, tp, th, thflags, tlen, &ret_val); ((struct tcp_rack *)tp->t_fb_ptr)->r_wanted_output = 1; return (ret_val); } else { ctf_do_drop(m, NULL); return (0); } } /* * Ack processing. */ if (rack_process_ack(m, th, so, tp, to, tiwin, tlen, NULL, thflags, &ret_val)) { return (ret_val); } if (sbavail(&so->so_snd)) { if (ctf_progress_timeout_check(tp, true)) { rack_log_progress_event((struct tcp_rack *)tp->t_fb_ptr, tp, tick, PROGRESS_DROP, __LINE__); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } } return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } static int rack_check_data_after_close(struct mbuf *m, struct tcpcb *tp, int32_t *tlen, struct tcphdr *th, struct socket *so) { struct tcp_rack *rack; rack = (struct tcp_rack *)tp->t_fb_ptr; if (rack->rc_allow_data_af_clo == 0) { close_now: tcp_log_end_status(tp, TCP_EI_STATUS_DATA_A_CLOSE); /* tcp_close will kill the inp pre-log the Reset */ tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST); tp = tcp_close(tp); KMOD_TCPSTAT_INC(tcps_rcvafterclose); ctf_do_dropwithreset(m, tp, th, BANDLIM_UNLIMITED, (*tlen)); return (1); } if (sbavail(&so->so_snd) == 0) goto close_now; /* Ok we allow data that is ignored and a followup reset */ tcp_log_end_status(tp, TCP_EI_STATUS_DATA_A_CLOSE); tp->rcv_nxt = th->th_seq + *tlen; tp->t_flags2 |= TF2_DROP_AF_DATA; rack->r_wanted_output = 1; *tlen = 0; return (0); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCP is still * locked. */ static int rack_do_fin_wait_1(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t ret_val = 0; int32_t ourfinisacked = 0; struct tcp_rack *rack; rack = (struct tcp_rack *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (__ctf_process_rst(m, th, so, tp, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. */ if (thflags & TH_SYN) { ctf_challenge_ack(m, th, tp, iptos, &ret_val); return (ret_val); } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)) { return (ret_val); } /* * If new data are received on a connection after the user processes * are gone, then RST the other end. */ if ((tp->t_flags & TF_CLOSED) && tlen && rack_check_data_after_close(m, tp, &tlen, th, so)) return (1); /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = to->to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_flags & TF_NEEDSYN) { return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } else if (tp->t_flags & TF_ACKNOW) { ctf_do_dropafterack(m, tp, th, thflags, tlen, &ret_val); ((struct tcp_rack *)tp->t_fb_ptr)->r_wanted_output = 1; return (ret_val); } else { ctf_do_drop(m, NULL); return (0); } } /* * Ack processing. */ if (rack_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) { return (ret_val); } if (ourfinisacked) { /* * If we can't receive any more data, then closing user can * proceed. Starting the timer is contrary to the * specification, but if we don't get a FIN we'll hang * forever. * * XXXjl: we should release the tp also, and use a * compressed state. */ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { soisdisconnected(so); tcp_timer_activate(tp, TT_2MSL, (tcp_fast_finwait2_recycle ? tcp_finwait2_timeout : TP_MAXIDLE(tp))); } tcp_state_change(tp, TCPS_FIN_WAIT_2); } if (sbavail(&so->so_snd)) { if (ctf_progress_timeout_check(tp, true)) { rack_log_progress_event((struct tcp_rack *)tp->t_fb_ptr, tp, tick, PROGRESS_DROP, __LINE__); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } } return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCP is still * locked. */ static int rack_do_closing(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t ret_val = 0; int32_t ourfinisacked = 0; struct tcp_rack *rack; rack = (struct tcp_rack *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (__ctf_process_rst(m, th, so, tp, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. */ if (thflags & TH_SYN) { ctf_challenge_ack(m, th, tp, iptos, &ret_val); return (ret_val); } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)) { return (ret_val); } /* * If new data are received on a connection after the user processes * are gone, then RST the other end. */ if ((tp->t_flags & TF_CLOSED) && tlen && rack_check_data_after_close(m, tp, &tlen, th, so)) return (1); /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = to->to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_flags & TF_NEEDSYN) { return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } else if (tp->t_flags & TF_ACKNOW) { ctf_do_dropafterack(m, tp, th, thflags, tlen, &ret_val); ((struct tcp_rack *)tp->t_fb_ptr)->r_wanted_output = 1; return (ret_val); } else { ctf_do_drop(m, NULL); return (0); } } /* * Ack processing. */ if (rack_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) { return (ret_val); } if (ourfinisacked) { tcp_twstart(tp); m_freem(m); return (1); } if (sbavail(&so->so_snd)) { if (ctf_progress_timeout_check(tp, true)) { rack_log_progress_event((struct tcp_rack *)tp->t_fb_ptr, tp, tick, PROGRESS_DROP, __LINE__); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } } return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCP is still * locked. */ static int rack_do_lastack(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t ret_val = 0; int32_t ourfinisacked = 0; struct tcp_rack *rack; rack = (struct tcp_rack *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (__ctf_process_rst(m, th, so, tp, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. */ if (thflags & TH_SYN) { ctf_challenge_ack(m, th, tp, iptos, &ret_val); return (ret_val); } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)) { return (ret_val); } /* * If new data are received on a connection after the user processes * are gone, then RST the other end. */ if ((tp->t_flags & TF_CLOSED) && tlen && rack_check_data_after_close(m, tp, &tlen, th, so)) return (1); /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = to->to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_flags & TF_NEEDSYN) { return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } else if (tp->t_flags & TF_ACKNOW) { ctf_do_dropafterack(m, tp, th, thflags, tlen, &ret_val); ((struct tcp_rack *)tp->t_fb_ptr)->r_wanted_output = 1; return (ret_val); } else { ctf_do_drop(m, NULL); return (0); } } /* * case TCPS_LAST_ACK: Ack processing. */ if (rack_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) { return (ret_val); } if (ourfinisacked) { tp = tcp_close(tp); ctf_do_drop(m, tp); return (1); } if (sbavail(&so->so_snd)) { if (ctf_progress_timeout_check(tp, true)) { rack_log_progress_event((struct tcp_rack *)tp->t_fb_ptr, tp, tick, PROGRESS_DROP, __LINE__); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } } return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } /* * Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCP is still * locked. */ static int rack_do_fin_wait_2(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos) { int32_t ret_val = 0; int32_t ourfinisacked = 0; struct tcp_rack *rack; rack = (struct tcp_rack *)tp->t_fb_ptr; ctf_calc_rwin(so, tp); /* Reset receive buffer auto scaling when not in bulk receive mode. */ if ((thflags & TH_RST) || (tp->t_fin_is_rst && (thflags & TH_FIN))) return (__ctf_process_rst(m, th, so, tp, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)); /* * RFC5961 Section 4.2 Send challenge ACK for any SYN in * synchronized state. */ if (thflags & TH_SYN) { ctf_challenge_ack(m, th, tp, iptos, &ret_val); return (ret_val); } /* * RFC 1323 PAWS: If we have a timestamp reply on this segment and * it's less than ts_recent, drop it. */ if ((to->to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to->to_tsval, tp->ts_recent)) { if (ctf_ts_check(m, th, tp, tlen, thflags, &ret_val)) return (ret_val); } if (_ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt)) { return (ret_val); } /* * If new data are received on a connection after the user processes * are gone, then RST the other end. */ if ((tp->t_flags & TF_CLOSED) && tlen && rack_check_data_after_close(m, tp, &tlen, th, so)) return (1); /* * If last ACK falls within this segment's sequence numbers, record * its timestamp. NOTE: 1) That the test incorporates suggestions * from the latest proposal of the tcplw@cray.com list (Braden * 1993/04/26). 2) That updating only on newer timestamps interferes * with our earlier PAWS tests, so this check should be solely * predicated on the sequence space of this segment. 3) That we * modify the segment boundary check to be Last.ACK.Sent <= SEG.SEQ * + SEG.Len instead of RFC1323's Last.ACK.Sent < SEG.SEQ + * SEG.Len, This modified check allows us to overcome RFC1323's * limitations as described in Stevens TCP/IP Illustrated Vol. 2 * p.869. In such cases, we can still calculate the RTT correctly * when RCV.NXT == Last.ACK.Sent. */ if ((to->to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN | TH_FIN)) != 0))) { tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = to->to_tsval; } /* * If the ACK bit is off: if in SYN-RECEIVED state or SENDSYN flag * is on (half-synchronized state), then queue data for later * processing; else drop segment and return. */ if ((thflags & TH_ACK) == 0) { if (tp->t_flags & TF_NEEDSYN) { return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } else if (tp->t_flags & TF_ACKNOW) { ctf_do_dropafterack(m, tp, th, thflags, tlen, &ret_val); ((struct tcp_rack *)tp->t_fb_ptr)->r_wanted_output = 1; return (ret_val); } else { ctf_do_drop(m, NULL); return (0); } } /* * Ack processing. */ if (rack_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) { return (ret_val); } if (sbavail(&so->so_snd)) { if (ctf_progress_timeout_check(tp, true)) { rack_log_progress_event((struct tcp_rack *)tp->t_fb_ptr, tp, tick, PROGRESS_DROP, __LINE__); ctf_do_dropwithreset_conn(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return (1); } } return (rack_process_data(m, th, so, tp, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt)); } static void inline rack_clear_rate_sample(struct tcp_rack *rack) { rack->r_ctl.rack_rs.rs_flags = RACK_RTT_EMPTY; rack->r_ctl.rack_rs.rs_rtt_cnt = 0; rack->r_ctl.rack_rs.rs_rtt_tot = 0; } static void rack_set_pace_segments(struct tcpcb *tp, struct tcp_rack *rack, uint32_t line, uint64_t *fill_override) { uint64_t bw_est, rate_wanted; int chged = 0; uint32_t user_max, orig_min, orig_max; orig_min = rack->r_ctl.rc_pace_min_segs; orig_max = rack->r_ctl.rc_pace_max_segs; user_max = ctf_fixed_maxseg(tp) * rack->rc_user_set_max_segs; if (ctf_fixed_maxseg(tp) != rack->r_ctl.rc_pace_min_segs) chged = 1; rack->r_ctl.rc_pace_min_segs = ctf_fixed_maxseg(tp); if (rack->use_fixed_rate || rack->rc_force_max_seg) { if (user_max != rack->r_ctl.rc_pace_max_segs) chged = 1; } if (rack->rc_force_max_seg) { rack->r_ctl.rc_pace_max_segs = user_max; } else if (rack->use_fixed_rate) { bw_est = rack_get_bw(rack); if ((rack->r_ctl.crte == NULL) || (bw_est != rack->r_ctl.crte->rate)) { rack->r_ctl.rc_pace_max_segs = user_max; } else { /* We are pacing right at the hardware rate */ uint32_t segsiz; segsiz = min(ctf_fixed_maxseg(tp), rack->r_ctl.rc_pace_min_segs); rack->r_ctl.rc_pace_max_segs = tcp_get_pacing_burst_size( tp, bw_est, segsiz, 0, rack->r_ctl.crte, NULL); } } else if (rack->rc_always_pace) { if (rack->r_ctl.gp_bw || #ifdef NETFLIX_PEAKRATE rack->rc_tp->t_maxpeakrate || #endif rack->r_ctl.init_rate) { /* We have a rate of some sort set */ uint32_t orig; bw_est = rack_get_bw(rack); orig = rack->r_ctl.rc_pace_max_segs; if (fill_override) rate_wanted = *fill_override; else rate_wanted = rack_get_output_bw(rack, bw_est, NULL, NULL); if (rate_wanted) { /* We have something */ rack->r_ctl.rc_pace_max_segs = rack_get_pacing_len(rack, rate_wanted, ctf_fixed_maxseg(rack->rc_tp)); } else rack->r_ctl.rc_pace_max_segs = rack->r_ctl.rc_pace_min_segs; if (orig != rack->r_ctl.rc_pace_max_segs) chged = 1; } else if ((rack->r_ctl.gp_bw == 0) && (rack->r_ctl.rc_pace_max_segs == 0)) { /* * If we have nothing limit us to bursting * out IW sized pieces. */ chged = 1; rack->r_ctl.rc_pace_max_segs = rc_init_window(rack); } } if (rack->r_ctl.rc_pace_max_segs > PACE_MAX_IP_BYTES) { chged = 1; rack->r_ctl.rc_pace_max_segs = PACE_MAX_IP_BYTES; } if (chged) rack_log_type_pacing_sizes(tp, rack, orig_min, orig_max, line, 2); } static void rack_init_fsb_block(struct tcpcb *tp, struct tcp_rack *rack) { #ifdef INET6 struct ip6_hdr *ip6 = NULL; #endif #ifdef INET struct ip *ip = NULL; #endif struct udphdr *udp = NULL; /* Ok lets fill in the fast block, it can only be used with no IP options! */ #ifdef INET6 if (rack->r_is_v6) { rack->r_ctl.fsb.tcp_ip_hdr_len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr); ip6 = (struct ip6_hdr *)rack->r_ctl.fsb.tcp_ip_hdr; if (tp->t_port) { rack->r_ctl.fsb.tcp_ip_hdr_len += sizeof(struct udphdr); udp = (struct udphdr *)((caddr_t)ip6 + sizeof(struct ip6_hdr)); udp->uh_sport = htons(V_tcp_udp_tunneling_port); udp->uh_dport = tp->t_port; rack->r_ctl.fsb.udp = udp; rack->r_ctl.fsb.th = (struct tcphdr *)(udp + 1); } else { rack->r_ctl.fsb.th = (struct tcphdr *)(ip6 + 1); rack->r_ctl.fsb.udp = NULL; } tcpip_fillheaders(rack->rc_inp, tp->t_port, ip6, rack->r_ctl.fsb.th); } else #endif /* INET6 */ { rack->r_ctl.fsb.tcp_ip_hdr_len = sizeof(struct tcpiphdr); ip = (struct ip *)rack->r_ctl.fsb.tcp_ip_hdr; if (tp->t_port) { rack->r_ctl.fsb.tcp_ip_hdr_len += sizeof(struct udphdr); udp = (struct udphdr *)((caddr_t)ip + sizeof(struct ip)); udp->uh_sport = htons(V_tcp_udp_tunneling_port); udp->uh_dport = tp->t_port; rack->r_ctl.fsb.udp = udp; rack->r_ctl.fsb.th = (struct tcphdr *)(udp + 1); } else { rack->r_ctl.fsb.udp = NULL; rack->r_ctl.fsb.th = (struct tcphdr *)(ip + 1); } tcpip_fillheaders(rack->rc_inp, tp->t_port, ip, rack->r_ctl.fsb.th); } rack->r_fsb_inited = 1; } static int rack_init_fsb(struct tcpcb *tp, struct tcp_rack *rack) { /* * Allocate the larger of spaces V6 if available else just * V4 and include udphdr (overbook) */ #ifdef INET6 rack->r_ctl.fsb.tcp_ip_hdr_len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr) + sizeof(struct udphdr); #else rack->r_ctl.fsb.tcp_ip_hdr_len = sizeof(struct tcpiphdr) + sizeof(struct udphdr); #endif rack->r_ctl.fsb.tcp_ip_hdr = malloc(rack->r_ctl.fsb.tcp_ip_hdr_len, M_TCPFSB, M_NOWAIT|M_ZERO); if (rack->r_ctl.fsb.tcp_ip_hdr == NULL) { return (ENOMEM); } rack->r_fsb_inited = 0; return (0); } static int rack_init(struct tcpcb *tp) { struct inpcb *inp = tptoinpcb(tp); struct tcp_rack *rack = NULL; #ifdef INVARIANTS struct rack_sendmap *insret; #endif uint32_t iwin, snt, us_cts; int err; tp->t_fb_ptr = uma_zalloc(rack_pcb_zone, M_NOWAIT); if (tp->t_fb_ptr == NULL) { /* * We need to allocate memory but cant. The INP and INP_INFO * locks and they are recursive (happens during setup. So a * scheme to drop the locks fails :( * */ return (ENOMEM); } memset(tp->t_fb_ptr, 0, sizeof(struct tcp_rack)); rack = (struct tcp_rack *)tp->t_fb_ptr; RB_INIT(&rack->r_ctl.rc_mtree); TAILQ_INIT(&rack->r_ctl.rc_free); TAILQ_INIT(&rack->r_ctl.rc_tmap); rack->rc_tp = tp; rack->rc_inp = inp; /* Set the flag */ rack->r_is_v6 = (inp->inp_vflag & INP_IPV6) != 0; /* Probably not needed but lets be sure */ rack_clear_rate_sample(rack); /* * Save off the default values, socket options will poke * at these if pacing is not on or we have not yet * reached where pacing is on (gp_ready/fixed enabled). * When they get set into the CC module (when gp_ready * is enabled or we enable fixed) then we will set these * values into the CC and place in here the old values * so we have a restoral. Then we will set the flag * rc_pacing_cc_set. That way whenever we turn off pacing * or switch off this stack, we will know to go restore * the saved values. */ rack->r_ctl.rc_saved_beta.beta = V_newreno_beta_ecn; rack->r_ctl.rc_saved_beta.beta_ecn = V_newreno_beta_ecn; /* We want abe like behavior as well */ rack->r_ctl.rc_saved_beta.newreno_flags |= CC_NEWRENO_BETA_ECN_ENABLED; rack->r_ctl.rc_reorder_fade = rack_reorder_fade; rack->rc_allow_data_af_clo = rack_ignore_data_after_close; rack->r_ctl.rc_tlp_threshold = rack_tlp_thresh; rack->r_ctl.roundends = tp->snd_max; if (use_rack_rr) rack->use_rack_rr = 1; if (V_tcp_delack_enabled) tp->t_delayed_ack = 1; else tp->t_delayed_ack = 0; #ifdef TCP_ACCOUNTING if (rack_tcp_accounting) { tp->t_flags2 |= TF2_TCP_ACCOUNTING; } #endif if (rack_enable_shared_cwnd) rack->rack_enable_scwnd = 1; rack->rc_user_set_max_segs = rack_hptsi_segments; rack->rc_force_max_seg = 0; if (rack_use_imac_dack) rack->rc_dack_mode = 1; TAILQ_INIT(&rack->r_ctl.opt_list); rack->r_ctl.rc_reorder_shift = rack_reorder_thresh; rack->r_ctl.rc_pkt_delay = rack_pkt_delay; rack->r_ctl.rc_tlp_cwnd_reduce = rack_lower_cwnd_at_tlp; rack->r_ctl.rc_lowest_us_rtt = 0xffffffff; rack->r_ctl.rc_highest_us_rtt = 0; rack->r_ctl.bw_rate_cap = rack_bw_rate_cap; rack->r_ctl.timer_slop = TICKS_2_USEC(tcp_rexmit_slop); if (rack_use_cmp_acks) rack->r_use_cmp_ack = 1; if (rack_disable_prr) rack->rack_no_prr = 1; if (rack_gp_no_rec_chg) rack->rc_gp_no_rec_chg = 1; if (rack_pace_every_seg && tcp_can_enable_pacing()) { rack->rc_always_pace = 1; if (rack->use_fixed_rate || rack->gp_ready) rack_set_cc_pacing(rack); } else rack->rc_always_pace = 0; if (rack_enable_mqueue_for_nonpaced || rack->r_use_cmp_ack) rack->r_mbuf_queue = 1; else rack->r_mbuf_queue = 0; if (rack->r_mbuf_queue || rack->rc_always_pace || rack->r_use_cmp_ack) inp->inp_flags2 |= INP_SUPPORTS_MBUFQ; else inp->inp_flags2 &= ~INP_SUPPORTS_MBUFQ; rack_set_pace_segments(tp, rack, __LINE__, NULL); if (rack_limits_scwnd) rack->r_limit_scw = 1; else rack->r_limit_scw = 0; rack->rc_labc = V_tcp_abc_l_var; rack->r_ctl.rc_high_rwnd = tp->snd_wnd; rack->r_ctl.cwnd_to_use = tp->snd_cwnd; rack->r_ctl.rc_rate_sample_method = rack_rate_sample_method; rack->rack_tlp_threshold_use = rack_tlp_threshold_use; rack->r_ctl.rc_prr_sendalot = rack_send_a_lot_in_prr; rack->r_ctl.rc_min_to = rack_min_to; microuptime(&rack->r_ctl.act_rcv_time); rack->r_ctl.rc_last_time_decay = rack->r_ctl.act_rcv_time; rack->rc_init_win = rack_default_init_window; rack->r_ctl.rack_per_of_gp_ss = rack_per_of_gp_ss; if (rack_hw_up_only) rack->r_up_only = 1; if (rack_do_dyn_mul) { /* When dynamic adjustment is on CA needs to start at 100% */ rack->rc_gp_dyn_mul = 1; if (rack_do_dyn_mul >= 100) rack->r_ctl.rack_per_of_gp_ca = rack_do_dyn_mul; } else rack->r_ctl.rack_per_of_gp_ca = rack_per_of_gp_ca; rack->r_ctl.rack_per_of_gp_rec = rack_per_of_gp_rec; rack->r_ctl.rack_per_of_gp_probertt = rack_per_of_gp_probertt; rack->r_ctl.rc_tlp_rxt_last_time = tcp_tv_to_mssectick(&rack->r_ctl.act_rcv_time); setup_time_filter_small(&rack->r_ctl.rc_gp_min_rtt, FILTER_TYPE_MIN, rack_probertt_filter_life); us_cts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); rack->r_ctl.rc_lower_rtt_us_cts = us_cts; rack->r_ctl.rc_time_of_last_probertt = us_cts; rack->r_ctl.challenge_ack_ts = tcp_ts_getticks(); rack->r_ctl.rc_time_probertt_starts = 0; if (rack_dsack_std_based & 0x1) { /* Basically this means all rack timers are at least (srtt + 1/4 srtt) */ rack->rc_rack_tmr_std_based = 1; } if (rack_dsack_std_based & 0x2) { /* Basically this means rack timers are extended based on dsack by up to (2 * srtt) */ rack->rc_rack_use_dsack = 1; } /* We require at least one measurement, even if the sysctl is 0 */ if (rack_req_measurements) rack->r_ctl.req_measurements = rack_req_measurements; else rack->r_ctl.req_measurements = 1; if (rack_enable_hw_pacing) rack->rack_hdw_pace_ena = 1; if (rack_hw_rate_caps) rack->r_rack_hw_rate_caps = 1; /* Do we force on detection? */ #ifdef NETFLIX_EXP_DETECTION if (tcp_force_detection) rack->do_detection = 1; else #endif rack->do_detection = 0; if (rack_non_rxt_use_cr) rack->rack_rec_nonrxt_use_cr = 1; err = rack_init_fsb(tp, rack); if (err) { uma_zfree(rack_pcb_zone, tp->t_fb_ptr); tp->t_fb_ptr = NULL; return (err); } if (tp->snd_una != tp->snd_max) { /* Create a send map for the current outstanding data */ struct rack_sendmap *rsm; rsm = rack_alloc(rack); if (rsm == NULL) { uma_zfree(rack_pcb_zone, tp->t_fb_ptr); tp->t_fb_ptr = NULL; return (ENOMEM); } rsm->r_no_rtt_allowed = 1; rsm->r_tim_lastsent[0] = rack_to_usec_ts(&rack->r_ctl.act_rcv_time); rsm->r_rtr_cnt = 1; rsm->r_rtr_bytes = 0; if (tp->t_flags & TF_SENTFIN) rsm->r_flags |= RACK_HAS_FIN; if ((tp->snd_una == tp->iss) && !TCPS_HAVEESTABLISHED(tp->t_state)) rsm->r_flags |= RACK_HAS_SYN; rsm->r_start = tp->snd_una; rsm->r_end = tp->snd_max; rsm->r_dupack = 0; if (rack->rc_inp->inp_socket->so_snd.sb_mb != NULL) { rsm->m = sbsndmbuf(&rack->rc_inp->inp_socket->so_snd, 0, &rsm->soff); if (rsm->m) rsm->orig_m_len = rsm->m->m_len; else rsm->orig_m_len = 0; } else { /* * This can happen if we have a stand-alone FIN or * SYN. */ rsm->m = NULL; rsm->orig_m_len = 0; rsm->soff = 0; } #ifndef INVARIANTS (void)RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); #else insret = RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); if (insret != NULL) { panic("Insert in rb tree fails ret:%p rack:%p rsm:%p", insret, rack, rsm); } #endif TAILQ_INSERT_TAIL(&rack->r_ctl.rc_tmap, rsm, r_tnext); rsm->r_in_tmap = 1; } /* * Timers in Rack are kept in microseconds so lets * convert any initial incoming variables * from ticks into usecs. Note that we * also change the values of t_srtt and t_rttvar, if * they are non-zero. They are kept with a 5 * bit decimal so we have to carefully convert * these to get the full precision. */ rack_convert_rtts(tp); tp->t_rttlow = TICKS_2_USEC(tp->t_rttlow); if (rack_do_hystart) { tp->t_ccv.flags |= CCF_HYSTART_ALLOWED; if (rack_do_hystart > 1) tp->t_ccv.flags |= CCF_HYSTART_CAN_SH_CWND; if (rack_do_hystart > 2) tp->t_ccv.flags |= CCF_HYSTART_CONS_SSTH; } if (rack_def_profile) rack_set_profile(rack, rack_def_profile); /* Cancel the GP measurement in progress */ tp->t_flags &= ~TF_GPUTINPROG; if (SEQ_GT(tp->snd_max, tp->iss)) snt = tp->snd_max - tp->iss; else snt = 0; iwin = rc_init_window(rack); if (snt < iwin) { /* We are not past the initial window * so we need to make sure cwnd is * correct. */ if (tp->snd_cwnd < iwin) tp->snd_cwnd = iwin; /* * If we are within the initial window * we want ssthresh to be unlimited. Setting * it to the rwnd (which the default stack does * and older racks) is not really a good idea * since we want to be in SS and grow both the * cwnd and the rwnd (via dynamic rwnd growth). If * we set it to the rwnd then as the peer grows its * rwnd we will be stuck in CA and never hit SS. * * Its far better to raise it up high (this takes the * risk that there as been a loss already, probably * we should have an indicator in all stacks of loss * but we don't), but considering the normal use this * is a risk worth taking. The consequences of not * hitting SS are far worse than going one more time * into it early on (before we have sent even a IW). * It is highly unlikely that we will have had a loss * before getting the IW out. */ tp->snd_ssthresh = 0xffffffff; } rack_stop_all_timers(tp); /* Lets setup the fsb block */ rack_start_hpts_timer(rack, tp, tcp_get_usecs(NULL), 0, 0, 0); rack_log_rtt_shrinks(rack, us_cts, tp->t_rxtcur, __LINE__, RACK_RTTS_INIT); return (0); } static int rack_handoff_ok(struct tcpcb *tp) { if ((tp->t_state == TCPS_CLOSED) || (tp->t_state == TCPS_LISTEN)) { /* Sure no problem though it may not stick */ return (0); } if ((tp->t_state == TCPS_SYN_SENT) || (tp->t_state == TCPS_SYN_RECEIVED)) { /* * We really don't know if you support sack, * you have to get to ESTAB or beyond to tell. */ return (EAGAIN); } if ((tp->t_flags & TF_SENTFIN) && ((tp->snd_max - tp->snd_una) > 1)) { /* * Rack will only send a FIN after all data is acknowledged. * So in this case we have more data outstanding. We can't * switch stacks until either all data and only the FIN * is left (in which case rack_init() now knows how * to deal with that) all is acknowledged and we * are only left with incoming data, though why you * would want to switch to rack after all data is acknowledged * I have no idea (rrs)! */ return (EAGAIN); } if ((tp->t_flags & TF_SACK_PERMIT) || rack_sack_not_required){ return (0); } /* * If we reach here we don't do SACK on this connection so we can * never do rack. */ return (EINVAL); } static void rack_fini(struct tcpcb *tp, int32_t tcb_is_purged) { struct inpcb *inp = tptoinpcb(tp); if (tp->t_fb_ptr) { struct tcp_rack *rack; struct rack_sendmap *rsm, *nrsm; #ifdef INVARIANTS struct rack_sendmap *rm; #endif rack = (struct tcp_rack *)tp->t_fb_ptr; if (tp->t_in_pkt) { /* * It is unsafe to process the packets since a * reset may be lurking in them (its rare but it * can occur). If we were to find a RST, then we * would end up dropping the connection and the * INP lock, so when we return the caller (tcp_usrreq) * will blow up when it trys to unlock the inp. */ struct mbuf *save, *m; m = tp->t_in_pkt; tp->t_in_pkt = NULL; tp->t_tail_pkt = NULL; while (m) { save = m->m_nextpkt; m->m_nextpkt = NULL; m_freem(m); m = save; } } tp->t_flags &= ~TF_FORCEDATA; #ifdef NETFLIX_SHARED_CWND if (rack->r_ctl.rc_scw) { uint32_t limit; if (rack->r_limit_scw) limit = max(1, rack->r_ctl.rc_lowest_us_rtt); else limit = 0; tcp_shared_cwnd_free_full(tp, rack->r_ctl.rc_scw, rack->r_ctl.rc_scw_index, limit); rack->r_ctl.rc_scw = NULL; } #endif if (rack->r_ctl.fsb.tcp_ip_hdr) { free(rack->r_ctl.fsb.tcp_ip_hdr, M_TCPFSB); rack->r_ctl.fsb.tcp_ip_hdr = NULL; rack->r_ctl.fsb.th = NULL; } /* Convert back to ticks, with */ if (tp->t_srtt > 1) { uint32_t val, frac; val = USEC_2_TICKS(tp->t_srtt); frac = tp->t_srtt % (HPTS_USEC_IN_SEC / hz); tp->t_srtt = val << TCP_RTT_SHIFT; /* * frac is the fractional part here is left * over from converting to hz and shifting. * We need to convert this to the 5 bit * remainder. */ if (frac) { if (hz == 1000) { frac = (((uint64_t)frac * (uint64_t)TCP_RTT_SCALE) / (uint64_t)HPTS_USEC_IN_MSEC); } else { frac = (((uint64_t)frac * (uint64_t)(hz) * (uint64_t)TCP_RTT_SCALE) /(uint64_t)HPTS_USEC_IN_SEC); } tp->t_srtt += frac; } } if (tp->t_rttvar) { uint32_t val, frac; val = USEC_2_TICKS(tp->t_rttvar); frac = tp->t_srtt % (HPTS_USEC_IN_SEC / hz); tp->t_rttvar = val << TCP_RTTVAR_SHIFT; /* * frac is the fractional part here is left * over from converting to hz and shifting. * We need to convert this to the 5 bit * remainder. */ if (frac) { if (hz == 1000) { frac = (((uint64_t)frac * (uint64_t)TCP_RTT_SCALE) / (uint64_t)HPTS_USEC_IN_MSEC); } else { frac = (((uint64_t)frac * (uint64_t)(hz) * (uint64_t)TCP_RTT_SCALE) /(uint64_t)HPTS_USEC_IN_SEC); } tp->t_rttvar += frac; } } tp->t_rxtcur = USEC_2_TICKS(tp->t_rxtcur); tp->t_rttlow = USEC_2_TICKS(tp->t_rttlow); if (rack->rc_always_pace) { tcp_decrement_paced_conn(); rack_undo_cc_pacing(rack); rack->rc_always_pace = 0; } /* Clean up any options if they were not applied */ while (!TAILQ_EMPTY(&rack->r_ctl.opt_list)) { struct deferred_opt_list *dol; dol = TAILQ_FIRST(&rack->r_ctl.opt_list); TAILQ_REMOVE(&rack->r_ctl.opt_list, dol, next); free(dol, M_TCPDO); } /* rack does not use force data but other stacks may clear it */ if (rack->r_ctl.crte != NULL) { tcp_rel_pacing_rate(rack->r_ctl.crte, tp); rack->rack_hdrw_pacing = 0; rack->r_ctl.crte = NULL; } #ifdef TCP_BLACKBOX tcp_log_flowend(tp); #endif RB_FOREACH_SAFE(rsm, rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm) { #ifndef INVARIANTS (void)RB_REMOVE(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); #else rm = RB_REMOVE(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rsm); if (rm != rsm) { panic("At fini, rack:%p rsm:%p rm:%p", rack, rsm, rm); } #endif uma_zfree(rack_zone, rsm); } rsm = TAILQ_FIRST(&rack->r_ctl.rc_free); while (rsm) { TAILQ_REMOVE(&rack->r_ctl.rc_free, rsm, r_tnext); uma_zfree(rack_zone, rsm); rsm = TAILQ_FIRST(&rack->r_ctl.rc_free); } rack->rc_free_cnt = 0; uma_zfree(rack_pcb_zone, tp->t_fb_ptr); tp->t_fb_ptr = NULL; } inp->inp_flags2 &= ~INP_SUPPORTS_MBUFQ; inp->inp_flags2 &= ~INP_MBUF_QUEUE_READY; inp->inp_flags2 &= ~INP_DONT_SACK_QUEUE; inp->inp_flags2 &= ~INP_MBUF_ACKCMP; /* Cancel the GP measurement in progress */ tp->t_flags &= ~TF_GPUTINPROG; inp->inp_flags2 &= ~INP_MBUF_L_ACKS; /* Make sure snd_nxt is correctly set */ tp->snd_nxt = tp->snd_max; } static void rack_set_state(struct tcpcb *tp, struct tcp_rack *rack) { if ((rack->r_state == TCPS_CLOSED) && (tp->t_state != TCPS_CLOSED)) { rack->r_is_v6 = (tptoinpcb(tp)->inp_vflag & INP_IPV6) != 0; } switch (tp->t_state) { case TCPS_SYN_SENT: rack->r_state = TCPS_SYN_SENT; rack->r_substate = rack_do_syn_sent; break; case TCPS_SYN_RECEIVED: rack->r_state = TCPS_SYN_RECEIVED; rack->r_substate = rack_do_syn_recv; break; case TCPS_ESTABLISHED: rack_set_pace_segments(tp, rack, __LINE__, NULL); rack->r_state = TCPS_ESTABLISHED; rack->r_substate = rack_do_established; break; case TCPS_CLOSE_WAIT: rack_set_pace_segments(tp, rack, __LINE__, NULL); rack->r_state = TCPS_CLOSE_WAIT; rack->r_substate = rack_do_close_wait; break; case TCPS_FIN_WAIT_1: rack_set_pace_segments(tp, rack, __LINE__, NULL); rack->r_state = TCPS_FIN_WAIT_1; rack->r_substate = rack_do_fin_wait_1; break; case TCPS_CLOSING: rack_set_pace_segments(tp, rack, __LINE__, NULL); rack->r_state = TCPS_CLOSING; rack->r_substate = rack_do_closing; break; case TCPS_LAST_ACK: rack_set_pace_segments(tp, rack, __LINE__, NULL); rack->r_state = TCPS_LAST_ACK; rack->r_substate = rack_do_lastack; break; case TCPS_FIN_WAIT_2: rack_set_pace_segments(tp, rack, __LINE__, NULL); rack->r_state = TCPS_FIN_WAIT_2; rack->r_substate = rack_do_fin_wait_2; break; case TCPS_LISTEN: case TCPS_CLOSED: case TCPS_TIME_WAIT: default: break; }; if (rack->r_use_cmp_ack && TCPS_HAVEESTABLISHED(tp->t_state)) rack->rc_inp->inp_flags2 |= INP_MBUF_ACKCMP; } static void rack_timer_audit(struct tcpcb *tp, struct tcp_rack *rack, struct sockbuf *sb) { /* * We received an ack, and then did not * call send or were bounced out due to the * hpts was running. Now a timer is up as well, is * it the right timer? */ struct rack_sendmap *rsm; int tmr_up; tmr_up = rack->r_ctl.rc_hpts_flags & PACE_TMR_MASK; if (rack->rc_in_persist && (tmr_up == PACE_TMR_PERSIT)) return; rsm = TAILQ_FIRST(&rack->r_ctl.rc_tmap); if (((rsm == NULL) || (tp->t_state < TCPS_ESTABLISHED)) && (tmr_up == PACE_TMR_RXT)) { /* Should be an RXT */ return; } if (rsm == NULL) { /* Nothing outstanding? */ if (tp->t_flags & TF_DELACK) { if (tmr_up == PACE_TMR_DELACK) /* We are supposed to have delayed ack up and we do */ return; } else if (sbavail(&tptosocket(tp)->so_snd) && (tmr_up == PACE_TMR_RXT)) { /* * if we hit enobufs then we would expect the possibility * of nothing outstanding and the RXT up (and the hptsi timer). */ return; } else if (((V_tcp_always_keepalive || rack->rc_inp->inp_socket->so_options & SO_KEEPALIVE) && (tp->t_state <= TCPS_CLOSING)) && (tmr_up == PACE_TMR_KEEP) && (tp->snd_max == tp->snd_una)) { /* We should have keep alive up and we do */ return; } } if (SEQ_GT(tp->snd_max, tp->snd_una) && ((tmr_up == PACE_TMR_TLP) || (tmr_up == PACE_TMR_RACK) || (tmr_up == PACE_TMR_RXT))) { /* * Either a Rack, TLP or RXT is fine if we * have outstanding data. */ return; } else if (tmr_up == PACE_TMR_DELACK) { /* * If the delayed ack was going to go off * before the rtx/tlp/rack timer were going to * expire, then that would be the timer in control. * Note we don't check the time here trusting the * code is correct. */ return; } /* * Ok the timer originally started is not what we want now. * We will force the hpts to be stopped if any, and restart * with the slot set to what was in the saved slot. */ if (tcp_in_hpts(rack->rc_inp)) { if (rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) { uint32_t us_cts; us_cts = tcp_get_usecs(NULL); if (TSTMP_GT(rack->r_ctl.rc_last_output_to, us_cts)) { rack->r_early = 1; rack->r_ctl.rc_agg_early += (rack->r_ctl.rc_last_output_to - us_cts); } rack->r_ctl.rc_hpts_flags &= ~PACE_PKT_OUTPUT; } tcp_hpts_remove(rack->rc_inp); } rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); rack_start_hpts_timer(rack, tp, tcp_get_usecs(NULL), 0, 0, 0); } static void rack_do_win_updates(struct tcpcb *tp, struct tcp_rack *rack, uint32_t tiwin, uint32_t seq, uint32_t ack, uint32_t cts, uint32_t high_seq) { if ((SEQ_LT(tp->snd_wl1, seq) || (tp->snd_wl1 == seq && (SEQ_LT(tp->snd_wl2, ack) || (tp->snd_wl2 == ack && tiwin > tp->snd_wnd))))) { /* keep track of pure window updates */ if ((tp->snd_wl2 == ack) && (tiwin > tp->snd_wnd)) KMOD_TCPSTAT_INC(tcps_rcvwinupd); tp->snd_wnd = tiwin; rack_validate_fo_sendwin_up(tp, rack); tp->snd_wl1 = seq; tp->snd_wl2 = ack; if (tp->snd_wnd > tp->max_sndwnd) tp->max_sndwnd = tp->snd_wnd; rack->r_wanted_output = 1; } else if ((tp->snd_wl2 == ack) && (tiwin < tp->snd_wnd)) { tp->snd_wnd = tiwin; rack_validate_fo_sendwin_up(tp, rack); tp->snd_wl1 = seq; tp->snd_wl2 = ack; } else { /* Not a valid win update */ return; } /* Do we exit persists? */ if ((rack->rc_in_persist != 0) && (tp->snd_wnd >= min((rack->r_ctl.rc_high_rwnd/2), rack->r_ctl.rc_pace_min_segs))) { rack_exit_persist(tp, rack, cts); } /* Do we enter persists? */ if ((rack->rc_in_persist == 0) && (tp->snd_wnd < min((rack->r_ctl.rc_high_rwnd/2), rack->r_ctl.rc_pace_min_segs)) && TCPS_HAVEESTABLISHED(tp->t_state) && ((tp->snd_max == tp->snd_una) || rack->rc_has_collapsed) && sbavail(&tptosocket(tp)->so_snd) && (sbavail(&tptosocket(tp)->so_snd) > tp->snd_wnd)) { /* * Here the rwnd is less than * the pacing size, we are established, * nothing is outstanding, and there is * data to send. Enter persists. */ rack_enter_persist(tp, rack, rack->r_ctl.rc_rcvtime); } } static void rack_log_input_packet(struct tcpcb *tp, struct tcp_rack *rack, struct tcp_ackent *ae, int ackval, uint32_t high_seq) { if (tp->t_logstate != TCP_LOG_STATE_OFF) { struct inpcb *inp = tptoinpcb(tp); union tcp_log_stackspecific log; struct timeval ltv; char tcp_hdr_buf[60]; struct tcphdr *th; struct timespec ts; uint32_t orig_snd_una; uint8_t xx = 0; #ifdef NETFLIX_HTTP_LOGGING struct http_sendfile_track *http_req; if (SEQ_GT(ae->ack, tp->snd_una)) { http_req = tcp_http_find_req_for_seq(tp, (ae->ack-1)); } else { http_req = tcp_http_find_req_for_seq(tp, ae->ack); } #endif memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); if (rack->rack_no_prr == 0) log.u_bbr.flex1 = rack->r_ctl.rc_prr_sndcnt; else log.u_bbr.flex1 = 0; log.u_bbr.use_lt_bw = rack->r_ent_rec_ns; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->r_might_revert; log.u_bbr.flex2 = rack->r_ctl.rc_num_maps_alloced; log.u_bbr.inflight = ctf_flight_size(tp, rack->r_ctl.rc_sacked); log.u_bbr.pkts_out = tp->t_maxseg; log.u_bbr.flex4 = rack->r_ctl.rc_hpts_flags; log.u_bbr.flex7 = 1; log.u_bbr.lost = ae->flags; log.u_bbr.cwnd_gain = ackval; log.u_bbr.pacing_gain = 0x2; if (ae->flags & TSTMP_HDWR) { /* Record the hardware timestamp if present */ log.u_bbr.flex3 = M_TSTMP; ts.tv_sec = ae->timestamp / 1000000000; ts.tv_nsec = ae->timestamp % 1000000000; ltv.tv_sec = ts.tv_sec; ltv.tv_usec = ts.tv_nsec / 1000; log.u_bbr.lt_epoch = tcp_tv_to_usectick(<v); } else if (ae->flags & TSTMP_LRO) { /* Record the LRO the arrival timestamp */ log.u_bbr.flex3 = M_TSTMP_LRO; ts.tv_sec = ae->timestamp / 1000000000; ts.tv_nsec = ae->timestamp % 1000000000; ltv.tv_sec = ts.tv_sec; ltv.tv_usec = ts.tv_nsec / 1000; log.u_bbr.flex5 = tcp_tv_to_usectick(<v); } log.u_bbr.timeStamp = tcp_get_usecs(<v); /* Log the rcv time */ log.u_bbr.delRate = ae->timestamp; #ifdef NETFLIX_HTTP_LOGGING log.u_bbr.applimited = tp->t_http_closed; log.u_bbr.applimited <<= 8; log.u_bbr.applimited |= tp->t_http_open; log.u_bbr.applimited <<= 8; log.u_bbr.applimited |= tp->t_http_req; if (http_req) { /* Copy out any client req info */ /* seconds */ log.u_bbr.pkt_epoch = (http_req->localtime / HPTS_USEC_IN_SEC); /* useconds */ log.u_bbr.delivered = (http_req->localtime % HPTS_USEC_IN_SEC); log.u_bbr.rttProp = http_req->timestamp; log.u_bbr.cur_del_rate = http_req->start; if (http_req->flags & TCP_HTTP_TRACK_FLG_OPEN) { log.u_bbr.flex8 |= 1; } else { log.u_bbr.flex8 |= 2; log.u_bbr.bw_inuse = http_req->end; } log.u_bbr.flex6 = http_req->start_seq; if (http_req->flags & TCP_HTTP_TRACK_FLG_COMP) { log.u_bbr.flex8 |= 4; log.u_bbr.epoch = http_req->end_seq; } } #endif memset(tcp_hdr_buf, 0, sizeof(tcp_hdr_buf)); th = (struct tcphdr *)tcp_hdr_buf; th->th_seq = ae->seq; th->th_ack = ae->ack; th->th_win = ae->win; /* Now fill in the ports */ th->th_sport = inp->inp_fport; th->th_dport = inp->inp_lport; tcp_set_flags(th, ae->flags); /* Now do we have a timestamp option? */ if (ae->flags & HAS_TSTMP) { u_char *cp; uint32_t val; th->th_off = ((sizeof(struct tcphdr) + TCPOLEN_TSTAMP_APPA) >> 2); cp = (u_char *)(th + 1); *cp = TCPOPT_NOP; cp++; *cp = TCPOPT_NOP; cp++; *cp = TCPOPT_TIMESTAMP; cp++; *cp = TCPOLEN_TIMESTAMP; cp++; val = htonl(ae->ts_value); bcopy((char *)&val, (char *)cp, sizeof(uint32_t)); val = htonl(ae->ts_echo); bcopy((char *)&val, (char *)(cp + 4), sizeof(uint32_t)); } else th->th_off = (sizeof(struct tcphdr) >> 2); /* * For sane logging we need to play a little trick. * If the ack were fully processed we would have moved * snd_una to high_seq, but since compressed acks are * processed in two phases, at this point (logging) snd_una * won't be advanced. So we would see multiple acks showing * the advancement. We can prevent that by "pretending" that * snd_una was advanced and then un-advancing it so that the * logging code has the right value for tlb_snd_una. */ if (tp->snd_una != high_seq) { orig_snd_una = tp->snd_una; tp->snd_una = high_seq; xx = 1; } else xx = 0; TCP_LOG_EVENTP(tp, th, &tptosocket(tp)->so_rcv, &tptosocket(tp)->so_snd, TCP_LOG_IN, 0, 0, &log, true, <v); if (xx) { tp->snd_una = orig_snd_una; } } } static void rack_handle_probe_response(struct tcp_rack *rack, uint32_t tiwin, uint32_t us_cts) { uint32_t us_rtt; /* * A persist or keep-alive was forced out, update our * min rtt time. Note now worry about lost responses. * When a subsequent keep-alive or persist times out * and forced_ack is still on, then the last probe * was not responded to. In such cases we have a * sysctl that controls the behavior. Either we apply * the rtt but with reduced confidence (0). Or we just * plain don't apply the rtt estimate. Having data flow * will clear the probe_not_answered flag i.e. cum-ack * move forward exiting and reentering persists. */ rack->forced_ack = 0; rack->rc_tp->t_rxtshift = 0; if ((rack->rc_in_persist && (tiwin == rack->rc_tp->snd_wnd)) || (rack->rc_in_persist == 0)) { /* * In persists only apply the RTT update if this is * a response to our window probe. And that * means the rwnd sent must match the current * snd_wnd. If it does not, then we got a * window update ack instead. For keepalive * we allow the answer no matter what the window. * * Note that if the probe_not_answered is set then * the forced_ack_ts is the oldest one i.e. the first * probe sent that might have been lost. This assures * us that if we do calculate an RTT it is longer not * some short thing. */ if (rack->rc_in_persist) counter_u64_add(rack_persists_acks, 1); us_rtt = us_cts - rack->r_ctl.forced_ack_ts; if (us_rtt == 0) us_rtt = 1; if (rack->probe_not_answered == 0) { rack_apply_updated_usrtt(rack, us_rtt, us_cts); tcp_rack_xmit_timer(rack, us_rtt, 0, us_rtt, 3, NULL, 1); } else { /* We have a retransmitted probe here too */ if (rack_apply_rtt_with_reduced_conf) { rack_apply_updated_usrtt(rack, us_rtt, us_cts); tcp_rack_xmit_timer(rack, us_rtt, 0, us_rtt, 0, NULL, 1); } } } } static int rack_do_compressed_ack_processing(struct tcpcb *tp, struct socket *so, struct mbuf *m, int nxt_pkt, struct timeval *tv) { /* * Handle a "special" compressed ack mbuf. Each incoming * ack has only four possible dispositions: * * A) It moves the cum-ack forward * B) It is behind the cum-ack. * C) It is a window-update ack. * D) It is a dup-ack. * * Note that we can have between 1 -> TCP_COMP_ACK_ENTRIES * in the incoming mbuf. We also need to still pay attention * to nxt_pkt since there may be another packet after this * one. */ #ifdef TCP_ACCOUNTING uint64_t ts_val; uint64_t rdstc; #endif int segsiz; struct timespec ts; struct tcp_rack *rack; struct tcp_ackent *ae; uint32_t tiwin, ms_cts, cts, acked, acked_amount, high_seq, win_seq, the_win, win_upd_ack; int cnt, i, did_out, ourfinisacked = 0; struct tcpopt to_holder, *to = NULL; #ifdef TCP_ACCOUNTING int win_up_req = 0; #endif int nsegs = 0; int under_pacing = 1; int recovery = 0; #ifdef TCP_ACCOUNTING sched_pin(); #endif rack = (struct tcp_rack *)tp->t_fb_ptr; if (rack->gp_ready && (rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT)) under_pacing = 0; else under_pacing = 1; if (rack->r_state != tp->t_state) rack_set_state(tp, rack); if ((tp->t_state >= TCPS_FIN_WAIT_1) && (tp->t_flags & TF_GPUTINPROG)) { /* * We have a goodput in progress * and we have entered a late state. * Do we have enough data in the sb * to handle the GPUT request? */ uint32_t bytes; bytes = tp->gput_ack - tp->gput_seq; if (SEQ_GT(tp->gput_seq, tp->snd_una)) bytes += tp->gput_seq - tp->snd_una; if (bytes > sbavail(&tptosocket(tp)->so_snd)) { /* * There are not enough bytes in the socket * buffer that have been sent to cover this * measurement. Cancel it. */ rack_log_pacing_delay_calc(rack, (tp->gput_ack - tp->gput_seq) /*flex2*/, rack->r_ctl.rc_gp_srtt /*flex1*/, tp->gput_seq, 0, 0, 18, __LINE__, NULL, 0); tp->t_flags &= ~TF_GPUTINPROG; } } to = &to_holder; to->to_flags = 0; KASSERT((m->m_len >= sizeof(struct tcp_ackent)), ("tp:%p m_cmpack:%p with invalid len:%u", tp, m, m->m_len)); cnt = m->m_len / sizeof(struct tcp_ackent); counter_u64_add(rack_multi_single_eq, cnt); high_seq = tp->snd_una; the_win = tp->snd_wnd; win_seq = tp->snd_wl1; win_upd_ack = tp->snd_wl2; cts = tcp_tv_to_usectick(tv); ms_cts = tcp_tv_to_mssectick(tv); rack->r_ctl.rc_rcvtime = cts; segsiz = ctf_fixed_maxseg(tp); if ((rack->rc_gp_dyn_mul) && (rack->use_fixed_rate == 0) && (rack->rc_always_pace)) { /* Check in on probertt */ rack_check_probe_rtt(rack, cts); } for (i = 0; i < cnt; i++) { #ifdef TCP_ACCOUNTING ts_val = get_cyclecount(); #endif rack_clear_rate_sample(rack); ae = ((mtod(m, struct tcp_ackent *)) + i); /* Setup the window */ tiwin = ae->win << tp->snd_scale; if (tiwin > rack->r_ctl.rc_high_rwnd) rack->r_ctl.rc_high_rwnd = tiwin; /* figure out the type of ack */ if (SEQ_LT(ae->ack, high_seq)) { /* Case B*/ ae->ack_val_set = ACK_BEHIND; } else if (SEQ_GT(ae->ack, high_seq)) { /* Case A */ ae->ack_val_set = ACK_CUMACK; } else if ((tiwin == the_win) && (rack->rc_in_persist == 0)){ /* Case D */ ae->ack_val_set = ACK_DUPACK; } else { /* Case C */ ae->ack_val_set = ACK_RWND; } rack_log_input_packet(tp, rack, ae, ae->ack_val_set, high_seq); /* Validate timestamp */ if (ae->flags & HAS_TSTMP) { /* Setup for a timestamp */ to->to_flags = TOF_TS; ae->ts_echo -= tp->ts_offset; to->to_tsecr = ae->ts_echo; to->to_tsval = ae->ts_value; /* * If echoed timestamp is later than the current time, fall back to * non RFC1323 RTT calculation. Normalize timestamp if syncookies * were used when this connection was established. */ if (TSTMP_GT(ae->ts_echo, ms_cts)) to->to_tsecr = 0; if (tp->ts_recent && TSTMP_LT(ae->ts_value, tp->ts_recent)) { if (ctf_ts_check_ac(tp, (ae->flags & 0xff))) { #ifdef TCP_ACCOUNTING rdstc = get_cyclecount(); if (rdstc > ts_val) { counter_u64_add(tcp_proc_time[ae->ack_val_set] , (rdstc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[ae->ack_val_set] += (rdstc - ts_val); } } #endif continue; } } if (SEQ_LEQ(ae->seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, ae->seq)) { tp->ts_recent_age = tcp_ts_getticks(); tp->ts_recent = ae->ts_value; } } else { /* Setup for a no options */ to->to_flags = 0; } /* Update the rcv time and perform idle reduction possibly */ if (tp->t_idle_reduce && (tp->snd_max == tp->snd_una) && (TICKS_2_USEC(ticks - tp->t_rcvtime) >= tp->t_rxtcur)) { counter_u64_add(rack_input_idle_reduces, 1); rack_cc_after_idle(rack, tp); } tp->t_rcvtime = ticks; /* Now what about ECN of a chain of pure ACKs? */ if (tcp_ecn_input_segment(tp, ae->flags, 0, tcp_packets_this_ack(tp, ae->ack), ae->codepoint)) rack_cong_signal(tp, CC_ECN, ae->ack, __LINE__); #ifdef TCP_ACCOUNTING /* Count for the specific type of ack in */ counter_u64_add(tcp_cnt_counters[ae->ack_val_set], 1); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[ae->ack_val_set]++; } #endif /* * Note how we could move up these in the determination * above, but we don't so that way the timestamp checks (and ECN) * is done first before we do any processing on the ACK. * The non-compressed path through the code has this * weakness (noted by @jtl) that it actually does some * processing before verifying the timestamp information. * We don't take that path here which is why we set * the ack_val_set first, do the timestamp and ecn * processing, and then look at what we have setup. */ if (ae->ack_val_set == ACK_BEHIND) { /* * Case B flag reordering, if window is not closed * or it could be a keep-alive or persists */ if (SEQ_LT(ae->ack, tp->snd_una) && (sbspace(&so->so_rcv) > segsiz)) { rack->r_ctl.rc_reorder_ts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); } } else if (ae->ack_val_set == ACK_DUPACK) { /* Case D */ rack_strike_dupack(rack); } else if (ae->ack_val_set == ACK_RWND) { /* Case C */ if ((ae->flags & TSTMP_LRO) || (ae->flags & TSTMP_HDWR)) { ts.tv_sec = ae->timestamp / 1000000000; ts.tv_nsec = ae->timestamp % 1000000000; rack->r_ctl.act_rcv_time.tv_sec = ts.tv_sec; rack->r_ctl.act_rcv_time.tv_usec = ts.tv_nsec/1000; } else { rack->r_ctl.act_rcv_time = *tv; } if (rack->forced_ack) { rack_handle_probe_response(rack, tiwin, tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time)); } #ifdef TCP_ACCOUNTING win_up_req = 1; #endif win_upd_ack = ae->ack; win_seq = ae->seq; the_win = tiwin; rack_do_win_updates(tp, rack, the_win, win_seq, win_upd_ack, cts, high_seq); } else { /* Case A */ if (SEQ_GT(ae->ack, tp->snd_max)) { /* * We just send an ack since the incoming * ack is beyond the largest seq we sent. */ if ((tp->t_flags & TF_ACKNOW) == 0) { ctf_ack_war_checks(tp, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt); if (tp->t_flags && TF_ACKNOW) rack->r_wanted_output = 1; } } else { nsegs++; /* If the window changed setup to update */ if (tiwin != tp->snd_wnd) { win_upd_ack = ae->ack; win_seq = ae->seq; the_win = tiwin; rack_do_win_updates(tp, rack, the_win, win_seq, win_upd_ack, cts, high_seq); } #ifdef TCP_ACCOUNTING /* Account for the acks */ if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[CNT_OF_ACKS_IN] += (((ae->ack - high_seq) + segsiz - 1) / segsiz); } counter_u64_add(tcp_cnt_counters[CNT_OF_ACKS_IN], (((ae->ack - high_seq) + segsiz - 1) / segsiz)); #endif high_seq = ae->ack; if (rack_verbose_logging && (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.flex1 = high_seq; log.u_bbr.flex2 = rack->r_ctl.roundends; log.u_bbr.flex3 = rack->r_ctl.current_round; log.u_bbr.rttProp = (uint64_t)CC_ALGO(tp)->newround; log.u_bbr.flex8 = 8; tcp_log_event_(tp, NULL, NULL, NULL, BBR_LOG_CWND, 0, 0, &log, false, NULL, NULL, 0, &tv); } /* * The draft (v3) calls for us to use SEQ_GEQ, but that * causes issues when we are just going app limited. Lets * instead use SEQ_GT where its equal but more data * is outstanding. */ if ((SEQ_GT(high_seq, rack->r_ctl.roundends)) || ((high_seq == rack->r_ctl.roundends) && SEQ_GT(tp->snd_max, tp->snd_una))) { rack->r_ctl.current_round++; rack->r_ctl.roundends = tp->snd_max; if (CC_ALGO(tp)->newround != NULL) { CC_ALGO(tp)->newround(&tp->t_ccv, rack->r_ctl.current_round); } } /* Setup our act_rcv_time */ if ((ae->flags & TSTMP_LRO) || (ae->flags & TSTMP_HDWR)) { ts.tv_sec = ae->timestamp / 1000000000; ts.tv_nsec = ae->timestamp % 1000000000; rack->r_ctl.act_rcv_time.tv_sec = ts.tv_sec; rack->r_ctl.act_rcv_time.tv_usec = ts.tv_nsec/1000; } else { rack->r_ctl.act_rcv_time = *tv; } rack_process_to_cumack(tp, rack, ae->ack, cts, to); if (rack->rc_dsack_round_seen) { /* Is the dsack round over? */ if (SEQ_GEQ(ae->ack, rack->r_ctl.dsack_round_end)) { /* Yes it is */ rack->rc_dsack_round_seen = 0; rack_log_dsack_event(rack, 3, __LINE__, 0, 0); } } } } /* And lets be sure to commit the rtt measurements for this ack */ tcp_rack_xmit_timer_commit(rack, tp); #ifdef TCP_ACCOUNTING rdstc = get_cyclecount(); if (rdstc > ts_val) { counter_u64_add(tcp_proc_time[ae->ack_val_set] , (rdstc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[ae->ack_val_set] += (rdstc - ts_val); if (ae->ack_val_set == ACK_CUMACK) tp->tcp_proc_time[CYC_HANDLE_MAP] += (rdstc - ts_val); } } #endif } #ifdef TCP_ACCOUNTING ts_val = get_cyclecount(); #endif /* Tend to any collapsed window */ if (SEQ_GT(tp->snd_max, high_seq) && (tp->snd_wnd < (tp->snd_max - high_seq))) { /* The peer collapsed the window */ rack_collapsed_window(rack, (tp->snd_max - high_seq), __LINE__); } else if (rack->rc_has_collapsed) rack_un_collapse_window(rack, __LINE__); if ((rack->r_collapse_point_valid) && (SEQ_GT(high_seq, rack->r_ctl.high_collapse_point))) rack->r_collapse_point_valid = 0; acked_amount = acked = (high_seq - tp->snd_una); if (acked) { /* * Clear the probe not answered flag * since cum-ack moved forward. */ rack->probe_not_answered = 0; if (rack->sack_attack_disable == 0) rack_do_decay(rack); if (acked >= segsiz) { /* * You only get credit for * MSS and greater (and you get extra * credit for larger cum-ack moves). */ int ac; ac = acked / segsiz; rack->r_ctl.ack_count += ac; counter_u64_add(rack_ack_total, ac); } if (rack->r_ctl.ack_count > 0xfff00000) { /* * reduce the number to keep us under * a uint32_t. */ rack->r_ctl.ack_count /= 2; rack->r_ctl.sack_count /= 2; } if (tp->t_flags & TF_NEEDSYN) { /* * T/TCP: Connection was half-synchronized, and our SYN has * been ACK'd (so connection is now fully synchronized). Go * to non-starred state, increment snd_una for ACK of SYN, * and check if we can do window scaling. */ tp->t_flags &= ~TF_NEEDSYN; tp->snd_una++; acked_amount = acked = (high_seq - tp->snd_una); } if (acked > sbavail(&so->so_snd)) acked_amount = sbavail(&so->so_snd); #ifdef NETFLIX_EXP_DETECTION /* * We only care on a cum-ack move if we are in a sack-disabled * state. We have already added in to the ack_count, and we never * would disable on a cum-ack move, so we only care to do the * detection if it may "undo" it, i.e. we were in disabled already. */ if (rack->sack_attack_disable) rack_do_detection(tp, rack, acked_amount, segsiz); #endif if (IN_FASTRECOVERY(tp->t_flags) && (rack->rack_no_prr == 0)) rack_update_prr(tp, rack, acked_amount, high_seq); if (IN_RECOVERY(tp->t_flags)) { if (SEQ_LT(high_seq, tp->snd_recover) && (SEQ_LT(high_seq, tp->snd_max))) { tcp_rack_partialack(tp); } else { rack_post_recovery(tp, high_seq); recovery = 1; } } /* Handle the rack-log-ack part (sendmap) */ if ((sbused(&so->so_snd) == 0) && (acked > acked_amount) && (tp->t_state >= TCPS_FIN_WAIT_1) && (tp->t_flags & TF_SENTFIN)) { /* * We must be sure our fin * was sent and acked (we can be * in FIN_WAIT_1 without having * sent the fin). */ ourfinisacked = 1; /* * Lets make sure snd_una is updated * since most likely acked_amount = 0 (it * should be). */ tp->snd_una = high_seq; } /* Did we make a RTO error? */ if ((tp->t_flags & TF_PREVVALID) && ((tp->t_flags & TF_RCVD_TSTMP) == 0)) { tp->t_flags &= ~TF_PREVVALID; if (tp->t_rxtshift == 1 && (int)(ticks - tp->t_badrxtwin) < 0) rack_cong_signal(tp, CC_RTO_ERR, high_seq, __LINE__); } /* Handle the data in the socket buffer */ KMOD_TCPSTAT_ADD(tcps_rcvackpack, 1); KMOD_TCPSTAT_ADD(tcps_rcvackbyte, acked); if (acked_amount > 0) { struct mbuf *mfree; rack_ack_received(tp, rack, high_seq, nsegs, CC_ACK, recovery); SOCKBUF_LOCK(&so->so_snd); mfree = sbcut_locked(&so->so_snd, acked_amount); tp->snd_una = high_seq; /* Note we want to hold the sb lock through the sendmap adjust */ rack_adjust_sendmap(rack, &so->so_snd, tp->snd_una); /* Wake up the socket if we have room to write more */ rack_log_wakeup(tp,rack, &so->so_snd, acked, 2); sowwakeup_locked(so); m_freem(mfree); } /* update progress */ tp->t_acktime = ticks; rack_log_progress_event(rack, tp, tp->t_acktime, PROGRESS_UPDATE, __LINE__); /* Clear out shifts and such */ tp->t_rxtshift = 0; RACK_TCPT_RANGESET(tp->t_rxtcur, RACK_REXMTVAL(tp), rack_rto_min, rack_rto_max, rack->r_ctl.timer_slop); rack->rc_tlp_in_progress = 0; rack->r_ctl.rc_tlp_cnt_out = 0; /* Send recover and snd_nxt must be dragged along */ if (SEQ_GT(tp->snd_una, tp->snd_recover)) tp->snd_recover = tp->snd_una; if (SEQ_LT(tp->snd_nxt, tp->snd_una)) tp->snd_nxt = tp->snd_una; /* * If the RXT timer is running we want to * stop it, so we can restart a TLP (or new RXT). */ if (rack->r_ctl.rc_hpts_flags & PACE_TMR_RXT) rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); #ifdef NETFLIX_HTTP_LOGGING tcp_http_check_for_comp(rack->rc_tp, high_seq); #endif tp->snd_wl2 = high_seq; tp->t_dupacks = 0; if (under_pacing && (rack->use_fixed_rate == 0) && (rack->in_probe_rtt == 0) && rack->rc_gp_dyn_mul && rack->rc_always_pace) { /* Check if we are dragging bottom */ rack_check_bottom_drag(tp, rack, so, acked); } if (tp->snd_una == tp->snd_max) { tp->t_flags &= ~TF_PREVVALID; rack->r_ctl.retran_during_recovery = 0; rack->r_ctl.dsack_byte_cnt = 0; rack->r_ctl.rc_went_idle_time = tcp_get_usecs(NULL); if (rack->r_ctl.rc_went_idle_time == 0) rack->r_ctl.rc_went_idle_time = 1; rack_log_progress_event(rack, tp, 0, PROGRESS_CLEAR, __LINE__); if (sbavail(&tptosocket(tp)->so_snd) == 0) tp->t_acktime = 0; /* Set so we might enter persists... */ rack->r_wanted_output = 1; rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); sack_filter_clear(&rack->r_ctl.rack_sf, tp->snd_una); if ((tp->t_state >= TCPS_FIN_WAIT_1) && (sbavail(&so->so_snd) == 0) && (tp->t_flags2 & TF2_DROP_AF_DATA)) { /* * The socket was gone and the * peer sent data (not now in the past), time to * reset him. */ rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); /* tcp_close will kill the inp pre-log the Reset */ tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST); #ifdef TCP_ACCOUNTING rdstc = get_cyclecount(); if (rdstc > ts_val) { counter_u64_add(tcp_proc_time[ACK_CUMACK] , (rdstc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[ACK_CUMACK] += (rdstc - ts_val); tp->tcp_proc_time[CYC_HANDLE_ACK] += (rdstc - ts_val); } } #endif m_freem(m); tp = tcp_close(tp); if (tp == NULL) { #ifdef TCP_ACCOUNTING sched_unpin(); #endif return (1); } /* * We would normally do drop-with-reset which would * send back a reset. We can't since we don't have * all the needed bits. Instead lets arrange for * a call to tcp_output(). That way since we * are in the closed state we will generate a reset. * * Note if tcp_accounting is on we don't unpin since * we do that after the goto label. */ goto send_out_a_rst; } if ((sbused(&so->so_snd) == 0) && (tp->t_state >= TCPS_FIN_WAIT_1) && (tp->t_flags & TF_SENTFIN)) { /* * If we can't receive any more data, then closing user can * proceed. Starting the timer is contrary to the * specification, but if we don't get a FIN we'll hang * forever. * */ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { soisdisconnected(so); tcp_timer_activate(tp, TT_2MSL, (tcp_fast_finwait2_recycle ? tcp_finwait2_timeout : TP_MAXIDLE(tp))); } if (ourfinisacked == 0) { /* * We don't change to fin-wait-2 if we have our fin acked * which means we are probably in TCPS_CLOSING. */ tcp_state_change(tp, TCPS_FIN_WAIT_2); } } } /* Wake up the socket if we have room to write more */ if (sbavail(&so->so_snd)) { rack->r_wanted_output = 1; if (ctf_progress_timeout_check(tp, true)) { rack_log_progress_event((struct tcp_rack *)tp->t_fb_ptr, tp, tick, PROGRESS_DROP, __LINE__); /* * We cheat here and don't send a RST, we should send one * when the pacer drops the connection. */ #ifdef TCP_ACCOUNTING rdstc = get_cyclecount(); if (rdstc > ts_val) { counter_u64_add(tcp_proc_time[ACK_CUMACK] , (rdstc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[ACK_CUMACK] += (rdstc - ts_val); tp->tcp_proc_time[CYC_HANDLE_ACK] += (rdstc - ts_val); } } sched_unpin(); #endif (void)tcp_drop(tp, ETIMEDOUT); m_freem(m); return (1); } } if (ourfinisacked) { switch(tp->t_state) { case TCPS_CLOSING: #ifdef TCP_ACCOUNTING rdstc = get_cyclecount(); if (rdstc > ts_val) { counter_u64_add(tcp_proc_time[ACK_CUMACK] , (rdstc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[ACK_CUMACK] += (rdstc - ts_val); tp->tcp_proc_time[CYC_HANDLE_ACK] += (rdstc - ts_val); } } sched_unpin(); #endif tcp_twstart(tp); m_freem(m); return (1); break; case TCPS_LAST_ACK: #ifdef TCP_ACCOUNTING rdstc = get_cyclecount(); if (rdstc > ts_val) { counter_u64_add(tcp_proc_time[ACK_CUMACK] , (rdstc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[ACK_CUMACK] += (rdstc - ts_val); tp->tcp_proc_time[CYC_HANDLE_ACK] += (rdstc - ts_val); } } sched_unpin(); #endif tp = tcp_close(tp); ctf_do_drop(m, tp); return (1); break; case TCPS_FIN_WAIT_1: #ifdef TCP_ACCOUNTING rdstc = get_cyclecount(); if (rdstc > ts_val) { counter_u64_add(tcp_proc_time[ACK_CUMACK] , (rdstc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[ACK_CUMACK] += (rdstc - ts_val); tp->tcp_proc_time[CYC_HANDLE_ACK] += (rdstc - ts_val); } } #endif if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { soisdisconnected(so); tcp_timer_activate(tp, TT_2MSL, (tcp_fast_finwait2_recycle ? tcp_finwait2_timeout : TP_MAXIDLE(tp))); } tcp_state_change(tp, TCPS_FIN_WAIT_2); break; default: break; } } if (rack->r_fast_output) { /* * We re doing fast output.. can we expand that? */ rack_gain_for_fastoutput(rack, tp, so, acked_amount); } #ifdef TCP_ACCOUNTING rdstc = get_cyclecount(); if (rdstc > ts_val) { counter_u64_add(tcp_proc_time[ACK_CUMACK] , (rdstc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[ACK_CUMACK] += (rdstc - ts_val); tp->tcp_proc_time[CYC_HANDLE_ACK] += (rdstc - ts_val); } } } else if (win_up_req) { rdstc = get_cyclecount(); if (rdstc > ts_val) { counter_u64_add(tcp_proc_time[ACK_RWND] , (rdstc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[ACK_RWND] += (rdstc - ts_val); } } #endif } /* Now is there a next packet, if so we are done */ m_freem(m); did_out = 0; if (nxt_pkt) { #ifdef TCP_ACCOUNTING sched_unpin(); #endif rack_log_doseg_done(rack, cts, nxt_pkt, did_out, 5, nsegs); return (0); } rack_handle_might_revert(tp, rack); ctf_calc_rwin(so, tp); if ((rack->r_wanted_output != 0) || (rack->r_fast_output != 0)) { send_out_a_rst: if (tcp_output(tp) < 0) { #ifdef TCP_ACCOUNTING sched_unpin(); #endif return (1); } did_out = 1; } rack_free_trim(rack); #ifdef TCP_ACCOUNTING sched_unpin(); #endif rack_timer_audit(tp, rack, &so->so_snd); rack_log_doseg_done(rack, cts, nxt_pkt, did_out, 6, nsegs); return (0); } static int rack_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, uint8_t iptos, int32_t nxt_pkt, struct timeval *tv) { struct inpcb *inp = tptoinpcb(tp); #ifdef TCP_ACCOUNTING uint64_t ts_val; #endif int32_t thflags, retval, did_out = 0; int32_t way_out = 0; /* * cts - is the current time from tv (caller gets ts) in microseconds. * ms_cts - is the current time from tv in milliseconds. * us_cts - is the time that LRO or hardware actually got the packet in microseconds. */ uint32_t cts, us_cts, ms_cts; uint32_t tiwin, high_seq; struct timespec ts; struct tcpopt to; struct tcp_rack *rack; struct rack_sendmap *rsm; int32_t prev_state = 0; #ifdef TCP_ACCOUNTING int ack_val_set = 0xf; #endif int nsegs; NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(inp); /* * tv passed from common code is from either M_TSTMP_LRO or * tcp_get_usecs() if no LRO m_pkthdr timestamp is present. */ rack = (struct tcp_rack *)tp->t_fb_ptr; if (m->m_flags & M_ACKCMP) { /* * All compressed ack's are ack's by definition so * remove any ack required flag and then do the processing. */ rack->rc_ack_required = 0; return (rack_do_compressed_ack_processing(tp, so, m, nxt_pkt, tv)); } if (m->m_flags & M_ACKCMP) { panic("Impossible reach m has ackcmp? m:%p tp:%p", m, tp); } cts = tcp_tv_to_usectick(tv); ms_cts = tcp_tv_to_mssectick(tv); nsegs = m->m_pkthdr.lro_nsegs; counter_u64_add(rack_proc_non_comp_ack, 1); thflags = tcp_get_flags(th); #ifdef TCP_ACCOUNTING sched_pin(); if (thflags & TH_ACK) ts_val = get_cyclecount(); #endif if ((m->m_flags & M_TSTMP) || (m->m_flags & M_TSTMP_LRO)) { mbuf_tstmp2timespec(m, &ts); rack->r_ctl.act_rcv_time.tv_sec = ts.tv_sec; rack->r_ctl.act_rcv_time.tv_usec = ts.tv_nsec/1000; } else rack->r_ctl.act_rcv_time = *tv; kern_prefetch(rack, &prev_state); prev_state = 0; /* * Unscale the window into a 32-bit value. For the SYN_SENT state * the scale is zero. */ tiwin = th->th_win << tp->snd_scale; #ifdef TCP_ACCOUNTING if (thflags & TH_ACK) { /* * We have a tradeoff here. We can either do what we are * doing i.e. pinning to this CPU and then doing the accounting * we could do a critical enter, setup the rdtsc and cpu * as in below, and then validate we are on the same CPU on * exit. I have choosen to not do the critical enter since * that often will gain you a context switch, and instead lock * us (line above this if) to the same CPU with sched_pin(). This * means we may be context switched out for a higher priority * interupt but we won't be moved to another CPU. * * If this occurs (which it won't very often since we most likely * are running this code in interupt context and only a higher * priority will bump us ... clock?) we will falsely add in * to the time the interupt processing time plus the ack processing * time. This is ok since its a rare event. */ ack_val_set = tcp_do_ack_accounting(tp, th, &to, tiwin, ctf_fixed_maxseg(tp)); } #endif /* * Parse options on any incoming segment. */ memset(&to, 0, sizeof(to)); tcp_dooptions(&to, (u_char *)(th + 1), (th->th_off << 2) - sizeof(struct tcphdr), (thflags & TH_SYN) ? TO_SYN : 0); KASSERT(tp->t_state > TCPS_LISTEN, ("%s: TCPS_LISTEN", __func__)); KASSERT(tp->t_state != TCPS_TIME_WAIT, ("%s: TCPS_TIME_WAIT", __func__)); if ((tp->t_state >= TCPS_FIN_WAIT_1) && (tp->t_flags & TF_GPUTINPROG)) { /* * We have a goodput in progress * and we have entered a late state. * Do we have enough data in the sb * to handle the GPUT request? */ uint32_t bytes; bytes = tp->gput_ack - tp->gput_seq; if (SEQ_GT(tp->gput_seq, tp->snd_una)) bytes += tp->gput_seq - tp->snd_una; if (bytes > sbavail(&tptosocket(tp)->so_snd)) { /* * There are not enough bytes in the socket * buffer that have been sent to cover this * measurement. Cancel it. */ rack_log_pacing_delay_calc(rack, (tp->gput_ack - tp->gput_seq) /*flex2*/, rack->r_ctl.rc_gp_srtt /*flex1*/, tp->gput_seq, 0, 0, 18, __LINE__, NULL, 0); tp->t_flags &= ~TF_GPUTINPROG; } } high_seq = th->th_ack; if (tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval ltv; #ifdef NETFLIX_HTTP_LOGGING struct http_sendfile_track *http_req; if (SEQ_GT(th->th_ack, tp->snd_una)) { http_req = tcp_http_find_req_for_seq(tp, (th->th_ack-1)); } else { http_req = tcp_http_find_req_for_seq(tp, th->th_ack); } #endif memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); if (rack->rack_no_prr == 0) log.u_bbr.flex1 = rack->r_ctl.rc_prr_sndcnt; else log.u_bbr.flex1 = 0; log.u_bbr.use_lt_bw = rack->r_ent_rec_ns; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->r_might_revert; log.u_bbr.flex2 = rack->r_ctl.rc_num_maps_alloced; log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.pkts_out = rack->rc_tp->t_maxseg; log.u_bbr.flex3 = m->m_flags; log.u_bbr.flex4 = rack->r_ctl.rc_hpts_flags; log.u_bbr.lost = thflags; log.u_bbr.pacing_gain = 0x1; #ifdef TCP_ACCOUNTING log.u_bbr.cwnd_gain = ack_val_set; #endif log.u_bbr.flex7 = 2; if (m->m_flags & M_TSTMP) { /* Record the hardware timestamp if present */ mbuf_tstmp2timespec(m, &ts); ltv.tv_sec = ts.tv_sec; ltv.tv_usec = ts.tv_nsec / 1000; log.u_bbr.lt_epoch = tcp_tv_to_usectick(<v); } else if (m->m_flags & M_TSTMP_LRO) { /* Record the LRO the arrival timestamp */ mbuf_tstmp2timespec(m, &ts); ltv.tv_sec = ts.tv_sec; ltv.tv_usec = ts.tv_nsec / 1000; log.u_bbr.flex5 = tcp_tv_to_usectick(<v); } log.u_bbr.timeStamp = tcp_get_usecs(<v); /* Log the rcv time */ log.u_bbr.delRate = m->m_pkthdr.rcv_tstmp; #ifdef NETFLIX_HTTP_LOGGING log.u_bbr.applimited = tp->t_http_closed; log.u_bbr.applimited <<= 8; log.u_bbr.applimited |= tp->t_http_open; log.u_bbr.applimited <<= 8; log.u_bbr.applimited |= tp->t_http_req; if (http_req) { /* Copy out any client req info */ /* seconds */ log.u_bbr.pkt_epoch = (http_req->localtime / HPTS_USEC_IN_SEC); /* useconds */ log.u_bbr.delivered = (http_req->localtime % HPTS_USEC_IN_SEC); log.u_bbr.rttProp = http_req->timestamp; log.u_bbr.cur_del_rate = http_req->start; if (http_req->flags & TCP_HTTP_TRACK_FLG_OPEN) { log.u_bbr.flex8 |= 1; } else { log.u_bbr.flex8 |= 2; log.u_bbr.bw_inuse = http_req->end; } log.u_bbr.flex6 = http_req->start_seq; if (http_req->flags & TCP_HTTP_TRACK_FLG_COMP) { log.u_bbr.flex8 |= 4; log.u_bbr.epoch = http_req->end_seq; } } #endif TCP_LOG_EVENTP(tp, th, &so->so_rcv, &so->so_snd, TCP_LOG_IN, 0, tlen, &log, true, <v); } /* Remove ack required flag if set, we have one */ if (thflags & TH_ACK) rack->rc_ack_required = 0; if ((thflags & TH_SYN) && (thflags & TH_FIN) && V_drop_synfin) { way_out = 4; retval = 0; m_freem(m); goto done_with_input; } /* * If a segment with the ACK-bit set arrives in the SYN-SENT state * check SEQ.ACK first as described on page 66 of RFC 793, section 3.9. */ if ((tp->t_state == TCPS_SYN_SENT) && (thflags & TH_ACK) && (SEQ_LEQ(th->th_ack, tp->iss) || SEQ_GT(th->th_ack, tp->snd_max))) { tcp_log_end_status(tp, TCP_EI_STATUS_RST_IN_FRONT); ctf_do_dropwithreset(m, tp, th, BANDLIM_RST_OPENPORT, tlen); #ifdef TCP_ACCOUNTING sched_unpin(); #endif return (1); } /* * If timestamps were negotiated during SYN/ACK and a * segment without a timestamp is received, silently drop * the segment, unless it is a RST segment or missing timestamps are * tolerated. * See section 3.2 of RFC 7323. */ if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS) && ((thflags & TH_RST) == 0) && (V_tcp_tolerate_missing_ts == 0)) { way_out = 5; retval = 0; m_freem(m); goto done_with_input; } /* * Segment received on connection. Reset idle time and keep-alive * timer. XXX: This should be done after segment validation to * ignore broken/spoofed segs. */ if (tp->t_idle_reduce && (tp->snd_max == tp->snd_una) && (TICKS_2_USEC(ticks - tp->t_rcvtime) >= tp->t_rxtcur)) { counter_u64_add(rack_input_idle_reduces, 1); rack_cc_after_idle(rack, tp); } tp->t_rcvtime = ticks; #ifdef STATS stats_voi_update_abs_ulong(tp->t_stats, VOI_TCP_FRWIN, tiwin); #endif if (tiwin > rack->r_ctl.rc_high_rwnd) rack->r_ctl.rc_high_rwnd = tiwin; /* * TCP ECN processing. XXXJTL: If we ever use ECN, we need to move * this to occur after we've validated the segment. */ if (tcp_ecn_input_segment(tp, thflags, tlen, tcp_packets_this_ack(tp, th->th_ack), iptos)) rack_cong_signal(tp, CC_ECN, th->th_ack, __LINE__); /* * If echoed timestamp is later than the current time, fall back to * non RFC1323 RTT calculation. Normalize timestamp if syncookies * were used when this connection was established. */ if ((to.to_flags & TOF_TS) && (to.to_tsecr != 0)) { to.to_tsecr -= tp->ts_offset; if (TSTMP_GT(to.to_tsecr, ms_cts)) to.to_tsecr = 0; } /* * If its the first time in we need to take care of options and * verify we can do SACK for rack! */ if (rack->r_state == 0) { /* Should be init'd by rack_init() */ KASSERT(rack->rc_inp != NULL, ("%s: rack->rc_inp unexpectedly NULL", __func__)); if (rack->rc_inp == NULL) { rack->rc_inp = inp; } /* * Process options only when we get SYN/ACK back. The SYN * case for incoming connections is handled in tcp_syncache. * According to RFC1323 the window field in a SYN (i.e., a * or ) segment itself is never scaled. XXX * this is traditional behavior, may need to be cleaned up. */ if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) { /* Handle parallel SYN for ECN */ tcp_ecn_input_parallel_syn(tp, thflags, iptos); if ((to.to_flags & TOF_SCALE) && (tp->t_flags & TF_REQ_SCALE)) { tp->t_flags |= TF_RCVD_SCALE; tp->snd_scale = to.to_wscale; } else tp->t_flags &= ~TF_REQ_SCALE; /* * Initial send window. It will be updated with the * next incoming segment to the scaled value. */ tp->snd_wnd = th->th_win; rack_validate_fo_sendwin_up(tp, rack); if ((to.to_flags & TOF_TS) && (tp->t_flags & TF_REQ_TSTMP)) { tp->t_flags |= TF_RCVD_TSTMP; tp->ts_recent = to.to_tsval; tp->ts_recent_age = cts; } else tp->t_flags &= ~TF_REQ_TSTMP; if (to.to_flags & TOF_MSS) { tcp_mss(tp, to.to_mss); } if ((tp->t_flags & TF_SACK_PERMIT) && (to.to_flags & TOF_SACKPERM) == 0) tp->t_flags &= ~TF_SACK_PERMIT; if (IS_FASTOPEN(tp->t_flags)) { if (to.to_flags & TOF_FASTOPEN) { uint16_t mss; if (to.to_flags & TOF_MSS) mss = to.to_mss; else if ((inp->inp_vflag & INP_IPV6) != 0) mss = TCP6_MSS; else mss = TCP_MSS; tcp_fastopen_update_cache(tp, mss, to.to_tfo_len, to.to_tfo_cookie); } else tcp_fastopen_disable_path(tp); } } /* * At this point we are at the initial call. Here we decide * if we are doing RACK or not. We do this by seeing if * TF_SACK_PERMIT is set and the sack-not-required is clear. * The code now does do dup-ack counting so if you don't * switch back you won't get rack & TLP, but you will still * get this stack. */ if ((rack_sack_not_required == 0) && ((tp->t_flags & TF_SACK_PERMIT) == 0)) { tcp_switch_back_to_default(tp); (*tp->t_fb->tfb_tcp_do_segment) (m, th, so, tp, drop_hdrlen, tlen, iptos); #ifdef TCP_ACCOUNTING sched_unpin(); #endif return (1); } tcp_set_hpts(inp); sack_filter_clear(&rack->r_ctl.rack_sf, th->th_ack); } if (thflags & TH_FIN) tcp_log_end_status(tp, TCP_EI_STATUS_CLIENT_FIN); us_cts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); if ((rack->rc_gp_dyn_mul) && (rack->use_fixed_rate == 0) && (rack->rc_always_pace)) { /* Check in on probertt */ rack_check_probe_rtt(rack, us_cts); } rack_clear_rate_sample(rack); if ((rack->forced_ack) && ((tcp_get_flags(th) & TH_RST) == 0)) { rack_handle_probe_response(rack, tiwin, us_cts); } /* * This is the one exception case where we set the rack state * always. All other times (timers etc) we must have a rack-state * set (so we assure we have done the checks above for SACK). */ rack->r_ctl.rc_rcvtime = cts; if (rack->r_state != tp->t_state) rack_set_state(tp, rack); if (SEQ_GT(th->th_ack, tp->snd_una) && (rsm = RB_MIN(rack_rb_tree_head, &rack->r_ctl.rc_mtree)) != NULL) kern_prefetch(rsm, &prev_state); prev_state = rack->r_state; retval = (*rack->r_substate) (m, th, so, tp, &to, drop_hdrlen, tlen, tiwin, thflags, nxt_pkt, iptos); if (retval == 0) { /* * If retval is 1 the tcb is unlocked and most likely the tp * is gone. */ INP_WLOCK_ASSERT(inp); if ((rack->rc_gp_dyn_mul) && (rack->rc_always_pace) && (rack->use_fixed_rate == 0) && rack->in_probe_rtt && (rack->r_ctl.rc_time_probertt_starts == 0)) { /* * If we are going for target, lets recheck before * we output. */ rack_check_probe_rtt(rack, us_cts); } if (rack->set_pacing_done_a_iw == 0) { /* How much has been acked? */ if ((tp->snd_una - tp->iss) > (ctf_fixed_maxseg(tp) * 10)) { /* We have enough to set in the pacing segment size */ rack->set_pacing_done_a_iw = 1; rack_set_pace_segments(tp, rack, __LINE__, NULL); } } tcp_rack_xmit_timer_commit(rack, tp); #ifdef TCP_ACCOUNTING /* * If we set the ack_val_se to what ack processing we are doing * we also want to track how many cycles we burned. Note * the bits after tcp_output we let be "free". This is because * we are also tracking the tcp_output times as well. Note the * use of 0xf here since we only have 11 counter (0 - 0xa) and * 0xf cannot be returned and is what we initialize it too to * indicate we are not doing the tabulations. */ if (ack_val_set != 0xf) { uint64_t crtsc; crtsc = get_cyclecount(); counter_u64_add(tcp_proc_time[ack_val_set] , (crtsc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[ack_val_set] += (crtsc - ts_val); } } #endif if (nxt_pkt == 0) { if ((rack->r_wanted_output != 0) || (rack->r_fast_output != 0)) { do_output_now: if (tcp_output(tp) < 0) return (1); did_out = 1; } rack_start_hpts_timer(rack, tp, cts, 0, 0, 0); rack_free_trim(rack); } /* Update any rounds needed */ if (rack_verbose_logging && (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF)) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.flex1 = high_seq; log.u_bbr.flex2 = rack->r_ctl.roundends; log.u_bbr.flex3 = rack->r_ctl.current_round; log.u_bbr.rttProp = (uint64_t)CC_ALGO(tp)->newround; log.u_bbr.flex8 = 9; tcp_log_event_(tp, NULL, NULL, NULL, BBR_LOG_CWND, 0, 0, &log, false, NULL, NULL, 0, &tv); } /* * The draft (v3) calls for us to use SEQ_GEQ, but that * causes issues when we are just going app limited. Lets * instead use SEQ_GT where its equal but more data * is outstanding. */ if ((SEQ_GT(tp->snd_una, rack->r_ctl.roundends)) || ((tp->snd_una == rack->r_ctl.roundends) && SEQ_GT(tp->snd_max, tp->snd_una))) { rack->r_ctl.current_round++; rack->r_ctl.roundends = tp->snd_max; if (CC_ALGO(tp)->newround != NULL) { CC_ALGO(tp)->newround(&tp->t_ccv, rack->r_ctl.current_round); } } if ((nxt_pkt == 0) && ((rack->r_ctl.rc_hpts_flags & PACE_TMR_MASK) == 0) && (SEQ_GT(tp->snd_max, tp->snd_una) || (tp->t_flags & TF_DELACK) || ((V_tcp_always_keepalive || rack->rc_inp->inp_socket->so_options & SO_KEEPALIVE) && (tp->t_state <= TCPS_CLOSING)))) { /* We could not send (probably in the hpts but stopped the timer earlier)? */ if ((tp->snd_max == tp->snd_una) && ((tp->t_flags & TF_DELACK) == 0) && (tcp_in_hpts(rack->rc_inp)) && (rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT)) { /* keep alive not needed if we are hptsi output yet */ ; } else { int late = 0; if (tcp_in_hpts(inp)) { if (rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) { us_cts = tcp_get_usecs(NULL); if (TSTMP_GT(rack->r_ctl.rc_last_output_to, us_cts)) { rack->r_early = 1; rack->r_ctl.rc_agg_early += (rack->r_ctl.rc_last_output_to - us_cts); } else late = 1; rack->r_ctl.rc_hpts_flags &= ~PACE_PKT_OUTPUT; } tcp_hpts_remove(inp); } if (late && (did_out == 0)) { /* * We are late in the sending * and we did not call the output * (this probably should not happen). */ goto do_output_now; } rack_start_hpts_timer(rack, tp, tcp_get_usecs(NULL), 0, 0, 0); } way_out = 1; } else if (nxt_pkt == 0) { /* Do we have the correct timer running? */ rack_timer_audit(tp, rack, &so->so_snd); way_out = 2; } done_with_input: rack_log_doseg_done(rack, cts, nxt_pkt, did_out, way_out, max(1, nsegs)); if (did_out) rack->r_wanted_output = 0; #ifdef TCP_ACCOUNTING } else { /* * Track the time (see above). */ if (ack_val_set != 0xf) { uint64_t crtsc; crtsc = get_cyclecount(); counter_u64_add(tcp_proc_time[ack_val_set] , (crtsc - ts_val)); /* * Note we *DO NOT* increment the per-tcb counters since * in the else the TP may be gone!! */ } #endif } #ifdef TCP_ACCOUNTING sched_unpin(); #endif return (retval); } void rack_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, uint8_t iptos) { struct timeval tv; /* First lets see if we have old packets */ if (tp->t_in_pkt) { if (ctf_do_queued_segments(so, tp, 1)) { m_freem(m); return; } } if (m->m_flags & M_TSTMP_LRO) { mbuf_tstmp2timeval(m, &tv); } else { /* Should not be should we kassert instead? */ tcp_get_usecs(&tv); } if (rack_do_segment_nounlock(m, th, so, tp, drop_hdrlen, tlen, iptos, 0, &tv) == 0) { INP_WUNLOCK(tptoinpcb(tp)); } } struct rack_sendmap * tcp_rack_output(struct tcpcb *tp, struct tcp_rack *rack, uint32_t tsused) { struct rack_sendmap *rsm = NULL; int32_t idx; uint32_t srtt = 0, thresh = 0, ts_low = 0; /* Return the next guy to be re-transmitted */ if (RB_EMPTY(&rack->r_ctl.rc_mtree)) { return (NULL); } if (tp->t_flags & TF_SENTFIN) { /* retran the end FIN? */ return (NULL); } /* ok lets look at this one */ rsm = TAILQ_FIRST(&rack->r_ctl.rc_tmap); if (rack->r_must_retran && rsm && (rsm->r_flags & RACK_MUST_RXT)) { return (rsm); } if (rsm && ((rsm->r_flags & RACK_ACKED) == 0)) { goto check_it; } rsm = rack_find_lowest_rsm(rack); if (rsm == NULL) { return (NULL); } check_it: if (((rack->rc_tp->t_flags & TF_SACK_PERMIT) == 0) && (rsm->r_dupack >= DUP_ACK_THRESHOLD)) { /* * No sack so we automatically do the 3 strikes and * retransmit (no rack timer would be started). */ return (rsm); } if (rsm->r_flags & RACK_ACKED) { return (NULL); } if (((rsm->r_flags & RACK_SACK_PASSED) == 0) && (rsm->r_dupack < DUP_ACK_THRESHOLD)) { /* Its not yet ready */ return (NULL); } srtt = rack_grab_rtt(tp, rack); idx = rsm->r_rtr_cnt - 1; ts_low = (uint32_t)rsm->r_tim_lastsent[idx]; thresh = rack_calc_thresh_rack(rack, srtt, tsused); if ((tsused == ts_low) || (TSTMP_LT(tsused, ts_low))) { /* No time since sending */ return (NULL); } if ((tsused - ts_low) < thresh) { /* It has not been long enough yet */ return (NULL); } if ((rsm->r_dupack >= DUP_ACK_THRESHOLD) || ((rsm->r_flags & RACK_SACK_PASSED) && (rack->sack_attack_disable == 0))) { /* * We have passed the dup-ack threshold * a SACK has indicated this is missing. * Note that if you are a declared attacker * it is only the dup-ack threshold that * will cause retransmits. */ /* log retransmit reason */ rack_log_retran_reason(rack, rsm, (tsused - ts_low), thresh, 1); rack->r_fast_output = 0; return (rsm); } return (NULL); } static void rack_log_pacing_delay_calc(struct tcp_rack *rack, uint32_t len, uint32_t slot, uint64_t bw_est, uint64_t bw, uint64_t len_time, int method, int line, struct rack_sendmap *rsm, uint8_t quality) { if (rack->rc_tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log, 0, sizeof(log)); log.u_bbr.flex1 = slot; log.u_bbr.flex2 = len; log.u_bbr.flex3 = rack->r_ctl.rc_pace_min_segs; log.u_bbr.flex4 = rack->r_ctl.rc_pace_max_segs; log.u_bbr.flex5 = rack->r_ctl.rack_per_of_gp_ss; log.u_bbr.flex6 = rack->r_ctl.rack_per_of_gp_ca; log.u_bbr.use_lt_bw = rack->rc_ack_can_sendout_data; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->r_late; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->r_early; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->app_limited_needs_set; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->rc_gp_filled; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->measure_saw_probe_rtt; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->in_probe_rtt; log.u_bbr.use_lt_bw <<= 1; log.u_bbr.use_lt_bw |= rack->gp_ready; log.u_bbr.pkt_epoch = line; log.u_bbr.epoch = rack->r_ctl.rc_agg_delayed; log.u_bbr.lt_epoch = rack->r_ctl.rc_agg_early; log.u_bbr.applimited = rack->r_ctl.rack_per_of_gp_rec; log.u_bbr.bw_inuse = bw_est; log.u_bbr.delRate = bw; if (rack->r_ctl.gp_bw == 0) log.u_bbr.cur_del_rate = 0; else log.u_bbr.cur_del_rate = rack_get_bw(rack); log.u_bbr.rttProp = len_time; log.u_bbr.pkts_out = rack->r_ctl.rc_rack_min_rtt; log.u_bbr.lost = rack->r_ctl.rc_probertt_sndmax_atexit; log.u_bbr.pacing_gain = rack_get_output_gain(rack, rsm); if (rack->r_ctl.cwnd_to_use < rack->rc_tp->snd_ssthresh) { /* We are in slow start */ log.u_bbr.flex7 = 1; } else { /* we are on congestion avoidance */ log.u_bbr.flex7 = 0; } log.u_bbr.flex8 = method; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.cwnd_gain = rack->rc_gp_saw_rec; log.u_bbr.cwnd_gain <<= 1; log.u_bbr.cwnd_gain |= rack->rc_gp_saw_ss; log.u_bbr.cwnd_gain <<= 1; log.u_bbr.cwnd_gain |= rack->rc_gp_saw_ca; log.u_bbr.bbr_substate = quality; TCP_LOG_EVENTP(rack->rc_tp, NULL, &rack->rc_inp->inp_socket->so_rcv, &rack->rc_inp->inp_socket->so_snd, BBR_LOG_HPTSI_CALC, 0, 0, &log, false, &tv); } } static uint32_t rack_get_pacing_len(struct tcp_rack *rack, uint64_t bw, uint32_t mss) { uint32_t new_tso, user_max; user_max = rack->rc_user_set_max_segs * mss; if (rack->rc_force_max_seg) { return (user_max); } if (rack->use_fixed_rate && ((rack->r_ctl.crte == NULL) || (bw != rack->r_ctl.crte->rate))) { /* Use the user mss since we are not exactly matched */ return (user_max); } new_tso = tcp_get_pacing_burst_size(rack->rc_tp, bw, mss, rack_pace_one_seg, rack->r_ctl.crte, NULL); if (new_tso > user_max) new_tso = user_max; return (new_tso); } static int32_t pace_to_fill_cwnd(struct tcp_rack *rack, int32_t slot, uint32_t len, uint32_t segsiz, int *capped, uint64_t *rate_wanted, uint8_t non_paced) { uint64_t lentim, fill_bw; /* Lets first see if we are full, if so continue with normal rate */ rack->r_via_fill_cw = 0; if (ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked) > rack->r_ctl.cwnd_to_use) return (slot); if ((ctf_outstanding(rack->rc_tp) + (segsiz-1)) > rack->rc_tp->snd_wnd) return (slot); if (rack->r_ctl.rc_last_us_rtt == 0) return (slot); if (rack->rc_pace_fill_if_rttin_range && (rack->r_ctl.rc_last_us_rtt >= (get_filter_value_small(&rack->r_ctl.rc_gp_min_rtt) * rack->rtt_limit_mul))) { /* The rtt is huge, N * smallest, lets not fill */ return (slot); } /* * first lets calculate the b/w based on the last us-rtt * and the sndwnd. */ fill_bw = rack->r_ctl.cwnd_to_use; /* Take the rwnd if its smaller */ if (fill_bw > rack->rc_tp->snd_wnd) fill_bw = rack->rc_tp->snd_wnd; if (rack->r_fill_less_agg) { /* * Now take away the inflight (this will reduce our * aggressiveness and yeah, if we get that much out in 1RTT * we will have had acks come back and still be behind). */ fill_bw -= ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); } /* Now lets make it into a b/w */ fill_bw *= (uint64_t)HPTS_USEC_IN_SEC; fill_bw /= (uint64_t)rack->r_ctl.rc_last_us_rtt; /* We are below the min b/w */ if (non_paced) *rate_wanted = fill_bw; if ((fill_bw < RACK_MIN_BW) || (fill_bw < *rate_wanted)) return (slot); if (rack->r_ctl.bw_rate_cap && (fill_bw > rack->r_ctl.bw_rate_cap)) fill_bw = rack->r_ctl.bw_rate_cap; rack->r_via_fill_cw = 1; if (rack->r_rack_hw_rate_caps && (rack->r_ctl.crte != NULL)) { uint64_t high_rate; high_rate = tcp_hw_highest_rate(rack->r_ctl.crte); if (fill_bw > high_rate) { /* We are capping bw at the highest rate table entry */ if (*rate_wanted > high_rate) { /* The original rate was also capped */ rack->r_via_fill_cw = 0; } rack_log_hdwr_pacing(rack, fill_bw, high_rate, __LINE__, 0, 3); fill_bw = high_rate; if (capped) *capped = 1; } } else if ((rack->r_ctl.crte == NULL) && (rack->rack_hdrw_pacing == 0) && (rack->rack_hdw_pace_ena) && rack->r_rack_hw_rate_caps && (rack->rack_attempt_hdwr_pace == 0) && (rack->rc_inp->inp_route.ro_nh != NULL) && (rack->rc_inp->inp_route.ro_nh->nh_ifp != NULL)) { /* * Ok we may have a first attempt that is greater than our top rate * lets check. */ uint64_t high_rate; high_rate = tcp_hw_highest_rate_ifp(rack->rc_inp->inp_route.ro_nh->nh_ifp, rack->rc_inp); if (high_rate) { if (fill_bw > high_rate) { fill_bw = high_rate; if (capped) *capped = 1; } } } /* * Ok fill_bw holds our mythical b/w to fill the cwnd * in a rtt, what does that time wise equate too? */ lentim = (uint64_t)(len) * (uint64_t)HPTS_USEC_IN_SEC; lentim /= fill_bw; *rate_wanted = fill_bw; if (non_paced || (lentim < slot)) { rack_log_pacing_delay_calc(rack, len, slot, fill_bw, 0, lentim, 12, __LINE__, NULL, 0); return ((int32_t)lentim); } else return (slot); } static int32_t rack_get_pacing_delay(struct tcp_rack *rack, struct tcpcb *tp, uint32_t len, struct rack_sendmap *rsm, uint32_t segsiz) { uint64_t srtt; int32_t slot = 0; int can_start_hw_pacing = 1; int err; if (rack->rc_always_pace == 0) { /* * We use the most optimistic possible cwnd/srtt for * sending calculations. This will make our * calculation anticipate getting more through * quicker then possible. But thats ok we don't want * the peer to have a gap in data sending. */ uint64_t cwnd, tr_perms = 0; int32_t reduce = 0; old_method: /* * We keep no precise pacing with the old method * instead we use the pacer to mitigate bursts. */ if (rack->r_ctl.rc_rack_min_rtt) srtt = rack->r_ctl.rc_rack_min_rtt; else srtt = max(tp->t_srtt, 1); if (rack->r_ctl.rc_rack_largest_cwnd) cwnd = rack->r_ctl.rc_rack_largest_cwnd; else cwnd = rack->r_ctl.cwnd_to_use; /* Inflate cwnd by 1000 so srtt of usecs is in ms */ tr_perms = (cwnd * 1000) / srtt; if (tr_perms == 0) { tr_perms = ctf_fixed_maxseg(tp); } /* * Calculate how long this will take to drain, if * the calculation comes out to zero, thats ok we * will use send_a_lot to possibly spin around for * more increasing tot_len_this_send to the point * that its going to require a pace, or we hit the * cwnd. Which in that case we are just waiting for * a ACK. */ slot = len / tr_perms; /* Now do we reduce the time so we don't run dry? */ if (slot && rack_slot_reduction) { reduce = (slot / rack_slot_reduction); if (reduce < slot) { slot -= reduce; } else slot = 0; } slot *= HPTS_USEC_IN_MSEC; if (rack->rc_pace_to_cwnd) { uint64_t rate_wanted = 0; slot = pace_to_fill_cwnd(rack, slot, len, segsiz, NULL, &rate_wanted, 1); rack->rc_ack_can_sendout_data = 1; rack_log_pacing_delay_calc(rack, len, slot, rate_wanted, 0, 0, 14, __LINE__, NULL, 0); } else rack_log_pacing_delay_calc(rack, len, slot, tr_perms, reduce, 0, 7, __LINE__, NULL, 0); } else { uint64_t bw_est, res, lentim, rate_wanted; uint32_t orig_val, segs, oh; int capped = 0; int prev_fill; if ((rack->r_rr_config == 1) && rsm) { return (rack->r_ctl.rc_min_to); } if (rack->use_fixed_rate) { rate_wanted = bw_est = rack_get_fixed_pacing_bw(rack); } else if ((rack->r_ctl.init_rate == 0) && #ifdef NETFLIX_PEAKRATE (rack->rc_tp->t_maxpeakrate == 0) && #endif (rack->r_ctl.gp_bw == 0)) { /* no way to yet do an estimate */ bw_est = rate_wanted = 0; } else { bw_est = rack_get_bw(rack); rate_wanted = rack_get_output_bw(rack, bw_est, rsm, &capped); } if ((bw_est == 0) || (rate_wanted == 0) || ((rack->gp_ready == 0) && (rack->use_fixed_rate == 0))) { /* * No way yet to make a b/w estimate or * our raise is set incorrectly. */ goto old_method; } /* We need to account for all the overheads */ segs = (len + segsiz - 1) / segsiz; /* * We need the diff between 1514 bytes (e-mtu with e-hdr) * and how much data we put in each packet. Yes this * means we may be off if we are larger than 1500 bytes * or smaller. But this just makes us more conservative. */ if (rack_hw_rate_min && (bw_est < rack_hw_rate_min)) can_start_hw_pacing = 0; if (ETHERNET_SEGMENT_SIZE > segsiz) oh = ETHERNET_SEGMENT_SIZE - segsiz; else oh = 0; segs *= oh; lentim = (uint64_t)(len + segs) * (uint64_t)HPTS_USEC_IN_SEC; res = lentim / rate_wanted; slot = (uint32_t)res; orig_val = rack->r_ctl.rc_pace_max_segs; if (rack->r_ctl.crte == NULL) { /* * Only do this if we are not hardware pacing * since if we are doing hw-pacing below we will * set make a call after setting up or changing * the rate. */ rack_set_pace_segments(rack->rc_tp, rack, __LINE__, NULL); } else if (rack->rc_inp->inp_snd_tag == NULL) { /* * We lost our rate somehow, this can happen * if the interface changed underneath us. */ tcp_rel_pacing_rate(rack->r_ctl.crte, rack->rc_tp); rack->r_ctl.crte = NULL; /* Lets re-allow attempting to setup pacing */ rack->rack_hdrw_pacing = 0; rack->rack_attempt_hdwr_pace = 0; rack_log_hdwr_pacing(rack, rate_wanted, bw_est, __LINE__, 0, 6); } /* Did we change the TSO size, if so log it */ if (rack->r_ctl.rc_pace_max_segs != orig_val) rack_log_pacing_delay_calc(rack, len, slot, orig_val, 0, 0, 15, __LINE__, NULL, 0); prev_fill = rack->r_via_fill_cw; if ((rack->rc_pace_to_cwnd) && (capped == 0) && (rack->use_fixed_rate == 0) && (rack->in_probe_rtt == 0) && (IN_FASTRECOVERY(rack->rc_tp->t_flags) == 0)) { /* * We want to pace at our rate *or* faster to * fill the cwnd to the max if its not full. */ slot = pace_to_fill_cwnd(rack, slot, (len+segs), segsiz, &capped, &rate_wanted, 0); } if ((rack->rc_inp->inp_route.ro_nh != NULL) && (rack->rc_inp->inp_route.ro_nh->nh_ifp != NULL)) { if ((rack->rack_hdw_pace_ena) && (can_start_hw_pacing > 0) && (rack->rack_hdrw_pacing == 0) && (rack->rack_attempt_hdwr_pace == 0)) { /* * Lets attempt to turn on hardware pacing * if we can. */ rack->rack_attempt_hdwr_pace = 1; rack->r_ctl.crte = tcp_set_pacing_rate(rack->rc_tp, rack->rc_inp->inp_route.ro_nh->nh_ifp, rate_wanted, RS_PACING_GEQ, &err, &rack->r_ctl.crte_prev_rate); if (rack->r_ctl.crte) { rack->rack_hdrw_pacing = 1; rack->r_ctl.rc_pace_max_segs = tcp_get_pacing_burst_size(tp, rate_wanted, segsiz, 0, rack->r_ctl.crte, NULL); rack_log_hdwr_pacing(rack, rate_wanted, rack->r_ctl.crte->rate, __LINE__, err, 0); rack->r_ctl.last_hw_bw_req = rate_wanted; } else { counter_u64_add(rack_hw_pace_init_fail, 1); } } else if (rack->rack_hdrw_pacing && (rack->r_ctl.last_hw_bw_req != rate_wanted)) { /* Do we need to adjust our rate? */ const struct tcp_hwrate_limit_table *nrte; if (rack->r_up_only && (rate_wanted < rack->r_ctl.crte->rate)) { /** * We have four possible states here * having to do with the previous time * and this time. * previous | this-time * A) 0 | 0 -- fill_cw not in the picture * B) 1 | 0 -- we were doing a fill-cw but now are not * C) 1 | 1 -- all rates from fill_cw * D) 0 | 1 -- we were doing non-fill and now we are filling * * For case A, C and D we don't allow a drop. But for * case B where we now our on our steady rate we do * allow a drop. * */ if (!((prev_fill == 1) && (rack->r_via_fill_cw == 0))) goto done_w_hdwr; } if ((rate_wanted > rack->r_ctl.crte->rate) || (rate_wanted <= rack->r_ctl.crte_prev_rate)) { if (rack_hw_rate_to_low && (bw_est < rack_hw_rate_to_low)) { /* * The pacing rate is too low for hardware, but * do allow hardware pacing to be restarted. */ rack_log_hdwr_pacing(rack, bw_est, rack->r_ctl.crte->rate, __LINE__, 0, 5); tcp_rel_pacing_rate(rack->r_ctl.crte, rack->rc_tp); rack->r_ctl.crte = NULL; rack->rack_attempt_hdwr_pace = 0; rack->rack_hdrw_pacing = 0; rack_set_pace_segments(rack->rc_tp, rack, __LINE__, &rate_wanted); goto done_w_hdwr; } nrte = tcp_chg_pacing_rate(rack->r_ctl.crte, rack->rc_tp, rack->rc_inp->inp_route.ro_nh->nh_ifp, rate_wanted, RS_PACING_GEQ, &err, &rack->r_ctl.crte_prev_rate); if (nrte == NULL) { /* Lost the rate */ rack->rack_hdrw_pacing = 0; rack->r_ctl.crte = NULL; rack_log_hdwr_pacing(rack, rate_wanted, 0, __LINE__, err, 1); rack_set_pace_segments(rack->rc_tp, rack, __LINE__, &rate_wanted); counter_u64_add(rack_hw_pace_lost, 1); } else if (nrte != rack->r_ctl.crte) { rack->r_ctl.crte = nrte; rack->r_ctl.rc_pace_max_segs = tcp_get_pacing_burst_size(tp, rate_wanted, segsiz, 0, rack->r_ctl.crte, NULL); rack_log_hdwr_pacing(rack, rate_wanted, rack->r_ctl.crte->rate, __LINE__, err, 2); rack->r_ctl.last_hw_bw_req = rate_wanted; } } else { /* We just need to adjust the segment size */ rack_set_pace_segments(rack->rc_tp, rack, __LINE__, &rate_wanted); rack_log_hdwr_pacing(rack, rate_wanted, rack->r_ctl.crte->rate, __LINE__, 0, 4); rack->r_ctl.last_hw_bw_req = rate_wanted; } } } if ((rack->r_ctl.crte != NULL) && (rack->r_ctl.crte->rate == rate_wanted)) { /* * We need to add a extra if the rates * are exactly matched. The idea is * we want the software to make sure the * queue is empty before adding more, this * gives us N MSS extra pace times where * N is our sysctl */ slot += (rack->r_ctl.crte->time_between * rack_hw_pace_extra_slots); } done_w_hdwr: if (rack_limit_time_with_srtt && (rack->use_fixed_rate == 0) && #ifdef NETFLIX_PEAKRATE (rack->rc_tp->t_maxpeakrate == 0) && #endif (rack->rack_hdrw_pacing == 0)) { /* * Sanity check, we do not allow the pacing delay * to be longer than the SRTT of the path. If it is * a slow path, then adding a packet should increase * the RTT and compensate for this i.e. the srtt will * be greater so the allowed pacing time will be greater. * * Note this restriction is not for where a peak rate * is set, we are doing fixed pacing or hardware pacing. */ if (rack->rc_tp->t_srtt) srtt = rack->rc_tp->t_srtt; else srtt = RACK_INITIAL_RTO * HPTS_USEC_IN_MSEC; /* its in ms convert */ if (srtt < (uint64_t)slot) { rack_log_pacing_delay_calc(rack, srtt, slot, rate_wanted, bw_est, lentim, 99, __LINE__, NULL, 0); slot = srtt; } } rack_log_pacing_delay_calc(rack, len, slot, rate_wanted, bw_est, lentim, 2, __LINE__, rsm, 0); } if (rack->r_ctl.crte && (rack->r_ctl.crte->rs_num_enobufs > 0)) { /* * If this rate is seeing enobufs when it * goes to send then either the nic is out * of gas or we are mis-estimating the time * somehow and not letting the queue empty * completely. Lets add to the pacing time. */ int hw_boost_delay; hw_boost_delay = rack->r_ctl.crte->time_between * rack_enobuf_hw_boost_mult; if (hw_boost_delay > rack_enobuf_hw_max) hw_boost_delay = rack_enobuf_hw_max; else if (hw_boost_delay < rack_enobuf_hw_min) hw_boost_delay = rack_enobuf_hw_min; slot += hw_boost_delay; } return (slot); } static void rack_start_gp_measurement(struct tcpcb *tp, struct tcp_rack *rack, tcp_seq startseq, uint32_t sb_offset) { struct rack_sendmap *my_rsm = NULL; struct rack_sendmap fe; if (tp->t_state < TCPS_ESTABLISHED) { /* * We don't start any measurements if we are * not at least established. */ return; } if (tp->t_state >= TCPS_FIN_WAIT_1) { /* * We will get no more data into the SB * this means we need to have the data available * before we start a measurement. */ if (sbavail(&tptosocket(tp)->so_snd) < max(rc_init_window(rack), (MIN_GP_WIN * ctf_fixed_maxseg(tp)))) { /* Nope not enough data */ return; } } tp->t_flags |= TF_GPUTINPROG; rack->r_ctl.rc_gp_lowrtt = 0xffffffff; rack->r_ctl.rc_gp_high_rwnd = rack->rc_tp->snd_wnd; tp->gput_seq = startseq; rack->app_limited_needs_set = 0; if (rack->in_probe_rtt) rack->measure_saw_probe_rtt = 1; else if ((rack->measure_saw_probe_rtt) && (SEQ_GEQ(tp->gput_seq, rack->r_ctl.rc_probertt_sndmax_atexit))) rack->measure_saw_probe_rtt = 0; if (rack->rc_gp_filled) tp->gput_ts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); else { /* Special case initial measurement */ struct timeval tv; tp->gput_ts = tcp_get_usecs(&tv); rack->r_ctl.rc_gp_output_ts = rack_to_usec_ts(&tv); } /* * We take a guess out into the future, * if we have no measurement and no * initial rate, we measure the first * initial-windows worth of data to * speed up getting some GP measurement and * thus start pacing. */ if ((rack->rc_gp_filled == 0) && (rack->r_ctl.init_rate == 0)) { rack->app_limited_needs_set = 1; tp->gput_ack = startseq + max(rc_init_window(rack), (MIN_GP_WIN * ctf_fixed_maxseg(tp))); rack_log_pacing_delay_calc(rack, tp->gput_seq, tp->gput_ack, 0, tp->gput_ts, rack->r_ctl.rc_app_limited_cnt, 9, __LINE__, NULL, 0); return; } if (sb_offset) { /* * We are out somewhere in the sb * can we use the already outstanding data? */ if (rack->r_ctl.rc_app_limited_cnt == 0) { /* * Yes first one is good and in this case * the tp->gput_ts is correctly set based on * the last ack that arrived (no need to * set things up when an ack comes in). */ my_rsm = RB_MIN(rack_rb_tree_head, &rack->r_ctl.rc_mtree); if ((my_rsm == NULL) || (my_rsm->r_rtr_cnt != 1)) { /* retransmission? */ goto use_latest; } } else { if (rack->r_ctl.rc_first_appl == NULL) { /* * If rc_first_appl is NULL * then the cnt should be 0. * This is probably an error, maybe * a KASSERT would be approprate. */ goto use_latest; } /* * If we have a marker pointer to the last one that is * app limited we can use that, but we need to set * things up so that when it gets ack'ed we record * the ack time (if its not already acked). */ rack->app_limited_needs_set = 1; /* * We want to get to the rsm that is either * next with space i.e. over 1 MSS or the one * after that (after the app-limited). */ my_rsm = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, rack->r_ctl.rc_first_appl); if (my_rsm) { if ((my_rsm->r_end - my_rsm->r_start) <= ctf_fixed_maxseg(tp)) /* Have to use the next one */ my_rsm = RB_NEXT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, my_rsm); else { /* Use after the first MSS of it is acked */ tp->gput_seq = my_rsm->r_start + ctf_fixed_maxseg(tp); goto start_set; } } if ((my_rsm == NULL) || (my_rsm->r_rtr_cnt != 1)) { /* * Either its a retransmit or * the last is the app-limited one. */ goto use_latest; } } tp->gput_seq = my_rsm->r_start; start_set: if (my_rsm->r_flags & RACK_ACKED) { /* * This one has been acked use the arrival ack time */ tp->gput_ts = (uint32_t)my_rsm->r_ack_arrival; rack->app_limited_needs_set = 0; } rack->r_ctl.rc_gp_output_ts = my_rsm->r_tim_lastsent[(my_rsm->r_rtr_cnt-1)]; tp->gput_ack = tp->gput_seq + rack_get_measure_window(tp, rack); rack_log_pacing_delay_calc(rack, tp->gput_seq, tp->gput_ack, (uint64_t)my_rsm, tp->gput_ts, rack->r_ctl.rc_app_limited_cnt, 9, __LINE__, NULL, 0); return; } use_latest: /* * We don't know how long we may have been * idle or if this is the first-send. Lets * setup the flag so we will trim off * the first ack'd data so we get a true * measurement. */ rack->app_limited_needs_set = 1; tp->gput_ack = startseq + rack_get_measure_window(tp, rack); /* Find this guy so we can pull the send time */ fe.r_start = startseq; my_rsm = RB_FIND(rack_rb_tree_head, &rack->r_ctl.rc_mtree, &fe); if (my_rsm) { rack->r_ctl.rc_gp_output_ts = my_rsm->r_tim_lastsent[(my_rsm->r_rtr_cnt-1)]; if (my_rsm->r_flags & RACK_ACKED) { /* * Unlikely since its probably what was * just transmitted (but I am paranoid). */ tp->gput_ts = (uint32_t)my_rsm->r_ack_arrival; rack->app_limited_needs_set = 0; } if (SEQ_LT(my_rsm->r_start, tp->gput_seq)) { /* This also is unlikely */ tp->gput_seq = my_rsm->r_start; } } else { /* * TSNH unless we have some send-map limit, * and even at that it should not be hitting * that limit (we should have stopped sending). */ struct timeval tv; microuptime(&tv); rack->r_ctl.rc_gp_output_ts = rack_to_usec_ts(&tv); } rack_log_pacing_delay_calc(rack, tp->gput_seq, tp->gput_ack, (uint64_t)my_rsm, tp->gput_ts, rack->r_ctl.rc_app_limited_cnt, 9, __LINE__, NULL, 0); } static inline uint32_t rack_what_can_we_send(struct tcpcb *tp, struct tcp_rack *rack, uint32_t cwnd_to_use, uint32_t avail, int32_t sb_offset) { uint32_t len; uint32_t sendwin; if (tp->snd_wnd > cwnd_to_use) sendwin = cwnd_to_use; else sendwin = tp->snd_wnd; if (ctf_outstanding(tp) >= tp->snd_wnd) { /* We never want to go over our peers rcv-window */ len = 0; } else { uint32_t flight; flight = ctf_flight_size(tp, rack->r_ctl.rc_sacked); if (flight >= sendwin) { /* * We have in flight what we are allowed by cwnd (if * it was rwnd blocking it would have hit above out * >= tp->snd_wnd). */ return (0); } len = sendwin - flight; if ((len + ctf_outstanding(tp)) > tp->snd_wnd) { /* We would send too much (beyond the rwnd) */ len = tp->snd_wnd - ctf_outstanding(tp); } if ((len + sb_offset) > avail) { /* * We don't have that much in the SB, how much is * there? */ len = avail - sb_offset; } } return (len); } static void rack_log_fsb(struct tcp_rack *rack, struct tcpcb *tp, struct socket *so, uint32_t flags, unsigned ipoptlen, int32_t orig_len, int32_t len, int error, int rsm_is_null, int optlen, int line, uint16_t mode) { if (tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); log.u_bbr.flex1 = error; log.u_bbr.flex2 = flags; log.u_bbr.flex3 = rsm_is_null; log.u_bbr.flex4 = ipoptlen; log.u_bbr.flex5 = tp->rcv_numsacks; log.u_bbr.flex6 = rack->r_ctl.rc_agg_early; log.u_bbr.flex7 = optlen; log.u_bbr.flex8 = rack->r_fsb_inited; log.u_bbr.applimited = rack->r_fast_output; log.u_bbr.bw_inuse = rack_get_bw(rack); log.u_bbr.pacing_gain = rack_get_output_gain(rack, NULL); log.u_bbr.cwnd_gain = mode; log.u_bbr.pkts_out = orig_len; log.u_bbr.lt_epoch = len; log.u_bbr.delivered = line; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); tcp_log_event_(tp, NULL, &so->so_rcv, &so->so_snd, TCP_LOG_FSB, 0, len, &log, false, NULL, NULL, 0, &tv); } } static struct mbuf * rack_fo_base_copym(struct mbuf *the_m, uint32_t the_off, int32_t *plen, struct rack_fast_send_blk *fsb, int32_t seglimit, int32_t segsize, int hw_tls) { #ifdef KERN_TLS struct ktls_session *tls, *ntls; #ifdef INVARIANTS struct mbuf *start; #endif #endif struct mbuf *m, *n, **np, *smb; struct mbuf *top; int32_t off, soff; int32_t len = *plen; int32_t fragsize; int32_t len_cp = 0; uint32_t mlen, frags; soff = off = the_off; smb = m = the_m; np = ⊤ top = NULL; #ifdef KERN_TLS if (hw_tls && (m->m_flags & M_EXTPG)) tls = m->m_epg_tls; else tls = NULL; #ifdef INVARIANTS start = m; #endif #endif while (len > 0) { if (m == NULL) { *plen = len_cp; break; } #ifdef KERN_TLS if (hw_tls) { if (m->m_flags & M_EXTPG) ntls = m->m_epg_tls; else ntls = NULL; /* * Avoid mixing TLS records with handshake * data or TLS records from different * sessions. */ if (tls != ntls) { MPASS(m != start); *plen = len_cp; break; } } #endif mlen = min(len, m->m_len - off); if (seglimit) { /* * For M_EXTPG mbufs, add 3 segments * + 1 in case we are crossing page boundaries * + 2 in case the TLS hdr/trailer are used * It is cheaper to just add the segments * than it is to take the cache miss to look * at the mbuf ext_pgs state in detail. */ if (m->m_flags & M_EXTPG) { fragsize = min(segsize, PAGE_SIZE); frags = 3; } else { fragsize = segsize; frags = 0; } /* Break if we really can't fit anymore. */ if ((frags + 1) >= seglimit) { *plen = len_cp; break; } /* * Reduce size if you can't copy the whole * mbuf. If we can't copy the whole mbuf, also * adjust len so the loop will end after this * mbuf. */ if ((frags + howmany(mlen, fragsize)) >= seglimit) { mlen = (seglimit - frags - 1) * fragsize; len = mlen; *plen = len_cp + len; } frags += howmany(mlen, fragsize); if (frags == 0) frags++; seglimit -= frags; KASSERT(seglimit > 0, ("%s: seglimit went too low", __func__)); } n = m_get(M_NOWAIT, m->m_type); *np = n; if (n == NULL) goto nospace; n->m_len = mlen; soff += mlen; len_cp += n->m_len; if (m->m_flags & (M_EXT|M_EXTPG)) { n->m_data = m->m_data + off; mb_dupcl(n, m); } else { bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t), (u_int)n->m_len); } len -= n->m_len; off = 0; m = m->m_next; np = &n->m_next; if (len || (soff == smb->m_len)) { /* * We have more so we move forward or * we have consumed the entire mbuf and * len has fell to 0. */ soff = 0; smb = m; } } if (fsb != NULL) { fsb->m = smb; fsb->off = soff; if (smb) { /* * Save off the size of the mbuf. We do * this so that we can recognize when it * has been trimmed by sbcut() as acks * come in. */ fsb->o_m_len = smb->m_len; } else { /* * This is the case where the next mbuf went to NULL. This * means with this copy we have sent everything in the sb. * In theory we could clear the fast_output flag, but lets * not since its possible that we could get more added * and acks that call the extend function which would let * us send more. */ fsb->o_m_len = 0; } } return (top); nospace: if (top) m_freem(top); return (NULL); } /* * This is a copy of m_copym(), taking the TSO segment size/limit * constraints into account, and advancing the sndptr as it goes. */ static struct mbuf * rack_fo_m_copym(struct tcp_rack *rack, int32_t *plen, int32_t seglimit, int32_t segsize, struct mbuf **s_mb, int *s_soff) { struct mbuf *m, *n; int32_t soff; soff = rack->r_ctl.fsb.off; m = rack->r_ctl.fsb.m; if (rack->r_ctl.fsb.o_m_len > m->m_len) { /* * The mbuf had the front of it chopped off by an ack * we need to adjust the soff/off by that difference. */ uint32_t delta; delta = rack->r_ctl.fsb.o_m_len - m->m_len; soff -= delta; } else if (rack->r_ctl.fsb.o_m_len < m->m_len) { /* * The mbuf was expanded probably by * a m_compress. Just update o_m_len. */ rack->r_ctl.fsb.o_m_len = m->m_len; } KASSERT(soff >= 0, ("%s, negative off %d", __FUNCTION__, soff)); KASSERT(*plen >= 0, ("%s, negative len %d", __FUNCTION__, *plen)); KASSERT(soff < m->m_len, ("%s rack:%p len:%u m:%p m->m_len:%u < off?", __FUNCTION__, rack, *plen, m, m->m_len)); /* Save off the right location before we copy and advance */ *s_soff = soff; *s_mb = rack->r_ctl.fsb.m; n = rack_fo_base_copym(m, soff, plen, &rack->r_ctl.fsb, seglimit, segsize, rack->r_ctl.fsb.hw_tls); return (n); } static int rack_fast_rsm_output(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendmap *rsm, uint64_t ts_val, uint32_t cts, uint32_t ms_cts, struct timeval *tv, int len, uint8_t doing_tlp) { /* * Enter the fast retransmit path. We are given that a sched_pin is * in place (if accounting is compliled in) and the cycle count taken * at the entry is in the ts_val. The concept her is that the rsm * now holds the mbuf offsets and such so we can directly transmit * without a lot of overhead, the len field is already set for * us to prohibit us from sending too much (usually its 1MSS). */ struct ip *ip = NULL; struct udphdr *udp = NULL; struct tcphdr *th = NULL; struct mbuf *m = NULL; struct inpcb *inp; uint8_t *cpto; struct tcp_log_buffer *lgb; #ifdef TCP_ACCOUNTING uint64_t crtsc; int cnt_thru = 1; #endif struct tcpopt to; u_char opt[TCP_MAXOLEN]; uint32_t hdrlen, optlen; int32_t slot, segsiz, max_val, tso = 0, error, ulen = 0; uint16_t flags; uint32_t if_hw_tsomaxsegcount = 0, startseq; uint32_t if_hw_tsomaxsegsize; #ifdef INET6 struct ip6_hdr *ip6 = NULL; if (rack->r_is_v6) { ip6 = (struct ip6_hdr *)rack->r_ctl.fsb.tcp_ip_hdr; hdrlen = sizeof(struct ip6_hdr) + sizeof(struct tcphdr); } else #endif /* INET6 */ { ip = (struct ip *)rack->r_ctl.fsb.tcp_ip_hdr; hdrlen = sizeof(struct tcpiphdr); } if (tp->t_port && (V_tcp_udp_tunneling_port == 0)) { goto failed; } if (doing_tlp) { /* Its a TLP add the flag, it may already be there but be sure */ rsm->r_flags |= RACK_TLP; } else { /* If it was a TLP it is not not on this retransmit */ rsm->r_flags &= ~RACK_TLP; } startseq = rsm->r_start; segsiz = min(ctf_fixed_maxseg(tp), rack->r_ctl.rc_pace_min_segs); inp = rack->rc_inp; to.to_flags = 0; flags = tcp_outflags[tp->t_state]; if (flags & (TH_SYN|TH_RST)) { goto failed; } if (rsm->r_flags & RACK_HAS_FIN) { /* We can't send a FIN here */ goto failed; } if (flags & TH_FIN) { /* We never send a FIN */ flags &= ~TH_FIN; } if (tp->t_flags & TF_RCVD_TSTMP) { to.to_tsval = ms_cts + tp->ts_offset; to.to_tsecr = tp->ts_recent; to.to_flags = TOF_TS; } optlen = tcp_addoptions(&to, opt); hdrlen += optlen; udp = rack->r_ctl.fsb.udp; if (udp) hdrlen += sizeof(struct udphdr); if (rack->r_ctl.rc_pace_max_segs) max_val = rack->r_ctl.rc_pace_max_segs; else if (rack->rc_user_set_max_segs) max_val = rack->rc_user_set_max_segs * segsiz; else max_val = len; if ((tp->t_flags & TF_TSO) && V_tcp_do_tso && (len > segsiz) && (tp->t_port == 0)) tso = 1; #ifdef INET6 if (MHLEN < hdrlen + max_linkhdr) m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); else #endif m = m_gethdr(M_NOWAIT, MT_DATA); if (m == NULL) goto failed; m->m_data += max_linkhdr; m->m_len = hdrlen; th = rack->r_ctl.fsb.th; /* Establish the len to send */ if (len > max_val) len = max_val; if ((tso) && (len + optlen > tp->t_maxseg)) { uint32_t if_hw_tsomax; int32_t max_len; /* extract TSO information */ if_hw_tsomax = tp->t_tsomax; if_hw_tsomaxsegcount = tp->t_tsomaxsegcount; if_hw_tsomaxsegsize = tp->t_tsomaxsegsize; /* * Check if we should limit by maximum payload * length: */ if (if_hw_tsomax != 0) { /* compute maximum TSO length */ max_len = (if_hw_tsomax - hdrlen - max_linkhdr); if (max_len <= 0) { goto failed; } else if (len > max_len) { len = max_len; } } if (len <= segsiz) { /* * In case there are too many small fragments don't * use TSO: */ tso = 0; } } else { tso = 0; } if ((tso == 0) && (len > segsiz)) len = segsiz; if ((len == 0) || (len <= MHLEN - hdrlen - max_linkhdr)) { goto failed; } th->th_seq = htonl(rsm->r_start); th->th_ack = htonl(tp->rcv_nxt); /* * The PUSH bit should only be applied * if the full retransmission is made. If * we are sending less than this is the * left hand edge and should not have * the PUSH bit. */ if ((rsm->r_flags & RACK_HAD_PUSH) && (len == (rsm->r_end - rsm->r_start))) flags |= TH_PUSH; th->th_win = htons((u_short)(rack->r_ctl.fsb.recwin >> tp->rcv_scale)); if (th->th_win == 0) { tp->t_sndzerowin++; tp->t_flags |= TF_RXWIN0SENT; } else tp->t_flags &= ~TF_RXWIN0SENT; if (rsm->r_flags & RACK_TLP) { /* * TLP should not count in retran count, but * in its own bin */ counter_u64_add(rack_tlp_retran, 1); counter_u64_add(rack_tlp_retran_bytes, len); } else { tp->t_sndrexmitpack++; KMOD_TCPSTAT_INC(tcps_sndrexmitpack); KMOD_TCPSTAT_ADD(tcps_sndrexmitbyte, len); } #ifdef STATS stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RETXPB, len); #endif if (rsm->m == NULL) goto failed; if (rsm->orig_m_len != rsm->m->m_len) { /* Fix up the orig_m_len and possibly the mbuf offset */ rack_adjust_orig_mlen(rsm); } m->m_next = rack_fo_base_copym(rsm->m, rsm->soff, &len, NULL, if_hw_tsomaxsegcount, if_hw_tsomaxsegsize, rsm->r_hw_tls); if (len <= segsiz) { /* * Must have ran out of mbufs for the copy * shorten it to no longer need tso. Lets * not put on sendalot since we are low on * mbufs. */ tso = 0; } if ((m->m_next == NULL) || (len <= 0)){ goto failed; } if (udp) { if (rack->r_is_v6) ulen = hdrlen + len - sizeof(struct ip6_hdr); else ulen = hdrlen + len - sizeof(struct ip); udp->uh_ulen = htons(ulen); } m->m_pkthdr.rcvif = (struct ifnet *)0; if (TCPS_HAVERCVDSYN(tp->t_state) && (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT))) { int ect = tcp_ecn_output_established(tp, &flags, len, true); if ((tp->t_state == TCPS_SYN_RECEIVED) && (tp->t_flags2 & TF2_ECN_SND_ECE)) tp->t_flags2 &= ~TF2_ECN_SND_ECE; #ifdef INET6 if (rack->r_is_v6) { ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20); ip6->ip6_flow |= htonl(ect << 20); } else #endif { ip->ip_tos &= ~IPTOS_ECN_MASK; ip->ip_tos |= ect; } } tcp_set_flags(th, flags); m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */ #ifdef INET6 if (rack->r_is_v6) { if (tp->t_port) { m->m_pkthdr.csum_flags = CSUM_UDP_IPV6; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); udp->uh_sum = in6_cksum_pseudo(ip6, ulen, IPPROTO_UDP, 0); th->th_sum = htons(0); UDPSTAT_INC(udps_opackets); } else { m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); th->th_sum = in6_cksum_pseudo(ip6, sizeof(struct tcphdr) + optlen + len, IPPROTO_TCP, 0); } } #endif #if defined(INET6) && defined(INET) else #endif #ifdef INET { if (tp->t_port) { m->m_pkthdr.csum_flags = CSUM_UDP; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(ulen + IPPROTO_UDP)); th->th_sum = htons(0); UDPSTAT_INC(udps_opackets); } else { m->m_pkthdr.csum_flags = CSUM_TCP; m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(sizeof(struct tcphdr) + IPPROTO_TCP + len + optlen)); } /* IP version must be set here for ipv4/ipv6 checking later */ KASSERT(ip->ip_v == IPVERSION, ("%s: IP version incorrect: %d", __func__, ip->ip_v)); } #endif if (tso) { KASSERT(len > tp->t_maxseg - optlen, ("%s: len <= tso_segsz tp:%p", __func__, tp)); m->m_pkthdr.csum_flags |= CSUM_TSO; m->m_pkthdr.tso_segsz = tp->t_maxseg - optlen; } #ifdef INET6 if (rack->r_is_v6) { ip6->ip6_hlim = rack->r_ctl.fsb.hoplimit; ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); if (V_path_mtu_discovery && tp->t_maxseg > V_tcp_minmss) tp->t_flags2 |= TF2_PLPMTU_PMTUD; else tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; } #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET { ip->ip_len = htons(m->m_pkthdr.len); ip->ip_ttl = rack->r_ctl.fsb.hoplimit; if (V_path_mtu_discovery && tp->t_maxseg > V_tcp_minmss) { tp->t_flags2 |= TF2_PLPMTU_PMTUD; if (tp->t_port == 0 || len < V_tcp_minmss) { ip->ip_off |= htons(IP_DF); } } else { tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; } } #endif /* Time to copy in our header */ cpto = mtod(m, uint8_t *); memcpy(cpto, rack->r_ctl.fsb.tcp_ip_hdr, rack->r_ctl.fsb.tcp_ip_hdr_len); th = (struct tcphdr *)(cpto + ((uint8_t *)rack->r_ctl.fsb.th - rack->r_ctl.fsb.tcp_ip_hdr)); if (optlen) { bcopy(opt, th + 1, optlen); th->th_off = (sizeof(struct tcphdr) + optlen) >> 2; } else { th->th_off = sizeof(struct tcphdr) >> 2; } if (tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; if (rsm->r_flags & RACK_RWND_COLLAPSED) { rack_log_collapse(rack, rsm->r_start, rsm->r_end, 0, __LINE__, 5, rsm->r_flags, rsm); counter_u64_add(rack_collapsed_win_rxt, 1); counter_u64_add(rack_collapsed_win_rxt_bytes, (rsm->r_end - rsm->r_start)); } memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); if (rack->rack_no_prr) log.u_bbr.flex1 = 0; else log.u_bbr.flex1 = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.flex2 = rack->r_ctl.rc_pace_min_segs; log.u_bbr.flex3 = rack->r_ctl.rc_pace_max_segs; log.u_bbr.flex4 = max_val; log.u_bbr.flex5 = 0; /* Save off the early/late values */ log.u_bbr.flex6 = rack->r_ctl.rc_agg_early; log.u_bbr.applimited = rack->r_ctl.rc_agg_delayed; log.u_bbr.bw_inuse = rack_get_bw(rack); if (doing_tlp == 0) log.u_bbr.flex8 = 1; else log.u_bbr.flex8 = 2; log.u_bbr.pacing_gain = rack_get_output_gain(rack, NULL); log.u_bbr.flex7 = 55; log.u_bbr.pkts_out = tp->t_maxseg; log.u_bbr.timeStamp = cts; log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.lt_epoch = rack->r_ctl.cwnd_to_use; log.u_bbr.delivered = 0; lgb = tcp_log_event_(tp, th, NULL, NULL, TCP_LOG_OUT, ERRNO_UNK, len, &log, false, NULL, NULL, 0, tv); } else lgb = NULL; #ifdef INET6 if (rack->r_is_v6) { error = ip6_output(m, NULL, &inp->inp_route6, 0, NULL, NULL, inp); } #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET { error = ip_output(m, NULL, &inp->inp_route, 0, 0, inp); } #endif m = NULL; if (lgb) { lgb->tlb_errno = error; lgb = NULL; } if (error) { goto failed; } rack_log_output(tp, &to, len, rsm->r_start, flags, error, rack_to_usec_ts(tv), rsm, RACK_SENT_FP, rsm->m, rsm->soff, rsm->r_hw_tls); if (doing_tlp && (rack->fast_rsm_hack == 0)) { rack->rc_tlp_in_progress = 1; rack->r_ctl.rc_tlp_cnt_out++; } if (error == 0) { tcp_account_for_send(tp, len, 1, doing_tlp, rsm->r_hw_tls); if (doing_tlp) { rack->rc_last_sent_tlp_past_cumack = 0; rack->rc_last_sent_tlp_seq_valid = 1; rack->r_ctl.last_sent_tlp_seq = rsm->r_start; rack->r_ctl.last_sent_tlp_len = rsm->r_end - rsm->r_start; } } tp->t_flags &= ~(TF_ACKNOW | TF_DELACK); rack->forced_ack = 0; /* If we send something zap the FA flag */ if (IN_FASTRECOVERY(tp->t_flags) && rsm) rack->r_ctl.retran_during_recovery += len; { int idx; idx = (len / segsiz) + 3; if (idx >= TCP_MSS_ACCT_ATIMER) counter_u64_add(rack_out_size[(TCP_MSS_ACCT_ATIMER-1)], 1); else counter_u64_add(rack_out_size[idx], 1); } if (tp->t_rtttime == 0) { tp->t_rtttime = ticks; tp->t_rtseq = startseq; KMOD_TCPSTAT_INC(tcps_segstimed); } counter_u64_add(rack_fto_rsm_send, 1); if (error && (error == ENOBUFS)) { if (rack->r_ctl.crte != NULL) { rack_trace_point(rack, RACK_TP_HWENOBUF); } else rack_trace_point(rack, RACK_TP_ENOBUF); slot = ((1 + rack->rc_enobuf) * HPTS_USEC_IN_MSEC); if (rack->rc_enobuf < 0x7f) rack->rc_enobuf++; if (slot < (10 * HPTS_USEC_IN_MSEC)) slot = 10 * HPTS_USEC_IN_MSEC; } else slot = rack_get_pacing_delay(rack, tp, len, NULL, segsiz); if ((slot == 0) || (rack->rc_always_pace == 0) || (rack->r_rr_config == 1)) { /* * We have no pacing set or we * are using old-style rack or * we are overridden to use the old 1ms pacing. */ slot = rack->r_ctl.rc_min_to; } rack_start_hpts_timer(rack, tp, cts, slot, len, 0); #ifdef TCP_ACCOUNTING crtsc = get_cyclecount(); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[SND_OUT_DATA] += cnt_thru; } counter_u64_add(tcp_cnt_counters[SND_OUT_DATA], cnt_thru); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[SND_OUT_DATA] += (crtsc - ts_val); } counter_u64_add(tcp_proc_time[SND_OUT_DATA], (crtsc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[CNT_OF_MSS_OUT] += ((len + segsiz - 1) / segsiz); } counter_u64_add(tcp_cnt_counters[CNT_OF_MSS_OUT], ((len + segsiz - 1) / segsiz)); sched_unpin(); #endif return (0); failed: if (m) m_free(m); return (-1); } static void rack_sndbuf_autoscale(struct tcp_rack *rack) { /* * Automatic sizing of send socket buffer. Often the send buffer * size is not optimally adjusted to the actual network conditions * at hand (delay bandwidth product). Setting the buffer size too * small limits throughput on links with high bandwidth and high * delay (eg. trans-continental/oceanic links). Setting the * buffer size too big consumes too much real kernel memory, * especially with many connections on busy servers. * * The criteria to step up the send buffer one notch are: * 1. receive window of remote host is larger than send buffer * (with a fudge factor of 5/4th); * 2. send buffer is filled to 7/8th with data (so we actually * have data to make use of it); * 3. send buffer fill has not hit maximal automatic size; * 4. our send window (slow start and cogestion controlled) is * larger than sent but unacknowledged data in send buffer. * * Note that the rack version moves things much faster since * we want to avoid hitting cache lines in the rack_fast_output() * path so this is called much less often and thus moves * the SB forward by a percentage. */ struct socket *so; struct tcpcb *tp; uint32_t sendwin, scaleup; tp = rack->rc_tp; so = rack->rc_inp->inp_socket; sendwin = min(rack->r_ctl.cwnd_to_use, tp->snd_wnd); if (V_tcp_do_autosndbuf && so->so_snd.sb_flags & SB_AUTOSIZE) { if ((tp->snd_wnd / 4 * 5) >= so->so_snd.sb_hiwat && sbused(&so->so_snd) >= (so->so_snd.sb_hiwat / 8 * 7) && sbused(&so->so_snd) < V_tcp_autosndbuf_max && sendwin >= (sbused(&so->so_snd) - (tp->snd_nxt - tp->snd_una))) { if (rack_autosndbuf_inc) scaleup = (rack_autosndbuf_inc * so->so_snd.sb_hiwat) / 100; else scaleup = V_tcp_autosndbuf_inc; if (scaleup < V_tcp_autosndbuf_inc) scaleup = V_tcp_autosndbuf_inc; scaleup += so->so_snd.sb_hiwat; if (scaleup > V_tcp_autosndbuf_max) scaleup = V_tcp_autosndbuf_max; if (!sbreserve_locked(so, SO_SND, scaleup, curthread)) so->so_snd.sb_flags &= ~SB_AUTOSIZE; } } } static int rack_fast_output(struct tcpcb *tp, struct tcp_rack *rack, uint64_t ts_val, uint32_t cts, uint32_t ms_cts, struct timeval *tv, long tot_len, int *send_err) { /* * Enter to do fast output. We are given that the sched_pin is * in place (if accounting is compiled in) and the cycle count taken * at entry is in place in ts_val. The idea here is that * we know how many more bytes needs to be sent (presumably either * during pacing or to fill the cwnd and that was greater than * the max-burst). We have how much to send and all the info we * need to just send. */ struct ip *ip = NULL; struct udphdr *udp = NULL; struct tcphdr *th = NULL; struct mbuf *m, *s_mb; struct inpcb *inp; uint8_t *cpto; struct tcp_log_buffer *lgb; #ifdef TCP_ACCOUNTING uint64_t crtsc; #endif struct tcpopt to; u_char opt[TCP_MAXOLEN]; uint32_t hdrlen, optlen; #ifdef TCP_ACCOUNTING int cnt_thru = 1; #endif int32_t slot, segsiz, len, max_val, tso = 0, sb_offset, error, ulen = 0; uint16_t flags; uint32_t s_soff; uint32_t if_hw_tsomaxsegcount = 0, startseq; uint32_t if_hw_tsomaxsegsize; uint16_t add_flag = RACK_SENT_FP; #ifdef INET6 struct ip6_hdr *ip6 = NULL; if (rack->r_is_v6) { ip6 = (struct ip6_hdr *)rack->r_ctl.fsb.tcp_ip_hdr; hdrlen = sizeof(struct ip6_hdr) + sizeof(struct tcphdr); } else #endif /* INET6 */ { ip = (struct ip *)rack->r_ctl.fsb.tcp_ip_hdr; hdrlen = sizeof(struct tcpiphdr); } if (tp->t_port && (V_tcp_udp_tunneling_port == 0)) { m = NULL; goto failed; } startseq = tp->snd_max; segsiz = min(ctf_fixed_maxseg(tp), rack->r_ctl.rc_pace_min_segs); inp = rack->rc_inp; len = rack->r_ctl.fsb.left_to_send; to.to_flags = 0; flags = rack->r_ctl.fsb.tcp_flags; if (tp->t_flags & TF_RCVD_TSTMP) { to.to_tsval = ms_cts + tp->ts_offset; to.to_tsecr = tp->ts_recent; to.to_flags = TOF_TS; } optlen = tcp_addoptions(&to, opt); hdrlen += optlen; udp = rack->r_ctl.fsb.udp; if (udp) hdrlen += sizeof(struct udphdr); if (rack->r_ctl.rc_pace_max_segs) max_val = rack->r_ctl.rc_pace_max_segs; else if (rack->rc_user_set_max_segs) max_val = rack->rc_user_set_max_segs * segsiz; else max_val = len; if ((tp->t_flags & TF_TSO) && V_tcp_do_tso && (len > segsiz) && (tp->t_port == 0)) tso = 1; again: #ifdef INET6 if (MHLEN < hdrlen + max_linkhdr) m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); else #endif m = m_gethdr(M_NOWAIT, MT_DATA); if (m == NULL) goto failed; m->m_data += max_linkhdr; m->m_len = hdrlen; th = rack->r_ctl.fsb.th; /* Establish the len to send */ if (len > max_val) len = max_val; if ((tso) && (len + optlen > tp->t_maxseg)) { uint32_t if_hw_tsomax; int32_t max_len; /* extract TSO information */ if_hw_tsomax = tp->t_tsomax; if_hw_tsomaxsegcount = tp->t_tsomaxsegcount; if_hw_tsomaxsegsize = tp->t_tsomaxsegsize; /* * Check if we should limit by maximum payload * length: */ if (if_hw_tsomax != 0) { /* compute maximum TSO length */ max_len = (if_hw_tsomax - hdrlen - max_linkhdr); if (max_len <= 0) { goto failed; } else if (len > max_len) { len = max_len; } } if (len <= segsiz) { /* * In case there are too many small fragments don't * use TSO: */ tso = 0; } } else { tso = 0; } if ((tso == 0) && (len > segsiz)) len = segsiz; if ((len == 0) || (len <= MHLEN - hdrlen - max_linkhdr)) { goto failed; } sb_offset = tp->snd_max - tp->snd_una; th->th_seq = htonl(tp->snd_max); th->th_ack = htonl(tp->rcv_nxt); th->th_win = htons((u_short)(rack->r_ctl.fsb.recwin >> tp->rcv_scale)); if (th->th_win == 0) { tp->t_sndzerowin++; tp->t_flags |= TF_RXWIN0SENT; } else tp->t_flags &= ~TF_RXWIN0SENT; tp->snd_up = tp->snd_una; /* drag it along, its deprecated */ KMOD_TCPSTAT_INC(tcps_sndpack); KMOD_TCPSTAT_ADD(tcps_sndbyte, len); #ifdef STATS stats_voi_update_abs_u64(tp->t_stats, VOI_TCP_TXPB, len); #endif if (rack->r_ctl.fsb.m == NULL) goto failed; /* s_mb and s_soff are saved for rack_log_output */ m->m_next = rack_fo_m_copym(rack, &len, if_hw_tsomaxsegcount, if_hw_tsomaxsegsize, &s_mb, &s_soff); if (len <= segsiz) { /* * Must have ran out of mbufs for the copy * shorten it to no longer need tso. Lets * not put on sendalot since we are low on * mbufs. */ tso = 0; } if (rack->r_ctl.fsb.rfo_apply_push && (len == rack->r_ctl.fsb.left_to_send)) { flags |= TH_PUSH; add_flag |= RACK_HAD_PUSH; } if ((m->m_next == NULL) || (len <= 0)){ goto failed; } if (udp) { if (rack->r_is_v6) ulen = hdrlen + len - sizeof(struct ip6_hdr); else ulen = hdrlen + len - sizeof(struct ip); udp->uh_ulen = htons(ulen); } m->m_pkthdr.rcvif = (struct ifnet *)0; if (TCPS_HAVERCVDSYN(tp->t_state) && (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT))) { int ect = tcp_ecn_output_established(tp, &flags, len, false); if ((tp->t_state == TCPS_SYN_RECEIVED) && (tp->t_flags2 & TF2_ECN_SND_ECE)) tp->t_flags2 &= ~TF2_ECN_SND_ECE; #ifdef INET6 if (rack->r_is_v6) { ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20); ip6->ip6_flow |= htonl(ect << 20); } else #endif { ip->ip_tos &= ~IPTOS_ECN_MASK; ip->ip_tos |= ect; } } tcp_set_flags(th, flags); m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */ #ifdef INET6 if (rack->r_is_v6) { if (tp->t_port) { m->m_pkthdr.csum_flags = CSUM_UDP_IPV6; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); udp->uh_sum = in6_cksum_pseudo(ip6, ulen, IPPROTO_UDP, 0); th->th_sum = htons(0); UDPSTAT_INC(udps_opackets); } else { m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); th->th_sum = in6_cksum_pseudo(ip6, sizeof(struct tcphdr) + optlen + len, IPPROTO_TCP, 0); } } #endif #if defined(INET6) && defined(INET) else #endif #ifdef INET { if (tp->t_port) { m->m_pkthdr.csum_flags = CSUM_UDP; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(ulen + IPPROTO_UDP)); th->th_sum = htons(0); UDPSTAT_INC(udps_opackets); } else { m->m_pkthdr.csum_flags = CSUM_TCP; m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(sizeof(struct tcphdr) + IPPROTO_TCP + len + optlen)); } /* IP version must be set here for ipv4/ipv6 checking later */ KASSERT(ip->ip_v == IPVERSION, ("%s: IP version incorrect: %d", __func__, ip->ip_v)); } #endif if (tso) { KASSERT(len > tp->t_maxseg - optlen, ("%s: len <= tso_segsz tp:%p", __func__, tp)); m->m_pkthdr.csum_flags |= CSUM_TSO; m->m_pkthdr.tso_segsz = tp->t_maxseg - optlen; } #ifdef INET6 if (rack->r_is_v6) { ip6->ip6_hlim = rack->r_ctl.fsb.hoplimit; ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); if (V_path_mtu_discovery && tp->t_maxseg > V_tcp_minmss) tp->t_flags2 |= TF2_PLPMTU_PMTUD; else tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; } #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET { ip->ip_len = htons(m->m_pkthdr.len); ip->ip_ttl = rack->r_ctl.fsb.hoplimit; if (V_path_mtu_discovery && tp->t_maxseg > V_tcp_minmss) { tp->t_flags2 |= TF2_PLPMTU_PMTUD; if (tp->t_port == 0 || len < V_tcp_minmss) { ip->ip_off |= htons(IP_DF); } } else { tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; } } #endif /* Time to copy in our header */ cpto = mtod(m, uint8_t *); memcpy(cpto, rack->r_ctl.fsb.tcp_ip_hdr, rack->r_ctl.fsb.tcp_ip_hdr_len); th = (struct tcphdr *)(cpto + ((uint8_t *)rack->r_ctl.fsb.th - rack->r_ctl.fsb.tcp_ip_hdr)); if (optlen) { bcopy(opt, th + 1, optlen); th->th_off = (sizeof(struct tcphdr) + optlen) >> 2; } else { th->th_off = sizeof(struct tcphdr) >> 2; } if (tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); if (rack->rack_no_prr) log.u_bbr.flex1 = 0; else log.u_bbr.flex1 = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.flex2 = rack->r_ctl.rc_pace_min_segs; log.u_bbr.flex3 = rack->r_ctl.rc_pace_max_segs; log.u_bbr.flex4 = max_val; log.u_bbr.flex5 = 0; /* Save off the early/late values */ log.u_bbr.flex6 = rack->r_ctl.rc_agg_early; log.u_bbr.applimited = rack->r_ctl.rc_agg_delayed; log.u_bbr.bw_inuse = rack_get_bw(rack); log.u_bbr.flex8 = 0; log.u_bbr.pacing_gain = rack_get_output_gain(rack, NULL); log.u_bbr.flex7 = 44; log.u_bbr.pkts_out = tp->t_maxseg; log.u_bbr.timeStamp = cts; log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.lt_epoch = rack->r_ctl.cwnd_to_use; log.u_bbr.delivered = 0; lgb = tcp_log_event_(tp, th, NULL, NULL, TCP_LOG_OUT, ERRNO_UNK, len, &log, false, NULL, NULL, 0, tv); } else lgb = NULL; #ifdef INET6 if (rack->r_is_v6) { error = ip6_output(m, NULL, &inp->inp_route6, 0, NULL, NULL, inp); } #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET { error = ip_output(m, NULL, &inp->inp_route, 0, 0, inp); } #endif if (lgb) { lgb->tlb_errno = error; lgb = NULL; } if (error) { *send_err = error; m = NULL; goto failed; } rack_log_output(tp, &to, len, tp->snd_max, flags, error, rack_to_usec_ts(tv), NULL, add_flag, s_mb, s_soff, rack->r_ctl.fsb.hw_tls); m = NULL; if (tp->snd_una == tp->snd_max) { rack->r_ctl.rc_tlp_rxt_last_time = cts; rack_log_progress_event(rack, tp, ticks, PROGRESS_START, __LINE__); tp->t_acktime = ticks; } if (error == 0) tcp_account_for_send(tp, len, 0, 0, rack->r_ctl.fsb.hw_tls); rack->forced_ack = 0; /* If we send something zap the FA flag */ tot_len += len; if ((tp->t_flags & TF_GPUTINPROG) == 0) rack_start_gp_measurement(tp, rack, tp->snd_max, sb_offset); tp->snd_max += len; tp->snd_nxt = tp->snd_max; { int idx; idx = (len / segsiz) + 3; if (idx >= TCP_MSS_ACCT_ATIMER) counter_u64_add(rack_out_size[(TCP_MSS_ACCT_ATIMER-1)], 1); else counter_u64_add(rack_out_size[idx], 1); } if (len <= rack->r_ctl.fsb.left_to_send) rack->r_ctl.fsb.left_to_send -= len; else rack->r_ctl.fsb.left_to_send = 0; if (rack->r_ctl.fsb.left_to_send < segsiz) { rack->r_fast_output = 0; rack->r_ctl.fsb.left_to_send = 0; /* At the end of fast_output scale up the sb */ SOCKBUF_LOCK(&rack->rc_inp->inp_socket->so_snd); rack_sndbuf_autoscale(rack); SOCKBUF_UNLOCK(&rack->rc_inp->inp_socket->so_snd); } if (tp->t_rtttime == 0) { tp->t_rtttime = ticks; tp->t_rtseq = startseq; KMOD_TCPSTAT_INC(tcps_segstimed); } if ((rack->r_ctl.fsb.left_to_send >= segsiz) && (max_val > len) && (tso == 0)) { max_val -= len; len = segsiz; th = rack->r_ctl.fsb.th; #ifdef TCP_ACCOUNTING cnt_thru++; #endif goto again; } tp->t_flags &= ~(TF_ACKNOW | TF_DELACK); counter_u64_add(rack_fto_send, 1); slot = rack_get_pacing_delay(rack, tp, tot_len, NULL, segsiz); rack_start_hpts_timer(rack, tp, cts, slot, tot_len, 0); #ifdef TCP_ACCOUNTING crtsc = get_cyclecount(); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[SND_OUT_DATA] += cnt_thru; } counter_u64_add(tcp_cnt_counters[SND_OUT_DATA], cnt_thru); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[SND_OUT_DATA] += (crtsc - ts_val); } counter_u64_add(tcp_proc_time[SND_OUT_DATA], (crtsc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[CNT_OF_MSS_OUT] += ((tot_len + segsiz - 1) / segsiz); } counter_u64_add(tcp_cnt_counters[CNT_OF_MSS_OUT], ((tot_len + segsiz - 1) / segsiz)); sched_unpin(); #endif return (0); failed: if (m) m_free(m); rack->r_fast_output = 0; return (-1); } static struct rack_sendmap * rack_check_collapsed(struct tcp_rack *rack, uint32_t cts) { struct rack_sendmap *rsm = NULL; struct rack_sendmap fe; int thresh; restart: fe.r_start = rack->r_ctl.last_collapse_point; rsm = RB_FIND(rack_rb_tree_head, &rack->r_ctl.rc_mtree, &fe); if ((rsm == NULL) || ((rsm->r_flags & RACK_RWND_COLLAPSED) == 0)) { /* Nothing, strange turn off validity */ rack->r_collapse_point_valid = 0; return (NULL); } /* Can we send it yet? */ if (rsm->r_end > (rack->rc_tp->snd_una + rack->rc_tp->snd_wnd)) { /* * Receiver window has not grown enough for * the segment to be put on the wire. */ return (NULL); } if (rsm->r_flags & RACK_ACKED) { /* * It has been sacked, lets move to the * next one if possible. */ rack->r_ctl.last_collapse_point = rsm->r_end; /* Are we done? */ if (SEQ_GEQ(rack->r_ctl.last_collapse_point, rack->r_ctl.high_collapse_point)) { rack->r_collapse_point_valid = 0; return (NULL); } goto restart; } /* Now has it been long enough ? */ thresh = rack_calc_thresh_rack(rack, rack_grab_rtt(rack->rc_tp, rack), cts); if ((cts - ((uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)])) > thresh) { rack_log_collapse(rack, rsm->r_start, (cts - ((uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)])), thresh, __LINE__, 6, rsm->r_flags, rsm); return (rsm); } /* Not enough time */ rack_log_collapse(rack, rsm->r_start, (cts - ((uint32_t)rsm->r_tim_lastsent[(rsm->r_rtr_cnt-1)])), thresh, __LINE__, 7, rsm->r_flags, rsm); return (NULL); } static int rack_output(struct tcpcb *tp) { struct socket *so; uint32_t recwin; uint32_t sb_offset, s_moff = 0; int32_t len, error = 0; uint16_t flags; struct mbuf *m, *s_mb = NULL; struct mbuf *mb; uint32_t if_hw_tsomaxsegcount = 0; uint32_t if_hw_tsomaxsegsize; int32_t segsiz, minseg; long tot_len_this_send = 0; #ifdef INET struct ip *ip = NULL; #endif struct udphdr *udp = NULL; struct tcp_rack *rack; struct tcphdr *th; uint8_t pass = 0; uint8_t mark = 0; uint8_t wanted_cookie = 0; u_char opt[TCP_MAXOLEN]; unsigned ipoptlen, optlen, hdrlen, ulen=0; uint32_t rack_seq; #if defined(IPSEC) || defined(IPSEC_SUPPORT) unsigned ipsec_optlen = 0; #endif int32_t idle, sendalot; int32_t sub_from_prr = 0; volatile int32_t sack_rxmit; struct rack_sendmap *rsm = NULL; int32_t tso, mtu; struct tcpopt to; int32_t slot = 0; int32_t sup_rack = 0; uint32_t cts, ms_cts, delayed, early; uint16_t add_flag = RACK_SENT_SP; /* The doing_tlp flag will be set by the actual rack_timeout_tlp() */ uint8_t hpts_calling, doing_tlp = 0; uint32_t cwnd_to_use, pace_max_seg; int32_t do_a_prefetch = 0; int32_t prefetch_rsm = 0; int32_t orig_len = 0; struct timeval tv; int32_t prefetch_so_done = 0; struct tcp_log_buffer *lgb; struct inpcb *inp = tptoinpcb(tp); struct sockbuf *sb; uint64_t ts_val = 0; #ifdef TCP_ACCOUNTING uint64_t crtsc; #endif #ifdef INET6 struct ip6_hdr *ip6 = NULL; int32_t isipv6; #endif bool hw_tls = false; NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(inp); /* setup and take the cache hits here */ rack = (struct tcp_rack *)tp->t_fb_ptr; #ifdef TCP_ACCOUNTING sched_pin(); ts_val = get_cyclecount(); #endif hpts_calling = inp->inp_hpts_calls; #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) { #ifdef TCP_ACCOUNTING sched_unpin(); #endif return (tcp_offload_output(tp)); } #endif /* * For TFO connections in SYN_RECEIVED, only allow the initial * SYN|ACK and those sent by the retransmit timer. */ if (IS_FASTOPEN(tp->t_flags) && (tp->t_state == TCPS_SYN_RECEIVED) && SEQ_GT(tp->snd_max, tp->snd_una) && /* initial SYN|ACK sent */ (rack->r_ctl.rc_resend == NULL)) { /* not a retransmit */ #ifdef TCP_ACCOUNTING sched_unpin(); #endif return (0); } #ifdef INET6 if (rack->r_state) { /* Use the cache line loaded if possible */ isipv6 = rack->r_is_v6; } else { isipv6 = (rack->rc_inp->inp_vflag & INP_IPV6) != 0; } #endif early = 0; cts = tcp_get_usecs(&tv); ms_cts = tcp_tv_to_mssectick(&tv); if (((rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) == 0) && tcp_in_hpts(rack->rc_inp)) { /* * We are on the hpts for some timer but not hptsi output. * Remove from the hpts unconditionally. */ rack_timer_cancel(tp, rack, cts, __LINE__); } /* Are we pacing and late? */ if ((rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) && TSTMP_GEQ(cts, rack->r_ctl.rc_last_output_to)) { /* We are delayed */ delayed = cts - rack->r_ctl.rc_last_output_to; } else { delayed = 0; } /* Do the timers, which may override the pacer */ if (rack->r_ctl.rc_hpts_flags & PACE_TMR_MASK) { int retval; retval = rack_process_timers(tp, rack, cts, hpts_calling, &doing_tlp); if (retval != 0) { counter_u64_add(rack_out_size[TCP_MSS_ACCT_ATIMER], 1); #ifdef TCP_ACCOUNTING sched_unpin(); #endif /* * If timers want tcp_drop(), then pass error out, * otherwise suppress it. */ return (retval < 0 ? retval : 0); } } if (rack->rc_in_persist) { if (tcp_in_hpts(rack->rc_inp) == 0) { /* Timer is not running */ rack_start_hpts_timer(rack, tp, cts, 0, 0, 0); } #ifdef TCP_ACCOUNTING sched_unpin(); #endif return (0); } if ((rack->rc_ack_required == 1) && (rack->r_timer_override == 0)){ /* A timeout occurred and no ack has arrived */ if (tcp_in_hpts(rack->rc_inp) == 0) { /* Timer is not running */ rack_start_hpts_timer(rack, tp, cts, 0, 0, 0); } #ifdef TCP_ACCOUNTING sched_unpin(); #endif return (0); } if ((rack->r_timer_override) || (rack->rc_ack_can_sendout_data) || (delayed) || (tp->t_state < TCPS_ESTABLISHED)) { rack->rc_ack_can_sendout_data = 0; if (tcp_in_hpts(rack->rc_inp)) tcp_hpts_remove(rack->rc_inp); } else if (tcp_in_hpts(rack->rc_inp)) { /* * On the hpts you can't pass even if ACKNOW is on, we will * when the hpts fires. */ #ifdef TCP_ACCOUNTING crtsc = get_cyclecount(); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[SND_BLOCKED] += (crtsc - ts_val); } counter_u64_add(tcp_proc_time[SND_BLOCKED], (crtsc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[SND_BLOCKED]++; } counter_u64_add(tcp_cnt_counters[SND_BLOCKED], 1); sched_unpin(); #endif counter_u64_add(rack_out_size[TCP_MSS_ACCT_INPACE], 1); return (0); } rack->rc_inp->inp_hpts_calls = 0; /* Finish out both pacing early and late accounting */ if ((rack->r_ctl.rc_hpts_flags & PACE_PKT_OUTPUT) && TSTMP_GT(rack->r_ctl.rc_last_output_to, cts)) { early = rack->r_ctl.rc_last_output_to - cts; } else early = 0; if (delayed) { rack->r_ctl.rc_agg_delayed += delayed; rack->r_late = 1; } else if (early) { rack->r_ctl.rc_agg_early += early; rack->r_early = 1; } /* Now that early/late accounting is done turn off the flag */ rack->r_ctl.rc_hpts_flags &= ~PACE_PKT_OUTPUT; rack->r_wanted_output = 0; rack->r_timer_override = 0; if ((tp->t_state != rack->r_state) && TCPS_HAVEESTABLISHED(tp->t_state)) { rack_set_state(tp, rack); } if ((rack->r_fast_output) && (doing_tlp == 0) && (tp->rcv_numsacks == 0)) { int ret; error = 0; ret = rack_fast_output(tp, rack, ts_val, cts, ms_cts, &tv, tot_len_this_send, &error); if (ret >= 0) return(ret); else if (error) { inp = rack->rc_inp; so = inp->inp_socket; sb = &so->so_snd; goto nomore; } } inp = rack->rc_inp; /* * For TFO connections in SYN_SENT or SYN_RECEIVED, * only allow the initial SYN or SYN|ACK and those sent * by the retransmit timer. */ if (IS_FASTOPEN(tp->t_flags) && ((tp->t_state == TCPS_SYN_RECEIVED) || (tp->t_state == TCPS_SYN_SENT)) && SEQ_GT(tp->snd_max, tp->snd_una) && /* initial SYN or SYN|ACK sent */ (tp->t_rxtshift == 0)) { /* not a retransmit */ cwnd_to_use = rack->r_ctl.cwnd_to_use = tp->snd_cwnd; so = inp->inp_socket; sb = &so->so_snd; goto just_return_nolock; } /* * Determine length of data that should be transmitted, and flags * that will be used. If there is some data or critical controls * (SYN, RST) to send, then transmit; otherwise, investigate * further. */ idle = (tp->t_flags & TF_LASTIDLE) || (tp->snd_max == tp->snd_una); if (tp->t_idle_reduce) { if (idle && (TICKS_2_USEC(ticks - tp->t_rcvtime) >= tp->t_rxtcur)) rack_cc_after_idle(rack, tp); } tp->t_flags &= ~TF_LASTIDLE; if (idle) { if (tp->t_flags & TF_MORETOCOME) { tp->t_flags |= TF_LASTIDLE; idle = 0; } } if ((tp->snd_una == tp->snd_max) && rack->r_ctl.rc_went_idle_time && TSTMP_GT(cts, rack->r_ctl.rc_went_idle_time)) { idle = cts - rack->r_ctl.rc_went_idle_time; if (idle > rack_min_probertt_hold) { /* Count as a probe rtt */ if (rack->in_probe_rtt == 0) { rack->r_ctl.rc_lower_rtt_us_cts = cts; rack->r_ctl.rc_time_probertt_entered = rack->r_ctl.rc_lower_rtt_us_cts; rack->r_ctl.rc_time_probertt_starts = rack->r_ctl.rc_lower_rtt_us_cts; rack->r_ctl.rc_time_of_last_probertt = rack->r_ctl.rc_lower_rtt_us_cts; } else { rack_exit_probertt(rack, cts); } } idle = 0; } if (rack_use_fsb && (rack->r_fsb_inited == 0) && (rack->r_state != TCPS_CLOSED)) rack_init_fsb_block(tp, rack); again: /* * If we've recently taken a timeout, snd_max will be greater than * snd_nxt. There may be SACK information that allows us to avoid * resending already delivered data. Adjust snd_nxt accordingly. */ sendalot = 0; cts = tcp_get_usecs(&tv); ms_cts = tcp_tv_to_mssectick(&tv); tso = 0; mtu = 0; segsiz = min(ctf_fixed_maxseg(tp), rack->r_ctl.rc_pace_min_segs); minseg = segsiz; if (rack->r_ctl.rc_pace_max_segs == 0) pace_max_seg = rack->rc_user_set_max_segs * segsiz; else pace_max_seg = rack->r_ctl.rc_pace_max_segs; sb_offset = tp->snd_max - tp->snd_una; cwnd_to_use = rack->r_ctl.cwnd_to_use = tp->snd_cwnd; flags = tcp_outflags[tp->t_state]; while (rack->rc_free_cnt < rack_free_cache) { rsm = rack_alloc(rack); if (rsm == NULL) { if (inp->inp_hpts_calls) /* Retry in a ms */ slot = (1 * HPTS_USEC_IN_MSEC); so = inp->inp_socket; sb = &so->so_snd; goto just_return_nolock; } TAILQ_INSERT_TAIL(&rack->r_ctl.rc_free, rsm, r_tnext); rack->rc_free_cnt++; rsm = NULL; } if (inp->inp_hpts_calls) inp->inp_hpts_calls = 0; sack_rxmit = 0; len = 0; rsm = NULL; if (flags & TH_RST) { SOCKBUF_LOCK(&inp->inp_socket->so_snd); so = inp->inp_socket; sb = &so->so_snd; goto send; } if (rack->r_ctl.rc_resend) { /* Retransmit timer */ rsm = rack->r_ctl.rc_resend; rack->r_ctl.rc_resend = NULL; len = rsm->r_end - rsm->r_start; sack_rxmit = 1; sendalot = 0; KASSERT(SEQ_LEQ(tp->snd_una, rsm->r_start), ("%s:%d: r.start:%u < SND.UNA:%u; tp:%p, rack:%p, rsm:%p", __func__, __LINE__, rsm->r_start, tp->snd_una, tp, rack, rsm)); sb_offset = rsm->r_start - tp->snd_una; if (len >= segsiz) len = segsiz; } else if (rack->r_collapse_point_valid && ((rsm = rack_check_collapsed(rack, cts)) != NULL)) { /* * If an RSM is returned then enough time has passed * for us to retransmit it. Move up the collapse point, * since this rsm has its chance to retransmit now. */ rack_trace_point(rack, RACK_TP_COLLAPSED_RXT); rack->r_ctl.last_collapse_point = rsm->r_end; /* Are we done? */ if (SEQ_GEQ(rack->r_ctl.last_collapse_point, rack->r_ctl.high_collapse_point)) rack->r_collapse_point_valid = 0; sack_rxmit = 1; /* We are not doing a TLP */ doing_tlp = 0; len = rsm->r_end - rsm->r_start; sb_offset = rsm->r_start - tp->snd_una; sendalot = 0; if ((rack->full_size_rxt == 0) && (rack->shape_rxt_to_pacing_min == 0) && (len >= segsiz)) len = segsiz; } else if ((rsm = tcp_rack_output(tp, rack, cts)) != NULL) { /* We have a retransmit that takes precedence */ if ((!IN_FASTRECOVERY(tp->t_flags)) && ((rsm->r_flags & RACK_MUST_RXT) == 0) && ((tp->t_flags & TF_WASFRECOVERY) == 0)) { /* Enter recovery if not induced by a time-out */ rack_cong_signal(tp, CC_NDUPACK, tp->snd_una, __LINE__); } #ifdef INVARIANTS if (SEQ_LT(rsm->r_start, tp->snd_una)) { panic("Huh, tp:%p rack:%p rsm:%p start:%u < snd_una:%u\n", tp, rack, rsm, rsm->r_start, tp->snd_una); } #endif len = rsm->r_end - rsm->r_start; KASSERT(SEQ_LEQ(tp->snd_una, rsm->r_start), ("%s:%d: r.start:%u < SND.UNA:%u; tp:%p, rack:%p, rsm:%p", __func__, __LINE__, rsm->r_start, tp->snd_una, tp, rack, rsm)); sb_offset = rsm->r_start - tp->snd_una; sendalot = 0; if (len >= segsiz) len = segsiz; if (len > 0) { sack_rxmit = 1; KMOD_TCPSTAT_INC(tcps_sack_rexmits); KMOD_TCPSTAT_ADD(tcps_sack_rexmit_bytes, min(len, segsiz)); } } else if (rack->r_ctl.rc_tlpsend) { /* Tail loss probe */ long cwin; long tlen; /* * Check if we can do a TLP with a RACK'd packet * this can happen if we are not doing the rack * cheat and we skipped to a TLP and it * went off. */ rsm = rack->r_ctl.rc_tlpsend; /* We are doing a TLP make sure the flag is preent */ rsm->r_flags |= RACK_TLP; rack->r_ctl.rc_tlpsend = NULL; sack_rxmit = 1; tlen = rsm->r_end - rsm->r_start; if (tlen > segsiz) tlen = segsiz; KASSERT(SEQ_LEQ(tp->snd_una, rsm->r_start), ("%s:%d: r.start:%u < SND.UNA:%u; tp:%p, rack:%p, rsm:%p", __func__, __LINE__, rsm->r_start, tp->snd_una, tp, rack, rsm)); sb_offset = rsm->r_start - tp->snd_una; cwin = min(tp->snd_wnd, tlen); len = cwin; } if (rack->r_must_retran && (doing_tlp == 0) && (SEQ_GT(tp->snd_max, tp->snd_una)) && (rsm == NULL)) { /* * There are two different ways that we * can get into this block: * a) This is a non-sack connection, we had a time-out * and thus r_must_retran was set and everything * left outstanding as been marked for retransmit. * b) The MTU of the path shrank, so that everything * was marked to be retransmitted with the smaller * mtu and r_must_retran was set. * * This means that we expect the sendmap (outstanding) * to all be marked must. We can use the tmap to * look at them. * */ int sendwin, flight; sendwin = min(tp->snd_wnd, tp->snd_cwnd); flight = ctf_flight_size(tp, rack->r_ctl.rc_out_at_rto); if (flight >= sendwin) { /* * We can't send yet. */ so = inp->inp_socket; sb = &so->so_snd; goto just_return_nolock; } /* * This is the case a/b mentioned above. All * outstanding/not-acked should be marked. * We can use the tmap to find them. */ rsm = TAILQ_FIRST(&rack->r_ctl.rc_tmap); if (rsm == NULL) { /* TSNH */ rack->r_must_retran = 0; rack->r_ctl.rc_out_at_rto = 0; so = inp->inp_socket; sb = &so->so_snd; goto just_return_nolock; } if ((rsm->r_flags & RACK_MUST_RXT) == 0) { /* * The first one does not have the flag, did we collapse * further up in our list? */ rack->r_must_retran = 0; rack->r_ctl.rc_out_at_rto = 0; rsm = NULL; sack_rxmit = 0; } else { sack_rxmit = 1; len = rsm->r_end - rsm->r_start; sb_offset = rsm->r_start - tp->snd_una; sendalot = 0; if ((rack->full_size_rxt == 0) && (rack->shape_rxt_to_pacing_min == 0) && (len >= segsiz)) len = segsiz; /* * Delay removing the flag RACK_MUST_RXT so * that the fastpath for retransmit will * work with this rsm. */ } } /* * Enforce a connection sendmap count limit if set * as long as we are not retransmiting. */ if ((rsm == NULL) && (rack->do_detection == 0) && (V_tcp_map_entries_limit > 0) && (rack->r_ctl.rc_num_maps_alloced >= V_tcp_map_entries_limit)) { counter_u64_add(rack_to_alloc_limited, 1); if (!rack->alloc_limit_reported) { rack->alloc_limit_reported = 1; counter_u64_add(rack_alloc_limited_conns, 1); } so = inp->inp_socket; sb = &so->so_snd; goto just_return_nolock; } if (rsm && (rsm->r_flags & RACK_HAS_FIN)) { /* we are retransmitting the fin */ len--; if (len) { /* * When retransmitting data do *not* include the * FIN. This could happen from a TLP probe. */ flags &= ~TH_FIN; } } if (rsm && rack->r_fsb_inited && rack_use_rsm_rfo && ((rsm->r_flags & RACK_HAS_FIN) == 0)) { int ret; ret = rack_fast_rsm_output(tp, rack, rsm, ts_val, cts, ms_cts, &tv, len, doing_tlp); if (ret == 0) return (0); } so = inp->inp_socket; sb = &so->so_snd; if (do_a_prefetch == 0) { kern_prefetch(sb, &do_a_prefetch); do_a_prefetch = 1; } #ifdef NETFLIX_SHARED_CWND if ((tp->t_flags2 & TF2_TCP_SCWND_ALLOWED) && rack->rack_enable_scwnd) { /* We are doing cwnd sharing */ if (rack->gp_ready && (rack->rack_attempted_scwnd == 0) && (rack->r_ctl.rc_scw == NULL) && tp->t_lib) { /* The pcbid is in, lets make an attempt */ counter_u64_add(rack_try_scwnd, 1); rack->rack_attempted_scwnd = 1; rack->r_ctl.rc_scw = tcp_shared_cwnd_alloc(tp, &rack->r_ctl.rc_scw_index, segsiz); } if (rack->r_ctl.rc_scw && (rack->rack_scwnd_is_idle == 1) && sbavail(&so->so_snd)) { /* we are no longer out of data */ tcp_shared_cwnd_active(rack->r_ctl.rc_scw, rack->r_ctl.rc_scw_index); rack->rack_scwnd_is_idle = 0; } if (rack->r_ctl.rc_scw) { /* First lets update and get the cwnd */ rack->r_ctl.cwnd_to_use = cwnd_to_use = tcp_shared_cwnd_update(rack->r_ctl.rc_scw, rack->r_ctl.rc_scw_index, tp->snd_cwnd, tp->snd_wnd, segsiz); } } #endif /* * Get standard flags, and add SYN or FIN if requested by 'hidden' * state flags. */ if (tp->t_flags & TF_NEEDFIN) flags |= TH_FIN; if (tp->t_flags & TF_NEEDSYN) flags |= TH_SYN; if ((sack_rxmit == 0) && (prefetch_rsm == 0)) { void *end_rsm; end_rsm = TAILQ_LAST_FAST(&rack->r_ctl.rc_tmap, rack_sendmap, r_tnext); if (end_rsm) kern_prefetch(end_rsm, &prefetch_rsm); prefetch_rsm = 1; } SOCKBUF_LOCK(sb); /* * If snd_nxt == snd_max and we have transmitted a FIN, the * sb_offset will be > 0 even if so_snd.sb_cc is 0, resulting in a * negative length. This can also occur when TCP opens up its * congestion window while receiving additional duplicate acks after * fast-retransmit because TCP will reset snd_nxt to snd_max after * the fast-retransmit. * * In the normal retransmit-FIN-only case, however, snd_nxt will be * set to snd_una, the sb_offset will be 0, and the length may wind * up 0. * * If sack_rxmit is true we are retransmitting from the scoreboard * in which case len is already set. */ if ((sack_rxmit == 0) && (TCPS_HAVEESTABLISHED(tp->t_state) || IS_FASTOPEN(tp->t_flags))) { uint32_t avail; avail = sbavail(sb); if (SEQ_GT(tp->snd_nxt, tp->snd_una) && avail) sb_offset = tp->snd_nxt - tp->snd_una; else sb_offset = 0; if ((IN_FASTRECOVERY(tp->t_flags) == 0) || rack->rack_no_prr) { if (rack->r_ctl.rc_tlp_new_data) { /* TLP is forcing out new data */ if (rack->r_ctl.rc_tlp_new_data > (uint32_t) (avail - sb_offset)) { rack->r_ctl.rc_tlp_new_data = (uint32_t) (avail - sb_offset); } if ((rack->r_ctl.rc_tlp_new_data + sb_offset) > tp->snd_wnd) { if (tp->snd_wnd > sb_offset) len = tp->snd_wnd - sb_offset; else len = 0; } else { len = rack->r_ctl.rc_tlp_new_data; } rack->r_ctl.rc_tlp_new_data = 0; } else { len = rack_what_can_we_send(tp, rack, cwnd_to_use, avail, sb_offset); } if ((rack->r_ctl.crte == NULL) && IN_FASTRECOVERY(tp->t_flags) && (len > segsiz)) { /* * For prr=off, we need to send only 1 MSS * at a time. We do this because another sack could * be arriving that causes us to send retransmits and * we don't want to be on a long pace due to a larger send * that keeps us from sending out the retransmit. */ len = segsiz; } } else { uint32_t outstanding; /* * We are inside of a Fast recovery episode, this * is caused by a SACK or 3 dup acks. At this point * we have sent all the retransmissions and we rely * on PRR to dictate what we will send in the form of * new data. */ outstanding = tp->snd_max - tp->snd_una; if ((rack->r_ctl.rc_prr_sndcnt + outstanding) > tp->snd_wnd) { if (tp->snd_wnd > outstanding) { len = tp->snd_wnd - outstanding; /* Check to see if we have the data */ if ((sb_offset + len) > avail) { /* It does not all fit */ if (avail > sb_offset) len = avail - sb_offset; else len = 0; } } else { len = 0; } } else if (avail > sb_offset) { len = avail - sb_offset; } else { len = 0; } if (len > 0) { if (len > rack->r_ctl.rc_prr_sndcnt) { len = rack->r_ctl.rc_prr_sndcnt; } if (len > 0) { sub_from_prr = 1; } } if (len > segsiz) { /* * We should never send more than a MSS when * retransmitting or sending new data in prr * mode unless the override flag is on. Most * likely the PRR algorithm is not going to * let us send a lot as well :-) */ if (rack->r_ctl.rc_prr_sendalot == 0) { len = segsiz; } } else if (len < segsiz) { /* * Do we send any? The idea here is if the * send empty's the socket buffer we want to * do it. However if not then lets just wait * for our prr_sndcnt to get bigger. */ long leftinsb; leftinsb = sbavail(sb) - sb_offset; if (leftinsb > len) { /* This send does not empty the sb */ len = 0; } } } } else if (!TCPS_HAVEESTABLISHED(tp->t_state)) { /* * If you have not established * and are not doing FAST OPEN * no data please. */ if ((sack_rxmit == 0) && (!IS_FASTOPEN(tp->t_flags))){ len = 0; sb_offset = 0; } } if (prefetch_so_done == 0) { kern_prefetch(so, &prefetch_so_done); prefetch_so_done = 1; } /* * Lop off SYN bit if it has already been sent. However, if this is * SYN-SENT state and if segment contains data and if we don't know * that foreign host supports TAO, suppress sending segment. */ if ((flags & TH_SYN) && SEQ_GT(tp->snd_nxt, tp->snd_una) && ((sack_rxmit == 0) && (tp->t_rxtshift == 0))) { /* * When sending additional segments following a TFO SYN|ACK, * do not include the SYN bit. */ if (IS_FASTOPEN(tp->t_flags) && (tp->t_state == TCPS_SYN_RECEIVED)) flags &= ~TH_SYN; } /* * Be careful not to send data and/or FIN on SYN segments. This * measure is needed to prevent interoperability problems with not * fully conformant TCP implementations. */ if ((flags & TH_SYN) && (tp->t_flags & TF_NOOPT)) { len = 0; flags &= ~TH_FIN; } /* * On TFO sockets, ensure no data is sent in the following cases: * * - When retransmitting SYN|ACK on a passively-created socket * * - When retransmitting SYN on an actively created socket * * - When sending a zero-length cookie (cookie request) on an * actively created socket * * - When the socket is in the CLOSED state (RST is being sent) */ if (IS_FASTOPEN(tp->t_flags) && (((flags & TH_SYN) && (tp->t_rxtshift > 0)) || ((tp->t_state == TCPS_SYN_SENT) && (tp->t_tfo_client_cookie_len == 0)) || (flags & TH_RST))) { sack_rxmit = 0; len = 0; } /* Without fast-open there should never be data sent on a SYN */ if ((flags & TH_SYN) && (!IS_FASTOPEN(tp->t_flags))) { tp->snd_nxt = tp->iss; len = 0; } if ((len > segsiz) && (tcp_dsack_block_exists(tp))) { /* We only send 1 MSS if we have a DSACK block */ add_flag |= RACK_SENT_W_DSACK; len = segsiz; } orig_len = len; if (len <= 0) { /* * If FIN has been sent but not acked, but we haven't been * called to retransmit, len will be < 0. Otherwise, window * shrank after we sent into it. If window shrank to 0, * cancel pending retransmit, pull snd_nxt back to (closed) * window, and set the persist timer if it isn't already * going. If the window didn't close completely, just wait * for an ACK. * * We also do a general check here to ensure that we will * set the persist timer when we have data to send, but a * 0-byte window. This makes sure the persist timer is set * even if the packet hits one of the "goto send" lines * below. */ len = 0; if ((tp->snd_wnd == 0) && (TCPS_HAVEESTABLISHED(tp->t_state)) && (tp->snd_una == tp->snd_max) && (sb_offset < (int)sbavail(sb))) { rack_enter_persist(tp, rack, cts); } } else if ((rsm == NULL) && (doing_tlp == 0) && (len < pace_max_seg)) { /* * We are not sending a maximum sized segment for * some reason. Should we not send anything (think * sws or persists)? */ if ((tp->snd_wnd < min((rack->r_ctl.rc_high_rwnd/2), minseg)) && (TCPS_HAVEESTABLISHED(tp->t_state)) && (len < minseg) && (len < (int)(sbavail(sb) - sb_offset))) { /* * Here the rwnd is less than * the minimum pacing size, this is not a retransmit, * we are established and * the send is not the last in the socket buffer * we send nothing, and we may enter persists * if nothing is outstanding. */ len = 0; if (tp->snd_max == tp->snd_una) { /* * Nothing out we can * go into persists. */ rack_enter_persist(tp, rack, cts); } } else if ((cwnd_to_use >= max(minseg, (segsiz * 4))) && (ctf_flight_size(tp, rack->r_ctl.rc_sacked) > (2 * segsiz)) && (len < (int)(sbavail(sb) - sb_offset)) && (len < minseg)) { /* * Here we are not retransmitting, and * the cwnd is not so small that we could * not send at least a min size (rxt timer * not having gone off), We have 2 segments or * more already in flight, its not the tail end * of the socket buffer and the cwnd is blocking * us from sending out a minimum pacing segment size. * Lets not send anything. */ len = 0; } else if (((tp->snd_wnd - ctf_outstanding(tp)) < min((rack->r_ctl.rc_high_rwnd/2), minseg)) && (ctf_flight_size(tp, rack->r_ctl.rc_sacked) > (2 * segsiz)) && (len < (int)(sbavail(sb) - sb_offset)) && (TCPS_HAVEESTABLISHED(tp->t_state))) { /* * Here we have a send window but we have * filled it up and we can't send another pacing segment. * We also have in flight more than 2 segments * and we are not completing the sb i.e. we allow * the last bytes of the sb to go out even if * its not a full pacing segment. */ len = 0; } else if ((rack->r_ctl.crte != NULL) && (tp->snd_wnd >= (pace_max_seg * max(1, rack_hw_rwnd_factor))) && (cwnd_to_use >= (pace_max_seg + (4 * segsiz))) && (ctf_flight_size(tp, rack->r_ctl.rc_sacked) >= (2 * segsiz)) && (len < (int)(sbavail(sb) - sb_offset))) { /* * Here we are doing hardware pacing, this is not a TLP, * we are not sending a pace max segment size, there is rwnd * room to send at least N pace_max_seg, the cwnd is greater * than or equal to a full pacing segments plus 4 mss and we have 2 or * more segments in flight and its not the tail of the socket buffer. * * We don't want to send instead we need to get more ack's in to * allow us to send a full pacing segment. Normally, if we are pacing * about the right speed, we should have finished our pacing * send as most of the acks have come back if we are at the * right rate. This is a bit fuzzy since return path delay * can delay the acks, which is why we want to make sure we * have cwnd space to have a bit more than a max pace segments in flight. * * If we have not gotten our acks back we are pacing at too high a * rate delaying will not hurt and will bring our GP estimate down by * injecting the delay. If we don't do this we will send * 2 MSS out in response to the acks being clocked in which * defeats the point of hw-pacing (i.e. to help us get * larger TSO's out). */ len = 0; } } /* len will be >= 0 after this point. */ KASSERT(len >= 0, ("[%s:%d]: len < 0", __func__, __LINE__)); rack_sndbuf_autoscale(rack); /* * Decide if we can use TCP Segmentation Offloading (if supported by * hardware). * * TSO may only be used if we are in a pure bulk sending state. The * presence of TCP-MD5, SACK retransmits, SACK advertizements and IP * options prevent using TSO. With TSO the TCP header is the same * (except for the sequence number) for all generated packets. This * makes it impossible to transmit any options which vary per * generated segment or packet. * * IPv4 handling has a clear separation of ip options and ip header * flags while IPv6 combines both in in6p_outputopts. ip6_optlen() does * the right thing below to provide length of just ip options and thus * checking for ipoptlen is enough to decide if ip options are present. */ ipoptlen = 0; #if defined(IPSEC) || defined(IPSEC_SUPPORT) /* * Pre-calculate here as we save another lookup into the darknesses * of IPsec that way and can actually decide if TSO is ok. */ #ifdef INET6 if (isipv6 && IPSEC_ENABLED(ipv6)) ipsec_optlen = IPSEC_HDRSIZE(ipv6, inp); #ifdef INET else #endif #endif /* INET6 */ #ifdef INET if (IPSEC_ENABLED(ipv4)) ipsec_optlen = IPSEC_HDRSIZE(ipv4, inp); #endif /* INET */ #endif #if defined(IPSEC) || defined(IPSEC_SUPPORT) ipoptlen += ipsec_optlen; #endif if ((tp->t_flags & TF_TSO) && V_tcp_do_tso && len > segsiz && (tp->t_port == 0) && ((tp->t_flags & TF_SIGNATURE) == 0) && tp->rcv_numsacks == 0 && sack_rxmit == 0 && ipoptlen == 0) tso = 1; { uint32_t outstanding __unused; outstanding = tp->snd_max - tp->snd_una; if (tp->t_flags & TF_SENTFIN) { /* * If we sent a fin, snd_max is 1 higher than * snd_una */ outstanding--; } if (sack_rxmit) { if ((rsm->r_flags & RACK_HAS_FIN) == 0) flags &= ~TH_FIN; } else { if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + sbused(sb))) flags &= ~TH_FIN; } } recwin = lmin(lmax(sbspace(&so->so_rcv), 0), (long)TCP_MAXWIN << tp->rcv_scale); /* * Sender silly window avoidance. We transmit under the following * conditions when len is non-zero: * * - We have a full segment (or more with TSO) - This is the last * buffer in a write()/send() and we are either idle or running * NODELAY - we've timed out (e.g. persist timer) - we have more * then 1/2 the maximum send window's worth of data (receiver may be * limited the window size) - we need to retransmit */ if (len) { if (len >= segsiz) { goto send; } /* * NOTE! on localhost connections an 'ack' from the remote * end may occur synchronously with the output and cause us * to flush a buffer queued with moretocome. XXX * */ if (!(tp->t_flags & TF_MORETOCOME) && /* normal case */ (idle || (tp->t_flags & TF_NODELAY)) && ((uint32_t)len + (uint32_t)sb_offset >= sbavail(sb)) && (tp->t_flags & TF_NOPUSH) == 0) { pass = 2; goto send; } if ((tp->snd_una == tp->snd_max) && len) { /* Nothing outstanding */ pass = 22; goto send; } if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0) { pass = 4; goto send; } if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { /* retransmit case */ pass = 5; goto send; } if (sack_rxmit) { pass = 6; goto send; } if (((tp->snd_wnd - ctf_outstanding(tp)) < segsiz) && (ctf_outstanding(tp) < (segsiz * 2))) { /* * We have less than two MSS outstanding (delayed ack) * and our rwnd will not let us send a full sized * MSS. Lets go ahead and let this small segment * out because we want to try to have at least two * packets inflight to not be caught by delayed ack. */ pass = 12; goto send; } } /* * Sending of standalone window updates. * * Window updates are important when we close our window due to a * full socket buffer and are opening it again after the application * reads data from it. Once the window has opened again and the * remote end starts to send again the ACK clock takes over and * provides the most current window information. * * We must avoid the silly window syndrome whereas every read from * the receive buffer, no matter how small, causes a window update * to be sent. We also should avoid sending a flurry of window * updates when the socket buffer had queued a lot of data and the * application is doing small reads. * * Prevent a flurry of pointless window updates by only sending an * update when we can increase the advertized window by more than * 1/4th of the socket buffer capacity. When the buffer is getting * full or is very small be more aggressive and send an update * whenever we can increase by two mss sized segments. In all other * situations the ACK's to new incoming data will carry further * window increases. * * Don't send an independent window update if a delayed ACK is * pending (it will get piggy-backed on it) or the remote side * already has done a half-close and won't send more data. Skip * this if the connection is in T/TCP half-open state. */ if (recwin > 0 && !(tp->t_flags & TF_NEEDSYN) && !(tp->t_flags & TF_DELACK) && !TCPS_HAVERCVDFIN(tp->t_state)) { /* * "adv" is the amount we could increase the window, taking * into account that we are limited by TCP_MAXWIN << * tp->rcv_scale. */ int32_t adv; int oldwin; adv = recwin; if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) { oldwin = (tp->rcv_adv - tp->rcv_nxt); if (adv > oldwin) adv -= oldwin; else { /* We can't increase the window */ adv = 0; } } else oldwin = 0; /* * If the new window size ends up being the same as or less * than the old size when it is scaled, then don't force * a window update. */ if (oldwin >> tp->rcv_scale >= (adv + oldwin) >> tp->rcv_scale) goto dontupdate; if (adv >= (int32_t)(2 * segsiz) && (adv >= (int32_t)(so->so_rcv.sb_hiwat / 4) || recwin <= (int32_t)(so->so_rcv.sb_hiwat / 8) || so->so_rcv.sb_hiwat <= 8 * segsiz)) { pass = 7; goto send; } if (2 * adv >= (int32_t) so->so_rcv.sb_hiwat) { pass = 23; goto send; } } dontupdate: /* * Send if we owe the peer an ACK, RST, SYN, or urgent data. ACKNOW * is also a catch-all for the retransmit timer timeout case. */ if (tp->t_flags & TF_ACKNOW) { pass = 8; goto send; } if (((flags & TH_SYN) && (tp->t_flags & TF_NEEDSYN) == 0)) { pass = 9; goto send; } /* * If our state indicates that FIN should be sent and we have not * yet done so, then we need to send. */ if ((flags & TH_FIN) && (tp->snd_nxt == tp->snd_una)) { pass = 11; goto send; } /* * No reason to send a segment, just return. */ just_return: SOCKBUF_UNLOCK(sb); just_return_nolock: { int app_limited = CTF_JR_SENT_DATA; if (tot_len_this_send > 0) { /* Make sure snd_nxt is up to max */ rack->r_ctl.fsb.recwin = recwin; slot = rack_get_pacing_delay(rack, tp, tot_len_this_send, NULL, segsiz); if ((error == 0) && rack_use_rfo && ((flags & (TH_SYN|TH_FIN)) == 0) && (ipoptlen == 0) && (tp->snd_nxt == tp->snd_max) && (tp->rcv_numsacks == 0) && rack->r_fsb_inited && TCPS_HAVEESTABLISHED(tp->t_state) && (rack->r_must_retran == 0) && ((tp->t_flags & TF_NEEDFIN) == 0) && (len > 0) && (orig_len > 0) && (orig_len > len) && ((orig_len - len) >= segsiz) && ((optlen == 0) || ((optlen == TCPOLEN_TSTAMP_APPA) && (to.to_flags & TOF_TS)))) { /* We can send at least one more MSS using our fsb */ rack->r_fast_output = 1; rack->r_ctl.fsb.m = sbsndmbuf(sb, (tp->snd_max - tp->snd_una), &rack->r_ctl.fsb.off); rack->r_ctl.fsb.o_m_len = rack->r_ctl.fsb.m->m_len; rack->r_ctl.fsb.tcp_flags = flags; rack->r_ctl.fsb.left_to_send = orig_len - len; if (hw_tls) rack->r_ctl.fsb.hw_tls = 1; else rack->r_ctl.fsb.hw_tls = 0; KASSERT((rack->r_ctl.fsb.left_to_send <= (sbavail(sb) - (tp->snd_max - tp->snd_una))), ("rack:%p left_to_send:%u sbavail:%u out:%u", rack, rack->r_ctl.fsb.left_to_send, sbavail(sb), (tp->snd_max - tp->snd_una))); if (rack->r_ctl.fsb.left_to_send < segsiz) rack->r_fast_output = 0; else { if (rack->r_ctl.fsb.left_to_send == (sbavail(sb) - (tp->snd_max - tp->snd_una))) rack->r_ctl.fsb.rfo_apply_push = 1; else rack->r_ctl.fsb.rfo_apply_push = 0; } } else rack->r_fast_output = 0; rack_log_fsb(rack, tp, so, flags, ipoptlen, orig_len, len, 0, 1, optlen, __LINE__, 1); if (SEQ_GT(tp->snd_max, tp->snd_nxt)) tp->snd_nxt = tp->snd_max; } else { int end_window = 0; uint32_t seq = tp->gput_ack; rsm = RB_MAX(rack_rb_tree_head, &rack->r_ctl.rc_mtree); if (rsm) { /* * Mark the last sent that we just-returned (hinting * that delayed ack may play a role in any rtt measurement). */ rsm->r_just_ret = 1; } counter_u64_add(rack_out_size[TCP_MSS_ACCT_JUSTRET], 1); rack->r_ctl.rc_agg_delayed = 0; rack->r_early = 0; rack->r_late = 0; rack->r_ctl.rc_agg_early = 0; if ((ctf_outstanding(tp) + min(max(segsiz, (rack->r_ctl.rc_high_rwnd/2)), minseg)) >= tp->snd_wnd) { /* We are limited by the rwnd */ app_limited = CTF_JR_RWND_LIMITED; if (IN_FASTRECOVERY(tp->t_flags)) rack->r_ctl.rc_prr_sndcnt = 0; } else if (ctf_outstanding(tp) >= sbavail(sb)) { /* We are limited by whats available -- app limited */ app_limited = CTF_JR_APP_LIMITED; if (IN_FASTRECOVERY(tp->t_flags)) rack->r_ctl.rc_prr_sndcnt = 0; } else if ((idle == 0) && ((tp->t_flags & TF_NODELAY) == 0) && ((uint32_t)len + (uint32_t)sb_offset >= sbavail(sb)) && (len < segsiz)) { /* * No delay is not on and the * user is sending less than 1MSS. This * brings out SWS avoidance so we * don't send. Another app-limited case. */ app_limited = CTF_JR_APP_LIMITED; } else if (tp->t_flags & TF_NOPUSH) { /* * The user has requested no push of * the last segment and we are * at the last segment. Another app * limited case. */ app_limited = CTF_JR_APP_LIMITED; } else if ((ctf_outstanding(tp) + minseg) > cwnd_to_use) { /* Its the cwnd */ app_limited = CTF_JR_CWND_LIMITED; } else if (IN_FASTRECOVERY(tp->t_flags) && (rack->rack_no_prr == 0) && (rack->r_ctl.rc_prr_sndcnt < segsiz)) { app_limited = CTF_JR_PRR; } else { /* Now why here are we not sending? */ #ifdef NOW #ifdef INVARIANTS panic("rack:%p hit JR_ASSESSING case cwnd_to_use:%u?", rack, cwnd_to_use); #endif #endif app_limited = CTF_JR_ASSESSING; } /* * App limited in some fashion, for our pacing GP * measurements we don't want any gap (even cwnd). * Close down the measurement window. */ if (rack_cwnd_block_ends_measure && ((app_limited == CTF_JR_CWND_LIMITED) || (app_limited == CTF_JR_PRR))) { /* * The reason we are not sending is * the cwnd (or prr). We have been configured * to end the measurement window in * this case. */ end_window = 1; } else if (rack_rwnd_block_ends_measure && (app_limited == CTF_JR_RWND_LIMITED)) { /* * We are rwnd limited and have been * configured to end the measurement * window in this case. */ end_window = 1; } else if (app_limited == CTF_JR_APP_LIMITED) { /* * A true application limited period, we have * ran out of data. */ end_window = 1; } else if (app_limited == CTF_JR_ASSESSING) { /* * In the assessing case we hit the end of * the if/else and had no known reason * This will panic us under invariants.. * * If we get this out in logs we need to * investagate which reason we missed. */ end_window = 1; } if (end_window) { uint8_t log = 0; /* Adjust the Gput measurement */ if ((tp->t_flags & TF_GPUTINPROG) && SEQ_GT(tp->gput_ack, tp->snd_max)) { tp->gput_ack = tp->snd_max; if ((tp->gput_ack - tp->gput_seq) < (MIN_GP_WIN * segsiz)) { /* * There is not enough to measure. */ tp->t_flags &= ~TF_GPUTINPROG; rack_log_pacing_delay_calc(rack, (tp->gput_ack - tp->gput_seq) /*flex2*/, rack->r_ctl.rc_gp_srtt /*flex1*/, tp->gput_seq, 0, 0, 18, __LINE__, NULL, 0); } else log = 1; } /* Mark the last packet has app limited */ rsm = RB_MAX(rack_rb_tree_head, &rack->r_ctl.rc_mtree); if (rsm && ((rsm->r_flags & RACK_APP_LIMITED) == 0)) { if (rack->r_ctl.rc_app_limited_cnt == 0) rack->r_ctl.rc_end_appl = rack->r_ctl.rc_first_appl = rsm; else { /* * Go out to the end app limited and mark * this new one as next and move the end_appl up * to this guy. */ if (rack->r_ctl.rc_end_appl) rack->r_ctl.rc_end_appl->r_nseq_appl = rsm->r_start; rack->r_ctl.rc_end_appl = rsm; } rsm->r_flags |= RACK_APP_LIMITED; rack->r_ctl.rc_app_limited_cnt++; } if (log) rack_log_pacing_delay_calc(rack, rack->r_ctl.rc_app_limited_cnt, seq, tp->gput_ack, 0, 0, 4, __LINE__, NULL, 0); } } /* Check if we need to go into persists or not */ if ((tp->snd_max == tp->snd_una) && TCPS_HAVEESTABLISHED(tp->t_state) && sbavail(sb) && (sbavail(sb) > tp->snd_wnd) && (tp->snd_wnd < min((rack->r_ctl.rc_high_rwnd/2), minseg))) { /* Yes lets make sure to move to persist before timer-start */ rack_enter_persist(tp, rack, rack->r_ctl.rc_rcvtime); } rack_start_hpts_timer(rack, tp, cts, slot, tot_len_this_send, sup_rack); rack_log_type_just_return(rack, cts, tot_len_this_send, slot, hpts_calling, app_limited, cwnd_to_use); } #ifdef NETFLIX_SHARED_CWND if ((sbavail(sb) == 0) && rack->r_ctl.rc_scw) { tcp_shared_cwnd_idle(rack->r_ctl.rc_scw, rack->r_ctl.rc_scw_index); rack->rack_scwnd_is_idle = 1; } #endif #ifdef TCP_ACCOUNTING if (tot_len_this_send > 0) { crtsc = get_cyclecount(); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[SND_OUT_DATA]++; } counter_u64_add(tcp_cnt_counters[SND_OUT_DATA], 1); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[SND_OUT_DATA] += (crtsc - ts_val); } counter_u64_add(tcp_proc_time[SND_OUT_DATA], (crtsc - ts_val)); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[CNT_OF_MSS_OUT] += ((tot_len_this_send + segsiz - 1) / segsiz); } counter_u64_add(tcp_cnt_counters[CNT_OF_MSS_OUT], ((tot_len_this_send + segsiz - 1) / segsiz)); } else { crtsc = get_cyclecount(); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[SND_LIMITED]++; } counter_u64_add(tcp_cnt_counters[SND_LIMITED], 1); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[SND_LIMITED] += (crtsc - ts_val); } counter_u64_add(tcp_proc_time[SND_LIMITED], (crtsc - ts_val)); } sched_unpin(); #endif return (0); send: if (rsm || sack_rxmit) counter_u64_add(rack_nfto_resend, 1); else counter_u64_add(rack_non_fto_send, 1); if ((flags & TH_FIN) && sbavail(sb)) { /* * We do not transmit a FIN * with data outstanding. We * need to make it so all data * is acked first. */ flags &= ~TH_FIN; } /* Enforce stack imposed max seg size if we have one */ if (rack->r_ctl.rc_pace_max_segs && (len > rack->r_ctl.rc_pace_max_segs)) { mark = 1; len = rack->r_ctl.rc_pace_max_segs; } SOCKBUF_LOCK_ASSERT(sb); if (len > 0) { if (len >= segsiz) tp->t_flags2 |= TF2_PLPMTU_MAXSEGSNT; else tp->t_flags2 &= ~TF2_PLPMTU_MAXSEGSNT; } /* * Before ESTABLISHED, force sending of initial options unless TCP * set not to do any options. NOTE: we assume that the IP/TCP header * plus TCP options always fit in a single mbuf, leaving room for a * maximum link header, i.e. max_linkhdr + sizeof (struct tcpiphdr) * + optlen <= MCLBYTES */ optlen = 0; #ifdef INET6 if (isipv6) hdrlen = sizeof(struct ip6_hdr) + sizeof(struct tcphdr); else #endif hdrlen = sizeof(struct tcpiphdr); /* * Compute options for segment. We only have to care about SYN and * established connection segments. Options for SYN-ACK segments * are handled in TCP syncache. */ to.to_flags = 0; if ((tp->t_flags & TF_NOOPT) == 0) { /* Maximum segment size. */ if (flags & TH_SYN) { tp->snd_nxt = tp->iss; to.to_mss = tcp_mssopt(&inp->inp_inc); if (tp->t_port) to.to_mss -= V_tcp_udp_tunneling_overhead; to.to_flags |= TOF_MSS; /* * On SYN or SYN|ACK transmits on TFO connections, * only include the TFO option if it is not a * retransmit, as the presence of the TFO option may * have caused the original SYN or SYN|ACK to have * been dropped by a middlebox. */ if (IS_FASTOPEN(tp->t_flags) && (tp->t_rxtshift == 0)) { if (tp->t_state == TCPS_SYN_RECEIVED) { to.to_tfo_len = TCP_FASTOPEN_COOKIE_LEN; to.to_tfo_cookie = (u_int8_t *)&tp->t_tfo_cookie.server; to.to_flags |= TOF_FASTOPEN; wanted_cookie = 1; } else if (tp->t_state == TCPS_SYN_SENT) { to.to_tfo_len = tp->t_tfo_client_cookie_len; to.to_tfo_cookie = tp->t_tfo_cookie.client; to.to_flags |= TOF_FASTOPEN; wanted_cookie = 1; /* * If we wind up having more data to * send with the SYN than can fit in * one segment, don't send any more * until the SYN|ACK comes back from * the other end. */ sendalot = 0; } } } /* Window scaling. */ if ((flags & TH_SYN) && (tp->t_flags & TF_REQ_SCALE)) { to.to_wscale = tp->request_r_scale; to.to_flags |= TOF_SCALE; } /* Timestamps. */ if ((tp->t_flags & TF_RCVD_TSTMP) || ((flags & TH_SYN) && (tp->t_flags & TF_REQ_TSTMP))) { to.to_tsval = ms_cts + tp->ts_offset; to.to_tsecr = tp->ts_recent; to.to_flags |= TOF_TS; } /* Set receive buffer autosizing timestamp. */ if (tp->rfbuf_ts == 0 && (so->so_rcv.sb_flags & SB_AUTOSIZE)) tp->rfbuf_ts = tcp_ts_getticks(); /* Selective ACK's. */ if (tp->t_flags & TF_SACK_PERMIT) { if (flags & TH_SYN) to.to_flags |= TOF_SACKPERM; else if (TCPS_HAVEESTABLISHED(tp->t_state) && tp->rcv_numsacks > 0) { to.to_flags |= TOF_SACK; to.to_nsacks = tp->rcv_numsacks; to.to_sacks = (u_char *)tp->sackblks; } } #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) /* TCP-MD5 (RFC2385). */ if (tp->t_flags & TF_SIGNATURE) to.to_flags |= TOF_SIGNATURE; #endif /* TCP_SIGNATURE */ /* Processing the options. */ hdrlen += optlen = tcp_addoptions(&to, opt); /* * If we wanted a TFO option to be added, but it was unable * to fit, ensure no data is sent. */ if (IS_FASTOPEN(tp->t_flags) && wanted_cookie && !(to.to_flags & TOF_FASTOPEN)) len = 0; } if (tp->t_port) { if (V_tcp_udp_tunneling_port == 0) { /* The port was removed?? */ SOCKBUF_UNLOCK(&so->so_snd); #ifdef TCP_ACCOUNTING crtsc = get_cyclecount(); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[SND_OUT_FAIL]++; } counter_u64_add(tcp_cnt_counters[SND_OUT_FAIL], 1); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[SND_OUT_FAIL] += (crtsc - ts_val); } counter_u64_add(tcp_proc_time[SND_OUT_FAIL], (crtsc - ts_val)); sched_unpin(); #endif return (EHOSTUNREACH); } hdrlen += sizeof(struct udphdr); } #ifdef INET6 if (isipv6) ipoptlen = ip6_optlen(inp); else #endif if (inp->inp_options) ipoptlen = inp->inp_options->m_len - offsetof(struct ipoption, ipopt_list); else ipoptlen = 0; #if defined(IPSEC) || defined(IPSEC_SUPPORT) ipoptlen += ipsec_optlen; #endif /* * Adjust data length if insertion of options will bump the packet * length beyond the t_maxseg length. Clear the FIN bit because we * cut off the tail of the segment. */ if (len + optlen + ipoptlen > tp->t_maxseg) { if (tso) { uint32_t if_hw_tsomax; uint32_t moff; int32_t max_len; /* extract TSO information */ if_hw_tsomax = tp->t_tsomax; if_hw_tsomaxsegcount = tp->t_tsomaxsegcount; if_hw_tsomaxsegsize = tp->t_tsomaxsegsize; KASSERT(ipoptlen == 0, ("%s: TSO can't do IP options", __func__)); /* * Check if we should limit by maximum payload * length: */ if (if_hw_tsomax != 0) { /* compute maximum TSO length */ max_len = (if_hw_tsomax - hdrlen - max_linkhdr); if (max_len <= 0) { len = 0; } else if (len > max_len) { sendalot = 1; len = max_len; mark = 2; } } /* * Prevent the last segment from being fractional * unless the send sockbuf can be emptied: */ max_len = (tp->t_maxseg - optlen); if ((sb_offset + len) < sbavail(sb)) { moff = len % (u_int)max_len; if (moff != 0) { mark = 3; len -= moff; } } /* * In case there are too many small fragments don't * use TSO: */ if (len <= segsiz) { mark = 4; tso = 0; } /* * Send the FIN in a separate segment after the bulk * sending is done. We don't trust the TSO * implementations to clear the FIN flag on all but * the last segment. */ if (tp->t_flags & TF_NEEDFIN) { sendalot = 4; } } else { mark = 5; if (optlen + ipoptlen >= tp->t_maxseg) { /* * Since we don't have enough space to put * the IP header chain and the TCP header in * one packet as required by RFC 7112, don't * send it. Also ensure that at least one * byte of the payload can be put into the * TCP segment. */ SOCKBUF_UNLOCK(&so->so_snd); error = EMSGSIZE; sack_rxmit = 0; goto out; } len = tp->t_maxseg - optlen - ipoptlen; sendalot = 5; } } else { tso = 0; mark = 6; } KASSERT(len + hdrlen + ipoptlen <= IP_MAXPACKET, ("%s: len > IP_MAXPACKET", __func__)); #ifdef DIAGNOSTIC #ifdef INET6 if (max_linkhdr + hdrlen > MCLBYTES) #else if (max_linkhdr + hdrlen > MHLEN) #endif panic("tcphdr too big"); #endif /* * This KASSERT is here to catch edge cases at a well defined place. * Before, those had triggered (random) panic conditions further * down. */ KASSERT(len >= 0, ("[%s:%d]: len < 0", __func__, __LINE__)); if ((len == 0) && (flags & TH_FIN) && (sbused(sb))) { /* * We have outstanding data, don't send a fin by itself!. */ goto just_return; } /* * Grab a header mbuf, attaching a copy of data to be transmitted, * and initialize the header from the template for sends on this * connection. */ hw_tls = (sb->sb_flags & SB_TLS_IFNET) != 0; if (len) { uint32_t max_val; uint32_t moff; if (rack->r_ctl.rc_pace_max_segs) max_val = rack->r_ctl.rc_pace_max_segs; else if (rack->rc_user_set_max_segs) max_val = rack->rc_user_set_max_segs * segsiz; else max_val = len; /* * We allow a limit on sending with hptsi. */ if (len > max_val) { mark = 7; len = max_val; } #ifdef INET6 if (MHLEN < hdrlen + max_linkhdr) m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); else #endif m = m_gethdr(M_NOWAIT, MT_DATA); if (m == NULL) { SOCKBUF_UNLOCK(sb); error = ENOBUFS; sack_rxmit = 0; goto out; } m->m_data += max_linkhdr; m->m_len = hdrlen; /* * Start the m_copy functions from the closest mbuf to the * sb_offset in the socket buffer chain. */ mb = sbsndptr_noadv(sb, sb_offset, &moff); s_mb = mb; s_moff = moff; if (len <= MHLEN - hdrlen - max_linkhdr && !hw_tls) { m_copydata(mb, moff, (int)len, mtod(m, caddr_t)+hdrlen); if (SEQ_LT(tp->snd_nxt, tp->snd_max)) sbsndptr_adv(sb, mb, len); m->m_len += len; } else { struct sockbuf *msb; if (SEQ_LT(tp->snd_nxt, tp->snd_max)) msb = NULL; else msb = sb; m->m_next = tcp_m_copym( mb, moff, &len, if_hw_tsomaxsegcount, if_hw_tsomaxsegsize, msb, ((rsm == NULL) ? hw_tls : 0) #ifdef NETFLIX_COPY_ARGS , &s_mb, &s_moff #endif ); if (len <= (tp->t_maxseg - optlen)) { /* * Must have ran out of mbufs for the copy * shorten it to no longer need tso. Lets * not put on sendalot since we are low on * mbufs. */ tso = 0; } if (m->m_next == NULL) { SOCKBUF_UNLOCK(sb); (void)m_free(m); error = ENOBUFS; sack_rxmit = 0; goto out; } } if (SEQ_LT(tp->snd_nxt, tp->snd_max) || sack_rxmit) { if (rsm && (rsm->r_flags & RACK_TLP)) { /* * TLP should not count in retran count, but * in its own bin */ counter_u64_add(rack_tlp_retran, 1); counter_u64_add(rack_tlp_retran_bytes, len); } else { tp->t_sndrexmitpack++; KMOD_TCPSTAT_INC(tcps_sndrexmitpack); KMOD_TCPSTAT_ADD(tcps_sndrexmitbyte, len); } #ifdef STATS stats_voi_update_abs_u32(tp->t_stats, VOI_TCP_RETXPB, len); #endif } else { KMOD_TCPSTAT_INC(tcps_sndpack); KMOD_TCPSTAT_ADD(tcps_sndbyte, len); #ifdef STATS stats_voi_update_abs_u64(tp->t_stats, VOI_TCP_TXPB, len); #endif } /* * If we're sending everything we've got, set PUSH. (This * will keep happy those implementations which only give * data to the user when a buffer fills or a PUSH comes in.) */ if (sb_offset + len == sbused(sb) && sbused(sb) && !(flags & TH_SYN)) { flags |= TH_PUSH; add_flag |= RACK_HAD_PUSH; } SOCKBUF_UNLOCK(sb); } else { SOCKBUF_UNLOCK(sb); if (tp->t_flags & TF_ACKNOW) KMOD_TCPSTAT_INC(tcps_sndacks); else if (flags & (TH_SYN | TH_FIN | TH_RST)) KMOD_TCPSTAT_INC(tcps_sndctrl); else KMOD_TCPSTAT_INC(tcps_sndwinup); m = m_gethdr(M_NOWAIT, MT_DATA); if (m == NULL) { error = ENOBUFS; sack_rxmit = 0; goto out; } #ifdef INET6 if (isipv6 && (MHLEN < hdrlen + max_linkhdr) && MHLEN >= hdrlen) { M_ALIGN(m, hdrlen); } else #endif m->m_data += max_linkhdr; m->m_len = hdrlen; } SOCKBUF_UNLOCK_ASSERT(sb); m->m_pkthdr.rcvif = (struct ifnet *)0; #ifdef MAC mac_inpcb_create_mbuf(inp, m); #endif if ((ipoptlen == 0) && (rack->r_ctl.fsb.tcp_ip_hdr) && rack->r_fsb_inited) { #ifdef INET6 if (isipv6) ip6 = (struct ip6_hdr *)rack->r_ctl.fsb.tcp_ip_hdr; else #endif /* INET6 */ ip = (struct ip *)rack->r_ctl.fsb.tcp_ip_hdr; th = rack->r_ctl.fsb.th; udp = rack->r_ctl.fsb.udp; if (udp) { #ifdef INET6 if (isipv6) ulen = hdrlen + len - sizeof(struct ip6_hdr); else #endif /* INET6 */ ulen = hdrlen + len - sizeof(struct ip); udp->uh_ulen = htons(ulen); } } else { #ifdef INET6 if (isipv6) { ip6 = mtod(m, struct ip6_hdr *); if (tp->t_port) { udp = (struct udphdr *)((caddr_t)ip6 + sizeof(struct ip6_hdr)); udp->uh_sport = htons(V_tcp_udp_tunneling_port); udp->uh_dport = tp->t_port; ulen = hdrlen + len - sizeof(struct ip6_hdr); udp->uh_ulen = htons(ulen); th = (struct tcphdr *)(udp + 1); } else th = (struct tcphdr *)(ip6 + 1); tcpip_fillheaders(inp, tp->t_port, ip6, th); } else #endif /* INET6 */ { ip = mtod(m, struct ip *); if (tp->t_port) { udp = (struct udphdr *)((caddr_t)ip + sizeof(struct ip)); udp->uh_sport = htons(V_tcp_udp_tunneling_port); udp->uh_dport = tp->t_port; ulen = hdrlen + len - sizeof(struct ip); udp->uh_ulen = htons(ulen); th = (struct tcphdr *)(udp + 1); } else th = (struct tcphdr *)(ip + 1); tcpip_fillheaders(inp, tp->t_port, ip, th); } } /* * Fill in fields, remembering maximum advertised window for use in * delaying messages about window sizes. If resending a FIN, be sure * not to use a new sequence number. */ if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && tp->snd_nxt == tp->snd_max) tp->snd_nxt--; /* * If we are starting a connection, send ECN setup SYN packet. If we * are on a retransmit, we may resend those bits a number of times * as per RFC 3168. */ if (tp->t_state == TCPS_SYN_SENT && V_tcp_do_ecn) { flags |= tcp_ecn_output_syn_sent(tp); } /* Also handle parallel SYN for ECN */ if (TCPS_HAVERCVDSYN(tp->t_state) && (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT))) { int ect = tcp_ecn_output_established(tp, &flags, len, sack_rxmit); if ((tp->t_state == TCPS_SYN_RECEIVED) && (tp->t_flags2 & TF2_ECN_SND_ECE)) tp->t_flags2 &= ~TF2_ECN_SND_ECE; #ifdef INET6 if (isipv6) { ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20); ip6->ip6_flow |= htonl(ect << 20); } else #endif { ip->ip_tos &= ~IPTOS_ECN_MASK; ip->ip_tos |= ect; } } /* * If we are doing retransmissions, then snd_nxt will not reflect * the first unsent octet. For ACK only packets, we do not want the * sequence number of the retransmitted packet, we want the sequence * number of the next unsent octet. So, if there is no data (and no * SYN or FIN), use snd_max instead of snd_nxt when filling in * ti_seq. But if we are in persist state, snd_max might reflect * one byte beyond the right edge of the window, so use snd_nxt in * that case, since we know we aren't doing a retransmission. * (retransmit and persist are mutually exclusive...) */ if (sack_rxmit == 0) { if (len || (flags & (TH_SYN | TH_FIN))) { th->th_seq = htonl(tp->snd_nxt); rack_seq = tp->snd_nxt; } else { th->th_seq = htonl(tp->snd_max); rack_seq = tp->snd_max; } } else { th->th_seq = htonl(rsm->r_start); rack_seq = rsm->r_start; } th->th_ack = htonl(tp->rcv_nxt); tcp_set_flags(th, flags); /* * Calculate receive window. Don't shrink window, but avoid silly * window syndrome. * If a RST segment is sent, advertise a window of zero. */ if (flags & TH_RST) { recwin = 0; } else { if (recwin < (long)(so->so_rcv.sb_hiwat / 4) && recwin < (long)segsiz) { recwin = 0; } if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt) && recwin < (long)(tp->rcv_adv - tp->rcv_nxt)) recwin = (long)(tp->rcv_adv - tp->rcv_nxt); } /* * According to RFC1323 the window field in a SYN (i.e., a or * ) segment itself is never scaled. The case is * handled in syncache. */ if (flags & TH_SYN) th->th_win = htons((u_short) (min(sbspace(&so->so_rcv), TCP_MAXWIN))); else { /* Avoid shrinking window with window scaling. */ recwin = roundup2(recwin, 1 << tp->rcv_scale); th->th_win = htons((u_short)(recwin >> tp->rcv_scale)); } /* * Adjust the RXWIN0SENT flag - indicate that we have advertised a 0 * window. This may cause the remote transmitter to stall. This * flag tells soreceive() to disable delayed acknowledgements when * draining the buffer. This can occur if the receiver is * attempting to read more data than can be buffered prior to * transmitting on the connection. */ if (th->th_win == 0) { tp->t_sndzerowin++; tp->t_flags |= TF_RXWIN0SENT; } else tp->t_flags &= ~TF_RXWIN0SENT; tp->snd_up = tp->snd_una; /* drag it along, its deprecated */ /* Now are we using fsb?, if so copy the template data to the mbuf */ if ((ipoptlen == 0) && (rack->r_ctl.fsb.tcp_ip_hdr) && rack->r_fsb_inited) { uint8_t *cpto; cpto = mtod(m, uint8_t *); memcpy(cpto, rack->r_ctl.fsb.tcp_ip_hdr, rack->r_ctl.fsb.tcp_ip_hdr_len); /* * We have just copied in: * IP/IP6 * * tcphdr (no options) * * We need to grab the correct pointers into the mbuf * for both the tcp header, and possibly the udp header (if tunneling). * We do this by using the offset in the copy buffer and adding it * to the mbuf base pointer (cpto). */ #ifdef INET6 if (isipv6) ip6 = mtod(m, struct ip6_hdr *); else #endif /* INET6 */ ip = mtod(m, struct ip *); th = (struct tcphdr *)(cpto + ((uint8_t *)rack->r_ctl.fsb.th - rack->r_ctl.fsb.tcp_ip_hdr)); /* If we have a udp header lets set it into the mbuf as well */ if (udp) udp = (struct udphdr *)(cpto + ((uint8_t *)rack->r_ctl.fsb.udp - rack->r_ctl.fsb.tcp_ip_hdr)); } #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) if (to.to_flags & TOF_SIGNATURE) { /* * Calculate MD5 signature and put it into the place * determined before. * NOTE: since TCP options buffer doesn't point into * mbuf's data, calculate offset and use it. */ if (!TCPMD5_ENABLED() || TCPMD5_OUTPUT(m, th, (u_char *)(th + 1) + (to.to_signature - opt)) != 0) { /* * Do not send segment if the calculation of MD5 * digest has failed. */ goto out; } } #endif if (optlen) { bcopy(opt, th + 1, optlen); th->th_off = (sizeof(struct tcphdr) + optlen) >> 2; } /* * Put TCP length in extended header, and then checksum extended * header and data. */ m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */ #ifdef INET6 if (isipv6) { /* * ip6_plen is not need to be filled now, and will be filled * in ip6_output. */ if (tp->t_port) { m->m_pkthdr.csum_flags = CSUM_UDP_IPV6; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); udp->uh_sum = in6_cksum_pseudo(ip6, ulen, IPPROTO_UDP, 0); th->th_sum = htons(0); UDPSTAT_INC(udps_opackets); } else { m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); th->th_sum = in6_cksum_pseudo(ip6, sizeof(struct tcphdr) + optlen + len, IPPROTO_TCP, 0); } } #endif #if defined(INET6) && defined(INET) else #endif #ifdef INET { if (tp->t_port) { m->m_pkthdr.csum_flags = CSUM_UDP; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(ulen + IPPROTO_UDP)); th->th_sum = htons(0); UDPSTAT_INC(udps_opackets); } else { m->m_pkthdr.csum_flags = CSUM_TCP; m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(sizeof(struct tcphdr) + IPPROTO_TCP + len + optlen)); } /* IP version must be set here for ipv4/ipv6 checking later */ KASSERT(ip->ip_v == IPVERSION, ("%s: IP version incorrect: %d", __func__, ip->ip_v)); } #endif /* * Enable TSO and specify the size of the segments. The TCP pseudo * header checksum is always provided. XXX: Fixme: This is currently * not the case for IPv6. */ if (tso) { KASSERT(len > tp->t_maxseg - optlen, ("%s: len <= tso_segsz", __func__)); m->m_pkthdr.csum_flags |= CSUM_TSO; m->m_pkthdr.tso_segsz = tp->t_maxseg - optlen; } KASSERT(len + hdrlen == m_length(m, NULL), ("%s: mbuf chain different than expected: %d + %u != %u", __func__, len, hdrlen, m_length(m, NULL))); #ifdef TCP_HHOOK /* Run HHOOK_TCP_ESTABLISHED_OUT helper hooks. */ hhook_run_tcp_est_out(tp, th, &to, len, tso); #endif /* We're getting ready to send; log now. */ if (tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = tcp_in_hpts(rack->rc_inp); if (rack->rack_no_prr) log.u_bbr.flex1 = 0; else log.u_bbr.flex1 = rack->r_ctl.rc_prr_sndcnt; log.u_bbr.flex2 = rack->r_ctl.rc_pace_min_segs; log.u_bbr.flex3 = rack->r_ctl.rc_pace_max_segs; log.u_bbr.flex4 = orig_len; /* Save off the early/late values */ log.u_bbr.flex6 = rack->r_ctl.rc_agg_early; log.u_bbr.applimited = rack->r_ctl.rc_agg_delayed; log.u_bbr.bw_inuse = rack_get_bw(rack); log.u_bbr.flex8 = 0; if (rsm) { if (rsm->r_flags & RACK_RWND_COLLAPSED) { rack_log_collapse(rack, rsm->r_start, rsm->r_end, 0, __LINE__, 5, rsm->r_flags, rsm); counter_u64_add(rack_collapsed_win_rxt, 1); counter_u64_add(rack_collapsed_win_rxt_bytes, (rsm->r_end - rsm->r_start)); } if (doing_tlp) log.u_bbr.flex8 = 2; else log.u_bbr.flex8 = 1; } else { if (doing_tlp) log.u_bbr.flex8 = 3; else log.u_bbr.flex8 = 0; } log.u_bbr.pacing_gain = rack_get_output_gain(rack, rsm); log.u_bbr.flex7 = mark; log.u_bbr.flex7 <<= 8; log.u_bbr.flex7 |= pass; log.u_bbr.pkts_out = tp->t_maxseg; log.u_bbr.timeStamp = cts; log.u_bbr.inflight = ctf_flight_size(rack->rc_tp, rack->r_ctl.rc_sacked); log.u_bbr.lt_epoch = cwnd_to_use; log.u_bbr.delivered = sendalot; lgb = tcp_log_event_(tp, th, &so->so_rcv, &so->so_snd, TCP_LOG_OUT, ERRNO_UNK, len, &log, false, NULL, NULL, 0, &tv); } else lgb = NULL; /* * Fill in IP length and desired time to live and send to IP level. * There should be a better way to handle ttl and tos; we could keep * them in the template, but need a way to checksum without them. */ /* * m->m_pkthdr.len should have been set before cksum calcuration, * because in6_cksum() need it. */ #ifdef INET6 if (isipv6) { /* * we separately set hoplimit for every segment, since the * user might want to change the value via setsockopt. Also, * desired default hop limit might be changed via Neighbor * Discovery. */ rack->r_ctl.fsb.hoplimit = ip6->ip6_hlim = in6_selecthlim(inp, NULL); /* * Set the packet size here for the benefit of DTrace * probes. ip6_output() will set it properly; it's supposed * to include the option header lengths as well. */ ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); if (V_path_mtu_discovery && tp->t_maxseg > V_tcp_minmss) tp->t_flags2 |= TF2_PLPMTU_PMTUD; else tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; if (tp->t_state == TCPS_SYN_SENT) TCP_PROBE5(connect__request, NULL, tp, ip6, tp, th); TCP_PROBE5(send, NULL, tp, ip6, tp, th); /* TODO: IPv6 IP6TOS_ECT bit on */ error = ip6_output(m, #if defined(IPSEC) || defined(IPSEC_SUPPORT) inp->in6p_outputopts, #else NULL, #endif &inp->inp_route6, ((rsm || sack_rxmit) ? IP_NO_SND_TAG_RL : 0), NULL, NULL, inp); if (error == EMSGSIZE && inp->inp_route6.ro_nh != NULL) mtu = inp->inp_route6.ro_nh->nh_mtu; } #endif /* INET6 */ #if defined(INET) && defined(INET6) else #endif #ifdef INET { ip->ip_len = htons(m->m_pkthdr.len); #ifdef INET6 if (inp->inp_vflag & INP_IPV6PROTO) ip->ip_ttl = in6_selecthlim(inp, NULL); #endif /* INET6 */ rack->r_ctl.fsb.hoplimit = ip->ip_ttl; /* * If we do path MTU discovery, then we set DF on every * packet. This might not be the best thing to do according * to RFC3390 Section 2. However the tcp hostcache migitates * the problem so it affects only the first tcp connection * with a host. * * NB: Don't set DF on small MTU/MSS to have a safe * fallback. */ if (V_path_mtu_discovery && tp->t_maxseg > V_tcp_minmss) { tp->t_flags2 |= TF2_PLPMTU_PMTUD; if (tp->t_port == 0 || len < V_tcp_minmss) { ip->ip_off |= htons(IP_DF); } } else { tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; } if (tp->t_state == TCPS_SYN_SENT) TCP_PROBE5(connect__request, NULL, tp, ip, tp, th); TCP_PROBE5(send, NULL, tp, ip, tp, th); error = ip_output(m, #if defined(IPSEC) || defined(IPSEC_SUPPORT) inp->inp_options, #else NULL, #endif &inp->inp_route, ((rsm || sack_rxmit) ? IP_NO_SND_TAG_RL : 0), 0, inp); if (error == EMSGSIZE && inp->inp_route.ro_nh != NULL) mtu = inp->inp_route.ro_nh->nh_mtu; } #endif /* INET */ out: if (lgb) { lgb->tlb_errno = error; lgb = NULL; } /* * In transmit state, time the transmission and arrange for the * retransmit. In persist state, just set snd_max. */ if (error == 0) { tcp_account_for_send(tp, len, (rsm != NULL), doing_tlp, hw_tls); if (rsm && doing_tlp) { rack->rc_last_sent_tlp_past_cumack = 0; rack->rc_last_sent_tlp_seq_valid = 1; rack->r_ctl.last_sent_tlp_seq = rsm->r_start; rack->r_ctl.last_sent_tlp_len = rsm->r_end - rsm->r_start; } rack->forced_ack = 0; /* If we send something zap the FA flag */ if (rsm && (doing_tlp == 0)) { /* Set we retransmitted */ rack->rc_gp_saw_rec = 1; } else { if (cwnd_to_use > tp->snd_ssthresh) { /* Set we sent in CA */ rack->rc_gp_saw_ca = 1; } else { /* Set we sent in SS */ rack->rc_gp_saw_ss = 1; } } if (TCPS_HAVEESTABLISHED(tp->t_state) && (tp->t_flags & TF_SACK_PERMIT) && tp->rcv_numsacks > 0) tcp_clean_dsack_blocks(tp); tot_len_this_send += len; if (len == 0) counter_u64_add(rack_out_size[TCP_MSS_ACCT_SNDACK], 1); else if (len == 1) { counter_u64_add(rack_out_size[TCP_MSS_ACCT_PERSIST], 1); } else if (len > 1) { int idx; idx = (len / segsiz) + 3; if (idx >= TCP_MSS_ACCT_ATIMER) counter_u64_add(rack_out_size[(TCP_MSS_ACCT_ATIMER-1)], 1); else counter_u64_add(rack_out_size[idx], 1); } } if ((rack->rack_no_prr == 0) && sub_from_prr && (error == 0)) { if (rack->r_ctl.rc_prr_sndcnt >= len) rack->r_ctl.rc_prr_sndcnt -= len; else rack->r_ctl.rc_prr_sndcnt = 0; } sub_from_prr = 0; if (doing_tlp) { /* Make sure the TLP is added */ add_flag |= RACK_TLP; } else if (rsm) { /* If its a resend without TLP then it must not have the flag */ rsm->r_flags &= ~RACK_TLP; } rack_log_output(tp, &to, len, rack_seq, (uint8_t) flags, error, rack_to_usec_ts(&tv), rsm, add_flag, s_mb, s_moff, hw_tls); if ((error == 0) && (len > 0) && (tp->snd_una == tp->snd_max)) rack->r_ctl.rc_tlp_rxt_last_time = cts; { tcp_seq startseq = tp->snd_nxt; /* Track our lost count */ if (rsm && (doing_tlp == 0)) rack->r_ctl.rc_loss_count += rsm->r_end - rsm->r_start; /* * Advance snd_nxt over sequence space of this segment. */ if (error) /* We don't log or do anything with errors */ goto nomore; if (doing_tlp == 0) { if (rsm == NULL) { /* * Not a retransmission of some * sort, new data is going out so * clear our TLP count and flag. */ rack->rc_tlp_in_progress = 0; rack->r_ctl.rc_tlp_cnt_out = 0; } } else { /* * We have just sent a TLP, mark that it is true * and make sure our in progress is set so we * continue to check the count. */ rack->rc_tlp_in_progress = 1; rack->r_ctl.rc_tlp_cnt_out++; } if (flags & (TH_SYN | TH_FIN)) { if (flags & TH_SYN) tp->snd_nxt++; if (flags & TH_FIN) { tp->snd_nxt++; tp->t_flags |= TF_SENTFIN; } } /* In the ENOBUFS case we do *not* update snd_max */ if (sack_rxmit) goto nomore; tp->snd_nxt += len; if (SEQ_GT(tp->snd_nxt, tp->snd_max)) { if (tp->snd_una == tp->snd_max) { /* * Update the time we just added data since * none was outstanding. */ rack_log_progress_event(rack, tp, ticks, PROGRESS_START, __LINE__); tp->t_acktime = ticks; } tp->snd_max = tp->snd_nxt; /* * Time this transmission if not a retransmission and * not currently timing anything. * This is only relevant in case of switching back to * the base stack. */ if (tp->t_rtttime == 0) { tp->t_rtttime = ticks; tp->t_rtseq = startseq; KMOD_TCPSTAT_INC(tcps_segstimed); } if (len && ((tp->t_flags & TF_GPUTINPROG) == 0)) rack_start_gp_measurement(tp, rack, startseq, sb_offset); } /* * If we are doing FO we need to update the mbuf position and subtract * this happens when the peer sends us duplicate information and * we thus want to send a DSACK. * * XXXRRS: This brings to mind a ?, when we send a DSACK block is TSO * turned off? If not then we are going to echo multiple DSACK blocks * out (with the TSO), which we should not be doing. */ if (rack->r_fast_output && len) { if (rack->r_ctl.fsb.left_to_send > len) rack->r_ctl.fsb.left_to_send -= len; else rack->r_ctl.fsb.left_to_send = 0; if (rack->r_ctl.fsb.left_to_send < segsiz) rack->r_fast_output = 0; if (rack->r_fast_output) { rack->r_ctl.fsb.m = sbsndmbuf(sb, (tp->snd_max - tp->snd_una), &rack->r_ctl.fsb.off); rack->r_ctl.fsb.o_m_len = rack->r_ctl.fsb.m->m_len; } } } nomore: if (error) { rack->r_ctl.rc_agg_delayed = 0; rack->r_early = 0; rack->r_late = 0; rack->r_ctl.rc_agg_early = 0; SOCKBUF_UNLOCK_ASSERT(sb); /* Check gotos. */ /* * Failures do not advance the seq counter above. For the * case of ENOBUFS we will fall out and retry in 1ms with * the hpts. Everything else will just have to retransmit * with the timer. * * In any case, we do not want to loop around for another * send without a good reason. */ sendalot = 0; switch (error) { case EPERM: tp->t_softerror = error; #ifdef TCP_ACCOUNTING crtsc = get_cyclecount(); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[SND_OUT_FAIL]++; } counter_u64_add(tcp_cnt_counters[SND_OUT_FAIL], 1); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[SND_OUT_FAIL] += (crtsc - ts_val); } counter_u64_add(tcp_proc_time[SND_OUT_FAIL], (crtsc - ts_val)); sched_unpin(); #endif return (error); case ENOBUFS: /* * Pace us right away to retry in a some * time */ if (rack->r_ctl.crte != NULL) { rack_trace_point(rack, RACK_TP_HWENOBUF); } else rack_trace_point(rack, RACK_TP_ENOBUF); slot = ((1 + rack->rc_enobuf) * HPTS_USEC_IN_MSEC); if (rack->rc_enobuf < 0x7f) rack->rc_enobuf++; if (slot < (10 * HPTS_USEC_IN_MSEC)) slot = 10 * HPTS_USEC_IN_MSEC; if (rack->r_ctl.crte != NULL) { counter_u64_add(rack_saw_enobuf_hw, 1); tcp_rl_log_enobuf(rack->r_ctl.crte); } counter_u64_add(rack_saw_enobuf, 1); goto enobufs; case EMSGSIZE: /* * For some reason the interface we used initially * to send segments changed to another or lowered * its MTU. If TSO was active we either got an * interface without TSO capabilits or TSO was * turned off. If we obtained mtu from ip_output() * then update it and try again. */ if (tso) tp->t_flags &= ~TF_TSO; if (mtu != 0) { tcp_mss_update(tp, -1, mtu, NULL, NULL); goto again; } slot = 10 * HPTS_USEC_IN_MSEC; rack_start_hpts_timer(rack, tp, cts, slot, 0, 0); #ifdef TCP_ACCOUNTING crtsc = get_cyclecount(); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[SND_OUT_FAIL]++; } counter_u64_add(tcp_cnt_counters[SND_OUT_FAIL], 1); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[SND_OUT_FAIL] += (crtsc - ts_val); } counter_u64_add(tcp_proc_time[SND_OUT_FAIL], (crtsc - ts_val)); sched_unpin(); #endif return (error); case ENETUNREACH: counter_u64_add(rack_saw_enetunreach, 1); case EHOSTDOWN: case EHOSTUNREACH: case ENETDOWN: if (TCPS_HAVERCVDSYN(tp->t_state)) { tp->t_softerror = error; } /* FALLTHROUGH */ default: slot = 10 * HPTS_USEC_IN_MSEC; rack_start_hpts_timer(rack, tp, cts, slot, 0, 0); #ifdef TCP_ACCOUNTING crtsc = get_cyclecount(); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[SND_OUT_FAIL]++; } counter_u64_add(tcp_cnt_counters[SND_OUT_FAIL], 1); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[SND_OUT_FAIL] += (crtsc - ts_val); } counter_u64_add(tcp_proc_time[SND_OUT_FAIL], (crtsc - ts_val)); sched_unpin(); #endif return (error); } } else { rack->rc_enobuf = 0; if (IN_FASTRECOVERY(tp->t_flags) && rsm) rack->r_ctl.retran_during_recovery += len; } KMOD_TCPSTAT_INC(tcps_sndtotal); /* * Data sent (as far as we can tell). If this advertises a larger * window than any other segment, then remember the size of the * advertised window. Any pending ACK has now been sent. */ if (recwin > 0 && SEQ_GT(tp->rcv_nxt + recwin, tp->rcv_adv)) tp->rcv_adv = tp->rcv_nxt + recwin; tp->last_ack_sent = tp->rcv_nxt; tp->t_flags &= ~(TF_ACKNOW | TF_DELACK); enobufs: if (sendalot) { /* Do we need to turn off sendalot? */ if (rack->r_ctl.rc_pace_max_segs && (tot_len_this_send >= rack->r_ctl.rc_pace_max_segs)) { /* We hit our max. */ sendalot = 0; } else if ((rack->rc_user_set_max_segs) && (tot_len_this_send >= (rack->rc_user_set_max_segs * segsiz))) { /* We hit the user defined max */ sendalot = 0; } } if ((error == 0) && (flags & TH_FIN)) tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_FIN); if (flags & TH_RST) { /* * We don't send again after sending a RST. */ slot = 0; sendalot = 0; if (error == 0) tcp_log_end_status(tp, TCP_EI_STATUS_SERVER_RST); } else if ((slot == 0) && (sendalot == 0) && tot_len_this_send) { /* * Get our pacing rate, if an error * occurred in sending (ENOBUF) we would * hit the else if with slot preset. Other * errors return. */ slot = rack_get_pacing_delay(rack, tp, tot_len_this_send, rsm, segsiz); } if (rsm && (rsm->r_flags & RACK_HAS_SYN) == 0 && rack->use_rack_rr) { /* Its a retransmit and we use the rack cheat? */ if ((slot == 0) || (rack->rc_always_pace == 0) || (rack->r_rr_config == 1)) { /* * We have no pacing set or we * are using old-style rack or * we are overridden to use the old 1ms pacing. */ slot = rack->r_ctl.rc_min_to; } } /* We have sent clear the flag */ rack->r_ent_rec_ns = 0; if (rack->r_must_retran) { if (rsm) { rack->r_ctl.rc_out_at_rto -= (rsm->r_end - rsm->r_start); if (SEQ_GEQ(rsm->r_end, rack->r_ctl.rc_snd_max_at_rto)) { /* * We have retransmitted all. */ rack->r_must_retran = 0; rack->r_ctl.rc_out_at_rto = 0; } } else if (SEQ_GEQ(tp->snd_max, rack->r_ctl.rc_snd_max_at_rto)) { /* * Sending new data will also kill * the loop. */ rack->r_must_retran = 0; rack->r_ctl.rc_out_at_rto = 0; } } rack->r_ctl.fsb.recwin = recwin; if ((tp->t_flags & (TF_WASCRECOVERY|TF_WASFRECOVERY)) && SEQ_GT(tp->snd_max, rack->r_ctl.rc_snd_max_at_rto)) { /* * We hit an RTO and now have past snd_max at the RTO * clear all the WAS flags. */ tp->t_flags &= ~(TF_WASCRECOVERY|TF_WASFRECOVERY); } if (slot) { /* set the rack tcb into the slot N */ if ((error == 0) && rack_use_rfo && ((flags & (TH_SYN|TH_FIN)) == 0) && (rsm == NULL) && (tp->snd_nxt == tp->snd_max) && (ipoptlen == 0) && (tp->rcv_numsacks == 0) && rack->r_fsb_inited && TCPS_HAVEESTABLISHED(tp->t_state) && (rack->r_must_retran == 0) && ((tp->t_flags & TF_NEEDFIN) == 0) && (len > 0) && (orig_len > 0) && (orig_len > len) && ((orig_len - len) >= segsiz) && ((optlen == 0) || ((optlen == TCPOLEN_TSTAMP_APPA) && (to.to_flags & TOF_TS)))) { /* We can send at least one more MSS using our fsb */ rack->r_fast_output = 1; rack->r_ctl.fsb.m = sbsndmbuf(sb, (tp->snd_max - tp->snd_una), &rack->r_ctl.fsb.off); rack->r_ctl.fsb.o_m_len = rack->r_ctl.fsb.m->m_len; rack->r_ctl.fsb.tcp_flags = flags; rack->r_ctl.fsb.left_to_send = orig_len - len; if (hw_tls) rack->r_ctl.fsb.hw_tls = 1; else rack->r_ctl.fsb.hw_tls = 0; KASSERT((rack->r_ctl.fsb.left_to_send <= (sbavail(sb) - (tp->snd_max - tp->snd_una))), ("rack:%p left_to_send:%u sbavail:%u out:%u", rack, rack->r_ctl.fsb.left_to_send, sbavail(sb), (tp->snd_max - tp->snd_una))); if (rack->r_ctl.fsb.left_to_send < segsiz) rack->r_fast_output = 0; else { if (rack->r_ctl.fsb.left_to_send == (sbavail(sb) - (tp->snd_max - tp->snd_una))) rack->r_ctl.fsb.rfo_apply_push = 1; else rack->r_ctl.fsb.rfo_apply_push = 0; } } else rack->r_fast_output = 0; rack_log_fsb(rack, tp, so, flags, ipoptlen, orig_len, len, error, (rsm == NULL), optlen, __LINE__, 2); } else if (sendalot) { int ret; sack_rxmit = 0; if ((error == 0) && rack_use_rfo && ((flags & (TH_SYN|TH_FIN)) == 0) && (rsm == NULL) && (ipoptlen == 0) && (tp->rcv_numsacks == 0) && (tp->snd_nxt == tp->snd_max) && (rack->r_must_retran == 0) && rack->r_fsb_inited && TCPS_HAVEESTABLISHED(tp->t_state) && ((tp->t_flags & TF_NEEDFIN) == 0) && (len > 0) && (orig_len > 0) && (orig_len > len) && ((orig_len - len) >= segsiz) && ((optlen == 0) || ((optlen == TCPOLEN_TSTAMP_APPA) && (to.to_flags & TOF_TS)))) { /* we can use fast_output for more */ rack->r_fast_output = 1; rack->r_ctl.fsb.m = sbsndmbuf(sb, (tp->snd_max - tp->snd_una), &rack->r_ctl.fsb.off); rack->r_ctl.fsb.o_m_len = rack->r_ctl.fsb.m->m_len; rack->r_ctl.fsb.tcp_flags = flags; rack->r_ctl.fsb.left_to_send = orig_len - len; if (hw_tls) rack->r_ctl.fsb.hw_tls = 1; else rack->r_ctl.fsb.hw_tls = 0; KASSERT((rack->r_ctl.fsb.left_to_send <= (sbavail(sb) - (tp->snd_max - tp->snd_una))), ("rack:%p left_to_send:%u sbavail:%u out:%u", rack, rack->r_ctl.fsb.left_to_send, sbavail(sb), (tp->snd_max - tp->snd_una))); if (rack->r_ctl.fsb.left_to_send < segsiz) { rack->r_fast_output = 0; } if (rack->r_fast_output) { if (rack->r_ctl.fsb.left_to_send == (sbavail(sb) - (tp->snd_max - tp->snd_una))) rack->r_ctl.fsb.rfo_apply_push = 1; else rack->r_ctl.fsb.rfo_apply_push = 0; rack_log_fsb(rack, tp, so, flags, ipoptlen, orig_len, len, error, (rsm == NULL), optlen, __LINE__, 3); error = 0; ret = rack_fast_output(tp, rack, ts_val, cts, ms_cts, &tv, tot_len_this_send, &error); if (ret >= 0) return (ret); else if (error) goto nomore; } } goto again; } /* Assure when we leave that snd_nxt will point to top */ if (SEQ_GT(tp->snd_max, tp->snd_nxt)) tp->snd_nxt = tp->snd_max; rack_start_hpts_timer(rack, tp, cts, slot, tot_len_this_send, 0); #ifdef TCP_ACCOUNTING crtsc = get_cyclecount() - ts_val; if (tot_len_this_send) { if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[SND_OUT_DATA]++; } counter_u64_add(tcp_cnt_counters[SND_OUT_DATA], 1); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[SND_OUT_DATA] += crtsc; } counter_u64_add(tcp_proc_time[SND_OUT_DATA], crtsc); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[CNT_OF_MSS_OUT] += ((tot_len_this_send + segsiz - 1) /segsiz); } counter_u64_add(tcp_cnt_counters[CNT_OF_MSS_OUT], ((tot_len_this_send + segsiz - 1) /segsiz)); } else { if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_cnt_counters[SND_OUT_ACK]++; } counter_u64_add(tcp_cnt_counters[SND_OUT_ACK], 1); if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { tp->tcp_proc_time[SND_OUT_ACK] += crtsc; } counter_u64_add(tcp_proc_time[SND_OUT_ACK], crtsc); } sched_unpin(); #endif if (error == ENOBUFS) error = 0; return (error); } static void rack_update_seg(struct tcp_rack *rack) { uint32_t orig_val; orig_val = rack->r_ctl.rc_pace_max_segs; rack_set_pace_segments(rack->rc_tp, rack, __LINE__, NULL); if (orig_val != rack->r_ctl.rc_pace_max_segs) rack_log_pacing_delay_calc(rack, 0, 0, orig_val, 0, 0, 15, __LINE__, NULL, 0); } static void rack_mtu_change(struct tcpcb *tp) { /* * The MSS may have changed */ struct tcp_rack *rack; struct rack_sendmap *rsm; rack = (struct tcp_rack *)tp->t_fb_ptr; if (rack->r_ctl.rc_pace_min_segs != ctf_fixed_maxseg(tp)) { /* * The MTU has changed we need to resend everything * since all we have sent is lost. We first fix * up the mtu though. */ rack_set_pace_segments(tp, rack, __LINE__, NULL); /* We treat this like a full retransmit timeout without the cwnd adjustment */ rack_remxt_tmr(tp); rack->r_fast_output = 0; rack->r_ctl.rc_out_at_rto = ctf_flight_size(tp, rack->r_ctl.rc_sacked); rack->r_ctl.rc_snd_max_at_rto = tp->snd_max; rack->r_must_retran = 1; /* Mark all inflight to needing to be rxt'd */ TAILQ_FOREACH(rsm, &rack->r_ctl.rc_tmap, r_tnext) { rsm->r_flags |= RACK_MUST_RXT; } } sack_filter_clear(&rack->r_ctl.rack_sf, tp->snd_una); /* We don't use snd_nxt to retransmit */ tp->snd_nxt = tp->snd_max; } static int rack_set_profile(struct tcp_rack *rack, int prof) { int err = EINVAL; if (prof == 1) { /* pace_always=1 */ if (rack->rc_always_pace == 0) { if (tcp_can_enable_pacing() == 0) return (EBUSY); } rack->rc_always_pace = 1; if (rack->use_fixed_rate || rack->gp_ready) rack_set_cc_pacing(rack); rack->rc_inp->inp_flags2 |= INP_SUPPORTS_MBUFQ; rack->rack_attempt_hdwr_pace = 0; /* cmpack=1 */ if (rack_use_cmp_acks) rack->r_use_cmp_ack = 1; if (TCPS_HAVEESTABLISHED(rack->rc_tp->t_state) && rack->r_use_cmp_ack) rack->rc_inp->inp_flags2 |= INP_MBUF_ACKCMP; /* scwnd=1 */ rack->rack_enable_scwnd = 1; /* dynamic=100 */ rack->rc_gp_dyn_mul = 1; /* gp_inc_ca */ rack->r_ctl.rack_per_of_gp_ca = 100; /* rrr_conf=3 */ rack->r_rr_config = 3; /* npush=2 */ rack->r_ctl.rc_no_push_at_mrtt = 2; /* fillcw=1 */ rack->rc_pace_to_cwnd = 1; rack->rc_pace_fill_if_rttin_range = 0; rack->rtt_limit_mul = 0; /* noprr=1 */ rack->rack_no_prr = 1; /* lscwnd=1 */ rack->r_limit_scw = 1; /* gp_inc_rec */ rack->r_ctl.rack_per_of_gp_rec = 90; err = 0; } else if (prof == 3) { /* Same as profile one execept fill_cw becomes 2 (less aggressive set) */ /* pace_always=1 */ if (rack->rc_always_pace == 0) { if (tcp_can_enable_pacing() == 0) return (EBUSY); } rack->rc_always_pace = 1; if (rack->use_fixed_rate || rack->gp_ready) rack_set_cc_pacing(rack); rack->rc_inp->inp_flags2 |= INP_SUPPORTS_MBUFQ; rack->rack_attempt_hdwr_pace = 0; /* cmpack=1 */ if (rack_use_cmp_acks) rack->r_use_cmp_ack = 1; if (TCPS_HAVEESTABLISHED(rack->rc_tp->t_state) && rack->r_use_cmp_ack) rack->rc_inp->inp_flags2 |= INP_MBUF_ACKCMP; /* scwnd=1 */ rack->rack_enable_scwnd = 1; /* dynamic=100 */ rack->rc_gp_dyn_mul = 1; /* gp_inc_ca */ rack->r_ctl.rack_per_of_gp_ca = 100; /* rrr_conf=3 */ rack->r_rr_config = 3; /* npush=2 */ rack->r_ctl.rc_no_push_at_mrtt = 2; /* fillcw=2 */ rack->rc_pace_to_cwnd = 1; rack->r_fill_less_agg = 1; rack->rc_pace_fill_if_rttin_range = 0; rack->rtt_limit_mul = 0; /* noprr=1 */ rack->rack_no_prr = 1; /* lscwnd=1 */ rack->r_limit_scw = 1; /* gp_inc_rec */ rack->r_ctl.rack_per_of_gp_rec = 90; err = 0; } else if (prof == 2) { /* cmpack=1 */ if (rack->rc_always_pace == 0) { if (tcp_can_enable_pacing() == 0) return (EBUSY); } rack->rc_always_pace = 1; if (rack->use_fixed_rate || rack->gp_ready) rack_set_cc_pacing(rack); rack->r_use_cmp_ack = 1; if (TCPS_HAVEESTABLISHED(rack->rc_tp->t_state)) rack->rc_inp->inp_flags2 |= INP_MBUF_ACKCMP; /* pace_always=1 */ rack->rc_inp->inp_flags2 |= INP_SUPPORTS_MBUFQ; /* scwnd=1 */ rack->rack_enable_scwnd = 1; /* dynamic=100 */ rack->rc_gp_dyn_mul = 1; rack->r_ctl.rack_per_of_gp_ca = 100; /* rrr_conf=3 */ rack->r_rr_config = 3; /* npush=2 */ rack->r_ctl.rc_no_push_at_mrtt = 2; /* fillcw=1 */ rack->rc_pace_to_cwnd = 1; rack->rc_pace_fill_if_rttin_range = 0; rack->rtt_limit_mul = 0; /* noprr=1 */ rack->rack_no_prr = 1; /* lscwnd=0 */ rack->r_limit_scw = 0; err = 0; } else if (prof == 0) { /* This changes things back to the default settings */ err = 0; if (rack->rc_always_pace) { tcp_decrement_paced_conn(); rack_undo_cc_pacing(rack); rack->rc_always_pace = 0; } if (rack_pace_every_seg && tcp_can_enable_pacing()) { rack->rc_always_pace = 1; if (rack->use_fixed_rate || rack->gp_ready) rack_set_cc_pacing(rack); } else rack->rc_always_pace = 0; if (rack_dsack_std_based & 0x1) { /* Basically this means all rack timers are at least (srtt + 1/4 srtt) */ rack->rc_rack_tmr_std_based = 1; } if (rack_dsack_std_based & 0x2) { /* Basically this means rack timers are extended based on dsack by up to (2 * srtt) */ rack->rc_rack_use_dsack = 1; } if (rack_use_cmp_acks) rack->r_use_cmp_ack = 1; else rack->r_use_cmp_ack = 0; if (rack_disable_prr) rack->rack_no_prr = 1; else rack->rack_no_prr = 0; if (rack_gp_no_rec_chg) rack->rc_gp_no_rec_chg = 1; else rack->rc_gp_no_rec_chg = 0; if (rack_enable_mqueue_for_nonpaced || rack->r_use_cmp_ack) { rack->r_mbuf_queue = 1; if (TCPS_HAVEESTABLISHED(rack->rc_tp->t_state)) rack->rc_inp->inp_flags2 |= INP_MBUF_ACKCMP; rack->rc_inp->inp_flags2 |= INP_SUPPORTS_MBUFQ; } else { rack->r_mbuf_queue = 0; rack->rc_inp->inp_flags2 &= ~INP_SUPPORTS_MBUFQ; } if (rack_enable_shared_cwnd) rack->rack_enable_scwnd = 1; else rack->rack_enable_scwnd = 0; if (rack_do_dyn_mul) { /* When dynamic adjustment is on CA needs to start at 100% */ rack->rc_gp_dyn_mul = 1; if (rack_do_dyn_mul >= 100) rack->r_ctl.rack_per_of_gp_ca = rack_do_dyn_mul; } else { rack->r_ctl.rack_per_of_gp_ca = rack_per_of_gp_ca; rack->rc_gp_dyn_mul = 0; } rack->r_rr_config = 0; rack->r_ctl.rc_no_push_at_mrtt = 0; rack->rc_pace_to_cwnd = 0; rack->rc_pace_fill_if_rttin_range = 0; rack->rtt_limit_mul = 0; if (rack_enable_hw_pacing) rack->rack_hdw_pace_ena = 1; else rack->rack_hdw_pace_ena = 0; if (rack_disable_prr) rack->rack_no_prr = 1; else rack->rack_no_prr = 0; if (rack_limits_scwnd) rack->r_limit_scw = 1; else rack->r_limit_scw = 0; err = 0; } return (err); } static int rack_add_deferred_option(struct tcp_rack *rack, int sopt_name, uint64_t loptval) { struct deferred_opt_list *dol; dol = malloc(sizeof(struct deferred_opt_list), M_TCPFSB, M_NOWAIT|M_ZERO); if (dol == NULL) { /* * No space yikes -- fail out.. */ return (0); } dol->optname = sopt_name; dol->optval = loptval; TAILQ_INSERT_TAIL(&rack->r_ctl.opt_list, dol, next); return (1); } static int rack_process_option(struct tcpcb *tp, struct tcp_rack *rack, int sopt_name, uint32_t optval, uint64_t loptval) { struct epoch_tracker et; struct sockopt sopt; struct cc_newreno_opts opt; struct inpcb *inp = tptoinpcb(tp); uint64_t val; int error = 0; uint16_t ca, ss; switch (sopt_name) { case TCP_RACK_DSACK_OPT: RACK_OPTS_INC(tcp_rack_dsack_opt); if (optval & 0x1) { rack->rc_rack_tmr_std_based = 1; } else { rack->rc_rack_tmr_std_based = 0; } if (optval & 0x2) { rack->rc_rack_use_dsack = 1; } else { rack->rc_rack_use_dsack = 0; } rack_log_dsack_event(rack, 5, __LINE__, 0, 0); break; case TCP_RACK_PACING_BETA: RACK_OPTS_INC(tcp_rack_beta); if (strcmp(tp->t_cc->name, CCALGONAME_NEWRENO) != 0) { /* This only works for newreno. */ error = EINVAL; break; } if (rack->rc_pacing_cc_set) { /* * Set them into the real CC module * whats in the rack pcb is the old values * to be used on restoral/ */ sopt.sopt_dir = SOPT_SET; opt.name = CC_NEWRENO_BETA; opt.val = optval; if (CC_ALGO(tp)->ctl_output != NULL) error = CC_ALGO(tp)->ctl_output(&tp->t_ccv, &sopt, &opt); else { error = ENOENT; break; } } else { /* * Not pacing yet so set it into our local * rack pcb storage. */ rack->r_ctl.rc_saved_beta.beta = optval; } break; case TCP_RACK_TIMER_SLOP: RACK_OPTS_INC(tcp_rack_timer_slop); rack->r_ctl.timer_slop = optval; if (rack->rc_tp->t_srtt) { /* * If we have an SRTT lets update t_rxtcur * to have the new slop. */ RACK_TCPT_RANGESET(tp->t_rxtcur, RACK_REXMTVAL(tp), rack_rto_min, rack_rto_max, rack->r_ctl.timer_slop); } break; case TCP_RACK_PACING_BETA_ECN: RACK_OPTS_INC(tcp_rack_beta_ecn); if (strcmp(tp->t_cc->name, CCALGONAME_NEWRENO) != 0) { /* This only works for newreno. */ error = EINVAL; break; } if (rack->rc_pacing_cc_set) { /* * Set them into the real CC module * whats in the rack pcb is the old values * to be used on restoral/ */ sopt.sopt_dir = SOPT_SET; opt.name = CC_NEWRENO_BETA_ECN; opt.val = optval; if (CC_ALGO(tp)->ctl_output != NULL) error = CC_ALGO(tp)->ctl_output(&tp->t_ccv, &sopt, &opt); else error = ENOENT; } else { /* * Not pacing yet so set it into our local * rack pcb storage. */ rack->r_ctl.rc_saved_beta.beta_ecn = optval; rack->r_ctl.rc_saved_beta.newreno_flags = CC_NEWRENO_BETA_ECN_ENABLED; } break; case TCP_DEFER_OPTIONS: RACK_OPTS_INC(tcp_defer_opt); if (optval) { if (rack->gp_ready) { /* Too late */ error = EINVAL; break; } rack->defer_options = 1; } else rack->defer_options = 0; break; case TCP_RACK_MEASURE_CNT: RACK_OPTS_INC(tcp_rack_measure_cnt); if (optval && (optval <= 0xff)) { rack->r_ctl.req_measurements = optval; } else error = EINVAL; break; case TCP_REC_ABC_VAL: RACK_OPTS_INC(tcp_rec_abc_val); if (optval > 0) rack->r_use_labc_for_rec = 1; else rack->r_use_labc_for_rec = 0; break; case TCP_RACK_ABC_VAL: RACK_OPTS_INC(tcp_rack_abc_val); if ((optval > 0) && (optval < 255)) rack->rc_labc = optval; else error = EINVAL; break; case TCP_HDWR_UP_ONLY: RACK_OPTS_INC(tcp_pacing_up_only); if (optval) rack->r_up_only = 1; else rack->r_up_only = 0; break; case TCP_PACING_RATE_CAP: RACK_OPTS_INC(tcp_pacing_rate_cap); rack->r_ctl.bw_rate_cap = loptval; break; case TCP_RACK_PROFILE: RACK_OPTS_INC(tcp_profile); error = rack_set_profile(rack, optval); break; case TCP_USE_CMP_ACKS: RACK_OPTS_INC(tcp_use_cmp_acks); if ((optval == 0) && (rack->rc_inp->inp_flags2 & INP_MBUF_ACKCMP)) { /* You can't turn it off once its on! */ error = EINVAL; } else if ((optval == 1) && (rack->r_use_cmp_ack == 0)) { rack->r_use_cmp_ack = 1; rack->r_mbuf_queue = 1; inp->inp_flags2 |= INP_SUPPORTS_MBUFQ; } if (rack->r_use_cmp_ack && TCPS_HAVEESTABLISHED(tp->t_state)) inp->inp_flags2 |= INP_MBUF_ACKCMP; break; case TCP_SHARED_CWND_TIME_LIMIT: RACK_OPTS_INC(tcp_lscwnd); if (optval) rack->r_limit_scw = 1; else rack->r_limit_scw = 0; break; case TCP_RACK_PACE_TO_FILL: RACK_OPTS_INC(tcp_fillcw); if (optval == 0) rack->rc_pace_to_cwnd = 0; else { rack->rc_pace_to_cwnd = 1; if (optval > 1) rack->r_fill_less_agg = 1; } if ((optval >= rack_gp_rtt_maxmul) && rack_gp_rtt_maxmul && (optval < 0xf)) { rack->rc_pace_fill_if_rttin_range = 1; rack->rtt_limit_mul = optval; } else { rack->rc_pace_fill_if_rttin_range = 0; rack->rtt_limit_mul = 0; } break; case TCP_RACK_NO_PUSH_AT_MAX: RACK_OPTS_INC(tcp_npush); if (optval == 0) rack->r_ctl.rc_no_push_at_mrtt = 0; else if (optval < 0xff) rack->r_ctl.rc_no_push_at_mrtt = optval; else error = EINVAL; break; case TCP_SHARED_CWND_ENABLE: RACK_OPTS_INC(tcp_rack_scwnd); if (optval == 0) rack->rack_enable_scwnd = 0; else rack->rack_enable_scwnd = 1; break; case TCP_RACK_MBUF_QUEUE: /* Now do we use the LRO mbuf-queue feature */ RACK_OPTS_INC(tcp_rack_mbufq); if (optval || rack->r_use_cmp_ack) rack->r_mbuf_queue = 1; else rack->r_mbuf_queue = 0; if (rack->r_mbuf_queue || rack->rc_always_pace || rack->r_use_cmp_ack) inp->inp_flags2 |= INP_SUPPORTS_MBUFQ; else inp->inp_flags2 &= ~INP_SUPPORTS_MBUFQ; break; case TCP_RACK_NONRXT_CFG_RATE: RACK_OPTS_INC(tcp_rack_cfg_rate); if (optval == 0) rack->rack_rec_nonrxt_use_cr = 0; else rack->rack_rec_nonrxt_use_cr = 1; break; case TCP_NO_PRR: RACK_OPTS_INC(tcp_rack_noprr); if (optval == 0) rack->rack_no_prr = 0; else if (optval == 1) rack->rack_no_prr = 1; else if (optval == 2) rack->no_prr_addback = 1; else error = EINVAL; break; case TCP_TIMELY_DYN_ADJ: RACK_OPTS_INC(tcp_timely_dyn); if (optval == 0) rack->rc_gp_dyn_mul = 0; else { rack->rc_gp_dyn_mul = 1; if (optval >= 100) { /* * If the user sets something 100 or more * its the gp_ca value. */ rack->r_ctl.rack_per_of_gp_ca = optval; } } break; case TCP_RACK_DO_DETECTION: RACK_OPTS_INC(tcp_rack_do_detection); if (optval == 0) rack->do_detection = 0; else rack->do_detection = 1; break; case TCP_RACK_TLP_USE: if ((optval < TLP_USE_ID) || (optval > TLP_USE_TWO_TWO)) { error = EINVAL; break; } RACK_OPTS_INC(tcp_tlp_use); rack->rack_tlp_threshold_use = optval; break; case TCP_RACK_TLP_REDUCE: /* RACK TLP cwnd reduction (bool) */ RACK_OPTS_INC(tcp_rack_tlp_reduce); rack->r_ctl.rc_tlp_cwnd_reduce = optval; break; /* Pacing related ones */ case TCP_RACK_PACE_ALWAYS: /* * zero is old rack method, 1 is new * method using a pacing rate. */ RACK_OPTS_INC(tcp_rack_pace_always); if (optval > 0) { if (rack->rc_always_pace) { error = EALREADY; break; } else if (tcp_can_enable_pacing()) { rack->rc_always_pace = 1; if (rack->use_fixed_rate || rack->gp_ready) rack_set_cc_pacing(rack); } else { error = ENOSPC; break; } } else { if (rack->rc_always_pace) { tcp_decrement_paced_conn(); rack->rc_always_pace = 0; rack_undo_cc_pacing(rack); } } if (rack->r_mbuf_queue || rack->rc_always_pace || rack->r_use_cmp_ack) inp->inp_flags2 |= INP_SUPPORTS_MBUFQ; else inp->inp_flags2 &= ~INP_SUPPORTS_MBUFQ; /* A rate may be set irate or other, if so set seg size */ rack_update_seg(rack); break; case TCP_BBR_RACK_INIT_RATE: RACK_OPTS_INC(tcp_initial_rate); val = optval; /* Change from kbits per second to bytes per second */ val *= 1000; val /= 8; rack->r_ctl.init_rate = val; if (rack->rc_init_win != rack_default_init_window) { uint32_t win, snt; /* * Options don't always get applied * in the order you think. So in order * to assure we update a cwnd we need * to check and see if we are still * where we should raise the cwnd. */ win = rc_init_window(rack); if (SEQ_GT(tp->snd_max, tp->iss)) snt = tp->snd_max - tp->iss; else snt = 0; if ((snt < win) && (tp->snd_cwnd < win)) tp->snd_cwnd = win; } if (rack->rc_always_pace) rack_update_seg(rack); break; case TCP_BBR_IWINTSO: RACK_OPTS_INC(tcp_initial_win); if (optval && (optval <= 0xff)) { uint32_t win, snt; rack->rc_init_win = optval; win = rc_init_window(rack); if (SEQ_GT(tp->snd_max, tp->iss)) snt = tp->snd_max - tp->iss; else snt = 0; if ((snt < win) && (tp->t_srtt | #ifdef NETFLIX_PEAKRATE tp->t_maxpeakrate | #endif rack->r_ctl.init_rate)) { /* * We are not past the initial window * and we have some bases for pacing, * so we need to possibly adjust up * the cwnd. Note even if we don't set * the cwnd, its still ok to raise the rc_init_win * which can be used coming out of idle when we * would have a rate. */ if (tp->snd_cwnd < win) tp->snd_cwnd = win; } if (rack->rc_always_pace) rack_update_seg(rack); } else error = EINVAL; break; case TCP_RACK_FORCE_MSEG: RACK_OPTS_INC(tcp_rack_force_max_seg); if (optval) rack->rc_force_max_seg = 1; else rack->rc_force_max_seg = 0; break; case TCP_RACK_PACE_MAX_SEG: /* Max segments size in a pace in bytes */ RACK_OPTS_INC(tcp_rack_max_seg); rack->rc_user_set_max_segs = optval; rack_set_pace_segments(tp, rack, __LINE__, NULL); break; case TCP_RACK_PACE_RATE_REC: /* Set the fixed pacing rate in Bytes per second ca */ RACK_OPTS_INC(tcp_rack_pace_rate_rec); rack->r_ctl.rc_fixed_pacing_rate_rec = optval; if (rack->r_ctl.rc_fixed_pacing_rate_ca == 0) rack->r_ctl.rc_fixed_pacing_rate_ca = optval; if (rack->r_ctl.rc_fixed_pacing_rate_ss == 0) rack->r_ctl.rc_fixed_pacing_rate_ss = optval; rack->use_fixed_rate = 1; if (rack->rc_always_pace) rack_set_cc_pacing(rack); rack_log_pacing_delay_calc(rack, rack->r_ctl.rc_fixed_pacing_rate_ss, rack->r_ctl.rc_fixed_pacing_rate_ca, rack->r_ctl.rc_fixed_pacing_rate_rec, 0, 0, 8, __LINE__, NULL,0); break; case TCP_RACK_PACE_RATE_SS: /* Set the fixed pacing rate in Bytes per second ca */ RACK_OPTS_INC(tcp_rack_pace_rate_ss); rack->r_ctl.rc_fixed_pacing_rate_ss = optval; if (rack->r_ctl.rc_fixed_pacing_rate_ca == 0) rack->r_ctl.rc_fixed_pacing_rate_ca = optval; if (rack->r_ctl.rc_fixed_pacing_rate_rec == 0) rack->r_ctl.rc_fixed_pacing_rate_rec = optval; rack->use_fixed_rate = 1; if (rack->rc_always_pace) rack_set_cc_pacing(rack); rack_log_pacing_delay_calc(rack, rack->r_ctl.rc_fixed_pacing_rate_ss, rack->r_ctl.rc_fixed_pacing_rate_ca, rack->r_ctl.rc_fixed_pacing_rate_rec, 0, 0, 8, __LINE__, NULL, 0); break; case TCP_RACK_PACE_RATE_CA: /* Set the fixed pacing rate in Bytes per second ca */ RACK_OPTS_INC(tcp_rack_pace_rate_ca); rack->r_ctl.rc_fixed_pacing_rate_ca = optval; if (rack->r_ctl.rc_fixed_pacing_rate_ss == 0) rack->r_ctl.rc_fixed_pacing_rate_ss = optval; if (rack->r_ctl.rc_fixed_pacing_rate_rec == 0) rack->r_ctl.rc_fixed_pacing_rate_rec = optval; rack->use_fixed_rate = 1; if (rack->rc_always_pace) rack_set_cc_pacing(rack); rack_log_pacing_delay_calc(rack, rack->r_ctl.rc_fixed_pacing_rate_ss, rack->r_ctl.rc_fixed_pacing_rate_ca, rack->r_ctl.rc_fixed_pacing_rate_rec, 0, 0, 8, __LINE__, NULL, 0); break; case TCP_RACK_GP_INCREASE_REC: RACK_OPTS_INC(tcp_gp_inc_rec); rack->r_ctl.rack_per_of_gp_rec = optval; rack_log_pacing_delay_calc(rack, rack->r_ctl.rack_per_of_gp_ss, rack->r_ctl.rack_per_of_gp_ca, rack->r_ctl.rack_per_of_gp_rec, 0, 0, 1, __LINE__, NULL, 0); break; case TCP_RACK_GP_INCREASE_CA: RACK_OPTS_INC(tcp_gp_inc_ca); ca = optval; if (ca < 100) { /* * We don't allow any reduction * over the GP b/w. */ error = EINVAL; break; } rack->r_ctl.rack_per_of_gp_ca = ca; rack_log_pacing_delay_calc(rack, rack->r_ctl.rack_per_of_gp_ss, rack->r_ctl.rack_per_of_gp_ca, rack->r_ctl.rack_per_of_gp_rec, 0, 0, 1, __LINE__, NULL, 0); break; case TCP_RACK_GP_INCREASE_SS: RACK_OPTS_INC(tcp_gp_inc_ss); ss = optval; if (ss < 100) { /* * We don't allow any reduction * over the GP b/w. */ error = EINVAL; break; } rack->r_ctl.rack_per_of_gp_ss = ss; rack_log_pacing_delay_calc(rack, rack->r_ctl.rack_per_of_gp_ss, rack->r_ctl.rack_per_of_gp_ca, rack->r_ctl.rack_per_of_gp_rec, 0, 0, 1, __LINE__, NULL, 0); break; case TCP_RACK_RR_CONF: RACK_OPTS_INC(tcp_rack_rrr_no_conf_rate); if (optval && optval <= 3) rack->r_rr_config = optval; else rack->r_rr_config = 0; break; case TCP_HDWR_RATE_CAP: RACK_OPTS_INC(tcp_hdwr_rate_cap); if (optval) { if (rack->r_rack_hw_rate_caps == 0) rack->r_rack_hw_rate_caps = 1; else error = EALREADY; } else { rack->r_rack_hw_rate_caps = 0; } break; case TCP_BBR_HDWR_PACE: RACK_OPTS_INC(tcp_hdwr_pacing); if (optval){ if (rack->rack_hdrw_pacing == 0) { rack->rack_hdw_pace_ena = 1; rack->rack_attempt_hdwr_pace = 0; } else error = EALREADY; } else { rack->rack_hdw_pace_ena = 0; #ifdef RATELIMIT if (rack->r_ctl.crte != NULL) { rack->rack_hdrw_pacing = 0; rack->rack_attempt_hdwr_pace = 0; tcp_rel_pacing_rate(rack->r_ctl.crte, tp); rack->r_ctl.crte = NULL; } #endif } break; /* End Pacing related ones */ case TCP_RACK_PRR_SENDALOT: /* Allow PRR to send more than one seg */ RACK_OPTS_INC(tcp_rack_prr_sendalot); rack->r_ctl.rc_prr_sendalot = optval; break; case TCP_RACK_MIN_TO: /* Minimum time between rack t-o's in ms */ RACK_OPTS_INC(tcp_rack_min_to); rack->r_ctl.rc_min_to = optval; break; case TCP_RACK_EARLY_SEG: /* If early recovery max segments */ RACK_OPTS_INC(tcp_rack_early_seg); rack->r_ctl.rc_early_recovery_segs = optval; break; case TCP_RACK_ENABLE_HYSTART: { if (optval) { tp->t_ccv.flags |= CCF_HYSTART_ALLOWED; if (rack_do_hystart > RACK_HYSTART_ON) tp->t_ccv.flags |= CCF_HYSTART_CAN_SH_CWND; if (rack_do_hystart > RACK_HYSTART_ON_W_SC) tp->t_ccv.flags |= CCF_HYSTART_CONS_SSTH; } else { tp->t_ccv.flags &= ~(CCF_HYSTART_ALLOWED|CCF_HYSTART_CAN_SH_CWND|CCF_HYSTART_CONS_SSTH); } } break; case TCP_RACK_REORD_THRESH: /* RACK reorder threshold (shift amount) */ RACK_OPTS_INC(tcp_rack_reord_thresh); if ((optval > 0) && (optval < 31)) rack->r_ctl.rc_reorder_shift = optval; else error = EINVAL; break; case TCP_RACK_REORD_FADE: /* Does reordering fade after ms time */ RACK_OPTS_INC(tcp_rack_reord_fade); rack->r_ctl.rc_reorder_fade = optval; break; case TCP_RACK_TLP_THRESH: /* RACK TLP theshold i.e. srtt+(srtt/N) */ RACK_OPTS_INC(tcp_rack_tlp_thresh); if (optval) rack->r_ctl.rc_tlp_threshold = optval; else error = EINVAL; break; case TCP_BBR_USE_RACK_RR: RACK_OPTS_INC(tcp_rack_rr); if (optval) rack->use_rack_rr = 1; else rack->use_rack_rr = 0; break; case TCP_FAST_RSM_HACK: RACK_OPTS_INC(tcp_rack_fastrsm_hack); if (optval) rack->fast_rsm_hack = 1; else rack->fast_rsm_hack = 0; break; case TCP_RACK_PKT_DELAY: /* RACK added ms i.e. rack-rtt + reord + N */ RACK_OPTS_INC(tcp_rack_pkt_delay); rack->r_ctl.rc_pkt_delay = optval; break; case TCP_DELACK: RACK_OPTS_INC(tcp_rack_delayed_ack); if (optval == 0) tp->t_delayed_ack = 0; else tp->t_delayed_ack = 1; if (tp->t_flags & TF_DELACK) { tp->t_flags &= ~TF_DELACK; tp->t_flags |= TF_ACKNOW; NET_EPOCH_ENTER(et); rack_output(tp); NET_EPOCH_EXIT(et); } break; case TCP_BBR_RACK_RTT_USE: RACK_OPTS_INC(tcp_rack_rtt_use); if ((optval != USE_RTT_HIGH) && (optval != USE_RTT_LOW) && (optval != USE_RTT_AVG)) error = EINVAL; else rack->r_ctl.rc_rate_sample_method = optval; break; case TCP_DATA_AFTER_CLOSE: RACK_OPTS_INC(tcp_data_after_close); if (optval) rack->rc_allow_data_af_clo = 1; else rack->rc_allow_data_af_clo = 0; break; default: break; } #ifdef NETFLIX_STATS tcp_log_socket_option(tp, sopt_name, optval, error); #endif return (error); } static void rack_apply_deferred_options(struct tcp_rack *rack) { struct deferred_opt_list *dol, *sdol; uint32_t s_optval; TAILQ_FOREACH_SAFE(dol, &rack->r_ctl.opt_list, next, sdol) { TAILQ_REMOVE(&rack->r_ctl.opt_list, dol, next); /* Disadvantage of deferal is you loose the error return */ s_optval = (uint32_t)dol->optval; (void)rack_process_option(rack->rc_tp, rack, dol->optname, s_optval, dol->optval); free(dol, M_TCPDO); } } static void rack_hw_tls_change(struct tcpcb *tp, int chg) { /* * HW tls state has changed.. fix all * rsm's in flight. */ struct tcp_rack *rack; struct rack_sendmap *rsm; rack = (struct tcp_rack *)tp->t_fb_ptr; RB_FOREACH(rsm, rack_rb_tree_head, &rack->r_ctl.rc_mtree) { if (chg) rsm->r_hw_tls = 1; else rsm->r_hw_tls = 0; } if (chg) rack->r_ctl.fsb.hw_tls = 1; else rack->r_ctl.fsb.hw_tls = 0; } static int rack_pru_options(struct tcpcb *tp, int flags) { if (flags & PRUS_OOB) return (EOPNOTSUPP); return (0); } static struct tcp_function_block __tcp_rack = { .tfb_tcp_block_name = __XSTRING(STACKNAME), .tfb_tcp_output = rack_output, .tfb_do_queued_segments = ctf_do_queued_segments, .tfb_do_segment_nounlock = rack_do_segment_nounlock, .tfb_tcp_do_segment = rack_do_segment, .tfb_tcp_ctloutput = rack_ctloutput, .tfb_tcp_fb_init = rack_init, .tfb_tcp_fb_fini = rack_fini, .tfb_tcp_timer_stop_all = rack_stopall, .tfb_tcp_rexmit_tmr = rack_remxt_tmr, .tfb_tcp_handoff_ok = rack_handoff_ok, .tfb_tcp_mtu_chg = rack_mtu_change, .tfb_pru_options = rack_pru_options, .tfb_hwtls_change = rack_hw_tls_change, .tfb_compute_pipe = rack_compute_pipe, .tfb_flags = TCP_FUNC_OUTPUT_CANDROP, }; /* * rack_ctloutput() must drop the inpcb lock before performing copyin on * socket option arguments. When it re-acquires the lock after the copy, it * has to revalidate that the connection is still valid for the socket * option. */ static int rack_set_sockopt(struct inpcb *inp, struct sockopt *sopt) { #ifdef INET6 struct ip6_hdr *ip6; #endif #ifdef INET struct ip *ip; #endif struct tcpcb *tp; struct tcp_rack *rack; uint64_t loptval; int32_t error = 0, optval; tp = intotcpcb(inp); rack = (struct tcp_rack *)tp->t_fb_ptr; if (rack == NULL) { INP_WUNLOCK(inp); return (EINVAL); } #ifdef INET6 ip6 = (struct ip6_hdr *)rack->r_ctl.fsb.tcp_ip_hdr; #endif #ifdef INET ip = (struct ip *)rack->r_ctl.fsb.tcp_ip_hdr; #endif switch (sopt->sopt_level) { #ifdef INET6 case IPPROTO_IPV6: MPASS(inp->inp_vflag & INP_IPV6PROTO); switch (sopt->sopt_name) { case IPV6_USE_MIN_MTU: tcp6_use_min_mtu(tp); break; case IPV6_TCLASS: /* * The DSCP codepoint has changed, update the fsb. */ ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) | (rack->rc_inp->inp_flow & IPV6_FLOWINFO_MASK); break; } INP_WUNLOCK(inp); return (0); #endif #ifdef INET case IPPROTO_IP: switch (sopt->sopt_name) { case IP_TOS: /* * The DSCP codepoint has changed, update the fsb. */ ip->ip_tos = rack->rc_inp->inp_ip_tos; break; case IP_TTL: /* * The TTL has changed, update the fsb. */ ip->ip_ttl = rack->rc_inp->inp_ip_ttl; break; } INP_WUNLOCK(inp); return (0); #endif } switch (sopt->sopt_name) { case TCP_RACK_TLP_REDUCE: /* URL:tlp_reduce */ /* Pacing related ones */ case TCP_RACK_PACE_ALWAYS: /* URL:pace_always */ case TCP_BBR_RACK_INIT_RATE: /* URL:irate */ case TCP_BBR_IWINTSO: /* URL:tso_iwin */ case TCP_RACK_PACE_MAX_SEG: /* URL:pace_max_seg */ case TCP_RACK_FORCE_MSEG: /* URL:force_max_seg */ case TCP_RACK_PACE_RATE_CA: /* URL:pr_ca */ case TCP_RACK_PACE_RATE_SS: /* URL:pr_ss*/ case TCP_RACK_PACE_RATE_REC: /* URL:pr_rec */ case TCP_RACK_GP_INCREASE_CA: /* URL:gp_inc_ca */ case TCP_RACK_GP_INCREASE_SS: /* URL:gp_inc_ss */ case TCP_RACK_GP_INCREASE_REC: /* URL:gp_inc_rec */ case TCP_RACK_RR_CONF: /* URL:rrr_conf */ case TCP_BBR_HDWR_PACE: /* URL:hdwrpace */ case TCP_HDWR_RATE_CAP: /* URL:hdwrcap boolean */ case TCP_PACING_RATE_CAP: /* URL:cap -- used by side-channel */ case TCP_HDWR_UP_ONLY: /* URL:uponly -- hardware pacing boolean */ /* End pacing related */ case TCP_FAST_RSM_HACK: /* URL:frsm_hack */ case TCP_DELACK: /* URL:delack (in base TCP i.e. tcp_hints along with cc etc ) */ case TCP_RACK_PRR_SENDALOT: /* URL:prr_sendalot */ case TCP_RACK_MIN_TO: /* URL:min_to */ case TCP_RACK_EARLY_SEG: /* URL:early_seg */ case TCP_RACK_REORD_THRESH: /* URL:reord_thresh */ case TCP_RACK_REORD_FADE: /* URL:reord_fade */ case TCP_RACK_TLP_THRESH: /* URL:tlp_thresh */ case TCP_RACK_PKT_DELAY: /* URL:pkt_delay */ case TCP_RACK_TLP_USE: /* URL:tlp_use */ case TCP_BBR_RACK_RTT_USE: /* URL:rttuse */ case TCP_BBR_USE_RACK_RR: /* URL:rackrr */ case TCP_RACK_DO_DETECTION: /* URL:detect */ case TCP_NO_PRR: /* URL:noprr */ case TCP_TIMELY_DYN_ADJ: /* URL:dynamic */ case TCP_DATA_AFTER_CLOSE: /* no URL */ case TCP_RACK_NONRXT_CFG_RATE: /* URL:nonrxtcr */ case TCP_SHARED_CWND_ENABLE: /* URL:scwnd */ case TCP_RACK_MBUF_QUEUE: /* URL:mqueue */ case TCP_RACK_NO_PUSH_AT_MAX: /* URL:npush */ case TCP_RACK_PACE_TO_FILL: /* URL:fillcw */ case TCP_SHARED_CWND_TIME_LIMIT: /* URL:lscwnd */ case TCP_RACK_PROFILE: /* URL:profile */ case TCP_USE_CMP_ACKS: /* URL:cmpack */ case TCP_RACK_ABC_VAL: /* URL:labc */ case TCP_REC_ABC_VAL: /* URL:reclabc */ case TCP_RACK_MEASURE_CNT: /* URL:measurecnt */ case TCP_DEFER_OPTIONS: /* URL:defer */ case TCP_RACK_DSACK_OPT: /* URL:dsack */ case TCP_RACK_PACING_BETA: /* URL:pacing_beta */ case TCP_RACK_PACING_BETA_ECN: /* URL:pacing_beta_ecn */ case TCP_RACK_TIMER_SLOP: /* URL:timer_slop */ case TCP_RACK_ENABLE_HYSTART: /* URL:hystart */ break; default: /* Filter off all unknown options to the base stack */ return (tcp_default_ctloutput(inp, sopt)); break; } INP_WUNLOCK(inp); if (sopt->sopt_name == TCP_PACING_RATE_CAP) { error = sooptcopyin(sopt, &loptval, sizeof(loptval), sizeof(loptval)); /* * We truncate it down to 32 bits for the socket-option trace this * means rates > 34Gbps won't show right, but thats probably ok. */ optval = (uint32_t)loptval; } else { error = sooptcopyin(sopt, &optval, sizeof(optval), sizeof(optval)); /* Save it in 64 bit form too */ loptval = optval; } if (error) return (error); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { INP_WUNLOCK(inp); return (ECONNRESET); } if (tp->t_fb != &__tcp_rack) { INP_WUNLOCK(inp); return (ENOPROTOOPT); } if (rack->defer_options && (rack->gp_ready == 0) && (sopt->sopt_name != TCP_DEFER_OPTIONS) && (sopt->sopt_name != TCP_RACK_PACING_BETA) && (sopt->sopt_name != TCP_RACK_PACING_BETA_ECN) && (sopt->sopt_name != TCP_RACK_MEASURE_CNT)) { /* Options are beind deferred */ if (rack_add_deferred_option(rack, sopt->sopt_name, loptval)) { INP_WUNLOCK(inp); return (0); } else { /* No memory to defer, fail */ INP_WUNLOCK(inp); return (ENOMEM); } } error = rack_process_option(tp, rack, sopt->sopt_name, optval, loptval); INP_WUNLOCK(inp); return (error); } static void rack_fill_info(struct tcpcb *tp, struct tcp_info *ti) { INP_WLOCK_ASSERT(tptoinpcb(tp)); bzero(ti, sizeof(*ti)); ti->tcpi_state = tp->t_state; if ((tp->t_flags & TF_REQ_TSTMP) && (tp->t_flags & TF_RCVD_TSTMP)) ti->tcpi_options |= TCPI_OPT_TIMESTAMPS; if (tp->t_flags & TF_SACK_PERMIT) ti->tcpi_options |= TCPI_OPT_SACK; if ((tp->t_flags & TF_REQ_SCALE) && (tp->t_flags & TF_RCVD_SCALE)) { ti->tcpi_options |= TCPI_OPT_WSCALE; ti->tcpi_snd_wscale = tp->snd_scale; ti->tcpi_rcv_wscale = tp->rcv_scale; } if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) ti->tcpi_options |= TCPI_OPT_ECN; if (tp->t_flags & TF_FASTOPEN) ti->tcpi_options |= TCPI_OPT_TFO; /* still kept in ticks is t_rcvtime */ ti->tcpi_last_data_recv = ((uint32_t)ticks - tp->t_rcvtime) * tick; /* Since we hold everything in precise useconds this is easy */ ti->tcpi_rtt = tp->t_srtt; ti->tcpi_rttvar = tp->t_rttvar; ti->tcpi_rto = tp->t_rxtcur; ti->tcpi_snd_ssthresh = tp->snd_ssthresh; ti->tcpi_snd_cwnd = tp->snd_cwnd; /* * FreeBSD-specific extension fields for tcp_info. */ ti->tcpi_rcv_space = tp->rcv_wnd; ti->tcpi_rcv_nxt = tp->rcv_nxt; ti->tcpi_snd_wnd = tp->snd_wnd; ti->tcpi_snd_bwnd = 0; /* Unused, kept for compat. */ ti->tcpi_snd_nxt = tp->snd_nxt; ti->tcpi_snd_mss = tp->t_maxseg; ti->tcpi_rcv_mss = tp->t_maxseg; ti->tcpi_snd_rexmitpack = tp->t_sndrexmitpack; ti->tcpi_rcv_ooopack = tp->t_rcvoopack; ti->tcpi_snd_zerowin = tp->t_sndzerowin; #ifdef NETFLIX_STATS ti->tcpi_total_tlp = tp->t_sndtlppack; ti->tcpi_total_tlp_bytes = tp->t_sndtlpbyte; memcpy(&ti->tcpi_rxsyninfo, &tp->t_rxsyninfo, sizeof(struct tcpsyninfo)); #endif #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) { ti->tcpi_options |= TCPI_OPT_TOE; tcp_offload_tcp_info(tp, ti); } #endif } static int rack_get_sockopt(struct inpcb *inp, struct sockopt *sopt) { struct tcpcb *tp; struct tcp_rack *rack; int32_t error, optval; uint64_t val, loptval; struct tcp_info ti; /* * Because all our options are either boolean or an int, we can just * pull everything into optval and then unlock and copy. If we ever * add a option that is not a int, then this will have quite an * impact to this routine. */ error = 0; tp = intotcpcb(inp); rack = (struct tcp_rack *)tp->t_fb_ptr; if (rack == NULL) { INP_WUNLOCK(inp); return (EINVAL); } switch (sopt->sopt_name) { case TCP_INFO: /* First get the info filled */ rack_fill_info(tp, &ti); /* Fix up the rtt related fields if needed */ INP_WUNLOCK(inp); error = sooptcopyout(sopt, &ti, sizeof ti); return (error); /* * Beta is the congestion control value for NewReno that influences how * much of a backoff happens when loss is detected. It is normally set * to 50 for 50% i.e. the cwnd is reduced to 50% of its previous value * when you exit recovery. */ case TCP_RACK_PACING_BETA: if (strcmp(tp->t_cc->name, CCALGONAME_NEWRENO) != 0) error = EINVAL; else if (rack->rc_pacing_cc_set == 0) optval = rack->r_ctl.rc_saved_beta.beta; else { /* * Reach out into the CC data and report back what * I have previously set. Yeah it looks hackish but * we don't want to report the saved values. */ if (tp->t_ccv.cc_data) optval = ((struct newreno *)tp->t_ccv.cc_data)->beta; else error = EINVAL; } break; /* * Beta_ecn is the congestion control value for NewReno that influences how * much of a backoff happens when a ECN mark is detected. It is normally set * to 80 for 80% i.e. the cwnd is reduced by 20% of its previous value when * you exit recovery. Note that classic ECN has a beta of 50, it is only * ABE Ecn that uses this "less" value, but we do too with pacing :) */ case TCP_RACK_PACING_BETA_ECN: if (strcmp(tp->t_cc->name, CCALGONAME_NEWRENO) != 0) error = EINVAL; else if (rack->rc_pacing_cc_set == 0) optval = rack->r_ctl.rc_saved_beta.beta_ecn; else { /* * Reach out into the CC data and report back what * I have previously set. Yeah it looks hackish but * we don't want to report the saved values. */ if (tp->t_ccv.cc_data) optval = ((struct newreno *)tp->t_ccv.cc_data)->beta_ecn; else error = EINVAL; } break; case TCP_RACK_DSACK_OPT: optval = 0; if (rack->rc_rack_tmr_std_based) { optval |= 1; } if (rack->rc_rack_use_dsack) { optval |= 2; } break; case TCP_RACK_ENABLE_HYSTART: { if (tp->t_ccv.flags & CCF_HYSTART_ALLOWED) { optval = RACK_HYSTART_ON; if (tp->t_ccv.flags & CCF_HYSTART_CAN_SH_CWND) optval = RACK_HYSTART_ON_W_SC; if (tp->t_ccv.flags & CCF_HYSTART_CONS_SSTH) optval = RACK_HYSTART_ON_W_SC_C; } else { optval = RACK_HYSTART_OFF; } } break; case TCP_FAST_RSM_HACK: optval = rack->fast_rsm_hack; break; case TCP_DEFER_OPTIONS: optval = rack->defer_options; break; case TCP_RACK_MEASURE_CNT: optval = rack->r_ctl.req_measurements; break; case TCP_REC_ABC_VAL: optval = rack->r_use_labc_for_rec; break; case TCP_RACK_ABC_VAL: optval = rack->rc_labc; break; case TCP_HDWR_UP_ONLY: optval= rack->r_up_only; break; case TCP_PACING_RATE_CAP: loptval = rack->r_ctl.bw_rate_cap; break; case TCP_RACK_PROFILE: /* You cannot retrieve a profile, its write only */ error = EINVAL; break; case TCP_USE_CMP_ACKS: optval = rack->r_use_cmp_ack; break; case TCP_RACK_PACE_TO_FILL: optval = rack->rc_pace_to_cwnd; if (optval && rack->r_fill_less_agg) optval++; break; case TCP_RACK_NO_PUSH_AT_MAX: optval = rack->r_ctl.rc_no_push_at_mrtt; break; case TCP_SHARED_CWND_ENABLE: optval = rack->rack_enable_scwnd; break; case TCP_RACK_NONRXT_CFG_RATE: optval = rack->rack_rec_nonrxt_use_cr; break; case TCP_NO_PRR: if (rack->rack_no_prr == 1) optval = 1; else if (rack->no_prr_addback == 1) optval = 2; else optval = 0; break; case TCP_RACK_DO_DETECTION: optval = rack->do_detection; break; case TCP_RACK_MBUF_QUEUE: /* Now do we use the LRO mbuf-queue feature */ optval = rack->r_mbuf_queue; break; case TCP_TIMELY_DYN_ADJ: optval = rack->rc_gp_dyn_mul; break; case TCP_BBR_IWINTSO: optval = rack->rc_init_win; break; case TCP_RACK_TLP_REDUCE: /* RACK TLP cwnd reduction (bool) */ optval = rack->r_ctl.rc_tlp_cwnd_reduce; break; case TCP_BBR_RACK_INIT_RATE: val = rack->r_ctl.init_rate; /* convert to kbits per sec */ val *= 8; val /= 1000; optval = (uint32_t)val; break; case TCP_RACK_FORCE_MSEG: optval = rack->rc_force_max_seg; break; case TCP_RACK_PACE_MAX_SEG: /* Max segments in a pace */ optval = rack->rc_user_set_max_segs; break; case TCP_RACK_PACE_ALWAYS: /* Use the always pace method */ optval = rack->rc_always_pace; break; case TCP_RACK_PRR_SENDALOT: /* Allow PRR to send more than one seg */ optval = rack->r_ctl.rc_prr_sendalot; break; case TCP_RACK_MIN_TO: /* Minimum time between rack t-o's in ms */ optval = rack->r_ctl.rc_min_to; break; case TCP_RACK_EARLY_SEG: /* If early recovery max segments */ optval = rack->r_ctl.rc_early_recovery_segs; break; case TCP_RACK_REORD_THRESH: /* RACK reorder threshold (shift amount) */ optval = rack->r_ctl.rc_reorder_shift; break; case TCP_RACK_REORD_FADE: /* Does reordering fade after ms time */ optval = rack->r_ctl.rc_reorder_fade; break; case TCP_BBR_USE_RACK_RR: /* Do we use the rack cheat for rxt */ optval = rack->use_rack_rr; break; case TCP_RACK_RR_CONF: optval = rack->r_rr_config; break; case TCP_HDWR_RATE_CAP: optval = rack->r_rack_hw_rate_caps; break; case TCP_BBR_HDWR_PACE: optval = rack->rack_hdw_pace_ena; break; case TCP_RACK_TLP_THRESH: /* RACK TLP theshold i.e. srtt+(srtt/N) */ optval = rack->r_ctl.rc_tlp_threshold; break; case TCP_RACK_PKT_DELAY: /* RACK added ms i.e. rack-rtt + reord + N */ optval = rack->r_ctl.rc_pkt_delay; break; case TCP_RACK_TLP_USE: optval = rack->rack_tlp_threshold_use; break; case TCP_RACK_PACE_RATE_CA: optval = rack->r_ctl.rc_fixed_pacing_rate_ca; break; case TCP_RACK_PACE_RATE_SS: optval = rack->r_ctl.rc_fixed_pacing_rate_ss; break; case TCP_RACK_PACE_RATE_REC: optval = rack->r_ctl.rc_fixed_pacing_rate_rec; break; case TCP_RACK_GP_INCREASE_SS: optval = rack->r_ctl.rack_per_of_gp_ca; break; case TCP_RACK_GP_INCREASE_CA: optval = rack->r_ctl.rack_per_of_gp_ss; break; case TCP_BBR_RACK_RTT_USE: optval = rack->r_ctl.rc_rate_sample_method; break; case TCP_DELACK: optval = tp->t_delayed_ack; break; case TCP_DATA_AFTER_CLOSE: optval = rack->rc_allow_data_af_clo; break; case TCP_SHARED_CWND_TIME_LIMIT: optval = rack->r_limit_scw; break; case TCP_RACK_TIMER_SLOP: optval = rack->r_ctl.timer_slop; break; default: return (tcp_default_ctloutput(inp, sopt)); break; } INP_WUNLOCK(inp); if (error == 0) { if (TCP_PACING_RATE_CAP) error = sooptcopyout(sopt, &loptval, sizeof loptval); else error = sooptcopyout(sopt, &optval, sizeof optval); } return (error); } static int rack_ctloutput(struct inpcb *inp, struct sockopt *sopt) { if (sopt->sopt_dir == SOPT_SET) { return (rack_set_sockopt(inp, sopt)); } else if (sopt->sopt_dir == SOPT_GET) { return (rack_get_sockopt(inp, sopt)); } else { panic("%s: sopt_dir $%d", __func__, sopt->sopt_dir); } } static const char *rack_stack_names[] = { __XSTRING(STACKNAME), #ifdef STACKALIAS __XSTRING(STACKALIAS), #endif }; static int rack_ctor(void *mem, int32_t size, void *arg, int32_t how) { memset(mem, 0, size); return (0); } static void rack_dtor(void *mem, int32_t size, void *arg) { } static bool rack_mod_inited = false; static int tcp_addrack(module_t mod, int32_t type, void *data) { int32_t err = 0; int num_stacks; switch (type) { case MOD_LOAD: rack_zone = uma_zcreate(__XSTRING(MODNAME) "_map", sizeof(struct rack_sendmap), rack_ctor, rack_dtor, NULL, NULL, UMA_ALIGN_PTR, 0); rack_pcb_zone = uma_zcreate(__XSTRING(MODNAME) "_pcb", sizeof(struct tcp_rack), rack_ctor, NULL, NULL, NULL, UMA_ALIGN_CACHE, 0); sysctl_ctx_init(&rack_sysctl_ctx); rack_sysctl_root = SYSCTL_ADD_NODE(&rack_sysctl_ctx, SYSCTL_STATIC_CHILDREN(_net_inet_tcp), OID_AUTO, #ifdef STACKALIAS __XSTRING(STACKALIAS), #else __XSTRING(STACKNAME), #endif CTLFLAG_RW | CTLFLAG_MPSAFE, 0, ""); if (rack_sysctl_root == NULL) { printf("Failed to add sysctl node\n"); err = EFAULT; goto free_uma; } rack_init_sysctls(); num_stacks = nitems(rack_stack_names); err = register_tcp_functions_as_names(&__tcp_rack, M_WAITOK, rack_stack_names, &num_stacks); if (err) { printf("Failed to register %s stack name for " "%s module\n", rack_stack_names[num_stacks], __XSTRING(MODNAME)); sysctl_ctx_free(&rack_sysctl_ctx); free_uma: uma_zdestroy(rack_zone); uma_zdestroy(rack_pcb_zone); rack_counter_destroy(); printf("Failed to register rack module -- err:%d\n", err); return (err); } tcp_lro_reg_mbufq(); rack_mod_inited = true; break; case MOD_QUIESCE: err = deregister_tcp_functions(&__tcp_rack, true, false); break; case MOD_UNLOAD: err = deregister_tcp_functions(&__tcp_rack, false, true); if (err == EBUSY) break; if (rack_mod_inited) { uma_zdestroy(rack_zone); uma_zdestroy(rack_pcb_zone); sysctl_ctx_free(&rack_sysctl_ctx); rack_counter_destroy(); rack_mod_inited = false; } tcp_lro_dereg_mbufq(); err = 0; break; default: return (EOPNOTSUPP); } return (err); } static moduledata_t tcp_rack = { .name = __XSTRING(MODNAME), .evhand = tcp_addrack, .priv = 0 }; MODULE_VERSION(MODNAME, 1); DECLARE_MODULE(MODNAME, tcp_rack, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY); MODULE_DEPEND(MODNAME, tcphpts, 1, 1, 1); diff --git a/sys/netinet/tcp_stacks/rack_bbr_common.c b/sys/netinet/tcp_stacks/rack_bbr_common.c index b51d82e9270e..d684132f80c3 100644 --- a/sys/netinet/tcp_stacks/rack_bbr_common.c +++ b/sys/netinet/tcp_stacks/rack_bbr_common.c @@ -1,1066 +1,1062 @@ /*- * Copyright (c) 2016-2020 Netflix, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * */ /* * Author: Randall Stewart * This work is based on the ACM Queue paper * BBR - Congestion Based Congestion Control * and also numerous discussions with Neal, Yuchung and Van. */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" -#include "opt_tcpdebug.h" #include "opt_ratelimit.h" #include "opt_kern_tls.h" #include #include #include #include #ifdef TCP_HHOOK #include #endif #include #include #include #include #include #include #ifdef KERN_TLS #include #endif #include #include #include #ifdef NETFLIX_STATS #include /* Must come after qmath.h and tree.h */ #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define TCPSTATES /* for logging */ #include #include #include #include #include /* required for icmp_var.h */ #include /* for ICMP_BANDLIM */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#ifdef TCPDEBUG -#include -#endif /* TCPDEBUG */ #ifdef TCP_OFFLOAD #include #endif #ifdef INET6 #include #endif #include #include #include #include #if defined(IPSEC) || defined(IPSEC_SUPPORT) #include #include #endif /* IPSEC */ #include #include #include #ifdef MAC #include #endif #include "rack_bbr_common.h" /* * Common TCP Functions - These are shared by borth * rack and BBR. */ #ifdef KERN_TLS uint32_t ctf_get_opt_tls_size(struct socket *so, uint32_t rwnd) { struct ktls_session *tls; uint32_t len; again: tls = so->so_snd.sb_tls_info; len = tls->params.max_frame_len; /* max tls payload */ len += tls->params.tls_hlen; /* tls header len */ len += tls->params.tls_tlen; /* tls trailer len */ if ((len * 4) > rwnd) { /* * Stroke this will suck counter and what * else should we do Drew? From the * TCP perspective I am not sure * what should be done... */ if (tls->params.max_frame_len > 4096) { tls->params.max_frame_len -= 4096; if (tls->params.max_frame_len < 4096) tls->params.max_frame_len = 4096; goto again; } } return (len); } #endif static int ctf_get_enet_type(struct ifnet *ifp, struct mbuf *m) { struct ether_header *eh; #ifdef INET6 struct ip6_hdr *ip6 = NULL; /* Keep compiler happy. */ #endif #ifdef INET struct ip *ip = NULL; /* Keep compiler happy. */ #endif #if defined(INET) || defined(INET6) struct tcphdr *th; int32_t tlen; uint16_t drop_hdrlen; #endif uint16_t etype; #ifdef INET uint8_t iptos; #endif /* Is it the easy way? */ if (m->m_flags & M_LRO_EHDRSTRP) return (m->m_pkthdr.lro_etype); /* * Ok this is the old style call, the ethernet header is here. * This also means no checksum or BPF were done. This * can happen if the race to setup the inp fails and * LRO sees no INP at packet input, but by the time * we queue the packets an INP gets there. Its rare * but it can occur so we will handle it. Note that * this means duplicated work but with the rarity of it * its not worth worrying about. */ /* Let the BPF see the packet */ if (bpf_peers_present(ifp->if_bpf)) ETHER_BPF_MTAP(ifp, m); /* Now the csum */ eh = mtod(m, struct ether_header *); etype = ntohs(eh->ether_type); m_adj(m, sizeof(*eh)); switch (etype) { #ifdef INET6 case ETHERTYPE_IPV6: { if (m->m_len < (sizeof(*ip6) + sizeof(*th))) { m = m_pullup(m, sizeof(*ip6) + sizeof(*th)); if (m == NULL) { KMOD_TCPSTAT_INC(tcps_rcvshort); return (-1); } } ip6 = (struct ip6_hdr *)(eh + 1); th = (struct tcphdr *)(ip6 + 1); drop_hdrlen = sizeof(*ip6); tlen = ntohs(ip6->ip6_plen); if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) { if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) th->th_sum = m->m_pkthdr.csum_data; else th->th_sum = in6_cksum_pseudo(ip6, tlen, IPPROTO_TCP, m->m_pkthdr.csum_data); th->th_sum ^= 0xffff; } else th->th_sum = in6_cksum(m, IPPROTO_TCP, drop_hdrlen, tlen); if (th->th_sum) { KMOD_TCPSTAT_INC(tcps_rcvbadsum); m_freem(m); return (-1); } return (etype); } #endif #ifdef INET case ETHERTYPE_IP: { if (m->m_len < sizeof (struct tcpiphdr)) { m = m_pullup(m, sizeof (struct tcpiphdr)); if (m == NULL) { KMOD_TCPSTAT_INC(tcps_rcvshort); return (-1); } } ip = (struct ip *)(eh + 1); th = (struct tcphdr *)(ip + 1); drop_hdrlen = sizeof(*ip); iptos = ip->ip_tos; tlen = ntohs(ip->ip_len) - sizeof(struct ip); if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) th->th_sum = m->m_pkthdr.csum_data; else th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htonl(m->m_pkthdr.csum_data + tlen + IPPROTO_TCP)); th->th_sum ^= 0xffff; } else { int len; struct ipovly *ipov = (struct ipovly *)ip; /* * Checksum extended TCP header and data. */ len = drop_hdrlen + tlen; bzero(ipov->ih_x1, sizeof(ipov->ih_x1)); ipov->ih_len = htons(tlen); th->th_sum = in_cksum(m, len); /* Reset length for SDT probes. */ ip->ip_len = htons(len); /* Reset TOS bits */ ip->ip_tos = iptos; /* Re-initialization for later version check */ ip->ip_v = IPVERSION; ip->ip_hl = sizeof(*ip) >> 2; } if (th->th_sum) { KMOD_TCPSTAT_INC(tcps_rcvbadsum); m_freem(m); return (-1); } break; } #endif }; return (etype); } /* * The function ctf_process_inbound_raw() is used by * transport developers to do the steps needed to * support MBUF Queuing i.e. the flags in * inp->inp_flags2: * * - INP_SUPPORTS_MBUFQ * - INP_MBUF_QUEUE_READY * - INP_DONT_SACK_QUEUE * - INP_MBUF_ACKCMP * * These flags help control how LRO will deliver * packets to the transport. You first set in inp_flags2 * the INP_SUPPORTS_MBUFQ to tell the LRO code that you * will gladly take a queue of packets instead of a compressed * single packet. You also set in your t_fb pointer the * tfb_do_queued_segments to point to ctf_process_inbound_raw. * * This then gets you lists of inbound ACK's/Data instead * of a condensed compressed ACK/DATA packet. Why would you * want that? This will get you access to all the arrival * times of at least LRO and possibly at the Hardware (if * the interface card supports that) of the actual ACK/DATA. * In some transport designs this is important since knowing * the actual time we got the packet is useful information. * * A new special type of mbuf may also be supported by the transport * if it has set the INP_MBUF_ACKCMP flag. If its set, LRO will * possibly create a M_ACKCMP type mbuf. This is a mbuf with * an array of "acks". One thing also to note is that when this * occurs a subsequent LRO may find at the back of the untouched * mbuf queue chain a M_ACKCMP and append on to it. This means * that until the transport pulls in the mbuf chain queued * for it more ack's may get on the mbufs that were already * delivered. There currently is a limit of 6 acks condensed * into 1 mbuf which means often when this is occuring, we * don't get that effect but it does happen. * * Now there are some interesting Caveats that the transport * designer needs to take into account when using this feature. * * 1) It is used with HPTS and pacing, when the pacing timer * for output calls it will first call the input. * 2) When you set INP_MBUF_QUEUE_READY this tells LRO * queue normal packets, I am busy pacing out data and * will process the queued packets before my tfb_tcp_output * call from pacing. If a non-normal packet arrives, (e.g. sack) * you will be awoken immediately. * 3) Finally you can add the INP_DONT_SACK_QUEUE to not even * be awoken if a SACK has arrived. You would do this when * you were not only running a pacing for output timer * but a Rack timer as well i.e. you know you are in recovery * and are in the process (via the timers) of dealing with * the loss. * * Now a critical thing you must be aware of here is that the * use of the flags has a far greater scope then just your * typical LRO. Why? Well thats because in the normal compressed * LRO case at the end of a driver interupt all packets are going * to get presented to the transport no matter if there is one * or 100. With the MBUF_QUEUE model, this is not true. You will * only be awoken to process the queue of packets when: * a) The flags discussed above allow it. * * b) You exceed a ack or data limit (by default the * ack limit is infinity (64k acks) and the data * limit is 64k of new TCP data) * * c) The push bit has been set by the peer */ int ctf_process_inbound_raw(struct tcpcb *tp, struct socket *so, struct mbuf *m, int has_pkt) { /* * We are passed a raw change of mbuf packets * that arrived in LRO. They are linked via * the m_nextpkt link in the pkt-headers. * * We process each one by: * a) saving off the next * b) stripping off the ether-header * c) formulating the arguments for * the tfb_tcp_hpts_do_segment * d) calling each mbuf to tfb_tcp_hpts_do_segment * after adjusting the time to match the arrival time. * Note that the LRO code assures no IP options are present. * * The symantics for calling tfb_tcp_hpts_do_segment are the * following: * 1) It returns 0 if all went well and you (the caller) need * to release the lock. * 2) If nxt_pkt is set, then the function will surpress calls * to tcp_output() since you are promising to call again * with another packet. * 3) If it returns 1, then you must free all the packets being * shipped in, the tcb has been destroyed (or about to be destroyed). */ struct mbuf *m_save; struct tcphdr *th; #ifdef INET6 struct ip6_hdr *ip6 = NULL; /* Keep compiler happy. */ #endif #ifdef INET struct ip *ip = NULL; /* Keep compiler happy. */ #endif struct ifnet *ifp; struct timeval tv; struct inpcb *inp __diagused; int32_t retval, nxt_pkt, tlen, off; int etype = 0; uint16_t drop_hdrlen; uint8_t iptos, no_vn=0; inp = tptoinpcb(tp); INP_WLOCK_ASSERT(inp); NET_EPOCH_ASSERT(); if (m) ifp = m_rcvif(m); else ifp = NULL; if (ifp == NULL) { /* * We probably should not work around * but kassert, since lro alwasy sets rcvif. */ no_vn = 1; goto skip_vnet; } CURVNET_SET(ifp->if_vnet); skip_vnet: tcp_get_usecs(&tv); while (m) { m_save = m->m_nextpkt; m->m_nextpkt = NULL; if ((m->m_flags & M_ACKCMP) == 0) { /* Now lets get the ether header */ etype = ctf_get_enet_type(ifp, m); if (etype == -1) { /* Skip this packet it was freed by checksum */ goto skipped_pkt; } KASSERT(((etype == ETHERTYPE_IPV6) || (etype == ETHERTYPE_IP)), ("tp:%p m:%p etype:0x%x -- not IP or IPv6", tp, m, etype)); /* Trim off the ethernet header */ switch (etype) { #ifdef INET6 case ETHERTYPE_IPV6: ip6 = mtod(m, struct ip6_hdr *); th = (struct tcphdr *)(ip6 + 1); tlen = ntohs(ip6->ip6_plen); drop_hdrlen = sizeof(*ip6); iptos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; break; #endif #ifdef INET case ETHERTYPE_IP: ip = mtod(m, struct ip *); th = (struct tcphdr *)(ip + 1); drop_hdrlen = sizeof(*ip); iptos = ip->ip_tos; tlen = ntohs(ip->ip_len) - sizeof(struct ip); break; #endif } /* end switch */ /* * Convert TCP protocol specific fields to host format. */ tcp_fields_to_host(th); off = th->th_off << 2; if (off < sizeof (struct tcphdr) || off > tlen) { printf("off:%d < hdrlen:%zu || > tlen:%u -- dump\n", off, sizeof(struct tcphdr), tlen); KMOD_TCPSTAT_INC(tcps_rcvbadoff); m_freem(m); goto skipped_pkt; } tlen -= off; drop_hdrlen += off; /* * Now lets setup the timeval to be when we should * have been called (if we can). */ m->m_pkthdr.lro_nsegs = 1; /* Now what about next packet? */ } else { /* * This mbuf is an array of acks that have * been compressed. We assert the inp has * the flag set to enable this! */ KASSERT((inp->inp_flags2 & INP_MBUF_ACKCMP), ("tp:%p inp:%p no INP_MBUF_ACKCMP flags?", tp, inp)); tlen = 0; drop_hdrlen = 0; th = NULL; iptos = 0; } tcp_get_usecs(&tv); if (m_save || has_pkt) nxt_pkt = 1; else nxt_pkt = 0; if ((m->m_flags & M_ACKCMP) == 0) KMOD_TCPSTAT_INC(tcps_rcvtotal); else KMOD_TCPSTAT_ADD(tcps_rcvtotal, (m->m_len / sizeof(struct tcp_ackent))); retval = (*tp->t_fb->tfb_do_segment_nounlock)(m, th, so, tp, drop_hdrlen, tlen, iptos, nxt_pkt, &tv); if (retval) { /* We lost the lock and tcb probably */ m = m_save; while(m) { m_save = m->m_nextpkt; m->m_nextpkt = NULL; m_freem(m); m = m_save; } if (no_vn == 0) { CURVNET_RESTORE(); } INP_UNLOCK_ASSERT(inp); return(retval); } skipped_pkt: m = m_save; } if (no_vn == 0) { CURVNET_RESTORE(); } return(retval); } int ctf_do_queued_segments(struct socket *so, struct tcpcb *tp, int have_pkt) { struct mbuf *m; /* First lets see if we have old packets */ if (tp->t_in_pkt) { m = tp->t_in_pkt; tp->t_in_pkt = NULL; tp->t_tail_pkt = NULL; if (ctf_process_inbound_raw(tp, so, m, have_pkt)) { /* We lost the tcpcb (maybe a RST came in)? */ return(1); } } return (0); } uint32_t ctf_outstanding(struct tcpcb *tp) { uint32_t bytes_out; bytes_out = tp->snd_max - tp->snd_una; if (tp->t_state < TCPS_ESTABLISHED) bytes_out++; if (tp->t_flags & TF_SENTFIN) bytes_out++; return (bytes_out); } uint32_t ctf_flight_size(struct tcpcb *tp, uint32_t rc_sacked) { if (rc_sacked <= ctf_outstanding(tp)) return(ctf_outstanding(tp) - rc_sacked); else { return (0); } } void ctf_do_dropwithreset(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32_t rstreason, int32_t tlen) { if (tp != NULL) { tcp_dropwithreset(m, th, tp, tlen, rstreason); INP_WUNLOCK(tptoinpcb(tp)); } else tcp_dropwithreset(m, th, NULL, tlen, rstreason); } void ctf_ack_war_checks(struct tcpcb *tp, uint32_t *ts, uint32_t *cnt) { if ((ts != NULL) && (cnt != NULL) && (tcp_ack_war_time_window > 0) && (tcp_ack_war_cnt > 0)) { /* We are possibly doing ack war prevention */ uint32_t cts; /* * We use a msec tick here which gives us * roughly 49 days. We don't need the * precision of a microsecond timestamp which * would only give us hours. */ cts = tcp_ts_getticks(); if (TSTMP_LT((*ts), cts)) { /* Timestamp is in the past */ *cnt = 0; *ts = (cts + tcp_ack_war_time_window); } if (*cnt < tcp_ack_war_cnt) { *cnt = (*cnt + 1); tp->t_flags |= TF_ACKNOW; } else tp->t_flags &= ~TF_ACKNOW; } else tp->t_flags |= TF_ACKNOW; } /* * ctf_drop_checks returns 1 for you should not proceed. It places * in ret_val what should be returned 1/0 by the caller. The 1 indicates * that the TCB is unlocked and probably dropped. The 0 indicates the * TCB is still valid and locked. */ int _ctf_drop_checks(struct tcpopt *to, struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, int32_t *tlenp, int32_t *thf, int32_t *drop_hdrlen, int32_t *ret_val, uint32_t *ts, uint32_t *cnt) { int32_t todrop; int32_t thflags; int32_t tlen; thflags = *thf; tlen = *tlenp; todrop = tp->rcv_nxt - th->th_seq; if (todrop > 0) { if (thflags & TH_SYN) { thflags &= ~TH_SYN; th->th_seq++; if (th->th_urp > 1) th->th_urp--; else thflags &= ~TH_URG; todrop--; } /* * Following if statement from Stevens, vol. 2, p. 960. */ if (todrop > tlen || (todrop == tlen && (thflags & TH_FIN) == 0)) { /* * Any valid FIN must be to the left of the window. * At this point the FIN must be a duplicate or out * of sequence; drop it. */ thflags &= ~TH_FIN; /* * Send an ACK to resynchronize and drop any data. * But keep on processing for RST or ACK. */ ctf_ack_war_checks(tp, ts, cnt); todrop = tlen; KMOD_TCPSTAT_INC(tcps_rcvduppack); KMOD_TCPSTAT_ADD(tcps_rcvdupbyte, todrop); } else { KMOD_TCPSTAT_INC(tcps_rcvpartduppack); KMOD_TCPSTAT_ADD(tcps_rcvpartdupbyte, todrop); } /* * DSACK - add SACK block for dropped range */ if ((todrop > 0) && (tp->t_flags & TF_SACK_PERMIT)) { /* * ACK now, as the next in-sequence segment * will clear the DSACK block again */ ctf_ack_war_checks(tp, ts, cnt); if (tp->t_flags & TF_ACKNOW) tcp_update_sack_list(tp, th->th_seq, th->th_seq + todrop); } *drop_hdrlen += todrop; /* drop from the top afterwards */ th->th_seq += todrop; tlen -= todrop; if (th->th_urp > todrop) th->th_urp -= todrop; else { thflags &= ~TH_URG; th->th_urp = 0; } } /* * If segment ends after window, drop trailing data (and PUSH and * FIN); if nothing left, just ACK. */ todrop = (th->th_seq + tlen) - (tp->rcv_nxt + tp->rcv_wnd); if (todrop > 0) { KMOD_TCPSTAT_INC(tcps_rcvpackafterwin); if (todrop >= tlen) { KMOD_TCPSTAT_ADD(tcps_rcvbyteafterwin, tlen); /* * If window is closed can only take segments at * window edge, and have to drop data and PUSH from * incoming segments. Continue processing, but * remember to ack. Otherwise, drop segment and * ack. */ if (tp->rcv_wnd == 0 && th->th_seq == tp->rcv_nxt) { ctf_ack_war_checks(tp, ts, cnt); KMOD_TCPSTAT_INC(tcps_rcvwinprobe); } else { __ctf_do_dropafterack(m, tp, th, thflags, tlen, ret_val, ts, cnt); return (1); } } else KMOD_TCPSTAT_ADD(tcps_rcvbyteafterwin, todrop); m_adj(m, -todrop); tlen -= todrop; thflags &= ~(TH_PUSH | TH_FIN); } *thf = thflags; *tlenp = tlen; return (0); } /* * The value in ret_val informs the caller * if we dropped the tcb (and lock) or not. * 1 = we dropped it, 0 = the TCB is still locked * and valid. */ void __ctf_do_dropafterack(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32_t thflags, int32_t tlen, int32_t *ret_val, uint32_t *ts, uint32_t *cnt) { /* * Generate an ACK dropping incoming segment if it occupies sequence * space, where the ACK reflects our state. * * We can now skip the test for the RST flag since all paths to this * code happen after packets containing RST have been dropped. * * In the SYN-RECEIVED state, don't send an ACK unless the segment * we received passes the SYN-RECEIVED ACK test. If it fails send a * RST. This breaks the loop in the "LAND" DoS attack, and also * prevents an ACK storm between two listening ports that have been * sent forged SYN segments, each with the source address of the * other. */ if (tp->t_state == TCPS_SYN_RECEIVED && (thflags & TH_ACK) && (SEQ_GT(tp->snd_una, th->th_ack) || SEQ_GT(th->th_ack, tp->snd_max))) { *ret_val = 1; ctf_do_dropwithreset(m, tp, th, BANDLIM_RST_OPENPORT, tlen); return; } else *ret_val = 0; ctf_ack_war_checks(tp, ts, cnt); if (m) m_freem(m); } void ctf_do_drop(struct mbuf *m, struct tcpcb *tp) { /* * Drop space held by incoming segment and return. */ if (tp != NULL) INP_WUNLOCK(tptoinpcb(tp)); if (m) m_freem(m); } int __ctf_process_rst(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, uint32_t *ts, uint32_t *cnt) { /* * RFC5961 Section 3.2 * * - RST drops connection only if SEG.SEQ == RCV.NXT. - If RST is in * window, we send challenge ACK. * * Note: to take into account delayed ACKs, we should test against * last_ack_sent instead of rcv_nxt. Note 2: we handle special case * of closed window, not covered by the RFC. */ int dropped = 0; if ((SEQ_GEQ(th->th_seq, tp->last_ack_sent) && SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) || (tp->rcv_wnd == 0 && tp->last_ack_sent == th->th_seq)) { KASSERT(tp->t_state != TCPS_SYN_SENT, ("%s: TH_RST for TCPS_SYN_SENT th %p tp %p", __func__, th, tp)); if (V_tcp_insecure_rst || (tp->last_ack_sent == th->th_seq) || (tp->rcv_nxt == th->th_seq)) { KMOD_TCPSTAT_INC(tcps_drops); /* Drop the connection. */ switch (tp->t_state) { case TCPS_SYN_RECEIVED: so->so_error = ECONNREFUSED; goto close; case TCPS_ESTABLISHED: case TCPS_FIN_WAIT_1: case TCPS_FIN_WAIT_2: case TCPS_CLOSE_WAIT: case TCPS_CLOSING: case TCPS_LAST_ACK: so->so_error = ECONNRESET; close: tcp_state_change(tp, TCPS_CLOSED); /* FALLTHROUGH */ default: tcp_log_end_status(tp, TCP_EI_STATUS_CLIENT_RST); tp = tcp_close(tp); } dropped = 1; ctf_do_drop(m, tp); } else { int send_challenge; KMOD_TCPSTAT_INC(tcps_badrst); if ((ts != NULL) && (cnt != NULL) && (tcp_ack_war_time_window > 0) && (tcp_ack_war_cnt > 0)) { /* We are possibly preventing an ack-rst war prevention */ uint32_t cts; /* * We use a msec tick here which gives us * roughly 49 days. We don't need the * precision of a microsecond timestamp which * would only give us hours. */ cts = tcp_ts_getticks(); if (TSTMP_LT((*ts), cts)) { /* Timestamp is in the past */ *cnt = 0; *ts = (cts + tcp_ack_war_time_window); } if (*cnt < tcp_ack_war_cnt) { *cnt = (*cnt + 1); send_challenge = 1; } else send_challenge = 0; } else send_challenge = 1; if (send_challenge) { /* Send challenge ACK. */ tcp_respond(tp, mtod(m, void *), th, m, tp->rcv_nxt, tp->snd_nxt, TH_ACK); tp->last_ack_sent = tp->rcv_nxt; } } } else { m_freem(m); } return (dropped); } /* * The value in ret_val informs the caller * if we dropped the tcb (and lock) or not. * 1 = we dropped it, 0 = the TCB is still locked * and valid. */ void ctf_challenge_ack(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, uint8_t iptos, int32_t * ret_val) { NET_EPOCH_ASSERT(); KMOD_TCPSTAT_INC(tcps_badsyn); if (V_tcp_insecure_syn && SEQ_GEQ(th->th_seq, tp->last_ack_sent) && SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) { tp = tcp_drop(tp, ECONNRESET); *ret_val = 1; ctf_do_drop(m, tp); } else { tcp_ecn_input_syn_sent(tp, tcp_get_flags(th), iptos); /* Send challenge ACK. */ tcp_respond(tp, mtod(m, void *), th, m, tp->rcv_nxt, tp->snd_nxt, TH_ACK); tp->last_ack_sent = tp->rcv_nxt; m = NULL; *ret_val = 0; ctf_do_drop(m, NULL); } } /* * ctf_ts_check returns 1 for you should not proceed, the state * machine should return. It places in ret_val what should * be returned 1/0 by the caller (hpts_do_segment). The 1 indicates * that the TCB is unlocked and probably dropped. The 0 indicates the * TCB is still valid and locked. */ int ctf_ts_check(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, int32_t tlen, int32_t thflags, int32_t * ret_val) { if (tcp_ts_getticks() - tp->ts_recent_age > TCP_PAWS_IDLE) { /* * Invalidate ts_recent. If this segment updates ts_recent, * the age will be reset later and ts_recent will get a * valid value. If it does not, setting ts_recent to zero * will at least satisfy the requirement that zero be placed * in the timestamp echo reply when ts_recent isn't valid. * The age isn't reset until we get a valid ts_recent * because we don't want out-of-order segments to be dropped * when ts_recent is old. */ tp->ts_recent = 0; } else { KMOD_TCPSTAT_INC(tcps_rcvduppack); KMOD_TCPSTAT_ADD(tcps_rcvdupbyte, tlen); KMOD_TCPSTAT_INC(tcps_pawsdrop); *ret_val = 0; if (tlen) { ctf_do_dropafterack(m, tp, th, thflags, tlen, ret_val); } else { ctf_do_drop(m, NULL); } return (1); } return (0); } int ctf_ts_check_ac(struct tcpcb *tp, int32_t thflags) { if (tcp_ts_getticks() - tp->ts_recent_age > TCP_PAWS_IDLE) { /* * Invalidate ts_recent. If this segment updates ts_recent, * the age will be reset later and ts_recent will get a * valid value. If it does not, setting ts_recent to zero * will at least satisfy the requirement that zero be placed * in the timestamp echo reply when ts_recent isn't valid. * The age isn't reset until we get a valid ts_recent * because we don't want out-of-order segments to be dropped * when ts_recent is old. */ tp->ts_recent = 0; } else { KMOD_TCPSTAT_INC(tcps_rcvduppack); KMOD_TCPSTAT_INC(tcps_pawsdrop); return (1); } return (0); } void ctf_calc_rwin(struct socket *so, struct tcpcb *tp) { int32_t win; /* * Calculate amount of space in receive window, and then do TCP * input processing. Receive window is amount of space in rcv queue, * but not less than advertised window. */ win = sbspace(&so->so_rcv); if (win < 0) win = 0; tp->rcv_wnd = imax(win, (int)(tp->rcv_adv - tp->rcv_nxt)); } void ctf_do_dropwithreset_conn(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32_t rstreason, int32_t tlen) { tcp_dropwithreset(m, th, tp, tlen, rstreason); tp = tcp_drop(tp, ETIMEDOUT); if (tp) INP_WUNLOCK(tptoinpcb(tp)); } uint32_t ctf_fixed_maxseg(struct tcpcb *tp) { return (tcp_fixed_maxseg(tp)); } void ctf_log_sack_filter(struct tcpcb *tp, int num_sack_blks, struct sackblk *sack_blocks) { if (tp->t_logstate != TCP_LOG_STATE_OFF) { union tcp_log_stackspecific log; struct timeval tv; memset(&log, 0, sizeof(log)); log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.flex8 = num_sack_blks; if (num_sack_blks > 0) { log.u_bbr.flex1 = sack_blocks[0].start; log.u_bbr.flex2 = sack_blocks[0].end; } if (num_sack_blks > 1) { log.u_bbr.flex3 = sack_blocks[1].start; log.u_bbr.flex4 = sack_blocks[1].end; } if (num_sack_blks > 2) { log.u_bbr.flex5 = sack_blocks[2].start; log.u_bbr.flex6 = sack_blocks[2].end; } if (num_sack_blks > 3) { log.u_bbr.applimited = sack_blocks[3].start; log.u_bbr.pkts_out = sack_blocks[3].end; } TCP_LOG_EVENTP(tp, NULL, &tptosocket(tp)->so_rcv, &tptosocket(tp)->so_snd, TCP_SACK_FILTER_RES, 0, 0, &log, false, &tv); } } uint32_t ctf_decay_count(uint32_t count, uint32_t decay) { /* * Given a count, decay it by a set percentage. The * percentage is in thousands i.e. 100% = 1000, * 19.3% = 193. */ uint64_t perc_count, decay_per; uint32_t decayed_count; if (decay > 1000) { /* We don't raise it */ return (count); } perc_count = count; decay_per = decay; perc_count *= decay_per; perc_count /= 1000; /* * So now perc_count holds the * count decay value. */ decayed_count = count - (uint32_t)perc_count; return(decayed_count); } int32_t ctf_progress_timeout_check(struct tcpcb *tp, bool log) { if (tp->t_maxunacktime && tp->t_acktime && TSTMP_GT(ticks, tp->t_acktime)) { if ((ticks - tp->t_acktime) >= tp->t_maxunacktime) { /* * There is an assumption that the caller * will drop the connection so we will * increment the counters here. */ if (log) tcp_log_end_status(tp, TCP_EI_STATUS_PROGRESS); #ifdef NETFLIX_STATS KMOD_TCPSTAT_INC(tcps_progdrops); #endif return (1); } } return (0); } diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 658e72ffa804..607abecfef97 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1,3970 +1,3962 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * @(#)tcp_subr.c 8.2 (Berkeley) 5/24/95 */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" #include "opt_kern_tls.h" -#include "opt_tcpdebug.h" #include #include #include #include #include #ifdef TCP_HHOOK #include #endif #include #ifdef TCP_HHOOK #include #endif #ifdef KERN_TLS #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef INET6 #include #include #include #include #include #include #include #endif #include #ifdef INVARIANTS #define TCPSTATES #endif #include #include #include #include #include #include #include #include #include #include #include #ifdef TCPPCAP #include #endif -#ifdef TCPDEBUG -#include -#endif #ifdef TCP_OFFLOAD #include #endif #include #include #ifdef INET6 #include #endif #include #include #include #include #ifdef INET6 static ip6proto_ctlinput_t tcp6_ctlinput; static udp_tun_icmp_t tcp6_ctlinput_viaudp; #endif VNET_DEFINE(int, tcp_mssdflt) = TCP_MSS; #ifdef INET6 VNET_DEFINE(int, tcp_v6mssdflt) = TCP6_MSS; #endif #ifdef NETFLIX_EXP_DETECTION /* Sack attack detection thresholds and such */ SYSCTL_NODE(_net_inet_tcp, OID_AUTO, sack_attack, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Sack Attack detection thresholds"); int32_t tcp_force_detection = 0; SYSCTL_INT(_net_inet_tcp_sack_attack, OID_AUTO, force_detection, CTLFLAG_RW, &tcp_force_detection, 0, "Do we force detection even if the INP has it off?"); int32_t tcp_sack_to_ack_thresh = 700; /* 70 % */ SYSCTL_INT(_net_inet_tcp_sack_attack, OID_AUTO, sack_to_ack_thresh, CTLFLAG_RW, &tcp_sack_to_ack_thresh, 700, "Percentage of sacks to acks we must see above (10.1 percent is 101)?"); int32_t tcp_sack_to_move_thresh = 600; /* 60 % */ SYSCTL_INT(_net_inet_tcp_sack_attack, OID_AUTO, move_thresh, CTLFLAG_RW, &tcp_sack_to_move_thresh, 600, "Percentage of sack moves we must see above (10.1 percent is 101)"); int32_t tcp_restoral_thresh = 650; /* 65 % (sack:2:ack -5%) */ SYSCTL_INT(_net_inet_tcp_sack_attack, OID_AUTO, restore_thresh, CTLFLAG_RW, &tcp_restoral_thresh, 550, "Percentage of sack to ack percentage we must see below to restore(10.1 percent is 101)"); int32_t tcp_sad_decay_val = 800; SYSCTL_INT(_net_inet_tcp_sack_attack, OID_AUTO, decay_per, CTLFLAG_RW, &tcp_sad_decay_val, 800, "The decay percentage (10.1 percent equals 101 )"); int32_t tcp_map_minimum = 500; SYSCTL_INT(_net_inet_tcp_sack_attack, OID_AUTO, nummaps, CTLFLAG_RW, &tcp_map_minimum, 500, "Number of Map enteries before we start detection"); int32_t tcp_attack_on_turns_on_logging = 0; SYSCTL_INT(_net_inet_tcp_sack_attack, OID_AUTO, attacks_logged, CTLFLAG_RW, &tcp_attack_on_turns_on_logging, 0, "When we have a positive hit on attack, do we turn on logging?"); int32_t tcp_sad_pacing_interval = 2000; SYSCTL_INT(_net_inet_tcp_sack_attack, OID_AUTO, sad_pacing_int, CTLFLAG_RW, &tcp_sad_pacing_interval, 2000, "What is the minimum pacing interval for a classified attacker?"); int32_t tcp_sad_low_pps = 100; SYSCTL_INT(_net_inet_tcp_sack_attack, OID_AUTO, sad_low_pps, CTLFLAG_RW, &tcp_sad_low_pps, 100, "What is the input pps that below which we do not decay?"); #endif uint32_t tcp_ack_war_time_window = 1000; SYSCTL_UINT(_net_inet_tcp, OID_AUTO, ack_war_timewindow, CTLFLAG_RW, &tcp_ack_war_time_window, 1000, "If the tcp_stack does ack-war prevention how many milliseconds are in its time window?"); uint32_t tcp_ack_war_cnt = 5; SYSCTL_UINT(_net_inet_tcp, OID_AUTO, ack_war_cnt, CTLFLAG_RW, &tcp_ack_war_cnt, 5, "If the tcp_stack does ack-war prevention how many acks can be sent in its time window?"); struct rwlock tcp_function_lock; static int sysctl_net_inet_tcp_mss_check(SYSCTL_HANDLER_ARGS) { int error, new; new = V_tcp_mssdflt; error = sysctl_handle_int(oidp, &new, 0, req); if (error == 0 && req->newptr) { if (new < TCP_MINMSS) error = EINVAL; else V_tcp_mssdflt = new; } return (error); } SYSCTL_PROC(_net_inet_tcp, TCPCTL_MSSDFLT, mssdflt, CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &VNET_NAME(tcp_mssdflt), 0, &sysctl_net_inet_tcp_mss_check, "I", "Default TCP Maximum Segment Size"); #ifdef INET6 static int sysctl_net_inet_tcp_mss_v6_check(SYSCTL_HANDLER_ARGS) { int error, new; new = V_tcp_v6mssdflt; error = sysctl_handle_int(oidp, &new, 0, req); if (error == 0 && req->newptr) { if (new < TCP_MINMSS) error = EINVAL; else V_tcp_v6mssdflt = new; } return (error); } SYSCTL_PROC(_net_inet_tcp, TCPCTL_V6MSSDFLT, v6mssdflt, CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &VNET_NAME(tcp_v6mssdflt), 0, &sysctl_net_inet_tcp_mss_v6_check, "I", "Default TCP Maximum Segment Size for IPv6"); #endif /* INET6 */ /* * Minimum MSS we accept and use. This prevents DoS attacks where * we are forced to a ridiculous low MSS like 20 and send hundreds * of packets instead of one. The effect scales with the available * bandwidth and quickly saturates the CPU and network interface * with packet generation and sending. Set to zero to disable MINMSS * checking. This setting prevents us from sending too small packets. */ VNET_DEFINE(int, tcp_minmss) = TCP_MINMSS; SYSCTL_INT(_net_inet_tcp, OID_AUTO, minmss, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_minmss), 0, "Minimum TCP Maximum Segment Size"); VNET_DEFINE(int, tcp_do_rfc1323) = 1; SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1323, rfc1323, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_rfc1323), 0, "Enable rfc1323 (high performance TCP) extensions"); /* * As of June 2021, several TCP stacks violate RFC 7323 from September 2014. * Some stacks negotiate TS, but never send them after connection setup. Some * stacks negotiate TS, but don't send them when sending keep-alive segments. * These include modern widely deployed TCP stacks. * Therefore tolerating violations for now... */ VNET_DEFINE(int, tcp_tolerate_missing_ts) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, tolerate_missing_ts, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_tolerate_missing_ts), 0, "Tolerate missing TCP timestamps"); VNET_DEFINE(int, tcp_ts_offset_per_conn) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, ts_offset_per_conn, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_ts_offset_per_conn), 0, "Initialize TCP timestamps per connection instead of per host pair"); /* How many connections are pacing */ static volatile uint32_t number_of_tcp_connections_pacing = 0; static uint32_t shadow_num_connections = 0; static int tcp_pacing_limit = 10000; SYSCTL_INT(_net_inet_tcp, OID_AUTO, pacing_limit, CTLFLAG_RW, &tcp_pacing_limit, 1000, "If the TCP stack does pacing, is there a limit (-1 = no, 0 = no pacing N = number of connections)"); SYSCTL_UINT(_net_inet_tcp, OID_AUTO, pacing_count, CTLFLAG_RD, &shadow_num_connections, 0, "Number of TCP connections being paced"); static int tcp_log_debug = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_debug, CTLFLAG_RW, &tcp_log_debug, 0, "Log errors caused by incoming TCP segments"); static int tcp_tcbhashsize; SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &tcp_tcbhashsize, 0, "Size of TCP control-block hashtable"); static int do_tcpdrain = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_tcpdrain, CTLFLAG_RW, &do_tcpdrain, 0, "Enable tcp_drain routine for extra help when low on mbufs"); SYSCTL_UINT(_net_inet_tcp, OID_AUTO, pcbcount, CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(tcbinfo.ipi_count), 0, "Number of active PCBs"); VNET_DEFINE_STATIC(int, icmp_may_rst) = 1; #define V_icmp_may_rst VNET(icmp_may_rst) SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_may_rst, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(icmp_may_rst), 0, "Certain ICMP unreachable messages may abort connections in SYN_SENT"); VNET_DEFINE_STATIC(int, tcp_isn_reseed_interval) = 0; #define V_tcp_isn_reseed_interval VNET(tcp_isn_reseed_interval) SYSCTL_INT(_net_inet_tcp, OID_AUTO, isn_reseed_interval, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_isn_reseed_interval), 0, "Seconds between reseeding of ISN secret"); static int tcp_soreceive_stream; SYSCTL_INT(_net_inet_tcp, OID_AUTO, soreceive_stream, CTLFLAG_RDTUN, &tcp_soreceive_stream, 0, "Using soreceive_stream for TCP sockets"); VNET_DEFINE(uma_zone_t, sack_hole_zone); #define V_sack_hole_zone VNET(sack_hole_zone) VNET_DEFINE(uint32_t, tcp_map_entries_limit) = 0; /* unlimited */ static int sysctl_net_inet_tcp_map_limit_check(SYSCTL_HANDLER_ARGS) { int error; uint32_t new; new = V_tcp_map_entries_limit; error = sysctl_handle_int(oidp, &new, 0, req); if (error == 0 && req->newptr) { /* only allow "0" and value > minimum */ if (new > 0 && new < TCP_MIN_MAP_ENTRIES_LIMIT) error = EINVAL; else V_tcp_map_entries_limit = new; } return (error); } SYSCTL_PROC(_net_inet_tcp, OID_AUTO, map_limit, CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &VNET_NAME(tcp_map_entries_limit), 0, &sysctl_net_inet_tcp_map_limit_check, "IU", "Total sendmap entries limit"); VNET_DEFINE(uint32_t, tcp_map_split_limit) = 0; /* unlimited */ SYSCTL_UINT(_net_inet_tcp, OID_AUTO, split_limit, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_map_split_limit), 0, "Total sendmap split entries limit"); #ifdef TCP_HHOOK VNET_DEFINE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST+1]); #endif #define TS_OFFSET_SECRET_LENGTH SIPHASH_KEY_LENGTH VNET_DEFINE_STATIC(u_char, ts_offset_secret[TS_OFFSET_SECRET_LENGTH]); #define V_ts_offset_secret VNET(ts_offset_secret) static int tcp_default_fb_init(struct tcpcb *tp); static void tcp_default_fb_fini(struct tcpcb *tp, int tcb_is_purged); static int tcp_default_handoff_ok(struct tcpcb *tp); static struct inpcb *tcp_notify(struct inpcb *, int); static struct inpcb *tcp_mtudisc_notify(struct inpcb *, int); static struct inpcb *tcp_mtudisc(struct inpcb *, int); static struct inpcb *tcp_drop_syn_sent(struct inpcb *, int); static char * tcp_log_addr(struct in_conninfo *inc, struct tcphdr *th, const void *ip4hdr, const void *ip6hdr); static ipproto_ctlinput_t tcp_ctlinput; static udp_tun_icmp_t tcp_ctlinput_viaudp; static struct tcp_function_block tcp_def_funcblk = { .tfb_tcp_block_name = "freebsd", .tfb_tcp_output = tcp_default_output, .tfb_tcp_do_segment = tcp_do_segment, .tfb_tcp_ctloutput = tcp_default_ctloutput, .tfb_tcp_handoff_ok = tcp_default_handoff_ok, .tfb_tcp_fb_init = tcp_default_fb_init, .tfb_tcp_fb_fini = tcp_default_fb_fini, }; static int tcp_fb_cnt = 0; struct tcp_funchead t_functions; static struct tcp_function_block *tcp_func_set_ptr = &tcp_def_funcblk; void tcp_record_dsack(struct tcpcb *tp, tcp_seq start, tcp_seq end, int tlp) { TCPSTAT_INC(tcps_dsack_count); tp->t_dsack_pack++; if (tlp == 0) { if (SEQ_GT(end, start)) { tp->t_dsack_bytes += (end - start); TCPSTAT_ADD(tcps_dsack_bytes, (end - start)); } else { tp->t_dsack_tlp_bytes += (start - end); TCPSTAT_ADD(tcps_dsack_bytes, (start - end)); } } else { if (SEQ_GT(end, start)) { tp->t_dsack_bytes += (end - start); TCPSTAT_ADD(tcps_dsack_tlp_bytes, (end - start)); } else { tp->t_dsack_tlp_bytes += (start - end); TCPSTAT_ADD(tcps_dsack_tlp_bytes, (start - end)); } } } static struct tcp_function_block * find_tcp_functions_locked(struct tcp_function_set *fs) { struct tcp_function *f; struct tcp_function_block *blk=NULL; TAILQ_FOREACH(f, &t_functions, tf_next) { if (strcmp(f->tf_name, fs->function_set_name) == 0) { blk = f->tf_fb; break; } } return(blk); } static struct tcp_function_block * find_tcp_fb_locked(struct tcp_function_block *blk, struct tcp_function **s) { struct tcp_function_block *rblk=NULL; struct tcp_function *f; TAILQ_FOREACH(f, &t_functions, tf_next) { if (f->tf_fb == blk) { rblk = blk; if (s) { *s = f; } break; } } return (rblk); } struct tcp_function_block * find_and_ref_tcp_functions(struct tcp_function_set *fs) { struct tcp_function_block *blk; rw_rlock(&tcp_function_lock); blk = find_tcp_functions_locked(fs); if (blk) refcount_acquire(&blk->tfb_refcnt); rw_runlock(&tcp_function_lock); return(blk); } struct tcp_function_block * find_and_ref_tcp_fb(struct tcp_function_block *blk) { struct tcp_function_block *rblk; rw_rlock(&tcp_function_lock); rblk = find_tcp_fb_locked(blk, NULL); if (rblk) refcount_acquire(&rblk->tfb_refcnt); rw_runlock(&tcp_function_lock); return(rblk); } /* Find a matching alias for the given tcp_function_block. */ int find_tcp_function_alias(struct tcp_function_block *blk, struct tcp_function_set *fs) { struct tcp_function *f; int found; found = 0; rw_rlock(&tcp_function_lock); TAILQ_FOREACH(f, &t_functions, tf_next) { if ((f->tf_fb == blk) && (strncmp(f->tf_name, blk->tfb_tcp_block_name, TCP_FUNCTION_NAME_LEN_MAX) != 0)) { /* Matching function block with different name. */ strncpy(fs->function_set_name, f->tf_name, TCP_FUNCTION_NAME_LEN_MAX); found = 1; break; } } /* Null terminate the string appropriately. */ if (found) { fs->function_set_name[TCP_FUNCTION_NAME_LEN_MAX - 1] = '\0'; } else { fs->function_set_name[0] = '\0'; } rw_runlock(&tcp_function_lock); return (found); } static struct tcp_function_block * find_and_ref_tcp_default_fb(void) { struct tcp_function_block *rblk; rw_rlock(&tcp_function_lock); rblk = tcp_func_set_ptr; refcount_acquire(&rblk->tfb_refcnt); rw_runlock(&tcp_function_lock); return (rblk); } void tcp_switch_back_to_default(struct tcpcb *tp) { struct tcp_function_block *tfb; KASSERT(tp->t_fb != &tcp_def_funcblk, ("%s: called by the built-in default stack", __func__)); /* * Release the old stack. This function will either find a new one * or panic. */ if (tp->t_fb->tfb_tcp_fb_fini != NULL) (*tp->t_fb->tfb_tcp_fb_fini)(tp, 0); refcount_release(&tp->t_fb->tfb_refcnt); /* * Now, we'll find a new function block to use. * Start by trying the current user-selected * default, unless this stack is the user-selected * default. */ tfb = find_and_ref_tcp_default_fb(); if (tfb == tp->t_fb) { refcount_release(&tfb->tfb_refcnt); tfb = NULL; } /* Does the stack accept this connection? */ if (tfb != NULL && tfb->tfb_tcp_handoff_ok != NULL && (*tfb->tfb_tcp_handoff_ok)(tp)) { refcount_release(&tfb->tfb_refcnt); tfb = NULL; } /* Try to use that stack. */ if (tfb != NULL) { /* Initialize the new stack. If it succeeds, we are done. */ tp->t_fb = tfb; if (tp->t_fb->tfb_tcp_fb_init == NULL || (*tp->t_fb->tfb_tcp_fb_init)(tp) == 0) return; /* * Initialization failed. Release the reference count on * the stack. */ refcount_release(&tfb->tfb_refcnt); } /* * If that wasn't feasible, use the built-in default * stack which is not allowed to reject anyone. */ tfb = find_and_ref_tcp_fb(&tcp_def_funcblk); if (tfb == NULL) { /* there always should be a default */ panic("Can't refer to tcp_def_funcblk"); } if (tfb->tfb_tcp_handoff_ok != NULL) { if ((*tfb->tfb_tcp_handoff_ok) (tp)) { /* The default stack cannot say no */ panic("Default stack rejects a new session?"); } } tp->t_fb = tfb; if (tp->t_fb->tfb_tcp_fb_init != NULL && (*tp->t_fb->tfb_tcp_fb_init)(tp)) { /* The default stack cannot fail */ panic("Default stack initialization failed"); } } static bool tcp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp, const struct sockaddr *sa, void *ctx) { struct ip *iph; #ifdef INET6 struct ip6_hdr *ip6; #endif struct udphdr *uh; struct tcphdr *th; int thlen; uint16_t port; TCPSTAT_INC(tcps_tunneled_pkts); if ((m->m_flags & M_PKTHDR) == 0) { /* Can't handle one that is not a pkt hdr */ TCPSTAT_INC(tcps_tunneled_errs); goto out; } thlen = sizeof(struct tcphdr); if (m->m_len < off + sizeof(struct udphdr) + thlen && (m = m_pullup(m, off + sizeof(struct udphdr) + thlen)) == NULL) { TCPSTAT_INC(tcps_tunneled_errs); goto out; } iph = mtod(m, struct ip *); uh = (struct udphdr *)((caddr_t)iph + off); th = (struct tcphdr *)(uh + 1); thlen = th->th_off << 2; if (m->m_len < off + sizeof(struct udphdr) + thlen) { m = m_pullup(m, off + sizeof(struct udphdr) + thlen); if (m == NULL) { TCPSTAT_INC(tcps_tunneled_errs); goto out; } else { iph = mtod(m, struct ip *); uh = (struct udphdr *)((caddr_t)iph + off); th = (struct tcphdr *)(uh + 1); } } m->m_pkthdr.tcp_tun_port = port = uh->uh_sport; bcopy(th, uh, m->m_len - off); m->m_len -= sizeof(struct udphdr); m->m_pkthdr.len -= sizeof(struct udphdr); /* * We use the same algorithm for * both UDP and TCP for c-sum. So * the code in tcp_input will skip * the checksum. So we do nothing * with the flag (m->m_pkthdr.csum_flags). */ switch (iph->ip_v) { #ifdef INET case IPVERSION: iph->ip_len = htons(ntohs(iph->ip_len) - sizeof(struct udphdr)); tcp_input_with_port(&m, &off, IPPROTO_TCP, port); break; #endif #ifdef INET6 case IPV6_VERSION >> 4: ip6 = mtod(m, struct ip6_hdr *); ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - sizeof(struct udphdr)); tcp6_input_with_port(&m, &off, IPPROTO_TCP, port); break; #endif default: goto out; break; } return (true); out: m_freem(m); return (true); } static int sysctl_net_inet_default_tcp_functions(SYSCTL_HANDLER_ARGS) { int error=ENOENT; struct tcp_function_set fs; struct tcp_function_block *blk; memset(&fs, 0, sizeof(fs)); rw_rlock(&tcp_function_lock); blk = find_tcp_fb_locked(tcp_func_set_ptr, NULL); if (blk) { /* Found him */ strcpy(fs.function_set_name, blk->tfb_tcp_block_name); fs.pcbcnt = blk->tfb_refcnt; } rw_runlock(&tcp_function_lock); error = sysctl_handle_string(oidp, fs.function_set_name, sizeof(fs.function_set_name), req); /* Check for error or no change */ if (error != 0 || req->newptr == NULL) return(error); rw_wlock(&tcp_function_lock); blk = find_tcp_functions_locked(&fs); if ((blk == NULL) || (blk->tfb_flags & TCP_FUNC_BEING_REMOVED)) { error = ENOENT; goto done; } tcp_func_set_ptr = blk; done: rw_wunlock(&tcp_function_lock); return (error); } SYSCTL_PROC(_net_inet_tcp, OID_AUTO, functions_default, CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_NEEDGIANT, NULL, 0, sysctl_net_inet_default_tcp_functions, "A", "Set/get the default TCP functions"); static int sysctl_net_inet_list_available(SYSCTL_HANDLER_ARGS) { int error, cnt, linesz; struct tcp_function *f; char *buffer, *cp; size_t bufsz, outsz; bool alias; cnt = 0; rw_rlock(&tcp_function_lock); TAILQ_FOREACH(f, &t_functions, tf_next) { cnt++; } rw_runlock(&tcp_function_lock); bufsz = (cnt+2) * ((TCP_FUNCTION_NAME_LEN_MAX * 2) + 13) + 1; buffer = malloc(bufsz, M_TEMP, M_WAITOK); error = 0; cp = buffer; linesz = snprintf(cp, bufsz, "\n%-32s%c %-32s %s\n", "Stack", 'D', "Alias", "PCB count"); cp += linesz; bufsz -= linesz; outsz = linesz; rw_rlock(&tcp_function_lock); TAILQ_FOREACH(f, &t_functions, tf_next) { alias = (f->tf_name != f->tf_fb->tfb_tcp_block_name); linesz = snprintf(cp, bufsz, "%-32s%c %-32s %u\n", f->tf_fb->tfb_tcp_block_name, (f->tf_fb == tcp_func_set_ptr) ? '*' : ' ', alias ? f->tf_name : "-", f->tf_fb->tfb_refcnt); if (linesz >= bufsz) { error = EOVERFLOW; break; } cp += linesz; bufsz -= linesz; outsz += linesz; } rw_runlock(&tcp_function_lock); if (error == 0) error = sysctl_handle_string(oidp, buffer, outsz + 1, req); free(buffer, M_TEMP); return (error); } SYSCTL_PROC(_net_inet_tcp, OID_AUTO, functions_available, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT, NULL, 0, sysctl_net_inet_list_available, "A", "list available TCP Function sets"); VNET_DEFINE(int, tcp_udp_tunneling_port) = TCP_TUNNELING_PORT_DEFAULT; #ifdef INET VNET_DEFINE(struct socket *, udp4_tun_socket) = NULL; #define V_udp4_tun_socket VNET(udp4_tun_socket) #endif #ifdef INET6 VNET_DEFINE(struct socket *, udp6_tun_socket) = NULL; #define V_udp6_tun_socket VNET(udp6_tun_socket) #endif static void tcp_over_udp_stop(void) { /* * This function assumes sysctl caller holds inp_rinfo_lock() * for writing! */ #ifdef INET if (V_udp4_tun_socket != NULL) { soclose(V_udp4_tun_socket); V_udp4_tun_socket = NULL; } #endif #ifdef INET6 if (V_udp6_tun_socket != NULL) { soclose(V_udp6_tun_socket); V_udp6_tun_socket = NULL; } #endif } static int tcp_over_udp_start(void) { uint16_t port; int ret; #ifdef INET struct sockaddr_in sin; #endif #ifdef INET6 struct sockaddr_in6 sin6; #endif /* * This function assumes sysctl caller holds inp_info_rlock() * for writing! */ port = V_tcp_udp_tunneling_port; if (ntohs(port) == 0) { /* Must have a port set */ return (EINVAL); } #ifdef INET if (V_udp4_tun_socket != NULL) { /* Already running -- must stop first */ return (EALREADY); } #endif #ifdef INET6 if (V_udp6_tun_socket != NULL) { /* Already running -- must stop first */ return (EALREADY); } #endif #ifdef INET if ((ret = socreate(PF_INET, &V_udp4_tun_socket, SOCK_DGRAM, IPPROTO_UDP, curthread->td_ucred, curthread))) { tcp_over_udp_stop(); return (ret); } /* Call the special UDP hook. */ if ((ret = udp_set_kernel_tunneling(V_udp4_tun_socket, tcp_recv_udp_tunneled_packet, tcp_ctlinput_viaudp, NULL))) { tcp_over_udp_stop(); return (ret); } /* Ok, we have a socket, bind it to the port. */ memset(&sin, 0, sizeof(struct sockaddr_in)); sin.sin_len = sizeof(struct sockaddr_in); sin.sin_family = AF_INET; sin.sin_port = htons(port); if ((ret = sobind(V_udp4_tun_socket, (struct sockaddr *)&sin, curthread))) { tcp_over_udp_stop(); return (ret); } #endif #ifdef INET6 if ((ret = socreate(PF_INET6, &V_udp6_tun_socket, SOCK_DGRAM, IPPROTO_UDP, curthread->td_ucred, curthread))) { tcp_over_udp_stop(); return (ret); } /* Call the special UDP hook. */ if ((ret = udp_set_kernel_tunneling(V_udp6_tun_socket, tcp_recv_udp_tunneled_packet, tcp6_ctlinput_viaudp, NULL))) { tcp_over_udp_stop(); return (ret); } /* Ok, we have a socket, bind it to the port. */ memset(&sin6, 0, sizeof(struct sockaddr_in6)); sin6.sin6_len = sizeof(struct sockaddr_in6); sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(port); if ((ret = sobind(V_udp6_tun_socket, (struct sockaddr *)&sin6, curthread))) { tcp_over_udp_stop(); return (ret); } #endif return (0); } static int sysctl_net_inet_tcp_udp_tunneling_port_check(SYSCTL_HANDLER_ARGS) { int error; uint32_t old, new; old = V_tcp_udp_tunneling_port; new = old; error = sysctl_handle_int(oidp, &new, 0, req); if ((error == 0) && (req->newptr != NULL)) { if ((new < TCP_TUNNELING_PORT_MIN) || (new > TCP_TUNNELING_PORT_MAX)) { error = EINVAL; } else { V_tcp_udp_tunneling_port = new; if (old != 0) { tcp_over_udp_stop(); } if (new != 0) { error = tcp_over_udp_start(); } } } return (error); } SYSCTL_PROC(_net_inet_tcp, OID_AUTO, udp_tunneling_port, CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, &VNET_NAME(tcp_udp_tunneling_port), 0, &sysctl_net_inet_tcp_udp_tunneling_port_check, "IU", "Tunneling port for tcp over udp"); VNET_DEFINE(int, tcp_udp_tunneling_overhead) = TCP_TUNNELING_OVERHEAD_DEFAULT; static int sysctl_net_inet_tcp_udp_tunneling_overhead_check(SYSCTL_HANDLER_ARGS) { int error, new; new = V_tcp_udp_tunneling_overhead; error = sysctl_handle_int(oidp, &new, 0, req); if (error == 0 && req->newptr) { if ((new < TCP_TUNNELING_OVERHEAD_MIN) || (new > TCP_TUNNELING_OVERHEAD_MAX)) error = EINVAL; else V_tcp_udp_tunneling_overhead = new; } return (error); } SYSCTL_PROC(_net_inet_tcp, OID_AUTO, udp_tunneling_overhead, CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, &VNET_NAME(tcp_udp_tunneling_overhead), 0, &sysctl_net_inet_tcp_udp_tunneling_overhead_check, "IU", "MSS reduction when using tcp over udp"); /* * Exports one (struct tcp_function_info) for each alias/name. */ static int sysctl_net_inet_list_func_info(SYSCTL_HANDLER_ARGS) { int cnt, error; struct tcp_function *f; struct tcp_function_info tfi; /* * We don't allow writes. */ if (req->newptr != NULL) return (EINVAL); /* * Wire the old buffer so we can directly copy the functions to * user space without dropping the lock. */ if (req->oldptr != NULL) { error = sysctl_wire_old_buffer(req, 0); if (error) return (error); } /* * Walk the list and copy out matching entries. If INVARIANTS * is compiled in, also walk the list to verify the length of * the list matches what we have recorded. */ rw_rlock(&tcp_function_lock); cnt = 0; #ifndef INVARIANTS if (req->oldptr == NULL) { cnt = tcp_fb_cnt; goto skip_loop; } #endif TAILQ_FOREACH(f, &t_functions, tf_next) { #ifdef INVARIANTS cnt++; #endif if (req->oldptr != NULL) { bzero(&tfi, sizeof(tfi)); tfi.tfi_refcnt = f->tf_fb->tfb_refcnt; tfi.tfi_id = f->tf_fb->tfb_id; (void)strlcpy(tfi.tfi_alias, f->tf_name, sizeof(tfi.tfi_alias)); (void)strlcpy(tfi.tfi_name, f->tf_fb->tfb_tcp_block_name, sizeof(tfi.tfi_name)); error = SYSCTL_OUT(req, &tfi, sizeof(tfi)); /* * Don't stop on error, as that is the * mechanism we use to accumulate length * information if the buffer was too short. */ } } KASSERT(cnt == tcp_fb_cnt, ("%s: cnt (%d) != tcp_fb_cnt (%d)", __func__, cnt, tcp_fb_cnt)); #ifndef INVARIANTS skip_loop: #endif rw_runlock(&tcp_function_lock); if (req->oldptr == NULL) error = SYSCTL_OUT(req, NULL, (cnt + 1) * sizeof(struct tcp_function_info)); return (error); } SYSCTL_PROC(_net_inet_tcp, OID_AUTO, function_info, CTLTYPE_OPAQUE | CTLFLAG_SKIP | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, sysctl_net_inet_list_func_info, "S,tcp_function_info", "List TCP function block name-to-ID mappings"); /* * tfb_tcp_handoff_ok() function for the default stack. * Note that we'll basically try to take all comers. */ static int tcp_default_handoff_ok(struct tcpcb *tp) { return (0); } /* * tfb_tcp_fb_init() function for the default stack. * * This handles making sure we have appropriate timers set if you are * transitioning a socket that has some amount of setup done. * * The init() fuction from the default can *never* return non-zero i.e. * it is required to always succeed since it is the stack of last resort! */ static int tcp_default_fb_init(struct tcpcb *tp) { struct socket *so = tptosocket(tp); INP_WLOCK_ASSERT(tptoinpcb(tp)); KASSERT(tp->t_state >= 0 && tp->t_state < TCPS_TIME_WAIT, ("%s: connection %p in unexpected state %d", __func__, tp, tp->t_state)); /* * Nothing to do for ESTABLISHED or LISTEN states. And, we don't * know what to do for unexpected states (which includes TIME_WAIT). */ if (tp->t_state <= TCPS_LISTEN || tp->t_state >= TCPS_TIME_WAIT) return (0); /* * Make sure some kind of transmission timer is set if there is * outstanding data. */ if ((!TCPS_HAVEESTABLISHED(tp->t_state) || sbavail(&so->so_snd) || tp->snd_una != tp->snd_max) && !(tcp_timer_active(tp, TT_REXMT) || tcp_timer_active(tp, TT_PERSIST))) { /* * If the session has established and it looks like it should * be in the persist state, set the persist timer. Otherwise, * set the retransmit timer. */ if (TCPS_HAVEESTABLISHED(tp->t_state) && tp->snd_wnd == 0 && (int32_t)(tp->snd_nxt - tp->snd_una) < (int32_t)sbavail(&so->so_snd)) tcp_setpersist(tp); else tcp_timer_activate(tp, TT_REXMT, tp->t_rxtcur); } /* All non-embryonic sessions get a keepalive timer. */ if (!tcp_timer_active(tp, TT_KEEP)) tcp_timer_activate(tp, TT_KEEP, TCPS_HAVEESTABLISHED(tp->t_state) ? TP_KEEPIDLE(tp) : TP_KEEPINIT(tp)); /* * Make sure critical variables are initialized * if transitioning while in Recovery. */ if IN_FASTRECOVERY(tp->t_flags) { if (tp->sackhint.recover_fs == 0) tp->sackhint.recover_fs = max(1, tp->snd_nxt - tp->snd_una); } return (0); } /* * tfb_tcp_fb_fini() function for the default stack. * * This changes state as necessary (or prudent) to prepare for another stack * to assume responsibility for the connection. */ static void tcp_default_fb_fini(struct tcpcb *tp, int tcb_is_purged) { INP_WLOCK_ASSERT(tptoinpcb(tp)); } /* * Target size of TCP PCB hash tables. Must be a power of two. * * Note that this can be overridden by the kernel environment * variable net.inet.tcp.tcbhashsize */ #ifndef TCBHASHSIZE #define TCBHASHSIZE 0 #endif MALLOC_DEFINE(M_TCPLOG, "tcplog", "TCP address and flags print buffers"); MALLOC_DEFINE(M_TCPFUNCTIONS, "tcpfunc", "TCP function set memory"); static struct mtx isn_mtx; #define ISN_LOCK_INIT() mtx_init(&isn_mtx, "isn_mtx", NULL, MTX_DEF) #define ISN_LOCK() mtx_lock(&isn_mtx) #define ISN_UNLOCK() mtx_unlock(&isn_mtx) INPCBSTORAGE_DEFINE(tcpcbstor, tcpcb, "tcpinp", "tcp_inpcb", "tcp", "tcphash"); /* * Take a value and get the next power of 2 that doesn't overflow. * Used to size the tcp_inpcb hash buckets. */ static int maketcp_hashsize(int size) { int hashsize; /* * auto tune. * get the next power of 2 higher than maxsockets. */ hashsize = 1 << fls(size); /* catch overflow, and just go one power of 2 smaller */ if (hashsize < size) { hashsize = 1 << (fls(size) - 1); } return (hashsize); } static volatile int next_tcp_stack_id = 1; /* * Register a TCP function block with the name provided in the names * array. (Note that this function does NOT automatically register * blk->tfb_tcp_block_name as a stack name. Therefore, you should * explicitly include blk->tfb_tcp_block_name in the list of names if * you wish to register the stack with that name.) * * Either all name registrations will succeed or all will fail. If * a name registration fails, the function will update the num_names * argument to point to the array index of the name that encountered * the failure. * * Returns 0 on success, or an error code on failure. */ int register_tcp_functions_as_names(struct tcp_function_block *blk, int wait, const char *names[], int *num_names) { struct tcp_function *n; struct tcp_function_set fs; int error, i; KASSERT(names != NULL && *num_names > 0, ("%s: Called with 0-length name list", __func__)); KASSERT(names != NULL, ("%s: Called with NULL name list", __func__)); KASSERT(rw_initialized(&tcp_function_lock), ("%s: called too early", __func__)); if ((blk->tfb_tcp_output == NULL) || (blk->tfb_tcp_do_segment == NULL) || (blk->tfb_tcp_ctloutput == NULL) || (strlen(blk->tfb_tcp_block_name) == 0)) { /* * These functions are required and you * need a name. */ *num_names = 0; return (EINVAL); } if (blk->tfb_flags & TCP_FUNC_BEING_REMOVED) { *num_names = 0; return (EINVAL); } refcount_init(&blk->tfb_refcnt, 0); blk->tfb_id = atomic_fetchadd_int(&next_tcp_stack_id, 1); for (i = 0; i < *num_names; i++) { n = malloc(sizeof(struct tcp_function), M_TCPFUNCTIONS, wait); if (n == NULL) { error = ENOMEM; goto cleanup; } n->tf_fb = blk; (void)strlcpy(fs.function_set_name, names[i], sizeof(fs.function_set_name)); rw_wlock(&tcp_function_lock); if (find_tcp_functions_locked(&fs) != NULL) { /* Duplicate name space not allowed */ rw_wunlock(&tcp_function_lock); free(n, M_TCPFUNCTIONS); error = EALREADY; goto cleanup; } (void)strlcpy(n->tf_name, names[i], sizeof(n->tf_name)); TAILQ_INSERT_TAIL(&t_functions, n, tf_next); tcp_fb_cnt++; rw_wunlock(&tcp_function_lock); } return(0); cleanup: /* * Deregister the names we just added. Because registration failed * for names[i], we don't need to deregister that name. */ *num_names = i; rw_wlock(&tcp_function_lock); while (--i >= 0) { TAILQ_FOREACH(n, &t_functions, tf_next) { if (!strncmp(n->tf_name, names[i], TCP_FUNCTION_NAME_LEN_MAX)) { TAILQ_REMOVE(&t_functions, n, tf_next); tcp_fb_cnt--; n->tf_fb = NULL; free(n, M_TCPFUNCTIONS); break; } } } rw_wunlock(&tcp_function_lock); return (error); } /* * Register a TCP function block using the name provided in the name * argument. * * Returns 0 on success, or an error code on failure. */ int register_tcp_functions_as_name(struct tcp_function_block *blk, const char *name, int wait) { const char *name_list[1]; int num_names, rv; num_names = 1; if (name != NULL) name_list[0] = name; else name_list[0] = blk->tfb_tcp_block_name; rv = register_tcp_functions_as_names(blk, wait, name_list, &num_names); return (rv); } /* * Register a TCP function block using the name defined in * blk->tfb_tcp_block_name. * * Returns 0 on success, or an error code on failure. */ int register_tcp_functions(struct tcp_function_block *blk, int wait) { return (register_tcp_functions_as_name(blk, NULL, wait)); } /* * Deregister all names associated with a function block. This * functionally removes the function block from use within the system. * * When called with a true quiesce argument, mark the function block * as being removed so no more stacks will use it and determine * whether the removal would succeed. * * When called with a false quiesce argument, actually attempt the * removal. * * When called with a force argument, attempt to switch all TCBs to * use the default stack instead of returning EBUSY. * * Returns 0 on success (or if the removal would succeed, or an error * code on failure. */ int deregister_tcp_functions(struct tcp_function_block *blk, bool quiesce, bool force) { struct tcp_function *f; if (blk == &tcp_def_funcblk) { /* You can't un-register the default */ return (EPERM); } rw_wlock(&tcp_function_lock); if (blk == tcp_func_set_ptr) { /* You can't free the current default */ rw_wunlock(&tcp_function_lock); return (EBUSY); } /* Mark the block so no more stacks can use it. */ blk->tfb_flags |= TCP_FUNC_BEING_REMOVED; /* * If TCBs are still attached to the stack, attempt to switch them * to the default stack. */ if (force && blk->tfb_refcnt) { struct inpcb_iterator inpi = INP_ALL_ITERATOR(&V_tcbinfo, INPLOOKUP_WLOCKPCB); struct inpcb *inp; struct tcpcb *tp; VNET_ITERATOR_DECL(vnet_iter); rw_wunlock(&tcp_function_lock); VNET_LIST_RLOCK(); VNET_FOREACH(vnet_iter) { CURVNET_SET(vnet_iter); while ((inp = inp_next(&inpi)) != NULL) { tp = intotcpcb(inp); if (tp == NULL || tp->t_fb != blk) continue; tcp_switch_back_to_default(tp); } CURVNET_RESTORE(); } VNET_LIST_RUNLOCK(); rw_wlock(&tcp_function_lock); } if (blk->tfb_refcnt) { /* TCBs still attached. */ rw_wunlock(&tcp_function_lock); return (EBUSY); } if (quiesce) { /* Skip removal. */ rw_wunlock(&tcp_function_lock); return (0); } /* Remove any function names that map to this function block. */ while (find_tcp_fb_locked(blk, &f) != NULL) { TAILQ_REMOVE(&t_functions, f, tf_next); tcp_fb_cnt--; f->tf_fb = NULL; free(f, M_TCPFUNCTIONS); } rw_wunlock(&tcp_function_lock); return (0); } static void tcp_drain(void) { struct epoch_tracker et; VNET_ITERATOR_DECL(vnet_iter); if (!do_tcpdrain) return; NET_EPOCH_ENTER(et); VNET_LIST_RLOCK_NOSLEEP(); VNET_FOREACH(vnet_iter) { CURVNET_SET(vnet_iter); struct inpcb_iterator inpi = INP_ALL_ITERATOR(&V_tcbinfo, INPLOOKUP_WLOCKPCB); struct inpcb *inpb; struct tcpcb *tcpb; /* * Walk the tcpbs, if existing, and flush the reassembly queue, * if there is one... * XXX: The "Net/3" implementation doesn't imply that the TCP * reassembly queue should be flushed, but in a situation * where we're really low on mbufs, this is potentially * useful. */ while ((inpb = inp_next(&inpi)) != NULL) { if ((tcpb = intotcpcb(inpb)) != NULL) { tcp_reass_flush(tcpb); tcp_clean_sackreport(tcpb); #ifdef TCP_BLACKBOX tcp_log_drain(tcpb); #endif #ifdef TCPPCAP if (tcp_pcap_aggressive_free) { /* Free the TCP PCAP queues. */ tcp_pcap_drain(&(tcpb->t_inpkts)); tcp_pcap_drain(&(tcpb->t_outpkts)); } #endif } } CURVNET_RESTORE(); } VNET_LIST_RUNLOCK_NOSLEEP(); NET_EPOCH_EXIT(et); } static void tcp_vnet_init(void *arg __unused) { #ifdef TCP_HHOOK if (hhook_head_register(HHOOK_TYPE_TCP, HHOOK_TCP_EST_IN, &V_tcp_hhh[HHOOK_TCP_EST_IN], HHOOK_NOWAIT|HHOOK_HEADISINVNET) != 0) printf("%s: WARNING: unable to register helper hook\n", __func__); if (hhook_head_register(HHOOK_TYPE_TCP, HHOOK_TCP_EST_OUT, &V_tcp_hhh[HHOOK_TCP_EST_OUT], HHOOK_NOWAIT|HHOOK_HEADISINVNET) != 0) printf("%s: WARNING: unable to register helper hook\n", __func__); #endif #ifdef STATS if (tcp_stats_init()) printf("%s: WARNING: unable to initialise TCP stats\n", __func__); #endif in_pcbinfo_init(&V_tcbinfo, &tcpcbstor, tcp_tcbhashsize, tcp_tcbhashsize); syncache_init(); tcp_hc_init(); TUNABLE_INT_FETCH("net.inet.tcp.sack.enable", &V_tcp_do_sack); V_sack_hole_zone = uma_zcreate("sackhole", sizeof(struct sackhole), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); tcp_fastopen_init(); COUNTER_ARRAY_ALLOC(V_tcps_states, TCP_NSTATES, M_WAITOK); VNET_PCPUSTAT_ALLOC(tcpstat, M_WAITOK); V_tcp_msl = TCPTV_MSL; } VNET_SYSINIT(tcp_vnet_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, tcp_vnet_init, NULL); static void tcp_init(void *arg __unused) { const char *tcbhash_tuneable; int hashsize; tcp_reass_global_init(); /* XXX virtualize those below? */ tcp_delacktime = TCPTV_DELACK; tcp_keepinit = TCPTV_KEEP_INIT; tcp_keepidle = TCPTV_KEEP_IDLE; tcp_keepintvl = TCPTV_KEEPINTVL; tcp_maxpersistidle = TCPTV_KEEP_IDLE; tcp_rexmit_initial = TCPTV_RTOBASE; if (tcp_rexmit_initial < 1) tcp_rexmit_initial = 1; tcp_rexmit_min = TCPTV_MIN; if (tcp_rexmit_min < 1) tcp_rexmit_min = 1; tcp_persmin = TCPTV_PERSMIN; tcp_persmax = TCPTV_PERSMAX; tcp_rexmit_slop = TCPTV_CPU_VAR; tcp_finwait2_timeout = TCPTV_FINWAIT2_TIMEOUT; /* Setup the tcp function block list */ TAILQ_INIT(&t_functions); rw_init(&tcp_function_lock, "tcp_func_lock"); register_tcp_functions(&tcp_def_funcblk, M_WAITOK); #ifdef TCP_BLACKBOX /* Initialize the TCP logging data. */ tcp_log_init(); #endif arc4rand(&V_ts_offset_secret, sizeof(V_ts_offset_secret), 0); if (tcp_soreceive_stream) { #ifdef INET tcp_protosw.pr_soreceive = soreceive_stream; #endif #ifdef INET6 tcp6_protosw.pr_soreceive = soreceive_stream; #endif /* INET6 */ } #ifdef INET6 max_protohdr_grow(sizeof(struct ip6_hdr) + sizeof(struct tcphdr)); #else /* INET6 */ max_protohdr_grow(sizeof(struct tcpiphdr)); #endif /* INET6 */ ISN_LOCK_INIT(); EVENTHANDLER_REGISTER(shutdown_pre_sync, tcp_fini, NULL, SHUTDOWN_PRI_DEFAULT); EVENTHANDLER_REGISTER(vm_lowmem, tcp_drain, NULL, LOWMEM_PRI_DEFAULT); EVENTHANDLER_REGISTER(mbuf_lowmem, tcp_drain, NULL, LOWMEM_PRI_DEFAULT); tcp_inp_lro_direct_queue = counter_u64_alloc(M_WAITOK); tcp_inp_lro_wokeup_queue = counter_u64_alloc(M_WAITOK); tcp_inp_lro_compressed = counter_u64_alloc(M_WAITOK); tcp_inp_lro_locks_taken = counter_u64_alloc(M_WAITOK); tcp_extra_mbuf = counter_u64_alloc(M_WAITOK); tcp_would_have_but = counter_u64_alloc(M_WAITOK); tcp_comp_total = counter_u64_alloc(M_WAITOK); tcp_uncomp_total = counter_u64_alloc(M_WAITOK); tcp_bad_csums = counter_u64_alloc(M_WAITOK); #ifdef TCPPCAP tcp_pcap_init(); #endif hashsize = TCBHASHSIZE; tcbhash_tuneable = "net.inet.tcp.tcbhashsize"; TUNABLE_INT_FETCH(tcbhash_tuneable, &hashsize); if (hashsize == 0) { /* * Auto tune the hash size based on maxsockets. * A perfect hash would have a 1:1 mapping * (hashsize = maxsockets) however it's been * suggested that O(2) average is better. */ hashsize = maketcp_hashsize(maxsockets / 4); /* * Our historical default is 512, * do not autotune lower than this. */ if (hashsize < 512) hashsize = 512; if (bootverbose) printf("%s: %s auto tuned to %d\n", __func__, tcbhash_tuneable, hashsize); } /* * We require a hashsize to be a power of two. * Previously if it was not a power of two we would just reset it * back to 512, which could be a nasty surprise if you did not notice * the error message. * Instead what we do is clip it to the closest power of two lower * than the specified hash value. */ if (!powerof2(hashsize)) { int oldhashsize = hashsize; hashsize = maketcp_hashsize(hashsize); /* prevent absurdly low value */ if (hashsize < 16) hashsize = 16; printf("%s: WARNING: TCB hash size not a power of 2, " "clipped from %d to %d.\n", __func__, oldhashsize, hashsize); } tcp_tcbhashsize = hashsize; #ifdef INET IPPROTO_REGISTER(IPPROTO_TCP, tcp_input, tcp_ctlinput); #endif #ifdef INET6 IP6PROTO_REGISTER(IPPROTO_TCP, tcp6_input, tcp6_ctlinput); #endif } SYSINIT(tcp_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, tcp_init, NULL); #ifdef VIMAGE static void tcp_destroy(void *unused __unused) { int n; #ifdef TCP_HHOOK int error; #endif /* * All our processes are gone, all our sockets should be cleaned * up, which means, we should be past the tcp_discardcb() calls. * Sleep to let all tcpcb timers really disappear and cleanup. */ for (;;) { INP_INFO_WLOCK(&V_tcbinfo); n = V_tcbinfo.ipi_count; INP_INFO_WUNLOCK(&V_tcbinfo); if (n == 0) break; pause("tcpdes", hz / 10); } tcp_hc_destroy(); syncache_destroy(); in_pcbinfo_destroy(&V_tcbinfo); /* tcp_discardcb() clears the sack_holes up. */ uma_zdestroy(V_sack_hole_zone); /* * Cannot free the zone until all tcpcbs are released as we attach * the allocations to them. */ tcp_fastopen_destroy(); COUNTER_ARRAY_FREE(V_tcps_states, TCP_NSTATES); VNET_PCPUSTAT_FREE(tcpstat); #ifdef TCP_HHOOK error = hhook_head_deregister(V_tcp_hhh[HHOOK_TCP_EST_IN]); if (error != 0) { printf("%s: WARNING: unable to deregister helper hook " "type=%d, id=%d: error %d returned\n", __func__, HHOOK_TYPE_TCP, HHOOK_TCP_EST_IN, error); } error = hhook_head_deregister(V_tcp_hhh[HHOOK_TCP_EST_OUT]); if (error != 0) { printf("%s: WARNING: unable to deregister helper hook " "type=%d, id=%d: error %d returned\n", __func__, HHOOK_TYPE_TCP, HHOOK_TCP_EST_OUT, error); } #endif } VNET_SYSUNINIT(tcp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, tcp_destroy, NULL); #endif void tcp_fini(void *xtp) { } /* * Fill in the IP and TCP headers for an outgoing packet, given the tcpcb. * tcp_template used to store this data in mbufs, but we now recopy it out * of the tcpcb each time to conserve mbufs. */ void tcpip_fillheaders(struct inpcb *inp, uint16_t port, void *ip_ptr, void *tcp_ptr) { struct tcphdr *th = (struct tcphdr *)tcp_ptr; INP_WLOCK_ASSERT(inp); #ifdef INET6 if ((inp->inp_vflag & INP_IPV6) != 0) { struct ip6_hdr *ip6; ip6 = (struct ip6_hdr *)ip_ptr; ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) | (inp->inp_flow & IPV6_FLOWINFO_MASK); ip6->ip6_vfc = (ip6->ip6_vfc & ~IPV6_VERSION_MASK) | (IPV6_VERSION & IPV6_VERSION_MASK); if (port == 0) ip6->ip6_nxt = IPPROTO_TCP; else ip6->ip6_nxt = IPPROTO_UDP; ip6->ip6_plen = htons(sizeof(struct tcphdr)); ip6->ip6_src = inp->in6p_laddr; ip6->ip6_dst = inp->in6p_faddr; } #endif /* INET6 */ #if defined(INET6) && defined(INET) else #endif #ifdef INET { struct ip *ip; ip = (struct ip *)ip_ptr; ip->ip_v = IPVERSION; ip->ip_hl = 5; ip->ip_tos = inp->inp_ip_tos; ip->ip_len = 0; ip->ip_id = 0; ip->ip_off = 0; ip->ip_ttl = inp->inp_ip_ttl; ip->ip_sum = 0; if (port == 0) ip->ip_p = IPPROTO_TCP; else ip->ip_p = IPPROTO_UDP; ip->ip_src = inp->inp_laddr; ip->ip_dst = inp->inp_faddr; } #endif /* INET */ th->th_sport = inp->inp_lport; th->th_dport = inp->inp_fport; th->th_seq = 0; th->th_ack = 0; th->th_off = 5; tcp_set_flags(th, 0); th->th_win = 0; th->th_urp = 0; th->th_sum = 0; /* in_pseudo() is called later for ipv4 */ } /* * Create template to be used to send tcp packets on a connection. * Allocates an mbuf and fills in a skeletal tcp/ip header. The only * use for this function is in keepalives, which use tcp_respond. */ struct tcptemp * tcpip_maketemplate(struct inpcb *inp) { struct tcptemp *t; t = malloc(sizeof(*t), M_TEMP, M_NOWAIT); if (t == NULL) return (NULL); tcpip_fillheaders(inp, 0, (void *)&t->tt_ipgen, (void *)&t->tt_t); return (t); } /* * Send a single message to the TCP at address specified by * the given TCP/IP header. If m == NULL, then we make a copy * of the tcpiphdr at th and send directly to the addressed host. * This is used to force keep alive messages out using the TCP * template for a connection. If flags are given then we send * a message back to the TCP which originated the segment th, * and discard the mbuf containing it and any other attached mbufs. * * In any case the ack and sequence number of the transmitted * segment are as specified by the parameters. * * NOTE: If m != NULL, then th must point to *inside* the mbuf. */ void tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m, tcp_seq ack, tcp_seq seq, uint16_t flags) { struct tcpopt to; struct inpcb *inp; struct ip *ip; struct mbuf *optm; struct udphdr *uh = NULL; struct tcphdr *nth; struct tcp_log_buffer *lgb; u_char *optp; #ifdef INET6 struct ip6_hdr *ip6; int isipv6; #endif /* INET6 */ int optlen, tlen, win, ulen; int ect = 0; bool incl_opts; uint16_t port; int output_ret; #ifdef INVARIANTS int thflags = tcp_get_flags(th); #endif KASSERT(tp != NULL || m != NULL, ("tcp_respond: tp and m both NULL")); NET_EPOCH_ASSERT(); #ifdef INET6 isipv6 = ((struct ip *)ipgen)->ip_v == (IPV6_VERSION >> 4); ip6 = ipgen; #endif /* INET6 */ ip = ipgen; if (tp != NULL) { inp = tptoinpcb(tp); INP_LOCK_ASSERT(inp); } else inp = NULL; if (m != NULL) { #ifdef INET6 if (isipv6 && ip6 && (ip6->ip6_nxt == IPPROTO_UDP)) port = m->m_pkthdr.tcp_tun_port; else #endif if (ip && (ip->ip_p == IPPROTO_UDP)) port = m->m_pkthdr.tcp_tun_port; else port = 0; } else port = tp->t_port; incl_opts = false; win = 0; if (tp != NULL) { if (!(flags & TH_RST)) { win = sbspace(&inp->inp_socket->so_rcv); if (win > TCP_MAXWIN << tp->rcv_scale) win = TCP_MAXWIN << tp->rcv_scale; } if ((tp->t_flags & TF_NOOPT) == 0) incl_opts = true; } if (m == NULL) { m = m_gethdr(M_NOWAIT, MT_DATA); if (m == NULL) return; m->m_data += max_linkhdr; #ifdef INET6 if (isipv6) { bcopy((caddr_t)ip6, mtod(m, caddr_t), sizeof(struct ip6_hdr)); ip6 = mtod(m, struct ip6_hdr *); nth = (struct tcphdr *)(ip6 + 1); if (port) { /* Insert a UDP header */ uh = (struct udphdr *)nth; uh->uh_sport = htons(V_tcp_udp_tunneling_port); uh->uh_dport = port; nth = (struct tcphdr *)(uh + 1); } } else #endif /* INET6 */ { bcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip)); ip = mtod(m, struct ip *); nth = (struct tcphdr *)(ip + 1); if (port) { /* Insert a UDP header */ uh = (struct udphdr *)nth; uh->uh_sport = htons(V_tcp_udp_tunneling_port); uh->uh_dport = port; nth = (struct tcphdr *)(uh + 1); } } bcopy((caddr_t)th, (caddr_t)nth, sizeof(struct tcphdr)); flags = TH_ACK; } else if ((!M_WRITABLE(m)) || (port != 0)) { struct mbuf *n; /* Can't reuse 'm', allocate a new mbuf. */ n = m_gethdr(M_NOWAIT, MT_DATA); if (n == NULL) { m_freem(m); return; } if (!m_dup_pkthdr(n, m, M_NOWAIT)) { m_freem(m); m_freem(n); return; } n->m_data += max_linkhdr; /* m_len is set later */ #define xchg(a,b,type) { type t; t=a; a=b; b=t; } #ifdef INET6 if (isipv6) { bcopy((caddr_t)ip6, mtod(n, caddr_t), sizeof(struct ip6_hdr)); ip6 = mtod(n, struct ip6_hdr *); xchg(ip6->ip6_dst, ip6->ip6_src, struct in6_addr); nth = (struct tcphdr *)(ip6 + 1); if (port) { /* Insert a UDP header */ uh = (struct udphdr *)nth; uh->uh_sport = htons(V_tcp_udp_tunneling_port); uh->uh_dport = port; nth = (struct tcphdr *)(uh + 1); } } else #endif /* INET6 */ { bcopy((caddr_t)ip, mtod(n, caddr_t), sizeof(struct ip)); ip = mtod(n, struct ip *); xchg(ip->ip_dst.s_addr, ip->ip_src.s_addr, uint32_t); nth = (struct tcphdr *)(ip + 1); if (port) { /* Insert a UDP header */ uh = (struct udphdr *)nth; uh->uh_sport = htons(V_tcp_udp_tunneling_port); uh->uh_dport = port; nth = (struct tcphdr *)(uh + 1); } } bcopy((caddr_t)th, (caddr_t)nth, sizeof(struct tcphdr)); xchg(nth->th_dport, nth->th_sport, uint16_t); th = nth; m_freem(m); m = n; } else { /* * reuse the mbuf. * XXX MRT We inherit the FIB, which is lucky. */ m_freem(m->m_next); m->m_next = NULL; m->m_data = (caddr_t)ipgen; /* m_len is set later */ #ifdef INET6 if (isipv6) { xchg(ip6->ip6_dst, ip6->ip6_src, struct in6_addr); nth = (struct tcphdr *)(ip6 + 1); } else #endif /* INET6 */ { xchg(ip->ip_dst.s_addr, ip->ip_src.s_addr, uint32_t); nth = (struct tcphdr *)(ip + 1); } if (th != nth) { /* * this is usually a case when an extension header * exists between the IPv6 header and the * TCP header. */ nth->th_sport = th->th_sport; nth->th_dport = th->th_dport; } xchg(nth->th_dport, nth->th_sport, uint16_t); #undef xchg } tlen = 0; #ifdef INET6 if (isipv6) tlen = sizeof (struct ip6_hdr) + sizeof (struct tcphdr); #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET tlen = sizeof (struct tcpiphdr); #endif if (port) tlen += sizeof (struct udphdr); #ifdef INVARIANTS m->m_len = 0; KASSERT(M_TRAILINGSPACE(m) >= tlen, ("Not enough trailing space for message (m=%p, need=%d, have=%ld)", m, tlen, (long)M_TRAILINGSPACE(m))); #endif m->m_len = tlen; to.to_flags = 0; if (incl_opts) { ect = tcp_ecn_output_established(tp, &flags, 0, false); /* Make sure we have room. */ if (M_TRAILINGSPACE(m) < TCP_MAXOLEN) { m->m_next = m_get(M_NOWAIT, MT_DATA); if (m->m_next) { optp = mtod(m->m_next, u_char *); optm = m->m_next; } else incl_opts = false; } else { optp = (u_char *) (nth + 1); optm = m; } } if (incl_opts) { /* Timestamps. */ if (tp->t_flags & TF_RCVD_TSTMP) { to.to_tsval = tcp_ts_getticks() + tp->ts_offset; to.to_tsecr = tp->ts_recent; to.to_flags |= TOF_TS; } #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) /* TCP-MD5 (RFC2385). */ if (tp->t_flags & TF_SIGNATURE) to.to_flags |= TOF_SIGNATURE; #endif /* Add the options. */ tlen += optlen = tcp_addoptions(&to, optp); /* Update m_len in the correct mbuf. */ optm->m_len += optlen; } else optlen = 0; #ifdef INET6 if (isipv6) { if (uh) { ulen = tlen - sizeof(struct ip6_hdr); uh->uh_ulen = htons(ulen); } ip6->ip6_flow = htonl(ect << 20); ip6->ip6_vfc = IPV6_VERSION; if (port) ip6->ip6_nxt = IPPROTO_UDP; else ip6->ip6_nxt = IPPROTO_TCP; ip6->ip6_plen = htons(tlen - sizeof(*ip6)); } #endif #if defined(INET) && defined(INET6) else #endif #ifdef INET { if (uh) { ulen = tlen - sizeof(struct ip); uh->uh_ulen = htons(ulen); } ip->ip_tos = ect; ip->ip_len = htons(tlen); ip->ip_ttl = V_ip_defttl; if (port) { ip->ip_p = IPPROTO_UDP; } else { ip->ip_p = IPPROTO_TCP; } if (V_path_mtu_discovery) ip->ip_off |= htons(IP_DF); } #endif m->m_pkthdr.len = tlen; m->m_pkthdr.rcvif = NULL; #ifdef MAC if (inp != NULL) { /* * Packet is associated with a socket, so allow the * label of the response to reflect the socket label. */ INP_LOCK_ASSERT(inp); mac_inpcb_create_mbuf(inp, m); } else { /* * Packet is not associated with a socket, so possibly * update the label in place. */ mac_netinet_tcp_reply(m); } #endif nth->th_seq = htonl(seq); nth->th_ack = htonl(ack); nth->th_off = (sizeof (struct tcphdr) + optlen) >> 2; tcp_set_flags(nth, flags); if (tp != NULL) nth->th_win = htons((u_short) (win >> tp->rcv_scale)); else nth->th_win = htons((u_short)win); nth->th_urp = 0; #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) if (to.to_flags & TOF_SIGNATURE) { if (!TCPMD5_ENABLED() || TCPMD5_OUTPUT(m, nth, to.to_signature) != 0) { m_freem(m); return; } } #endif #ifdef INET6 if (isipv6) { if (port) { m->m_pkthdr.csum_flags = CSUM_UDP_IPV6; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); uh->uh_sum = in6_cksum_pseudo(ip6, ulen, IPPROTO_UDP, 0); nth->th_sum = 0; } else { m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); nth->th_sum = in6_cksum_pseudo(ip6, tlen - sizeof(struct ip6_hdr), IPPROTO_TCP, 0); } ip6->ip6_hlim = in6_selecthlim(inp, NULL); } #endif /* INET6 */ #if defined(INET6) && defined(INET) else #endif #ifdef INET { if (port) { uh->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(ulen + IPPROTO_UDP)); m->m_pkthdr.csum_flags = CSUM_UDP; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); nth->th_sum = 0; } else { m->m_pkthdr.csum_flags = CSUM_TCP; m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); nth->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons((u_short)(tlen - sizeof(struct ip) + ip->ip_p))); } } #endif /* INET */ -#ifdef TCPDEBUG - if (tp == NULL || (inp->inp_socket->so_options & SO_DEBUG)) - tcp_trace(TA_OUTPUT, 0, tp, mtod(m, void *), th, 0); -#endif TCP_PROBE3(debug__output, tp, th, m); if (flags & TH_RST) TCP_PROBE5(accept__refused, NULL, NULL, m, tp, nth); lgb = NULL; if ((tp != NULL) && (tp->t_logstate != TCP_LOG_STATE_OFF)) { if (INP_WLOCKED(inp)) { union tcp_log_stackspecific log; struct timeval tv; memset(&log.u_bbr, 0, sizeof(log.u_bbr)); log.u_bbr.inhpts = inp->inp_in_hpts; log.u_bbr.flex8 = 4; log.u_bbr.pkts_out = tp->t_maxseg; log.u_bbr.timeStamp = tcp_get_usecs(&tv); log.u_bbr.delivered = 0; lgb = tcp_log_event_(tp, nth, NULL, NULL, TCP_LOG_OUT, ERRNO_UNK, 0, &log, false, NULL, NULL, 0, &tv); } else { /* * We can not log the packet, since we only own the * read lock, but a write lock is needed. The read lock * is not upgraded to a write lock, since only getting * the read lock was done intentionally to improve the * handling of SYN flooding attacks. * This happens only for pure SYN segments received in * the initial CLOSED state, or received in a more * advanced state than listen and the UDP encapsulation * port is unexpected. * The incoming SYN segments do not really belong to * the TCP connection and the handling does not change * the state of the TCP connection. Therefore, the * sending of the RST segments is not logged. Please * note that also the incoming SYN segments are not * logged. * * The following code ensures that the above description * is and stays correct. */ KASSERT((thflags & (TH_ACK|TH_SYN)) == TH_SYN && (tp->t_state == TCPS_CLOSED || (tp->t_state > TCPS_LISTEN && tp->t_port != port)), ("%s: Logging of TCP segment with flags 0x%b and " "UDP encapsulation port %u skipped in state %s", __func__, thflags, PRINT_TH_FLAGS, ntohs(port), tcpstates[tp->t_state])); } } if (flags & TH_ACK) TCPSTAT_INC(tcps_sndacks); else if (flags & (TH_SYN|TH_FIN|TH_RST)) TCPSTAT_INC(tcps_sndctrl); TCPSTAT_INC(tcps_sndtotal); #ifdef INET6 if (isipv6) { TCP_PROBE5(send, NULL, tp, ip6, tp, nth); output_ret = ip6_output(m, NULL, NULL, 0, NULL, NULL, inp); } #endif /* INET6 */ #if defined(INET) && defined(INET6) else #endif #ifdef INET { TCP_PROBE5(send, NULL, tp, ip, tp, nth); output_ret = ip_output(m, NULL, NULL, 0, NULL, inp); } #endif if (lgb != NULL) lgb->tlb_errno = output_ret; } /* * Create a new TCP control block, making an empty reassembly queue and hooking * it to the argument protocol control block. The `inp' parameter must have * come from the zone allocator set up by tcpcbstor declaration. */ struct tcpcb * tcp_newtcpcb(struct inpcb *inp) { struct tcpcb *tp = intotcpcb(inp); #ifdef INET6 int isipv6 = (inp->inp_vflag & INP_IPV6) != 0; #endif /* INET6 */ /* * Historically allocation was done with M_ZERO. There is a lot of * code that rely on that. For now take safe approach and zero whole * tcpcb. This definitely can be optimized. */ bzero(&tp->t_start_zero, t_zero_size); /* Initialise cc_var struct for this tcpcb. */ tp->t_ccv.type = IPPROTO_TCP; tp->t_ccv.ccvc.tcp = tp; rw_rlock(&tcp_function_lock); tp->t_fb = tcp_func_set_ptr; refcount_acquire(&tp->t_fb->tfb_refcnt); rw_runlock(&tcp_function_lock); /* * Use the current system default CC algorithm. */ cc_attach(tp, CC_DEFAULT_ALGO()); if (CC_ALGO(tp)->cb_init != NULL) if (CC_ALGO(tp)->cb_init(&tp->t_ccv, NULL) > 0) { cc_detach(tp); if (tp->t_fb->tfb_tcp_fb_fini) (*tp->t_fb->tfb_tcp_fb_fini)(tp, 1); refcount_release(&tp->t_fb->tfb_refcnt); return (NULL); } #ifdef TCP_HHOOK if (khelp_init_osd(HELPER_CLASS_TCP, &tp->t_osd)) { if (tp->t_fb->tfb_tcp_fb_fini) (*tp->t_fb->tfb_tcp_fb_fini)(tp, 1); refcount_release(&tp->t_fb->tfb_refcnt); return (NULL); } #endif TAILQ_INIT(&tp->t_segq); tp->t_maxseg = #ifdef INET6 isipv6 ? V_tcp_v6mssdflt : #endif /* INET6 */ V_tcp_mssdflt; callout_init_rw(&tp->t_callout, &inp->inp_lock, CALLOUT_RETURNUNLOCKED); for (int i = 0; i < TT_N; i++) tp->t_timers[i] = SBT_MAX; switch (V_tcp_do_rfc1323) { case 0: break; default: case 1: tp->t_flags = (TF_REQ_SCALE|TF_REQ_TSTMP); break; case 2: tp->t_flags = TF_REQ_SCALE; break; case 3: tp->t_flags = TF_REQ_TSTMP; break; } if (V_tcp_do_sack) tp->t_flags |= TF_SACK_PERMIT; TAILQ_INIT(&tp->snd_holes); /* * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no * rtt estimate. Set rttvar so that srtt + 4 * rttvar gives * reasonable initial retransmit time. */ tp->t_srtt = TCPTV_SRTTBASE; tp->t_rttvar = ((tcp_rexmit_initial - TCPTV_SRTTBASE) << TCP_RTTVAR_SHIFT) / 4; tp->t_rttmin = tcp_rexmit_min; tp->t_rxtcur = tcp_rexmit_initial; tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; tp->t_rcvtime = ticks; /* * IPv4 TTL initialization is necessary for an IPv6 socket as well, * because the socket may be bound to an IPv6 wildcard address, * which may match an IPv4-mapped IPv6 address. */ inp->inp_ip_ttl = V_ip_defttl; #ifdef TCPHPTS /* * If using hpts lets drop a random number in so * not all new connections fall on the same CPU. */ inp->inp_hpts_cpu = hpts_random_cpu(inp); #endif #ifdef TCPPCAP /* * Init the TCP PCAP queues. */ tcp_pcap_tcpcb_init(tp); #endif #ifdef TCP_BLACKBOX /* Initialize the per-TCPCB log data. */ tcp_log_tcpcbinit(tp); #endif tp->t_pacing_rate = -1; if (tp->t_fb->tfb_tcp_fb_init) { if ((*tp->t_fb->tfb_tcp_fb_init)(tp)) { refcount_release(&tp->t_fb->tfb_refcnt); return (NULL); } } #ifdef STATS if (V_tcp_perconn_stats_enable == 1) tp->t_stats = stats_blob_alloc(V_tcp_perconn_stats_dflt_tpl, 0); #endif if (V_tcp_do_lrd) tp->t_flags |= TF_LRD; return (tp); } /* * Drop a TCP connection, reporting * the specified error. If connection is synchronized, * then send a RST to peer. */ struct tcpcb * tcp_drop(struct tcpcb *tp, int errno) { struct socket *so = tptosocket(tp); NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(tptoinpcb(tp)); if (TCPS_HAVERCVDSYN(tp->t_state)) { tcp_state_change(tp, TCPS_CLOSED); /* Don't use tcp_output() here due to possible recursion. */ (void)tcp_output_nodrop(tp); TCPSTAT_INC(tcps_drops); } else TCPSTAT_INC(tcps_conndrops); if (errno == ETIMEDOUT && tp->t_softerror) errno = tp->t_softerror; so->so_error = errno; return (tcp_close(tp)); } void tcp_discardcb(struct tcpcb *tp) { struct inpcb *inp = tptoinpcb(tp); struct socket *so = tptosocket(tp); #ifdef INET6 bool isipv6 = (inp->inp_vflag & INP_IPV6) != 0; #endif INP_WLOCK_ASSERT(inp); tcp_timer_stop(tp); if (tp->t_fb->tfb_tcp_timer_stop_all) { tp->t_fb->tfb_tcp_timer_stop_all(tp); } /* free the reassembly queue, if any */ tcp_reass_flush(tp); #ifdef TCP_OFFLOAD /* Disconnect offload device, if any. */ if (tp->t_flags & TF_TOE) tcp_offload_detach(tp); #endif tcp_free_sackholes(tp); #ifdef TCPPCAP /* Free the TCP PCAP queues. */ tcp_pcap_drain(&(tp->t_inpkts)); tcp_pcap_drain(&(tp->t_outpkts)); #endif /* Allow the CC algorithm to clean up after itself. */ if (CC_ALGO(tp)->cb_destroy != NULL) CC_ALGO(tp)->cb_destroy(&tp->t_ccv); CC_DATA(tp) = NULL; /* Detach from the CC algorithm */ cc_detach(tp); #ifdef TCP_HHOOK khelp_destroy_osd(&tp->t_osd); #endif #ifdef STATS stats_blob_destroy(tp->t_stats); #endif CC_ALGO(tp) = NULL; #ifdef TCP_BLACKBOX tcp_log_tcpcbfini(tp); #endif TCPSTATES_DEC(tp->t_state); if (tp->t_fb->tfb_tcp_fb_fini) (*tp->t_fb->tfb_tcp_fb_fini)(tp, 1); /* * If we got enough samples through the srtt filter, * save the rtt and rttvar in the routing entry. * 'Enough' is arbitrarily defined as 4 rtt samples. * 4 samples is enough for the srtt filter to converge * to within enough % of the correct value; fewer samples * and we could save a bogus rtt. The danger is not high * as tcp quickly recovers from everything. * XXX: Works very well but needs some more statistics! * * XXXRRS: Updating must be after the stack fini() since * that may be converting some internal representation of * say srtt etc into the general one used by other stacks. * Lets also at least protect against the so being NULL * as RW stated below. */ if ((tp->t_rttupdated >= 4) && (so != NULL)) { struct hc_metrics_lite metrics; uint32_t ssthresh; bzero(&metrics, sizeof(metrics)); /* * Update the ssthresh always when the conditions below * are satisfied. This gives us better new start value * for the congestion avoidance for new connections. * ssthresh is only set if packet loss occurred on a session. * * XXXRW: 'so' may be NULL here, and/or socket buffer may be * being torn down. Ideally this code would not use 'so'. */ ssthresh = tp->snd_ssthresh; if (ssthresh != 0 && ssthresh < so->so_snd.sb_hiwat / 2) { /* * convert the limit from user data bytes to * packets then to packet data bytes. */ ssthresh = (ssthresh + tp->t_maxseg / 2) / tp->t_maxseg; if (ssthresh < 2) ssthresh = 2; ssthresh *= (tp->t_maxseg + #ifdef INET6 (isipv6 ? sizeof (struct ip6_hdr) + sizeof (struct tcphdr) : #endif sizeof (struct tcpiphdr) #ifdef INET6 ) #endif ); } else ssthresh = 0; metrics.rmx_ssthresh = ssthresh; metrics.rmx_rtt = tp->t_srtt; metrics.rmx_rttvar = tp->t_rttvar; metrics.rmx_cwnd = tp->snd_cwnd; metrics.rmx_sendpipe = 0; metrics.rmx_recvpipe = 0; tcp_hc_update(&inp->inp_inc, &metrics); } refcount_release(&tp->t_fb->tfb_refcnt); } /* * Attempt to close a TCP control block, marking it as dropped, and freeing * the socket if we hold the only reference. */ struct tcpcb * tcp_close(struct tcpcb *tp) { struct inpcb *inp = tptoinpcb(tp); struct socket *so = tptosocket(tp); INP_WLOCK_ASSERT(inp); #ifdef TCP_OFFLOAD if (tp->t_state == TCPS_LISTEN) tcp_offload_listen_stop(tp); #endif /* * This releases the TFO pending counter resource for TFO listen * sockets as well as passively-created TFO sockets that transition * from SYN_RECEIVED to CLOSED. */ if (tp->t_tfo_pending) { tcp_fastopen_decrement_counter(tp->t_tfo_pending); tp->t_tfo_pending = NULL; } #ifdef TCPHPTS tcp_hpts_remove(inp); #endif in_pcbdrop(inp); TCPSTAT_INC(tcps_closed); if (tp->t_state != TCPS_CLOSED) tcp_state_change(tp, TCPS_CLOSED); KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL")); soisdisconnected(so); if (inp->inp_flags & INP_SOCKREF) { inp->inp_flags &= ~INP_SOCKREF; INP_WUNLOCK(inp); sorele(so); return (NULL); } return (tp); } /* * Notify a tcp user of an asynchronous error; * store error as soft error, but wake up user * (for now, won't do anything until can select for soft error). * * Do not wake up user since there currently is no mechanism for * reporting soft errors (yet - a kqueue filter may be added). */ static struct inpcb * tcp_notify(struct inpcb *inp, int error) { struct tcpcb *tp; INP_WLOCK_ASSERT(inp); tp = intotcpcb(inp); KASSERT(tp != NULL, ("tcp_notify: tp == NULL")); /* * Ignore some errors if we are hooked up. * If connection hasn't completed, has retransmitted several times, * and receives a second error, give up now. This is better * than waiting a long time to establish a connection that * can never complete. */ if (tp->t_state == TCPS_ESTABLISHED && (error == EHOSTUNREACH || error == ENETUNREACH || error == EHOSTDOWN)) { if (inp->inp_route.ro_nh) { NH_FREE(inp->inp_route.ro_nh); inp->inp_route.ro_nh = (struct nhop_object *)NULL; } return (inp); } else if (tp->t_state < TCPS_ESTABLISHED && tp->t_rxtshift > 3 && tp->t_softerror) { tp = tcp_drop(tp, error); if (tp != NULL) return (inp); else return (NULL); } else { tp->t_softerror = error; return (inp); } #if 0 wakeup( &so->so_timeo); sorwakeup(so); sowwakeup(so); #endif } static int tcp_pcblist(SYSCTL_HANDLER_ARGS) { struct inpcb_iterator inpi = INP_ALL_ITERATOR(&V_tcbinfo, INPLOOKUP_RLOCKPCB); struct xinpgen xig; struct inpcb *inp; int error; if (req->newptr != NULL) return (EPERM); if (req->oldptr == NULL) { int n; n = V_tcbinfo.ipi_count + counter_u64_fetch(V_tcps_states[TCPS_SYN_RECEIVED]); n += imax(n / 8, 10); req->oldidx = 2 * (sizeof xig) + n * sizeof(struct xtcpcb); return (0); } if ((error = sysctl_wire_old_buffer(req, 0)) != 0) return (error); bzero(&xig, sizeof(xig)); xig.xig_len = sizeof xig; xig.xig_count = V_tcbinfo.ipi_count + counter_u64_fetch(V_tcps_states[TCPS_SYN_RECEIVED]); xig.xig_gen = V_tcbinfo.ipi_gencnt; xig.xig_sogen = so_gencnt; error = SYSCTL_OUT(req, &xig, sizeof xig); if (error) return (error); error = syncache_pcblist(req); if (error) return (error); while ((inp = inp_next(&inpi)) != NULL) { if (inp->inp_gencnt <= xig.xig_gen && cr_canseeinpcb(req->td->td_ucred, inp) == 0) { struct xtcpcb xt; tcp_inptoxtp(inp, &xt); error = SYSCTL_OUT(req, &xt, sizeof xt); if (error) { INP_RUNLOCK(inp); break; } else continue; } } if (!error) { /* * Give the user an updated idea of our state. * If the generation differs from what we told * her before, she knows that something happened * while we were processing this request, and it * might be necessary to retry. */ xig.xig_gen = V_tcbinfo.ipi_gencnt; xig.xig_sogen = so_gencnt; xig.xig_count = V_tcbinfo.ipi_count + counter_u64_fetch(V_tcps_states[TCPS_SYN_RECEIVED]); error = SYSCTL_OUT(req, &xig, sizeof xig); } return (error); } SYSCTL_PROC(_net_inet_tcp, TCPCTL_PCBLIST, pcblist, CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_NEEDGIANT, NULL, 0, tcp_pcblist, "S,xtcpcb", "List of active TCP connections"); #ifdef INET static int tcp_getcred(SYSCTL_HANDLER_ARGS) { struct xucred xuc; struct sockaddr_in addrs[2]; struct epoch_tracker et; struct inpcb *inp; int error; error = priv_check(req->td, PRIV_NETINET_GETCRED); if (error) return (error); error = SYSCTL_IN(req, addrs, sizeof(addrs)); if (error) return (error); NET_EPOCH_ENTER(et); inp = in_pcblookup(&V_tcbinfo, addrs[1].sin_addr, addrs[1].sin_port, addrs[0].sin_addr, addrs[0].sin_port, INPLOOKUP_RLOCKPCB, NULL); NET_EPOCH_EXIT(et); if (inp != NULL) { if (error == 0) error = cr_canseeinpcb(req->td->td_ucred, inp); if (error == 0) cru2x(inp->inp_cred, &xuc); INP_RUNLOCK(inp); } else error = ENOENT; if (error == 0) error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); return (error); } SYSCTL_PROC(_net_inet_tcp, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_NEEDGIANT, 0, 0, tcp_getcred, "S,xucred", "Get the xucred of a TCP connection"); #endif /* INET */ #ifdef INET6 static int tcp6_getcred(SYSCTL_HANDLER_ARGS) { struct epoch_tracker et; struct xucred xuc; struct sockaddr_in6 addrs[2]; struct inpcb *inp; int error; #ifdef INET int mapped = 0; #endif error = priv_check(req->td, PRIV_NETINET_GETCRED); if (error) return (error); error = SYSCTL_IN(req, addrs, sizeof(addrs)); if (error) return (error); if ((error = sa6_embedscope(&addrs[0], V_ip6_use_defzone)) != 0 || (error = sa6_embedscope(&addrs[1], V_ip6_use_defzone)) != 0) { return (error); } if (IN6_IS_ADDR_V4MAPPED(&addrs[0].sin6_addr)) { #ifdef INET if (IN6_IS_ADDR_V4MAPPED(&addrs[1].sin6_addr)) mapped = 1; else #endif return (EINVAL); } NET_EPOCH_ENTER(et); #ifdef INET if (mapped == 1) inp = in_pcblookup(&V_tcbinfo, *(struct in_addr *)&addrs[1].sin6_addr.s6_addr[12], addrs[1].sin6_port, *(struct in_addr *)&addrs[0].sin6_addr.s6_addr[12], addrs[0].sin6_port, INPLOOKUP_RLOCKPCB, NULL); else #endif inp = in6_pcblookup(&V_tcbinfo, &addrs[1].sin6_addr, addrs[1].sin6_port, &addrs[0].sin6_addr, addrs[0].sin6_port, INPLOOKUP_RLOCKPCB, NULL); NET_EPOCH_EXIT(et); if (inp != NULL) { if (error == 0) error = cr_canseeinpcb(req->td->td_ucred, inp); if (error == 0) cru2x(inp->inp_cred, &xuc); INP_RUNLOCK(inp); } else error = ENOENT; if (error == 0) error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); return (error); } SYSCTL_PROC(_net_inet6_tcp6, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_NEEDGIANT, 0, 0, tcp6_getcred, "S,xucred", "Get the xucred of a TCP6 connection"); #endif /* INET6 */ #ifdef INET /* Path MTU to try next when a fragmentation-needed message is received. */ static inline int tcp_next_pmtu(const struct icmp *icp, const struct ip *ip) { int mtu = ntohs(icp->icmp_nextmtu); /* If no alternative MTU was proposed, try the next smaller one. */ if (!mtu) mtu = ip_next_mtu(ntohs(ip->ip_len), 1); if (mtu < V_tcp_minmss + sizeof(struct tcpiphdr)) mtu = V_tcp_minmss + sizeof(struct tcpiphdr); return (mtu); } static void tcp_ctlinput_with_port(struct icmp *icp, uint16_t port) { struct ip *ip; struct tcphdr *th; struct inpcb *inp; struct tcpcb *tp; struct inpcb *(*notify)(struct inpcb *, int); struct in_conninfo inc; tcp_seq icmp_tcp_seq; int errno, mtu; errno = icmp_errmap(icp); switch (errno) { case 0: return; case EMSGSIZE: notify = tcp_mtudisc_notify; break; case ECONNREFUSED: if (V_icmp_may_rst) notify = tcp_drop_syn_sent; else notify = tcp_notify; break; case EHOSTUNREACH: if (V_icmp_may_rst && icp->icmp_type == ICMP_TIMXCEED) notify = tcp_drop_syn_sent; else notify = tcp_notify; break; default: notify = tcp_notify; } ip = &icp->icmp_ip; th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2)); icmp_tcp_seq = th->th_seq; inp = in_pcblookup(&V_tcbinfo, ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport, INPLOOKUP_WLOCKPCB, NULL); if (inp != NULL) { tp = intotcpcb(inp); #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE && errno == EMSGSIZE) { /* * MTU discovery for offloaded connections. Let * the TOE driver verify seq# and process it. */ mtu = tcp_next_pmtu(icp, ip); tcp_offload_pmtu_update(tp, icmp_tcp_seq, mtu); goto out; } #endif if (tp->t_port != port) goto out; if (SEQ_GEQ(ntohl(icmp_tcp_seq), tp->snd_una) && SEQ_LT(ntohl(icmp_tcp_seq), tp->snd_max)) { if (errno == EMSGSIZE) { /* * MTU discovery: we got a needfrag and * will potentially try a lower MTU. */ mtu = tcp_next_pmtu(icp, ip); /* * Only process the offered MTU if it * is smaller than the current one. */ if (mtu < tp->t_maxseg + sizeof(struct tcpiphdr)) { bzero(&inc, sizeof(inc)); inc.inc_faddr = ip->ip_dst; inc.inc_fibnum = inp->inp_inc.inc_fibnum; tcp_hc_updatemtu(&inc, mtu); inp = tcp_mtudisc(inp, mtu); } } else inp = (*notify)(inp, errno); } } else { bzero(&inc, sizeof(inc)); inc.inc_fport = th->th_dport; inc.inc_lport = th->th_sport; inc.inc_faddr = ip->ip_dst; inc.inc_laddr = ip->ip_src; syncache_unreach(&inc, icmp_tcp_seq, port); } out: if (inp != NULL) INP_WUNLOCK(inp); } static void tcp_ctlinput(struct icmp *icmp) { tcp_ctlinput_with_port(icmp, htons(0)); } static void tcp_ctlinput_viaudp(udp_tun_icmp_param_t param) { /* Its a tunneled TCP over UDP icmp */ struct icmp *icmp = param.icmp; struct ip *outer_ip, *inner_ip; struct udphdr *udp; struct tcphdr *th, ttemp; int i_hlen, o_len; uint16_t port; outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip)); inner_ip = &icmp->icmp_ip; i_hlen = inner_ip->ip_hl << 2; o_len = ntohs(outer_ip->ip_len); if (o_len < (sizeof(struct ip) + 8 + i_hlen + sizeof(struct udphdr) + offsetof(struct tcphdr, th_ack))) { /* Not enough data present */ return; } /* Ok lets strip out the inner udphdr header by copying up on top of it the tcp hdr */ udp = (struct udphdr *)(((caddr_t)inner_ip) + i_hlen); if (ntohs(udp->uh_sport) != V_tcp_udp_tunneling_port) { return; } port = udp->uh_dport; th = (struct tcphdr *)(udp + 1); memcpy(&ttemp, th, sizeof(struct tcphdr)); memcpy(udp, &ttemp, sizeof(struct tcphdr)); /* Now adjust down the size of the outer IP header */ o_len -= sizeof(struct udphdr); outer_ip->ip_len = htons(o_len); /* Now call in to the normal handling code */ tcp_ctlinput_with_port(icmp, port); } #endif /* INET */ #ifdef INET6 static inline int tcp6_next_pmtu(const struct icmp6_hdr *icmp6) { int mtu = ntohl(icmp6->icmp6_mtu); /* * If no alternative MTU was proposed, or the proposed MTU was too * small, set to the min. */ if (mtu < IPV6_MMTU) mtu = IPV6_MMTU - 8; /* XXXNP: what is the adjustment for? */ return (mtu); } static void tcp6_ctlinput_with_port(struct ip6ctlparam *ip6cp, uint16_t port) { struct in6_addr *dst; struct inpcb *(*notify)(struct inpcb *, int); struct ip6_hdr *ip6; struct mbuf *m; struct inpcb *inp; struct tcpcb *tp; struct icmp6_hdr *icmp6; struct in_conninfo inc; struct tcp_ports { uint16_t th_sport; uint16_t th_dport; } t_ports; tcp_seq icmp_tcp_seq; unsigned int mtu; unsigned int off; int errno; icmp6 = ip6cp->ip6c_icmp6; m = ip6cp->ip6c_m; ip6 = ip6cp->ip6c_ip6; off = ip6cp->ip6c_off; dst = &ip6cp->ip6c_finaldst->sin6_addr; errno = icmp6_errmap(icmp6); switch (errno) { case 0: return; case EMSGSIZE: notify = tcp_mtudisc_notify; break; case ECONNREFUSED: if (V_icmp_may_rst) notify = tcp_drop_syn_sent; else notify = tcp_notify; break; case EHOSTUNREACH: /* * There are only four ICMPs that may reset connection: * - administratively prohibited * - port unreachable * - time exceeded in transit * - unknown next header */ if (V_icmp_may_rst && ((icmp6->icmp6_type == ICMP6_DST_UNREACH && (icmp6->icmp6_code == ICMP6_DST_UNREACH_ADMIN || icmp6->icmp6_code == ICMP6_DST_UNREACH_NOPORT)) || (icmp6->icmp6_type == ICMP6_TIME_EXCEEDED && icmp6->icmp6_code == ICMP6_TIME_EXCEED_TRANSIT) || (icmp6->icmp6_type == ICMP6_PARAM_PROB && icmp6->icmp6_code == ICMP6_PARAMPROB_NEXTHEADER))) notify = tcp_drop_syn_sent; else notify = tcp_notify; break; default: notify = tcp_notify; } /* Check if we can safely get the ports from the tcp hdr */ if (m == NULL || (m->m_pkthdr.len < (int32_t) (off + sizeof(struct tcp_ports)))) { return; } bzero(&t_ports, sizeof(struct tcp_ports)); m_copydata(m, off, sizeof(struct tcp_ports), (caddr_t)&t_ports); inp = in6_pcblookup(&V_tcbinfo, &ip6->ip6_dst, t_ports.th_dport, &ip6->ip6_src, t_ports.th_sport, INPLOOKUP_WLOCKPCB, NULL); off += sizeof(struct tcp_ports); if (m->m_pkthdr.len < (int32_t) (off + sizeof(tcp_seq))) { goto out; } m_copydata(m, off, sizeof(tcp_seq), (caddr_t)&icmp_tcp_seq); if (inp != NULL) { tp = intotcpcb(inp); #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE && errno == EMSGSIZE) { /* MTU discovery for offloaded connections. */ mtu = tcp6_next_pmtu(icmp6); tcp_offload_pmtu_update(tp, icmp_tcp_seq, mtu); goto out; } #endif if (tp->t_port != port) goto out; if (SEQ_GEQ(ntohl(icmp_tcp_seq), tp->snd_una) && SEQ_LT(ntohl(icmp_tcp_seq), tp->snd_max)) { if (errno == EMSGSIZE) { /* * MTU discovery: * If we got a needfrag set the MTU * in the route to the suggested new * value (if given) and then notify. */ mtu = tcp6_next_pmtu(icmp6); 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)) goto out; /* * Only process the offered MTU if it * is smaller than the current one. */ if (mtu < tp->t_maxseg + sizeof (struct tcphdr) + sizeof (struct ip6_hdr)) { tcp_hc_updatemtu(&inc, mtu); tcp_mtudisc(inp, mtu); ICMP6STAT_INC(icp6s_pmtuchg); } } else inp = (*notify)(inp, errno); } } else { bzero(&inc, sizeof(inc)); inc.inc_fibnum = M_GETFIB(m); inc.inc_flags |= INC_ISIPV6; inc.inc_fport = t_ports.th_dport; inc.inc_lport = t_ports.th_sport; inc.inc6_faddr = *dst; inc.inc6_laddr = ip6->ip6_src; syncache_unreach(&inc, icmp_tcp_seq, port); } out: if (inp != NULL) INP_WUNLOCK(inp); } static void tcp6_ctlinput(struct ip6ctlparam *ctl) { tcp6_ctlinput_with_port(ctl, htons(0)); } static void tcp6_ctlinput_viaudp(udp_tun_icmp_param_t param) { struct ip6ctlparam *ip6cp = param.ip6cp; struct mbuf *m; struct udphdr *udp; uint16_t port; m = m_pulldown(ip6cp->ip6c_m, ip6cp->ip6c_off, sizeof(struct udphdr), NULL); if (m == NULL) { return; } udp = mtod(m, struct udphdr *); if (ntohs(udp->uh_sport) != V_tcp_udp_tunneling_port) { return; } port = udp->uh_dport; m_adj(m, sizeof(struct udphdr)); if ((m->m_flags & M_PKTHDR) == 0) { ip6cp->ip6c_m->m_pkthdr.len -= sizeof(struct udphdr); } /* Now call in to the normal handling code */ tcp6_ctlinput_with_port(ip6cp, port); } #endif /* INET6 */ static uint32_t tcp_keyed_hash(struct in_conninfo *inc, u_char *key, u_int len) { SIPHASH_CTX ctx; uint32_t hash[2]; KASSERT(len >= SIPHASH_KEY_LENGTH, ("%s: keylen %u too short ", __func__, len)); SipHash24_Init(&ctx); SipHash_SetKey(&ctx, (uint8_t *)key); SipHash_Update(&ctx, &inc->inc_fport, sizeof(uint16_t)); SipHash_Update(&ctx, &inc->inc_lport, sizeof(uint16_t)); switch (inc->inc_flags & INC_ISIPV6) { #ifdef INET case 0: SipHash_Update(&ctx, &inc->inc_faddr, sizeof(struct in_addr)); SipHash_Update(&ctx, &inc->inc_laddr, sizeof(struct in_addr)); break; #endif #ifdef INET6 case INC_ISIPV6: SipHash_Update(&ctx, &inc->inc6_faddr, sizeof(struct in6_addr)); SipHash_Update(&ctx, &inc->inc6_laddr, sizeof(struct in6_addr)); break; #endif } SipHash_Final((uint8_t *)hash, &ctx); return (hash[0] ^ hash[1]); } uint32_t tcp_new_ts_offset(struct in_conninfo *inc) { struct in_conninfo inc_store, *local_inc; if (!V_tcp_ts_offset_per_conn) { memcpy(&inc_store, inc, sizeof(struct in_conninfo)); inc_store.inc_lport = 0; inc_store.inc_fport = 0; local_inc = &inc_store; } else { local_inc = inc; } return (tcp_keyed_hash(local_inc, V_ts_offset_secret, sizeof(V_ts_offset_secret))); } /* * Following is where TCP initial sequence number generation occurs. * * There are two places where we must use initial sequence numbers: * 1. In SYN-ACK packets. * 2. In SYN packets. * * All ISNs for SYN-ACK packets are generated by the syncache. See * tcp_syncache.c for details. * * The ISNs in SYN packets must be monotonic; TIME_WAIT recycling * depends on this property. In addition, these ISNs should be * unguessable so as to prevent connection hijacking. To satisfy * the requirements of this situation, the algorithm outlined in * RFC 1948 is used, with only small modifications. * * Implementation details: * * Time is based off the system timer, and is corrected so that it * increases by one megabyte per second. This allows for proper * recycling on high speed LANs while still leaving over an hour * before rollover. * * As reading the *exact* system time is too expensive to be done * whenever setting up a TCP connection, we increment the time * offset in two ways. First, a small random positive increment * is added to isn_offset for each connection that is set up. * Second, the function tcp_isn_tick fires once per clock tick * and increments isn_offset as necessary so that sequence numbers * are incremented at approximately ISN_BYTES_PER_SECOND. The * random positive increments serve only to ensure that the same * exact sequence number is never sent out twice (as could otherwise * happen when a port is recycled in less than the system tick * interval.) * * net.inet.tcp.isn_reseed_interval controls the number of seconds * between seeding of isn_secret. This is normally set to zero, * as reseeding should not be necessary. * * Locking of the global variables isn_secret, isn_last_reseed, isn_offset, * isn_offset_old, and isn_ctx is performed using the ISN lock. In * general, this means holding an exclusive (write) lock. */ #define ISN_BYTES_PER_SECOND 1048576 #define ISN_STATIC_INCREMENT 4096 #define ISN_RANDOM_INCREMENT (4096 - 1) #define ISN_SECRET_LENGTH SIPHASH_KEY_LENGTH VNET_DEFINE_STATIC(u_char, isn_secret[ISN_SECRET_LENGTH]); VNET_DEFINE_STATIC(int, isn_last); VNET_DEFINE_STATIC(int, isn_last_reseed); VNET_DEFINE_STATIC(u_int32_t, isn_offset); VNET_DEFINE_STATIC(u_int32_t, isn_offset_old); #define V_isn_secret VNET(isn_secret) #define V_isn_last VNET(isn_last) #define V_isn_last_reseed VNET(isn_last_reseed) #define V_isn_offset VNET(isn_offset) #define V_isn_offset_old VNET(isn_offset_old) tcp_seq tcp_new_isn(struct in_conninfo *inc) { tcp_seq new_isn; u_int32_t projected_offset; ISN_LOCK(); /* Seed if this is the first use, reseed if requested. */ if ((V_isn_last_reseed == 0) || ((V_tcp_isn_reseed_interval > 0) && (((u_int)V_isn_last_reseed + (u_int)V_tcp_isn_reseed_interval*hz) < (u_int)ticks))) { arc4rand(&V_isn_secret, sizeof(V_isn_secret), 0); V_isn_last_reseed = ticks; } /* Compute the hash and return the ISN. */ new_isn = (tcp_seq)tcp_keyed_hash(inc, V_isn_secret, sizeof(V_isn_secret)); V_isn_offset += ISN_STATIC_INCREMENT + (arc4random() & ISN_RANDOM_INCREMENT); if (ticks != V_isn_last) { projected_offset = V_isn_offset_old + ISN_BYTES_PER_SECOND / hz * (ticks - V_isn_last); if (SEQ_GT(projected_offset, V_isn_offset)) V_isn_offset = projected_offset; V_isn_offset_old = V_isn_offset; V_isn_last = ticks; } new_isn += V_isn_offset; ISN_UNLOCK(); return (new_isn); } /* * When a specific ICMP unreachable message is received and the * connection state is SYN-SENT, drop the connection. This behavior * is controlled by the icmp_may_rst sysctl. */ static struct inpcb * tcp_drop_syn_sent(struct inpcb *inp, int errno) { struct tcpcb *tp; NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(inp); tp = intotcpcb(inp); if (tp->t_state != TCPS_SYN_SENT) return (inp); if (IS_FASTOPEN(tp->t_flags)) tcp_fastopen_disable_path(tp); tp = tcp_drop(tp, errno); if (tp != NULL) return (inp); else return (NULL); } /* * When `need fragmentation' ICMP is received, update our idea of the MSS * based on the new value. Also nudge TCP to send something, since we * know the packet we just sent was dropped. * This duplicates some code in the tcp_mss() function in tcp_input.c. */ static struct inpcb * tcp_mtudisc_notify(struct inpcb *inp, int error) { return (tcp_mtudisc(inp, -1)); } static struct inpcb * tcp_mtudisc(struct inpcb *inp, int mtuoffer) { struct tcpcb *tp; struct socket *so; INP_WLOCK_ASSERT(inp); tp = intotcpcb(inp); KASSERT(tp != NULL, ("tcp_mtudisc: tp == NULL")); tcp_mss_update(tp, -1, mtuoffer, NULL, NULL); so = inp->inp_socket; SOCKBUF_LOCK(&so->so_snd); /* If the mss is larger than the socket buffer, decrease the mss. */ if (so->so_snd.sb_hiwat < tp->t_maxseg) tp->t_maxseg = so->so_snd.sb_hiwat; SOCKBUF_UNLOCK(&so->so_snd); TCPSTAT_INC(tcps_mturesent); tp->t_rtttime = 0; tp->snd_nxt = tp->snd_una; tcp_free_sackholes(tp); tp->snd_recover = tp->snd_max; if (tp->t_flags & TF_SACK_PERMIT) EXIT_FASTRECOVERY(tp->t_flags); if (tp->t_fb->tfb_tcp_mtu_chg != NULL) { /* * Conceptually the snd_nxt setting * and freeing sack holes should * be done by the default stacks * own tfb_tcp_mtu_chg(). */ tp->t_fb->tfb_tcp_mtu_chg(tp); } if (tcp_output(tp) < 0) return (NULL); else return (inp); } #ifdef INET /* * Look-up the routing entry to the peer of this inpcb. If no route * is found and it cannot be allocated, then return 0. This routine * is called by TCP routines that access the rmx structure and by * tcp_mss_update to get the peer/interface MTU. */ uint32_t tcp_maxmtu(struct in_conninfo *inc, struct tcp_ifcap *cap) { struct nhop_object *nh; struct ifnet *ifp; uint32_t maxmtu = 0; KASSERT(inc != NULL, ("tcp_maxmtu with NULL in_conninfo pointer")); if (inc->inc_faddr.s_addr != INADDR_ANY) { nh = fib4_lookup(inc->inc_fibnum, inc->inc_faddr, 0, NHR_NONE, 0); if (nh == NULL) return (0); ifp = nh->nh_ifp; maxmtu = nh->nh_mtu; /* Report additional interface capabilities. */ if (cap != NULL) { if (ifp->if_capenable & IFCAP_TSO4 && ifp->if_hwassist & CSUM_TSO) { cap->ifcap |= CSUM_TSO; cap->tsomax = ifp->if_hw_tsomax; cap->tsomaxsegcount = ifp->if_hw_tsomaxsegcount; cap->tsomaxsegsize = ifp->if_hw_tsomaxsegsize; } } } return (maxmtu); } #endif /* INET */ #ifdef INET6 uint32_t tcp_maxmtu6(struct in_conninfo *inc, struct tcp_ifcap *cap) { struct nhop_object *nh; struct in6_addr dst6; uint32_t scopeid; struct ifnet *ifp; uint32_t maxmtu = 0; KASSERT(inc != NULL, ("tcp_maxmtu6 with NULL in_conninfo pointer")); if (inc->inc_flags & INC_IPV6MINMTU) return (IPV6_MMTU); if (!IN6_IS_ADDR_UNSPECIFIED(&inc->inc6_faddr)) { in6_splitscope(&inc->inc6_faddr, &dst6, &scopeid); nh = fib6_lookup(inc->inc_fibnum, &dst6, scopeid, NHR_NONE, 0); if (nh == NULL) return (0); ifp = nh->nh_ifp; maxmtu = nh->nh_mtu; /* Report additional interface capabilities. */ if (cap != NULL) { if (ifp->if_capenable & IFCAP_TSO6 && ifp->if_hwassist & CSUM_TSO) { cap->ifcap |= CSUM_TSO; cap->tsomax = ifp->if_hw_tsomax; cap->tsomaxsegcount = ifp->if_hw_tsomaxsegcount; cap->tsomaxsegsize = ifp->if_hw_tsomaxsegsize; } } } return (maxmtu); } /* * Handle setsockopt(IPV6_USE_MIN_MTU) by a TCP stack. * * XXXGL: we are updating inpcb here with INC_IPV6MINMTU flag. * The right place to do that is ip6_setpktopt() that has just been * executed. By the way it just filled ip6po_minmtu for us. */ void tcp6_use_min_mtu(struct tcpcb *tp) { struct inpcb *inp = tptoinpcb(tp); INP_WLOCK_ASSERT(inp); /* * In case of the IPV6_USE_MIN_MTU socket * option, the INC_IPV6MINMTU flag to announce * a corresponding MSS during the initial * handshake. If the TCP connection is not in * the front states, just reduce the MSS being * used. This avoids the sending of TCP * segments which will be fragmented at the * IPv6 layer. */ inp->inp_inc.inc_flags |= INC_IPV6MINMTU; if ((tp->t_state >= TCPS_SYN_SENT) && (inp->inp_inc.inc_flags & INC_ISIPV6)) { struct ip6_pktopts *opt; opt = inp->in6p_outputopts; if (opt != NULL && opt->ip6po_minmtu == IP6PO_MINMTU_ALL && tp->t_maxseg > TCP6_MSS) tp->t_maxseg = TCP6_MSS; } } #endif /* INET6 */ /* * Calculate effective SMSS per RFC5681 definition for a given TCP * connection at its current state, taking into account SACK and etc. */ u_int tcp_maxseg(const struct tcpcb *tp) { u_int optlen; if (tp->t_flags & TF_NOOPT) return (tp->t_maxseg); /* * Here we have a simplified code from tcp_addoptions(), * without a proper loop, and having most of paddings hardcoded. * We might make mistakes with padding here in some edge cases, * but this is harmless, since result of tcp_maxseg() is used * only in cwnd and ssthresh estimations. */ if (TCPS_HAVEESTABLISHED(tp->t_state)) { if (tp->t_flags & TF_RCVD_TSTMP) optlen = TCPOLEN_TSTAMP_APPA; else optlen = 0; #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) if (tp->t_flags & TF_SIGNATURE) optlen += PADTCPOLEN(TCPOLEN_SIGNATURE); #endif if ((tp->t_flags & TF_SACK_PERMIT) && tp->rcv_numsacks > 0) { optlen += TCPOLEN_SACKHDR; optlen += tp->rcv_numsacks * TCPOLEN_SACK; optlen = PADTCPOLEN(optlen); } } else { if (tp->t_flags & TF_REQ_TSTMP) optlen = TCPOLEN_TSTAMP_APPA; else optlen = PADTCPOLEN(TCPOLEN_MAXSEG); if (tp->t_flags & TF_REQ_SCALE) optlen += PADTCPOLEN(TCPOLEN_WINDOW); #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) if (tp->t_flags & TF_SIGNATURE) optlen += PADTCPOLEN(TCPOLEN_SIGNATURE); #endif if (tp->t_flags & TF_SACK_PERMIT) optlen += PADTCPOLEN(TCPOLEN_SACK_PERMITTED); } #undef PAD optlen = min(optlen, TCP_MAXOLEN); return (tp->t_maxseg - optlen); } u_int tcp_fixed_maxseg(const struct tcpcb *tp) { int optlen; if (tp->t_flags & TF_NOOPT) return (tp->t_maxseg); /* * Here we have a simplified code from tcp_addoptions(), * without a proper loop, and having most of paddings hardcoded. * We only consider fixed options that we would send every * time I.e. SACK is not considered. This is important * for cc modules to figure out what the modulo of the * cwnd should be. */ #define PAD(len) ((((len) / 4) + !!((len) % 4)) * 4) if (TCPS_HAVEESTABLISHED(tp->t_state)) { if (tp->t_flags & TF_RCVD_TSTMP) optlen = TCPOLEN_TSTAMP_APPA; else optlen = 0; #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) if (tp->t_flags & TF_SIGNATURE) optlen += PAD(TCPOLEN_SIGNATURE); #endif } else { if (tp->t_flags & TF_REQ_TSTMP) optlen = TCPOLEN_TSTAMP_APPA; else optlen = PAD(TCPOLEN_MAXSEG); if (tp->t_flags & TF_REQ_SCALE) optlen += PAD(TCPOLEN_WINDOW); #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) if (tp->t_flags & TF_SIGNATURE) optlen += PAD(TCPOLEN_SIGNATURE); #endif if (tp->t_flags & TF_SACK_PERMIT) optlen += PAD(TCPOLEN_SACK_PERMITTED); } #undef PAD optlen = min(optlen, TCP_MAXOLEN); return (tp->t_maxseg - optlen); } static int sysctl_drop(SYSCTL_HANDLER_ARGS) { /* addrs[0] is a foreign socket, addrs[1] is a local one. */ struct sockaddr_storage addrs[2]; struct inpcb *inp; struct tcpcb *tp; #ifdef INET struct sockaddr_in *fin = NULL, *lin = NULL; #endif struct epoch_tracker et; #ifdef INET6 struct sockaddr_in6 *fin6, *lin6; #endif int error; inp = NULL; #ifdef INET6 fin6 = lin6 = NULL; #endif error = 0; if (req->oldptr != NULL || req->oldlen != 0) return (EINVAL); if (req->newptr == NULL) return (EPERM); if (req->newlen < sizeof(addrs)) return (ENOMEM); error = SYSCTL_IN(req, &addrs, sizeof(addrs)); if (error) return (error); switch (addrs[0].ss_family) { #ifdef INET6 case AF_INET6: fin6 = (struct sockaddr_in6 *)&addrs[0]; lin6 = (struct sockaddr_in6 *)&addrs[1]; if (fin6->sin6_len != sizeof(struct sockaddr_in6) || lin6->sin6_len != sizeof(struct sockaddr_in6)) return (EINVAL); if (IN6_IS_ADDR_V4MAPPED(&fin6->sin6_addr)) { if (!IN6_IS_ADDR_V4MAPPED(&lin6->sin6_addr)) return (EINVAL); in6_sin6_2_sin_in_sock((struct sockaddr *)&addrs[0]); in6_sin6_2_sin_in_sock((struct sockaddr *)&addrs[1]); #ifdef INET fin = (struct sockaddr_in *)&addrs[0]; lin = (struct sockaddr_in *)&addrs[1]; #endif break; } error = sa6_embedscope(fin6, V_ip6_use_defzone); if (error) return (error); error = sa6_embedscope(lin6, V_ip6_use_defzone); if (error) return (error); break; #endif #ifdef INET case AF_INET: fin = (struct sockaddr_in *)&addrs[0]; lin = (struct sockaddr_in *)&addrs[1]; if (fin->sin_len != sizeof(struct sockaddr_in) || lin->sin_len != sizeof(struct sockaddr_in)) return (EINVAL); break; #endif default: return (EINVAL); } NET_EPOCH_ENTER(et); switch (addrs[0].ss_family) { #ifdef INET6 case AF_INET6: inp = in6_pcblookup(&V_tcbinfo, &fin6->sin6_addr, fin6->sin6_port, &lin6->sin6_addr, lin6->sin6_port, INPLOOKUP_WLOCKPCB, NULL); break; #endif #ifdef INET case AF_INET: inp = in_pcblookup(&V_tcbinfo, fin->sin_addr, fin->sin_port, lin->sin_addr, lin->sin_port, INPLOOKUP_WLOCKPCB, NULL); break; #endif } if (inp != NULL) { if (!SOLISTENING(inp->inp_socket)) { tp = intotcpcb(inp); tp = tcp_drop(tp, ECONNABORTED); if (tp != NULL) INP_WUNLOCK(inp); } else INP_WUNLOCK(inp); } else error = ESRCH; NET_EPOCH_EXIT(et); return (error); } SYSCTL_PROC(_net_inet_tcp, TCPCTL_DROP, drop, CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_WR | CTLFLAG_SKIP | CTLFLAG_NEEDGIANT, NULL, 0, sysctl_drop, "", "Drop TCP connection"); static int tcp_sysctl_setsockopt(SYSCTL_HANDLER_ARGS) { return (sysctl_setsockopt(oidp, arg1, arg2, req, &V_tcbinfo, &tcp_ctloutput_set)); } SYSCTL_PROC(_net_inet_tcp, OID_AUTO, setsockopt, CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_WR | CTLFLAG_SKIP | CTLFLAG_MPSAFE, NULL, 0, tcp_sysctl_setsockopt, "", "Set socket option for TCP endpoint"); #ifdef KERN_TLS static int sysctl_switch_tls(SYSCTL_HANDLER_ARGS) { /* addrs[0] is a foreign socket, addrs[1] is a local one. */ struct sockaddr_storage addrs[2]; struct inpcb *inp; #ifdef INET struct sockaddr_in *fin = NULL, *lin = NULL; #endif struct epoch_tracker et; #ifdef INET6 struct sockaddr_in6 *fin6, *lin6; #endif int error; inp = NULL; #ifdef INET6 fin6 = lin6 = NULL; #endif error = 0; if (req->oldptr != NULL || req->oldlen != 0) return (EINVAL); if (req->newptr == NULL) return (EPERM); if (req->newlen < sizeof(addrs)) return (ENOMEM); error = SYSCTL_IN(req, &addrs, sizeof(addrs)); if (error) return (error); switch (addrs[0].ss_family) { #ifdef INET6 case AF_INET6: fin6 = (struct sockaddr_in6 *)&addrs[0]; lin6 = (struct sockaddr_in6 *)&addrs[1]; if (fin6->sin6_len != sizeof(struct sockaddr_in6) || lin6->sin6_len != sizeof(struct sockaddr_in6)) return (EINVAL); if (IN6_IS_ADDR_V4MAPPED(&fin6->sin6_addr)) { if (!IN6_IS_ADDR_V4MAPPED(&lin6->sin6_addr)) return (EINVAL); in6_sin6_2_sin_in_sock((struct sockaddr *)&addrs[0]); in6_sin6_2_sin_in_sock((struct sockaddr *)&addrs[1]); #ifdef INET fin = (struct sockaddr_in *)&addrs[0]; lin = (struct sockaddr_in *)&addrs[1]; #endif break; } error = sa6_embedscope(fin6, V_ip6_use_defzone); if (error) return (error); error = sa6_embedscope(lin6, V_ip6_use_defzone); if (error) return (error); break; #endif #ifdef INET case AF_INET: fin = (struct sockaddr_in *)&addrs[0]; lin = (struct sockaddr_in *)&addrs[1]; if (fin->sin_len != sizeof(struct sockaddr_in) || lin->sin_len != sizeof(struct sockaddr_in)) return (EINVAL); break; #endif default: return (EINVAL); } NET_EPOCH_ENTER(et); switch (addrs[0].ss_family) { #ifdef INET6 case AF_INET6: inp = in6_pcblookup(&V_tcbinfo, &fin6->sin6_addr, fin6->sin6_port, &lin6->sin6_addr, lin6->sin6_port, INPLOOKUP_WLOCKPCB, NULL); break; #endif #ifdef INET case AF_INET: inp = in_pcblookup(&V_tcbinfo, fin->sin_addr, fin->sin_port, lin->sin_addr, lin->sin_port, INPLOOKUP_WLOCKPCB, NULL); break; #endif } NET_EPOCH_EXIT(et); if (inp != NULL) { struct socket *so; so = inp->inp_socket; soref(so); error = ktls_set_tx_mode(so, arg2 == 0 ? TCP_TLS_MODE_SW : TCP_TLS_MODE_IFNET); INP_WUNLOCK(inp); sorele(so); } else error = ESRCH; return (error); } SYSCTL_PROC(_net_inet_tcp, OID_AUTO, switch_to_sw_tls, CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_WR | CTLFLAG_SKIP | CTLFLAG_NEEDGIANT, NULL, 0, sysctl_switch_tls, "", "Switch TCP connection to SW TLS"); SYSCTL_PROC(_net_inet_tcp, OID_AUTO, switch_to_ifnet_tls, CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_WR | CTLFLAG_SKIP | CTLFLAG_NEEDGIANT, NULL, 1, sysctl_switch_tls, "", "Switch TCP connection to ifnet TLS"); #endif /* * Generate a standardized TCP log line for use throughout the * tcp subsystem. Memory allocation is done with M_NOWAIT to * allow use in the interrupt context. * * NB: The caller MUST free(s, M_TCPLOG) the returned string. * NB: The function may return NULL if memory allocation failed. * * Due to header inclusion and ordering limitations the struct ip * and ip6_hdr pointers have to be passed as void pointers. */ char * tcp_log_vain(struct in_conninfo *inc, struct tcphdr *th, const void *ip4hdr, const void *ip6hdr) { /* Is logging enabled? */ if (V_tcp_log_in_vain == 0) return (NULL); return (tcp_log_addr(inc, th, ip4hdr, ip6hdr)); } char * tcp_log_addrs(struct in_conninfo *inc, struct tcphdr *th, const void *ip4hdr, const void *ip6hdr) { /* Is logging enabled? */ if (tcp_log_debug == 0) return (NULL); return (tcp_log_addr(inc, th, ip4hdr, ip6hdr)); } static char * tcp_log_addr(struct in_conninfo *inc, struct tcphdr *th, const void *ip4hdr, const void *ip6hdr) { char *s, *sp; size_t size; #ifdef INET const struct ip *ip = (const struct ip *)ip4hdr; #endif #ifdef INET6 const struct ip6_hdr *ip6 = (const struct ip6_hdr *)ip6hdr; #endif /* INET6 */ /* * The log line looks like this: * "TCP: [1.2.3.4]:50332 to [1.2.3.4]:80 tcpflags 0x2" */ size = sizeof("TCP: []:12345 to []:12345 tcpflags 0x2<>") + sizeof(PRINT_TH_FLAGS) + 1 + #ifdef INET6 2 * INET6_ADDRSTRLEN; #else 2 * INET_ADDRSTRLEN; #endif /* INET6 */ s = malloc(size, M_TCPLOG, M_ZERO|M_NOWAIT); if (s == NULL) return (NULL); strcat(s, "TCP: ["); sp = s + strlen(s); if (inc && ((inc->inc_flags & INC_ISIPV6) == 0)) { inet_ntoa_r(inc->inc_faddr, sp); sp = s + strlen(s); sprintf(sp, "]:%i to [", ntohs(inc->inc_fport)); sp = s + strlen(s); inet_ntoa_r(inc->inc_laddr, sp); sp = s + strlen(s); sprintf(sp, "]:%i", ntohs(inc->inc_lport)); #ifdef INET6 } else if (inc) { ip6_sprintf(sp, &inc->inc6_faddr); sp = s + strlen(s); sprintf(sp, "]:%i to [", ntohs(inc->inc_fport)); sp = s + strlen(s); ip6_sprintf(sp, &inc->inc6_laddr); sp = s + strlen(s); sprintf(sp, "]:%i", ntohs(inc->inc_lport)); } else if (ip6 && th) { ip6_sprintf(sp, &ip6->ip6_src); sp = s + strlen(s); sprintf(sp, "]:%i to [", ntohs(th->th_sport)); sp = s + strlen(s); ip6_sprintf(sp, &ip6->ip6_dst); sp = s + strlen(s); sprintf(sp, "]:%i", ntohs(th->th_dport)); #endif /* INET6 */ #ifdef INET } else if (ip && th) { inet_ntoa_r(ip->ip_src, sp); sp = s + strlen(s); sprintf(sp, "]:%i to [", ntohs(th->th_sport)); sp = s + strlen(s); inet_ntoa_r(ip->ip_dst, sp); sp = s + strlen(s); sprintf(sp, "]:%i", ntohs(th->th_dport)); #endif /* INET */ } else { free(s, M_TCPLOG); return (NULL); } sp = s + strlen(s); if (th) sprintf(sp, " tcpflags 0x%b", tcp_get_flags(th), PRINT_TH_FLAGS); if (*(s + size - 1) != '\0') panic("%s: string too long", __func__); return (s); } /* * A subroutine which makes it easy to track TCP state changes with DTrace. * This function shouldn't be called for t_state initializations that don't * correspond to actual TCP state transitions. */ void tcp_state_change(struct tcpcb *tp, int newstate) { #if defined(KDTRACE_HOOKS) int pstate = tp->t_state; #endif TCPSTATES_DEC(tp->t_state); TCPSTATES_INC(newstate); tp->t_state = newstate; TCP_PROBE6(state__change, NULL, tp, NULL, tp, NULL, pstate); } /* * Create an external-format (``xtcpcb'') structure using the information in * the kernel-format tcpcb structure pointed to by tp. This is done to * reduce the spew of irrelevant information over this interface, to isolate * user code from changes in the kernel structure, and potentially to provide * information-hiding if we decide that some of this information should be * hidden from users. */ void tcp_inptoxtp(const struct inpcb *inp, struct xtcpcb *xt) { struct tcpcb *tp = intotcpcb(inp); sbintime_t now; bzero(xt, sizeof(*xt)); xt->t_state = tp->t_state; xt->t_logstate = tp->t_logstate; xt->t_flags = tp->t_flags; xt->t_sndzerowin = tp->t_sndzerowin; xt->t_sndrexmitpack = tp->t_sndrexmitpack; xt->t_rcvoopack = tp->t_rcvoopack; xt->t_rcv_wnd = tp->rcv_wnd; xt->t_snd_wnd = tp->snd_wnd; xt->t_snd_cwnd = tp->snd_cwnd; xt->t_snd_ssthresh = tp->snd_ssthresh; xt->t_dsack_bytes = tp->t_dsack_bytes; xt->t_dsack_tlp_bytes = tp->t_dsack_tlp_bytes; xt->t_dsack_pack = tp->t_dsack_pack; xt->t_maxseg = tp->t_maxseg; xt->xt_ecn = (tp->t_flags2 & TF2_ECN_PERMIT) ? 1 : 0 + (tp->t_flags2 & TF2_ACE_PERMIT) ? 2 : 0; now = getsbinuptime(); #define COPYTIMER(which,where) do { \ if (tp->t_timers[which] != SBT_MAX) \ xt->where = (tp->t_timers[which] - now) / SBT_1MS; \ else \ xt->where = 0; \ } while (0) COPYTIMER(TT_DELACK, tt_delack); COPYTIMER(TT_REXMT, tt_rexmt); COPYTIMER(TT_PERSIST, tt_persist); COPYTIMER(TT_KEEP, tt_keep); COPYTIMER(TT_2MSL, tt_2msl); #undef COPYTIMER xt->t_rcvtime = 1000 * (ticks - tp->t_rcvtime) / hz; xt->xt_encaps_port = tp->t_port; bcopy(tp->t_fb->tfb_tcp_block_name, xt->xt_stack, TCP_FUNCTION_NAME_LEN_MAX); bcopy(CC_ALGO(tp)->name, xt->xt_cc, TCP_CA_NAME_MAX); #ifdef TCP_BLACKBOX (void)tcp_log_get_id(tp, xt->xt_logid); #endif xt->xt_len = sizeof(struct xtcpcb); in_pcbtoxinpcb(inp, &xt->xt_inp); } void tcp_log_end_status(struct tcpcb *tp, uint8_t status) { uint32_t bit, i; if ((tp == NULL) || (status > TCP_EI_STATUS_MAX_VALUE) || (status == 0)) { /* Invalid */ return; } if (status > (sizeof(uint32_t) * 8)) { /* Should this be a KASSERT? */ return; } bit = 1U << (status - 1); if (bit & tp->t_end_info_status) { /* already logged */ return; } for (i = 0; i < TCP_END_BYTE_INFO; i++) { if (tp->t_end_info_bytes[i] == TCP_EI_EMPTY_SLOT) { tp->t_end_info_bytes[i] = status; tp->t_end_info_status |= bit; break; } } } int tcp_can_enable_pacing(void) { if ((tcp_pacing_limit == -1) || (tcp_pacing_limit > number_of_tcp_connections_pacing)) { atomic_fetchadd_int(&number_of_tcp_connections_pacing, 1); shadow_num_connections = number_of_tcp_connections_pacing; return (1); } else { return (0); } } static uint8_t tcp_pacing_warning = 0; void tcp_decrement_paced_conn(void) { uint32_t ret; ret = atomic_fetchadd_int(&number_of_tcp_connections_pacing, -1); shadow_num_connections = number_of_tcp_connections_pacing; KASSERT(ret != 0, ("tcp_paced_connection_exits -1 would cause wrap?")); if (ret == 0) { if (tcp_pacing_limit != -1) { printf("Warning all pacing is now disabled, count decrements invalidly!\n"); tcp_pacing_limit = 0; } else if (tcp_pacing_warning == 0) { printf("Warning pacing count is invalid, invalid decrement\n"); tcp_pacing_warning = 1; } } } diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index 8c94218ec9d9..0186d6a9827a 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -1,915 +1,913 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * @(#)tcp_timer.c 8.2 (Berkeley) 5/24/95 */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" -#include "opt_tcpdebug.h" #include "opt_rss.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef INET6 #include #endif #include #include #include #include #include #include #include #include #ifdef INET6 #include #endif #include -#include int tcp_persmin; SYSCTL_PROC(_net_inet_tcp, OID_AUTO, persmin, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &tcp_persmin, 0, sysctl_msec_to_ticks, "I", "minimum persistence interval"); int tcp_persmax; SYSCTL_PROC(_net_inet_tcp, OID_AUTO, persmax, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &tcp_persmax, 0, sysctl_msec_to_ticks, "I", "maximum persistence interval"); int tcp_keepinit; SYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPINIT, keepinit, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &tcp_keepinit, 0, sysctl_msec_to_ticks, "I", "time to establish connection"); int tcp_keepidle; SYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPIDLE, keepidle, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &tcp_keepidle, 0, sysctl_msec_to_ticks, "I", "time before keepalive probes begin"); int tcp_keepintvl; SYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPINTVL, keepintvl, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &tcp_keepintvl, 0, sysctl_msec_to_ticks, "I", "time between keepalive probes"); int tcp_delacktime; SYSCTL_PROC(_net_inet_tcp, TCPCTL_DELACKTIME, delacktime, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &tcp_delacktime, 0, sysctl_msec_to_ticks, "I", "Time before a delayed ACK is sent"); VNET_DEFINE(int, tcp_msl); SYSCTL_PROC(_net_inet_tcp, OID_AUTO, msl, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_VNET, &VNET_NAME(tcp_msl), 0, sysctl_msec_to_ticks, "I", "Maximum segment lifetime"); int tcp_rexmit_initial; SYSCTL_PROC(_net_inet_tcp, OID_AUTO, rexmit_initial, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &tcp_rexmit_initial, 0, sysctl_msec_to_ticks, "I", "Initial Retransmission Timeout"); int tcp_rexmit_min; SYSCTL_PROC(_net_inet_tcp, OID_AUTO, rexmit_min, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &tcp_rexmit_min, 0, sysctl_msec_to_ticks, "I", "Minimum Retransmission Timeout"); int tcp_rexmit_slop; SYSCTL_PROC(_net_inet_tcp, OID_AUTO, rexmit_slop, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &tcp_rexmit_slop, 0, sysctl_msec_to_ticks, "I", "Retransmission Timer Slop"); VNET_DEFINE(int, tcp_always_keepalive) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, always_keepalive, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(tcp_always_keepalive) , 0, "Assume SO_KEEPALIVE on all TCP connections"); int tcp_fast_finwait2_recycle = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, fast_finwait2_recycle, CTLFLAG_RW, &tcp_fast_finwait2_recycle, 0, "Recycle closed FIN_WAIT_2 connections faster"); int tcp_finwait2_timeout; SYSCTL_PROC(_net_inet_tcp, OID_AUTO, finwait2_timeout, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &tcp_finwait2_timeout, 0, sysctl_msec_to_ticks, "I", "FIN-WAIT2 timeout"); int tcp_keepcnt = TCPTV_KEEPCNT; SYSCTL_INT(_net_inet_tcp, OID_AUTO, keepcnt, CTLFLAG_RW, &tcp_keepcnt, 0, "Number of keepalive probes to send"); /* max idle probes */ int tcp_maxpersistidle; int tcp_rexmit_drop_options = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, rexmit_drop_options, CTLFLAG_RW, &tcp_rexmit_drop_options, 0, "Drop TCP options from 3rd and later retransmitted SYN"); int tcp_maxunacktime = TCPTV_MAXUNACKTIME; SYSCTL_PROC(_net_inet_tcp, OID_AUTO, maxunacktime, CTLTYPE_INT|CTLFLAG_RW | CTLFLAG_NEEDGIANT, &tcp_maxunacktime, 0, sysctl_msec_to_ticks, "I", "Maximum time (in ms) that a session can linger without making progress"); VNET_DEFINE(int, tcp_pmtud_blackhole_detect); SYSCTL_INT(_net_inet_tcp, OID_AUTO, pmtud_blackhole_detection, CTLFLAG_RW|CTLFLAG_VNET, &VNET_NAME(tcp_pmtud_blackhole_detect), 0, "Path MTU Discovery Black Hole Detection Enabled"); #ifdef INET VNET_DEFINE(int, tcp_pmtud_blackhole_mss) = 1200; SYSCTL_INT(_net_inet_tcp, OID_AUTO, pmtud_blackhole_mss, CTLFLAG_RW|CTLFLAG_VNET, &VNET_NAME(tcp_pmtud_blackhole_mss), 0, "Path MTU Discovery Black Hole Detection lowered MSS"); #endif #ifdef INET6 VNET_DEFINE(int, tcp_v6pmtud_blackhole_mss) = 1220; SYSCTL_INT(_net_inet_tcp, OID_AUTO, v6pmtud_blackhole_mss, CTLFLAG_RW|CTLFLAG_VNET, &VNET_NAME(tcp_v6pmtud_blackhole_mss), 0, "Path MTU Discovery IPv6 Black Hole Detection lowered MSS"); #endif #ifdef RSS static int per_cpu_timers = 1; #else static int per_cpu_timers = 0; #endif SYSCTL_INT(_net_inet_tcp, OID_AUTO, per_cpu_timers, CTLFLAG_RW, &per_cpu_timers , 0, "run tcp timers on all cpus"); /* * Map the given inp to a CPU id. * * This queries RSS if it's compiled in, else it defaults to the current * CPU ID. */ inline int inp_to_cpuid(struct inpcb *inp) { u_int cpuid; if (per_cpu_timers) { #ifdef RSS cpuid = rss_hash2cpuid(inp->inp_flowid, inp->inp_flowtype); if (cpuid == NETISR_CPUID_NONE) return (curcpu); /* XXX */ else return (cpuid); #endif /* * We don't have a flowid -> cpuid mapping, so cheat and * just map unknown cpuids to curcpu. Not the best, but * apparently better than defaulting to swi 0. */ cpuid = inp->inp_flowid % (mp_maxid + 1); if (! CPU_ABSENT(cpuid)) return (cpuid); return (curcpu); } else { return (0); } } int tcp_backoff[TCP_MAXRXTSHIFT + 1] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 512, 512, 512 }; int tcp_totbackoff = 2559; /* sum of tcp_backoff[] */ /* * TCP timer processing. * * Each connection has 5 timers associated with it, which can be scheduled * simultaneously. They all are serviced by one callout tcp_timer_enter(). * This function executes the next timer via tcp_timersw[] vector. Each * timer is supposed to return 'true' unless the connection was destroyed. * In the former case tcp_timer_enter() will schedule callout for next timer. */ typedef bool tcp_timer_t(struct tcpcb *); static tcp_timer_t tcp_timer_delack; static tcp_timer_t tcp_timer_2msl; static tcp_timer_t tcp_timer_keep; static tcp_timer_t tcp_timer_persist; static tcp_timer_t tcp_timer_rexmt; static tcp_timer_t * const tcp_timersw[TT_N] = { [TT_DELACK] = tcp_timer_delack, [TT_REXMT] = tcp_timer_rexmt, [TT_PERSIST] = tcp_timer_persist, [TT_KEEP] = tcp_timer_keep, [TT_2MSL] = tcp_timer_2msl, }; /* * tcp_output_locked() s a timer specific variation of call to tcp_output(), * see tcp_var.h for the rest. It handles drop request from advanced stacks, * but keeps tcpcb locked unless tcp_drop() destroyed it. * Returns true if tcpcb is valid and locked. */ static inline bool tcp_output_locked(struct tcpcb *tp) { int rv; INP_WLOCK_ASSERT(tptoinpcb(tp)); if ((rv = tp->t_fb->tfb_tcp_output(tp)) < 0) { KASSERT(tp->t_fb->tfb_flags & TCP_FUNC_OUTPUT_CANDROP, ("TCP stack %s requested tcp_drop(%p)", tp->t_fb->tfb_tcp_block_name, tp)); tp = tcp_drop(tp, rv); } return (tp != NULL); } static bool tcp_timer_delack(struct tcpcb *tp) { struct epoch_tracker et; #if defined(INVARIANTS) || defined(VIMAGE) struct inpcb *inp = tptoinpcb(tp); #endif bool rv; INP_WLOCK_ASSERT(inp); CURVNET_SET(inp->inp_vnet); tp->t_flags |= TF_ACKNOW; TCPSTAT_INC(tcps_delack); NET_EPOCH_ENTER(et); rv = tcp_output_locked(tp); NET_EPOCH_EXIT(et); CURVNET_RESTORE(); return (rv); } static bool tcp_timer_2msl(struct tcpcb *tp) { struct inpcb *inp = tptoinpcb(tp); bool close = false; INP_WLOCK_ASSERT(inp); TCP_PROBE2(debug__user, tp, PRU_SLOWTIMO); CURVNET_SET(inp->inp_vnet); tcp_log_end_status(tp, TCP_EI_STATUS_2MSL); tcp_free_sackholes(tp); /* * 2 MSL timeout in shutdown went off. If we're closed but * still waiting for peer to close and connection has been idle * too long delete connection control block. Otherwise, check * again in a bit. * * If fastrecycle of FIN_WAIT_2, in FIN_WAIT_2 and receiver has closed, * there's no point in hanging onto FIN_WAIT_2 socket. Just close it. * Ignore fact that there were recent incoming segments. * * XXXGL: check if inp_socket shall always be !NULL here? */ if (tp->t_state == TCPS_TIME_WAIT) { close = true; } else if (tp->t_state == TCPS_FIN_WAIT_2 && tcp_fast_finwait2_recycle && inp->inp_socket && (inp->inp_socket->so_rcv.sb_state & SBS_CANTRCVMORE)) { TCPSTAT_INC(tcps_finwait2_drops); close = true; } else { if (ticks - tp->t_rcvtime <= TP_MAXIDLE(tp)) tcp_timer_activate(tp, TT_2MSL, TP_KEEPINTVL(tp)); else close = true; } if (close) { struct epoch_tracker et; NET_EPOCH_ENTER(et); tp = tcp_close(tp); NET_EPOCH_EXIT(et); } CURVNET_RESTORE(); return (tp != NULL); } static bool tcp_timer_keep(struct tcpcb *tp) { struct epoch_tracker et; struct inpcb *inp = tptoinpcb(tp); struct tcptemp *t_template; INP_WLOCK_ASSERT(inp); TCP_PROBE2(debug__user, tp, PRU_SLOWTIMO); CURVNET_SET(inp->inp_vnet); /* * Because we don't regularly reset the keepalive callout in * the ESTABLISHED state, it may be that we don't actually need * to send a keepalive yet. If that occurs, schedule another * call for the next time the keepalive timer might expire. */ if (TCPS_HAVEESTABLISHED(tp->t_state)) { u_int idletime; idletime = ticks - tp->t_rcvtime; if (idletime < TP_KEEPIDLE(tp)) { tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp) - idletime); CURVNET_RESTORE(); return (true); } } /* * Keep-alive timer went off; send something * or drop connection if idle for too long. */ TCPSTAT_INC(tcps_keeptimeo); if (tp->t_state < TCPS_ESTABLISHED) goto dropit; if ((V_tcp_always_keepalive || inp->inp_socket->so_options & SO_KEEPALIVE) && tp->t_state <= TCPS_CLOSING) { if (ticks - tp->t_rcvtime >= TP_KEEPIDLE(tp) + TP_MAXIDLE(tp)) goto dropit; /* * Send a packet designed to force a response * if the peer is up and reachable: * either an ACK if the connection is still alive, * or an RST if the peer has closed the connection * due to timeout or reboot. * Using sequence number tp->snd_una-1 * causes the transmitted zero-length segment * to lie outside the receive window; * by the protocol spec, this requires the * correspondent TCP to respond. */ TCPSTAT_INC(tcps_keepprobe); t_template = tcpip_maketemplate(inp); if (t_template) { NET_EPOCH_ENTER(et); tcp_respond(tp, t_template->tt_ipgen, &t_template->tt_t, (struct mbuf *)NULL, tp->rcv_nxt, tp->snd_una - 1, 0); NET_EPOCH_EXIT(et); free(t_template, M_TEMP); } tcp_timer_activate(tp, TT_KEEP, TP_KEEPINTVL(tp)); } else tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp)); CURVNET_RESTORE(); return (true); dropit: TCPSTAT_INC(tcps_keepdrops); NET_EPOCH_ENTER(et); tcp_log_end_status(tp, TCP_EI_STATUS_KEEP_MAX); tp = tcp_drop(tp, ETIMEDOUT); NET_EPOCH_EXIT(et); CURVNET_RESTORE(); return (tp != NULL); } /* * Has this session exceeded the maximum time without seeing a substantive * acknowledgement? If so, return true; otherwise false. */ static bool tcp_maxunacktime_check(struct tcpcb *tp) { /* Are we tracking this timer for this session? */ if (TP_MAXUNACKTIME(tp) == 0) return false; /* Do we have a current measurement. */ if (tp->t_acktime == 0) return false; /* Are we within the acceptable range? */ if (TSTMP_GT(TP_MAXUNACKTIME(tp) + tp->t_acktime, (u_int)ticks)) return false; /* We exceeded the timer. */ TCPSTAT_INC(tcps_progdrops); return true; } static bool tcp_timer_persist(struct tcpcb *tp) { struct epoch_tracker et; #if defined(INVARIANTS) || defined(VIMAGE) struct inpcb *inp = tptoinpcb(tp); #endif bool progdrop, rv; INP_WLOCK_ASSERT(inp); TCP_PROBE2(debug__user, tp, PRU_SLOWTIMO); CURVNET_SET(inp->inp_vnet); /* * Persistence timer into zero window. * Force a byte to be output, if possible. */ TCPSTAT_INC(tcps_persisttimeo); /* * Hack: if the peer is dead/unreachable, we do not * time out if the window is closed. After a full * backoff, drop the connection if the idle time * (no responses to probes) reaches the maximum * backoff that we would use if retransmitting. * Also, drop the connection if we haven't been making * progress. */ progdrop = tcp_maxunacktime_check(tp); if (progdrop || (tp->t_rxtshift == TCP_MAXRXTSHIFT && (ticks - tp->t_rcvtime >= tcp_maxpersistidle || ticks - tp->t_rcvtime >= TCP_REXMTVAL(tp) * tcp_totbackoff))) { if (!progdrop) TCPSTAT_INC(tcps_persistdrop); tcp_log_end_status(tp, TCP_EI_STATUS_PERSIST_MAX); goto dropit; } /* * If the user has closed the socket then drop a persisting * connection after a much reduced timeout. */ if (tp->t_state > TCPS_CLOSE_WAIT && (ticks - tp->t_rcvtime) >= TCPTV_PERSMAX) { TCPSTAT_INC(tcps_persistdrop); tcp_log_end_status(tp, TCP_EI_STATUS_PERSIST_MAX); goto dropit; } tcp_setpersist(tp); tp->t_flags |= TF_FORCEDATA; NET_EPOCH_ENTER(et); if ((rv = tcp_output_locked(tp))) tp->t_flags &= ~TF_FORCEDATA; NET_EPOCH_EXIT(et); CURVNET_RESTORE(); return (rv); dropit: NET_EPOCH_ENTER(et); tp = tcp_drop(tp, ETIMEDOUT); NET_EPOCH_EXIT(et); CURVNET_RESTORE(); return (tp != NULL); } static bool tcp_timer_rexmt(struct tcpcb *tp) { struct epoch_tracker et; struct inpcb *inp = tptoinpcb(tp); int rexmt; bool isipv6, rv; INP_WLOCK_ASSERT(inp); TCP_PROBE2(debug__user, tp, PRU_SLOWTIMO); CURVNET_SET(inp->inp_vnet); tcp_free_sackholes(tp); TCP_LOG_EVENT(tp, NULL, NULL, NULL, TCP_LOG_RTO, 0, 0, NULL, false); if (tp->t_fb->tfb_tcp_rexmit_tmr) { /* The stack has a timer action too. */ (*tp->t_fb->tfb_tcp_rexmit_tmr)(tp); } /* * Retransmission timer went off. Message has not * been acked within retransmit interval. Back off * to a longer retransmit interval and retransmit one segment. * * If we've either exceeded the maximum number of retransmissions, * or we've gone long enough without making progress, then drop * the session. */ if (++tp->t_rxtshift > TCP_MAXRXTSHIFT || tcp_maxunacktime_check(tp)) { if (tp->t_rxtshift > TCP_MAXRXTSHIFT) TCPSTAT_INC(tcps_timeoutdrop); tp->t_rxtshift = TCP_MAXRXTSHIFT; tcp_log_end_status(tp, TCP_EI_STATUS_RETRAN); NET_EPOCH_ENTER(et); tp = tcp_drop(tp, ETIMEDOUT); NET_EPOCH_EXIT(et); CURVNET_RESTORE(); return (tp != NULL); } if (tp->t_state == TCPS_SYN_SENT) { /* * If the SYN was retransmitted, indicate CWND to be * limited to 1 segment in cc_conn_init(). */ tp->snd_cwnd = 1; } else if (tp->t_rxtshift == 1) { /* * first retransmit; record ssthresh and cwnd so they can * be recovered if this turns out to be a "bad" retransmit. * A retransmit is considered "bad" if an ACK for this * segment is received within RTT/2 interval; the assumption * here is that the ACK was already in flight. See * "On Estimating End-to-End Network Path Properties" by * Allman and Paxson for more details. */ tp->snd_cwnd_prev = tp->snd_cwnd; tp->snd_ssthresh_prev = tp->snd_ssthresh; tp->snd_recover_prev = tp->snd_recover; if (IN_FASTRECOVERY(tp->t_flags)) tp->t_flags |= TF_WASFRECOVERY; else tp->t_flags &= ~TF_WASFRECOVERY; if (IN_CONGRECOVERY(tp->t_flags)) tp->t_flags |= TF_WASCRECOVERY; else tp->t_flags &= ~TF_WASCRECOVERY; if ((tp->t_flags & TF_RCVD_TSTMP) == 0) tp->t_badrxtwin = ticks + (tp->t_srtt >> (TCP_RTT_SHIFT + 1)); /* In the event that we've negotiated timestamps * badrxtwin will be set to the value that we set * the retransmitted packet's to_tsval to by tcp_output */ tp->t_flags |= TF_PREVVALID; } else tp->t_flags &= ~TF_PREVVALID; TCPSTAT_INC(tcps_rexmttimeo); if ((tp->t_state == TCPS_SYN_SENT) || (tp->t_state == TCPS_SYN_RECEIVED)) rexmt = tcp_rexmit_initial * tcp_backoff[tp->t_rxtshift]; else rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift]; TCPT_RANGESET(tp->t_rxtcur, rexmt, tp->t_rttmin, TCPTV_REXMTMAX); /* * We enter the path for PLMTUD if connection is established or, if * connection is FIN_WAIT_1 status, reason for the last is that if * amount of data we send is very small, we could send it in couple of * packets and process straight to FIN. In that case we won't catch * ESTABLISHED state. */ #ifdef INET6 isipv6 = (inp->inp_vflag & INP_IPV6) ? true : false; #else isipv6 = false; #endif if (((V_tcp_pmtud_blackhole_detect == 1) || (V_tcp_pmtud_blackhole_detect == 2 && !isipv6) || (V_tcp_pmtud_blackhole_detect == 3 && isipv6)) && ((tp->t_state == TCPS_ESTABLISHED) || (tp->t_state == TCPS_FIN_WAIT_1))) { if (tp->t_rxtshift == 1) { /* * We enter blackhole detection after the first * unsuccessful timer based retransmission. * Then we reduce up to two times the MSS, each * candidate giving two tries of retransmissions. * But we give a candidate only two tries, if it * actually reduces the MSS. */ tp->t_blackhole_enter = 2; tp->t_blackhole_exit = tp->t_blackhole_enter; if (isipv6) { #ifdef INET6 if (tp->t_maxseg > V_tcp_v6pmtud_blackhole_mss) tp->t_blackhole_exit += 2; if (tp->t_maxseg > V_tcp_v6mssdflt && V_tcp_v6pmtud_blackhole_mss > V_tcp_v6mssdflt) tp->t_blackhole_exit += 2; #endif } else { #ifdef INET if (tp->t_maxseg > V_tcp_pmtud_blackhole_mss) tp->t_blackhole_exit += 2; if (tp->t_maxseg > V_tcp_mssdflt && V_tcp_pmtud_blackhole_mss > V_tcp_mssdflt) tp->t_blackhole_exit += 2; #endif } } if (((tp->t_flags2 & (TF2_PLPMTU_PMTUD|TF2_PLPMTU_MAXSEGSNT)) == (TF2_PLPMTU_PMTUD|TF2_PLPMTU_MAXSEGSNT)) && (tp->t_rxtshift >= tp->t_blackhole_enter && tp->t_rxtshift < tp->t_blackhole_exit && (tp->t_rxtshift - tp->t_blackhole_enter) % 2 == 0)) { /* * Enter Path MTU Black-hole Detection mechanism: * - Disable Path MTU Discovery (IP "DF" bit). * - Reduce MTU to lower value than what we * negotiated with peer. */ if ((tp->t_flags2 & TF2_PLPMTU_BLACKHOLE) == 0) { /* Record that we may have found a black hole. */ tp->t_flags2 |= TF2_PLPMTU_BLACKHOLE; /* Keep track of previous MSS. */ tp->t_pmtud_saved_maxseg = tp->t_maxseg; } /* * Reduce the MSS to blackhole value or to the default * in an attempt to retransmit. */ #ifdef INET6 if (isipv6 && tp->t_maxseg > V_tcp_v6pmtud_blackhole_mss && V_tcp_v6pmtud_blackhole_mss > V_tcp_v6mssdflt) { /* Use the sysctl tuneable blackhole MSS. */ tp->t_maxseg = V_tcp_v6pmtud_blackhole_mss; TCPSTAT_INC(tcps_pmtud_blackhole_activated); } else if (isipv6) { /* Use the default MSS. */ tp->t_maxseg = V_tcp_v6mssdflt; /* * Disable Path MTU Discovery when we switch to * minmss. */ tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; TCPSTAT_INC(tcps_pmtud_blackhole_activated_min_mss); } #endif #if defined(INET6) && defined(INET) else #endif #ifdef INET if (tp->t_maxseg > V_tcp_pmtud_blackhole_mss && V_tcp_pmtud_blackhole_mss > V_tcp_mssdflt) { /* Use the sysctl tuneable blackhole MSS. */ tp->t_maxseg = V_tcp_pmtud_blackhole_mss; TCPSTAT_INC(tcps_pmtud_blackhole_activated); } else { /* Use the default MSS. */ tp->t_maxseg = V_tcp_mssdflt; /* * Disable Path MTU Discovery when we switch to * minmss. */ tp->t_flags2 &= ~TF2_PLPMTU_PMTUD; TCPSTAT_INC(tcps_pmtud_blackhole_activated_min_mss); } #endif /* * Reset the slow-start flight size * as it may depend on the new MSS. */ if (CC_ALGO(tp)->conn_init != NULL) CC_ALGO(tp)->conn_init(&tp->t_ccv); } else { /* * If further retransmissions are still unsuccessful * with a lowered MTU, maybe this isn't a blackhole and * we restore the previous MSS and blackhole detection * flags. */ if ((tp->t_flags2 & TF2_PLPMTU_BLACKHOLE) && (tp->t_rxtshift >= tp->t_blackhole_exit)) { tp->t_flags2 |= TF2_PLPMTU_PMTUD; tp->t_flags2 &= ~TF2_PLPMTU_BLACKHOLE; tp->t_maxseg = tp->t_pmtud_saved_maxseg; TCPSTAT_INC(tcps_pmtud_blackhole_failed); /* * Reset the slow-start flight size as it * may depend on the new MSS. */ if (CC_ALGO(tp)->conn_init != NULL) CC_ALGO(tp)->conn_init(&tp->t_ccv); } } } /* * Disable RFC1323 and SACK if we haven't got any response to * our third SYN to work-around some broken terminal servers * (most of which have hopefully been retired) that have bad VJ * header compression code which trashes TCP segments containing * unknown-to-them TCP options. */ if (tcp_rexmit_drop_options && (tp->t_state == TCPS_SYN_SENT) && (tp->t_rxtshift == 3)) tp->t_flags &= ~(TF_REQ_SCALE|TF_REQ_TSTMP|TF_SACK_PERMIT); /* * If we backed off this far, notify the L3 protocol that we're having * connection problems. */ if (tp->t_rxtshift > TCP_RTT_INVALIDATE) { #ifdef INET6 if ((inp->inp_vflag & INP_IPV6) != 0) in6_losing(inp); else #endif in_losing(inp); } tp->snd_nxt = tp->snd_una; tp->snd_recover = tp->snd_max; /* * Force a segment to be sent. */ tp->t_flags |= TF_ACKNOW; /* * If timing a segment in this window, stop the timer. */ tp->t_rtttime = 0; cc_cong_signal(tp, NULL, CC_RTO); NET_EPOCH_ENTER(et); rv = tcp_output_locked(tp); NET_EPOCH_EXIT(et); CURVNET_RESTORE(); return (rv); } static inline tt_which tcp_timer_next(struct tcpcb *tp, sbintime_t *precision) { tt_which i, rv; sbintime_t after, before; for (i = 0, rv = TT_N, after = before = SBT_MAX; i < TT_N; i++) { if (tp->t_timers[i] < after) { after = tp->t_timers[i]; rv = i; } before = MIN(before, tp->t_timers[i] + tp->t_precisions[i]); } if (precision != NULL) *precision = before - after; return (rv); } static void tcp_timer_enter(void *xtp) { struct tcpcb *tp = xtp; struct inpcb *inp = tptoinpcb(tp); sbintime_t precision; tt_which which; INP_WLOCK_ASSERT(inp); MPASS((curthread->td_pflags & TDP_INTCPCALLOUT) == 0); curthread->td_pflags |= TDP_INTCPCALLOUT; which = tcp_timer_next(tp, NULL); MPASS(which < TT_N); tp->t_timers[which] = SBT_MAX; tp->t_precisions[which] = 0; if (tcp_timersw[which](tp)) { if ((which = tcp_timer_next(tp, &precision)) != TT_N) { callout_reset_sbt_on(&tp->t_callout, tp->t_timers[which], precision, tcp_timer_enter, tp, inp_to_cpuid(inp), C_ABSOLUTE); } INP_WUNLOCK(inp); } curthread->td_pflags &= ~TDP_INTCPCALLOUT; } /* * Activate or stop (delta == 0) a TCP timer. */ void tcp_timer_activate(struct tcpcb *tp, tt_which which, u_int delta) { struct inpcb *inp = tptoinpcb(tp); sbintime_t precision; #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) return; #endif INP_WLOCK_ASSERT(inp); if (delta > 0) callout_when(tick_sbt * delta, 0, C_HARDCLOCK, &tp->t_timers[which], &tp->t_precisions[which]); else tp->t_timers[which] = SBT_MAX; if ((which = tcp_timer_next(tp, &precision)) != TT_N) callout_reset_sbt_on(&tp->t_callout, tp->t_timers[which], precision, tcp_timer_enter, tp, inp_to_cpuid(inp), C_ABSOLUTE); else callout_stop(&tp->t_callout); } bool tcp_timer_active(struct tcpcb *tp, tt_which which) { INP_WLOCK_ASSERT(tptoinpcb(tp)); return (tp->t_timers[which] != SBT_MAX); } /* * Stop all timers associated with tcpcb. * * Called only on tcpcb destruction. The tcpcb shall already be dropped from * the pcb lookup database and socket is not losing the last reference. * * XXXGL: unfortunately our callout(9) is not able to fully stop a locked * callout even when only two threads are involved: the callout itself and the * thread that does callout_stop(). See where softclock_call_cc() swaps the * callwheel lock to callout lock and then checks cc_exec_cancel(). This is * the race window. If it happens, the tcp_timer_enter() won't be executed, * however pcb lock will be locked and released, hence we can't free memory. * Until callout(9) is improved, just keep retrying. In my profiling I've seen * such event happening less than 1 time per hour with 20-30 Gbit/s of traffic. */ void tcp_timer_stop(struct tcpcb *tp) { struct inpcb *inp = tptoinpcb(tp); INP_WLOCK_ASSERT(inp); if (curthread->td_pflags & TDP_INTCPCALLOUT) { int stopped __diagused; stopped = callout_stop(&tp->t_callout); MPASS(stopped == 0); } else while(__predict_false(callout_stop(&tp->t_callout) == 0)) { INP_WUNLOCK(inp); kern_yield(PRI_UNCHANGED); INP_WLOCK(inp); } } diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index fb77a2e0d628..124a254cae3d 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -1,314 +1,310 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * @(#)tcp_subr.c 8.2 (Berkeley) 5/24/95 */ #include __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" -#include "opt_tcpdebug.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef INET6 #include #include #include #include #include #endif #include #include #include #include #include #include #include -#ifdef TCPDEBUG -#include -#endif #include #include #include #include #include VNET_DEFINE_STATIC(bool, nolocaltimewait) = true; #define V_nolocaltimewait VNET(nolocaltimewait) SYSCTL_BOOL(_net_inet_tcp, OID_AUTO, nolocaltimewait, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nolocaltimewait), true, "Do not create TCP TIME_WAIT state for local connections"); /* * Move a TCP connection into TIME_WAIT state. * inp is locked, and is unlocked before returning. * * This function used to free tcpcb and allocate a compressed TCP time-wait * structure tcptw. This served well for 20 years but is no longer relevant * on modern machines in the modern internet. However, the function remains * so that TCP stacks require less modification and we don't burn the bridge * to go back to using compressed time-wait. */ void tcp_twstart(struct tcpcb *tp) { struct inpcb *inp = tptoinpcb(tp); #ifdef INET6 bool isipv6 = inp->inp_inc.inc_flags & INC_ISIPV6; #endif NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(inp); /* A dropped inp should never transition to TIME_WAIT state. */ KASSERT((inp->inp_flags & INP_DROPPED) == 0, ("tcp_twstart: " "(inp->inp_flags & INP_DROPPED) != 0")); tcp_state_change(tp, TCPS_TIME_WAIT); soisdisconnected(inp->inp_socket); if (tp->t_flags & TF_ACKNOW) tcp_output(tp); if (V_nolocaltimewait && ( #ifdef INET6 isipv6 ? in6_localaddr(&inp->in6p_faddr) : #endif #ifdef INET in_localip(inp->inp_faddr) #else false #endif )) { if ((tp = tcp_close(tp)) != NULL) INP_WUNLOCK(inp); return; } tcp_timer_activate(tp, TT_2MSL, 2 * V_tcp_msl); INP_WUNLOCK(inp); } /* * Returns true if the TIME_WAIT state was killed and we should start over, * looking for a pcb in the listen state. Otherwise returns false and frees * the mbuf. * * For pure SYN-segments the PCB shall be read-locked and the tcpopt pointer * may be NULL. For the rest write-lock and valid tcpopt. */ bool tcp_twcheck(struct inpcb *inp, struct tcpopt *to, struct tcphdr *th, struct mbuf *m, int tlen) { struct tcpcb *tp = intotcpcb(inp); char *s; int thflags; tcp_seq seq; NET_EPOCH_ASSERT(); INP_LOCK_ASSERT(inp); thflags = tcp_get_flags(th); #ifdef INVARIANTS if ((thflags & (TH_SYN | TH_ACK)) == TH_SYN) INP_RLOCK_ASSERT(inp); else { INP_WLOCK_ASSERT(inp); KASSERT(to != NULL, ("%s: called without options on a non-SYN segment", __func__)); } #endif /* * NOTE: for FIN_WAIT_2 (to be added later), * must validate sequence number before accepting RST */ /* * If the segment contains RST: * Drop the segment - see Stevens, vol. 2, p. 964 and * RFC 1337. */ if (thflags & TH_RST) goto drop; #if 0 /* PAWS not needed at the moment */ /* * RFC 1323 PAWS: If we have a timestamp reply on this segment * and it's less than ts_recent, drop it. */ if ((to.to_flags & TOF_TS) != 0 && tp->ts_recent && TSTMP_LT(to.to_tsval, tp->ts_recent)) { if ((thflags & TH_ACK) == 0) goto drop; goto ack; } /* * ts_recent is never updated because we never accept new segments. */ #endif /* Honor the drop_synfin sysctl variable. */ if ((thflags & TH_SYN) && (thflags & TH_FIN) && V_drop_synfin) { if ((s = tcp_log_addrs(&inp->inp_inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: " "SYN|FIN segment ignored (based on " "sysctl setting)\n", s, __func__); free(s, M_TCPLOG); } goto drop; } /* * If a new connection request is received * while in TIME_WAIT, drop the old connection * and start over if the sequence numbers * are above the previous ones. * Allow UDP port number changes in this case. */ if (((thflags & (TH_SYN | TH_ACK)) == TH_SYN) && SEQ_GT(th->th_seq, tp->rcv_nxt)) { /* * In case we can't upgrade our lock just pretend we have * lost this packet. */ if (INP_TRY_UPGRADE(inp) == 0) goto drop; if ((tp = tcp_close(tp)) != NULL) INP_WUNLOCK(inp); TCPSTAT_INC(tcps_tw_recycles); return (true); } /* * Send RST if UDP port numbers don't match */ if (tp->t_port != m->m_pkthdr.tcp_tun_port) { if (tcp_get_flags(th) & TH_ACK) { tcp_respond(tp, mtod(m, void *), th, m, (tcp_seq)0, th->th_ack, TH_RST); } else { if (tcp_get_flags(th) & TH_SYN) tlen++; if (tcp_get_flags(th) & TH_FIN) tlen++; tcp_respond(tp, mtod(m, void *), th, m, th->th_seq+tlen, (tcp_seq)0, TH_RST|TH_ACK); } INP_UNLOCK(inp); TCPSTAT_INC(tcps_tw_resets); return (false); } /* * Drop the segment if it does not contain an ACK. */ if ((thflags & TH_ACK) == 0) goto drop; INP_WLOCK_ASSERT(inp); /* * If timestamps were negotiated during SYN/ACK and a * segment without a timestamp is received, silently drop * the segment, unless the missing timestamps are tolerated. * See section 3.2 of RFC 7323. */ if (((to->to_flags & TOF_TS) == 0) && (tp->ts_recent != 0) && (V_tcp_tolerate_missing_ts == 0)) { goto drop; } /* * Reset the 2MSL timer if this is a duplicate FIN. */ if (thflags & TH_FIN) { seq = th->th_seq + tlen + (thflags & TH_SYN ? 1 : 0); if (seq + 1 == tp->rcv_nxt) tcp_timer_activate(tp, TT_2MSL, 2 * V_tcp_msl); } /* * Acknowledge the segment if it has data or is not a duplicate ACK. */ if (thflags != TH_ACK || tlen != 0 || th->th_seq != tp->rcv_nxt || th->th_ack != tp->snd_nxt) { TCP_PROBE5(receive, NULL, NULL, m, NULL, th); tcp_respond(tp, mtod(m, void *), th, m, tp->rcv_nxt, tp->snd_nxt, TH_ACK); INP_UNLOCK(inp); TCPSTAT_INC(tcps_tw_responds); return (false); } drop: TCP_PROBE5(receive, NULL, NULL, m, NULL, th); INP_UNLOCK(inp); m_freem(m); return (false); } diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 327f0b1d2f0f..61c077ea66c6 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1,3186 +1,3123 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1982, 1986, 1988, 1993 * The Regents of the University of California. * Copyright (c) 2006-2007 Robert N. M. Watson * Copyright (c) 2010-2011 Juniper Networks, Inc. * All rights reserved. * * Portions of this software were developed by Robert N. M. Watson under * contract to Juniper Networks, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94 */ #include __FBSDID("$FreeBSD$"); #include "opt_ddb.h" #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" #include "opt_kern_tls.h" -#include "opt_tcpdebug.h" #include #include #include #include #include #include #include #include #include #include #include #ifdef INET6 #include #endif /* INET6 */ #include #include #include #include #include #include #ifdef DDB #include #endif #include #include #include #include #include #include #include #include #include #include #include #ifdef INET6 #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #ifdef TCPPCAP #include #endif -#include #ifdef TCP_OFFLOAD #include #endif #include #include #include #include #include #include #include /* * TCP protocol interface to socket abstraction. */ #ifdef INET static int tcp_connect(struct tcpcb *, struct sockaddr *, struct thread *td); #endif /* INET */ #ifdef INET6 static int tcp6_connect(struct tcpcb *, struct sockaddr *, struct thread *td); #endif /* INET6 */ static void tcp_disconnect(struct tcpcb *); static void tcp_usrclosed(struct tcpcb *); static void tcp_fill_info(struct tcpcb *, struct tcp_info *); static int tcp_pru_options_support(struct tcpcb *tp, int flags); -#ifdef TCPDEBUG -#define TCPDEBUG0 int ostate = 0 -#define TCPDEBUG1() ostate = tp ? tp->t_state : 0 -#define TCPDEBUG2(req) if (tp && (so->so_options & SO_DEBUG)) \ - tcp_trace(TA_USER, ostate, tp, 0, 0, req) -#else -#define TCPDEBUG0 -#define TCPDEBUG1() -#define TCPDEBUG2(req) -#endif - /* * tcp_require_unique port requires a globally-unique source port for each * outgoing connection. The default is to require the 4-tuple to be unique. */ VNET_DEFINE(int, tcp_require_unique_port) = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, require_unique_port, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_require_unique_port), 0, "Require globally-unique ephemeral port for outgoing connections"); #define V_tcp_require_unique_port VNET(tcp_require_unique_port) /* * TCP attaches to socket via pru_attach(), reserving space, * and an internet control block. */ static int tcp_usr_attach(struct socket *so, int proto, struct thread *td) { struct inpcb *inp; struct tcpcb *tp = NULL; int error; - TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp == NULL, ("tcp_usr_attach: inp != NULL")); - TCPDEBUG1(); error = soreserve(so, V_tcp_sendspace, V_tcp_recvspace); if (error) goto out; so->so_rcv.sb_flags |= SB_AUTOSIZE; so->so_snd.sb_flags |= SB_AUTOSIZE; error = in_pcballoc(so, &V_tcbinfo); if (error) goto out; inp = sotoinpcb(so); tp = tcp_newtcpcb(inp); if (tp == NULL) { error = ENOBUFS; in_pcbdetach(inp); in_pcbfree(inp); goto out; } tp->t_state = TCPS_CLOSED; INP_WUNLOCK(inp); TCPSTATES_INC(TCPS_CLOSED); out: - TCPDEBUG2(PRU_ATTACH); TCP_PROBE2(debug__user, tp, PRU_ATTACH); return (error); } /* * tcp_usr_detach is called when the socket layer loses its final reference * to the socket, be it a file descriptor reference, a reference from TCP, * etc. At this point, there is only one case in which we will keep around * inpcb state: time wait. */ static void tcp_usr_detach(struct socket *so) { struct inpcb *inp; struct tcpcb *tp; inp = sotoinpcb(so); KASSERT(inp != NULL, ("%s: inp == NULL", __func__)); INP_WLOCK(inp); KASSERT(so->so_pcb == inp && inp->inp_socket == so, ("%s: socket %p inp %p mismatch", __func__, so, inp)); tp = intotcpcb(inp); KASSERT(inp->inp_flags & INP_DROPPED || tp->t_state < TCPS_SYN_SENT, ("%s: inp %p not dropped or embryonic", __func__, inp)); tcp_discardcb(tp); in_pcbdetach(inp); in_pcbfree(inp); } #ifdef INET /* * Give the socket an address. */ static int tcp_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td) { int error = 0; struct inpcb *inp; #ifdef KDTRACE_HOOKS struct tcpcb *tp = NULL; #endif struct sockaddr_in *sinp; sinp = (struct sockaddr_in *)nam; if (nam->sa_family != AF_INET) { /* * Preserve compatibility with old programs. */ if (nam->sa_family != AF_UNSPEC || nam->sa_len < offsetof(struct sockaddr_in, sin_zero) || sinp->sin_addr.s_addr != INADDR_ANY) return (EAFNOSUPPORT); nam->sa_family = AF_INET; } if (nam->sa_len != sizeof(*sinp)) return (EINVAL); /* * Must check for multicast addresses and disallow binding * to them. */ if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) return (EAFNOSUPPORT); - TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_bind: inp == NULL")); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { error = EINVAL; goto out; } #ifdef KDTRACE_HOOKS tp = intotcpcb(inp); #endif - TCPDEBUG1(); INP_HASH_WLOCK(&V_tcbinfo); error = in_pcbbind(inp, nam, td->td_ucred); INP_HASH_WUNLOCK(&V_tcbinfo); out: - TCPDEBUG2(PRU_BIND); TCP_PROBE2(debug__user, tp, PRU_BIND); INP_WUNLOCK(inp); return (error); } #endif /* INET */ #ifdef INET6 static int tcp6_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td) { int error = 0; struct inpcb *inp; #ifdef KDTRACE_HOOKS struct tcpcb *tp = NULL; #endif struct sockaddr_in6 *sin6; u_char vflagsav; sin6 = (struct sockaddr_in6 *)nam; if (nam->sa_family != AF_INET6) return (EAFNOSUPPORT); if (nam->sa_len != sizeof(*sin6)) return (EINVAL); /* * Must check for multicast addresses and disallow binding * to them. */ if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) return (EAFNOSUPPORT); - TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_bind: inp == NULL")); INP_WLOCK(inp); vflagsav = inp->inp_vflag; if (inp->inp_flags & INP_DROPPED) { error = EINVAL; goto out; } #ifdef KDTRACE_HOOKS tp = intotcpcb(inp); #endif - TCPDEBUG1(); INP_HASH_WLOCK(&V_tcbinfo); inp->inp_vflag &= ~INP_IPV4; inp->inp_vflag |= INP_IPV6; #ifdef INET if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) { if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) inp->inp_vflag |= INP_IPV4; else if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { struct sockaddr_in sin; in6_sin6_2_sin(&sin, sin6); if (IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) { error = EAFNOSUPPORT; INP_HASH_WUNLOCK(&V_tcbinfo); goto out; } inp->inp_vflag |= INP_IPV4; inp->inp_vflag &= ~INP_IPV6; error = in_pcbbind(inp, (struct sockaddr *)&sin, td->td_ucred); INP_HASH_WUNLOCK(&V_tcbinfo); goto out; } } #endif error = in6_pcbbind(inp, nam, td->td_ucred); INP_HASH_WUNLOCK(&V_tcbinfo); out: if (error != 0) inp->inp_vflag = vflagsav; - TCPDEBUG2(PRU_BIND); TCP_PROBE2(debug__user, tp, PRU_BIND); INP_WUNLOCK(inp); return (error); } #endif /* INET6 */ #ifdef INET /* * Prepare to accept connections. */ static int tcp_usr_listen(struct socket *so, int backlog, struct thread *td) { int error = 0; struct inpcb *inp; struct tcpcb *tp = NULL; - TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_listen: inp == NULL")); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { error = EINVAL; goto out; } tp = intotcpcb(inp); - TCPDEBUG1(); SOCK_LOCK(so); error = solisten_proto_check(so); if (error != 0) { SOCK_UNLOCK(so); goto out; } if (inp->inp_lport == 0) { INP_HASH_WLOCK(&V_tcbinfo); error = in_pcbbind(inp, NULL, td->td_ucred); INP_HASH_WUNLOCK(&V_tcbinfo); } if (error == 0) { tcp_state_change(tp, TCPS_LISTEN); solisten_proto(so, backlog); #ifdef TCP_OFFLOAD if ((so->so_options & SO_NO_OFFLOAD) == 0) tcp_offload_listen_start(tp); #endif } else { solisten_proto_abort(so); } SOCK_UNLOCK(so); if (IS_FASTOPEN(tp->t_flags)) tp->t_tfo_pending = tcp_fastopen_alloc_counter(); out: - TCPDEBUG2(PRU_LISTEN); TCP_PROBE2(debug__user, tp, PRU_LISTEN); INP_WUNLOCK(inp); return (error); } #endif /* INET */ #ifdef INET6 static int tcp6_usr_listen(struct socket *so, int backlog, struct thread *td) { int error = 0; struct inpcb *inp; struct tcpcb *tp = NULL; u_char vflagsav; - TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_listen: inp == NULL")); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { error = EINVAL; goto out; } vflagsav = inp->inp_vflag; tp = intotcpcb(inp); - TCPDEBUG1(); SOCK_LOCK(so); error = solisten_proto_check(so); if (error != 0) { SOCK_UNLOCK(so); goto out; } INP_HASH_WLOCK(&V_tcbinfo); if (inp->inp_lport == 0) { inp->inp_vflag &= ~INP_IPV4; if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) inp->inp_vflag |= INP_IPV4; error = in6_pcbbind(inp, NULL, td->td_ucred); } INP_HASH_WUNLOCK(&V_tcbinfo); if (error == 0) { tcp_state_change(tp, TCPS_LISTEN); solisten_proto(so, backlog); #ifdef TCP_OFFLOAD if ((so->so_options & SO_NO_OFFLOAD) == 0) tcp_offload_listen_start(tp); #endif } else { solisten_proto_abort(so); } SOCK_UNLOCK(so); if (IS_FASTOPEN(tp->t_flags)) tp->t_tfo_pending = tcp_fastopen_alloc_counter(); if (error != 0) inp->inp_vflag = vflagsav; out: - TCPDEBUG2(PRU_LISTEN); TCP_PROBE2(debug__user, tp, PRU_LISTEN); INP_WUNLOCK(inp); return (error); } #endif /* INET6 */ #ifdef INET /* * Initiate connection to peer. * Create a template for use in transmissions on this connection. * Enter SYN_SENT state, and mark socket as connecting. * Start keep-alive timer, and seed output sequence space. * Send initial segment on connection. */ static int tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td) { struct epoch_tracker et; int error = 0; struct inpcb *inp; struct tcpcb *tp = NULL; struct sockaddr_in *sinp; sinp = (struct sockaddr_in *)nam; if (nam->sa_family != AF_INET) return (EAFNOSUPPORT); if (nam->sa_len != sizeof (*sinp)) return (EINVAL); /* * Must disallow TCP ``connections'' to multicast addresses. */ if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) return (EAFNOSUPPORT); if (ntohl(sinp->sin_addr.s_addr) == INADDR_BROADCAST) return (EACCES); if ((error = prison_remote_ip4(td->td_ucred, &sinp->sin_addr)) != 0) return (error); - TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_connect: inp == NULL")); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { error = ECONNREFUSED; goto out; } if (SOLISTENING(so)) { error = EOPNOTSUPP; goto out; } tp = intotcpcb(inp); - TCPDEBUG1(); NET_EPOCH_ENTER(et); if ((error = tcp_connect(tp, nam, td)) != 0) goto out_in_epoch; #ifdef TCP_OFFLOAD if (registered_toedevs > 0 && (so->so_options & SO_NO_OFFLOAD) == 0 && (error = tcp_offload_connect(so, nam)) == 0) goto out_in_epoch; #endif tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp)); error = tcp_output(tp); KASSERT(error >= 0, ("TCP stack %s requested tcp_drop(%p) at connect()" ", error code %d", tp->t_fb->tfb_tcp_block_name, tp, -error)); out_in_epoch: NET_EPOCH_EXIT(et); out: - TCPDEBUG2(PRU_CONNECT); TCP_PROBE2(debug__user, tp, PRU_CONNECT); INP_WUNLOCK(inp); return (error); } #endif /* INET */ #ifdef INET6 static int tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td) { struct epoch_tracker et; int error = 0; struct inpcb *inp; struct tcpcb *tp = NULL; struct sockaddr_in6 *sin6; u_int8_t incflagsav; u_char vflagsav; - TCPDEBUG0; - sin6 = (struct sockaddr_in6 *)nam; if (nam->sa_family != AF_INET6) return (EAFNOSUPPORT); if (nam->sa_len != sizeof (*sin6)) return (EINVAL); /* * Must disallow TCP ``connections'' to multicast addresses. */ if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) return (EAFNOSUPPORT); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_connect: inp == NULL")); INP_WLOCK(inp); vflagsav = inp->inp_vflag; incflagsav = inp->inp_inc.inc_flags; if (inp->inp_flags & INP_DROPPED) { error = ECONNREFUSED; goto out; } if (SOLISTENING(so)) { error = EINVAL; goto out; } tp = intotcpcb(inp); - TCPDEBUG1(); #ifdef INET /* * XXXRW: Some confusion: V4/V6 flags relate to binding, and * therefore probably require the hash lock, which isn't held here. * Is this a significant problem? */ if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { struct sockaddr_in sin; if ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0) { error = EINVAL; goto out; } if ((inp->inp_vflag & INP_IPV4) == 0) { error = EAFNOSUPPORT; goto out; } in6_sin6_2_sin(&sin, sin6); if (IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) { error = EAFNOSUPPORT; goto out; } if (ntohl(sin.sin_addr.s_addr) == INADDR_BROADCAST) { error = EACCES; goto out; } if ((error = prison_remote_ip4(td->td_ucred, &sin.sin_addr)) != 0) goto out; inp->inp_vflag |= INP_IPV4; inp->inp_vflag &= ~INP_IPV6; NET_EPOCH_ENTER(et); if ((error = tcp_connect(tp, (struct sockaddr *)&sin, td)) != 0) goto out_in_epoch; #ifdef TCP_OFFLOAD if (registered_toedevs > 0 && (so->so_options & SO_NO_OFFLOAD) == 0 && (error = tcp_offload_connect(so, nam)) == 0) goto out_in_epoch; #endif error = tcp_output(tp); goto out_in_epoch; } else { if ((inp->inp_vflag & INP_IPV6) == 0) { error = EAFNOSUPPORT; goto out; } } #endif if ((error = prison_remote_ip6(td->td_ucred, &sin6->sin6_addr)) != 0) goto out; inp->inp_vflag &= ~INP_IPV4; inp->inp_vflag |= INP_IPV6; inp->inp_inc.inc_flags |= INC_ISIPV6; NET_EPOCH_ENTER(et); if ((error = tcp6_connect(tp, nam, td)) != 0) goto out_in_epoch; #ifdef TCP_OFFLOAD if (registered_toedevs > 0 && (so->so_options & SO_NO_OFFLOAD) == 0 && (error = tcp_offload_connect(so, nam)) == 0) goto out_in_epoch; #endif tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp)); error = tcp_output(tp); out_in_epoch: NET_EPOCH_EXIT(et); out: KASSERT(error >= 0, ("TCP stack %s requested tcp_drop(%p) at connect()" ", error code %d", tp->t_fb->tfb_tcp_block_name, tp, -error)); /* * If the implicit bind in the connect call fails, restore * the flags we modified. */ if (error != 0 && inp->inp_lport == 0) { inp->inp_vflag = vflagsav; inp->inp_inc.inc_flags = incflagsav; } - TCPDEBUG2(PRU_CONNECT); TCP_PROBE2(debug__user, tp, PRU_CONNECT); INP_WUNLOCK(inp); return (error); } #endif /* INET6 */ /* * Initiate disconnect from peer. * If connection never passed embryonic stage, just drop; * else if don't need to let data drain, then can just drop anyways, * else have to begin TCP shutdown process: mark socket disconnecting, * drain unread data, state switch to reflect user close, and * send segment (e.g. FIN) to peer. Socket will be really disconnected * when peer sends FIN and acks ours. * * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB. */ static int tcp_usr_disconnect(struct socket *so) { struct inpcb *inp; struct tcpcb *tp = NULL; struct epoch_tracker et; int error = 0; - TCPDEBUG0; NET_EPOCH_ENTER(et); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_disconnect: inp == NULL")); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { error = ECONNRESET; goto out; } tp = intotcpcb(inp); - TCPDEBUG1(); tcp_disconnect(tp); out: - TCPDEBUG2(PRU_DISCONNECT); TCP_PROBE2(debug__user, tp, PRU_DISCONNECT); INP_WUNLOCK(inp); NET_EPOCH_EXIT(et); return (error); } #ifdef INET /* * Accept a connection. Essentially all the work is done at higher levels; * just return the address of the peer, storing through addr. */ static int tcp_usr_accept(struct socket *so, struct sockaddr **nam) { int error = 0; struct inpcb *inp = NULL; #ifdef KDTRACE_HOOKS struct tcpcb *tp = NULL; #endif struct in_addr addr; in_port_t port = 0; - TCPDEBUG0; if (so->so_state & SS_ISDISCONNECTED) return (ECONNABORTED); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_accept: inp == NULL")); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { error = ECONNABORTED; goto out; } #ifdef KDTRACE_HOOKS tp = intotcpcb(inp); #endif - TCPDEBUG1(); /* * We inline in_getpeeraddr and COMMON_END here, so that we can * copy the data of interest and defer the malloc until after we * release the lock. */ port = inp->inp_fport; addr = inp->inp_faddr; out: - TCPDEBUG2(PRU_ACCEPT); TCP_PROBE2(debug__user, tp, PRU_ACCEPT); INP_WUNLOCK(inp); if (error == 0) *nam = in_sockaddr(port, &addr); return error; } #endif /* INET */ #ifdef INET6 static int tcp6_usr_accept(struct socket *so, struct sockaddr **nam) { struct inpcb *inp = NULL; int error = 0; #ifdef KDTRACE_HOOKS struct tcpcb *tp = NULL; #endif struct in_addr addr; struct in6_addr addr6; struct epoch_tracker et; in_port_t port = 0; int v4 = 0; - TCPDEBUG0; if (so->so_state & SS_ISDISCONNECTED) return (ECONNABORTED); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp6_usr_accept: inp == NULL")); NET_EPOCH_ENTER(et); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { error = ECONNABORTED; goto out; } #ifdef KDTRACE_HOOKS tp = intotcpcb(inp); #endif - TCPDEBUG1(); /* * We inline in6_mapped_peeraddr and COMMON_END here, so that we can * copy the data of interest and defer the malloc until after we * release the lock. */ if (inp->inp_vflag & INP_IPV4) { v4 = 1; port = inp->inp_fport; addr = inp->inp_faddr; } else { port = inp->inp_fport; addr6 = inp->in6p_faddr; } out: - TCPDEBUG2(PRU_ACCEPT); TCP_PROBE2(debug__user, tp, PRU_ACCEPT); INP_WUNLOCK(inp); NET_EPOCH_EXIT(et); if (error == 0) { if (v4) *nam = in6_v4mapsin6_sockaddr(port, &addr); else *nam = in6_sockaddr(port, &addr6); } return error; } #endif /* INET6 */ /* * Mark the connection as being incapable of further output. */ static int tcp_usr_shutdown(struct socket *so) { int error = 0; struct inpcb *inp; struct tcpcb *tp = NULL; struct epoch_tracker et; - TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("inp == NULL")); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { INP_WUNLOCK(inp); return (ECONNRESET); } tp = intotcpcb(inp); NET_EPOCH_ENTER(et); - TCPDEBUG1(); socantsendmore(so); tcp_usrclosed(tp); if (!(inp->inp_flags & INP_DROPPED)) error = tcp_output_nodrop(tp); - TCPDEBUG2(PRU_SHUTDOWN); TCP_PROBE2(debug__user, tp, PRU_SHUTDOWN); error = tcp_unlock_or_drop(tp, error); NET_EPOCH_EXIT(et); return (error); } /* * After a receive, possibly send window update to peer. */ static int tcp_usr_rcvd(struct socket *so, int flags) { struct epoch_tracker et; struct inpcb *inp; struct tcpcb *tp = NULL; int outrv = 0, error = 0; - TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_rcvd: inp == NULL")); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { INP_WUNLOCK(inp); return (ECONNRESET); } tp = intotcpcb(inp); NET_EPOCH_ENTER(et); - TCPDEBUG1(); /* * For passively-created TFO connections, don't attempt a window * update while still in SYN_RECEIVED as this may trigger an early * SYN|ACK. It is preferable to have the SYN|ACK be sent along with * application response data, or failing that, when the DELACK timer * expires. */ if (IS_FASTOPEN(tp->t_flags) && (tp->t_state == TCPS_SYN_RECEIVED)) goto out; #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) tcp_offload_rcvd(tp); else #endif outrv = tcp_output_nodrop(tp); out: - TCPDEBUG2(PRU_RCVD); TCP_PROBE2(debug__user, tp, PRU_RCVD); (void) tcp_unlock_or_drop(tp, outrv); NET_EPOCH_EXIT(et); return (error); } /* * Do a send by putting data in output queue and updating urgent * marker if URG set. Possibly send more data. Unlike the other * pru_*() routines, the mbuf chains are our responsibility. We * must either enqueue them or free them. The other pru_* routines * generally are caller-frees. */ static int tcp_usr_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, struct mbuf *control, struct thread *td) { struct epoch_tracker et; int error = 0; struct inpcb *inp; struct tcpcb *tp = NULL; #ifdef INET #ifdef INET6 struct sockaddr_in sin; #endif struct sockaddr_in *sinp; #endif #ifdef INET6 int isipv6; #endif u_int8_t incflagsav; u_char vflagsav; bool restoreflags; - TCPDEBUG0; if (control != NULL) { /* TCP doesn't do control messages (rights, creds, etc) */ if (control->m_len) { m_freem(control); return (EINVAL); } m_freem(control); /* empty control, just free it */ } inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL")); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { if (m != NULL && (flags & PRUS_NOTREADY) == 0) m_freem(m); INP_WUNLOCK(inp); return (ECONNRESET); } vflagsav = inp->inp_vflag; incflagsav = inp->inp_inc.inc_flags; restoreflags = false; tp = intotcpcb(inp); NET_EPOCH_ENTER(et); if ((flags & PRUS_OOB) != 0 && (error = tcp_pru_options_support(tp, PRUS_OOB)) != 0) goto out; - TCPDEBUG1(); if (nam != NULL && tp->t_state < TCPS_SYN_SENT) { if (tp->t_state == TCPS_LISTEN) { error = EINVAL; goto out; } switch (nam->sa_family) { #ifdef INET case AF_INET: sinp = (struct sockaddr_in *)nam; if (sinp->sin_len != sizeof(struct sockaddr_in)) { error = EINVAL; goto out; } if ((inp->inp_vflag & INP_IPV6) != 0) { error = EAFNOSUPPORT; goto out; } if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) { error = EAFNOSUPPORT; goto out; } if (ntohl(sinp->sin_addr.s_addr) == INADDR_BROADCAST) { error = EACCES; goto out; } if ((error = prison_remote_ip4(td->td_ucred, &sinp->sin_addr))) goto out; #ifdef INET6 isipv6 = 0; #endif break; #endif /* INET */ #ifdef INET6 case AF_INET6: { struct sockaddr_in6 *sin6; sin6 = (struct sockaddr_in6 *)nam; if (sin6->sin6_len != sizeof(*sin6)) { error = EINVAL; goto out; } if ((inp->inp_vflag & INP_IPV6PROTO) == 0) { error = EAFNOSUPPORT; goto out; } if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { error = EAFNOSUPPORT; goto out; } if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { #ifdef INET if ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0) { error = EINVAL; goto out; } if ((inp->inp_vflag & INP_IPV4) == 0) { error = EAFNOSUPPORT; goto out; } restoreflags = true; inp->inp_vflag &= ~INP_IPV6; sinp = &sin; in6_sin6_2_sin(sinp, sin6); if (IN_MULTICAST( ntohl(sinp->sin_addr.s_addr))) { error = EAFNOSUPPORT; goto out; } if ((error = prison_remote_ip4(td->td_ucred, &sinp->sin_addr))) goto out; isipv6 = 0; #else /* !INET */ error = EAFNOSUPPORT; goto out; #endif /* INET */ } else { if ((inp->inp_vflag & INP_IPV6) == 0) { error = EAFNOSUPPORT; goto out; } restoreflags = true; inp->inp_vflag &= ~INP_IPV4; inp->inp_inc.inc_flags |= INC_ISIPV6; if ((error = prison_remote_ip6(td->td_ucred, &sin6->sin6_addr))) goto out; isipv6 = 1; } break; } #endif /* INET6 */ default: error = EAFNOSUPPORT; goto out; } } if (!(flags & PRUS_OOB)) { if (tp->t_acktime == 0) tp->t_acktime = ticks; sbappendstream(&so->so_snd, m, flags); m = NULL; if (nam && tp->t_state < TCPS_SYN_SENT) { KASSERT(tp->t_state == TCPS_CLOSED, ("%s: tp %p is listening", __func__, tp)); /* * Do implied connect if not yet connected, * initialize window to default value, and * initialize maxseg using peer's cached MSS. */ #ifdef INET6 if (isipv6) error = tcp6_connect(tp, nam, td); #endif /* INET6 */ #if defined(INET6) && defined(INET) else #endif #ifdef INET error = tcp_connect(tp, (struct sockaddr *)sinp, td); #endif /* * The bind operation in tcp_connect succeeded. We * no longer want to restore the flags if later * operations fail. */ if (error == 0 || inp->inp_lport != 0) restoreflags = false; if (error) { /* m is freed if PRUS_NOTREADY is unset. */ sbflush(&so->so_snd); goto out; } if (IS_FASTOPEN(tp->t_flags)) tcp_fastopen_connect(tp); else { tp->snd_wnd = TTCP_CLIENT_SND_WND; tcp_mss(tp, -1); } } if (flags & PRUS_EOF) { /* * Close the send side of the connection after * the data is sent. */ socantsendmore(so); tcp_usrclosed(tp); } if (TCPS_HAVEESTABLISHED(tp->t_state) && ((tp->t_flags2 & TF2_FBYTES_COMPLETE) == 0) && (tp->t_fbyte_out == 0) && (so->so_snd.sb_ccc > 0)) { tp->t_fbyte_out = ticks; if (tp->t_fbyte_out == 0) tp->t_fbyte_out = 1; if (tp->t_fbyte_out && tp->t_fbyte_in) tp->t_flags2 |= TF2_FBYTES_COMPLETE; } if (!(inp->inp_flags & INP_DROPPED) && !(flags & PRUS_NOTREADY)) { if (flags & PRUS_MORETOCOME) tp->t_flags |= TF_MORETOCOME; error = tcp_output_nodrop(tp); if (flags & PRUS_MORETOCOME) tp->t_flags &= ~TF_MORETOCOME; } } else { /* * XXXRW: PRUS_EOF not implemented with PRUS_OOB? */ SOCKBUF_LOCK(&so->so_snd); if (sbspace(&so->so_snd) < -512) { SOCKBUF_UNLOCK(&so->so_snd); error = ENOBUFS; goto out; } /* * According to RFC961 (Assigned Protocols), * the urgent pointer points to the last octet * of urgent data. We continue, however, * to consider it to indicate the first octet * of data past the urgent section. * Otherwise, snd_up should be one lower. */ if (tp->t_acktime == 0) tp->t_acktime = ticks; sbappendstream_locked(&so->so_snd, m, flags); SOCKBUF_UNLOCK(&so->so_snd); m = NULL; if (nam && tp->t_state < TCPS_SYN_SENT) { /* * Do implied connect if not yet connected, * initialize window to default value, and * initialize maxseg using peer's cached MSS. */ /* * Not going to contemplate SYN|URG */ if (IS_FASTOPEN(tp->t_flags)) tp->t_flags &= ~TF_FASTOPEN; #ifdef INET6 if (isipv6) error = tcp6_connect(tp, nam, td); #endif /* INET6 */ #if defined(INET6) && defined(INET) else #endif #ifdef INET error = tcp_connect(tp, (struct sockaddr *)sinp, td); #endif /* * The bind operation in tcp_connect succeeded. We * no longer want to restore the flags if later * operations fail. */ if (error == 0 || inp->inp_lport != 0) restoreflags = false; if (error != 0) { /* m is freed if PRUS_NOTREADY is unset. */ sbflush(&so->so_snd); goto out; } tp->snd_wnd = TTCP_CLIENT_SND_WND; tcp_mss(tp, -1); } tp->snd_up = tp->snd_una + sbavail(&so->so_snd); if ((flags & PRUS_NOTREADY) == 0) { tp->t_flags |= TF_FORCEDATA; error = tcp_output_nodrop(tp); tp->t_flags &= ~TF_FORCEDATA; } } TCP_LOG_EVENT(tp, NULL, &inp->inp_socket->so_rcv, &inp->inp_socket->so_snd, TCP_LOG_USERSEND, error, 0, NULL, false); out: /* * In case of PRUS_NOTREADY, the caller or tcp_usr_ready() is * responsible for freeing memory. */ if (m != NULL && (flags & PRUS_NOTREADY) == 0) m_freem(m); /* * If the request was unsuccessful and we changed flags, * restore the original flags. */ if (error != 0 && restoreflags) { inp->inp_vflag = vflagsav; inp->inp_inc.inc_flags = incflagsav; } - TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB : - ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND)); TCP_PROBE2(debug__user, tp, (flags & PRUS_OOB) ? PRU_SENDOOB : ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND)); error = tcp_unlock_or_drop(tp, error); NET_EPOCH_EXIT(et); return (error); } static int tcp_usr_ready(struct socket *so, struct mbuf *m, int count) { struct epoch_tracker et; struct inpcb *inp; struct tcpcb *tp; int error; inp = sotoinpcb(so); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { INP_WUNLOCK(inp); mb_free_notready(m, count); return (ECONNRESET); } tp = intotcpcb(inp); SOCKBUF_LOCK(&so->so_snd); error = sbready(&so->so_snd, m, count); SOCKBUF_UNLOCK(&so->so_snd); if (error) { INP_WUNLOCK(inp); return (error); } NET_EPOCH_ENTER(et); error = tcp_output_unlock(tp); NET_EPOCH_EXIT(et); return (error); } /* * Abort the TCP. Drop the connection abruptly. */ static void tcp_usr_abort(struct socket *so) { struct inpcb *inp; struct tcpcb *tp = NULL; struct epoch_tracker et; - TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_abort: inp == NULL")); NET_EPOCH_ENTER(et); INP_WLOCK(inp); KASSERT(inp->inp_socket != NULL, ("tcp_usr_abort: inp_socket == NULL")); /* * If we still have full TCP state, and we're not dropped, drop. */ if (!(inp->inp_flags & INP_DROPPED)) { tp = intotcpcb(inp); - TCPDEBUG1(); tp = tcp_drop(tp, ECONNABORTED); if (tp == NULL) goto dropped; - TCPDEBUG2(PRU_ABORT); TCP_PROBE2(debug__user, tp, PRU_ABORT); } if (!(inp->inp_flags & INP_DROPPED)) { soref(so); inp->inp_flags |= INP_SOCKREF; } INP_WUNLOCK(inp); dropped: NET_EPOCH_EXIT(et); } /* * TCP socket is closed. Start friendly disconnect. */ static void tcp_usr_close(struct socket *so) { struct inpcb *inp; struct tcpcb *tp = NULL; struct epoch_tracker et; - TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_close: inp == NULL")); NET_EPOCH_ENTER(et); INP_WLOCK(inp); KASSERT(inp->inp_socket != NULL, ("tcp_usr_close: inp_socket == NULL")); /* * If we still have full TCP state, and we're not dropped, initiate * a disconnect. */ if (!(inp->inp_flags & INP_DROPPED)) { tp = intotcpcb(inp); tp->t_flags |= TF_CLOSED; - TCPDEBUG1(); tcp_disconnect(tp); - TCPDEBUG2(PRU_CLOSE); TCP_PROBE2(debug__user, tp, PRU_CLOSE); } if (!(inp->inp_flags & INP_DROPPED)) { soref(so); inp->inp_flags |= INP_SOCKREF; } INP_WUNLOCK(inp); NET_EPOCH_EXIT(et); } static int tcp_pru_options_support(struct tcpcb *tp, int flags) { /* * If the specific TCP stack has a pru_options * specified then it does not always support * all the PRU_XX options and we must ask it. * If the function is not specified then all * of the PRU_XX options are supported. */ int ret = 0; if (tp->t_fb->tfb_pru_options) { ret = (*tp->t_fb->tfb_pru_options)(tp, flags); } return (ret); } /* * Receive out-of-band data. */ static int tcp_usr_rcvoob(struct socket *so, struct mbuf *m, int flags) { int error = 0; struct inpcb *inp; struct tcpcb *tp = NULL; - TCPDEBUG0; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_rcvoob: inp == NULL")); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { error = ECONNRESET; goto out; } tp = intotcpcb(inp); error = tcp_pru_options_support(tp, PRUS_OOB); if (error) { goto out; } - TCPDEBUG1(); if ((so->so_oobmark == 0 && (so->so_rcv.sb_state & SBS_RCVATMARK) == 0) || so->so_options & SO_OOBINLINE || tp->t_oobflags & TCPOOB_HADDATA) { error = EINVAL; goto out; } if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) { error = EWOULDBLOCK; goto out; } m->m_len = 1; *mtod(m, caddr_t) = tp->t_iobc; if ((flags & MSG_PEEK) == 0) tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA); out: - TCPDEBUG2(PRU_RCVOOB); TCP_PROBE2(debug__user, tp, PRU_RCVOOB); INP_WUNLOCK(inp); return (error); } #ifdef INET struct protosw tcp_protosw = { .pr_type = SOCK_STREAM, .pr_protocol = IPPROTO_TCP, .pr_flags = PR_CONNREQUIRED | PR_IMPLOPCL | PR_WANTRCVD | PR_CAPATTACH, .pr_ctloutput = tcp_ctloutput, .pr_abort = tcp_usr_abort, .pr_accept = tcp_usr_accept, .pr_attach = tcp_usr_attach, .pr_bind = tcp_usr_bind, .pr_connect = tcp_usr_connect, .pr_control = in_control, .pr_detach = tcp_usr_detach, .pr_disconnect = tcp_usr_disconnect, .pr_listen = tcp_usr_listen, .pr_peeraddr = in_getpeeraddr, .pr_rcvd = tcp_usr_rcvd, .pr_rcvoob = tcp_usr_rcvoob, .pr_send = tcp_usr_send, .pr_ready = tcp_usr_ready, .pr_shutdown = tcp_usr_shutdown, .pr_sockaddr = in_getsockaddr, .pr_sosetlabel = in_pcbsosetlabel, .pr_close = tcp_usr_close, }; #endif /* INET */ #ifdef INET6 struct protosw tcp6_protosw = { .pr_type = SOCK_STREAM, .pr_protocol = IPPROTO_TCP, .pr_flags = PR_CONNREQUIRED | PR_IMPLOPCL |PR_WANTRCVD | PR_CAPATTACH, .pr_ctloutput = tcp_ctloutput, .pr_abort = tcp_usr_abort, .pr_accept = tcp6_usr_accept, .pr_attach = tcp_usr_attach, .pr_bind = tcp6_usr_bind, .pr_connect = tcp6_usr_connect, .pr_control = in6_control, .pr_detach = tcp_usr_detach, .pr_disconnect = tcp_usr_disconnect, .pr_listen = tcp6_usr_listen, .pr_peeraddr = in6_mapped_peeraddr, .pr_rcvd = tcp_usr_rcvd, .pr_rcvoob = tcp_usr_rcvoob, .pr_send = tcp_usr_send, .pr_ready = tcp_usr_ready, .pr_shutdown = tcp_usr_shutdown, .pr_sockaddr = in6_mapped_sockaddr, .pr_sosetlabel = in_pcbsosetlabel, .pr_close = tcp_usr_close, }; #endif /* INET6 */ #ifdef INET /* * Common subroutine to open a TCP connection to remote host specified * by struct sockaddr_in in mbuf *nam. Call in_pcbbind to assign a local * port number if needed. Call in_pcbconnect_setup to do the routing and * to choose a local host address (interface). If there is an existing * incarnation of the same connection in TIME-WAIT state and if the remote * host was sending CC options and if the connection duration was < MSL, then * truncate the previous TIME-WAIT state and proceed. * Initialize connection parameters and enter SYN-SENT state. */ static int tcp_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td) { struct inpcb *inp = tptoinpcb(tp), *oinp; struct socket *so = tptosocket(tp); struct in_addr laddr; u_short lport; int error; NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(inp); INP_HASH_WLOCK(&V_tcbinfo); if (V_tcp_require_unique_port && inp->inp_lport == 0) { error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); if (error) goto out; } /* * Cannot simply call in_pcbconnect, because there might be an * earlier incarnation of this same connection still in * TIME_WAIT state, creating an ADDRINUSE error. */ laddr = inp->inp_laddr; lport = inp->inp_lport; error = in_pcbconnect_setup(inp, nam, &laddr.s_addr, &lport, &inp->inp_faddr.s_addr, &inp->inp_fport, &oinp, td->td_ucred); if (error && oinp == NULL) goto out; if (oinp) { error = EADDRINUSE; goto out; } /* Handle initial bind if it hadn't been done in advance. */ if (inp->inp_lport == 0) { inp->inp_lport = lport; if (in_pcbinshash(inp) != 0) { inp->inp_lport = 0; error = EAGAIN; goto out; } } inp->inp_laddr = laddr; in_pcbrehash(inp); INP_HASH_WUNLOCK(&V_tcbinfo); /* * Compute window scaling to request: * Scale to fit into sweet spot. See tcp_syncache.c. * XXX: This should move to tcp_output(). */ while (tp->request_r_scale < TCP_MAX_WINSHIFT && (TCP_MAXWIN << tp->request_r_scale) < sb_max) tp->request_r_scale++; soisconnecting(so); TCPSTAT_INC(tcps_connattempt); tcp_state_change(tp, TCPS_SYN_SENT); tp->iss = tcp_new_isn(&inp->inp_inc); if (tp->t_flags & TF_REQ_TSTMP) tp->ts_offset = tcp_new_ts_offset(&inp->inp_inc); tcp_sendseqinit(tp); return 0; out: INP_HASH_WUNLOCK(&V_tcbinfo); return (error); } #endif /* INET */ #ifdef INET6 static int tcp6_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td) { struct inpcb *inp = tptoinpcb(tp); int error; INP_WLOCK_ASSERT(inp); INP_HASH_WLOCK(&V_tcbinfo); if (V_tcp_require_unique_port && inp->inp_lport == 0) { error = in6_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); if (error) goto out; } error = in6_pcbconnect(inp, nam, td->td_ucred); if (error != 0) goto out; INP_HASH_WUNLOCK(&V_tcbinfo); /* Compute window scaling to request. */ while (tp->request_r_scale < TCP_MAX_WINSHIFT && (TCP_MAXWIN << tp->request_r_scale) < sb_max) tp->request_r_scale++; soisconnecting(inp->inp_socket); TCPSTAT_INC(tcps_connattempt); tcp_state_change(tp, TCPS_SYN_SENT); tp->iss = tcp_new_isn(&inp->inp_inc); if (tp->t_flags & TF_REQ_TSTMP) tp->ts_offset = tcp_new_ts_offset(&inp->inp_inc); tcp_sendseqinit(tp); return 0; out: INP_HASH_WUNLOCK(&V_tcbinfo); return error; } #endif /* INET6 */ /* * Export TCP internal state information via a struct tcp_info, based on the * Linux 2.6 API. Not ABI compatible as our constants are mapped differently * (TCP state machine, etc). We export all information using FreeBSD-native * constants -- for example, the numeric values for tcpi_state will differ * from Linux. */ static void tcp_fill_info(struct tcpcb *tp, struct tcp_info *ti) { INP_WLOCK_ASSERT(tptoinpcb(tp)); bzero(ti, sizeof(*ti)); ti->tcpi_state = tp->t_state; if ((tp->t_flags & TF_REQ_TSTMP) && (tp->t_flags & TF_RCVD_TSTMP)) ti->tcpi_options |= TCPI_OPT_TIMESTAMPS; if (tp->t_flags & TF_SACK_PERMIT) ti->tcpi_options |= TCPI_OPT_SACK; if ((tp->t_flags & TF_REQ_SCALE) && (tp->t_flags & TF_RCVD_SCALE)) { ti->tcpi_options |= TCPI_OPT_WSCALE; ti->tcpi_snd_wscale = tp->snd_scale; ti->tcpi_rcv_wscale = tp->rcv_scale; } if (tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) ti->tcpi_options |= TCPI_OPT_ECN; ti->tcpi_rto = tp->t_rxtcur * tick; ti->tcpi_last_data_recv = ((uint32_t)ticks - tp->t_rcvtime) * tick; ti->tcpi_rtt = ((u_int64_t)tp->t_srtt * tick) >> TCP_RTT_SHIFT; ti->tcpi_rttvar = ((u_int64_t)tp->t_rttvar * tick) >> TCP_RTTVAR_SHIFT; ti->tcpi_snd_ssthresh = tp->snd_ssthresh; ti->tcpi_snd_cwnd = tp->snd_cwnd; /* * FreeBSD-specific extension fields for tcp_info. */ ti->tcpi_rcv_space = tp->rcv_wnd; ti->tcpi_rcv_nxt = tp->rcv_nxt; ti->tcpi_snd_wnd = tp->snd_wnd; ti->tcpi_snd_bwnd = 0; /* Unused, kept for compat. */ ti->tcpi_snd_nxt = tp->snd_nxt; ti->tcpi_snd_mss = tp->t_maxseg; ti->tcpi_rcv_mss = tp->t_maxseg; ti->tcpi_snd_rexmitpack = tp->t_sndrexmitpack; ti->tcpi_rcv_ooopack = tp->t_rcvoopack; ti->tcpi_snd_zerowin = tp->t_sndzerowin; #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) { ti->tcpi_options |= TCPI_OPT_TOE; tcp_offload_tcp_info(tp, ti); } #endif /* * AccECN related counters. */ if ((tp->t_flags2 & (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) == (TF2_ECN_PERMIT | TF2_ACE_PERMIT)) /* * Internal counter starts at 5 for AccECN * but 0 for RFC3168 ECN. */ ti->tcpi_delivered_ce = tp->t_scep - 5; else ti->tcpi_delivered_ce = tp->t_scep; ti->tcpi_received_ce = tp->t_rcep; } /* * tcp_ctloutput() must drop the inpcb lock before performing copyin on * socket option arguments. When it re-acquires the lock after the copy, it * has to revalidate that the connection is still valid for the socket * option. */ #define INP_WLOCK_RECHECK_CLEANUP(inp, cleanup) do { \ INP_WLOCK(inp); \ if (inp->inp_flags & INP_DROPPED) { \ INP_WUNLOCK(inp); \ cleanup; \ return (ECONNRESET); \ } \ tp = intotcpcb(inp); \ } while(0) #define INP_WLOCK_RECHECK(inp) INP_WLOCK_RECHECK_CLEANUP((inp), /* noop */) int tcp_ctloutput_set(struct inpcb *inp, struct sockopt *sopt) { struct socket *so = inp->inp_socket; struct tcpcb *tp = intotcpcb(inp); int error = 0; MPASS(sopt->sopt_dir == SOPT_SET); INP_WLOCK_ASSERT(inp); KASSERT((inp->inp_flags & INP_DROPPED) == 0, ("inp_flags == %x", inp->inp_flags)); KASSERT(so != NULL, ("inp_socket == NULL")); if (sopt->sopt_level != IPPROTO_TCP) { INP_WUNLOCK(inp); #ifdef INET6 if (inp->inp_vflag & INP_IPV6PROTO) error = ip6_ctloutput(so, sopt); #endif #if defined(INET6) && defined(INET) else #endif #ifdef INET error = ip_ctloutput(so, sopt); #endif /* * When an IP-level socket option affects TCP, pass control * down to stack tfb_tcp_ctloutput, otherwise return what * IP level returned. */ switch (sopt->sopt_level) { #ifdef INET6 case IPPROTO_IPV6: if ((inp->inp_vflag & INP_IPV6PROTO) == 0) return (error); switch (sopt->sopt_name) { case IPV6_TCLASS: /* Notify tcp stacks that care (e.g. RACK). */ break; case IPV6_USE_MIN_MTU: /* Update t_maxseg accordingly. */ break; default: return (error); } break; #endif #ifdef INET case IPPROTO_IP: switch (sopt->sopt_name) { case IP_TOS: inp->inp_ip_tos &= ~IPTOS_ECN_MASK; break; case IP_TTL: /* Notify tcp stacks that care (e.g. RACK). */ break; default: return (error); } break; #endif default: return (error); } INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { INP_WUNLOCK(inp); return (ECONNRESET); } } else if (sopt->sopt_name == TCP_FUNCTION_BLK) { /* * Protect the TCP option TCP_FUNCTION_BLK so * that a sub-function can *never* overwrite this. */ struct tcp_function_set fsn; struct tcp_function_block *blk; INP_WUNLOCK(inp); error = sooptcopyin(sopt, &fsn, sizeof fsn, sizeof fsn); if (error) return (error); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { INP_WUNLOCK(inp); return (ECONNRESET); } tp = intotcpcb(inp); blk = find_and_ref_tcp_functions(&fsn); if (blk == NULL) { INP_WUNLOCK(inp); return (ENOENT); } if (tp->t_fb == blk) { /* You already have this */ refcount_release(&blk->tfb_refcnt); INP_WUNLOCK(inp); return (0); } if (tp->t_state != TCPS_CLOSED) { /* * The user has advanced the state * past the initial point, we may not * be able to switch. */ if (blk->tfb_tcp_handoff_ok != NULL) { /* * Does the stack provide a * query mechanism, if so it may * still be possible? */ error = (*blk->tfb_tcp_handoff_ok)(tp); } else error = EINVAL; if (error) { refcount_release(&blk->tfb_refcnt); INP_WUNLOCK(inp); return(error); } } if (blk->tfb_flags & TCP_FUNC_BEING_REMOVED) { refcount_release(&blk->tfb_refcnt); INP_WUNLOCK(inp); return (ENOENT); } /* * Release the old refcnt, the * lookup acquired a ref on the * new one already. */ if (tp->t_fb->tfb_tcp_fb_fini) { struct epoch_tracker et; /* * Tell the stack to cleanup with 0 i.e. * the tcb is not going away. */ NET_EPOCH_ENTER(et); (*tp->t_fb->tfb_tcp_fb_fini)(tp, 0); NET_EPOCH_EXIT(et); } #ifdef TCPHPTS /* Assure that we are not on any hpts */ tcp_hpts_remove(tptoinpcb(tp)); #endif if (blk->tfb_tcp_fb_init) { error = (*blk->tfb_tcp_fb_init)(tp); if (error) { refcount_release(&blk->tfb_refcnt); if (tp->t_fb->tfb_tcp_fb_init) { if((*tp->t_fb->tfb_tcp_fb_init)(tp) != 0) { /* Fall back failed, drop the connection */ INP_WUNLOCK(inp); soabort(so); return (error); } } goto err_out; } } refcount_release(&tp->t_fb->tfb_refcnt); tp->t_fb = blk; #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) { tcp_offload_ctloutput(tp, sopt->sopt_dir, sopt->sopt_name); } #endif err_out: INP_WUNLOCK(inp); return (error); } /* Pass in the INP locked, callee must unlock it. */ return (tp->t_fb->tfb_tcp_ctloutput(inp, sopt)); } static int tcp_ctloutput_get(struct inpcb *inp, struct sockopt *sopt) { struct socket *so = inp->inp_socket; struct tcpcb *tp = intotcpcb(inp); int error = 0; MPASS(sopt->sopt_dir == SOPT_GET); INP_WLOCK_ASSERT(inp); KASSERT((inp->inp_flags & INP_DROPPED) == 0, ("inp_flags == %x", inp->inp_flags)); KASSERT(so != NULL, ("inp_socket == NULL")); if (sopt->sopt_level != IPPROTO_TCP) { INP_WUNLOCK(inp); #ifdef INET6 if (inp->inp_vflag & INP_IPV6PROTO) error = ip6_ctloutput(so, sopt); #endif /* INET6 */ #if defined(INET6) && defined(INET) else #endif #ifdef INET error = ip_ctloutput(so, sopt); #endif return (error); } if (((sopt->sopt_name == TCP_FUNCTION_BLK) || (sopt->sopt_name == TCP_FUNCTION_ALIAS))) { struct tcp_function_set fsn; if (sopt->sopt_name == TCP_FUNCTION_ALIAS) { memset(&fsn, 0, sizeof(fsn)); find_tcp_function_alias(tp->t_fb, &fsn); } else { strncpy(fsn.function_set_name, tp->t_fb->tfb_tcp_block_name, TCP_FUNCTION_NAME_LEN_MAX); fsn.function_set_name[TCP_FUNCTION_NAME_LEN_MAX - 1] = '\0'; } fsn.pcbcnt = tp->t_fb->tfb_refcnt; INP_WUNLOCK(inp); error = sooptcopyout(sopt, &fsn, sizeof fsn); return (error); } /* Pass in the INP locked, callee must unlock it. */ return (tp->t_fb->tfb_tcp_ctloutput(inp, sopt)); } int tcp_ctloutput(struct socket *so, struct sockopt *sopt) { struct inpcb *inp; inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_ctloutput: inp == NULL")); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { INP_WUNLOCK(inp); return (ECONNRESET); } if (sopt->sopt_dir == SOPT_SET) return (tcp_ctloutput_set(inp, sopt)); else if (sopt->sopt_dir == SOPT_GET) return (tcp_ctloutput_get(inp, sopt)); else panic("%s: sopt_dir $%d", __func__, sopt->sopt_dir); } /* * If this assert becomes untrue, we need to change the size of the buf * variable in tcp_default_ctloutput(). */ #ifdef CTASSERT CTASSERT(TCP_CA_NAME_MAX <= TCP_LOG_ID_LEN); CTASSERT(TCP_LOG_REASON_LEN <= TCP_LOG_ID_LEN); #endif #ifdef KERN_TLS static int copyin_tls_enable(struct sockopt *sopt, struct tls_enable *tls) { struct tls_enable_v0 tls_v0; int error; if (sopt->sopt_valsize == sizeof(tls_v0)) { error = sooptcopyin(sopt, &tls_v0, sizeof(tls_v0), sizeof(tls_v0)); if (error) return (error); memset(tls, 0, sizeof(*tls)); tls->cipher_key = tls_v0.cipher_key; tls->iv = tls_v0.iv; tls->auth_key = tls_v0.auth_key; tls->cipher_algorithm = tls_v0.cipher_algorithm; tls->cipher_key_len = tls_v0.cipher_key_len; tls->iv_len = tls_v0.iv_len; tls->auth_algorithm = tls_v0.auth_algorithm; tls->auth_key_len = tls_v0.auth_key_len; tls->flags = tls_v0.flags; tls->tls_vmajor = tls_v0.tls_vmajor; tls->tls_vminor = tls_v0.tls_vminor; return (0); } return (sooptcopyin(sopt, tls, sizeof(*tls), sizeof(*tls))); } #endif extern struct cc_algo newreno_cc_algo; static int tcp_set_cc_mod(struct inpcb *inp, struct sockopt *sopt) { struct cc_algo *algo; void *ptr = NULL; struct tcpcb *tp; struct cc_var cc_mem; char buf[TCP_CA_NAME_MAX]; size_t mem_sz; int error; INP_WUNLOCK(inp); error = sooptcopyin(sopt, buf, TCP_CA_NAME_MAX - 1, 1); if (error) return(error); buf[sopt->sopt_valsize] = '\0'; CC_LIST_RLOCK(); STAILQ_FOREACH(algo, &cc_list, entries) { if (strncmp(buf, algo->name, TCP_CA_NAME_MAX) == 0) { if (algo->flags & CC_MODULE_BEING_REMOVED) { /* We can't "see" modules being unloaded */ continue; } break; } } if (algo == NULL) { CC_LIST_RUNLOCK(); return(ESRCH); } /* * With a reference the algorithm cannot be removed * so we hold a reference through the change process. */ cc_refer(algo); CC_LIST_RUNLOCK(); if (algo->cb_init != NULL) { /* We can now pre-get the memory for the CC */ mem_sz = (*algo->cc_data_sz)(); if (mem_sz == 0) { goto no_mem_needed; } ptr = malloc(mem_sz, M_CC_MEM, M_WAITOK); } else { no_mem_needed: mem_sz = 0; ptr = NULL; } /* * Make sure its all clean and zero and also get * back the inplock. */ memset(&cc_mem, 0, sizeof(cc_mem)); INP_WLOCK(inp); if (inp->inp_flags & INP_DROPPED) { INP_WUNLOCK(inp); if (ptr) free(ptr, M_CC_MEM); /* Release our temp reference */ CC_LIST_RLOCK(); cc_release(algo); CC_LIST_RUNLOCK(); return (ECONNRESET); } tp = intotcpcb(inp); if (ptr != NULL) memset(ptr, 0, mem_sz); cc_mem.ccvc.tcp = tp; /* * We once again hold a write lock over the tcb so it's * safe to do these things without ordering concerns. * Note here we init into stack memory. */ if (algo->cb_init != NULL) error = algo->cb_init(&cc_mem, ptr); else error = 0; /* * The CC algorithms, when given their memory * should not fail we could in theory have a * KASSERT here. */ if (error == 0) { /* * Touchdown, lets go ahead and move the * connection to the new CC module by * copying in the cc_mem after we call * the old ones cleanup (if any). */ if (CC_ALGO(tp)->cb_destroy != NULL) CC_ALGO(tp)->cb_destroy(&tp->t_ccv); /* Detach the old CC from the tcpcb */ cc_detach(tp); /* Copy in our temp memory that was inited */ memcpy(&tp->t_ccv, &cc_mem, sizeof(struct cc_var)); /* Now attach the new, which takes a reference */ cc_attach(tp, algo); /* Ok now are we where we have gotten past any conn_init? */ if (TCPS_HAVEESTABLISHED(tp->t_state) && (CC_ALGO(tp)->conn_init != NULL)) { /* Yep run the connection init for the new CC */ CC_ALGO(tp)->conn_init(&tp->t_ccv); } } else if (ptr) free(ptr, M_CC_MEM); INP_WUNLOCK(inp); /* Now lets release our temp reference */ CC_LIST_RLOCK(); cc_release(algo); CC_LIST_RUNLOCK(); return (error); } int tcp_default_ctloutput(struct inpcb *inp, struct sockopt *sopt) { struct tcpcb *tp = intotcpcb(inp); int error, opt, optval; u_int ui; struct tcp_info ti; #ifdef KERN_TLS struct tls_enable tls; struct socket *so = inp->inp_socket; #endif char *pbuf, buf[TCP_LOG_ID_LEN]; #ifdef STATS struct statsblob *sbp; #endif size_t len; INP_WLOCK_ASSERT(inp); KASSERT((inp->inp_flags & INP_DROPPED) == 0, ("inp_flags == %x", inp->inp_flags)); KASSERT(inp->inp_socket != NULL, ("inp_socket == NULL")); switch (sopt->sopt_level) { #ifdef INET6 case IPPROTO_IPV6: MPASS(inp->inp_vflag & INP_IPV6PROTO); switch (sopt->sopt_name) { case IPV6_USE_MIN_MTU: tcp6_use_min_mtu(tp); /* FALLTHROUGH */ } INP_WUNLOCK(inp); return (0); #endif #ifdef INET case IPPROTO_IP: INP_WUNLOCK(inp); return (0); #endif } /* * For TCP_CCALGOOPT forward the control to CC module, for both * SOPT_SET and SOPT_GET. */ switch (sopt->sopt_name) { case TCP_CCALGOOPT: INP_WUNLOCK(inp); if (sopt->sopt_valsize > CC_ALGOOPT_LIMIT) return (EINVAL); pbuf = malloc(sopt->sopt_valsize, M_TEMP, M_WAITOK | M_ZERO); error = sooptcopyin(sopt, pbuf, sopt->sopt_valsize, sopt->sopt_valsize); if (error) { free(pbuf, M_TEMP); return (error); } INP_WLOCK_RECHECK_CLEANUP(inp, free(pbuf, M_TEMP)); if (CC_ALGO(tp)->ctl_output != NULL) error = CC_ALGO(tp)->ctl_output(&tp->t_ccv, sopt, pbuf); else error = ENOENT; INP_WUNLOCK(inp); if (error == 0 && sopt->sopt_dir == SOPT_GET) error = sooptcopyout(sopt, pbuf, sopt->sopt_valsize); free(pbuf, M_TEMP); return (error); } switch (sopt->sopt_dir) { case SOPT_SET: switch (sopt->sopt_name) { #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) case TCP_MD5SIG: INP_WUNLOCK(inp); if (!TCPMD5_ENABLED()) return (ENOPROTOOPT); error = TCPMD5_PCBCTL(inp, sopt); if (error) return (error); INP_WLOCK_RECHECK(inp); goto unlock_and_done; #endif /* IPSEC */ case TCP_NODELAY: case TCP_NOOPT: case TCP_LRD: INP_WUNLOCK(inp); error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval); if (error) return (error); INP_WLOCK_RECHECK(inp); switch (sopt->sopt_name) { case TCP_NODELAY: opt = TF_NODELAY; break; case TCP_NOOPT: opt = TF_NOOPT; break; case TCP_LRD: opt = TF_LRD; break; default: opt = 0; /* dead code to fool gcc */ break; } if (optval) tp->t_flags |= opt; else tp->t_flags &= ~opt; unlock_and_done: #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) { tcp_offload_ctloutput(tp, sopt->sopt_dir, sopt->sopt_name); } #endif INP_WUNLOCK(inp); break; case TCP_NOPUSH: INP_WUNLOCK(inp); error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval); if (error) return (error); INP_WLOCK_RECHECK(inp); if (optval) tp->t_flags |= TF_NOPUSH; else if (tp->t_flags & TF_NOPUSH) { tp->t_flags &= ~TF_NOPUSH; if (TCPS_HAVEESTABLISHED(tp->t_state)) { struct epoch_tracker et; NET_EPOCH_ENTER(et); error = tcp_output_nodrop(tp); NET_EPOCH_EXIT(et); } } goto unlock_and_done; case TCP_REMOTE_UDP_ENCAPS_PORT: INP_WUNLOCK(inp); error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval); if (error) return (error); if ((optval < TCP_TUNNELING_PORT_MIN) || (optval > TCP_TUNNELING_PORT_MAX)) { /* Its got to be in range */ return (EINVAL); } if ((V_tcp_udp_tunneling_port == 0) && (optval != 0)) { /* You have to have enabled a UDP tunneling port first */ return (EINVAL); } INP_WLOCK_RECHECK(inp); if (tp->t_state != TCPS_CLOSED) { /* You can't change after you are connected */ error = EINVAL; } else { /* Ok we are all good set the port */ tp->t_port = htons(optval); } goto unlock_and_done; case TCP_MAXSEG: INP_WUNLOCK(inp); error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval); if (error) return (error); INP_WLOCK_RECHECK(inp); if (optval > 0 && optval <= tp->t_maxseg && optval + 40 >= V_tcp_minmss) tp->t_maxseg = optval; else error = EINVAL; goto unlock_and_done; case TCP_INFO: INP_WUNLOCK(inp); error = EINVAL; break; case TCP_STATS: INP_WUNLOCK(inp); #ifdef STATS error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval); if (error) return (error); if (optval > 0) sbp = stats_blob_alloc( V_tcp_perconn_stats_dflt_tpl, 0); else sbp = NULL; INP_WLOCK_RECHECK(inp); if ((tp->t_stats != NULL && sbp == NULL) || (tp->t_stats == NULL && sbp != NULL)) { struct statsblob *t = tp->t_stats; tp->t_stats = sbp; sbp = t; } INP_WUNLOCK(inp); stats_blob_destroy(sbp); #else return (EOPNOTSUPP); #endif /* !STATS */ break; case TCP_CONGESTION: error = tcp_set_cc_mod(inp, sopt); break; case TCP_REUSPORT_LB_NUMA: INP_WUNLOCK(inp); error = sooptcopyin(sopt, &optval, sizeof(optval), sizeof(optval)); INP_WLOCK_RECHECK(inp); if (!error) error = in_pcblbgroup_numa(inp, optval); INP_WUNLOCK(inp); break; #ifdef KERN_TLS case TCP_TXTLS_ENABLE: INP_WUNLOCK(inp); error = copyin_tls_enable(sopt, &tls); if (error) break; error = ktls_enable_tx(so, &tls); break; case TCP_TXTLS_MODE: INP_WUNLOCK(inp); error = sooptcopyin(sopt, &ui, sizeof(ui), sizeof(ui)); if (error) return (error); INP_WLOCK_RECHECK(inp); error = ktls_set_tx_mode(so, ui); INP_WUNLOCK(inp); break; case TCP_RXTLS_ENABLE: INP_WUNLOCK(inp); error = sooptcopyin(sopt, &tls, sizeof(tls), sizeof(tls)); if (error) break; error = ktls_enable_rx(so, &tls); break; #endif case TCP_MAXUNACKTIME: case TCP_KEEPIDLE: case TCP_KEEPINTVL: case TCP_KEEPINIT: INP_WUNLOCK(inp); error = sooptcopyin(sopt, &ui, sizeof(ui), sizeof(ui)); if (error) return (error); if (ui > (UINT_MAX / hz)) { error = EINVAL; break; } ui *= hz; INP_WLOCK_RECHECK(inp); switch (sopt->sopt_name) { case TCP_MAXUNACKTIME: tp->t_maxunacktime = ui; break; case TCP_KEEPIDLE: tp->t_keepidle = ui; /* * XXX: better check current remaining * timeout and "merge" it with new value. */ if ((tp->t_state > TCPS_LISTEN) && (tp->t_state <= TCPS_CLOSING)) tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp)); break; case TCP_KEEPINTVL: tp->t_keepintvl = ui; if ((tp->t_state == TCPS_FIN_WAIT_2) && (TP_MAXIDLE(tp) > 0)) tcp_timer_activate(tp, TT_2MSL, TP_MAXIDLE(tp)); break; case TCP_KEEPINIT: tp->t_keepinit = ui; if (tp->t_state == TCPS_SYN_RECEIVED || tp->t_state == TCPS_SYN_SENT) tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp)); break; } goto unlock_and_done; case TCP_KEEPCNT: INP_WUNLOCK(inp); error = sooptcopyin(sopt, &ui, sizeof(ui), sizeof(ui)); if (error) return (error); INP_WLOCK_RECHECK(inp); tp->t_keepcnt = ui; if ((tp->t_state == TCPS_FIN_WAIT_2) && (TP_MAXIDLE(tp) > 0)) tcp_timer_activate(tp, TT_2MSL, TP_MAXIDLE(tp)); goto unlock_and_done; #ifdef TCPPCAP case TCP_PCAP_OUT: case TCP_PCAP_IN: INP_WUNLOCK(inp); error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval); if (error) return (error); INP_WLOCK_RECHECK(inp); if (optval >= 0) tcp_pcap_set_sock_max(TCP_PCAP_OUT ? &(tp->t_outpkts) : &(tp->t_inpkts), optval); else error = EINVAL; goto unlock_and_done; #endif case TCP_FASTOPEN: { struct tcp_fastopen tfo_optval; INP_WUNLOCK(inp); if (!V_tcp_fastopen_client_enable && !V_tcp_fastopen_server_enable) return (EPERM); error = sooptcopyin(sopt, &tfo_optval, sizeof(tfo_optval), sizeof(int)); if (error) return (error); INP_WLOCK_RECHECK(inp); if ((tp->t_state != TCPS_CLOSED) && (tp->t_state != TCPS_LISTEN)) { error = EINVAL; goto unlock_and_done; } if (tfo_optval.enable) { if (tp->t_state == TCPS_LISTEN) { if (!V_tcp_fastopen_server_enable) { error = EPERM; goto unlock_and_done; } if (tp->t_tfo_pending == NULL) tp->t_tfo_pending = tcp_fastopen_alloc_counter(); } else { /* * If a pre-shared key was provided, * stash it in the client cookie * field of the tcpcb for use during * connect. */ if (sopt->sopt_valsize == sizeof(tfo_optval)) { memcpy(tp->t_tfo_cookie.client, tfo_optval.psk, TCP_FASTOPEN_PSK_LEN); tp->t_tfo_client_cookie_len = TCP_FASTOPEN_PSK_LEN; } } tp->t_flags |= TF_FASTOPEN; } else tp->t_flags &= ~TF_FASTOPEN; goto unlock_and_done; } #ifdef TCP_BLACKBOX case TCP_LOG: INP_WUNLOCK(inp); error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval); if (error) return (error); INP_WLOCK_RECHECK(inp); error = tcp_log_state_change(tp, optval); goto unlock_and_done; case TCP_LOGBUF: INP_WUNLOCK(inp); error = EINVAL; break; case TCP_LOGID: INP_WUNLOCK(inp); error = sooptcopyin(sopt, buf, TCP_LOG_ID_LEN - 1, 0); if (error) break; buf[sopt->sopt_valsize] = '\0'; INP_WLOCK_RECHECK(inp); error = tcp_log_set_id(tp, buf); /* tcp_log_set_id() unlocks the INP. */ break; case TCP_LOGDUMP: case TCP_LOGDUMPID: INP_WUNLOCK(inp); error = sooptcopyin(sopt, buf, TCP_LOG_REASON_LEN - 1, 0); if (error) break; buf[sopt->sopt_valsize] = '\0'; INP_WLOCK_RECHECK(inp); if (sopt->sopt_name == TCP_LOGDUMP) { error = tcp_log_dump_tp_logbuf(tp, buf, M_WAITOK, true); INP_WUNLOCK(inp); } else { tcp_log_dump_tp_bucket_logbufs(tp, buf); /* * tcp_log_dump_tp_bucket_logbufs() drops the * INP lock. */ } break; #endif default: INP_WUNLOCK(inp); error = ENOPROTOOPT; break; } break; case SOPT_GET: tp = intotcpcb(inp); switch (sopt->sopt_name) { #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) case TCP_MD5SIG: INP_WUNLOCK(inp); if (!TCPMD5_ENABLED()) return (ENOPROTOOPT); error = TCPMD5_PCBCTL(inp, sopt); break; #endif case TCP_NODELAY: optval = tp->t_flags & TF_NODELAY; INP_WUNLOCK(inp); error = sooptcopyout(sopt, &optval, sizeof optval); break; case TCP_MAXSEG: optval = tp->t_maxseg; INP_WUNLOCK(inp); error = sooptcopyout(sopt, &optval, sizeof optval); break; case TCP_REMOTE_UDP_ENCAPS_PORT: optval = ntohs(tp->t_port); INP_WUNLOCK(inp); error = sooptcopyout(sopt, &optval, sizeof optval); break; case TCP_NOOPT: optval = tp->t_flags & TF_NOOPT; INP_WUNLOCK(inp); error = sooptcopyout(sopt, &optval, sizeof optval); break; case TCP_NOPUSH: optval = tp->t_flags & TF_NOPUSH; INP_WUNLOCK(inp); error = sooptcopyout(sopt, &optval, sizeof optval); break; case TCP_INFO: tcp_fill_info(tp, &ti); INP_WUNLOCK(inp); error = sooptcopyout(sopt, &ti, sizeof ti); break; case TCP_STATS: { #ifdef STATS int nheld; TYPEOF_MEMBER(struct statsblob, flags) sbflags = 0; error = 0; socklen_t outsbsz = sopt->sopt_valsize; if (tp->t_stats == NULL) error = ENOENT; else if (outsbsz >= tp->t_stats->cursz) outsbsz = tp->t_stats->cursz; else if (outsbsz >= sizeof(struct statsblob)) outsbsz = sizeof(struct statsblob); else error = EINVAL; INP_WUNLOCK(inp); if (error) break; sbp = sopt->sopt_val; nheld = atop(round_page(((vm_offset_t)sbp) + (vm_size_t)outsbsz) - trunc_page((vm_offset_t)sbp)); vm_page_t ma[nheld]; if (vm_fault_quick_hold_pages( &curproc->p_vmspace->vm_map, (vm_offset_t)sbp, outsbsz, VM_PROT_READ | VM_PROT_WRITE, ma, nheld) < 0) { error = EFAULT; break; } if ((error = copyin_nofault(&(sbp->flags), &sbflags, SIZEOF_MEMBER(struct statsblob, flags)))) goto unhold; INP_WLOCK_RECHECK(inp); error = stats_blob_snapshot(&sbp, outsbsz, tp->t_stats, sbflags | SB_CLONE_USRDSTNOFAULT); INP_WUNLOCK(inp); sopt->sopt_valsize = outsbsz; unhold: vm_page_unhold_pages(ma, nheld); #else INP_WUNLOCK(inp); error = EOPNOTSUPP; #endif /* !STATS */ break; } case TCP_CONGESTION: len = strlcpy(buf, CC_ALGO(tp)->name, TCP_CA_NAME_MAX); INP_WUNLOCK(inp); error = sooptcopyout(sopt, buf, len + 1); break; case TCP_MAXUNACKTIME: case TCP_KEEPIDLE: case TCP_KEEPINTVL: case TCP_KEEPINIT: case TCP_KEEPCNT: switch (sopt->sopt_name) { case TCP_MAXUNACKTIME: ui = TP_MAXUNACKTIME(tp) / hz; break; case TCP_KEEPIDLE: ui = TP_KEEPIDLE(tp) / hz; break; case TCP_KEEPINTVL: ui = TP_KEEPINTVL(tp) / hz; break; case TCP_KEEPINIT: ui = TP_KEEPINIT(tp) / hz; break; case TCP_KEEPCNT: ui = TP_KEEPCNT(tp); break; } INP_WUNLOCK(inp); error = sooptcopyout(sopt, &ui, sizeof(ui)); break; #ifdef TCPPCAP case TCP_PCAP_OUT: case TCP_PCAP_IN: optval = tcp_pcap_get_sock_max(TCP_PCAP_OUT ? &(tp->t_outpkts) : &(tp->t_inpkts)); INP_WUNLOCK(inp); error = sooptcopyout(sopt, &optval, sizeof optval); break; #endif case TCP_FASTOPEN: optval = tp->t_flags & TF_FASTOPEN; INP_WUNLOCK(inp); error = sooptcopyout(sopt, &optval, sizeof optval); break; #ifdef TCP_BLACKBOX case TCP_LOG: optval = tp->t_logstate; INP_WUNLOCK(inp); error = sooptcopyout(sopt, &optval, sizeof(optval)); break; case TCP_LOGBUF: /* tcp_log_getlogbuf() does INP_WUNLOCK(inp) */ error = tcp_log_getlogbuf(sopt, tp); break; case TCP_LOGID: len = tcp_log_get_id(tp, buf); INP_WUNLOCK(inp); error = sooptcopyout(sopt, buf, len + 1); break; case TCP_LOGDUMP: case TCP_LOGDUMPID: INP_WUNLOCK(inp); error = EINVAL; break; #endif #ifdef KERN_TLS case TCP_TXTLS_MODE: error = ktls_get_tx_mode(so, &optval); INP_WUNLOCK(inp); if (error == 0) error = sooptcopyout(sopt, &optval, sizeof(optval)); break; case TCP_RXTLS_MODE: error = ktls_get_rx_mode(so, &optval); INP_WUNLOCK(inp); if (error == 0) error = sooptcopyout(sopt, &optval, sizeof(optval)); break; #endif case TCP_LRD: optval = tp->t_flags & TF_LRD; INP_WUNLOCK(inp); error = sooptcopyout(sopt, &optval, sizeof optval); break; default: INP_WUNLOCK(inp); error = ENOPROTOOPT; break; } break; } return (error); } #undef INP_WLOCK_RECHECK #undef INP_WLOCK_RECHECK_CLEANUP /* * Initiate (or continue) disconnect. * If embryonic state, just send reset (once). * If in ``let data drain'' option and linger null, just drop. * Otherwise (hard), mark socket disconnecting and drop * current input data; switch states based on user close, and * send segment to peer (with FIN). */ static void tcp_disconnect(struct tcpcb *tp) { struct inpcb *inp = tptoinpcb(tp); struct socket *so = tptosocket(tp); NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(inp); /* * Neither tcp_close() nor tcp_drop() should return NULL, as the * socket is still open. */ if (tp->t_state < TCPS_ESTABLISHED && !(tp->t_state > TCPS_LISTEN && IS_FASTOPEN(tp->t_flags))) { tp = tcp_close(tp); KASSERT(tp != NULL, ("tcp_disconnect: tcp_close() returned NULL")); } else if ((so->so_options & SO_LINGER) && so->so_linger == 0) { tp = tcp_drop(tp, 0); KASSERT(tp != NULL, ("tcp_disconnect: tcp_drop() returned NULL")); } else { soisdisconnecting(so); sbflush(&so->so_rcv); tcp_usrclosed(tp); if (!(inp->inp_flags & INP_DROPPED)) /* Ignore stack's drop request, we already at it. */ (void)tcp_output_nodrop(tp); } } /* * User issued close, and wish to trail through shutdown states: * if never received SYN, just forget it. If got a SYN from peer, * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. * If already got a FIN from peer, then almost done; go to LAST_ACK * state. In all other cases, have already sent FIN to peer (e.g. * after PRU_SHUTDOWN), and just have to play tedious game waiting * for peer to send FIN or not respond to keep-alives, etc. * We can let the user exit from the close as soon as the FIN is acked. */ static void tcp_usrclosed(struct tcpcb *tp) { NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(tptoinpcb(tp)); switch (tp->t_state) { case TCPS_LISTEN: #ifdef TCP_OFFLOAD tcp_offload_listen_stop(tp); #endif tcp_state_change(tp, TCPS_CLOSED); /* FALLTHROUGH */ case TCPS_CLOSED: tp = tcp_close(tp); /* * tcp_close() should never return NULL here as the socket is * still open. */ KASSERT(tp != NULL, ("tcp_usrclosed: tcp_close() returned NULL")); break; case TCPS_SYN_SENT: case TCPS_SYN_RECEIVED: tp->t_flags |= TF_NEEDFIN; break; case TCPS_ESTABLISHED: tcp_state_change(tp, TCPS_FIN_WAIT_1); break; case TCPS_CLOSE_WAIT: tcp_state_change(tp, TCPS_LAST_ACK); break; } if (tp->t_acktime == 0) tp->t_acktime = ticks; if (tp->t_state >= TCPS_FIN_WAIT_2) { soisdisconnected(tptosocket(tp)); /* Prevent the connection hanging in FIN_WAIT_2 forever. */ if (tp->t_state == TCPS_FIN_WAIT_2) { int timeout; timeout = (tcp_fast_finwait2_recycle) ? tcp_finwait2_timeout : TP_MAXIDLE(tp); tcp_timer_activate(tp, TT_2MSL, timeout); } } } #ifdef DDB static void db_print_indent(int indent) { int i; for (i = 0; i < indent; i++) db_printf(" "); } static void db_print_tstate(int t_state) { switch (t_state) { case TCPS_CLOSED: db_printf("TCPS_CLOSED"); return; case TCPS_LISTEN: db_printf("TCPS_LISTEN"); return; case TCPS_SYN_SENT: db_printf("TCPS_SYN_SENT"); return; case TCPS_SYN_RECEIVED: db_printf("TCPS_SYN_RECEIVED"); return; case TCPS_ESTABLISHED: db_printf("TCPS_ESTABLISHED"); return; case TCPS_CLOSE_WAIT: db_printf("TCPS_CLOSE_WAIT"); return; case TCPS_FIN_WAIT_1: db_printf("TCPS_FIN_WAIT_1"); return; case TCPS_CLOSING: db_printf("TCPS_CLOSING"); return; case TCPS_LAST_ACK: db_printf("TCPS_LAST_ACK"); return; case TCPS_FIN_WAIT_2: db_printf("TCPS_FIN_WAIT_2"); return; case TCPS_TIME_WAIT: db_printf("TCPS_TIME_WAIT"); return; default: db_printf("unknown"); return; } } static void db_print_tflags(u_int t_flags) { int comma; comma = 0; if (t_flags & TF_ACKNOW) { db_printf("%sTF_ACKNOW", comma ? ", " : ""); comma = 1; } if (t_flags & TF_DELACK) { db_printf("%sTF_DELACK", comma ? ", " : ""); comma = 1; } if (t_flags & TF_NODELAY) { db_printf("%sTF_NODELAY", comma ? ", " : ""); comma = 1; } if (t_flags & TF_NOOPT) { db_printf("%sTF_NOOPT", comma ? ", " : ""); comma = 1; } if (t_flags & TF_SENTFIN) { db_printf("%sTF_SENTFIN", comma ? ", " : ""); comma = 1; } if (t_flags & TF_REQ_SCALE) { db_printf("%sTF_REQ_SCALE", comma ? ", " : ""); comma = 1; } if (t_flags & TF_RCVD_SCALE) { db_printf("%sTF_RECVD_SCALE", comma ? ", " : ""); comma = 1; } if (t_flags & TF_REQ_TSTMP) { db_printf("%sTF_REQ_TSTMP", comma ? ", " : ""); comma = 1; } if (t_flags & TF_RCVD_TSTMP) { db_printf("%sTF_RCVD_TSTMP", comma ? ", " : ""); comma = 1; } if (t_flags & TF_SACK_PERMIT) { db_printf("%sTF_SACK_PERMIT", comma ? ", " : ""); comma = 1; } if (t_flags & TF_NEEDSYN) { db_printf("%sTF_NEEDSYN", comma ? ", " : ""); comma = 1; } if (t_flags & TF_NEEDFIN) { db_printf("%sTF_NEEDFIN", comma ? ", " : ""); comma = 1; } if (t_flags & TF_NOPUSH) { db_printf("%sTF_NOPUSH", comma ? ", " : ""); comma = 1; } if (t_flags & TF_PREVVALID) { db_printf("%sTF_PREVVALID", comma ? ", " : ""); comma = 1; } if (t_flags & TF_MORETOCOME) { db_printf("%sTF_MORETOCOME", comma ? ", " : ""); comma = 1; } if (t_flags & TF_SONOTCONN) { db_printf("%sTF_SONOTCONN", comma ? ", " : ""); comma = 1; } if (t_flags & TF_LASTIDLE) { db_printf("%sTF_LASTIDLE", comma ? ", " : ""); comma = 1; } if (t_flags & TF_RXWIN0SENT) { db_printf("%sTF_RXWIN0SENT", comma ? ", " : ""); comma = 1; } if (t_flags & TF_FASTRECOVERY) { db_printf("%sTF_FASTRECOVERY", comma ? ", " : ""); comma = 1; } if (t_flags & TF_CONGRECOVERY) { db_printf("%sTF_CONGRECOVERY", comma ? ", " : ""); comma = 1; } if (t_flags & TF_WASFRECOVERY) { db_printf("%sTF_WASFRECOVERY", comma ? ", " : ""); comma = 1; } if (t_flags & TF_WASCRECOVERY) { db_printf("%sTF_WASCRECOVERY", comma ? ", " : ""); comma = 1; } if (t_flags & TF_SIGNATURE) { db_printf("%sTF_SIGNATURE", comma ? ", " : ""); comma = 1; } if (t_flags & TF_FORCEDATA) { db_printf("%sTF_FORCEDATA", comma ? ", " : ""); comma = 1; } if (t_flags & TF_TSO) { db_printf("%sTF_TSO", comma ? ", " : ""); comma = 1; } if (t_flags & TF_FASTOPEN) { db_printf("%sTF_FASTOPEN", comma ? ", " : ""); comma = 1; } } static void db_print_tflags2(u_int t_flags2) { int comma; comma = 0; if (t_flags2 & TF2_PLPMTU_BLACKHOLE) { db_printf("%sTF2_PLPMTU_BLACKHOLE", comma ? ", " : ""); comma = 1; } if (t_flags2 & TF2_PLPMTU_PMTUD) { db_printf("%sTF2_PLPMTU_PMTUD", comma ? ", " : ""); comma = 1; } if (t_flags2 & TF2_PLPMTU_MAXSEGSNT) { db_printf("%sTF2_PLPMTU_MAXSEGSNT", comma ? ", " : ""); comma = 1; } if (t_flags2 & TF2_LOG_AUTO) { db_printf("%sTF2_LOG_AUTO", comma ? ", " : ""); comma = 1; } if (t_flags2 & TF2_DROP_AF_DATA) { db_printf("%sTF2_DROP_AF_DATA", comma ? ", " : ""); comma = 1; } if (t_flags2 & TF2_ECN_PERMIT) { db_printf("%sTF2_ECN_PERMIT", comma ? ", " : ""); comma = 1; } if (t_flags2 & TF2_ECN_SND_CWR) { db_printf("%sTF2_ECN_SND_CWR", comma ? ", " : ""); comma = 1; } if (t_flags2 & TF2_ECN_SND_ECE) { db_printf("%sTF2_ECN_SND_ECE", comma ? ", " : ""); comma = 1; } if (t_flags2 & TF2_ACE_PERMIT) { db_printf("%sTF2_ACE_PERMIT", comma ? ", " : ""); comma = 1; } if (t_flags2 & TF2_FBYTES_COMPLETE) { db_printf("%sTF2_FBYTES_COMPLETE", comma ? ", " : ""); comma = 1; } } static void db_print_toobflags(char t_oobflags) { int comma; comma = 0; if (t_oobflags & TCPOOB_HAVEDATA) { db_printf("%sTCPOOB_HAVEDATA", comma ? ", " : ""); comma = 1; } if (t_oobflags & TCPOOB_HADDATA) { db_printf("%sTCPOOB_HADDATA", comma ? ", " : ""); comma = 1; } } static void db_print_tcpcb(struct tcpcb *tp, const char *name, int indent) { db_print_indent(indent); db_printf("%s at %p\n", name, tp); indent += 2; db_print_indent(indent); db_printf("t_segq first: %p t_segqlen: %d t_dupacks: %d\n", TAILQ_FIRST(&tp->t_segq), tp->t_segqlen, tp->t_dupacks); db_print_indent(indent); db_printf("t_callout: %p t_timers: %p\n", &tp->t_callout, &tp->t_timers); db_print_indent(indent); db_printf("t_state: %d (", tp->t_state); db_print_tstate(tp->t_state); db_printf(")\n"); db_print_indent(indent); db_printf("t_flags: 0x%x (", tp->t_flags); db_print_tflags(tp->t_flags); db_printf(")\n"); db_print_indent(indent); db_printf("t_flags2: 0x%x (", tp->t_flags2); db_print_tflags2(tp->t_flags2); db_printf(")\n"); db_print_indent(indent); db_printf("snd_una: 0x%08x snd_max: 0x%08x snd_nxt: x0%08x\n", tp->snd_una, tp->snd_max, tp->snd_nxt); db_print_indent(indent); db_printf("snd_up: 0x%08x snd_wl1: 0x%08x snd_wl2: 0x%08x\n", tp->snd_up, tp->snd_wl1, tp->snd_wl2); db_print_indent(indent); db_printf("iss: 0x%08x irs: 0x%08x rcv_nxt: 0x%08x\n", tp->iss, tp->irs, tp->rcv_nxt); db_print_indent(indent); db_printf("rcv_adv: 0x%08x rcv_wnd: %u rcv_up: 0x%08x\n", tp->rcv_adv, tp->rcv_wnd, tp->rcv_up); db_print_indent(indent); db_printf("snd_wnd: %u snd_cwnd: %u\n", tp->snd_wnd, tp->snd_cwnd); db_print_indent(indent); db_printf("snd_ssthresh: %u snd_recover: " "0x%08x\n", tp->snd_ssthresh, tp->snd_recover); db_print_indent(indent); db_printf("t_rcvtime: %u t_startime: %u\n", tp->t_rcvtime, tp->t_starttime); db_print_indent(indent); db_printf("t_rttime: %u t_rtsq: 0x%08x\n", tp->t_rtttime, tp->t_rtseq); db_print_indent(indent); db_printf("t_rxtcur: %d t_maxseg: %u t_srtt: %d\n", tp->t_rxtcur, tp->t_maxseg, tp->t_srtt); db_print_indent(indent); db_printf("t_rttvar: %d t_rxtshift: %d t_rttmin: %u\n", tp->t_rttvar, tp->t_rxtshift, tp->t_rttmin); db_print_indent(indent); db_printf("t_rttupdated: %lu max_sndwnd: %u t_softerror: %d\n", tp->t_rttupdated, tp->max_sndwnd, tp->t_softerror); db_print_indent(indent); db_printf("t_oobflags: 0x%x (", tp->t_oobflags); db_print_toobflags(tp->t_oobflags); db_printf(") t_iobc: 0x%02x\n", tp->t_iobc); db_print_indent(indent); db_printf("snd_scale: %u rcv_scale: %u request_r_scale: %u\n", tp->snd_scale, tp->rcv_scale, tp->request_r_scale); db_print_indent(indent); db_printf("ts_recent: %u ts_recent_age: %u\n", tp->ts_recent, tp->ts_recent_age); db_print_indent(indent); db_printf("ts_offset: %u last_ack_sent: 0x%08x snd_cwnd_prev: " "%u\n", tp->ts_offset, tp->last_ack_sent, tp->snd_cwnd_prev); db_print_indent(indent); db_printf("snd_ssthresh_prev: %u snd_recover_prev: 0x%08x " "t_badrxtwin: %u\n", tp->snd_ssthresh_prev, tp->snd_recover_prev, tp->t_badrxtwin); db_print_indent(indent); db_printf("snd_numholes: %d snd_holes first: %p\n", tp->snd_numholes, TAILQ_FIRST(&tp->snd_holes)); db_print_indent(indent); db_printf("snd_fack: 0x%08x rcv_numsacks: %d\n", tp->snd_fack, tp->rcv_numsacks); /* Skip sackblks, sackhint. */ db_print_indent(indent); db_printf("t_rttlow: %d rfbuf_ts: %u rfbuf_cnt: %d\n", tp->t_rttlow, tp->rfbuf_ts, tp->rfbuf_cnt); } DB_SHOW_COMMAND(tcpcb, db_show_tcpcb) { struct tcpcb *tp; if (!have_addr) { db_printf("usage: show tcpcb \n"); return; } tp = (struct tcpcb *)addr; db_print_tcpcb(tp, "tcpcb", 0); } #endif diff --git a/usr.bin/systat/netstat.c b/usr.bin/systat/netstat.c index 33e13cc5c906..4b602578b077 100644 --- a/usr.bin/systat/netstat.c +++ b/usr.bin/systat/netstat.c @@ -1,642 +1,641 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1980, 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ #include __FBSDID("$FreeBSD$"); #ifdef lint static const char sccsid[] = "@(#)netstat.c 8.1 (Berkeley) 6/6/93"; #endif /* * netstat */ #include #include #include #include #define _WANT_SOCKET #include #include #include #include #include #include #include #ifdef INET6 #include #endif #define _WANT_INPCB #include #include #include #include #include #include #include #define TCPSTATES #include #include #define _WANT_TCPCB #include -#include #include #include #include #include #include #include #include #include "systat.h" #include "extern.h" static struct netinfo *enter(struct in_conninfo *, uint8_t, int, const char *); static void enter_kvm(struct inpcb *, struct socket *, int, const char *); static void enter_sysctl(struct xinpcb *, struct xsocket *, int, const char *); static void fetchnetstat_kvm(void); static void fetchnetstat_sysctl(void); static char *inetname(struct sockaddr *); static void inetprint(struct sockaddr *, const char *); #define streq(a,b) (strcmp(a,b)==0) #define YMAX(w) (getmaxy(w)-2) WINDOW * opennetstat(void) { sethostent(1); setnetent(1); return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0)); } struct netinfo { TAILQ_ENTRY(netinfo) chain; short ni_line; /* line on screen */ short ni_seen; /* 0 when not present in list */ short ni_flags; #define NIF_LACHG 0x1 /* local address changed */ #define NIF_FACHG 0x2 /* foreign address changed */ short ni_state; /* tcp state */ const char *ni_proto; /* protocol */ struct sockaddr_storage ni_lsa; /* local address */ struct sockaddr_storage ni_fsa; /* foreign address */ u_int ni_rcvcc; /* rcv buffer character count */ u_int ni_sndcc; /* snd buffer character count */ }; static TAILQ_HEAD(netinfohead, netinfo) netcb = TAILQ_HEAD_INITIALIZER(netcb); static int aflag = 0; static int nflag = 0; static int lastrow = 1; void closenetstat(WINDOW *w) { struct netinfo *p; endhostent(); endnetent(); TAILQ_FOREACH(p, &netcb, chain) { if (p->ni_line != -1) lastrow--; p->ni_line = -1; } if (w != NULL) { wclear(w); wrefresh(w); delwin(w); } } static const char *miblist[] = { "net.inet.tcp.pcblist", "net.inet.udp.pcblist" }; static char tcb[] = "tcb", udb[] = "udb"; struct nlist namelist[] = { #define X_TCB 0 { .n_name = tcb }, #define X_UDB 1 { .n_name = udb }, { .n_name = NULL }, }; int initnetstat(void) { protos = TCP|UDP; return(1); } void fetchnetstat(void) { if (use_kvm) fetchnetstat_kvm(); else fetchnetstat_sysctl(); } static void fetchnetstat_kvm(void) { struct inpcb *next; struct netinfo *p; struct inpcbhead head; struct inpcb inpcb; struct socket sockb; struct tcpcb tcpcb; void *off; int istcp; if (namelist[X_TCB].n_value == 0) return; TAILQ_FOREACH(p, &netcb, chain) p->ni_seen = 0; if (protos&TCP) { off = NPTR(X_TCB); istcp = 1; } else if (protos&UDP) { off = NPTR(X_UDB); istcp = 0; } else { error("No protocols to display"); return; } again: KREAD(off, &head, sizeof (struct inpcbhead)); LIST_FOREACH(next, &head, inp_list) { KREAD(next, &inpcb, sizeof (inpcb)); next = &inpcb; if (!aflag) { if (inpcb.inp_vflag & INP_IPV4) { if (inpcb.inp_laddr.s_addr == INADDR_ANY) continue; } #ifdef INET6 else if (inpcb.inp_vflag & INP_IPV6) { if (memcmp(&inpcb.in6p_laddr, &in6addr_any, sizeof(in6addr_any)) == 0) continue; } #endif } if (nhosts && !checkhost(&inpcb.inp_inc)) continue; if (nports && !checkport(&inpcb.inp_inc)) continue; if (istcp) { KREAD(inpcb.inp_socket, &sockb, sizeof (sockb)); KREAD(inpcb.inp_ppcb, &tcpcb, sizeof (tcpcb)); enter_kvm(&inpcb, &sockb, tcpcb.t_state, "tcp"); } else enter_kvm(&inpcb, &sockb, 0, "udp"); } if (istcp && (protos&UDP)) { istcp = 0; off = NPTR(X_UDB); goto again; } } static void fetchnetstat_sysctl(void) { struct netinfo *p; int idx; struct xinpgen *inpg; char *cur, *end; struct xinpcb *xip = NULL; struct xtcpcb *xtp = NULL; int plen; size_t lsz; TAILQ_FOREACH(p, &netcb, chain) p->ni_seen = 0; if (protos&TCP) { idx = 0; } else if (protos&UDP) { idx = 1; } else { error("No protocols to display"); return; } for (;idx < 2; idx++) { if (idx == 1 && !(protos&UDP)) break; inpg = (struct xinpgen *)sysctl_dynread(miblist[idx], &lsz); if (inpg == NULL) { error("sysctl(%s...) failed", miblist[idx]); continue; } /* * We currently do no require a consistent pcb list. * Try to be robust in case of struct size changes */ cur = ((char *)inpg) + inpg->xig_len; /* There is also a trailing struct xinpgen */ end = ((char *)inpg) + lsz - inpg->xig_len; if (end <= cur) { free(inpg); continue; } if (idx == 0) { /* TCP */ xtp = (struct xtcpcb *)cur; plen = xtp->xt_len; } else { xip = (struct xinpcb *)cur; plen = xip->xi_len; } while (cur + plen <= end) { if (idx == 0) { /* TCP */ xtp = (struct xtcpcb *)cur; xip = &xtp->xt_inp; } else { xip = (struct xinpcb *)cur; } cur += plen; if (!aflag) { if (xip->inp_vflag & INP_IPV4) { if (xip->inp_laddr.s_addr == INADDR_ANY) continue; } #ifdef INET6 else if (xip->inp_vflag & INP_IPV6) { if (memcmp(&xip->in6p_laddr, &in6addr_any, sizeof(in6addr_any)) == 0) continue; } #endif } if (nhosts && !checkhost(&xip->inp_inc)) continue; if (nports && !checkport(&xip->inp_inc)) continue; if (idx == 0) enter_sysctl(xip, &xip->xi_socket, xtp->t_state, "tcp"); else enter_sysctl(xip, &xip->xi_socket, 0, "udp"); } free(inpg); } } static void enter_kvm(struct inpcb *inp, struct socket *so, int state, const char *proto) { struct netinfo *p; if ((p = enter(&inp->inp_inc, inp->inp_vflag, state, proto)) != NULL) { p->ni_rcvcc = so->so_rcv.sb_ccc; p->ni_sndcc = so->so_snd.sb_ccc; } } static void enter_sysctl(struct xinpcb *xip, struct xsocket *so, int state, const char *proto) { struct netinfo *p; if ((p = enter(&xip->inp_inc, xip->inp_vflag, state, proto)) != NULL) { p->ni_rcvcc = so->so_rcv.sb_cc; p->ni_sndcc = so->so_snd.sb_cc; } } static struct netinfo * enter(struct in_conninfo *inc, uint8_t vflag, int state, const char *proto) { struct netinfo *p; struct sockaddr_storage lsa, fsa; struct sockaddr_in *sa4; #ifdef INET6 struct sockaddr_in6 *sa6; #endif memset(&lsa, 0, sizeof(lsa)); memset(&fsa, 0, sizeof(fsa)); if (vflag & INP_IPV4) { sa4 = (struct sockaddr_in *)&lsa; sa4->sin_addr = inc->inc_laddr; sa4->sin_port = inc->inc_lport; sa4->sin_family = AF_INET; sa4->sin_len = sizeof(struct sockaddr_in); sa4 = (struct sockaddr_in *)&fsa; sa4->sin_addr = inc->inc_faddr; sa4->sin_port = inc->inc_fport; sa4->sin_family = AF_INET; sa4->sin_len = sizeof(struct sockaddr_in); } #ifdef INET6 else if (vflag & INP_IPV6) { sa6 = (struct sockaddr_in6 *)&lsa; memcpy(&sa6->sin6_addr, &inc->inc6_laddr, sizeof(struct in6_addr)); sa6->sin6_port = inc->inc_lport; sa6->sin6_family = AF_INET6; sa6->sin6_len = sizeof(struct sockaddr_in6); sa6 = (struct sockaddr_in6 *)&fsa; memcpy(&sa6->sin6_addr, &inc->inc6_faddr, sizeof(struct in6_addr)); sa6->sin6_port = inc->inc_fport; sa6->sin6_family = AF_INET6; sa6->sin6_len = sizeof(struct sockaddr_in6); } #endif else return NULL; /* * Only take exact matches, any sockets with * previously unbound addresses will be deleted * below in the display routine because they * will appear as ``not seen'' in the kernel * data structures. */ TAILQ_FOREACH(p, &netcb, chain) { if (!streq(proto, p->ni_proto)) continue; if (p->ni_lsa.ss_family != lsa.ss_family || memcmp(&p->ni_lsa, &lsa, lsa.ss_len) != 0) continue; if (p->ni_fsa.ss_family == fsa.ss_family && memcmp(&p->ni_fsa, &fsa, fsa.ss_len) == 0) break; } if (p == NULL) { if ((p = malloc(sizeof(*p))) == NULL) { error("Out of memory"); return NULL; } TAILQ_INSERT_HEAD(&netcb, p, chain); p->ni_line = -1; memcpy(&p->ni_lsa, &lsa, lsa.ss_len); memcpy(&p->ni_fsa, &fsa, fsa.ss_len); p->ni_proto = strdup(proto); p->ni_flags = NIF_LACHG|NIF_FACHG; } p->ni_state = state; p->ni_seen = 1; return p; } /* column locations */ #define LADDR 0 #define FADDR LADDR+23 #define PROTO FADDR+23 #define RCVCC PROTO+6 #define SNDCC RCVCC+7 #define STATE SNDCC+7 void labelnetstat(void) { if (use_kvm && namelist[X_TCB].n_type == 0) return; wmove(wnd, 0, 0); wclrtobot(wnd); mvwaddstr(wnd, 0, LADDR, "Local Address"); mvwaddstr(wnd, 0, FADDR, "Foreign Address"); mvwaddstr(wnd, 0, PROTO, "Proto"); mvwaddstr(wnd, 0, RCVCC, "Recv-Q"); mvwaddstr(wnd, 0, SNDCC, "Send-Q"); mvwaddstr(wnd, 0, STATE, "(state)"); } void shownetstat(void) { struct netinfo *p, *q; char proto[6]; const char *family = ""; /* * First, delete any connections that have gone * away and adjust the position of connections * below to reflect the deleted line. */ p = TAILQ_FIRST(&netcb); while (p != NULL) { if (p->ni_line == -1 || p->ni_seen) { p = TAILQ_NEXT(p, chain); continue; } wmove(wnd, p->ni_line, 0); wdeleteln(wnd); TAILQ_FOREACH(q, &netcb, chain) if (q != p && q->ni_line > p->ni_line) { q->ni_line--; /* this shouldn't be necessary */ q->ni_flags |= NIF_LACHG|NIF_FACHG; } lastrow--; q = TAILQ_NEXT(p, chain); TAILQ_REMOVE(&netcb, p, chain); free(p); p = q; } /* * Update existing connections and add new ones. */ TAILQ_FOREACH(p, &netcb, chain) { if (p->ni_line == -1) { /* * Add a new entry if possible. */ if (lastrow > YMAX(wnd)) continue; p->ni_line = lastrow++; p->ni_flags |= NIF_LACHG|NIF_FACHG; } if (p->ni_flags & NIF_LACHG) { wmove(wnd, p->ni_line, LADDR); inetprint((struct sockaddr *)&p->ni_lsa, p->ni_proto); p->ni_flags &= ~NIF_LACHG; } if (p->ni_flags & NIF_FACHG) { wmove(wnd, p->ni_line, FADDR); inetprint((struct sockaddr *)&p->ni_fsa, p->ni_proto); p->ni_flags &= ~NIF_FACHG; } #ifdef INET6 family = (p->ni_lsa.ss_family == AF_INET) ? "4" : "6"; #endif snprintf(proto, sizeof(proto), "%s%s", p->ni_proto, family); mvwaddstr(wnd, p->ni_line, PROTO, proto); mvwprintw(wnd, p->ni_line, RCVCC, "%6u", p->ni_rcvcc); mvwprintw(wnd, p->ni_line, SNDCC, "%6u", p->ni_sndcc); if (streq(p->ni_proto, "tcp")) { if (p->ni_state < 0 || p->ni_state >= TCP_NSTATES) mvwprintw(wnd, p->ni_line, STATE, "%d", p->ni_state); else mvwaddstr(wnd, p->ni_line, STATE, tcpstates[p->ni_state]); } wclrtoeol(wnd); } if (lastrow < YMAX(wnd)) { wmove(wnd, lastrow, 0); wclrtobot(wnd); wmove(wnd, YMAX(wnd), 0); wdeleteln(wnd); /* XXX */ } } /* * Pretty print an Internet address (net address + port). * If the nflag was specified, use numbers instead of names. */ static void inetprint(struct sockaddr *sa, const char *proto) { struct servent *sp = 0; char line[80], *cp; int port; switch (sa->sa_family) { case AF_INET: port = ((struct sockaddr_in *)sa)->sin_port; break; #ifdef INET6 case AF_INET6: port = ((struct sockaddr_in6 *)sa)->sin6_port; break; #endif default: port = 0; break; } snprintf(line, sizeof(line), "%.*s.", 16, inetname(sa)); cp = strchr(line, '\0'); if (!nflag && port) sp = getservbyport(port, proto); if (sp || port == 0) snprintf(cp, sizeof(line) - (cp - line), "%.8s", sp ? sp->s_name : "*"); else snprintf(cp, sizeof(line) - (cp - line), "%d", ntohs((u_short)port)); /* pad to full column to clear any garbage */ cp = strchr(line, '\0'); while (cp - line < 22) *cp++ = ' '; line[22] = '\0'; waddstr(wnd, line); } /* * Construct an Internet address representation. * If the nflag has been supplied, give * numeric value, otherwise try for symbolic name. */ static char * inetname(struct sockaddr *sa) { char *cp = 0; static char line[NI_MAXHOST]; struct hostent *hp; struct in_addr in; #ifdef INET6 if (sa->sa_family == AF_INET6) { if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0) strcpy(line, "*"); else getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0, nflag ? NI_NUMERICHOST : 0); return (line); } #endif in = ((struct sockaddr_in *)sa)->sin_addr; if (!nflag && in.s_addr != INADDR_ANY) { hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET); if (hp) cp = hp->h_name; } if (in.s_addr == INADDR_ANY) strcpy(line, "*"); else if (cp) snprintf(line, sizeof(line), "%s", cp); else { in.s_addr = ntohl(in.s_addr); #define C(x) ((x) & 0xff) snprintf(line, sizeof(line), "%u.%u.%u.%u", C(in.s_addr >> 24), C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr)); } return (line); } int cmdnetstat(const char *cmd, const char *args) { if (prefix(cmd, "all")) { aflag = !aflag; goto fixup; } if (prefix(cmd, "numbers") || prefix(cmd, "names")) { struct netinfo *p; int new; new = prefix(cmd, "numbers"); if (new == nflag) return (1); TAILQ_FOREACH(p, &netcb, chain) { if (p->ni_line == -1) continue; p->ni_flags |= NIF_LACHG|NIF_FACHG; } nflag = new; goto redisplay; } if (!netcmd(cmd, args)) return (0); fixup: fetchnetstat(); redisplay: shownetstat(); refresh(); return (1); }