diff options
Diffstat (limited to 'scripts/package-build')
127 files changed, 29406 insertions, 777 deletions
diff --git a/scripts/package-build/opennhrp/.gitignore b/scripts/package-build/.gitignore index 65d0752b..a1b8b226 100644 --- a/scripts/package-build/opennhrp/.gitignore +++ b/scripts/package-build/.gitignore @@ -1,6 +1,8 @@ -opennhrp/ *.buildinfo *.build *.changes *.deb +*.udeb *.dsc +*.tar.gz +*.tar.xz diff --git a/scripts/package-build/amazon-cloudwatch-agent/.gitignore b/scripts/package-build/amazon-cloudwatch-agent/.gitignore new file mode 100644 index 00000000..5eb3e42a --- /dev/null +++ b/scripts/package-build/amazon-cloudwatch-agent/.gitignore @@ -0,0 +1 @@ +/amazon-cloudwatch-agent/ diff --git a/scripts/package-build/opennhrp/build.py b/scripts/package-build/amazon-cloudwatch-agent/build.py index 3c76af73..3c76af73 120000 --- a/scripts/package-build/opennhrp/build.py +++ b/scripts/package-build/amazon-cloudwatch-agent/build.py diff --git a/scripts/package-build/amazon-cloudwatch-agent/package.toml b/scripts/package-build/amazon-cloudwatch-agent/package.toml new file mode 100644 index 00000000..120a17f9 --- /dev/null +++ b/scripts/package-build/amazon-cloudwatch-agent/package.toml @@ -0,0 +1,14 @@ +[[packages]] +name = "amazon-cloudwatch-agent" +commit_id = "v1.300050.0" +scm_url = "https://github.com/aws/amazon-cloudwatch-agent" + +build_cmd = """ + +make clean test check_secrets amazon-cloudwatch-agent-linux package-deb +ARCH=$(dpkg --print-architecture) +TAG=$(git describe --tags --abbrev=0) +COMMIT=$(git rev-parse --short HEAD) +cp ./build/bin/linux/${ARCH}/*.deb ../amazon-cloudwatch-agent_${TAG}_${COMMIT}_${ARCH}.deb + +""" diff --git a/scripts/package-build/amazon-ssm-agent/.gitignore b/scripts/package-build/amazon-ssm-agent/.gitignore new file mode 100644 index 00000000..78fa9ab9 --- /dev/null +++ b/scripts/package-build/amazon-ssm-agent/.gitignore @@ -0,0 +1 @@ +/amazon-ssm-agent/ diff --git a/scripts/package-build/pam_tacplus/build.py b/scripts/package-build/amazon-ssm-agent/build.py index 3c76af73..3c76af73 120000 --- a/scripts/package-build/pam_tacplus/build.py +++ b/scripts/package-build/amazon-ssm-agent/build.py diff --git a/scripts/package-build/amazon-ssm-agent/package.toml b/scripts/package-build/amazon-ssm-agent/package.toml new file mode 100644 index 00000000..ecd2fdf6 --- /dev/null +++ b/scripts/package-build/amazon-ssm-agent/package.toml @@ -0,0 +1,16 @@ +[[packages]] +name = "amazon-ssm-agent" +commit_id = "3.3.1311.0" +scm_url = "https://github.com/aws/amazon-ssm-agent" + +build_cmd = """ + +ARCH=$(dpkg --print-architecture) +TAG=$(git describe --tags --abbrev=0) +COMMIT=$(git rev-parse --short HEAD) + +make build-linux +make package-deb +cp ./bin/debian_${ARCH}/*.deb ../amazon-ssm-agent_${TAG}_${COMMIT}_${ARCH}.deb + +""" diff --git a/scripts/package-build/aws-gwlbtun/.gitignore b/scripts/package-build/aws-gwlbtun/.gitignore index 0fe7946f..dab49f62 100644 --- a/scripts/package-build/aws-gwlbtun/.gitignore +++ b/scripts/package-build/aws-gwlbtun/.gitignore @@ -1,8 +1 @@ -aws-gwlbtun*/ -*.tar.gz -*.tar.xz -*.deb -*.dsc -*.buildinfo -*.build -*.changes
\ No newline at end of file +/aws-gwlbtun*/ diff --git a/scripts/package-build/bash-completion/.gitignore b/scripts/package-build/bash-completion/.gitignore new file mode 100644 index 00000000..73e9d517 --- /dev/null +++ b/scripts/package-build/bash-completion/.gitignore @@ -0,0 +1 @@ +/bash-completion/ diff --git a/scripts/package-build/bash-completion/build.py b/scripts/package-build/bash-completion/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/bash-completion/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/bash-completion/package.toml b/scripts/package-build/bash-completion/package.toml new file mode 100644 index 00000000..49667429 --- /dev/null +++ b/scripts/package-build/bash-completion/package.toml @@ -0,0 +1,12 @@ +# VyOS CLI requires an older version of bash-completion to work + +[[packages]] +name = "bash-completion" +commit_id = "debian/2.8-6" +scm_url = "https://salsa.debian.org/debian/bash-completion" + +build_cmd = """ + +# Build deb +dpkg-buildpackage -b -us -uc +""" diff --git a/scripts/package-build/blackbox_exporter/.gitignore b/scripts/package-build/blackbox_exporter/.gitignore new file mode 100644 index 00000000..435e791f --- /dev/null +++ b/scripts/package-build/blackbox_exporter/.gitignore @@ -0,0 +1 @@ +/blackbox_exporter/ diff --git a/scripts/package-build/blackbox_exporter/build.py b/scripts/package-build/blackbox_exporter/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/blackbox_exporter/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/blackbox_exporter/build.sh b/scripts/package-build/blackbox_exporter/build.sh new file mode 100755 index 00000000..127c03be --- /dev/null +++ b/scripts/package-build/blackbox_exporter/build.sh @@ -0,0 +1,66 @@ +#!/bin/sh +CWD=$(pwd) +set -e + +BUILD_ARCH=$(dpkg-architecture -qDEB_TARGET_ARCH) + +SRC="blackbox_exporter" +if [ ! -d ${SRC} ]; then + echo "Source directory does not exist, please 'git clone'" + exit 1 +fi + +cd $SRC + +mkdir -p debian + +echo "I: Create $SRC/debian/control" +cat <<EOF > debian/control +Source: blackbox-exporter +Section: net +Priority: optional +Maintainer: VyOS Package Maintainers <maintainers@vyos.net> +Build-Depends: debhelper-compat (= 13) +Standards-Version: 4.5.1 +Homepage: https://github.com/prometheus/blackbox_exporter + +Package: blackbox-exporter +Architecture: ${BUILD_ARCH} +Depends: \${shlibs:Depends}, \${misc:Depends} +Description: The blackbox exporter allows blackbox probing of endpoints over HTTP, HTTPS, DNS, TCP, ICMP and gRPC. +EOF + +echo "I: Create $SRC/debian/changelog" +cat <<EOF > debian/changelog +blackbox-exporter (0.26.0) UNRELEASED; urgency=medium + + * Upstream package + + -- VyOS Maintainers <maintainers@vyos.io> Thu, 26 Sep 2024 12:35:47 +0000 +EOF + +echo "I: Create $SRC/debian/rules" +cat <<EOF > debian/rules +#!/usr/bin/make -f + +clean: + @# Do nothing + +build: + @# Do nothing + +binary: + mkdir -p debian/blackbox-exporter + mkdir -p debian/blackbox-exporter/usr/sbin + mkdir -p debian/blackbox-exporter/run/blackbox_exporter + cp blackbox_exporter debian/blackbox-exporter/usr/sbin/blackbox_exporter + dh_gencontrol + dh_builddeb +EOF +chmod +x debian/rules + +echo "I: Build blackbox_exporter" +go build + +echo "I: Build Debian Package" +dpkg-buildpackage -uc -us -tc -b -d diff --git a/scripts/package-build/blackbox_exporter/package.toml b/scripts/package-build/blackbox_exporter/package.toml new file mode 100644 index 00000000..a59a3fdd --- /dev/null +++ b/scripts/package-build/blackbox_exporter/package.toml @@ -0,0 +1,5 @@ +[[packages]] +name = "blackbox_exporter" +commit_id = "v0.26.0" +scm_url = "https://github.com/prometheus/blackbox_exporter" +build_cmd = "cd ..; y | ./build.sh" diff --git a/scripts/package-build/build.py b/scripts/package-build/build.py index 99180e17..9c1df7b3 100755 --- a/scripts/package-build/build.py +++ b/scripts/package-build/build.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2024 VyOS maintainers and contributors +# Copyright (C) 2024-2025 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -58,7 +58,6 @@ def apply_patches(repo_dir: Path, patch_dir: Path) -> None: series.write(patch.name + '\n') print(f"I: Applied patch: {patch.name}") - def prepare_package(repo_dir: Path, install_data: str) -> None: """Prepare a package""" if not install_data: @@ -75,12 +74,11 @@ def prepare_package(repo_dir: Path, install_data: str) -> None: raise -def build_package(package: list, dependencies: list, patch_dir: Path) -> None: +def build_package(package: list, patch_dir: Path) -> None: """Build a package from the repository Args: package (list): List of Packages from toml - dependencies (list): List of additional dependencies patch_dir (Path): Directory containing patches """ repo_name = package['name'] @@ -94,12 +92,51 @@ def build_package(package: list, dependencies: list, patch_dir: Path) -> None: # Check out the specific commit run(['git', 'checkout', package['commit_id']], cwd=repo_dir, check=True) - # Ensure dependencies - ensure_dependencies(dependencies) - - # Apply patches if any - if (repo_dir / 'patches'): - apply_patches(repo_dir, patch_dir) + # The `pre_build_hook` is an optional configuration defined in `package.toml`. + # It executes after the repository is checked out and before the build process begins. + # This hook allows you to perform preparatory tasks, such as creating directories, + # copying files, or running custom scripts/commands. + # + # Usage: + # - Single command: + # pre_build_hook = "echo 'Hello Pre-Build-Hook'" + # + # - Multi-line commands: + # pre_build_hook = """ + # mkdir -p ../hello/vyos + # mkdir -p ../vyos + # cp example.txt ../vyos + # """ + # + # - Combination of commands and scripts: + # pre_build_hook = "ls -l; ./script.sh" + pre_build_hook = package.get('pre_build_hook', '') + if pre_build_hook: + try: + print(f'I: execute pre_build_hook for the package "{repo_name}"') + run(pre_build_hook, cwd=repo_dir, check=True, shell=True) + except CalledProcessError as e: + print(e) + print(f"I: pre_build_hook failed for the {repo_name}") + raise + + # Apply patches if the 'apply_patches' key is set to True (default) in the package configuration + # This allows skipping patch application for specific packages when desired + # + # Usage: + # apply_patches = false + # + # Default to True if the key is missing + if package.get('apply_patches', True): + # Check if the 'patches' directory exists in the repository + if (repo_dir / 'patches'): + apply_patches(repo_dir, patch_dir / repo_name) + + # Sanitize the commit ID and build a tarball for the package + commit_id_sanitized = package['commit_id'].replace('/', '_') + tarball_name = f"{repo_name}_{commit_id_sanitized}.tar.gz" + run(['tar', '-czf', tarball_name, '-C', str(repo_dir.parent), repo_name], check=True) + print(f"I: Tarball created: {tarball_name}") # Prepare the package if required if package.get('prepare_package', False): @@ -171,11 +208,14 @@ if __name__ == '__main__': packages = config['packages'] patch_dir = Path(args.patch_dir) - for package in packages: - dependencies = package.get('dependencies', {}).get('packages', []) + # Load global dependencies + global_dependencies = config.get('dependencies', {}).get('packages', []) + if global_dependencies: + ensure_dependencies(global_dependencies) + for package in packages: # Build the package - build_package(package, dependencies, patch_dir) + build_package(package, patch_dir) # Clean up build dependency packages after build cleanup_build_deps(Path(package['name'])) diff --git a/scripts/package-build/ddclient/.gitignore b/scripts/package-build/ddclient/.gitignore index aeb8af66..17d0b753 100644 --- a/scripts/package-build/ddclient/.gitignore +++ b/scripts/package-build/ddclient/.gitignore @@ -1,7 +1 @@ -ddclient/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc - +/ddclient/ diff --git a/scripts/package-build/dropbear/.gitignore b/scripts/package-build/dropbear/.gitignore index 6e8cff9c..58c2ff3d 100644 --- a/scripts/package-build/dropbear/.gitignore +++ b/scripts/package-build/dropbear/.gitignore @@ -1,7 +1 @@ -dropbear/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc - +/dropbear/ diff --git a/scripts/package-build/dropbear/package.toml b/scripts/package-build/dropbear/package.toml index cbb885ee..a00aad3d 100644 --- a/scripts/package-build/dropbear/package.toml +++ b/scripts/package-build/dropbear/package.toml @@ -3,5 +3,5 @@ name = "dropbear" commit_id = "debian/2022.83-1+deb12u1" scm_url = "https://salsa.debian.org/debian/dropbear.git" -[packages.dependencies] -packages = ["libpam0g-dev"]
\ No newline at end of file +[dependencies] +packages = ["libpam0g-dev"] diff --git a/scripts/package-build/dropbear/patches/0001-Enable-PAM-support.patch b/scripts/package-build/dropbear/patches/dropbear/0001-Enable-PAM-support.patch index fa6cf620..fa6cf620 100644 --- a/scripts/package-build/dropbear/patches/0001-Enable-PAM-support.patch +++ b/scripts/package-build/dropbear/patches/dropbear/0001-Enable-PAM-support.patch diff --git a/scripts/package-build/ethtool/.gitignore b/scripts/package-build/ethtool/.gitignore index f964bd07..16adf9e5 100644 --- a/scripts/package-build/ethtool/.gitignore +++ b/scripts/package-build/ethtool/.gitignore @@ -1,7 +1 @@ -ethtool/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc - +/ethtool/ diff --git a/scripts/package-build/ethtool/package.toml b/scripts/package-build/ethtool/package.toml index 9468ed82..ec22a06c 100644 --- a/scripts/package-build/ethtool/package.toml +++ b/scripts/package-build/ethtool/package.toml @@ -1,4 +1,4 @@ [[packages]] name = "ethtool" -commit_id = "debian/1%6.6-1" +commit_id = "debian/1%6.10-1" scm_url = "https://salsa.debian.org/kernel-team/ethtool" diff --git a/scripts/package-build/frr/.gitignore b/scripts/package-build/frr/.gitignore index 590895c0..93dfaca8 100644 --- a/scripts/package-build/frr/.gitignore +++ b/scripts/package-build/frr/.gitignore @@ -1,8 +1,3 @@ -frr/ -rtrlib/ -libyang/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc +/frr/ +/rtrlib/ +/libyang/ diff --git a/scripts/package-build/frr/package.toml b/scripts/package-build/frr/package.toml index 48d51ae6..8ff35777 100644 --- a/scripts/package-build/frr/package.toml +++ b/scripts/package-build/frr/package.toml @@ -1,6 +1,6 @@ [[packages]] name = "libyang" -commit_id = "v2.1.148" +commit_id = "v3.4.2" scm_url = "https://github.com/CESNET/libyang.git" build_cmd = "pipx run apkg build -i && find pkg/pkgs -type f -name *.deb -exec mv -t .. {} +" @@ -8,20 +8,20 @@ build_cmd = "pipx run apkg build -i && find pkg/pkgs -type f -name *.deb -exec m name = "rtrlib" commit_id = "v0.8.0" scm_url = "https://github.com/rtrlib/rtrlib.git" -build_cmd = "sudo mk-build-deps --install --tool 'apt-get --yes --no-install-recommends'; dpkg-buildpackage -uc -us -tc -b" [[packages]] name = "frr" -commit_id = "stable/9.1" +commit_id = "stable/10.2" scm_url = "https://github.com/FRRouting/frr.git" -build_cmd = "sudo dpkg -i ../*.deb; sudo dpkg-buildpackage -us -uc -tc -b -Ppkg.frr.rtrlib,pkg.frr.lua" +build_cmd = "sudo dpkg -i ../*.deb; dpkg-buildpackage -us -uc -tc -b -Ppkg.frr.rtrlib,pkg.frr.lua" -[packages.dependencies] +[dependencies] packages = [ "chrpath", "gawk", "install-info", "libcap-dev", + "libc-ares-dev", "libjson-c-dev", "librtr-dev", "libpam-dev", @@ -32,5 +32,6 @@ packages = [ "protobuf-c-compiler", "python3-dev:native", "texinfo", - "lua5.3" + "lua5.3", + "doxygen" ] diff --git a/scripts/package-build/frr/patches/frr/0001-Enable-PCRE2-in-Debian-package-builds.patch b/scripts/package-build/frr/patches/frr/0001-Enable-PCRE2-in-Debian-package-builds.patch new file mode 100644 index 00000000..545e7d5e --- /dev/null +++ b/scripts/package-build/frr/patches/frr/0001-Enable-PCRE2-in-Debian-package-builds.patch @@ -0,0 +1,24 @@ +From 21800432167ac022c01772df993efca8d4969b38 Mon Sep 17 00:00:00 2001 +From: Daniil Baturin <daniil@baturin.org> +Date: Wed, 6 Nov 2024 15:58:10 +0000 +Subject: [PATCH] Enable PCRE2 in Debian package builds + +--- + debian/rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/debian/rules b/debian/rules +index 43e5d7e61..1f971ab22 100755 +--- a/debian/rules ++++ b/debian/rules +@@ -69,6 +69,7 @@ override_dh_auto_configure: + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ ++ --enable-pcre2posix \ + # end + + override_dh_auto_install: +-- +2.47.0 + diff --git a/scripts/package-build/frr/patches/frr/0001-ldpd-Option-for-disabled-LDP-hello-message-during-TC.patch b/scripts/package-build/frr/patches/frr/0001-ldpd-Option-for-disabled-LDP-hello-message-during-TC.patch new file mode 100644 index 00000000..67f85d01 --- /dev/null +++ b/scripts/package-build/frr/patches/frr/0001-ldpd-Option-for-disabled-LDP-hello-message-during-TC.patch @@ -0,0 +1,176 @@ +From 945eff42df61982585011fa8427050c74ca90c6b Mon Sep 17 00:00:00 2001 +From: Andrii Melnychenko <a.melnychenko@vyos.io> +Date: Mon, 17 Mar 2025 13:25:20 +0100 +Subject: [PATCH 1/1] ldpd: Option for disabled LDP hello message during TCP + +Added option "disable-establish-hello" that disableds +sending additional LDP hello multicast messages during +TCP session establishment. +This option enables per interface: "(config-ldp-af-if)". + +Signed-off-by: Andrii Melnychenko <a.melnychenko@vyos.io> +--- + ldpd/interface.c | 2 ++ + ldpd/ldp_vty.h | 1 + + ldpd/ldp_vty_cmds.c | 11 +++++++++++ + ldpd/ldp_vty_conf.c | 32 ++++++++++++++++++++++++++++++++ + ldpd/ldpd.c | 1 + + ldpd/ldpd.h | 1 + + ldpd/neighbor.c | 5 +++-- + 7 files changed, 51 insertions(+), 2 deletions(-) + +diff --git a/ldpd/interface.c b/ldpd/interface.c +index f0e70cbac..6fccd4af5 100644 +--- a/ldpd/interface.c ++++ b/ldpd/interface.c +@@ -63,11 +63,13 @@ if_new(const char *name) + iface->ipv4.af = AF_INET; + iface->ipv4.iface = iface; + iface->ipv4.enabled = 0; ++ iface->ipv4.disable_establish_hello = 0; + + /* ipv6 */ + iface->ipv6.af = AF_INET6; + iface->ipv6.iface = iface; + iface->ipv6.enabled = 0; ++ iface->ipv6.disable_establish_hello = 0; + + return (iface); + } +diff --git a/ldpd/ldp_vty.h b/ldpd/ldp_vty.h +index 5c83d1c56..196d05c93 100644 +--- a/ldpd/ldp_vty.h ++++ b/ldpd/ldp_vty.h +@@ -24,6 +24,7 @@ int ldp_vty_allow_broken_lsp(struct vty *, const char *); + int ldp_vty_address_family (struct vty *, const char *, const char *); + int ldp_vty_disc_holdtime(struct vty *, const char *, enum hello_type, long); + int ldp_vty_disc_interval(struct vty *, const char *, enum hello_type, long); ++int ldp_vty_disable_establish_hello(struct vty *, const char *); + int ldp_vty_targeted_hello_accept(struct vty *, const char *, const char *); + int ldp_vty_nbr_session_holdtime(struct vty *, const char *, struct in_addr, long); + int ldp_vty_af_session_holdtime(struct vty *, const char *, long); +diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c +index e046ae996..d6c36c35b 100644 +--- a/ldpd/ldp_vty_cmds.c ++++ b/ldpd/ldp_vty_cmds.c +@@ -122,6 +122,15 @@ DEFPY (ldp_discovery_link_interval, + return (ldp_vty_disc_interval(vty, no, HELLO_LINK, interval)); + } + ++DEFPY (ldp_disable_establish_hello, ++ ldp_disable_establish_hello_cmd, ++ "[no] disable-establish-hello", ++ NO_STR ++ "Disable sending additional LDP hello message on establishing LDP tcp connection\n") ++{ ++ return ldp_vty_disable_establish_hello(vty, no); ++} ++ + DEFPY (ldp_discovery_targeted_interval, + ldp_discovery_targeted_interval_cmd, + "[no] discovery targeted-hello interval (1-65535)$interval", +@@ -866,9 +875,11 @@ ldp_vty_init (void) + + install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_link_holdtime_cmd); + install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_link_interval_cmd); ++ install_element(LDP_IPV4_IFACE_NODE, &ldp_disable_establish_hello_cmd); + + install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_link_holdtime_cmd); + install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_link_interval_cmd); ++ install_element(LDP_IPV6_IFACE_NODE, &ldp_disable_establish_hello_cmd); + + install_element(LDP_L2VPN_NODE, &ldp_bridge_cmd); + install_element(LDP_L2VPN_NODE, &ldp_mtu_cmd); +diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c +index ffff67683..56ad071c8 100644 +--- a/ldpd/ldp_vty_conf.c ++++ b/ldpd/ldp_vty_conf.c +@@ -119,6 +119,8 @@ ldp_af_iface_config_write(struct vty *vty, int af) + ia->hello_interval != 0) + vty_out (vty, " discovery hello interval %u\n", + ia->hello_interval); ++ if (ia->disable_establish_hello) ++ vty_out (vty, " disable-establish-hello\n"); + + vty_out (vty, " exit\n"); + } +@@ -632,6 +634,36 @@ ldp_vty_disc_interval(struct vty *vty, const char *negate, + return (CMD_SUCCESS); + } + ++int ++ldp_vty_disable_establish_hello(struct vty *vty, ++ const char *negate) ++{ ++ struct iface *iface; ++ struct iface_af *ia; ++ int af; ++ ++ switch (vty->node) { ++ case LDP_IPV4_IFACE_NODE: ++ case LDP_IPV6_IFACE_NODE: ++ af = ldp_vty_get_af(vty); ++ iface = VTY_GET_CONTEXT(iface); ++ VTY_CHECK_CONTEXT(iface); ++ ++ ia = iface_af_get(iface, af); ++ if (negate) ++ ia->disable_establish_hello = 0; ++ else ++ ia->disable_establish_hello = 1; ++ ++ ldp_config_apply(vty, vty_conf); ++ break; ++ default: ++ fatalx("ldp_vty_disable_establish_hello: unexpected node"); ++ } ++ ++ return (CMD_SUCCESS); ++} ++ + int + ldp_vty_targeted_hello_accept(struct vty *vty, const char *negate, + const char *acl_from_str) +diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c +index 4d38fdcd0..9a5667c26 100644 +--- a/ldpd/ldpd.c ++++ b/ldpd/ldpd.c +@@ -1604,6 +1604,7 @@ merge_iface_af(struct iface_af *ia, struct iface_af *xi) + } + ia->hello_holdtime = xi->hello_holdtime; + ia->hello_interval = xi->hello_interval; ++ ia->disable_establish_hello = xi->disable_establish_hello; + } + + static void +diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h +index ad831a6ea..40a1e8c3c 100644 +--- a/ldpd/ldpd.h ++++ b/ldpd/ldpd.h +@@ -332,6 +332,7 @@ struct iface_af { + struct event *hello_timer; + uint16_t hello_holdtime; + uint16_t hello_interval; ++ int disable_establish_hello; + }; + + struct iface_ldp_sync { +diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c +index 2596c7948..00a809186 100644 +--- a/ldpd/neighbor.c ++++ b/ldpd/neighbor.c +@@ -630,8 +630,9 @@ nbr_establish_connection(struct nbr *nbr) + * an adjacency as well. + */ + RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree) +- send_hello(adj->source.type, adj->source.link.ia, +- adj->source.target); ++ if (!(adj->source.type == HELLO_LINK && adj->source.link.ia->disable_establish_hello)) ++ send_hello(adj->source.type, adj->source.link.ia, ++ adj->source.target); + + if (connect(nbr->fd, &remote_su.sa, sockaddr_len(&remote_su.sa)) == -1) { + if (errno == EINPROGRESS) { +-- +2.43.0 + diff --git a/scripts/package-build/frr/patches/frr/0003-Clear-Babel-Config-On-Stop.patch b/scripts/package-build/frr/patches/frr/0003-Clear-Babel-Config-On-Stop.patch new file mode 100644 index 00000000..fea45891 --- /dev/null +++ b/scripts/package-build/frr/patches/frr/0003-Clear-Babel-Config-On-Stop.patch @@ -0,0 +1,29 @@ +From c3c70e87b040233263b9594d14582dfedfecc92e Mon Sep 17 00:00:00 2001 +From: Yaroslav Kholod <y.kholod@vyos.io> +Date: Wed, 18 Dec 2024 11:48:29 +0200 +Subject: [PATCH] #17413: Clean babeld config on stop + +--- + babeld/babeld.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/babeld/babeld.c b/babeld/babeld.c +index b562f0b70..6f1a9a3d7 100644 +--- a/babeld/babeld.c ++++ b/babeld/babeld.c +@@ -304,6 +304,12 @@ void babel_clean_routing_process(void) + flush_all_routes(); + babel_interface_close_all(); + ++ /* Clean babel config */ ++ diversity_kind = DIVERSITY_NONE; ++ diversity_factor = BABEL_DEFAULT_DIVERSITY_FACTOR; ++ resend_delay = BABEL_DEFAULT_RESEND_DELAY; ++ smoothing_half_life = BABEL_DEFAULT_SMOOTHING_HALF_LIFE; ++ + /* cancel events */ + event_cancel(&babel_routing_process->t_read); + event_cancel(&babel_routing_process->t_update); +-- +2.43.0 + diff --git a/scripts/package-build/frr_exporter/.gitignore b/scripts/package-build/frr_exporter/.gitignore new file mode 100644 index 00000000..aee4cba5 --- /dev/null +++ b/scripts/package-build/frr_exporter/.gitignore @@ -0,0 +1 @@ +/frr_exporter/ diff --git a/scripts/package-build/frr_exporter/build.py b/scripts/package-build/frr_exporter/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/frr_exporter/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/frr_exporter/package.toml b/scripts/package-build/frr_exporter/package.toml new file mode 100644 index 00000000..607c4c68 --- /dev/null +++ b/scripts/package-build/frr_exporter/package.toml @@ -0,0 +1,22 @@ +[[packages]] +name = "frr_exporter" +commit_id = "v1.5.0" +scm_url = "https://github.com/tynany/frr_exporter" + +build_cmd = """ + +# Create the install directory +mkdir -p debian/usr/sbin +make setup_promu +go build + +# Move the frr_exporter binary to the install directory +mv frr_exporter debian/usr/sbin + +# Build the Debian package +fpm --input-type dir --output-type deb --name frr-exporter \ + --version $(git describe --tags --always | cut -c2-) --deb-compression gz \ + --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \ + --description "Prometheus exporter for FRR" \ + --license Apache-2.0 -C debian --package .. +""" diff --git a/scripts/package-build/hostap/.gitignore b/scripts/package-build/hostap/.gitignore index f9c7eb32..1a2c97d8 100644 --- a/scripts/package-build/hostap/.gitignore +++ b/scripts/package-build/hostap/.gitignore @@ -1,7 +1,2 @@ -hostap/ -wpa/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc +/hostap/ +/wpa/ diff --git a/scripts/package-build/hsflowd/.gitignore b/scripts/package-build/hsflowd/.gitignore index d0964b29..aebf1d06 100644 --- a/scripts/package-build/hsflowd/.gitignore +++ b/scripts/package-build/hsflowd/.gitignore @@ -1,6 +1 @@ -host-sflow/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc +/host-sflow/ diff --git a/scripts/package-build/hsflowd/package.toml b/scripts/package-build/hsflowd/package.toml index 75d320a7..823b0db3 100644 --- a/scripts/package-build/hsflowd/package.toml +++ b/scripts/package-build/hsflowd/package.toml @@ -1,8 +1,8 @@ [[packages]] name = "host-sflow" -commit_id = "v2.0.55-1" +commit_id = "v2.1.11-5" scm_url = "https://github.com/sflow/host-sflow.git" -build_cmd = "make deb FEATURES='PCAP DROPMON DBUS'" +build_cmd = "make deb FEATURES='PCAP DROPMON DBUS PSAMPLE VPP'" -[packages.dependencies] +[dependencies] packages = ["libpcap0.8-dev"] diff --git a/scripts/package-build/isc-dhcp/.gitignore b/scripts/package-build/isc-dhcp/.gitignore index 66d17cc8..41aa96b8 100644 --- a/scripts/package-build/isc-dhcp/.gitignore +++ b/scripts/package-build/isc-dhcp/.gitignore @@ -1,7 +1 @@ -isc-dhcp/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc - +/isc-dhcp/ diff --git a/scripts/package-build/isc-dhcp/package.toml b/scripts/package-build/isc-dhcp/package.toml index 76a0e4a1..f07e71e3 100644 --- a/scripts/package-build/isc-dhcp/package.toml +++ b/scripts/package-build/isc-dhcp/package.toml @@ -3,5 +3,5 @@ name = "isc-dhcp" commit_id = "debian/4.4.3-P1-4" scm_url = "https://salsa.debian.org/debian/isc-dhcp" -[packages.dependencies] +[dependencies] packages = ["libpam0g-dev"] diff --git a/scripts/package-build/isc-dhcp/patches/0001-Add-support-for-raw-IP-interface-type.patch b/scripts/package-build/isc-dhcp/patches/isc-dhcp/0001-Add-support-for-raw-IP-interface-type.patch index c13569ad..c13569ad 100644 --- a/scripts/package-build/isc-dhcp/patches/0001-Add-support-for-raw-IP-interface-type.patch +++ b/scripts/package-build/isc-dhcp/patches/isc-dhcp/0001-Add-support-for-raw-IP-interface-type.patch diff --git a/scripts/package-build/isc-dhcp/patches/0002-Checkpoint-improved-patch.patch b/scripts/package-build/isc-dhcp/patches/isc-dhcp/0002-Checkpoint-improved-patch.patch index 60b693f6..60b693f6 100644 --- a/scripts/package-build/isc-dhcp/patches/0002-Checkpoint-improved-patch.patch +++ b/scripts/package-build/isc-dhcp/patches/isc-dhcp/0002-Checkpoint-improved-patch.patch diff --git a/scripts/package-build/isc-dhcp/patches/0003-fix-compilation-errors.patch b/scripts/package-build/isc-dhcp/patches/isc-dhcp/0003-fix-compilation-errors.patch index c66e0c7c..c66e0c7c 100644 --- a/scripts/package-build/isc-dhcp/patches/0003-fix-compilation-errors.patch +++ b/scripts/package-build/isc-dhcp/patches/isc-dhcp/0003-fix-compilation-errors.patch diff --git a/scripts/package-build/isc-dhcp/patches/0004-add-support-for-ARPHRD_NONE-interface-type.patch b/scripts/package-build/isc-dhcp/patches/isc-dhcp/0004-add-support-for-ARPHRD_NONE-interface-type.patch index 32089b4d..32089b4d 100644 --- a/scripts/package-build/isc-dhcp/patches/0004-add-support-for-ARPHRD_NONE-interface-type.patch +++ b/scripts/package-build/isc-dhcp/patches/isc-dhcp/0004-add-support-for-ARPHRD_NONE-interface-type.patch diff --git a/scripts/package-build/kea/.gitignore b/scripts/package-build/kea/.gitignore index 1f9d42c9..70219f63 100644 --- a/scripts/package-build/kea/.gitignore +++ b/scripts/package-build/kea/.gitignore @@ -1,7 +1 @@ -isc-kea/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc - +/isc-kea/ diff --git a/scripts/package-build/kea/package.toml b/scripts/package-build/kea/package.toml index 0bfce21e..872be441 100644 --- a/scripts/package-build/kea/package.toml +++ b/scripts/package-build/kea/package.toml @@ -1,4 +1,4 @@ [[packages]] name = "isc-kea" -commit_id = "debian/2.4.1-3" +commit_id = "debian/2.6.1-2" scm_url = "https://salsa.debian.org/debian/isc-kea" diff --git a/scripts/package-build/kea/patches/isc-kea/0001-Add-multithreading-test-mode.patch b/scripts/package-build/kea/patches/isc-kea/0001-Add-multithreading-test-mode.patch new file mode 100644 index 00000000..981e6f1d --- /dev/null +++ b/scripts/package-build/kea/patches/isc-kea/0001-Add-multithreading-test-mode.patch @@ -0,0 +1,135 @@ +From cb2b064162e2d5bf09331c619abf76a40130ade1 Mon Sep 17 00:00:00 2001 +From: sarthurdev <s.arthur@vyos.io> +Date: Wed, 2 Apr 2025 08:48:48 +0000 +Subject: [PATCH 1/2] Add multithreading test mode + +--- + src/bin/dhcp4/json_config_parser.cc | 4 ++++ + src/bin/dhcp6/json_config_parser.cc | 6 +++++- + src/lib/config/cmd_http_listener.cc | 3 +++ + src/lib/tcp/mt_tcp_listener_mgr.cc | 3 +++ + src/lib/util/multi_threading_mgr.cc | 3 ++- + src/lib/util/multi_threading_mgr.h | 19 +++++++++++++++++++ + 6 files changed, 36 insertions(+), 2 deletions(-) + +diff --git a/src/bin/dhcp4/json_config_parser.cc b/src/bin/dhcp4/json_config_parser.cc +index c2e34c5..1350816 100644 +--- a/src/bin/dhcp4/json_config_parser.cc ++++ b/src/bin/dhcp4/json_config_parser.cc +@@ -718,6 +718,10 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set, + LOG_DEBUG(dhcp4_logger, DBG_DHCP4_COMMAND, DHCP4_CONFIG_START) + .arg(server.redactConfig(config_set)->str()); + ++ if (check_only) { ++ MultiThreadingMgr::instance().setTestMode(true); ++ } ++ + auto answer = processDhcp4Config(config_set); + + int status_code = CONTROL_RESULT_SUCCESS; +diff --git a/src/bin/dhcp6/json_config_parser.cc b/src/bin/dhcp6/json_config_parser.cc +index 671d69a..a74a568 100644 +--- a/src/bin/dhcp6/json_config_parser.cc ++++ b/src/bin/dhcp6/json_config_parser.cc +@@ -850,6 +850,10 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set, + LOG_DEBUG(dhcp6_logger, DBG_DHCP6_COMMAND, DHCP6_CONFIG_START) + .arg(server.redactConfig(config_set)->str()); + ++ if (check_only) { ++ MultiThreadingMgr::instance().setTestMode(true); ++ } ++ + auto answer = processDhcp6Config(config_set); + + int status_code = CONTROL_RESULT_SUCCESS; +@@ -953,7 +957,7 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set, + // configuration. This will add created subnets and option values into + // the server's configuration. + // This operation should be exception safe but let's make sure. +- if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) { ++ if (status_code == CONTROL_RESULT_SUCCESS && !check_only) { + try { + + // Setup the command channel. +diff --git a/src/lib/config/cmd_http_listener.cc b/src/lib/config/cmd_http_listener.cc +index 9dfea59..394806e 100644 +--- a/src/lib/config/cmd_http_listener.cc ++++ b/src/lib/config/cmd_http_listener.cc +@@ -40,6 +40,9 @@ CmdHttpListener::~CmdHttpListener() { + + void + CmdHttpListener::start() { ++ if (MultiThreadingMgr::instance().isTestMode()) { ++ return; ++ } + // We must be in multi-threading mode. + if (!MultiThreadingMgr::instance().getMode()) { + isc_throw(InvalidOperation, "CmdHttpListener cannot be started" +diff --git a/src/lib/tcp/mt_tcp_listener_mgr.cc b/src/lib/tcp/mt_tcp_listener_mgr.cc +index e880284..4680717 100644 +--- a/src/lib/tcp/mt_tcp_listener_mgr.cc ++++ b/src/lib/tcp/mt_tcp_listener_mgr.cc +@@ -40,6 +40,9 @@ MtTcpListenerMgr::~MtTcpListenerMgr() { + + void + MtTcpListenerMgr::start() { ++ if (MultiThreadingMgr::instance().isTestMode()) { ++ return; ++ } + // We must be in multi-threading mode. + if (!MultiThreadingMgr::instance().getMode()) { + isc_throw(InvalidOperation, "MtTcpListenerMgr cannot be started" +diff --git a/src/lib/util/multi_threading_mgr.cc b/src/lib/util/multi_threading_mgr.cc +index d1526b9..cab284d 100644 +--- a/src/lib/util/multi_threading_mgr.cc ++++ b/src/lib/util/multi_threading_mgr.cc +@@ -14,7 +14,8 @@ namespace isc { + namespace util { + + MultiThreadingMgr::MultiThreadingMgr() +- : enabled_(false), critical_section_count_(0), thread_pool_size_(0) { ++ : enabled_(false), test_mode_(false), critical_section_count_(0), ++ thread_pool_size_(0) { + } + + MultiThreadingMgr::~MultiThreadingMgr() { +diff --git a/src/lib/util/multi_threading_mgr.h b/src/lib/util/multi_threading_mgr.h +index e86c488..f3da67b 100644 +--- a/src/lib/util/multi_threading_mgr.h ++++ b/src/lib/util/multi_threading_mgr.h +@@ -154,6 +154,22 @@ public: + /// @param enabled The new mode. + void setMode(bool enabled); + ++ /// @brief Sets or clears the test mode for @c MultiThreadingMgr. ++ /// ++ /// @param test_mode A flag which indicates that the @c MultiThreadingMgr is ++ /// in the test mode (if true), or not (if false). ++ void setTestMode(const bool test_mode) { ++ test_mode_ = test_mode; ++ } ++ ++ /// @brief Checks if the @c MultiThreadingMgr is in the test mode. ++ /// ++ /// @return true if the @c MultiThreadingMgr is in the test mode, false ++ /// otherwise. ++ bool isTestMode() const { ++ return (test_mode_); ++ } ++ + /// @brief Enter critical section. + /// + /// When entering @ref MultiThreadingCriticalSection, increment internal +@@ -308,6 +324,9 @@ private: + /// otherwise. + bool enabled_; + ++ /// @brief Indicates if the @c MultiThreadingMgr is in the test mode. ++ bool test_mode_; ++ + /// @brief The critical section count. + /// + /// In case the configuration is applied within a +-- +2.39.5 + diff --git a/scripts/package-build/kea/patches/isc-kea/0002-Add-ping_check-hook-library.patch b/scripts/package-build/kea/patches/isc-kea/0002-Add-ping_check-hook-library.patch new file mode 100644 index 00000000..c2f172ca --- /dev/null +++ b/scripts/package-build/kea/patches/isc-kea/0002-Add-ping_check-hook-library.patch @@ -0,0 +1,13277 @@ +From 6f198a187195a7fa4ad2cf9d147532bd64724f65 Mon Sep 17 00:00:00 2001 +From: sarthurdev <965089+sarthurdev@users.noreply.github.com> +Date: Mon, 24 Mar 2025 19:38:34 +0100 +Subject: [PATCH] Add ping_check hook library + +--- + configure.ac | 3 + + src/hooks/dhcp/Makefile.am | 2 +- + src/hooks/dhcp/ping_check/Doxyfile | 2568 +++++++++++++++++ + src/hooks/dhcp/ping_check/Makefile.am | 104 + + src/hooks/dhcp/ping_check/config_cache.cc | 107 + + src/hooks/dhcp/ping_check/config_cache.h | 146 + + src/hooks/dhcp/ping_check/icmp_endpoint.h | 134 + + src/hooks/dhcp/ping_check/icmp_msg.cc | 112 + + src/hooks/dhcp/ping_check/icmp_msg.h | 223 ++ + src/hooks/dhcp/ping_check/icmp_socket.h | 359 +++ + .../dhcp/ping_check/libloadtests/.gitignore | 1 + + .../dhcp/ping_check/libloadtests/Makefile.am | 60 + + .../libloadtests/load_unload_unittests.cc | 107 + + .../dhcp/ping_check/libloadtests/meson.build | 21 + + .../ping_check/libloadtests/run_unittests.cc | 19 + + src/hooks/dhcp/ping_check/meson.build | 41 + + src/hooks/dhcp/ping_check/ping_channel.cc | 466 +++ + src/hooks/dhcp/ping_check/ping_channel.h | 371 +++ + src/hooks/dhcp/ping_check/ping_check.dox | 44 + + .../dhcp/ping_check/ping_check_callouts.cc | 240 ++ + .../dhcp/ping_check/ping_check_config.cc | 98 + + src/hooks/dhcp/ping_check/ping_check_config.h | 134 + + src/hooks/dhcp/ping_check/ping_check_log.cc | 17 + + src/hooks/dhcp/ping_check/ping_check_log.h | 23 + + .../dhcp/ping_check/ping_check_messages.cc | 99 + + .../dhcp/ping_check/ping_check_messages.h | 50 + + .../dhcp/ping_check/ping_check_messages.mes | 229 ++ + src/hooks/dhcp/ping_check/ping_check_mgr.cc | 798 +++++ + src/hooks/dhcp/ping_check/ping_check_mgr.h | 436 +++ + src/hooks/dhcp/ping_check/ping_context.cc | 237 ++ + src/hooks/dhcp/ping_check/ping_context.h | 280 ++ + .../dhcp/ping_check/ping_context_store.cc | 144 + + .../dhcp/ping_check/ping_context_store.h | 240 ++ + src/hooks/dhcp/ping_check/tests/.gitignore | 1 + + src/hooks/dhcp/ping_check/tests/Makefile.am | 70 + + .../tests/config_cache_unittests.cc | 245 ++ + .../tests/icmp_endpoint_unittests.cc | 44 + + .../ping_check/tests/icmp_msg_unittests.cc | 172 ++ + .../ping_check/tests/icmp_socket_unittests.cc | 380 +++ + src/hooks/dhcp/ping_check/tests/meson.build | 21 + + .../tests/ping_channel_unittests.cc | 821 ++++++ + .../tests/ping_check_config_unittests.cc | 287 ++ + .../tests/ping_check_mgr_unittests.cc | 1878 ++++++++++++ + .../tests/ping_context_store_unittests.cc | 467 +++ + .../tests/ping_context_unittests.cc | 146 + + .../dhcp/ping_check/tests/ping_test_utils.h | 396 +++ + .../dhcp/ping_check/tests/run_unittests.cc | 19 + + src/hooks/dhcp/ping_check/version.cc | 17 + + 48 files changed, 12876 insertions(+), 1 deletion(-) + create mode 100644 src/hooks/dhcp/ping_check/Doxyfile + create mode 100644 src/hooks/dhcp/ping_check/Makefile.am + create mode 100644 src/hooks/dhcp/ping_check/config_cache.cc + create mode 100644 src/hooks/dhcp/ping_check/config_cache.h + create mode 100644 src/hooks/dhcp/ping_check/icmp_endpoint.h + create mode 100644 src/hooks/dhcp/ping_check/icmp_msg.cc + create mode 100644 src/hooks/dhcp/ping_check/icmp_msg.h + create mode 100644 src/hooks/dhcp/ping_check/icmp_socket.h + create mode 100644 src/hooks/dhcp/ping_check/libloadtests/.gitignore + create mode 100644 src/hooks/dhcp/ping_check/libloadtests/Makefile.am + create mode 100644 src/hooks/dhcp/ping_check/libloadtests/load_unload_unittests.cc + create mode 100644 src/hooks/dhcp/ping_check/libloadtests/meson.build + create mode 100644 src/hooks/dhcp/ping_check/libloadtests/run_unittests.cc + create mode 100644 src/hooks/dhcp/ping_check/meson.build + create mode 100644 src/hooks/dhcp/ping_check/ping_channel.cc + create mode 100644 src/hooks/dhcp/ping_check/ping_channel.h + create mode 100644 src/hooks/dhcp/ping_check/ping_check.dox + create mode 100644 src/hooks/dhcp/ping_check/ping_check_callouts.cc + create mode 100644 src/hooks/dhcp/ping_check/ping_check_config.cc + create mode 100644 src/hooks/dhcp/ping_check/ping_check_config.h + create mode 100644 src/hooks/dhcp/ping_check/ping_check_log.cc + create mode 100644 src/hooks/dhcp/ping_check/ping_check_log.h + create mode 100644 src/hooks/dhcp/ping_check/ping_check_messages.cc + create mode 100644 src/hooks/dhcp/ping_check/ping_check_messages.h + create mode 100644 src/hooks/dhcp/ping_check/ping_check_messages.mes + create mode 100644 src/hooks/dhcp/ping_check/ping_check_mgr.cc + create mode 100644 src/hooks/dhcp/ping_check/ping_check_mgr.h + create mode 100644 src/hooks/dhcp/ping_check/ping_context.cc + create mode 100644 src/hooks/dhcp/ping_check/ping_context.h + create mode 100644 src/hooks/dhcp/ping_check/ping_context_store.cc + create mode 100644 src/hooks/dhcp/ping_check/ping_context_store.h + create mode 100644 src/hooks/dhcp/ping_check/tests/.gitignore + create mode 100644 src/hooks/dhcp/ping_check/tests/Makefile.am + create mode 100644 src/hooks/dhcp/ping_check/tests/config_cache_unittests.cc + create mode 100644 src/hooks/dhcp/ping_check/tests/icmp_endpoint_unittests.cc + create mode 100644 src/hooks/dhcp/ping_check/tests/icmp_msg_unittests.cc + create mode 100644 src/hooks/dhcp/ping_check/tests/icmp_socket_unittests.cc + create mode 100644 src/hooks/dhcp/ping_check/tests/meson.build + create mode 100644 src/hooks/dhcp/ping_check/tests/ping_channel_unittests.cc + create mode 100644 src/hooks/dhcp/ping_check/tests/ping_check_config_unittests.cc + create mode 100644 src/hooks/dhcp/ping_check/tests/ping_check_mgr_unittests.cc + create mode 100644 src/hooks/dhcp/ping_check/tests/ping_context_store_unittests.cc + create mode 100644 src/hooks/dhcp/ping_check/tests/ping_context_unittests.cc + create mode 100644 src/hooks/dhcp/ping_check/tests/ping_test_utils.h + create mode 100644 src/hooks/dhcp/ping_check/tests/run_unittests.cc + create mode 100644 src/hooks/dhcp/ping_check/version.cc + +diff --git a/configure.ac b/configure.ac +index cc1b31af71..23c8eefb81 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1582,6 +1582,9 @@ AC_CONFIG_FILES([src/hooks/dhcp/lease_cmds/tests/Makefile]) + AC_CONFIG_FILES([src/hooks/dhcp/mysql_cb/Makefile]) + AC_CONFIG_FILES([src/hooks/dhcp/mysql_cb/libloadtests/Makefile]) + AC_CONFIG_FILES([src/hooks/dhcp/mysql_cb/tests/Makefile]) ++AC_CONFIG_FILES([src/hooks/dhcp/ping_check/Makefile]) ++AC_CONFIG_FILES([src/hooks/dhcp/ping_check/libloadtests/Makefile]) ++AC_CONFIG_FILES([src/hooks/dhcp/ping_check/tests/Makefile]) + AC_CONFIG_FILES([src/hooks/dhcp/pgsql_cb/Makefile]) + AC_CONFIG_FILES([src/hooks/dhcp/pgsql_cb/libloadtests/Makefile]) + AC_CONFIG_FILES([src/hooks/dhcp/pgsql_cb/tests/Makefile]) +diff --git a/src/hooks/dhcp/Makefile.am b/src/hooks/dhcp/Makefile.am +index 1b77976424..806e310a17 100644 +--- a/src/hooks/dhcp/Makefile.am ++++ b/src/hooks/dhcp/Makefile.am +@@ -8,4 +8,4 @@ if HAVE_PGSQL + SUBDIRS += pgsql_cb + endif + +-SUBDIRS += run_script stat_cmds user_chk ++SUBDIRS += run_script stat_cmds user_chk ping_check +diff --git a/src/hooks/dhcp/ping_check/Doxyfile b/src/hooks/dhcp/ping_check/Doxyfile +new file mode 100644 +index 0000000000..7c8554b557 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/Doxyfile +@@ -0,0 +1,2568 @@ ++# Doxyfile 1.9.1 ++ ++# This file describes the settings to be used by the documentation system ++# doxygen (www.doxygen.org) for a project. ++# ++# All text after a double hash (##) is considered a comment and is placed in ++# front of the TAG it is preceding. ++# ++# All text after a single hash (#) is considered a comment and will be ignored. ++# The format is: ++# TAG = value [value, ...] ++# For lists, items can also be appended using: ++# TAG += value [value, ...] ++# Values that contain spaces should be placed between quotes (\" \"). ++ ++#--------------------------------------------------------------------------- ++# Project related configuration options ++#--------------------------------------------------------------------------- ++ ++# This tag specifies the encoding used for all characters in the configuration ++# file that follow. The default is UTF-8 which is also the encoding used for all ++# text before the first occurrence of this tag. Doxygen uses libiconv (or the ++# iconv built into libc) for the transcoding. See ++# https://www.gnu.org/software/libiconv/ for the list of possible encodings. ++# The default value is: UTF-8. ++ ++DOXYFILE_ENCODING = UTF-8 ++ ++# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by ++# double-quotes, unless you are using Doxywizard) that should identify the ++# project for which the documentation is generated. This name is used in the ++# title of most generated pages and in a few other places. ++# The default value is: My Project. ++ ++PROJECT_NAME = "Kea Ping Check Hooks Library" ++ ++# The PROJECT_NUMBER tag can be used to enter a project or revision number. This ++# could be handy for archiving the generated documentation or if some version ++# control system is used. ++ ++PROJECT_NUMBER = ++ ++# Using the PROJECT_BRIEF tag one can provide an optional one line description ++# for a project that appears at the top of each page and should give viewer a ++# quick idea about the purpose of the project. Keep the description short. ++ ++PROJECT_BRIEF = ++ ++# With the PROJECT_LOGO tag one can specify a logo or an icon that is included ++# in the documentation. The maximum height of the logo should not exceed 55 ++# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy ++# the logo to the output directory. ++ ++PROJECT_LOGO = ../../../../../doc/images/kea-logo-100x70.png ++ ++# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path ++# into which the generated documentation will be written. If a relative path is ++# entered, it will be relative to the location where doxygen was started. If ++# left blank the current directory will be used. ++ ++OUTPUT_DIRECTORY = html ++ ++# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- ++# directories (in 2 levels) under the output directory of each output format and ++# will distribute the generated files over these directories. Enabling this ++# option can be useful when feeding doxygen a huge amount of source files, where ++# putting all generated files in the same directory would otherwise causes ++# performance problems for the file system. ++# The default value is: NO. ++ ++CREATE_SUBDIRS = YES ++ ++# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII ++# characters to appear in the names of generated files. If set to NO, non-ASCII ++# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode ++# U+3044. ++# The default value is: NO. ++ ++ALLOW_UNICODE_NAMES = NO ++ ++# The OUTPUT_LANGUAGE tag is used to specify the language in which all ++# documentation generated by doxygen is written. Doxygen will use this ++# information to generate all constant output in the proper language. ++# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, ++# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), ++# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, ++# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), ++# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, ++# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, ++# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, ++# Ukrainian and Vietnamese. ++# The default value is: English. ++ ++OUTPUT_LANGUAGE = English ++ ++# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all ++# documentation generated by doxygen is written. Doxygen will use this ++# information to generate all generated output in the proper direction. ++# Possible values are: None, LTR, RTL and Context. ++# The default value is: None. ++ ++OUTPUT_TEXT_DIRECTION = None ++ ++# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member ++# descriptions after the members that are listed in the file and class ++# documentation (similar to Javadoc). Set to NO to disable this. ++# The default value is: YES. ++ ++BRIEF_MEMBER_DESC = YES ++ ++# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief ++# description of a member or function before the detailed description ++# ++# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the ++# brief descriptions will be completely suppressed. ++# The default value is: YES. ++ ++REPEAT_BRIEF = YES ++ ++# This tag implements a quasi-intelligent brief description abbreviator that is ++# used to form the text in various listings. Each string in this list, if found ++# as the leading text of the brief description, will be stripped from the text ++# and the result, after processing the whole list, is used as the annotated ++# text. Otherwise, the brief description is used as-is. If left blank, the ++# following values are used ($name is automatically replaced with the name of ++# the entity):The $name class, The $name widget, The $name file, is, provides, ++# specifies, contains, represents, a, an and the. ++ ++ABBREVIATE_BRIEF = ++ ++# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then ++# doxygen will generate a detailed section even if there is only a brief ++# description. ++# The default value is: NO. ++ ++ALWAYS_DETAILED_SEC = NO ++ ++# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all ++# inherited members of a class in the documentation of that class as if those ++# members were ordinary class members. Constructors, destructors and assignment ++# operators of the base classes will not be shown. ++# The default value is: NO. ++ ++INLINE_INHERITED_MEMB = NO ++ ++# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path ++# before files name in the file list and in the header files. If set to NO the ++# shortest path that makes the file name unique will be used ++# The default value is: YES. ++ ++FULL_PATH_NAMES = NO ++ ++# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. ++# Stripping is only done if one of the specified strings matches the left-hand ++# part of the path. The tag can be used to show relative paths in the file list. ++# If left blank the directory from which doxygen is run is used as the path to ++# strip. ++# ++# Note that you can specify absolute paths here, but also relative paths, which ++# will be relative from the directory where doxygen is started. ++# This tag requires that the tag FULL_PATH_NAMES is set to YES. ++ ++STRIP_FROM_PATH = ++ ++# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the ++# path mentioned in the documentation of a class, which tells the reader which ++# header file to include in order to use a class. If left blank only the name of ++# the header file containing the class definition is used. Otherwise one should ++# specify the list of include paths that are normally passed to the compiler ++# using the -I flag. ++ ++STRIP_FROM_INC_PATH = ++ ++# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but ++# less readable) file names. This can be useful is your file systems doesn't ++# support long names like on DOS, Mac, or CD-ROM. ++# The default value is: NO. ++ ++SHORT_NAMES = NO ++ ++# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the ++# first line (until the first dot) of a Javadoc-style comment as the brief ++# description. If set to NO, the Javadoc-style will behave just like regular Qt- ++# style comments (thus requiring an explicit @brief command for a brief ++# description.) ++# The default value is: NO. ++ ++JAVADOC_AUTOBRIEF = YES ++ ++# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line ++# such as ++# /*************** ++# as being the beginning of a Javadoc-style comment "banner". If set to NO, the ++# Javadoc-style will behave just like regular comments and it will not be ++# interpreted by doxygen. ++# The default value is: NO. ++ ++JAVADOC_BANNER = NO ++ ++# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first ++# line (until the first dot) of a Qt-style comment as the brief description. If ++# set to NO, the Qt-style will behave just like regular Qt-style comments (thus ++# requiring an explicit \brief command for a brief description.) ++# The default value is: NO. ++ ++QT_AUTOBRIEF = NO ++ ++# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a ++# multi-line C++ special comment block (i.e. a block of //! or /// comments) as ++# a brief description. This used to be the default behavior. The new default is ++# to treat a multi-line C++ comment block as a detailed description. Set this ++# tag to YES if you prefer the old behavior instead. ++# ++# Note that setting this tag to YES also means that rational rose comments are ++# not recognized any more. ++# The default value is: NO. ++ ++MULTILINE_CPP_IS_BRIEF = NO ++ ++# By default Python docstrings are displayed as preformatted text and doxygen's ++# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the ++# doxygen's special commands can be used and the contents of the docstring ++# documentation blocks is shown as doxygen documentation. ++# The default value is: YES. ++ ++PYTHON_DOCSTRING = YES ++ ++# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the ++# documentation from any documented member that it re-implements. ++# The default value is: YES. ++ ++INHERIT_DOCS = YES ++ ++# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new ++# page for each member. If set to NO, the documentation of a member will be part ++# of the file/class/namespace that contains it. ++# The default value is: NO. ++ ++SEPARATE_MEMBER_PAGES = NO ++ ++# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen ++# uses this value to replace tabs by spaces in code fragments. ++# Minimum value: 1, maximum value: 16, default value: 4. ++ ++TAB_SIZE = 4 ++ ++# This tag can be used to specify a number of aliases that act as commands in ++# the documentation. An alias has the form: ++# name=value ++# For example adding ++# "sideeffect=@par Side Effects:\n" ++# will allow you to put the command \sideeffect (or @sideeffect) in the ++# documentation, which will result in a user-defined paragraph with heading ++# "Side Effects:". You can put \n's in the value part of an alias to insert ++# newlines (in the resulting output). You can put ^^ in the value part of an ++# alias to insert a newline as if a physical newline was in the original file. ++# When you need a literal { or } or , in the value part of an alias you have to ++# escape them by means of a backslash (\), this can lead to conflicts with the ++# commands \{ and \} for these it is advised to use the version @{ and @} or use ++# a double escape (\\{ and \\}) ++ ++ALIASES = ++ ++# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources ++# only. Doxygen will then generate output that is more tailored for C. For ++# instance, some of the names that are used will be different. The list of all ++# members will be omitted, etc. ++# The default value is: NO. ++ ++OPTIMIZE_OUTPUT_FOR_C = NO ++ ++# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or ++# Python sources only. Doxygen will then generate output that is more tailored ++# for that language. For instance, namespaces will be presented as packages, ++# qualified scopes will look different, etc. ++# The default value is: NO. ++ ++OPTIMIZE_OUTPUT_JAVA = NO ++ ++# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran ++# sources. Doxygen will then generate output that is tailored for Fortran. ++# The default value is: NO. ++ ++OPTIMIZE_FOR_FORTRAN = NO ++ ++# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL ++# sources. Doxygen will then generate output that is tailored for VHDL. ++# The default value is: NO. ++ ++OPTIMIZE_OUTPUT_VHDL = NO ++ ++# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice ++# sources only. Doxygen will then generate output that is more tailored for that ++# language. For instance, namespaces will be presented as modules, types will be ++# separated into more groups, etc. ++# The default value is: NO. ++ ++OPTIMIZE_OUTPUT_SLICE = NO ++ ++# Doxygen selects the parser to use depending on the extension of the files it ++# parses. With this tag you can assign which parser to use for a given ++# extension. Doxygen has a built-in mapping, but you can override or extend it ++# using this tag. The format is ext=language, where ext is a file extension, and ++# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, ++# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, ++# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: ++# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser ++# tries to guess whether the code is fixed or free formatted code, this is the ++# default for Fortran type files). For instance to make doxygen treat .inc files ++# as Fortran files (default is PHP), and .f files as C (default is Fortran), ++# use: inc=Fortran f=C. ++# ++# Note: For files without extension you can use no_extension as a placeholder. ++# ++# Note that for custom extensions you also need to set FILE_PATTERNS otherwise ++# the files are not read by doxygen. When specifying no_extension you should add ++# * to the FILE_PATTERNS. ++# ++# Note see also the list of default file extension mappings. ++ ++EXTENSION_MAPPING = ++ ++# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments ++# according to the Markdown format, which allows for more readable ++# documentation. See https://daringfireball.net/projects/markdown/ for details. ++# The output of markdown processing is further processed by doxygen, so you can ++# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in ++# case of backward compatibilities issues. ++# The default value is: YES. ++ ++MARKDOWN_SUPPORT = YES ++ ++# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up ++# to that level are automatically included in the table of contents, even if ++# they do not have an id attribute. ++# Note: This feature currently applies only to Markdown headings. ++# Minimum value: 0, maximum value: 99, default value: 5. ++# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. ++ ++TOC_INCLUDE_HEADINGS = 5 ++ ++# When enabled doxygen tries to link words that correspond to documented ++# classes, or namespaces to their corresponding documentation. Such a link can ++# be prevented in individual cases by putting a % sign in front of the word or ++# globally by setting AUTOLINK_SUPPORT to NO. ++# The default value is: YES. ++ ++AUTOLINK_SUPPORT = YES ++ ++# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want ++# to include (a tag file for) the STL sources as input, then you should set this ++# tag to YES in order to let doxygen match functions declarations and ++# definitions whose arguments contain STL classes (e.g. func(std::string); ++# versus func(std::string) {}). This also make the inheritance and collaboration ++# diagrams that involve STL classes more complete and accurate. ++# The default value is: NO. ++ ++BUILTIN_STL_SUPPORT = YES ++ ++# If you use Microsoft's C++/CLI language, you should set this option to YES to ++# enable parsing support. ++# The default value is: NO. ++ ++CPP_CLI_SUPPORT = NO ++ ++# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: ++# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen ++# will parse them like normal C++ but will assume all classes use public instead ++# of private inheritance when no explicit protection keyword is present. ++# The default value is: NO. ++ ++SIP_SUPPORT = NO ++ ++# For Microsoft's IDL there are propget and propput attributes to indicate ++# getter and setter methods for a property. Setting this option to YES will make ++# doxygen to replace the get and set methods by a property in the documentation. ++# This will only work if the methods are indeed getting or setting a simple ++# type. If this is not the case, or you want to show the methods anyway, you ++# should set this option to NO. ++# The default value is: YES. ++ ++IDL_PROPERTY_SUPPORT = YES ++ ++# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC ++# tag is set to YES then doxygen will reuse the documentation of the first ++# member in the group (if any) for the other members of the group. By default ++# all members of a group must be documented explicitly. ++# The default value is: NO. ++ ++DISTRIBUTE_GROUP_DOC = NO ++ ++# If one adds a struct or class to a group and this option is enabled, then also ++# any nested class or struct is added to the same group. By default this option ++# is disabled and one has to add nested compounds explicitly via \ingroup. ++# The default value is: NO. ++ ++GROUP_NESTED_COMPOUNDS = NO ++ ++# Set the SUBGROUPING tag to YES to allow class member groups of the same type ++# (for instance a group of public functions) to be put as a subgroup of that ++# type (e.g. under the Public Functions section). Set it to NO to prevent ++# subgrouping. Alternatively, this can be done per class using the ++# \nosubgrouping command. ++# The default value is: YES. ++ ++SUBGROUPING = YES ++ ++# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions ++# are shown inside the group in which they are included (e.g. using \ingroup) ++# instead of on a separate page (for HTML and Man pages) or section (for LaTeX ++# and RTF). ++# ++# Note that this feature does not work in combination with ++# SEPARATE_MEMBER_PAGES. ++# The default value is: NO. ++ ++INLINE_GROUPED_CLASSES = NO ++ ++# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions ++# with only public data fields or simple typedef fields will be shown inline in ++# the documentation of the scope in which they are defined (i.e. file, ++# namespace, or group documentation), provided this scope is documented. If set ++# to NO, structs, classes, and unions are shown on a separate page (for HTML and ++# Man pages) or section (for LaTeX and RTF). ++# The default value is: NO. ++ ++INLINE_SIMPLE_STRUCTS = NO ++ ++# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or ++# enum is documented as struct, union, or enum with the name of the typedef. So ++# typedef struct TypeS {} TypeT, will appear in the documentation as a struct ++# with name TypeT. When disabled the typedef will appear as a member of a file, ++# namespace, or class. And the struct will be named TypeS. This can typically be ++# useful for C code in case the coding convention dictates that all compound ++# types are typedef'ed and only the typedef is referenced, never the tag name. ++# The default value is: NO. ++ ++TYPEDEF_HIDES_STRUCT = NO ++ ++# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This ++# cache is used to resolve symbols given their name and scope. Since this can be ++# an expensive process and often the same symbol appears multiple times in the ++# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small ++# doxygen will become slower. If the cache is too large, memory is wasted. The ++# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range ++# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 ++# symbols. At the end of a run doxygen will report the cache usage and suggest ++# the optimal cache size from a speed point of view. ++# Minimum value: 0, maximum value: 9, default value: 0. ++ ++LOOKUP_CACHE_SIZE = 0 ++ ++# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use ++# during processing. When set to 0 doxygen will based this on the number of ++# cores available in the system. You can set it explicitly to a value larger ++# than 0 to get more control over the balance between CPU load and processing ++# speed. At this moment only the input processing can be done using multiple ++# threads. Since this is still an experimental feature the default is set to 1, ++# which effectively disables parallel processing. Please report any issues you ++# encounter. Generating dot graphs in parallel is controlled by the ++# DOT_NUM_THREADS setting. ++# Minimum value: 0, maximum value: 32, default value: 1. ++ ++NUM_PROC_THREADS = 1 ++ ++#--------------------------------------------------------------------------- ++# Build related configuration options ++#--------------------------------------------------------------------------- ++ ++# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in ++# documentation are documented, even if no documentation was available. Private ++# class members and static file members will be hidden unless the ++# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. ++# Note: This will also disable the warnings about undocumented members that are ++# normally produced when WARNINGS is set to YES. ++# The default value is: NO. ++ ++EXTRACT_ALL = YES ++ ++# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will ++# be included in the documentation. ++# The default value is: NO. ++ ++EXTRACT_PRIVATE = NO ++ ++# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual ++# methods of a class will be included in the documentation. ++# The default value is: NO. ++ ++EXTRACT_PRIV_VIRTUAL = NO ++ ++# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal ++# scope will be included in the documentation. ++# The default value is: NO. ++ ++EXTRACT_PACKAGE = NO ++ ++# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be ++# included in the documentation. ++# The default value is: NO. ++ ++EXTRACT_STATIC = NO ++ ++# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined ++# locally in source files will be included in the documentation. If set to NO, ++# only classes defined in header files are included. Does not have any effect ++# for Java sources. ++# The default value is: YES. ++ ++EXTRACT_LOCAL_CLASSES = YES ++ ++# This flag is only useful for Objective-C code. If set to YES, local methods, ++# which are defined in the implementation section but not in the interface are ++# included in the documentation. If set to NO, only methods in the interface are ++# included. ++# The default value is: NO. ++ ++EXTRACT_LOCAL_METHODS = NO ++ ++# If this flag is set to YES, the members of anonymous namespaces will be ++# extracted and appear in the documentation as a namespace called ++# 'anonymous_namespace{file}', where file will be replaced with the base name of ++# the file that contains the anonymous namespace. By default anonymous namespace ++# are hidden. ++# The default value is: NO. ++ ++EXTRACT_ANON_NSPACES = NO ++ ++# If this flag is set to YES, the name of an unnamed parameter in a declaration ++# will be determined by the corresponding definition. By default unnamed ++# parameters remain unnamed in the output. ++# The default value is: YES. ++ ++RESOLVE_UNNAMED_PARAMS = YES ++ ++# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all ++# undocumented members inside documented classes or files. If set to NO these ++# members will be included in the various overviews, but no documentation ++# section is generated. This option has no effect if EXTRACT_ALL is enabled. ++# The default value is: NO. ++ ++HIDE_UNDOC_MEMBERS = NO ++ ++# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all ++# undocumented classes that are normally visible in the class hierarchy. If set ++# to NO, these classes will be included in the various overviews. This option ++# has no effect if EXTRACT_ALL is enabled. ++# The default value is: NO. ++ ++HIDE_UNDOC_CLASSES = NO ++ ++# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend ++# declarations. If set to NO, these declarations will be included in the ++# documentation. ++# The default value is: NO. ++ ++HIDE_FRIEND_COMPOUNDS = NO ++ ++# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any ++# documentation blocks found inside the body of a function. If set to NO, these ++# blocks will be appended to the function's detailed documentation block. ++# The default value is: NO. ++ ++HIDE_IN_BODY_DOCS = NO ++ ++# The INTERNAL_DOCS tag determines if documentation that is typed after a ++# \internal command is included. If the tag is set to NO then the documentation ++# will be excluded. Set it to YES to include the internal documentation. ++# The default value is: NO. ++ ++INTERNAL_DOCS = NO ++ ++# With the correct setting of option CASE_SENSE_NAMES doxygen will better be ++# able to match the capabilities of the underlying filesystem. In case the ++# filesystem is case sensitive (i.e. it supports files in the same directory ++# whose names only differ in casing), the option must be set to YES to properly ++# deal with such files in case they appear in the input. For filesystems that ++# are not case sensitive the option should be be set to NO to properly deal with ++# output files written for symbols that only differ in casing, such as for two ++# classes, one named CLASS and the other named Class, and to also support ++# references to files without having to specify the exact matching casing. On ++# Windows (including Cygwin) and MacOS, users should typically set this option ++# to NO, whereas on Linux or other Unix flavors it should typically be set to ++# YES. ++# The default value is: system dependent. ++ ++CASE_SENSE_NAMES = YES ++ ++# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with ++# their full class and namespace scopes in the documentation. If set to YES, the ++# scope will be hidden. ++# The default value is: NO. ++ ++HIDE_SCOPE_NAMES = NO ++ ++# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will ++# append additional text to a page's title, such as Class Reference. If set to ++# YES the compound reference will be hidden. ++# The default value is: NO. ++ ++HIDE_COMPOUND_REFERENCE= NO ++ ++# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of ++# the files that are included by a file in the documentation of that file. ++# The default value is: YES. ++ ++SHOW_INCLUDE_FILES = YES ++ ++# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each ++# grouped member an include statement to the documentation, telling the reader ++# which file to include in order to use the member. ++# The default value is: NO. ++ ++SHOW_GROUPED_MEMB_INC = NO ++ ++# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include ++# files with double quotes in the documentation rather than with sharp brackets. ++# The default value is: NO. ++ ++FORCE_LOCAL_INCLUDES = NO ++ ++# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the ++# documentation for inline members. ++# The default value is: YES. ++ ++INLINE_INFO = YES ++ ++# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the ++# (detailed) documentation of file and class members alphabetically by member ++# name. If set to NO, the members will appear in declaration order. ++# The default value is: YES. ++ ++SORT_MEMBER_DOCS = YES ++ ++# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief ++# descriptions of file, namespace and class members alphabetically by member ++# name. If set to NO, the members will appear in declaration order. Note that ++# this will also influence the order of the classes in the class list. ++# The default value is: NO. ++ ++SORT_BRIEF_DOCS = YES ++ ++# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the ++# (brief and detailed) documentation of class members so that constructors and ++# destructors are listed first. If set to NO the constructors will appear in the ++# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. ++# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief ++# member documentation. ++# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting ++# detailed member documentation. ++# The default value is: NO. ++ ++SORT_MEMBERS_CTORS_1ST = YES ++ ++# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy ++# of group names into alphabetical order. If set to NO the group names will ++# appear in their defined order. ++# The default value is: NO. ++ ++SORT_GROUP_NAMES = YES ++ ++# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by ++# fully-qualified names, including namespaces. If set to NO, the class list will ++# be sorted only by class name, not including the namespace part. ++# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. ++# Note: This option applies only to the class list, not to the alphabetical ++# list. ++# The default value is: NO. ++ ++SORT_BY_SCOPE_NAME = NO ++ ++# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper ++# type resolution of all parameters of a function it will reject a match between ++# the prototype and the implementation of a member function even if there is ++# only one candidate or it is obvious which candidate to choose by doing a ++# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still ++# accept a match between prototype and implementation in such cases. ++# The default value is: NO. ++ ++STRICT_PROTO_MATCHING = NO ++ ++# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo ++# list. This list is created by putting \todo commands in the documentation. ++# The default value is: YES. ++ ++GENERATE_TODOLIST = YES ++ ++# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test ++# list. This list is created by putting \test commands in the documentation. ++# The default value is: YES. ++ ++GENERATE_TESTLIST = YES ++ ++# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug ++# list. This list is created by putting \bug commands in the documentation. ++# The default value is: YES. ++ ++GENERATE_BUGLIST = YES ++ ++# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) ++# the deprecated list. This list is created by putting \deprecated commands in ++# the documentation. ++# The default value is: YES. ++ ++GENERATE_DEPRECATEDLIST= YES ++ ++# The ENABLED_SECTIONS tag can be used to enable conditional documentation ++# sections, marked by \if <section_label> ... \endif and \cond <section_label> ++# ... \endcond blocks. ++ ++ENABLED_SECTIONS = ++ ++# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the ++# initial value of a variable or macro / define can have for it to appear in the ++# documentation. If the initializer consists of more lines than specified here ++# it will be hidden. Use a value of 0 to hide initializers completely. The ++# appearance of the value of individual variables and macros / defines can be ++# controlled using \showinitializer or \hideinitializer command in the ++# documentation regardless of this setting. ++# Minimum value: 0, maximum value: 10000, default value: 30. ++ ++MAX_INITIALIZER_LINES = 30 ++ ++# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at ++# the bottom of the documentation of classes and structs. If set to YES, the ++# list will mention the files that were used to generate the documentation. ++# The default value is: YES. ++ ++SHOW_USED_FILES = YES ++ ++# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This ++# will remove the Files entry from the Quick Index and from the Folder Tree View ++# (if specified). ++# The default value is: YES. ++ ++SHOW_FILES = YES ++ ++# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces ++# page. This will remove the Namespaces entry from the Quick Index and from the ++# Folder Tree View (if specified). ++# The default value is: YES. ++ ++SHOW_NAMESPACES = YES ++ ++# The FILE_VERSION_FILTER tag can be used to specify a program or script that ++# doxygen should invoke to get the current version for each file (typically from ++# the version control system). Doxygen will invoke the program by executing (via ++# popen()) the command command input-file, where command is the value of the ++# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided ++# by doxygen. Whatever the program writes to standard output is used as the file ++# version. For an example see the documentation. ++ ++FILE_VERSION_FILTER = ++ ++# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed ++# by doxygen. The layout file controls the global structure of the generated ++# output files in an output format independent way. To create the layout file ++# that represents doxygen's defaults, run doxygen with the -l option. You can ++# optionally specify a file name after the option, if omitted DoxygenLayout.xml ++# will be used as the name of the layout file. ++# ++# Note that if you run doxygen from a directory containing a file called ++# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE ++# tag is left empty. ++ ++LAYOUT_FILE = ++ ++# The CITE_BIB_FILES tag can be used to specify one or more bib files containing ++# the reference definitions. This must be a list of .bib files. The .bib ++# extension is automatically appended if omitted. This requires the bibtex tool ++# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. ++# For LaTeX the style of the bibliography can be controlled using ++# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the ++# search path. See also \cite for info how to create references. ++ ++CITE_BIB_FILES = ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to warning and progress messages ++#--------------------------------------------------------------------------- ++ ++# The QUIET tag can be used to turn on/off the messages that are generated to ++# standard output by doxygen. If QUIET is set to YES this implies that the ++# messages are off. ++# The default value is: NO. ++ ++QUIET = YES ++ ++# The WARNINGS tag can be used to turn on/off the warning messages that are ++# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES ++# this implies that the warnings are on. ++# ++# Tip: Turn warnings on while writing the documentation. ++# The default value is: YES. ++ ++WARNINGS = YES ++ ++# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate ++# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag ++# will automatically be disabled. ++# The default value is: YES. ++ ++WARN_IF_UNDOCUMENTED = YES ++ ++# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for ++# potential errors in the documentation, such as not documenting some parameters ++# in a documented function, or documenting parameters that don't exist or using ++# markup commands wrongly. ++# The default value is: YES. ++ ++WARN_IF_DOC_ERROR = YES ++ ++# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that ++# are documented, but have no documentation for their parameters or return ++# value. If set to NO, doxygen will only warn about wrong or incomplete ++# parameter documentation, but not about the absence of documentation. If ++# EXTRACT_ALL is set to YES then this flag will automatically be disabled. ++# The default value is: NO. ++ ++WARN_NO_PARAMDOC = NO ++ ++# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when ++# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS ++# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but ++# at the end of the doxygen process doxygen will return with a non-zero status. ++# Possible values are: NO, YES and FAIL_ON_WARNINGS. ++# The default value is: NO. ++ ++WARN_AS_ERROR = NO ++ ++# The WARN_FORMAT tag determines the format of the warning messages that doxygen ++# can produce. The string should contain the $file, $line, and $text tags, which ++# will be replaced by the file and line number from which the warning originated ++# and the warning text. Optionally the format may contain $version, which will ++# be replaced by the version of the file (if it could be obtained via ++# FILE_VERSION_FILTER) ++# The default value is: $file:$line: $text. ++ ++WARN_FORMAT = "$file:$line: $text" ++ ++# The WARN_LOGFILE tag can be used to specify a file to which warning and error ++# messages should be written. If left blank the output is written to standard ++# error (stderr). ++ ++WARN_LOGFILE = ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to the input files ++#--------------------------------------------------------------------------- ++ ++# The INPUT tag is used to specify the files and/or directories that contain ++# documented source files. You may enter file names like myfile.cpp or ++# directories like /usr/src/myproject. Separate the files or directories with ++# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING ++# Note: If this tag is empty the current directory is searched. ++ ++INPUT = ++ ++# This tag can be used to specify the character encoding of the source files ++# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses ++# libiconv (or the iconv built into libc) for the transcoding. See the libiconv ++# documentation (see: ++# https://www.gnu.org/software/libiconv/) for the list of possible encodings. ++# The default value is: UTF-8. ++ ++INPUT_ENCODING = UTF-8 ++ ++# If the value of the INPUT tag contains directories, you can use the ++# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and ++# *.h) to filter out the source-files in the directories. ++# ++# Note that for custom extensions or not directly supported extensions you also ++# need to set EXTENSION_MAPPING for the extension otherwise the files are not ++# read by doxygen. ++# ++# Note the list of default checked file patterns might differ from the list of ++# default file extension mappings. ++# ++# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, ++# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, ++# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, ++# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), ++# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl, ++# *.ucf, *.qsf and *.ice. ++ ++FILE_PATTERNS = *.c \ ++ *.cc \ ++ *.h \ ++ *.hpp \ ++ *.dox ++ ++# The RECURSIVE tag can be used to specify whether or not subdirectories should ++# be searched for input files as well. ++# The default value is: NO. ++ ++RECURSIVE = NO ++ ++# The EXCLUDE tag can be used to specify files and/or directories that should be ++# excluded from the INPUT source files. This way you can easily exclude a ++# subdirectory from a directory tree whose root is specified with the INPUT tag. ++# ++# Note that relative paths are relative to the directory from which doxygen is ++# run. ++ ++EXCLUDE = ++ ++# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or ++# directories that are symbolic links (a Unix file system feature) are excluded ++# from the input. ++# The default value is: NO. ++ ++EXCLUDE_SYMLINKS = NO ++ ++# If the value of the INPUT tag contains directories, you can use the ++# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude ++# certain files from those directories. ++# ++# Note that the wildcards are matched against the file with absolute path, so to ++# exclude all test directories for example use the pattern */test/* ++ ++EXCLUDE_PATTERNS = ++ ++# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names ++# (namespaces, classes, functions, etc.) that should be excluded from the ++# output. The symbol name can be a fully qualified name, a word, or if the ++# wildcard * is used, a substring. Examples: ANamespace, AClass, ++# AClass::ANamespace, ANamespace::*Test ++# ++# Note that the wildcards are matched against the file with absolute path, so to ++# exclude all test directories use the pattern */test/* ++ ++EXCLUDE_SYMBOLS = ++ ++# The EXAMPLE_PATH tag can be used to specify one or more files or directories ++# that contain example code fragments that are included (see the \include ++# command). ++ ++EXAMPLE_PATH = ++ ++# If the value of the EXAMPLE_PATH tag contains directories, you can use the ++# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and ++# *.h) to filter out the source-files in the directories. If left blank all ++# files are included. ++ ++EXAMPLE_PATTERNS = ++ ++# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be ++# searched for input files to be used with the \include or \dontinclude commands ++# irrespective of the value of the RECURSIVE tag. ++# The default value is: NO. ++ ++EXAMPLE_RECURSIVE = NO ++ ++# The IMAGE_PATH tag can be used to specify one or more files or directories ++# that contain images that are to be included in the documentation (see the ++# \image command). ++ ++IMAGE_PATH = ../../../../../doc/images ++ ++# The INPUT_FILTER tag can be used to specify a program that doxygen should ++# invoke to filter for each input file. Doxygen will invoke the filter program ++# by executing (via popen()) the command: ++# ++# <filter> <input-file> ++# ++# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the ++# name of an input file. Doxygen will then use the output that the filter ++# program writes to standard output. If FILTER_PATTERNS is specified, this tag ++# will be ignored. ++# ++# Note that the filter must not add or remove lines; it is applied before the ++# code is scanned, but not when the output code is generated. If lines are added ++# or removed, the anchors will not be placed correctly. ++# ++# Note that for custom extensions or not directly supported extensions you also ++# need to set EXTENSION_MAPPING for the extension otherwise the files are not ++# properly processed by doxygen. ++ ++INPUT_FILTER = ++ ++# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern ++# basis. Doxygen will compare the file name with each pattern and apply the ++# filter if there is a match. The filters are a list of the form: pattern=filter ++# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how ++# filters are used. If the FILTER_PATTERNS tag is empty or if none of the ++# patterns match the file name, INPUT_FILTER is applied. ++# ++# Note that for custom extensions or not directly supported extensions you also ++# need to set EXTENSION_MAPPING for the extension otherwise the files are not ++# properly processed by doxygen. ++ ++FILTER_PATTERNS = ++ ++# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using ++# INPUT_FILTER) will also be used to filter the input files that are used for ++# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). ++# The default value is: NO. ++ ++FILTER_SOURCE_FILES = NO ++ ++# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file ++# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and ++# it is also possible to disable source filtering for a specific pattern using ++# *.ext= (so without naming a filter). ++# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. ++ ++FILTER_SOURCE_PATTERNS = ++ ++# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that ++# is part of the input, its contents will be placed on the main page ++# (index.html). This can be useful if you have a project on for instance GitHub ++# and want to reuse the introduction page also for the doxygen output. ++ ++USE_MDFILE_AS_MAINPAGE = ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to source browsing ++#--------------------------------------------------------------------------- ++ ++# If the SOURCE_BROWSER tag is set to YES then a list of source files will be ++# generated. Documented entities will be cross-referenced with these sources. ++# ++# Note: To get rid of all source code in the generated output, make sure that ++# also VERBATIM_HEADERS is set to NO. ++# The default value is: NO. ++ ++SOURCE_BROWSER = YES ++ ++# Setting the INLINE_SOURCES tag to YES will include the body of functions, ++# classes and enums directly into the documentation. ++# The default value is: NO. ++ ++INLINE_SOURCES = NO ++ ++# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any ++# special comment blocks from generated source code fragments. Normal C, C++ and ++# Fortran comments will always remain visible. ++# The default value is: YES. ++ ++STRIP_CODE_COMMENTS = YES ++ ++# If the REFERENCED_BY_RELATION tag is set to YES then for each documented ++# entity all documented functions referencing it will be listed. ++# The default value is: NO. ++ ++REFERENCED_BY_RELATION = YES ++ ++# If the REFERENCES_RELATION tag is set to YES then for each documented function ++# all documented entities called/used by that function will be listed. ++# The default value is: NO. ++ ++REFERENCES_RELATION = YES ++ ++# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set ++# to YES then the hyperlinks from functions in REFERENCES_RELATION and ++# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will ++# link to the documentation. ++# The default value is: YES. ++ ++REFERENCES_LINK_SOURCE = YES ++ ++# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the ++# source code will show a tooltip with additional information such as prototype, ++# brief description and links to the definition and documentation. Since this ++# will make the HTML file larger and loading of large files a bit slower, you ++# can opt to disable this feature. ++# The default value is: YES. ++# This tag requires that the tag SOURCE_BROWSER is set to YES. ++ ++SOURCE_TOOLTIPS = YES ++ ++# If the USE_HTAGS tag is set to YES then the references to source code will ++# point to the HTML generated by the htags(1) tool instead of doxygen built-in ++# source browser. The htags tool is part of GNU's global source tagging system ++# (see https://www.gnu.org/software/global/global.html). You will need version ++# 4.8.6 or higher. ++# ++# To use it do the following: ++# - Install the latest version of global ++# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file ++# - Make sure the INPUT points to the root of the source tree ++# - Run doxygen as normal ++# ++# Doxygen will invoke htags (and that will in turn invoke gtags), so these ++# tools must be available from the command line (i.e. in the search path). ++# ++# The result: instead of the source browser generated by doxygen, the links to ++# source code will now point to the output of htags. ++# The default value is: NO. ++# This tag requires that the tag SOURCE_BROWSER is set to YES. ++ ++USE_HTAGS = NO ++ ++# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a ++# verbatim copy of the header file for each class for which an include is ++# specified. Set to NO to disable this. ++# See also: Section \class. ++# The default value is: YES. ++ ++VERBATIM_HEADERS = YES ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to the alphabetical class index ++#--------------------------------------------------------------------------- ++ ++# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all ++# compounds will be generated. Enable this if the project contains a lot of ++# classes, structs, unions or interfaces. ++# The default value is: YES. ++ ++ALPHABETICAL_INDEX = YES ++ ++# In case all classes in a project start with a common prefix, all classes will ++# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag ++# can be used to specify a prefix (or a list of prefixes) that should be ignored ++# while generating the index headers. ++# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. ++ ++IGNORE_PREFIX = ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to the HTML output ++#--------------------------------------------------------------------------- ++ ++# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output ++# The default value is: YES. ++ ++GENERATE_HTML = YES ++ ++# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a ++# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of ++# it. ++# The default directory is: html. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_OUTPUT = ../html ++ ++# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each ++# generated HTML page (for example: .htm, .php, .asp). ++# The default value is: .html. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_FILE_EXTENSION = .html ++ ++# The HTML_HEADER tag can be used to specify a user-defined HTML header file for ++# each generated HTML page. If the tag is left blank doxygen will generate a ++# standard header. ++# ++# To get valid HTML the header file that includes any scripts and style sheets ++# that doxygen needs, which is dependent on the configuration options used (e.g. ++# the setting GENERATE_TREEVIEW). It is highly recommended to start with a ++# default header using ++# doxygen -w html new_header.html new_footer.html new_stylesheet.css ++# YourConfigFile ++# and then modify the file new_header.html. See also section "Doxygen usage" ++# for information on how to generate the default header that doxygen normally ++# uses. ++# Note: The header is subject to change so you typically have to regenerate the ++# default header when upgrading to a newer version of doxygen. For a description ++# of the possible markers and block names see the documentation. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_HEADER = ++ ++# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each ++# generated HTML page. If the tag is left blank doxygen will generate a standard ++# footer. See HTML_HEADER for more information on how to generate a default ++# footer and what special commands can be used inside the footer. See also ++# section "Doxygen usage" for information on how to generate the default footer ++# that doxygen normally uses. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_FOOTER = ++ ++# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style ++# sheet that is used by each HTML page. It can be used to fine-tune the look of ++# the HTML output. If left blank doxygen will generate a default style sheet. ++# See also section "Doxygen usage" for information on how to generate the style ++# sheet that doxygen normally uses. ++# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as ++# it is more robust and this tag (HTML_STYLESHEET) will in the future become ++# obsolete. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_STYLESHEET = ++ ++# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined ++# cascading style sheets that are included after the standard style sheets ++# created by doxygen. Using this option one can overrule certain style aspects. ++# This is preferred over using HTML_STYLESHEET since it does not replace the ++# standard style sheet and is therefore more robust against future updates. ++# Doxygen will copy the style sheet files to the output directory. ++# Note: The order of the extra style sheet files is of importance (e.g. the last ++# style sheet in the list overrules the setting of the previous ones in the ++# list). For an example see the documentation. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_EXTRA_STYLESHEET = ++ ++# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or ++# other source files which should be copied to the HTML output directory. Note ++# that these files will be copied to the base HTML output directory. Use the ++# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these ++# files. In the HTML_STYLESHEET file, use the file name only. Also note that the ++# files will be copied as-is; there are no commands or markers available. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_EXTRA_FILES = ++ ++# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen ++# will adjust the colors in the style sheet and background images according to ++# this color. Hue is specified as an angle on a colorwheel, see ++# https://en.wikipedia.org/wiki/Hue for more information. For instance the value ++# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 ++# purple, and 360 is red again. ++# Minimum value: 0, maximum value: 359, default value: 220. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_COLORSTYLE_HUE = 148 ++ ++# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors ++# in the HTML output. For a value of 0 the output will use grayscales only. A ++# value of 255 will produce the most vivid colors. ++# Minimum value: 0, maximum value: 255, default value: 100. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_COLORSTYLE_SAT = 93 ++ ++# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the ++# luminance component of the colors in the HTML output. Values below 100 ++# gradually make the output lighter, whereas values above 100 make the output ++# darker. The value divided by 100 is the actual gamma applied, so 80 represents ++# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not ++# change the gamma. ++# Minimum value: 40, maximum value: 240, default value: 80. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_COLORSTYLE_GAMMA = 80 ++ ++# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML ++# page will contain the date and time when the page was generated. Setting this ++# to YES can help to show when doxygen was last run and thus if the ++# documentation is up to date. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_TIMESTAMP = YES ++ ++# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML ++# documentation will contain a main index with vertical navigation menus that ++# are dynamically created via JavaScript. If disabled, the navigation index will ++# consists of multiple levels of tabs that are statically embedded in every HTML ++# page. Disable this option to support browsers that do not have JavaScript, ++# like the Qt help browser. ++# The default value is: YES. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_DYNAMIC_MENUS = YES ++ ++# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML ++# documentation will contain sections that can be hidden and shown after the ++# page has loaded. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_DYNAMIC_SECTIONS = YES ++ ++# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries ++# shown in the various tree structured indices initially; the user can expand ++# and collapse entries dynamically later on. Doxygen will expand the tree to ++# such a level that at most the specified number of entries are visible (unless ++# a fully collapsed tree already exceeds this amount). So setting the number of ++# entries 1 will produce a full collapsed tree by default. 0 is a special value ++# representing an infinite number of entries and will result in a full expanded ++# tree by default. ++# Minimum value: 0, maximum value: 9999, default value: 100. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_INDEX_NUM_ENTRIES = 100 ++ ++# If the GENERATE_DOCSET tag is set to YES, additional index files will be ++# generated that can be used as input for Apple's Xcode 3 integrated development ++# environment (see: ++# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To ++# create a documentation set, doxygen will generate a Makefile in the HTML ++# output directory. Running make will produce the docset in that directory and ++# running make install will install the docset in ++# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at ++# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy ++# genXcode/_index.html for more information. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++GENERATE_DOCSET = NO ++ ++# This tag determines the name of the docset feed. A documentation feed provides ++# an umbrella under which multiple documentation sets from a single provider ++# (such as a company or product suite) can be grouped. ++# The default value is: Doxygen generated docs. ++# This tag requires that the tag GENERATE_DOCSET is set to YES. ++ ++DOCSET_FEEDNAME = "Doxygen generated docs" ++ ++# This tag specifies a string that should uniquely identify the documentation ++# set bundle. This should be a reverse domain-name style string, e.g. ++# com.mycompany.MyDocSet. Doxygen will append .docset to the name. ++# The default value is: org.doxygen.Project. ++# This tag requires that the tag GENERATE_DOCSET is set to YES. ++ ++DOCSET_BUNDLE_ID = org.doxygen.Project ++ ++# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify ++# the documentation publisher. This should be a reverse domain-name style ++# string, e.g. com.mycompany.MyDocSet.documentation. ++# The default value is: org.doxygen.Publisher. ++# This tag requires that the tag GENERATE_DOCSET is set to YES. ++ ++DOCSET_PUBLISHER_ID = org.doxygen.Publisher ++ ++# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. ++# The default value is: Publisher. ++# This tag requires that the tag GENERATE_DOCSET is set to YES. ++ ++DOCSET_PUBLISHER_NAME = Publisher ++ ++# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three ++# additional HTML index files: index.hhp, index.hhc, and index.hhk. The ++# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop ++# (see: ++# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows. ++# ++# The HTML Help Workshop contains a compiler that can convert all HTML output ++# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML ++# files are now used as the Windows 98 help format, and will replace the old ++# Windows help format (.hlp) on all Windows platforms in the future. Compressed ++# HTML files also contain an index, a table of contents, and you can search for ++# words in the documentation. The HTML workshop also contains a viewer for ++# compressed HTML files. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++GENERATE_HTMLHELP = NO ++ ++# The CHM_FILE tag can be used to specify the file name of the resulting .chm ++# file. You can add a path in front of the file if the result should not be ++# written to the html output directory. ++# This tag requires that the tag GENERATE_HTMLHELP is set to YES. ++ ++CHM_FILE = ++ ++# The HHC_LOCATION tag can be used to specify the location (absolute path ++# including file name) of the HTML help compiler (hhc.exe). If non-empty, ++# doxygen will try to run the HTML help compiler on the generated index.hhp. ++# The file has to be specified with full path. ++# This tag requires that the tag GENERATE_HTMLHELP is set to YES. ++ ++HHC_LOCATION = ++ ++# The GENERATE_CHI flag controls if a separate .chi index file is generated ++# (YES) or that it should be included in the main .chm file (NO). ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTMLHELP is set to YES. ++ ++GENERATE_CHI = NO ++ ++# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) ++# and project file content. ++# This tag requires that the tag GENERATE_HTMLHELP is set to YES. ++ ++CHM_INDEX_ENCODING = ++ ++# The BINARY_TOC flag controls whether a binary table of contents is generated ++# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it ++# enables the Previous and Next buttons. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTMLHELP is set to YES. ++ ++BINARY_TOC = NO ++ ++# The TOC_EXPAND flag can be set to YES to add extra items for group members to ++# the table of contents of the HTML help documentation and to the tree view. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTMLHELP is set to YES. ++ ++TOC_EXPAND = NO ++ ++# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and ++# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that ++# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help ++# (.qch) of the generated HTML documentation. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++GENERATE_QHP = NO ++ ++# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify ++# the file name of the resulting .qch file. The path specified is relative to ++# the HTML output folder. ++# This tag requires that the tag GENERATE_QHP is set to YES. ++ ++QCH_FILE = ++ ++# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help ++# Project output. For more information please see Qt Help Project / Namespace ++# (see: ++# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). ++# The default value is: org.doxygen.Project. ++# This tag requires that the tag GENERATE_QHP is set to YES. ++ ++QHP_NAMESPACE = ++ ++# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt ++# Help Project output. For more information please see Qt Help Project / Virtual ++# Folders (see: ++# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). ++# The default value is: doc. ++# This tag requires that the tag GENERATE_QHP is set to YES. ++ ++QHP_VIRTUAL_FOLDER = doc ++ ++# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom ++# filter to add. For more information please see Qt Help Project / Custom ++# Filters (see: ++# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). ++# This tag requires that the tag GENERATE_QHP is set to YES. ++ ++QHP_CUST_FILTER_NAME = ++ ++# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the ++# custom filter to add. For more information please see Qt Help Project / Custom ++# Filters (see: ++# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). ++# This tag requires that the tag GENERATE_QHP is set to YES. ++ ++QHP_CUST_FILTER_ATTRS = ++ ++# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this ++# project's filter section matches. Qt Help Project / Filter Attributes (see: ++# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). ++# This tag requires that the tag GENERATE_QHP is set to YES. ++ ++QHP_SECT_FILTER_ATTRS = ++ ++# The QHG_LOCATION tag can be used to specify the location (absolute path ++# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to ++# run qhelpgenerator on the generated .qhp file. ++# This tag requires that the tag GENERATE_QHP is set to YES. ++ ++QHG_LOCATION = ++ ++# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be ++# generated, together with the HTML files, they form an Eclipse help plugin. To ++# install this plugin and make it available under the help contents menu in ++# Eclipse, the contents of the directory containing the HTML and XML files needs ++# to be copied into the plugins directory of eclipse. The name of the directory ++# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. ++# After copying Eclipse needs to be restarted before the help appears. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++GENERATE_ECLIPSEHELP = NO ++ ++# A unique identifier for the Eclipse help plugin. When installing the plugin ++# the directory name containing the HTML and XML files should also have this ++# name. Each documentation set should have its own identifier. ++# The default value is: org.doxygen.Project. ++# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ++ ++ECLIPSE_DOC_ID = org.doxygen.Project ++ ++# If you want full control over the layout of the generated HTML pages it might ++# be necessary to disable the index and replace it with your own. The ++# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top ++# of each HTML page. A value of NO enables the index and the value YES disables ++# it. Since the tabs in the index contain the same information as the navigation ++# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++DISABLE_INDEX = NO ++ ++# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index ++# structure should be generated to display hierarchical information. If the tag ++# value is set to YES, a side panel will be generated containing a tree-like ++# index structure (just like the one that is generated for HTML Help). For this ++# to work a browser that supports JavaScript, DHTML, CSS and frames is required ++# (i.e. any modern browser). Windows users are probably better off using the ++# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can ++# further fine-tune the look of the index. As an example, the default style ++# sheet generated by doxygen has an example that shows how to put an image at ++# the root of the tree instead of the PROJECT_NAME. Since the tree basically has ++# the same information as the tab index, you could consider setting ++# DISABLE_INDEX to YES when enabling this option. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++GENERATE_TREEVIEW = YES ++ ++# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that ++# doxygen will group on one line in the generated HTML documentation. ++# ++# Note that a value of 0 will completely suppress the enum values from appearing ++# in the overview section. ++# Minimum value: 0, maximum value: 20, default value: 4. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++ENUM_VALUES_PER_LINE = 4 ++ ++# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used ++# to set the initial width (in pixels) of the frame in which the tree is shown. ++# Minimum value: 0, maximum value: 1500, default value: 250. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++TREEVIEW_WIDTH = 180 ++ ++# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to ++# external symbols imported via tag files in a separate window. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++EXT_LINKS_IN_WINDOW = NO ++ ++# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg ++# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see ++# https://inkscape.org) to generate formulas as SVG images instead of PNGs for ++# the HTML output. These images will generally look nicer at scaled resolutions. ++# Possible values are: png (the default) and svg (looks nicer but requires the ++# pdf2svg or inkscape tool). ++# The default value is: png. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++HTML_FORMULA_FORMAT = png ++ ++# Use this tag to change the font size of LaTeX formulas included as images in ++# the HTML documentation. When you change the font size after a successful ++# doxygen run you need to manually remove any form_*.png images from the HTML ++# output directory to force them to be regenerated. ++# Minimum value: 8, maximum value: 50, default value: 10. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++FORMULA_FONTSIZE = 10 ++ ++# Use the FORMULA_TRANSPARENT tag to determine whether or not the images ++# generated for formulas are transparent PNGs. Transparent PNGs are not ++# supported properly for IE 6.0, but are supported on all modern browsers. ++# ++# Note that when changing this option you need to delete any form_*.png files in ++# the HTML output directory before the changes have effect. ++# The default value is: YES. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++FORMULA_TRANSPARENT = YES ++ ++# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands ++# to create new LaTeX commands to be used in formulas as building blocks. See ++# the section "Including formulas" for details. ++ ++FORMULA_MACROFILE = ++ ++# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see ++# https://www.mathjax.org) which uses client side JavaScript for the rendering ++# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX ++# installed or if you want to formulas look prettier in the HTML output. When ++# enabled you may also need to install MathJax separately and configure the path ++# to it using the MATHJAX_RELPATH option. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++USE_MATHJAX = NO ++ ++# When MathJax is enabled you can set the default output format to be used for ++# the MathJax output. See the MathJax site (see: ++# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. ++# Possible values are: HTML-CSS (which is slower, but has the best ++# compatibility), NativeMML (i.e. MathML) and SVG. ++# The default value is: HTML-CSS. ++# This tag requires that the tag USE_MATHJAX is set to YES. ++ ++MATHJAX_FORMAT = HTML-CSS ++ ++# When MathJax is enabled you need to specify the location relative to the HTML ++# output directory using the MATHJAX_RELPATH option. The destination directory ++# should contain the MathJax.js script. For instance, if the mathjax directory ++# is located at the same level as the HTML output directory, then ++# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax ++# Content Delivery Network so you can quickly see the result without installing ++# MathJax. However, it is strongly recommended to install a local copy of ++# MathJax from https://www.mathjax.org before deployment. ++# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. ++# This tag requires that the tag USE_MATHJAX is set to YES. ++ ++MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest ++ ++# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax ++# extension names that should be enabled during MathJax rendering. For example ++# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols ++# This tag requires that the tag USE_MATHJAX is set to YES. ++ ++MATHJAX_EXTENSIONS = ++ ++# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces ++# of code that will be used on startup of the MathJax code. See the MathJax site ++# (see: ++# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an ++# example see the documentation. ++# This tag requires that the tag USE_MATHJAX is set to YES. ++ ++MATHJAX_CODEFILE = ++ ++# When the SEARCHENGINE tag is enabled doxygen will generate a search box for ++# the HTML output. The underlying search engine uses javascript and DHTML and ++# should work on any modern browser. Note that when using HTML help ++# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) ++# there is already a search function so this one should typically be disabled. ++# For large projects the javascript based search engine can be slow, then ++# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to ++# search using the keyboard; to jump to the search box use <access key> + S ++# (what the <access key> is depends on the OS and browser, but it is typically ++# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down ++# key> to jump into the search results window, the results can be navigated ++# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel ++# the search. The filter options can be selected when the cursor is inside the ++# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> ++# to select a filter and <Enter> or <escape> to activate or cancel the filter ++# option. ++# The default value is: YES. ++# This tag requires that the tag GENERATE_HTML is set to YES. ++ ++SEARCHENGINE = NO ++ ++# When the SERVER_BASED_SEARCH tag is enabled the search engine will be ++# implemented using a web server instead of a web client using JavaScript. There ++# are two flavors of web server based searching depending on the EXTERNAL_SEARCH ++# setting. When disabled, doxygen will generate a PHP script for searching and ++# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing ++# and searching needs to be provided by external tools. See the section ++# "External Indexing and Searching" for details. ++# The default value is: NO. ++# This tag requires that the tag SEARCHENGINE is set to YES. ++ ++SERVER_BASED_SEARCH = NO ++ ++# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP ++# script for searching. Instead the search results are written to an XML file ++# which needs to be processed by an external indexer. Doxygen will invoke an ++# external search engine pointed to by the SEARCHENGINE_URL option to obtain the ++# search results. ++# ++# Doxygen ships with an example indexer (doxyindexer) and search engine ++# (doxysearch.cgi) which are based on the open source search engine library ++# Xapian (see: ++# https://xapian.org/). ++# ++# See the section "External Indexing and Searching" for details. ++# The default value is: NO. ++# This tag requires that the tag SEARCHENGINE is set to YES. ++ ++EXTERNAL_SEARCH = NO ++ ++# The SEARCHENGINE_URL should point to a search engine hosted by a web server ++# which will return the search results when EXTERNAL_SEARCH is enabled. ++# ++# Doxygen ships with an example indexer (doxyindexer) and search engine ++# (doxysearch.cgi) which are based on the open source search engine library ++# Xapian (see: ++# https://xapian.org/). See the section "External Indexing and Searching" for ++# details. ++# This tag requires that the tag SEARCHENGINE is set to YES. ++ ++SEARCHENGINE_URL = ++ ++# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed ++# search data is written to a file for indexing by an external tool. With the ++# SEARCHDATA_FILE tag the name of this file can be specified. ++# The default file is: searchdata.xml. ++# This tag requires that the tag SEARCHENGINE is set to YES. ++ ++SEARCHDATA_FILE = searchdata.xml ++ ++# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the ++# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is ++# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple ++# projects and redirect the results back to the right project. ++# This tag requires that the tag SEARCHENGINE is set to YES. ++ ++EXTERNAL_SEARCH_ID = ++ ++# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen ++# projects other than the one defined by this configuration file, but that are ++# all added to the same external search index. Each project needs to have a ++# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of ++# to a relative location where the documentation can be found. The format is: ++# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... ++# This tag requires that the tag SEARCHENGINE is set to YES. ++ ++EXTRA_SEARCH_MAPPINGS = ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to the LaTeX output ++#--------------------------------------------------------------------------- ++ ++# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. ++# The default value is: YES. ++ ++GENERATE_LATEX = NO ++ ++# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a ++# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of ++# it. ++# The default directory is: latex. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_OUTPUT = latex ++ ++# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be ++# invoked. ++# ++# Note that when not enabling USE_PDFLATEX the default is latex when enabling ++# USE_PDFLATEX the default is pdflatex and when in the later case latex is ++# chosen this is overwritten by pdflatex. For specific output languages the ++# default can have been set differently, this depends on the implementation of ++# the output language. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_CMD_NAME = latex ++ ++# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate ++# index for LaTeX. ++# Note: This tag is used in the Makefile / make.bat. ++# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file ++# (.tex). ++# The default file is: makeindex. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++MAKEINDEX_CMD_NAME = makeindex ++ ++# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to ++# generate index for LaTeX. In case there is no backslash (\) as first character ++# it will be automatically added in the LaTeX code. ++# Note: This tag is used in the generated output file (.tex). ++# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. ++# The default value is: makeindex. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_MAKEINDEX_CMD = makeindex ++ ++# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX ++# documents. This may be useful for small projects and may help to save some ++# trees in general. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++COMPACT_LATEX = NO ++ ++# The PAPER_TYPE tag can be used to set the paper type that is used by the ++# printer. ++# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x ++# 14 inches) and executive (7.25 x 10.5 inches). ++# The default value is: a4. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++PAPER_TYPE = a4 ++ ++# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names ++# that should be included in the LaTeX output. The package can be specified just ++# by its name or with the correct syntax as to be used with the LaTeX ++# \usepackage command. To get the times font for instance you can specify : ++# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} ++# To use the option intlimits with the amsmath package you can specify: ++# EXTRA_PACKAGES=[intlimits]{amsmath} ++# If left blank no extra packages will be included. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++EXTRA_PACKAGES = ++ ++# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the ++# generated LaTeX document. The header should contain everything until the first ++# chapter. If it is left blank doxygen will generate a standard header. See ++# section "Doxygen usage" for information on how to let doxygen write the ++# default header to a separate file. ++# ++# Note: Only use a user-defined header if you know what you are doing! The ++# following commands have a special meaning inside the header: $title, ++# $datetime, $date, $doxygenversion, $projectname, $projectnumber, ++# $projectbrief, $projectlogo. Doxygen will replace $title with the empty ++# string, for the replacement values of the other commands the user is referred ++# to HTML_HEADER. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_HEADER = ++ ++# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the ++# generated LaTeX document. The footer should contain everything after the last ++# chapter. If it is left blank doxygen will generate a standard footer. See ++# LATEX_HEADER for more information on how to generate a default footer and what ++# special commands can be used inside the footer. ++# ++# Note: Only use a user-defined footer if you know what you are doing! ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_FOOTER = ++ ++# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined ++# LaTeX style sheets that are included after the standard style sheets created ++# by doxygen. Using this option one can overrule certain style aspects. Doxygen ++# will copy the style sheet files to the output directory. ++# Note: The order of the extra style sheet files is of importance (e.g. the last ++# style sheet in the list overrules the setting of the previous ones in the ++# list). ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_EXTRA_STYLESHEET = ++ ++# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or ++# other source files which should be copied to the LATEX_OUTPUT output ++# directory. Note that the files will be copied as-is; there are no commands or ++# markers available. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_EXTRA_FILES = ++ ++# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is ++# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will ++# contain links (just like the HTML output) instead of page references. This ++# makes the output suitable for online browsing using a PDF viewer. ++# The default value is: YES. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++PDF_HYPERLINKS = NO ++ ++# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as ++# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX ++# files. Set this option to YES, to get a higher quality PDF documentation. ++# ++# See also section LATEX_CMD_NAME for selecting the engine. ++# The default value is: YES. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++USE_PDFLATEX = NO ++ ++# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode ++# command to the generated LaTeX files. This will instruct LaTeX to keep running ++# if errors occur, instead of asking the user for help. This option is also used ++# when generating formulas in HTML. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_BATCHMODE = NO ++ ++# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the ++# index chapters (such as File Index, Compound Index, etc.) in the output. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_HIDE_INDICES = NO ++ ++# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source ++# code with syntax highlighting in the LaTeX output. ++# ++# Note that which sources are shown also depends on other settings such as ++# SOURCE_BROWSER. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_SOURCE_CODE = NO ++ ++# The LATEX_BIB_STYLE tag can be used to specify the style to use for the ++# bibliography, e.g. plainnat, or ieeetr. See ++# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. ++# The default value is: plain. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_BIB_STYLE = plain ++ ++# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated ++# page will contain the date and time when the page was generated. Setting this ++# to NO can help when comparing the output of multiple runs. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_TIMESTAMP = NO ++ ++# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) ++# path from which the emoji images will be read. If a relative path is entered, ++# it will be relative to the LATEX_OUTPUT directory. If left blank the ++# LATEX_OUTPUT directory will be used. ++# This tag requires that the tag GENERATE_LATEX is set to YES. ++ ++LATEX_EMOJI_DIRECTORY = ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to the RTF output ++#--------------------------------------------------------------------------- ++ ++# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The ++# RTF output is optimized for Word 97 and may not look too pretty with other RTF ++# readers/editors. ++# The default value is: NO. ++ ++GENERATE_RTF = NO ++ ++# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a ++# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of ++# it. ++# The default directory is: rtf. ++# This tag requires that the tag GENERATE_RTF is set to YES. ++ ++RTF_OUTPUT = rtf ++ ++# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF ++# documents. This may be useful for small projects and may help to save some ++# trees in general. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_RTF is set to YES. ++ ++COMPACT_RTF = NO ++ ++# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will ++# contain hyperlink fields. The RTF file will contain links (just like the HTML ++# output) instead of page references. This makes the output suitable for online ++# browsing using Word or some other Word compatible readers that support those ++# fields. ++# ++# Note: WordPad (write) and others do not support links. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_RTF is set to YES. ++ ++RTF_HYPERLINKS = NO ++ ++# Load stylesheet definitions from file. Syntax is similar to doxygen's ++# configuration file, i.e. a series of assignments. You only have to provide ++# replacements, missing definitions are set to their default value. ++# ++# See also section "Doxygen usage" for information on how to generate the ++# default style sheet that doxygen normally uses. ++# This tag requires that the tag GENERATE_RTF is set to YES. ++ ++RTF_STYLESHEET_FILE = ++ ++# Set optional variables used in the generation of an RTF document. Syntax is ++# similar to doxygen's configuration file. A template extensions file can be ++# generated using doxygen -e rtf extensionFile. ++# This tag requires that the tag GENERATE_RTF is set to YES. ++ ++RTF_EXTENSIONS_FILE = ++ ++# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code ++# with syntax highlighting in the RTF output. ++# ++# Note that which sources are shown also depends on other settings such as ++# SOURCE_BROWSER. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_RTF is set to YES. ++ ++RTF_SOURCE_CODE = NO ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to the man page output ++#--------------------------------------------------------------------------- ++ ++# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for ++# classes and files. ++# The default value is: NO. ++ ++GENERATE_MAN = NO ++ ++# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a ++# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of ++# it. A directory man3 will be created inside the directory specified by ++# MAN_OUTPUT. ++# The default directory is: man. ++# This tag requires that the tag GENERATE_MAN is set to YES. ++ ++MAN_OUTPUT = man ++ ++# The MAN_EXTENSION tag determines the extension that is added to the generated ++# man pages. In case the manual section does not start with a number, the number ++# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is ++# optional. ++# The default value is: .3. ++# This tag requires that the tag GENERATE_MAN is set to YES. ++ ++MAN_EXTENSION = .3 ++ ++# The MAN_SUBDIR tag determines the name of the directory created within ++# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by ++# MAN_EXTENSION with the initial . removed. ++# This tag requires that the tag GENERATE_MAN is set to YES. ++ ++MAN_SUBDIR = ++ ++# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it ++# will generate one additional man file for each entity documented in the real ++# man page(s). These additional files only source the real man page, but without ++# them the man command would be unable to find the correct page. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_MAN is set to YES. ++ ++MAN_LINKS = NO ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to the XML output ++#--------------------------------------------------------------------------- ++ ++# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that ++# captures the structure of the code including all documentation. ++# The default value is: NO. ++ ++GENERATE_XML = NO ++ ++# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a ++# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of ++# it. ++# The default directory is: xml. ++# This tag requires that the tag GENERATE_XML is set to YES. ++ ++XML_OUTPUT = xml ++ ++# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program ++# listings (including syntax highlighting and cross-referencing information) to ++# the XML output. Note that enabling this will significantly increase the size ++# of the XML output. ++# The default value is: YES. ++# This tag requires that the tag GENERATE_XML is set to YES. ++ ++XML_PROGRAMLISTING = NO ++ ++# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include ++# namespace members in file scope as well, matching the HTML output. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_XML is set to YES. ++ ++XML_NS_MEMB_FILE_SCOPE = NO ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to the DOCBOOK output ++#--------------------------------------------------------------------------- ++ ++# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files ++# that can be used to generate PDF. ++# The default value is: NO. ++ ++GENERATE_DOCBOOK = NO ++ ++# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. ++# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in ++# front of it. ++# The default directory is: docbook. ++# This tag requires that the tag GENERATE_DOCBOOK is set to YES. ++ ++DOCBOOK_OUTPUT = docbook ++ ++# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the ++# program listings (including syntax highlighting and cross-referencing ++# information) to the DOCBOOK output. Note that enabling this will significantly ++# increase the size of the DOCBOOK output. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_DOCBOOK is set to YES. ++ ++DOCBOOK_PROGRAMLISTING = NO ++ ++#--------------------------------------------------------------------------- ++# Configuration options for the AutoGen Definitions output ++#--------------------------------------------------------------------------- ++ ++# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an ++# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures ++# the structure of the code including all documentation. Note that this feature ++# is still experimental and incomplete at the moment. ++# The default value is: NO. ++ ++GENERATE_AUTOGEN_DEF = NO ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to the Perl module output ++#--------------------------------------------------------------------------- ++ ++# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module ++# file that captures the structure of the code including all documentation. ++# ++# Note that this feature is still experimental and incomplete at the moment. ++# The default value is: NO. ++ ++GENERATE_PERLMOD = NO ++ ++# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary ++# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI ++# output from the Perl module output. ++# The default value is: NO. ++# This tag requires that the tag GENERATE_PERLMOD is set to YES. ++ ++PERLMOD_LATEX = NO ++ ++# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely ++# formatted so it can be parsed by a human reader. This is useful if you want to ++# understand what is going on. On the other hand, if this tag is set to NO, the ++# size of the Perl module output will be much smaller and Perl will parse it ++# just the same. ++# The default value is: YES. ++# This tag requires that the tag GENERATE_PERLMOD is set to YES. ++ ++PERLMOD_PRETTY = YES ++ ++# The names of the make variables in the generated doxyrules.make file are ++# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful ++# so different doxyrules.make files included by the same Makefile don't ++# overwrite each other's variables. ++# This tag requires that the tag GENERATE_PERLMOD is set to YES. ++ ++PERLMOD_MAKEVAR_PREFIX = ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to the preprocessor ++#--------------------------------------------------------------------------- ++ ++# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all ++# C-preprocessor directives found in the sources and include files. ++# The default value is: YES. ++ ++ENABLE_PREPROCESSING = YES ++ ++# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names ++# in the source code. If set to NO, only conditional compilation will be ++# performed. Macro expansion can be done in a controlled way by setting ++# EXPAND_ONLY_PREDEF to YES. ++# The default value is: NO. ++# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. ++ ++MACRO_EXPANSION = YES ++ ++# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then ++# the macro expansion is limited to the macros specified with the PREDEFINED and ++# EXPAND_AS_DEFINED tags. ++# The default value is: NO. ++# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. ++ ++EXPAND_ONLY_PREDEF = NO ++ ++# If the SEARCH_INCLUDES tag is set to YES, the include files in the ++# INCLUDE_PATH will be searched if a #include is found. ++# The default value is: YES. ++# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. ++ ++SEARCH_INCLUDES = YES ++ ++# The INCLUDE_PATH tag can be used to specify one or more directories that ++# contain include files that are not input files but should be processed by the ++# preprocessor. ++# This tag requires that the tag SEARCH_INCLUDES is set to YES. ++ ++INCLUDE_PATH = ++ ++# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard ++# patterns (like *.h and *.hpp) to filter out the header-files in the ++# directories. If left blank, the patterns specified with FILE_PATTERNS will be ++# used. ++# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. ++ ++INCLUDE_FILE_PATTERNS = ++ ++# The PREDEFINED tag can be used to specify one or more macro names that are ++# defined before the preprocessor is started (similar to the -D option of e.g. ++# gcc). The argument of the tag is a list of macros of the form: name or ++# name=definition (no spaces). If the definition and the "=" are omitted, "=1" ++# is assumed. To prevent a macro definition from being undefined via #undef or ++# recursively expanded use the := operator instead of the = operator. ++# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. ++ ++PREDEFINED = ++ ++# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this ++# tag can be used to specify a list of macro names that should be expanded. The ++# macro definition that is found in the sources will be used. Use the PREDEFINED ++# tag if you want to use a different macro definition that overrules the ++# definition found in the source code. ++# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. ++ ++EXPAND_AS_DEFINED = ++ ++# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will ++# remove all references to function-like macros that are alone on a line, have ++# an all uppercase name, and do not end with a semicolon. Such function macros ++# are typically used for boiler-plate code, and will confuse the parser if not ++# removed. ++# The default value is: YES. ++# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. ++ ++SKIP_FUNCTION_MACROS = YES ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to external references ++#--------------------------------------------------------------------------- ++ ++# The TAGFILES tag can be used to specify one or more tag files. For each tag ++# file the location of the external documentation should be added. The format of ++# a tag file without this location is as follows: ++# TAGFILES = file1 file2 ... ++# Adding location for the tag files is done as follows: ++# TAGFILES = file1=loc1 "file2 = loc2" ... ++# where loc1 and loc2 can be relative or absolute paths or URLs. See the ++# section "Linking to external documentation" for more information about the use ++# of tag files. ++# Note: Each tag file must have a unique name (where the name does NOT include ++# the path). If a tag file is not located in the directory in which doxygen is ++# run, you must also specify the path to the tagfile here. ++ ++TAGFILES = ++ ++# When a file name is specified after GENERATE_TAGFILE, doxygen will create a ++# tag file that is based on the input files it reads. See section "Linking to ++# external documentation" for more information about the usage of tag files. ++ ++GENERATE_TAGFILE = ++ ++# If the ALLEXTERNALS tag is set to YES, all external class will be listed in ++# the class index. If set to NO, only the inherited external classes will be ++# listed. ++# The default value is: NO. ++ ++ALLEXTERNALS = NO ++ ++# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed ++# in the modules index. If set to NO, only the current project's groups will be ++# listed. ++# The default value is: YES. ++ ++EXTERNAL_GROUPS = YES ++ ++# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in ++# the related pages index. If set to NO, only the current project's pages will ++# be listed. ++# The default value is: YES. ++ ++EXTERNAL_PAGES = YES ++ ++#--------------------------------------------------------------------------- ++# Configuration options related to the dot tool ++#--------------------------------------------------------------------------- ++ ++# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram ++# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to ++# NO turns the diagrams off. Note that this option also works with HAVE_DOT ++# disabled, but it is recommended to install and use dot, since it yields more ++# powerful graphs. ++# The default value is: YES. ++ ++CLASS_DIAGRAMS = YES ++ ++# You can include diagrams made with dia in doxygen documentation. Doxygen will ++# then run dia to produce the diagram and insert it in the documentation. The ++# DIA_PATH tag allows you to specify the directory where the dia binary resides. ++# If left empty dia is assumed to be found in the default search path. ++ ++DIA_PATH = ++ ++# If set to YES the inheritance and collaboration graphs will hide inheritance ++# and usage relations if the target is undocumented or is not a class. ++# The default value is: YES. ++ ++HIDE_UNDOC_RELATIONS = YES ++ ++# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is ++# available from the path. This tool is part of Graphviz (see: ++# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent ++# Bell Labs. The other options in this section have no effect if this option is ++# set to NO ++# The default value is: NO. ++ ++HAVE_DOT = YES ++ ++# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed ++# to run in parallel. When set to 0 doxygen will base this on the number of ++# processors available in the system. You can set it explicitly to a value ++# larger than 0 to get control over the balance between CPU load and processing ++# speed. ++# Minimum value: 0, maximum value: 32, default value: 0. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++DOT_NUM_THREADS = 0 ++ ++# When you want a differently looking font in the dot files that doxygen ++# generates you can specify the font name using DOT_FONTNAME. You need to make ++# sure dot is able to find the font, which can be done by putting it in a ++# standard location or by setting the DOTFONTPATH environment variable or by ++# setting DOT_FONTPATH to the directory containing the font. ++# The default value is: Helvetica. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++DOT_FONTNAME = Helvetica ++ ++# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of ++# dot graphs. ++# Minimum value: 4, maximum value: 24, default value: 10. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++DOT_FONTSIZE = 10 ++ ++# By default doxygen will tell dot to use the default font as specified with ++# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set ++# the path where dot can find it using this tag. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++DOT_FONTPATH = ++ ++# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for ++# each documented class showing the direct and indirect inheritance relations. ++# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. ++# The default value is: YES. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++CLASS_GRAPH = YES ++ ++# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a ++# graph for each documented class showing the direct and indirect implementation ++# dependencies (inheritance, containment, and class references variables) of the ++# class with other documented classes. ++# The default value is: YES. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++COLLABORATION_GRAPH = NO ++ ++# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for ++# groups, showing the direct groups dependencies. ++# The default value is: YES. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++GROUP_GRAPHS = YES ++ ++# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and ++# collaboration diagrams in a style similar to the OMG's Unified Modeling ++# Language. ++# The default value is: NO. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++UML_LOOK = NO ++ ++# If the UML_LOOK tag is enabled, the fields and methods are shown inside the ++# class node. If there are many fields or methods and many nodes the graph may ++# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the ++# number of items for each type to make the size more manageable. Set this to 0 ++# for no limit. Note that the threshold may be exceeded by 50% before the limit ++# is enforced. So when you set the threshold to 10, up to 15 fields may appear, ++# but if the number exceeds 15, the total amount of fields shown is limited to ++# 10. ++# Minimum value: 0, maximum value: 100, default value: 10. ++# This tag requires that the tag UML_LOOK is set to YES. ++ ++UML_LIMIT_NUM_FIELDS = 10 ++ ++# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and ++# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS ++# tag is set to YES, doxygen will add type and arguments for attributes and ++# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen ++# will not generate fields with class member information in the UML graphs. The ++# class diagrams will look similar to the default class diagrams but using UML ++# notation for the relationships. ++# Possible values are: NO, YES and NONE. ++# The default value is: NO. ++# This tag requires that the tag UML_LOOK is set to YES. ++ ++DOT_UML_DETAILS = NO ++ ++# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters ++# to display on a single line. If the actual line length exceeds this threshold ++# significantly it will wrapped across multiple lines. Some heuristics are apply ++# to avoid ugly line breaks. ++# Minimum value: 0, maximum value: 1000, default value: 17. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++DOT_WRAP_THRESHOLD = 17 ++ ++# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and ++# collaboration graphs will show the relations between templates and their ++# instances. ++# The default value is: NO. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++TEMPLATE_RELATIONS = NO ++ ++# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to ++# YES then doxygen will generate a graph for each documented file showing the ++# direct and indirect include dependencies of the file with other documented ++# files. ++# The default value is: YES. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++INCLUDE_GRAPH = YES ++ ++# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are ++# set to YES then doxygen will generate a graph for each documented file showing ++# the direct and indirect include dependencies of the file with other documented ++# files. ++# The default value is: YES. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++INCLUDED_BY_GRAPH = YES ++ ++# If the CALL_GRAPH tag is set to YES then doxygen will generate a call ++# dependency graph for every global function or class method. ++# ++# Note that enabling this option will significantly increase the time of a run. ++# So in most cases it will be better to enable call graphs for selected ++# functions only using the \callgraph command. Disabling a call graph can be ++# accomplished by means of the command \hidecallgraph. ++# The default value is: NO. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++CALL_GRAPH = YES ++ ++# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller ++# dependency graph for every global function or class method. ++# ++# Note that enabling this option will significantly increase the time of a run. ++# So in most cases it will be better to enable caller graphs for selected ++# functions only using the \callergraph command. Disabling a caller graph can be ++# accomplished by means of the command \hidecallergraph. ++# The default value is: NO. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++CALLER_GRAPH = NO ++ ++# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical ++# hierarchy of all classes instead of a textual one. ++# The default value is: YES. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++GRAPHICAL_HIERARCHY = YES ++ ++# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the ++# dependencies a directory has on other directories in a graphical way. The ++# dependency relations are determined by the #include relations between the ++# files in the directories. ++# The default value is: YES. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++DIRECTORY_GRAPH = YES ++ ++# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images ++# generated by dot. For an explanation of the image formats see the section ++# output formats in the documentation of the dot tool (Graphviz (see: ++# http://www.graphviz.org/)). ++# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order ++# to make the SVG files visible in IE 9+ (other browsers do not have this ++# requirement). ++# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, ++# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and ++# png:gdiplus:gdiplus. ++# The default value is: png. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++DOT_IMAGE_FORMAT = png ++ ++# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to ++# enable generation of interactive SVG images that allow zooming and panning. ++# ++# Note that this requires a modern browser other than Internet Explorer. Tested ++# and working are Firefox, Chrome, Safari, and Opera. ++# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make ++# the SVG files visible. Older versions of IE do not have SVG support. ++# The default value is: NO. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++INTERACTIVE_SVG = NO ++ ++# The DOT_PATH tag can be used to specify the path where the dot tool can be ++# found. If left blank, it is assumed the dot tool can be found in the path. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++DOT_PATH = ++ ++# The DOTFILE_DIRS tag can be used to specify one or more directories that ++# contain dot files that are included in the documentation (see the \dotfile ++# command). ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++DOTFILE_DIRS = ++ ++# The MSCFILE_DIRS tag can be used to specify one or more directories that ++# contain msc files that are included in the documentation (see the \mscfile ++# command). ++ ++MSCFILE_DIRS = ++ ++# The DIAFILE_DIRS tag can be used to specify one or more directories that ++# contain dia files that are included in the documentation (see the \diafile ++# command). ++ ++DIAFILE_DIRS = ++ ++# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the ++# path where java can find the plantuml.jar file. If left blank, it is assumed ++# PlantUML is not used or called during a preprocessing step. Doxygen will ++# generate a warning when it encounters a \startuml command in this case and ++# will not generate output for the diagram. ++ ++PLANTUML_JAR_PATH = ++ ++# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a ++# configuration file for plantuml. ++ ++PLANTUML_CFG_FILE = ++ ++# When using plantuml, the specified paths are searched for files specified by ++# the !include statement in a plantuml block. ++ ++PLANTUML_INCLUDE_PATH = ++ ++# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes ++# that will be shown in the graph. If the number of nodes in a graph becomes ++# larger than this value, doxygen will truncate the graph, which is visualized ++# by representing a node as a red box. Note that doxygen if the number of direct ++# children of the root node in a graph is already larger than ++# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that ++# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. ++# Minimum value: 0, maximum value: 10000, default value: 50. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++DOT_GRAPH_MAX_NODES = 200 ++ ++# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs ++# generated by dot. A depth value of 3 means that only nodes reachable from the ++# root by following a path via at most 3 edges will be shown. Nodes that lay ++# further from the root node will be omitted. Note that setting this option to 1 ++# or 2 may greatly reduce the computation time needed for large code bases. Also ++# note that the size of a graph can be further restricted by ++# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. ++# Minimum value: 0, maximum value: 1000, default value: 0. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++MAX_DOT_GRAPH_DEPTH = 0 ++ ++# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent ++# background. This is disabled by default, because dot on Windows does not seem ++# to support this out of the box. ++# ++# Warning: Depending on the platform used, enabling this option may lead to ++# badly anti-aliased labels on the edges of a graph (i.e. they become hard to ++# read). ++# The default value is: NO. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++DOT_TRANSPARENT = NO ++ ++# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output ++# files in one run (i.e. multiple -o and -T options on the command line). This ++# makes dot run faster, but since only newer versions of dot (>1.8.10) support ++# this, this feature is disabled by default. ++# The default value is: NO. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++DOT_MULTI_TARGETS = NO ++ ++# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page ++# explaining the meaning of the various boxes and arrows in the dot generated ++# graphs. ++# The default value is: YES. ++# This tag requires that the tag HAVE_DOT is set to YES. ++ ++GENERATE_LEGEND = YES ++ ++# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate ++# files that are used to generate the various graphs. ++# ++# Note: This setting is not only used for dot files but also for msc and ++# plantuml temporary files. ++# The default value is: YES. ++ ++DOT_CLEANUP = YES +diff --git a/src/hooks/dhcp/ping_check/Makefile.am b/src/hooks/dhcp/ping_check/Makefile.am +new file mode 100644 +index 0000000000..a7ea17f400 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/Makefile.am +@@ -0,0 +1,104 @@ ++SUBDIRS = . libloadtests tests ++ ++AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib ++AM_CPPFLAGS += $(BOOST_INCLUDES) $(CRYPTO_CFLAGS) $(CRYPTO_INCLUDES) ++AM_CXXFLAGS = $(KEA_CXXFLAGS) ++ ++# Ensure that the message file and doxygen file is included in the distribution ++EXTRA_DIST = ping_check_messages.mes ++ ++CLEANFILES = *.gcno *.gcda ++ ++# convenience archive ++ ++noinst_LTLIBRARIES = libping_check.la ++ ++libping_check_la_SOURCES = ping_check_callouts.cc ++libping_check_la_SOURCES += ping_check_log.cc ping_check_log.h ++libping_check_la_SOURCES += ping_check_messages.cc ping_check_messages.h ++libping_check_la_SOURCES += icmp_endpoint.h icmp_socket.h ++libping_check_la_SOURCES += ping_context.cc ping_context.h ++libping_check_la_SOURCES += ping_context_store.cc ping_context_store.h ++libping_check_la_SOURCES += icmp_msg.h icmp_msg.cc ++libping_check_la_SOURCES += ping_channel.cc ping_channel.h ++libping_check_la_SOURCES += ping_check_mgr.cc ping_check_mgr.h ++libping_check_la_SOURCES += ping_check_config.cc ping_check_config.h ++libping_check_la_SOURCES += config_cache.cc config_cache.h ++libping_check_la_SOURCES += version.cc ++ ++libping_check_la_CXXFLAGS = $(AM_CXXFLAGS) ++libping_check_la_CPPFLAGS = $(AM_CPPFLAGS) ++ ++# install the shared object into $(libdir)/kea/hooks ++lib_hooksdir = $(libdir)/kea/hooks ++lib_hooks_LTLIBRARIES = libdhcp_ping_check.la ++ ++libdhcp_ping_check_la_SOURCES = ++libdhcp_ping_check_la_LDFLAGS = $(AM_LDFLAGS) ++libdhcp_ping_check_la_LDFLAGS += -avoid-version -export-dynamic -module ++libdhcp_ping_check_la_LIBADD = libping_check.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/process/libkea-process.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/eval/libkea-eval.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/stats/libkea-stats.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/http/libkea-http.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/database/libkea-database.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/cc/libkea-cc.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/dns/libkea-dns++.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/log/libkea-log.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/util/libkea-util.la ++libdhcp_ping_check_la_LIBADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la ++libdhcp_ping_check_la_LIBADD += $(LOG4CPLUS_LIBS) ++libdhcp_ping_check_la_LIBADD += $(CRYPTO_LIBS) ++libdhcp_ping_check_la_LIBADD += $(BOOST_LIBS) ++ ++# Doxygen documentation ++EXTRA_DIST += ping_check.dox Doxyfile ++ ++devel: ++ mkdir -p html ++ (cat Doxyfile; echo PROJECT_NUMBER=$(PACKAGE_VERSION)) | doxygen - > html/doxygen.log 2> html/doxygen-error.log ++ echo `grep -i ": warning:" html/doxygen-error.log | wc -l` warnings/errors detected. ++ ++clean-local: ++ rm -rf html ++ ++# If we want to get rid of all generated messages files, we need to use ++# make maintainer-clean. The proper way to introduce custom commands for ++# that operation is to define maintainer-clean-local target. However, ++# make maintainer-clean also removes Makefile, so running configure script ++# is required. To make it easy to rebuild messages without going through ++# reconfigure, a new target messages-clean has been added. ++maintainer-clean-local: ++ rm -f ping_check_messages.h ping_check_messages.cc ++ ++# To regenerate messages files, one can do: ++# ++# make messages-clean ++# make messages ++# ++# This is needed only when a .mes file is modified. ++messages-clean: maintainer-clean-local ++ ++if GENERATE_MESSAGES ++ ++# Define rule to build logging source files from message file ++messages: ping_check_messages.h ping_check_messages.cc ++ @echo Message files regenerated ++ ++ping_check_messages.h ping_check_messages.cc: ping_check_messages.mes ++ (cd $(top_srcdir); \ ++ $(abs_top_builddir)/src/lib/log/compiler/kea-msg-compiler src/hooks/dhcp/ping_check/ping_check_messages.mes) ++ ++else ++ ++messages ping_check_messages.h ping_check_messages.cc: ++ @echo Messages generation disabled. Configure with --enable-generate-messages to enable it. ++ ++endif +diff --git a/src/hooks/dhcp/ping_check/config_cache.cc b/src/hooks/dhcp/ping_check/config_cache.cc +new file mode 100644 +index 0000000000..9a8f9dd4bb +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/config_cache.cc +@@ -0,0 +1,107 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++ ++#include <config_cache.h> ++#include <util/multi_threading_mgr.h> ++ ++using namespace isc; ++using namespace isc::data; ++using namespace isc::dhcp; ++using namespace isc::util; ++using namespace std; ++ ++namespace isc { ++namespace ping_check { ++ ++PingCheckConfigPtr& ++ConfigCache::getGlobalConfig() { ++ return (global_config_); ++} ++ ++void ++ConfigCache::setGlobalConfig(PingCheckConfigPtr& config) { ++ if (!config) { ++ isc_throw(BadValue, "ConfigCache - global config cannot be empty"); ++ } ++ ++ global_config_ = config; ++} ++ ++bool ++ConfigCache::findConfig(const SubnetID& subnet_id, PingCheckConfigPtr& config) { ++ MultiThreadingLock lock(*mutex_); ++ return (findConfigInternal(subnet_id, config)); ++} ++ ++bool ++ConfigCache::findConfigInternal(const SubnetID& subnet_id, PingCheckConfigPtr& config) const { ++ auto it = configs_.find(subnet_id); ++ if (it != configs_.end()) { ++ config = it->second; ++ return (true); ++ } ++ ++ config = PingCheckConfigPtr(); ++ return (false); ++} ++ ++PingCheckConfigPtr ++ConfigCache::parseAndCacheConfig(const SubnetID& subnet_id, ConstElementPtr& user_context) { ++ PingCheckConfigPtr config; ++ if (user_context) { ++ ConstElementPtr ping_check_params = user_context->get("ping-check"); ++ if (ping_check_params) { ++ // Copy construct from global to start with. ++ config.reset(new PingCheckConfig(*getGlobalConfig())); ++ ++ // Now parse in subnet-specific values. This may throw a DhcpConfigError but ++ // that's OK, dealt with by the caller. ++ try { ++ config->parse(ping_check_params); ++ } catch (...) { ++ throw; ++ } ++ } ++ } ++ ++ // Cache the config. We allow empty configs so higher precedence scopes may ++ // override lower precedence scopes. ++ cacheConfig(subnet_id, config); ++ return (config); ++} ++ ++void ++ConfigCache::cacheConfig(const SubnetID& subnet_id, PingCheckConfigPtr& config) { ++ MultiThreadingLock lock(*mutex_); ++ configs_[subnet_id] = config; ++} ++ ++void ++ConfigCache::flush() { ++ MultiThreadingLock lock(*mutex_); ++ // Discard the contents. ++ configs_.clear(); ++ ++ // We use modification time to remember the last time we flushed. ++ updateModificationTime(); ++} ++ ++size_t ++ConfigCache::size() { ++ MultiThreadingLock lock(*mutex_); ++ return (configs_.size()); ++} ++ ++boost::posix_time::ptime ++ConfigCache::getLastFlushTime() { ++ MultiThreadingLock lock(*mutex_); ++ return (BaseStampedElement::getModificationTime()); ++} ++ ++} // end of namespace ping_check ++} // end of namespace isc +diff --git a/src/hooks/dhcp/ping_check/config_cache.h b/src/hooks/dhcp/ping_check/config_cache.h +new file mode 100644 +index 0000000000..b69cf6f124 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/config_cache.h +@@ -0,0 +1,146 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#ifndef CONFIG_CACHE_H ++#define CONFIG_CACHE_H ++ ++#include <ping_check_config.h> ++#include <cc/base_stamped_element.h> ++#include <cc/data.h> ++#include <dhcpsrv/subnet.h> ++ ++#include <map> ++#include <mutex> ++ ++namespace isc { ++namespace ping_check { ++ ++/// @brief ConfigCache stores ping check config per subnet ++/// ++/// The intent is parse subnet ping-check parameters from its user-context ++/// as few times as possible rather than on every ping check request, while ++/// also allowing for run time updates via config back end or subnet cmds. ++/// ++/// For every subnet we store: ++/// ++/// -# subnet id ++/// -# PingCheckConfig pointer ++/// where: ++/// - empty config pointer means that subnet does not specify ping check config ++/// - non-empty means subnet specifies at least some ping check parameters ++/// ++/// Each time we clear the cache we update the modification time. ++/// ++/// When presented with a subnet: ++/// ++/// 1. no cache entry: ++/// cache it ++/// ++/// 2. entry exists: ++/// subnet mod time >= last flush ++/// cache is stale flush it ++/// cache it ++/// ++/// subnet mod time < last flush ++/// use it ++/// ++class ConfigCache : public data::BaseStampedElement { ++public: ++ /// @brief Constructor ++ ConfigCache() : configs_(), global_config_(new PingCheckConfig()), mutex_(new std::mutex) { ++ } ++ ++ /// @brief Destructor ++ virtual ~ConfigCache() = default; ++ ++ /// @brief Get the config for a given subnet. ++ /// ++ /// @param subnet_id ID of the subnet for which the config is desired. ++ /// @param[out] config a reference to a pointer in which to store the ++ /// config if found. If there is no entry for the subnet, it will be set ++ /// to an empty pointer. ++ /// ++ /// @return True if an entry for subnet was found, false otherwise. This ++ /// allows callers to distinguish between unknown subnets (entries that do ++ /// not exist) and subnets that are known but do not define a config. ++ bool findConfig(const dhcp::SubnetID& subnet_id, ++ PingCheckConfigPtr& config); ++ ++ /// @brief Parses a config string and caches for the given subnet. ++ /// ++ /// @param subnet_id ID of the subnet for which the config is desired. ++ /// @param user_context user-context Element map of the subnet. ++ /// ++ /// @return pointer to the parsed config. ++ /// @throw BadValue if an error occurred during config parsing. ++ PingCheckConfigPtr parseAndCacheConfig(const dhcp::SubnetID& subnet_id, ++ data::ConstElementPtr& user_context); ++ ++ /// @brief Adds (or replaces) the config for a given subnet to the cache. ++ /// ++ /// @param subnet_id ID of the subnet for which the config is desired. ++ /// @param config pointer to the config to store. This may be an ++ /// empty pointer. ++ void cacheConfig(const dhcp::SubnetID& subnet_id, ++ PingCheckConfigPtr& config); ++ ++ /// @brief Discards the subnet entries in the cache. ++ void flush(); ++ ++ /// @brief Get the number of entries in the cache. ++ /// ++ /// @return number of entries in the cache. ++ size_t size(); ++ ++ /// @brief Get the last time the cache was flushed. ++ /// ++ /// @return the last time the cache was flushed (or the time it was ++ /// created if it has never been flushed). ++ boost::posix_time::ptime getLastFlushTime(); ++ ++ /// @brief Get the global level configuration. ++ /// ++ /// @return pointer to the global configuration. ++ PingCheckConfigPtr& getGlobalConfig(); ++ ++ /// @brief Set the global level configuration. ++ /// ++ /// @param config configuration to store as the global configuration. ++ void setGlobalConfig(PingCheckConfigPtr& config); ++ ++private: ++ /// @brief Get the config for a given subnet. ++ /// ++ /// Must be called from with a thread-safe context. ++ /// ++ /// @param subnet_id ID of the subnet for which the config is desired. ++ /// @param[out] config a reference to a pointer in which to store the ++ /// config if found. If there is no entry for the subnet, it will be set ++ /// to an empty pointer. ++ /// ++ /// @return True if an entry for subnet was found, false otherwise. This ++ /// allows callers to distinguish between unknown subnets (entries that do ++ /// not exist) and subnets that are known but do not define a config. ++ bool findConfigInternal(const dhcp::SubnetID& subnet_id, ++ PingCheckConfigPtr& config) const; ++ ++ /// @brief Per subnet config cache. Note that the global config in stored ++ /// using SUBNET_ID_GLOBAL. ++ std::map<dhcp::SubnetID, PingCheckConfigPtr> configs_; ++ ++ /// @brief Stores the global configuration parameters. ++ PingCheckConfigPtr global_config_; ++ ++ /// @brief The mutex used to protect internal state. ++ const boost::scoped_ptr<std::mutex> mutex_; ++}; ++ ++/// @brief Defines a shared pointer to a ConfigCache. ++typedef boost::shared_ptr<ConfigCache> ConfigCachePtr; ++ ++} // end of namespace ping_check ++} // end of namespace isc ++#endif +diff --git a/src/hooks/dhcp/ping_check/icmp_endpoint.h b/src/hooks/dhcp/ping_check/icmp_endpoint.h +new file mode 100644 +index 0000000000..5d047d286f +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/icmp_endpoint.h +@@ -0,0 +1,134 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#ifndef ICMP_ENDPOINT_H ++#define ICMP_ENDPOINT_H 1 ++ ++#include <asiolink/io_endpoint.h> ++ ++namespace isc { ++namespace ping_check { ++ ++/// @brief The @c ICMPEndpoint class is a concrete derived class of ++/// @c IOEndpoint that represents an endpoint of a ICMP packet. ++/// ++/// Other notes about @c TCPEndpoint applies to this class, too. ++class ICMPEndpoint : public asiolink::IOEndpoint { ++public: ++ /// ++ /// @name Constructors and Destructor. ++ /// ++ //@{ ++ ++ /// @brief Default Constructor ++ /// ++ /// Creates an internal endpoint. This is expected to be set by some ++ /// external call. ++ ICMPEndpoint() : ++ asio_endpoint_placeholder_(new boost::asio::ip::icmp::endpoint()), ++ asio_endpoint_(*asio_endpoint_placeholder_) ++ {} ++ ++ /// @brief Constructor from an address. ++ /// ++ /// @param address The IP address of the endpoint. ++ explicit ICMPEndpoint(const asiolink::IOAddress& address) : ++ asio_endpoint_placeholder_( ++ new boost::asio::ip::icmp::endpoint(boost::asio::ip::make_address(address.toText()), 0)), ++ asio_endpoint_(*asio_endpoint_placeholder_) ++ {} ++ ++ /// @brief Copy Constructor from an ASIO ICMP endpoint. ++ /// ++ /// This constructor is designed to be an efficient wrapper for the ++ /// corresponding ASIO class, @c icmp::endpoint. ++ /// ++ /// @param asio_endpoint The ASIO representation of the ICMP endpoint. ++ explicit ICMPEndpoint(boost::asio::ip::icmp::endpoint& asio_endpoint) : ++ asio_endpoint_placeholder_(0), asio_endpoint_(asio_endpoint) ++ {} ++ ++ /// @brief Constructor from a const ASIO ICMP endpoint. ++ /// ++ /// This constructor is designed to be an efficient wrapper for the ++ /// corresponding ASIO class, @c icmp::endpoint. ++ /// ++ /// @param asio_endpoint The ASIO representation of the TCP endpoint. ++ explicit ICMPEndpoint(const boost::asio::ip::icmp::endpoint& asio_endpoint) : ++ asio_endpoint_placeholder_(new boost::asio::ip::icmp::endpoint(asio_endpoint)), ++ asio_endpoint_(*asio_endpoint_placeholder_) ++ {} ++ ++ /// @brief The destructor. ++ virtual ~ICMPEndpoint() { delete asio_endpoint_placeholder_; } ++ //@} ++ ++ /// @brief Fetches the IP address of the endpoint. ++ /// ++ /// @return the endpoint's IP address as an IOAddress. ++ virtual asiolink::IOAddress getAddress() const { ++ return (asio_endpoint_.address()); ++ } ++ ++ /// @brief Fetches the IP address of the endpoint in native form. ++ /// ++ /// @return the endpoint's IP address as a struct sockaddr. ++ virtual const struct sockaddr& getSockAddr() const { ++ return (*asio_endpoint_.data()); ++ } ++ ++ /// @brief Fetches the IP port number of the endpoint. ++ /// ++ /// @return the endpoint's port number as a unit16_t. ++ virtual uint16_t getPort() const { ++ return (asio_endpoint_.port()); ++ } ++ ++ /// @brief Fetches the network protocol of the endpoint. ++ /// ++ /// @return the endpoint's protocol as a short ++ virtual short getProtocol() const { ++ return (asio_endpoint_.protocol().protocol()); ++ } ++ ++ /// @brief Fetches the network protocol family of the endpoint. ++ /// ++ /// @return the endpoint's protocol as a short ++ virtual short getFamily() const { ++ return (asio_endpoint_.protocol().family()); ++ } ++ ++ /// @brief Fetches the underlying ASIO endpoint implementation ++ /// ++ /// This is not part of the exposed IOEndpoint API but allows ++ /// direct access to the ASIO implementation of the endpoint ++ /// ++ /// @return the wrapped ASIO endpoint instance as a const ++ inline const boost::asio::ip::icmp::endpoint& getASIOEndpoint() const { ++ return (asio_endpoint_); ++ } ++ ++ /// @brief Fetches the underlying ASIO endpoint implementation ++ /// ++ /// This is not part of the exposed IOEndpoint API but allows ++ /// direct access to the ASIO implementation of the endpoint ++ /// ++ /// @return the wrapped ASIO endpoint instance as a non-const ++ inline boost::asio::ip::icmp::endpoint& getASIOEndpoint() { ++ return (asio_endpoint_); ++ } ++ ++private: ++ /// @brief Pointer to the ASIO endpoint placeholder. ++ boost::asio::ip::icmp::endpoint* asio_endpoint_placeholder_; ++ ++ /// @brief Reference to the underlying ASIO endpoint instance. ++ boost::asio::ip::icmp::endpoint& asio_endpoint_; ++}; ++ ++} // namespace ping_check ++} // namespace isc ++#endif // ICMP_ENDPOINT_H +diff --git a/src/hooks/dhcp/ping_check/icmp_msg.cc b/src/hooks/dhcp/ping_check/icmp_msg.cc +new file mode 100644 +index 0000000000..3d236820da +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/icmp_msg.cc +@@ -0,0 +1,112 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++#include <icmp_msg.h> ++#include <util/io.h> ++#include <exceptions/exceptions.h> ++ ++#include <netinet/ip_icmp.h> ++#include <iostream> ++ ++using namespace isc; ++using namespace isc::asiolink; ++using namespace isc::util; ++ ++namespace isc { ++namespace ping_check { ++ ++ICMPMsg::ICMPMsg() ++ : source_(IOAddress::IPV4_ZERO_ADDRESS()), ++ destination_(IOAddress::IPV4_ZERO_ADDRESS()), ++ msg_type_(0), code_(0), check_sum_(0), id_(0), sequence_(0), ++ payload_(0) { ++} ++ ++ICMPMsgPtr ++ICMPMsg::unpack(const uint8_t* wire_data, size_t length) { ++ ICMPMsgPtr msg(new ICMPMsg()); ++ if (length < sizeof(struct ip)) { ++ isc_throw(BadValue, ++ "ICMPMsg::unpack - truncated ip header, length: " ++ << length); ++ } ++ ++ // Find the IP header length... ++ struct ip* ip_header = (struct ip*)(wire_data); ++ auto hlen = (ip_header->ip_hl << 2); ++ ++ // Make sure we received enough data. ++ if (length < (hlen + sizeof(struct icmp))) { ++ isc_throw(BadValue, "ICMPMsg::truncated packet? length: " ++ << length << ", hlen: " << hlen); ++ } ++ ++ // Grab the source and destination addresses. ++ msg->setSource(IOAddress(ntohl(ip_header->ip_src.s_addr))); ++ msg->setDestination(IOAddress(ntohl(ip_header->ip_dst.s_addr))); ++ ++ // Get the message type. ++ struct icmp* reply = (struct icmp*)(wire_data + hlen); ++ msg->setType(reply->icmp_type); ++ msg->setCode(reply->icmp_code); ++ ++ msg->setChecksum(ntohs(reply->icmp_cksum)); ++ msg->setId(ntohs(reply->icmp_hun.ih_idseq.icd_id)); ++ msg->setSequence(ntohs(reply->icmp_hun.ih_idseq.icd_seq)); ++ ++ auto payload_len = length - hlen - ICMP_HEADER_SIZE; ++ msg->setPayload((const uint8_t*)(&reply->icmp_dun), payload_len); ++ ++ return (msg); ++} ++ ++ICMPPtr ++ICMPMsg::pack() const { ++ ICMPPtr outbound(new struct icmp()); ++ memset(outbound.get(), 0x00, sizeof(struct icmp)); ++ outbound->icmp_type = msg_type_; ++ outbound->icmp_id = htons(id_); ++ outbound->icmp_seq = htons(sequence_); ++ /// @todo copy in payload - not needed for ECHO REQUEST ++ outbound->icmp_cksum = htons(~calcChecksum((const uint8_t*)(outbound.get()), sizeof(struct icmp))); ++ return (outbound); ++} ++ ++void ++ICMPMsg::setPayload(const uint8_t* data, size_t length) { ++ payload_.insert(payload_.end(), data, data + length); ++} ++ ++uint32_t ++ICMPMsg::calcChecksum(const uint8_t* buf, size_t length) { ++ uint32_t sum = 0; ++ ++ /* Checksum all the pairs of bytes first... */ ++ size_t i; ++ for (i = 0; i < (length & ~1U); i += 2) { ++ sum += static_cast<uint32_t>(readUint16(buf + i, sizeof(uint16_t))); ++ /* Add carry. */ ++ if (sum > 0xFFFF) { ++ sum -= 0xFFFF; ++ } ++ } ++ ++ /* If there's a single byte left over, checksum it, too. Network ++ byte order is big-endian, so the remaining byte is the high byte. */ ++ if (i < length) { ++ sum += buf[i] << 8; ++ /* Add carry. */ ++ if (sum > 0xFFFF) { ++ sum -= 0xFFFF; ++ } ++ } ++ ++ return (sum); ++} ++ ++} // end of namespace ping_check ++} // end of namespace isc +diff --git a/src/hooks/dhcp/ping_check/icmp_msg.h b/src/hooks/dhcp/ping_check/icmp_msg.h +new file mode 100644 +index 0000000000..ace322d1ca +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/icmp_msg.h +@@ -0,0 +1,223 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#ifndef ICMP_MSG_H ++#define ICMP_MSG_H ++ ++#include <asiolink/io_address.h> ++ ++#include <arpa/inet.h> ++#include <netinet/in.h> ++#include <netinet/ip.h> ++#include <unistd.h> ++#include <netinet/ip_icmp.h> ++#include <boost/shared_ptr.hpp> ++ ++namespace isc { ++namespace ping_check { ++ ++// Forward class definition. ++class ICMPMsg; ++ ++/// @brief Shared pointer type for ICMPMsg. ++typedef boost::shared_ptr<ICMPMsg> ICMPMsgPtr; ++ ++/// @brief Shared pointer type for struct icmp. ++typedef boost::shared_ptr<struct icmp> ICMPPtr; ++ ++/// @brief Embodies an ICMP message ++/// ++/// Provides functions for marshalling of ICMP protocol ++/// messages to and from wire form ++class ICMPMsg { ++public: ++ /// @brief ICMP message types. We only define the ones ++ /// we care about. ++ enum ICMPMsgType { ++ ECHO_REPLY = 0, ++ TARGET_UNREACHABLE = 3, ++ ECHO_REQUEST = 8 ++ }; ++ ++ /// @brief Size in octets of ICMP message header. ++ /// 1 (msg type) + 1 (code) + 2 (checksum) + 4 (either unused ++ /// or used differently basing on the ICMP type and code e.g ++ /// Identifier and Sequence Number for Echo or Echo Reply Message) ++ constexpr static size_t ICMP_HEADER_SIZE = 8; ++ ++ /// @brief Constructor. ++ ICMPMsg(); ++ ++ /// @brief Destructor. ++ virtual ~ICMPMsg() = default; ++ ++ /// @brief Unpacks an ICMP message from the given wire_data ++ /// ++ /// The wire data is expected to include the IP header followed ++ /// by an ICMP message. ++ /// ++ /// @param wire_data raw data received from the socket ++ /// @param length number of bytes in the wire_data contents ++ /// ++ /// @return Pointer to the newly constructed message ++ /// @throw BadValue if the wire data is invalid ++ static ICMPMsgPtr unpack(const uint8_t* wire_data, size_t length); ++ ++ /// @brief Packs the message into an ICMP structure. ++ /// ++ /// @return Pointer to the newly constructed ICMP structure. ++ ICMPPtr pack() const; ++ ++ /// @brief Fetches the ICMP message type (e.g. ECHO_REQUEST, ECHO_REPLY) ++ /// ++ /// @return message type as a uint8_t ++ uint8_t getType() const { ++ return (msg_type_); ++ } ++ ++ /// @brief Sets the ICMP message type ++ /// ++ /// @param msg_type new value for the message type ++ void setType(uint8_t msg_type) { ++ msg_type_ = msg_type; ++ } ++ ++ /// @brief Fetches the ICMP message code ++ /// ++ /// @return uint8_t containing the message code ++ uint8_t getCode() const { ++ return (code_); ++ } ++ ++ /// @brief Sets the ICMP code ++ /// ++ /// @param code new value for the message type ++ void setCode(uint8_t code) { ++ code_ = code; ++ } ++ ++ /// @brief Fetches the checksum ++ /// ++ /// @return uint16_t containing the message checksum ++ uint16_t getChecksum() const { ++ return (check_sum_); ++ } ++ ++ /// @brief Sets the check sum ++ /// ++ /// @param check_sum new value for the check sum ++ void setChecksum(uint16_t check_sum) { ++ check_sum_ = check_sum; ++ } ++ ++ /// @brief Fetches the message id ++ /// ++ /// @return uint16_t containing the id ++ uint16_t getId() const { ++ return (id_); ++ } ++ ++ /// @brief Sets the message id ++ /// ++ /// @param id new value for the message id ++ void setId(const uint16_t id) { ++ id_ = id; ++ } ++ ++ /// @brief Fetches the message sequence number ++ /// ++ /// @return uint16_t containing the sequence number ++ uint16_t getSequence() const { ++ return (sequence_); ++ } ++ ++ /// @brief Sets the message sequence number ++ /// ++ /// @param sequence new value for the message sequence number ++ void setSequence(uint16_t sequence) { ++ sequence_ = sequence; ++ } ++ ++ /// @brief Fetches the source IP address ++ /// ++ /// @return IOAddress containing the IP address of the message source ++ const isc::asiolink::IOAddress& getSource() const { ++ return (source_); ++ } ++ ++ /// @brief Sets the source IP address ++ /// ++ /// @param source new value for the source IP address ++ void setSource(const isc::asiolink::IOAddress& source) { ++ source_ = source; ++ } ++ ++ /// @brief Fetches the destination IP address ++ /// ++ /// @return IOAddress containing the IP address of the message destination ++ const isc::asiolink::IOAddress& getDestination() const { ++ return (destination_); ++ } ++ ++ /// @brief Sets the destination IP address ++ /// ++ /// @param destination new value for the destination IP address ++ void setDestination(const isc::asiolink::IOAddress& destination) { ++ destination_ = destination; ++ } ++ ++ /// @brief Fetches the message payload ++ /// ++ /// @return vector containing the message payload ++ const std::vector<uint8_t>& getPayload() const { ++ return (payload_); ++ } ++ ++ /// @brief Sets the message payload to the given data ++ /// ++ /// @param data pointer to data buffer from which to copy ++ /// @param length number of bytes in data buffer ++ void setPayload(const uint8_t* data, size_t length); ++ ++ /// @brief Calculates the checksum of the given data buffer ++ /// ++ /// @param data pointer to data buffer from which to copy ++ /// @param length number of bytes in data buffer ++ /// ++ /// @return uint32_t containing the calculated checksum ++ static uint32_t calcChecksum(const uint8_t* data, size_t length); ++ ++private: ++ /// @brief IP address from which the message origin ++ isc::asiolink::IOAddress source_; ++ ++ /// @brief IP address of the message destination ++ isc::asiolink::IOAddress destination_; ++ ++ /// @brief ICMP message type ++ uint8_t msg_type_; ++ ++ /// @brief ICMP message code ++ uint8_t code_; ++ ++ /// @brief Checksum of the message ++ uint16_t check_sum_; ++ ++ /// @brief Message ID ++ uint16_t id_; ++ ++ /// @brief Message sequence number ++ uint16_t sequence_; ++ ++ // data beyond the ICMP header ++ std::vector<uint8_t> payload_; ++}; ++ ++ ++} // end of namespace ping_check ++} // end of namespace isc ++ ++#endif +diff --git a/src/hooks/dhcp/ping_check/icmp_socket.h b/src/hooks/dhcp/ping_check/icmp_socket.h +new file mode 100644 +index 0000000000..091057d749 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/icmp_socket.h +@@ -0,0 +1,359 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#ifndef ICMP_SOCKET_H ++#define ICMP_SOCKET_H 1 ++ ++#include <netinet/in.h> ++#include <sys/socket.h> ++#include <unistd.h> ++ ++#include <cstddef> ++ ++#include <asiolink/io_asio_socket.h> ++#include <asiolink/io_service.h> ++#include <icmp_endpoint.h> ++ ++#include <exceptions/isc_assert.h> ++ ++namespace isc { ++namespace ping_check { ++ ++/// @brief The @c ICMPSocket class is a concrete derived class of @c IOAsioSocket ++/// that represents a ICMP socket. ++/// ++/// @param C Callback type ++template <typename C> ++class ICMPSocket : public asiolink::IOAsioSocket<C> { ++private: ++ /// @brief Class is non-copyable ++ explicit ICMPSocket(const ICMPSocket&); ++ ICMPSocket& operator=(const ICMPSocket&); ++ ++public: ++ enum { ++ MIN_SIZE = 4096 // Minimum send and receive size ++ }; ++ ++ /// @brief Constructor from an ASIO ICMP socket. ++ /// ++ /// @param socket The ASIO representation of the ICMP socket. It is assumed ++ /// that the caller will open and close the socket, so these ++ /// operations are a no-op for that socket. ++ explicit ICMPSocket(boost::asio::ip::icmp::socket& socket); ++ ++ /// @brief Constructor ++ /// ++ /// Used when the ICMPSocket is being asked to manage its own internal ++ /// socket. In this case, the open() and close() methods are used. ++ /// ++ /// @param service I/O Service object used to manage the socket. ++ explicit ICMPSocket(const asiolink::IOServicePtr& service); ++ ++ /// @brief Destructor ++ virtual ~ICMPSocket(); ++ ++ /// @brief Return file descriptor of underlying socket ++ /// ++ /// @return socket's native file descriptor as an int. ++ virtual int getNative() const { ++#if BOOST_VERSION < 106600 ++ return (socket_.native()); ++#else ++ return (socket_.native_handle()); ++#endif ++ } ++ ++ /// @brief Return protocol of socket ++ /// ++ /// @return Always IPPROTO_ICMP. ++ virtual int getProtocol() const { ++ return (IPPROTO_ICMP); ++ } ++ ++ /// @brief Is "open()" synchronous? ++ /// ++ /// Indicates that the opening of a ICMP socket is synchronous. ++ /// @return Always true. ++ virtual bool isOpenSynchronous() const { ++ return true; ++ } ++ ++ /// @brief Indicates if the socket is currently open. ++ /// ++ /// @return true if socket is open. ++ virtual bool isOpen() const { ++ return isopen_; ++ } ++ ++ /// @brief Open Socket ++ /// ++ /// Opens the ICMP socket. This is a synchronous operation. ++ /// ++ /// @param endpoint Endpoint to which the socket will send data. This is ++ /// used to determine the address family that should be used for the ++ /// underlying socket. ++ /// @param callback Unused as the operation is synchronous. ++ virtual void open(const asiolink::IOEndpoint* endpoint, C& callback); ++ ++ /// @brief Send Asynchronously ++ /// ++ /// Calls the underlying socket's async_send_to() method to send a packet of ++ /// data asynchronously to the remote endpoint. The callback will be called ++ /// on completion. ++ /// ++ /// @param data Data to send ++ /// @param length Length of data to send ++ /// @param endpoint Target of the send ++ /// @param callback Callback object. ++ virtual void asyncSend(const void* data, size_t length, ++ const asiolink::IOEndpoint* endpoint, C& callback); ++ ++ /// @brief Receive Asynchronously ++ /// ++ /// Calls the underlying socket's async_receive_from() method to read a ++ /// packet of data from a remote endpoint. Arrival of the data is signalled ++ /// via a call to the callback function. ++ /// ++ /// @param data Buffer to receive incoming message ++ /// @param length Length of the data buffer ++ /// @param offset Offset into buffer where data is to be put ++ /// @param endpoint Source of the communication ++ /// @param callback Callback object ++ virtual void asyncReceive(void* data, size_t length, size_t offset, ++ asiolink::IOEndpoint* endpoint, C& callback); ++ ++ /// @brief Process received data ++ /// ++ /// See the description of IOAsioSocket::receiveComplete for a complete ++ /// description of this method. ++ /// ++ /// @param staging Pointer to the start of the staging buffer. ++ /// @param length Amount of data in the staging buffer. ++ /// @param cumulative Amount of data received before the staging buffer is ++ /// processed. ++ /// @param offset Unused. ++ /// @param expected unused. ++ /// @param outbuff Output buffer. Data in the staging buffer is be copied ++ /// to this output buffer in the call. ++ /// ++ /// @return Always true ++ virtual bool processReceivedData(const void* staging, size_t length, ++ size_t& cumulative, size_t& offset, ++ size_t& expected, ++ isc::util::OutputBufferPtr& outbuff); ++ ++ /// @brief Cancel I/O On Socket ++ virtual void cancel(); ++ ++ /// @brief Close socket ++ virtual void close(); ++ ++ /// @brief Calculates the checksum for the given buffer of data. ++ /// ++ /// @param buf pointer to the data buffer. ++ /// @param buf_size number of bytes in the data buffer. ++ /// ++ /// @return calculated checksum of the data as a uint16_t. ++ static uint16_t calcChecksum(const uint8_t* buf, const uint32_t buf_size); ++ ++private: ++ /// @brief The IO service used to handle events. ++ isc::asiolink::IOServicePtr io_service_; ++ ++ // Two variables to hold the socket - a socket and a pointer to it. This ++ // handles the case where a socket is passed to the ICMPSocket on ++ // construction, or where it is asked to manage its own socket. ++ ++ /// Pointer to own socket ++ std::unique_ptr<boost::asio::ip::icmp::socket> socket_ptr_; ++ ++ // Socket ++ boost::asio::ip::icmp::socket& socket_; ++ ++ // True when socket is open ++ bool isopen_; ++}; ++ ++// Constructor - caller manages socket ++ ++template <typename C> ++ICMPSocket<C>::ICMPSocket(boost::asio::ip::icmp::socket& socket) : ++ socket_ptr_(), socket_(socket), isopen_(true) { ++} ++ ++// Constructor - create socket on the fly ++ ++template <typename C> ++ICMPSocket<C>::ICMPSocket(const asiolink::IOServicePtr& io_service) : ++ io_service_(io_service), ++ socket_ptr_(new boost::asio::ip::icmp::socket(io_service_->getInternalIOService())), ++ socket_(*socket_ptr_), isopen_(false) { ++} ++ ++// Destructor. ++ ++template <typename C> ++ICMPSocket<C>::~ICMPSocket() { ++} ++ ++// Open the socket. ++ ++template <typename C> void ++ICMPSocket<C>::open(const asiolink::IOEndpoint* endpoint, C&) { ++ ++ // Ignore opens on already-open socket. (Don't throw a failure because ++ // of uncertainties as to what precedes when using asynchronous I/O.) ++ // It also allows us a treat a passed-in socket in exactly the same way as ++ // a self-managed socket (in that we can call the open() and close() methods ++ // of this class). ++ if (!isopen_) { ++ if (endpoint->getFamily() == AF_INET) { ++ socket_.open(boost::asio::ip::icmp::v4()); ++ } else { ++ socket_.open(boost::asio::ip::icmp::v6()); ++ } ++ isopen_ = true; ++ ++ // Ensure it can send and receive at least 4K buffers. ++ boost::asio::ip::icmp::socket::send_buffer_size snd_size; ++ socket_.get_option(snd_size); ++ if (snd_size.value() < MIN_SIZE) { ++ snd_size = MIN_SIZE; ++ socket_.set_option(snd_size); ++ } ++ ++ boost::asio::ip::icmp::socket::receive_buffer_size rcv_size; ++ socket_.get_option(rcv_size); ++ if (rcv_size.value() < MIN_SIZE) { ++ rcv_size = MIN_SIZE; ++ socket_.set_option(rcv_size); ++ } ++ ++ boost::asio::socket_base::do_not_route option(true); ++ socket_.set_option(option); ++ } ++} ++ ++// Send a message. Should never do this if the socket is not open, so throw ++// an exception if this is the case. ++ ++template <typename C> void ++ICMPSocket<C>::asyncSend(const void* data, size_t length, ++ const asiolink::IOEndpoint* endpoint, C& callback) { ++ if (isopen_) { ++ ++ // Upconvert to a ICMPEndpoint. We need to do this because although ++ // IOEndpoint is the base class of ICMPEndpoint and TCPEndpoint, it ++ // does not contain a method for getting at the underlying endpoint ++ // type - that is in the derived class and the two classes differ on ++ // return type. ++ isc_throw_assert(endpoint->getProtocol() == IPPROTO_ICMP); ++ const ICMPEndpoint* udp_endpoint = ++ static_cast<const ICMPEndpoint*>(endpoint); ++ ++ // ... and send the message. ++ socket_.async_send_to(boost::asio::buffer(data, length), ++ udp_endpoint->getASIOEndpoint(), callback); ++ } else { ++ isc_throw(asiolink::SocketNotOpen, ++ "attempt to send on a ICMP socket that is not open"); ++ } ++} ++ ++// Receive a message. Should never do this if the socket is not open, so throw ++// an exception if this is the case. ++ ++template <typename C> void ++ICMPSocket<C>::asyncReceive(void* data, size_t length, size_t offset, ++ asiolink::IOEndpoint* endpoint, C& callback) { ++ if (isopen_) { ++ ++ // Upconvert the endpoint again. ++ isc_throw_assert(endpoint->getProtocol() == IPPROTO_ICMP); ++ ICMPEndpoint* udp_endpoint = static_cast<ICMPEndpoint*>(endpoint); ++ ++ // Ensure we can write into the buffer ++ if (offset >= length) { ++ isc_throw(asiolink::BufferOverflow, "attempt to read into area beyond end of " ++ "ICMP receive buffer"); ++ } ++ void* buffer_start = static_cast<void*>(static_cast<uint8_t*>(data) + offset); ++ ++ // Issue the read ++ socket_.async_receive_from(boost::asio::buffer(buffer_start, length - offset), ++ udp_endpoint->getASIOEndpoint(), callback); ++ } else { ++ isc_throw(asiolink::SocketNotOpen, ++ "attempt to receive from a ICMP socket that is not open"); ++ } ++} ++ ++// Receive complete. Just copy the data across to the output buffer and ++// update arguments as appropriate. ++ ++template <typename C> bool ++ICMPSocket<C>::processReceivedData(const void* staging, size_t length, ++ size_t& cumulative, size_t& offset, ++ size_t& expected, ++ isc::util::OutputBufferPtr& outbuff) { ++ // Set return values to what we should expect. ++ cumulative = length; ++ expected = length; ++ offset = 0; ++ ++ // Copy data across ++ outbuff->writeData(staging, length); ++ ++ // ... and mark that we have everything. ++ return (true); ++} ++ ++// Cancel I/O on the socket. No-op if the socket is not open. ++ ++template <typename C> void ++ICMPSocket<C>::cancel() { ++ if (isopen_) { ++ socket_.cancel(); ++ } ++} ++ ++// Close the socket down. Can only do this if the socket is open and we are ++// managing it ourself. ++ ++template <typename C> void ++ICMPSocket<C>::close() { ++ if (isopen_ && socket_ptr_) { ++ socket_.close(); ++ isopen_ = false; ++ } ++} ++ ++template <typename C> uint16_t ++ICMPSocket<C>::calcChecksum(const uint8_t* buf, const uint32_t buf_size) { ++ uint32_t sum = 0; ++ uint32_t i; ++ for (i = 0; i < (buf_size & ~1U); i += 2) { ++ uint16_t chunk = buf[i] << 8 | buf[i + 1]; ++ sum += chunk; ++ if (sum > 0xFFFF) { ++ sum -= 0xFFFF; ++ } ++ } ++ // If one byte has left, we also need to add it to the checksum. ++ if (i < buf_size) { ++ sum += buf[i] << 8; ++ if (sum > 0xFFFF) { ++ sum -= 0xFFFF; ++ } ++ } ++ ++ return (sum); ++} ++ ++} // namespace ping_check ++} // namespace isc ++#endif // ICMP_SOCKET_H +diff --git a/src/hooks/dhcp/ping_check/libloadtests/.gitignore b/src/hooks/dhcp/ping_check/libloadtests/.gitignore +new file mode 100644 +index 0000000000..ada6ed5036 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/libloadtests/.gitignore +@@ -0,0 +1 @@ ++hook_load_unittests +diff --git a/src/hooks/dhcp/ping_check/libloadtests/Makefile.am b/src/hooks/dhcp/ping_check/libloadtests/Makefile.am +new file mode 100644 +index 0000000000..139a068b3c +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/libloadtests/Makefile.am +@@ -0,0 +1,60 @@ ++SUBDIRS = . ++ ++AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib ++AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/ping_check -I$(top_srcdir)/src/hooks/dhcp/ping_check ++AM_CPPFLAGS += $(BOOST_INCLUDES) $(CRYPTO_CFLAGS) $(CRYPTO_INCLUDES) ++AM_CPPFLAGS += -DPING_CHECK_LIB_SO=\"$(abs_top_builddir)/src/hooks/dhcp/ping_check/.libs/libdhcp_ping_check.so\" ++AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\" ++ ++AM_CXXFLAGS = $(KEA_CXXFLAGS) ++ ++if USE_STATIC_LINK ++AM_LDFLAGS = -static ++endif ++ ++# Unit test data files need to get installed. ++EXTRA_DIST = ++ ++CLEANFILES = *.gcno *.gcda ++ ++TESTS_ENVIRONMENT = $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND) ++ ++LOG_COMPILER = $(LIBTOOL) ++AM_LOG_FLAGS = --mode=execute ++ ++TESTS = ++if HAVE_GTEST ++TESTS += hook_load_unittests ++ ++hook_load_unittests_SOURCES = run_unittests.cc ++hook_load_unittests_SOURCES += load_unload_unittests.cc ++ ++hook_load_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES) ++ ++hook_load_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS) ++ ++hook_load_unittests_CXXFLAGS = $(AM_CXXFLAGS) ++ ++hook_load_unittests_LDADD = $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/http/libkea-http.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/database/libkea-database.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la ++hook_load_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la ++hook_load_unittests_LDADD += $(LOG4CPLUS_LIBS) ++hook_load_unittests_LDADD += $(CRYPTO_LIBS) ++hook_load_unittests_LDADD += $(BOOST_LIBS) ++hook_load_unittests_LDADD += $(GTEST_LDADD) ++endif ++noinst_PROGRAMS = $(TESTS) +diff --git a/src/hooks/dhcp/ping_check/libloadtests/load_unload_unittests.cc b/src/hooks/dhcp/ping_check/libloadtests/load_unload_unittests.cc +new file mode 100644 +index 0000000000..67275db617 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/libloadtests/load_unload_unittests.cc +@@ -0,0 +1,107 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++/// @file This file contains tests which exercise the load and unload ++/// functions in the ddns tuning hook library. In order to test the load ++/// function, one must be able to pass it hook library parameters. The ++/// the only way to populate these parameters is by actually loading the ++/// library via HooksManager::loadLibraries(). ++ ++#include <config.h> ++ ++#include <dhcpsrv/testutils/lib_load_test_fixture.h> ++#include <testutils/gtest_utils.h> ++ ++#include <gtest/gtest.h> ++#include <errno.h> ++ ++using namespace std; ++using namespace isc; ++using namespace isc::hooks; ++using namespace isc::data; ++using namespace isc::dhcp; ++using namespace isc::process; ++ ++namespace { ++ ++/// @brief Test fixture for testing loading and unloading the ddns tuning library ++class PingCheckLibLoadTest : public isc::test::LibLoadTest { ++public: ++ /// @brief Constructor ++ PingCheckLibLoadTest() : LibLoadTest(PING_CHECK_LIB_SO) { ++ } ++ ++ /// @brief Destructor ++ virtual ~PingCheckLibLoadTest() { ++ } ++ ++ /// @brief Registers hooks in the hook manager. ++ /// Normally this is done by the server core code (@c Dhcpv4Srv). ++ void registerHooks() { ++ hook_index_dhcp4_srv_configured_ = HooksManager::registerHook("dhcp4_srv_configured"); ++ hook_index_lease4_offer_ = HooksManager::registerHook("lease4_offer"); ++ } ++ ++ /// @brief Checks that expected callouts are present. ++ void calloutsPresent() { ++ bool result; ++ ASSERT_NO_THROW_LOG(result = HooksManager::calloutsPresent(hook_index_dhcp4_srv_configured_)); ++ EXPECT_TRUE(result); ++ ASSERT_NO_THROW_LOG(result = HooksManager::calloutsPresent(hook_index_lease4_offer_)); ++ EXPECT_TRUE(result); ++ } ++ ++ /// @brief Creates a valid set of ping-check hook parameters. ++ virtual ElementPtr validConfigParams() { ++ ElementPtr params = Element::createMap(); ++ params->set("min-ping-requests", Element::create(3)); ++ params->set("reply-timeout", Element::create(100)); ++ params->set("enable-ping-check", Element::create(true)); ++ params->set("ping-cltt-secs", Element::create(60)); ++ params->set("ping-channel-threads", Element::create(1)); ++ return (params); ++ } ++ ++ /// @brief Hook index values. ++ int hook_index_dhcp4_srv_configured_; ++ int hook_index_lease4_offer_; ++}; ++ ++// Simple V4 test that checks the library can be loaded and unloaded several times. ++TEST_F(PingCheckLibLoadTest, validLoad4) { ++ validDaemonTest("kea-dhcp4", AF_INET, valid_params_); ++} ++ ++// Simple test that checks the library cannot be loaded by invalid daemons. ++TEST_F(PingCheckLibLoadTest, invalidDaemonLoad) { ++ // V6 is invalid regardless of family. ++ invalidDaemonTest("kea-dhcp6", AF_INET, valid_params_); ++ invalidDaemonTest("kea-dhcp6", AF_INET6, valid_params_); ++ ++ invalidDaemonTest("kea-ctrl-agent", AF_INET, valid_params_); ++ invalidDaemonTest("kea-dhcp-ddns", AF_INET, valid_params_); ++ invalidDaemonTest("bogus", AF_INET, valid_params_); ++} ++ ++// Verifies that callout functions exist after loading the library. ++TEST_F(PingCheckLibLoadTest, verifyCallouts) { ++ // Set family and daemon's proc name and register hook points. ++ isc::dhcp::CfgMgr::instance().setFamily(AF_INET); ++ isc::process::Daemon::setProcName("kea-dhcp4"); ++ registerHooks(); ++ ++ // Add library to config and load it. ++ ASSERT_NO_THROW_LOG(addLibrary(lib_so_name_, valid_params_)); ++ ASSERT_NO_THROW_LOG(loadLibraries()); ++ ++ // Verify that expected callouts are present. ++ calloutsPresent(); ++ ++ // Unload the library. ++ ASSERT_NO_THROW_LOG(unloadLibraries()); ++} ++ ++} // end of anonymous namespace +diff --git a/src/hooks/dhcp/ping_check/libloadtests/meson.build b/src/hooks/dhcp/ping_check/libloadtests/meson.build +new file mode 100644 +index 0000000000..da8bf439c0 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/libloadtests/meson.build +@@ -0,0 +1,21 @@ ++if not TESTS_OPT.enabled() ++ subdir_done() ++endif ++ ++dhcp_ping_check_libloadtests = executable( ++ 'dhcp-ping-check-libload-tests', ++ 'load_unload_unittests.cc', ++ 'run_unittests.cc', ++ cpp_args: [ ++ f'-DPING_CHECK_LIB_SO="@TOP_BUILD_DIR@/src/hooks/dhcp/ping_check/libdhcp_ping_check.so"', ++ ], ++ dependencies: [GTEST_DEP, CRYPTO_DEP], ++ include_directories: [include_directories('.')] + INCLUDES, ++ link_with: LIBS_BUILT_SO_FAR, ++) ++test( ++ 'dhcp-ping-check-libloadtests', ++ dhcp_ping_check_libloadtests, ++ depends: [dhcp_ping_check_lib], ++ protocol: 'gtest', ++) +diff --git a/src/hooks/dhcp/ping_check/libloadtests/run_unittests.cc b/src/hooks/dhcp/ping_check/libloadtests/run_unittests.cc +new file mode 100644 +index 0000000000..d249e2362e +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/libloadtests/run_unittests.cc +@@ -0,0 +1,19 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++ ++#include <log/logger_support.h> ++#include <gtest/gtest.h> ++ ++int ++main(int argc, char* argv[]) { ++ ::testing::InitGoogleTest(&argc, argv); ++ isc::log::initLogger(); ++ int result = RUN_ALL_TESTS(); ++ ++ return (result); ++} +diff --git a/src/hooks/dhcp/ping_check/meson.build b/src/hooks/dhcp/ping_check/meson.build +new file mode 100644 +index 0000000000..d3a1e70b49 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/meson.build +@@ -0,0 +1,41 @@ ++dhcp_ping_check_lib = shared_library( ++ 'dhcp_ping_check', ++ 'config_cache.cc', ++ 'icmp_msg.cc', ++ 'ping_channel.cc', ++ 'ping_check_callouts.cc', ++ 'ping_check_config.cc', ++ 'ping_check_log.cc', ++ 'ping_check_messages.cc', ++ 'ping_check_mgr.cc', ++ 'ping_context.cc', ++ 'ping_context_store.cc', ++ 'version.cc', ++ dependencies: [CRYPTO_DEP], ++ include_directories: [include_directories('.')] + INCLUDES, ++ install: true, ++ install_dir: HOOKS_PATH, ++ install_rpath: INSTALL_RPATH, ++ build_rpath: BUILD_RPATH, ++ link_with: LIBS_BUILT_SO_FAR, ++ name_suffix: 'so', ++) ++dhcp_ping_check_archive = static_library( ++ 'dhcp_ping_check', ++ objects: dhcp_ping_check_lib.extract_all_objects(recursive: false), ++) ++subdir('libloadtests') ++subdir('tests') ++ ++if KEA_MSG_COMPILER.found() ++ target_gen_messages = run_target( ++ 'src-hooks-dhcp-ping_check-ping_check_messages', ++ command: [ ++ CD_AND_RUN, ++ TOP_SOURCE_DIR, ++ KEA_MSG_COMPILER, ++ 'src/hooks/dhcp/ping_check/ping_check_messages.mes', ++ ], ++ ) ++ TARGETS_GEN_MESSAGES += [target_gen_messages] ++endif +diff --git a/src/hooks/dhcp/ping_check/ping_channel.cc b/src/hooks/dhcp/ping_check/ping_channel.cc +new file mode 100644 +index 0000000000..6a6a88c038 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_channel.cc +@@ -0,0 +1,466 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++#include <ping_channel.h> ++#include <ping_check_log.h> ++#include <dhcp/iface_mgr.h> ++#include <exceptions/exceptions.h> ++#include <util/multi_threading_mgr.h> ++#include <iostream> ++ ++using namespace isc; ++using namespace isc::asiolink; ++using namespace isc::dhcp; ++using namespace isc::util; ++ ++namespace ph = std::placeholders; ++ ++namespace isc { ++namespace ping_check { ++ ++uint32_t ++PingChannel::nextEchoInstanceNum() { ++ static uint32_t echo_instance_num = 0x00010000; ++ if (echo_instance_num == UINT32_MAX) { ++ echo_instance_num = 0x00010001; ++ } else { ++ ++echo_instance_num; ++ } ++ ++ return (echo_instance_num); ++} ++ ++PingChannel::PingChannel(IOServicePtr& io_service, ++ NextToSendCallback next_to_send_cb, ++ EchoSentCallback echo_sent_cb, ++ ReplyReceivedCallback reply_received_cb, ++ ShutdownCallback shutdown_cb) ++ : io_service_(io_service), ++ next_to_send_cb_(next_to_send_cb), ++ echo_sent_cb_(echo_sent_cb), ++ reply_received_cb_(reply_received_cb), ++ shutdown_cb_(shutdown_cb), ++ socket_(0), input_buf_(256), ++ reading_(false), sending_(false), stopping_(false), mutex_(new std::mutex), ++ single_threaded_(!MultiThreadingMgr::instance().getMode()), ++ watch_socket_(0), registered_write_fd_(-1), registered_read_fd_(-1) { ++ if (!io_service_) { ++ isc_throw(BadValue, ++ "PingChannel ctor - io_service cannot be empty"); ++ } ++} ++ ++PingChannel::~PingChannel() { ++ close(); ++} ++ ++void ++PingChannel::open() { ++ try { ++ MultiThreadingLock lock(*mutex_); ++ if (socket_ && socket_->isOpen()) { ++ return; ++ } ++ ++ // For open(), the endpoint is only used to determine protocol, ++ // the address is irrelevant. ++ ICMPEndpoint ping_to_endpoint(IOAddress::IPV4_ZERO_ADDRESS()); ++ SocketCallback socket_cb( ++ [](boost::system::error_code ec, size_t /*length */) { ++ isc_throw(Unexpected, "ICMPSocket open is synchronous, should not invoke cb: " ++ << ec.message()); ++ } ++ ); ++ ++ socket_.reset(new PingSocket(io_service_)); ++ socket_->open(&ping_to_endpoint, socket_cb); ++ reading_ = false; ++ sending_ = false; ++ stopping_ = false; ++ ++ if (single_threaded_) { ++ // Open new watch socket. ++ watch_socket_.reset(new util::WatchSocket()); ++ ++ // Register the WatchSocket with IfaceMgr to signal data ready to write. ++ registered_write_fd_ = watch_socket_->getSelectFd(); ++ IfaceMgr::instance().addExternalSocket(registered_write_fd_, IfaceMgr::SocketCallback()); ++ ++ // Register ICMPSocket with IfaceMgr to signal data ready to read. ++ registered_read_fd_ = socket_->getNative(); ++ IfaceMgr::instance().addExternalSocket(registered_read_fd_, IfaceMgr::SocketCallback()); ++ } ++ ++ } catch (const std::exception& ex) { ++ isc_throw(Unexpected, "PingChannel::open failed:" << ex.what()); ++ } ++ ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_BASIC, PING_CHECK_CHANNEL_SOCKET_OPENED); ++} ++ ++bool ++PingChannel::isOpen() const { ++ MultiThreadingLock lock(*mutex_); ++ return (socket_ && socket_->isOpen()); ++} ++ ++void ++PingChannel::close() { ++ try { ++ MultiThreadingLock lock(*mutex_); ++ ++ if (single_threaded_) { ++ // Unregister from IfaceMgr. ++ if (registered_write_fd_ != -1) { ++ IfaceMgr::instance().deleteExternalSocket(registered_write_fd_); ++ registered_write_fd_ = -1; ++ } ++ ++ if (registered_read_fd_ != -1) { ++ IfaceMgr::instance().deleteExternalSocket(registered_read_fd_); ++ registered_read_fd_ = -1; ++ } ++ ++ // Close watch socket. ++ if (watch_socket_) { ++ std::string error_string; ++ watch_socket_->closeSocket(error_string); ++ if (!error_string.empty()) { ++ LOG_ERROR(ping_check_logger, PING_CHECK_CHANNEL_WATCH_SOCKET_CLOSE_ERROR) ++ .arg(error_string); ++ } ++ ++ watch_socket_.reset(); ++ } ++ } ++ ++ if (!socket_ || !socket_->isOpen()) { ++ return; ++ } ++ ++ socket_->close(); ++ } catch (const std::exception& ex) { ++ // On close error, log but do not throw. ++ LOG_ERROR(ping_check_logger, PING_CHECK_CHANNEL_SOCKET_CLOSE_ERROR) ++ .arg(ex.what()); ++ } ++ ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_BASIC, PING_CHECK_CHANNEL_SOCKET_CLOSED); ++} ++ ++void ++PingChannel::stopChannel() { ++ { ++ MultiThreadingLock lock(*mutex_); ++ if (stopping_) { ++ return; ++ } ++ ++ stopping_ = true; ++ } ++ ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_BASIC, PING_CHECK_CHANNEL_STOP); ++ close(); ++ ++ if (shutdown_cb_) { ++ (shutdown_cb_)(); ++ } ++} ++ ++void ++PingChannel::asyncReceive(void* data, size_t length, size_t offset, ++ asiolink::IOEndpoint* endpoint, SocketCallback& callback) { ++ socket_->asyncReceive(data, length, offset, endpoint, callback); ++} ++ ++void ++PingChannel::asyncSend(void* data, size_t length, asiolink::IOEndpoint* endpoint, ++ SocketCallback& callback) { ++ socket_->asyncSend(data, length, endpoint, callback); ++ ++ if (single_threaded_) { ++ // Set IO ready marker so sender activity is visible to select() or poll(). ++ watch_socket_->markReady(); ++ } ++} ++ ++void ++PingChannel::doRead() { ++ try { ++ MultiThreadingLock lock(*mutex_); ++ if (!canRead()) { ++ return; ++ } ++ ++ reading_ = true; ++ ++ // Create instance of the callback. It is safe to pass the ++ // local instance of the callback, because the underlying ++ // std functions make copies as needed. ++ SocketCallback cb(std::bind(&PingChannel::socketReadCallback, ++ shared_from_this(), ++ ph::_1, // error ++ ph::_2)); // bytes_transferred ++ asyncReceive(static_cast<void*>(getInputBufData()), getInputBufSize(), ++ 0, &reply_endpoint_, cb); ++ } catch (const std::exception& ex) { ++ // Normal IO failures should be passed to the callback. A failure here ++ // indicates the call to asyncReceive() itself failed. ++ LOG_ERROR(ping_check_logger, PING_CHECK_UNEXPECTED_READ_ERROR) ++ .arg(ex.what()); ++ stopChannel(); ++ } ++} ++ ++void ++PingChannel::socketReadCallback(boost::system::error_code ec, size_t length) { ++ { ++ MultiThreadingLock lock(*mutex_); ++ if (stopping_) { ++ return; ++ } ++ } ++ ++ if (ec) { ++ if (ec.value() == boost::asio::error::operation_aborted) { ++ // IO service has been stopped and the connection is probably ++ // going to be shutting down. ++ return; ++ } else if ((ec.value() == boost::asio::error::try_again) || ++ (ec.value() == boost::asio::error::would_block)) { ++ // We got EWOULDBLOCK or EAGAIN which indicates that we may be able to ++ // read something from the socket on the next attempt. Just make sure ++ // we don't try to read anything now in case there is any garbage ++ // passed in length. ++ length = 0; ++ } else { ++ // Anything else is fatal for the socket. ++ LOG_ERROR(ping_check_logger, PING_CHECK_CHANNEL_SOCKET_READ_FAILED) ++ .arg(ec.message()); ++ stopChannel(); ++ return; ++ } ++ } ++ ++ // Unpack the reply and pass it to the reply callback. ++ ICMPMsgPtr reply; ++ if (length > 0) { ++ { ++ try { ++ MultiThreadingLock lock(*mutex_); ++ reply = ICMPMsg::unpack(getInputBufData(), getInputBufSize()); ++ if (reply->getType() == ICMPMsg::ECHO_REPLY) { ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_DETAIL, ++ PING_CHECK_CHANNEL_ECHO_REPLY_RECEIVED) ++ .arg(reply->getSource()) ++ .arg(reply->getId()) ++ .arg(reply->getSequence()); ++ } ++ } catch (const std::exception& ex) { ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_BASIC, ++ PING_CHECK_CHANNEL_MALFORMED_PACKET_RECEIVED) ++ .arg(ex.what()); ++ } ++ } ++ } ++ ++ { ++ MultiThreadingLock lock(*mutex_); ++ reading_ = false; ++ } ++ ++ if (reply) { ++ (reply_received_cb_)(reply); ++ } ++ ++ // Start the next read. ++ doRead(); ++} ++ ++void ++PingChannel::startSend() { ++ MultiThreadingLock lock(*mutex_); ++ if (canSend()) { ++ // Post the call to sendNext to the IOService. ++ // This ensures its carried out on a thread ++ // associated with the channel's IOService ++ // not the thread invoking this function. ++ auto f = [](PingChannelPtr ptr) { ptr->sendNext(); }; ++ io_service_->post(std::bind(f, shared_from_this())); ++ } ++} ++ ++void ++PingChannel::startRead() { ++ MultiThreadingLock lock(*mutex_); ++ if (canRead()) { ++ // Post the call to doRead to the IOService. ++ // This ensures its carried out on a thread ++ // associated with the channel's IOService ++ // not the thread invoking this function. ++ auto f = [](PingChannelPtr ptr) { ptr->doRead(); }; ++ io_service_->post(std::bind(f, shared_from_this())); ++ } ++} ++ ++void ++PingChannel::sendNext() { ++ try { ++ MultiThreadingLock lock(*mutex_); ++ if (!canSend()) { ++ // Can't send right now, get out. ++ return; ++ } ++ ++ // Fetch the next one to send. ++ IOAddress target("0.0.0.0"); ++ if (!((next_to_send_cb_)(target))) { ++ // Nothing to send. ++ return; ++ } ++ ++ // Have an target IP, build an ECHO REQUEST for it. ++ sending_ = true; ++ ICMPMsgPtr next_echo(new ICMPMsg()); ++ next_echo->setType(ICMPMsg::ECHO_REQUEST); ++ next_echo->setDestination(target); ++ ++ uint32_t instance_num = nextEchoInstanceNum(); ++ next_echo->setId(static_cast<uint16_t>(instance_num >> 16)); ++ next_echo->setSequence(static_cast<uint16_t>(instance_num & 0x0000FFFF)); ++ ++ // Get packed wire-form. ++ ICMPPtr echo_icmp = next_echo->pack(); ++ ++ // Create instance of the callback. It is safe to pass the ++ // local instance of the callback, because the underlying ++ // std functions make copies as needed. ++ SocketCallback cb(std::bind(&PingChannel::socketWriteCallback, ++ shared_from_this(), ++ next_echo, ++ ph::_1, // error ++ ph::_2)); // bytes_transferred ++ ++ ICMPEndpoint target_endpoint(target); ++ asyncSend(echo_icmp.get(), sizeof(struct icmp), &target_endpoint, cb); ++ } catch (const std::exception& ex) { ++ // Normal IO failures should be passed to the callback. A failure here ++ // indicates the call to asyncSend() itself failed. ++ LOG_ERROR(ping_check_logger, PING_CHECK_UNEXPECTED_WRITE_ERROR) ++ .arg(ex.what()); ++ stopChannel(); ++ return; ++ } ++} ++ ++void ++PingChannel::socketWriteCallback(ICMPMsgPtr echo, boost::system::error_code ec, ++ size_t length) { ++ { ++ MultiThreadingLock lock(*mutex_); ++ if (stopping_) { ++ return; ++ } ++ } ++ ++ if (single_threaded_) { ++ try { ++ // Clear the IO ready marker. ++ watch_socket_->clearReady(); ++ } catch (const std::exception& ex) { ++ // This can only happen if the WatchSocket's select_fd has been ++ // compromised which is a programmatic error. We'll log the error ++ // here, then continue on and process the IO result we were given. ++ // WatchSocket issue will resurface on the next send as a closed ++ // fd in markReady() rather than fail out of this callback. ++ LOG_ERROR(ping_check_logger, PING_CHECK_CHANNEL_WATCH_SOCKET_CLEAR_ERROR) ++ .arg(ex.what()); ++ } ++ } ++ ++ // Handle an error. Note we can't use a case statement as some values ++ // on some OSes are the same (e.g. try_again and would_block) which causes ++ // duplicate case compilation errors. ++ bool send_failed = false; ++ if (ec) { ++ auto error_value = ec.value(); ++ if (error_value == boost::asio::error::operation_aborted) { ++ // IO service has been stopped and the connection is probably ++ // going to be shutting down. ++ return; ++ } else if ((error_value == boost::asio::error::try_again) || ++ (error_value == boost::asio::error::would_block)) { ++ // We got EWOULDBLOCK or EAGAIN which indicates that we may be able to ++ // write something from the socket on the next attempt. Set the length ++ // to zero so we skip the completion callback. ++ length = 0; ++ } else if ((error_value == boost::asio::error::network_unreachable) || ++ (error_value == boost::asio::error::host_unreachable) || ++ (error_value == boost::asio::error::network_down)) { ++ // One of these implies an interface might be down, or there's no ++ // way to ping this network. Other networks might be working OK. ++ send_failed = true; ++ } else if (error_value == boost::asio::error::no_buffer_space) { ++ // Writing faster than the kernel will write them out. ++ send_failed = true; ++ } else if (error_value == boost::asio::error::access_denied) { ++ // Means the address we tried to ping is not allowed. Most likey a broadcast ++ // address. ++ send_failed = true; ++ } else { ++ // Anything else is fatal for the socket. ++ LOG_ERROR(ping_check_logger, PING_CHECK_CHANNEL_SOCKET_WRITE_FAILED) ++ .arg(ec.message()); ++ stopChannel(); ++ return; ++ } ++ } ++ ++ { ++ MultiThreadingLock lock(*mutex_); ++ sending_ = false; ++ } ++ ++ if (send_failed) { ++ // Invoke the callback with send failed. This instructs the manager ++ // to treat the address as free to use. ++ LOG_ERROR(ping_check_logger, PING_CHECK_CHANNEL_NETWORK_WRITE_ERROR) ++ .arg(echo->getDestination()) ++ .arg(ec.message()); ++ // Invoke the send completed callback. ++ (echo_sent_cb_)(echo, true); ++ } else if (length > 0) { ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_DETAIL, ++ PING_CHECK_CHANNEL_ECHO_REQUEST_SENT) ++ .arg(echo->getDestination()) ++ .arg(echo->getId()) ++ .arg(echo->getSequence()); ++ // Invoke the send completed callback. ++ (echo_sent_cb_)(echo, false); ++ } ++ ++ // Schedule the next send. ++ sendNext(); ++} ++ ++size_t ++PingChannel::getInputBufSize() const { ++ return (input_buf_.size()); ++} ++ ++unsigned char* ++PingChannel::getInputBufData() { ++ if (input_buf_.empty()) { ++ isc_throw(InvalidOperation, ++ "PingChannel::getInputBufData() - cannot access empty buffer"); ++ } ++ ++ return (input_buf_.data()); ++} ++ ++} // end of namespace ping_check ++} // end of namespace isc +diff --git a/src/hooks/dhcp/ping_check/ping_channel.h b/src/hooks/dhcp/ping_check/ping_channel.h +new file mode 100644 +index 0000000000..ad798188e3 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_channel.h +@@ -0,0 +1,371 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#ifndef PING_CHANNEL_H ++#define PING_CHANNEL_H ++ ++#include <asiolink/asio_wrapper.h> ++#include <asiolink/io_address.h> ++#include <asiolink/io_service.h> ++#include <util/watch_socket.h> ++#include <icmp_msg.h> ++#include <icmp_socket.h> ++ ++#include <boost/scoped_ptr.hpp> ++#include <boost/enable_shared_from_this.hpp> ++ ++#include <iostream> ++#include <mutex> ++ ++namespace isc { ++namespace ping_check { ++ ++/// @brief Type of the function implementing a callback invoked by the ++/// @c SocketCallback functor. ++typedef std::function<void(boost::system::error_code ec, size_t length)> SocketCallbackFunction; ++ ++/// @brief Functor associated with the socket object. ++/// ++/// This functor calls a callback function specified in the constructor. ++class SocketCallback { ++public: ++ /// @brief Constructor. ++ /// ++ /// @param socket_callback Callback to be invoked by the functor upon ++ /// an event associated with the socket. ++ explicit inline SocketCallback(SocketCallbackFunction socket_callback) ++ : callback_(socket_callback) { ++ }; ++ ++ /// @brief Operator called when event associated with a socket occurs. ++ /// ++ /// This operator returns immediately when received @c boost::system::error_code ++ /// is equal to @c boost::asio::error::operation_aborted. ++ /// ++ /// @param ec Error code. ++ /// @param length Data length. ++ inline void operator()(boost::system::error_code ec, size_t length = 0) { ++ if (ec.value() == boost::asio::error::operation_aborted) { ++ return; ++ } ++ ++ callback_(ec, length); ++ }; ++ ++private: ++ /// @brief Supplied callback. ++ SocketCallbackFunction callback_; ++}; ++ ++/// @brief Socket type for performing ICMP socket IO. ++typedef ICMPSocket<SocketCallback> PingSocket; ++ ++/// @brief Defines a pointer to PingSocket. ++typedef boost::shared_ptr<PingSocket> PingSocketPtr; ++ ++/// @brief Function type for callback that fetches next IOAddress to ping. ++typedef std::function<bool(asiolink::IOAddress& target)> NextToSendCallback; ++ ++/// @brief Function type for callback to invoke upon ECHO send completion. ++typedef std::function<void(ICMPMsgPtr& echo, bool send_failed)> EchoSentCallback; ++ ++/// @brief Function type for callback to invoke when an ICMP reply has been ++/// received. ++typedef std::function<void(ICMPMsgPtr& reply)> ReplyReceivedCallback; ++ ++/// @brief Function type for callback to invoke when the channel has shutdown. ++typedef std::function<void()> ShutdownCallback; ++ ++/// @brief Provides thread-safe ICMP ECHO REQUEST/ECHO REPLY service ++/// ++/// PingChannel uses a @ref PingSocket to send out ECHO REQUESTs and ++/// receive ICMP replies. It is thread-safe and can be driven either ++/// with a single-threaded IOService or a multi-threaded ++/// IOServiceThreadPool. It uses series of callbacks to perpetually ++/// send requests to target addresses and feed back replies received: ++/// ++/// -# next_to_send_cb_ - callback to invoke to fetch the next address to ping ++/// -# echo_sent_cb_ - callback to invoke when an ECHO REQUEST has been sent out ++/// -# reply_received_cb_ - callback to invoke when an ICMP reply has been received. ++/// -# channel_shutdown_cb_ - callback to invoke when the channel has shutdown ++/// ++/// Callback handlers are supplied via the PingChannel constructor. Higher order ++/// functions are provided, that once instantiated, can be used by calling layers ++/// to control the channel (e.g. open the channel, initiate reading, initiate ++/// writing, and close the channel). ++/// ++/// @note Callbacks handlers must be thread-safe if the channel is ++/// driven by an IOServiceThreadPool. ++/// ++class PingChannel : public boost::enable_shared_from_this<PingChannel> { ++public: ++ /// @brief Constructor ++ /// ++ /// Instantiates the channel with its socket closed. ++ /// ++ /// @param io_service pointer to the IOService instance that will manage ++ /// the channel's IO. Must not be empty ++ /// @param next_to_send_cb callback to invoke to fetch the next IOAddress ++ /// to ping ++ /// @param echo_sent_cb callback to invoke when an ECHO send has completed ++ /// @param reply_received_cb callback to invoke when an ICMP reply has been ++ /// received. This callback is passed all inbound ICMP messages (e.g. ECHO ++ /// REPLY, UNREACHABLE, etc...) ++ /// @param shutdown_cb callback to invoke when the channel has shutdown due ++ /// to an error ++ /// ++ /// @throw BadValue if io_service is empty. ++ PingChannel(asiolink::IOServicePtr& io_service, ++ NextToSendCallback next_to_send_cb, ++ EchoSentCallback echo_sent_cb, ++ ReplyReceivedCallback reply_received_cb, ++ ShutdownCallback shutdown_cb = ShutdownCallback()); ++ ++ /// @brief Destructor ++ /// ++ /// Closes the socket if its open. ++ virtual ~PingChannel(); ++ ++ /// @brief Opens the socket for communications ++ /// ++ /// (Re)Creates the @ref PingSocket instance and opens it. ++ /// ++ /// @throw Unexpected if the open fails. ++ void open(); ++ ++ /// @brief Indicates whether or not the channel socket is open. ++ /// ++ /// @return true if the socket is open. ++ bool isOpen() const; ++ ++ // @brief Schedules the next send. ++ // ++ // If the socket is not currently sending it posts a call to @c sendNext() ++ // to the channel's IOService. ++ virtual void startSend(); ++ ++ // @brief Schedules the next read. ++ // ++ // If the socket is not currently reading it posts a call to @c doRead() ++ // to the channel's IOService. ++ void startRead(); ++ ++ /// @brief Closes the channel's socket. ++ void close(); ++ ++ /// @brief Fetches the channel's IOService ++ /// ++ /// @return pointer to the IOService. ++ asiolink::IOServicePtr getIOService() { ++ return (io_service_); ++ } ++ ++protected: ++ /// @brief Receive data on the socket asynchronously ++ /// ++ /// Calls the underlying socket's asyncReceive() method to read a ++ /// packet of data from a remote endpoint. Arrival of the data is signalled ++ /// via a call to the callback function. ++ /// ++ /// This virtual function is provided as means to inject errors during ++ /// read operations to facilitate testing. ++ /// ++ /// @param data buffer to receive incoming message ++ /// @param length length of the data buffer ++ /// @param offset offset into buffer where data is to be put ++ /// @param endpoint source of the communication ++ /// @param callback callback object ++ virtual void asyncReceive(void* data, size_t length, size_t offset, ++ asiolink::IOEndpoint* endpoint, SocketCallback& callback); ++ ++ /// @brief Send data on the socket asynchronously ++ /// ++ /// Calls the underlying socket's asyncSend() method to send a ++ /// packet of data from a remote endpoint. Arrival of the data is signalled ++ /// via a call to the callback function. ++ /// ++ /// This virtual function is provided as means to inject errors during ++ /// write operations to facilitate testing. ++ /// ++ /// @param data buffer containing the data to send ++ /// @param length length of the data buffer ++ /// @param endpoint destination of the communication ++ /// @param callback callback object ++ virtual void asyncSend(void* data, size_t length, asiolink::IOEndpoint* endpoint, ++ SocketCallback& callback); ++ ++protected: ++ /// @brief Initiates an asynchronous socket read. ++ /// ++ /// If the channel is able to read (is open, not stopping and not ++ /// currently reading) it invokes @ref PingSocket::asyncReceive() ++ /// otherwise it simply returns. If the call to asyncReceive() fails ++ /// it calls @c stopChannel() otherwise, when it completes it will ++ /// invoke @c socketReadCallback(). ++ void doRead(); ++ ++ /// @brief Socket read completion callback ++ /// ++ /// Invoked when PingSocket::asyncRead() completes. ++ /// Upon read success and data received: ++ /// ++ /// -# Unpacks the wire data ++ /// -# Pass the resultant ICMPMsg to reply received callback ++ /// -# start next read ++ /// ++ /// On error conditions: ++ /// ++ /// -# Operation aborted: socket is shutting down, simply return ++ /// -# Operation would block/try again: start a new read ++ /// -# Any other error, shut down the channel ++ /// ++ /// @param ec error code indicating either success or the error encountered ++ /// @param length number of bytes read ++ void socketReadCallback(boost::system::error_code ec, size_t length); ++ ++ /// @brief Initiates sending the next ECHO REQUEST ++ /// ++ /// If the channel is able to send (i.e is open, not stopping and not ++ /// currently writing): ++ /// -# Invoke next to send callback to fetch the next target IP address ++ /// -# If there is no next target, return ++ /// -# Construct the ECHO REQUEST for the target and pack it into wire form ++ /// -# Begin sending the request by passing to @c PingSocket::asyncSend() ++ /// -# If the asyncSend() call fails shutdown the channel, otherwise when ++ /// it completes it invokes @c socketWriteCallback(). ++ virtual void sendNext(); ++ ++ /// @brief Socket write completion callback ++ /// ++ /// Invoked when PingSocket::asyncWrite() completes. ++ /// Upon write success: ++ /// ++ /// -# Pass the ECHO REQUEST (i.e. echo_sent) to echo sent callback ++ /// -# start next write ++ /// ++ /// On error conditions: ++ /// ++ /// -# Operation aborted: socket is shutting down, simply return ++ /// -# Operation would block/try again: start a new write ++ /// -# Any other error, shut down the channel ++ /// ++ /// @param echo_sent ECHO REQUEST that was written (or attempted to be ++ /// written) ++ /// @param ec error code indicating either success or the error encountered ++ /// @param length number of bytes written ++ void socketWriteCallback(ICMPMsgPtr echo_sent, boost::system::error_code ec, ++ size_t length); ++ ++ /// @brief Closes the socket channel and invokes the shutdown callback. ++ /// ++ /// This function is invoked to notify the calling layer that the socket ++ /// has encountered an unrecoverable error and is stopping operations. ++ void stopChannel(); ++ ++ /// @brief returns the next unique ECHO instance number. ++ /// ++ /// This method generates and returns the next ECHO instance ++ /// number by incrementing the current value. It is a strictly ++ /// monotonously increasing value beginning at 0x00010001. ++ /// At roll over it resets to 0x00010001. ++ /// ++ /// Must be called in a thread-safe context ++ /// ++ /// @return the next unique instance number. ++ static uint32_t nextEchoInstanceNum(); ++ ++ /// @brief Indicates whether or not a send can be initiated. ++ /// ++ /// Must be called in a thread-safe context ++ /// ++ /// @return True if the socket is open, is not attempting to stop, and is ++ /// not currently sending. ++ bool canSend() { ++ return (socket_ && socket_->isOpen() && !stopping_ && !sending_); ++ } ++ ++ /// @brief Indicates whether or not a read can be initiated. ++ /// ++ /// Must be called in a thread-safe context ++ /// ++ /// @return True if the socket is open, is not attempting to stop, and is ++ /// not currently reading. ++ bool canRead() { ++ return (socket_ && socket_->isOpen() && !stopping_ && !reading_); ++ } ++ ++ /// @brief Returns input buffer size. ++ /// ++ /// Must be called in a thread-safe context ++ /// ++ /// @return size of the input buf ++ size_t getInputBufSize() const; ++ ++ /// @brief Returns pointer to the first byte of the input buffer. ++ /// ++ /// Must be called in a thread-safe context ++ /// ++ /// @return pointer to the data buffer ++ /// @throw InvalidOperation if called when the buffer is empty. ++ unsigned char* getInputBufData(); ++ ++ /// @brief IOService instance the drives socket IO ++ asiolink::IOServicePtr io_service_; ++ ++ /// @brief Callback to invoke to fetch the next address to ping. ++ NextToSendCallback next_to_send_cb_; ++ ++ /// @brief Callback to invoke when an ECHO write has completed. ++ EchoSentCallback echo_sent_cb_; ++ ++ /// @brief Callback to invoke when an ICMP reply has been received. ++ ReplyReceivedCallback reply_received_cb_; ++ ++ /// @brief Callback to invoke when the channel has shutdown. ++ ShutdownCallback shutdown_cb_; ++ ++ /// @brief Socket through which to ping. ++ PingSocketPtr socket_; ++ ++ /// @brief Buffer to hold the contents for most recent socket read. ++ std::vector<uint8_t> input_buf_; ++ ++ /// @brief Retains the endpoint from which the most recent reply was received. ++ ICMPEndpoint reply_endpoint_; ++ ++ /// @brief Indicates whether or not the socket has a read in progress. ++ bool reading_; ++ ++ /// @brief Indicates whether or not the socket has a write in progress. ++ bool sending_; ++ ++ /// @brief Indicates whether or not the channel has been told to stop. ++ bool stopping_; ++ ++ /// @brief The mutex used to protect internal state. ++ const boost::scoped_ptr<std::mutex> mutex_; ++ ++ /// @brief True if channel was opened in single-threaded mode, false ++ /// otherwise. ++ bool single_threaded_; ++ ++ /// @brief Pointer to WatchSocket instance supplying the "select-fd". ++ util::WatchSocketPtr watch_socket_; ++ ++ /// @brief WatchSocket fd registered with IfaceMgr. ++ int registered_write_fd_; ++ ++ /// @brief ICMPSocket fd registered with IfaceMgr. ++ int registered_read_fd_; ++}; ++ ++/// @brief Defines a smart pointer to PingChannel ++typedef boost::shared_ptr<PingChannel> PingChannelPtr; ++ ++} // end of namespace ping_check ++} // end of namespace isc ++ ++#endif +diff --git a/src/hooks/dhcp/ping_check/ping_check.dox b/src/hooks/dhcp/ping_check/ping_check.dox +new file mode 100644 +index 0000000000..a7fbe839c0 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_check.dox +@@ -0,0 +1,44 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++/** ++ ++@mainpage Kea Ping Check Hooks Library ++ ++Welcome to Kea Ping Check Hooks Library. This documentation is ++addressed at developers who are interested in internal operation of the ++library. This file provides information needed to understand and perhaps ++extend this library. ++ ++This documentation is stand-alone: you should have read and ++understood <a href="https://reports.kea.isc.org/dev_guide/">Kea ++Developer's Guide</a> and in particular its section about hooks: <a ++href="https://reports.kea.isc.org/dev_guide/df/d46/hooksdgDevelopersGuide.html"> ++Hooks Developer's Guide</a>. ++ ++@section cbPingCheckOverview Overview ++The @c ping_check hooks library provides the ability for kea-dhcp4 to carry ++out an ICMP ECHO test of a candidate IP address prior to sending that address to ++a DHCPv4 client in a DHCPOFFER message. ++ ++@section cbPingCheckInternals Library Internals ++ ++In addition to the requisite @ref load() and @ref unload() functions, the library ++implements the following callouts: ++ ++- @ref dhcp4_srv_configured() - schedules a (re)start of the ICMP IO layer ++- @ref lease4_offer() - handles requests from kea-dhcp4 core to initiate a ping check ++for a candidate lease ++ ++The load() function instantiates an instance of @ref isc::ping_check::PingCheckMgr. ++This class is the top level object that provides configuration processing and supervises ++the execution of ping checks. ++ ++@section cbPingCheckMTCompatibility Multi-Threading Compatibility ++ ++The @c ping_check hooks library requires multi-threading. ++ ++*/ +diff --git a/src/hooks/dhcp/ping_check/ping_check_callouts.cc b/src/hooks/dhcp/ping_check/ping_check_callouts.cc +new file mode 100644 +index 0000000000..ae006359be +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_check_callouts.cc +@@ -0,0 +1,240 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++ ++#include <asiolink/io_service_mgr.h> ++#include <database/audit_entry.h> ++#include <dhcpsrv/cfgmgr.h> ++#include <ping_check_log.h> ++#include <ping_check_mgr.h> ++#include <hooks/hooks.h> ++#include <process/daemon.h> ++#include <string> ++ ++namespace isc { ++namespace ping_check { ++ ++/// @brief PingCheckMgr singleton ++PingCheckMgrPtr mgr; ++ ++} // end of namespace ping_check ++} // end of namespace isc ++ ++using namespace isc; ++using namespace isc::asiolink; ++using namespace isc::log; ++using namespace isc::data; ++using namespace isc::db; ++using namespace isc::dhcp; ++using namespace isc::ping_check; ++using namespace isc::hooks; ++using namespace isc::process; ++using namespace std; ++ ++// Functions accessed by the hooks framework use C linkage to avoid the name ++// mangling that accompanies use of the C++ compiler as well as to avoid ++// issues related to namespaces. ++extern "C" { ++ ++/// @brief dhcp4_srv_configured implementation. ++/// ++/// @param handle callout handle. ++int dhcp4_srv_configured(CalloutHandle& handle) { ++ try { ++ SrvConfigPtr server_config; ++ handle.getArgument("server_config", server_config); ++ mgr->updateSubnetConfig(server_config); ++ ++ NetworkStatePtr network_state; ++ handle.getArgument("network_state", network_state); ++ ++ // Schedule a start of the services. This ensures we begin after ++ // the dust has settled and Kea MT mode has been firmly established. ++ mgr->startService(network_state); ++ IOServiceMgr::instance().registerIOService(mgr->getIOService()); ++ } catch (const std::exception& ex) { ++ LOG_ERROR(ping_check_logger, PING_CHECK_DHCP4_SRV_CONFIGURED_FAILED) ++ .arg(ex.what()); ++ ++ handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP); ++ ostringstream os; ++ os << "Error: " << ex.what(); ++ string error(os.str()); ++ handle.setArgument("error", error); ++ return (1); ++ } ++ ++ return (0); ++} ++ ++/// @brief cb4_updated callout implementation. ++/// ++/// If it detects that any subnets were altered by the update it ++/// replaces the subnet cache contents. If any of the subnets ++/// fail to parse, the error is logged and the function returns ++/// a non-zero value. ++/// ++/// @param handle CalloutHandle. ++/// ++/// @return 0 upon success, 1 otherwise ++int cb4_updated(CalloutHandle& handle) { ++ AuditEntryCollectionPtr audit_entries; ++ handle.getArgument("audit_entries", audit_entries); ++ ++ auto const& object_type_idx = audit_entries->get<AuditEntryObjectTypeTag>(); ++ auto range = object_type_idx.equal_range("dhcp4_subnet"); ++ if (std::distance(range.first, range.second)) { ++ try { ++ // Server config has been committed, so use the current configuration. ++ mgr->updateSubnetConfig(CfgMgr::instance().getCurrentCfg()); ++ } catch (const std::exception& ex) { ++ LOG_ERROR(ping_check_logger, PING_CHECK_CB4_UPDATE_FAILED) ++ .arg(ex.what()); ++ return (1); ++ } ++ } ++ ++ return (0); ++} ++ ++/// @brief lease4_offer callout implementation. ++/// ++/// @param handle callout handle. ++int lease4_offer(CalloutHandle& handle) { ++ CalloutHandle::CalloutNextStep status = handle.getStatus(); ++ if (status == CalloutHandle::NEXT_STEP_DROP || ++ status == CalloutHandle::NEXT_STEP_SKIP) { ++ return (0); ++ } ++ ++ Pkt4Ptr query4; ++ Lease4Ptr lease4; ++ ParkingLotHandlePtr parking_lot; ++ try { ++ // Get all arguments available for the leases4_committed hook point. ++ // If any of these arguments is not available this is a programmatic ++ // error. An exception will be thrown which will be caught by the ++ // caller and logged. ++ handle.getArgument("query4", query4); ++ ++ Lease4CollectionPtr leases4; ++ handle.getArgument("leases4", leases4); ++ ++ uint32_t offer_lifetime; ++ handle.getArgument("offer_lifetime", offer_lifetime); ++ ++ Lease4Ptr old_lease; ++ handle.getArgument("old_lease", old_lease); ++ ++ if (query4->getType() != DHCPDISCOVER) { ++ isc_throw(InvalidOperation, "query4 is not a DHCPDISCOVER"); ++ } ++ ++ if (!leases4) { ++ isc_throw(InvalidOperation, "leases4 is null"); ++ } ++ ++ if (!leases4->empty()) { ++ lease4 = (*leases4)[0]; ++ } ++ ++ if (!lease4) { ++ isc_throw(InvalidOperation, "leases4 is empty, no lease to check"); ++ } ++ ++ // Fetch the parking lot. If it's empty the server is not employing ++ // parking, which is fine. ++ // Create a reference to the parked packet. This signals that we have a ++ // stake in unparking it. ++ parking_lot = handle.getParkingLotHandlePtr(); ++ if (parking_lot) { ++ parking_lot->reference(query4); ++ } ++ ++ // Get configuration based on the lease's subnet. ++ auto const& config = mgr->getScopedConfig(lease4); ++ ++ // Call shouldPing() to determine if we should ping check or not. ++ // - status == PARK - ping check it ++ // - status == CONTINUE - check not needed, release DHCPOFFER to client ++ // - status == DROP - duplicate check, drop the duplicate DHCPOFFER ++ status = mgr->shouldPing(lease4, query4, old_lease, config); ++ handle.setStatus(status); ++ if (status == CalloutHandle::NEXT_STEP_PARK) { ++ mgr->startPing(lease4, query4, parking_lot, config); ++ } else { ++ // Dereference the parked packet. This releases our stake in it. ++ if (parking_lot) { ++ parking_lot->dereference(query4); ++ } ++ } ++ ++ } catch (const std::exception& ex) { ++ LOG_ERROR(ping_check_logger, PING_CHECK_LEASE4_OFFER_FAILED) ++ .arg(query4 ? query4->getLabel() : "<no query>") ++ .arg(lease4 ? lease4->addr_.toText() : "<no lease>") ++ .arg(ex.what()); ++ // Make sure we dereference. ++ if (parking_lot) { ++ parking_lot->dereference(query4); ++ } ++ ++ return (1); ++ } ++ ++ return (0); ++} ++ ++/// @brief This function is called when the library is loaded. ++/// ++/// @param handle library handle ++/// @return 0 when initialization is successful, 1 otherwise ++int load(LibraryHandle& handle) { ++ try { ++ // Make the hook library only loadable by kea-dhcp4. ++ const string& proc_name = Daemon::getProcName(); ++ if (proc_name != "kea-dhcp4") { ++ isc_throw(isc::Unexpected, "Bad process name: " << proc_name ++ << ", expected kea-dhcp4"); ++ } ++ ++ // Instantiate the manager singleton. ++ mgr.reset(new PingCheckMgr()); ++ ++ // Configure the manager using the hook library's parameters. ++ ConstElementPtr json = handle.getParameters(); ++ mgr->configure(json); ++ } catch (const exception& ex) { ++ LOG_ERROR(ping_check_logger, PING_CHECK_LOAD_ERROR) ++ .arg(ex.what()); ++ return (1); ++ } ++ ++ LOG_INFO(ping_check_logger, PING_CHECK_LOAD_OK); ++ return (0); ++} ++ ++/// @brief This function is called when the library is unloaded. ++/// ++/// @return always 0. ++int unload() { ++ if (mgr) { ++ IOServiceMgr::instance().unregisterIOService(mgr->getIOService()); ++ mgr.reset(); ++ } ++ LOG_INFO(ping_check_logger, PING_CHECK_UNLOAD); ++ return (0); ++} ++ ++/// @brief This function is called to retrieve the multi-threading compatibility. ++/// ++/// @return 1 which means compatible with multi-threading. ++int multi_threading_compatible() { ++ return (1); ++} ++ ++} // end extern "C" +diff --git a/src/hooks/dhcp/ping_check/ping_check_config.cc b/src/hooks/dhcp/ping_check/ping_check_config.cc +new file mode 100644 +index 0000000000..a1c69da61e +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_check_config.cc +@@ -0,0 +1,98 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++ ++#include <ping_check_config.h> ++ ++using namespace isc; ++using namespace isc::data; ++using namespace isc::dhcp; ++ ++namespace isc { ++namespace ping_check { ++ ++const data::SimpleKeywords ++PingCheckConfig::CONFIG_KEYWORDS = ++{ ++ { "enable-ping-check", Element::boolean }, ++ { "min-ping-requests", Element::integer }, ++ { "reply-timeout", Element::integer }, ++ { "ping-cltt-secs", Element::integer}, ++ { "ping-channel-threads", Element::integer} ++}; ++ ++PingCheckConfig::PingCheckConfig() : ++ enable_ping_check_(true), ++ min_ping_requests_(1), ++ reply_timeout_(100), ++ ping_cltt_secs_(60), ++ ping_channel_threads_(0) { ++} ++ ++void ++PingCheckConfig::parse(data::ConstElementPtr config) { ++ // Use a local instance to collect values. This way we ++ // avoid corrupting current values if there are any errors. ++ PingCheckConfig local; ++ ++ // Note checkKeywords() will throw DhcpConfigError if there is a problem. ++ SimpleParser::checkKeywords(CONFIG_KEYWORDS, config); ++ ConstElementPtr value = config->get("enable-ping-check"); ++ if (value) { ++ local.setEnablePingCheck(value->boolValue()); ++ } ++ ++ value = config->get("min-ping-requests"); ++ if (value) { ++ int64_t val = value->intValue(); ++ if (val <= 0) { ++ isc_throw(DhcpConfigError, "invalid min-ping-requests: '" ++ << val << "', must be greater than 0"); ++ } ++ ++ local.setMinPingRequests(static_cast<size_t>(val)); ++ } ++ ++ value = config->get("reply-timeout"); ++ if (value) { ++ int64_t val = value->intValue(); ++ if (val <= 0) { ++ isc_throw(DhcpConfigError, "invalid reply-timeout: '" ++ << val << "', must be greater than 0"); ++ } ++ ++ local.setReplyTimeout(static_cast<size_t>(val)); ++ } ++ ++ value = config->get("ping-cltt-secs"); ++ if (value) { ++ int64_t val = value->intValue(); ++ if (val < 0) { ++ isc_throw(DhcpConfigError, "invalid ping-cltt-secs: '" ++ << val << "', cannot be less than 0"); ++ } ++ ++ local.setPingClttSecs(static_cast<size_t>(val)); ++ } ++ ++ value = config->get("ping-channel-threads"); ++ if (value) { ++ int64_t val = value->intValue(); ++ if (val < 0) { ++ isc_throw(DhcpConfigError, "invalid ping-channel-threads: '" ++ << val << "', cannot be less than 0"); ++ } ++ ++ local.setPingChannelThreads(static_cast<size_t>(val)); ++ } ++ ++ // All values good, copy from local instance. ++ *this = local; ++} ++ ++} // end of namespace ping_check ++} // end of namespace isc +diff --git a/src/hooks/dhcp/ping_check/ping_check_config.h b/src/hooks/dhcp/ping_check/ping_check_config.h +new file mode 100644 +index 0000000000..9fd23eba59 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_check_config.h +@@ -0,0 +1,134 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#ifndef PING_CHECK_CONFIG_H ++#define PING_CHECK_CONFIG_H ++ ++#include <cc/data.h> ++#include <cc/simple_parser.h> ++ ++namespace isc { ++namespace ping_check { ++ ++/// @brief Houses the Ping check configuration parameters for a single scope ++/// (e.g. global, subnet...); ++class PingCheckConfig { ++public: ++ /// @brief List of valid parameters and expected types. ++ static const data::SimpleKeywords CONFIG_KEYWORDS; ++ ++ /// @brief Constructor ++ PingCheckConfig(); ++ ++ /// @brief Destructor ++ ~PingCheckConfig() = default; ++ ++ /// @brief Extracts member values from an Element::map ++ /// ++ /// @param config map of configuration parameters ++ /// ++ /// @throw BadValue if invalid values are detected. ++ void parse(data::ConstElementPtr config); ++ ++ /// @brief Fetches the value of enable-ping-check ++ /// ++ /// @return boolean value of enable-ping-check ++ bool getEnablePingCheck() const { ++ return (enable_ping_check_); ++ }; ++ ++ /// @brief Sets the value of enable-ping-check ++ /// ++ /// @param value new value for enable-ping-check ++ void setEnablePingCheck(bool value) { ++ enable_ping_check_ = value; ++ } ++ ++ /// @brief Fetches the value of min-ping-requests ++ /// ++ /// @return integer value of min-ping-requests ++ uint32_t getMinPingRequests() const { ++ return (min_ping_requests_); ++ }; ++ ++ /// @brief Sets the value of min-ping-requests ++ /// ++ /// @param value new value for min-ping-requests ++ void setMinPingRequests(uint32_t value) { ++ min_ping_requests_ = value; ++ } ++ ++ /// @brief Fetches the value of reply-timeout ++ /// ++ /// @return integer value of reply-timeout ++ uint32_t getReplyTimeout() const { ++ return (reply_timeout_); ++ } ++ ++ /// @brief Sets the value of reply-timeout ++ /// ++ /// @param value new value for reply-timeout ++ void setReplyTimeout(uint32_t value) { ++ reply_timeout_ = value; ++ } ++ ++ /// @brief Fetches the value of ping-cltt-secs ++ /// ++ /// @return integer value of ping-cltt-secs ++ uint32_t getPingClttSecs() const { ++ return (ping_cltt_secs_); ++ } ++ ++ /// @brief Sets the value of ping-cltt-secs ++ /// ++ /// @param value new value for ping-cltt-secs ++ void setPingClttSecs(uint32_t value) { ++ ping_cltt_secs_ = value; ++ } ++ ++ /// @brief Fetches the value of ping-channel-threads ++ /// ++ /// @return integer value of ping-channel-threads ++ uint32_t getPingChannelThreads() const { ++ return (ping_channel_threads_); ++ } ++ ++ /// @brief Sets the value of ping-channel-threads ++ /// ++ /// @param value new value for ping-channel-threads ++ void setPingChannelThreads(uint32_t value) { ++ ping_channel_threads_ = value; ++ } ++ ++private: ++ // @brief True if checking is enabled. ++ bool enable_ping_check_; ++ ++ /// @brief minimum number of ECHO REQUESTs sent, without replies received, ++ /// required to declare an address free to offer. ++ uint32_t min_ping_requests_; ++ ++ /// @brief maximum number of milliseconds to wait for an ECHO REPLY after ++ /// an ECHO REQUEST has been sent. ++ uint32_t reply_timeout_; ++ ++ /// @brief minimum number of seconds that must elapse after the lease's CLTT ++ /// before a ping check will be conducted, when the client is the lease's ++ /// previous owner. ++ uint32_t ping_cltt_secs_; ++ ++ /// @brief Number of threads to use if Kea core is multi-threaded. ++ /// Defaults to 0 (for now) which means follow core number of threads. ++ size_t ping_channel_threads_; ++}; ++ ++/// @brief Defines a shared pointer to a PingCheckConfig. ++typedef boost::shared_ptr<PingCheckConfig> PingCheckConfigPtr; ++ ++} // end of namespace ping_check ++} // end of namespace isc ++ ++#endif +diff --git a/src/hooks/dhcp/ping_check/ping_check_log.cc b/src/hooks/dhcp/ping_check/ping_check_log.cc +new file mode 100644 +index 0000000000..9e877ff9b5 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_check_log.cc +@@ -0,0 +1,17 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++ ++#include <ping_check_log.h> ++ ++namespace isc { ++namespace ping_check { ++ ++isc::log::Logger ping_check_logger("ping-check-hooks"); ++ ++} // namespace ping_check ++} // namespace isc +diff --git a/src/hooks/dhcp/ping_check/ping_check_log.h b/src/hooks/dhcp/ping_check/ping_check_log.h +new file mode 100644 +index 0000000000..22e0fca953 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_check_log.h +@@ -0,0 +1,23 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#ifndef PING_CHECK_LOG_H ++#define PING_CHECK_LOG_H ++ ++#include <log/logger_support.h> ++#include <log/macros.h> ++#include <log/log_dbglevels.h> ++#include <ping_check_messages.h> ++#include <iostream> ++ ++namespace isc { ++namespace ping_check { ++ ++extern isc::log::Logger ping_check_logger; ++ ++} // end of namespace ping_check ++} // end of namespace isc ++#endif +diff --git a/src/hooks/dhcp/ping_check/ping_check_messages.cc b/src/hooks/dhcp/ping_check/ping_check_messages.cc +new file mode 100644 +index 0000000000..7dea2c2397 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_check_messages.cc +@@ -0,0 +1,99 @@ ++// File created from src/hooks/dhcp/ping_check/ping_check_messages.mes ++ ++#include <cstddef> ++#include <log/message_types.h> ++#include <log/message_initializer.h> ++ ++extern const isc::log::MessageID PING_CHECK_CB4_UPDATE_FAILED = "PING_CHECK_CB4_UPDATE_FAILED"; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_ECHO_REPLY_RECEIVED = "PING_CHECK_CHANNEL_ECHO_REPLY_RECEIVED"; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_ECHO_REQUEST_SENT = "PING_CHECK_CHANNEL_ECHO_REQUEST_SENT"; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_MALFORMED_PACKET_RECEIVED = "PING_CHECK_CHANNEL_MALFORMED_PACKET_RECEIVED"; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_NETWORK_WRITE_ERROR = "PING_CHECK_CHANNEL_NETWORK_WRITE_ERROR"; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_SOCKET_CLOSED = "PING_CHECK_CHANNEL_SOCKET_CLOSED"; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_SOCKET_CLOSE_ERROR = "PING_CHECK_CHANNEL_SOCKET_CLOSE_ERROR"; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_SOCKET_OPENED = "PING_CHECK_CHANNEL_SOCKET_OPENED"; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_SOCKET_READ_FAILED = "PING_CHECK_CHANNEL_SOCKET_READ_FAILED"; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_SOCKET_WRITE_FAILED = "PING_CHECK_CHANNEL_SOCKET_WRITE_FAILED"; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_STOP = "PING_CHECK_CHANNEL_STOP"; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_WATCH_SOCKET_CLEAR_ERROR = "PING_CHECK_CHANNEL_WATCH_SOCKET_CLEAR_ERROR"; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_WATCH_SOCKET_CLOSE_ERROR = "PING_CHECK_CHANNEL_WATCH_SOCKET_CLOSE_ERROR"; ++extern const isc::log::MessageID PING_CHECK_DHCP4_SRV_CONFIGURED_FAILED = "PING_CHECK_DHCP4_SRV_CONFIGURED_FAILED"; ++extern const isc::log::MessageID PING_CHECK_DUPLICATE_CHECK = "PING_CHECK_DUPLICATE_CHECK"; ++extern const isc::log::MessageID PING_CHECK_LEASE4_OFFER_FAILED = "PING_CHECK_LEASE4_OFFER_FAILED"; ++extern const isc::log::MessageID PING_CHECK_LOAD_ERROR = "PING_CHECK_LOAD_ERROR"; ++extern const isc::log::MessageID PING_CHECK_LOAD_OK = "PING_CHECK_LOAD_OK"; ++extern const isc::log::MessageID PING_CHECK_MGR_CHANNEL_DOWN = "PING_CHECK_MGR_CHANNEL_DOWN"; ++extern const isc::log::MessageID PING_CHECK_MGR_LEASE_FREE_TO_USE = "PING_CHECK_MGR_LEASE_FREE_TO_USE"; ++extern const isc::log::MessageID PING_CHECK_MGR_NEXT_ECHO_SCHEDULED = "PING_CHECK_MGR_NEXT_ECHO_SCHEDULED"; ++extern const isc::log::MessageID PING_CHECK_MGR_RECEIVED_ECHO_REPLY = "PING_CHECK_MGR_RECEIVED_ECHO_REPLY"; ++extern const isc::log::MessageID PING_CHECK_MGR_RECEIVED_UNEXPECTED_ECHO_REPLY = "PING_CHECK_MGR_RECEIVED_UNEXPECTED_ECHO_REPLY"; ++extern const isc::log::MessageID PING_CHECK_MGR_RECEIVED_UNEXPECTED_UNREACHABLE_MSG = "PING_CHECK_MGR_RECEIVED_UNEXPECTED_UNREACHABLE_MSG"; ++extern const isc::log::MessageID PING_CHECK_MGR_RECEIVED_UNREACHABLE_MSG = "PING_CHECK_MGR_RECEIVED_UNREACHABLE_MSG"; ++extern const isc::log::MessageID PING_CHECK_MGR_REPLY_RECEIVED_ERROR = "PING_CHECK_MGR_REPLY_RECEIVED_ERROR"; ++extern const isc::log::MessageID PING_CHECK_MGR_REPLY_TIMEOUT_EXPIRED = "PING_CHECK_MGR_REPLY_TIMEOUT_EXPIRED"; ++extern const isc::log::MessageID PING_CHECK_MGR_SEND_COMPLETED_ERROR = "PING_CHECK_MGR_SEND_COMPLETED_ERROR"; ++extern const isc::log::MessageID PING_CHECK_MGR_STARTED = "PING_CHECK_MGR_STARTED"; ++extern const isc::log::MessageID PING_CHECK_MGR_STARTED_SINGLE_THREADED = "PING_CHECK_MGR_STARTED_SINGLE_THREADED"; ++extern const isc::log::MessageID PING_CHECK_MGR_START_PING_CHECK = "PING_CHECK_MGR_START_PING_CHECK"; ++extern const isc::log::MessageID PING_CHECK_MGR_STOPPED = "PING_CHECK_MGR_STOPPED"; ++extern const isc::log::MessageID PING_CHECK_MGR_STOPPING = "PING_CHECK_MGR_STOPPING"; ++extern const isc::log::MessageID PING_CHECK_MGR_SUBNET_CONFIG_FAILED = "PING_CHECK_MGR_SUBNET_CONFIG_FAILED"; ++extern const isc::log::MessageID PING_CHECK_PAUSE_FAILED = "PING_CHECK_PAUSE_FAILED"; ++extern const isc::log::MessageID PING_CHECK_PAUSE_ILLEGAL = "PING_CHECK_PAUSE_ILLEGAL"; ++extern const isc::log::MessageID PING_CHECK_PAUSE_PERMISSIONS_FAILED = "PING_CHECK_PAUSE_PERMISSIONS_FAILED"; ++extern const isc::log::MessageID PING_CHECK_RESUME_FAILED = "PING_CHECK_RESUME_FAILED"; ++extern const isc::log::MessageID PING_CHECK_UNEXPECTED_READ_ERROR = "PING_CHECK_UNEXPECTED_READ_ERROR"; ++extern const isc::log::MessageID PING_CHECK_UNEXPECTED_WRITE_ERROR = "PING_CHECK_UNEXPECTED_WRITE_ERROR"; ++extern const isc::log::MessageID PING_CHECK_UNLOAD = "PING_CHECK_UNLOAD"; ++ ++namespace { ++ ++const char* values[] = { ++ "PING_CHECK_CB4_UPDATE_FAILED", "A subnet ping-check parameters failed to parse after being updated %1", ++ "PING_CHECK_CHANNEL_ECHO_REPLY_RECEIVED", "from address %1, id %2, sequence %3", ++ "PING_CHECK_CHANNEL_ECHO_REQUEST_SENT", "to address %1, id %2, sequence %3", ++ "PING_CHECK_CHANNEL_MALFORMED_PACKET_RECEIVED", "error occurred unpacking message %1, discarding it", ++ "PING_CHECK_CHANNEL_NETWORK_WRITE_ERROR", "occurred trying to ping %1, error %2", ++ "PING_CHECK_CHANNEL_SOCKET_CLOSED", "ICMP socket has been closed.", ++ "PING_CHECK_CHANNEL_SOCKET_CLOSE_ERROR", "an attempt to close the ICMP socket failed %1", ++ "PING_CHECK_CHANNEL_SOCKET_OPENED", "ICMP socket been opened successfully.", ++ "PING_CHECK_CHANNEL_SOCKET_READ_FAILED", "socket read completed with an error %1", ++ "PING_CHECK_CHANNEL_SOCKET_WRITE_FAILED", "socket write completed with an error %1", ++ "PING_CHECK_CHANNEL_STOP", "channel is stopping operations.", ++ "PING_CHECK_CHANNEL_WATCH_SOCKET_CLEAR_ERROR", "an attempt to clear the WatchSocket associated with", ++ "PING_CHECK_CHANNEL_WATCH_SOCKET_CLOSE_ERROR", "an attempt to close the WatchSocket associated with", ++ "PING_CHECK_DHCP4_SRV_CONFIGURED_FAILED", "dhcp4_srv_configured callout failed %1", ++ "PING_CHECK_DUPLICATE_CHECK", "Ping check already in progress for %1, initiated by %2", ++ "PING_CHECK_LEASE4_OFFER_FAILED", "lease4_offer callout failed for query %1, lease address %2, reason %3", ++ "PING_CHECK_LOAD_ERROR", "loading Ping Check hooks library failed %1", ++ "PING_CHECK_LOAD_OK", "Ping Check hooks library loaded successfully.", ++ "PING_CHECK_MGR_CHANNEL_DOWN", "Ping Channel has shutdown, ping checking will be skipped", ++ "PING_CHECK_MGR_LEASE_FREE_TO_USE", "address %1 is free to use for %2", ++ "PING_CHECK_MGR_NEXT_ECHO_SCHEDULED", "for %1, scheduling ECHO_REQUEST %2 of %3", ++ "PING_CHECK_MGR_RECEIVED_ECHO_REPLY", "from %1, id %2, sequence %3", ++ "PING_CHECK_MGR_RECEIVED_UNEXPECTED_ECHO_REPLY", "from %1, id %2, sequence %3 received after reply-timeout expired", ++ "PING_CHECK_MGR_RECEIVED_UNEXPECTED_UNREACHABLE_MSG", "for %1, id %2, sequence %3 received after reply-timeout expired", ++ "PING_CHECK_MGR_RECEIVED_UNREACHABLE_MSG", "for %1, id %2, sequence %3", ++ "PING_CHECK_MGR_REPLY_RECEIVED_ERROR", "an error occurred processing an ICMP reply message %1", ++ "PING_CHECK_MGR_REPLY_TIMEOUT_EXPIRED", "for %1, ECHO REQUEST %2 of %3, reply-timeout %4", ++ "PING_CHECK_MGR_SEND_COMPLETED_ERROR", "an error occurred in the send completion callback %1", ++ "PING_CHECK_MGR_STARTED", "ping channel operations are running, number of threads %1", ++ "PING_CHECK_MGR_STARTED_SINGLE_THREADED", "single-threaded ping channel operations are running", ++ "PING_CHECK_MGR_START_PING_CHECK", "for %1, initiated by %2", ++ "PING_CHECK_MGR_STOPPED", "channel operations have stopped", ++ "PING_CHECK_MGR_STOPPING", "ping channel operations are stopping", ++ "PING_CHECK_MGR_SUBNET_CONFIG_FAILED", "user-context for subnet id %1, contains invalid ping-check %2", ++ "PING_CHECK_PAUSE_FAILED", "Pausing ping channel operations failed %1", ++ "PING_CHECK_PAUSE_ILLEGAL", "Pausing ping channel operations not allowed %1", ++ "PING_CHECK_PAUSE_PERMISSIONS_FAILED", "Permissions check for ping-channel pause failed %1", ++ "PING_CHECK_RESUME_FAILED", "Resuming ping channel operations failed %1", ++ "PING_CHECK_UNEXPECTED_READ_ERROR", "could not start next socket read %1", ++ "PING_CHECK_UNEXPECTED_WRITE_ERROR", "could not start next socket write %1", ++ "PING_CHECK_UNLOAD", "Ping Check hooks library has been unloaded", ++ NULL ++}; ++ ++const isc::log::MessageInitializer initializer(values); ++ ++} // Anonymous namespace ++ +diff --git a/src/hooks/dhcp/ping_check/ping_check_messages.h b/src/hooks/dhcp/ping_check/ping_check_messages.h +new file mode 100644 +index 0000000000..9326c699e8 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_check_messages.h +@@ -0,0 +1,50 @@ ++// File created from src/hooks/dhcp/ping_check/ping_check_messages.mes ++ ++#ifndef PING_CHECK_MESSAGES_H ++#define PING_CHECK_MESSAGES_H ++ ++#include <log/message_types.h> ++ ++extern const isc::log::MessageID PING_CHECK_CB4_UPDATE_FAILED; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_ECHO_REPLY_RECEIVED; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_ECHO_REQUEST_SENT; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_MALFORMED_PACKET_RECEIVED; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_NETWORK_WRITE_ERROR; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_SOCKET_CLOSED; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_SOCKET_CLOSE_ERROR; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_SOCKET_OPENED; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_SOCKET_READ_FAILED; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_SOCKET_WRITE_FAILED; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_STOP; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_WATCH_SOCKET_CLEAR_ERROR; ++extern const isc::log::MessageID PING_CHECK_CHANNEL_WATCH_SOCKET_CLOSE_ERROR; ++extern const isc::log::MessageID PING_CHECK_DHCP4_SRV_CONFIGURED_FAILED; ++extern const isc::log::MessageID PING_CHECK_DUPLICATE_CHECK; ++extern const isc::log::MessageID PING_CHECK_LEASE4_OFFER_FAILED; ++extern const isc::log::MessageID PING_CHECK_LOAD_ERROR; ++extern const isc::log::MessageID PING_CHECK_LOAD_OK; ++extern const isc::log::MessageID PING_CHECK_MGR_CHANNEL_DOWN; ++extern const isc::log::MessageID PING_CHECK_MGR_LEASE_FREE_TO_USE; ++extern const isc::log::MessageID PING_CHECK_MGR_NEXT_ECHO_SCHEDULED; ++extern const isc::log::MessageID PING_CHECK_MGR_RECEIVED_ECHO_REPLY; ++extern const isc::log::MessageID PING_CHECK_MGR_RECEIVED_UNEXPECTED_ECHO_REPLY; ++extern const isc::log::MessageID PING_CHECK_MGR_RECEIVED_UNEXPECTED_UNREACHABLE_MSG; ++extern const isc::log::MessageID PING_CHECK_MGR_RECEIVED_UNREACHABLE_MSG; ++extern const isc::log::MessageID PING_CHECK_MGR_REPLY_RECEIVED_ERROR; ++extern const isc::log::MessageID PING_CHECK_MGR_REPLY_TIMEOUT_EXPIRED; ++extern const isc::log::MessageID PING_CHECK_MGR_SEND_COMPLETED_ERROR; ++extern const isc::log::MessageID PING_CHECK_MGR_STARTED; ++extern const isc::log::MessageID PING_CHECK_MGR_STARTED_SINGLE_THREADED; ++extern const isc::log::MessageID PING_CHECK_MGR_START_PING_CHECK; ++extern const isc::log::MessageID PING_CHECK_MGR_STOPPED; ++extern const isc::log::MessageID PING_CHECK_MGR_STOPPING; ++extern const isc::log::MessageID PING_CHECK_MGR_SUBNET_CONFIG_FAILED; ++extern const isc::log::MessageID PING_CHECK_PAUSE_FAILED; ++extern const isc::log::MessageID PING_CHECK_PAUSE_ILLEGAL; ++extern const isc::log::MessageID PING_CHECK_PAUSE_PERMISSIONS_FAILED; ++extern const isc::log::MessageID PING_CHECK_RESUME_FAILED; ++extern const isc::log::MessageID PING_CHECK_UNEXPECTED_READ_ERROR; ++extern const isc::log::MessageID PING_CHECK_UNEXPECTED_WRITE_ERROR; ++extern const isc::log::MessageID PING_CHECK_UNLOAD; ++ ++#endif // PING_CHECK_MESSAGES_H +diff --git a/src/hooks/dhcp/ping_check/ping_check_messages.mes b/src/hooks/dhcp/ping_check/ping_check_messages.mes +new file mode 100644 +index 0000000000..21d407bedf +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_check_messages.mes +@@ -0,0 +1,229 @@ ++# Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++# ++# This Source Code Form is subject to the terms of the Mozilla Public ++# License, v. 2.0. If a copy of the MPL was not distributed with this ++# file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++% PING_CHECK_CB4_UPDATE_FAILED A subnet ping-check parameters failed to parse after being updated %1 ++This error message is emitted when an error occurs trying to parse a subnet ++ping-check parameters after the subnet was updated via configuration backend. ++This implies one or more of the parameters is invalid and must be corrected. ++ ++% PING_CHECK_CHANNEL_ECHO_REPLY_RECEIVED from address %1, id %2, sequence %3 ++Logged at debug log level 50. ++This debug message is issued when an ECHO REPLY has been received on ++the ping channel's ICMP socket. ++ ++% PING_CHECK_CHANNEL_ECHO_REQUEST_SENT to address %1, id %2, sequence %3 ++Logged at debug log level 50. ++This debug message is issued when an ECHO REQUEST has been written to the ++ping channel's ICMP socket. ++ ++% PING_CHECK_CHANNEL_MALFORMED_PACKET_RECEIVED error occurred unpacking message %1, discarding it ++Logged at debug log level 40. ++This debug message is emitted when an ICMP packet has been received ++that could not be unpacked. ++ ++% PING_CHECK_CHANNEL_NETWORK_WRITE_ERROR occurred trying to ping %1, error %2 ++This error message occurs when an asynchronous write on the ICMP socket ++failed trying to send on the ping target's network. This may mean an interface ++is down or there is a configuration error. The lease address to ping and the ++type of the error are provided in the arguments. ++ ++% PING_CHECK_CHANNEL_SOCKET_CLOSED ICMP socket has been closed. ++Logged at debug log level 40. ++This debug message is emitted when the ICMP socket for carrying out ++ping checks has been closed. ++ ++% PING_CHECK_CHANNEL_SOCKET_CLOSE_ERROR an attempt to close the ICMP socket failed %1 ++This error message is emitted when an unexpected error occurred ++while closing the ping check ICMP socket. The error detail is ++provided as an argument of the log message. ++ ++% PING_CHECK_CHANNEL_SOCKET_OPENED ICMP socket been opened successfully. ++Logged at debug log level 40. ++This debug message is emitted when the ICMP socket for carrying out ++ping checks has been successfully opened. ++ ++% PING_CHECK_CHANNEL_SOCKET_READ_FAILED socket read completed with an error %1 ++This error message occurs when an asynchronous read on the ICMP socket ++failed. The details of the error are provided as an argument of the log ++message. ++ ++% PING_CHECK_CHANNEL_SOCKET_WRITE_FAILED socket write completed with an error %1 ++This error message occurs when an asynchronous write on the ICMP socket ++failed. The details of the error are provided as an argument of the log ++message. ++ ++% PING_CHECK_CHANNEL_STOP channel is stopping operations. ++Logged at debug log level 40. ++This debug message indicates that the channel is stopping operations and ++closing the ICMP socket. The reason for stopping should be apparent in ++preceding log messages. ++ ++% PING_CHECK_CHANNEL_WATCH_SOCKET_CLEAR_ERROR an attempt to clear the WatchSocket associated with ++the single-threaded ping-channel failed %1 ++This error message is emitted when an unexpected error occurred ++while clearing the ready marker of the WatchSocket associated with ++the ping check channel. This can only occur when running in ++single-threaded mode. The error detail is provided as an argument ++of the log message. ++ ++% PING_CHECK_CHANNEL_WATCH_SOCKET_CLOSE_ERROR an attempt to close the WatchSocket associated with ++the single-threaded ping-channel failed %1 ++This error message is emitted when an unexpected error occurred ++while closing the WatchSocket associated with the ping check channel. ++This can only occur when running in single-threaded mode. ++The error detail is provided as an argument of the log message. ++ ++% PING_CHECK_DHCP4_SRV_CONFIGURED_FAILED dhcp4_srv_configured callout failed %1 ++This error message indicates an error during the Ping Check hook ++library dhcp4_srv_configured callout. The details of the error are ++provided as argument of the log message. ++ ++% PING_CHECK_DUPLICATE_CHECK Ping check already in progress for %1, initiated by %2 ++Logged at debug log level 40. ++This debug message is emitted when a duplicate request to test an address ++is received. When this occurs the duplicate test will be skipped and ++the associated DHCPOFFER will be dropped. ++ ++% PING_CHECK_LEASE4_OFFER_FAILED lease4_offer callout failed for query %1, lease address %2, reason %3 ++This error message indicates an error during the Ping Check hook ++library lease4_offer callout. The details of the error are ++provided as argument of the log message. ++ ++% PING_CHECK_LOAD_ERROR loading Ping Check hooks library failed %1 ++This error message indicates an error during loading the Ping Check ++hooks library. The details of the error are provided as argument of ++the log message. ++ ++% PING_CHECK_LOAD_OK Ping Check hooks library loaded successfully. ++This info message indicates that the Ping Check hooks library has ++been loaded successfully. ++ ++% PING_CHECK_MGR_CHANNEL_DOWN Ping Channel has shutdown, ping checking will be skipped ++This error message is emitted when the underlying ICMP channel ++has stopped due to an unrecoverable error. DHCP service may continue ++to function but without performing ping checks. Prior log messages should ++provide details. ++ ++% PING_CHECK_MGR_LEASE_FREE_TO_USE address %1 is free to use for %2 ++Logged at debug log level 40. ++This debug message is emitted when ping check has deemed an ++address is free to use. The log arguments detail the lease address ++checked and the query which initiated the check. ++ ++% PING_CHECK_MGR_NEXT_ECHO_SCHEDULED for %1, scheduling ECHO_REQUEST %2 of %3 ++Logged at debug log level 50. ++This debug message is emitted when the minimum number of ECHO REQUESTs ++is greater than 1 and the next ECHO REQUEST for a given lease address has ++been scheduled. ++ ++% PING_CHECK_MGR_RECEIVED_ECHO_REPLY from %1, id %2, sequence %3 ++Logged at debug log level 40. ++This debug message is emitted when an ECHO REPLY message has been received. ++The log argument details the source IP address, id, and sequence number of ++the ECHO REPLY. ++ ++% PING_CHECK_MGR_RECEIVED_UNEXPECTED_ECHO_REPLY from %1, id %2, sequence %3 received after reply-timeout expired ++Logged at debug log level 50. ++This debug message is emitted when an ECHO REPLY has been received after the ++reply-timeout has expired and is no longer of interest. This may be an errant ++ECHO REPLY or it may indicate that the reply-timeout value is too short. The ++log argument details the source IP address, id, and sequence number of the reply. ++ ++% PING_CHECK_MGR_RECEIVED_UNEXPECTED_UNREACHABLE_MSG for %1, id %2, sequence %3 received after reply-timeout expired ++Logged at debug log level 50. ++This debug message is emitted when an UNREACHABLE message has been received ++after the reply-timeout has expired and is no longer of interest. This may ++be an errant message or it may indicate that the reply-timeout value is ++too short. ++ ++% PING_CHECK_MGR_RECEIVED_UNREACHABLE_MSG for %1, id %2, sequence %3 ++Logged at debug log level 50. ++This debug message is emitted when an UNREACHABLE message has been received. ++The log argument details the target IP address, id, and sequence number from ++the embedded ECHO REQUEST. ++ ++% PING_CHECK_MGR_REPLY_RECEIVED_ERROR an error occurred processing an ICMP reply message %1 ++This debug message is emitted when an error occurred while processing an inbound ++ICMP message. The log argument describes the specific error. ++ ++% PING_CHECK_MGR_REPLY_TIMEOUT_EXPIRED for %1, ECHO REQUEST %2 of %3, reply-timeout %4 ++Logged at debug log level 50. ++This debug message is emitted when no reply is received to an ++ECHO REQUEST before the configured timeout value, `reply-timeout` ++was reached. The log arguments provides details. ++ ++% PING_CHECK_MGR_SEND_COMPLETED_ERROR an error occurred in the send completion callback %1 ++This error message is emitted when an unexpected error occurred after the completion of ++a successful write to the PingChannel socket. The log argument describes the ++specific error. ++ ++% PING_CHECK_MGR_STARTED ping channel operations are running, number of threads %1 ++This message is emitted when the ping check channel has been opened ++and is ready to process requests. The log argument includes the number of ++threads in the channel's thread pool. ++ ++% PING_CHECK_MGR_STARTED_SINGLE_THREADED single-threaded ping channel operations are running ++This message is emitted when the ping check channel has been opened ++and is ready to process requests in single-threaded mode. ++ ++% PING_CHECK_MGR_START_PING_CHECK for %1, initiated by %2 ++Logged at debug log level 40. ++This debug message is emitted when a ping check for an address ++has been initiated. The log arguments detail the lease address to ++ping and the query which initiated the check. ++ ++% PING_CHECK_MGR_STOPPED channel operations have stopped ++This message is emitted when the ping check channel operations ++have been stopped. ++ ++% PING_CHECK_MGR_STOPPING ping channel operations are stopping ++Logged at debug log level 40. ++This debug message is emitted when the ping check channel is stopping ++operations, typically due to configuration event or server shutdown. ++ ++% PING_CHECK_MGR_SUBNET_CONFIG_FAILED user-context for subnet id %1, contains invalid ping-check %2 ++This error message indicates that a subnet was updated via subnet commands ++and its 'user-context' contains invalid 'ping-check' configuration. The ++server will log the error once and then use global ping-check parameters ++for the subnet until the configuration is corrected. ++ ++% PING_CHECK_PAUSE_FAILED Pausing ping channel operations failed %1 ++This error message is emitted when an unexpected error occurred while ++attempting to pause the ping channel's thread pool. This error is highly ++unlikely and indicates a programmatic issue that should be reported as ++defect. ++ ++% PING_CHECK_PAUSE_ILLEGAL Pausing ping channel operations not allowed %1 ++This error message is emitted when attempting to pause the ping channel's ++thread pool. This indicates that a channel thread attempted to use a critical ++section which would result in a dead-lock. This error is highly unlikely ++and indicates a programmatic issue that should be reported as a defect. ++ ++% PING_CHECK_PAUSE_PERMISSIONS_FAILED Permissions check for ping-channel pause failed %1 ++This error message is emitted when an unexpected error occurred while ++validating an attempt to pause the ping channel's thread pool. This error ++is highly unlikely and indicates a programmatic issue that should be ++reported as a defect. ++ ++% PING_CHECK_RESUME_FAILED Resuming ping channel operations failed %1 ++This error message is emitted when an unexpected error occurred while ++attempting to resume operation of the ping channel's thread pool. This ++error is highly unlikely and indicates a programmatic issue that should ++be reported as defect. ++ ++% PING_CHECK_UNEXPECTED_READ_ERROR could not start next socket read %1 ++This error message occurs when initiating an asynchronous read on the ICMP ++socket failed in an unexpected fashion. The details of the error are provided ++as an argument of the log message. ++ ++% PING_CHECK_UNEXPECTED_WRITE_ERROR could not start next socket write %1 ++This error message occurs when initiating an asynchronous write on the ICMP ++socket failed in an unexpected fashion. The details of the error are provided ++as an argument of the log message. ++ ++% PING_CHECK_UNLOAD Ping Check hooks library has been unloaded ++This info message indicates that the Ping Check hooks library has been ++unloaded. +diff --git a/src/hooks/dhcp/ping_check/ping_check_mgr.cc b/src/hooks/dhcp/ping_check/ping_check_mgr.cc +new file mode 100644 +index 0000000000..cb4f2ee1dc +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_check_mgr.cc +@@ -0,0 +1,798 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++ ++#include <ping_check_mgr.h> ++#include <ping_check_log.h> ++#include <dhcpsrv/cfgmgr.h> ++#include <hooks/hooks_manager.h> ++#include <util/multi_threading_mgr.h> ++#include <util/chrono_time_utils.h> ++ ++using namespace isc; ++using namespace isc::asiolink; ++using namespace isc::dhcp; ++using namespace isc::data; ++using namespace isc::hooks; ++using namespace isc::util; ++using namespace std; ++using namespace std::chrono; ++ ++namespace ph = std::placeholders; ++ ++namespace isc { ++namespace ping_check { ++ ++PingCheckMgr::PingCheckMgr() ++ : io_service_(new IOService()), thread_pool_(), ++ store_(new PingContextStore()), ++ channel_(), ++ config_cache_(new ConfigCache()), ++ mutex_(new mutex()), ++ suspended_(false) { ++} ++ ++PingCheckMgr::PingCheckMgr(uint32_t num_threads, ++ uint32_t min_echos, ++ uint32_t reply_timeout) ++ : io_service_(new IOService()), thread_pool_(), ++ store_(new PingContextStore()), ++ channel_(), ++ config_cache_(new ConfigCache()), ++ mutex_(new mutex()), ++ suspended_(false) { ++ PingCheckConfigPtr config(new PingCheckConfig()); ++ config->setMinPingRequests(min_echos); ++ config->setReplyTimeout(reply_timeout); ++ config->setPingChannelThreads(num_threads); ++ config_cache_->setGlobalConfig(config); ++} ++ ++PingCheckMgr::~PingCheckMgr() { ++ stop(); ++} ++ ++void ++PingCheckMgr::configure(ConstElementPtr params) { ++ if (!params) { ++ isc_throw(dhcp::DhcpConfigError, "params must not be null"); ++ return; ++ } ++ ++ if (params->getType() != Element::map) { ++ isc_throw(dhcp::DhcpConfigError, "params must be an Element::map"); ++ return; ++ } ++ ++ PingCheckConfigPtr config(new PingCheckConfig()); ++ config->parse(params); ++ config_cache_->setGlobalConfig(config); ++} ++ ++void ++PingCheckMgr::updateSubnetConfig(SrvConfigPtr server_config) { ++ // Iterate over subnets and cache configurations for each. ++ ConfigCachePtr local_cache(new ConfigCache()); ++ local_cache->setGlobalConfig(config_cache_->getGlobalConfig()); ++ auto const& subnets = server_config->getCfgSubnets4()->getAll(); ++ for (auto const& subnet : (*subnets)) { ++ auto user_context = subnet->getContext(); ++ local_cache->parseAndCacheConfig(subnet->getID(), user_context); ++ } ++ ++ // No errors above, replace the existing cache. ++ config_cache_ = local_cache; ++} ++ ++const PingCheckConfigPtr ++PingCheckMgr::getGlobalConfig() const { ++ return (config_cache_->getGlobalConfig()); ++} ++ ++const PingCheckConfigPtr ++PingCheckMgr::getScopedConfig(Lease4Ptr& lease) { ++ if (!lease) { ++ // This really shouldn't happen. ++ isc_throw(InvalidOperation, "PingCheckConfig::getScopedConfig() - lease cannot be empty"); ++ } ++ ++ auto subnet_id = lease->subnet_id_; ++ ++ // If the cache is stale, update it. We do this to catch subnets that have been updated ++ // via subnet_cmds. ++ auto server_config = CfgMgr::instance().getCurrentCfg(); ++ auto const& subnet = server_config->getCfgSubnets4()->getBySubnetId(subnet_id); ++ if (!subnet) { ++ // This really shouldn't happen. ++ isc_throw(InvalidOperation, "PingCheckMgr::getScopedConfig() - " ++ "no subnet for id: " << subnet_id ++ << ", for lease address: " << lease->addr_); ++ } ++ ++ // If cache is stale flush it and we'll lazy init subnets as we see them. ++ if (subnet->getModificationTime() > config_cache_->getLastFlushTime()) { ++ config_cache_->flush(); ++ } ++ ++ // If we don't find an entry for this subnet then we haven't seen it ++ // before so parse and cache it. If the subnet doesn't specify ping-check ++ // we cache an empty entry. ++ PingCheckConfigPtr config; ++ if (!config_cache_->findConfig(subnet_id, config)) { ++ auto user_context = subnet->getContext(); ++ try { ++ config = config_cache_->parseAndCacheConfig(subnet_id, user_context); ++ } catch (const std::exception& ex) { ++ // We emit and error and then cache an empty entry. This causes us ++ // to log the error once and then default to global settings afterward. ++ // This avoids us relentlessly logging and failing. Remember this ++ // is happening because a subnet was updated with an invalid context via ++ // subnet-cmd. ++ LOG_ERROR(ping_check_logger, PING_CHECK_MGR_SUBNET_CONFIG_FAILED) ++ .arg(subnet_id) ++ .arg(ex.what()); ++ config_cache_->cacheConfig(subnet_id, config); ++ } ++ } ++ ++ // Return subnet's ping-check config if it specified one, otherwise ++ // return the global config. ++ return (config ? config : config_cache_->getGlobalConfig()); ++} ++ ++void ++PingCheckMgr::startPing(dhcp::Lease4Ptr& lease, dhcp::Pkt4Ptr& query, hooks::ParkingLotHandlePtr& parking_lot, ++ const PingCheckConfigPtr& config) { ++ if (checkSuspended()) { ++ // Server should not be submitting requests. ++ isc_throw(InvalidOperation, "PingCheckMgr::startPing() - DHCP service is suspended!"); ++ } ++ ++ if (!channel_ || !channel_->isOpen()) { ++ isc_throw(InvalidOperation, "PingCheckMgr::startPing() - channel isn't open"); ++ } ++ ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_BASIC, ++ PING_CHECK_MGR_START_PING_CHECK) ++ .arg(lease->addr_) ++ .arg(query->getLabel()); ++ ++ // Adds a context to the store ++ store_->addContext(lease, query, config->getMinPingRequests(), ++ config->getReplyTimeout(), parking_lot); ++ ++ // Posts a call to channel's startSend() and startRead(). This will kick-start perpetual ++ // write and read cycles if they are not already running. ++ if (channel_) { ++ channel_->startSend(); ++ channel_->startRead(); ++ } ++} ++ ++void ++PingCheckMgr::startPing(dhcp::Lease4Ptr& lease, dhcp::Pkt4Ptr& query, hooks::ParkingLotHandlePtr& parking_lot) { ++ startPing(lease, query, parking_lot, getGlobalConfig()); ++} ++ ++bool ++PingCheckMgr::nextToSend(IOAddress& next) { ++ if (checkSuspended()) { ++ return (false); ++ } ++ ++ PingContextPtr context = store_->getNextToSend(); ++ if (!context) { ++ return (false); ++ } ++ ++ next = context->getTarget(); ++ // Transition to sending. ++ context->setState(PingContext::SENDING); ++ store_->updateContext(context); ++ ++ return (true); ++} ++ ++void ++PingCheckMgr::sendCompleted(const ICMPMsgPtr& echo, bool send_failed) { ++ if (checkSuspended()) { ++ return; ++ } ++ ++ try { ++ if (!echo) { ++ isc_throw(BadValue, "PingCheckMgr::sendCompleted() - echo is empty"); ++ } ++ ++ if (echo->getType() != ICMPMsg::ECHO_REQUEST) { ++ isc_throw(BadValue, "PingCheckMgr::sendCompleted() - message type: " ++ << echo->getType() << " is not an ECHO_REQUEST"); ++ } ++ ++ // Update the context associated with this ECHO_REQUEST. ++ PingContextPtr context = store_->getContextByAddress(echo->getDestination()); ++ if (!context) { ++ isc_throw(Unexpected, "PingCheckMgr::sendCompleted() " ++ " no context found for: " << echo->getDestination()); ++ } ++ ++ if (send_failed) { ++ // Recoverable error occurred which means we can't get to the target's ++ // network (interface down?). Treat this the same as TARGET UNREACHABLE. ++ finishFree(context); ++ } else { ++ // Transition the context to WAITING_FOR_REPLY. ++ context->beginWaitingForReply(); ++ store_->updateContext(context); ++ } ++ ++ // Update the expiration timer if necessary. ++ setNextExpiration(); ++ } catch (const std::exception& ex) { ++ LOG_ERROR(ping_check_logger, PING_CHECK_MGR_SEND_COMPLETED_ERROR) ++ .arg(ex.what()); ++ } ++} ++ ++void ++PingCheckMgr::replyReceived(const ICMPMsgPtr& reply) { ++ if (checkSuspended()) { ++ return; ++ } ++ ++ try { ++ if (!reply) { ++ isc_throw(BadValue, "PingCheckMgr::replyReceived() - echo is empty"); ++ } ++ ++ switch (reply->getType()) { ++ case ICMPMsg::ECHO_REPLY: ++ handleEchoReply(reply); ++ break; ++ case ICMPMsg::TARGET_UNREACHABLE: ++ // Extract embedded ECHO REQUEST ++ handleTargetUnreachable(reply); ++ break; ++ default: ++ // Ignore anything else. ++ return; ++ } ++ ++ setNextExpiration(); ++ } catch (const std::exception& ex) { ++ LOG_ERROR(ping_check_logger, PING_CHECK_MGR_REPLY_RECEIVED_ERROR) ++ .arg(ex.what()); ++ } ++} ++ ++void ++PingCheckMgr::handleEchoReply(const ICMPMsgPtr& echo_reply) { ++ // Update the context associated with this ECHO_REQUEST. ++ PingContextPtr context = store_->getContextByAddress(echo_reply->getSource()); ++ if (!context) { ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_DETAIL, ++ PING_CHECK_MGR_RECEIVED_UNEXPECTED_ECHO_REPLY) ++ .arg(echo_reply->getSource()) ++ .arg(echo_reply->getId()) ++ .arg(echo_reply->getSequence()); ++ return; ++ } ++ ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_BASIC, ++ PING_CHECK_MGR_RECEIVED_ECHO_REPLY) ++ .arg(echo_reply->getSource()) ++ .arg(echo_reply->getId()) ++ .arg(echo_reply->getSequence()); ++ ++ context->setState(PingContext::TARGET_IN_USE); ++ store_->updateContext(context); ++ ++ // If parking is employed, unpark the query from the parking lot, ++ // and set the offer_address_in_use argument in the callout handle ++ // to true, indicating to the server that the lease should be declined ++ // and the DHCPOFFER discarded. ++ auto parking_lot = context->getParkingLot(); ++ if (parking_lot) { ++ auto query = context->getQuery(); ++ auto callout_handle = query->getCalloutHandle(); ++ callout_handle->setArgument("offer_address_in_use", true); ++ parking_lot->unpark(query); ++ } ++ ++ // Remove the context from the store. ++ store_->deleteContext(context); ++} ++ ++void ++PingCheckMgr::handleTargetUnreachable(const ICMPMsgPtr& unreachable) { ++ // Unpack the embedded ECHO REQUEST. ++ ICMPMsgPtr embedded_echo; ++ auto payload = unreachable->getPayload(); ++ embedded_echo = ICMPMsg::unpack(payload.data(), payload.size()); ++ ++ // Fetch the context associated with the ECHO_REQUEST. ++ PingContextPtr context = store_->getContextByAddress(embedded_echo->getDestination()); ++ if (!context) { ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_DETAIL, ++ PING_CHECK_MGR_RECEIVED_UNEXPECTED_UNREACHABLE_MSG) ++ .arg(embedded_echo->getDestination()) ++ .arg(embedded_echo->getId()) ++ .arg(embedded_echo->getSequence()); ++ return; ++ } ++ ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_DETAIL, ++ PING_CHECK_MGR_RECEIVED_UNREACHABLE_MSG) ++ .arg(embedded_echo->getDestination()) ++ .arg(embedded_echo->getId()) ++ .arg(embedded_echo->getSequence()); ++ ++ // Render the address usable. ++ finishFree(context); ++} ++ ++void ++PingCheckMgr::finishFree(const PingContextPtr& context) { ++ context->setState(PingContext::TARGET_FREE); ++ store_->updateContext(context); ++ ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_BASIC, ++ PING_CHECK_MGR_LEASE_FREE_TO_USE) ++ .arg(context->getTarget()) ++ .arg(context->getQuery()->getLabel()); ++ ++ // If parking is employed, unpark the query from the parking lot, ++ // and set the offer_address_in_use argument in the callout handle ++ // to false, indicating to the server that the lease is available ++ // and the DHCPOFFER should be sent to the client. ++ auto parking_lot = context->getParkingLot(); ++ if (parking_lot) { ++ auto query = context->getQuery(); ++ auto callout_handle = query->getCalloutHandle(); ++ callout_handle->setArgument("offer_address_in_use", false); ++ parking_lot->unpark(context->getQuery()); ++ } ++ ++ // Remove the context from the store. ++ store_->deleteContext(context); ++} ++ ++void ++PingCheckMgr::channelShutdown() { ++ LOG_ERROR(ping_check_logger, PING_CHECK_MGR_CHANNEL_DOWN); ++ if (io_service_) { ++ // As this is a callback that may be invoked by a channel ++ // thread we post a call to stopService() rather than call ++ // it directly. ++ io_service_->post([&]() { stopService(true); }); ++ } ++} ++ ++size_t ++PingCheckMgr::processExpiredSince(const TimeStamp& since /* = PingContext::now() */) { ++ auto expired_pings = store_->getExpiredSince(since); ++ size_t more_pings = 0; ++ for (auto const& context : *(expired_pings)) { ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_DETAIL, ++ PING_CHECK_MGR_REPLY_TIMEOUT_EXPIRED) ++ .arg(context->getTarget()) ++ .arg(context->getEchosSent()) ++ .arg(context->getMinEchos()) ++ .arg(context->getReplyTimeout()); ++ ++ if (context->getEchosSent() < context->getMinEchos()) { ++ doNextEcho(context); ++ ++more_pings; ++ } else { ++ finishFree(context); ++ } ++ } ++ ++ return (more_pings); ++} ++ ++void ++PingCheckMgr::doNextEcho(const PingContextPtr& context) { ++ // Position to do another ping by re-entering WAITING_TO_SEND ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_DETAIL, ++ PING_CHECK_MGR_NEXT_ECHO_SCHEDULED) ++ .arg(context->getTarget()) ++ .arg(context->getEchosSent() + 1) ++ .arg(context->getMinEchos()); ++ ++ context->beginWaitingToSend(); ++ store_->updateContext(context); ++} ++ ++TimeStamp ++PingCheckMgr::getNextExpiry() { ++ MultiThreadingLock lock(*mutex_); ++ return (next_expiry_); ++} ++ ++void ++PingCheckMgr::setNextExpiration() { ++ MultiThreadingLock lock(*mutex_); ++ if (checkSuspendedInternal()) { ++ return; ++ } ++ ++ setNextExpirationInternal(); ++} ++ ++void ++PingCheckMgr::setNextExpirationInternal() { ++ // Find the context that expires soonest. ++ PingContextPtr context = store_->getExpiresNext(); ++ if (context) { ++ // if the context's expiry is sooner than current expiry ++ // reschedule expiration timer ++ if ((next_expiry_ == PingContext::EMPTY_TIME()) || ++ (context->getNextExpiry() < next_expiry_)) { ++ auto now = PingContext::now(); ++ auto timeout = duration_cast<milliseconds>(context->getNextExpiry() - now); ++ /// @todo For now we'll impose a 2 ms minimum to avoid thrashing the timer. ++ timeout = (timeout > milliseconds(2) ? timeout : milliseconds(2)); ++ next_expiry_ = now + timeout; ++ expiration_timer_->setup(std::bind(&PingCheckMgr::expirationTimedOut, ++ shared_from_this()), ++ timeout.count(), IntervalTimer::ONE_SHOT); ++ } ++ } else { ++ // Nothing waiting to expire. Cancel the timer. ++ cancelExpirationTimerInternal(); ++ } ++} ++ ++void ++PingCheckMgr::cancelExpirationTimer() { ++ MultiThreadingLock lock(*mutex_); ++ cancelExpirationTimerInternal(); ++} ++ ++void ++PingCheckMgr::cancelExpirationTimerInternal() { ++ if (expiration_timer_) { ++ expiration_timer_->cancel(); ++ next_expiry_ = PingContext::EMPTY_TIME(); ++ } ++} ++ ++void ++PingCheckMgr::expirationTimedOut() { ++ MultiThreadingLock lock(*mutex_); ++ if (checkSuspendedInternal()) { ++ return; ++ } ++ ++ // Process everything that has expired since current time. ++ auto more_pings = processExpiredSince(); ++ ++ // Update the expiration timer. ++ next_expiry_ = PingContext::EMPTY_TIME(); ++ setNextExpirationInternal(); ++ ++ // In the event there was nothing left to process when timed out, ++ // poke the channel to make sure things are moving. ++ if (more_pings && channel_) { ++ channel_->startSend(); ++ channel_->startRead(); ++ } ++} ++ ++CalloutHandle::CalloutNextStep ++PingCheckMgr::shouldPing(Lease4Ptr& lease, Pkt4Ptr& query, ++ Lease4Ptr& old_lease, ++ const PingCheckConfigPtr& config) { ++ ++ // If ping-check is disabled or the channel isn't open, ++ // drop the query from parking and release the offer to the client. ++ if (!config->getEnablePingCheck() || !channel_ || !channel_->isOpen()) { ++ return (CalloutHandle::CalloutNextStep::NEXT_STEP_CONTINUE); ++ } ++ ++ // If we're already running check on this address then drop the ++ // query from parking and discard the offer. ++ if (store_->getContextByAddress(lease->addr_)) { ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_BASIC, ++ PING_CHECK_DUPLICATE_CHECK) ++ .arg(lease->addr_) ++ .arg(query->getLabel()); ++ return (CalloutHandle::CalloutNextStep::NEXT_STEP_DROP); ++ } ++ ++ // If there's a previous lease that belongs to this client and ++ // it was touched by the client less than ping-cltt-secs ago then ++ // no check is needed. Drop the query from parking and release the ++ // offer to the client, ++ if (old_lease && (old_lease->addr_ == lease->addr_)) { ++ if (old_lease->belongsToClient(lease->hwaddr_, lease->client_id_)) { ++ auto now = time(0); ++ if ((now - old_lease->cltt_) < config->getPingClttSecs()) { ++ return (CalloutHandle::CalloutNextStep::NEXT_STEP_CONTINUE); ++ } ++ } ++ } ++ ++ // Leave it parked and do the ping check. ++ return (CalloutHandle::CalloutNextStep::NEXT_STEP_PARK); ++} ++ ++void ++PingCheckMgr::startService(NetworkStatePtr network_state) { ++ network_state_ = network_state; ++ io_service_->post([&]() { start(); }); ++} ++ ++bool ++PingCheckMgr::checkSuspended() { ++ MultiThreadingLock lock(*mutex_); ++ return (checkSuspendedInternal()); ++} ++ ++bool ++PingCheckMgr::checkSuspendedInternal() { ++ if (!network_state_ || network_state_->isServiceEnabled()) { ++ suspended_ = false; ++ } else { ++ if (!suspended_) { ++ suspended_ = true; ++ ++ // Flush the context store, dropping parked queries. ++ flush(false); ++ } ++ } ++ ++ return (suspended_); ++} ++ ++void ++PingCheckMgr::stopService(bool finish_free) { ++ // Pause the thread pool while we flush the store. ++ pause(); ++ ++ // Flush the context store. If finish_free is true ++ // the flush will treat the remaining context lease ++ // addresses as free to use and unpark them. This ++ // will cause the server to send out the associated ++ // OFFERs. If it's false we just drop them from ++ // the parking lot. ++ flush(finish_free); ++ ++ // Stop the thread pool, destroy the channel and the like. ++ stop(); ++} ++ ++void ++PingCheckMgr::start() { ++ if (MultiThreadingMgr::instance().isTestMode()) { ++ return; ++ } ++ if (!MultiThreadingMgr::instance().getMode()) { ++ startSingleThreaded(); ++ return; ++ } ++ ++ // We must be in multi-threading mode. ++ // Add critical section callbacks. ++ MultiThreadingMgr::instance().addCriticalSectionCallbacks("PING_CHECK", ++ std::bind(&PingCheckMgr::checkPermissions, this), ++ std::bind(&PingCheckMgr::pause, this), ++ std::bind(&PingCheckMgr::resume, this)); ++ ++ // Punt if we're already started. ++ if (thread_pool_ && thread_pool_->isStopped()) { ++ isc_throw(InvalidOperation, "PingCheckMgr already started!"); ++ } ++ ++ try { ++ auto config = config_cache_->getGlobalConfig(); ++ auto use_threads = (config->getPingChannelThreads() ? config->getPingChannelThreads() ++ : MultiThreadingMgr::instance().getThreadPoolSize()); ++ thread_pool_.reset(new IoServiceThreadPool(IOServicePtr(), use_threads, true)); ++ IOServicePtr pool_ios = thread_pool_->getIOService(); ++ channel_ = createChannel(pool_ios); ++ channel_->open(); ++ expiration_timer_.reset(new IntervalTimer(pool_ios)); ++ thread_pool_->run(); ++ LOG_INFO(ping_check_logger, PING_CHECK_MGR_STARTED) ++ .arg(use_threads); ++ } catch (const std::exception& ex) { ++ channel_.reset(); ++ thread_pool_.reset(); ++ isc_throw(Unexpected, "PingCheckMgr::start failed:" << ex.what()); ++ } ++} ++ ++void ++PingCheckMgr::startSingleThreaded() { ++ try { ++ auto config = config_cache_->getGlobalConfig(); ++ channel_ = createChannel(io_service_); ++ channel_->open(); ++ expiration_timer_.reset(new IntervalTimer(io_service_)); ++ LOG_INFO(ping_check_logger, PING_CHECK_MGR_STARTED_SINGLE_THREADED); ++ } catch (const std::exception& ex) { ++ channel_.reset(); ++ isc_throw(Unexpected, "PingCheckMgr::startSingleThreaded() failed:" << ex.what()); ++ } ++} ++ ++PingChannelPtr ++PingCheckMgr::createChannel(IOServicePtr io_service) { ++ return (PingChannelPtr(new PingChannel(io_service, ++ std::bind(&PingCheckMgr::nextToSend, ++ this, ph::_1), ++ std::bind(&PingCheckMgr::sendCompleted, ++ this, ph::_1, ph::_2), ++ std::bind(&PingCheckMgr::replyReceived, ++ this, ph::_1), ++ std::bind(&PingCheckMgr::channelShutdown, ++ this)))); ++} ++ ++void ++PingCheckMgr::checkPermissions() { ++ // Since this function is used as CS callback all exceptions must be ++ // suppressed, unlikely though they may be. ++ try { ++ if (thread_pool_) { ++ thread_pool_->checkPausePermissions(); ++ } ++ } catch (const isc::MultiThreadingInvalidOperation& ex) { ++ LOG_ERROR(ping_check_logger, PING_CHECK_PAUSE_ILLEGAL) ++ .arg(ex.what()); ++ // The exception needs to be propagated to the caller of the ++ // @ref MultiThreadingCriticalSection constructor. ++ throw; ++ } catch (const std::exception& ex) { ++ LOG_ERROR(ping_check_logger, PING_CHECK_PAUSE_PERMISSIONS_FAILED) ++ .arg(ex.what()); ++ } ++} ++ ++void ++PingCheckMgr::pause() { ++ if (!MultiThreadingMgr::instance().getMode()) { ++ return; ++ } ++ ++ // Since this function is used as CS callback all exceptions must be ++ // suppressed, unlikely though they may be. ++ try { ++ // Cancel the expiration timer. ++ cancelExpirationTimer(); ++ ++ // Pause the thread pool. ++ if (thread_pool_) { ++ thread_pool_->pause(); ++ } ++ } catch (const std::exception& ex) { ++ LOG_ERROR(ping_check_logger, PING_CHECK_PAUSE_FAILED) ++ .arg(ex.what()); ++ } ++} ++ ++void ++PingCheckMgr::resume() { ++ if (!MultiThreadingMgr::instance().getMode()) { ++ return; ++ } ++ ++ // Since this function is used as CS callback all exceptions must be ++ // suppressed, unlikely though they may be. ++ try { ++ if (thread_pool_) { ++ thread_pool_->run(); ++ } ++ ++ // Restore the expiration timer. ++ setNextExpiration(); ++ } catch (const std::exception& ex) { ++ LOG_ERROR(ping_check_logger, PING_CHECK_RESUME_FAILED) ++ .arg(ex.what()); ++ } ++} ++ ++void ++PingCheckMgr::stop() { ++ LOG_DEBUG(ping_check_logger, isc::log::DBGLVL_TRACE_BASIC, PING_CHECK_MGR_STOPPING); ++ ++ // Cancel the expiration timer. ++ cancelExpirationTimer(); ++ ++ if (channel_) { ++ channel_->close(); ++ } ++ ++ if (thread_pool_) { ++ // Remove critical section callbacks. ++ MultiThreadingMgr::instance().removeCriticalSectionCallbacks("PING_CHECK"); ++ ++ // Stop the thread pool. ++ thread_pool_->stop(); ++ ++ thread_pool_->getIOService()->stopAndPoll(); ++ ++ // Ditch the thread_pool ++ thread_pool_.reset(); ++ } ++ // Ditch the timer. It must be destroyed before the thread pool because in ++ // MT it holds a reference to the pool's IOService. ++ expiration_timer_.reset(); ++ ++ // Get rid of the channel. ++ channel_.reset(); ++ ++ if (io_service_) { ++ io_service_->stopAndPoll(); ++ } ++ ++ LOG_INFO(ping_check_logger, PING_CHECK_MGR_STOPPED); ++} ++ ++bool ++PingCheckMgr::isRunning() { ++ // In ST mode, running is an open channel. ++ if (!MultiThreadingMgr::instance().getMode()) { ++ return (channel_ && channel_->isOpen()); ++ } ++ ++ if (thread_pool_) { ++ return (thread_pool_->isRunning()); ++ } ++ ++ return (false); ++} ++ ++bool ++PingCheckMgr::isStopped() { ++ // In ST mode, stopped equates to no channel. ++ if (!MultiThreadingMgr::instance().getMode()) { ++ return (!channel_); ++ } ++ ++ if (thread_pool_) { ++ return (thread_pool_->isStopped()); ++ } ++ ++ return (true); ++} ++ ++bool ++PingCheckMgr::isPaused() { ++ if (thread_pool_) { ++ return (thread_pool_->isPaused()); ++ } ++ ++ return (false); ++} ++ ++void ++PingCheckMgr::flush(bool finish_free /* = false */) { ++ if (!store_) { ++ return; ++ } ++ ++ // Fetch them all. ++ auto contexts = store_->getAll(); ++ for (auto const& context : *contexts) { ++ if (finish_free) { ++ finishFree(context); ++ } else { ++ auto parking_lot = context->getParkingLot(); ++ if (parking_lot) { ++ parking_lot->drop(context->getQuery()); ++ } ++ } ++ } ++ ++ store_->clear(); ++} ++ ++} // end of namespace ping_check ++} // end of namespace isc +diff --git a/src/hooks/dhcp/ping_check/ping_check_mgr.h b/src/hooks/dhcp/ping_check/ping_check_mgr.h +new file mode 100644 +index 0000000000..42d11c1b48 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_check_mgr.h +@@ -0,0 +1,436 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#ifndef PING_CHECK_MGR_H ++#define PING_CHECK_MGR_H ++ ++#include <asiolink/interval_timer.h> ++#include <asiolink/io_address.h> ++#include <asiolink/io_service.h> ++#include <asiolink/io_service_thread_pool.h> ++#include <cc/data.h> ++#include <cc/simple_parser.h> ++#include <dhcpsrv/srv_config.h> ++#include <hooks/callout_handle.h> ++#include <dhcp/pkt4.h> ++#include <dhcpsrv/lease.h> ++#include <dhcpsrv/network_state.h> ++#include <ping_context_store.h> ++#include <ping_channel.h> ++#include <config_cache.h> ++ ++#include <boost/enable_shared_from_this.hpp> ++ ++#include <mutex> ++ ++namespace isc { ++namespace ping_check { ++ ++/// @brief Defines a pointer to a PingContextStore. ++typedef boost::shared_ptr<PingContextStore> PingContextStorePtr; ++ ++/// @brief Ping Check Manager. ++/// ++/// PinCheckMgr carries out the higher order management of requests for ping ++/// checks from the server. It is a singleton, instantiated when the library ++/// is loaded. It is responsible for: ++/// 1. Parsing and applying configuration. ++/// 2. Maintaining in-memory store of current ping requests (PingContextStore). ++/// 3. Creating and managing the PingChannel through which individual ICMP ECHO/REPLY ++/// cycles are conducted. ++/// 4. When in multi-threaded mode, it creates an IOServiceThread and synchronizes ++/// its state with Kea core MT. ++class PingCheckMgr : public boost::enable_shared_from_this<PingCheckMgr> { ++public: ++ /// @brief Constructor. ++ explicit PingCheckMgr(); ++ ++ /// @brief Constructor. ++ /// ++ /// This constructor is used in testing. It permits setting some basic behavior ++ /// parameters directly, rather than requiring calls to @c configure(). ++ /// ++ /// @param num_threads number of threads to use in the thread pool (0 means follow ++ /// core thread pool size). ++ /// @param min_echos minimum number of ECHO REQUESTs sent without replies ++ /// received required to declare an address free to offer. Defaults to 1, ++ /// must be greater than zero. ++ /// @param reply_timeout maximum number of milliseconds to wait for an ++ /// ECHO REPLY after an ECHO REQUEST has been sent. Defaults to 100. ++ PingCheckMgr(uint32_t num_threads, ++ uint32_t min_echos = 1, ++ uint32_t reply_timeout = 100); ++ ++ /// @brief Destructor. ++ virtual ~PingCheckMgr(); ++ ++ /// @brief Configure the PingCheckMgr. ++ /// ++ /// @param params map containing the hook library parameters. ++ /// @throw BadValue and similar exceptions on error. ++ void configure(data::ConstElementPtr params); ++ ++ /// @brief Update the cache of subnet ping check configurations. ++ /// ++ /// Iterates over the subnets in the given server configuration, ++ /// and caches their ping-check configuration. ++ /// ++ /// @param server_config Server configuration containing the ++ /// configured subnets to process. ++ void updateSubnetConfig(dhcp::SrvConfigPtr server_config); ++ ++ /// @brief Creates a ping channel instance. ++ /// ++ /// @param io_service IOService that will drive the channel. ++ /// ++ /// @return pointer to the newly created channel. ++ virtual PingChannelPtr createChannel(asiolink::IOServicePtr io_service); ++ ++ /// @brief Initiates a ping check for a given lease and its associated ++ /// DHCPDISCOVER packet. ++ /// ++ /// Adds a context to the store and posts a call to @c PingChannel::startSend(). ++ /// ++ /// @param lease lease whose address needs to be ping checked. ++ /// @param query parked DHCPDISCOVER associated with the lease. ++ /// @param parking_lot parking lot in which query is parked. If empty, ++ /// parking is assumed to not be employed. ++ /// @param config configuration parameters to employ. ++ void startPing(dhcp::Lease4Ptr& lease, dhcp::Pkt4Ptr& query, ++ hooks::ParkingLotHandlePtr& parking_lot, ++ const PingCheckConfigPtr& config); ++ ++ /// @brief Initiates a ping check for a given lease and its associated ++ /// DHCPDISCOVER packet. ++ /// ++ /// Convenience method used in unit tests which uses global ++ /// configuration parameters only. ++ /// ++ /// @param lease lease whose address needs to be ping checked. ++ /// @param query parked DHCPDISCOVER associated with the lease. ++ /// @param parking_lot parking lot in which query is parked. If empty, ++ /// parking is assumed to not be employed. ++ void startPing(dhcp::Lease4Ptr& lease, dhcp::Pkt4Ptr& query, ++ hooks::ParkingLotHandlePtr& parking_lot); ++ ++ /// @brief Callback passed to PingChannel to use to retrieve the next ++ /// address to check. ++ /// ++ /// Fetches the context which has been in the WAITING_TO_SEND state the ++ /// longest and returns its lease address. ++ /// ++ /// @param[out] next upon return it will contain the next target address. ++ /// Contents are only meaningful if the function returns true. ++ /// ++ /// @return True another target address exists, false otherwise. ++ virtual bool nextToSend(asiolink::IOAddress& next); ++ ++ /// @brief Callback passed to PingChannel to invoke when an ECHO REQUEST ++ /// send has completed. ++ /// ++ /// If the send completed successfully we'll transition the context to ++ /// WAITING_FOR_REPLY, update the context in the store, and the update ++ /// next expiration. ++ /// ++ /// If the send failed, this implies that a recoverable error occurred, such ++ /// as a interface being down and thus, there is currently no way to send ++ /// the ping to the target network. We'll treat this the same as an ICMP ++ /// TARGET_UNREACHABLE and release the OFFER by calling @c finishFree(). ++ /// ++ /// @param echo ICMP echo message that as sent. ++ /// @param send_failed True if the send completed with a non-fatal error, ++ /// false otherwise. ++ virtual void sendCompleted(const ICMPMsgPtr& echo, bool send_failed); ++ ++ /// @brief Callback passed to PingChannel to invoke when an ICMP ++ /// reply has been received. ++ /// ++ /// If the reply type is an ECHO REQUEST, it is passed to ++ /// handleEchoRequest(), if it is an UNREACHABLE message it ++ /// is passed to handleTargetUnreachable(), any other message ++ /// type is dropped on the floor and the function returns. ++ /// Upon handler completion, it calls setNextExpiration() to ++ /// update the expiration timer. ++ /// ++ /// @param reply ICMP message that was received. ++ virtual void replyReceived(const ICMPMsgPtr& reply); ++ ++ /// @brief Process an ECHO REPLY message. ++ /// ++ /// @param echo_reply ICMP ECHO REPLY message to process. ++ void handleEchoReply(const ICMPMsgPtr& echo_reply); ++ ++ /// @brief Process an UNREACHABLE message. ++ /// ++ /// @param unreachable ICMP UNREACHABLE message to process. ++ void handleTargetUnreachable(const ICMPMsgPtr& unreachable); ++ ++ /// @brief Processes a context whose address has been deemed free to use. ++ /// ++ /// -# Moves the context to TARGET_FREE state ++ /// -# Updates the context in the store ++ /// -# Unparks the query which will release the DHCPOFFER to the client ++ /// -# Invokes the target free callback (do we still need this?) ++ /// -# Deletes the store from the context ++ /// ++ /// @param context context to process. ++ void finishFree(const PingContextPtr& context); ++ ++ /// @brief Position a context to do another ping test. ++ /// ++ /// -# Moves the context to WAITING_SEND_STATE ++ /// -# Updates the context in the store ++ /// ++ /// @param context context to process. ++ void doNextEcho(const PingContextPtr& context); ++ ++ /// @brief Callback passed to PingChannel to invoke when it shuts down. ++ /// ++ /// Logs the shutdown and then posts a call to @c stopService() to the ++ /// main IOService. ++ virtual void channelShutdown(); ++ ++ /// @brief Performs expiration processing for contexts whose WAITING_FOR_REPLY ++ /// states expired prior to a given point in time. ++ /// ++ /// expired_pings = store_->getExpiredSince(since) ++ /// for context : expired_pings { ++ /// unpark context->getQuery() ++ /// store_->deleteContext(context) ++ /// } ++ /// ++ /// @param since point in time to select against. Defaults to current time. ++ /// @return number of contexts scheduled for another ping, zero if none. ++ virtual size_t processExpiredSince(const TimeStamp& since = PingContext::now()); ++ ++ /// @brief Fetches the time at which expiration timer will next expire. ++ /// ++ /// @return TimeStamp containing the next expiration time. ++ TimeStamp getNextExpiry(); ++ ++ /// @brief Updates the expiration timer (thread safe). ++ /// ++ /// PingContextPtr next = pings->getExpiresNext() ++ /// if next ++ /// reschedule expiration timer for next->getNextExpiry(); ++ /// else ++ /// cancel expiration timer ++ virtual void setNextExpiration(); ++ ++ /// @brief Updates the expiration timer. ++ /// ++ /// PingContextPtr next = pings->getExpiresNext() ++ /// if next ++ /// reschedule expiration timer for next->getNextExpiry(); ++ /// else ++ /// cancel expiration timer ++ virtual void setNextExpirationInternal(); ++ ++ /// @brief Cancels the expiration timer (thread safe). ++ void cancelExpirationTimer(); ++ ++ /// @brief Cancels the expiration timer. ++ void cancelExpirationTimerInternal(); ++ ++ /// @brief Callback passed to expiration timer to invoke on timeout. ++ virtual void expirationTimedOut(); ++ ++ /// @brief Determines whether or not a lease should be ping checked. ++ /// ++ /// Employs the following logic to determine if a ping-check should ++ /// be conducted: ++ /// ++ /// If there's a previous lease that belongs to this client and ++ /// it was touched by the client less than ping-cltt-secs ago, ++ /// then send the offer to the client without ping checking. ++ /// ++ /// Otherwise a ping-check is called for, leave the query parked. ++ /// ++ /// @param lease prospective lease to check. ++ /// @param query DHCPDISCOVER associated with the lease. ++ /// @param old_lease pre-existing lease for this client (if one). ++ /// @param config configuration parameters to employ. ++ /// ++ /// @return CalloutNextStep indicating what should happen next: ++ /// - status == PARK - ping check it ++ /// - status == CONTINUE - check not needed, release DHCPOFFER to client ++ /// - status == DROP - duplicate check, drop the duplicate DHCPOFFER ++ virtual hooks::CalloutHandle::CalloutNextStep shouldPing(dhcp::Lease4Ptr& lease, ++ dhcp::Pkt4Ptr& query, ++ dhcp::Lease4Ptr& old_lease, ++ const PingCheckConfigPtr& config); ++ ++ /// @brief Check if the current thread can perform thread pool state ++ /// transition. ++ /// ++ /// @throw MultiThreadingInvalidOperation if the state transition is done on ++ /// any of the worker threads. ++ void checkPermissions(); ++ ++ /// @brief Performs a deferred start by posting an invocation of @c start() ++ /// to the given IOService. ++ /// ++ /// @param network_state pointer to server's networks state object. ++ void startService(dhcp::NetworkStatePtr network_state); ++ ++ /// @brief Shuts down the manager's channel, flushes the store. ++ /// ++ /// This function gracefully winds down operation: ++ /// ++ /// 1. Pauses the thread pool. ++ /// 2. Flushes the context store, either finishing all contexts as free ++ /// or just dropping them from parking, depending on finish_free parameter. ++ /// 3. Stop the thread pool, shutdown the channel. ++ /// ++ /// @param finish_free if true finishFree() will be invoke on all remaining ++ /// contexts in the store, otherwise their queries are simply dropped from ++ /// the parking lot. ++ void stopService(bool finish_free = false); ++ ++ /// @brief Start PingChannel operations. ++ /// ++ /// Will start multi-threaded if core MT is enabled, or calls ++ /// @c startSingleThreaded() if core MT is disabled. Creates ++ /// a thread pool with its own IOService, uses that IOService ++ /// when creating the channel. ++ void start(); ++ ++ /// @brief Start single-threaded PingChannel operations. ++ /// ++ /// Does not create a thread pool. Uses main thread's IOService ++ /// when creating the channel. ++ void startSingleThreaded(); ++ ++ /// @brief Pause PingChannel operations. ++ /// ++ /// In multi-threaded mode this pauses the thread pool threads, in ++ /// single-threaded mode it does nothing. ++ void pause(); ++ ++ /// @brief Resume PingChannel operations. ++ /// ++ /// In multi-threaded mode this resumes the thread pool threads, in ++ /// single-threaded mode it does nothing. ++ void resume(); ++ ++ /// @brief Flushes the ping context store. ++ /// ++ /// This function iterates over the contexts in the store and then ++ /// either invokes finishFree() or drops their queries from parking ++ /// depending upon finish_free parameter. It assumes the operations ++ /// have ceased (i.e. thread pool is not running). ++ /// ++ /// @param finish_free if true finishFree() will be invoke on all remaining ++ /// contexts in the store, otherwise their queries are simply dropped from ++ /// the parking lot. ++ void flush(bool finish_free = false); ++ ++ /// @brief Stop PingChannel operations. ++ void stop(); ++ ++ /// @brief Indicates if the thread pool is running. ++ /// ++ /// @return True if the thread pool exists and it is in the RUNNING state in ++ /// multi-threaded mode, true if the channel exists and is open in single-threaded ++ /// mode, false otherwise. ++ bool isRunning(); ++ ++ /// @brief Indicates if the thread pool is stopped. ++ /// ++ /// @return True if the thread pool does not exist or it is in the STOPPED ++ /// state in multi-threaded mode, true if the channel does not exist in ++ /// single-threaded mode, false otherwise. ++ bool isStopped(); ++ ++ /// @brief Indicates if the thread pool is paused. ++ /// ++ /// @return True if the thread pool exists and it is in the PAUSED state, ++ /// false otherwise. Always returns false in single-threaded mode. ++ bool isPaused(); ++ ++ /// @brief Checks if operations are currently suspended due to NetworkState. ++ /// ++ /// Thread-safe wrapper around checkSuspendedInternal(). ++ /// ++ /// @return True if operations are suspended, false otherwise. ++ bool checkSuspended(); ++ ++ /// @brief Checks if operations are currently suspended due to NetworkState. ++ /// ++ /// If DHCP service is enabled, operations are not suspended and the function ++ /// returns false. Otherwise operations, if not already suspended, are suspended ++ /// by flushing the PingContext store and the function returns true. The queries ++ /// for flushed contexts are dropped from parking and thus their offers discarded. ++ /// ++ /// @return True if operations are suspended, false otherwise. ++ bool checkSuspendedInternal(); ++ ++ /// @brief Fetches the current, global configuration parameters. ++ /// ++ /// @return PingCheckConfig reference containing the current configuration. ++ const PingCheckConfigPtr getGlobalConfig() const; ++ ++ /// @brief Fetches the current, scoped configuration parameters. ++ /// ++ /// @param lease lease for which the parameters are desired. ++ /// ++ /// @return PingCheckConfig reference containing the current configuration. ++ const PingCheckConfigPtr getScopedConfig(dhcp::Lease4Ptr& lease); ++ ++ /// @brief Get the hook I/O service. ++ /// ++ /// @return the hook I/O service. ++ isc::asiolink::IOServicePtr getIOService() { ++ return (io_service_); ++ } ++ ++ /// @brief Set the hook I/O service. ++ /// ++ /// @param io_service the hook I/O service. ++ void setIOService(isc::asiolink::IOServicePtr io_service) { ++ io_service_ = io_service; ++ } ++ ++protected: ++ ++ /// @brief The hook I/O service. ++ isc::asiolink::IOServicePtr io_service_; ++ ++ /// @brief Thread pool used when running multi-threaded. ++ asiolink::IoServiceThreadPoolPtr thread_pool_; ++ ++ /// @brief In-memory store of PingContexts. ++ PingContextStorePtr store_; ++ ++ /// @brief Channel that conducts ICMP messaging. ++ PingChannelPtr channel_; ++ ++ /// @brief Warehouses parsed global and subnet configuration. ++ ConfigCachePtr config_cache_; ++ ++ /// @brief Tracks whether or not the server is processing DHCP packets. ++ dhcp::NetworkStatePtr network_state_; ++ ++ /// @brief TimeStamp of the next expiration event. ++ TimeStamp next_expiry_; ++ ++ /// @brief Timer which tracks the next expiration event. ++ asiolink::IntervalTimerPtr expiration_timer_; ++ ++ /// @brief The mutex used to protect internal state. ++ const boost::scoped_ptr<std::mutex> mutex_; ++ ++ /// @brief Indicates whether or not operations have been suspended. ++ bool suspended_; ++}; ++ ++/// @brief Defines a shared pointer to a PingCheckMgr. ++typedef boost::shared_ptr<PingCheckMgr> PingCheckMgrPtr; ++ ++} // end of namespace ping_check ++} // end of namespace isc ++ ++#endif +diff --git a/src/hooks/dhcp/ping_check/ping_context.cc b/src/hooks/dhcp/ping_check/ping_context.cc +new file mode 100644 +index 0000000000..45e896f948 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_context.cc +@@ -0,0 +1,237 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++ ++#include <ping_context.h> ++#include <ping_check_log.h> ++#include <exceptions/exceptions.h> ++#include <util/chrono_time_utils.h> ++#include <iostream> ++ ++using namespace std; ++using namespace isc; ++using namespace isc::asiolink; ++using namespace isc::dhcp; ++using namespace isc::hooks; ++using namespace std::chrono; ++ ++namespace isc { ++namespace ping_check { ++ ++PingContext::PingContext(Lease4Ptr& lease, Pkt4Ptr& query, ++ uint32_t min_echos /* = 1 */, ++ uint32_t reply_timeout /* = 100 */, ++ ParkingLotHandlePtr& parking_lot /* = EMPTY_LOT() */) ++ : min_echos_(min_echos), ++ reply_timeout_(reply_timeout), ++ echos_sent_(0), ++ last_echo_sent_time_(EMPTY_TIME()), ++ send_wait_start_(EMPTY_TIME()), ++ next_expiry_(EMPTY_TIME()), ++ created_time_(PingContext::now()), ++ lease_(lease), ++ query_(query), ++ state_(NEW), ++ parking_lot_(parking_lot) { ++ if (!lease_) { ++ isc_throw(BadValue, "PingContext ctor - lease cannot be empty"); ++ } ++ ++ if (!query_) { ++ isc_throw(BadValue, "PingContext ctor - query cannot be empty"); ++ } ++ ++ if (getTarget() == IOAddress::IPV4_ZERO_ADDRESS()) { ++ isc_throw(BadValue, "PingContext ctor - target address cannot be 0.0.0.0"); ++ } ++ ++ if (min_echos_ == 0) { ++ isc_throw(BadValue, "PingContext ctor - min_echos must be greater than 0"); ++ } ++ ++ if (reply_timeout_ == 0) { ++ isc_throw(BadValue, "PingContext ctor - reply_timeout must be greater than 0"); ++ } ++} ++ ++PingContext::State ++PingContext::stringToState(const std::string& state_str) { ++ if (state_str == "NEW") { ++ return (NEW); ++ } ++ ++ if (state_str == "WAITING_TO_SEND") { ++ return (WAITING_TO_SEND); ++ } ++ ++ if (state_str == "SENDING") { ++ return (SENDING); ++ } ++ ++ if (state_str == "WAITING_FOR_REPLY") { ++ return (WAITING_FOR_REPLY); ++ } ++ ++ if (state_str == "TARGET_FREE") { ++ return (TARGET_FREE); ++ } ++ ++ if (state_str == "TARGET_IN_USE") { ++ return (TARGET_IN_USE); ++ } ++ ++ isc_throw(BadValue, "Invalid PingContext::State: '" << state_str << "'"); ++} ++ ++TimeStamp ++PingContext::now() { ++ return (time_point_cast<milliseconds>(std::chrono::system_clock::now())); ++} ++ ++std::string ++PingContext::stateToString(const PingContext::State& state) { ++ std::string label = ""; ++ switch (state) { ++ case NEW: ++ label = "NEW"; ++ break; ++ case WAITING_TO_SEND: ++ label = "WAITING_TO_SEND"; ++ break; ++ case SENDING: ++ label = "SENDING"; ++ break; ++ case WAITING_FOR_REPLY: ++ label = "WAITING_FOR_REPLY"; ++ break; ++ case TARGET_FREE: ++ label = "TARGET_FREE"; ++ break; ++ case TARGET_IN_USE: ++ label = "TARGET_IN_USE"; ++ break; ++ } ++ ++ return (label); ++} ++ ++const IOAddress& PingContext::getTarget() const { ++ return (lease_->addr_); ++} ++ ++uint32_t ++PingContext::getMinEchos() const { ++ return (min_echos_); ++} ++ ++void ++PingContext::setMinEchos(uint32_t value) { ++ min_echos_ = value; ++} ++ ++uint32_t ++PingContext::getReplyTimeout() const { ++ return (reply_timeout_); ++} ++ ++void ++PingContext::setReplyTimeout(uint32_t value) { ++ reply_timeout_ = value; ++} ++ ++uint32_t ++PingContext::getEchosSent() const { ++ return (echos_sent_); ++} ++ ++void ++PingContext::setEchosSent(uint32_t value) { ++ echos_sent_ = value; ++} ++ ++const TimeStamp& ++PingContext::getLastEchoSentTime() const { ++ return (last_echo_sent_time_); ++} ++ ++void ++PingContext::setLastEchoSentTime(const TimeStamp& value) { ++ last_echo_sent_time_ = value; ++} ++ ++const TimeStamp& ++PingContext::getSendWaitStart() const { ++ return (send_wait_start_); ++} ++ ++bool ++PingContext::isWaitingToSend() const { ++ return (state_ == WAITING_TO_SEND); ++} ++ ++void ++PingContext::setSendWaitStart(const TimeStamp& value) { ++ send_wait_start_ = value; ++} ++ ++const TimeStamp& ++PingContext::getNextExpiry() const { ++ return (next_expiry_); ++} ++ ++bool ++PingContext::isWaitingForReply() const { ++ return (state_ == WAITING_FOR_REPLY); ++} ++ ++void ++PingContext::setNextExpiry(const TimeStamp& value) { ++ next_expiry_ = value; ++} ++ ++const TimeStamp& ++PingContext::getCreatedTime() const { ++ return (created_time_); ++} ++ ++PingContext::State ++PingContext::getState() const { ++ return (state_); ++} ++ ++void ++PingContext::setState(const PingContext::State& value) { ++ state_ = value; ++} ++ ++Pkt4Ptr ++PingContext::getQuery() const { ++ return (query_); ++} ++ ++Lease4Ptr ++PingContext::getLease() const { ++ return (lease_); ++} ++ ++void ++PingContext::beginWaitingToSend(const TimeStamp& begin_time /* = now() */) { ++ state_ = WAITING_TO_SEND; ++ send_wait_start_ = begin_time; ++} ++ ++void ++PingContext::beginWaitingForReply(const TimeStamp& begin_time /* = now() */) { ++ ++echos_sent_; ++ last_echo_sent_time_ = begin_time; ++ next_expiry_ = begin_time + milliseconds(reply_timeout_); ++ state_ = WAITING_FOR_REPLY; ++} ++ ++} // end of namespace ping_check ++} // end of namespace isc ++ +diff --git a/src/hooks/dhcp/ping_check/ping_context.h b/src/hooks/dhcp/ping_check/ping_context.h +new file mode 100644 +index 0000000000..2c5b704a04 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_context.h +@@ -0,0 +1,280 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#ifndef PING_CONTEXT_H ++#define PING_CONTEXT_H ++ ++#include <dhcp/pkt4.h> ++#include <dhcpsrv/lease.h> ++#include <hooks/parking_lots.h> ++ ++#include <chrono> ++ ++namespace isc { ++namespace ping_check { ++ ++/// @brief Specifies the type for time stamps. ++using TimeStamp = std::chrono::time_point<std::chrono::system_clock>; ++ ++/// @brief Embodies the life cycle of a ping check test for a single address ++/// for a single DHCPDISCOVER. ++/// ++/// The class uses a state-model to direct the tasks needed to execute one ++/// or more ECHO REQUEST SEND/WAIT FOR REPLY cycles until the address is ++/// either deemed free to offer or in-use and should not be offered. The ++/// number of cycles conducted is dictated by the minimum number of echos ++/// (@c min_echos_) and whether or not either an ECHO REPLY or DESTINATION ++/// UNREACHABLE are received. ++class PingContext { ++public: ++ ++ /// @brief Defines PingContext life cycle states ++ enum State { ++ NEW, // Newly created ++ WAITING_TO_SEND, // Waiting to send next ECHO REQUEST ++ SENDING, // Next ECHO REQUEST is being sent ++ WAITING_FOR_REPLY, // ECHO REQUEST sent, Waiting for reply or timeout ++ TARGET_FREE, // Target has been deemed free to offer. ++ TARGET_IN_USE // Target has been deemed in-use, do not offer ++ }; ++ ++ /// @brief Converts a string to State ++ /// ++ /// @param state_str Upper case string label to convert ++ /// @return State value corresponding to the given string ++ /// ++ /// @throw BadValue if the string is not a valid state label ++ static State stringToState(const std::string& state_str); ++ ++ /// @brief Converts a State to a string ++ /// ++ /// @param state State to convert ++ /// @return string label corresponding to the given state ++ static std::string stateToString(const State& state); ++ ++ /// @brief Constructor ++ /// ++ /// @param lease pointer to the lease whose address needs to be checked ++ /// @param query DHCPDISCOVER that instigated the check ++ /// @param min_echos minimum number of ECHO REQUESTs sent without replies ++ /// received required to declare an address free to offer. Defaults to 1, ++ /// must be greater than zero. ++ /// @param reply_timeout maximum number of milliseconds to wait for an ++ /// ECHO REPLY after an ECHO REQUEST has been sent. Defaults to 100, ++ /// must be greater than 0. ++ /// @param parking_lot parking lot in which the query is parked. Defaults ++ /// to an empty pointer. ++ /// ++ /// @throw BadValue if either lease or query are empty, or if the lease ++ /// address is 0.0.0.0 ++ PingContext(isc::dhcp::Lease4Ptr& lease, isc::dhcp::Pkt4Ptr& query, ++ uint32_t min_echos = 1, uint32_t reply_timeout = 100, ++ isc::hooks::ParkingLotHandlePtr& parking_lot = EMPTY_LOT()); ++ ++ /// @brief Destructor ++ virtual ~PingContext() = default; ++ ++ /// @brief Fetches the current timestamp (UTC/milliseconds precision) ++ /// ++ /// @return current time as a TimeStamp ++ static TimeStamp now(); ++ ++ /// @brief Fetches an empty timestamp ++ /// ++ /// @return an empty TimeStamp ++ static const TimeStamp& EMPTY_TIME() { ++ static TimeStamp empty_time; ++ return (empty_time); ++ } ++ ++ /// @brief Fetches the minimum timestamp ++ /// ++ /// @return the minimum timestamp ++ static const TimeStamp& MIN_TIME() { ++ static TimeStamp min_time = std::chrono::system_clock::time_point::min(); ++ return (min_time); ++ } ++ ++ /// @brief Fetches an empty parking lot handle ++ /// ++ /// @return an empty ParkingLotHandlePtr ++ static hooks::ParkingLotHandlePtr& EMPTY_LOT() { ++ static hooks::ParkingLotHandlePtr empty_lot(0); ++ return (empty_lot); ++ } ++ ++ /// @brief Fetches the IP address that is under test. ++ /// ++ /// @return IP address as an IOAddress ++ const isc::asiolink::IOAddress& getTarget() const; ++ ++ /// @brief Fetches the minimum number of ECHO REQUESTs ++ /// ++ /// @return minimum number of echos as a uint32_t ++ uint32_t getMinEchos() const; ++ ++ /// @brief Sets the minimum number of ECHO REQUESTs ++ /// ++ /// @param value new value, must be greater than 0 ++ /// ++ /// @throw BadValue if the given value is 0 ++ void setMinEchos(uint32_t value); ++ ++ /// @brief Fetches the reply timeout (milliseconds) ++ /// ++ /// @return reply timeout as a unit32_t ++ uint32_t getReplyTimeout() const; ++ ++ /// @brief Sets the reply timeout ++ /// ++ /// @param value new value in milliseconds, must be greater than 0 ++ /// ++ /// @throw BadValue if the given value is 0. ++ void setReplyTimeout(uint32_t value); ++ ++ /// @brief Fetches the number of ECHO REQUESTs sent. ++ /// ++ /// @return number of echos sent as a unit32_t ++ uint32_t getEchosSent() const; ++ ++ /// @brief Sets the number of ECHO REQUESTs sent. ++ /// ++ /// @param value new value ++ void setEchosSent(uint32_t value); ++ ++ /// @brief Fetches the timestamp of when the most recent ECHO REQUEST ++ /// was sent ++ /// ++ /// @return time the last echo was sent as a TimeStamp ++ const TimeStamp& getLastEchoSentTime() const; ++ ++ /// @brief Sets the timestamp the most recent ECHO REQUEST was sent ++ /// ++ /// @param value new value ++ void setLastEchoSentTime(const TimeStamp& value); ++ ++ /// @brief Fetches the time the context went into WAITING_TO_SEND state ++ /// ++ /// The value returned is only meaningful when the context state is WAITING_TO_SEND. ++ /// ++ /// @return send waits start time as a TimeStamp ++ const TimeStamp& getSendWaitStart() const; ++ ++ /// @brief Sets the send wait start timestamp ++ /// ++ /// @param value new value ++ void setSendWaitStart(const TimeStamp& value); ++ ++ /// @brief Returns true if state is WAITING_TO_SEND ++ /// ++ /// @return True if the context is in WAITING_TO_SEND state ++ bool isWaitingToSend() const; ++ ++ /// @brief Fetches the time at which the WAITING_FOR_REPLY state expires(ed) ++ /// ++ /// The value returned is only meaningful when the context state is WAITING_FOR_REPLY. ++ /// ++ /// @return expiration ++ const TimeStamp& getNextExpiry() const; ++ ++ /// @brief Sets the timestamp which specifies the time at which the WAITING_FOR_REPLY state expires ++ /// @param value new value ++ void setNextExpiry(const TimeStamp& value); ++ ++ /// @brief Returns true if state is WAITING_FOR_REPLY ++ /// ++ /// @return True if the context is in WAITING_TO_REPLY state ++ bool isWaitingForReply() const; ++ ++ /// @brief Fetches the time at which the context was created ++ /// ++ /// @return creation time as a TimeStamp ++ const TimeStamp& getCreatedTime() const; ++ ++ /// @brief Fetches the current state. ++ /// ++ /// @return current state as PingContext::State ++ State getState() const; ++ ++ /// @brief Sets the state. ++ /// ++ /// @param value new state value ++ void setState(const State& value); ++ ++ /// @brief Returns the query that instigated this check ++ /// ++ /// @return query as a Pkt4Ptr ++ isc::dhcp::Pkt4Ptr getQuery() const; ++ ++ /// @brief Returns the candidate lease whose address is the target to check ++ /// ++ /// @return lease under test as a Lease4Ptr ++ isc::dhcp::Lease4Ptr getLease() const; ++ ++ /// @brief Enters WAITING_TO_SEND state ++ /// ++ /// @param begin_time timestamp of when the state began. Defaults to ++ /// time now. Provided for testing purposes. ++ void beginWaitingToSend(const TimeStamp& begin_time = PingContext::now()); ++ ++ /// @brief Enters WAITING_TO_REPLY state ++ /// ++ /// @param begin_time timestamp of when the state began. Defaults to ++ /// time now. Provided for testing purposes. ++ void beginWaitingForReply(const TimeStamp& begin_time = PingContext::now()); ++ ++ /// @brief Fetches the parking lot used for this context. ++ /// ++ /// @return Pointer to the parking lot handle or empty if parking is not ++ /// employed. ++ isc::hooks::ParkingLotHandlePtr getParkingLot() { ++ return (parking_lot_); ++ }; ++ ++private: ++ /// @brief Minimum number of echos to send without receiving a reply ++ /// before giving up ++ uint32_t min_echos_ = 0; ++ ++ /// @brief Amount of time (likely in ms) to wait for an echo reply ++ uint32_t reply_timeout_ = 0; ++ ++ /// @brief Number of echos sent since instantiation ++ uint32_t echos_sent_ = 0; ++ ++ /// @brief Timestamp the most recent echo send completed ++ TimeStamp last_echo_sent_time_; ++ ++ /// @brief Timestamp of entry into waiting_to_send ++ TimeStamp send_wait_start_; ++ ++ /// @brief Timestamp the most recent echo times out ++ TimeStamp next_expiry_; ++ ++ /// @brief Time context was created ++ TimeStamp created_time_; ++ ++ /// @brief Candidate lease to check ++ isc::dhcp::Lease4Ptr lease_; ++ ++ /// @brief DHCPDISCOVER packet that instigated this check. ++ isc::dhcp::Pkt4Ptr query_; ++ ++ /// @brief Current state of this context ++ State state_; ++ ++ /// @brief Parking lot where the associated query is parked. ++ /// If empty parking is not being employed. ++ isc::hooks::ParkingLotHandlePtr parking_lot_; ++}; ++ ++/// @brief Defines a shared pointer to a PingContext. ++typedef boost::shared_ptr<PingContext> PingContextPtr; ++ ++} // end of namespace ping_check ++} // end of namespace isc ++ ++#endif +diff --git a/src/hooks/dhcp/ping_check/ping_context_store.cc b/src/hooks/dhcp/ping_check/ping_context_store.cc +new file mode 100644 +index 0000000000..35712d5afe +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_context_store.cc +@@ -0,0 +1,144 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++ ++#include <ping_context_store.h> ++#include <util/multi_threading_mgr.h> ++ ++using namespace std; ++using namespace isc; ++using namespace isc::asiolink; ++using namespace isc::dhcp; ++using namespace isc::hooks; ++using namespace isc::util; ++using namespace std::chrono; ++ ++namespace isc { ++namespace ping_check { ++ ++PingContextPtr ++PingContextStore::addContext(Lease4Ptr& lease, Pkt4Ptr& query, ++ uint32_t min_echos, uint32_t reply_timeout, ++ ParkingLotHandlePtr& parking_lot) { ++ ++ MultiThreadingLock lock(*mutex_); ++ PingContextPtr context; ++ try { ++ context.reset(new PingContext(lease, query, min_echos, reply_timeout, parking_lot)); ++ } catch (const std::exception& ex) { ++ isc_throw(BadValue, "PingContextStore::addContext failed: " << ex.what()); ++ } ++ ++ context->beginWaitingToSend(); ++ auto ret = pings_.insert(context); ++ if (ret.second == false) { ++ isc_throw(DuplicateContext, "PingContextStore::addContex: context already exists for: " ++ << lease->addr_); ++ } ++ ++ return (context); ++} ++ ++void ++PingContextStore::updateContext(const PingContextPtr& context) { ++ MultiThreadingLock lock(*mutex_); ++ auto& index = pings_.get<AddressIndexTag>(); ++ auto context_iter = index.find(context->getTarget()); ++ if (context_iter == index.end()) { ++ isc_throw(InvalidOperation, "PingContextStore::updateContext failed for address: " ++ << context->getTarget() << ", not in store"); ++ } ++ ++ // Use replace() to re-index contexts. ++ index.replace(context_iter, PingContextPtr(new PingContext(*context))); ++} ++ ++void ++PingContextStore::deleteContext(const PingContextPtr& context) { ++ MultiThreadingLock lock(*mutex_); ++ auto& index = pings_.get<AddressIndexTag>(); ++ auto context_iter = index.find(context->getTarget()); ++ if (context_iter == index.end()) { ++ // Not there, just return. ++ return; ++ } ++ ++ // Remove the context from the store. ++ pings_.erase(context_iter); ++} ++ ++PingContextPtr ++PingContextStore::getContextByAddress(const IOAddress& address) { ++ MultiThreadingLock lock(*mutex_); ++ auto const& index = pings_.get<AddressIndexTag>(); ++ auto context_iter = index.find(address); ++ return (context_iter == index.end() ? PingContextPtr() ++ : PingContextPtr(new PingContext(**context_iter))); ++} ++ ++PingContextPtr ++PingContextStore::getContextByQuery(Pkt4Ptr& query) { ++ MultiThreadingLock lock(*mutex_); ++ auto const& index = pings_.get<QueryIndexTag>(); ++ auto context_iter = index.find(query); ++ return (context_iter == index.end() ? PingContextPtr() ++ : PingContextPtr(new PingContext(**context_iter))); ++} ++ ++PingContextPtr ++PingContextStore::getNextToSend() { ++ MultiThreadingLock lock(*mutex_); ++ auto const& index = pings_.get<NextToSendIndexTag>(); ++ auto context_iter = index.lower_bound(boost::make_tuple(true, PingContext::MIN_TIME())); ++ return (context_iter == index.end() ? PingContextPtr() ++ : PingContextPtr(new PingContext(**context_iter))); ++} ++ ++PingContextPtr ++PingContextStore::getExpiresNext() { ++ MultiThreadingLock lock(*mutex_); ++ auto const& index = pings_.get<ExpirationIndexTag>(); ++ auto context_iter = index.lower_bound(boost::make_tuple(true, PingContext::now() + milliseconds(1))); ++ return (context_iter == index.end() ? PingContextPtr() ++ : PingContextPtr(new PingContext(**context_iter))); ++} ++ ++PingContextCollectionPtr ++PingContextStore::getExpiredSince(const TimeStamp& since) { ++ MultiThreadingLock lock(*mutex_); ++ auto const& index = pings_.get<ExpirationIndexTag>(); ++ auto lower_limit = index.lower_bound(boost::make_tuple(true, PingContext::MIN_TIME())); ++ auto upper_limit = index.upper_bound(boost::make_tuple(true, since)); ++ ++ PingContextCollectionPtr collection(new PingContextCollection()); ++ for (auto context_iter = lower_limit; context_iter != upper_limit; ++context_iter) { ++ PingContextPtr context(new PingContext(**context_iter)); ++ collection->push_back(context); ++ } ++ ++ return (collection); ++} ++ ++PingContextCollectionPtr ++PingContextStore::getAll() { ++ MultiThreadingLock lock(*mutex_); ++ auto const& index = pings_.get<AddressIndexTag>(); ++ PingContextCollectionPtr collection(new PingContextCollection()); ++ for (auto const& context_iter : index) { ++ collection->push_back(PingContextPtr(new PingContext(*context_iter))); ++ } ++ ++ return (collection); ++} ++ ++void PingContextStore::clear() { ++ MultiThreadingLock lock(*mutex_); ++ pings_.clear(); ++} ++ ++} // end of namespace ping_check ++} // end of namespace isc +diff --git a/src/hooks/dhcp/ping_check/ping_context_store.h b/src/hooks/dhcp/ping_check/ping_context_store.h +new file mode 100644 +index 0000000000..3a7664bfca +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/ping_context_store.h +@@ -0,0 +1,240 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#ifndef PING_CONTEXT_STORE_H ++#define PING_CONTEXT_STORE_H ++ ++#include <asiolink/io_address.h> ++#include <ping_context.h> ++ ++#include <boost/multi_index/indexed_by.hpp> ++#include <boost/multi_index/member.hpp> ++#include <boost/multi_index/mem_fun.hpp> ++#include <boost/multi_index/ordered_index.hpp> ++#include <boost/multi_index_container.hpp> ++#include <boost/multi_index/composite_key.hpp> ++#include <boost/scoped_ptr.hpp> ++ ++#include <mutex> ++#include <vector> ++ ++namespace isc { ++namespace ping_check { ++ ++/// @brief Exception thrown when an attempt was made to add a duplicate context ++class DuplicateContext : public Exception { ++public: ++ DuplicateContext(const char* file, size_t line, const char* what) : ++ isc::Exception(file, line, what) {} ++}; ++ ++/// @brief Tag for index by target address. ++struct AddressIndexTag { }; ++ ++/// @brief Tag for index by the query packet. ++struct QueryIndexTag { }; ++ ++/// @brief Tag for index by send wait start time. ++struct NextToSendIndexTag { }; ++ ++/// @brief Tag for index by expiration time. ++struct ExpirationIndexTag { }; ++ ++/// @brief Tag for index by state. ++struct StateIndexTag { }; ++ ++/// @brief A multi index container holding pointers to PingContexts. ++/// ++/// The contexts in the container may be accessed using different indexes: ++/// - using an IPv4 address, ++/// - using a query packet ++/// - using a send wait start time ++/// - using an expiration time ++/// - using a context state ++/// ++/// Indexes can be accessed using the index number (from 0 to 2) or a ++/// name tag. It is recommended to use the tags to access indexes as ++/// they do not depend on the order of indexes in the container. ++typedef boost::multi_index_container< ++ // It holds pointers to Lease6 objects. ++ PingContextPtr, ++ boost::multi_index::indexed_by< ++ // Specification of the first index starts here. ++ // This index sorts PingContexts by IPv4 addresses represented as ++ // IOAddress objects. ++ /// @todo Does it need to be ordered or only unique? ++ boost::multi_index::ordered_unique< ++ boost::multi_index::tag<AddressIndexTag>, ++ boost::multi_index::const_mem_fun<PingContext, const isc::asiolink::IOAddress&, ++ &PingContext::getTarget> ++ >, ++ ++ // Specification of the second index starts here. ++ // This index sorts contexts by query. ++ boost::multi_index::ordered_unique< ++ boost::multi_index::tag<QueryIndexTag>, ++ boost::multi_index::const_mem_fun<PingContext, isc::dhcp::Pkt4Ptr, ++ &PingContext::getQuery> ++ >, ++ ++ // Specification of the third index starts here. ++ // This index sorts contexts by send_wait_start. ++ boost::multi_index::ordered_non_unique< ++ boost::multi_index::tag<NextToSendIndexTag>, ++ boost::multi_index::composite_key< ++ PingContext, ++ // The boolean value specifying if context is waiting to send ++ boost::multi_index::const_mem_fun<PingContext, bool, ++ &PingContext::isWaitingToSend>, ++ // Context expiration time. ++ boost::multi_index::const_mem_fun<PingContext, const TimeStamp&, ++ &PingContext::getSendWaitStart> ++ > ++ >, ++ ++ // Specification of the fourth index starts here. ++ // This index sorts contexts by next_expiry. ++ boost::multi_index::ordered_non_unique< ++ boost::multi_index::tag<ExpirationIndexTag>, ++ boost::multi_index::composite_key< ++ PingContext, ++ // The boolean value specifying if context is waiting for a reply ++ boost::multi_index::const_mem_fun<PingContext, bool, ++ &PingContext::isWaitingForReply>, ++ // Context expiration time. ++ boost::multi_index::const_mem_fun<PingContext, const TimeStamp&, ++ &PingContext::getNextExpiry> ++ > ++ >, ++ ++ // Specification of the fifth index starts here. ++ // This index sorts contexts by State. ++ boost::multi_index::ordered_non_unique< ++ boost::multi_index::tag<StateIndexTag>, ++ boost::multi_index::const_mem_fun<PingContext, PingContext::State, ++ &PingContext::getState> ++ > ++ > ++> PingContextContainer; ++ ++/// @brief Type for a collection of PingContextPtrs. ++typedef std::vector<PingContextPtr> PingContextCollection; ++/// @brief Type for a pointer to a collection of PingContextPtrs. ++typedef boost::shared_ptr<PingContextCollection> PingContextCollectionPtr; ++ ++/// @brief Maintains an in-memory store of PingContexts ++/// ++/// Provides essential CRUD functions for managing a collection of ++/// PingContexts. Additionally there are finders that can return ++/// contexts by target IP address, instigating query, WAITING_TO_SEND ++/// start time, WAITING_FOR_REPLY expiration time, and context state. ++/// All finders return copies of the contexts found, rather than the ++/// stored context itself. ++class PingContextStore { ++public: ++ ++ /// @brief Constructor ++ PingContextStore() : pings_(), mutex_(new std::mutex) { ++ } ++ ++ /// @brief Destructor ++ ~PingContextStore() = default; ++ ++ /// @brief Creates a new PingContext and adds it to the store ++ /// ++ /// @param lease lease whose address is to be ping checked ++ /// @param query query that instigated the lease ++ /// @param min_echos minimum number of ECHO REQUESTs sent without replies ++ /// received required to declare an address free to offer. Must be ++ /// greater than zero. ++ /// @param reply_timeout maximum number of milliseconds to wait for an ++ /// ECHO REPLY after an ECHO REQUEST has been sent. Must be greater than 0. ++ /// @param parking_lot parking lot in which query is parked. If empty, ++ /// parking is assumed to not be employed. ++ /// ++ /// @return pointer to the newly created context ++ /// @throw DuplicateContext is a context for the lease address already ++ /// exists in the store. ++ PingContextPtr addContext(isc::dhcp::Lease4Ptr& lease, ++ isc::dhcp::Pkt4Ptr& query, ++ uint32_t min_echos, ++ uint32_t reply_timeout, ++ isc::hooks::ParkingLotHandlePtr& parking_lot ++ = PingContext::EMPTY_LOT()); ++ ++ /// @brief Updates a context in the store. ++ /// ++ /// The context is assumed to already exist in the store. ++ /// ++ /// @param context context to update. ++ /// ++ /// @throw InvalidOperation if PingContext does not exist in the store. ++ void updateContext(const PingContextPtr& context); ++ ++ /// @brief Removes the context from the store. ++ /// ++ /// If the context does not exist in the store, it simply returns. ++ /// ++ /// @param context context to delete. ++ void deleteContext(const PingContextPtr& context); ++ ++ /// @brief Fetches the context with a given target address ++ /// ++ /// @param address target IP address for which to search ++ /// ++ /// @return pointer to the matching PingContext or an empty pointer if ++ /// not found. ++ PingContextPtr getContextByAddress(const isc::asiolink::IOAddress& address); ++ ++ /// @brief Fetches the context with a given query packet ++ /// ++ /// @param query query for which to search ++ /// ++ /// @return pointer to the matching PingContext or an empty pointer if ++ /// not found. ++ PingContextPtr getContextByQuery(isc::dhcp::Pkt4Ptr& query); ++ ++ /// @brief Fetches the context in WAITING_TO_SEND with the oldest send wait ++ /// start time. ++ /// ++ /// @return pointer to the matching PingContext or an empty pointer if ++ /// not found. ++ PingContextPtr getNextToSend(); ++ ++ /// @brief Fetches the context in WAITING_FOR_REPLY with the oldest expiration ++ /// time that has not already passed (i.e. is still in the future) ++ /// ++ /// @return pointer to the matching PingContext or an empty pointer if ++ /// not found. ++ PingContextPtr getExpiresNext(); ++ ++ /// @brief Fetches the contexts in WAITING_FOR_REPLY that expired since a given time ++ /// ++ /// @param since timestamp to search by. Defaults to current time. ++ /// ++ /// @return a collection of the matching contexts, ordered by expiration time. ++ PingContextCollectionPtr getExpiredSince(const TimeStamp& since = PingContext::now()); ++ ++ /// @brief Fetches all of the contexts (in order by target) ++ /// ++ /// @return a collection of all contexts in the store. ++ PingContextCollectionPtr getAll(); ++ ++ /// @brief Removes all contexts from the store. ++ void clear(); ++ ++private: ++ /// @brief Container instance. ++ PingContextContainer pings_; ++ ++ /// @brief The mutex used to protect internal state. ++ const boost::scoped_ptr<std::mutex> mutex_; ++}; ++ ++} // end of namespace ping_check ++} // end of namespace isc ++ ++#endif +diff --git a/src/hooks/dhcp/ping_check/tests/.gitignore b/src/hooks/dhcp/ping_check/tests/.gitignore +new file mode 100644 +index 0000000000..7e12f9e5be +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/.gitignore +@@ -0,0 +1 @@ ++ping_check_unittests +diff --git a/src/hooks/dhcp/ping_check/tests/Makefile.am b/src/hooks/dhcp/ping_check/tests/Makefile.am +new file mode 100644 +index 0000000000..a8c2ea4d92 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/Makefile.am +@@ -0,0 +1,70 @@ ++SUBDIRS = . ++ ++AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib ++AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/ping_check -I$(top_srcdir)/src/hooks/dhcp/ping_check ++AM_CPPFLAGS += $(BOOST_INCLUDES) $(CRYPTO_CFLAGS) $(CRYPTO_INCLUDES) ++AM_CPPFLAGS += -DPING_CHECK_LIB_SO=\"$(abs_top_builddir)/src/hooks/dhcp/ping_check/.libs/libdhcp_ping_check.so\" ++AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\" ++ ++AM_CXXFLAGS = $(KEA_CXXFLAGS) ++ ++if USE_STATIC_LINK ++AM_LDFLAGS = -static ++endif ++ ++# Unit test data files need to get installed. ++EXTRA_DIST = ++ ++CLEANFILES = *.gcno *.gcda ++ ++TESTS_ENVIRONMENT = $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND) ++ ++LOG_COMPILER = $(LIBTOOL) ++AM_LOG_FLAGS = --mode=execute ++ ++TESTS = ++if HAVE_GTEST ++TESTS += ping_check_unittests ++ ++ping_check_unittests_SOURCES = run_unittests.cc ++ping_check_unittests_SOURCES += icmp_endpoint_unittests.cc ++ping_check_unittests_SOURCES += icmp_socket_unittests.cc ++ping_check_unittests_SOURCES += ping_context_unittests.cc ++ping_check_unittests_SOURCES += ping_context_store_unittests.cc ++ping_check_unittests_SOURCES += icmp_msg_unittests.cc ++ping_check_unittests_SOURCES += ping_test_utils.h ++ping_check_unittests_SOURCES += ping_channel_unittests.cc ++ping_check_unittests_SOURCES += ping_check_mgr_unittests.cc ++ping_check_unittests_SOURCES += ping_check_config_unittests.cc ++ping_check_unittests_SOURCES += config_cache_unittests.cc ++ ++ping_check_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES) ++ ++ping_check_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS) ++ ++ping_check_unittests_CXXFLAGS = $(AM_CXXFLAGS) ++ ++ping_check_unittests_LDADD = $(top_builddir)/src/hooks/dhcp/ping_check/libping_check.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/http/libkea-http.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/database/libkea-database.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la ++ping_check_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la ++ping_check_unittests_LDADD += $(LOG4CPLUS_LIBS) ++ping_check_unittests_LDADD += $(CRYPTO_LIBS) ++ping_check_unittests_LDADD += $(BOOST_LIBS) ++ping_check_unittests_LDADD += $(GTEST_LDADD) ++endif ++noinst_PROGRAMS = $(TESTS) +diff --git a/src/hooks/dhcp/ping_check/tests/config_cache_unittests.cc b/src/hooks/dhcp/ping_check/tests/config_cache_unittests.cc +new file mode 100644 +index 0000000000..f4e48d6591 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/config_cache_unittests.cc +@@ -0,0 +1,245 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++/// @file This file contains tests which verify the subnet ping-check ++/// configuration cache. ++ ++#include <config.h> ++#include <config_cache.h> ++#include <dhcpsrv/cfgmgr.h> ++#include <hooks/callout_manager.h> ++#include <hooks/hooks.h> ++#include <testutils/gtest_utils.h> ++#include <testutils/multi_threading_utils.h> ++ ++#include <boost/date_time/posix_time/posix_time.hpp> ++#include <gtest/gtest.h> ++#include <sstream> ++ ++using namespace std; ++using namespace isc; ++using namespace isc::data; ++using namespace isc::dhcp; ++using namespace isc::hooks; ++using namespace isc::ping_check; ++using namespace isc::test; ++using namespace boost::posix_time; ++ ++namespace { ++ ++/// @brief ConfigCache derivation that allows flush time to be modified. ++class TestConfigCache : public ConfigCache { ++public: ++ /// @brief Constructor ++ TestConfigCache() { ++ } ++ ++ /// @brief Destructor ++ virtual ~TestConfigCache() { ++ } ++ ++ /// @brief Adjusts the last flush time by the given amount. ++ /// ++ /// @param offset signed value in seconds to add to cache's last ++ /// flush time value ++ void tweakLastFlushTime(int offset) { ++ setModificationTime(getLastFlushTime() + seconds(offset)); ++ } ++}; ++ ++/// @brief Test fixture for testing ConfigCache. ++class ConfigCacheTest : public ::testing::Test { ++public: ++ /// @brief Constructor ++ ConfigCacheTest() { ++ isc::util::MultiThreadingMgr::instance().setMode(false); ++ } ++ ++ /// @brief Destructor ++ virtual ~ConfigCacheTest() { ++ } ++ ++ /// @brief Verifies construction of a ConfigCache. ++ void testConstruction() { ++ // We use a BaseStampedElement to get the current time to ensure we ++ // are using the same time perspective (currently local) as StampedElements do. ++ BaseStampedElement now; ++ ptime start_time = now.getModificationTime(); ++ ++ // Create a new cache. ++ TestConfigCache configs; ++ EXPECT_EQ(configs.size(), 0); ++ ++ // Verify that last_flush_time_ has been set and that the ++ // cache has no entries. ++ ptime last_flush_time = configs.getLastFlushTime(); ++ EXPECT_GE(last_flush_time, start_time); ++ ++ // Verify that looking for an entry in an empty cache ++ // gracefully finds nothing. ++ PingCheckConfigPtr fetched_config; ++ EXPECT_FALSE(configs.findConfig(999, fetched_config)); ++ EXPECT_FALSE(fetched_config); ++ } ++ ++ /// @brief Verifies that invalid user-context config is rejected gracefully. ++ void testInvalidConfig() { ++ // Create a new cache. ++ TestConfigCache configs; ++ EXPECT_EQ(configs.size(), 0); ++ ++ // An invalid keyword should fail. ++ std::string json = ++ R"({ ++ "ping-check" : { ++ "bogus" : 777 ++ } ++ })"; ++ ++ ConstElementPtr user_context; ++ ASSERT_NO_THROW_LOG(user_context = Element::fromJSON(json)); ++ ++ ASSERT_THROW_MSG(configs.parseAndCacheConfig(1, user_context), DhcpConfigError, ++ "spurious 'bogus' parameter"); ++ ++ EXPECT_EQ(configs.size(), 0); ++ } ++ ++ /// @brief Verifies that valid user-context supplied config are cached correctly. ++ void testValidConfig() { ++ // Create a new cache. ++ TestConfigCache configs; ++ EXPECT_EQ(configs.size(), 0); ++ ++ // A valid config should get cached. ++ std::string json = ++ R"({ ++ "ping-check" : { ++ "enable-ping-check" : false, ++ "min-ping-requests" : 2, ++ "reply-timeout" : 375, ++ "ping-cltt-secs" : 120, ++ "ping-channel-threads" : 6 ++ } ++ })"; ++ ++ ConstElementPtr user_context; ++ ASSERT_NO_THROW_LOG(user_context = Element::fromJSON(json)); ++ ++ // Verify that we cache a valid config. ++ PingCheckConfigPtr config; ++ ASSERT_NO_THROW_LOG(config = configs.parseAndCacheConfig(1, user_context)); ++ ASSERT_TRUE(config); ++ EXPECT_EQ(configs.size(), 1); ++ ++ // Verify we can retrieve the cached config. ++ PingCheckConfigPtr fetched_config; ++ ASSERT_TRUE(configs.findConfig(1, fetched_config)); ++ EXPECT_EQ(fetched_config, config); ++ } ++ ++ /// @brief Verifies that an empty config pointer can be cached. ++ void testConfigCacheEmptyConfig() { ++ // Create a new cache. ++ TestConfigCache configs; ++ EXPECT_EQ(configs.size(), 0); ++ ++ // Verify that we can cache an empty config pointer. ++ PingCheckConfigPtr no_config; ++ ASSERT_NO_THROW_LOG(configs.cacheConfig(1, no_config)); ++ EXPECT_EQ(configs.size(), 1); ++ ++ // Verify we can retrieve the cached empty config pointer. ++ PingCheckConfigPtr fetched_config; ++ ASSERT_TRUE(configs.findConfig(1, fetched_config)); ++ ASSERT_FALSE(fetched_config); ++ } ++ ++ /// @brief Verifies that the cache can be cleared correctly. ++ void testFlushCache() { ++ // Create a new cache. ++ TestConfigCache configs; ++ EXPECT_EQ(configs.size(), 0); ++ ++ ptime last_flush_time = configs.getLastFlushTime(); ++ ++ // Now let's wind the clock back on last_flush_time. ++ configs.tweakLastFlushTime(-1000); ++ EXPECT_LT(configs.getLastFlushTime(), last_flush_time); ++ last_flush_time = configs.getLastFlushTime(); ++ ++ // Make a simple valid config. ++ std::string json = ++ R"({ ++ "ping-check": { ++ "enable-ping-check" : true ++ } ++ })"; ++ ++ ConstElementPtr user_context; ++ ASSERT_NO_THROW_LOG(user_context = Element::fromJSON(json)); ++ ++ for (int id = 1; id < 5; ++id) { ++ PingCheckConfigPtr config; ++ ASSERT_NO_THROW_LOG(config = configs.parseAndCacheConfig(id, user_context)); ++ ASSERT_TRUE(config); ++ EXPECT_EQ(configs.size(), id); ++ } ++ ++ // Verify we can explicitly clear the cache. Should be no entries ++ // and last_flush_time should be updated. ++ configs.flush(); ++ EXPECT_GT(configs.getLastFlushTime(), last_flush_time); ++ EXPECT_EQ(configs.size(), 0); ++ } ++}; ++ ++TEST_F(ConfigCacheTest, construction) { ++ testConstruction(); ++} ++ ++TEST_F(ConfigCacheTest, constructionMultiThreading) { ++ MultiThreadingTest mt; ++ testConstruction(); ++} ++ ++TEST_F(ConfigCacheTest, invalidConfig) { ++ testInvalidConfig(); ++} ++ ++TEST_F(ConfigCacheTest, invalidConfigMultiThreading) { ++ MultiThreadingTest mt; ++ testInvalidConfig(); ++} ++ ++TEST_F(ConfigCacheTest, validConfig) { ++ testValidConfig(); ++} ++ ++TEST_F(ConfigCacheTest, validConfigMultiThreading) { ++ MultiThreadingTest mt; ++ testValidConfig(); ++} ++ ++TEST_F(ConfigCacheTest, configCacheEmptyConfig) { ++ testConfigCacheEmptyConfig(); ++} ++ ++TEST_F(ConfigCacheTest, configCacheEmptyConfigMultiThreading) { ++ MultiThreadingTest mt; ++ testConfigCacheEmptyConfig(); ++} ++ ++TEST_F(ConfigCacheTest, flushCache) { ++ testFlushCache(); ++} ++ ++TEST_F(ConfigCacheTest, flushCacheMultiThreading) { ++ MultiThreadingTest mt; ++ testFlushCache(); ++} ++ ++} // end of anonymous namespace +diff --git a/src/hooks/dhcp/ping_check/tests/icmp_endpoint_unittests.cc b/src/hooks/dhcp/ping_check/tests/icmp_endpoint_unittests.cc +new file mode 100644 +index 0000000000..e9ed8dcb9b +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/icmp_endpoint_unittests.cc +@@ -0,0 +1,44 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++#include <asiolink/asio_wrapper.h> ++#include <asiolink/io_address.h> ++#include <icmp_endpoint.h> ++ ++#include <gtest/gtest.h> ++ ++#include <string> ++ ++using namespace isc::asiolink; ++using namespace isc::ping_check; ++using namespace std; ++ ++// This test checks that the endpoint can manage its own internal ++// boost::asio::ip::icmp::endpoint object for IPv4. ++TEST(ICMPEndpointTest, v4Address) { ++ const string test_address("192.0.2.1"); ++ ++ IOAddress address(test_address); ++ ICMPEndpoint endpoint(address); ++ ++ EXPECT_TRUE(address == endpoint.getAddress()); ++ EXPECT_EQ(static_cast<short>(IPPROTO_ICMP), endpoint.getProtocol()); ++ EXPECT_EQ(AF_INET, endpoint.getFamily()); ++} ++ ++// This test checks that the endpoint can manage its own internal ++// boost::asio::ip::icmp::endpoint object for IPv6. ++TEST(ICMPEndpointTest, v6Address) { ++ const string test_address("2001:db8::1235"); ++ ++ IOAddress address(test_address); ++ ICMPEndpoint endpoint(address); ++ ++ EXPECT_TRUE(address == endpoint.getAddress()); ++ EXPECT_EQ(static_cast<short>(IPPROTO_ICMPV6), endpoint.getProtocol()); ++ EXPECT_EQ(AF_INET6, endpoint.getFamily()); ++} +diff --git a/src/hooks/dhcp/ping_check/tests/icmp_msg_unittests.cc b/src/hooks/dhcp/ping_check/tests/icmp_msg_unittests.cc +new file mode 100644 +index 0000000000..36c7056840 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/icmp_msg_unittests.cc +@@ -0,0 +1,172 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++/// @file This file contains tests which exercise the ICMPMsg class. ++ ++#include <config.h> ++#include <icmp_msg.h> ++#include <asiolink/io_address.h> ++#include <testutils/gtest_utils.h> ++#include <util/str.h> ++ ++#include <gtest/gtest.h> ++#include <list> ++ ++using namespace std; ++using namespace isc; ++using namespace isc::asiolink; ++using namespace isc::ping_check; ++ ++namespace { ++ ++// Verifies accessors. ++TEST(ICMPMsgTest, basics) { ++ ICMPMsgPtr msg(new ICMPMsg()); ++ ++ msg->setType(ICMPMsg::ECHO_REPLY); ++ EXPECT_EQ(ICMPMsg::ECHO_REPLY, msg->getType()); ++ ++ msg->setCode(77); ++ EXPECT_EQ(77, msg->getCode()); ++ ++ msg->setChecksum(0x8899); ++ EXPECT_EQ(0x8899, msg->getChecksum()); ++ ++ msg->setId(0x1122); ++ EXPECT_EQ(0x1122, msg->getId()); ++ ++ msg->setSequence(0x3344); ++ EXPECT_EQ(0x3344, msg->getSequence()); ++ ++ msg->setSource(IOAddress("192.0.2.1")); ++ EXPECT_EQ(IOAddress("192.0.2.1"), msg->getSource()); ++ ++ msg->setDestination(IOAddress("192.0.2.2")); ++ EXPECT_EQ(IOAddress("192.0.2.2"), msg->getDestination()); ++ ++ std::vector<uint8_t> payload{ 0x55, 0x66, 0x77, 0x88, 0x99 }; ++ msg->setPayload(payload.data(), payload.size()); ++ EXPECT_EQ(payload, msg->getPayload()); ++} ++ ++// Verifies that a valid ECHO REPLY message can be unpacked. ++TEST(ICMPMsgTest, unpackValidEchoReply) { ++ // Create wire data for a valid ECHO REPLY. ++ std::string echo_reply = ++ "45:00:00:30:73:8a:00:00:40:01:a0:ff:b2:10:01:19:b2:10:01:0a:" ++ "00:00:33:11:55:66:77:88:" ++ "00:00:00:00:00:00:00:00:" ++ "00:00:00:00:00:00:00:00:" ++ "00:00:00:00"; ++ ++ std::vector<uint8_t> wire_data; ++ ASSERT_NO_THROW_LOG(util::str::decodeSeparatedHexString(echo_reply, ":", wire_data)); ++ ++ // Unpack the wire data. ++ ICMPMsgPtr msg; ++ ASSERT_NO_THROW_LOG(msg = ICMPMsg::unpack(wire_data.data(), wire_data.size())); ++ ASSERT_TRUE(msg); ++ ++ // Verify the reply contents. ++ EXPECT_EQ(ICMPMsg::ECHO_REPLY, msg->getType()); ++ EXPECT_EQ(0, msg->getCode()); ++ EXPECT_EQ(0x3311, msg->getChecksum()); ++ EXPECT_EQ(0x5566, msg->getId()); ++ EXPECT_EQ(0x7788, msg->getSequence()); ++ EXPECT_EQ(IOAddress("178.16.1.25"), msg->getSource()); ++ EXPECT_EQ(IOAddress("178.16.1.10"), msg->getDestination()); ++ ++ std::vector<uint8_t> payload{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; ++ EXPECT_EQ(payload, msg->getPayload()); ++} ++ ++// Verifies that a valid DESTINATION UNREACHABLE message can be unpacked. ++TEST(ICMPMsgTest, unpackValidUnreachable) { ++ // Valid destination unreachable message. Payload is the original ++ // ECHO request. ++ std::string unreachable = ++ "45:c0:00:4c:31:b3:00:00:40:01:e2:09:b2:10:01:0a:b2:10:01:0a:" ++ "03:01:fc:fe:00:00:00:00:" ++ "45:00:00:30:e3:e2:40:00:40:01:f0:5c:" ++ "b2:10:01:0a:b2:10:01:63:08:00:2b:11:" ++ "55:66:77:88:00:00:00:00:00:00:00:00:" ++ "00:00:00:00:00:00:00:00:00:00:00:00"; ++ ++ // Create the wire data. ++ std::vector<uint8_t> wire_data; ++ ASSERT_NO_THROW_LOG(util::str::decodeSeparatedHexString(unreachable, ":", wire_data)); ++ ++ // Unpack the outer message. ++ ICMPMsgPtr msg; ++ ASSERT_NO_THROW_LOG(msg = ICMPMsg::unpack(wire_data.data(), wire_data.size())); ++ ASSERT_TRUE(msg); ++ ++ // Verify its contents. ++ EXPECT_EQ(ICMPMsg::TARGET_UNREACHABLE, msg->getType()); ++ EXPECT_EQ(1, msg->getCode()); ++ EXPECT_EQ(0xfcfe, msg->getChecksum()); ++ EXPECT_EQ(0, msg->getId()); ++ EXPECT_EQ(0, msg->getSequence()); ++ EXPECT_EQ(IOAddress("178.16.1.10"), msg->getSource()); ++ EXPECT_EQ(IOAddress("178.16.1.10"), msg->getDestination()); ++ ++ // Now unpack the original ECHO from the outer message payload. ++ std::vector<uint8_t> payload(wire_data.begin() + 28, wire_data.end()); ++ EXPECT_EQ(payload, msg->getPayload()); ++ ++ ICMPMsgPtr payload_msg; ++ ASSERT_NO_THROW_LOG(payload_msg = ICMPMsg::unpack(payload.data(), payload.size())); ++ ASSERT_TRUE(payload_msg); ++ ++ // Verify the original ECHO contents. ++ EXPECT_EQ(ICMPMsg::ECHO_REQUEST, payload_msg->getType()); ++ EXPECT_EQ(0, payload_msg->getCode()); ++ EXPECT_EQ(0x2b11, payload_msg->getChecksum()); ++ EXPECT_EQ(0x5566, payload_msg->getId()); ++ EXPECT_EQ(0x7788, payload_msg->getSequence()); ++ EXPECT_EQ(IOAddress("178.16.1.10"), payload_msg->getSource()); ++ EXPECT_EQ(IOAddress("178.16.1.99"), payload_msg->getDestination()); ++} ++ ++// Verifies the malformed packets are detected. ++TEST(ICMPMsgTest, unpackInValidPackets) { ++ // Contains a test scenario. ++ struct Scenario { ++ // Wire data to submit to unpack. ++ std::string wire_data_; ++ // Expected exception message. ++ std::string error_msg_; ++ }; ++ ++ // List of scenarios to test. ++ std::list<Scenario> scenarios = { ++ { ++ // Truncated IP header ++ "45:c0:00:4c:31:b3:00:00:40:01:e2:09:b2", ++ "ICMPMsg::unpack - truncated ip header, length: 13" ++ }, ++ { ++ // Truncated packet ++ "45:c0:00:4c:31:b3:00:00:40:01:e2:09:b2:10:01:0a:b2:10:01:0a:" ++ "03:01:fc:fe:00:00:00:00:" ++ "45:00:00:30:e3:e2:40:00:40:01:f0:5c", ++ "ICMPMsg::truncated packet? length: 40, hlen: 20" ++ } ++ ++ }; ++ ++ // Iterate over scenarios. ++ for (auto const& scenario : scenarios) { ++ // Create the wire data. ++ std::vector<uint8_t> wire_data; ++ ASSERT_NO_THROW_LOG(util::str::decodeSeparatedHexString(scenario.wire_data_, ":", wire_data)); ++ ASSERT_THROW_MSG(ICMPMsg::unpack(wire_data.data(), wire_data.size()), BadValue, scenario.error_msg_); ++ } ++} ++ ++/// @todo YOU NEED some round trip tests that test packing! ++ ++} // end of anonymous namespace +diff --git a/src/hooks/dhcp/ping_check/tests/icmp_socket_unittests.cc b/src/hooks/dhcp/ping_check/tests/icmp_socket_unittests.cc +new file mode 100644 +index 0000000000..2394b360ca +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/icmp_socket_unittests.cc +@@ -0,0 +1,380 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++/// \brief Test of ICMPSocket ++/// ++/// Tests the functionality of a ICMPSocket by working through an open-send- ++/// receive-close sequence and checking that the asynchronous notifications ++/// work. ++ ++#include <config.h> ++#include <asiolink/asio_wrapper.h> ++#include <asiolink/interval_timer.h> ++#include <asiolink/io_address.h> ++#include <asiolink/io_service.h> ++#include <icmp_socket.h> ++#include <icmp_msg.h> ++#include <exceptions/exceptions.h> ++#include <util/buffer.h> ++#include <testutils/gtest_utils.h> ++ ++#include <boost/shared_ptr.hpp> ++#include <boost/enable_shared_from_this.hpp> ++#include <boost/date_time/posix_time/posix_time.hpp> ++#include <gtest/gtest.h> ++ ++#include <string> ++#include <arpa/inet.h> ++#include <netinet/in.h> ++#include <sys/types.h> ++#include <sys/socket.h> ++#include <algorithm> ++#include <cstdlib> ++#include <cstddef> ++#include <list> ++#include <vector> ++#include <unistd.h> ++ ++#include <netinet/ip.h> ++#include <netinet/ip_icmp.h> ++ ++using namespace isc; ++using namespace boost::asio; ++using namespace boost::posix_time; ++using namespace isc::asiolink; ++using namespace isc::ping_check; ++using namespace isc::util; ++using namespace std; ++ ++namespace ph = std::placeholders; ++ ++namespace { ++ ++/// @brief Test timeout (ms). ++const long TEST_TIMEOUT = 10000; ++ ++/// @brief Type of the function implementing a callback invoked by the ++/// @c SocketCallback functor. ++typedef std::function<void(boost::system::error_code ec, size_t length)> ++ SocketCallbackFunction; ++ ++/// @brief Callback class for socket IO operations ++/// ++/// An instance of this object is passed to the asynchronous I/O functions ++/// and the operator() method is called when when an asynchronous I/O ++/// completes. The arguments to the completion callback are stored for later ++/// retrieval. ++class SocketCallback { ++public: ++ ++ /// @brief Structure that houses callback invocation data. ++ struct PrivateData { ++ PrivateData() : ++ error_code_(), length_(0), called_(false), name_("") ++ {} ++ ++ boost::system::error_code error_code_; ///< Completion error code ++ size_t length_; ///< Number of bytes transferred ++ bool called_; ///< Set true when callback called ++ std::string name_; ///< Which of the objects this is ++ }; ++ ++ /// @brief Constructor ++ /// ++ /// Constructs the object. It also creates the data member pointed to by ++ /// a shared pointer. When used as a callback object, this is copied as it ++ /// is passed into the asynchronous function. This means that there are two ++ /// objects and inspecting the one we passed in does not tell us anything. ++ /// ++ /// Therefore we use a boost::shared_ptr. When the object is copied, the ++ /// shared pointer is copied, which leaves both objects pointing to the same ++ /// data. ++ /// ++ /// @param which Which of the two callback objects this is ++ explicit SocketCallback(const std::string& which) : data_(new PrivateData()) ++ { ++ setName(which); ++ } ++ ++ /// @brief Destructor ++ /// ++ /// No code needed, destroying the shared pointer destroys the private data. ++ virtual ~SocketCallback() ++ {} ++ ++ /// @brief Clears the current values of invocation data members. ++ void clear() { ++ setCode(0); ++ setLength(0); ++ setCalled(false); ++ } ++ ++ /// @brief Callback Function ++ /// ++ /// Called when an asynchronous I/O completes, this stores the ++ /// completion error code and the number of bytes transferred. ++ /// ++ /// @param ec I/O completion error code passed to callback function. ++ /// @param length Number of bytes transferred ++ virtual void operator()(boost::system::error_code ec, size_t length = 0) { ++ data_->error_code_ = ec; ++ setLength(length); ++ setCalled(true); ++ } ++ ++ /// @brief Get I/O completion error code ++ int getCode() { ++ return (data_->error_code_.value()); ++ } ++ ++ /// @brief Set I/O completion code ++ /// ++ /// @param code New value of completion code ++ void setCode(int code) { ++ data_->error_code_ = boost::system::error_code(code, boost::system::error_code().category()); ++ } ++ ++ /// @brief Get number of bytes transferred in I/O ++ size_t getLength() const { ++ return (data_->length_); ++ } ++ ++ /// @brief Set number of bytes transferred in I/O ++ /// ++ /// @param length New value of length parameter ++ void setLength(size_t length) { ++ data_->length_ = length; ++ } ++ ++ /// @brief Get flag to say when callback was called ++ bool getCalled() const { ++ return (data_->called_); ++ } ++ ++ /// @brief Set flag to say when callback was called ++ /// ++ /// @param called New value of called parameter ++ void setCalled(bool called) { ++ data_->called_ = called; ++ } ++ ++ /// @brief Return instance of callback name ++ std::string getName() const { ++ return (data_->name_); ++ } ++ ++ /// @brief Set callback name ++ /// ++ /// @param name New value of the callback name ++ void setName(const std::string& name) { ++ data_->name_ = name; ++ } ++ ++private: ++ boost::shared_ptr<PrivateData> data_; ///< Pointer to private data ++}; ++ ++/// @brief Socket and pointer types for sending and receiving ICMP echos. ++typedef ICMPSocket<SocketCallback> PingSocket; ++typedef boost::shared_ptr<PingSocket> PingSocketPtr; ++ ++/// @brief Simple test fixture for testing ICMPSocket. ++class ICMPSocketTest : public ::testing::Test { ++public: ++ /// @brief Constructor. ++ ICMPSocketTest() ++ : io_service_(new IOService()), test_timer_(io_service_) { ++ test_timer_.setup(std::bind(&ICMPSocketTest::timeoutHandler, this, true), ++ TEST_TIMEOUT, IntervalTimer::ONE_SHOT); ++ } ++ ++ /// @brief Destructor. ++ virtual ~ICMPSocketTest() { ++ test_timer_.cancel(); ++ io_service_->stopAndPoll(); ++ } ++ ++ /// @brief Indicates if current user is not root ++ /// ++ /// @return True if neither the uid or the effective ++ /// uid is root. ++ static bool notRoot() { ++ return (getuid() != 0 && geteuid() != 0); ++ } ++ ++ /// @brief Callback function invoke upon test timeout. ++ /// ++ /// It stops the IO service and reports test timeout. ++ /// ++ /// @param fail_on_timeout Specifies if test failure should be reported. ++ void timeoutHandler(const bool fail_on_timeout) { ++ if (fail_on_timeout) { ++ ADD_FAILURE() << "Timeout occurred while running the test!"; ++ } ++ io_service_->stop(); ++ } ++ ++ /// @brief IOService instance used by thread pools. ++ IOServicePtr io_service_; ++ ++ /// @brief Asynchronous timer service to detect timeouts. ++ IntervalTimer test_timer_; ++ ++ /// @brief Returns pointer to the first byte of the input buffer. ++ /// ++ /// @throw InvalidOperation if called when the buffer is empty. ++ uint8_t* getInputBufData() { ++ if (input_buf_.empty()) { ++ isc_throw(InvalidOperation, "TcpConnection::getInputBufData() - cannot access empty buffer"); ++ } ++ ++ return (input_buf_.data()); ++ } ++ ++ /// @brief Returns input buffer size. ++ size_t getInputBufSize() const { ++ return (input_buf_.size()); ++ } ++ ++ /// @brief Set the capacity of the input buffer ++ /// ++ /// @param buf_size maximum number of bytes allowed in the buffer ++ void resizeInputBuf(size_t buf_size) { ++ input_buf_.resize(buf_size); ++ } ++ ++ /// @brief Buffer for a single socket read. ++ std::vector<uint8_t> input_buf_; ++}; ++ ++ ++// Verifies that an ICMP socket can be opened and closed. ++TEST_F(ICMPSocketTest, openClose) { ++ SKIP_IF(notRoot()); ++ ++ // For open the endpoint is only used to determine protocol, the address is irrelevant. ++ ICMPEndpoint ping_to_endpoint(IOAddress::IPV4_ZERO_ADDRESS()); ++ ++ PingSocket socket(io_service_); ++ SocketCallback socket_cb("open"); ++ ++ // Verify the socket is closed. ++ ASSERT_FALSE(socket.isOpen()); ++ ++ // Open the socket. ++ ASSERT_NO_THROW_LOG(socket.open(&ping_to_endpoint, socket_cb)); ++ ++ // Verify the socket is open. ++ ASSERT_TRUE(socket.isOpen()); ++ // Since open() is synchronous the callback should not have been invoked. ++ ASSERT_FALSE(socket_cb.getCalled()); ++ ++ // Opening an already open should be harmless. ++ ASSERT_NO_THROW_LOG(socket.open(&ping_to_endpoint, socket_cb)); ++ ASSERT_TRUE(socket.isOpen()); ++ ++ // Close the socket. ++ ASSERT_NO_THROW_LOG(socket.close()); ++ ASSERT_FALSE(socket.isOpen()); ++ ++ // Closing a closed socket should be harmless. ++ ASSERT_NO_THROW_LOG(socket.close()); ++ ASSERT_FALSE(socket.isOpen()); ++} ++ ++// Verifies that an ICMP socket can send and receive ICMP messages. ++TEST_F(ICMPSocketTest, sendReceive) { ++ SKIP_IF(notRoot()); ++ ++ PingSocket socket(io_service_); ++ ++ // For open the endpoint is only used to determine protocol, the address is irrelevant. ++ ICMPEndpoint endpoint(IOAddress::IPV4_ZERO_ADDRESS()); ++ ++ // Open the socket. ++ SocketCallback open_cb("open"); ++ ASSERT_NO_THROW_LOG(socket.open(&endpoint, open_cb)); ++ ++ // Build a ping. ++ struct icmp echo; ++ memset(&echo, 0, sizeof(echo)); ++ echo.icmp_type = ICMPMsg::ECHO_REQUEST; ++ echo.icmp_id = htons(0x1122); ++ echo.icmp_seq = htons(0x3344); ++ echo.icmp_cksum = htons(~(socket.calcChecksum((const uint8_t*)&echo, sizeof(echo)))); ++ ++ // Send it to the loopback. ++ IOAddress ping_to_addr("127.0.0.1"); ++ SocketCallback send_cb("send"); ++ ICMPEndpoint ping_to_endpoint(ping_to_addr); ++ ASSERT_NO_THROW_LOG(socket.asyncSend(&echo, sizeof(echo), &ping_to_endpoint, send_cb)); ++ ++ // Run the send handler. ++ io_service_->runOne(); ++ ++ // Callback should have been invoked without an error code. ++ ASSERT_TRUE(send_cb.getCalled()); ++ ASSERT_EQ(0, send_cb.getCode()); ++ // Verify we sent the whole message. ++ ASSERT_EQ(send_cb.getLength(), sizeof(echo)); ++ ++ // Call asyncReceive until we get our reply. ++ resizeInputBuf(1500); ++ ICMPEndpoint reply_endpoint; ++ SocketCallback receive_cb("receive"); ++ ++ // We need two receives when pinging loop back, only one with a real address. ++ size_t pass = 0; ++ do { ++ receive_cb.clear(); ++ memset(getInputBufData(), 0x00, getInputBufSize()); ++ ASSERT_NO_THROW(socket.asyncReceive(static_cast<void*>(getInputBufData()), ++ getInputBufSize(), 0, &reply_endpoint, receive_cb)); ++ ++ // Run the read handler. ++ io_service_->runOne(); ++ } while (++pass < 2 && (!receive_cb.getCalled())); ++ ++ // Callback should have been invoked without an error code. ++ ASSERT_TRUE(receive_cb.getCalled()); ++ ASSERT_EQ(0, receive_cb.getCode()); ++ ++ // Verify the reply came from the target address. ++ EXPECT_EQ(ping_to_addr.toText(), reply_endpoint.getAddress().toText()); ++ ++ // Verify we got at least enough data for an IP header. ++ size_t bytes_received = receive_cb.getLength(); ++ ASSERT_GE(bytes_received, sizeof(struct ip)); ++ ++ // Build the reply from data ++ uint8_t* icbuf = getInputBufData(); ++ ++ // Find the IP header length... ++ struct ip* ip_header = (struct ip*)(icbuf); ++ auto hlen = (ip_header->ip_hl << 2); ++ ++ // Make sure we received enough data. ++ ASSERT_TRUE(bytes_received >= (hlen + sizeof(struct icmp))) ++ << "received packet too short to be ICMP"; ++ ++ // Verify the message type. ++ struct icmp* reply = (struct icmp*)(icbuf + hlen); ++ auto msg_type = reply->icmp_type; ++ ASSERT_EQ(ICMPMsg::ECHO_REPLY, msg_type); ++ ++ // Verify the id and sequence values. ++ auto id = ntohs(reply->icmp_hun.ih_idseq.icd_id); ++ EXPECT_EQ(0x1122, id); ++ ++ auto sequence = ntohs(reply->icmp_hun.ih_idseq.icd_seq); ++ EXPECT_EQ(0x3344, sequence); ++ ++ // Close the socket. ++ ASSERT_NO_THROW_LOG(socket.close()); ++ ASSERT_FALSE(socket.isOpen()); ++} ++ ++} +diff --git a/src/hooks/dhcp/ping_check/tests/meson.build b/src/hooks/dhcp/ping_check/tests/meson.build +new file mode 100644 +index 0000000000..8beca7813e +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/meson.build +@@ -0,0 +1,21 @@ ++if not TESTS_OPT.enabled() ++ subdir_done() ++endif ++ ++dhcp_ping_check_tests = executable( ++ 'dhcp-ping-check-tests', ++ 'config_cache_unittests.cc', ++ 'icmp_endpoint_unittests.cc', ++ 'icmp_msg_unittests.cc', ++ 'icmp_socket_unittests.cc', ++ 'ping_channel_unittests.cc', ++ 'ping_check_config_unittests.cc', ++ 'ping_check_mgr_unittests.cc', ++ 'ping_context_store_unittests.cc', ++ 'ping_context_unittests.cc', ++ 'run_unittests.cc', ++ dependencies: [CRYPTO_DEP, GTEST_DEP], ++ include_directories: [include_directories('.'), include_directories('..')] + INCLUDES, ++ link_with: [dhcp_ping_check_archive] + LIBS_BUILT_SO_FAR, ++) ++test('dhcp-ping-check-tests', dhcp_ping_check_tests, protocol: 'gtest') +diff --git a/src/hooks/dhcp/ping_check/tests/ping_channel_unittests.cc b/src/hooks/dhcp/ping_check/tests/ping_channel_unittests.cc +new file mode 100644 +index 0000000000..4c57a2e500 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/ping_channel_unittests.cc +@@ -0,0 +1,821 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++/// @file This file contains tests which exercise the PingChannel class. ++ ++#include <config.h> ++ ++#include <ping_channel.h> ++#include <ping_test_utils.h> ++#include <asiolink/interval_timer.h> ++#include <asiolink/io_service_thread_pool.h> ++#include <dhcp/iface_mgr.h> ++#include <util/multi_threading_mgr.h> ++#include <testutils/multi_threading_utils.h> ++#include <testutils/gtest_utils.h> ++#include <gtest/gtest.h> ++ ++#include <boost/multi_index/indexed_by.hpp> ++#include <boost/multi_index/member.hpp> ++#include <boost/multi_index/mem_fun.hpp> ++#include <boost/multi_index/hashed_index.hpp> ++#include <boost/multi_index/ordered_index.hpp> ++#include <boost/multi_index_container.hpp> ++#include <boost/multi_index/composite_key.hpp> ++ ++#include <queue> ++#include <list> ++#include <thread> ++#include <mutex> ++ ++using namespace std; ++using namespace isc; ++using namespace isc::asiolink; ++using namespace isc::dhcp; ++using namespace isc::ping_check; ++using namespace isc::util; ++using namespace isc::test; ++using namespace boost::asio::error; ++ ++namespace ph = std::placeholders; ++ ++namespace { ++ ++/// @brief Tag for index by address. ++struct AddressIdSequenceIndexTag { }; ++ ++/// @brief A multi index container holding pointers ICMPMsgPtr ++/// ++/// The message may be accessed using the following index(es): ++/// - using an IPv4 address, id, and sequence number ++typedef boost::multi_index_container< ++ // It holds pointers to ICMPMsg objects. ++ ICMPMsgPtr, ++ boost::multi_index::indexed_by< ++ // Specification of the first index starts here. ++ // This index sorts PingContexts by IPv4 addresses represented as ++ // IOAddress objects. ++ // Specification of the first index starts here. ++ boost::multi_index::ordered_unique< ++ boost::multi_index::tag<AddressIdSequenceIndexTag>, ++ boost::multi_index::composite_key< ++ ICMPMsg, ++ // The boolean value specifying if context is waiting for a reply ++ boost::multi_index::const_mem_fun<ICMPMsg, const IOAddress&, ++ &ICMPMsg::getSource>, ++ boost::multi_index::const_mem_fun<ICMPMsg, uint16_t, ++ &ICMPMsg::getId>, ++ boost::multi_index::const_mem_fun<ICMPMsg, uint16_t, ++ &ICMPMsg::getSequence> ++ > ++ > ++ > ++> ReplyContainer; ++ ++/// @brief Single-threaded test fixture for exercising a PingChannel. ++class PingChannelTest : public IOServiceTest { ++public: ++ /// @brief Constructor ++ PingChannelTest() : mutex_(new mutex()), stopped_(false) { ++ MultiThreadingMgr::instance().setMode(false); ++ }; ++ ++ /// @brief Destructor ++ virtual ~PingChannelTest() { ++ stopped_ = true; ++ if (channel_) { ++ channel_->close(); ++ } ++ if (ios_pool_) { ++ ios_pool_->getIOService()->stopAndPoll(); ++ ios_pool_->stop(); ++ } ++ ios_pool_.reset(); ++ test_timer_.cancel(); ++ test_io_service_->stopAndPoll(); ++ MultiThreadingMgr::instance().setMode(false); ++ } ++ ++ /// @brief Called prior to test destruction. ++ /// Ensure we stop the pool in the even a test failed in an unexpected ++ /// manner that left it running. Otherwise we can get false TSAN complaints. ++ virtual void TearDown() { ++ // Stop the thread pool (if one). ++ if (ios_pool_) { ++ ios_pool_->stop(); ++ } ++ } ++ ++ /// @brief Initializes the IOServiceThreadPool ++ /// ++ /// @param num_threads number of threads in the pool ++ /// @param defer_start enables deferred start of the pool's IOService ++ void initThreadPool(size_t num_threads = 1, bool defer_start = false) { ++ ios_pool_.reset(new IoServiceThreadPool(IOServicePtr(), num_threads, defer_start)); ++ }; ++ ++ /// @brief Callback to invoke to fetch the next ping target. ++ /// ++ /// Fetches the next entry from the front of the send queue (if one). Checks for ++ /// test completion before returning. ++ /// ++ /// @param[out] next upon return it will contain the next target address. Contents are ++ /// only meaningful if the function returns true. ++ /// ++ /// @return True another target address exists, false otherwise. ++ virtual bool nextToSend(IOAddress& next) { ++ if (stopped_) { ++ return (false); ++ } ++ MultiThreadingLock lock(*mutex_); ++ bool use_next = true; ++ if (send_queue_.empty()) { ++ use_next = false; ++ } else { ++ next = send_queue_.front(); ++ } ++ ++ stopIfDone(); ++ return (use_next); ++ } ++ ++ /// @brief Callback to invoke when an ECHO write has completed. ++ /// ++ /// Ensures the completed echo matches the front of the send queue and then ++ /// pops it from the front of the queue. Checks for test completion before ++ /// returning. ++ /// ++ /// @param echo ICMP echo message that as sent ++ virtual void echoSent(ICMPMsgPtr& echo, bool send_failed) { ++ if (stopped_) { ++ return; ++ } ++ MultiThreadingLock lock(*mutex_); ++ ASSERT_EQ(echo->getDestination(), send_queue_.front()) << "send queue mismatch"; ++ send_queue_.pop(); ++ if (!send_failed) { ++ echos_sent_.push_back(echo); ++ } ++ stopIfDone(); ++ } ++ ++ /// @brief Callback to invoke when an ICMP reply has been received. ++ /// ++ /// Stores the reply if it is an ECHO REPLY message. We check to the ++ /// do avoid storing our outbound ECHO REQUESTs when testing with loop back ++ /// address. Checks for test completion before returning. ++ /// ++ /// @param reply ICMP message that was received ++ virtual void replyReceived(ICMPMsgPtr& reply) { ++ if (stopped_) { ++ return; ++ } ++ MultiThreadingLock lock(*mutex_); ++ if (reply->getType() == ICMPMsg::ECHO_REPLY) { ++ // If loopback routing is enabled, Insert the original destination address ++ // as the reply's source address. ++ if (channel_->route_loopback_) { ++ IOAddress address = channel_->loopback_map_.find(reply->getSequence()); ++ if (address != IOAddress::IPV4_ZERO_ADDRESS()) { ++ reply->setSource(address); ++ } ++ } ++ ++ replies_received_.push_back(reply); ++ storeReply(reply); ++ } ++ ++ stopIfDone(); ++ } ++ ++ /// @brief Tests that a channel can send and receive, reliably ++ /// in either single or multi-threaded mode. ++ /// ++ /// The test queues the given number of requests, beginning with ++ /// address 127.0.0.1 and incrementing the address through the number ++ /// of targets. It then opens the channel and initiates reading and ++ /// and writing, running until the test completes or times out. ++ /// It expects to receive a reply for every request. ++ /// ++ /// @param num_threads number of threads in the thread pool. If 0, ++ /// the channel will be single-threaded, sharing the test's IOService, ++ /// otherwise the channel will be driven by an IOServiceThreadPool with ++ /// the given number of threads. ++ /// @param num_targets number of target IP addresses to ping. Must not ++ /// be greater than 253. ++ /// @param set_error_trigger optional function that sets the error trigger ++ /// condition. ++ void sendReceiveTest(size_t num_threads, size_t num_targets = 25, ++ const std::function<void()>& set_error_trigger = [](){}); ++ ++ /// @brief Tests for graceful behavior when a channel encounters a read ++ /// or write error, in either single or multi-threaded mode. ++ /// ++ /// The test runs in two passes. The first pass sends and receives until ++ /// the error trigger occurs. The error should induce a graceful cessation ++ /// of operations. After verifying expected state of affairs, the second pass ++ /// is begun by re-opening the channel and resuming operations until the test ++ /// completes or times out. ++ /// ++ /// @param set_error_trigger function that sets the error trigger condition ++ /// @param num_threads number of threads in the thread pool. If 0, ++ /// the channel will be single-threaded, sharing the test's IOService, ++ /// otherwise the channel will be driven by an IOServiceThreadPool with ++ /// the given number of threads. ++ /// @param num_targets number of target IP addresses to ping. Must not ++ /// be greater than 253. ++ void ioErrorTest(const std::function<void()>& set_error_trigger, ++ size_t num_threads, size_t num_targets = 10); ++ ++ /// @brief Adds a reply to reply store. ++ /// ++ /// Fails if a reply for the same address, id, and sequence number is already ++ /// in the store. Must be used in a thread-safe context. ++ /// ++ /// @param reply reply to store ++ void storeReply(ICMPMsgPtr& reply) { ++ auto retpair = replies_map_.insert(reply); ++ ASSERT_TRUE(retpair.second) ++ << "failed to insert reply for: " << reply->getSource() ++ << ", id: " << reply->getId() << ", sequence: " << reply->getSequence(); ++ } ++ ++ /// @brief Fetches a reply from the store that matches a given ECHO ++ /// ++ /// Must be used in a thread-safe context. ++ /// ++ /// @param echo echo for whom a reply is sought ++ /// ++ /// @return The matching reply if found, otherwise an empty ICMPMsgPtr. ++ ICMPMsgPtr findReply(const ICMPMsgPtr& echo) { ++ auto const& index = replies_map_.get<AddressIdSequenceIndexTag>(); ++ auto key = boost::make_tuple(echo->getDestination(), echo->getId(), echo->getSequence()); ++ auto iter = index.find(key); ++ return (iter == index.end() ? ICMPMsgPtr() : *iter); ++ } ++ ++ /// @brief Channel instance. ++ TestablePingChannelPtr channel_; ++ ++ /// @brief IoServiceThreadPool instance ++ IoServiceThreadPoolPtr ios_pool_; ++ ++ /// @brief The mutex used to protect internal state. ++ const boost::scoped_ptr<std::mutex> mutex_; ++ ++ /// @brief Queue of IOAddresses for which to send ECHO REQUESTs. ++ std::queue<IOAddress> send_queue_; ++ ++ /// @brief List of ECHO REQUESTs that have been successfully sent in the order ++ /// they were sent. ++ std::list<ICMPMsgPtr> echos_sent_; ++ ++ /// @brief List of ECHO REPLYs that have been successfully received in the ++ /// order they were received. ++ std::list<ICMPMsgPtr> replies_received_; ++ ++ /// @brief Map of ECHO REPLYs received, indexed by source IP, id, and sequence number. ++ ReplyContainer replies_map_; ++ ++ /// @brief Flag which indicates that the manager has been stopped. ++ bool stopped_; ++}; ++ ++void ++PingChannelTest::sendReceiveTest(size_t num_threads, size_t num_targets /* = 25 */, ++ const std::function<void()>& set_error_trigger) { ++ stopped_ = false; ++ ++ // Clear state. ++ send_queue_ = {}; ++ echos_sent_.clear(); ++ replies_received_.clear(); ++ replies_map_.clear(); ++ ++ SKIP_IF(notRoot()); ++ ++ ASSERT_TRUE(num_targets < 253); ++ auto channel_ios = test_io_service_; ++ if (num_threads) { ++ // Enable MT mode. ++ util::MultiThreadingMgr::instance().setMode(true); ++ ++ // Initialize the thread pool to num_threads, defer start. ++ ASSERT_NO_THROW_LOG(initThreadPool(num_threads, true)); ++ ASSERT_TRUE(ios_pool_->isStopped()); ++ channel_ios = ios_pool_->getIOService(); ++ } ++ ++ // Create the channel instance with the appropriate io_service. ++ ASSERT_NO_THROW_LOG(channel_.reset(new TestablePingChannel( ++ channel_ios, ++ std::bind(&PingChannelTest::nextToSend, this, ph::_1), ++ std::bind(&PingChannelTest::echoSent, this, ph::_1, ph::_2), ++ std::bind(&PingChannelTest::replyReceived, this, ph::_1) ++ ))); ++ ++ // Create the callback to check test completion criteria. ++ // It returns true if we have sent out all the echos and received ++ // all the replies. ++ test_done_cb_ = [this]() { ++ return (send_queue_.empty() && (echos_sent_.size() == replies_received_.size())); ++ }; ++ ++ // Fill the send queue with num_target addresses to ping. ++ IOAddress target("127.0.0.1"); ++ for (auto i = 0; i < num_targets; ++i) { ++ send_queue_.push(target); ++ target = IOAddress::increase(target); ++ } ++ ++ (set_error_trigger)(); ++ ++ // Open the channel. ++ ASSERT_NO_THROW_LOG(channel_->open()); ++ ASSERT_TRUE(channel_->isOpen()); ++ ++ if (num_threads) { ++ ios_pool_->run(); ++ } ++ ++ // Initiate reading and writing. ++ ASSERT_NO_THROW_LOG(channel_->startRead()); ++ ASSERT_NO_THROW_LOG(channel_->startSend()); ++ ++ // Run the main thread's IOService until we complete or timeout. ++ ASSERT_NO_THROW_LOG(runIOService(1000)); ++ ++ if (ios_pool_) { ++ // Stop the thread pool. ++ ASSERT_NO_THROW_LOG(ios_pool_->stop()); ++ ASSERT_TRUE(ios_pool_->isStopped()); ++ } ++ ++ // Send queue should be empty. ++ EXPECT_TRUE(send_queue_.empty()); ++ ++ // Should have as many replies as echos. ++ EXPECT_EQ(echos_sent_.size(), replies_received_.size()); ++ ++ // Should have a reply for every echo. ++ for (auto const& echo : echos_sent_) { ++ ICMPMsgPtr reply = findReply(echo); ++ EXPECT_TRUE(reply) << "no reply found for:" << echo->getDestination() ++ << ", id:" << echo->getId() << ", sequence: " << echo->getSequence(); ++ } ++ ++ stopped_ = true; ++ if (channel_) { ++ channel_->close(); ++ } ++ if (ios_pool_) { ++ ios_pool_->getIOService()->stopAndPoll(); ++ ios_pool_->stop(); ++ } ++ ios_pool_.reset(); ++ test_timer_.cancel(); ++ test_io_service_->stopAndPoll(); ++ MultiThreadingMgr::instance().setMode(false); ++} ++ ++void ++PingChannelTest::ioErrorTest(const std::function<void()>& set_error_trigger, ++ size_t num_threads, size_t num_targets) { ++ ASSERT_TRUE(num_targets < 253); ++ SKIP_IF(notRoot()); ++ ++ ASSERT_TRUE(replies_received_.empty()); ++ ++ /// If it's an MT test create the thread pool. ++ auto channel_ios = test_io_service_; ++ if (num_threads) { ++ // Enable MT mode. ++ util::MultiThreadingMgr::instance().setMode(true); ++ ++ // Initialize the thread pool to num_threads, defer start. ++ ASSERT_NO_THROW_LOG(initThreadPool(num_threads, true)); ++ ASSERT_TRUE(ios_pool_->isStopped()); ++ channel_ios = ios_pool_->getIOService(); ++ } ++ ++ // Set local shutdown called flag to false. ++ bool shutdown_cb_called = false; ++ ++ // Create the channel instance with the appropriate io_service. ++ ASSERT_NO_THROW_LOG(channel_.reset(new TestablePingChannel( ++ channel_ios, ++ std::bind(&PingChannelTest::nextToSend, this, ph::_1), ++ std::bind(&PingChannelTest::echoSent, this, ph::_1, ph::_2), ++ std::bind(&PingChannelTest::replyReceived, this, ph::_1), ++ ([this, &shutdown_cb_called]() { ++ shutdown_cb_called = true; ++ test_io_service_->stop(); ++ }) ++ ))); ++ ++ // Set the test_done_cb_ to always return false (i.e. test is not ++ // done). ++ test_done_cb_ = []() { ++ return (false); ++ }; ++ ++ // Fill the send queue with target addresses to ping. ++ IOAddress target("127.0.0.1"); ++ for (auto i = 0; i < (num_targets / 2); ++i) { ++ send_queue_.push(target); ++ target = IOAddress::increase(target); ++ } ++ ++ // Set the error trigger. ++ (set_error_trigger)(); ++ ++ // FIRST PASS ++ ++ // Open the channel. ++ ASSERT_NO_THROW_LOG(channel_->open()); ++ ASSERT_TRUE(channel_->isOpen()); ++ ++ if (num_threads) { ++ ios_pool_->run(); ++ } ++ ++ // Initiate reading and writing. ++ ASSERT_NO_THROW_LOG(channel_->startRead()); ++ ASSERT_NO_THROW_LOG(channel_->startSend()); ++ ++ // Run the main thread's IOService until we stop or timeout. ++ ASSERT_NO_THROW_LOG(runIOService(1000)); ++ ++ // Shutdown callback should have been invoked, the channel should be closed, ++ // but the pool should still be running. ++ ASSERT_TRUE(shutdown_cb_called); ++ ASSERT_FALSE(channel_->isOpen()); ++ ++ if (ios_pool_) { ++ ASSERT_TRUE(ios_pool_->isRunning()); ++ ++ // Pause the thread pool. ++ ASSERT_NO_THROW_LOG(ios_pool_->pause()); ++ ASSERT_TRUE(ios_pool_->isPaused()); ++ } ++ ++ // Save how many echos sent and replies received during the first pass. ++ auto first_pass_echo_count = echos_sent_.size(); ++ auto first_pass_reply_count = replies_received_.size(); ++ ++ // Should have sent some but not all. ++ EXPECT_LE(first_pass_echo_count, num_targets); ++ ++ // SECOND PASS ++ ++ // Modify the test done callback to check test completion criteria. ++ // It returns true if we have sent out all the echos and received ++ // all the replies. ++ test_done_cb_ = [this, &first_pass_reply_count]() { ++ return (send_queue_.empty() && (replies_received_.size() > first_pass_reply_count)); ++ }; ++ ++ // Fill the send queue with target addresses to ping. ++ for (auto i = 0; i < (num_targets / 2); ++i) { ++ send_queue_.push(target); ++ target = IOAddress::increase(target); ++ } ++ ++ // Resume running the thread pool (if one). ++ if (ios_pool_) { ++ ASSERT_NO_THROW_LOG(ios_pool_->run()); ++ ASSERT_TRUE(ios_pool_->isRunning()); ++ } ++ ++ // Resume reopening the channel and restarting IO operations. ++ ASSERT_NO_THROW_LOG(channel_->open()); ++ ASSERT_TRUE(channel_->isOpen()); ++ ASSERT_NO_THROW_LOG(channel_->startRead()); ++ ASSERT_NO_THROW_LOG(channel_->startSend()); ++ ++ // Run the main thread's IOService until we complete or timeout. ++ ASSERT_NO_THROW_LOG(runIOService(1000)); ++ ++ // Stop the thread pool (if one). ++ if (ios_pool_) { ++ ASSERT_NO_THROW_LOG(ios_pool_->stop()); ++ ASSERT_TRUE(ios_pool_->isStopped()); ++ } ++ ++ // Send queue should be empty. ++ EXPECT_TRUE(send_queue_.empty()); ++ ++ // Should have sent as many echos as we queued. ++ EXPECT_EQ(echos_sent_.size(), num_targets); ++ ++ // Should have more replies than we had, but likely not all. ++ EXPECT_GE(replies_received_.size(), first_pass_reply_count); ++} ++ ++// Verifies PingChannel open and close operations. ++TEST_F(PingChannelTest, openCloseST) { ++ SKIP_IF(notRoot()); ++ ++ // Create the channel instance. ++ ASSERT_NO_THROW_LOG(channel_.reset(new TestablePingChannel( ++ test_io_service_, ++ std::bind(&PingChannelTest::nextToSend, this, ph::_1), ++ std::bind(&PingChannelTest::echoSent, this, ph::_1, ph::_2), ++ std::bind(&PingChannelTest::replyReceived, this, ph::_1) ++ ))); ++ ++ ASSERT_TRUE(channel_); ++ ++ ASSERT_TRUE(channel_->getSingleThreaded()); ++ ++ // Verify it is not open. ++ ASSERT_FALSE(channel_->isOpen()); ++ ++ EXPECT_FALSE(channel_->getWatchSocket()); ++ EXPECT_EQ(channel_->getRegisteredWriteFd(), -1); ++ EXPECT_EQ(channel_->getRegisteredReadFd(), -1); ++ ++ // Verify that invoking close is harmless. ++ ASSERT_NO_THROW_LOG(channel_->close()); ++ ++ // Attempt to open the channel. ++ ASSERT_NO_THROW_LOG(channel_->open()); ++ ++ // PingChannel::open() is synchronous and while it has a callback ++ // it should never be invoked. Run the service to make sure. ++ ASSERT_NO_THROW_LOG(runIOService(1000)); ++ ++ // Verify the channel is open. ++ ASSERT_TRUE(channel_->isOpen()); ++ ++ // Verify the WatchSocket was created and that its fd and that of the ++ // PingSocket are both registered with IfaceMgr. ++ ASSERT_TRUE(channel_->getWatchSocket()); ++ int registered_write_fd = channel_->getRegisteredWriteFd(); ++ EXPECT_EQ(registered_write_fd, channel_->getWatchSocket()->getSelectFd()); ++ EXPECT_TRUE(IfaceMgr::instance().isExternalSocket(registered_write_fd)); ++ int registered_read_fd = channel_->getRegisteredReadFd(); ++ EXPECT_EQ(registered_read_fd, channel_->getPingSocket()->getNative()); ++ EXPECT_TRUE(IfaceMgr::instance().isExternalSocket(registered_read_fd)); ++ ++ // A subsequent open should be harmless. ++ ASSERT_NO_THROW_LOG(channel_->open()); ++ ++ // Closing the socket should work. ++ ASSERT_NO_THROW_LOG(channel_->close()); ++ ++ // Verify watch socket is gone, registered fds are reset, and prior ++ // registered fds are no longer registered. ++ EXPECT_FALSE(channel_->getWatchSocket()); ++ EXPECT_EQ(channel_->getRegisteredWriteFd(), -1); ++ EXPECT_FALSE(IfaceMgr::instance().isExternalSocket(registered_write_fd)); ++ EXPECT_EQ(channel_->getRegisteredReadFd(), -1); ++ EXPECT_FALSE(IfaceMgr::instance().isExternalSocket(registered_read_fd)); ++ ++ // Verify it is not open. ++ ASSERT_FALSE(channel_->isOpen()); ++} ++ ++// Verifies PingChannel open and close operations. ++TEST_F(PingChannelTest, openCloseMT) { ++ SKIP_IF(notRoot()); ++ MultiThreadingTest mt; ++ ++ // Create the channel instance. ++ ASSERT_NO_THROW_LOG(channel_.reset(new TestablePingChannel( ++ test_io_service_, ++ std::bind(&PingChannelTest::nextToSend, this, ph::_1), ++ std::bind(&PingChannelTest::echoSent, this, ph::_1, ph::_2), ++ std::bind(&PingChannelTest::replyReceived, this, ph::_1) ++ ))); ++ ++ ASSERT_TRUE(channel_); ++ ++ ASSERT_FALSE(channel_->getSingleThreaded()); ++ ++ // Verify it is not open. ++ ASSERT_FALSE(channel_->isOpen()); ++ ++ // Verify that invoking close is harmless. ++ ASSERT_NO_THROW_LOG(channel_->close()); ++ ++ // Attempt to open the channel. ++ ASSERT_NO_THROW_LOG(channel_->open()); ++ ++ // PingChannel::open() is synchronous and while it has a callback ++ // it should never be invoked. Run the service to make sure. ++ ASSERT_NO_THROW_LOG(runIOService(1000)); ++ ++ // Verify the channel is open. ++ ASSERT_TRUE(channel_->isOpen()); ++ ++ // Verify that single-threaded members are not set. ++ EXPECT_FALSE(channel_->getWatchSocket()); ++ EXPECT_EQ(channel_->getRegisteredWriteFd(), -1); ++ EXPECT_EQ(channel_->getRegisteredReadFd(), -1); ++ ++ // A subsequent open should be harmless. ++ ASSERT_NO_THROW_LOG(channel_->open()); ++ ++ // Closing the socket should work. ++ ASSERT_NO_THROW_LOG(channel_->close()); ++ ++ // Verify it is not open. ++ ASSERT_FALSE(channel_->isOpen()); ++} ++ ++// Verifies that a PingChannel can perpetuate sending requests and receiving ++// replies when driven by a single-threaded IOService. ++TEST_F(PingChannelTest, sendReceiveST) { ++ sendReceiveTest(0); ++} ++ ++// Verifies that a PingChannel can perpetuate sending requests and receiving ++// replies when driven by a multi-threaded IOServiceThreadPool 3 threads ++TEST_F(PingChannelTest, sendReceiveMT) { ++ // Use a thread pool with 3 threads. ++ sendReceiveTest(3); ++} ++ ++// Verifies that an exception throw from asyncRead triggers graceful channel ++// shutdown and that operations can be resumed with a single-threaded channel. ++TEST_F(PingChannelTest, readExceptionErrorST) { ++ ioErrorTest( ++ [this]() { ++ channel_->throw_on_read_number_ = 5; ++ }, 0); ++} ++ ++// Verifies that an exception throw from asyncRead triggers graceful channel ++// shutdown and that operations can be resumed with a multi-threaded channel. ++TEST_F(PingChannelTest, readExceptionErrorMT) { ++ // Use a thread pool with 3 threads. ++ ioErrorTest( ++ [this]() { ++ channel_->throw_on_read_number_ = 5; ++ }, 3, 20); ++} ++ ++// Verifies that a fatal error code passed into socketReadCallback triggers graceful channel ++// shutdown and that operations can be resumed with a single-threaded channel. ++TEST_F(PingChannelTest, readFatalErrorST) { ++ ioErrorTest( ++ [this]() { ++ channel_->ec_on_read_number_ = 3; ++ // See boost/asio/error.hpp for error codes ++ channel_->read_error_ec_ = make_error_code(fault); ++ }, 0); ++} ++ ++// Verifies that a fatal error code passed into socketReadCallback triggers graceful channel ++// shutdown and that operations can be resumed with a single-threaded channel. ++TEST_F(PingChannelTest, readFatalErrorMT) { ++ ioErrorTest( ++ [this]() { ++ channel_->ec_on_read_number_ = 3; ++ // See boost/asio/error.hpp for error codes ++ channel_->read_error_ec_ = make_error_code(fault); ++ }, 4); ++} ++ ++// Verifies that a non-fatal, EWOULDBLOCK error passed into socketReadCallback does ++// not disrupt reading for a single-threaded channel. ++TEST_F(PingChannelTest, readAgainErrorST) { ++ sendReceiveTest(0, 10, ++ [this]() { ++ channel_->ec_on_read_number_ = 4; ++ // See boost/asio/error.hpp for error codes ++ channel_->read_error_ec_ = make_error_code(would_block); ++ }); ++} ++ ++// Verifies that a non-fatal, EWOULDBLOCK error passed into socketReadCallback does ++// not disrupt reading for a multi-threaded channel. ++TEST_F(PingChannelTest, readAgainErrorMT) { ++ sendReceiveTest(3, 10, ++ [this]() { ++ channel_->ec_on_read_number_ = 4; ++ // See boost/asio/error.hpp for error codes ++ channel_->read_error_ec_ = make_error_code(would_block); ++ }); ++} ++ ++// Verifies that an exception throw from asyncRead triggers graceful channel ++// shutdown and that operations can be resumed with a single-threaded channel. ++TEST_F(PingChannelTest, writeExceptionErrorST) { ++ ioErrorTest( ++ [this]() { ++ channel_->throw_on_write_number_ = 5; ++ }, 0); ++} ++ ++// Verifies that an exception throw from asyncRead triggers graceful channel ++// shutdown and that operations can be resumed with a multi-threaded channel. ++TEST_F(PingChannelTest, writeExceptionErrorMT) { ++ // Use a thread pool with 3 threads. ++ ioErrorTest( ++ [this]() { ++ channel_->throw_on_write_number_ = 5; ++ }, 3); ++} ++ ++// Verifies that a fatal error code passed into socketReadCallback triggers graceful channel ++// shutdown and that operations can be resumed with a single-threaded channel. ++TEST_F(PingChannelTest, writeFatalErrorST) { ++ ioErrorTest( ++ [this]() { ++ channel_->ec_on_write_number_ = 3; ++ // See boost/asio/error.hpp for error codes ++ channel_->write_error_ec_ = make_error_code(fault); ++ }, 0); ++} ++ ++// Verifies that a fatal error code passed into socketReadCallback triggers graceful channel ++// shutdown and that operations can be resumed with a single-threaded channel. ++TEST_F(PingChannelTest, writeFatalErrorMT) { ++ ioErrorTest( ++ [this]() { ++ channel_->ec_on_write_number_ = 3; ++ // See boost/asio/error.hpp for error codes ++ channel_->write_error_ec_ = make_error_code(fault); ++ }, 4); ++} ++ ++// Verifies that a non-fatal, EWOULDBLOCK error passed into socketWriteCallback does ++// not disrupt writing for a single-threaded channel. ++TEST_F(PingChannelTest, writeAgainErrorST) { ++ sendReceiveTest(0, 10, ++ [this]() { ++ channel_->ec_on_write_number_ = 6; ++ // See boost/asio/error.hpp for error codes ++ channel_->write_error_ec_ = make_error_code(would_block); ++ }); ++} ++ ++// Verifies that a non-fatal, EWOULDBLOCK error passed into socketWriteCallback ++// does not disrupt writing for a multi-threaded channel. ++TEST_F(PingChannelTest, writeAgainErrorMT) { ++ sendReceiveTest(3, 10, ++ [this]() { ++ channel_->ec_on_write_number_ = 6; ++ // See boost/asio/error.hpp for error codes ++ channel_->write_error_ec_ = make_error_code(would_block); ++ }); ++} ++ ++// Verify the recoverable write errors do not disrupt writing for a ++// single-threaded channel. ++TEST_F(PingChannelTest, writeSendFailedErrorST) { ++ SKIP_IF(notRoot()); ++ ++ std::list<boost::asio::error::basic_errors> errors = { ++ boost::asio::error::network_unreachable, ++ boost::asio::error::host_unreachable, ++ boost::asio::error::network_down, ++ boost::asio::error::no_buffer_space, ++ boost::asio::error::access_denied ++ }; ++ ++ for (auto const& error : errors) { ++ sendReceiveTest(0, 10, ++ [this, error]() { ++ channel_->ec_on_write_number_ = 6; ++ // See boost/asio/error.hpp for error codes ++ channel_->write_error_ec_ = make_error_code(error); ++ }); ++ ++ // Sanity check, we should have sent one less than we targeted. ++ EXPECT_EQ(echos_sent_.size(), 9); ++ } ++} ++ ++// Verify the recoverable write errors do not disrupt writing for a ++// multi-threaded channel. ++TEST_F(PingChannelTest, writeSendFailedErrorMT) { ++ SKIP_IF(notRoot()); ++ ++ std::list<boost::asio::error::basic_errors> errors = { ++ boost::asio::error::network_unreachable, ++ boost::asio::error::host_unreachable, ++ boost::asio::error::network_down, ++ boost::asio::error::no_buffer_space, ++ boost::asio::error::access_denied ++ }; ++ ++ for (auto const& error : errors) { ++ sendReceiveTest(3, 10, ++ [this, error]() { ++ channel_->ec_on_write_number_ = 6; ++ // See boost/asio/error.hpp for error codes ++ channel_->write_error_ec_ = make_error_code(error); ++ }); ++ ++ // Sanity check, we should have sent one less than we targeted. ++ EXPECT_EQ(echos_sent_.size(), 9); ++ } ++} ++ ++} // end of anonymous namespace +diff --git a/src/hooks/dhcp/ping_check/tests/ping_check_config_unittests.cc b/src/hooks/dhcp/ping_check/tests/ping_check_config_unittests.cc +new file mode 100644 +index 0000000000..a831a0efab +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/ping_check_config_unittests.cc +@@ -0,0 +1,287 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++/// @file This file contains tests which exercise the PingCheckConfig class. ++ ++#include <config.h> ++#include <ping_check_config.h> ++#include <testutils/gtest_utils.h> ++ ++#include <gtest/gtest.h> ++#include <list> ++ ++using namespace std; ++using namespace isc; ++using namespace isc::data; ++using namespace isc::ping_check; ++ ++namespace { ++ ++// Verifies PingCheckConfig constructors and accessors. ++TEST(PingCheckConfigTest, basics) { ++ PingCheckConfig config; ++ ++ // Verify initial values. ++ EXPECT_TRUE(config.getEnablePingCheck()); ++ EXPECT_EQ(1, config.getMinPingRequests()); ++ EXPECT_EQ(100, config.getReplyTimeout()); ++ EXPECT_EQ(60, config.getPingClttSecs()); ++ EXPECT_EQ(0, config.getPingChannelThreads()); ++ ++ // Verify accessors. ++ EXPECT_NO_THROW_LOG(config.setEnablePingCheck(false)); ++ EXPECT_FALSE(config.getEnablePingCheck()); ++ ++ EXPECT_NO_THROW_LOG(config.setMinPingRequests(4)); ++ EXPECT_EQ(4, config.getMinPingRequests()); ++ ++ EXPECT_NO_THROW_LOG(config.setReplyTimeout(250)); ++ EXPECT_EQ(250, config.getReplyTimeout()); ++ ++ EXPECT_NO_THROW_LOG(config.setPingClttSecs(120)); ++ EXPECT_EQ(120, config.getPingClttSecs()); ++ ++ EXPECT_NO_THROW_LOG(config.setPingChannelThreads(6)); ++ EXPECT_EQ(6, config.getPingChannelThreads()); ++ ++ // Verify copy construction. ++ PingCheckConfig config2(config); ++ EXPECT_FALSE(config2.getEnablePingCheck()); ++ EXPECT_EQ(4, config2.getMinPingRequests()); ++ EXPECT_EQ(250, config2.getReplyTimeout()); ++ EXPECT_EQ(120, config2.getPingClttSecs()); ++ EXPECT_EQ(6, config2.getPingChannelThreads()); ++} ++ ++// Exercises PingCheckConfig parameter parsing with valid configuration ++// permutations. ++TEST(PingCheckConfigTest, parseValidScenarios) { ++ // Describes a test scenario. ++ struct Scenario { ++ int line_; // Scenario line number ++ std::string json_; // JSON configuration to parse ++ bool exp_enable_ping_check_; // Expected value for enable-ping-check ++ uint32_t exp_min_ping_requests_; // Expected value for min-ping-requests ++ uint32_t exp_reply_timeout_; // Expected value for reply-timeout ++ uint32_t exp_ping_cltt_secs_; // Expected value for ping-cltt-secs ++ size_t exp_num_threads_; // Expected value for ping-channel-threads ++ }; ++ ++ // List of test scenarios to run. ++ list<Scenario> scenarios = { ++ { ++ // Empty map ++ __LINE__, ++ R"({ })", ++ true, 1, 100, 60, 0 ++ }, ++ { ++ // Only enable-ping-check", ++ __LINE__, ++ R"({ "enable-ping-check" : false })", ++ false, 1, 100, 60, 0 ++ }, ++ { ++ // Only min-ping-requests", ++ __LINE__, ++ R"({ "min-ping-requests" : 3 })", ++ true, 3, 100, 60, 0 ++ }, ++ { ++ // Only reply-timeout", ++ __LINE__, ++ R"({ "reply-timeout" : 250 })", ++ true, 1, 250, 60, 0 ++ }, ++ { ++ // Only ping-cltt-secs", ++ __LINE__, ++ R"({ "ping-cltt-secs" : 77 })", ++ true, 1, 100, 77, 0 ++ }, ++ { ++ // Only ping-channel-threads", ++ __LINE__, ++ R"({ "ping-channel-threads" : 5 })", ++ true, 1, 100, 60, 5 ++ }, ++ { ++ // All parameters", ++ __LINE__, ++ R"( ++ { ++ "enable-ping-check" : false, ++ "min-ping-requests" : 2, ++ "reply-timeout" : 375, ++ "ping-cltt-secs" : 120, ++ "ping-channel-threads" : 6 ++ })", ++ false, 2, 375, 120, 6 ++ }, ++ }; ++ ++ // Iterate over the scenarios. ++ for (auto const& scenario : scenarios) { ++ stringstream oss; ++ oss << "scenario at line: " << scenario.line_; ++ SCOPED_TRACE(oss.str()); ++ ++ // Convert JSON texts to Element map. ++ ConstElementPtr json_elements; ++ ASSERT_NO_THROW_LOG(json_elements = Element::fromJSON(scenario.json_)); ++ ++ // Parsing elements should succeed. ++ PingCheckConfig config; ++ ASSERT_NO_THROW_LOG(config.parse(json_elements)); ++ ++ // Verify expected values. ++ EXPECT_EQ(scenario.exp_enable_ping_check_, config.getEnablePingCheck()); ++ EXPECT_EQ(scenario.exp_min_ping_requests_, config.getMinPingRequests()); ++ EXPECT_EQ(scenario.exp_reply_timeout_, config.getReplyTimeout()); ++ EXPECT_EQ(scenario.exp_ping_cltt_secs_, config.getPingClttSecs()); ++ EXPECT_EQ(scenario.exp_num_threads_, config.getPingChannelThreads()); ++ } ++} ++ ++// Exercises PingCheckConfig parameter parsing with invalid configuration ++// permutations. ++TEST(PingCheckConfigTest, parseInvalidScenarios) { ++ // Describes a test scenario. ++ struct Scenario { ++ int line_; // Scenario line number ++ string json_; // JSON configuration to parse ++ string exp_message_; // Expected exception message ++ }; ++ ++ // List of test scenarios to run. Most scenario supply ++ // all valid parameters except one in error. This allows ++ // us to verify that no values are changed if any are in error. ++ list<Scenario> scenarios = { ++ { ++ __LINE__, ++ R"( ++ { ++ "enable-ping-check" : false, ++ "min-ping-requests" : 3, ++ "reply-timeout" : 250, ++ "ping-cltt-secs" : 90, ++ "ping-channel-threads" : 4, ++ "bogus" : false ++ })", ++ "spurious 'bogus' parameter" ++ }, ++ { ++ __LINE__, ++ R"( ++ { ++ "enable-ping-check" : "not bool", ++ "min-ping-requests" : 3, ++ "reply-timeout" : 250, ++ "ping-cltt-secs" : 90, ++ "ping-channel-threads" : 4 ++ })", ++ "'enable-ping-check' parameter is not a boolean" ++ }, ++ { ++ __LINE__, ++ R"( ++ { ++ "enable-ping-check" : false, ++ "min-ping-requests" : 0, ++ "reply-timeout" : 250, ++ "ping-cltt-secs" : 90, ++ "ping-channel-threads" : 4 ++ })", ++ "invalid min-ping-requests: '0', must be greater than 0" ++ }, ++ { ++ __LINE__, ++ R"( ++ { ++ "enable-ping-check" : false, ++ "min-ping-requests" : -2, ++ "reply-timeout" : 250, ++ "ping-cltt-secs" : 90, ++ "ping-channel-threads" : 4 ++ })", ++ "invalid min-ping-requests: '-2', must be greater than 0" ++ }, ++ { ++ __LINE__, ++ R"( ++ { ++ "enable-ping-check" : false, ++ "min-ping-requests" : 1, ++ "reply-timeout" : 0, ++ "ping-cltt-secs" : 90, ++ "ping-channel-threads" : 4 ++ })", ++ "invalid reply-timeout: '0', must be greater than 0" ++ }, ++ { ++ __LINE__, ++ R"( ++ { ++ "enable-ping-check" : false, ++ "min-ping-requests" : 1, ++ "reply-timeout" : -77, ++ "ping-cltt-secs" : 90, ++ "ping-channel-threads" : 4 ++ })", ++ "invalid reply-timeout: '-77', must be greater than 0" ++ }, ++ { ++ __LINE__, ++ R"( ++ { ++ "enable-ping-check" : false, ++ "min-ping-requests" : 1, ++ "reply-timeout" : 250, ++ "ping-cltt-secs" : -3, ++ "ping-channel-threads" : 4 ++ })", ++ "invalid ping-cltt-secs: '-3', cannot be less than 0" ++ }, ++ { ++ __LINE__, ++ R"( ++ { ++ "enable-ping-check" : false, ++ "min-ping-requests" : 1, ++ "reply-timeout" : 250, ++ "ping-cltt-secs" : 90, ++ "ping-channel-threads" : -1 ++ })", ++ "invalid ping-channel-threads: '-1', cannot be less than 0" ++ } ++ }; ++ ++ // Iterate over the scenarios. ++ PingCheckConfig default_config; ++ for (auto const& scenario : scenarios) { ++ stringstream oss; ++ oss << "scenario at line: " << scenario.line_; ++ SCOPED_TRACE(oss.str()); ++ ++ // Convert JSON text to a map of parameters. ++ ConstElementPtr json_elements; ++ ASSERT_NO_THROW_LOG(json_elements = Element::fromJSON(scenario.json_)); ++ ++ // Parsing parameters should throw. ++ PingCheckConfig config; ++ ASSERT_THROW_MSG(config.parse(json_elements), dhcp::DhcpConfigError, ++ scenario.exp_message_); ++ ++ // Original values should be intact. ++ EXPECT_EQ(default_config.getEnablePingCheck(), config.getEnablePingCheck()); ++ EXPECT_EQ(default_config.getMinPingRequests(), config.getMinPingRequests()); ++ EXPECT_EQ(default_config.getReplyTimeout(), config.getReplyTimeout()); ++ EXPECT_EQ(default_config.getPingClttSecs(), config.getPingClttSecs()); ++ EXPECT_EQ(default_config.getPingChannelThreads(), config.getPingChannelThreads()); ++ } ++} ++ ++} // end of anonymous namespace +diff --git a/src/hooks/dhcp/ping_check/tests/ping_check_mgr_unittests.cc b/src/hooks/dhcp/ping_check/tests/ping_check_mgr_unittests.cc +new file mode 100644 +index 0000000000..ded13b085c +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/ping_check_mgr_unittests.cc +@@ -0,0 +1,1878 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++/// @file This file contains tests which exercise the PingCheckMgr class. ++#include <config.h> ++ ++#include <ping_check_mgr.h> ++#include <ping_test_utils.h> ++#include <cc/data.h> ++#include <dhcp/pkt4.h> ++#include <dhcpsrv/cfgmgr.h> ++#include <dhcpsrv/lease.h> ++#include <hooks/hooks_manager.h> ++#include <util/chrono_time_utils.h> ++#include <testutils/gtest_utils.h> ++#include <testutils/multi_threading_utils.h> ++ ++#include <gtest/gtest.h> ++#include <mutex> ++#include <chrono> ++ ++using namespace std; ++using namespace isc; ++using namespace isc::data; ++using namespace isc::dhcp; ++using namespace isc::util; ++using namespace isc::asiolink; ++using namespace isc::ping_check; ++using namespace isc::hooks; ++using namespace isc::test; ++using namespace std::chrono; ++using namespace boost::asio::error; ++ ++namespace ph = std::placeholders; ++ ++namespace { ++ ++// Sanity check the basics for production class, PingCheckMgr, single-threaded mode. ++TEST(PingCheckMgr, basicsST) { ++ SKIP_IF(IOServiceTest::notRoot()); ++ MultiThreadingMgr::instance().setMode(false); ++ ++ // Create a multi-threaded manager. ++ IOServicePtr main_ios(new IOService()); ++ PingCheckMgrPtr mgr; ++ ASSERT_NO_THROW_LOG(mgr.reset(new PingCheckMgr(0))); ++ ASSERT_TRUE(mgr); ++ mgr->setIOService(main_ios); ++ ++ // Sanity check the global configuration. More robust tests are done ++ // elsewhere. ++ auto& config = mgr->getGlobalConfig(); ++ EXPECT_TRUE(config->getEnablePingCheck()); ++ EXPECT_EQ(1, config->getMinPingRequests()); ++ EXPECT_EQ(100, config->getReplyTimeout()); ++ EXPECT_EQ(60, config->getPingClttSecs()); ++ EXPECT_EQ(0, config->getPingChannelThreads()); ++ ++ // Verify we report as stopped. ++ EXPECT_FALSE(mgr->isRunning()); ++ EXPECT_TRUE(mgr->isStopped()); ++ EXPECT_FALSE(mgr->isPaused()); ++ ++ // Starting it should be OK. ++ ASSERT_NO_THROW_LOG(mgr->start()); ++ ++ // Verify we report as running. ++ EXPECT_TRUE(mgr->isRunning()); ++ EXPECT_FALSE(mgr->isStopped()); ++ EXPECT_FALSE(mgr->isPaused()); ++ ++ // Pausing it should be harmless. ++ ASSERT_NO_THROW_LOG(mgr->pause()); ++ ++ // Verify we report as running. ++ EXPECT_TRUE(mgr->isRunning()); ++ EXPECT_FALSE(mgr->isStopped()); ++ EXPECT_FALSE(mgr->isPaused()); ++ ++ // Resuming it should be harmless. ++ ASSERT_NO_THROW_LOG(mgr->resume()); ++ ++ // Verify we report as running. ++ EXPECT_TRUE(mgr->isRunning()); ++ EXPECT_FALSE(mgr->isStopped()); ++ EXPECT_FALSE(mgr->isPaused()); ++ ++ // Stopping it should be fine ++ ASSERT_NO_THROW_LOG(mgr->stop()); ++ ++ // Verify we report as stopped. ++ EXPECT_FALSE(mgr->isRunning()); ++ EXPECT_TRUE(mgr->isStopped()); ++ EXPECT_FALSE(mgr->isPaused()); ++ ++ // Re-starting it should be OK. ++ ASSERT_NO_THROW_LOG(mgr->start()); ++ ++ // Verify we report as running. ++ EXPECT_TRUE(mgr->isRunning()); ++ EXPECT_FALSE(mgr->isStopped()); ++ EXPECT_FALSE(mgr->isPaused()); ++ ++ // Calling destructor when its running should be OK. ++ ASSERT_NO_THROW_LOG(mgr.reset()); ++ ++ main_ios->stopAndPoll(); ++} ++ ++// Sanity check the basics for production class, PingCheckMgr. Bulk of testing ++// is done with test derivation, TestPingCheckMgr. ++TEST(PingCheckMgr, basicsMT) { ++ SKIP_IF(IOServiceTest::notRoot()); ++ MultiThreadingTest mt; ++ ++ // Create a multi-threaded manager. ++ IOServicePtr main_ios(new IOService()); ++ PingCheckMgrPtr mgr; ++ ASSERT_NO_THROW_LOG(mgr.reset(new PingCheckMgr(3))); ++ ASSERT_TRUE(mgr); ++ mgr->setIOService(main_ios); ++ ++ // Sanity check the global configuration. More robust tests are done ++ // elsewhere. ++ auto& config = mgr->getGlobalConfig(); ++ EXPECT_TRUE(config->getEnablePingCheck()); ++ EXPECT_EQ(1, config->getMinPingRequests()); ++ EXPECT_EQ(100, config->getReplyTimeout()); ++ EXPECT_EQ(60, config->getPingClttSecs()); ++ EXPECT_EQ(3, config->getPingChannelThreads()); ++ ++ // It should not be running yet. ++ EXPECT_FALSE(mgr->isRunning()); ++ EXPECT_TRUE(mgr->isStopped()); ++ EXPECT_FALSE(mgr->isPaused()); ++ ++ // Starting it should be OK. ++ ASSERT_NO_THROW_LOG(mgr->start()); ++ ++ // Verify it's running. ++ EXPECT_TRUE(mgr->isRunning()); ++ EXPECT_FALSE(mgr->isStopped()); ++ EXPECT_FALSE(mgr->isPaused()); ++ ++ // Pausing it should be fine. ++ ASSERT_NO_THROW_LOG(mgr->pause()); ++ ++ // Verify it's paused. ++ EXPECT_FALSE(mgr->isRunning()); ++ EXPECT_FALSE(mgr->isStopped()); ++ EXPECT_TRUE(mgr->isPaused()); ++ ++ // Resuming it should be fine. ++ ASSERT_NO_THROW_LOG(mgr->resume()); ++ ++ // Verify it's running. ++ EXPECT_TRUE(mgr->isRunning()); ++ EXPECT_FALSE(mgr->isStopped()); ++ EXPECT_FALSE(mgr->isPaused()); ++ ++ // Stopping it should be fine ++ ASSERT_NO_THROW_LOG(mgr->stop()); ++ ++ // It should not be running. ++ EXPECT_FALSE(mgr->isRunning()); ++ EXPECT_TRUE(mgr->isStopped()); ++ EXPECT_FALSE(mgr->isPaused()); ++ ++ // Re-starting it should be OK. ++ ASSERT_NO_THROW_LOG(mgr->start()); ++ ++ // Verify it's running. ++ EXPECT_TRUE(mgr->isRunning()); ++ EXPECT_FALSE(mgr->isStopped()); ++ EXPECT_FALSE(mgr->isPaused()); ++ ++ // Calling destructor when its running should be OK. ++ ASSERT_NO_THROW_LOG(mgr.reset()); ++} ++ ++// Verify basic behavior of PingCheckMgr::configure(). ++TEST(PingCheckMgr, configure) { ++ // Create a manager. ++ IOServicePtr main_ios(new IOService()); ++ PingCheckMgrPtr mgr; ++ ASSERT_NO_THROW_LOG(mgr.reset(new PingCheckMgr())); ++ ASSERT_TRUE(mgr); ++ ++ // Verify initial global configuration. ++ auto& default_config = mgr->getGlobalConfig(); ++ EXPECT_TRUE(default_config->getEnablePingCheck()); ++ EXPECT_EQ(1, default_config->getMinPingRequests()); ++ EXPECT_EQ(100, default_config->getReplyTimeout()); ++ EXPECT_EQ(60, default_config->getPingClttSecs()); ++ EXPECT_EQ(0, default_config->getPingChannelThreads()); ++ ++ //Create a valid configuration. ++ std::string valid_json_cfg = ++ R"({ ++ "enable-ping-check" : false, ++ "min-ping-requests" : 2, ++ "reply-timeout" : 250, ++ "ping-cltt-secs" : 90, ++ "ping-channel-threads" : 3 ++ })"; ++ ++ auto parameters = Element::fromJSON(valid_json_cfg); ++ ++ // Parse it. ++ ASSERT_NO_THROW_LOG(mgr->configure(parameters)); ++ ++ // Verify updated global configuration. ++ auto& config = mgr->getGlobalConfig(); ++ ASSERT_TRUE(config); ++ EXPECT_FALSE(config->getEnablePingCheck()); ++ EXPECT_EQ(2, config->getMinPingRequests()); ++ EXPECT_EQ(250, config->getReplyTimeout()); ++ EXPECT_EQ(90, config->getPingClttSecs()); ++ EXPECT_EQ(3, config->getPingChannelThreads()); ++ ++ // Create an invalid configuration. ++ std::string invalid_json_cfg = ++ R"({ ++ "enable-ping-check" : true, ++ "min-ping-requests" : 4, ++ "reply-timeout" : 500, ++ "ping-cltt-secs" : 45, ++ "ping-channel-threads" : 6, ++ "bogus" : 0 ++ })"; ++ ++ parameters = Element::fromJSON(invalid_json_cfg); ++ ++ // Parsing it should throw. ++ ASSERT_THROW_MSG(mgr->configure(parameters), DhcpConfigError, "spurious 'bogus' parameter"); ++ ++ // Verify configuration values were left unchanged. ++ auto& final_config = mgr->getGlobalConfig(); ++ ASSERT_TRUE(final_config); ++ EXPECT_EQ(final_config->getEnablePingCheck(), config->getEnablePingCheck()); ++ EXPECT_EQ(final_config->getMinPingRequests(), config->getMinPingRequests()); ++ EXPECT_EQ(final_config->getReplyTimeout(), config->getReplyTimeout()); ++ EXPECT_EQ(final_config->getPingClttSecs(), config->getPingClttSecs()); ++ EXPECT_EQ(final_config->getPingChannelThreads(), config->getPingChannelThreads()); ++} ++ ++/// @brief Defines a callback to invoke at the bottom of sendCompleted() ++typedef std::function<void(const ICMPMsgPtr& echo, bool send_failed)> SendCompletedCallback; ++ ++/// @brief Defines a callback to invoke at the bottom of replyReceived() ++typedef std::function<void(const ICMPMsgPtr& reply)> ReplyReceivedCallback; ++ ++/// @brief Testable derivation of PingCheckMgr ++/// ++/// Uses a TestablePingChannel to facilitate more robust testing. ++class TestablePingCheckMgr : public PingCheckMgr { ++public: ++ /// @brief Constructor. ++ /// ++ /// @param num_threads number of threads to use in the thread pool (0 means follow ++ /// core thread pool size) ++ /// @param min_echos minimum number of ECHO REQUESTs sent without replies ++ /// received required to declare an address free to offer. Defaults to 1, ++ /// must be greater than zero. ++ /// @param reply_timeout maximum number of milliseconds to wait for an ++ /// ECHO REPLY after an ECHO REQUEST has been sent. Defaults to 100, ++ TestablePingCheckMgr(uint32_t num_threads, uint32_t min_echos = 1, ++ uint32_t reply_timeout = 100) ++ : PingCheckMgr(num_threads, min_echos, reply_timeout), ++ post_send_completed_cb_(SendCompletedCallback()), ++ post_reply_received_cb_(ReplyReceivedCallback()) { ++ } ++ ++ /// @brief Destructor. ++ virtual ~TestablePingCheckMgr() { ++ post_send_completed_cb_ = SendCompletedCallback(); ++ post_reply_received_cb_ = ReplyReceivedCallback(); ++ if (getIOService()) { ++ getIOService()->stopAndPoll(); ++ } ++ } ++ ++ /// @brief Fetch the current channel instance. ++ /// ++ /// @return pointer to the TestablePingChannel instance (or an empty pointer). ++ TestablePingChannelPtr getChannel() { ++ return (boost::dynamic_pointer_cast<TestablePingChannel>(channel_)); ++ } ++ ++ /// @brief Fetches the manager's context store. ++ /// ++ /// @return Pointer to the PingContextStore. ++ PingContextStorePtr getStore() { ++ return (store_); ++ } ++ ++ /// @brief Fetches the expiration timer's current interval (in milliseconds). ++ /// ++ /// @return current interval as long or 0L if the timer is not currently ++ /// running or does not exist. ++ long getExpirationTimerInterval() { ++ if (expiration_timer_) { ++ return (expiration_timer_->getInterval()); ++ } ++ ++ return (0); ++ } ++ ++protected: ++ /// @brief Creates a TestablePingChannel instance. ++ /// ++ /// This override the base case creator. ++ /// ++ /// @param io_service IOService that will drive the channel. ++ /// @return pointer to the newly created channel. ++ virtual PingChannelPtr createChannel(asiolink::IOServicePtr io_service) { ++ return (TestablePingChannelPtr( ++ new TestablePingChannel(io_service, ++ std::bind(&PingCheckMgr::nextToSend, this, ph::_1), ++ std::bind(&TestablePingCheckMgr::sendCompleted, ++ this, ph::_1, ph::_2), ++ std::bind(&TestablePingCheckMgr::replyReceived, this, ph::_1), ++ std::bind(&PingCheckMgr::channelShutdown, this)))); ++ } ++ ++public: ++ /// @brief Fetches the current size of the parking lot. ++ /// ++ /// @return size_t containing the number of entries parked. ++ size_t parkingLotSize() const { ++ auto const& parking_lot = ServerHooks::getServerHooks().getParkingLotPtr("lease4_offer"); ++ return (parking_lot->size()); ++ } ++ ++ /// @brief Callback passed to PingChannel to invoke when an ECHO REQUEST ++ /// send has completed. ++ /// ++ /// -# Invokes the base class implementation ++ /// -# Invokes an optional callback ++ /// ++ /// @param echo ICMP echo message that is sent. ++ /// @param send_failed True if the send completed with a non-fatal error, ++ /// false otherwise. ++ virtual void sendCompleted(const ICMPMsgPtr& echo, bool send_failed) { ++ // Call the production callback. ++ PingCheckMgr::sendCompleted(echo, send_failed); ++ ++ // Invoke the post check, if one. ++ if (post_send_completed_cb_) { ++ (post_send_completed_cb_)(echo, send_failed); ++ } ++ } ++ ++ /// @brief Callback invoked by the channel to process received ICMP messages. ++ /// ++ /// -# Invokes the base class implementation ++ /// -# Pauses the test IOService thread and returns if the parking lot is empty ++ /// -# Invokes an option callback passing in the reply received ++ /// ++ /// @param reply pointer to the ICMP message received. ++ virtual void replyReceived(const ICMPMsgPtr& reply) { ++ if (reply->getType() == ICMPMsg::ECHO_REQUEST) { ++ return; ++ } ++ ++ // If we're routing loopback messages, look up the original address based ++ // on the sequence number and use it as the reply's source address. ++ if (getChannel()->route_loopback_) { ++ IOAddress address = getChannel()->loopback_map_.find(reply->getSequence()); ++ if (address != IOAddress::IPV4_ZERO_ADDRESS()) { ++ reply->setSource(address); ++ } ++ } ++ ++ // Call the production callback. ++ PingCheckMgr::replyReceived(reply); ++ ++ // Invoke the post check, if one. ++ if (post_reply_received_cb_) { ++ (post_reply_received_cb_)(reply); ++ } ++ } ++ ++ /// @brief Fetches the thread pool (if it exists). ++ /// ++ /// @return pointer to theIoServiceThreadPool. Will be empty ++ /// in ST mode or if the manager has not been started. ++ asiolink::IoServiceThreadPoolPtr getThreadPool() { ++ return (thread_pool_); ++ } ++ ++ /// @brief Sets the network_state object. ++ /// ++ /// @param network_state pointer to a NetworkState instance. ++ void setNetworkState(NetworkStatePtr network_state) { ++ network_state_ = network_state; ++ } ++ ++ /// @brief Callback to invoke at the bottom of sendCompleted(). ++ SendCompletedCallback post_send_completed_cb_; ++ ++ /// @brief Callback to invoke at the bottom of replyReceived(). ++ ReplyReceivedCallback post_reply_received_cb_; ++}; ++ ++/// @brief Defines a shared pointer to a PingCheckMgr. ++typedef boost::shared_ptr<TestablePingCheckMgr> TestablePingCheckMgrPtr; ++ ++/// @brief Holds a lease and its associated query. ++struct LeaseQueryPair { ++public: ++ /// @brief Constructor. ++ /// ++ /// @param lease pointer to the lease. ++ /// @param query pointer to the query. ++ LeaseQueryPair(Lease4Ptr lease, Pkt4Ptr query) : lease_(lease), query_(query) { ++ }; ++ ++ /// @brief Pointer to the lease. ++ Lease4Ptr lease_; ++ ++ /// @brief Pointer to the query. ++ Pkt4Ptr query_; ++}; ++ ++/// @brief Container of leases and their associated queries. ++typedef std::vector<LeaseQueryPair> LeaseQueryPairs; ++ ++/// @brief Test fixture for exercising PingCheckMgr. ++/// ++/// Uses a TestablePingCheckMgr instance for all tests and ++/// provides numerous helper functions. ++class PingCheckMgrTest : public IOServiceTest { ++public: ++ /// @brief Constructor. ++ PingCheckMgrTest() : mgr_(), lease_query_pairs_(), mutex_(new mutex()), ++ test_start_time_(PingContext::now()), unparked_(0) { ++ MultiThreadingMgr::instance().setMode(false); ++ }; ++ ++ /// @brief Destructor. ++ virtual ~PingCheckMgrTest() { ++ test_timer_.cancel(); ++ test_io_service_->stopAndPoll(); ++ MultiThreadingMgr::instance().setMode(false); ++ } ++ ++ /// @brief Pretest setup. ++ /// ++ /// Registers the hook point and creates its parking lot. ++ virtual void SetUp() { ++ HooksManager::registerHook("lease4_offer"); ++ parking_lot_ = boost::make_shared<ParkingLotHandle>( ++ ServerHooks::getServerHooks().getParkingLotPtr("lease4_offer")); ++ } ++ ++ /// @brief Ensure we stop cleanly. ++ virtual void TearDown() { ++ if (mgr_) { ++ mgr_->stop(); ++ } ++ ++ HooksManager::clearParkingLots(); ++ } ++ ++ /// @brief Creates the test's manager instance. ++ /// ++ /// @param num_threads number of threads in the thread pool. ++ /// @param min_echos minimum number of echos per ping check. ++ /// @param reply_timeout reply timeout per ping. ++ /// @param start_and_pause when false, the manager is only created, ++ /// when true it is created, started and then paused. This allows ++ /// manipulation of context store contents while the threads are doing ++ /// no work. ++ void createMgr(uint32_t num_threads, ++ uint32_t min_echos = 1, ++ uint32_t reply_timeout = 100, ++ bool start_and_pause = false) { ++ ASSERT_NO_THROW_LOG( ++ mgr_.reset(new TestablePingCheckMgr(num_threads, min_echos, reply_timeout))); ++ ASSERT_TRUE(mgr_); ++ mgr_->setIOService(test_io_service_); ++ ++ if (start_and_pause) { ++ ASSERT_NO_THROW_LOG(mgr_->start()); ++ ++ if (!MultiThreadingMgr::instance().getMode()) { ++ ASSERT_FALSE(mgr_->getThreadPool()); ++ } else { ++ ASSERT_TRUE(mgr_->getThreadPool()); ++ ASSERT_NO_THROW_LOG(mgr_->pause()); ++ ASSERT_TRUE(mgr_->isPaused()); ++ } ++ } ++ } ++ ++ /// @brief Add a new lease and query pair to the test's list of lease query pairs. ++ /// ++ /// Creates a bare-bones DHCPv4 lease and DHCPDISCOVER, wraps them in a ++ /// LeaseQueryPair and adds the pair to the end of the test's internal ++ /// list of pairs, lease_query_pairs_. ++ /// ++ /// @param target IOAddress of the lease. ++ /// @param transid transaction id of the query. ++ /// ++ /// @return A copy of the newly created pair. ++ LeaseQueryPair makeLeaseQueryPair(IOAddress target, uint16_t transid) { ++ // Make a lease and query pair ++ Lease4Ptr lease(new Lease4()); ++ lease->addr_ = IOAddress(target); ++ Pkt4Ptr query(new Pkt4(DHCPDISCOVER, transid)); ++ LeaseQueryPair lqp(lease, query); ++ lease_query_pairs_.push_back(lqp); ++ return (lqp); ++ } ++ ++ /// @brief Start ping checks for a given number of targets. ++ /// ++ /// The function first creates and parks the given number of targets, and ++ /// then starts a ping check for each of them. Parking them all first ++ /// establishes the number of ping checks expected to be conducted during ++ /// the test prior to actually starting any of them. This avoids the ++ /// parking lot from becoming empty part way through the test. ++ /// ++ /// It unpark callback lambda increments the unparked_ counter and then ++ /// pushes the unparked lease/query pair to either the list of frees ++ /// or list of declines. ++ /// ++ /// @param num_targets number of target ip addresses to ping check. ++ /// @param start_address starting target address. Defaults to 127.0.0.1. ++ /// ++ /// @return last target address started. ++ IOAddress startTargets(size_t num_targets, IOAddress start_address = IOAddress("127.0.0.1")) { ++ IOAddress target = start_address; ++ for (auto i = 0; i < num_targets; ++i) { ++ auto lqp = makeLeaseQueryPair(IOAddress(target), i+1); ++ HooksManager::park("lease4_offer", lqp.query_, ++ [this, lqp]() { ++ MultiThreadingLock lock(*mutex_); ++ ++unparked_; ++ auto handle = lqp.query_->getCalloutHandle(); ++ bool offer_address_in_use; ++ handle->getArgument("offer_address_in_use", offer_address_in_use); ++ offer_address_in_use ? declines_.push_back(lqp) : frees_.push_back(lqp); ++ }); ++ ++ try { ++ mgr_->startPing(lqp.lease_, lqp.query_, parking_lot_); ++ } catch (const std::exception& ex) { ++ ADD_FAILURE() << "startPing threw: " << ex.what(); ++ } ++ ++ target = IOAddress::increase(target); ++ } ++ ++ return(target); ++ } ++ ++ /// @brief Fetches the context, by lease address, from the store for a ++ /// given lease query pair. ++ /// ++ /// @param lqp LeaseQueryPair for which the context is desired. ++ /// @return pointer to the found context or an empty pointer. ++ PingContextPtr getContext(const LeaseQueryPair& lqp) { ++ return (getContext(lqp.lease_->addr_)); ++ } ++ ++ /// @brief Fetches the context, by lease address, from the store for address. ++ /// ++ /// @param address lease ip address for which the context is desired. ++ /// @return pointer to the found context or an empty pointer. ++ PingContextPtr getContext(const IOAddress& address) { ++ return (mgr_->getStore()->getContextByAddress(address)); ++ } ++ ++ /// @brief Updates a context in the store. ++ /// ++ /// @param context context to update. ++ void updateContext(PingContextPtr& context) { ++ ASSERT_NO_THROW_LOG(mgr_->getStore()->updateContext(context)); ++ } ++ ++ /// @brief Tests equality of two timestamps within a given tolerance. ++ /// ++ /// The two time stamps are considered equal if the absolute value of their ++ /// difference is between 0 and the specified tolerance (inclusive). ++ /// ++ /// @param lhs first TimeStamp to compare. ++ /// @param rhs second TimeStamp to compare. ++ /// @param tolerance margin of difference allowed for equality in milliseconds. ++ /// Defaults to 10. ++ /// ++ /// @return True if the time stamps are "equal", false otherwise. ++ bool fuzzyEqual(const TimeStamp& lhs, const TimeStamp& rhs, long tolerance = 10) { ++ auto diff = abs(duration_cast<milliseconds>(lhs - rhs).count()); ++ return (diff >= 0 && diff <= tolerance); ++ } ++ ++ /// @brief Tests equality of two longs within a given tolerance. ++ /// ++ /// The two values are considered equal if the absolute value of their ++ /// difference is between 0 and the specified tolerance (inclusive). ++ /// ++ /// @param lhs first value to compare. ++ /// @param rhs second value to compare. ++ /// @param tolerance margin of difference allowed for equality in milliseconds. ++ /// Defaults to 10. ++ /// ++ /// @return True if the time values are "equal", false otherwise. ++ bool fuzzyEqual(const long& lhs, const long& rhs, long tolerance = 10) { ++ auto diff = abs(lhs - rhs); ++ return (diff >= 0 && diff <= tolerance); ++ } ++ ++ /// @brief Creates an ECHO REQUEST message from a given address. ++ /// ++ /// @param target ip address to use as the echo's destination address. ++ /// @return Pointer to the new message. ++ ICMPMsgPtr makeEchoRequest(const IOAddress& target) { ++ ICMPMsgPtr msg(new ICMPMsg()); ++ msg->setType(ICMPMsg::ECHO_REQUEST); ++ msg->setDestination(IOAddress(target)); ++ msg->setSource(IOAddress("127.0.0.1")); ++ return (msg); ++ } ++ ++ /// @brief Creates an ECHO_REPLY message from a given address. ++ /// ++ /// @param from ip address to use as the reply's source address. ++ /// @return Pointer to the new message. ++ ICMPMsgPtr makeEchoReply(const IOAddress& from) { ++ ICMPMsgPtr msg(new ICMPMsg()); ++ msg->setType(ICMPMsg::ECHO_REPLY); ++ msg->setSource(IOAddress(from)); ++ msg->setDestination(IOAddress("127.0.0.1")); ++ return (msg); ++ } ++ ++ /// @brief Creates an TARGET_UNREACHABLE message from a given address. ++ /// ++ /// @param target ip address to use as the reply's source address. ++ /// @return Pointer to the new message. ++ ICMPMsgPtr makeUnreachable(const IOAddress& target) { ++ // Make the TARGET_UNREACHABLE message first. ++ ICMPMsgPtr msg(new ICMPMsg()); ++ msg->setType(ICMPMsg::TARGET_UNREACHABLE); ++ msg->setSource(IOAddress("127.0.0.1")); ++ msg->setDestination(IOAddress("127.0.0.1")); ++ ++ // Now embed the ping target's "original" echo into the unreachable ++ // message's payload. This includes the IP header followed by the ++ // ECHO REQUEST. First make the IP header and add it to the payload. ++ // We only set values we care about. ++ struct ip ip_header; ++ memset((void *)(&ip_header), 0x00, sizeof(struct ip)); ++ ip_header.ip_v = 4; ++ ip_header.ip_hl = 5; /* shift left twice = 20 */ ++ ip_header.ip_len = 48; /* ip_header + echo length */ ++ ip_header.ip_dst.s_addr = htonl(target.toUint32()); ++ ip_header.ip_src.s_addr = htonl(msg->getSource().toUint32()); ++ msg->setPayload((const uint8_t*)(&ip_header), sizeof(struct ip)); ++ ++ // Now make the ECHO_REQUEST, pack it and add that to the payload. ++ ICMPMsgPtr echo = makeEchoRequest(target); ++ ICMPPtr packed_echo = echo->pack(); ++ msg->setPayload((const uint8_t*)(packed_echo.get()), sizeof(struct icmp)); ++ ++ return (msg); ++ } ++ ++ /// @brief Compares a LeaseQueryPair collection to the internal collection ++ /// of pairs created (see makeLeaseQueryPairs()). ++ /// ++ /// @param test_collection Collection of pairs to compare against those in ++ /// the creation collection. ++ void compareLeaseQueryPairs(LeaseQueryPairs& test_collection) { ++ // We should have as many in the test_collection as we have creation ++ // collection. ++ ASSERT_EQ(test_collection.size(), lease_query_pairs_.size()); ++ ++ // Order is not guaranteed so we sort both lists then compare. ++ std::sort(test_collection.begin(), test_collection.end(), ++ [](LeaseQueryPair const& a, LeaseQueryPair const& b) ++ { return (a.lease_->addr_ < b.lease_->addr_); }); ++ ++ std::sort(lease_query_pairs_.begin(), lease_query_pairs_.end(), ++ [](LeaseQueryPair const& a, LeaseQueryPair const& b) ++ { return (a.lease_->addr_ < b.lease_->addr_); }); ++ ++ auto dpi = test_collection.begin(); ++ for (auto const& lqpi : lease_query_pairs_) { ++ ASSERT_EQ((*dpi).lease_->addr_, lqpi.lease_->addr_); ++ ++dpi; ++ } ++ } ++ ++ /// @brief Exercises the operational basics: create, start, and stop ++ /// for TestablePingCheckMgr. ++ /// ++ /// @param num_threads number of threads in the thread pool. ++ void testOperationalBasics(size_t num_threads) { ++ SKIP_IF(notRoot()); ++ ++ // Create manager with the given number of threads. ++ ASSERT_NO_THROW_LOG(createMgr(num_threads)); ++ ASSERT_TRUE(mgr_); ++ ++ // Should not be running. ++ EXPECT_FALSE(mgr_->isRunning()); ++ EXPECT_TRUE(mgr_->isStopped()); ++ EXPECT_FALSE(mgr_->isPaused()); ++ ++ // Channel should not yet exist. ++ ASSERT_FALSE(mgr_->getChannel()); ++ ++ // Start the manager. ++ ASSERT_NO_THROW_LOG(mgr_->start()); ++ ++ // Thread pool should exist in MT mode only. ++ if (MultiThreadingMgr::instance().getMode()) { ++ ASSERT_TRUE(mgr_->getThreadPool()); ++ } else { ++ ASSERT_FALSE(mgr_->getThreadPool()); ++ } ++ ++ // Should be running. ++ EXPECT_TRUE(mgr_->isRunning()); ++ EXPECT_FALSE(mgr_->isStopped()); ++ EXPECT_FALSE(mgr_->isPaused()); ++ ++ // Channel should exist and be open. ++ auto channel = mgr_->getChannel(); ++ ASSERT_TRUE(channel); ++ ASSERT_TRUE(channel->isOpen()); ++ ++ // Context store should exist and be empty. ++ auto store = mgr_->getStore(); ++ ASSERT_TRUE(store); ++ auto pings = store->getAll(); ++ ASSERT_EQ(0, pings->size()); ++ ++ // Destruction should be graceful. ++ ASSERT_NO_THROW_LOG(mgr_.reset()); ++ } ++ ++ /// @brief Verifies that startPing() creates a new context in the store and ++ /// it can be fetched with the nextToSend() callback. ++ void testStartPing() { ++ SKIP_IF(notRoot()); ++ ++ // Create manager with thread-pool size of 3, min_echos 2, reply_timeout 250 ms. ++ // ST mode should ingore requested thread number. ++ ASSERT_NO_THROW_LOG(createMgr(3, 2, 250)); ++ ASSERT_TRUE(mgr_); ++ ++ // Make a lease and query pair ++ auto lqp1 = makeLeaseQueryPair(IOAddress("127.0.0.101"), 101); ++ ++ // Channel isn't open, startPing should throw. ++ ASSERT_THROW_MSG(mgr_->startPing(lqp1.lease_, lqp1.query_, parking_lot_), InvalidOperation, ++ "PingCheckMgr::startPing() - channel isn't open"); ++ ++ // Start the manager. This will open the channel. ++ ASSERT_NO_THROW_LOG(mgr_->start()); ++ ASSERT_TRUE(mgr_->isRunning()); ++ ++ if (mgr_->getThreadPool()) { ++ // Pause the manager so startPing() will succeed but no events will occur. ++ // This should let us add contexts that sit in WAITING_TO_SEND state. ++ ASSERT_NO_THROW_LOG(mgr_->pause()); ++ ASSERT_TRUE(mgr_->isPaused()); ++ } ++ ++ // Call startPing() again. It should work. ++ ASSERT_NO_THROW_LOG(mgr_->startPing(lqp1.lease_, lqp1.query_, parking_lot_)); ++ ++ // Calling startPing() on the same lease should fail, duplicates not allowed. ++ ASSERT_THROW_MSG(mgr_->startPing(lqp1.lease_, lqp1.query_, parking_lot_), DuplicateContext, ++ "PingContextStore::addContex: context already exists for: 127.0.0.101"); ++ ++ // Our context should be present. ++ auto const& store = mgr_->getStore(); ++ auto pings = store->getAll(); ++ ASSERT_EQ(1, pings->size()); ++ PingContextPtr context1; ++ ASSERT_NO_THROW_LOG(context1 = store->getContextByAddress(lqp1.lease_->addr_)); ++ ASSERT_TRUE(context1); ++ ++ // Verify the context's state. ++ EXPECT_EQ(2, context1->getMinEchos()); ++ EXPECT_EQ(250, context1->getReplyTimeout()); ++ EXPECT_EQ(0, context1->getEchosSent()); ++ EXPECT_EQ(PingContext::EMPTY_TIME(), context1->getLastEchoSentTime()); ++ EXPECT_LE(test_start_time_, context1->getSendWaitStart()); ++ EXPECT_EQ(PingContext::EMPTY_TIME(), context1->getNextExpiry()); ++ EXPECT_LE(test_start_time_, context1->getCreatedTime()); ++ EXPECT_EQ(lqp1.lease_, context1->getLease()); ++ EXPECT_EQ(lqp1.query_, context1->getQuery()); ++ EXPECT_EQ(PingContext::WAITING_TO_SEND, context1->getState()); ++ ++ // Sleep a bit to make sure there's a difference in context times. ++ usleep(5); ++ ++ // Make a second lease and query pair ++ auto lqp2 = makeLeaseQueryPair(IOAddress("127.0.0.102"), 102); ++ ++ // Start a ping for lease2. ++ ASSERT_NO_THROW_LOG(mgr_->startPing(lqp2.lease_, lqp2.query_, parking_lot_)); ++ ++ // Both contexts should be present. ++ pings = store->getAll(); ++ ASSERT_EQ(2, pings->size()); ++ ++ // Fetch the second context by address. ++ PingContextPtr context2; ++ ASSERT_NO_THROW_LOG(context2 = store->getContextByAddress(lqp2.lease_->addr_)); ++ ASSERT_TRUE(context2); ++ ++ // Verify the second context's state. ++ EXPECT_EQ(2, context2->getMinEchos()); ++ EXPECT_EQ(250, context2->getReplyTimeout()); ++ EXPECT_EQ(0, context2->getEchosSent()); ++ EXPECT_EQ(PingContext::EMPTY_TIME(), context2->getLastEchoSentTime()); ++ // Its send_wait_start_time_ should be more recent than context1. ++ EXPECT_LE(context1->getSendWaitStart(), context2->getSendWaitStart()); ++ EXPECT_EQ(PingContext::EMPTY_TIME(), context2->getNextExpiry()); ++ // Its created_time_ should be more recent than context1. ++ EXPECT_LE(context1->getCreatedTime(), context2->getCreatedTime()); ++ EXPECT_EQ(lqp2.lease_, context2->getLease()); ++ EXPECT_EQ(lqp2.query_, context2->getQuery()); ++ EXPECT_EQ(PingContext::WAITING_TO_SEND, context2->getState()); ++ } ++ ++ /// @brief Exercises PingCheckMgr::nextToSend(). ++ void testNextToSend() { ++ SKIP_IF(notRoot()); ++ ++ // Create a paused manager. 3 threads, 2 echos, 250 ms timeout. ++ // ST mode should ingore requested thread number. ++ createMgr(3, 2, 250, true); ++ ++ // Calling nextToSend() should return false. ++ IOAddress next("0.0.0.0"); ++ ASSERT_FALSE(mgr_->nextToSend(next)); ++ ++ // Now let's start 3 contexts. ++ size_t num_targets = 3; ++ IOAddress target("127.0.0.1"); ++ for (auto i = 0; i < num_targets; ++i) { ++ auto lqp = makeLeaseQueryPair(IOAddress(target), i+1); ++ ++ // Call startPing(). ++ ASSERT_NO_THROW_LOG(mgr_->startPing(lqp.lease_, lqp.query_, parking_lot_)); ++ target = IOAddress::increase(target); ++ ++ PingContextPtr context = getContext(lqp); ++ ASSERT_TRUE(context); ++ ++ // Verify the context's initial state is correct. ++ EXPECT_EQ(0, context->getEchosSent()); ++ EXPECT_EQ(PingContext::EMPTY_TIME(), context->getLastEchoSentTime()); ++ EXPECT_LE(test_start_time_, context->getSendWaitStart()); ++ EXPECT_EQ(PingContext::EMPTY_TIME(), context->getNextExpiry()); ++ EXPECT_LE(test_start_time_, context->getCreatedTime()); ++ EXPECT_EQ(PingContext::WAITING_TO_SEND, context->getState()); ++ ++ // Sleep a few before we add the next one to ensure ordering by ++ // time is consistent. ++ usleep(5); ++ } ++ ++ // Consecutive calls to nextToSend() should return target addresses ++ // in the order they were created. ++ for (auto const& lqp : lease_query_pairs_) { ++ // Next to send should return the next address to send. ++ ASSERT_TRUE(mgr_->nextToSend(next)); ++ ++ // It should match the lease as created. ++ ASSERT_EQ(next, lqp.lease_->addr_); ++ ++ // Fetch the corresponding context. ++ PingContextPtr context = getContext(next); ++ ASSERT_TRUE(context); ++ ++ // Verify the state has properly moved to SENDING. ++ EXPECT_EQ(0, context->getEchosSent()); ++ EXPECT_EQ(PingContext::EMPTY_TIME(), context->getLastEchoSentTime()); ++ EXPECT_EQ(PingContext::EMPTY_TIME(), context->getNextExpiry()); ++ EXPECT_EQ(PingContext::SENDING, context->getState()); ++ } ++ ++ // A final call to nextToSend should return false. ++ ASSERT_FALSE(mgr_->nextToSend(next)); ++ } ++ ++ /// @brief Exercises PingCheckMgr::setNextExpiration. ++ void testSetNextExpiration() { ++ SKIP_IF(notRoot()); ++ ++ // Create a paused manager. 3 threads, 2 echos, 500 ms timeout. ++ // ST mode should ingore requested thread number. ++ createMgr(3, 2, 500, true); ++ ++ // Should not have an expiration time, timer should not be running. ++ ASSERT_EQ(PingContext::EMPTY_TIME(), mgr_->getNextExpiry()); ++ ASSERT_EQ(mgr_->getExpirationTimerInterval(), 0); ++ ++ // Now let's start 3 contexts. ++ size_t num_targets = 3; ++ IOAddress target("127.0.0.1"); ++ for (auto i = 0; i < num_targets; ++i) { ++ auto lqp = makeLeaseQueryPair(IOAddress(target), i+1); ++ ++ // Call startPing(). ++ ASSERT_NO_THROW_LOG(mgr_->startPing(lqp.lease_, lqp.query_, parking_lot_)); ++ target = IOAddress::increase(target); ++ } ++ ++ // Still should not have an expiration time nor running timer. ++ ASSERT_EQ(PingContext::EMPTY_TIME(), mgr_->getNextExpiry()); ++ EXPECT_EQ(mgr_->getExpirationTimerInterval(), 0); ++ ++ // Simulate a completed send for the second context. ++ PingContextPtr context2; ++ context2 = getContext(lease_query_pairs_[1]); ++ ASSERT_TRUE(context2); ++ context2->beginWaitingForReply(test_start_time_ - milliseconds(50)); ++ updateContext(context2); ++ ++ // Call setNextExpiration(). ++ ASSERT_NO_THROW_LOG(mgr_->setNextExpiration()); ++ ++ // Refresh the context. ++ context2 = getContext(lease_query_pairs_[1]); ++ ++ // Verify the mgr has the same next expiration as the context and ++ // that the expiration timer is running. Allow for some fudge in ++ // the checks. ++ auto original_mgr_expiry = mgr_->getNextExpiry(); ++ EXPECT_TRUE(fuzzyEqual(original_mgr_expiry, context2->getNextExpiry())); ++ ++ auto original_interval = mgr_->getExpirationTimerInterval(); ++ EXPECT_TRUE(fuzzyEqual(original_interval, 450)); ++ ++ // Simulate a completed send for the third context. ++ PingContextPtr context3; ++ context3 = getContext(lease_query_pairs_[2]); ++ ASSERT_TRUE(context3); ++ context3->beginWaitingForReply(); ++ updateContext(context3); ++ ++ // Call setNextExpiration(). ++ ASSERT_NO_THROW_LOG(mgr_->setNextExpiration()); ++ ++ // Refresh the context. ++ context3 = getContext(lease_query_pairs_[2]); ++ ++ // Context3 should have a later expiration than context2. ++ EXPECT_LT(context2->getNextExpiry(), context3->getNextExpiry()); ++ ++ // Expiration and timer should still match the original values based on ++ // the second context. ++ EXPECT_TRUE(fuzzyEqual(mgr_->getNextExpiry(), original_mgr_expiry)); ++ EXPECT_EQ(mgr_->getExpirationTimerInterval(), original_interval); ++ ++ // Simulate a completed send for the first context but use a smaller ++ // timeout and back date it. ++ PingContextPtr context1; ++ context1 = getContext(lease_query_pairs_[0]); ++ ASSERT_TRUE(context1); ++ context1->setReplyTimeout(50); ++ context1->beginWaitingForReply(test_start_time_ - milliseconds(1)); ++ updateContext(context1); ++ ++ // Call setNextExpiration(). ++ ASSERT_NO_THROW_LOG(mgr_->setNextExpiration()); ++ ++ // Refresh the context. ++ context1 = getContext(lease_query_pairs_[0]); ++ ++ // Context1 should have a earlier expiration than context2. ++ EXPECT_LT(context1->getNextExpiry(), context2->getNextExpiry()); ++ // Timer interval should be based on context1. ++ EXPECT_TRUE(fuzzyEqual(mgr_->getExpirationTimerInterval(), 50, 20)) ++ << " interval: " << mgr_->getExpirationTimerInterval(); ++ ++ // Move all contexts to TARGET_FREE. This should leave none ++ // still waiting. ++ context1->setState(PingContext::TARGET_FREE); ++ updateContext(context1); ++ context2->setState(PingContext::TARGET_FREE); ++ updateContext(context2); ++ context3->setState(PingContext::TARGET_FREE); ++ updateContext(context3); ++ ++ // Call setNextExpiration(). ++ ASSERT_NO_THROW_LOG(mgr_->setNextExpiration()); ++ ++ // Should not have an expiration time, timer should not be running. ++ ASSERT_EQ(PingContext::EMPTY_TIME(), mgr_->getNextExpiry()); ++ ASSERT_EQ(mgr_->getExpirationTimerInterval(), 0); ++ } ++ ++ /// @brief Exercises PingCheckMgr::sendCompleted. ++ void testSendCompleted() { ++ SKIP_IF(notRoot()); ++ ++ // Create a paused manager. 3 threads, 2 echos, 500 ms timeout. ++ // ST mode should ingore requested thread number. ++ createMgr(3, 2, 500, true); ++ ++ // Start a ping for an address so we have a context. ++ IOAddress target("127.0.0.2"); ++ auto lqp = makeLeaseQueryPair(IOAddress(target), 102); ++ ++ // Call startPing(). ++ ASSERT_NO_THROW_LOG(mgr_->startPing(lqp.lease_, lqp.query_, parking_lot_)); ++ ++ // Simulate a completed send for the context. ++ PingContextPtr context; ++ context = getContext(lqp); ++ ASSERT_TRUE(context); ++ ++ // Make an ECHO REQUEST packet based on context. ++ ICMPMsgPtr echo_request = makeEchoRequest(context->getLease()->addr_); ++ ++ // Invoke sendCompleted() with fabricated request. Should succeed. ++ ASSERT_NO_THROW_LOG(mgr_->sendCompleted(echo_request, false)); ++ ++ // Refresh the context. ++ context = getContext(context->getLease()->addr_); ++ ++ EXPECT_EQ(PingContext::WAITING_FOR_REPLY, context->getState()); ++ EXPECT_EQ(1, context->getEchosSent()); ++ EXPECT_GE(context->getLastEchoSentTime(), test_start_time_); ++ ++ // Verify the mgr has the same next expiration as the context and ++ // that the expiration timer is running. Allow for some fudge in ++ // the checks. ++ EXPECT_GT(context->getNextExpiry(), test_start_time_); ++ EXPECT_TRUE(fuzzyEqual(mgr_->getNextExpiry(), context->getNextExpiry())); ++ EXPECT_TRUE(fuzzyEqual(mgr_->getExpirationTimerInterval(), 500)); ++ ++ // Make an ECHO REQUEST packet for an address that has no context. ++ echo_request = makeEchoRequest(IOAddress("192.168.0.1")); ++ ++ // Invoking sendCompleted() with request for a non-existent address be harmless. ++ ASSERT_NO_THROW_LOG(mgr_->sendCompleted(echo_request, false)); ++ ++ // Invoking sendCompleted() with an invalid message type should be harmless. ++ echo_request->setType(ICMPMsg::ECHO_REPLY); ++ ASSERT_NO_THROW_LOG(mgr_->sendCompleted(ICMPMsgPtr(), false)); ++ ++ // Invoking sendCompleted() with an empty message should be harmless. ++ echo_request.reset(); ++ ASSERT_NO_THROW_LOG(mgr_->sendCompleted(ICMPMsgPtr(), false)); ++ ++ // Verify expiration values should not have not been altered. ++ EXPECT_TRUE(fuzzyEqual(mgr_->getNextExpiry(), context->getNextExpiry())); ++ EXPECT_TRUE(fuzzyEqual(mgr_->getExpirationTimerInterval(), 500)); ++ } ++ ++ /// @brief Exercises PingCheckMgr::replyReceived() for ECHO REPLYs. Note this ++ /// also exercises handleEchoReply(). ++ void testReplyReceivedForEchoReply() { ++ SKIP_IF(notRoot()); ++ ++ // Create a paused manager. 3 threads, 2 echos, 500 ms timeout. ++ // ST mode should ingore requested thread number. ++ createMgr(3, 2, 500, true); ++ ++ // Install a post reply received callback to stop the test if we're done. ++ mgr_->post_reply_received_cb_ = ++ [this](const ICMPMsgPtr& /* reply */) { ++ MultiThreadingLock lock(*mutex_); ++ if (mgr_->parkingLotSize() == 0) { ++ stopTestService(); ++ return; ++ } ++ }; ++ ++ // Turn off loopback routing. ++ mgr_->getChannel()->route_loopback_ = false; ++ ++ // Start a ping for an address so we have a context. ++ startTargets(1); ++ auto lqp = lease_query_pairs_[0]; ++ ++ // Simulate a completed send for the context. ++ PingContextPtr context; ++ context = getContext(lqp); ++ ASSERT_TRUE(context); ++ ++ // Make an ECHO REQUEST packet based on context and invoke sendCompleted(). ++ ICMPMsgPtr echo_request = makeEchoRequest(context->getLease()->addr_); ++ ASSERT_NO_THROW_LOG(mgr_->sendCompleted(echo_request, false)); ++ ++ // Should still have one parked query. ++ EXPECT_EQ(1, mgr_->parkingLotSize()); ++ ++ // Verify the expiration timer is running. ++ EXPECT_TRUE(fuzzyEqual(mgr_->getExpirationTimerInterval(), 500)); ++ ++ // Make an ECHO REPLY packet based on context and invoke replyReceived(). ++ ICMPMsgPtr echo_reply = makeEchoReply(context->getLease()->addr_); ++ ASSERT_NO_THROW_LOG(mgr_->replyReceived(echo_reply)); ++ ++ // Verify the expiration timer is no longer running. ++ EXPECT_EQ(mgr_->getExpirationTimerInterval(), 0); ++ ++ // The context should no longer be in the store. ++ EXPECT_FALSE(getContext(lqp)); ++ ++ // We should have dropped the query from the lot rather than unparking it. ++ EXPECT_EQ(mgr_->parkingLotSize(), 0); ++ EXPECT_EQ(unparked_, 1); ++ ++ // We should have one decline that matches our lease query pair. ++ compareLeaseQueryPairs(declines_); ++ ++ // Make an ECHO REPLY packet for an address that has no context. ++ echo_reply = makeEchoReply(IOAddress("192.168.0.1")); ++ ++ // Invoke replyReceived() for a reply with no matching context, ++ // it should not throw. ++ ASSERT_NO_THROW_LOG(mgr_->PingCheckMgr::replyReceived(echo_reply)); ++ ++ // Invoke replyReceived() an empty message, it should not throw. ++ // (Bypass test implementation for this check). ++ echo_reply.reset(); ++ ASSERT_NO_THROW_LOG(mgr_->PingCheckMgr::replyReceived(echo_reply)); ++ } ++ ++ /// @brief Exercises PingCheckMgr::replyReceived() for UNREACHABLEs. Note this ++ /// also exercises handleTargetUnreachable(). ++ void testReplyReceivedForTargetUnreachable() { ++ SKIP_IF(notRoot()); ++ ++ // Create a paused manager. 3 threads, 2 echos, 500 ms timeout. ++ // ST mode should ingore requested thread number. ++ createMgr(3, 2, 500, true); ++ ++ // Install a post reply received callback to stop the test if we're done. ++ mgr_->post_reply_received_cb_ = ++ [this](const ICMPMsgPtr& /* reply */) { ++ MultiThreadingLock lock(*mutex_); ++ if (mgr_->parkingLotSize() == 0) { ++ stopTestService(); ++ return; ++ } ++ }; ++ ++ // Turn off loopback routing. ++ mgr_->getChannel()->route_loopback_ = false; ++ ++ // Start a ping for an address so we have a context. ++ startTargets(1); ++ auto lqp = lease_query_pairs_[0]; ++ ++ // Simulate a completed send for the context. ++ PingContextPtr context; ++ context = getContext(lqp); ++ ASSERT_TRUE(context); ++ ++ // Make an ECHO REQUEST packet based on context and invoke sendCompleted(). ++ ICMPMsgPtr echo_request = makeEchoRequest(context->getLease()->addr_); ++ ASSERT_NO_THROW_LOG(mgr_->sendCompleted(echo_request, false)); ++ ++ // Should still have one parked query. ++ EXPECT_EQ(1, mgr_->parkingLotSize()); ++ ++ // Verify the expiration timer is running. ++ EXPECT_TRUE(fuzzyEqual(mgr_->getExpirationTimerInterval(), 500)); ++ ++ // Make an ECHO REPLY packet based on context and invoke replyReceived(). ++ ICMPMsgPtr unreachable = makeUnreachable(context->getLease()->addr_); ++ ASSERT_NO_THROW_LOG(mgr_->replyReceived(unreachable)); ++ ++ // Verify the expiration timer is no longer running. ++ EXPECT_EQ(mgr_->getExpirationTimerInterval(), 0); ++ ++ // The context should no longer be in the store. ++ EXPECT_FALSE(getContext(lqp)); ++ ++ // We should have unparked the query from the lot. ++ EXPECT_EQ(mgr_->parkingLotSize(), 0); ++ EXPECT_EQ(unparked_, 1); ++ ++ // We should have one free that matches our lease query pair. ++ compareLeaseQueryPairs(frees_); ++ ++ // Invoke replyReceived() for an unreachable with no matching context, ++ // it should not throw. ++ unreachable = makeUnreachable(IOAddress("192.168.0.1")); ++ ASSERT_NO_THROW_LOG(mgr_->replyReceived(unreachable)); ++ } ++ ++ /// @brief Verifies expiration processing by invoking expirationTimedout(). ++ /// This also exercises processExpiredSince(), doNextEcho(), finishFree(), ++ /// and setNextExpiration(). ++ void testExpirationProcessing() { ++ SKIP_IF(notRoot()); ++ ++ // Create a paused manager. 3 threads, 1 echos, 250 ms timeout. ++ // ST mode should ingore requested thread number. ++ createMgr(3, 1, 250, true); ++ ++ // Start four ping checks, then stage them so: ++ // ++ // First context is WAITING_TO_SEND, no expiry. ++ // Second context is WAITING_FOR_REPLY, has expired and has ++ // exhausted min_echos_. ++ // Third context is WAITING_FOR_REPLY, has expired but has ++ // not exhausted min_echos_. ++ // Fourth context is WAITING_FOR_REPLY but has not yet expired. ++ // ++ size_t num_targets = 4; ++ ++ // Start the desired number of targets with an unpark callback ++ // that increments the unparked count. ++ startTargets(num_targets); ++ ++ // Now establish the desired state for each context. ++ // First context is in WAITING_TO_SEND, no expiry. ++ PingContextPtr context1 = getContext(lease_query_pairs_[0]); ++ ASSERT_TRUE(context1); ++ EXPECT_EQ(context1->getState(), PingContext::WAITING_TO_SEND); ++ ++ // Second context setup: expired and has exhausted min_echos_ ++ PingContextPtr context2 = getContext(lease_query_pairs_[1]); ++ ASSERT_TRUE(context2); ++ context2->beginWaitingForReply(test_start_time_ - milliseconds(500)); ++ updateContext(context2); ++ ++ // Third context setup: expired but has not exhausted min_echos_ ++ PingContextPtr context3 = getContext(lease_query_pairs_[2]); ++ ASSERT_TRUE(context3); ++ context3->setMinEchos(2); ++ context3->beginWaitingForReply(test_start_time_ - milliseconds(500)); ++ updateContext(context3); ++ ++ // Fourth context setup: has not yet expired ++ PingContextPtr context4 = getContext(lease_query_pairs_[3]); ++ ASSERT_TRUE(context4); ++ context4->beginWaitingForReply(test_start_time_); ++ updateContext(context4); ++ ++ // Now invoke expirationTimedout(). ++ ASSERT_NO_THROW_LOG(mgr_->expirationTimedOut()); ++ ++ // Verify the contexts are in the expected states. ++ // Context1 should still be WAITING_TO_SEND. ++ context1 = getContext(lease_query_pairs_[0]); ++ ASSERT_TRUE(context1); ++ EXPECT_EQ(context1->getState(), PingContext::WAITING_TO_SEND); ++ ++ // Context2 should be gone by unparking and its address freed. ++ IOAddress address = lease_query_pairs_[1].lease_->addr_; ++ context2 = getContext(address); ++ ASSERT_FALSE(context2); ++ EXPECT_EQ(unparked_, 1); ++ ASSERT_EQ(frees_.size(), 1); ++ EXPECT_EQ(frees_[0].lease_->addr_, address); ++ ++ // Context3 should be in WAITING_TO_SEND. ++ context3 = getContext(lease_query_pairs_[2]); ++ ASSERT_TRUE(context3); ++ EXPECT_EQ(context3->getState(), PingContext::WAITING_TO_SEND); ++ ++ // Context4 should still be WAITING_FOR_REPLY. ++ context4 = getContext(lease_query_pairs_[3]); ++ ASSERT_TRUE(context4); ++ EXPECT_EQ(context4->getState(), PingContext::WAITING_FOR_REPLY); ++ ++ // Manager's next_expiry_ should be based on context4? ++ EXPECT_TRUE(fuzzyEqual(mgr_->getNextExpiry(), context4->getNextExpiry())); ++ } ++ ++ /// @brief Generates a number of ping checks to local loop back addresses. ++ /// ++ /// Pings should all result in ECHO_REPLYs that get "declined". Declined ++ /// addresses are added to a list. Test completion is gated by the parking ++ /// lot becoming empty or test times out. ++ void testMultiplePingsWithReply() { ++ SKIP_IF(notRoot()); ++ ++ // Create manager with thread-pool size of 3, min_echos 1, ++ // reply_timeout 1000 milliseconds. Larger time out for this test ++ // avoids sporadic expirations which leads to unaccounted for UNPARKs. ++ // ST mode should ingore requested thread number. ++ ASSERT_NO_THROW_LOG(createMgr(3, 1, 1000)); ++ ASSERT_TRUE(mgr_); ++ ++ // Install a post reply received callback to stop the test if we're done. ++ int num_targets = 25; ++ mgr_->post_reply_received_cb_ = ++ [this, num_targets](const ICMPMsgPtr& /* reply */) { ++ MultiThreadingLock lock(*mutex_); ++ if (unparked_ == num_targets) { ++ stopTestService(); ++ return; ++ } ++ }; ++ ++ // Start the manager. This will open the channel. ++ ASSERT_NO_THROW_LOG(mgr_->start()); ++ ASSERT_TRUE(mgr_->isRunning()); ++ ++ // Start the ping checks. ++ startTargets(num_targets); ++ ++ // Run the main thread's IOService until we complete or timeout. ++ ASSERT_NO_THROW_LOG(runIOService()); ++ ++ // Stop the thread pool. ++ ASSERT_NO_THROW_LOG(mgr_->stop()); ++ ASSERT_TRUE(mgr_->isStopped()); ++ ++ // Calling nextToSend() should return false. ++ IOAddress next("0.0.0.0"); ++ ASSERT_FALSE(mgr_->nextToSend(next)); ++ ++ // We should have as many declines as we have pairs created. ++ compareLeaseQueryPairs(declines_); ++ } ++ ++ /// @brief Generates a large number of ping checks to local loop back addresses. ++ /// ++ /// A pause is induced approximately halfway through the number of replies ++ /// at which point the manager is paused and then resumed. This is intended ++ /// to demonstrate the ability to pause and resume the manager gracefully. ++ /// The pings should all result in ECHO_REPLYs that get "declined". Declined ++ /// addresses are added to a list. Test completion is gated by the parking ++ /// lot becoming empty or test times out. ++ void testMultiplePingsWithReplyAndPause() { ++ SKIP_IF(notRoot()); ++ ++ // Create manager with thread-pool size of 3, min_echos 1, ++ // reply_timeout 1000 milliseconds. Larger time out for this test ++ // avoids sporadic expirations which leads to unaccounted for UNPARKs. ++ // ST mode should ingore requested thread number. ++ ASSERT_NO_THROW_LOG(createMgr(3, 1, 1000)); ++ ASSERT_TRUE(mgr_); ++ ++ // Generate ping checks to the desired number of targets. ++ // Set up the pause callback to pause at half the number of ++ // expected replies. ++ size_t num_targets = 24; ++ size_t reply_cnt = 0; ++ size_t pause_at = num_targets / 2; ++ bool test_paused = false; ++ ++ // Install post reply callback to stop the test thread when we reach ++ // the pause count. ++ mgr_->post_reply_received_cb_ = ++ [this, &reply_cnt, &test_paused, &pause_at](const ICMPMsgPtr& reply) { ++ MultiThreadingLock lock(*mutex_); ++ if (reply->getType() == ICMPMsg::ECHO_REPLY) { ++ ++reply_cnt; ++ if (pause_at && (reply_cnt >= pause_at)) { ++ test_paused = true; ++ stopTestService(); ++ pause_at = 0; ++ } ++ } ++ }; ++ ++ // Start the manager. This will open the channel. ++ ASSERT_NO_THROW_LOG(mgr_->start()); ++ ASSERT_TRUE(mgr_->isRunning()); ++ ASSERT_NO_THROW_LOG(mgr_->pause()); ++ ++ // Start 1/2 desired number of ping checks. ++ startTargets(num_targets / 2); ++ ++ // Run the main thread's IOService until we pause or timeout. ++ ASSERT_NO_THROW_LOG(mgr_->resume()); ++ ASSERT_TRUE(mgr_->isRunning()); ++ ASSERT_NO_THROW_LOG(runIOService()); ++ ++ // Manager should still be running. Pause it. ++ ASSERT_TRUE(mgr_->isRunning()); ++ if (mgr_->getThreadPool()) { ++ ASSERT_NO_THROW_LOG(mgr_->pause()); ++ ASSERT_TRUE(mgr_->isPaused()); ++ } ++ ++ // Verify that the pause callback is why we stopped, that we ++ // received at least as many as we should have before pause ++ // and that we have more work to do. The test is a range as ++ // pausing does not happen exactly at the same point from test ++ // run to test run. ++ ASSERT_TRUE(test_paused); ++ ASSERT_TRUE((reply_cnt >= pause_at) && (reply_cnt < num_targets)) ++ << "reply_cnt " << reply_cnt ++ << ", pause_at " << pause_at ++ << ", num_targets " << num_targets; ++ ++ mgr_->post_reply_received_cb_ = ++ [this, num_targets](const ICMPMsgPtr& /* reply */) { ++ MultiThreadingLock lock(*mutex_); ++ if (unparked_ == num_targets) { ++ stopTestService(); ++ return; ++ } ++ }; ++ ++ // Start second batch of targets. ++ startTargets(num_targets / 2, IOAddress("127.0.0.15")); ++ ++ ASSERT_NO_THROW_LOG(mgr_->resume()); ++ ASSERT_TRUE(mgr_->isRunning()); ++ ++ // Restart the main thread's IOService until we complete or timeout. ++ ASSERT_NO_THROW_LOG(runIOService()); ++ ++ ASSERT_NO_THROW_LOG(mgr_->stop()); ++ ASSERT_TRUE(mgr_->isStopped()); ++ ++ // Calling nextToSend() should return false. ++ IOAddress next("0.0.0.0"); ++ ASSERT_FALSE(mgr_->nextToSend(next)); ++ ++ // We should have as many declines as we have pairs created. ++ compareLeaseQueryPairs(declines_); ++ } ++ ++ /// @brief Verifies that a recoverable error completion in sendCompleted() results ++ /// in the target address being free to use. In other words, it should have ++ /// the same outcome as the receiving a TARGET_UNREACHABLE reply from the OS. ++ void testSendCompletedSendFailed() { ++ SKIP_IF(notRoot()); ++ ++ // Create manager with thread-pool size of 3, min_echos 1, ++ // reply_timeout 250 milliseconds. ++ // ST mode should ingore requested thread number. ++ ASSERT_NO_THROW_LOG(createMgr(3, 1, 250)); ++ ASSERT_TRUE(mgr_); ++ ++ // Install a post send completed callback to stop the test if we're done. ++ mgr_->post_send_completed_cb_ = ++ [this](const ICMPMsgPtr& /* echo */, bool send_failed) { ++ MultiThreadingLock lock(*mutex_); ++ if (send_failed) { ++ stopTestService(); ++ } ++ }; ++ ++ // Start the manager. ++ ASSERT_NO_THROW_LOG(mgr_->start()); ++ ++ // Set the test channel to complete the first send with a network_unreachable ++ // error. This saves us from trying to determine an address in the test ++ // environment that would cause it. ++ mgr_->getChannel()->ec_on_write_number_ = 1; ++ mgr_->getChannel()->write_error_ec_ = make_error_code(network_unreachable); ++ ++ // Start a ping for one target. ++ startTargets(1); ++ auto lqp = lease_query_pairs_[0]; ++ ++ // Run the main thread's IOService until we complete or timeout. ++ ASSERT_NO_THROW_LOG(runIOService()); ++ ++ // Verify the expiration timer is no longer running. ++ EXPECT_EQ(mgr_->getExpirationTimerInterval(), 0); ++ ++ // The context should no longer be in the store. ++ EXPECT_FALSE(getContext(lqp)); ++ ++ // We should have unparked the query from the lot. ++ EXPECT_EQ(mgr_->parkingLotSize(), 0); ++ EXPECT_EQ(unparked_, 1); ++ ++ // We should have one free that matches our lease query pair. ++ compareLeaseQueryPairs(frees_); ++ } ++ ++ /// @brief Exercises shouldPing(). ++ void testShouldPingTest() { ++ SKIP_IF(notRoot()); ++ ++ // Create manager with thread-pool size of 3, min_echos 1, ++ // reply_timeout 250 milliseconds. ++ // ST mode should ingore requested thread number. ++ ASSERT_NO_THROW_LOG(createMgr(3, 1, 250)); ++ ASSERT_TRUE(mgr_); ++ ++ // Make a default config. ++ PingCheckConfigPtr config(new PingCheckConfig()); ++ ++ // Make a lease query pair. ++ auto lqp1 = makeLeaseQueryPair(IOAddress("127.0.0.2"), 111); ++ const uint8_t id1[] = { 0x31, 0x32, 0x33, 0x34 }; ++ ClientIdPtr cid1(new ClientId(id1, sizeof(id1))); ++ lqp1.lease_->client_id_ = cid1; ++ ++ Lease4Ptr empty_lease; ++ CalloutHandle::CalloutNextStep status; ++ ++ // Ping checking enabled, no old lease, channel doesn't exist, should return CONTINUE. ++ ASSERT_TRUE(config->getEnablePingCheck()); ++ ASSERT_NO_THROW_LOG(status = mgr_->shouldPing(lqp1.lease_, lqp1.query_, empty_lease, config)); ++ EXPECT_EQ(status, CalloutHandle::NEXT_STEP_CONTINUE); ++ ++ // Start the manager, then pause it. This lets us start pings without ++ // them changing state. ++ ASSERT_NO_THROW_LOG(mgr_->start()); ++ ASSERT_NO_THROW_LOG(mgr_->pause()); ++ ++ // Ping checking disabled, no old lease, should return CONTINUE. ++ config->setEnablePingCheck(false); ++ ASSERT_NO_THROW_LOG(status = mgr_->shouldPing(lqp1.lease_, lqp1.query_, empty_lease, config)); ++ EXPECT_EQ(status, CalloutHandle::NEXT_STEP_CONTINUE); ++ ++ // Ping checking enabled, no old lease, should return PARK. ++ config->setEnablePingCheck(true); ++ ASSERT_NO_THROW_LOG(status = mgr_->shouldPing(lqp1.lease_, lqp1.query_, empty_lease, config)); ++ EXPECT_EQ(status, CalloutHandle::NEXT_STEP_PARK); ++ ++ // Make an old lease based on the first lease. ++ time_t now = time(0); ++ Lease4Ptr old_lease(new Lease4(*(lqp1.lease_))); ++ ++ // Prior lease belonging to the same client with cltt greater than ping-cltt-secs ++ // should return PARK. ++ old_lease->cltt_ = now - config->getPingClttSecs() * 2; ++ ASSERT_NO_THROW_LOG(status = mgr_->shouldPing(lqp1.lease_, lqp1.query_, old_lease, config)); ++ EXPECT_EQ(status, CalloutHandle::NEXT_STEP_PARK); ++ ++ // Prior lease belonging to the same client but with cltt less than ping-cltt-secs ++ // should return CONTINUE. ++ old_lease->cltt_ = now - config->getPingClttSecs() / 2; ++ ASSERT_NO_THROW_LOG(status = mgr_->shouldPing(lqp1.lease_, lqp1.query_, old_lease, config)); ++ EXPECT_EQ(status, CalloutHandle::NEXT_STEP_CONTINUE); ++ ++ // Prior lease belonging to a different client, should return PARK. ++ const uint8_t id2[] = { 0x35, 0x36, 0x37, 0x34 }; ++ old_lease->client_id_.reset(new ClientId(id2, sizeof(id2))); ++ ASSERT_NO_THROW_LOG(status = mgr_->shouldPing(lqp1.lease_, lqp1.query_, old_lease, config)); ++ EXPECT_EQ(status, CalloutHandle::NEXT_STEP_PARK); ++ ++ // Now let's start a ping for the lease-query pair. ++ ASSERT_NO_THROW_LOG(mgr_->startPing(lqp1.lease_, lqp1.query_, parking_lot_)); ++ ++ // Make a second lease query pair. Same address, different client. ++ auto lqp2 = makeLeaseQueryPair(IOAddress("127.0.0.2"), 333); ++ lqp2.lease_->client_id_ = old_lease->client_id_; ++ ++ // Trying to start a ping for an address already being checked should return DROP. ++ ASSERT_NO_THROW_LOG(status = mgr_->shouldPing(lqp2.lease_, lqp2.query_, empty_lease, config)); ++ EXPECT_EQ(status, CalloutHandle::NEXT_STEP_DROP); ++ ++ // Stop the mgr. ++ ASSERT_NO_THROW(mgr_->stop()); ++ ++ // Ping checking enabled, no old lease, channel isn't open, should return CONTINUE. ++ ASSERT_TRUE(config->getEnablePingCheck()); ++ ASSERT_NO_THROW_LOG(status = mgr_->shouldPing(lqp1.lease_, lqp1.query_, empty_lease, config)); ++ EXPECT_EQ(status, CalloutHandle::NEXT_STEP_CONTINUE); ++ } ++ ++ /// @brief Exercise's getScopedConfig(). ++ void testGetScopedConfig() { ++ CfgMgr::instance().setFamily(AF_INET); ++ ++ // Start with empty cache, any subnet that hasn't been seen should get parsed ++ // and, if valid, added to the cache. ++ CfgMgr& cfg_mgr = CfgMgr::instance(); ++ CfgSubnets4Ptr subnets = cfg_mgr.getStagingCfg()->getCfgSubnets4(); ++ ++ // Subnet 1 has no ping-check config. Should return global config. ++ ElementPtr user_context = Element::createMap(); ++ Subnet4Ptr subnet(new Subnet4(IOAddress("192.0.1.0"), 24, 30, 40, 60, 1)); ++ subnet->setContext(user_context); ++ subnets->add(subnet); ++ ++ // Subnet 2 has invalid ping-check content. Should return global config. ++ std::string invalid_json_cfg = ++ R"({ ++ "ping-check": { ++ "enable-ping-check" : true, ++ "bogus-key-word" : true ++ } ++ })"; ++ ++ user_context = Element::fromJSON(invalid_json_cfg); ++ subnet.reset(new Subnet4(IOAddress("192.0.2.0"), 24, 30, 40, 60, 2)); ++ subnet->setContext(user_context); ++ subnets->add(subnet); ++ ++ // Subnet 3 has valid ping check. Should return subnet config ++ std::string valid_json_cfg = ++ R"({ ++ "ping-check": { ++ "enable-ping-check" : true, ++ "min-ping-requests" : 13 ++ } ++ })"; ++ ++ user_context = Element::fromJSON(valid_json_cfg); ++ subnet.reset(new Subnet4(IOAddress("192.0.3.0"), 24, 30, 40, 60, 3)); ++ subnet->setContext(user_context); ++ subnets->add(subnet); ++ ++ // Commit the subnet configuration. ++ cfg_mgr.commit(); ++ ++ // Create manager with thread-pool size of 3, min_echos 2, reply_timeout 250 ms. ++ ASSERT_NO_THROW_LOG(createMgr(3, 2, 250)); ++ ASSERT_TRUE(mgr_); ++ ++ Lease4Ptr lease(new Lease4()); ++ PingCheckConfigPtr config; ++ ++ // Should get the global configuration for subnet 1. ++ lease->addr_ = IOAddress("192.0.1.1"); ++ lease->subnet_id_ = 1; ++ ASSERT_NO_THROW_LOG(config = mgr_->getScopedConfig(lease)); ++ ASSERT_TRUE(config); ++ ASSERT_EQ(config, mgr_->getGlobalConfig()); ++ ++ // Should get the global configuration for subnet 2. ++ lease->addr_ = IOAddress("192.0.2.1"); ++ lease->subnet_id_ = 2; ++ ASSERT_NO_THROW_LOG(config = mgr_->getScopedConfig(lease)); ++ ASSERT_TRUE(config); ++ ASSERT_EQ(config, mgr_->getGlobalConfig()); ++ ++ // Should get subnet configuration for subnet 3. ++ lease->addr_ = IOAddress("192.0.3.1"); ++ lease->subnet_id_ = 3; ++ ASSERT_NO_THROW_LOG(config = mgr_->getScopedConfig(lease)); ++ ASSERT_TRUE(config); ++ ASSERT_NE(config, mgr_->getGlobalConfig()); ++ EXPECT_EQ(config->getMinPingRequests(), 13); ++ } ++ ++ /// @brief Exercises checkSuspended(). ++ /// ++ /// This is intended to verify that ping checking is suspended and resumed based ++ /// on the DHCP service state, not to verify every place that checkSuspended() ++ /// is called. ++ void testCheckSuspended() { ++ SKIP_IF(notRoot()); ++ ++ // Create manager with thread-pool size of 3, min_echos 1, ++ // reply_timeout 250 milliseconds. ++ ASSERT_NO_THROW_LOG(createMgr(3, 1, 250)); ++ ASSERT_TRUE(mgr_); ++ ++ // Make a default config. ++ PingCheckConfigPtr config(new PingCheckConfig()); ++ ++ // Give the manager a NetworkState instance. ++ NetworkStatePtr network_state(new NetworkState()); ++ mgr_->setNetworkState(network_state); ++ ++ // Verify that ping checking is not suspended. ++ ASSERT_FALSE(mgr_->checkSuspended()); ++ ++ // Start the manager, then pause it. This lets us start pings without ++ // them changing state. ++ ASSERT_NO_THROW_LOG(mgr_->start()); ++ ASSERT_NO_THROW_LOG(mgr_->pause()); ++ ++ // Verfify the ping store is empty. ++ auto store = mgr_->getStore(); ++ ASSERT_TRUE(store); ++ auto pings = store->getAll(); ++ ASSERT_EQ(0, pings->size()); ++ ++ // Make a lease query pair. ++ auto lqp1 = makeLeaseQueryPair(IOAddress("127.0.0.2"), 111); ++ const uint8_t id1[] = { 0x31, 0x32, 0x33, 0x34 }; ++ ClientIdPtr cid1(new ClientId(id1, sizeof(id1))); ++ lqp1.lease_->client_id_ = cid1; ++ ++ // Now let's try to start a ping for the lease-query pair. It should work. ++ ASSERT_NO_THROW_LOG(mgr_->startPing(lqp1.lease_, lqp1.query_, parking_lot_)); ++ ++ // Verify we have an entry in the store. ++ pings = store->getAll(); ++ ASSERT_EQ(1, pings->size()); ++ ++ // Disable the DHCP service. ++ network_state->disableService(NetworkState::USER_COMMAND); ++ ++ // Make a second lease query pair. Different address, different client. ++ auto lqp2 = makeLeaseQueryPair(IOAddress("127.0.0.3"), 333); ++ const uint8_t id2[] = { 0x31, 0x32, 0x33, 0x35 }; ++ ClientIdPtr cid2(new ClientId(id1, sizeof(id2))); ++ lqp2.lease_->client_id_ = cid2; ++ ++ // Try to start a ping. We should not be able to do it. ++ ASSERT_THROW_MSG(mgr_->startPing(lqp2.lease_, lqp2.query_, parking_lot_), ++ InvalidOperation, ++ "PingCheckMgr::startPing() - DHCP service is suspended!"); ++ ++ // Store should be empty, having been flushed by suspension detection. ++ pings = store->getAll(); ++ ASSERT_EQ(0, pings->size()); ++ ++ // Ping checking should report as suspended. ++ ASSERT_TRUE(mgr_->checkSuspended()); ++ ++ // Re-enable the DHCP service. ++ network_state->enableService(NetworkState::USER_COMMAND); ++ ++ // Suspension checking should lift the suspension and we should once again ++ // be able to start a new ping check. ++ ASSERT_NO_THROW_LOG(mgr_->startPing(lqp2.lease_, lqp2.query_, parking_lot_)); ++ ++ // Store should have one check in it. ++ pings = store->getAll(); ++ ASSERT_EQ(1, pings->size()); ++ ++ // Ping checking should report as not suspended. ++ ASSERT_FALSE(mgr_->checkSuspended()); ++ } ++ ++ /// @brief Manager instance. ++ TestablePingCheckMgrPtr mgr_; ++ ++ /// @brief List of lease/query pairs used during the test, in the order ++ /// they were created. ++ LeaseQueryPairs lease_query_pairs_; ++ ++ /// @brief The mutex used to protect internal state. ++ const boost::scoped_ptr<std::mutex> mutex_; ++ ++ /// @brief Marks the start time of a test. ++ TimeStamp test_start_time_; ++ ++ /// @brief Parking lot where the associated query is parked. ++ /// If empty parking is not being employed. ++ ParkingLotHandlePtr parking_lot_; ++ ++ /// @brief Number of queries unparked during a test. ++ size_t unparked_; ++ ++ /// @brief List of leases that were found to be in-use during a test. ++ LeaseQueryPairs declines_; ++ ++ /// @brief List of leases that were found to be free to use during a test. ++ LeaseQueryPairs frees_; ++}; ++ ++TEST_F(PingCheckMgrTest, operationalBasicsST) { ++ testOperationalBasics(0); ++} ++ ++TEST_F(PingCheckMgrTest, operationalBasicsMT) { ++ MultiThreadingTest mt; ++ testOperationalBasics(3); ++} ++ ++TEST_F(PingCheckMgrTest, startPingST) { ++ testStartPing(); ++} ++ ++TEST_F(PingCheckMgrTest, startPingMT) { ++ MultiThreadingTest mt; ++ testStartPing(); ++} ++ ++TEST_F(PingCheckMgrTest, nextToSendST) { ++ testNextToSend(); ++} ++ ++TEST_F(PingCheckMgrTest, nextToSendMT) { ++ MultiThreadingTest mt; ++ testNextToSend(); ++} ++ ++TEST_F(PingCheckMgrTest, setNextExpirationST) { ++ testSetNextExpiration(); ++} ++ ++TEST_F(PingCheckMgrTest, setNextExpirationMT) { ++ MultiThreadingTest mt; ++ testSetNextExpiration(); ++} ++ ++TEST_F(PingCheckMgrTest, sendCompletedST) { ++ testSendCompleted(); ++} ++ ++TEST_F(PingCheckMgrTest, sendCompletedMT) { ++ MultiThreadingTest mt; ++ testSendCompleted(); ++} ++ ++TEST_F(PingCheckMgrTest, replyReceivedForEchoReplyST) { ++ testReplyReceivedForEchoReply(); ++} ++ ++TEST_F(PingCheckMgrTest, replyReceivedForEchoReplyMT) { ++ MultiThreadingTest mt; ++ testReplyReceivedForEchoReply(); ++} ++ ++TEST_F(PingCheckMgrTest, replyReceivedForTargetUnreachableST) { ++ testReplyReceivedForTargetUnreachable(); ++} ++ ++TEST_F(PingCheckMgrTest, replyReceivedForTargetUnreachableMT) { ++ MultiThreadingTest mt; ++ testReplyReceivedForTargetUnreachable(); ++} ++ ++TEST_F(PingCheckMgrTest, expirationProcessingST) { ++ testExpirationProcessing(); ++} ++ ++TEST_F(PingCheckMgrTest, expirationProcessingMT) { ++ MultiThreadingTest mt; ++ testExpirationProcessing(); ++} ++ ++TEST_F(PingCheckMgrTest, multiplePingsWithReplyST) { ++ testMultiplePingsWithReply(); ++} ++ ++TEST_F(PingCheckMgrTest, multiplePingsWithReplyMT) { ++ MultiThreadingTest mt; ++ testMultiplePingsWithReply(); ++} ++ ++TEST_F(PingCheckMgrTest, multiplePingsWithReplyAndPauseST) { ++ testMultiplePingsWithReplyAndPause(); ++} ++ ++TEST_F(PingCheckMgrTest, multiplePingsWithReplyAndPauseMT) { ++ MultiThreadingTest mt; ++ testMultiplePingsWithReplyAndPause(); ++} ++ ++TEST_F(PingCheckMgrTest, sendCompletedSendFailedST) { ++ testSendCompletedSendFailed(); ++} ++ ++TEST_F(PingCheckMgrTest, sendCompletedSendFailedMT) { ++ MultiThreadingTest mt; ++ testSendCompletedSendFailed(); ++} ++ ++TEST_F(PingCheckMgrTest, shouldPingST) { ++ testShouldPingTest(); ++} ++ ++TEST_F(PingCheckMgrTest, shouldPingMT) { ++ MultiThreadingTest mt; ++ testShouldPingTest(); ++} ++ ++TEST_F(PingCheckMgrTest, getScopedConfigST) { ++ testGetScopedConfig(); ++} ++ ++TEST_F(PingCheckMgrTest, getScopedConfigMT) { ++ MultiThreadingTest mt; ++ testGetScopedConfig(); ++} ++ ++TEST_F(PingCheckMgrTest, checkSuspendedST) { ++ testCheckSuspended(); ++} ++ ++TEST_F(PingCheckMgrTest, checkSuspendedMT) { ++ MultiThreadingTest mt; ++ testCheckSuspended(); ++} ++ ++} // end of anonymous namespace +diff --git a/src/hooks/dhcp/ping_check/tests/ping_context_store_unittests.cc b/src/hooks/dhcp/ping_check/tests/ping_context_store_unittests.cc +new file mode 100644 +index 0000000000..3a8854eb0e +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/ping_context_store_unittests.cc +@@ -0,0 +1,467 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++/// @file This file contains tests which exercise the PingContextStore class. ++ ++#include <config.h> ++#include <ping_context_store.h> ++#include <asiolink/io_address.h> ++#include <testutils/gtest_utils.h> ++#include <testutils/multi_threading_utils.h> ++ ++#include <gtest/gtest.h> ++#include <sstream> ++ ++using namespace std; ++using namespace isc; ++using namespace isc::asiolink; ++using namespace isc::dhcp; ++using namespace isc::ping_check; ++using namespace isc::test; ++using namespace std::chrono; ++ ++namespace { ++ ++/// @brief Text fixture class for @c PingContextStore ++/// ++/// In order to facilitate single and multi threaded testing, ++/// individual tests are implemented as methods that are called ++/// from within TEST_F bodies rather than in TEST_F bodies. ++class PingContextStoreTest : public ::testing::Test { ++public: ++ ++ /// @brief Constructor ++ PingContextStoreTest() { ++ } ++ ++ /// @brief Destructor ++ virtual ~PingContextStoreTest() = default; ++ ++ /// @brief Verifies that contexts can be added to the store given valid leases and queries. ++ /// Also verifies that they can be fetched by address. ++ void addContextTest() { ++ PingContextStore store; ++ PingContextPtr context; ++ ++ // Add three contexts, one for each lease/query. ++ auto now = PingContext::now(); ++ for (int i = 0; i < leases_.size(); ++i) { ++ ASSERT_NO_THROW_LOG(context = store.addContext(leases_[i], queries_[i], 2, 300)); ++ ASSERT_TRUE(context); ++ EXPECT_EQ(leases_[i], context->getLease()); ++ EXPECT_EQ(queries_[i], context->getQuery()); ++ ++ // Check initial values. ++ EXPECT_EQ(PingContext::WAITING_TO_SEND, context->getState()); ++ EXPECT_LE(now, context->getSendWaitStart()); ++ EXPECT_EQ(2, context->getMinEchos()); ++ EXPECT_EQ(300, context->getReplyTimeout()); ++ } ++ ++ // Make sure they can be fetched by address and by query individually. ++ for (int i = 0; i < leases_.size(); ++i) { ++ ASSERT_NO_THROW_LOG(context = store.getContextByAddress(leases_[i]->addr_)); ++ ASSERT_TRUE(context); ++ EXPECT_EQ(leases_[i], context->getLease()); ++ ++ ASSERT_NO_THROW_LOG(context = store.getContextByQuery(queries_[i])); ++ ASSERT_TRUE(context); ++ EXPECT_EQ(queries_[i], context->getQuery()); ++ } ++ } ++ ++ /// @brief Verifies that the store only allows once entry per IP address. ++ void addContextDuplicateTest() { ++ PingContextStore store; ++ PingContextPtr context; ++ ++ ASSERT_NO_THROW_LOG(context = store.addContext(leases_[0], queries_[0], 1, 100)); ++ ASSERT_TRUE(context); ++ ASSERT_THROW_MSG(store.addContext(leases_[0], queries_[0], 1, 100), DuplicateContext, ++ "PingContextStore::addContex: context already exists for: 192.0.2.1"); ++ } ++ ++ /// @brief Verify that addContext fails given invalid input. ++ void addContextInvalidTest() { ++ PingContextStore store; ++ ++ // Verify that given an empty lease the add will fail. ++ Lease4Ptr empty_lease; ++ ASSERT_THROW_MSG(store.addContext(empty_lease, queries_[0], 1, 100), BadValue, ++ "PingContextStore::addContext failed:" ++ " PingContext ctor - lease cannot be empty"); ++ ++ // Verify that given an empty query the add will fail. ++ Pkt4Ptr empty_query; ++ ASSERT_THROW_MSG(store.addContext(leases_[0], empty_query, 1, 100), BadValue, ++ "PingContextStore::addContext failed:" ++ " PingContext ctor - query cannot be empty"); ++ } ++ ++ /// @brief Verify that contexts can be deleted from the store. ++ void deleteContextTest() { ++ PingContextStore store; ++ ++ // Add contexts to store. ++ for (int i = 0; i < leases_.size(); ++i) { ++ PingContextPtr context; ++ ASSERT_NO_THROW_LOG(context = store.addContext(leases_[i], queries_[i], 1, 100)); ++ ASSERT_TRUE(context); ++ EXPECT_EQ(leases_[i], context->getLease()); ++ EXPECT_EQ(queries_[i], context->getQuery()); ++ } ++ ++ // Fetch the second context. ++ PingContextPtr orig_context; ++ ASSERT_NO_THROW_LOG(orig_context = store.getContextByAddress(leases_[1]->addr_)); ++ ASSERT_TRUE(orig_context); ++ EXPECT_EQ(leases_[1], orig_context->getLease()); ++ ++ // Delete it. ++ ASSERT_NO_THROW_LOG(store.deleteContext(orig_context)); ++ ++ // Try to fetch it, shouldn't find it. ++ PingContextPtr context; ++ ASSERT_NO_THROW_LOG(context = store.getContextByAddress(leases_[1]->addr_)); ++ ASSERT_FALSE(context); ++ ++ // Deleting it again should do no harm. ++ ASSERT_NO_THROW_LOG(store.deleteContext(orig_context)); ++ } ++ ++ /// @brief Verify that contexts in the store can be updated. ++ void updateContextTest() { ++ PingContextStore store; ++ PingContextPtr context; ++ ++ // Try to update a context that doesn't exist. It should throw. ++ ASSERT_NO_THROW_LOG(context.reset(new PingContext(leases_[0], queries_[0]))); ++ ASSERT_THROW_MSG(store.updateContext(context), InvalidOperation, ++ "PingContextStore::updateContext failed for address:" ++ " 192.0.2.1, not in store"); ++ ++ auto test_start = PingContext::now(); ++ ++ // Add contexts to store. ++ for (int i = 0; i < leases_.size(); ++i) { ++ ASSERT_NO_THROW_LOG(context = store.addContext(leases_[i], queries_[i], 1, 100)); ++ ASSERT_TRUE(context); ++ EXPECT_EQ(leases_[i], context->getLease()); ++ EXPECT_EQ(queries_[i], context->getQuery()); ++ } ++ ++ // Fetch the second context. ++ ASSERT_NO_THROW_LOG(context = store.getContextByAddress(leases_[1]->addr_)); ++ ASSERT_TRUE(context); ++ ASSERT_EQ(leases_[1], context->getLease()); ++ ASSERT_EQ(queries_[1], context->getQuery()); ++ ++ // Check initial values for state and expiration. ++ EXPECT_EQ(PingContext::WAITING_TO_SEND, context->getState()); ++ EXPECT_LE(test_start, context->getSendWaitStart()); ++ EXPECT_LE(PingContext::EMPTY_TIME(), context->getNextExpiry()); ++ ++ // Modify the state and expiration, then update the context. ++ auto wait_start = PingContext::now(); ++ context->beginWaitingForReply(wait_start); ++ ASSERT_NO_THROW_LOG(store.updateContext(context)); ++ ++ // Fetch the context and verify the values are correct. ++ ASSERT_NO_THROW_LOG(context = store.getContextByAddress(leases_[1]->addr_)); ++ ASSERT_TRUE(context); ++ EXPECT_EQ(PingContext::WAITING_FOR_REPLY, context->getState()); ++ EXPECT_LE(wait_start + milliseconds(context->getReplyTimeout()), context->getNextExpiry()); ++ } ++ ++ /// @brief Verify that contexts can be fetched based on when they entered WAITING_TO_SEND ++ /// by getNextToSend(). ++ void getNextToSendTest() { ++ PingContextStore store; ++ PingContextPtr context; ++ ++ // Capture time now. ++ auto start_time = PingContext::now(); ++ ++ // Add contexts to store. ++ for (int i = 0; i < leases_.size(); ++i) { ++ ASSERT_NO_THROW_LOG(context = store.addContext(leases_[i], queries_[i], 1, 100)); ++ ASSERT_TRUE(context); ++ EXPECT_EQ(leases_[i], context->getLease()); ++ EXPECT_EQ(queries_[i], context->getQuery()); ++ usleep(1000); ++ } ++ ++ // Fetching the next context to send should return the first context as ++ // it has the oldest send wait start time. ++ context.reset(); ++ ASSERT_NO_THROW(context = store.getNextToSend()); ++ ASSERT_TRUE(context); ++ EXPECT_EQ(leases_[0], context->getLease()); ++ EXPECT_EQ(queries_[0], context->getQuery()); ++ EXPECT_LE(start_time, context->getSendWaitStart()); ++ ++ // Update the first context's state to TARGET_FREE which should ++ // disqualify it from being returned as next to send. ++ ASSERT_NO_THROW_LOG(context = store.getContextByAddress(leases_[0]->addr_)); ++ ASSERT_TRUE(context); ++ ASSERT_EQ(PingContext::WAITING_TO_SEND, context->getState()); ++ context->setState(PingContext::TARGET_FREE); ++ ASSERT_NO_THROW_LOG(store.updateContext(context)); ++ ++ // Update the send wait start of the second context making it the ++ // youngest send wait start time. ++ ASSERT_NO_THROW_LOG(context = store.getContextByAddress(leases_[1]->addr_)); ++ ASSERT_TRUE(context); ++ ASSERT_EQ(PingContext::WAITING_TO_SEND, context->getState()); ++ context->setSendWaitStart(start_time + milliseconds(1000)); ++ ASSERT_NO_THROW_LOG(store.updateContext(context)); ++ ++ // Update the send wait start of the third context, making it the oldest. ++ ASSERT_NO_THROW_LOG(context = store.getContextByAddress(leases_[2]->addr_)); ++ ASSERT_TRUE(context); ++ ASSERT_EQ(PingContext::WAITING_TO_SEND, context->getState()); ++ context->setSendWaitStart(start_time + milliseconds(500)); ++ ASSERT_NO_THROW_LOG(store.updateContext(context)); ++ ++ // Fetching the next context to send should return the third context. ++ context.reset(); ++ ASSERT_NO_THROW(context = store.getNextToSend()); ++ ASSERT_TRUE(context); ++ EXPECT_EQ(leases_[2], context->getLease()); ++ EXPECT_EQ(queries_[2], context->getQuery()); ++ EXPECT_EQ(start_time + milliseconds(500), context->getSendWaitStart()); ++ } ++ ++ /// @brief Verify that contexts can be fetched based on when they expire using ++ /// getExpiresNext() and getExpiredSince(). ++ void getByExpirationTest() { ++ PingContextStore store; ++ PingContextPtr context; ++ ++ // Add contexts to store. ++ for (int i = 0; i < leases_.size(); ++i) { ++ ASSERT_NO_THROW_LOG(context = store.addContext(leases_[i], queries_[i], 1, 100)); ++ ASSERT_TRUE(context); ++ EXPECT_EQ(leases_[i], context->getLease()); ++ EXPECT_EQ(queries_[i], context->getQuery()); ++ } ++ ++ // Capture time now. ++ auto start_time = PingContext::now(); ++ ++ // Update the state and expiration of the first context. ++ // State set to TARGET_FREE should disqualify if from ++ // fetch by expiration even though it has the soonest expiration ++ // time. ++ ASSERT_NO_THROW_LOG(context = store.getContextByAddress(leases_[0]->addr_)); ++ ASSERT_TRUE(context); ++ context->setState(PingContext::TARGET_FREE); ++ context->setNextExpiry(start_time + milliseconds(1)); ++ ASSERT_NO_THROW_LOG(store.updateContext(context)); ++ ++ // Update the state and expiration of the second context giving it ++ // the youngest expiration time. ++ ASSERT_NO_THROW_LOG(context = store.getContextByAddress(leases_[1]->addr_)); ++ ASSERT_TRUE(context); ++ context->setState(PingContext::WAITING_FOR_REPLY); ++ context->setNextExpiry(start_time + milliseconds(1000)); ++ ASSERT_NO_THROW_LOG(store.updateContext(context)); ++ ++ // Update the state and expiration of the third context, make it the ++ // soonest qualified expiration time. ++ ASSERT_NO_THROW_LOG(context = store.getContextByAddress(leases_[2]->addr_)); ++ ASSERT_TRUE(context); ++ context->setState(PingContext::WAITING_FOR_REPLY); ++ context->setNextExpiry(start_time + milliseconds(500)); ++ ASSERT_NO_THROW_LOG(store.updateContext(context)); ++ ++ // Fetching the context that expires next should return the third context. ++ context.reset(); ++ ASSERT_NO_THROW(context = store.getExpiresNext()); ++ ASSERT_TRUE(context); ++ EXPECT_EQ(leases_[2], context->getLease()); ++ EXPECT_EQ(queries_[2], context->getQuery()); ++ EXPECT_EQ(start_time + milliseconds(500), context->getNextExpiry()); ++ ++ // Fetch all that have expired since current time. Should be none. ++ PingContextCollectionPtr expired_since; ++ ASSERT_NO_THROW_LOG(expired_since = store.getExpiredSince()); ++ ASSERT_TRUE(expired_since); ++ EXPECT_EQ(0, expired_since->size()); ++ ++ // Fetch all that have expired since start time + 750 ms, should be third context. ++ ASSERT_NO_THROW_LOG(expired_since = store.getExpiredSince(start_time + milliseconds(750))); ++ ASSERT_TRUE(expired_since); ++ EXPECT_EQ(1, expired_since->size()); ++ context = (*expired_since)[0]; ++ EXPECT_EQ(leases_[2], context->getLease()); ++ EXPECT_EQ(queries_[2], context->getQuery()); ++ EXPECT_EQ(start_time + milliseconds(500), context->getNextExpiry()); ++ ++ // Fetch all that have expired since start time + 1500 ms ++ // Should be the third and second contexts ++ ASSERT_NO_THROW_LOG(expired_since = store.getExpiredSince(start_time + milliseconds(1500))); ++ ASSERT_TRUE(expired_since); ++ EXPECT_EQ(2, expired_since->size()); ++ ++ // First in list should be the third context. ++ context = (*expired_since)[0]; ++ EXPECT_EQ(leases_[2], context->getLease()); ++ EXPECT_EQ(queries_[2], context->getQuery()); ++ EXPECT_EQ(start_time + milliseconds(500), context->getNextExpiry()); ++ ++ // The last one in the list should be the second context. ++ context = (*expired_since)[1]; ++ EXPECT_EQ(leases_[1], context->getLease()); ++ EXPECT_EQ(queries_[1], context->getQuery()); ++ EXPECT_EQ(start_time + milliseconds(1000), context->getNextExpiry()); ++ } ++ ++ /// @brief Verifies that getAll() and clear() work properly. ++ void getAllAndClearTest() { ++ PingContextStore store; ++ ++ // Add contexts to store. ++ for (int i = 0; i < leases_.size(); ++i) { ++ PingContextPtr context; ++ ASSERT_NO_THROW_LOG(context = store.addContext(leases_[i], queries_[i], 1, 100)); ++ ASSERT_TRUE(context); ++ EXPECT_EQ(leases_[i], context->getLease()); ++ EXPECT_EQ(queries_[i], context->getQuery()); ++ } ++ ++ // Fetch them all. ++ PingContextCollectionPtr contexts; ++ ASSERT_NO_THROW_LOG(contexts = store.getAll()); ++ ASSERT_EQ(leases_.size(), contexts->size()); ++ ++ // Verify we got them all in order. ++ int i = 0; ++ for (auto const& context : *contexts) { ++ EXPECT_EQ(leases_[i], context->getLease()); ++ EXPECT_EQ(queries_[i], context->getQuery()); ++ ++i; ++ } ++ ++ // Now clear the store. Verify it's empty. ++ ASSERT_NO_THROW_LOG(store.clear()); ++ ASSERT_NO_THROW_LOG(contexts = store.getAll()); ++ ASSERT_EQ(0, contexts->size()); ++ ++ // Verify clearing an empty store does no harm. ++ ASSERT_NO_THROW_LOG(store.clear()); ++ } ++ ++private: ++ /// @brief Prepares the class for a test. ++ virtual void SetUp() { ++ Lease4Ptr lease; ++ lease.reset(new Lease4()); ++ lease->addr_ = IOAddress("192.0.2.1"); ++ leases_.push_back(lease); ++ ++ lease.reset(new Lease4()); ++ lease->addr_ = IOAddress("192.0.2.2"); ++ leases_.push_back(lease); ++ ++ lease.reset(new Lease4()); ++ lease->addr_ = IOAddress("192.0.2.3"); ++ leases_.push_back(lease); ++ ++ Pkt4Ptr query; ++ query.reset(new Pkt4(DHCPDISCOVER, 101)); ++ queries_.push_back(query); ++ ++ query.reset(new Pkt4(DHCPDISCOVER, 102)); ++ queries_.push_back(query); ++ ++ query.reset(new Pkt4(DHCPDISCOVER, 103)); ++ queries_.push_back(query); ++ ++ ASSERT_EQ(leases_.size(), queries_.size()); ++ } ++ ++public: ++ /// @brief List of pre-made leases. ++ std::vector<Lease4Ptr> leases_; ++ ++ /// @brief List of pre-made queries. ++ std::vector<Pkt4Ptr> queries_; ++}; ++ ++TEST_F(PingContextStoreTest, addContext) { ++ addContextTest(); ++} ++ ++TEST_F(PingContextStoreTest, addContextMultiThreading) { ++ MultiThreadingTest mt; ++ addContextTest(); ++} ++ ++TEST_F(PingContextStoreTest, addContextDuplicate) { ++ addContextDuplicateTest(); ++} ++ ++TEST_F(PingContextStoreTest, addContextDuplicateMultiThreading) { ++ MultiThreadingTest mt; ++ addContextDuplicateTest(); ++} ++ ++TEST_F(PingContextStoreTest, addContextInvalid) { ++ addContextInvalidTest(); ++} ++ ++TEST_F(PingContextStoreTest, addContextInvalidMultiThreading) { ++ MultiThreadingTest mt; ++ addContextInvalidTest(); ++} ++ ++TEST_F(PingContextStoreTest, deleteContext) { ++ deleteContextTest(); ++} ++ ++TEST_F(PingContextStoreTest, deleteContextMultiThreading) { ++ MultiThreadingTest mt; ++ deleteContextTest(); ++} ++ ++TEST_F(PingContextStoreTest, updateContext) { ++ updateContextTest(); ++} ++ ++TEST_F(PingContextStoreTest, updateContextMultiThreading) { ++ MultiThreadingTest mt; ++ updateContextTest(); ++} ++ ++TEST_F(PingContextStoreTest, getNextToSend) { ++ getNextToSendTest(); ++} ++ ++TEST_F(PingContextStoreTest, getNextToSendMultiThreading) { ++ MultiThreadingTest mt; ++ getNextToSendTest(); ++} ++ ++TEST_F(PingContextStoreTest, getByExpiration) { ++ getByExpirationTest(); ++} ++ ++TEST_F(PingContextStoreTest, getByExpirationMultiThreading) { ++ MultiThreadingTest mt; ++ getByExpirationTest(); ++} ++ ++TEST_F(PingContextStoreTest, getAllAndClear) { ++ getAllAndClearTest(); ++} ++ ++TEST_F(PingContextStoreTest, getAllAndClearMultiThreading) { ++ MultiThreadingTest mt; ++ getAllAndClearTest(); ++} ++ ++} // end of anonymous namespace +diff --git a/src/hooks/dhcp/ping_check/tests/ping_context_unittests.cc b/src/hooks/dhcp/ping_check/tests/ping_context_unittests.cc +new file mode 100644 +index 0000000000..4a38277ad6 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/ping_context_unittests.cc +@@ -0,0 +1,146 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++/// @file This file contains tests which exercise the PingContext class. ++ ++#include <config.h> ++#include <ping_context.h> ++#include <asiolink/io_address.h> ++#include <testutils/gtest_utils.h> ++ ++#include <gtest/gtest.h> ++#include <sstream> ++ ++using namespace std; ++using namespace isc; ++using namespace isc::asiolink; ++using namespace isc::dhcp; ++using namespace isc::ping_check; ++using namespace std::chrono; ++ ++namespace { ++ ++TEST(PingContextTest, validConstruction) { ++ // Make a valid lease and query. ++ Lease4Ptr lease(new Lease4()); ++ lease->addr_ = IOAddress("192.0.2.1"); ++ Pkt4Ptr query(new Pkt4(DHCPDISCOVER, 1234)); ++ ++ // Capture time now. ++ auto start_time = PingContext::now(); ++ ++ // Construct the context. ++ PingContextPtr context; ++ ASSERT_NO_THROW_LOG(context.reset(new PingContext(lease, query))); ++ ++ // Verify initial content. ++ EXPECT_EQ(lease->addr_, context->getTarget()); ++ EXPECT_EQ(1, context->getMinEchos()); ++ EXPECT_EQ(100, context->getReplyTimeout()); ++ EXPECT_EQ(0, context->getEchosSent()); ++ EXPECT_EQ(PingContext::EMPTY_TIME(), context->getLastEchoSentTime()); ++ EXPECT_EQ(PingContext::EMPTY_TIME(), context->getSendWaitStart()); ++ EXPECT_EQ(PingContext::EMPTY_TIME(), context->getNextExpiry()); ++ EXPECT_EQ(PingContext::NEW, context->getState()); ++ ++ // Start time should be less than or equal to created time. ++ EXPECT_LE(start_time, context->getCreatedTime()); ++ EXPECT_EQ(lease, context->getLease()); ++ EXPECT_EQ(query, context->getQuery()); ++} ++ ++TEST(PingContextTest, invalidConstruction) { ++ // Make a valid lease and query. ++ Lease4Ptr lease(new Lease4()); ++ lease->addr_ = IOAddress("192.0.2.1"); ++ Pkt4Ptr query(new Pkt4(DHCPDISCOVER, 1234)); ++ ++ // Empty lease should throw. ++ Lease4Ptr empty_lease; ++ PingContextPtr context; ++ ASSERT_THROW_MSG(context.reset(new PingContext(empty_lease, query)), BadValue, ++ "PingContext ctor - lease cannot be empty"); ++ ++ // Empty query should throw. ++ Pkt4Ptr empty_query; ++ ASSERT_THROW_MSG(context.reset(new PingContext(lease, empty_query)), BadValue, ++ "PingContext ctor - query cannot be empty"); ++ ++ // Empty lease address should throw. ++ lease->addr_ = IOAddress::IPV4_ZERO_ADDRESS(); ++ ASSERT_THROW_MSG(context.reset(new PingContext(lease, query)), BadValue, ++ "PingContext ctor - target address cannot be 0.0.0.0"); ++} ++ ++// Tests conversion of PingContext::State to string and vice-versa. ++TEST(PingContext, stateConversion) { ++ EXPECT_EQ(PingContext::NEW, PingContext::stringToState("NEW")); ++ EXPECT_EQ(PingContext::WAITING_TO_SEND, PingContext::stringToState("WAITING_TO_SEND")); ++ EXPECT_EQ(PingContext::SENDING, PingContext::stringToState("SENDING")); ++ EXPECT_EQ(PingContext::WAITING_FOR_REPLY, PingContext::stringToState("WAITING_FOR_REPLY")); ++ EXPECT_EQ(PingContext::TARGET_FREE, PingContext::stringToState("TARGET_FREE")); ++ EXPECT_EQ(PingContext::TARGET_IN_USE, PingContext::stringToState("TARGET_IN_USE")); ++ ASSERT_THROW_MSG(PingContext::stringToState("bogus"), BadValue, ++ "Invalid PingContext::State: 'bogus'"); ++ ++ EXPECT_EQ("NEW", PingContext::stateToString(PingContext::NEW)); ++ EXPECT_EQ("WAITING_TO_SEND", PingContext::stateToString(PingContext::WAITING_TO_SEND)); ++ EXPECT_EQ("SENDING", PingContext::stateToString(PingContext::SENDING)); ++ EXPECT_EQ("WAITING_FOR_REPLY", PingContext::stateToString(PingContext::WAITING_FOR_REPLY)); ++ EXPECT_EQ("TARGET_FREE", PingContext::stateToString(PingContext::TARGET_FREE)); ++ EXPECT_EQ("TARGET_IN_USE", PingContext::stateToString(PingContext::TARGET_IN_USE)); ++} ++ ++TEST(PingContext, accessors) { ++ // Make a valid lease and query. ++ Lease4Ptr lease(new Lease4()); ++ lease->addr_ = IOAddress("192.0.2.1"); ++ Pkt4Ptr query(new Pkt4(DHCPDISCOVER, 1234)); ++ ++ // Capture time now. ++ auto time_now = PingContext::now(); ++ ++ // Construct a context. ++ PingContextPtr context; ++ ASSERT_NO_THROW_LOG(context.reset(new PingContext(lease, query, 1, 50))); ++ ++ EXPECT_NO_THROW_LOG(context->setMinEchos(4)); ++ EXPECT_EQ(4, context->getMinEchos()); ++ ++ EXPECT_NO_THROW_LOG(context->setReplyTimeout(200)); ++ EXPECT_EQ(200, context->getReplyTimeout()); ++ ++ EXPECT_NO_THROW_LOG(context->setEchosSent(7)); ++ EXPECT_EQ(7, context->getEchosSent()); ++ ++ EXPECT_NO_THROW_LOG(context->setLastEchoSentTime(time_now)); ++ EXPECT_EQ(time_now, context->getLastEchoSentTime()); ++ ++ EXPECT_NO_THROW_LOG(context->setState(PingContext::SENDING)); ++ EXPECT_EQ(PingContext::SENDING, context->getState()); ++ ++ time_now += milliseconds(100); ++ EXPECT_NO_THROW_LOG(context->setSendWaitStart(time_now)); ++ EXPECT_EQ(time_now, context->getSendWaitStart()); ++ ++ time_now += milliseconds(100); ++ EXPECT_NO_THROW_LOG(context->setNextExpiry(time_now)); ++ EXPECT_EQ(time_now, context->getNextExpiry()); ++ ++ EXPECT_FALSE(context->isWaitingToSend()); ++ time_now += milliseconds(100); ++ ASSERT_NO_THROW_LOG(context->beginWaitingToSend(time_now)); ++ EXPECT_EQ(time_now, context->getSendWaitStart()); ++ EXPECT_TRUE(context->isWaitingToSend()); ++ ++ EXPECT_FALSE(context->isWaitingForReply()); ++ auto exp_expiry = time_now + milliseconds(context->getReplyTimeout()); ++ ASSERT_NO_THROW_LOG(context->beginWaitingForReply(time_now)); ++ EXPECT_EQ(exp_expiry, context->getNextExpiry()); ++ EXPECT_TRUE(context->isWaitingForReply()); ++} ++ ++} // end of anonymous namespace +diff --git a/src/hooks/dhcp/ping_check/tests/ping_test_utils.h b/src/hooks/dhcp/ping_check/tests/ping_test_utils.h +new file mode 100644 +index 0000000000..df1ede7526 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/ping_test_utils.h +@@ -0,0 +1,396 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#ifndef PING_TEST_UTILS_H ++#define PING_TEST_UTILS_H ++ ++#include <ping_channel.h> ++#include <asiolink/interval_timer.h> ++#include <asiolink/io_service.h> ++#include <asiolink/io_address.h> ++#include <testutils/gtest_utils.h> ++#include <asiolink/io_service_thread_pool.h> ++#include <util/multi_threading_mgr.h> ++#include <mutex> ++ ++#include <gtest/gtest.h> ++#include <queue> ++#include <list> ++#include <thread> ++#include <map> ++ ++namespace isc { ++namespace ping_check { ++ ++/// @brief Test timeout (ms). ++const long TEST_TIMEOUT = 10000; ++ ++/// @brief Maps IOAddresses to sequence numbers. ++/// ++/// Outbound requests are assigned a unique id and sequence ++/// number. This map is used to track the request's destination ++/// address by its sequence number. The channel can then substitute ++/// the loopback address, 127.0.0.1, as the destination address. ++/// Upon response receipt, the original destination can be found by ++/// the sequence number sent back in the response. ++class LoopbackMap { ++public: ++ /// @brief Constructor. ++ LoopbackMap() : map_(), mutex_(new std::mutex) { ++ } ++ ++ /// @brief Destructor. ++ ~LoopbackMap() = default; ++ ++ /// @brief Find and IOAddress associated with a sequence number. ++ /// ++ /// @param sequence sequence number to search by ++ /// ++ /// @return address found or IPV4_ZERO_ADDRESS. ++ asiolink::IOAddress find(uint16_t sequence) { ++ util::MultiThreadingLock lock(*mutex_); ++ auto const& iter = map_.find(sequence); ++ if (iter == map_.end()) { ++ return (asiolink::IOAddress::IPV4_ZERO_ADDRESS()); ++ } ++ ++ return (iter->second); ++ } ++ ++ /// @brief Adds an entry for a sequence number and address ++ /// ++ /// @param sequence sequence number associated with the address ++ /// @param address address to add to the map ++ /// ++ /// @return true if the entry was added, false otherwise. ++ bool add(uint16_t sequence, const asiolink::IOAddress& address) { ++ util::MultiThreadingLock lock(*mutex_); ++ if (map_.count(sequence)) { ++ return (false); ++ } ++ ++ map_.emplace(sequence, address); ++ return (true); ++ }; ++ ++ /// @brief Map of addresses by sequence number. ++ std::map<uint16_t, asiolink::IOAddress> map_; ++ ++ /// @brief Mutex to protect the map during operations. ++ const boost::scoped_ptr<std::mutex> mutex_; ++}; ++ ++/// @brief Testable derivation of PingChannel ++/// ++/// Overrides read and write functions to inject IO errors. ++class TestablePingChannel : public PingChannel { ++public: ++ /// @brief Constructor ++ /// ++ /// Instantiates the channel with its socket closed. ++ /// ++ /// @param io_service pointer to the IOService instance that will manage ++ /// the channel's IO. Must not be empty ++ /// @param next_to_send_cb callback to invoke to fetch the next IOAddress ++ /// to ping ++ /// @param echo_sent_cb callback to invoke when an ECHO send has completed ++ /// @param reply_received_cb callback to invoke when an ICMP reply has been ++ /// received. This callback is passed all inbound ICMP messages (e.g. ECHO ++ /// REPLY, UNREACHABLE, etc...) ++ /// @param shutdown_cb callback to invoke when the channel has shutdown due ++ /// to an error ++ /// ++ /// @throw BadValue if io_service is empty. ++ TestablePingChannel(asiolink::IOServicePtr& io_service, ++ NextToSendCallback next_to_send_cb, ++ EchoSentCallback echo_sent_cb, ++ ReplyReceivedCallback reply_received_cb, ++ ShutdownCallback shutdown_cb = ShutdownCallback()) ++ : PingChannel(io_service, next_to_send_cb, echo_sent_cb, reply_received_cb, shutdown_cb), ++ read_number_(0), throw_on_read_number_(0), ec_on_read_number_(0), read_error_ec_(), ++ write_number_(0), throw_on_write_number_(0), ec_on_write_number_(0), write_error_ec_(), ++ route_loopback_(true), loopback_map_(), stopped_(false) { ++ } ++ ++ /// @brief Virtual destructor ++ virtual ~TestablePingChannel() { ++ stopped_ = true; ++ } ++ ++ // @brief Schedules the next send. ++ // ++ // If the socket is not currently sending it posts a call to @c sendNext() ++ // to the channel's IOService. ++ virtual void startSend() { ++ if (stopped_) { ++ return; ++ } ++ PingChannel::startSend(); ++ } ++ ++ /// @brief Perform asynchronous read or feign a read error ++ /// ++ /// This virtual function is provided as means to inject errors during ++ /// read operations to facilitate testing. It tracks the number of ++ /// reads that have occurred since channel open and instigates an ++ /// error trigger on the trigger read number if a trigger has been set. ++ /// ++ /// @param data buffer to receive incoming message ++ /// @param length length of the data buffer ++ /// @param offset offset into buffer where data is to be put ++ /// @param endpoint source of the communication ++ /// @param callback callback object ++ virtual void asyncReceive(void* data, size_t length, size_t offset, ++ asiolink::IOEndpoint* endpoint, SocketCallback& callback) { ++ if (stopped_) { ++ return; ++ } ++ ++read_number_; ++ ++ // If we're set to fail with an exception, do so. ++ if (throw_on_read_number_ && (read_number_ == throw_on_read_number_)) { ++ isc_throw(Unexpected, "Injected read error"); ++ } ++ ++ // If we're set to fail via the callback, post a call with the ++ // desired error code. ++ if (ec_on_read_number_ && read_number_ == ec_on_read_number_) { ++ getIOService()->post([this]() { socketReadCallback(read_error_ec_, 0); }); ++ return; ++ } ++ ++ // No scheduled error, proceed with normal read. ++ PingChannel::asyncReceive(data, length, offset, endpoint, callback); ++ } ++ ++ /// @brief Perform asynchronous write or feign a write error ++ /// ++ /// This virtual function is provided as means to inject errors during ++ /// write operations to facilitate testing. It tracks the number of ++ /// writes that have occurred since channel open and instigates an ++ /// error trigger on the trigger write number if a trigger has been set. ++ /// ++ /// @param data buffer of data to write ++ /// @param length length of the data buffer ++ /// @param endpoint destination of the communication ++ /// @param callback callback object ++ virtual void asyncSend(void* data, size_t length, asiolink::IOEndpoint* endpoint, ++ SocketCallback& callback) { ++ if (stopped_) { ++ return; ++ } ++ ++write_number_; ++ if (throw_on_write_number_ && (write_number_ == throw_on_write_number_)) { ++ isc_throw(Unexpected, "Injected write error"); ++ } ++ ++ if (ec_on_write_number_ && write_number_ == ec_on_write_number_) { ++ ICMPMsgPtr fake_echo(new ICMPMsg()); ++ fake_echo->setType(ICMPMsg::ECHO_REQUEST); ++ fake_echo->setDestination(endpoint->getAddress()); ++ getIOService()->post([this, fake_echo]() { socketWriteCallback(fake_echo, write_error_ec_, 0); }); ++ return; ++ } ++ ++ // In order to make testing more predictable, we need slow writes down a bit. ++ usleep(5000); ++ ++ // If loopback routing is enabled, store the destination address by ++ // sequence number in the loopback map, then replace the destination ++ // endpoint with 127.0.0.1 and send it there. ++ if (route_loopback_) { ++ struct icmp* reply = (struct icmp*)(data); ++ auto sequence = (ntohs(reply->icmp_hun.ih_idseq.icd_seq)); ++ loopback_map_.add(sequence, endpoint->getAddress()); ++ ICMPEndpoint lo_endpoint(asiolink::IOAddress("127.0.0.1")); ++ PingChannel::asyncSend(data, length, &lo_endpoint, callback); ++ return; ++ } ++ ++ PingChannel::asyncSend(data, length, endpoint, callback); ++ } ++ ++ /// @brief Fetches the PingSocket. ++ /// ++ /// @return pointer to the PingSocket instance. ++ PingSocketPtr getPingSocket() { ++ return (socket_); ++ } ++ ++ /// @brief Checks if channel was opened in single-threaded mode. ++ /// ++ /// @return True if channel is single-threaded. ++ bool getSingleThreaded() const { ++ return (single_threaded_); ++ } ++ ++ /// @brief Fetch the WatchSocket instance. ++ /// ++ /// @return pointer to the WatchSocket. ++ util::WatchSocketPtr getWatchSocket() const { ++ return (watch_socket_); ++ } ++ ++ /// @brief The "write-ready" socket descriptor registered IfaceMgr. ++ /// ++ /// @return registered socket descriptor. ++ int getRegisteredWriteFd() const { ++ return (registered_write_fd_); ++ } ++ ++ /// @brief The "read-ready" socket descriptor registered IfaceMgr. ++ /// ++ /// @return registered socket descriptor. ++ int getRegisteredReadFd() const { ++ return (registered_read_fd_); ++ } ++ ++ /// @brief Tracks the number of reads since the channel was created ++ size_t read_number_; ++ ++ /// @brief Read number on which to thrown an exception from asyncReceive() ++ size_t throw_on_read_number_; ++ ++ /// @brief Read number on which to inject a socketReadCallback with an error code ++ size_t ec_on_read_number_; ++ ++ /// @brief Error code to inject on read error trigger ++ boost::system::error_code read_error_ec_; ++ ++ /// @brief Tracks the number of writes since the channel was created ++ size_t write_number_; ++ ++ /// @brief Write number on which to thrown an exception from asyncSend() ++ size_t throw_on_write_number_; ++ ++ /// @brief Error code to inject on write error trigger ++ size_t ec_on_write_number_; ++ ++ /// @brief Error code to inject on write error trigger ++ boost::system::error_code write_error_ec_; ++ ++ /// @brief Enables routing of 127.0.0.x by to 127.0.0.1 via sequence number. ++ bool route_loopback_; ++ ++ /// @brief Maps loopback addresses to sequence numbers when loopback routing ++ /// is enabled. ++ LoopbackMap loopback_map_; ++ ++ /// @brief Flag which indicates that the manager has been stopped. ++ bool stopped_; ++}; ++ ++/// @brief Defines a pointer to a TestablePingChannel ++typedef boost::shared_ptr<TestablePingChannel> TestablePingChannelPtr; ++ ++/// @brief Defines a callback type for test completion check functions. ++typedef std::function<bool()> TestDoneCallback; ++ ++/// @brief Test fixture class which uses an IOService for time management and/or IO ++class IOServiceTest : public ::testing::Test { ++public: ++ /// @brief Constructor. ++ /// ++ /// Starts test timer which detects timeouts. ++ IOServiceTest() ++ : test_io_service_(new asiolink::IOService()), ++ test_timer_(test_io_service_), ++ run_io_service_timer_(test_io_service_), ++ test_done_cb_() { ++ test_timer_.setup(std::bind(&IOServiceTest::timeoutHandler, this, true), ++ TEST_TIMEOUT, ++ asiolink::IntervalTimer::ONE_SHOT); ++ } ++ ++ /// @brief Indicates if current user is not root ++ /// ++ /// @return True if neither the uid or the effective ++ /// uid is root. ++ static bool notRoot() { ++ return (getuid() != 0 && geteuid() != 0); ++ } ++ ++ /// @brief Destructor. ++ /// ++ /// Removes active clients. ++ virtual ~IOServiceTest() { ++ test_timer_.cancel(); ++ run_io_service_timer_.cancel(); ++ test_io_service_->stopAndPoll(); ++ } ++ ++ /// @brief Callback function invoke upon test timeout. ++ /// ++ /// It stops the IO service and reports test timeout. ++ /// ++ /// @param fail_on_timeout Specifies if test failure should be reported. ++ void timeoutHandler(const bool fail_on_timeout) { ++ if (fail_on_timeout) { ++ ADD_FAILURE() << "Timeout occurred while running the test!"; ++ } ++ ++ test_io_service_->stop(); ++ } ++ ++ /// @brief Stops the IOService if criteria for test completion has been met. ++ /// ++ /// Stops the IOService If there either no test completion callback or the ++ /// call back returns true. ++ void stopIfDone() { ++ // If there is no done test callback or it returns true, stop the service. ++ if (!test_done_cb_ || (test_done_cb_)()) { ++ test_io_service_->stop(); ++ } ++ } ++ ++ /// @brief Posts a call to stop the io service to the io service. ++ /// ++ /// This should be used when stopping the service from callbacks on ++ /// thread pool threads. ++ void stopTestService() { ++ if (!test_io_service_->stopped()) { ++ test_io_service_->post([&]() { test_io_service_->stop(); }); ++ } ++ } ++ ++ /// @brief Runs IO service with optional timeout. ++ /// ++ /// @param timeout number of milliseconds to run the io service. Defaults to ++ /// zero which means run forever. ++ void runIOService(long timeout = 0) { ++ test_io_service_->stop(); ++ test_io_service_->restart(); ++ ++ if (timeout > 0) { ++ run_io_service_timer_.setup(std::bind(&IOServiceTest::timeoutHandler, ++ this, false), ++ timeout, ++ asiolink::IntervalTimer::ONE_SHOT); ++ } ++ ++ test_io_service_->run(); ++ test_io_service_->stopAndPoll(); ++ } ++ ++ /// @brief IO service used in the tests. ++ asiolink::IOServicePtr test_io_service_; ++ ++ /// @brief Asynchronous timer service to detect timeouts. ++ asiolink::IntervalTimer test_timer_; ++ ++ /// @brief Asynchronous timer for running IO service for a specified amount ++ /// of time. ++ asiolink::IntervalTimer run_io_service_timer_; ++ ++ /// @brief Callback function which event handlers can use to check if service ++ /// run should stop. ++ TestDoneCallback test_done_cb_; ++}; ++ ++} // end of namespace ping_check ++} // end of namespace isc ++ ++#endif +diff --git a/src/hooks/dhcp/ping_check/tests/run_unittests.cc b/src/hooks/dhcp/ping_check/tests/run_unittests.cc +new file mode 100644 +index 0000000000..d249e2362e +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/tests/run_unittests.cc +@@ -0,0 +1,19 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++ ++#include <log/logger_support.h> ++#include <gtest/gtest.h> ++ ++int ++main(int argc, char* argv[]) { ++ ::testing::InitGoogleTest(&argc, argv); ++ isc::log::initLogger(); ++ int result = RUN_ALL_TESTS(); ++ ++ return (result); ++} +diff --git a/src/hooks/dhcp/ping_check/version.cc b/src/hooks/dhcp/ping_check/version.cc +new file mode 100644 +index 0000000000..f2250ab126 +--- /dev/null ++++ b/src/hooks/dhcp/ping_check/version.cc +@@ -0,0 +1,17 @@ ++// Copyright (C) 2023-2025 Internet Systems Consortium, Inc. ("ISC") ++// ++// This Source Code Form is subject to the terms of the Mozilla Public ++// License, v. 2.0. If a copy of the MPL was not distributed with this ++// file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++#include <config.h> ++#include <hooks/hooks.h> ++ ++extern "C" { ++ ++/// @brief returns Kea hooks version. ++int version() { ++ return (KEA_HOOKS_VERSION); ++} ++ ++} +-- +2.39.5 (Apple Git-154) + diff --git a/scripts/package-build/keepalived/.gitignore b/scripts/package-build/keepalived/.gitignore index fa96cd3f..b6513f29 100644 --- a/scripts/package-build/keepalived/.gitignore +++ b/scripts/package-build/keepalived/.gitignore @@ -1,7 +1 @@ -keepalived/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc - +/keepalived/ diff --git a/scripts/package-build/keepalived/package.toml b/scripts/package-build/keepalived/package.toml index ad1008e6..3f5ec071 100644 --- a/scripts/package-build/keepalived/package.toml +++ b/scripts/package-build/keepalived/package.toml @@ -1,4 +1,4 @@ [[packages]] name = "keepalived" -commit_id = "debian/1%2.2.8-1" +commit_id = "debian/1%2.3.2-1" scm_url = "https://salsa.debian.org/debian/pkg-keepalived.git" diff --git a/scripts/package-build/keepalived/patches/0001-vrrp-Set-sysctl-arp_ignore-to-1-on-IPv6-VMACs.patch b/scripts/package-build/keepalived/patches/0001-vrrp-Set-sysctl-arp_ignore-to-1-on-IPv6-VMACs.patch deleted file mode 100644 index b099dc7b..00000000 --- a/scripts/package-build/keepalived/patches/0001-vrrp-Set-sysctl-arp_ignore-to-1-on-IPv6-VMACs.patch +++ /dev/null @@ -1,129 +0,0 @@ -From af4aa758c3512bec8233549e138b03741c5404f9 Mon Sep 17 00:00:00 2001 -From: Quentin Armitage <quentin@armitage.org.uk> -Date: Sat, 14 Oct 2023 15:37:19 +0100 -Subject: [PATCH] vrrp: Set sysctl arp_ignore to 1 on IPv6 VMACs - -Setting arp_ignore to 1 ensures that the VMAC interface does not respond -to ARP requests for IPv4 addresses not configured on the VMAC. - -Signed-off-by: Quentin Armitage <quentin@armitage.org.uk> ---- - keepalived/include/vrrp_if_config.h | 2 +- - keepalived/vrrp/vrrp_if_config.c | 28 ++++++++++++++++++++-------- - keepalived/vrrp/vrrp_vmac.c | 5 ++--- - 3 files changed, 23 insertions(+), 12 deletions(-) - -diff --git a/keepalived/include/vrrp_if_config.h b/keepalived/include/vrrp_if_config.h -index 35465cd..c35e56e 100644 ---- a/keepalived/include/vrrp_if_config.h -+++ b/keepalived/include/vrrp_if_config.h -@@ -34,7 +34,7 @@ extern void set_promote_secondaries(interface_t*); - extern void reset_promote_secondaries(interface_t*); - #ifdef _HAVE_VRRP_VMAC_ - extern void restore_rp_filter(void); --extern void set_interface_parameters(const interface_t*, interface_t*); -+extern void set_interface_parameters(const interface_t*, interface_t*, sa_family_t); - extern void reset_interface_parameters(interface_t*); - extern void link_set_ipv6(const interface_t*, bool); - #endif -diff --git a/keepalived/vrrp/vrrp_if_config.c b/keepalived/vrrp/vrrp_if_config.c -index cfce7e2..fbfd34c 100644 ---- a/keepalived/vrrp/vrrp_if_config.c -+++ b/keepalived/vrrp/vrrp_if_config.c -@@ -81,6 +81,11 @@ static sysctl_opts_t vmac_sysctl[] = { - { 0, 0} - }; - -+static sysctl_opts_t vmac_sysctl_6[] = { -+ { IPV4_DEVCONF_ARP_IGNORE, 1 }, -+ { 0, 0} -+}; -+ - #endif - #endif - -@@ -216,11 +221,14 @@ netlink_set_interface_flags(unsigned ifindex, const sysctl_opts_t *sys_opts) - - #ifdef _HAVE_VRRP_VMAC_ - static inline int --netlink_set_interface_parameters(const interface_t *ifp, interface_t *base_ifp) -+netlink_set_interface_parameters(const interface_t *ifp, interface_t *base_ifp, sa_family_t family) - { -- if (netlink_set_interface_flags(ifp->ifindex, vmac_sysctl)) -+ if (netlink_set_interface_flags(ifp->ifindex, family == AF_INET6 ? vmac_sysctl_6 : vmac_sysctl)) - return -1; - -+ if (family == AF_INET6) -+ return 0; -+ - /* If the underlying interface is a MACVLAN that has been moved into - * a separate network namespace from the parent, we can't access the - * parent. */ -@@ -271,9 +279,9 @@ netlink_reset_interface_parameters(const interface_t* ifp) - } - - static inline void --set_interface_parameters_devconf(const interface_t *ifp, interface_t *base_ifp) -+set_interface_parameters_devconf(const interface_t *ifp, interface_t *base_ifp, sa_family_t family) - { -- if (netlink_set_interface_parameters(ifp, base_ifp)) -+ if (netlink_set_interface_parameters(ifp, base_ifp, family)) - log_message(LOG_INFO, "Unable to set parameters for %s", ifp->ifname); - } - -@@ -310,11 +318,15 @@ reset_promote_secondaries_devconf(interface_t *ifp) - - #ifdef _HAVE_VRRP_VMAC_ - static inline void --set_interface_parameters_sysctl(const interface_t *ifp, interface_t *base_ifp) -+set_interface_parameters_sysctl(const interface_t *ifp, interface_t *base_ifp, sa_family_t family) - { - unsigned val; - - set_sysctl("net/ipv4/conf", ifp->ifname, "arp_ignore", 1); -+ -+ if (family == AF_INET6) -+ return; -+ - set_sysctl("net/ipv4/conf", ifp->ifname, "accept_local", 1); - set_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter", 0); - -@@ -524,15 +536,15 @@ restore_rp_filter(void) - } - - void --set_interface_parameters(const interface_t *ifp, interface_t *base_ifp) -+set_interface_parameters(const interface_t *ifp, interface_t *base_ifp, sa_family_t family) - { - if (all_rp_filter == UINT_MAX) - clear_rp_filter(); - - #ifdef _HAVE_IPV4_DEVCONF_ -- set_interface_parameters_devconf(ifp, base_ifp); -+ set_interface_parameters_devconf(ifp, base_ifp, family); - #else -- set_interface_parameters_sysctl(ifp, base_ifp); -+ set_interface_parameters_sysctl(ifp, base_ifp, family); - #endif - } - -diff --git a/keepalived/vrrp/vrrp_vmac.c b/keepalived/vrrp/vrrp_vmac.c -index e5ff0e9..021953a 100644 ---- a/keepalived/vrrp/vrrp_vmac.c -+++ b/keepalived/vrrp/vrrp_vmac.c -@@ -407,10 +407,9 @@ netlink_link_add_vmac(vrrp_t *vrrp, const interface_t *old_interface) - if (!ifp->ifindex) - return false; - -- if (vrrp->family == AF_INET && create_interface) { -+ if (create_interface) { - /* Set the necessary kernel parameters to make macvlans work for us */ --// If this saves current base_ifp's settings, we need to be careful if multiple VMACs on same i/f -- set_interface_parameters(ifp, ifp->base_ifp); -+ set_interface_parameters(ifp, ifp->base_ifp, vrrp->family); - } - - #ifdef _WITH_FIREWALL_ --- -2.34.1 - diff --git a/scripts/package-build/libnss-mapuser/.gitignore b/scripts/package-build/libnss-mapuser/.gitignore new file mode 100644 index 00000000..15657c19 --- /dev/null +++ b/scripts/package-build/libnss-mapuser/.gitignore @@ -0,0 +1 @@ +/libnss-mapuser/ diff --git a/scripts/package-build/libnss-mapuser/build.py b/scripts/package-build/libnss-mapuser/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/libnss-mapuser/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/libnss-mapuser/package.toml b/scripts/package-build/libnss-mapuser/package.toml new file mode 100644 index 00000000..20ff65b4 --- /dev/null +++ b/scripts/package-build/libnss-mapuser/package.toml @@ -0,0 +1,9 @@ +[[packages]] +name = "libnss-mapuser" +commit_id = "current" +scm_url = "https://github.com/vyos/libnss-mapuser.git" + +[dependencies] +packages = [ + "libaudit-dev" +] diff --git a/scripts/package-build/libpam-radius-auth/.gitignore b/scripts/package-build/libpam-radius-auth/.gitignore new file mode 100644 index 00000000..b6ba8742 --- /dev/null +++ b/scripts/package-build/libpam-radius-auth/.gitignore @@ -0,0 +1 @@ +/libpam-radius-auth/ diff --git a/scripts/package-build/libpam-radius-auth/build.py b/scripts/package-build/libpam-radius-auth/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/libpam-radius-auth/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/libpam-radius-auth/package.toml b/scripts/package-build/libpam-radius-auth/package.toml new file mode 100644 index 00000000..d2c760c8 --- /dev/null +++ b/scripts/package-build/libpam-radius-auth/package.toml @@ -0,0 +1,10 @@ +[[packages]] +name = "libpam-radius-auth" +commit_id = "current" +scm_url = "https://github.com/vyos/libpam-radius-auth.git" + +[dependencies] +packages = [ + "libpam-dev", + "libaudit-dev" +] diff --git a/scripts/package-build/linux-kernel/.gitignore b/scripts/package-build/linux-kernel/.gitignore index 0a18ea8c..f1fb5374 100644 --- a/scripts/package-build/linux-kernel/.gitignore +++ b/scripts/package-build/linux-kernel/.gitignore @@ -9,6 +9,7 @@ /ovpn-dco /nat-rtsp* /jool* +/ipt-netflow* /qat* /QAT* *.tar.gz @@ -18,13 +19,12 @@ # Intel Driver source i40e-*/ igb-*/ -ixgbe-*/ -ixgbevf-*/ +ethernet-linux-*/ vyos-intel-*/ vyos-linux-firmware*/ kernel-vars r8152-*.tar.bz2 - +ephemeral.* *.buildinfo *.build *.changes diff --git a/scripts/package-build/linux-kernel/README.md b/scripts/package-build/linux-kernel/README.md index 56954e5a..927e880c 100644 --- a/scripts/package-build/linux-kernel/README.md +++ b/scripts/package-build/linux-kernel/README.md @@ -5,9 +5,9 @@ # About -VyOS runs on a custom Linux Kernel (which is 4.19) at the time of this writing. -This repository holds a Jenkins Pipeline which is used to build the Custom -Kernel (x86_64/amd64 at the moment) and all required out-of tree modules. +VyOS runs on a custom Linux Kernel (which is 6.6) at the time of this writing. +This repository holds build scripts that are used to build the Custom Kernel +(x86_64/amd64 at the moment) and all required out-of tree modules. VyOS does not utilize the build in Intel Kernel drivers for its NICs as those Kernels sometimes lack features e.g. configurable receive-side-scaling queues. @@ -33,9 +33,3 @@ VyOS utilizes several Out-of-Tree modules (e.g. WireGuard, Accel-PPP and Intel network interface card drivers). Module source code is retrieved from the upstream repository and - when needed - patched so it can be build using this pipeline. - -In the past VyOS maintainers had a fork of the Linux Kernel, WireGuard and -Accel-PPP. This is fine but increases maintenance effort. By utilizing vanilla -repositories upgrading to new versions is very easy - only the branch/commit/tag -used when cloning the repository via [Jenkinsfile](Jenkinsfile) needs to be -adjusted. diff --git a/scripts/package-build/linux-kernel/arch b/scripts/package-build/linux-kernel/arch deleted file mode 120000 index f5f81fdc..00000000 --- a/scripts/package-build/linux-kernel/arch +++ /dev/null @@ -1 +0,0 @@ -../../../packages/linux-kernel/arch
\ No newline at end of file diff --git a/scripts/package-build/linux-kernel/arch/arm64/configs/vyos_defconfig b/scripts/package-build/linux-kernel/arch/arm64/configs/vyos_defconfig new file mode 100644 index 00000000..e6ea3893 --- /dev/null +++ b/scripts/package-build/linux-kernel/arch/arm64/configs/vyos_defconfig @@ -0,0 +1,7274 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm64 6.6.15 Kernel Configuration +# +CONFIG_CC_VERSION_TEXT="gcc (Debian 12.2.0-14) 12.2.0" +CONFIG_CC_IS_GCC=y +CONFIG_GCC_VERSION=120200 +CONFIG_CLANG_VERSION=0 +CONFIG_AS_IS_GNU=y +CONFIG_AS_VERSION=24000 +CONFIG_LD_IS_BFD=y +CONFIG_LD_VERSION=24000 +CONFIG_LLD_VERSION=0 +CONFIG_CC_CAN_LINK=y +CONFIG_CC_CAN_LINK_STATIC=y +CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y +CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y +CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y +CONFIG_PAHOLE_VERSION=0 +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_TABLE_SORT=y +CONFIG_THREAD_INFO_IN_TASK=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +# CONFIG_COMPILE_TEST is not set +# CONFIG_WERROR is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_BUILD_SALT="" +CONFIG_DEFAULT_INIT="" +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_WATCH_QUEUE is not set +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_USELIB=y +CONFIG_AUDIT=y +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +CONFIG_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_GENERIC_IRQ_INJECTION=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y +CONFIG_GENERIC_IRQ_IPI=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_IRQ_MSI_IOMMU=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +# CONFIG_GENERIC_IRQ_DEBUGFS is not set +# end of IRQ subsystem + +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +# end of Timers subsystem + +CONFIG_BPF=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y + +# +# BPF subsystem +# +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +# CONFIG_BPF_JIT_ALWAYS_ON is not set +CONFIG_BPF_JIT_DEFAULT_ON=y +# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set +# CONFIG_BPF_PRELOAD is not set +# end of BPF subsystem + +CONFIG_PREEMPT_BUILD=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_COUNT=y +CONFIG_PREEMPTION=y +CONFIG_PREEMPT_DYNAMIC=y +# CONFIG_SCHED_CORE is not set + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_PSI is not set +# end of CPU/Task time and stats accounting + +CONFIG_CPU_ISOLATION=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +CONFIG_PREEMPT_RCU=y +# CONFIG_RCU_EXPERT is not set +CONFIG_TREE_SRCU=y +CONFIG_TASKS_RCU_GENERIC=y +CONFIG_TASKS_RCU=y +CONFIG_TASKS_TRACE_RCU=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_NEED_SEGCBLIST=y +# end of RCU Subsystem + +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_IKHEADERS is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +# CONFIG_PRINTK_INDEX is not set +CONFIG_GENERIC_SCHED_CLOCK=y + +# +# Scheduler features +# +# CONFIG_UCLAMP_TASK is not set +# end of Scheduler features + +CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y +CONFIG_CC_HAS_INT128=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_GCC11_NO_ARRAY_BOUNDS=y +CONFIG_CC_NO_ARRAY_BOUNDS=y +CONFIG_ARCH_SUPPORTS_INT128=y +CONFIG_NUMA_BALANCING=y +CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y +CONFIG_CGROUPS=y +CONFIG_PAGE_COUNTER=y +# CONFIG_CGROUP_FAVOR_DYNMODS is not set +CONFIG_MEMCG=y +CONFIG_MEMCG_KMEM=y +# CONFIG_BLK_CGROUP is not set +CONFIG_CGROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_SCHED_MM_CID=y +CONFIG_CGROUP_PIDS=y +# CONFIG_CGROUP_RDMA is not set +# CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_HUGETLB is not set +CONFIG_CPUSETS=y +# CONFIG_CGROUP_DEVICE is not set +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_PERF is not set +CONFIG_CGROUP_BPF=y +# CONFIG_CGROUP_MISC is not set +# CONFIG_CGROUP_DEBUG is not set +CONFIG_SOCK_CGROUP_DATA=y +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_TIME_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_RD_ZSTD=y +# CONFIG_BOOT_CONFIG is not set +CONFIG_INITRAMFS_PRESERVE_MTIME=y +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_LD_ORPHAN_WARN=y +CONFIG_LD_ORPHAN_WARN_LEVEL="warn" +CONFIG_SYSCTL=y +CONFIG_HAVE_UID16=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_MULTIUSER=y +CONFIG_SGETMASK_SYSCALL=y +CONFIG_SYSFS_SYSCALL=y +CONFIG_FHANDLE=y +CONFIG_POSIX_TIMERS=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_FUTEX_PI=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +# CONFIG_IO_URING is not set +CONFIG_ADVISE_SYSCALLS=y +CONFIG_MEMBARRIER=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_SELFTEST is not set +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_BASE_RELATIVE=y +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +# CONFIG_KCMP is not set +CONFIG_RSEQ=y +CONFIG_CACHESTAT_SYSCALL=y +# CONFIG_DEBUG_RSEQ is not set +CONFIG_HAVE_PERF_EVENTS=y +# CONFIG_PC104 is not set + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# end of Kernel Performance Events And Counters + +CONFIG_SYSTEM_DATA_VERIFICATION=y +# CONFIG_PROFILING is not set +CONFIG_TRACEPOINTS=y + +# +# Kexec and crash features +# +CONFIG_CRASH_CORE=y +CONFIG_KEXEC_CORE=y +CONFIG_KEXEC=y +# CONFIG_KEXEC_FILE is not set +# CONFIG_CRASH_DUMP is not set +# end of Kexec and crash features +# end of General setup + +CONFIG_ARM64=y +CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y +CONFIG_64BIT=y +CONFIG_MMU=y +CONFIG_ARM64_PAGE_SHIFT=12 +CONFIG_ARM64_CONT_PTE_SHIFT=4 +CONFIG_ARM64_CONT_PMD_SHIFT=4 +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=33 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_SMP=y +CONFIG_KERNEL_MODE_NEON=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_PGTABLE_LEVELS=4 +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y + +# +# Platform selection +# +# CONFIG_ARCH_ACTIONS is not set +CONFIG_ARCH_SUNXI=y +# CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_APPLE is not set +CONFIG_ARCH_BCM=y +CONFIG_ARCH_BCM2835=y +# CONFIG_ARCH_BCM_IPROC is not set +# CONFIG_ARCH_BCMBCA is not set +# CONFIG_ARCH_BRCMSTB is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_BITMAIN is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SPARX5 is not set +CONFIG_ARCH_K3=y +# CONFIG_ARCH_LG1K is not set +CONFIG_ARCH_HISI=y +# CONFIG_ARCH_KEEMBAY is not set +# CONFIG_ARCH_MEDIATEK is not set +CONFIG_ARCH_MESON=y +CONFIG_ARCH_MVEBU=y +CONFIG_ARCH_NXP=y +CONFIG_ARCH_LAYERSCAPE=y +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_S32 is not set +# CONFIG_ARCH_MA35 is not set +# CONFIG_ARCH_NPCM is not set +CONFIG_ARCH_QCOM=y +# CONFIG_ARCH_REALTEK is not set +CONFIG_ARCH_RENESAS=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_ARCH_SEATTLE=y +# CONFIG_ARCH_INTEL_SOCFPGA is not set +# CONFIG_ARCH_STM32 is not set +CONFIG_ARCH_SYNQUACER=y +CONFIG_ARCH_TEGRA=y +# CONFIG_ARCH_SPRD is not set +CONFIG_ARCH_THUNDER=y +CONFIG_ARCH_THUNDER2=y +# CONFIG_ARCH_UNIPHIER is not set +CONFIG_ARCH_VEXPRESS=y +# CONFIG_ARCH_VISCONTI is not set +CONFIG_ARCH_XGENE=y +# CONFIG_ARCH_ZYNQMP is not set +# end of Platform selection + +# +# Kernel Features +# + +# +# ARM errata workarounds via the alternatives framework +# +CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y +CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y +CONFIG_ARM64_ERRATUM_826319=y +CONFIG_ARM64_ERRATUM_827319=y +CONFIG_ARM64_ERRATUM_824069=y +CONFIG_ARM64_ERRATUM_819472=y +CONFIG_ARM64_ERRATUM_832075=y +CONFIG_ARM64_ERRATUM_1742098=y +CONFIG_ARM64_ERRATUM_845719=y +CONFIG_ARM64_ERRATUM_843419=y +CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y +CONFIG_ARM64_ERRATUM_1024718=y +CONFIG_ARM64_ERRATUM_1418040=y +CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y +CONFIG_ARM64_ERRATUM_1165522=y +CONFIG_ARM64_ERRATUM_1319367=y +CONFIG_ARM64_ERRATUM_1530923=y +CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y +CONFIG_ARM64_ERRATUM_2441007=y +CONFIG_ARM64_ERRATUM_1286807=y +CONFIG_ARM64_ERRATUM_1463225=y +CONFIG_ARM64_ERRATUM_1542419=y +CONFIG_ARM64_ERRATUM_1508412=y +CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE=y +CONFIG_ARM64_ERRATUM_2051678=y +CONFIG_ARM64_ERRATUM_2077057=y +CONFIG_ARM64_ERRATUM_2658417=y +CONFIG_ARM64_ERRATUM_2119858=y +CONFIG_ARM64_ERRATUM_2139208=y +CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y +CONFIG_ARM64_ERRATUM_2054223=y +CONFIG_ARM64_ERRATUM_2067961=y +CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE=y +CONFIG_ARM64_ERRATUM_2253138=y +CONFIG_ARM64_ERRATUM_2224489=y +CONFIG_ARM64_ERRATUM_2441009=y +CONFIG_ARM64_ERRATUM_2064142=y +CONFIG_ARM64_ERRATUM_2038923=y +CONFIG_ARM64_ERRATUM_1902691=y +CONFIG_ARM64_ERRATUM_2457168=y +CONFIG_ARM64_ERRATUM_2645198=y +CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD=y +CONFIG_ARM64_ERRATUM_2966298=y +CONFIG_ARM64_ERRATUM_3117295=y +CONFIG_CAVIUM_ERRATUM_22375=y +CONFIG_CAVIUM_ERRATUM_23144=y +CONFIG_CAVIUM_ERRATUM_23154=y +CONFIG_CAVIUM_ERRATUM_27456=y +CONFIG_CAVIUM_ERRATUM_30115=y +CONFIG_CAVIUM_TX2_ERRATUM_219=y +CONFIG_FUJITSU_ERRATUM_010001=y +CONFIG_HISILICON_ERRATUM_161600802=y +CONFIG_QCOM_FALKOR_ERRATUM_1003=y +CONFIG_QCOM_FALKOR_ERRATUM_1009=y +CONFIG_QCOM_QDF2400_ERRATUM_0065=y +CONFIG_QCOM_FALKOR_ERRATUM_E1041=y +CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y +CONFIG_ROCKCHIP_ERRATUM_3588001=y +CONFIG_SOCIONEXT_SYNQUACER_PREITS=y +# end of ARM errata workarounds via the alternatives framework + +CONFIG_ARM64_4K_PAGES=y +# CONFIG_ARM64_16K_PAGES is not set +# CONFIG_ARM64_64K_PAGES is not set +# CONFIG_ARM64_VA_BITS_39 is not set +CONFIG_ARM64_VA_BITS_48=y +CONFIG_ARM64_VA_BITS=48 +CONFIG_ARM64_PA_BITS_48=y +CONFIG_ARM64_PA_BITS=48 +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SCHED_MC=y +# CONFIG_SCHED_CLUSTER is not set +CONFIG_SCHED_SMT=y +CONFIG_NR_CPUS=256 +CONFIG_HOTPLUG_CPU=y +CONFIG_NUMA=y +CONFIG_NODES_SHIFT=6 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +CONFIG_HZ_1000=y +CONFIG_HZ=1000 +CONFIG_SCHED_HRTICK=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_CC_HAVE_SHADOW_CALL_STACK=y +CONFIG_PARAVIRT=y +# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set +CONFIG_ARCH_SUPPORTS_KEXEC=y +CONFIG_ARCH_SUPPORTS_KEXEC_FILE=y +CONFIG_ARCH_SUPPORTS_KEXEC_SIG=y +CONFIG_ARCH_SUPPORTS_KEXEC_IMAGE_VERIFY_SIG=y +CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y +CONFIG_ARCH_SUPPORTS_CRASH_DUMP=y +CONFIG_TRANS_TABLE=y +CONFIG_XEN_DOM0=y +CONFIG_XEN=y +CONFIG_ARCH_FORCE_MAX_ORDER=10 +CONFIG_UNMAP_KERNEL_AT_EL0=y +CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y +CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +# CONFIG_ARM64_SW_TTBR0_PAN is not set +CONFIG_ARM64_TAGGED_ADDR_ABI=y +CONFIG_COMPAT=y +CONFIG_KUSER_HELPERS=y +CONFIG_COMPAT_ALIGNMENT_FIXUPS=y +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_SETEND_EMULATION=y + +# +# ARMv8.1 architectural features +# +CONFIG_ARM64_HW_AFDBM=y +CONFIG_ARM64_PAN=y +CONFIG_AS_HAS_LSE_ATOMICS=y +CONFIG_ARM64_LSE_ATOMICS=y +CONFIG_ARM64_USE_LSE_ATOMICS=y +# end of ARMv8.1 architectural features + +# +# ARMv8.2 architectural features +# +CONFIG_AS_HAS_ARMV8_2=y +CONFIG_AS_HAS_SHA3=y +CONFIG_ARM64_PMEM=y +CONFIG_ARM64_RAS_EXTN=y +CONFIG_ARM64_CNP=y +# end of ARMv8.2 architectural features + +# +# ARMv8.3 architectural features +# +CONFIG_ARM64_PTR_AUTH=y +CONFIG_ARM64_PTR_AUTH_KERNEL=y +CONFIG_CC_HAS_BRANCH_PROT_PAC_RET=y +CONFIG_CC_HAS_SIGN_RETURN_ADDRESS=y +CONFIG_AS_HAS_ARMV8_3=y +CONFIG_AS_HAS_CFI_NEGATE_RA_STATE=y +CONFIG_AS_HAS_LDAPR=y +# end of ARMv8.3 architectural features + +# +# ARMv8.4 architectural features +# +CONFIG_ARM64_AMU_EXTN=y +CONFIG_AS_HAS_ARMV8_4=y +CONFIG_ARM64_TLB_RANGE=y +# end of ARMv8.4 architectural features + +# +# ARMv8.5 architectural features +# +CONFIG_AS_HAS_ARMV8_5=y +CONFIG_ARM64_BTI=y +CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI=y +CONFIG_ARM64_E0PD=y +CONFIG_ARM64_AS_HAS_MTE=y +CONFIG_ARM64_MTE=y +# end of ARMv8.5 architectural features + +# +# ARMv8.7 architectural features +# +CONFIG_ARM64_EPAN=y +# end of ARMv8.7 architectural features + +CONFIG_ARM64_SVE=y +CONFIG_ARM64_SME=y +# CONFIG_ARM64_PSEUDO_NMI is not set +CONFIG_RELOCATABLE=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_RANDOMIZE_MODULE_REGION_FULL=y +CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y +CONFIG_STACKPROTECTOR_PER_TASK=y +# end of Kernel Features + +# +# Boot options +# +CONFIG_ARM64_ACPI_PARKING_PROTOCOL=y +CONFIG_CMDLINE="" +CONFIG_EFI_STUB=y +CONFIG_EFI=y +CONFIG_DMI=y +# end of Boot options + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_USERSPACE_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_CPU_PM=y +# CONFIG_ENERGY_MODEL is not set +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# end of Power management options + +# +# CPU Power Management +# + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_CPU_IDLE_GOV_TEO is not set +CONFIG_DT_IDLE_STATES=y +CONFIG_DT_IDLE_GENPD=y + +# +# ARM CPU Idle Drivers +# +CONFIG_ARM_PSCI_CPUIDLE=y +CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y +# end of ARM CPU Idle Drivers +# end of CPU Idle + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y + +# +# CPU frequency scaling drivers +# +CONFIG_CPUFREQ_DT=m +CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_ACPI_CPPC_CPUFREQ=m +CONFIG_ACPI_CPPC_CPUFREQ_FIE=y +CONFIG_ARM_ARMADA_37XX_CPUFREQ=m +# CONFIG_ARM_ARMADA_8K_CPUFREQ is not set +CONFIG_ARM_SCPI_CPUFREQ=m +CONFIG_ARM_IMX_CPUFREQ_DT=m +CONFIG_ARM_QCOM_CPUFREQ_HW=m +CONFIG_ARM_RASPBERRYPI_CPUFREQ=m +# CONFIG_ARM_SCMI_CPUFREQ is not set +CONFIG_ARM_TEGRA20_CPUFREQ=m +CONFIG_ARM_TEGRA124_CPUFREQ=y +CONFIG_ARM_TI_CPUFREQ=y +CONFIG_QORIQ_CPUFREQ=m +# end of CPU Frequency scaling +# end of CPU Power Management + +CONFIG_ARCH_SUPPORTS_ACPI=y +CONFIG_ACPI=y +CONFIG_ACPI_GENERIC_GSI=y +CONFIG_ACPI_CCA_REQUIRED=y +# CONFIG_ACPI_DEBUGGER is not set +CONFIG_ACPI_SPCR_TABLE=y +# CONFIG_ACPI_FPDT is not set +# CONFIG_ACPI_EC_DEBUGFS is not set +# CONFIG_ACPI_AC is not set +# CONFIG_ACPI_BATTERY is not set +CONFIG_ACPI_BUTTON=m +# CONFIG_ACPI_TINY_POWER_BUTTON is not set +CONFIG_ACPI_FAN=m +# CONFIG_ACPI_TAD is not set +# CONFIG_ACPI_DOCK is not set +CONFIG_ACPI_PROCESSOR_IDLE=y +CONFIG_ACPI_MCFG=y +CONFIG_ACPI_CPPC_LIB=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_IPMI=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_THERMAL=m +CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y +CONFIG_ACPI_TABLE_UPGRADE=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_PCI_SLOT=y +CONFIG_ACPI_CONTAINER=y +CONFIG_ACPI_HOTPLUG_MEMORY=y +CONFIG_ACPI_HED=y +# CONFIG_ACPI_CUSTOM_METHOD is not set +CONFIG_ACPI_BGRT=y +CONFIG_ACPI_REDUCED_HARDWARE_ONLY=y +CONFIG_ACPI_NFIT=m +# CONFIG_NFIT_SECURITY_DEBUG is not set +CONFIG_ACPI_NUMA=y +# CONFIG_ACPI_HMAT is not set +CONFIG_HAVE_ACPI_APEI=y +CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_GHES=y +CONFIG_ACPI_APEI_PCIEAER=y +CONFIG_ACPI_APEI_SEA=y +CONFIG_ACPI_APEI_MEMORY_FAILURE=y +# CONFIG_ACPI_APEI_EINJ is not set +# CONFIG_ACPI_APEI_ERST_DEBUG is not set +# CONFIG_ACPI_CONFIGFS is not set +# CONFIG_ACPI_PFRUT is not set +CONFIG_ACPI_IORT=y +CONFIG_ACPI_GTDT=y +CONFIG_ACPI_APMT=y +CONFIG_ACPI_PPTT=y +CONFIG_ACPI_PCC=y +# CONFIG_ACPI_FFH is not set +# CONFIG_PMIC_OPREGION is not set +CONFIG_ACPI_PRMT=y +CONFIG_IRQ_BYPASS_MANAGER=m +CONFIG_HAVE_KVM=y +# CONFIG_VIRTUALIZATION is not set + +# +# General architecture-dependent options +# +CONFIG_ARCH_HAS_SUBPAGE_FAULTS=y +CONFIG_HOTPLUG_CORE_SYNC=y +CONFIG_HOTPLUG_CORE_SYNC_DEAD=y +# CONFIG_KPROBES is not set +CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set +CONFIG_UPROBES=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y +CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y +CONFIG_HAVE_NMI=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_KEEPINITRD=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_SET_DIRECT_MAP=y +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_HAVE_ASM_MODVERSIONS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y +CONFIG_MMU_GATHER_TABLE_FREE=y +CONFIG_MMU_GATHER_RCU_TABLE_FREE=y +CONFIG_MMU_LAZY_TLB_REFCOUNT=y +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_ARCH_HAS_NMI_SAFE_THIS_CPU_OPS=y +CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y +CONFIG_HAVE_CMPXCHG_LOCAL=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP=y +CONFIG_SECCOMP_FILTER=y +# CONFIG_SECCOMP_CACHE_DEBUG is not set +CONFIG_HAVE_ARCH_STACKLEAK=y +CONFIG_HAVE_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR_STRONG=y +CONFIG_ARCH_SUPPORTS_SHADOW_CALL_STACK=y +# CONFIG_SHADOW_CALL_STACK is not set +CONFIG_ARCH_SUPPORTS_LTO_CLANG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y +CONFIG_LTO_NONE=y +CONFIG_ARCH_SUPPORTS_CFI_CLANG=y +CONFIG_HAVE_CONTEXT_TRACKING_USER=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOVE_PUD=y +CONFIG_HAVE_MOVE_PMD=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_HUGE_VMAP=y +CONFIG_HAVE_ARCH_HUGE_VMALLOC=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_ARCH_WANT_PMD_MKWRITE=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_COMPAT_OLD_SIGACTION=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_HAVE_ARCH_VMAP_STACK=y +CONFIG_VMAP_STACK=y +CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y +CONFIG_RANDOMIZE_KSTACK_OFFSET=y +# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_STRICT_MODULE_RWX=y +CONFIG_HAVE_ARCH_COMPILER_H=y +CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y +CONFIG_ARCH_USE_MEMREMAP_PROT=y +# CONFIG_LOCK_EVENT_COUNTS is not set +CONFIG_ARCH_HAS_RELR=y +CONFIG_HAVE_PREEMPT_DYNAMIC=y +CONFIG_HAVE_PREEMPT_DYNAMIC_KEY=y +CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y +CONFIG_ARCH_HAVE_TRACE_MMIO_ACCESS=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +# end of GCOV-based kernel profiling + +CONFIG_HAVE_GCC_PLUGINS=y +CONFIG_FUNCTION_ALIGNMENT_4B=y +CONFIG_FUNCTION_ALIGNMENT=4 +# end of General architecture-dependent options + +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_DEBUG is not set +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set +CONFIG_MODVERSIONS=y +CONFIG_ASM_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +CONFIG_MODULE_COMPRESS_NONE=y +# CONFIG_MODULE_COMPRESS_GZIP is not set +# CONFIG_MODULE_COMPRESS_XZ is not set +# CONFIG_MODULE_COMPRESS_ZSTD is not set +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +CONFIG_MODPROBE_PATH="/sbin/modprobe" +# CONFIG_TRIM_UNUSED_KSYMS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_BLOCK_LEGACY_AUTOLOAD=y +CONFIG_BLK_DEV_BSG_COMMON=y +CONFIG_BLK_ICQ=y +CONFIG_BLK_DEV_BSGLIB=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_INTEGRITY_T10=y +# CONFIG_BLK_DEV_ZONED is not set +CONFIG_BLK_WBT=y +CONFIG_BLK_WBT_MQ=y +CONFIG_BLK_DEBUG_FS=y +CONFIG_BLK_SED_OPAL=y +# CONFIG_BLK_INLINE_ENCRYPTION is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +# end of Partition Types + +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_MQ_VIRTIO=y +CONFIG_BLK_PM=y +CONFIG_BLOCK_HOLDER_DEPRECATED=y +CONFIG_BLK_MQ_STACKING=y + +# +# IO Schedulers +# +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +CONFIG_IOSCHED_BFQ=y +# end of IO Schedulers + +CONFIG_PADATA=y +CONFIG_ASN1=y +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_ARCH_USE_QUEUED_RWLOCKS=y +CONFIG_QUEUED_RWLOCKS=y +CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y +CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y +CONFIG_FREEZER=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_STATE=y +CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y +CONFIG_ARCH_HAVE_ELF_PROT=y +CONFIG_ARCH_USE_GNU_PROPERTY=y +CONFIG_ELFCORE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +CONFIG_BINFMT_MISC=m +CONFIG_COREDUMP=y +# end of Executable file formats + +# +# Memory Management options +# +# CONFIG_SWAP is not set + +# +# SLAB allocator options +# +# CONFIG_SLAB_DEPRECATED is not set +CONFIG_SLUB=y +# CONFIG_SLUB_TINY is not set +CONFIG_SLAB_MERGE_DEFAULT=y +CONFIG_SLAB_FREELIST_RANDOM=y +CONFIG_SLAB_FREELIST_HARDENED=y +# CONFIG_SLUB_STATS is not set +CONFIG_SLUB_CPU_PARTIAL=y +# CONFIG_RANDOM_KMALLOC_CACHES is not set +# end of SLAB allocator options + +# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_HAVE_FAST_GUP=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_NUMA_KEEP_MEMINFO=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_MEMORY_HOTPLUG=y +# CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE is not set +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_MHP_MEMMAP_ON_MEMORY=y +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y +CONFIG_MEMORY_BALLOON=y +CONFIG_BALLOON_COMPACTION=y +CONFIG_COMPACTION=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 +CONFIG_PAGE_REPORTING=y +CONFIG_MIGRATION=y +CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y +CONFIG_ARCH_ENABLE_THP_MIGRATION=y +CONFIG_CONTIG_ALLOC=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_MMU_NOTIFIER=y +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 +CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y +CONFIG_MEMORY_FAILURE=y +# CONFIG_HWPOISON_INJECT is not set +CONFIG_ARCH_WANTS_THP_SWAP=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y +# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set +# CONFIG_READ_ONLY_THP_FOR_FS is not set +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y +CONFIG_USE_PERCPU_NUMA_NODE_ID=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set +# CONFIG_CMA_DEBUGFS is not set +# CONFIG_CMA_SYSFS is not set +CONFIG_CMA_AREAS=19 +CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y +CONFIG_ARCH_HAS_PTE_DEVMAP=y +CONFIG_ARCH_HAS_ZONE_DMA_SET=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA32=y +# CONFIG_ZONE_DEVICE is not set +CONFIG_HMM_MIRROR=y +CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y +CONFIG_ARCH_USES_PG_ARCH_X=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_PERCPU_STATS is not set +# CONFIG_GUP_TEST is not set +# CONFIG_DMAPOOL_TEST is not set +CONFIG_ARCH_HAS_PTE_SPECIAL=y +CONFIG_MEMFD_CREATE=y +CONFIG_SECRETMEM=y +# CONFIG_ANON_VMA_NAME is not set +CONFIG_USERFAULTFD=y +CONFIG_HAVE_ARCH_USERFAULTFD_MINOR=y +# CONFIG_LRU_GEN is not set +CONFIG_ARCH_SUPPORTS_PER_VMA_LOCK=y +CONFIG_PER_VMA_LOCK=y +CONFIG_LOCK_MM_AND_FIND_VMA=y + +# +# Data Access Monitoring +# +# CONFIG_DAMON is not set +# end of Data Access Monitoring +# end of Memory Management options + +CONFIG_NET=y +CONFIG_COMPAT_NETLINK_MESSAGES=y +CONFIG_NET_INGRESS=y +CONFIG_NET_EGRESS=y +CONFIG_NET_XGRESS=y +CONFIG_NET_REDIRECT=y +CONFIG_SKB_EXTENSIONS=y + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_DIAG=m +CONFIG_UNIX=y +CONFIG_UNIX_SCM=y +CONFIG_AF_UNIX_OOB=y +CONFIG_UNIX_DIAG=m +CONFIG_TLS=y +CONFIG_TLS_DEVICE=y +# CONFIG_TLS_TOE is not set +CONFIG_XFRM=y +CONFIG_XFRM_OFFLOAD=y +CONFIG_XFRM_ALGO=m +CONFIG_XFRM_USER=m +CONFIG_XFRM_INTERFACE=m +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_MIGRATE=y +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_AH=m +CONFIG_XFRM_ESP=m +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y +CONFIG_XFRM_ESPINTCP=y +# CONFIG_SMC is not set +CONFIG_XDP_SOCKETS=y +# CONFIG_XDP_SOCKETS_DIAG is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_FIB_TRIE_STATS=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_ROUTE_CLASSID=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IP_TUNNEL=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE_COMMON=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_NET_UDP_TUNNEL=m +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_ESP_OFFLOAD=m +CONFIG_INET_ESPINTCP=y +CONFIG_INET_IPCOMP=m +CONFIG_INET_TABLE_PERTURB_ORDER=16 +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_UDP_DIAG=m +# CONFIG_INET_RAW_DIAG is not set +CONFIG_INET_DIAG_DESTROY=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_NV=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_DCTCP=m +CONFIG_TCP_CONG_CDG=m +CONFIG_TCP_CONG_BBR=m +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_ESP_OFFLOAD=m +CONFIG_INET6_ESPINTCP=y +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_ILA=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_IPV6_VTI=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_IPV6_SEG6_LWTUNNEL=y +CONFIG_IPV6_SEG6_HMAC=y +CONFIG_IPV6_SEG6_BPF=y +# CONFIG_IPV6_RPL_LWTUNNEL is not set +# CONFIG_IPV6_IOAM6_LWTUNNEL is not set +CONFIG_MPTCP=y +CONFIG_INET_MPTCP_DIAG=m +CONFIG_MPTCP_IPV6=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NET_PTP_CLASSIFY=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=m + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_INGRESS=y +CONFIG_NETFILTER_EGRESS=y +CONFIG_NETFILTER_SKIP_EGRESS=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_FAMILY_BRIDGE=y +CONFIG_NETFILTER_FAMILY_ARP=y +CONFIG_NETFILTER_BPF_LINK=y +# CONFIG_NETFILTER_NETLINK_HOOK is not set +CONFIG_NETFILTER_NETLINK_ACCT=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_OSF=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_LOG_SYSLOG=m +CONFIG_NETFILTER_CONNCOUNT=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_LABELS=y +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_GRE=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NF_CT_NETLINK_HELPER=m +CONFIG_NETFILTER_NETLINK_GLUE_CT=y +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_REDIRECT=y +CONFIG_NF_NAT_MASQUERADE=y +CONFIG_NETFILTER_SYNPROXY=m +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_NUMGEN=m +CONFIG_NFT_CT=m +CONFIG_NFT_FLOW_OFFLOAD=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_QUOTA=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_REJECT_INET=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_FIB=m +CONFIG_NFT_FIB_INET=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_TPROXY=m +CONFIG_NFT_SYNPROXY=m +CONFIG_NF_DUP_NETDEV=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_FIB_NETDEV=m +# CONFIG_NFT_REJECT_NETDEV is not set +CONFIG_NF_FLOW_TABLE_INET=m +CONFIG_NF_FLOW_TABLE=m +# CONFIG_NF_FLOW_TABLE_PROCFS is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XTABLES_COMPAT=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CGROUP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_L2TP=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +# end of Core Netfilter Configuration + +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPMARK=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_IPMAC=m +CONFIG_IP_SET_HASH_MAC=m +CONFIG_IP_SET_HASH_NETPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETNET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_FO=m +CONFIG_IP_VS_OVF=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +# CONFIG_IP_VS_MH is not set +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +# CONFIG_IP_VS_TWOS is not set + +# +# IPVS SH scheduler +# +CONFIG_IP_VS_SH_TAB_BITS=8 + +# +# IPVS MH scheduler +# +CONFIG_IP_VS_MH_TAB_INDEX=12 + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_NFCT=y +CONFIG_IP_VS_PE_SIP=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_SOCKET_IPV4=m +CONFIG_NF_TPROXY_IPV4=m +CONFIG_NF_TABLES_IPV4=y +CONFIG_NFT_REJECT_IPV4=m +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y +CONFIG_NF_DUP_IPV4=m +CONFIG_NF_LOG_ARP=m +CONFIG_NF_LOG_IPV4=m +CONFIG_NF_REJECT_IPV4=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SYNPROXY=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +# end of IP: Netfilter Configuration + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_SOCKET_IPV6=m +CONFIG_NF_TPROXY_IPV6=m +CONFIG_NF_TABLES_IPV6=y +CONFIG_NFT_REJECT_IPV6=m +CONFIG_NFT_DUP_IPV6=m +CONFIG_NFT_FIB_IPV6=m +CONFIG_NF_DUP_IPV6=m +CONFIG_NF_REJECT_IPV6=m +CONFIG_NF_LOG_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_SRH=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_SYNPROXY=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +# end of IPv6: Netfilter Configuration + +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_TABLES_BRIDGE=m +# CONFIG_NFT_BRIDGE_META is not set +CONFIG_NFT_BRIDGE_REJECT=m +CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +# CONFIG_BPFILTER is not set +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=y +# end of DCCP CCIDs Configuration + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set +# end of DCCP Kernel Hacking + +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set +CONFIG_SCTP_COOKIE_HMAC_MD5=y +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_INET_SCTP_DIAG=m +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_MRP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_BRIDGE_VLAN_FILTERING=y +# CONFIG_BRIDGE_MRP is not set +# CONFIG_BRIDGE_CFM is not set +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_6LOWPAN is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_CBS=m +CONFIG_NET_SCH_ETF=m +CONFIG_NET_SCH_MQPRIO_LIB=m +# CONFIG_NET_SCH_TAPRIO is not set +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_SKBPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_CAKE=m +CONFIG_NET_SCH_FQ=m +CONFIG_NET_SCH_HHF=m +CONFIG_NET_SCH_PIE=m +# CONFIG_NET_SCH_FQ_PIE is not set +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m +# CONFIG_NET_SCH_ETS is not set +# CONFIG_NET_SCH_DEFAULT is not set + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=m +CONFIG_NET_CLS_BPF=m +CONFIG_NET_CLS_FLOWER=m +CONFIG_NET_CLS_MATCHALL=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_IPSET=m +# CONFIG_NET_EMATCH_IPT is not set +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +# CONFIG_NET_ACT_SAMPLE is not set +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_NET_ACT_MPLS=m +CONFIG_NET_ACT_VLAN=m +CONFIG_NET_ACT_BPF=m +CONFIG_NET_ACT_CONNMARK=m +# CONFIG_NET_ACT_CTINFO is not set +CONFIG_NET_ACT_SKBMOD=m +# CONFIG_NET_ACT_IFE is not set +CONFIG_NET_ACT_TUNNEL_KEY=m +# CONFIG_NET_ACT_CT is not set +# CONFIG_NET_ACT_GATE is not set +# CONFIG_NET_TC_SKB_EXT is not set +CONFIG_NET_SCH_FIFO=y +CONFIG_DCB=y +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_VSOCKETS=m +CONFIG_VSOCKETS_DIAG=m +CONFIG_VSOCKETS_LOOPBACK=m +CONFIG_VMWARE_VMCI_VSOCKETS=m +CONFIG_VIRTIO_VSOCKETS=m +CONFIG_VIRTIO_VSOCKETS_COMMON=m +CONFIG_HYPERV_VSOCKETS=m +CONFIG_NETLINK_DIAG=m +CONFIG_MPLS=y +CONFIG_NET_MPLS_GSO=y +CONFIG_MPLS_ROUTING=m +CONFIG_MPLS_IPTUNNEL=m +# CONFIG_NET_NSH is not set +CONFIG_HSR=y +CONFIG_NET_SWITCHDEV=y +CONFIG_NET_L3_MASTER_DEV=y +# CONFIG_QRTR is not set +# CONFIG_NET_NCSI is not set +CONFIG_PCPU_DEV_REFCNT=y +CONFIG_MAX_SKB_FRAGS=17 +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_XPS=y +CONFIG_CGROUP_NET_PRIO=y +CONFIG_CGROUP_NET_CLASSID=y +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_STREAM_PARSER is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NET_DROP_MONITOR=y +# end of Network testing +# end of Networking options + +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_AF_KCM is not set +CONFIG_STREAM_PARSER=y +# CONFIG_MCTP is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +CONFIG_CFG80211_CERTIFICATION_ONUS=y +CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y +CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y +CONFIG_CFG80211_EXTRA_REGDB_KEYDIR="" +# CONFIG_CFG80211_REG_CELLULAR_HINTS is not set +# CONFIG_CFG80211_REG_RELAX_NO_IR is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_CFG80211_CRDA_SUPPORT=y +CONFIG_CFG80211_WEXT=y +CONFIG_CFG80211_WEXT_EXPORT=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_MESSAGE_TRACING is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +CONFIG_RFKILL=m +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +# CONFIG_RFKILL_GPIO is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +CONFIG_PSAMPLE=y +# CONFIG_NET_IFE is not set +CONFIG_LWTUNNEL=y +CONFIG_LWTUNNEL_BPF=y +CONFIG_DST_CACHE=y +CONFIG_GRO_CELLS=y +CONFIG_SOCK_VALIDATE_XMIT=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_SOCK_MSG=y +CONFIG_NET_DEVLINK=y +CONFIG_PAGE_POOL=y +# CONFIG_PAGE_POOL_STATS is not set +CONFIG_FAILOVER=m +CONFIG_ETHTOOL_NETLINK=y + +# +# Device Drivers +# +CONFIG_ARM_AMBA=y +CONFIG_TEGRA_AHB=y +CONFIG_HAVE_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_SYSCALL=y +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=y +CONFIG_PCIEAER=y +CONFIG_PCIEAER_INJECT=m +# CONFIG_PCIE_ECRC is not set +CONFIG_PCIEASPM=y +CONFIG_PCIEASPM_DEFAULT=y +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set +# CONFIG_PCIEASPM_PERFORMANCE is not set +CONFIG_PCIE_PME=y +CONFIG_PCIE_DPC=y +CONFIG_PCIE_PTM=y +# CONFIG_PCIE_EDR is not set +CONFIG_PCI_MSI=y +CONFIG_PCI_QUIRKS=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_REALLOC_ENABLE_AUTO=y +CONFIG_PCI_STUB=m +# CONFIG_PCI_PF_STUB is not set +CONFIG_PCI_ATS=y +CONFIG_PCI_ECAM=y +CONFIG_PCI_BRIDGE_EMUL=y +CONFIG_PCI_IOV=y +CONFIG_PCI_PRI=y +CONFIG_PCI_PASID=y +CONFIG_PCI_LABEL=y +CONFIG_PCI_HYPERV=m +# CONFIG_PCI_DYNAMIC_OF_NODES is not set +# CONFIG_PCIE_BUS_TUNE_OFF is not set +CONFIG_PCIE_BUS_DEFAULT=y +# CONFIG_PCIE_BUS_SAFE is not set +# CONFIG_PCIE_BUS_PERFORMANCE is not set +# CONFIG_PCIE_BUS_PEER2PEER is not set +# CONFIG_VGA_ARB is not set +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_ACPI=y +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_SHPC=y + +# +# PCI controller drivers +# +CONFIG_PCI_AARDVARK=y +# CONFIG_PCIE_ALTERA is not set +CONFIG_PCIE_BRCMSTB=y +CONFIG_PCI_HOST_THUNDER_PEM=y +CONFIG_PCI_HOST_THUNDER_ECAM=y +# CONFIG_PCI_FTPCI100 is not set +CONFIG_PCI_HOST_COMMON=y +CONFIG_PCI_HOST_GENERIC=y +# CONFIG_PCIE_HISI_ERR is not set +# CONFIG_PCIE_MICROCHIP_HOST is not set +CONFIG_PCI_HYPERV_INTERFACE=m +CONFIG_PCI_TEGRA=y +# CONFIG_PCIE_RCAR_HOST is not set +CONFIG_PCIE_ROCKCHIP=y +CONFIG_PCIE_ROCKCHIP_HOST=y +CONFIG_PCI_XGENE=y +CONFIG_PCI_XGENE_MSI=y +# CONFIG_PCIE_XILINX is not set + +# +# Cadence-based PCIe controllers +# +# CONFIG_PCIE_CADENCE_PLAT_HOST is not set +# CONFIG_PCI_J721E_HOST is not set +# end of Cadence-based PCIe controllers + +# +# DesignWare-based PCIe controllers +# +# CONFIG_PCIE_AL is not set +# CONFIG_PCI_MESON is not set +# CONFIG_PCI_IMX6_HOST is not set +# CONFIG_PCI_LAYERSCAPE is not set +# CONFIG_PCI_HISI is not set +# CONFIG_PCIE_KIRIN is not set +# CONFIG_PCIE_HISI_STB is not set +# CONFIG_PCIE_ARMADA_8K is not set +# CONFIG_PCIE_DW_PLAT_HOST is not set +# CONFIG_PCIE_QCOM is not set +# CONFIG_PCIE_ROCKCHIP_DW_HOST is not set +# CONFIG_PCI_KEYSTONE_HOST is not set +# end of DesignWare-based PCIe controllers + +# +# Mobiveil-based PCIe controllers +# +# CONFIG_PCIE_LAYERSCAPE_GEN4 is not set +# end of Mobiveil-based PCIe controllers +# end of PCI controller drivers + +# +# PCI Endpoint +# +# CONFIG_PCI_ENDPOINT is not set +# end of PCI Endpoint + +# +# PCI switch controller drivers +# +# CONFIG_PCI_SW_SWITCHTEC is not set +# end of PCI switch controller drivers + +# CONFIG_CXL_BUS is not set +# CONFIG_PCCARD is not set +# CONFIG_RAPIDIO is not set + +# +# Generic Driver Options +# +CONFIG_AUXILIARY_BUS=y +# CONFIG_UEVENT_HELPER is not set +CONFIG_DEVTMPFS=y +# CONFIG_DEVTMPFS_MOUNT is not set +# CONFIG_DEVTMPFS_SAFE is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# Firmware loader +# +CONFIG_FW_LOADER=y +CONFIG_FW_LOADER_DEBUG=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FW_LOADER_USER_HELPER=y +# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set +# CONFIG_FW_LOADER_COMPRESS is not set +CONFIG_FW_CACHE=y +# CONFIG_FW_UPLOAD is not set +# end of Firmware loader + +CONFIG_WANT_DEV_COREDUMP=y +CONFIG_ALLOW_DEV_COREDUMP=y +CONFIG_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set +CONFIG_SYS_HYPERVISOR=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_SOC_BUS=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_DMA_FENCE_TRACE is not set +CONFIG_GENERIC_ARCH_TOPOLOGY=y +CONFIG_GENERIC_ARCH_NUMA=y +# CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT is not set +# end of Generic Driver Options + +# +# Bus devices +# +# CONFIG_BRCMSTB_GISB_ARB is not set +# CONFIG_HISILICON_LPC is not set +# CONFIG_IMX_WEIM is not set +CONFIG_QCOM_EBI2=y +# CONFIG_QCOM_SSC_BLOCK_BUS is not set +CONFIG_SUN50I_DE2_BUS=y +CONFIG_SUNXI_RSB=y +# CONFIG_TEGRA_GMI is not set +CONFIG_TI_SYSC=y +CONFIG_VEXPRESS_CONFIG=y +CONFIG_FSL_MC_BUS=y +# CONFIG_FSL_MC_UAPI_SUPPORT is not set +# CONFIG_MHI_BUS is not set +# CONFIG_MHI_BUS_EP is not set +# end of Bus devices + +# +# Cache Drivers +# +# end of Cache Drivers + +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y + +# +# Firmware Drivers +# + +# +# ARM System Control and Management Interface Protocol +# +CONFIG_ARM_SCMI_PROTOCOL=y +# CONFIG_ARM_SCMI_RAW_MODE_SUPPORT is not set +CONFIG_ARM_SCMI_HAVE_TRANSPORT=y +CONFIG_ARM_SCMI_HAVE_SHMEM=y +CONFIG_ARM_SCMI_TRANSPORT_MAILBOX=y +CONFIG_ARM_SCMI_TRANSPORT_SMC=y +# CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE is not set +CONFIG_ARM_SCMI_POWER_DOMAIN=y +# CONFIG_ARM_SCMI_POWER_CONTROL is not set +# end of ARM System Control and Management Interface Protocol + +CONFIG_ARM_SCPI_PROTOCOL=m +CONFIG_ARM_SCPI_POWER_DOMAIN=m +# CONFIG_ARM_SDE_INTERFACE is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_DMIID=y +CONFIG_DMI_SYSFS=y +# CONFIG_ISCSI_IBFT is not set +CONFIG_RASPBERRYPI_FIRMWARE=y +# CONFIG_FW_CFG_SYSFS is not set +CONFIG_QCOM_SCM=y +# CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is not set +CONFIG_SYSFB=y +CONFIG_SYSFB_SIMPLEFB=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_TURRIS_MOX_RWTM=m +# CONFIG_ARM_FFA_TRANSPORT is not set +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# EFI (Extensible Firmware Interface) Support +# +CONFIG_EFI_ESRT=y +CONFIG_EFI_VARS_PSTORE=m +# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set +CONFIG_EFI_PARAMS_FROM_FDT=y +CONFIG_EFI_RUNTIME_WRAPPERS=y +CONFIG_EFI_GENERIC_STUB=y +# CONFIG_EFI_ZBOOT is not set +CONFIG_EFI_ARMSTUB_DTB_LOADER=y +# CONFIG_EFI_BOOTLOADER_CONTROL is not set +# CONFIG_EFI_CAPSULE_LOADER is not set +# CONFIG_EFI_TEST is not set +# CONFIG_RESET_ATTACK_MITIGATION is not set +# CONFIG_EFI_DISABLE_PCI_DMA is not set +CONFIG_EFI_EARLYCON=y +CONFIG_EFI_CUSTOM_SSDT_OVERLAYS=y +# CONFIG_EFI_DISABLE_RUNTIME is not set +# CONFIG_EFI_COCO_SECRET is not set +# end of EFI (Extensible Firmware Interface) Support + +CONFIG_UEFI_CPER=y +CONFIG_UEFI_CPER_ARM=y +# CONFIG_IMX_DSP is not set +# CONFIG_IMX_SCU is not set +CONFIG_MESON_SM=y +CONFIG_ARM_PSCI_FW=y +# CONFIG_ARM_PSCI_CHECKER is not set +CONFIG_HAVE_ARM_SMCCC=y +CONFIG_HAVE_ARM_SMCCC_DISCOVERY=y +CONFIG_ARM_SMCCC_SOC_ID=y + +# +# Tegra firmware driver +# +# CONFIG_TEGRA_IVC is not set +# end of Tegra firmware driver +# end of Firmware Drivers + +# CONFIG_GNSS is not set +# CONFIG_MTD is not set +CONFIG_DTC=y +CONFIG_OF=y +# CONFIG_OF_UNITTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_KOBJ=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_RESERVED_MEM=y +# CONFIG_OF_OVERLAY is not set +CONFIG_OF_NUMA=y +CONFIG_PARPORT=y +# CONFIG_PARPORT_PC is not set +# CONFIG_PARPORT_1284 is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG_MESSAGES is not set + +# +# Protocols +# +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_NULL_BLK=m +CONFIG_CDROM=m +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +# CONFIG_ZRAM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_XEN_BLKDEV_FRONTEND=m +CONFIG_XEN_BLKDEV_BACKEND=m +CONFIG_VIRTIO_BLK=m +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_UBLK is not set + +# +# NVME Support +# +CONFIG_NVME_CORE=y +CONFIG_BLK_DEV_NVME=y +CONFIG_NVME_MULTIPATH=y +# CONFIG_NVME_VERBOSE_ERRORS is not set +CONFIG_NVME_HWMON=y +# CONFIG_NVME_RDMA is not set +# CONFIG_NVME_FC is not set +# CONFIG_NVME_TCP is not set +# CONFIG_NVME_AUTH is not set +# CONFIG_NVME_TARGET is not set +# end of NVME Support + +# +# Misc devices +# +CONFIG_SENSORS_LIS3LV02D=m +CONFIG_AD525X_DPOT=m +CONFIG_AD525X_DPOT_I2C=m +# CONFIG_DUMMY_IRQ is not set +CONFIG_PHANTOM=m +CONFIG_TIFM_CORE=m +CONFIG_TIFM_7XX1=m +CONFIG_ICS932S401=m +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_HP_ILO=m +# CONFIG_QCOM_FASTRPC is not set +CONFIG_APDS9802ALS=m +CONFIG_ISL29003=m +CONFIG_ISL29020=m +CONFIG_SENSORS_TSL2550=m +CONFIG_SENSORS_BH1770=m +CONFIG_SENSORS_APDS990X=m +CONFIG_HMC6352=m +CONFIG_DS1682=m +CONFIG_SRAM=y +# CONFIG_DW_XDATA_PCIE is not set +# CONFIG_PCI_ENDPOINT_TEST is not set +# CONFIG_XILINX_SDFEC is not set +CONFIG_MISC_RTSX=m +# CONFIG_OPEN_DICE is not set +# CONFIG_VCPU_STALL_DETECTOR is not set +CONFIG_C2PORT=m + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=m +CONFIG_EEPROM_LEGACY=m +CONFIG_EEPROM_MAX6875=m +CONFIG_EEPROM_93CX6=m +# CONFIG_EEPROM_IDT_89HPESX is not set +# CONFIG_EEPROM_EE1004 is not set +# end of EEPROM support + +CONFIG_CB710_CORE=m +# CONFIG_CB710_DEBUG is not set +CONFIG_CB710_DEBUG_ASSUMPTIONS=y + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# end of Texas Instruments shared transport line discipline + +CONFIG_SENSORS_LIS3_I2C=m +CONFIG_ALTERA_STAPL=m +CONFIG_VMWARE_VMCI=m +# CONFIG_GENWQE is not set +# CONFIG_ECHO is not set +# CONFIG_BCM_VK is not set +# CONFIG_MISC_ALCOR_PCI is not set +CONFIG_MISC_RTSX_PCI=m +CONFIG_MISC_RTSX_USB=m +# CONFIG_UACCE is not set +# CONFIG_PVPANIC is not set +# CONFIG_GP_PCI1XXXX is not set +# end of Misc devices + +# +# SCSI device support +# +CONFIG_SCSI_MOD=m +CONFIG_RAID_ATTRS=m +CONFIG_SCSI_COMMON=m +CONFIG_SCSI=m +CONFIG_SCSI_DMA=y +CONFIG_SCSI_NETLINK=y +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +# CONFIG_CHR_DEV_ST is not set +CONFIG_BLK_DEV_SR=m +CONFIG_CHR_DEV_SG=m +CONFIG_BLK_DEV_BSG=y +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_ENCLOSURE is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set +CONFIG_SCSI_SCAN_ASYNC=y + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SRP_ATTRS=m +# end of SCSI Transports + +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m +CONFIG_SCSI_CXGB3_ISCSI=m +CONFIG_SCSI_CXGB4_ISCSI=m +CONFIG_SCSI_BNX2_ISCSI=m +CONFIG_SCSI_BNX2X_FCOE=m +CONFIG_BE2ISCSI=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_HPSA=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_3W_SAS=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC94XX=m +# CONFIG_AIC94XX_DEBUG is not set +# CONFIG_SCSI_HISI_SAS is not set +CONFIG_SCSI_MVSAS=m +# CONFIG_SCSI_MVSAS_DEBUG is not set +# CONFIG_SCSI_MVSAS_TASKLET is not set +CONFIG_SCSI_MVUMI=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ESAS2R=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_MPT3SAS=m +CONFIG_SCSI_MPT2SAS_MAX_SGE=128 +CONFIG_SCSI_MPT3SAS_MAX_SGE=128 +CONFIG_SCSI_MPT2SAS=m +# CONFIG_SCSI_MPI3MR is not set +CONFIG_SCSI_SMARTPQI=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_BUSLOGIC=m +# CONFIG_SCSI_FLASHPOINT is not set +# CONFIG_SCSI_MYRB is not set +# CONFIG_SCSI_MYRS is not set +CONFIG_XEN_SCSI_FRONTEND=m +CONFIG_HYPERV_STORAGE=m +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +CONFIG_FCOE=m +CONFIG_SCSI_SNIC=m +# CONFIG_SCSI_SNIC_DEBUG_FS is not set +CONFIG_SCSI_DMX3191D=m +# CONFIG_SCSI_FDOMAIN_PCI is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_TRACE is not set +# CONFIG_SCSI_IPR_DUMP is not set +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +# CONFIG_QEDI is not set +# CONFIG_QEDF is not set +CONFIG_SCSI_LPFC=m +# CONFIG_SCSI_LPFC_DEBUG_FS is not set +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_AM53C974=m +CONFIG_SCSI_WD719X=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_PMCRAID=m +CONFIG_SCSI_PM8001=m +CONFIG_SCSI_BFA_FC=m +CONFIG_SCSI_VIRTIO=m +CONFIG_SCSI_CHELSIO_FCOE=m +CONFIG_SCSI_DH=y +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +# end of SCSI device support + +CONFIG_ATA=m +CONFIG_SATA_HOST=y +CONFIG_PATA_TIMINGS=y +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ATA_FORCE=y +CONFIG_ATA_ACPI=y +CONFIG_SATA_ZPODD=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +CONFIG_SATA_AHCI=m +CONFIG_SATA_MOBILE_LPM_POLICY=3 +# CONFIG_SATA_AHCI_PLATFORM is not set +# CONFIG_AHCI_DWC is not set +# CONFIG_AHCI_IMX is not set +# CONFIG_AHCI_CEVA is not set +# CONFIG_AHCI_MVEBU is not set +# CONFIG_AHCI_SUNXI is not set +# CONFIG_AHCI_TEGRA is not set +# CONFIG_AHCI_QORIQ is not set +# CONFIG_SATA_AHCI_SEATTLE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_ACARD_AHCI is not set +# CONFIG_SATA_SIL24 is not set +CONFIG_ATA_SFF=y + +# +# SFF controllers with custom DMA interface +# +CONFIG_PDC_ADMA=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SX4=m +CONFIG_ATA_BMDMA=y + +# +# SATA SFF controllers with BMDMA +# +CONFIG_ATA_PIIX=m +# CONFIG_SATA_DWC is not set +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +# CONFIG_SATA_RCAR is not set +CONFIG_SATA_SIL=m +CONFIG_SATA_SIS=m +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_ULI is not set +CONFIG_SATA_VIA=m +# CONFIG_SATA_VITESSE is not set + +# +# PATA SFF controllers with BMDMA +# +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_ATP867X is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IMX is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87415 is not set +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RDC is not set +CONFIG_PATA_SCH=m +# CONFIG_PATA_SERVERWORKS is not set +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +# CONFIG_PATA_TOSHIBA is not set +# CONFIG_PATA_TRIFLEX is not set +CONFIG_PATA_VIA=m +# CONFIG_PATA_WINBOND is not set + +# +# PIO-only SFF controllers +# +# CONFIG_PATA_CMD640_PCI is not set +CONFIG_PATA_MPIIX=m +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OF_PLATFORM is not set +# CONFIG_PATA_RZ1000 is not set + +# +# Generic fallback / legacy drivers +# +# CONFIG_PATA_ACPI is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_LEGACY is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_AUTODETECT=y +CONFIG_MD_BITMAP_FILE=y +# CONFIG_MD_LINEAR is not set +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID10=y +CONFIG_MD_RAID456=y +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +# CONFIG_BCACHE is not set +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=y +# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set +# CONFIG_DM_UNSTRIPED is not set +CONFIG_DM_CRYPT=y +CONFIG_DM_SNAPSHOT=y +# CONFIG_DM_THIN_PROVISIONING is not set +# CONFIG_DM_CACHE is not set +# CONFIG_DM_WRITECACHE is not set +# CONFIG_DM_EBS is not set +# CONFIG_DM_ERA is not set +# CONFIG_DM_CLONE is not set +# CONFIG_DM_MIRROR is not set +CONFIG_DM_RAID=y +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_DUST is not set +CONFIG_DM_INIT=y +CONFIG_DM_UEVENT=y +# CONFIG_DM_FLAKEY is not set +# CONFIG_DM_VERITY is not set +# CONFIG_DM_SWITCH is not set +# CONFIG_DM_LOG_WRITES is not set +# CONFIG_DM_INTEGRITY is not set +# CONFIG_DM_AUDIT is not set +# CONFIG_TARGET_CORE is not set +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_SAS=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_CTL=m +# CONFIG_FUSION_LOGGING is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +# end of IEEE 1394 (FireWire) support + +CONFIG_NETDEVICES=y +CONFIG_MII=m +CONFIG_NET_CORE=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_WIREGUARD=m +# CONFIG_WIREGUARD_DEBUG is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_FC is not set +CONFIG_IFB=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_RANDOM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN_L3S=y +CONFIG_IPVLAN=m +CONFIG_IPVTAP=m +CONFIG_VXLAN=m +CONFIG_GENEVE=m +# CONFIG_BAREUDP is not set +CONFIG_GTP=m +# CONFIG_AMT is not set +CONFIG_MACSEC=m +# CONFIG_NETCONSOLE is not set +CONFIG_TUN=m +CONFIG_TAP=m +# CONFIG_TUN_VNET_CROSS_LE is not set +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +CONFIG_NLMON=m +CONFIG_NET_VRF=m +# CONFIG_VSOCKMON is not set +# CONFIG_ARCNET is not set +CONFIG_ETHERNET=y +CONFIG_MDIO=m +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +CONFIG_NET_VENDOR_AGERE=y +CONFIG_ET131X=m +CONFIG_NET_VENDOR_ALACRITECH=y +# CONFIG_SLICOSS is not set +CONFIG_NET_VENDOR_ALLWINNER=y +# CONFIG_SUN4I_EMAC is not set +CONFIG_NET_VENDOR_ALTEON=y +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_ALTERA_TSE is not set +CONFIG_NET_VENDOR_AMAZON=y +CONFIG_ENA_ETHERNET=m +CONFIG_NET_VENDOR_AMD=y +CONFIG_AMD8111_ETH=m +CONFIG_PCNET32=m +CONFIG_AMD_XGBE=m +# CONFIG_AMD_XGBE_DCB is not set +# CONFIG_PDS_CORE is not set +# CONFIG_NET_XGENE is not set +# CONFIG_NET_XGENE_V2 is not set +CONFIG_NET_VENDOR_AQUANTIA=y +CONFIG_AQTION=m +# CONFIG_NET_VENDOR_ARC is not set +CONFIG_NET_VENDOR_ASIX=y +CONFIG_NET_VENDOR_ATHEROS=y +CONFIG_ATL2=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL1C=m +CONFIG_ALX=m +CONFIG_NET_VENDOR_BROADCOM=y +CONFIG_B44=m +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI=y +# CONFIG_BCMGENET is not set +CONFIG_BNX2=m +CONFIG_CNIC=m +CONFIG_TIGON3=m +CONFIG_TIGON3_HWMON=y +CONFIG_BNX2X=m +CONFIG_BNX2X_SRIOV=y +# CONFIG_SYSTEMPORT is not set +CONFIG_BNXT=m +CONFIG_BNXT_SRIOV=y +CONFIG_BNXT_FLOWER_OFFLOAD=y +# CONFIG_BNXT_DCB is not set +CONFIG_BNXT_HWMON=y +CONFIG_NET_VENDOR_CADENCE=y +# CONFIG_MACB is not set +CONFIG_NET_VENDOR_CAVIUM=y +# CONFIG_THUNDER_NIC_PF is not set +# CONFIG_THUNDER_NIC_VF is not set +# CONFIG_THUNDER_NIC_BGX is not set +# CONFIG_THUNDER_NIC_RGX is not set +CONFIG_CAVIUM_PTP=y +CONFIG_LIQUIDIO_CORE=m +CONFIG_LIQUIDIO=m +# CONFIG_LIQUIDIO_VF is not set +CONFIG_NET_VENDOR_CHELSIO=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3=m +CONFIG_CHELSIO_T4=m +# CONFIG_CHELSIO_T4_DCB is not set +CONFIG_CHELSIO_T4VF=m +CONFIG_CHELSIO_LIB=m +CONFIG_CHELSIO_INLINE_CRYPTO=y +# CONFIG_CHELSIO_IPSEC_INLINE is not set +# CONFIG_CHELSIO_TLS_DEVICE is not set +# CONFIG_NET_VENDOR_CISCO is not set +# CONFIG_NET_VENDOR_CORTINA is not set +CONFIG_NET_VENDOR_DAVICOM=y +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_DEC is not set +CONFIG_NET_VENDOR_DLINK=y +CONFIG_DL2K=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_NET_VENDOR_EMULEX=y +CONFIG_BE2NET=m +CONFIG_BE2NET_HWMON=y +CONFIG_BE2NET_BE2=y +CONFIG_BE2NET_BE3=y +CONFIG_BE2NET_LANCER=y +CONFIG_BE2NET_SKYHAWK=y +CONFIG_NET_VENDOR_ENGLEDER=y +# CONFIG_TSNEP is not set +CONFIG_NET_VENDOR_EZCHIP=y +# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set +CONFIG_NET_VENDOR_FREESCALE=y +# CONFIG_FEC is not set +# CONFIG_FSL_FMAN is not set +# CONFIG_FSL_PQ_MDIO is not set +# CONFIG_FSL_XGMAC_MDIO is not set +# CONFIG_GIANFAR is not set +# CONFIG_FSL_DPAA2_SWITCH is not set +# CONFIG_FSL_ENETC is not set +# CONFIG_FSL_ENETC_VF is not set +# CONFIG_FSL_ENETC_IERB is not set +# CONFIG_FSL_ENETC_MDIO is not set +CONFIG_NET_VENDOR_FUNGIBLE=y +# CONFIG_FUN_ETH is not set +CONFIG_NET_VENDOR_GOOGLE=y +CONFIG_GVE=m +CONFIG_NET_VENDOR_HISILICON=y +# CONFIG_HIX5HD2_GMAC is not set +# CONFIG_HISI_FEMAC is not set +# CONFIG_HIP04_ETH is not set +# CONFIG_HNS_DSAF is not set +# CONFIG_HNS_ENET is not set +# CONFIG_HNS3 is not set +CONFIG_NET_VENDOR_HUAWEI=y +CONFIG_HINIC=y +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_INTEL=y +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_IGB=m +CONFIG_IGB_HWMON=y +CONFIG_IGBVF=m +# CONFIG_IXGBE is not set +# CONFIG_IXGBEVF is not set +CONFIG_I40E=m +# CONFIG_I40E_DCB is not set +CONFIG_IAVF=m +CONFIG_I40EVF=m +CONFIG_ICE=m +CONFIG_ICE_SWITCHDEV=y +# CONFIG_FM10K is not set +CONFIG_IGC=m +CONFIG_JME=m +CONFIG_NET_VENDOR_LITEX=y +# CONFIG_LITEX_LITEETH is not set +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_MVMDIO is not set +# CONFIG_MVNETA is not set +# CONFIG_MVPP2 is not set +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKGE_GENESIS=y +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_OCTEONTX2_AF is not set +# CONFIG_OCTEONTX2_PF is not set +# CONFIG_OCTEON_EP is not set +# CONFIG_PRESTERA is not set +CONFIG_NET_VENDOR_MELLANOX=y +CONFIG_MLX4_EN=m +CONFIG_MLX4_EN_DCB=y +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_CORE_GEN2=y +CONFIG_MLX5_CORE=m +# CONFIG_MLX5_FPGA is not set +CONFIG_MLX5_CORE_EN=y +CONFIG_MLX5_EN_ARFS=y +CONFIG_MLX5_EN_RXNFC=y +CONFIG_MLX5_MPFS=y +CONFIG_MLX5_ESWITCH=y +CONFIG_MLX5_BRIDGE=y +CONFIG_MLX5_CORE_EN_DCB=y +# CONFIG_MLX5_CORE_IPOIB is not set +# CONFIG_MLX5_MACSEC is not set +CONFIG_MLX5_EN_IPSEC=y +CONFIG_MLX5_EN_TLS=y +CONFIG_MLX5_SW_STEERING=y +# CONFIG_MLX5_SF is not set +CONFIG_MLXSW_CORE=m +CONFIG_MLXSW_CORE_HWMON=y +CONFIG_MLXSW_CORE_THERMAL=y +CONFIG_MLXSW_PCI=m +CONFIG_MLXSW_I2C=m +CONFIG_MLXSW_SPECTRUM=m +CONFIG_MLXSW_SPECTRUM_DCB=y +CONFIG_MLXSW_MINIMAL=m +CONFIG_MLXFW=m +# CONFIG_MLXBF_GIGE is not set +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_KSZ884X_PCI=m +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_LAN743X is not set +# CONFIG_LAN966X_SWITCH is not set +# CONFIG_VCAP is not set +CONFIG_NET_VENDOR_MICROSEMI=y +# CONFIG_MSCC_OCELOT_SWITCH is not set +CONFIG_NET_VENDOR_MICROSOFT=y +CONFIG_NET_VENDOR_MYRI=y +CONFIG_MYRI10GE=m +CONFIG_FEALNX=m +# CONFIG_NET_VENDOR_NI is not set +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NATSEMI=m +CONFIG_NS83820=m +CONFIG_NET_VENDOR_NETERION=y +CONFIG_S2IO=m +# CONFIG_NET_VENDOR_NETRONOME is not set +# CONFIG_NET_VENDOR_8390 is not set +CONFIG_NET_VENDOR_NVIDIA=y +CONFIG_FORCEDETH=m +CONFIG_NET_VENDOR_OKI=y +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_PACKET_ENGINES=y +CONFIG_HAMACHI=m +CONFIG_YELLOWFIN=m +# CONFIG_NET_VENDOR_PENSANDO is not set +CONFIG_NET_VENDOR_QLOGIC=y +CONFIG_QLA3XXX=m +CONFIG_QLCNIC=m +CONFIG_QLCNIC_SRIOV=y +CONFIG_QLCNIC_DCB=y +CONFIG_QLCNIC_HWMON=y +CONFIG_NETXEN_NIC=m +CONFIG_QED=m +CONFIG_QED_SRIOV=y +CONFIG_QEDE=m +CONFIG_NET_VENDOR_BROCADE=y +CONFIG_BNA=m +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_RDC is not set +CONFIG_NET_VENDOR_REALTEK=y +CONFIG_8139CP=m +CONFIG_8139TOO=m +# CONFIG_8139TOO_PIO is not set +CONFIG_8139TOO_TUNE_TWISTER=y +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_R8169=m +CONFIG_NET_VENDOR_RENESAS=y +# CONFIG_SH_ETH is not set +# CONFIG_RAVB is not set +# CONFIG_RENESAS_ETHER_SWITCH is not set +CONFIG_NET_VENDOR_ROCKER=y +# CONFIG_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +CONFIG_NET_VENDOR_SILAN=y +CONFIG_SC92031=m +CONFIG_NET_VENDOR_SIS=y +CONFIG_SIS900=m +CONFIG_SIS190=m +CONFIG_NET_VENDOR_SOLARFLARE=y +CONFIG_SFC=m +CONFIG_SFC_MCDI_MON=y +CONFIG_SFC_SRIOV=y +CONFIG_SFC_MCDI_LOGGING=y +CONFIG_SFC_FALCON=m +# CONFIG_SFC_SIENA is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_SOCIONEXT is not set +CONFIG_NET_VENDOR_STMICRO=y +CONFIG_STMMAC_ETH=m +# CONFIG_STMMAC_SELFTESTS is not set +CONFIG_STMMAC_PLATFORM=m +# CONFIG_DWMAC_DWC_QOS_ETH is not set +CONFIG_DWMAC_GENERIC=m +CONFIG_DWMAC_IPQ806X=m +CONFIG_DWMAC_MESON=m +CONFIG_DWMAC_QCOM_ETHQOS=m +CONFIG_DWMAC_ROCKCHIP=m +CONFIG_DWMAC_SUNXI=m +CONFIG_DWMAC_SUN8I=m +CONFIG_DWMAC_IMX8=m +# CONFIG_DWMAC_INTEL_PLAT is not set +# CONFIG_DWMAC_TEGRA is not set +# CONFIG_STMMAC_PCI is not set +# CONFIG_NET_VENDOR_SUN is not set +CONFIG_NET_VENDOR_SYNOPSYS=y +# CONFIG_DWC_XLGMAC is not set +CONFIG_NET_VENDOR_TEHUTI=y +CONFIG_TEHUTI=m +CONFIG_NET_VENDOR_TI=y +# CONFIG_TI_DAVINCI_MDIO is not set +# CONFIG_TI_CPSW_PHY_SEL is not set +# CONFIG_TI_K3_AM65_CPSW_NUSS is not set +# CONFIG_TI_K3_AM65_CPTS is not set +CONFIG_TLAN=m +CONFIG_NET_VENDOR_VERTEXCOM=y +CONFIG_NET_VENDOR_VIA=y +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +CONFIG_VIA_VELOCITY=m +CONFIG_NET_VENDOR_WANGXUN=y +# CONFIG_NGBE is not set +# CONFIG_TXGBE is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_XILINX is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_NET_SB1000 is not set +CONFIG_PHYLINK=m +CONFIG_PHYLIB=y +CONFIG_SWPHY=y +# CONFIG_LED_TRIGGER_PHY is not set +CONFIG_PHYLIB_LEDS=y +CONFIG_FIXED_PHY=y +# CONFIG_SFP is not set + +# +# MII PHY device drivers +# +CONFIG_AMD_PHY=m +# CONFIG_MESON_GXL_PHY is not set +# CONFIG_ADIN_PHY is not set +# CONFIG_ADIN1100_PHY is not set +CONFIG_AQUANTIA_PHY=m +CONFIG_AX88796B_PHY=m +CONFIG_BROADCOM_PHY=m +# CONFIG_BCM54140_PHY is not set +CONFIG_BCM7XXX_PHY=m +# CONFIG_BCM84881_PHY is not set +CONFIG_BCM87XX_PHY=m +CONFIG_BCM_NET_PHYLIB=m +CONFIG_CICADA_PHY=m +CONFIG_CORTINA_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_ICPLUS_PHY=m +CONFIG_LXT_PHY=m +CONFIG_INTEL_XWAY_PHY=m +CONFIG_LSI_ET1011C_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_MARVELL_10G_PHY=m +# CONFIG_MARVELL_88Q2XXX_PHY is not set +# CONFIG_MARVELL_88X2222_PHY is not set +# CONFIG_MAXLINEAR_GPHY is not set +# CONFIG_MEDIATEK_GE_PHY is not set +CONFIG_MICREL_PHY=m +# CONFIG_MICROCHIP_T1S_PHY is not set +CONFIG_MICROCHIP_PHY=m +CONFIG_MICROCHIP_T1_PHY=m +CONFIG_MICROSEMI_PHY=m +# CONFIG_MOTORCOMM_PHY is not set +CONFIG_NATIONAL_PHY=m +# CONFIG_NXP_CBTX_PHY is not set +# CONFIG_NXP_C45_TJA11XX_PHY is not set +# CONFIG_NXP_TJA11XX_PHY is not set +# CONFIG_NCN26000_PHY is not set +CONFIG_AT803X_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_REALTEK_PHY=m +CONFIG_RENESAS_PHY=m +CONFIG_ROCKCHIP_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_STE10XP=m +CONFIG_TERANETICS_PHY=m +CONFIG_DP83822_PHY=m +CONFIG_DP83TC811_PHY=m +CONFIG_DP83848_PHY=m +CONFIG_DP83867_PHY=m +# CONFIG_DP83869_PHY is not set +# CONFIG_DP83TD510_PHY is not set +CONFIG_VITESSE_PHY=m +# CONFIG_XILINX_GMII2RGMII is not set +# CONFIG_PSE_CONTROLLER is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_BUS=y +CONFIG_FWNODE_MDIO=y +CONFIG_OF_MDIO=y +CONFIG_ACPI_MDIO=y +CONFIG_MDIO_DEVRES=y +# CONFIG_MDIO_SUN4I is not set +# CONFIG_MDIO_XGENE is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_MDIO_HISI_FEMAC is not set +# CONFIG_MDIO_MVUSB is not set +# CONFIG_MDIO_MSCC_MIIM is not set +# CONFIG_MDIO_OCTEON is not set +# CONFIG_MDIO_IPQ4019 is not set +# CONFIG_MDIO_IPQ8064 is not set +# CONFIG_MDIO_THUNDER is not set + +# +# MDIO Multiplexers +# +CONFIG_MDIO_BUS_MUX=m +CONFIG_MDIO_BUS_MUX_MESON_G12A=m +CONFIG_MDIO_BUS_MUX_MESON_GXL=m +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set + +# +# PCS device drivers +# +CONFIG_PCS_XPCS=m +# end of PCS device drivers + +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=m +# CONFIG_PPPOE_HASH_BITS_1 is not set +# CONFIG_PPPOE_HASH_BITS_2 is not set +CONFIG_PPPOE_HASH_BITS_4=y +# CONFIG_PPPOE_HASH_BITS_8 is not set +CONFIG_PPPOE_HASH_BITS=4 +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +# CONFIG_SLIP is not set +CONFIG_SLHC=m +CONFIG_USB_NET_DRIVERS=m +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +CONFIG_USB_NET_QMI_WWAN=m +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +CONFIG_USB_SIERRA_NET=m +# CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set +# CONFIG_USB_NET_AQC111 is not set +CONFIG_USB_RTL8153_ECM=m +CONFIG_WLAN=y +CONFIG_WLAN_VENDOR_ADMTEK=y +CONFIG_ADM8211=m +CONFIG_ATH_COMMON=m +CONFIG_WLAN_VENDOR_ATH=y +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y +CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING=y +CONFIG_ATH5K=m +# CONFIG_ATH5K_DEBUG is not set +# CONFIG_ATH5K_TRACER is not set +CONFIG_ATH5K_PCI=y +# CONFIG_ATH5K_TEST_CHANNELS is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +# CONFIG_ATH9K_BTCOEX_SUPPORT is not set +CONFIG_ATH9K=m +CONFIG_ATH9K_PCI=y +# CONFIG_ATH9K_AHB is not set +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DFS_CERTIFIED is not set +# CONFIG_ATH9K_DYNACK is not set +# CONFIG_ATH9K_WOW is not set +CONFIG_ATH9K_RFKILL=y +CONFIG_ATH9K_CHANNEL_CONTEXT=y +CONFIG_ATH9K_PCOEM=y +# CONFIG_ATH9K_PCI_NO_EEPROM is not set +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +# CONFIG_ATH9K_HWRNG is not set +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +CONFIG_CARL9170_WPC=y +# CONFIG_CARL9170_HWRNG is not set +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_ATH6KL_USB=m +# CONFIG_ATH6KL_DEBUG is not set +# CONFIG_ATH6KL_TRACING is not set +# CONFIG_ATH6KL_REGDOMAIN is not set +CONFIG_AR5523=m +CONFIG_WIL6210=m +CONFIG_WIL6210_ISR_COR=y +# CONFIG_WIL6210_TRACING is not set +CONFIG_WIL6210_DEBUGFS=y +CONFIG_ATH10K=m +CONFIG_ATH10K_CE=y +CONFIG_ATH10K_PCI=m +# CONFIG_ATH10K_AHB is not set +CONFIG_ATH10K_SDIO=m +CONFIG_ATH10K_USB=m +# CONFIG_ATH10K_DEBUG is not set +# CONFIG_ATH10K_DEBUGFS is not set +# CONFIG_ATH10K_TRACING is not set +CONFIG_ATH10K_DFS_CERTIFIED=y +# CONFIG_WCN36XX is not set +# CONFIG_ATH11K is not set +# CONFIG_ATH12K is not set +# CONFIG_WLAN_VENDOR_ATMEL is not set +CONFIG_WLAN_VENDOR_BROADCOM=y +CONFIG_B43=m +CONFIG_B43_BCMA=y +CONFIG_B43_SSB=y +CONFIG_B43_BUSES_BCMA_AND_SSB=y +# CONFIG_B43_BUSES_BCMA is not set +# CONFIG_B43_BUSES_SSB is not set +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_SDIO=y +CONFIG_B43_BCMA_PIO=y +CONFIG_B43_PIO=y +CONFIG_B43_PHY_G=y +CONFIG_B43_PHY_N=y +CONFIG_B43_PHY_LP=y +CONFIG_B43_PHY_HT=y +CONFIG_B43_LEDS=y +CONFIG_B43_HWRNG=y +# CONFIG_B43_DEBUG is not set +# CONFIG_B43LEGACY is not set +CONFIG_BRCMUTIL=m +CONFIG_BRCMSMAC=m +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_PROTO_BCDC=y +CONFIG_BRCMFMAC_PROTO_MSGBUF=y +CONFIG_BRCMFMAC_SDIO=y +CONFIG_BRCMFMAC_USB=y +CONFIG_BRCMFMAC_PCIE=y +# CONFIG_BRCM_TRACING is not set +# CONFIG_BRCMDBG is not set +# CONFIG_WLAN_VENDOR_CISCO is not set +CONFIG_WLAN_VENDOR_INTEL=y +# CONFIG_IPW2100 is not set +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +# CONFIG_IPW2200_DEBUG is not set +CONFIG_LIBIPW=m +# CONFIG_LIBIPW_DEBUG is not set +CONFIG_IWLEGACY=m +CONFIG_IWL4965=m +CONFIG_IWL3945=m + +# +# iwl3945 / iwl4965 Debugging Options +# +# CONFIG_IWLEGACY_DEBUG is not set +# end of iwl3945 / iwl4965 Debugging Options + +CONFIG_IWLWIFI=m +CONFIG_IWLWIFI_LEDS=y +CONFIG_IWLDVM=m +CONFIG_IWLMVM=m +CONFIG_IWLWIFI_OPMODE_MODULAR=y + +# +# Debugging Options +# +# CONFIG_IWLWIFI_DEBUG is not set +CONFIG_IWLWIFI_DEVICE_TRACING=y +# end of Debugging Options + +# CONFIG_WLAN_VENDOR_INTERSIL is not set +CONFIG_WLAN_VENDOR_MARVELL=y +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_MESH=y +CONFIG_LIBERTAS_THINFIRM=m +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m +CONFIG_MWIFIEX_PCIE=m +CONFIG_MWIFIEX_USB=m +CONFIG_MWL8K=m +CONFIG_WLAN_VENDOR_MEDIATEK=y +CONFIG_MT7601U=m +CONFIG_MT76_CORE=m +CONFIG_MT76_LEDS=y +CONFIG_MT76_USB=m +CONFIG_MT76_SDIO=m +CONFIG_MT76x02_LIB=m +CONFIG_MT76x02_USB=m +CONFIG_MT76_CONNAC_LIB=m +CONFIG_MT76x0_COMMON=m +CONFIG_MT76x0U=m +CONFIG_MT76x0E=m +CONFIG_MT76x2_COMMON=m +CONFIG_MT76x2E=m +CONFIG_MT76x2U=m +CONFIG_MT7603E=m +CONFIG_MT7615_COMMON=m +CONFIG_MT7615E=m +CONFIG_MT7663_USB_SDIO_COMMON=m +CONFIG_MT7663U=m +CONFIG_MT7663S=m +CONFIG_MT7915E=m +# CONFIG_MT7921E is not set +# CONFIG_MT7921S is not set +# CONFIG_MT7921U is not set +# CONFIG_MT7996E is not set +CONFIG_WLAN_VENDOR_MICROCHIP=y +# CONFIG_WILC1000_SDIO is not set +CONFIG_WLAN_VENDOR_PURELIFI=y +# CONFIG_PLFXLC is not set +CONFIG_WLAN_VENDOR_RALINK=y +CONFIG_RT2X00=m +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT61PCI=m +CONFIG_RT2800PCI=m +CONFIG_RT2800PCI_RT33XX=y +CONFIG_RT2800PCI_RT35XX=y +CONFIG_RT2800PCI_RT53XX=y +CONFIG_RT2800PCI_RT3290=y +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +# CONFIG_RT2800USB_UNKNOWN is not set +CONFIG_RT2800_LIB=m +CONFIG_RT2800_LIB_MMIO=m +CONFIG_RT2X00_LIB_MMIO=m +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_WLAN_VENDOR_REALTEK=y +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +CONFIG_RTL_CARDS=m +CONFIG_RTL8192CE=m +CONFIG_RTL8192SE=m +CONFIG_RTL8192DE=m +CONFIG_RTL8723AE=m +CONFIG_RTL8723BE=m +CONFIG_RTL8188EE=m +CONFIG_RTL8192EE=m +CONFIG_RTL8821AE=m +CONFIG_RTL8192CU=m +CONFIG_RTLWIFI=m +CONFIG_RTLWIFI_PCI=m +CONFIG_RTLWIFI_USB=m +# CONFIG_RTLWIFI_DEBUG is not set +CONFIG_RTL8192C_COMMON=m +CONFIG_RTL8723_COMMON=m +CONFIG_RTLBTCOEXIST=m +CONFIG_RTL8XXXU=m +# CONFIG_RTL8XXXU_UNTESTED is not set +# CONFIG_RTW88 is not set +# CONFIG_RTW89 is not set +CONFIG_WLAN_VENDOR_RSI=y +CONFIG_RSI_91X=m +CONFIG_RSI_DEBUGFS=y +CONFIG_RSI_SDIO=m +CONFIG_RSI_USB=m +CONFIG_WLAN_VENDOR_SILABS=y +# CONFIG_WFX is not set +# CONFIG_WLAN_VENDOR_ST is not set +# CONFIG_WLAN_VENDOR_TI is not set +# CONFIG_WLAN_VENDOR_ZYDAS is not set +# CONFIG_WLAN_VENDOR_QUANTENNA is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +CONFIG_MAC80211_HWSIM=m +# CONFIG_VIRT_WIFI is not set +# CONFIG_WAN is not set + +# +# Wireless WAN +# +# CONFIG_WWAN is not set +# end of Wireless WAN + +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_NETDEV_BACKEND=m +CONFIG_VMXNET3=m +# CONFIG_FUJITSU_ES is not set +CONFIG_HYPERV_NET=m +# CONFIG_NETDEVSIM is not set +CONFIG_NET_FAILOVER=m +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_LEDS is not set +# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_SPARSEKMAP=m +# CONFIG_INPUT_MATRIXKMAP is not set +CONFIG_INPUT_VIVALDIFMAP=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1050 is not set +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_DLINK_DIR685 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +CONFIG_KEYBOARD_GPIO_POLLED=m +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_SNVS_PWRKEY is not set +# CONFIG_KEYBOARD_IMX is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_TEGRA is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_PINEPHONE is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_SUN4I_LRADC is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_CAP11XX is not set +# CONFIG_KEYBOARD_BCM is not set +# CONFIG_KEYBOARD_CYPRESS_SF is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ATMEL_CAPTOUCH is not set +# CONFIG_INPUT_BBNSM_PWRKEY is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_E3X0_BUTTON is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_GPIO_BEEPER is not set +# CONFIG_INPUT_GPIO_DECODER is not set +# CONFIG_INPUT_GPIO_VIBRA is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_REGULATOR_HAPTIC is not set +# CONFIG_INPUT_AXP20X_PEK is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_DA7280_HAPTICS is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IBM_PANEL is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_IQS269A is not set +# CONFIG_INPUT_IQS626A is not set +# CONFIG_INPUT_IQS7222 is not set +# CONFIG_INPUT_CMA3000 is not set +CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m +# CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set +# CONFIG_INPUT_DRV2667_HAPTICS is not set +# CONFIG_INPUT_HISI_POWERKEY is not set +# CONFIG_RMI4_CORE is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=m +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_SERIO_APBPS2 is not set +CONFIG_HYPERV_KEYBOARD=m +# CONFIG_SERIO_SUN4I_PS2 is not set +# CONFIG_SERIO_GPIO_PS2 is not set +# CONFIG_USERIO is not set +# CONFIG_GAMEPORT is not set +# end of Hardware I/O ports +# end of Input device support + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_LEGACY_TIOCSTI=y +CONFIG_LDISC_AUTOLOAD=y + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_PNP=y +# CONFIG_SERIAL_8250_16550A_VARIANTS is not set +CONFIG_SERIAL_8250_FINTEK=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DMA=y +CONFIG_SERIAL_8250_PCILIB=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_EXAR=y +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +# CONFIG_SERIAL_8250_PCI1XXXX is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_DWLIB=y +# CONFIG_SERIAL_8250_BCM2835AUX is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_EM is not set +# CONFIG_SERIAL_8250_RT288X is not set +# CONFIG_SERIAL_8250_OMAP is not set +CONFIG_SERIAL_8250_PERICOM=y +CONFIG_SERIAL_8250_TEGRA=y +# CONFIG_SERIAL_OF_PLATFORM is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +# CONFIG_SERIAL_EARLYCON_SEMIHOST is not set +# CONFIG_SERIAL_MESON is not set +# CONFIG_SERIAL_TEGRA is not set +# CONFIG_SERIAL_IMX is not set +# CONFIG_SERIAL_IMX_EARLYCON is not set +# CONFIG_SERIAL_UARTLITE is not set +# CONFIG_SERIAL_SH_SCI is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +# CONFIG_SERIAL_MSM is not set +# CONFIG_SERIAL_SIFIVE is not set +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +CONFIG_SERIAL_RP2=m +CONFIG_SERIAL_RP2_NR_UARTS=32 +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_FSL_LINFLEXUART is not set +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +# CONFIG_SERIAL_SPRD is not set +# CONFIG_SERIAL_MVEBU_UART is not set +# end of Serial drivers + +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_MOXA_INTELLIO=m +CONFIG_MOXA_SMARTIO=m +CONFIG_N_HDLC=m +CONFIG_N_GSM=m +CONFIG_NOZOMI=m +# CONFIG_NULL_TTY is not set +CONFIG_HVC_DRIVER=y +CONFIG_HVC_IRQ=y +CONFIG_HVC_XEN=y +CONFIG_HVC_XEN_FRONTEND=y +# CONFIG_HVC_DCC is not set +# CONFIG_RPMSG_TTY is not set +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +CONFIG_TTY_PRINTK=m +CONFIG_TTY_PRINTK_LEVEL=6 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +CONFIG_VIRTIO_CONSOLE=y +CONFIG_IPMI_HANDLER=m +CONFIG_IPMI_DMI_DECODE=y +CONFIG_IPMI_PLAT_DATA=y +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +# CONFIG_IPMI_SSIF is not set +# CONFIG_IPMI_IPMB is not set +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +# CONFIG_SSIF_IPMI_BMC is not set +# CONFIG_IPMB_DEVICE_INTERFACE is not set +CONFIG_HW_RANDOM=m +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_HW_RANDOM_BA431 is not set +CONFIG_HW_RANDOM_BCM2835=m +CONFIG_HW_RANDOM_IPROC_RNG200=m +CONFIG_HW_RANDOM_OMAP=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HW_RANDOM_HISI=m +CONFIG_HW_RANDOM_HISTB=m +CONFIG_HW_RANDOM_XGENE=m +CONFIG_HW_RANDOM_MESON=m +CONFIG_HW_RANDOM_CAVIUM=m +# CONFIG_HW_RANDOM_CCTRNG is not set +# CONFIG_HW_RANDOM_XIPHERA is not set +CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=m +CONFIG_HW_RANDOM_CN10K=m +# CONFIG_APPLICOM is not set +CONFIG_DEVMEM=y +CONFIG_DEVPORT=y +CONFIG_TCG_TPM=m +CONFIG_HW_RANDOM_TPM=y +CONFIG_TCG_TIS_CORE=m +CONFIG_TCG_TIS=m +# CONFIG_TCG_TIS_I2C is not set +# CONFIG_TCG_TIS_SYNQUACER is not set +# CONFIG_TCG_TIS_I2C_CR50 is not set +CONFIG_TCG_TIS_I2C_ATMEL=m +CONFIG_TCG_TIS_I2C_INFINEON=m +CONFIG_TCG_TIS_I2C_NUVOTON=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_XEN=m +CONFIG_TCG_CRB=m +# CONFIG_TCG_VTPM_PROXY is not set +CONFIG_TCG_TIS_ST33ZP24=m +CONFIG_TCG_TIS_ST33ZP24_I2C=m +# CONFIG_XILLYBUS is not set +# CONFIG_XILLYUSB is not set +# end of Character devices + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_ACPI_I2C_OPREGION=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_MUX=m + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_GPMUX is not set +# CONFIG_I2C_MUX_LTC4306 is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +# CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set +# CONFIG_I2C_DEMUX_PINCTRL is not set +# CONFIG_I2C_MUX_MLXCPLD is not set +# end of Multiplexer I2C Chip support + +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_SMBUS=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +CONFIG_I2C_CCGX_UCSI=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD8111=m +# CONFIG_I2C_AMD_MP2 is not set +# CONFIG_I2C_HIX5HD2 is not set +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_NFORCE2=m +# CONFIG_I2C_NVIDIA_GPU is not set +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m + +# +# ACPI drivers +# +CONFIG_I2C_SCMI=m + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_BCM2835 is not set +CONFIG_I2C_BRCMSTB=y +# CONFIG_I2C_CADENCE is not set +# CONFIG_I2C_CBUS_GPIO is not set +CONFIG_I2C_DESIGNWARE_CORE=y +# CONFIG_I2C_DESIGNWARE_SLAVE is not set +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_I2C_DESIGNWARE_PCI=m +# CONFIG_I2C_EMEV2 is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_HISI is not set +# CONFIG_I2C_IMX is not set +# CONFIG_I2C_IMX_LPI2C is not set +CONFIG_I2C_KEMPLD=m +# CONFIG_I2C_MESON is not set +# CONFIG_I2C_MV64XXX is not set +# CONFIG_I2C_NOMADIK is not set +CONFIG_I2C_OCORES=m +# CONFIG_I2C_OMAP is not set +CONFIG_I2C_PCA_PLATFORM=m +# CONFIG_I2C_PXA is not set +# CONFIG_I2C_QCOM_CCI is not set +# CONFIG_I2C_QUP is not set +# CONFIG_I2C_RIIC is not set +# CONFIG_I2C_RK3X is not set +# CONFIG_I2C_RZV2M is not set +# CONFIG_I2C_SH_MOBILE is not set +CONFIG_I2C_SIMTEC=m +# CONFIG_I2C_SYNQUACER is not set +# CONFIG_I2C_TEGRA is not set +# CONFIG_I2C_VERSATILE is not set +# CONFIG_I2C_THUNDERX is not set +CONFIG_I2C_XILINX=m +# CONFIG_I2C_XLP9XX is not set +# CONFIG_I2C_RCAR is not set + +# +# External I2C/SMBus adapter drivers +# +CONFIG_I2C_DIOLAN_U2C=m +# CONFIG_I2C_CP2615 is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PCI1XXXX is not set +CONFIG_I2C_ROBOTFUZZ_OSIF=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIPERBOARD=m + +# +# Other I2C/SMBus bus drivers +# +CONFIG_I2C_MLXCPLD=m +# CONFIG_I2C_XGENE_SLIMPRO is not set +# CONFIG_I2C_VIRTIO is not set +# end of I2C Hardware Bus support + +CONFIG_I2C_STUB=m +CONFIG_I2C_SLAVE=y +CONFIG_I2C_SLAVE_EEPROM=m +# CONFIG_I2C_SLAVE_TESTUNIT is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# end of I2C support + +# CONFIG_I3C is not set +# CONFIG_SPI is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set +CONFIG_PPS=y +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +CONFIG_PPS_CLIENT_LDISC=m +# CONFIG_PPS_CLIENT_PARPORT is not set +# CONFIG_PPS_CLIENT_GPIO is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_PTP_1588_CLOCK_KVM=y +# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set +# CONFIG_PTP_1588_CLOCK_IDTCM is not set +# CONFIG_PTP_1588_CLOCK_MOCK is not set +# end of PTP clock support + +CONFIG_PINCTRL=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_PINMUX=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +CONFIG_PINCTRL_AMD=y +CONFIG_PINCTRL_AXP209=m +# CONFIG_PINCTRL_CY8C95X0 is not set +# CONFIG_PINCTRL_MCP23S08 is not set +# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set +# CONFIG_PINCTRL_OCELOT is not set +CONFIG_PINCTRL_ROCKCHIP=y +CONFIG_PINCTRL_SINGLE=y +# CONFIG_PINCTRL_STMFX is not set +# CONFIG_PINCTRL_SX150X is not set +CONFIG_PINCTRL_BCM2835=y +CONFIG_PINCTRL_IMX=y +CONFIG_PINCTRL_IMX8MM=y +CONFIG_PINCTRL_IMX8MN=y +CONFIG_PINCTRL_IMX8MP=y +CONFIG_PINCTRL_IMX8MQ=y +# CONFIG_PINCTRL_IMX8ULP is not set +# CONFIG_PINCTRL_IMXRT1050 is not set +# CONFIG_PINCTRL_IMX93 is not set +# CONFIG_PINCTRL_IMXRT1170 is not set +CONFIG_PINCTRL_MESON=y +CONFIG_PINCTRL_MESON_GXBB=y +CONFIG_PINCTRL_MESON_GXL=y +CONFIG_PINCTRL_MESON8_PMX=y +CONFIG_PINCTRL_MESON_AXG=y +CONFIG_PINCTRL_MESON_AXG_PMX=y +CONFIG_PINCTRL_MESON_G12A=y +CONFIG_PINCTRL_MESON_A1=y +CONFIG_PINCTRL_MESON_S4=y +CONFIG_PINCTRL_AMLOGIC_C3=y +CONFIG_PINCTRL_MVEBU=y +CONFIG_PINCTRL_ARMADA_AP806=y +CONFIG_PINCTRL_ARMADA_CP110=y +CONFIG_PINCTRL_AC5=y +CONFIG_PINCTRL_ARMADA_37XX=y +CONFIG_PINCTRL_MSM=y +# CONFIG_PINCTRL_IPQ5018 is not set +# CONFIG_PINCTRL_IPQ5332 is not set +# CONFIG_PINCTRL_IPQ8074 is not set +# CONFIG_PINCTRL_IPQ6018 is not set +# CONFIG_PINCTRL_IPQ9574 is not set +# CONFIG_PINCTRL_MDM9607 is not set +CONFIG_PINCTRL_MSM8916=y +# CONFIG_PINCTRL_MSM8953 is not set +# CONFIG_PINCTRL_MSM8976 is not set +# CONFIG_PINCTRL_MSM8994 is not set +CONFIG_PINCTRL_MSM8996=y +# CONFIG_PINCTRL_MSM8998 is not set +# CONFIG_PINCTRL_QCM2290 is not set +# CONFIG_PINCTRL_QCS404 is not set +# CONFIG_PINCTRL_QDF2XXX is not set +# CONFIG_PINCTRL_QDU1000 is not set +# CONFIG_PINCTRL_SA8775P is not set +# CONFIG_PINCTRL_SC7180 is not set +# CONFIG_PINCTRL_SC7280 is not set +# CONFIG_PINCTRL_SC8180X is not set +# CONFIG_PINCTRL_SC8280XP is not set +# CONFIG_PINCTRL_SDM660 is not set +# CONFIG_PINCTRL_SDM670 is not set +CONFIG_PINCTRL_SDM845=y +# CONFIG_PINCTRL_SDX75 is not set +# CONFIG_PINCTRL_SM6115 is not set +# CONFIG_PINCTRL_SM6125 is not set +# CONFIG_PINCTRL_SM6350 is not set +# CONFIG_PINCTRL_SM6375 is not set +# CONFIG_PINCTRL_SM7150 is not set +# CONFIG_PINCTRL_SM8150 is not set +# CONFIG_PINCTRL_SM8250 is not set +# CONFIG_PINCTRL_SM8350 is not set +# CONFIG_PINCTRL_SM8450 is not set +# CONFIG_PINCTRL_SM8550 is not set +CONFIG_PINCTRL_QCOM_SSBI_PMIC=y +# CONFIG_PINCTRL_LPASS_LPI is not set + +# +# Renesas pinctrl drivers +# +CONFIG_PINCTRL_RENESAS=y +# end of Renesas pinctrl drivers + +CONFIG_PINCTRL_SUNXI=y +# CONFIG_PINCTRL_SUN4I_A10 is not set +# CONFIG_PINCTRL_SUN5I is not set +# CONFIG_PINCTRL_SUN6I_A31 is not set +# CONFIG_PINCTRL_SUN6I_A31_R is not set +# CONFIG_PINCTRL_SUN8I_A23 is not set +# CONFIG_PINCTRL_SUN8I_A33 is not set +# CONFIG_PINCTRL_SUN8I_A83T is not set +# CONFIG_PINCTRL_SUN8I_A83T_R is not set +# CONFIG_PINCTRL_SUN8I_A23_R is not set +# CONFIG_PINCTRL_SUN8I_H3 is not set +CONFIG_PINCTRL_SUN8I_H3_R=y +# CONFIG_PINCTRL_SUN8I_V3S is not set +# CONFIG_PINCTRL_SUN9I_A80 is not set +# CONFIG_PINCTRL_SUN9I_A80_R is not set +# CONFIG_PINCTRL_SUN20I_D1 is not set +CONFIG_PINCTRL_SUN50I_A64=y +CONFIG_PINCTRL_SUN50I_A64_R=y +CONFIG_PINCTRL_SUN50I_A100=y +CONFIG_PINCTRL_SUN50I_A100_R=y +CONFIG_PINCTRL_SUN50I_H5=y +CONFIG_PINCTRL_SUN50I_H6=y +CONFIG_PINCTRL_SUN50I_H6_R=y +CONFIG_PINCTRL_SUN50I_H616=y +CONFIG_PINCTRL_SUN50I_H616_R=y +CONFIG_PINCTRL_TEGRA_XUSB=y +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_FASTPATH_LIMIT=512 +CONFIG_OF_GPIO=y +CONFIG_GPIO_ACPI=y +CONFIG_GPIOLIB_IRQCHIP=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_CDEV_V1=y +CONFIG_GPIO_GENERIC=y + +# +# Memory mapped GPIO drivers +# +# CONFIG_GPIO_74XX_MMIO is not set +# CONFIG_GPIO_ALTERA is not set +# CONFIG_GPIO_AMDPT is not set +CONFIG_GPIO_RASPBERRYPI_EXP=y +# CONFIG_GPIO_CADENCE is not set +CONFIG_GPIO_DAVINCI=y +# CONFIG_GPIO_DWAPB is not set +CONFIG_GPIO_EXAR=m +# CONFIG_GPIO_FTGPIO010 is not set +CONFIG_GPIO_GENERIC_PLATFORM=y +# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_HISI is not set +# CONFIG_GPIO_HLWD is not set +# CONFIG_GPIO_LOGICVC is not set +CONFIG_GPIO_MB86S7X=m +CONFIG_GPIO_MPC8XXX=y +CONFIG_GPIO_MVEBU=y +CONFIG_GPIO_MXC=y +CONFIG_GPIO_PL061=y +CONFIG_GPIO_RCAR=m +CONFIG_GPIO_ROCKCHIP=y +# CONFIG_GPIO_SIFIVE is not set +# CONFIG_GPIO_SYSCON is not set +CONFIG_GPIO_TEGRA=y +# CONFIG_GPIO_THUNDERX is not set +CONFIG_GPIO_VF610=y +CONFIG_GPIO_XGENE=y +CONFIG_GPIO_XGENE_SB=m +# CONFIG_GPIO_XILINX is not set +CONFIG_GPIO_XLP=y +# CONFIG_GPIO_AMD_FCH is not set +# end of Memory mapped GPIO drivers + +# +# I2C GPIO expanders +# +# CONFIG_GPIO_ADNP is not set +# CONFIG_GPIO_FXL6408 is not set +# CONFIG_GPIO_DS4520 is not set +# CONFIG_GPIO_GW_PLD is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCA9570 is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_TPIC2810 is not set +# end of I2C GPIO expanders + +# +# MFD GPIO expanders +# +# CONFIG_GPIO_KEMPLD is not set +# end of MFD GPIO expanders + +# +# PCI GPIO expanders +# +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_PCI_IDIO_16 is not set +# CONFIG_GPIO_PCIE_IDIO_24 is not set +# CONFIG_GPIO_RDC321X is not set +# end of PCI GPIO expanders + +# +# USB GPIO expanders +# +CONFIG_GPIO_VIPERBOARD=m +# end of USB GPIO expanders + +# +# Virtual GPIO drivers +# +# CONFIG_GPIO_AGGREGATOR is not set +# CONFIG_GPIO_LATCH is not set +# CONFIG_GPIO_MOCKUP is not set +# CONFIG_GPIO_VIRTIO is not set +# CONFIG_GPIO_SIM is not set +# end of Virtual GPIO drivers + +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m +# CONFIG_W1_MASTER_MXC is not set +CONFIG_W1_MASTER_GPIO=m +# CONFIG_W1_MASTER_SGI is not set +# end of 1-wire Bus Masters + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2405=m +CONFIG_W1_SLAVE_DS2408=m +CONFIG_W1_SLAVE_DS2408_READBACK=y +CONFIG_W1_SLAVE_DS2413=m +CONFIG_W1_SLAVE_DS2406=m +CONFIG_W1_SLAVE_DS2423=m +CONFIG_W1_SLAVE_DS2805=m +# CONFIG_W1_SLAVE_DS2430 is not set +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +CONFIG_W1_SLAVE_DS2433_CRC=y +CONFIG_W1_SLAVE_DS2438=m +# CONFIG_W1_SLAVE_DS250X is not set +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_DS2781=m +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_W1_SLAVE_DS28E17=m +# end of 1-wire Slaves + +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_BRCMSTB is not set +# CONFIG_POWER_RESET_GPIO is not set +# CONFIG_POWER_RESET_GPIO_RESTART is not set +# CONFIG_POWER_RESET_HISI is not set +# CONFIG_POWER_RESET_LINKSTATION is not set +# CONFIG_POWER_RESET_MSM is not set +# CONFIG_POWER_RESET_ODROID_GO_ULTRA_POWEROFF is not set +# CONFIG_POWER_RESET_LTC2952 is not set +# CONFIG_POWER_RESET_REGULATOR is not set +# CONFIG_POWER_RESET_RESTART is not set +# CONFIG_POWER_RESET_VEXPRESS is not set +# CONFIG_POWER_RESET_XGENE is not set +# CONFIG_POWER_RESET_SYSCON is not set +# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set +# CONFIG_SYSCON_REBOOT_MODE is not set +# CONFIG_NVMEM_REBOOT_MODE is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_POWER_SUPPLY_HWMON=y +# CONFIG_IP5XXX_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_CHARGER_ADP5061 is not set +# CONFIG_BATTERY_CW2015 is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_SAMSUNG_SDI is not set +CONFIG_BATTERY_SBS=m +# CONFIG_CHARGER_SBS is not set +# CONFIG_MANAGER_SBS is not set +CONFIG_BATTERY_BQ27XXX=m +# CONFIG_BATTERY_BQ27XXX_I2C is not set +CONFIG_BATTERY_BQ27XXX_HDQ=m +# CONFIG_BATTERY_MAX17040 is not set +CONFIG_BATTERY_MAX17042=m +# CONFIG_BATTERY_MAX1721X is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +# CONFIG_CHARGER_GPIO is not set +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_CHARGER_LT3651 is not set +# CONFIG_CHARGER_LTC4162L is not set +# CONFIG_CHARGER_DETECTOR_MAX14656 is not set +# CONFIG_CHARGER_MAX77976 is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24257 is not set +# CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ2515X is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_BQ25980 is not set +# CONFIG_CHARGER_BQ256XX is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_BATTERY_GOLDFISH is not set +# CONFIG_BATTERY_RT5033 is not set +# CONFIG_CHARGER_RT9455 is not set +# CONFIG_CHARGER_RT9467 is not set +# CONFIG_CHARGER_RT9471 is not set +# CONFIG_CHARGER_UCS1002 is not set +# CONFIG_CHARGER_BD99954 is not set +# CONFIG_BATTERY_UG3105 is not set +CONFIG_HWMON=y +CONFIG_HWMON_VID=m +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +# CONFIG_SENSORS_ADM1177 is not set +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7X10=m +CONFIG_SENSORS_ADT7410=m +CONFIG_SENSORS_ADT7411=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7475=m +# CONFIG_SENSORS_AHT10 is not set +# CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set +# CONFIG_SENSORS_AS370 is not set +CONFIG_SENSORS_ASC7621=m +# CONFIG_SENSORS_AXI_FAN_CONTROL is not set +# CONFIG_SENSORS_ARM_SCMI is not set +CONFIG_SENSORS_ARM_SCPI=m +CONFIG_SENSORS_ATXP1=m +# CONFIG_SENSORS_CORSAIR_CPRO is not set +# CONFIG_SENSORS_CORSAIR_PSU is not set +CONFIG_SENSORS_DRIVETEMP=m +CONFIG_SENSORS_DS620=m +# CONFIG_SENSORS_DS1621 is not set +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FTSTEUTATES=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_G760A=m +CONFIG_SENSORS_G762=m +# CONFIG_SENSORS_GPIO_FAN is not set +CONFIG_SENSORS_HIH6130=m +# CONFIG_SENSORS_HS3001 is not set +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_JC42=m +CONFIG_SENSORS_POWR1220=m +CONFIG_SENSORS_LINEAGE=m +CONFIG_SENSORS_LTC2945=m +# CONFIG_SENSORS_LTC2947_I2C is not set +CONFIG_SENSORS_LTC2990=m +# CONFIG_SENSORS_LTC2992 is not set +CONFIG_SENSORS_LTC4151=m +CONFIG_SENSORS_LTC4215=m +CONFIG_SENSORS_LTC4222=m +CONFIG_SENSORS_LTC4245=m +CONFIG_SENSORS_LTC4260=m +CONFIG_SENSORS_LTC4261=m +# CONFIG_SENSORS_MAX127 is not set +CONFIG_SENSORS_MAX16065=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX1668=m +CONFIG_SENSORS_MAX197=m +# CONFIG_SENSORS_MAX31730 is not set +# CONFIG_SENSORS_MAX31760 is not set +# CONFIG_MAX31827 is not set +# CONFIG_SENSORS_MAX6620 is not set +CONFIG_SENSORS_MAX6621=m +CONFIG_SENSORS_MAX6639=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6697=m +CONFIG_SENSORS_MAX31790=m +# CONFIG_SENSORS_MC34VR500 is not set +CONFIG_SENSORS_MCP3021=m +CONFIG_SENSORS_TC654=m +# CONFIG_SENSORS_TPS23861 is not set +CONFIG_SENSORS_MENF21BMC_HWMON=m +# CONFIG_SENSORS_MR75203 is not set +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM73=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_LM95234=m +CONFIG_SENSORS_LM95241=m +CONFIG_SENSORS_LM95245=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_NCT6683=m +CONFIG_SENSORS_NCT6775_CORE=m +CONFIG_SENSORS_NCT6775=m +# CONFIG_SENSORS_NCT6775_I2C is not set +CONFIG_SENSORS_NCT7802=m +CONFIG_SENSORS_NCT7904=m +CONFIG_SENSORS_NPCM7XX=m +# CONFIG_SENSORS_NZXT_KRAKEN2 is not set +# CONFIG_SENSORS_NZXT_SMART2 is not set +# CONFIG_SENSORS_OCC_P8_I2C is not set +CONFIG_SENSORS_PCF8591=m +CONFIG_PMBUS=m +CONFIG_SENSORS_PMBUS=m +# CONFIG_SENSORS_ACBEL_FSG032 is not set +# CONFIG_SENSORS_ADM1266 is not set +CONFIG_SENSORS_ADM1275=m +# CONFIG_SENSORS_BEL_PFE is not set +# CONFIG_SENSORS_BPA_RS600 is not set +# CONFIG_SENSORS_DELTA_AHE50DC_FAN is not set +# CONFIG_SENSORS_FSP_3Y is not set +CONFIG_SENSORS_IBM_CFFPS=m +# CONFIG_SENSORS_DPS920AB is not set +# CONFIG_SENSORS_INSPUR_IPSPS is not set +CONFIG_SENSORS_IR35221=m +# CONFIG_SENSORS_IR36021 is not set +# CONFIG_SENSORS_IR38064 is not set +# CONFIG_SENSORS_IRPS5401 is not set +# CONFIG_SENSORS_ISL68137 is not set +CONFIG_SENSORS_LM25066=m +# CONFIG_SENSORS_LM25066_REGULATOR is not set +# CONFIG_SENSORS_LT7182S is not set +CONFIG_SENSORS_LTC2978=m +CONFIG_SENSORS_LTC2978_REGULATOR=y +CONFIG_SENSORS_LTC3815=m +# CONFIG_SENSORS_MAX15301 is not set +CONFIG_SENSORS_MAX16064=m +# CONFIG_SENSORS_MAX16601 is not set +# CONFIG_SENSORS_MAX20730 is not set +CONFIG_SENSORS_MAX20751=m +CONFIG_SENSORS_MAX31785=m +CONFIG_SENSORS_MAX34440=m +CONFIG_SENSORS_MAX8688=m +# CONFIG_SENSORS_MP2888 is not set +# CONFIG_SENSORS_MP2975 is not set +# CONFIG_SENSORS_MP5023 is not set +# CONFIG_SENSORS_MPQ7932 is not set +# CONFIG_SENSORS_PIM4328 is not set +# CONFIG_SENSORS_PLI1209BC is not set +# CONFIG_SENSORS_PM6764TR is not set +# CONFIG_SENSORS_PXE1610 is not set +# CONFIG_SENSORS_Q54SJ108A2 is not set +# CONFIG_SENSORS_STPDDC60 is not set +# CONFIG_SENSORS_TDA38640 is not set +CONFIG_SENSORS_TPS40422=m +CONFIG_SENSORS_TPS53679=m +# CONFIG_SENSORS_TPS546D24 is not set +CONFIG_SENSORS_UCD9000=m +CONFIG_SENSORS_UCD9200=m +# CONFIG_SENSORS_XDPE152 is not set +# CONFIG_SENSORS_XDPE122 is not set +CONFIG_SENSORS_ZL6100=m +# CONFIG_SENSORS_RASPBERRYPI_HWMON is not set +# CONFIG_SENSORS_SBTSI is not set +# CONFIG_SENSORS_SBRMI is not set +CONFIG_SENSORS_SHT15=m +CONFIG_SENSORS_SHT21=m +CONFIG_SENSORS_SHT3x=m +# CONFIG_SENSORS_SHT4x is not set +CONFIG_SENSORS_SHTC1=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_EMC1403=m +CONFIG_SENSORS_EMC2103=m +# CONFIG_SENSORS_EMC2305 is not set +CONFIG_SENSORS_EMC6W201=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SCH56XX_COMMON=m +CONFIG_SENSORS_SCH5627=m +CONFIG_SENSORS_SCH5636=m +CONFIG_SENSORS_STTS751=m +CONFIG_SENSORS_ADC128D818=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_AMC6821=m +CONFIG_SENSORS_INA209=m +CONFIG_SENSORS_INA2XX=m +# CONFIG_SENSORS_INA238 is not set +CONFIG_SENSORS_INA3221=m +CONFIG_SENSORS_TC74=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TMP102=m +CONFIG_SENSORS_TMP103=m +CONFIG_SENSORS_TMP108=m +CONFIG_SENSORS_TMP401=m +CONFIG_SENSORS_TMP421=m +# CONFIG_SENSORS_TMP464 is not set +# CONFIG_SENSORS_TMP513 is not set +# CONFIG_SENSORS_VEXPRESS is not set +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83773G=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83795=m +# CONFIG_SENSORS_W83795_FANCTRL is not set +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_XGENE=m + +# +# ACPI drivers +# +CONFIG_SENSORS_ACPI_POWER=m +CONFIG_THERMAL=y +# CONFIG_THERMAL_NETLINK is not set +# CONFIG_THERMAL_STATISTICS is not set +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_BANG_BANG is not set +CONFIG_THERMAL_GOV_FAIR_SHARE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_GOV_BANG_BANG=y +CONFIG_THERMAL_GOV_USER_SPACE=y +# CONFIG_CPU_THERMAL is not set +# CONFIG_DEVFREQ_THERMAL is not set +# CONFIG_THERMAL_EMULATION is not set +# CONFIG_THERMAL_MMIO is not set +CONFIG_HISI_THERMAL=m +# CONFIG_IMX_THERMAL is not set +# CONFIG_IMX8MM_THERMAL is not set +CONFIG_K3_THERMAL=m +CONFIG_QORIQ_THERMAL=m +CONFIG_SUN8I_THERMAL=m +CONFIG_ROCKCHIP_THERMAL=m +# CONFIG_RCAR_THERMAL is not set +# CONFIG_RCAR_GEN3_THERMAL is not set +# CONFIG_RZG2L_THERMAL is not set +CONFIG_ARMADA_THERMAL=m +CONFIG_AMLOGIC_THERMAL=y + +# +# Broadcom thermal drivers +# +CONFIG_BCM2711_THERMAL=m +CONFIG_BCM2835_THERMAL=m +# end of Broadcom thermal drivers + +# +# NVIDIA Tegra thermal drivers +# +CONFIG_TEGRA_SOCTHERM=y +# end of NVIDIA Tegra thermal drivers + +# +# Qualcomm thermal drivers +# +# CONFIG_QCOM_LMH is not set +# end of Qualcomm thermal drivers + +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y +CONFIG_WATCHDOG_OPEN_TIMEOUT=0 +CONFIG_WATCHDOG_SYSFS=y +# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set + +# +# Watchdog Pretimeout Governors +# +# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +# CONFIG_GPIO_WATCHDOG is not set +# CONFIG_MENF21BMC_WATCHDOG is not set +# CONFIG_WDAT_WDT is not set +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_XILINX_WINDOW_WATCHDOG is not set +# CONFIG_ZIIRAVE_WATCHDOG is not set +CONFIG_ARM_SP805_WATCHDOG=y +CONFIG_ARM_SBSA_WATCHDOG=y +# CONFIG_ARMADA_37XX_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +CONFIG_K3_RTI_WATCHDOG=m +CONFIG_SUNXI_WATCHDOG=m +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_IMX2_WDT is not set +# CONFIG_IMX7ULP_WDT is not set +# CONFIG_TEGRA_WATCHDOG is not set +# CONFIG_QCOM_WDT is not set +# CONFIG_MESON_GXBB_WATCHDOG is not set +# CONFIG_MESON_WATCHDOG is not set +# CONFIG_ARM_SMC_WATCHDOG is not set +# CONFIG_RENESAS_WDT is not set +# CONFIG_RENESAS_RZAWDT is not set +# CONFIG_RENESAS_RZN1WDT is not set +# CONFIG_RENESAS_RZG2LWDT is not set +CONFIG_ALIM7101_WDT=m +CONFIG_I6300ESB_WDT=m +CONFIG_HP_WATCHDOG=m +CONFIG_KEMPLD_WDT=m +CONFIG_MARVELL_GTI_WDT=y +# CONFIG_BCM2835_WDT is not set +# CONFIG_MEN_A21_WDT is not set +CONFIG_XEN_WDT=m + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_B43_PCI_BRIDGE=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +CONFIG_SSB_SDIOHOST=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +# CONFIG_SSB_DRIVER_GPIO is not set +CONFIG_BCMA_POSSIBLE=y +CONFIG_BCMA=m +CONFIG_BCMA_BLOCKIO=y +CONFIG_BCMA_HOST_PCI_POSSIBLE=y +CONFIG_BCMA_HOST_PCI=y +# CONFIG_BCMA_HOST_SOC is not set +CONFIG_BCMA_DRIVER_PCI=y +# CONFIG_BCMA_DRIVER_GMAC_CMN is not set +# CONFIG_BCMA_DRIVER_GPIO is not set +# CONFIG_BCMA_DEBUG is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_ACT8945A is not set +# CONFIG_MFD_SUN4I_GPADC is not set +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_SMPRO is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_BD9571MWV is not set +# CONFIG_MFD_AC100 is not set +CONFIG_MFD_AXP20X=m +CONFIG_MFD_AXP20X_I2C=m +# CONFIG_MFD_AXP20X_RSB is not set +# CONFIG_MFD_CS42L43_I2C is not set +# CONFIG_MFD_MADERA is not set +# CONFIG_MFD_MAX5970 is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_GATEWORKS_GSC is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_MP2629 is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_MFD_HI655X_PMIC is not set +CONFIG_LPC_ICH=m +CONFIG_LPC_SCH=m +# CONFIG_MFD_IQS62X is not set +# CONFIG_MFD_JANZ_CMODIO is not set +CONFIG_MFD_KEMPLD=m +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_MAX77541 is not set +# CONFIG_MFD_MAX77620 is not set +# CONFIG_MFD_MAX77650 is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77714 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6360 is not set +# CONFIG_MFD_MT6370 is not set +# CONFIG_MFD_MT6397 is not set +CONFIG_MFD_MENF21BMC=m +CONFIG_MFD_VIPERBOARD=m +# CONFIG_MFD_NTXEC is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_QCOM_RPM is not set +# CONFIG_MFD_SY7636A is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_RT4831 is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RT5120 is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_RK8XX_I2C is not set +# CONFIG_MFD_RN5T618 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SL28CPLD is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_SUN6I_PRCM is not set +CONFIG_MFD_SYSCON=y +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_TI_LMU is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65086 is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TI_LP873X is not set +# CONFIG_MFD_TI_LP87565 is not set +# CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS65219 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS6594_I2C is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TQMX86 is not set +# CONFIG_MFD_VX855 is not set +# CONFIG_MFD_LOCHNAGAR is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_ROHM_BD718XX is not set +# CONFIG_MFD_ROHM_BD71828 is not set +# CONFIG_MFD_ROHM_BD957XMUF is not set +# CONFIG_MFD_STPMIC1 is not set +# CONFIG_MFD_STMFX is not set +# CONFIG_MFD_ATC260X_I2C is not set +# CONFIG_MFD_KHADAS_MCU is not set +# CONFIG_MFD_QCOM_PM8008 is not set +CONFIG_MFD_VEXPRESS_SYSREG=y +# CONFIG_RAVE_SP_CORE is not set +# CONFIG_MFD_RSMU_I2C is not set +# end of Multifunction device drivers + +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +CONFIG_REGULATOR_FIXED_VOLTAGE=m +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m +CONFIG_REGULATOR_USERSPACE_CONSUMER=m +CONFIG_REGULATOR_88PG86X=m +CONFIG_REGULATOR_ACT8865=m +CONFIG_REGULATOR_AD5398=m +# CONFIG_REGULATOR_ANATOP is not set +# CONFIG_REGULATOR_ARM_SCMI is not set +# CONFIG_REGULATOR_AW37503 is not set +CONFIG_REGULATOR_AXP20X=m +# CONFIG_REGULATOR_DA9121 is not set +CONFIG_REGULATOR_DA9210=m +CONFIG_REGULATOR_DA9211=m +CONFIG_REGULATOR_FAN53555=m +# CONFIG_REGULATOR_FAN53880 is not set +CONFIG_REGULATOR_GPIO=m +CONFIG_REGULATOR_ISL9305=m +CONFIG_REGULATOR_ISL6271A=m +CONFIG_REGULATOR_LP3971=m +CONFIG_REGULATOR_LP3972=m +CONFIG_REGULATOR_LP872X=m +CONFIG_REGULATOR_LP8755=m +CONFIG_REGULATOR_LTC3589=m +CONFIG_REGULATOR_LTC3676=m +CONFIG_REGULATOR_MAX1586=m +# CONFIG_REGULATOR_MAX77857 is not set +CONFIG_REGULATOR_MAX8649=m +CONFIG_REGULATOR_MAX8660=m +# CONFIG_REGULATOR_MAX8893 is not set +CONFIG_REGULATOR_MAX8952=m +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MAX20086 is not set +# CONFIG_REGULATOR_MAX20411 is not set +# CONFIG_REGULATOR_MAX77826 is not set +# CONFIG_REGULATOR_MCP16502 is not set +# CONFIG_REGULATOR_MP5416 is not set +# CONFIG_REGULATOR_MP8859 is not set +# CONFIG_REGULATOR_MP886X is not set +# CONFIG_REGULATOR_MPQ7920 is not set +CONFIG_REGULATOR_MT6311=m +# CONFIG_REGULATOR_PCA9450 is not set +# CONFIG_REGULATOR_PF8X00 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +CONFIG_REGULATOR_PV88060=m +CONFIG_REGULATOR_PV88080=m +CONFIG_REGULATOR_PV88090=m +# CONFIG_REGULATOR_QCOM_REFGEN is not set +# CONFIG_REGULATOR_RAA215300 is not set +# CONFIG_REGULATOR_RT4801 is not set +# CONFIG_REGULATOR_RT4803 is not set +# CONFIG_REGULATOR_RT5190A is not set +# CONFIG_REGULATOR_RT5739 is not set +# CONFIG_REGULATOR_RT5759 is not set +# CONFIG_REGULATOR_RT6160 is not set +# CONFIG_REGULATOR_RT6190 is not set +# CONFIG_REGULATOR_RT6245 is not set +# CONFIG_REGULATOR_RTQ2134 is not set +# CONFIG_REGULATOR_RTMV20 is not set +# CONFIG_REGULATOR_RTQ6752 is not set +# CONFIG_REGULATOR_RTQ2208 is not set +# CONFIG_REGULATOR_SLG51000 is not set +# CONFIG_REGULATOR_SY8106A is not set +# CONFIG_REGULATOR_SY8824X is not set +# CONFIG_REGULATOR_SY8827N is not set +CONFIG_REGULATOR_TPS51632=m +CONFIG_REGULATOR_TPS62360=m +# CONFIG_REGULATOR_TPS6286X is not set +# CONFIG_REGULATOR_TPS6287X is not set +CONFIG_REGULATOR_TPS65023=m +CONFIG_REGULATOR_TPS6507X=m +CONFIG_REGULATOR_TPS65132=m +# CONFIG_REGULATOR_VCTRL is not set +# CONFIG_REGULATOR_VEXPRESS is not set +# CONFIG_REGULATOR_VQMMC_IPQ4019 is not set +# CONFIG_RC_CORE is not set + +# +# CEC support +# +# CONFIG_MEDIA_CEC_SUPPORT is not set +# end of CEC support + +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +CONFIG_APERTURE_HELPERS=y +CONFIG_VIDEO_CMDLINE=y +# CONFIG_AUXDISPLAY is not set +# CONFIG_PANEL is not set +# CONFIG_TEGRA_HOST1X is not set +CONFIG_DRM=y +# CONFIG_DRM_DEBUG_MM is not set +CONFIG_DRM_KMS_HELPER=y +# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set +# CONFIG_DRM_DEBUG_MODESET_LOCK is not set +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_FBDEV_OVERALLOC=100 +# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set +# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set +CONFIG_DRM_TTM=y +CONFIG_DRM_TTM_HELPER=y +CONFIG_DRM_GEM_SHMEM_HELPER=y + +# +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_I2C_NXP_TDA9950 is not set +# end of I2C encoder or helper chips + +# +# ARM devices +# +# CONFIG_DRM_HDLCD is not set +# CONFIG_DRM_MALI_DISPLAY is not set +# CONFIG_DRM_KOMEDA is not set +# end of ARM devices + +# CONFIG_DRM_RADEON is not set +# CONFIG_DRM_AMDGPU is not set +# CONFIG_DRM_NOUVEAU is not set +# CONFIG_DRM_VGEM is not set +# CONFIG_DRM_VKMS is not set +# CONFIG_DRM_ROCKCHIP is not set +# CONFIG_DRM_VMWGFX is not set +# CONFIG_DRM_UDL is not set +# CONFIG_DRM_AST is not set +# CONFIG_DRM_MGAG200 is not set +# CONFIG_DRM_RCAR_DU is not set +# CONFIG_DRM_RZG2L_MIPI_DSI is not set +# CONFIG_DRM_SHMOBILE is not set +# CONFIG_DRM_SUN4I is not set +CONFIG_DRM_QXL=y +CONFIG_DRM_VIRTIO_GPU=y +CONFIG_DRM_VIRTIO_GPU_KMS=y +# CONFIG_DRM_MSM is not set +# CONFIG_DRM_TEGRA is not set +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +# CONFIG_DRM_PANEL_ARM_VERSATILE is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set +# end of Display Panels + +CONFIG_DRM_BRIDGE=y +CONFIG_DRM_PANEL_BRIDGE=y + +# +# Display Interface Bridges +# +# CONFIG_DRM_CHIPONE_ICN6211 is not set +# CONFIG_DRM_CHRONTEL_CH7033 is not set +# CONFIG_DRM_DISPLAY_CONNECTOR is not set +# CONFIG_DRM_FSL_LDB is not set +# CONFIG_DRM_ITE_IT6505 is not set +# CONFIG_DRM_LONTIUM_LT8912B is not set +# CONFIG_DRM_LONTIUM_LT9211 is not set +# CONFIG_DRM_LONTIUM_LT9611 is not set +# CONFIG_DRM_LONTIUM_LT9611UXC is not set +# CONFIG_DRM_ITE_IT66121 is not set +# CONFIG_DRM_LVDS_CODEC is not set +# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set +# CONFIG_DRM_NWL_MIPI_DSI is not set +# CONFIG_DRM_NXP_PTN3460 is not set +# CONFIG_DRM_PARADE_PS8622 is not set +# CONFIG_DRM_PARADE_PS8640 is not set +# CONFIG_DRM_SAMSUNG_DSIM is not set +# CONFIG_DRM_SIL_SII8620 is not set +# CONFIG_DRM_SII902X is not set +# CONFIG_DRM_SII9234 is not set +# CONFIG_DRM_SIMPLE_BRIDGE is not set +# CONFIG_DRM_THINE_THC63LVD1024 is not set +# CONFIG_DRM_TOSHIBA_TC358762 is not set +# CONFIG_DRM_TOSHIBA_TC358764 is not set +# CONFIG_DRM_TOSHIBA_TC358767 is not set +# CONFIG_DRM_TOSHIBA_TC358768 is not set +# CONFIG_DRM_TOSHIBA_TC358775 is not set +# CONFIG_DRM_TI_DLPC3433 is not set +# CONFIG_DRM_TI_TFP410 is not set +# CONFIG_DRM_TI_SN65DSI83 is not set +# CONFIG_DRM_TI_SN65DSI86 is not set +# CONFIG_DRM_TI_TPD12S015 is not set +# CONFIG_DRM_ANALOGIX_ANX6345 is not set +# CONFIG_DRM_ANALOGIX_ANX78XX is not set +# CONFIG_DRM_ANALOGIX_ANX7625 is not set +# CONFIG_DRM_I2C_ADV7511 is not set +# CONFIG_DRM_CDNS_DSI is not set +# CONFIG_DRM_CDNS_MHDP8546 is not set +# CONFIG_DRM_IMX8QM_LDB is not set +# CONFIG_DRM_IMX8QXP_LDB is not set +# CONFIG_DRM_IMX8QXP_PIXEL_COMBINER is not set +# CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI is not set +# end of Display Interface Bridges + +# CONFIG_DRM_IMX_DCSS is not set +# CONFIG_DRM_IMX_LCDC is not set +# CONFIG_DRM_V3D is not set +# CONFIG_DRM_LOONGSON is not set +# CONFIG_DRM_ETNAVIV is not set +# CONFIG_DRM_HISI_HIBMC is not set +# CONFIG_DRM_HISI_KIRIN is not set +# CONFIG_DRM_LOGICVC is not set +# CONFIG_DRM_MXSFB is not set +# CONFIG_DRM_IMX_LCDIF is not set +# CONFIG_DRM_MESON is not set +# CONFIG_DRM_ARCPGU is not set +# CONFIG_DRM_BOCHS is not set +# CONFIG_DRM_CIRRUS_QEMU is not set +# CONFIG_DRM_GM12U320 is not set +CONFIG_DRM_SIMPLEDRM=y +# CONFIG_DRM_PL111 is not set +# CONFIG_DRM_XEN_FRONTEND is not set +# CONFIG_DRM_LIMA is not set +# CONFIG_DRM_PANFROST is not set +# CONFIG_DRM_TIDSS is not set +# CONFIG_DRM_GUD is not set +# CONFIG_DRM_SSD130X is not set +# CONFIG_DRM_HYPERV is not set +# CONFIG_DRM_LEGACY is not set +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y + +# +# Frame buffer Devices +# +CONFIG_FB=y +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_IMX is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_UVESA is not set +CONFIG_FB_EFI=y +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SH_MOBILE_LCDC is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_XEN_FBDEV_FRONTEND is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_HYPERV is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SSD1307 is not set +# CONFIG_FB_SM712 is not set +CONFIG_FB_CORE=y +CONFIG_FB_NOTIFY=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_DEVICE=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_IOMEM_HELPERS=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +# end of Frame buffer Devices + +# +# Backlight & LCD device support +# +# CONFIG_LCD_CLASS_DEVICE is not set +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set +# end of Backlight & LCD device support + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=80 +CONFIG_DUMMY_CONSOLE_ROWS=25 +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +# end of Console display driver support + +# CONFIG_LOGO is not set +# end of Graphics support + +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=m +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +# CONFIG_UHID is not set +CONFIG_HID_GENERIC=m + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACCUTOUCH is not set +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_APPLEIR is not set +# CONFIG_HID_ASUS is not set +# CONFIG_HID_AUREAL is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_BETOP_FF is not set +# CONFIG_HID_BIGBEN_FF is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CORSAIR is not set +# CONFIG_HID_COUGAR is not set +# CONFIG_HID_MACALLY is not set +# CONFIG_HID_CMEDIA is not set +# CONFIG_HID_CP2112 is not set +# CONFIG_HID_CREATIVE_SB0540 is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELAN is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_ELO is not set +# CONFIG_HID_EVISION is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_FT260 is not set +# CONFIG_HID_GEMBIRD is not set +# CONFIG_HID_GFRM is not set +# CONFIG_HID_GLORIOUS is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_GOOGLE_STADIA_FF is not set +# CONFIG_HID_VIVALDI is not set +# CONFIG_HID_GT683R is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_VIEWSONIC is not set +# CONFIG_HID_VRC2 is not set +# CONFIG_HID_XIAOMI is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_ICADE is not set +# CONFIG_HID_ITE is not set +# CONFIG_HID_JABRA is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LED is not set +# CONFIG_HID_LENOVO is not set +# CONFIG_HID_LETSKETCH is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MALTRON is not set +# CONFIG_HID_MAYFLASH is not set +# CONFIG_HID_MEGAWORLD_FF is not set +# CONFIG_HID_REDRAGON is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_NINTENDO is not set +# CONFIG_HID_NTI is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PENMOUNT is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PLANTRONICS is not set +# CONFIG_HID_PXRC is not set +# CONFIG_HID_RAZER is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_RETRODE is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SEMITEK is not set +# CONFIG_HID_SIGMAMICRO is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEAM is not set +# CONFIG_HID_STEELSERIES is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_RMI is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_HYPERV_MOUSE is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_TOPRE is not set +# CONFIG_HID_THINGM is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_UDRAW_PS3 is not set +# CONFIG_HID_U2FZERO is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_WIIMOTE is not set +# CONFIG_HID_XINMO is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +# CONFIG_HID_SENSOR_HUB is not set +# CONFIG_HID_ALPS is not set +# CONFIG_HID_MCP2221 is not set +# end of Special HID drivers + +# +# HID-BPF support +# +# end of HID-BPF support + +# +# USB HID support +# +CONFIG_USB_HID=m +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# end of USB HID Boot Protocol drivers +# end of USB HID support + +CONFIG_I2C_HID=m +# CONFIG_I2C_HID_ACPI is not set +# CONFIG_I2C_HID_OF is not set +# CONFIG_I2C_HID_OF_ELAN is not set +# CONFIG_I2C_HID_OF_GOODIX is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +# CONFIG_USB_LED_TRIG is not set +# CONFIG_USB_ULPI_BUS is not set +# CONFIG_USB_CONN_GPIO is not set +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_PCI=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_FEW_INIT_RETRIES is not set +CONFIG_USB_DYNAMIC_MINORS=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_PRODUCTLIST is not set +# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set +# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set +CONFIG_USB_AUTOSUSPEND_DELAY=2 +# CONFIG_USB_MON is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_XHCI_HCD=m +# CONFIG_USB_XHCI_DBGCAP is not set +CONFIG_USB_XHCI_PCI=m +# CONFIG_USB_XHCI_PCI_RENESAS is not set +# CONFIG_USB_XHCI_PLATFORM is not set +# CONFIG_USB_XHCI_MVEBU is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=m +# CONFIG_USB_EHCI_FSL is not set +CONFIG_USB_EHCI_HCD_ORION=m +# CONFIG_USB_EHCI_TEGRA is not set +# CONFIG_USB_EHCI_HCD_PLATFORM is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_HCD_PCI=m +# CONFIG_USB_OHCI_HCD_SSB is not set +# CONFIG_USB_OHCI_HCD_PLATFORM is not set +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_SL811_HCD=m +# CONFIG_USB_SL811_HCD_ISO is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HCD_BCMA is not set +# CONFIG_USB_HCD_SSB is not set +# CONFIG_USB_HCD_TEST_MODE is not set +# CONFIG_USB_XEN_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +# CONFIG_USB_PRINTER is not set +CONFIG_USB_WDM=m +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_UAS is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set + +# +# USB dual-mode controller drivers +# +# CONFIG_USB_CDNS_SUPPORT is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_DWC2 is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_ISP1760 is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_SIMPLE=m +# CONFIG_USB_SERIAL_AIRCABLE is not set +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=m +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_F81232=m +CONFIG_USB_SERIAL_F8153X=m +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +CONFIG_USB_SERIAL_IUU=m +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +CONFIG_USB_SERIAL_KEYSPAN=m +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +CONFIG_USB_SERIAL_MCT_U232=m +# CONFIG_USB_SERIAL_METRO is not set +CONFIG_USB_SERIAL_MOS7720=m +# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MXUPORT=m +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +# CONFIG_USB_SERIAL_SYMBOL is not set +CONFIG_USB_SERIAL_TI=m +# CONFIG_USB_SERIAL_CYBERJACK is not set +CONFIG_USB_SERIAL_WWAN=m +CONFIG_USB_SERIAL_OPTION=m +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_XSENS_MT is not set +# CONFIG_USB_SERIAL_WISHBONE is not set +CONFIG_USB_SERIAL_SSU100=m +CONFIG_USB_SERIAL_QT2=m +CONFIG_USB_SERIAL_UPD78F0730=m +# CONFIG_USB_SERIAL_XR is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_USS720 is not set +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_QCOM_EUD is not set +# CONFIG_APPLE_MFI_FASTCHARGE is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_EZUSB_FX2=m +# CONFIG_USB_HUB_USB251XB is not set +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_HSIC_USB4604 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set +# CONFIG_USB_ONBOARD_HUB is not set + +# +# USB Physical Layer drivers +# +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +# CONFIG_USB_MXS_PHY is not set +# CONFIG_USB_TEGRA_PHY is not set +# CONFIG_USB_ULPI is not set +# end of USB Physical Layer drivers + +# CONFIG_USB_GADGET is not set +# CONFIG_TYPEC is not set +# CONFIG_USB_ROLE_SWITCH is not set +CONFIG_MMC=m +CONFIG_PWRSEQ_EMMC=m +# CONFIG_PWRSEQ_SD8787 is not set +CONFIG_PWRSEQ_SIMPLE=m +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_MINORS=256 +CONFIG_SDIO_UART=m +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_ARMMMCI is not set +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_RICOH_MMC=y +CONFIG_MMC_SDHCI_ACPI=m +CONFIG_MMC_SDHCI_PLTFM=m +# CONFIG_MMC_SDHCI_OF_ARASAN is not set +# CONFIG_MMC_SDHCI_OF_AT91 is not set +# CONFIG_MMC_SDHCI_OF_ESDHC is not set +# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set +# CONFIG_MMC_SDHCI_CADENCE is not set +# CONFIG_MMC_SDHCI_ESDHC_IMX is not set +# CONFIG_MMC_SDHCI_TEGRA is not set +# CONFIG_MMC_SDHCI_PXAV3 is not set +CONFIG_MMC_SDHCI_F_SDH30=m +# CONFIG_MMC_SDHCI_MILBEAUT is not set +# CONFIG_MMC_SDHCI_IPROC is not set +# CONFIG_MMC_MESON_GX is not set +# CONFIG_MMC_MESON_MX_SDIO is not set +# CONFIG_MMC_SDHCI_MSM is not set +# CONFIG_MMC_MXC is not set +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_SDHI is not set +CONFIG_MMC_CB710=m +CONFIG_MMC_VIA_SDMMC=m +# CONFIG_MMC_DW is not set +# CONFIG_MMC_SH_MMCIF is not set +CONFIG_MMC_VUB300=m +CONFIG_MMC_USHC=m +CONFIG_MMC_USDHI6ROL0=m +CONFIG_MMC_REALTEK_PCI=m +CONFIG_MMC_REALTEK_USB=m +# CONFIG_MMC_SUNXI is not set +CONFIG_MMC_CQHCI=m +# CONFIG_MMC_HSQ is not set +# CONFIG_MMC_TOSHIBA_PCI is not set +# CONFIG_MMC_BCM2835 is not set +CONFIG_MMC_MTK=m +CONFIG_MMC_SDHCI_XENON=m +# CONFIG_MMC_SDHCI_AM654 is not set +CONFIG_SCSI_UFSHCD=m +# CONFIG_SCSI_UFS_BSG is not set +# CONFIG_SCSI_UFS_HWMON is not set +CONFIG_SCSI_UFSHCD_PCI=m +# CONFIG_SCSI_UFS_DWC_TC_PCI is not set +# CONFIG_SCSI_UFSHCD_PLATFORM is not set +# CONFIG_SCSI_UFS_TI_J721E is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_FLASH=m +# CONFIG_LEDS_CLASS_MULTICOLOR is not set +CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y + +# +# LED drivers +# +# CONFIG_LEDS_AN30259A is not set +# CONFIG_LEDS_AW200XX is not set +# CONFIG_LEDS_AW2013 is not set +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set +CONFIG_LEDS_LM3530=m +# CONFIG_LEDS_LM3532 is not set +CONFIG_LEDS_LM3642=m +# CONFIG_LEDS_LM3692X is not set +CONFIG_LEDS_PCA9532=m +# CONFIG_LEDS_PCA9532_GPIO is not set +CONFIG_LEDS_GPIO=m +CONFIG_LEDS_LP3944=m +CONFIG_LEDS_LP3952=m +# CONFIG_LEDS_LP50XX is not set +# CONFIG_LEDS_LP55XX_COMMON is not set +# CONFIG_LEDS_LP8860 is not set +CONFIG_LEDS_PCA955X=m +# CONFIG_LEDS_PCA955X_GPIO is not set +CONFIG_LEDS_PCA963X=m +# CONFIG_LEDS_PCA995X is not set +CONFIG_LEDS_REGULATOR=m +# CONFIG_LEDS_BD2606MVV is not set +CONFIG_LEDS_BD2802=m +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TCA6507=m +CONFIG_LEDS_TLC591XX=m +CONFIG_LEDS_LM355x=m +CONFIG_LEDS_MENF21BMC=m +# CONFIG_LEDS_IS31FL319X is not set +# CONFIG_LEDS_IS31FL32XX is not set + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +CONFIG_LEDS_BLINKM=m +# CONFIG_LEDS_SYSCON is not set +CONFIG_LEDS_MLXREG=m +# CONFIG_LEDS_USER is not set +# CONFIG_LEDS_LM3697 is not set + +# +# Flash and Torch LED drivers +# +# CONFIG_LEDS_AAT1290 is not set +CONFIG_LEDS_AS3645A=m +# CONFIG_LEDS_KTD2692 is not set +CONFIG_LEDS_LM3601X=m +# CONFIG_LEDS_RT4505 is not set +# CONFIG_LEDS_RT8515 is not set +# CONFIG_LEDS_SGM3140 is not set + +# +# RGB LED drivers +# + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_ONESHOT=m +CONFIG_LEDS_TRIGGER_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_ACTIVITY=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_LEDS_TRIGGER_TRANSIENT=m +CONFIG_LEDS_TRIGGER_CAMERA=m +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_LEDS_TRIGGER_NETDEV=m +# CONFIG_LEDS_TRIGGER_PATTERN is not set +# CONFIG_LEDS_TRIGGER_AUDIO is not set +# CONFIG_LEDS_TRIGGER_TTY is not set + +# +# Simple LED drivers +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_INFINIBAND=m +# CONFIG_INFINIBAND_USER_MAD is not set +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFINIBAND_ON_DEMAND_PAGING=y +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS=y +CONFIG_INFINIBAND_VIRT_DMA=y +# CONFIG_INFINIBAND_BNXT_RE is not set +# CONFIG_INFINIBAND_CXGB4 is not set +# CONFIG_INFINIBAND_EFA is not set +# CONFIG_INFINIBAND_ERDMA is not set +# CONFIG_INFINIBAND_IRDMA is not set +CONFIG_MLX4_INFINIBAND=m +CONFIG_MLX5_INFINIBAND=m +# CONFIG_INFINIBAND_MTHCA is not set +# CONFIG_INFINIBAND_OCRDMA is not set +# CONFIG_INFINIBAND_QEDR is not set +# CONFIG_INFINIBAND_VMWARE_PVRDMA is not set +# CONFIG_RDMA_RXE is not set +# CONFIG_RDMA_SIW is not set +# CONFIG_INFINIBAND_IPOIB is not set +# CONFIG_INFINIBAND_SRP is not set +# CONFIG_INFINIBAND_ISER is not set +# CONFIG_INFINIBAND_RTRS_CLIENT is not set +# CONFIG_INFINIBAND_RTRS_SERVER is not set +CONFIG_EDAC_SUPPORT=y +CONFIG_EDAC=y +CONFIG_EDAC_LEGACY_SYSFS=y +# CONFIG_EDAC_DEBUG is not set +# CONFIG_EDAC_GHES is not set +# CONFIG_EDAC_LAYERSCAPE is not set +# CONFIG_EDAC_THUNDERX is not set +# CONFIG_EDAC_SYNOPSYS is not set +# CONFIG_EDAC_XGENE is not set +# CONFIG_EDAC_DMC520 is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_NVMEM=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABEOZ9 is not set +# CONFIG_RTC_DRV_ABX80X is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_HYM8563 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_NCT3018Y is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_ISL12026 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF85363 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8010 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3028 is not set +# CONFIG_RTC_DRV_RV3032 is not set +# CONFIG_RTC_DRV_RV8803 is not set +# CONFIG_RTC_DRV_SD3078 is not set + +# +# SPI RTC drivers +# +CONFIG_RTC_I2C_AND_SPI=y + +# +# SPI and I2C RTC drivers +# +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set +# CONFIG_RTC_DRV_RX6110 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_EFI is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_ZYNQMP is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_IMXDI is not set +# CONFIG_RTC_DRV_FSL_FTM_ALARM is not set +CONFIG_RTC_DRV_MESON_VRTC=m +# CONFIG_RTC_DRV_SH is not set +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_SUN6I is not set +# CONFIG_RTC_DRV_MV is not set +# CONFIG_RTC_DRV_ARMADA38X is not set +# CONFIG_RTC_DRV_CADENCE is not set +# CONFIG_RTC_DRV_FTRTC010 is not set +# CONFIG_RTC_DRV_TEGRA is not set +# CONFIG_RTC_DRV_MXC is not set +# CONFIG_RTC_DRV_MXC_V2 is not set +# CONFIG_RTC_DRV_SNVS is not set +# CONFIG_RTC_DRV_BBNSM is not set +# CONFIG_RTC_DRV_XGENE is not set +# CONFIG_RTC_DRV_R7301 is not set +# CONFIG_RTC_DRV_TI_K3 is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_GOLDFISH is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DMA_ACPI=y +CONFIG_DMA_OF=y +# CONFIG_ALTERA_MSGDMA is not set +# CONFIG_AMBA_PL08X is not set +# CONFIG_BCM_SBA_RAID is not set +CONFIG_DMA_BCM2835=y +CONFIG_DMA_SUN6I=m +# CONFIG_DW_AXI_DMAC is not set +CONFIG_FSL_EDMA=m +CONFIG_FSL_QDMA=m +# CONFIG_HISI_DMA is not set +# CONFIG_IMX_DMA is not set +CONFIG_IMX_SDMA=m +# CONFIG_INTEL_IDMA64 is not set +CONFIG_K3_DMA=m +CONFIG_MV_XOR=y +CONFIG_MV_XOR_V2=y +# CONFIG_MXS_DMA is not set +CONFIG_PL330_DMA=m +# CONFIG_PLX_DMA is not set +# CONFIG_TEGRA186_GPC_DMA is not set +CONFIG_TEGRA20_APB_DMA=y +CONFIG_XGENE_DMA=m +# CONFIG_XILINX_DMA is not set +# CONFIG_XILINX_XDMA is not set +# CONFIG_XILINX_ZYNQMP_DMA is not set +# CONFIG_XILINX_ZYNQMP_DPDMA is not set +CONFIG_QCOM_BAM_DMA=m +# CONFIG_QCOM_GPI_DMA is not set +CONFIG_QCOM_HIDMA_MGMT=m +CONFIG_QCOM_HIDMA=m +# CONFIG_DW_DMAC is not set +# CONFIG_DW_DMAC_PCI is not set +# CONFIG_DW_EDMA is not set +# CONFIG_SF_PDMA is not set +# CONFIG_RCAR_DMAC is not set +# CONFIG_RENESAS_USB_DMAC is not set +CONFIG_TI_K3_UDMA=y +CONFIG_TI_K3_UDMA_GLUE_LAYER=y +CONFIG_TI_K3_PSIL=y + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE_RAID=y + +# +# DMABUF options +# +CONFIG_SYNC_FILE=y +# CONFIG_SW_SYNC is not set +# CONFIG_UDMABUF is not set +# CONFIG_DMABUF_MOVE_NOTIFY is not set +# CONFIG_DMABUF_DEBUG is not set +# CONFIG_DMABUF_SELFTESTS is not set +# CONFIG_DMABUF_HEAPS is not set +# CONFIG_DMABUF_SYSFS_STATS is not set +# end of DMABUF options + +CONFIG_UIO=m +# CONFIG_UIO_CIF is not set +# CONFIG_UIO_PDRV_GENIRQ is not set +# CONFIG_UIO_DMEM_GENIRQ is not set +# CONFIG_UIO_AEC is not set +# CONFIG_UIO_SERCOS3 is not set +CONFIG_UIO_PCI_GENERIC=m +# CONFIG_UIO_NETX is not set +# CONFIG_UIO_PRUSS is not set +# CONFIG_UIO_MF624 is not set +CONFIG_UIO_HV_GENERIC=m +CONFIG_VFIO=m +CONFIG_VFIO_GROUP=y +CONFIG_VFIO_CONTAINER=y +CONFIG_VFIO_IOMMU_TYPE1=m +CONFIG_VFIO_NOIOMMU=y +CONFIG_VFIO_VIRQFD=y + +# +# VFIO support for PCI devices +# +CONFIG_VFIO_PCI_CORE=m +CONFIG_VFIO_PCI_MMAP=y +CONFIG_VFIO_PCI_INTX=y +CONFIG_VFIO_PCI=m +# CONFIG_MLX5_VFIO_PCI is not set +# end of VFIO support for PCI devices + +# +# VFIO support for platform devices +# +# CONFIG_VFIO_PLATFORM is not set +# CONFIG_VFIO_AMBA is not set +# end of VFIO support for platform devices + +# +# VFIO support for FSL_MC bus devices +# +CONFIG_VFIO_FSL_MC=m +# end of VFIO support for FSL_MC bus devices + +CONFIG_VIRT_DRIVERS=y +CONFIG_VMGENID=y +# CONFIG_NITRO_ENCLAVES is not set +CONFIG_VIRTIO_ANCHOR=y +CONFIG_VIRTIO=m +CONFIG_VIRTIO_PCI_LIB=m +CONFIG_VIRTIO_PCI_LIB_LEGACY=m +CONFIG_VIRTIO_MENU=y +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_PCI_LEGACY=y +# CONFIG_VIRTIO_PMEM is not set +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_MEM=m +CONFIG_VIRTIO_INPUT=m +CONFIG_VIRTIO_MMIO=m +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y +CONFIG_VIRTIO_VDPA=m +CONFIG_VDPA=m +CONFIG_VHOST_VDPA=m +CONFIG_VHOST_IOTLB=m +CONFIG_VHOST_TASK=y +CONFIG_VHOST=m +CONFIG_VHOST_MENU=y +CONFIG_VHOST_NET=m +CONFIG_VHOST_VSOCK=m +# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_HYPERV=m +CONFIG_HYPERV_UTILS=m +CONFIG_HYPERV_BALLOON=m +# end of Microsoft Hyper-V guest support + +# +# Xen driver support +# +CONFIG_XEN_BALLOON=y +CONFIG_XEN_BALLOON_MEMORY_HOTPLUG=y +CONFIG_XEN_SCRUB_PAGES_DEFAULT=y +CONFIG_XEN_DEV_EVTCHN=m +CONFIG_XEN_BACKEND=y +CONFIG_XENFS=m +CONFIG_XEN_COMPAT_XENFS=y +CONFIG_XEN_SYS_HYPERVISOR=y +CONFIG_XEN_XENBUS_FRONTEND=y +CONFIG_XEN_GNTDEV=m +CONFIG_XEN_GRANT_DEV_ALLOC=m +# CONFIG_XEN_GRANT_DMA_ALLOC is not set +CONFIG_SWIOTLB_XEN=y +CONFIG_XEN_PCI_STUB=y +CONFIG_XEN_PCIDEV_STUB=m +# CONFIG_XEN_PVCALLS_FRONTEND is not set +# CONFIG_XEN_PVCALLS_BACKEND is not set +CONFIG_XEN_PRIVCMD=m +CONFIG_XEN_EFI=y +CONFIG_XEN_AUTO_XLATE=y +# CONFIG_XEN_VIRTIO is not set +# end of Xen driver support + +# CONFIG_GREYBUS is not set +# CONFIG_COMEDI is not set +# CONFIG_STAGING is not set +# CONFIG_GOLDFISH is not set +# CONFIG_CHROME_PLATFORMS is not set +# CONFIG_MELLANOX_PLATFORM is not set +CONFIG_SURFACE_PLATFORMS=y +# CONFIG_SURFACE_3_POWER_OPREGION is not set +# CONFIG_SURFACE_GPE is not set +# CONFIG_SURFACE_HOTPLUG is not set +# CONFIG_SURFACE_PRO3_BUTTON is not set +# CONFIG_SURFACE_AGGREGATOR is not set +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Clock driver for ARM Reference designs +# +# CONFIG_CLK_ICST is not set +# CONFIG_CLK_SP810 is not set +CONFIG_CLK_VEXPRESS_OSC=y +# end of Clock driver for ARM Reference designs + +# CONFIG_COMMON_CLK_MAX9485 is not set +CONFIG_COMMON_CLK_SCMI=y +CONFIG_COMMON_CLK_SCPI=m +CONFIG_COMMON_CLK_SI5341=y +# CONFIG_COMMON_CLK_SI5351 is not set +# CONFIG_COMMON_CLK_SI514 is not set +# CONFIG_COMMON_CLK_SI544 is not set +# CONFIG_COMMON_CLK_SI570 is not set +# CONFIG_COMMON_CLK_CDCE706 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set +# CONFIG_COMMON_CLK_CS2000_CP is not set +CONFIG_COMMON_CLK_FSL_FLEXSPI=m +CONFIG_COMMON_CLK_FSL_SAI=y +# CONFIG_COMMON_CLK_AXI_CLKGEN is not set +CONFIG_CLK_QORIQ=y +CONFIG_CLK_LS1028A_PLLDIG=y +CONFIG_COMMON_CLK_XGENE=y +# CONFIG_COMMON_CLK_RS9_PCIE is not set +# CONFIG_COMMON_CLK_SI521XX is not set +# CONFIG_COMMON_CLK_VC3 is not set +# CONFIG_COMMON_CLK_VC5 is not set +# CONFIG_COMMON_CLK_VC7 is not set +# CONFIG_COMMON_CLK_FIXED_MMIO is not set +CONFIG_CLK_BCM2711_DVP=y +CONFIG_CLK_BCM2835=y +CONFIG_CLK_RASPBERRYPI=y +CONFIG_COMMON_CLK_HI3516CV300=y +CONFIG_COMMON_CLK_HI3519=y +CONFIG_COMMON_CLK_HI3559A=y +CONFIG_COMMON_CLK_HI3660=y +CONFIG_COMMON_CLK_HI3670=y +CONFIG_COMMON_CLK_HI3798CV200=y +CONFIG_COMMON_CLK_HI6220=y +CONFIG_RESET_HISI=y +CONFIG_STUB_CLK_HI6220=y +CONFIG_STUB_CLK_HI3660=y +CONFIG_MXC_CLK=y +CONFIG_CLK_IMX8MM=y +CONFIG_CLK_IMX8MN=y +CONFIG_CLK_IMX8MP=y +CONFIG_CLK_IMX8MQ=y +# CONFIG_CLK_IMX8ULP is not set +# CONFIG_CLK_IMX93 is not set +CONFIG_TI_SCI_CLK=y +# CONFIG_TI_SCI_CLK_PROBE_FROM_FW is not set +CONFIG_TI_SYSCON_CLK=y + +# +# Clock support for Amlogic platforms +# +CONFIG_COMMON_CLK_MESON_REGMAP=y +CONFIG_COMMON_CLK_MESON_DUALDIV=y +CONFIG_COMMON_CLK_MESON_MPLL=y +CONFIG_COMMON_CLK_MESON_PHASE=m +CONFIG_COMMON_CLK_MESON_PLL=y +CONFIG_COMMON_CLK_MESON_SCLK_DIV=m +CONFIG_COMMON_CLK_MESON_VID_PLL_DIV=y +CONFIG_COMMON_CLK_MESON_CLKC_UTILS=y +CONFIG_COMMON_CLK_MESON_AO_CLKC=y +CONFIG_COMMON_CLK_MESON_EE_CLKC=y +CONFIG_COMMON_CLK_MESON_CPU_DYNDIV=y +CONFIG_COMMON_CLK_GXBB=y +CONFIG_COMMON_CLK_AXG=y +CONFIG_COMMON_CLK_AXG_AUDIO=m +# CONFIG_COMMON_CLK_A1_PLL is not set +# CONFIG_COMMON_CLK_A1_PERIPHERALS is not set +CONFIG_COMMON_CLK_G12A=y +# end of Clock support for Amlogic platforms + +CONFIG_ARMADA_AP_CP_HELPER=y +CONFIG_ARMADA_37XX_CLK=y +CONFIG_ARMADA_AP806_SYSCON=y +CONFIG_ARMADA_CP110_SYSCON=y +CONFIG_QCOM_GDSC=y +CONFIG_COMMON_CLK_QCOM=y +# CONFIG_QCOM_A53PLL is not set +# CONFIG_QCOM_A7PLL is not set +# CONFIG_QCOM_CLK_APCS_MSM8916 is not set +# CONFIG_QCOM_CLK_APCC_MSM8996 is not set +# CONFIG_IPQ_APSS_PLL is not set +# CONFIG_IPQ_GCC_4019 is not set +# CONFIG_IPQ_GCC_5018 is not set +# CONFIG_IPQ_GCC_5332 is not set +# CONFIG_IPQ_GCC_6018 is not set +# CONFIG_IPQ_GCC_8074 is not set +# CONFIG_IPQ_GCC_9574 is not set +CONFIG_MSM_GCC_8916=y +# CONFIG_MSM_GCC_8917 is not set +# CONFIG_MSM_GCC_8939 is not set +# CONFIG_MSM_GCC_8953 is not set +# CONFIG_MSM_GCC_8976 is not set +# CONFIG_MSM_MMCC_8994 is not set +# CONFIG_MSM_GCC_8994 is not set +CONFIG_MSM_GCC_8996=y +CONFIG_MSM_MMCC_8996=y +# CONFIG_MSM_GCC_8998 is not set +# CONFIG_MSM_GPUCC_8998 is not set +# CONFIG_MSM_MMCC_8998 is not set +# CONFIG_QCM_GCC_2290 is not set +# CONFIG_QCM_DISPCC_2290 is not set +# CONFIG_QCS_GCC_404 is not set +# CONFIG_SC_CAMCC_7180 is not set +# CONFIG_SC_CAMCC_7280 is not set +# CONFIG_SC_DISPCC_7180 is not set +# CONFIG_SC_DISPCC_7280 is not set +# CONFIG_SC_DISPCC_8280XP is not set +# CONFIG_SA_GCC_8775P is not set +# CONFIG_SA_GPUCC_8775P is not set +# CONFIG_SC_GCC_7180 is not set +# CONFIG_SC_GCC_7280 is not set +# CONFIG_SC_GCC_8180X is not set +# CONFIG_SC_GCC_8280XP is not set +# CONFIG_SC_GPUCC_7180 is not set +# CONFIG_SC_GPUCC_7280 is not set +# CONFIG_SC_GPUCC_8280XP is not set +# CONFIG_SC_LPASSCC_7280 is not set +# CONFIG_SC_LPASSCC_8280XP is not set +# CONFIG_SC_LPASS_CORECC_7180 is not set +# CONFIG_SC_LPASS_CORECC_7280 is not set +# CONFIG_SC_MSS_7180 is not set +# CONFIG_SC_VIDEOCC_7180 is not set +# CONFIG_SC_VIDEOCC_7280 is not set +CONFIG_SDM_CAMCC_845=m +# CONFIG_SDM_GCC_660 is not set +# CONFIG_SDM_MMCC_660 is not set +# CONFIG_SDM_GPUCC_660 is not set +# CONFIG_QCS_TURING_404 is not set +# CONFIG_QCS_Q6SSTOP_404 is not set +# CONFIG_QDU_GCC_1000 is not set +CONFIG_SDM_GCC_845=y +CONFIG_SDM_GPUCC_845=m +CONFIG_SDM_VIDEOCC_845=m +CONFIG_SDM_DISPCC_845=m +# CONFIG_SDM_LPASSCC_845 is not set +# CONFIG_SDX_GCC_75 is not set +# CONFIG_SM_CAMCC_6350 is not set +# CONFIG_SM_CAMCC_8250 is not set +# CONFIG_SM_CAMCC_8450 is not set +# CONFIG_SM_GCC_6115 is not set +# CONFIG_SM_GCC_6125 is not set +# CONFIG_SM_GCC_6350 is not set +# CONFIG_SM_GCC_6375 is not set +# CONFIG_SM_GCC_7150 is not set +# CONFIG_SM_GCC_8150 is not set +# CONFIG_SM_GCC_8250 is not set +# CONFIG_SM_GCC_8350 is not set +# CONFIG_SM_GCC_8450 is not set +# CONFIG_SM_GCC_8550 is not set +# CONFIG_SM_GPUCC_6115 is not set +# CONFIG_SM_GPUCC_6125 is not set +# CONFIG_SM_GPUCC_6375 is not set +# CONFIG_SM_GPUCC_6350 is not set +# CONFIG_SM_GPUCC_8150 is not set +# CONFIG_SM_GPUCC_8250 is not set +# CONFIG_SM_GPUCC_8350 is not set +# CONFIG_SM_GPUCC_8450 is not set +# CONFIG_SM_GPUCC_8550 is not set +# CONFIG_SM_TCSRCC_8550 is not set +# CONFIG_SM_VIDEOCC_8150 is not set +# CONFIG_SM_VIDEOCC_8250 is not set +# CONFIG_SM_VIDEOCC_8350 is not set +# CONFIG_SM_VIDEOCC_8550 is not set +CONFIG_QCOM_HFPLL=y +# CONFIG_KPSS_XCC is not set +# CONFIG_CLK_GFM_LPASS_SM8250 is not set +# CONFIG_SM_VIDEOCC_8450 is not set +CONFIG_CLK_RENESAS=y +# CONFIG_CLK_RCAR_USB2_CLOCK_SEL is not set +CONFIG_COMMON_CLK_ROCKCHIP=y +CONFIG_CLK_PX30=y +CONFIG_CLK_RK3308=y +CONFIG_CLK_RK3328=y +CONFIG_CLK_RK3368=y +CONFIG_CLK_RK3399=y +CONFIG_CLK_RK3568=y +CONFIG_CLK_RK3588=y +CONFIG_SUNXI_CCU=y +CONFIG_SUN50I_A64_CCU=y +CONFIG_SUN50I_A100_CCU=y +CONFIG_SUN50I_A100_R_CCU=y +CONFIG_SUN50I_H6_CCU=y +CONFIG_SUN50I_H616_CCU=y +CONFIG_SUN50I_H6_R_CCU=y +CONFIG_SUN6I_RTC_CCU=y +CONFIG_SUN8I_H3_CCU=y +CONFIG_SUN8I_DE2_CCU=y +CONFIG_SUN8I_R_CCU=y +# CONFIG_XILINX_VCU is not set +# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set +# CONFIG_HWSPINLOCK is not set + +# +# Clock Source drivers +# +CONFIG_TIMER_OF=y +CONFIG_TIMER_ACPI=y +CONFIG_TIMER_PROBE=y +CONFIG_CLKSRC_MMIO=y +CONFIG_OMAP_DM_TIMER=y +CONFIG_ROCKCHIP_TIMER=y +CONFIG_SUN4I_TIMER=y +# CONFIG_TEGRA186_TIMER is not set +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y +CONFIG_FSL_ERRATUM_A008585=y +CONFIG_HISILICON_ERRATUM_161010101=y +CONFIG_ARM64_ERRATUM_858921=y +CONFIG_SUN50I_ERRATUM_UNKNOWN1=y +CONFIG_ARM_TIMER_SP804=y +# CONFIG_RENESAS_OSTM is not set +CONFIG_TIMER_IMX_SYS_CTR=y +# end of Clock Source drivers + +CONFIG_MAILBOX=y +CONFIG_ARM_MHU=m +# CONFIG_ARM_MHU_V2 is not set +CONFIG_IMX_MBOX=m +CONFIG_PLATFORM_MHU=m +# CONFIG_PL320_MBOX is not set +CONFIG_ARMADA_37XX_RWTM_MBOX=m +CONFIG_OMAP2PLUS_MBOX=y +CONFIG_OMAP_MBOX_KFIFO_SIZE=256 +# CONFIG_ROCKCHIP_MBOX is not set +CONFIG_PCC=y +# CONFIG_ALTERA_MBOX is not set +CONFIG_BCM2835_MBOX=y +CONFIG_TI_MESSAGE_MANAGER=y +CONFIG_HI3660_MBOX=y +CONFIG_HI6220_MBOX=y +# CONFIG_MAILBOX_TEST is not set +CONFIG_QCOM_APCS_IPC=m +# CONFIG_TEGRA_HSP_MBOX is not set +CONFIG_XGENE_SLIMPRO_MBOX=m +CONFIG_SUN6I_MSGBOX=y +# CONFIG_QCOM_IPCC is not set +CONFIG_IOMMU_IOVA=y +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +CONFIG_IOMMU_IO_PGTABLE=y +CONFIG_IOMMU_IO_PGTABLE_LPAE=y +# CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# CONFIG_IOMMU_IO_PGTABLE_DART is not set +# end of Generic IOMMU Pagetable Support + +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set +CONFIG_IOMMU_DEFAULT_DMA_LAZY=y +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_OF_IOMMU=y +CONFIG_IOMMU_DMA=y +# CONFIG_IOMMUFD is not set +CONFIG_ROCKCHIP_IOMMU=y +# CONFIG_SUN50I_IOMMU is not set +# CONFIG_IPMMU_VMSA is not set +CONFIG_ARM_SMMU=y +# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set +CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y +CONFIG_ARM_SMMU_QCOM=y +# CONFIG_ARM_SMMU_QCOM_DEBUG is not set +CONFIG_ARM_SMMU_V3=y +# CONFIG_ARM_SMMU_V3_SVA is not set +CONFIG_QCOM_IOMMU=y +# CONFIG_VIRTIO_IOMMU is not set + +# +# Remoteproc drivers +# +# CONFIG_REMOTEPROC is not set +# end of Remoteproc drivers + +# +# Rpmsg drivers +# +CONFIG_RPMSG=m +# CONFIG_RPMSG_CHAR is not set +# CONFIG_RPMSG_CTRL is not set +# CONFIG_RPMSG_NS is not set +CONFIG_RPMSG_QCOM_GLINK=m +CONFIG_RPMSG_QCOM_GLINK_RPM=m +# CONFIG_RPMSG_VIRTIO is not set +# end of Rpmsg drivers + +# CONFIG_SOUNDWIRE is not set + +# +# SOC (System On Chip) specific Drivers +# + +# +# Amlogic SoC drivers +# +# CONFIG_MESON_CANVAS is not set +CONFIG_MESON_CLK_MEASURE=y +CONFIG_MESON_GX_SOCINFO=y +CONFIG_MESON_GX_PM_DOMAINS=y +CONFIG_MESON_EE_PM_DOMAINS=y +CONFIG_MESON_SECURE_PM_DOMAINS=y +# end of Amlogic SoC drivers + +# +# Broadcom SoC drivers +# +CONFIG_BCM2835_POWER=y +# CONFIG_RASPBERRYPI_POWER is not set +# CONFIG_SOC_BRCMSTB is not set +# end of Broadcom SoC drivers + +# +# NXP/Freescale QorIQ SoC drivers +# +# CONFIG_FSL_DPAA is not set +# CONFIG_QUICC_ENGINE is not set +# CONFIG_FSL_MC_DPIO is not set +CONFIG_DPAA2_CONSOLE=y +# CONFIG_FSL_RCPM is not set +# end of NXP/Freescale QorIQ SoC drivers + +# +# fujitsu SoC drivers +# +# CONFIG_A64FX_DIAG is not set +# end of fujitsu SoC drivers + +# +# Hisilicon SoC drivers +# +# CONFIG_KUNPENG_HCCS is not set +# end of Hisilicon SoC drivers + +# +# i.MX SoC drivers +# +CONFIG_IMX_GPCV2_PM_DOMAINS=y +CONFIG_SOC_IMX8M=y +CONFIG_SOC_IMX9=y +CONFIG_IMX8M_BLK_CTRL=y +CONFIG_IMX9_BLK_CTRL=y +# end of i.MX SoC drivers + +# +# Enable LiteX SoC Builder specific drivers +# +# CONFIG_LITEX_SOC_CONTROLLER is not set +# end of Enable LiteX SoC Builder specific drivers + +# CONFIG_WPCM450_SOC is not set + +# +# Qualcomm SoC drivers +# +# CONFIG_QCOM_AOSS_QMP is not set +# CONFIG_QCOM_COMMAND_DB is not set +# CONFIG_QCOM_CPR is not set +# CONFIG_QCOM_GENI_SE is not set +# CONFIG_QCOM_GSBI is not set +# CONFIG_QCOM_LLCC is not set +# CONFIG_QCOM_OCMEM is not set +# CONFIG_QCOM_RAMP_CTRL is not set +# CONFIG_QCOM_RMTFS_MEM is not set +# CONFIG_QCOM_RPM_MASTER_STATS is not set +# CONFIG_QCOM_RPMH is not set +# CONFIG_QCOM_SMD_RPM is not set +# CONFIG_QCOM_SPM is not set +# CONFIG_QCOM_WCNSS_CTRL is not set +# CONFIG_QCOM_APR is not set +# CONFIG_QCOM_ICC_BWMON is not set +# end of Qualcomm SoC drivers + +CONFIG_SOC_RENESAS=y +# CONFIG_ARCH_R8A77995 is not set +# CONFIG_ARCH_R8A77990 is not set +# CONFIG_ARCH_R8A77951 is not set +# CONFIG_ARCH_R8A77965 is not set +# CONFIG_ARCH_R8A77960 is not set +# CONFIG_ARCH_R8A77961 is not set +# CONFIG_ARCH_R8A779F0 is not set +# CONFIG_ARCH_R8A77980 is not set +# CONFIG_ARCH_R8A77970 is not set +# CONFIG_ARCH_R8A779A0 is not set +# CONFIG_ARCH_R8A779G0 is not set +# CONFIG_ARCH_R8A774C0 is not set +# CONFIG_ARCH_R8A774E1 is not set +# CONFIG_ARCH_R8A774A1 is not set +# CONFIG_ARCH_R8A774B1 is not set +# CONFIG_ARCH_R9A07G043 is not set +# CONFIG_ARCH_R9A07G044 is not set +# CONFIG_ARCH_R9A07G054 is not set +# CONFIG_ARCH_R9A09G011 is not set +CONFIG_ROCKCHIP_GRF=y +# CONFIG_ROCKCHIP_IODOMAIN is not set +# CONFIG_ROCKCHIP_PM_DOMAINS is not set +CONFIG_SUNXI_MBUS=y +CONFIG_SUNXI_SRAM=y +# CONFIG_SUN20I_PPU is not set +# CONFIG_ARCH_TEGRA_132_SOC is not set +# CONFIG_ARCH_TEGRA_210_SOC is not set +# CONFIG_ARCH_TEGRA_186_SOC is not set +# CONFIG_ARCH_TEGRA_194_SOC is not set +# CONFIG_ARCH_TEGRA_234_SOC is not set +CONFIG_SOC_TEGRA_FUSE=y +CONFIG_SOC_TI=y +# CONFIG_TI_SCI_PM_DOMAINS is not set +CONFIG_TI_K3_RINGACC=y +CONFIG_TI_K3_SOCINFO=y +# CONFIG_TI_PRUSS is not set +CONFIG_TI_SCI_INTA_MSI_DOMAIN=y + +# +# Xilinx SoC drivers +# +# end of Xilinx SoC drivers +# end of SOC (System On Chip) specific Drivers + +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=m +# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +# CONFIG_DEVFREQ_GOV_USERSPACE is not set +# CONFIG_DEVFREQ_GOV_PASSIVE is not set + +# +# DEVFREQ Drivers +# +# CONFIG_ARM_IMX_BUS_DEVFREQ is not set +# CONFIG_ARM_IMX8M_DDRC_DEVFREQ is not set +# CONFIG_ARM_RK3399_DMC_DEVFREQ is not set +# CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ is not set +# CONFIG_PM_DEVFREQ_EVENT is not set +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_NTB is not set +# CONFIG_PWM is not set + +# +# IRQ chip support +# +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_PM=y +CONFIG_ARM_GIC_MAX_NR=1 +CONFIG_ARM_GIC_V2M=y +CONFIG_ARM_GIC_V3=y +CONFIG_ARM_GIC_V3_ITS=y +CONFIG_ARM_GIC_V3_ITS_PCI=y +CONFIG_ARM_GIC_V3_ITS_FSL_MC=y +# CONFIG_AL_FIC is not set +CONFIG_BRCMSTB_L2_IRQ=y +CONFIG_HISILICON_IRQ_MBIGEN=y +CONFIG_SUN6I_R_INTC=y +CONFIG_SUNXI_NMI_INTC=y +# CONFIG_XILINX_INTC is not set +CONFIG_IMX_GPCV2=y +CONFIG_MVEBU_GICP=y +CONFIG_MVEBU_ICU=y +CONFIG_MVEBU_ODMI=y +CONFIG_MVEBU_PIC=y +CONFIG_MVEBU_SEI=y +CONFIG_LS_EXTIRQ=y +CONFIG_LS_SCFG_MSI=y +CONFIG_PARTITION_PERCPU=y +# CONFIG_QCOM_IRQ_COMBINER is not set +CONFIG_MESON_IRQ_GPIO=y +# CONFIG_QCOM_PDC is not set +# CONFIG_QCOM_MPM is not set +CONFIG_IMX_IRQSTEER=y +CONFIG_IMX_INTMUX=y +CONFIG_IMX_MU_MSI=m +CONFIG_TI_SCI_INTR_IRQCHIP=y +CONFIG_TI_SCI_INTA_IRQCHIP=y +# end of IRQ chip support + +# CONFIG_IPACK_BUS is not set +CONFIG_ARCH_HAS_RESET_CONTROLLER=y +CONFIG_RESET_CONTROLLER=y +# CONFIG_RESET_IMX7 is not set +CONFIG_RESET_MESON=y +# CONFIG_RESET_MESON_AUDIO_ARB is not set +# CONFIG_RESET_QCOM_AOSS is not set +# CONFIG_RESET_QCOM_PDC is not set +CONFIG_RESET_RASPBERRYPI=m +CONFIG_RESET_SCMI=y +CONFIG_RESET_SIMPLE=y +CONFIG_RESET_SUNXI=y +# CONFIG_RESET_TI_SCI is not set +# CONFIG_RESET_TI_SYSCON is not set +# CONFIG_RESET_TI_TPS380X is not set +CONFIG_COMMON_RESET_HI3660=y +CONFIG_COMMON_RESET_HI6220=y + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PHY_MIPI_DPHY=y +# CONFIG_PHY_XGENE is not set +# CONFIG_PHY_CAN_TRANSCEIVER is not set +# CONFIG_PHY_SUN6I_MIPI_DPHY is not set +# CONFIG_PHY_SUN9I_USB is not set +# CONFIG_PHY_SUN50I_USB3 is not set +CONFIG_PHY_MESON8B_USB2=y +CONFIG_PHY_MESON_GXL_USB2=y +CONFIG_PHY_MESON_G12A_MIPI_DPHY_ANALOG=y +CONFIG_PHY_MESON_G12A_USB2=y +CONFIG_PHY_MESON_G12A_USB3_PCIE=y +CONFIG_PHY_MESON_AXG_PCIE=y +CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG=y +CONFIG_PHY_MESON_AXG_MIPI_DPHY=y + +# +# PHY drivers for Broadcom platforms +# +# CONFIG_BCM_KONA_USB2_PHY is not set +# end of PHY drivers for Broadcom platforms + +# CONFIG_PHY_CADENCE_TORRENT is not set +# CONFIG_PHY_CADENCE_DPHY is not set +# CONFIG_PHY_CADENCE_DPHY_RX is not set +# CONFIG_PHY_CADENCE_SIERRA is not set +# CONFIG_PHY_CADENCE_SALVO is not set +CONFIG_PHY_FSL_IMX8MQ_USB=y +# CONFIG_PHY_MIXEL_LVDS_PHY is not set +# CONFIG_PHY_MIXEL_MIPI_DPHY is not set +# CONFIG_PHY_FSL_IMX8M_PCIE is not set +# CONFIG_PHY_FSL_LYNX_28G is not set +# CONFIG_PHY_HI6220_USB is not set +# CONFIG_PHY_HI3660_USB is not set +# CONFIG_PHY_HI3670_USB is not set +# CONFIG_PHY_HI3670_PCIE is not set +# CONFIG_PHY_HISTB_COMBPHY is not set +# CONFIG_PHY_HISI_INNO_USB2 is not set +CONFIG_PHY_MVEBU_A3700_COMPHY=y +CONFIG_PHY_MVEBU_A3700_UTMI=y +# CONFIG_PHY_MVEBU_A38X_COMPHY is not set +# CONFIG_PHY_MVEBU_CP110_COMPHY is not set +# CONFIG_PHY_MVEBU_CP110_UTMI is not set +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_PHY_LAN966X_SERDES is not set +# CONFIG_PHY_MAPPHONE_MDM6600 is not set +# CONFIG_PHY_OCELOT_SERDES is not set +# CONFIG_PHY_QCOM_APQ8064_SATA is not set +# CONFIG_PHY_QCOM_EDP is not set +# CONFIG_PHY_QCOM_IPQ4019_USB is not set +# CONFIG_PHY_QCOM_IPQ806X_SATA is not set +# CONFIG_PHY_QCOM_PCIE2 is not set +# CONFIG_PHY_QCOM_QMP is not set +# CONFIG_PHY_QCOM_QUSB2 is not set +# CONFIG_PHY_QCOM_SNPS_EUSB2 is not set +# CONFIG_PHY_QCOM_EUSB2_REPEATER is not set +# CONFIG_PHY_QCOM_M31_USB is not set +# CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2 is not set +# CONFIG_PHY_QCOM_USB_HS_28NM is not set +# CONFIG_PHY_QCOM_USB_SS is not set +# CONFIG_PHY_QCOM_IPQ806X_USB is not set +# CONFIG_PHY_QCOM_SGMII_ETH is not set +# CONFIG_PHY_R8A779F0_ETHERNET_SERDES is not set +# CONFIG_PHY_RCAR_GEN2 is not set +# CONFIG_PHY_RCAR_GEN3_PCIE is not set +# CONFIG_PHY_RCAR_GEN3_USB2 is not set +# CONFIG_PHY_RCAR_GEN3_USB3 is not set +# CONFIG_PHY_ROCKCHIP_DP is not set +# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set +# CONFIG_PHY_ROCKCHIP_EMMC is not set +# CONFIG_PHY_ROCKCHIP_INNO_HDMI is not set +# CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY is not set +# CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY is not set +# CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY is not set +# CONFIG_PHY_ROCKCHIP_PCIE is not set +# CONFIG_PHY_ROCKCHIP_SNPS_PCIE3 is not set +# CONFIG_PHY_ROCKCHIP_TYPEC is not set +# CONFIG_PHY_ROCKCHIP_USB is not set +# CONFIG_PHY_TEGRA_XUSB is not set +# CONFIG_PHY_AM654_SERDES is not set +# CONFIG_PHY_J721E_WIZ is not set +# CONFIG_OMAP_USB2 is not set +# end of PHY Subsystem + +CONFIG_POWERCAP=y +# CONFIG_IDLE_INJECT is not set +# CONFIG_ARM_SCMI_POWERCAP is not set +# CONFIG_DTPM is not set +# CONFIG_MCB is not set + +# +# Performance monitor support +# +# CONFIG_ARM_CCI_PMU is not set +# CONFIG_ARM_CCN is not set +# CONFIG_ARM_CMN is not set +CONFIG_ARM_PMU=y +CONFIG_ARM_PMU_ACPI=y +# CONFIG_ARM_SMMU_V3_PMU is not set +CONFIG_ARM_PMUV3=y +# CONFIG_ARM_DSU_PMU is not set +# CONFIG_FSL_IMX8_DDR_PMU is not set +# CONFIG_FSL_IMX9_DDR_PMU is not set +# CONFIG_QCOM_L2_PMU is not set +# CONFIG_QCOM_L3_PMU is not set +CONFIG_THUNDERX2_PMU=m +# CONFIG_XGENE_PMU is not set +# CONFIG_ARM_SPE_PMU is not set +# CONFIG_ARM_DMC620_PMU is not set +# CONFIG_MARVELL_CN10K_TAD_PMU is not set +# CONFIG_ALIBABA_UNCORE_DRW_PMU is not set +# CONFIG_HISI_PMU is not set +# CONFIG_HISI_PCIE_PMU is not set +# CONFIG_HNS3_PMU is not set +# CONFIG_MARVELL_CN10K_DDR_PMU is not set +# CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU is not set +# CONFIG_MESON_DDR_PMU is not set +# end of Performance monitor support + +CONFIG_RAS=y +CONFIG_USB4=m +CONFIG_USB4_NET=m + +# +# Android +# +# CONFIG_ANDROID_BINDER_IPC is not set +# end of Android + +CONFIG_LIBNVDIMM=m +CONFIG_BLK_DEV_PMEM=m +CONFIG_ND_CLAIM=y +CONFIG_ND_BTT=m +CONFIG_BTT=y +CONFIG_OF_PMEM=m +CONFIG_DAX=y +# CONFIG_DEV_DAX is not set +CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y + +# +# Layout Types +# +# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set +# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set +# end of Layout Types + +# CONFIG_NVMEM_IMX_IIM is not set +# CONFIG_NVMEM_IMX_OCOTP is not set +# CONFIG_NVMEM_IMX_OCOTP_ELE is not set +# CONFIG_NVMEM_LAYERSCAPE_SFP is not set +# CONFIG_NVMEM_MESON_EFUSE is not set +# CONFIG_NVMEM_MESON_MX_EFUSE is not set +# CONFIG_NVMEM_QCOM_QFPROM is not set +# CONFIG_NVMEM_QCOM_SEC_QFPROM is not set +# CONFIG_NVMEM_RMEM is not set +# CONFIG_NVMEM_ROCKCHIP_EFUSE is not set +# CONFIG_NVMEM_ROCKCHIP_OTP is not set +# CONFIG_NVMEM_SNVS_LPGPR is not set +# CONFIG_NVMEM_SUNXI_SID is not set + +# +# HW tracing support +# +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set +# CONFIG_HISI_PTT is not set +# end of HW tracing support + +# CONFIG_FPGA is not set +# CONFIG_FSI is not set +# CONFIG_TEE is not set +CONFIG_PM_OPP=y +# CONFIG_SIOX is not set +# CONFIG_SLIMBUS is not set +# CONFIG_INTERCONNECT is not set +# CONFIG_COUNTER is not set +# CONFIG_MOST is not set +# CONFIG_PECI is not set +# CONFIG_HTE is not set +# CONFIG_CDX_BUS is not set +# end of Device Drivers + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +# CONFIG_VALIDATE_FS_PARSER is not set +CONFIG_FS_IOMAP=y +CONFIG_BUFFER_HEAD=y +CONFIG_LEGACY_DIRECT_IO=y +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=m +CONFIG_EXT4_USE_FOR_EXT2=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=m +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_F2FS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +# CONFIG_EXPORTFS_BLOCK_OPS is not set +CONFIG_FILE_LOCKING=y +# CONFIG_FS_ENCRYPTION is not set +# CONFIG_FS_VERITY is not set +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=m +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_VIRTIO_FS=m +CONFIG_OVERLAY_FS=m +# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set +CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y +# CONFIG_OVERLAY_FS_INDEX is not set +# CONFIG_OVERLAY_FS_XINO_AUTO is not set +# CONFIG_OVERLAY_FS_METACOPY is not set +# CONFIG_OVERLAY_FS_DEBUG is not set + +# +# Caches +# +CONFIG_NETFS_SUPPORT=m +CONFIG_NETFS_STATS=y +CONFIG_FSCACHE=m +CONFIG_FSCACHE_STATS=y +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_CACHEFILES is not set +# end of Caches + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +# end of CD-ROM/DVD Filesystems + +# +# DOS/FAT/EXFAT/NT Filesystems +# +CONFIG_FAT_FS=m +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_FAT_DEFAULT_UTF8=y +CONFIG_EXFAT_FS=m +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS3_FS is not set +# end of DOS/FAT/EXFAT/NT Filesystems + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PROC_CHILDREN=y +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_TMPFS_INODE64 is not set +# CONFIG_TMPFS_QUOTA is not set +CONFIG_ARCH_SUPPORTS_HUGETLBFS=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_ARCH_HAS_GIGANTIC_PAGE=y +CONFIG_CONFIGFS_FS=m +CONFIG_EFIVAR_FS=m +# end of Pseudo filesystems + +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ORANGEFS_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_FILE_CACHE=y +# CONFIG_SQUASHFS_FILE_DIRECT is not set +CONFIG_SQUASHFS_DECOMP_SINGLE=y +# CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT is not set +CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE=y +# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI is not set +# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU is not set +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_ZSTD=y +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_PSTORE=y +CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 +CONFIG_PSTORE_COMPRESS=y +# CONFIG_PSTORE_CONSOLE is not set +# CONFIG_PSTORE_PMSG is not set +# CONFIG_PSTORE_RAM is not set +# CONFIG_PSTORE_BLK is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_EROFS_FS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set +# CONFIG_UNICODE is not set +CONFIG_IO_WQ=y +# end of File systems + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_REQUEST_CACHE is not set +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_TRUSTED_KEYS is not set +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_KEY_DH_OPERATIONS is not set +CONFIG_SECURITY_DMESG_RESTRICT=y +# CONFIG_SECURITY is not set +CONFIG_SECURITYFS=y +CONFIG_HARDENED_USERCOPY=y +CONFIG_FORTIFY_SOURCE=y +# CONFIG_STATIC_USERMODEHELPER is not set +# CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" + +# +# Kernel hardening options +# + +# +# Memory initialization +# +CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y +CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y +CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y +CONFIG_INIT_STACK_NONE=y +# CONFIG_INIT_STACK_ALL_PATTERN is not set +# CONFIG_INIT_STACK_ALL_ZERO is not set +# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y +# CONFIG_ZERO_CALL_USED_REGS is not set +# end of Memory initialization + +# +# Hardening of kernel data structures +# +CONFIG_LIST_HARDENED=y +CONFIG_BUG_ON_DATA_CORRUPTION=y +# end of Hardening of kernel data structures + +CONFIG_RANDSTRUCT_NONE=y +# end of Kernel hardening options +# end of Security options + +CONFIG_XOR_BLOCKS=y +CONFIG_ASYNC_CORE=y +CONFIG_ASYNC_MEMCPY=y +CONFIG_ASYNC_XOR=y +CONFIG_ASYNC_PQ=y +CONFIG_ASYNC_RAID6_RECOV=y +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_SIG2=y +CONFIG_CRYPTO_SKCIPHER=y +CONFIG_CRYPTO_SKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=m +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_AKCIPHER=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_KPP=m +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_PCRYPT=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_ENGINE=m +# end of Crypto core or helper + +# +# Public-key cryptography +# +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_DH=m +# CONFIG_CRYPTO_DH_RFC7919_GROUPS is not set +CONFIG_CRYPTO_ECC=m +CONFIG_CRYPTO_ECDH=m +CONFIG_CRYPTO_ECDSA=m +CONFIG_CRYPTO_ECRDSA=m +# CONFIG_CRYPTO_SM2 is not set +# CONFIG_CRYPTO_CURVE25519 is not set +# end of Public-key cryptography + +# +# Block ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_AES_TI=m +CONFIG_CRYPTO_ANUBIS=m +# CONFIG_CRYPTO_ARIA is not set +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_BLOWFISH_COMMON=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST_COMMON=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +# CONFIG_CRYPTO_SM4_GENERIC is not set +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +# end of Block ciphers + +# +# Length-preserving ciphers and modes +# +CONFIG_CRYPTO_ADIANTUM=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_CHACHA20=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CFB=m +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_HCTR2 is not set +CONFIG_CRYPTO_KEYWRAP=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_OFB=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_NHPOLY1305=m +# end of Length-preserving ciphers and modes + +# +# AEAD (authenticated encryption with associated data) ciphers +# +CONFIG_CRYPTO_AEGIS128=m +CONFIG_CRYPTO_AEGIS128_SIMD=y +CONFIG_CRYPTO_CHACHA20POLY1305=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=y +CONFIG_CRYPTO_GENIV=m +CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_ECHAINIV=m +CONFIG_CRYPTO_ESSIV=y +# end of AEAD (authenticated encryption with associated data) ciphers + +# +# Hashes, digests, and MACs +# +# CONFIG_CRYPTO_BLAKE2B is not set +CONFIG_CRYPTO_CMAC=m +CONFIG_CRYPTO_GHASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_POLYVAL=m +CONFIG_CRYPTO_POLY1305=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_SHA3=m +# CONFIG_CRYPTO_SM3_GENERIC is not set +CONFIG_CRYPTO_STREEBOG=m +CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XXHASH=m +# end of Hashes, digests, and MACs + +# +# CRCs (cyclic redundancy checks) +# +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC32=m +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_CRC64_ROCKSOFT=y +# end of CRCs (cyclic redundancy checks) + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_842=m +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m +CONFIG_CRYPTO_ZSTD=m +# end of Compression + +# +# Random number generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_DRBG_MENU=m +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=m +CONFIG_CRYPTO_JITTERENTROPY=m +# CONFIG_CRYPTO_JITTERENTROPY_TESTINTERFACE is not set +# end of Random number generation + +# +# Userspace interface +# +CONFIG_CRYPTO_USER_API=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set +CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y +CONFIG_CRYPTO_STATS=y +# end of Userspace interface + +CONFIG_CRYPTO_HASH_INFO=y +# CONFIG_CRYPTO_NHPOLY1305_NEON is not set +CONFIG_CRYPTO_CHACHA20_NEON=m + +# +# Accelerated Cryptographic Algorithms for CPU (arm64) +# +CONFIG_CRYPTO_GHASH_ARM64_CE=m +CONFIG_CRYPTO_POLY1305_NEON=m +CONFIG_CRYPTO_SHA1_ARM64_CE=m +CONFIG_CRYPTO_SHA256_ARM64=m +CONFIG_CRYPTO_SHA2_ARM64_CE=m +CONFIG_CRYPTO_SHA512_ARM64=m +CONFIG_CRYPTO_SHA512_ARM64_CE=m +CONFIG_CRYPTO_SHA3_ARM64=m +# CONFIG_CRYPTO_SM3_NEON is not set +# CONFIG_CRYPTO_SM3_ARM64_CE is not set +CONFIG_CRYPTO_POLYVAL_ARM64_CE=m +# CONFIG_CRYPTO_AES_ARM64 is not set +CONFIG_CRYPTO_AES_ARM64_CE=m +CONFIG_CRYPTO_AES_ARM64_CE_BLK=m +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=m +CONFIG_CRYPTO_AES_ARM64_BS=m +# CONFIG_CRYPTO_SM4_ARM64_CE is not set +# CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set +# CONFIG_CRYPTO_SM4_ARM64_NEON_BLK is not set +CONFIG_CRYPTO_AES_ARM64_CE_CCM=m +# CONFIG_CRYPTO_SM4_ARM64_CE_CCM is not set +# CONFIG_CRYPTO_SM4_ARM64_CE_GCM is not set +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m +# end of Accelerated Cryptographic Algorithms for CPU (arm64) + +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_DEV_ALLWINNER=y +# CONFIG_CRYPTO_DEV_SUN4I_SS is not set +CONFIG_CRYPTO_DEV_SUN8I_CE=m +# CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG is not set +# CONFIG_CRYPTO_DEV_SUN8I_CE_HASH is not set +# CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG is not set +# CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG is not set +# CONFIG_CRYPTO_DEV_SUN8I_SS is not set +CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON=m +CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC=m +CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC=m +CONFIG_CRYPTO_DEV_FSL_CAAM=m +# CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG is not set +CONFIG_CRYPTO_DEV_FSL_CAAM_JR=m +CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9 +# CONFIG_CRYPTO_DEV_FSL_CAAM_INTC is not set +CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y +CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y +CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y +CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y +CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API=y +# CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_TEST is not set +# CONFIG_CRYPTO_DEV_SAHARA is not set +# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set +# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set +# CONFIG_CRYPTO_DEV_CCP is not set +# CONFIG_CRYPTO_DEV_MXS_DCP is not set +CONFIG_CRYPTO_DEV_CPT=m +CONFIG_CAVIUM_CPT=m +CONFIG_CRYPTO_DEV_NITROX=m +CONFIG_CRYPTO_DEV_NITROX_CNN55XX=m +CONFIG_CRYPTO_DEV_MARVELL=m +CONFIG_CRYPTO_DEV_MARVELL_CESA=m +# CONFIG_CRYPTO_DEV_OCTEONTX_CPT is not set +# CONFIG_CRYPTO_DEV_OCTEONTX2_CPT is not set +# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set +# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set +# CONFIG_CRYPTO_DEV_QAT_C62X is not set +# CONFIG_CRYPTO_DEV_QAT_4XXX is not set +# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set +# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set +# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set +# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set +CONFIG_CRYPTO_DEV_QCE=m +CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y +CONFIG_CRYPTO_DEV_QCE_SHA=y +CONFIG_CRYPTO_DEV_QCE_AEAD=y +CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y +# CONFIG_CRYPTO_DEV_QCE_ENABLE_SKCIPHER is not set +# CONFIG_CRYPTO_DEV_QCE_ENABLE_SHA is not set +# CONFIG_CRYPTO_DEV_QCE_ENABLE_AEAD is not set +CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512 +CONFIG_CRYPTO_DEV_QCOM_RNG=m +CONFIG_CRYPTO_DEV_ROCKCHIP=m +# CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG is not set +CONFIG_CRYPTO_DEV_CHELSIO=m +CONFIG_CRYPTO_DEV_VIRTIO=m +# CONFIG_CRYPTO_DEV_SAFEXCEL is not set +# CONFIG_CRYPTO_DEV_CCREE is not set +# CONFIG_CRYPTO_DEV_HISI_SEC is not set +# CONFIG_CRYPTO_DEV_HISI_SEC2 is not set +# CONFIG_CRYPTO_DEV_HISI_ZIP is not set +# CONFIG_CRYPTO_DEV_HISI_HPRE is not set +# CONFIG_CRYPTO_DEV_HISI_TRNG is not set +# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set +# CONFIG_CRYPTO_DEV_SA2UL is not set +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_X509_CERTIFICATE_PARSER=y +# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS7_TEST_KEY is not set +CONFIG_SIGNED_PE_FILE_VERIFICATION=y +# CONFIG_FIPS_SIGNATURE_SELFTEST is not set + +# +# Certificates for signature checking +# +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_SYSTEM_TRUSTED_KEYS="" +# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set +# CONFIG_SECONDARY_TRUSTED_KEYRING is not set +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set +# end of Certificates for signature checking + +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=y +CONFIG_RAID6_PQ_BENCHMARK=y +CONFIG_LINEAR_RANGES=y +# CONFIG_PACKING is not set +CONFIG_BITREVERSE=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_CORDIC=m +# CONFIG_PRIME_NUMBERS is not set +CONFIG_RATIONAL=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_HAS_FAST_MULTIPLIER=y +CONFIG_ARCH_USE_SYM_ANNOTATIONS=y +CONFIG_INDIRECT_PIO=y +# CONFIG_TRACE_MMIO_ACCESS is not set + +# +# Crypto library routines +# +CONFIG_CRYPTO_LIB_UTILS=y +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_ARC4=m +CONFIG_CRYPTO_LIB_GF128MUL=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m +CONFIG_CRYPTO_LIB_CHACHA=m +CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m +CONFIG_CRYPTO_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_DES=m +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m +CONFIG_CRYPTO_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y +# end of Crypto library routines + +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC_T10DIF=y +CONFIG_CRC64_ROCKSOFT=y +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +CONFIG_CRC64=y +# CONFIG_CRC4 is not set +CONFIG_CRC7=m +CONFIG_LIBCRC32C=y +CONFIG_CRC8=m +CONFIG_XXHASH=y +CONFIG_AUDIT_GENERIC=y +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +CONFIG_AUDIT_COMPAT_GENERIC=y +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_842_COMPRESS=m +CONFIG_842_DECOMPRESS=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_COMPRESS=m +CONFIG_LZ4HC_COMPRESS=m +CONFIG_LZ4_DECOMPRESS=m +CONFIG_ZSTD_COMMON=y +CONFIG_ZSTD_COMPRESS=m +CONFIG_ZSTD_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_ARM is not set +# CONFIG_XZ_DEC_ARMTHUMB is not set +# CONFIG_XZ_DEC_SPARC is not set +# CONFIG_XZ_DEC_MICROLZMA is not set +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_ZSTD=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_BTREE=y +CONFIG_INTERVAL_TREE=y +CONFIG_XARRAY_MULTI=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_DMA_OPS=y +CONFIG_NEED_SG_DMA_FLAGS=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_DMA_DECLARE_COHERENT=y +CONFIG_ARCH_HAS_SETUP_DMA_OPS=y +CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y +CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y +CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y +CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y +CONFIG_SWIOTLB=y +# CONFIG_SWIOTLB_DYNAMIC is not set +CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y +# CONFIG_DMA_RESTRICTED_POOL is not set +CONFIG_DMA_NONCOHERENT_MMAP=y +CONFIG_DMA_COHERENT_POOL=y +CONFIG_DMA_DIRECT_REMAP=y +# CONFIG_DMA_CMA is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_DMA_MAP_BENCHMARK is not set +CONFIG_SGL_ALLOC=y +CONFIG_CHECK_SIGNATURE=y +# CONFIG_FORCE_NR_CPUS is not set +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_GLOB=y +# CONFIG_GLOB_SELFTEST is not set +CONFIG_NLATTR=y +CONFIG_CLZ_TAB=y +CONFIG_IRQ_POLL=y +CONFIG_MPILIB=y +CONFIG_DIMLIB=y +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=y +CONFIG_UCS2_STRING=y +CONFIG_HAVE_GENERIC_VDSO=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_VDSO_TIME_NS=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_SG_POOL=y +CONFIG_ARCH_HAS_PMEM_API=y +CONFIG_MEMREGION=y +CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y +CONFIG_ARCH_STACKWALK=y +CONFIG_STACKDEPOT=y +CONFIG_SBITMAP=y +CONFIG_PARMAN=m +CONFIG_OBJAGG=m +# end of Library routines + +CONFIG_GENERIC_IOREMAP=y +CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y +CONFIG_PLDMFW=y + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_CALLER is not set +# CONFIG_STACKTRACE_BUILD_ID is not set +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 +CONFIG_CONSOLE_LOGLEVEL_QUIET=4 +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +CONFIG_BOOT_PRINTK_DELAY=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DYNAMIC_DEBUG_CORE=y +CONFIG_SYMBOLIC_ERRNAME=y +CONFIG_DEBUG_BUGVERBOSE=y +# end of printk and dmesg options + +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_MISC=y + +# +# Compile-time checks and compiler options +# +CONFIG_AS_HAS_NON_CONST_LEB128=y +CONFIG_DEBUG_INFO_NONE=y +# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +# CONFIG_DEBUG_INFO_DWARF5 is not set +CONFIG_FRAME_WARN=2048 +CONFIG_STRIP_ASM_SYMS=y +# CONFIG_READABLE_ASM is not set +# CONFIG_HEADERS_INSTALL is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_FRAME_POINTER=y +# CONFIG_VMLINUX_MAP is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# end of Compile-time checks and compiler options + +# +# Generic Kernel Debugging Instruments +# +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x01b6 +CONFIG_MAGIC_SYSRQ_SERIAL=y +CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_FS_ALLOW_ALL=y +# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set +# CONFIG_DEBUG_FS_ALLOW_NONE is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y +# CONFIG_UBSAN is not set +CONFIG_HAVE_ARCH_KCSAN=y +CONFIG_HAVE_KCSAN_COMPILER=y +# CONFIG_KCSAN is not set +# end of Generic Kernel Debugging Instruments + +# +# Networking Debugging +# +# CONFIG_NET_DEV_REFCNT_TRACKER is not set +# CONFIG_NET_NS_REFCNT_TRACKER is not set +# CONFIG_DEBUG_NET is not set +# end of Networking Debugging + +# +# Memory Debugging +# +CONFIG_PAGE_EXTENSION=y +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_PAGE_OWNER is not set +# CONFIG_PAGE_TABLE_CHECK is not set +CONFIG_PAGE_POISONING=y +# CONFIG_DEBUG_PAGE_REF is not set +# CONFIG_DEBUG_RODATA_TEST is not set +CONFIG_ARCH_HAS_DEBUG_WX=y +CONFIG_DEBUG_WX=y +CONFIG_GENERIC_PTDUMP=y +CONFIG_PTDUMP_CORE=y +# CONFIG_PTDUMP_DEBUGFS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_PER_VMA_LOCK_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SHRINKER_DEBUG is not set +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_SCHED_STACK_END_CHECK=y +CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VM_PGTABLE is not set +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_HAVE_ARCH_KASAN=y +CONFIG_HAVE_ARCH_KASAN_SW_TAGS=y +CONFIG_HAVE_ARCH_KASAN_HW_TAGS=y +CONFIG_HAVE_ARCH_KASAN_VMALLOC=y +CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_CC_HAS_KASAN_SW_TAGS=y +CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y +# CONFIG_KASAN is not set +CONFIG_HAVE_ARCH_KFENCE=y +# CONFIG_KFENCE is not set +# end of Memory Debugging + +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Oops, Lockups and Hangs +# +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_HAVE_HARDLOCKUP_DETECTOR_BUDDY=y +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_HARDLOCKUP_DETECTOR_PERF is not set +CONFIG_HARDLOCKUP_DETECTOR_BUDDY=y +# CONFIG_HARDLOCKUP_DETECTOR_ARCH is not set +CONFIG_HARDLOCKUP_DETECTOR_COUNTS_HRTIMER=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +# CONFIG_WQ_WATCHDOG is not set +# CONFIG_WQ_CPU_INTENSIVE_REPORT is not set +# CONFIG_TEST_LOCKUP is not set +# end of Debug Oops, Lockups and Hangs + +# +# Scheduler Debugging +# +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_INFO=y +CONFIG_SCHEDSTATS=y +# end of Scheduler Debugging + +# CONFIG_DEBUG_TIMEKEEPING is not set +CONFIG_DEBUG_PREEMPT=y + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +CONFIG_LOCK_DEBUGGING_SUPPORT=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +# CONFIG_WW_MUTEX_SELFTEST is not set +# CONFIG_SCF_TORTURE_TEST is not set +# CONFIG_CSD_LOCK_WAIT_DEBUG is not set +# end of Lock Debugging (spinlocks, mutexes, etc...) + +# CONFIG_DEBUG_IRQFLAGS is not set +CONFIG_STACKTRACE=y +# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set +# CONFIG_DEBUG_KOBJECT is not set + +# +# Debug kernel data structures +# +CONFIG_DEBUG_LIST=y +# CONFIG_DEBUG_PLIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_MAPLE_TREE is not set +# end of Debug kernel data structures + +# +# RCU Debugging +# +# CONFIG_RCU_SCALE_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_REF_SCALE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 +# CONFIG_RCU_CPU_STALL_CPUTIME is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# end of RCU Debugging + +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_LATENCYTOP is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_RETVAL=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_BOOTTIME_TRACING is not set +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_HWLAT_TRACER is not set +# CONFIG_OSNOISE_TRACER is not set +# CONFIG_TIMERLAT_TRACER is not set +# CONFIG_FTRACE_SYSCALLS is not set +# CONFIG_TRACER_SNAPSHOT is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_UPROBE_EVENTS=y +CONFIG_BPF_EVENTS=y +CONFIG_DYNAMIC_EVENTS=y +CONFIG_PROBE_EVENTS=y +# CONFIG_SYNTH_EVENTS is not set +# CONFIG_USER_EVENTS is not set +# CONFIG_HIST_TRIGGERS is not set +# CONFIG_TRACE_EVENT_INJECT is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_TRACE_EVAL_MAP_FILE is not set +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set +# CONFIG_PREEMPTIRQ_DELAY_TEST is not set +# CONFIG_RV is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y +CONFIG_STRICT_DEVMEM=y +CONFIG_IO_STRICT_DEVMEM=y + +# +# arm64 Debugging +# +CONFIG_PID_IN_CONTEXTIDR=y +# CONFIG_ARM64_RELOC_TEST is not set +CONFIG_CORESIGHT=m +CONFIG_CORESIGHT_LINKS_AND_SINKS=m +# CONFIG_CORESIGHT_LINK_AND_SINK_TMC is not set +# CONFIG_CORESIGHT_SINK_TPIU is not set +# CONFIG_CORESIGHT_SINK_ETBV10 is not set +CONFIG_CORESIGHT_SOURCE_ETM4X=m +# CONFIG_ETM4X_IMPDEF_FEATURE is not set +# CONFIG_CORESIGHT_STM is not set +# CONFIG_CORESIGHT_CPU_DEBUG is not set +# CONFIG_CORESIGHT_CTI is not set +CONFIG_CORESIGHT_TRBE=m +# CONFIG_ULTRASOC_SMB is not set +# CONFIG_CORESIGHT_TPDM is not set +# CONFIG_CORESIGHT_TPDA is not set +# CONFIG_CORESIGHT_DUMMY is not set +# end of arm64 Debugging + +# +# Kernel Testing and Coverage +# +# CONFIG_KUNIT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_ARCH_HAS_KCOV=y +CONFIG_CC_HAS_SANCOV_TRACE_PC=y +# CONFIG_KCOV is not set +# CONFIG_RUNTIME_TESTING_MENU is not set +CONFIG_ARCH_USE_MEMTEST=y +# CONFIG_MEMTEST is not set +# CONFIG_HYPERV_TESTING is not set +# end of Kernel Testing and Coverage + +# +# Rust hacking +# +# end of Rust hacking +# end of Kernel hacking diff --git a/scripts/package-build/linux-kernel/arch/x86/configs/vyos_defconfig b/scripts/package-build/linux-kernel/arch/x86/configs/vyos_defconfig new file mode 100644 index 00000000..de3b84aa --- /dev/null +++ b/scripts/package-build/linux-kernel/arch/x86/configs/vyos_defconfig @@ -0,0 +1,6396 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/x86 6.6.89 Kernel Configuration +# +CONFIG_CC_VERSION_TEXT="gcc (Debian 12.2.0-14) 12.2.0" +CONFIG_CC_IS_GCC=y +CONFIG_GCC_VERSION=120200 +CONFIG_CLANG_VERSION=0 +CONFIG_AS_IS_GNU=y +CONFIG_AS_VERSION=24000 +CONFIG_LD_IS_BFD=y +CONFIG_LD_VERSION=24000 +CONFIG_LLD_VERSION=0 +CONFIG_CC_CAN_LINK=y +CONFIG_CC_CAN_LINK_STATIC=y +CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y +CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y +CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y +CONFIG_TOOLS_SUPPORT_RELR=y +CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y +CONFIG_PAHOLE_VERSION=124 +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_TABLE_SORT=y +CONFIG_THREAD_INFO_IN_TASK=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +# CONFIG_COMPILE_TEST is not set +# CONFIG_WERROR is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_BUILD_SALT="" +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_HAVE_KERNEL_ZSTD=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +CONFIG_KERNEL_XZ=y +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +# CONFIG_KERNEL_ZSTD is not set +CONFIG_DEFAULT_INIT="" +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_WATCH_QUEUE is not set +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_USELIB=y +CONFIG_AUDIT=y +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +CONFIG_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_GENERIC_IRQ_INJECTION=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_IRQ_MSI_IOMMU=y +CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y +CONFIG_GENERIC_IRQ_RESERVATION_MODE=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +# CONFIG_GENERIC_IRQ_DEBUGFS is not set +# end of IRQ subsystem + +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_ARCH_CLOCKSOURCE_INIT=y +CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100 +# end of Timers subsystem + +CONFIG_BPF=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y + +# +# BPF subsystem +# +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +# CONFIG_BPF_JIT_ALWAYS_ON is not set +CONFIG_BPF_JIT_DEFAULT_ON=y +# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set +# CONFIG_BPF_PRELOAD is not set +# CONFIG_BPF_LSM is not set +# end of BPF subsystem + +CONFIG_PREEMPT_NONE_BUILD=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_PREEMPT_DYNAMIC is not set +# CONFIG_SCHED_CORE is not set + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_PSI is not set +# end of CPU/Task time and stats accounting + +CONFIG_CPU_ISOLATION=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_RCU_EXPERT is not set +CONFIG_TREE_SRCU=y +CONFIG_TASKS_RCU_GENERIC=y +CONFIG_TASKS_TRACE_RCU=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_NEED_SEGCBLIST=y +# end of RCU Subsystem + +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_IKHEADERS is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +# CONFIG_PRINTK_INDEX is not set +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y + +# +# Scheduler features +# +# CONFIG_UCLAMP_TASK is not set +# end of Scheduler features + +CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y +CONFIG_CC_HAS_INT128=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_GCC10_NO_ARRAY_BOUNDS=y +CONFIG_CC_NO_ARRAY_BOUNDS=y +CONFIG_ARCH_SUPPORTS_INT128=y +CONFIG_NUMA_BALANCING=y +CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y +CONFIG_CGROUPS=y +CONFIG_PAGE_COUNTER=y +# CONFIG_CGROUP_FAVOR_DYNMODS is not set +CONFIG_MEMCG=y +CONFIG_MEMCG_KMEM=y +# CONFIG_BLK_CGROUP is not set +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_SCHED_MM_CID=y +CONFIG_CGROUP_PIDS=y +# CONFIG_CGROUP_RDMA is not set +# CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_HUGETLB is not set +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +# CONFIG_CGROUP_DEVICE is not set +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_PERF is not set +CONFIG_CGROUP_BPF=y +# CONFIG_CGROUP_MISC is not set +# CONFIG_CGROUP_DEBUG is not set +CONFIG_SOCK_CGROUP_DATA=y +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_TIME_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_RD_ZSTD=y +# CONFIG_BOOT_CONFIG is not set +CONFIG_INITRAMFS_PRESERVE_MTIME=y +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_LD_ORPHAN_WARN=y +CONFIG_LD_ORPHAN_WARN_LEVEL="warn" +CONFIG_SYSCTL=y +CONFIG_HAVE_UID16=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_HAVE_PCSPKR_PLATFORM=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_MULTIUSER=y +CONFIG_SGETMASK_SYSCALL=y +CONFIG_SYSFS_SYSCALL=y +CONFIG_FHANDLE=y +CONFIG_POSIX_TIMERS=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_PCSPKR_PLATFORM=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_FUTEX_PI=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +# CONFIG_IO_URING is not set +CONFIG_ADVISE_SYSCALLS=y +CONFIG_MEMBARRIER=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_SELFTEST is not set +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y +CONFIG_KALLSYMS_BASE_RELATIVE=y +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +# CONFIG_KCMP is not set +CONFIG_RSEQ=y +CONFIG_CACHESTAT_SYSCALL=y +# CONFIG_DEBUG_RSEQ is not set +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_GUEST_PERF_EVENTS=y +# CONFIG_PC104 is not set + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# end of Kernel Performance Events And Counters + +CONFIG_SYSTEM_DATA_VERIFICATION=y +# CONFIG_PROFILING is not set +CONFIG_TRACEPOINTS=y + +# +# Kexec and crash features +# +CONFIG_CRASH_CORE=y +CONFIG_KEXEC_CORE=y +CONFIG_KEXEC=y +# CONFIG_KEXEC_FILE is not set +# CONFIG_CRASH_DUMP is not set +# end of Kexec and crash features +# end of General setup + +CONFIG_64BIT=y +CONFIG_X86_64=y +CONFIG_X86=y +CONFIG_INSTRUCTION_DECODER=y +CONFIG_OUTPUT_FORMAT="elf64-x86-64" +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_MMU=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=28 +CONFIG_ARCH_MMAP_RND_BITS_MAX=32 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_AUDIT_ARCH=y +CONFIG_HAVE_INTEL_TXT=y +CONFIG_X86_64_SMP=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_PGTABLE_LEVELS=4 +CONFIG_CC_HAS_SANE_STACKPROTECTOR=y + +# +# Processor type and features +# +CONFIG_SMP=y +CONFIG_X86_X2APIC=y +CONFIG_X86_MPPARSE=y +# CONFIG_GOLDFISH is not set +# CONFIG_X86_CPU_RESCTRL is not set +# CONFIG_X86_EXTENDED_PLATFORM is not set +CONFIG_X86_INTEL_LPSS=y +CONFIG_X86_AMD_PLATFORM_DEVICE=y +CONFIG_IOSF_MBI=y +# CONFIG_IOSF_MBI_DEBUG is not set +CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_HYPERVISOR_GUEST=y +CONFIG_PARAVIRT=y +CONFIG_PARAVIRT_XXL=y +# CONFIG_PARAVIRT_DEBUG is not set +CONFIG_PARAVIRT_SPINLOCKS=y +CONFIG_X86_HV_CALLBACK_VECTOR=y +CONFIG_XEN=y +CONFIG_XEN_PV=y +CONFIG_XEN_512GB=y +CONFIG_XEN_PV_SMP=y +CONFIG_XEN_PV_DOM0=y +CONFIG_XEN_PVHVM=y +CONFIG_XEN_PVHVM_SMP=y +CONFIG_XEN_PVHVM_GUEST=y +CONFIG_XEN_SAVE_RESTORE=y +# CONFIG_XEN_DEBUG_FS is not set +CONFIG_XEN_PVH=y +CONFIG_XEN_DOM0=y +CONFIG_XEN_PV_MSR_SAFE=y +CONFIG_KVM_GUEST=y +CONFIG_ARCH_CPUIDLE_HALTPOLL=y +CONFIG_PVH=y +# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set +CONFIG_PARAVIRT_CLOCK=y +# CONFIG_JAILHOUSE_GUEST is not set +# CONFIG_ACRN_GUEST is not set +# CONFIG_INTEL_TDX_GUEST is not set +# CONFIG_MK8 is not set +# CONFIG_MPSC is not set +# CONFIG_MCORE2 is not set +# CONFIG_MATOM is not set +CONFIG_GENERIC_CPU=y +CONFIG_X86_INTERNODE_CACHE_SHIFT=6 +CONFIG_X86_L1_CACHE_SHIFT=6 +CONFIG_X86_TSC=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_CMOV=y +CONFIG_X86_MINIMUM_CPU_FAMILY=64 +CONFIG_X86_DEBUGCTLMSR=y +CONFIG_IA32_FEAT_CTL=y +CONFIG_X86_VMX_FEATURE_NAMES=y +# CONFIG_PROCESSOR_SELECT is not set +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_HYGON=y +CONFIG_CPU_SUP_CENTAUR=y +CONFIG_CPU_SUP_ZHAOXIN=y +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_DMI=y +CONFIG_GART_IOMMU=y +CONFIG_BOOT_VESA_SUPPORT=y +# CONFIG_MAXSMP is not set +CONFIG_NR_CPUS_RANGE_BEGIN=2 +CONFIG_NR_CPUS_RANGE_END=512 +CONFIG_NR_CPUS_DEFAULT=64 +CONFIG_NR_CPUS=256 +CONFIG_SCHED_CLUSTER=y +CONFIG_SCHED_SMT=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_MC_PRIO=y +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y +CONFIG_X86_MCE=y +# CONFIG_X86_MCELOG_LEGACY is not set +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_AMD=y +CONFIG_X86_MCE_THRESHOLD=y +# CONFIG_X86_MCE_INJECT is not set + +# +# Performance monitoring +# +CONFIG_PERF_EVENTS_INTEL_UNCORE=m +CONFIG_PERF_EVENTS_INTEL_RAPL=m +CONFIG_PERF_EVENTS_INTEL_CSTATE=m +CONFIG_PERF_EVENTS_AMD_POWER=m +CONFIG_PERF_EVENTS_AMD_UNCORE=y +# CONFIG_PERF_EVENTS_AMD_BRS is not set +# end of Performance monitoring + +CONFIG_X86_16BIT=y +CONFIG_X86_ESPFIX64=y +CONFIG_X86_VSYSCALL_EMULATION=y +CONFIG_X86_IOPL_IOPERM=y +CONFIG_MICROCODE=y +# CONFIG_MICROCODE_LATE_LOADING is not set +CONFIG_X86_MSR=m +CONFIG_X86_CPUID=m +# CONFIG_X86_5LEVEL is not set +CONFIG_X86_DIRECT_GBPAGES=y +# CONFIG_X86_CPA_STATISTICS is not set +# CONFIG_AMD_MEM_ENCRYPT is not set +CONFIG_NUMA=y +CONFIG_AMD_NUMA=y +CONFIG_X86_64_ACPI_NUMA=y +# CONFIG_NUMA_EMU is not set +CONFIG_NODES_SHIFT=6 +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_X86_PMEM_LEGACY_DEVICE=y +CONFIG_X86_PMEM_LEGACY=m +# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set +CONFIG_MTRR=y +CONFIG_MTRR_SANITIZER=y +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 +CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 +CONFIG_X86_PAT=y +CONFIG_ARCH_USES_PG_UNCACHED=y +CONFIG_X86_UMIP=y +CONFIG_CC_HAS_IBT=y +# CONFIG_X86_KERNEL_IBT is not set +CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y +CONFIG_X86_INTEL_TSX_MODE_OFF=y +# CONFIG_X86_INTEL_TSX_MODE_ON is not set +# CONFIG_X86_INTEL_TSX_MODE_AUTO is not set +# CONFIG_X86_SGX is not set +# CONFIG_X86_USER_SHADOW_STACK is not set +CONFIG_EFI=y +CONFIG_EFI_STUB=y +CONFIG_EFI_HANDOVER_PROTOCOL=y +CONFIG_EFI_MIXED=y +# CONFIG_EFI_FAKE_MEMMAP is not set +CONFIG_EFI_RUNTIME_MAP=y +# CONFIG_HZ_100 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +CONFIG_HZ_1000=y +CONFIG_HZ=1000 +CONFIG_SCHED_HRTICK=y +CONFIG_ARCH_SUPPORTS_KEXEC=y +CONFIG_ARCH_SUPPORTS_KEXEC_FILE=y +CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY=y +CONFIG_ARCH_SUPPORTS_KEXEC_SIG=y +CONFIG_ARCH_SUPPORTS_KEXEC_SIG_FORCE=y +CONFIG_ARCH_SUPPORTS_KEXEC_BZIMAGE_VERIFY_SIG=y +CONFIG_ARCH_SUPPORTS_KEXEC_JUMP=y +CONFIG_ARCH_SUPPORTS_CRASH_DUMP=y +CONFIG_ARCH_SUPPORTS_CRASH_HOTPLUG=y +CONFIG_PHYSICAL_START=0x1000000 +CONFIG_RELOCATABLE=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_X86_NEED_RELOCS=y +CONFIG_PHYSICAL_ALIGN=0x200000 +CONFIG_DYNAMIC_MEMORY_LAYOUT=y +CONFIG_RANDOMIZE_MEMORY=y +CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0xa +CONFIG_HOTPLUG_CPU=y +# CONFIG_COMPAT_VDSO is not set +# CONFIG_LEGACY_VSYSCALL_XONLY is not set +CONFIG_LEGACY_VSYSCALL_NONE=y +# CONFIG_CMDLINE_BOOL is not set +CONFIG_MODIFY_LDT_SYSCALL=y +# CONFIG_STRICT_SIGALTSTACK_SIZE is not set +CONFIG_HAVE_LIVEPATCH=y +# end of Processor type and features + +CONFIG_CC_HAS_SLS=y +CONFIG_CC_HAS_RETURN_THUNK=y +CONFIG_CC_HAS_ENTRY_PADDING=y +CONFIG_FUNCTION_PADDING_CFI=11 +CONFIG_FUNCTION_PADDING_BYTES=16 +CONFIG_CALL_PADDING=y +CONFIG_HAVE_CALL_THUNKS=y +CONFIG_CALL_THUNKS=y +CONFIG_PREFIX_SYMBOLS=y +CONFIG_CPU_MITIGATIONS=y +CONFIG_PAGE_TABLE_ISOLATION=y +CONFIG_RETPOLINE=y +CONFIG_RETHUNK=y +CONFIG_CPU_UNRET_ENTRY=y +CONFIG_CALL_DEPTH_TRACKING=y +# CONFIG_CALL_THUNKS_DEBUG is not set +CONFIG_CPU_IBPB_ENTRY=y +CONFIG_CPU_IBRS_ENTRY=y +CONFIG_CPU_SRSO=y +# CONFIG_SLS is not set +# CONFIG_GDS_FORCE_MITIGATION is not set +CONFIG_MITIGATION_RFDS=y +CONFIG_MITIGATION_SPECTRE_BHI=y +CONFIG_ARCH_HAS_ADD_PAGES=y + +# +# Power management and ACPI options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set +CONFIG_HIBERNATE_CALLBACKS=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_USERSPACE_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_CLK=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +# CONFIG_ENERGY_MODEL is not set +CONFIG_ARCH_SUPPORTS_ACPI=y +CONFIG_ACPI=y +CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y +CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y +CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y +# CONFIG_ACPI_DEBUGGER is not set +CONFIG_ACPI_SPCR_TABLE=y +# CONFIG_ACPI_FPDT is not set +CONFIG_ACPI_LPIT=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y +# CONFIG_ACPI_EC_DEBUGFS is not set +# CONFIG_ACPI_AC is not set +# CONFIG_ACPI_BATTERY is not set +CONFIG_ACPI_BUTTON=m +# CONFIG_ACPI_TINY_POWER_BUTTON is not set +CONFIG_ACPI_FAN=m +# CONFIG_ACPI_TAD is not set +# CONFIG_ACPI_DOCK is not set +CONFIG_ACPI_CPU_FREQ_PSS=y +CONFIG_ACPI_PROCESSOR_CSTATE=y +CONFIG_ACPI_PROCESSOR_IDLE=y +CONFIG_ACPI_CPPC_LIB=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_IPMI=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_PROCESSOR_AGGREGATOR=m +CONFIG_ACPI_THERMAL=m +CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y +CONFIG_ACPI_TABLE_UPGRADE=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_PCI_SLOT=y +CONFIG_ACPI_CONTAINER=y +CONFIG_ACPI_HOTPLUG_IOAPIC=y +# CONFIG_ACPI_SBS is not set +CONFIG_ACPI_HED=y +# CONFIG_ACPI_CUSTOM_METHOD is not set +CONFIG_ACPI_BGRT=y +# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set +CONFIG_ACPI_NFIT=m +# CONFIG_NFIT_SECURITY_DEBUG is not set +CONFIG_ACPI_NUMA=y +# CONFIG_ACPI_HMAT is not set +CONFIG_HAVE_ACPI_APEI=y +CONFIG_HAVE_ACPI_APEI_NMI=y +CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_GHES=y +CONFIG_ACPI_APEI_PCIEAER=y +CONFIG_ACPI_APEI_MEMORY_FAILURE=y +# CONFIG_ACPI_APEI_EINJ is not set +# CONFIG_ACPI_APEI_ERST_DEBUG is not set +# CONFIG_ACPI_DPTF is not set +CONFIG_ACPI_EXTLOG=y +CONFIG_ACPI_ADXL=y +# CONFIG_ACPI_CONFIGFS is not set +# CONFIG_ACPI_PFRUT is not set +CONFIG_ACPI_PCC=y +# CONFIG_ACPI_FFH is not set +# CONFIG_PMIC_OPREGION is not set +CONFIG_ACPI_PRMT=y +CONFIG_X86_PM_TIMER=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y + +# +# CPU frequency scaling drivers +# +CONFIG_X86_INTEL_PSTATE=y +CONFIG_X86_PCC_CPUFREQ=m +CONFIG_X86_AMD_PSTATE=y +CONFIG_X86_AMD_PSTATE_DEFAULT_MODE=3 +# CONFIG_X86_AMD_PSTATE_UT is not set +CONFIG_X86_ACPI_CPUFREQ=m +CONFIG_X86_ACPI_CPUFREQ_CPB=y +CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_AMD_FREQ_SENSITIVITY=m +CONFIG_X86_SPEEDSTEP_CENTRINO=m +CONFIG_X86_P4_CLOCKMOD=m + +# +# shared options +# +CONFIG_X86_SPEEDSTEP_LIB=m +# end of CPU Frequency scaling + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_CPU_IDLE_GOV_TEO is not set +CONFIG_CPU_IDLE_GOV_HALTPOLL=y +CONFIG_HALTPOLL_CPUIDLE=y +# end of CPU Idle + +CONFIG_INTEL_IDLE=y +# end of Power management and ACPI options + +# +# Bus options (PCI etc.) +# +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_XEN=y +CONFIG_MMCONF_FAM10H=y +# CONFIG_PCI_CNB20LE_QUIRK is not set +# CONFIG_ISA_BUS is not set +CONFIG_ISA_DMA_API=y +CONFIG_AMD_NB=y +# end of Bus options (PCI etc.) + +# +# Binary Emulations +# +CONFIG_IA32_EMULATION=y +# CONFIG_X86_X32_ABI is not set +CONFIG_COMPAT_32=y +CONFIG_COMPAT=y +CONFIG_COMPAT_FOR_U64_ALIGNMENT=y +# end of Binary Emulations + +CONFIG_HAVE_KVM=y +# CONFIG_VIRTUALIZATION is not set +CONFIG_AS_AVX512=y +CONFIG_AS_SHA1_NI=y +CONFIG_AS_SHA256_NI=y +CONFIG_AS_TPAUSE=y +CONFIG_AS_GFNI=y +CONFIG_AS_WRUSS=y +CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS=y + +# +# General architecture-dependent options +# +CONFIG_HOTPLUG_SMT=y +CONFIG_HOTPLUG_CORE_SYNC=y +CONFIG_HOTPLUG_CORE_SYNC_DEAD=y +CONFIG_HOTPLUG_CORE_SYNC_FULL=y +CONFIG_HOTPLUG_SPLIT_STARTUP=y +CONFIG_HOTPLUG_PARALLEL=y +CONFIG_GENERIC_ENTRY=y +# CONFIG_KPROBES is not set +CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set +# CONFIG_STATIC_CALL_SELFTEST is not set +CONFIG_UPROBES=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_KPROBES_ON_FTRACE=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y +CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y +CONFIG_HAVE_NMI=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_SET_DIRECT_MAP=y +CONFIG_ARCH_HAS_CPU_FINALIZE_INIT=y +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y +CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_HAVE_ASM_MODVERSIONS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_RUST=y +CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y +CONFIG_HAVE_USER_RETURN_NOTIFIER=y +CONFIG_HAVE_PERF_EVENTS_NMI=y +CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y +CONFIG_MMU_GATHER_TABLE_FREE=y +CONFIG_MMU_GATHER_RCU_TABLE_FREE=y +CONFIG_MMU_GATHER_MERGE_VMAS=y +CONFIG_MMU_LAZY_TLB_REFCOUNT=y +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_ARCH_HAS_NMI_SAFE_THIS_CPU_OPS=y +CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y +CONFIG_HAVE_CMPXCHG_LOCAL=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y +CONFIG_HAVE_ARCH_SECCOMP=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP=y +CONFIG_SECCOMP_FILTER=y +# CONFIG_SECCOMP_CACHE_DEBUG is not set +CONFIG_HAVE_ARCH_STACKLEAK=y +CONFIG_HAVE_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR_STRONG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y +CONFIG_LTO_NONE=y +CONFIG_ARCH_SUPPORTS_CFI_CLANG=y +CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y +CONFIG_HAVE_CONTEXT_TRACKING_USER=y +CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOVE_PUD=y +CONFIG_HAVE_MOVE_PMD=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD=y +CONFIG_HAVE_ARCH_HUGE_VMAP=y +CONFIG_HAVE_ARCH_HUGE_VMALLOC=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_ARCH_WANT_PMD_MKWRITE=y +CONFIG_HAVE_ARCH_SOFT_DIRTY=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y +CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_HAVE_EXIT_THREAD=y +CONFIG_ARCH_MMAP_RND_BITS=28 +CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=8 +CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_HAVE_OBJTOOL=y +CONFIG_HAVE_JUMP_LABEL_HACK=y +CONFIG_HAVE_NOINSTR_HACK=y +CONFIG_HAVE_NOINSTR_VALIDATION=y +CONFIG_HAVE_UACCESS_VALIDATION=y +CONFIG_HAVE_STACK_VALIDATION=y +CONFIG_HAVE_RELIABLE_STACKTRACE=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_COMPAT_OLD_SIGACTION=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_HAVE_ARCH_VMAP_STACK=y +CONFIG_VMAP_STACK=y +CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y +CONFIG_RANDOMIZE_KSTACK_OFFSET=y +# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_STRICT_MODULE_RWX=y +CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y +CONFIG_ARCH_USE_MEMREMAP_PROT=y +# CONFIG_LOCK_EVENT_COUNTS is not set +CONFIG_ARCH_HAS_MEM_ENCRYPT=y +CONFIG_HAVE_STATIC_CALL=y +CONFIG_HAVE_STATIC_CALL_INLINE=y +CONFIG_HAVE_PREEMPT_DYNAMIC=y +CONFIG_HAVE_PREEMPT_DYNAMIC_CALL=y +CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y +CONFIG_ARCH_HAS_ELFCORE_COMPAT=y +CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y +CONFIG_DYNAMIC_SIGFRAME=y +CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +# end of GCOV-based kernel profiling + +CONFIG_HAVE_GCC_PLUGINS=y +CONFIG_FUNCTION_ALIGNMENT_4B=y +CONFIG_FUNCTION_ALIGNMENT_16B=y +CONFIG_FUNCTION_ALIGNMENT=16 +# end of General architecture-dependent options + +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULE_SIG_FORMAT=y +CONFIG_MODULES=y +# CONFIG_MODULE_DEBUG is not set +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set +CONFIG_MODVERSIONS=y +CONFIG_ASM_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_MODULE_SIG=y +CONFIG_MODULE_SIG_FORCE=y +CONFIG_MODULE_SIG_ALL=y +# CONFIG_MODULE_SIG_SHA1 is not set +# CONFIG_MODULE_SIG_SHA224 is not set +# CONFIG_MODULE_SIG_SHA256 is not set +# CONFIG_MODULE_SIG_SHA384 is not set +CONFIG_MODULE_SIG_SHA512=y +CONFIG_MODULE_SIG_HASH="sha512" +CONFIG_MODULE_COMPRESS_NONE=y +# CONFIG_MODULE_COMPRESS_GZIP is not set +# CONFIG_MODULE_COMPRESS_XZ is not set +# CONFIG_MODULE_COMPRESS_ZSTD is not set +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +CONFIG_MODPROBE_PATH="/sbin/modprobe" +# CONFIG_TRIM_UNUSED_KSYMS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_BLOCK_LEGACY_AUTOLOAD=y +CONFIG_BLK_DEV_BSG_COMMON=y +CONFIG_BLK_ICQ=y +CONFIG_BLK_DEV_BSGLIB=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_INTEGRITY_T10=y +# CONFIG_BLK_DEV_ZONED is not set +CONFIG_BLK_WBT=y +CONFIG_BLK_WBT_MQ=y +CONFIG_BLK_DEBUG_FS=y +CONFIG_BLK_SED_OPAL=y +# CONFIG_BLK_INLINE_ENCRYPTION is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +# end of Partition Types + +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_MQ_VIRTIO=y +CONFIG_BLK_PM=y +CONFIG_BLOCK_HOLDER_DEPRECATED=y +CONFIG_BLK_MQ_STACKING=y + +# +# IO Schedulers +# +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +CONFIG_IOSCHED_BFQ=y +# end of IO Schedulers + +CONFIG_PADATA=y +CONFIG_ASN1=y +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +CONFIG_INLINE_READ_UNLOCK=y +CONFIG_INLINE_READ_UNLOCK_IRQ=y +CONFIG_INLINE_WRITE_UNLOCK=y +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_ARCH_USE_QUEUED_RWLOCKS=y +CONFIG_QUEUED_RWLOCKS=y +CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y +CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y +CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y +CONFIG_FREEZER=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_ELFCORE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +CONFIG_BINFMT_MISC=m +CONFIG_COREDUMP=y +# end of Executable file formats + +# +# Memory Management options +# +# CONFIG_SWAP is not set + +# +# SLAB allocator options +# +# CONFIG_SLAB_DEPRECATED is not set +CONFIG_SLUB=y +# CONFIG_SLUB_TINY is not set +CONFIG_SLAB_MERGE_DEFAULT=y +CONFIG_SLAB_FREELIST_RANDOM=y +CONFIG_SLAB_FREELIST_HARDENED=y +# CONFIG_SLUB_STATS is not set +CONFIG_SLUB_CPU_PARTIAL=y +# CONFIG_RANDOM_KMALLOC_CACHES is not set +# end of SLAB allocator options + +# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP=y +CONFIG_ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP=y +CONFIG_HAVE_FAST_GUP=y +CONFIG_NUMA_KEEP_MEMINFO=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +# CONFIG_MEMORY_HOTPLUG is not set +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y +CONFIG_MEMORY_BALLOON=y +CONFIG_BALLOON_COMPACTION=y +CONFIG_COMPACTION=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 +CONFIG_PAGE_REPORTING=y +CONFIG_MIGRATION=y +CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y +CONFIG_ARCH_ENABLE_THP_MIGRATION=y +CONFIG_CONTIG_ALLOC=y +CONFIG_PCP_BATCH_SCALE_MAX=5 +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_MMU_NOTIFIER=y +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 +CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y +CONFIG_MEMORY_FAILURE=y +# CONFIG_HWPOISON_INJECT is not set +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANTS_THP_SWAP=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y +# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set +# CONFIG_READ_ONLY_THP_FOR_FS is not set +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y +CONFIG_USE_PERCPU_NUMA_NODE_ID=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set +# CONFIG_CMA_DEBUGFS is not set +# CONFIG_CMA_SYSFS is not set +CONFIG_CMA_AREAS=19 +CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y +CONFIG_ARCH_HAS_PTE_DEVMAP=y +CONFIG_ARCH_HAS_ZONE_DMA_SET=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA32=y +CONFIG_HMM_MIRROR=y +CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y +CONFIG_ARCH_HAS_PKEYS=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_PERCPU_STATS is not set +# CONFIG_GUP_TEST is not set +# CONFIG_DMAPOOL_TEST is not set +CONFIG_ARCH_HAS_PTE_SPECIAL=y +CONFIG_MEMFD_CREATE=y +CONFIG_SECRETMEM=y +# CONFIG_ANON_VMA_NAME is not set +CONFIG_USERFAULTFD=y +CONFIG_HAVE_ARCH_USERFAULTFD_WP=y +CONFIG_HAVE_ARCH_USERFAULTFD_MINOR=y +CONFIG_PTE_MARKER_UFFD_WP=y +# CONFIG_LRU_GEN is not set +CONFIG_ARCH_SUPPORTS_PER_VMA_LOCK=y +CONFIG_PER_VMA_LOCK=y +CONFIG_LOCK_MM_AND_FIND_VMA=y + +# +# Data Access Monitoring +# +# CONFIG_DAMON is not set +# end of Data Access Monitoring +# end of Memory Management options + +CONFIG_NET=y +CONFIG_COMPAT_NETLINK_MESSAGES=y +CONFIG_NET_INGRESS=y +CONFIG_NET_EGRESS=y +CONFIG_NET_XGRESS=y +CONFIG_NET_REDIRECT=y +CONFIG_SKB_EXTENSIONS=y + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_DIAG=m +CONFIG_UNIX=y +CONFIG_UNIX_SCM=y +CONFIG_AF_UNIX_OOB=y +CONFIG_UNIX_DIAG=m +CONFIG_TLS=y +CONFIG_TLS_DEVICE=y +# CONFIG_TLS_TOE is not set +CONFIG_XFRM=y +CONFIG_XFRM_OFFLOAD=y +CONFIG_XFRM_ALGO=m +CONFIG_XFRM_USER=m +# CONFIG_XFRM_USER_COMPAT is not set +CONFIG_XFRM_INTERFACE=m +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_MIGRATE=y +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_AH=m +CONFIG_XFRM_ESP=m +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y +CONFIG_XFRM_ESPINTCP=y +# CONFIG_SMC is not set +CONFIG_XDP_SOCKETS=y +# CONFIG_XDP_SOCKETS_DIAG is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_FIB_TRIE_STATS=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_ROUTE_CLASSID=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IP_TUNNEL=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE_COMMON=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_NET_UDP_TUNNEL=m +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_ESP_OFFLOAD=m +CONFIG_INET_ESPINTCP=y +CONFIG_INET_IPCOMP=m +CONFIG_INET_TABLE_PERTURB_ORDER=16 +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_UDP_DIAG=m +# CONFIG_INET_RAW_DIAG is not set +CONFIG_INET_DIAG_DESTROY=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_NV=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_DCTCP=m +CONFIG_TCP_CONG_CDG=m +CONFIG_TCP_CONG_BBR=m +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_ESP_OFFLOAD=m +CONFIG_INET6_ESPINTCP=y +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_ILA=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_IPV6_VTI=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_IPV6_SEG6_LWTUNNEL=y +CONFIG_IPV6_SEG6_HMAC=y +CONFIG_IPV6_SEG6_BPF=y +# CONFIG_IPV6_RPL_LWTUNNEL is not set +# CONFIG_IPV6_IOAM6_LWTUNNEL is not set +# CONFIG_NETLABEL is not set +CONFIG_MPTCP=y +CONFIG_INET_MPTCP_DIAG=m +CONFIG_MPTCP_IPV6=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NET_PTP_CLASSIFY=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=m + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_INGRESS=y +CONFIG_NETFILTER_EGRESS=y +CONFIG_NETFILTER_SKIP_EGRESS=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_FAMILY_BRIDGE=y +CONFIG_NETFILTER_FAMILY_ARP=y +CONFIG_NETFILTER_BPF_LINK=y +# CONFIG_NETFILTER_NETLINK_HOOK is not set +CONFIG_NETFILTER_NETLINK_ACCT=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_OSF=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_LOG_SYSLOG=m +CONFIG_NETFILTER_CONNCOUNT=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_LABELS=y +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_GRE=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NF_CT_NETLINK_HELPER=m +CONFIG_NETFILTER_NETLINK_GLUE_CT=y +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_REDIRECT=y +CONFIG_NF_NAT_MASQUERADE=y +CONFIG_NETFILTER_SYNPROXY=m +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_NUMGEN=m +CONFIG_NFT_CT=m +CONFIG_NFT_FLOW_OFFLOAD=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_QUOTA=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_REJECT_INET=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_FIB=m +CONFIG_NFT_FIB_INET=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_TPROXY=m +CONFIG_NFT_SYNPROXY=m +CONFIG_NF_DUP_NETDEV=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_FIB_NETDEV=m +# CONFIG_NFT_REJECT_NETDEV is not set +CONFIG_NF_FLOW_TABLE_INET=m +CONFIG_NF_FLOW_TABLE=m +# CONFIG_NF_FLOW_TABLE_PROCFS is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XTABLES_COMPAT=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CGROUP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_L2TP=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +# end of Core Netfilter Configuration + +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPMARK=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_IPMAC=m +CONFIG_IP_SET_HASH_MAC=m +CONFIG_IP_SET_HASH_NETPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETNET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_FO=m +CONFIG_IP_VS_OVF=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +# CONFIG_IP_VS_MH is not set +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +# CONFIG_IP_VS_TWOS is not set + +# +# IPVS SH scheduler +# +CONFIG_IP_VS_SH_TAB_BITS=8 + +# +# IPVS MH scheduler +# +CONFIG_IP_VS_MH_TAB_INDEX=12 + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_NFCT=y +CONFIG_IP_VS_PE_SIP=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_SOCKET_IPV4=m +CONFIG_NF_TPROXY_IPV4=m +CONFIG_NF_TABLES_IPV4=y +CONFIG_NFT_REJECT_IPV4=m +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y +CONFIG_NF_DUP_IPV4=m +CONFIG_NF_LOG_ARP=m +CONFIG_NF_LOG_IPV4=m +CONFIG_NF_REJECT_IPV4=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SYNPROXY=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +# CONFIG_IP_NF_SECURITY is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +# end of IP: Netfilter Configuration + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_SOCKET_IPV6=m +CONFIG_NF_TPROXY_IPV6=m +CONFIG_NF_TABLES_IPV6=y +CONFIG_NFT_REJECT_IPV6=m +CONFIG_NFT_DUP_IPV6=m +CONFIG_NFT_FIB_IPV6=m +CONFIG_NF_DUP_IPV6=m +CONFIG_NF_REJECT_IPV6=m +CONFIG_NF_LOG_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_SRH=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_SYNPROXY=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +# CONFIG_IP6_NF_SECURITY is not set +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +# end of IPv6: Netfilter Configuration + +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_TABLES_BRIDGE=m +# CONFIG_NFT_BRIDGE_META is not set +CONFIG_NFT_BRIDGE_REJECT=m +CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +# CONFIG_BPFILTER is not set +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=y +# end of DCCP CCIDs Configuration + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set +# end of DCCP Kernel Hacking + +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set +CONFIG_SCTP_COOKIE_HMAC_MD5=y +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_INET_SCTP_DIAG=m +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_MRP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_BRIDGE_VLAN_FILTERING=y +# CONFIG_BRIDGE_MRP is not set +# CONFIG_BRIDGE_CFM is not set +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_6LOWPAN is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_CBS=m +CONFIG_NET_SCH_ETF=m +CONFIG_NET_SCH_MQPRIO_LIB=m +# CONFIG_NET_SCH_TAPRIO is not set +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_SKBPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_CAKE=m +CONFIG_NET_SCH_FQ=m +CONFIG_NET_SCH_HHF=m +CONFIG_NET_SCH_PIE=m +# CONFIG_NET_SCH_FQ_PIE is not set +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m +# CONFIG_NET_SCH_ETS is not set +# CONFIG_NET_SCH_DEFAULT is not set + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=m +CONFIG_NET_CLS_BPF=m +CONFIG_NET_CLS_FLOWER=m +CONFIG_NET_CLS_MATCHALL=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_IPSET=m +# CONFIG_NET_EMATCH_IPT is not set +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +# CONFIG_NET_ACT_SAMPLE is not set +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_NET_ACT_MPLS=m +CONFIG_NET_ACT_VLAN=m +CONFIG_NET_ACT_BPF=m +CONFIG_NET_ACT_CONNMARK=m +# CONFIG_NET_ACT_CTINFO is not set +CONFIG_NET_ACT_SKBMOD=m +# CONFIG_NET_ACT_IFE is not set +CONFIG_NET_ACT_TUNNEL_KEY=m +# CONFIG_NET_ACT_CT is not set +# CONFIG_NET_ACT_GATE is not set +# CONFIG_NET_TC_SKB_EXT is not set +CONFIG_NET_SCH_FIFO=y +CONFIG_DCB=y +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_VSOCKETS=m +CONFIG_VSOCKETS_DIAG=m +CONFIG_VSOCKETS_LOOPBACK=m +CONFIG_VMWARE_VMCI_VSOCKETS=m +CONFIG_VIRTIO_VSOCKETS=m +CONFIG_VIRTIO_VSOCKETS_COMMON=m +CONFIG_HYPERV_VSOCKETS=m +CONFIG_NETLINK_DIAG=m +CONFIG_MPLS=y +CONFIG_NET_MPLS_GSO=y +CONFIG_MPLS_ROUTING=m +CONFIG_MPLS_IPTUNNEL=m +# CONFIG_NET_NSH is not set +CONFIG_HSR=y +CONFIG_NET_SWITCHDEV=y +CONFIG_NET_L3_MASTER_DEV=y +# CONFIG_QRTR is not set +# CONFIG_NET_NCSI is not set +CONFIG_PCPU_DEV_REFCNT=y +CONFIG_MAX_SKB_FRAGS=17 +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_XPS=y +CONFIG_CGROUP_NET_PRIO=y +CONFIG_CGROUP_NET_CLASSID=y +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_STREAM_PARSER is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NET_DROP_MONITOR=y +# end of Network testing +# end of Networking options + +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_AF_KCM is not set +CONFIG_STREAM_PARSER=y +# CONFIG_MCTP is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +CONFIG_CFG80211_CERTIFICATION_ONUS=y +CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y +CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y +CONFIG_CFG80211_EXTRA_REGDB_KEYDIR="" +# CONFIG_CFG80211_REG_CELLULAR_HINTS is not set +# CONFIG_CFG80211_REG_RELAX_NO_IR is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_CFG80211_CRDA_SUPPORT=y +CONFIG_CFG80211_WEXT=y +CONFIG_CFG80211_WEXT_EXPORT=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_MESSAGE_TRACING is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +CONFIG_RFKILL=m +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +# CONFIG_RFKILL_GPIO is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +CONFIG_PSAMPLE=y +# CONFIG_NET_IFE is not set +CONFIG_LWTUNNEL=y +CONFIG_LWTUNNEL_BPF=y +CONFIG_DST_CACHE=y +CONFIG_GRO_CELLS=y +CONFIG_SOCK_VALIDATE_XMIT=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_SOCK_MSG=y +CONFIG_NET_DEVLINK=y +CONFIG_PAGE_POOL=y +# CONFIG_PAGE_POOL_STATS is not set +CONFIG_FAILOVER=m +CONFIG_ETHTOOL_NETLINK=y + +# +# Device Drivers +# +CONFIG_HAVE_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=y +CONFIG_PCIEAER=y +CONFIG_PCIEAER_INJECT=m +# CONFIG_PCIE_ECRC is not set +CONFIG_PCIEASPM=y +CONFIG_PCIEASPM_DEFAULT=y +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set +# CONFIG_PCIEASPM_PERFORMANCE is not set +CONFIG_PCIE_PME=y +CONFIG_PCIE_DPC=y +CONFIG_PCIE_PTM=y +# CONFIG_PCIE_EDR is not set +CONFIG_PCI_MSI=y +CONFIG_PCI_QUIRKS=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_REALLOC_ENABLE_AUTO=y +CONFIG_PCI_STUB=m +# CONFIG_PCI_PF_STUB is not set +CONFIG_XEN_PCIDEV_FRONTEND=m +CONFIG_PCI_ATS=y +CONFIG_PCI_LOCKLESS_CONFIG=y +CONFIG_PCI_IOV=y +CONFIG_PCI_PRI=y +CONFIG_PCI_PASID=y +CONFIG_PCI_LABEL=y +CONFIG_PCI_HYPERV=m +# CONFIG_PCIE_BUS_TUNE_OFF is not set +CONFIG_PCIE_BUS_DEFAULT=y +# CONFIG_PCIE_BUS_SAFE is not set +# CONFIG_PCIE_BUS_PERFORMANCE is not set +# CONFIG_PCIE_BUS_PEER2PEER is not set +# CONFIG_VGA_ARB is not set +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_ACPI=y +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_SHPC=y + +# +# PCI controller drivers +# +CONFIG_VMD=m +CONFIG_PCI_HYPERV_INTERFACE=m + +# +# Cadence-based PCIe controllers +# +# end of Cadence-based PCIe controllers + +# +# DesignWare-based PCIe controllers +# +# CONFIG_PCI_MESON is not set +# CONFIG_PCIE_DW_PLAT_HOST is not set +# end of DesignWare-based PCIe controllers + +# +# Mobiveil-based PCIe controllers +# +# end of Mobiveil-based PCIe controllers +# end of PCI controller drivers + +# +# PCI Endpoint +# +# CONFIG_PCI_ENDPOINT is not set +# end of PCI Endpoint + +# +# PCI switch controller drivers +# +# CONFIG_PCI_SW_SWITCHTEC is not set +# end of PCI switch controller drivers + +# CONFIG_CXL_BUS is not set +# CONFIG_PCCARD is not set +# CONFIG_RAPIDIO is not set + +# +# Generic Driver Options +# +CONFIG_AUXILIARY_BUS=y +# CONFIG_UEVENT_HELPER is not set +CONFIG_DEVTMPFS=y +# CONFIG_DEVTMPFS_MOUNT is not set +# CONFIG_DEVTMPFS_SAFE is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# Firmware loader +# +CONFIG_FW_LOADER=y +CONFIG_FW_LOADER_DEBUG=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FW_LOADER_USER_HELPER=y +# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set +# CONFIG_FW_LOADER_COMPRESS is not set +CONFIG_FW_CACHE=y +# CONFIG_FW_UPLOAD is not set +# end of Firmware loader + +CONFIG_WANT_DEV_COREDUMP=y +CONFIG_ALLOW_DEV_COREDUMP=y +CONFIG_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set +CONFIG_SYS_HYPERVISOR=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_DMA_FENCE_TRACE is not set +# CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT is not set +# end of Generic Driver Options + +# +# Bus devices +# +# CONFIG_MHI_BUS is not set +# CONFIG_MHI_BUS_EP is not set +# end of Bus devices + +# +# Cache Drivers +# +# end of Cache Drivers + +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y + +# +# Firmware Drivers +# + +# +# ARM System Control and Management Interface Protocol +# +# end of ARM System Control and Management Interface Protocol + +CONFIG_EDD=m +# CONFIG_EDD_OFF is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_DMIID=y +CONFIG_DMI_SYSFS=y +CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y +# CONFIG_ISCSI_IBFT is not set +# CONFIG_FW_CFG_SYSFS is not set +CONFIG_SYSFB=y +# CONFIG_SYSFB_SIMPLEFB is not set +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# EFI (Extensible Firmware Interface) Support +# +CONFIG_EFI_ESRT=y +CONFIG_EFI_VARS_PSTORE=m +# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set +CONFIG_EFI_DXE_MEM_ATTRIBUTES=y +CONFIG_EFI_RUNTIME_WRAPPERS=y +# CONFIG_EFI_BOOTLOADER_CONTROL is not set +# CONFIG_EFI_CAPSULE_LOADER is not set +# CONFIG_EFI_TEST is not set +CONFIG_EFI_DEV_PATH_PARSER=y +CONFIG_APPLE_PROPERTIES=y +# CONFIG_RESET_ATTACK_MITIGATION is not set +# CONFIG_EFI_RCI2_TABLE is not set +# CONFIG_EFI_DISABLE_PCI_DMA is not set +CONFIG_EFI_EARLYCON=y +CONFIG_EFI_CUSTOM_SSDT_OVERLAYS=y +# CONFIG_EFI_DISABLE_RUNTIME is not set +# CONFIG_EFI_COCO_SECRET is not set +# end of EFI (Extensible Firmware Interface) Support + +CONFIG_UEFI_CPER=y +CONFIG_UEFI_CPER_X86=y + +# +# Tegra firmware driver +# +# end of Tegra firmware driver +# end of Firmware Drivers + +# CONFIG_GNSS is not set +# CONFIG_MTD is not set +# CONFIG_OF is not set +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_PARPORT=y +# CONFIG_PARPORT_PC is not set +# CONFIG_PARPORT_1284 is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG_MESSAGES is not set + +# +# Protocols +# +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_NULL_BLK=m +# CONFIG_BLK_DEV_FD is not set +CONFIG_CDROM=m +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +# CONFIG_ZRAM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_XEN_BLKDEV_FRONTEND=m +CONFIG_XEN_BLKDEV_BACKEND=m +CONFIG_VIRTIO_BLK=m +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_UBLK is not set + +# +# NVME Support +# +CONFIG_NVME_CORE=y +CONFIG_BLK_DEV_NVME=y +CONFIG_NVME_MULTIPATH=y +# CONFIG_NVME_VERBOSE_ERRORS is not set +CONFIG_NVME_HWMON=y +# CONFIG_NVME_RDMA is not set +# CONFIG_NVME_FC is not set +# CONFIG_NVME_TCP is not set +# CONFIG_NVME_AUTH is not set +# CONFIG_NVME_TARGET is not set +# end of NVME Support + +# +# Misc devices +# +CONFIG_SENSORS_LIS3LV02D=m +CONFIG_AD525X_DPOT=m +CONFIG_AD525X_DPOT_I2C=m +# CONFIG_DUMMY_IRQ is not set +CONFIG_IBM_ASM=m +CONFIG_PHANTOM=m +CONFIG_TIFM_CORE=m +CONFIG_TIFM_7XX1=m +CONFIG_ICS932S401=m +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_HP_ILO=m +CONFIG_APDS9802ALS=m +CONFIG_ISL29003=m +CONFIG_ISL29020=m +CONFIG_SENSORS_TSL2550=m +CONFIG_SENSORS_BH1770=m +CONFIG_SENSORS_APDS990X=m +CONFIG_HMC6352=m +CONFIG_DS1682=m +CONFIG_VMWARE_BALLOON=m +# CONFIG_SRAM is not set +# CONFIG_DW_XDATA_PCIE is not set +# CONFIG_PCI_ENDPOINT_TEST is not set +# CONFIG_XILINX_SDFEC is not set +CONFIG_MISC_RTSX=m +CONFIG_C2PORT=m +CONFIG_C2PORT_DURAMAR_2150=m + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=m +CONFIG_EEPROM_LEGACY=m +CONFIG_EEPROM_MAX6875=m +CONFIG_EEPROM_93CX6=m +# CONFIG_EEPROM_IDT_89HPESX is not set +# CONFIG_EEPROM_EE1004 is not set +# end of EEPROM support + +CONFIG_CB710_CORE=m +# CONFIG_CB710_DEBUG is not set +CONFIG_CB710_DEBUG_ASSUMPTIONS=y + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# end of Texas Instruments shared transport line discipline + +CONFIG_SENSORS_LIS3_I2C=m +CONFIG_ALTERA_STAPL=m +CONFIG_INTEL_MEI=m +CONFIG_INTEL_MEI_ME=m +# CONFIG_INTEL_MEI_TXE is not set +CONFIG_VMWARE_VMCI=m +# CONFIG_GENWQE is not set +# CONFIG_ECHO is not set +# CONFIG_BCM_VK is not set +# CONFIG_MISC_ALCOR_PCI is not set +CONFIG_MISC_RTSX_PCI=m +CONFIG_MISC_RTSX_USB=m +# CONFIG_UACCE is not set +# CONFIG_PVPANIC is not set +# CONFIG_GP_PCI1XXXX is not set +# end of Misc devices + +# +# SCSI device support +# +CONFIG_SCSI_MOD=m +CONFIG_RAID_ATTRS=m +CONFIG_SCSI_COMMON=m +CONFIG_SCSI=m +CONFIG_SCSI_DMA=y +CONFIG_SCSI_NETLINK=y +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +# CONFIG_CHR_DEV_ST is not set +CONFIG_BLK_DEV_SR=m +CONFIG_CHR_DEV_SG=m +CONFIG_BLK_DEV_BSG=y +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_ENCLOSURE is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set +CONFIG_SCSI_SCAN_ASYNC=y + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SRP_ATTRS=m +# end of SCSI Transports + +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m +CONFIG_SCSI_CXGB3_ISCSI=m +CONFIG_SCSI_CXGB4_ISCSI=m +CONFIG_SCSI_BNX2_ISCSI=m +CONFIG_SCSI_BNX2X_FCOE=m +CONFIG_BE2ISCSI=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_HPSA=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_3W_SAS=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC94XX=m +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_SCSI_MVSAS=m +# CONFIG_SCSI_MVSAS_DEBUG is not set +# CONFIG_SCSI_MVSAS_TASKLET is not set +CONFIG_SCSI_MVUMI=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ESAS2R=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_MPT3SAS=m +CONFIG_SCSI_MPT2SAS_MAX_SGE=128 +CONFIG_SCSI_MPT3SAS_MAX_SGE=128 +CONFIG_SCSI_MPT2SAS=m +# CONFIG_SCSI_MPI3MR is not set +CONFIG_SCSI_SMARTPQI=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_BUSLOGIC=m +# CONFIG_SCSI_FLASHPOINT is not set +# CONFIG_SCSI_MYRB is not set +# CONFIG_SCSI_MYRS is not set +CONFIG_VMWARE_PVSCSI=m +CONFIG_XEN_SCSI_FRONTEND=m +CONFIG_HYPERV_STORAGE=m +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +CONFIG_FCOE=m +CONFIG_FCOE_FNIC=m +CONFIG_SCSI_SNIC=m +# CONFIG_SCSI_SNIC_DEBUG_FS is not set +CONFIG_SCSI_DMX3191D=m +# CONFIG_SCSI_FDOMAIN_PCI is not set +CONFIG_SCSI_ISCI=m +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_TRACE is not set +# CONFIG_SCSI_IPR_DUMP is not set +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +# CONFIG_QEDI is not set +# CONFIG_QEDF is not set +CONFIG_SCSI_LPFC=m +# CONFIG_SCSI_LPFC_DEBUG_FS is not set +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_AM53C974=m +CONFIG_SCSI_WD719X=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_PMCRAID=m +CONFIG_SCSI_PM8001=m +CONFIG_SCSI_BFA_FC=m +CONFIG_SCSI_VIRTIO=m +CONFIG_SCSI_CHELSIO_FCOE=m +CONFIG_SCSI_DH=y +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +# end of SCSI device support + +CONFIG_ATA=m +CONFIG_SATA_HOST=y +CONFIG_PATA_TIMINGS=y +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ATA_FORCE=y +CONFIG_ATA_ACPI=y +CONFIG_SATA_ZPODD=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +CONFIG_SATA_AHCI=m +CONFIG_SATA_MOBILE_LPM_POLICY=3 +# CONFIG_SATA_AHCI_PLATFORM is not set +# CONFIG_AHCI_DWC is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_ACARD_AHCI is not set +# CONFIG_SATA_SIL24 is not set +CONFIG_ATA_SFF=y + +# +# SFF controllers with custom DMA interface +# +CONFIG_PDC_ADMA=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SX4=m +CONFIG_ATA_BMDMA=y + +# +# SATA SFF controllers with BMDMA +# +CONFIG_ATA_PIIX=m +# CONFIG_SATA_DWC is not set +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIS=m +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_ULI is not set +CONFIG_SATA_VIA=m +# CONFIG_SATA_VITESSE is not set + +# +# PATA SFF controllers with BMDMA +# +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_ATP867X is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87415 is not set +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RDC is not set +CONFIG_PATA_SCH=m +# CONFIG_PATA_SERVERWORKS is not set +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +# CONFIG_PATA_TOSHIBA is not set +# CONFIG_PATA_TRIFLEX is not set +CONFIG_PATA_VIA=m +# CONFIG_PATA_WINBOND is not set + +# +# PIO-only SFF controllers +# +# CONFIG_PATA_CMD640_PCI is not set +CONFIG_PATA_MPIIX=m +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_RZ1000 is not set + +# +# Generic fallback / legacy drivers +# +# CONFIG_PATA_ACPI is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_LEGACY is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_AUTODETECT=y +CONFIG_MD_BITMAP_FILE=y +# CONFIG_MD_LINEAR is not set +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID10=y +CONFIG_MD_RAID456=y +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +# CONFIG_BCACHE is not set +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=y +# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set +# CONFIG_DM_UNSTRIPED is not set +CONFIG_DM_CRYPT=y +CONFIG_DM_SNAPSHOT=y +# CONFIG_DM_THIN_PROVISIONING is not set +# CONFIG_DM_CACHE is not set +# CONFIG_DM_WRITECACHE is not set +# CONFIG_DM_EBS is not set +# CONFIG_DM_ERA is not set +# CONFIG_DM_CLONE is not set +# CONFIG_DM_MIRROR is not set +CONFIG_DM_RAID=y +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_DUST is not set +CONFIG_DM_INIT=y +CONFIG_DM_UEVENT=y +# CONFIG_DM_FLAKEY is not set +# CONFIG_DM_VERITY is not set +# CONFIG_DM_SWITCH is not set +# CONFIG_DM_LOG_WRITES is not set +# CONFIG_DM_INTEGRITY is not set +# CONFIG_DM_AUDIT is not set +# CONFIG_TARGET_CORE is not set +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_SAS=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_CTL=m +# CONFIG_FUSION_LOGGING is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +# end of IEEE 1394 (FireWire) support + +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +CONFIG_MII=m +CONFIG_NET_CORE=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_WIREGUARD=m +# CONFIG_WIREGUARD_DEBUG is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_FC is not set +CONFIG_IFB=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_RANDOM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN_L3S=y +CONFIG_IPVLAN=m +CONFIG_IPVTAP=m +CONFIG_VXLAN=m +CONFIG_GENEVE=m +# CONFIG_BAREUDP is not set +CONFIG_GTP=m +# CONFIG_AMT is not set +CONFIG_MACSEC=m +# CONFIG_NETCONSOLE is not set +CONFIG_TUN=m +CONFIG_TAP=m +# CONFIG_TUN_VNET_CROSS_LE is not set +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +CONFIG_NLMON=m +CONFIG_NET_VRF=y +# CONFIG_VSOCKMON is not set +# CONFIG_ARCNET is not set +CONFIG_ETHERNET=y +CONFIG_MDIO=m +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +CONFIG_NET_VENDOR_AGERE=y +CONFIG_ET131X=m +CONFIG_NET_VENDOR_ALACRITECH=y +# CONFIG_SLICOSS is not set +CONFIG_NET_VENDOR_ALTEON=y +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_ALTERA_TSE is not set +CONFIG_NET_VENDOR_AMAZON=y +CONFIG_ENA_ETHERNET=m +CONFIG_NET_VENDOR_AMD=y +CONFIG_AMD8111_ETH=m +CONFIG_PCNET32=m +CONFIG_AMD_XGBE=m +# CONFIG_AMD_XGBE_DCB is not set +CONFIG_AMD_XGBE_HAVE_ECC=y +# CONFIG_PDS_CORE is not set +CONFIG_NET_VENDOR_AQUANTIA=y +CONFIG_AQTION=m +# CONFIG_NET_VENDOR_ARC is not set +CONFIG_NET_VENDOR_ASIX=y +CONFIG_NET_VENDOR_ATHEROS=y +CONFIG_ATL2=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL1C=m +CONFIG_ALX=m +# CONFIG_CX_ECAT is not set +CONFIG_NET_VENDOR_BROADCOM=y +CONFIG_B44=m +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI=y +# CONFIG_BCMGENET is not set +CONFIG_BNX2=m +CONFIG_CNIC=m +CONFIG_TIGON3=m +CONFIG_TIGON3_HWMON=y +CONFIG_BNX2X=m +CONFIG_BNX2X_SRIOV=y +# CONFIG_SYSTEMPORT is not set +CONFIG_BNXT=m +CONFIG_BNXT_SRIOV=y +CONFIG_BNXT_FLOWER_OFFLOAD=y +# CONFIG_BNXT_DCB is not set +CONFIG_BNXT_HWMON=y +CONFIG_NET_VENDOR_CADENCE=y +# CONFIG_MACB is not set +CONFIG_NET_VENDOR_CAVIUM=y +# CONFIG_THUNDER_NIC_PF is not set +# CONFIG_THUNDER_NIC_VF is not set +# CONFIG_THUNDER_NIC_BGX is not set +# CONFIG_THUNDER_NIC_RGX is not set +CONFIG_CAVIUM_PTP=y +CONFIG_LIQUIDIO_CORE=m +CONFIG_LIQUIDIO=m +# CONFIG_LIQUIDIO_VF is not set +CONFIG_NET_VENDOR_CHELSIO=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3=m +CONFIG_CHELSIO_T4=m +# CONFIG_CHELSIO_T4_DCB is not set +CONFIG_CHELSIO_T4VF=m +CONFIG_CHELSIO_LIB=m +CONFIG_CHELSIO_INLINE_CRYPTO=y +# CONFIG_CHELSIO_IPSEC_INLINE is not set +# CONFIG_CHELSIO_TLS_DEVICE is not set +# CONFIG_NET_VENDOR_CISCO is not set +# CONFIG_NET_VENDOR_CORTINA is not set +CONFIG_NET_VENDOR_DAVICOM=y +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_DEC is not set +CONFIG_NET_VENDOR_DLINK=y +CONFIG_DL2K=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_NET_VENDOR_EMULEX=y +CONFIG_BE2NET=m +CONFIG_BE2NET_HWMON=y +CONFIG_BE2NET_BE2=y +CONFIG_BE2NET_BE3=y +CONFIG_BE2NET_LANCER=y +CONFIG_BE2NET_SKYHAWK=y +CONFIG_NET_VENDOR_ENGLEDER=y +# CONFIG_TSNEP is not set +CONFIG_NET_VENDOR_EZCHIP=y +CONFIG_NET_VENDOR_FUNGIBLE=y +# CONFIG_FUN_ETH is not set +CONFIG_NET_VENDOR_GOOGLE=y +CONFIG_GVE=m +CONFIG_NET_VENDOR_HUAWEI=y +CONFIG_HINIC=y +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_INTEL=y +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_E1000E_HWTS=y +CONFIG_IGB=m +CONFIG_IGB_HWMON=y +CONFIG_IGB_DCA=y +CONFIG_IGBVF=m +# CONFIG_IXGBE is not set +# CONFIG_IXGBEVF is not set +CONFIG_I40E=m +# CONFIG_I40E_DCB is not set +CONFIG_IAVF=m +CONFIG_I40EVF=m +CONFIG_ICE=m +CONFIG_ICE_SWITCHDEV=y +CONFIG_ICE_HWTS=y +# CONFIG_FM10K is not set +CONFIG_IGC=m +CONFIG_JME=m +CONFIG_NET_VENDOR_LITEX=y +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_MVMDIO is not set +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKGE_GENESIS=y +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_OCTEON_EP is not set +# CONFIG_PRESTERA is not set +CONFIG_NET_VENDOR_MELLANOX=y +CONFIG_MLX4_EN=m +CONFIG_MLX4_EN_DCB=y +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_CORE_GEN2=y +CONFIG_MLX5_CORE=m +# CONFIG_MLX5_FPGA is not set +CONFIG_MLX5_CORE_EN=y +CONFIG_MLX5_EN_ARFS=y +CONFIG_MLX5_EN_RXNFC=y +CONFIG_MLX5_MPFS=y +CONFIG_MLX5_ESWITCH=y +CONFIG_MLX5_BRIDGE=y +CONFIG_MLX5_CORE_EN_DCB=y +# CONFIG_MLX5_CORE_IPOIB is not set +# CONFIG_MLX5_MACSEC is not set +CONFIG_MLX5_EN_IPSEC=y +CONFIG_MLX5_EN_TLS=y +CONFIG_MLX5_SW_STEERING=y +# CONFIG_MLX5_SF is not set +CONFIG_MLXSW_CORE=m +CONFIG_MLXSW_CORE_HWMON=y +CONFIG_MLXSW_CORE_THERMAL=y +CONFIG_MLXSW_PCI=m +CONFIG_MLXSW_I2C=m +CONFIG_MLXSW_SPECTRUM=m +CONFIG_MLXSW_SPECTRUM_DCB=y +CONFIG_MLXSW_MINIMAL=m +CONFIG_MLXFW=m +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_KSZ884X_PCI=m +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_LAN743X is not set +# CONFIG_VCAP is not set +CONFIG_NET_VENDOR_MICROSEMI=y +CONFIG_NET_VENDOR_MICROSOFT=y +# CONFIG_MICROSOFT_MANA is not set +CONFIG_NET_VENDOR_MYRI=y +CONFIG_MYRI10GE=m +CONFIG_MYRI10GE_DCA=y +CONFIG_FEALNX=m +# CONFIG_NET_VENDOR_NI is not set +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NATSEMI=m +CONFIG_NS83820=m +CONFIG_NET_VENDOR_NETERION=y +CONFIG_S2IO=m +# CONFIG_NET_VENDOR_NETRONOME is not set +# CONFIG_NET_VENDOR_8390 is not set +CONFIG_NET_VENDOR_NVIDIA=y +CONFIG_FORCEDETH=m +CONFIG_NET_VENDOR_OKI=y +# CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_PACKET_ENGINES=y +CONFIG_HAMACHI=m +CONFIG_YELLOWFIN=m +# CONFIG_NET_VENDOR_PENSANDO is not set +CONFIG_NET_VENDOR_QLOGIC=y +CONFIG_QLA3XXX=m +CONFIG_QLCNIC=m +CONFIG_QLCNIC_SRIOV=y +CONFIG_QLCNIC_DCB=y +CONFIG_QLCNIC_HWMON=y +CONFIG_NETXEN_NIC=m +CONFIG_QED=m +CONFIG_QED_SRIOV=y +CONFIG_QEDE=m +CONFIG_NET_VENDOR_BROCADE=y +CONFIG_BNA=m +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_RDC is not set +CONFIG_NET_VENDOR_REALTEK=y +# CONFIG_ATP is not set +CONFIG_8139CP=m +CONFIG_8139TOO=m +# CONFIG_8139TOO_PIO is not set +CONFIG_8139TOO_TUNE_TWISTER=y +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_R8169=m +CONFIG_NET_VENDOR_RENESAS=y +CONFIG_NET_VENDOR_ROCKER=y +# CONFIG_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +CONFIG_NET_VENDOR_SILAN=y +CONFIG_SC92031=m +CONFIG_NET_VENDOR_SIS=y +CONFIG_SIS900=m +CONFIG_SIS190=m +CONFIG_NET_VENDOR_SOLARFLARE=y +CONFIG_SFC=m +CONFIG_SFC_MCDI_MON=y +CONFIG_SFC_SRIOV=y +CONFIG_SFC_MCDI_LOGGING=y +CONFIG_SFC_FALCON=m +# CONFIG_SFC_SIENA is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_SOCIONEXT is not set +CONFIG_NET_VENDOR_STMICRO=y +CONFIG_STMMAC_ETH=m +# CONFIG_STMMAC_SELFTESTS is not set +CONFIG_STMMAC_PLATFORM=m +CONFIG_DWMAC_GENERIC=m +CONFIG_DWMAC_INTEL=m +CONFIG_STMMAC_PCI=m +# CONFIG_NET_VENDOR_SUN is not set +CONFIG_NET_VENDOR_SYNOPSYS=y +# CONFIG_DWC_XLGMAC is not set +CONFIG_NET_VENDOR_TEHUTI=y +CONFIG_TEHUTI=m +CONFIG_NET_VENDOR_TI=y +# CONFIG_TI_CPSW_PHY_SEL is not set +CONFIG_TLAN=m +CONFIG_NET_VENDOR_VERTEXCOM=y +CONFIG_NET_VENDOR_VIA=y +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +CONFIG_VIA_VELOCITY=m +CONFIG_NET_VENDOR_WANGXUN=y +# CONFIG_NGBE is not set +# CONFIG_TXGBE is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_XILINX is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_NET_SB1000 is not set +CONFIG_PHYLINK=m +CONFIG_PHYLIB=y +CONFIG_SWPHY=y +# CONFIG_LED_TRIGGER_PHY is not set +CONFIG_FIXED_PHY=y +# CONFIG_SFP is not set + +# +# MII PHY device drivers +# +CONFIG_AMD_PHY=m +# CONFIG_ADIN_PHY is not set +# CONFIG_ADIN1100_PHY is not set +CONFIG_AQUANTIA_PHY=m +CONFIG_AX88796B_PHY=m +CONFIG_BROADCOM_PHY=m +# CONFIG_BCM54140_PHY is not set +CONFIG_BCM7XXX_PHY=m +# CONFIG_BCM84881_PHY is not set +CONFIG_BCM87XX_PHY=m +CONFIG_BCM_NET_PHYLIB=m +CONFIG_CICADA_PHY=m +CONFIG_CORTINA_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_ICPLUS_PHY=m +CONFIG_LXT_PHY=m +CONFIG_INTEL_XWAY_PHY=m +CONFIG_LSI_ET1011C_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_MARVELL_10G_PHY=m +# CONFIG_MARVELL_88Q2XXX_PHY is not set +# CONFIG_MARVELL_88X2222_PHY is not set +# CONFIG_MAXLINEAR_GPHY is not set +# CONFIG_MEDIATEK_GE_PHY is not set +CONFIG_MICREL_PHY=m +# CONFIG_MICROCHIP_T1S_PHY is not set +CONFIG_MICROCHIP_PHY=m +CONFIG_MICROCHIP_T1_PHY=m +CONFIG_MICROSEMI_PHY=m +# CONFIG_MOTORCOMM_PHY is not set +CONFIG_NATIONAL_PHY=m +# CONFIG_NXP_CBTX_PHY is not set +# CONFIG_NXP_C45_TJA11XX_PHY is not set +# CONFIG_NXP_TJA11XX_PHY is not set +# CONFIG_NCN26000_PHY is not set +CONFIG_AT803X_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_REALTEK_PHY=m +CONFIG_RENESAS_PHY=m +CONFIG_ROCKCHIP_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_STE10XP=m +CONFIG_TERANETICS_PHY=m +CONFIG_DP83822_PHY=m +CONFIG_DP83TC811_PHY=m +CONFIG_DP83848_PHY=m +CONFIG_DP83867_PHY=m +# CONFIG_DP83869_PHY is not set +# CONFIG_DP83TD510_PHY is not set +CONFIG_VITESSE_PHY=m +# CONFIG_XILINX_GMII2RGMII is not set +# CONFIG_PSE_CONTROLLER is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_BUS=y +CONFIG_FWNODE_MDIO=y +CONFIG_ACPI_MDIO=y +CONFIG_MDIO_DEVRES=y +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_MDIO_MVUSB is not set +# CONFIG_MDIO_MSCC_MIIM is not set +# CONFIG_MDIO_THUNDER is not set + +# +# MDIO Multiplexers +# + +# +# PCS device drivers +# +CONFIG_PCS_XPCS=m +# end of PCS device drivers + +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=m +# CONFIG_PPPOE_HASH_BITS_1 is not set +# CONFIG_PPPOE_HASH_BITS_2 is not set +CONFIG_PPPOE_HASH_BITS_4=y +# CONFIG_PPPOE_HASH_BITS_8 is not set +CONFIG_PPPOE_HASH_BITS=4 +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +# CONFIG_SLIP is not set +CONFIG_SLHC=m +CONFIG_USB_NET_DRIVERS=m +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_LAN78XX=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +CONFIG_USB_NET_QMI_WWAN=m +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +CONFIG_USB_SIERRA_NET=m +# CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set +# CONFIG_USB_NET_AQC111 is not set +CONFIG_USB_RTL8153_ECM=m +CONFIG_WLAN=y +CONFIG_WLAN_VENDOR_ADMTEK=y +CONFIG_ADM8211=m +CONFIG_ATH_COMMON=m +CONFIG_WLAN_VENDOR_ATH=y +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y +CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING=y +CONFIG_ATH5K=m +# CONFIG_ATH5K_DEBUG is not set +# CONFIG_ATH5K_TRACER is not set +CONFIG_ATH5K_PCI=y +# CONFIG_ATH5K_TEST_CHANNELS is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +# CONFIG_ATH9K_BTCOEX_SUPPORT is not set +CONFIG_ATH9K=m +CONFIG_ATH9K_PCI=y +# CONFIG_ATH9K_AHB is not set +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DFS_CERTIFIED is not set +# CONFIG_ATH9K_DYNACK is not set +# CONFIG_ATH9K_WOW is not set +CONFIG_ATH9K_RFKILL=y +CONFIG_ATH9K_CHANNEL_CONTEXT=y +CONFIG_ATH9K_PCOEM=y +# CONFIG_ATH9K_PCI_NO_EEPROM is not set +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +# CONFIG_ATH9K_HWRNG is not set +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +CONFIG_CARL9170_WPC=y +# CONFIG_CARL9170_HWRNG is not set +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_ATH6KL_USB=m +# CONFIG_ATH6KL_DEBUG is not set +# CONFIG_ATH6KL_TRACING is not set +# CONFIG_ATH6KL_REGDOMAIN is not set +CONFIG_AR5523=m +CONFIG_WIL6210=m +CONFIG_WIL6210_ISR_COR=y +# CONFIG_WIL6210_TRACING is not set +CONFIG_WIL6210_DEBUGFS=y +CONFIG_ATH10K=m +CONFIG_ATH10K_CE=y +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_SDIO=m +CONFIG_ATH10K_USB=m +# CONFIG_ATH10K_DEBUG is not set +# CONFIG_ATH10K_DEBUGFS is not set +# CONFIG_ATH10K_TRACING is not set +CONFIG_ATH10K_DFS_CERTIFIED=y +# CONFIG_WCN36XX is not set +# CONFIG_ATH11K is not set +# CONFIG_ATH12K is not set +# CONFIG_WLAN_VENDOR_ATMEL is not set +CONFIG_WLAN_VENDOR_BROADCOM=y +CONFIG_B43=m +CONFIG_B43_BCMA=y +CONFIG_B43_SSB=y +CONFIG_B43_BUSES_BCMA_AND_SSB=y +# CONFIG_B43_BUSES_BCMA is not set +# CONFIG_B43_BUSES_SSB is not set +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_SDIO=y +CONFIG_B43_BCMA_PIO=y +CONFIG_B43_PIO=y +CONFIG_B43_PHY_G=y +CONFIG_B43_PHY_N=y +CONFIG_B43_PHY_LP=y +CONFIG_B43_PHY_HT=y +CONFIG_B43_LEDS=y +CONFIG_B43_HWRNG=y +# CONFIG_B43_DEBUG is not set +# CONFIG_B43LEGACY is not set +CONFIG_BRCMUTIL=m +CONFIG_BRCMSMAC=m +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_PROTO_BCDC=y +CONFIG_BRCMFMAC_PROTO_MSGBUF=y +CONFIG_BRCMFMAC_SDIO=y +CONFIG_BRCMFMAC_USB=y +CONFIG_BRCMFMAC_PCIE=y +# CONFIG_BRCM_TRACING is not set +# CONFIG_BRCMDBG is not set +# CONFIG_WLAN_VENDOR_CISCO is not set +CONFIG_WLAN_VENDOR_INTEL=y +# CONFIG_IPW2100 is not set +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +# CONFIG_IPW2200_DEBUG is not set +CONFIG_LIBIPW=m +# CONFIG_LIBIPW_DEBUG is not set +CONFIG_IWLEGACY=m +CONFIG_IWL4965=m +CONFIG_IWL3945=m + +# +# iwl3945 / iwl4965 Debugging Options +# +# CONFIG_IWLEGACY_DEBUG is not set +# end of iwl3945 / iwl4965 Debugging Options + +CONFIG_IWLWIFI=m +CONFIG_IWLWIFI_LEDS=y +CONFIG_IWLDVM=m +CONFIG_IWLMVM=m +CONFIG_IWLWIFI_OPMODE_MODULAR=y + +# +# Debugging Options +# +# CONFIG_IWLWIFI_DEBUG is not set +CONFIG_IWLWIFI_DEVICE_TRACING=y +# end of Debugging Options + +# CONFIG_WLAN_VENDOR_INTERSIL is not set +CONFIG_WLAN_VENDOR_MARVELL=y +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_MESH=y +CONFIG_LIBERTAS_THINFIRM=m +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m +CONFIG_MWIFIEX_PCIE=m +CONFIG_MWIFIEX_USB=m +CONFIG_MWL8K=m +CONFIG_WLAN_VENDOR_MEDIATEK=y +CONFIG_MT7601U=m +CONFIG_MT76_CORE=m +CONFIG_MT76_LEDS=y +CONFIG_MT76_USB=m +CONFIG_MT76_SDIO=m +CONFIG_MT76x02_LIB=m +CONFIG_MT76x02_USB=m +CONFIG_MT76_CONNAC_LIB=m +CONFIG_MT76x0_COMMON=m +CONFIG_MT76x0U=m +CONFIG_MT76x0E=m +CONFIG_MT76x2_COMMON=m +CONFIG_MT76x2E=m +CONFIG_MT76x2U=m +CONFIG_MT7603E=m +CONFIG_MT7615_COMMON=m +CONFIG_MT7615E=m +CONFIG_MT7663_USB_SDIO_COMMON=m +CONFIG_MT7663U=m +CONFIG_MT7663S=m +CONFIG_MT7915E=m +# CONFIG_MT7921E is not set +# CONFIG_MT7921S is not set +# CONFIG_MT7921U is not set +# CONFIG_MT7996E is not set +CONFIG_WLAN_VENDOR_MICROCHIP=y +# CONFIG_WILC1000_SDIO is not set +CONFIG_WLAN_VENDOR_PURELIFI=y +# CONFIG_PLFXLC is not set +CONFIG_WLAN_VENDOR_RALINK=y +CONFIG_RT2X00=m +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT61PCI=m +CONFIG_RT2800PCI=m +CONFIG_RT2800PCI_RT33XX=y +CONFIG_RT2800PCI_RT35XX=y +CONFIG_RT2800PCI_RT53XX=y +CONFIG_RT2800PCI_RT3290=y +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +# CONFIG_RT2800USB_UNKNOWN is not set +CONFIG_RT2800_LIB=m +CONFIG_RT2800_LIB_MMIO=m +CONFIG_RT2X00_LIB_MMIO=m +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_WLAN_VENDOR_REALTEK=y +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +CONFIG_RTL_CARDS=m +CONFIG_RTL8192CE=m +CONFIG_RTL8192SE=m +CONFIG_RTL8192DE=m +CONFIG_RTL8723AE=m +CONFIG_RTL8723BE=m +CONFIG_RTL8188EE=m +CONFIG_RTL8192EE=m +CONFIG_RTL8821AE=m +CONFIG_RTL8192CU=m +CONFIG_RTLWIFI=m +CONFIG_RTLWIFI_PCI=m +CONFIG_RTLWIFI_USB=m +# CONFIG_RTLWIFI_DEBUG is not set +CONFIG_RTL8192C_COMMON=m +CONFIG_RTL8723_COMMON=m +CONFIG_RTLBTCOEXIST=m +CONFIG_RTL8XXXU=m +# CONFIG_RTL8XXXU_UNTESTED is not set +# CONFIG_RTW88 is not set +# CONFIG_RTW89 is not set +CONFIG_WLAN_VENDOR_RSI=y +CONFIG_RSI_91X=m +CONFIG_RSI_DEBUGFS=y +CONFIG_RSI_SDIO=m +CONFIG_RSI_USB=m +CONFIG_WLAN_VENDOR_SILABS=y +# CONFIG_WFX is not set +# CONFIG_WLAN_VENDOR_ST is not set +# CONFIG_WLAN_VENDOR_TI is not set +# CONFIG_WLAN_VENDOR_ZYDAS is not set +# CONFIG_WLAN_VENDOR_QUANTENNA is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +CONFIG_MAC80211_HWSIM=m +# CONFIG_VIRT_WIFI is not set +# CONFIG_WAN is not set + +# +# Wireless WAN +# +# CONFIG_WWAN is not set +# end of Wireless WAN + +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_NETDEV_BACKEND=m +CONFIG_VMXNET3=m +# CONFIG_FUJITSU_ES is not set +CONFIG_USB4_NET=m +CONFIG_HYPERV_NET=m +# CONFIG_NETDEVSIM is not set +CONFIG_NET_FAILOVER=m +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_LEDS is not set +# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_SPARSEKMAP=m +# CONFIG_INPUT_MATRIXKMAP is not set +CONFIG_INPUT_VIVALDIFMAP=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1050 is not set +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_DLINK_DIR685 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +CONFIG_KEYBOARD_GPIO_POLLED=m +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_PINEPHONE is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_CYPRESS_SF is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_E3X0_BUTTON is not set +CONFIG_INPUT_PCSPKR=m +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_APANEL is not set +# CONFIG_INPUT_GPIO_BEEPER is not set +# CONFIG_INPUT_GPIO_DECODER is not set +# CONFIG_INPUT_GPIO_VIBRA is not set +# CONFIG_INPUT_ATLAS_BTNS is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_REGULATOR_HAPTIC is not set +# CONFIG_INPUT_AXP20X_PEK is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_DA7280_HAPTICS is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IBM_PANEL is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_IQS269A is not set +# CONFIG_INPUT_IQS626A is not set +# CONFIG_INPUT_IQS7222 is not set +# CONFIG_INPUT_CMA3000 is not set +CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m +# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set +# CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set +# CONFIG_INPUT_DRV2667_HAPTICS is not set +# CONFIG_RMI4_CORE is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=m +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +CONFIG_HYPERV_KEYBOARD=m +# CONFIG_SERIO_GPIO_PS2 is not set +# CONFIG_USERIO is not set +# CONFIG_GAMEPORT is not set +# end of Hardware I/O ports +# end of Input device support + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_LEGACY_TIOCSTI=y +CONFIG_LDISC_AUTOLOAD=y + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_PNP=y +# CONFIG_SERIAL_8250_16550A_VARIANTS is not set +CONFIG_SERIAL_8250_FINTEK=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DMA=y +CONFIG_SERIAL_8250_PCILIB=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_EXAR=y +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +# CONFIG_SERIAL_8250_PCI1XXXX is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_DWLIB=y +CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_RT288X is not set +# CONFIG_SERIAL_8250_LPSS is not set +CONFIG_SERIAL_8250_MID=y +CONFIG_SERIAL_8250_PERICOM=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +# CONFIG_SERIAL_LANTIQ is not set +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_ARC is not set +CONFIG_SERIAL_RP2=m +CONFIG_SERIAL_RP2_NR_UARTS=32 +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_FSL_LINFLEXUART is not set +# CONFIG_SERIAL_SPRD is not set +# end of Serial drivers + +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_MOXA_INTELLIO=m +CONFIG_MOXA_SMARTIO=m +CONFIG_N_HDLC=m +CONFIG_N_GSM=m +CONFIG_NOZOMI=m +# CONFIG_NULL_TTY is not set +CONFIG_HVC_DRIVER=y +CONFIG_HVC_IRQ=y +CONFIG_HVC_XEN=y +CONFIG_HVC_XEN_FRONTEND=y +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +CONFIG_TTY_PRINTK=m +CONFIG_TTY_PRINTK_LEVEL=6 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +CONFIG_VIRTIO_CONSOLE=m +CONFIG_IPMI_HANDLER=m +CONFIG_IPMI_DMI_DECODE=y +CONFIG_IPMI_PLAT_DATA=y +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +# CONFIG_IPMI_SSIF is not set +# CONFIG_IPMI_IPMB is not set +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +# CONFIG_SSIF_IPMI_BMC is not set +# CONFIG_IPMB_DEVICE_INTERFACE is not set +CONFIG_HW_RANDOM=m +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_AMD=m +# CONFIG_HW_RANDOM_BA431 is not set +CONFIG_HW_RANDOM_VIA=m +CONFIG_HW_RANDOM_VIRTIO=m +# CONFIG_HW_RANDOM_XIPHERA is not set +# CONFIG_APPLICOM is not set +# CONFIG_MWAVE is not set +CONFIG_DEVMEM=y +CONFIG_NVRAM=m +CONFIG_DEVPORT=y +CONFIG_HPET=y +CONFIG_HPET_MMAP=y +CONFIG_HPET_MMAP_DEFAULT=y +CONFIG_HANGCHECK_TIMER=m +CONFIG_TCG_TPM=m +CONFIG_HW_RANDOM_TPM=y +CONFIG_TCG_TIS_CORE=m +CONFIG_TCG_TIS=m +# CONFIG_TCG_TIS_I2C is not set +# CONFIG_TCG_TIS_I2C_CR50 is not set +CONFIG_TCG_TIS_I2C_ATMEL=m +CONFIG_TCG_TIS_I2C_INFINEON=m +CONFIG_TCG_TIS_I2C_NUVOTON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_XEN=m +CONFIG_TCG_CRB=m +# CONFIG_TCG_VTPM_PROXY is not set +CONFIG_TCG_TIS_ST33ZP24=m +CONFIG_TCG_TIS_ST33ZP24_I2C=m +# CONFIG_TELCLOCK is not set +# CONFIG_XILLYBUS is not set +# CONFIG_XILLYUSB is not set +# end of Character devices + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_ACPI_I2C_OPREGION=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_MUX=m + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_LTC4306 is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +# CONFIG_I2C_MUX_REG is not set +# CONFIG_I2C_MUX_MLXCPLD is not set +# end of Multiplexer I2C Chip support + +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_SMBUS=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +CONFIG_I2C_CCGX_UCSI=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +# CONFIG_I2C_AMD_MP2 is not set +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_ISMT=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_CHT_WC=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NFORCE2_S4985=m +# CONFIG_I2C_NVIDIA_GPU is not set +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m + +# +# ACPI drivers +# +CONFIG_I2C_SCMI=m + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_CBUS_GPIO is not set +CONFIG_I2C_DESIGNWARE_CORE=y +# CONFIG_I2C_DESIGNWARE_SLAVE is not set +CONFIG_I2C_DESIGNWARE_PLATFORM=y +# CONFIG_I2C_DESIGNWARE_BAYTRAIL is not set +CONFIG_I2C_DESIGNWARE_PCI=m +# CONFIG_I2C_EMEV2 is not set +# CONFIG_I2C_GPIO is not set +CONFIG_I2C_KEMPLD=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_XILINX=m + +# +# External I2C/SMBus adapter drivers +# +CONFIG_I2C_DIOLAN_U2C=m +# CONFIG_I2C_CP2615 is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PCI1XXXX is not set +CONFIG_I2C_ROBOTFUZZ_OSIF=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIPERBOARD=m + +# +# Other I2C/SMBus bus drivers +# +CONFIG_I2C_MLXCPLD=m +# CONFIG_I2C_VIRTIO is not set +# end of I2C Hardware Bus support + +CONFIG_I2C_STUB=m +CONFIG_I2C_SLAVE=y +CONFIG_I2C_SLAVE_EEPROM=m +# CONFIG_I2C_SLAVE_TESTUNIT is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# end of I2C support + +# CONFIG_I3C is not set +# CONFIG_SPI is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set +CONFIG_PPS=y +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +CONFIG_PPS_CLIENT_LDISC=m +# CONFIG_PPS_CLIENT_PARPORT is not set +# CONFIG_PPS_CLIENT_GPIO is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_PTP_1588_CLOCK_KVM=y +# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set +# CONFIG_PTP_1588_CLOCK_IDTCM is not set +# CONFIG_PTP_1588_CLOCK_MOCK is not set +# CONFIG_PTP_1588_CLOCK_VMW is not set +# end of PTP clock support + +CONFIG_PINCTRL=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +CONFIG_PINCTRL_AMD=y +# CONFIG_PINCTRL_CY8C95X0 is not set +# CONFIG_PINCTRL_MCP23S08 is not set +# CONFIG_PINCTRL_SX150X is not set + +# +# Intel pinctrl drivers +# +CONFIG_PINCTRL_BAYTRAIL=y +CONFIG_PINCTRL_CHERRYVIEW=y +# CONFIG_PINCTRL_LYNXPOINT is not set +CONFIG_PINCTRL_INTEL=y +# CONFIG_PINCTRL_ALDERLAKE is not set +CONFIG_PINCTRL_BROXTON=y +# CONFIG_PINCTRL_CANNONLAKE is not set +# CONFIG_PINCTRL_CEDARFORK is not set +# CONFIG_PINCTRL_DENVERTON is not set +# CONFIG_PINCTRL_ELKHARTLAKE is not set +# CONFIG_PINCTRL_EMMITSBURG is not set +# CONFIG_PINCTRL_GEMINILAKE is not set +# CONFIG_PINCTRL_ICELAKE is not set +# CONFIG_PINCTRL_JASPERLAKE is not set +# CONFIG_PINCTRL_LAKEFIELD is not set +# CONFIG_PINCTRL_LEWISBURG is not set +# CONFIG_PINCTRL_METEORLAKE is not set +CONFIG_PINCTRL_SUNRISEPOINT=y +# CONFIG_PINCTRL_TIGERLAKE is not set +# end of Intel pinctrl drivers + +# +# Renesas pinctrl drivers +# +# end of Renesas pinctrl drivers + +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_FASTPATH_LIMIT=512 +CONFIG_GPIO_ACPI=y +CONFIG_GPIOLIB_IRQCHIP=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_CDEV_V1=y +CONFIG_GPIO_GENERIC=m + +# +# Memory mapped GPIO drivers +# +CONFIG_GPIO_AMDPT=m +# CONFIG_GPIO_DWAPB is not set +# CONFIG_GPIO_EXAR is not set +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_ICH is not set +# CONFIG_GPIO_MB86S7X is not set +CONFIG_GPIO_AMD_FCH=m +# end of Memory mapped GPIO drivers + +# +# Port-mapped I/O GPIO drivers +# +# CONFIG_GPIO_VX855 is not set +# CONFIG_GPIO_F7188X is not set +# CONFIG_GPIO_IT87 is not set +# CONFIG_GPIO_SCH is not set +# CONFIG_GPIO_SCH311X is not set +# CONFIG_GPIO_WINBOND is not set +# CONFIG_GPIO_WS16C48 is not set +# end of Port-mapped I/O GPIO drivers + +# +# I2C GPIO expanders +# +# CONFIG_GPIO_FXL6408 is not set +# CONFIG_GPIO_DS4520 is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCA9570 is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_TPIC2810 is not set +# end of I2C GPIO expanders + +# +# MFD GPIO expanders +# +# CONFIG_GPIO_ELKHARTLAKE is not set +CONFIG_GPIO_KEMPLD=m +# end of MFD GPIO expanders + +# +# PCI GPIO expanders +# +# CONFIG_GPIO_AMD8111 is not set +# CONFIG_GPIO_BT8XX is not set +CONFIG_GPIO_ML_IOH=m +# CONFIG_GPIO_PCI_IDIO_16 is not set +# CONFIG_GPIO_PCIE_IDIO_24 is not set +# CONFIG_GPIO_RDC321X is not set +# end of PCI GPIO expanders + +# +# USB GPIO expanders +# +CONFIG_GPIO_VIPERBOARD=m +# end of USB GPIO expanders + +# +# Virtual GPIO drivers +# +# CONFIG_GPIO_AGGREGATOR is not set +# CONFIG_GPIO_LATCH is not set +# CONFIG_GPIO_MOCKUP is not set +# CONFIG_GPIO_VIRTIO is not set +# CONFIG_GPIO_SIM is not set +# end of Virtual GPIO drivers + +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_GPIO=m +# CONFIG_W1_MASTER_SGI is not set +# end of 1-wire Bus Masters + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2405=m +CONFIG_W1_SLAVE_DS2408=m +CONFIG_W1_SLAVE_DS2408_READBACK=y +CONFIG_W1_SLAVE_DS2413=m +CONFIG_W1_SLAVE_DS2406=m +CONFIG_W1_SLAVE_DS2423=m +CONFIG_W1_SLAVE_DS2805=m +# CONFIG_W1_SLAVE_DS2430 is not set +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +CONFIG_W1_SLAVE_DS2433_CRC=y +CONFIG_W1_SLAVE_DS2438=m +# CONFIG_W1_SLAVE_DS250X is not set +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_DS2781=m +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_W1_SLAVE_DS28E17=m +# end of 1-wire Slaves + +# CONFIG_POWER_RESET is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_POWER_SUPPLY_HWMON=y +# CONFIG_IP5XXX_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_CHARGER_ADP5061 is not set +# CONFIG_BATTERY_CW2015 is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_SAMSUNG_SDI is not set +CONFIG_BATTERY_SBS=m +# CONFIG_CHARGER_SBS is not set +# CONFIG_MANAGER_SBS is not set +CONFIG_BATTERY_BQ27XXX=m +# CONFIG_BATTERY_BQ27XXX_I2C is not set +CONFIG_BATTERY_BQ27XXX_HDQ=m +# CONFIG_BATTERY_MAX17040 is not set +CONFIG_BATTERY_MAX17042=m +# CONFIG_BATTERY_MAX1721X is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +# CONFIG_CHARGER_GPIO is not set +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_CHARGER_LT3651 is not set +# CONFIG_CHARGER_LTC4162L is not set +# CONFIG_CHARGER_MAX77976 is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24257 is not set +# CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ2515X is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_BQ25980 is not set +# CONFIG_CHARGER_BQ256XX is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_BATTERY_GOLDFISH is not set +# CONFIG_BATTERY_RT5033 is not set +# CONFIG_CHARGER_RT9455 is not set +# CONFIG_CHARGER_RT9467 is not set +# CONFIG_CHARGER_RT9471 is not set +# CONFIG_CHARGER_BD99954 is not set +# CONFIG_BATTERY_UG3105 is not set +CONFIG_HWMON=y +CONFIG_HWMON_VID=m +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +# CONFIG_SENSORS_ADM1177 is not set +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7X10=m +CONFIG_SENSORS_ADT7410=m +CONFIG_SENSORS_ADT7411=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7475=m +# CONFIG_SENSORS_AHT10 is not set +# CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set +# CONFIG_SENSORS_AS370 is not set +CONFIG_SENSORS_ASC7621=m +# CONFIG_SENSORS_AXI_FAN_CONTROL is not set +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_K10TEMP=m +CONFIG_SENSORS_FAM15H_POWER=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +# CONFIG_SENSORS_CORSAIR_CPRO is not set +# CONFIG_SENSORS_CORSAIR_PSU is not set +CONFIG_SENSORS_DRIVETEMP=m +CONFIG_SENSORS_DS620=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_DELL_SMM=m +# CONFIG_I8K is not set +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_FTSTEUTATES=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_G760A=m +CONFIG_SENSORS_G762=m +CONFIG_SENSORS_HIH6130=m +# CONFIG_SENSORS_HS3001 is not set +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_I5500=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_JC42=m +CONFIG_SENSORS_POWR1220=m +CONFIG_SENSORS_LINEAGE=m +CONFIG_SENSORS_LTC2945=m +# CONFIG_SENSORS_LTC2947_I2C is not set +CONFIG_SENSORS_LTC2990=m +# CONFIG_SENSORS_LTC2992 is not set +CONFIG_SENSORS_LTC4151=m +CONFIG_SENSORS_LTC4215=m +CONFIG_SENSORS_LTC4222=m +CONFIG_SENSORS_LTC4245=m +CONFIG_SENSORS_LTC4260=m +CONFIG_SENSORS_LTC4261=m +# CONFIG_SENSORS_MAX127 is not set +CONFIG_SENSORS_MAX16065=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX1668=m +CONFIG_SENSORS_MAX197=m +# CONFIG_SENSORS_MAX31730 is not set +# CONFIG_SENSORS_MAX31760 is not set +# CONFIG_MAX31827 is not set +# CONFIG_SENSORS_MAX6620 is not set +CONFIG_SENSORS_MAX6621=m +CONFIG_SENSORS_MAX6639=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6697=m +CONFIG_SENSORS_MAX31790=m +# CONFIG_SENSORS_MC34VR500 is not set +CONFIG_SENSORS_MCP3021=m +CONFIG_SENSORS_TC654=m +# CONFIG_SENSORS_TPS23861 is not set +CONFIG_SENSORS_MENF21BMC_HWMON=m +# CONFIG_SENSORS_MR75203 is not set +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM73=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_LM95234=m +CONFIG_SENSORS_LM95241=m +CONFIG_SENSORS_LM95245=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_NCT6683=m +CONFIG_SENSORS_NCT6775_CORE=m +CONFIG_SENSORS_NCT6775=m +# CONFIG_SENSORS_NCT6775_I2C is not set +CONFIG_SENSORS_NCT7802=m +CONFIG_SENSORS_NCT7904=m +CONFIG_SENSORS_NPCM7XX=m +# CONFIG_SENSORS_NZXT_KRAKEN2 is not set +# CONFIG_SENSORS_NZXT_SMART2 is not set +# CONFIG_SENSORS_OCC_P8_I2C is not set +# CONFIG_SENSORS_OXP is not set +CONFIG_SENSORS_PCF8591=m +CONFIG_PMBUS=m +CONFIG_SENSORS_PMBUS=m +# CONFIG_SENSORS_ACBEL_FSG032 is not set +# CONFIG_SENSORS_ADM1266 is not set +CONFIG_SENSORS_ADM1275=m +# CONFIG_SENSORS_BEL_PFE is not set +# CONFIG_SENSORS_BPA_RS600 is not set +# CONFIG_SENSORS_DELTA_AHE50DC_FAN is not set +# CONFIG_SENSORS_FSP_3Y is not set +CONFIG_SENSORS_IBM_CFFPS=m +# CONFIG_SENSORS_DPS920AB is not set +# CONFIG_SENSORS_INSPUR_IPSPS is not set +CONFIG_SENSORS_IR35221=m +# CONFIG_SENSORS_IR36021 is not set +# CONFIG_SENSORS_IR38064 is not set +# CONFIG_SENSORS_IRPS5401 is not set +# CONFIG_SENSORS_ISL68137 is not set +CONFIG_SENSORS_LM25066=m +# CONFIG_SENSORS_LM25066_REGULATOR is not set +# CONFIG_SENSORS_LT7182S is not set +CONFIG_SENSORS_LTC2978=m +CONFIG_SENSORS_LTC2978_REGULATOR=y +CONFIG_SENSORS_LTC3815=m +# CONFIG_SENSORS_MAX15301 is not set +CONFIG_SENSORS_MAX16064=m +# CONFIG_SENSORS_MAX16601 is not set +# CONFIG_SENSORS_MAX20730 is not set +CONFIG_SENSORS_MAX20751=m +CONFIG_SENSORS_MAX31785=m +CONFIG_SENSORS_MAX34440=m +CONFIG_SENSORS_MAX8688=m +# CONFIG_SENSORS_MP2888 is not set +# CONFIG_SENSORS_MP2975 is not set +# CONFIG_SENSORS_MP5023 is not set +# CONFIG_SENSORS_MPQ7932 is not set +# CONFIG_SENSORS_PIM4328 is not set +# CONFIG_SENSORS_PLI1209BC is not set +# CONFIG_SENSORS_PM6764TR is not set +# CONFIG_SENSORS_PXE1610 is not set +# CONFIG_SENSORS_Q54SJ108A2 is not set +# CONFIG_SENSORS_STPDDC60 is not set +# CONFIG_SENSORS_TDA38640 is not set +CONFIG_SENSORS_TPS40422=m +CONFIG_SENSORS_TPS53679=m +# CONFIG_SENSORS_TPS546D24 is not set +CONFIG_SENSORS_UCD9000=m +CONFIG_SENSORS_UCD9200=m +# CONFIG_SENSORS_XDPE152 is not set +# CONFIG_SENSORS_XDPE122 is not set +CONFIG_SENSORS_ZL6100=m +# CONFIG_SENSORS_SBTSI is not set +# CONFIG_SENSORS_SBRMI is not set +CONFIG_SENSORS_SHT15=m +CONFIG_SENSORS_SHT21=m +CONFIG_SENSORS_SHT3x=m +# CONFIG_SENSORS_SHT4x is not set +CONFIG_SENSORS_SHTC1=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_EMC1403=m +CONFIG_SENSORS_EMC2103=m +# CONFIG_SENSORS_EMC2305 is not set +CONFIG_SENSORS_EMC6W201=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SCH56XX_COMMON=m +CONFIG_SENSORS_SCH5627=m +CONFIG_SENSORS_SCH5636=m +CONFIG_SENSORS_STTS751=m +CONFIG_SENSORS_ADC128D818=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_AMC6821=m +CONFIG_SENSORS_INA209=m +CONFIG_SENSORS_INA2XX=m +# CONFIG_SENSORS_INA238 is not set +CONFIG_SENSORS_INA3221=m +CONFIG_SENSORS_TC74=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TMP102=m +CONFIG_SENSORS_TMP103=m +CONFIG_SENSORS_TMP108=m +CONFIG_SENSORS_TMP401=m +CONFIG_SENSORS_TMP421=m +# CONFIG_SENSORS_TMP464 is not set +# CONFIG_SENSORS_TMP513 is not set +CONFIG_SENSORS_VIA_CPUTEMP=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83773G=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83795=m +# CONFIG_SENSORS_W83795_FANCTRL is not set +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_XGENE=m + +# +# ACPI drivers +# +CONFIG_SENSORS_ACPI_POWER=m +CONFIG_SENSORS_ATK0110=m +# CONFIG_SENSORS_ASUS_EC is not set +CONFIG_THERMAL=y +# CONFIG_THERMAL_NETLINK is not set +# CONFIG_THERMAL_STATISTICS is not set +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_ACPI=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_BANG_BANG is not set +CONFIG_THERMAL_GOV_FAIR_SHARE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_GOV_BANG_BANG=y +CONFIG_THERMAL_GOV_USER_SPACE=y +# CONFIG_DEVFREQ_THERMAL is not set +# CONFIG_THERMAL_EMULATION is not set + +# +# Intel thermal drivers +# +CONFIG_INTEL_POWERCLAMP=m +CONFIG_X86_THERMAL_VECTOR=y +CONFIG_INTEL_TCC=y +CONFIG_X86_PKG_TEMP_THERMAL=m +CONFIG_INTEL_SOC_DTS_IOSF_CORE=m +CONFIG_INTEL_SOC_DTS_THERMAL=m + +# +# ACPI INT340X thermal drivers +# +CONFIG_INT340X_THERMAL=m +CONFIG_ACPI_THERMAL_REL=m +CONFIG_PROC_THERMAL_MMIO_RAPL=m +# end of ACPI INT340X thermal drivers + +CONFIG_INTEL_PCH_THERMAL=m +# CONFIG_INTEL_TCC_COOLING is not set +# CONFIG_INTEL_HFI_THERMAL is not set +# end of Intel thermal drivers + +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y +CONFIG_WATCHDOG_OPEN_TIMEOUT=0 +CONFIG_WATCHDOG_SYSFS=y +# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set + +# +# Watchdog Pretimeout Governors +# +# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +CONFIG_MENF21BMC_WATCHDOG=m +# CONFIG_WDAT_WDT is not set +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_ZIIRAVE_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set +CONFIG_ACQUIRE_WDT=m +CONFIG_ADVANTECH_WDT=m +# CONFIG_ADVANTECH_EC_WDT is not set +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +# CONFIG_EBC_C384_WDT is not set +# CONFIG_EXAR_WDT is not set +CONFIG_F71808E_WDT=m +CONFIG_SP5100_TCO=m +CONFIG_SBC_FITPC2_WATCHDOG=m +CONFIG_EUROTECH_WDT=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_WAFER_WDT=m +CONFIG_I6300ESB_WDT=m +CONFIG_IE6XX_WDT=m +CONFIG_ITCO_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_IT8712F_WDT=m +CONFIG_IT87_WDT=m +CONFIG_HP_WATCHDOG=m +CONFIG_HPWDT_NMI_DECODING=y +CONFIG_KEMPLD_WDT=m +CONFIG_SC1200_WDT=m +CONFIG_PC87413_WDT=m +CONFIG_NV_TCO=m +CONFIG_60XX_WDT=m +CONFIG_CPU5_WDT=m +CONFIG_SMSC_SCH311X_WDT=m +CONFIG_SMSC37B787_WDT=m +# CONFIG_TQMX86_WDT is not set +CONFIG_VIA_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_MACHZ_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +# CONFIG_INTEL_MEI_WDT is not set +# CONFIG_NI903X_WDT is not set +# CONFIG_NIC7018_WDT is not set +# CONFIG_MEN_A21_WDT is not set +CONFIG_XEN_WDT=m + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_B43_PCI_BRIDGE=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +CONFIG_SSB_SDIOHOST=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +# CONFIG_SSB_DRIVER_GPIO is not set +CONFIG_BCMA_POSSIBLE=y +CONFIG_BCMA=m +CONFIG_BCMA_BLOCKIO=y +CONFIG_BCMA_HOST_PCI_POSSIBLE=y +CONFIG_BCMA_HOST_PCI=y +# CONFIG_BCMA_HOST_SOC is not set +CONFIG_BCMA_DRIVER_PCI=y +# CONFIG_BCMA_DRIVER_GMAC_CMN is not set +# CONFIG_BCMA_DRIVER_GPIO is not set +# CONFIG_BCMA_DEBUG is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_SMPRO is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_BD9571MWV is not set +CONFIG_MFD_AXP20X=m +CONFIG_MFD_AXP20X_I2C=m +# CONFIG_MFD_CS42L43_I2C is not set +# CONFIG_MFD_MADERA is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_MP2629 is not set +# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set +CONFIG_LPC_ICH=m +CONFIG_LPC_SCH=m +# CONFIG_INTEL_SOC_PMIC is not set +CONFIG_INTEL_SOC_PMIC_CHTWC=y +# CONFIG_INTEL_SOC_PMIC_CHTDC_TI is not set +CONFIG_MFD_INTEL_LPSS=m +CONFIG_MFD_INTEL_LPSS_ACPI=m +CONFIG_MFD_INTEL_LPSS_PCI=m +# CONFIG_MFD_INTEL_PMC_BXT is not set +# CONFIG_MFD_IQS62X is not set +# CONFIG_MFD_JANZ_CMODIO is not set +CONFIG_MFD_KEMPLD=m +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_MAX77541 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6360 is not set +# CONFIG_MFD_MT6370 is not set +# CONFIG_MFD_MT6397 is not set +CONFIG_MFD_MENF21BMC=m +CONFIG_MFD_VIPERBOARD=m +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_SY7636A is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_RT4831 is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RT5120 is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +CONFIG_MFD_SYSCON=y +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_TI_LMU is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65086 is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TI_LP873X is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS6594_I2C is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TQMX86 is not set +# CONFIG_MFD_VX855 is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_ATC260X_I2C is not set +# CONFIG_RAVE_SP_CORE is not set +# end of Multifunction device drivers + +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +CONFIG_REGULATOR_FIXED_VOLTAGE=m +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m +CONFIG_REGULATOR_USERSPACE_CONSUMER=m +CONFIG_REGULATOR_88PG86X=m +CONFIG_REGULATOR_ACT8865=m +CONFIG_REGULATOR_AD5398=m +# CONFIG_REGULATOR_AW37503 is not set +CONFIG_REGULATOR_AXP20X=m +CONFIG_REGULATOR_DA9210=m +CONFIG_REGULATOR_DA9211=m +CONFIG_REGULATOR_FAN53555=m +CONFIG_REGULATOR_GPIO=m +CONFIG_REGULATOR_ISL9305=m +CONFIG_REGULATOR_ISL6271A=m +CONFIG_REGULATOR_LP3971=m +CONFIG_REGULATOR_LP3972=m +CONFIG_REGULATOR_LP872X=m +CONFIG_REGULATOR_LP8755=m +CONFIG_REGULATOR_LTC3589=m +CONFIG_REGULATOR_LTC3676=m +CONFIG_REGULATOR_MAX1586=m +# CONFIG_REGULATOR_MAX77857 is not set +CONFIG_REGULATOR_MAX8649=m +CONFIG_REGULATOR_MAX8660=m +# CONFIG_REGULATOR_MAX8893 is not set +CONFIG_REGULATOR_MAX8952=m +# CONFIG_REGULATOR_MAX20086 is not set +# CONFIG_REGULATOR_MAX20411 is not set +# CONFIG_REGULATOR_MAX77826 is not set +# CONFIG_REGULATOR_MP8859 is not set +CONFIG_REGULATOR_MT6311=m +# CONFIG_REGULATOR_PCA9450 is not set +CONFIG_REGULATOR_PV88060=m +CONFIG_REGULATOR_PV88080=m +CONFIG_REGULATOR_PV88090=m +# CONFIG_REGULATOR_RAA215300 is not set +# CONFIG_REGULATOR_RT4801 is not set +# CONFIG_REGULATOR_RT4803 is not set +# CONFIG_REGULATOR_RT5190A is not set +# CONFIG_REGULATOR_RT5739 is not set +# CONFIG_REGULATOR_RT5759 is not set +# CONFIG_REGULATOR_RT6160 is not set +# CONFIG_REGULATOR_RT6190 is not set +# CONFIG_REGULATOR_RT6245 is not set +# CONFIG_REGULATOR_RTQ2134 is not set +# CONFIG_REGULATOR_RTMV20 is not set +# CONFIG_REGULATOR_RTQ6752 is not set +# CONFIG_REGULATOR_RTQ2208 is not set +# CONFIG_REGULATOR_SLG51000 is not set +CONFIG_REGULATOR_TPS51632=m +CONFIG_REGULATOR_TPS62360=m +CONFIG_REGULATOR_TPS65023=m +CONFIG_REGULATOR_TPS6507X=m +CONFIG_REGULATOR_TPS65132=m +# CONFIG_RC_CORE is not set + +# +# CEC support +# +# CONFIG_MEDIA_CEC_SUPPORT is not set +# end of CEC support + +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +CONFIG_APERTURE_HELPERS=y +CONFIG_SCREEN_INFO=y +CONFIG_VIDEO_CMDLINE=y +# CONFIG_AUXDISPLAY is not set +# CONFIG_PANEL is not set +# CONFIG_AGP is not set +# CONFIG_VGA_SWITCHEROO is not set +# CONFIG_DRM is not set +# CONFIG_DRM_DEBUG_MODESET_LOCK is not set +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y + +# +# Frame buffer Devices +# +CONFIG_FB=y +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ARC is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_UVESA is not set +CONFIG_FB_VESA=y +CONFIG_FB_EFI=y +# CONFIG_FB_N411 is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_VIA is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_XEN_FBDEV_FRONTEND is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_HYPERV is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SSD1307 is not set +# CONFIG_FB_SM712 is not set +CONFIG_FB_CORE=y +CONFIG_FB_NOTIFY=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_DEVICE=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_IOMEM_FOPS=y +CONFIG_FB_IOMEM_HELPERS=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +# end of Frame buffer Devices + +# +# Backlight & LCD device support +# +# CONFIG_LCD_CLASS_DEVICE is not set +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set +# end of Backlight & LCD device support + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=80 +CONFIG_DUMMY_CONSOLE_ROWS=25 +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +# end of Console display driver support + +# CONFIG_LOGO is not set +# end of Graphics support + +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=m +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +# CONFIG_UHID is not set +CONFIG_HID_GENERIC=m + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACCUTOUCH is not set +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_APPLEIR is not set +# CONFIG_HID_ASUS is not set +# CONFIG_HID_AUREAL is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_BETOP_FF is not set +# CONFIG_HID_BIGBEN_FF is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CORSAIR is not set +# CONFIG_HID_COUGAR is not set +# CONFIG_HID_MACALLY is not set +# CONFIG_HID_CMEDIA is not set +# CONFIG_HID_CP2112 is not set +# CONFIG_HID_CREATIVE_SB0540 is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELAN is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_ELO is not set +# CONFIG_HID_EVISION is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_FT260 is not set +# CONFIG_HID_GEMBIRD is not set +# CONFIG_HID_GFRM is not set +# CONFIG_HID_GLORIOUS is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_GOOGLE_STADIA_FF is not set +# CONFIG_HID_VIVALDI is not set +# CONFIG_HID_GT683R is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_VIEWSONIC is not set +# CONFIG_HID_VRC2 is not set +# CONFIG_HID_XIAOMI is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_ICADE is not set +# CONFIG_HID_ITE is not set +# CONFIG_HID_JABRA is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LED is not set +# CONFIG_HID_LENOVO is not set +# CONFIG_HID_LETSKETCH is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MALTRON is not set +# CONFIG_HID_MAYFLASH is not set +# CONFIG_HID_MEGAWORLD_FF is not set +# CONFIG_HID_REDRAGON is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_NINTENDO is not set +# CONFIG_HID_NTI is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PENMOUNT is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PLANTRONICS is not set +# CONFIG_HID_PXRC is not set +# CONFIG_HID_RAZER is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_RETRODE is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SEMITEK is not set +# CONFIG_HID_SIGMAMICRO is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEAM is not set +# CONFIG_HID_STEELSERIES is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_RMI is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_HYPERV_MOUSE is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_TOPRE is not set +# CONFIG_HID_THINGM is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_UDRAW_PS3 is not set +# CONFIG_HID_U2FZERO is not set +# CONFIG_HID_UNIVERSAL_PIDFF is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_WIIMOTE is not set +# CONFIG_HID_XINMO is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +# CONFIG_HID_SENSOR_HUB is not set +# CONFIG_HID_ALPS is not set +# CONFIG_HID_MCP2200 is not set +# CONFIG_HID_MCP2221 is not set +# end of Special HID drivers + +# +# HID-BPF support +# +# end of HID-BPF support + +# +# USB HID support +# +CONFIG_USB_HID=m +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# end of USB HID Boot Protocol drivers +# end of USB HID support + +CONFIG_I2C_HID=m +# CONFIG_I2C_HID_ACPI is not set +# CONFIG_I2C_HID_OF is not set + +# +# Intel ISH HID support +# +# CONFIG_INTEL_ISH_HID is not set +# end of Intel ISH HID support + +# +# AMD SFH HID Support +# +# CONFIG_AMD_SFH_HID is not set +# end of AMD SFH HID Support + +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +# CONFIG_USB_LED_TRIG is not set +# CONFIG_USB_ULPI_BUS is not set +# CONFIG_USB_CONN_GPIO is not set +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_PCI=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_FEW_INIT_RETRIES is not set +CONFIG_USB_DYNAMIC_MINORS=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_PRODUCTLIST is not set +# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set +# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set +CONFIG_USB_AUTOSUSPEND_DELAY=2 +# CONFIG_USB_MON is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_XHCI_HCD=m +# CONFIG_USB_XHCI_DBGCAP is not set +CONFIG_USB_XHCI_PCI=m +# CONFIG_USB_XHCI_PCI_RENESAS is not set +# CONFIG_USB_XHCI_PLATFORM is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=m +# CONFIG_USB_EHCI_FSL is not set +# CONFIG_USB_EHCI_HCD_PLATFORM is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_HCD_PCI=m +# CONFIG_USB_OHCI_HCD_SSB is not set +# CONFIG_USB_OHCI_HCD_PLATFORM is not set +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_SL811_HCD=m +# CONFIG_USB_SL811_HCD_ISO is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HCD_BCMA is not set +# CONFIG_USB_HCD_SSB is not set +# CONFIG_USB_HCD_TEST_MODE is not set +# CONFIG_USB_XEN_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +# CONFIG_USB_PRINTER is not set +CONFIG_USB_WDM=m +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_UAS is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set + +# +# USB dual-mode controller drivers +# +# CONFIG_USB_CDNS_SUPPORT is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_DWC2 is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_ISP1760 is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_SIMPLE=m +# CONFIG_USB_SERIAL_AIRCABLE is not set +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=m +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_F81232=m +CONFIG_USB_SERIAL_F8153X=m +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +CONFIG_USB_SERIAL_IUU=m +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +CONFIG_USB_SERIAL_KEYSPAN=m +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +CONFIG_USB_SERIAL_MCT_U232=m +# CONFIG_USB_SERIAL_METRO is not set +CONFIG_USB_SERIAL_MOS7720=m +# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MXUPORT=m +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +# CONFIG_USB_SERIAL_SYMBOL is not set +CONFIG_USB_SERIAL_TI=m +# CONFIG_USB_SERIAL_CYBERJACK is not set +CONFIG_USB_SERIAL_WWAN=m +CONFIG_USB_SERIAL_OPTION=m +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_XSENS_MT is not set +# CONFIG_USB_SERIAL_WISHBONE is not set +CONFIG_USB_SERIAL_SSU100=m +CONFIG_USB_SERIAL_QT2=m +CONFIG_USB_SERIAL_UPD78F0730=m +# CONFIG_USB_SERIAL_XR is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_USS720 is not set +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_APPLE_MFI_FASTCHARGE is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_EZUSB_FX2=m +# CONFIG_USB_HUB_USB251XB is not set +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_HSIC_USB4604 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set + +# +# USB Physical Layer drivers +# +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +# end of USB Physical Layer drivers + +# CONFIG_USB_GADGET is not set +# CONFIG_TYPEC is not set +# CONFIG_USB_ROLE_SWITCH is not set +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_MINORS=256 +CONFIG_SDIO_UART=m +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_RICOH_MMC=y +CONFIG_MMC_SDHCI_ACPI=m +CONFIG_MMC_SDHCI_PLTFM=m +CONFIG_MMC_SDHCI_F_SDH30=m +CONFIG_MMC_WBSD=m +CONFIG_MMC_TIFM_SD=m +CONFIG_MMC_CB710=m +CONFIG_MMC_VIA_SDMMC=m +CONFIG_MMC_VUB300=m +CONFIG_MMC_USHC=m +CONFIG_MMC_USDHI6ROL0=m +CONFIG_MMC_REALTEK_PCI=m +CONFIG_MMC_REALTEK_USB=m +CONFIG_MMC_CQHCI=m +# CONFIG_MMC_HSQ is not set +# CONFIG_MMC_TOSHIBA_PCI is not set +CONFIG_MMC_MTK=m +CONFIG_MMC_SDHCI_XENON=m +CONFIG_SCSI_UFSHCD=m +# CONFIG_SCSI_UFS_BSG is not set +# CONFIG_SCSI_UFS_HWMON is not set +CONFIG_SCSI_UFSHCD_PCI=m +# CONFIG_SCSI_UFS_DWC_TC_PCI is not set +# CONFIG_SCSI_UFSHCD_PLATFORM is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_FLASH=m +# CONFIG_LEDS_CLASS_MULTICOLOR is not set +CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y + +# +# LED drivers +# +# CONFIG_LEDS_APU is not set +# CONFIG_LEDS_AW200XX is not set +# CONFIG_LEDS_CHT_WCOVE is not set +CONFIG_LEDS_LM3530=m +# CONFIG_LEDS_LM3532 is not set +CONFIG_LEDS_LM3642=m +CONFIG_LEDS_PCA9532=m +# CONFIG_LEDS_PCA9532_GPIO is not set +CONFIG_LEDS_GPIO=m +CONFIG_LEDS_LP3944=m +CONFIG_LEDS_LP3952=m +# CONFIG_LEDS_LP50XX is not set +CONFIG_LEDS_PCA955X=m +# CONFIG_LEDS_PCA955X_GPIO is not set +CONFIG_LEDS_PCA963X=m +# CONFIG_LEDS_PCA995X is not set +CONFIG_LEDS_REGULATOR=m +# CONFIG_LEDS_BD2606MVV is not set +CONFIG_LEDS_BD2802=m +CONFIG_LEDS_INTEL_SS4200=m +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TCA6507=m +CONFIG_LEDS_TLC591XX=m +CONFIG_LEDS_LM355x=m +CONFIG_LEDS_MENF21BMC=m +# CONFIG_LEDS_IS31FL319X is not set + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +CONFIG_LEDS_BLINKM=m +CONFIG_LEDS_MLXCPLD=m +CONFIG_LEDS_MLXREG=m +# CONFIG_LEDS_USER is not set +CONFIG_LEDS_NIC78BX=m + +# +# Flash and Torch LED drivers +# +CONFIG_LEDS_AS3645A=m +CONFIG_LEDS_LM3601X=m +# CONFIG_LEDS_RT8515 is not set +# CONFIG_LEDS_SGM3140 is not set + +# +# RGB LED drivers +# + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_ONESHOT=m +CONFIG_LEDS_TRIGGER_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_ACTIVITY=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_LEDS_TRIGGER_TRANSIENT=m +CONFIG_LEDS_TRIGGER_CAMERA=m +CONFIG_LEDS_TRIGGER_PANIC=y +CONFIG_LEDS_TRIGGER_NETDEV=m +# CONFIG_LEDS_TRIGGER_PATTERN is not set +# CONFIG_LEDS_TRIGGER_AUDIO is not set +# CONFIG_LEDS_TRIGGER_TTY is not set + +# +# Simple LED drivers +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_INFINIBAND=m +# CONFIG_INFINIBAND_USER_MAD is not set +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFINIBAND_ON_DEMAND_PAGING=y +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS=y +CONFIG_INFINIBAND_VIRT_DMA=y +# CONFIG_INFINIBAND_BNXT_RE is not set +# CONFIG_INFINIBAND_CXGB4 is not set +# CONFIG_INFINIBAND_EFA is not set +# CONFIG_INFINIBAND_ERDMA is not set +# CONFIG_INFINIBAND_IRDMA is not set +CONFIG_MLX4_INFINIBAND=m +CONFIG_MLX5_INFINIBAND=m +# CONFIG_INFINIBAND_MTHCA is not set +# CONFIG_INFINIBAND_OCRDMA is not set +# CONFIG_INFINIBAND_QEDR is not set +# CONFIG_INFINIBAND_USNIC is not set +# CONFIG_INFINIBAND_VMWARE_PVRDMA is not set +# CONFIG_INFINIBAND_RDMAVT is not set +# CONFIG_RDMA_RXE is not set +# CONFIG_RDMA_SIW is not set +# CONFIG_INFINIBAND_IPOIB is not set +# CONFIG_INFINIBAND_SRP is not set +# CONFIG_INFINIBAND_ISER is not set +# CONFIG_INFINIBAND_RTRS_CLIENT is not set +# CONFIG_INFINIBAND_RTRS_SERVER is not set +# CONFIG_INFINIBAND_OPA_VNIC is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EDAC=y +CONFIG_EDAC_LEGACY_SYSFS=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_DECODE_MCE=m +# CONFIG_EDAC_GHES is not set +CONFIG_EDAC_AMD64=m +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I3200=m +CONFIG_EDAC_IE31200=m +CONFIG_EDAC_X38=m +CONFIG_EDAC_I5400=m +CONFIG_EDAC_I7CORE=m +CONFIG_EDAC_I5100=m +CONFIG_EDAC_I7300=m +CONFIG_EDAC_SBRIDGE=m +CONFIG_EDAC_SKX=m +# CONFIG_EDAC_I10NM is not set +CONFIG_EDAC_PND2=m +# CONFIG_EDAC_IGEN6 is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_MC146818_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_NVMEM=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABEOZ9 is not set +# CONFIG_RTC_DRV_ABX80X is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF85363 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8010 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3028 is not set +# CONFIG_RTC_DRV_RV3032 is not set +# CONFIG_RTC_DRV_RV8803 is not set +# CONFIG_RTC_DRV_SD3078 is not set + +# +# SPI RTC drivers +# +CONFIG_RTC_I2C_AND_SPI=y + +# +# SPI and I2C RTC drivers +# +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set +# CONFIG_RTC_DRV_RX6110 is not set + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_RP5C01 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_FTRTC010 is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_GOLDFISH is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_DMA_ENGINE=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DMA_ACPI=y +# CONFIG_ALTERA_MSGDMA is not set +CONFIG_INTEL_IDMA64=y +CONFIG_INTEL_IDXD_BUS=y +CONFIG_INTEL_IDXD=y +# CONFIG_INTEL_IDXD_COMPAT is not set +# CONFIG_INTEL_IDXD_SVM is not set +# CONFIG_INTEL_IDXD_PERFMON is not set +CONFIG_INTEL_IOATDMA=y +# CONFIG_PLX_DMA is not set +# CONFIG_XILINX_DMA is not set +# CONFIG_XILINX_XDMA is not set +# CONFIG_AMD_PTDMA is not set +# CONFIG_QCOM_HIDMA_MGMT is not set +# CONFIG_QCOM_HIDMA is not set +# CONFIG_DW_DMAC is not set +# CONFIG_DW_DMAC_PCI is not set +# CONFIG_DW_EDMA is not set +CONFIG_HSU_DMA=y +# CONFIG_SF_PDMA is not set +# CONFIG_INTEL_LDMA is not set + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE_RAID=y + +# +# DMABUF options +# +CONFIG_SYNC_FILE=y +# CONFIG_SW_SYNC is not set +# CONFIG_UDMABUF is not set +# CONFIG_DMABUF_MOVE_NOTIFY is not set +# CONFIG_DMABUF_DEBUG is not set +# CONFIG_DMABUF_SELFTESTS is not set +# CONFIG_DMABUF_HEAPS is not set +# CONFIG_DMABUF_SYSFS_STATS is not set +# end of DMABUF options + +CONFIG_DCA=y +CONFIG_UIO=m +# CONFIG_UIO_CIF is not set +# CONFIG_UIO_PDRV_GENIRQ is not set +# CONFIG_UIO_DMEM_GENIRQ is not set +# CONFIG_UIO_AEC is not set +# CONFIG_UIO_SERCOS3 is not set +CONFIG_UIO_PCI_GENERIC=m +# CONFIG_UIO_NETX is not set +# CONFIG_UIO_PRUSS is not set +# CONFIG_UIO_MF624 is not set +CONFIG_UIO_HV_GENERIC=m +CONFIG_VFIO=m +CONFIG_VFIO_GROUP=y +CONFIG_VFIO_CONTAINER=y +CONFIG_VFIO_IOMMU_TYPE1=m +CONFIG_VFIO_NOIOMMU=y +CONFIG_VFIO_VIRQFD=y + +# +# VFIO support for PCI devices +# +CONFIG_VFIO_PCI_CORE=m +CONFIG_VFIO_PCI_MMAP=y +CONFIG_VFIO_PCI_INTX=y +CONFIG_VFIO_PCI=m +CONFIG_VFIO_PCI_IGD=y +CONFIG_MLX5_VFIO_PCI=m +# end of VFIO support for PCI devices + +CONFIG_IRQ_BYPASS_MANAGER=m +# CONFIG_VIRT_DRIVERS is not set +CONFIG_VIRTIO_ANCHOR=y +CONFIG_VIRTIO=m +CONFIG_VIRTIO_PCI_LIB=m +CONFIG_VIRTIO_PCI_LIB_LEGACY=m +CONFIG_VIRTIO_MENU=y +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_PCI_LEGACY=y +CONFIG_VIRTIO_VDPA=m +# CONFIG_VIRTIO_PMEM is not set +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_INPUT=m +CONFIG_VIRTIO_MMIO=m +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y +CONFIG_VDPA=m +# CONFIG_VDPA_USER is not set +# CONFIG_IFCVF is not set +# CONFIG_MLX5_VDPA_NET is not set +# CONFIG_MLX5_VDPA_STEERING_DEBUG is not set +# CONFIG_VP_VDPA is not set +# CONFIG_ALIBABA_ENI_VDPA is not set +# CONFIG_SNET_VDPA is not set +CONFIG_VHOST_IOTLB=m +CONFIG_VHOST_TASK=y +CONFIG_VHOST=m +CONFIG_VHOST_MENU=y +CONFIG_VHOST_NET=m +CONFIG_VHOST_VSOCK=m +CONFIG_VHOST_VDPA=m +# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_HYPERV=m +# CONFIG_HYPERV_VTL_MODE is not set +CONFIG_HYPERV_TIMER=y +CONFIG_HYPERV_UTILS=m +CONFIG_HYPERV_BALLOON=m +# end of Microsoft Hyper-V guest support + +# +# Xen driver support +# +CONFIG_XEN_BALLOON=y +CONFIG_XEN_SCRUB_PAGES_DEFAULT=y +CONFIG_XEN_DEV_EVTCHN=m +CONFIG_XEN_BACKEND=y +CONFIG_XENFS=m +CONFIG_XEN_COMPAT_XENFS=y +CONFIG_XEN_SYS_HYPERVISOR=y +CONFIG_XEN_XENBUS_FRONTEND=y +CONFIG_XEN_GNTDEV=m +CONFIG_XEN_GRANT_DEV_ALLOC=m +# CONFIG_XEN_GRANT_DMA_ALLOC is not set +CONFIG_SWIOTLB_XEN=y +CONFIG_XEN_PCI_STUB=y +CONFIG_XEN_PCIDEV_BACKEND=m +# CONFIG_XEN_PVCALLS_FRONTEND is not set +# CONFIG_XEN_PVCALLS_BACKEND is not set +CONFIG_XEN_PRIVCMD=m +CONFIG_XEN_ACPI_PROCESSOR=m +CONFIG_XEN_MCE_LOG=y +CONFIG_XEN_HAVE_PVMMU=y +CONFIG_XEN_EFI=y +CONFIG_XEN_AUTO_XLATE=y +CONFIG_XEN_ACPI=y +CONFIG_XEN_SYMS=y +CONFIG_XEN_HAVE_VPMU=y +# CONFIG_XEN_VIRTIO is not set +# end of Xen driver support + +# CONFIG_GREYBUS is not set +# CONFIG_COMEDI is not set +# CONFIG_STAGING is not set +# CONFIG_CHROME_PLATFORMS is not set +# CONFIG_MELLANOX_PLATFORM is not set +CONFIG_SURFACE_PLATFORMS=y +# CONFIG_SURFACE_3_POWER_OPREGION is not set +# CONFIG_SURFACE_GPE is not set +# CONFIG_SURFACE_HOTPLUG is not set +# CONFIG_SURFACE_PRO3_BUTTON is not set +# CONFIG_SURFACE_AGGREGATOR is not set +CONFIG_X86_PLATFORM_DEVICES=y +# CONFIG_ACPI_WMI is not set +# CONFIG_ACERHDF is not set +# CONFIG_ACER_WIRELESS is not set +# CONFIG_AMD_PMF is not set +# CONFIG_AMD_PMC is not set +# CONFIG_AMD_HSMP is not set +# CONFIG_ADV_SWBUTTON is not set +# CONFIG_ASUS_WIRELESS is not set +# CONFIG_ASUS_TF103C_DOCK is not set +# CONFIG_X86_PLATFORM_DRIVERS_DELL is not set +# CONFIG_AMILO_RFKILL is not set +# CONFIG_FUJITSU_TABLET is not set +# CONFIG_GPD_POCKET_FAN is not set +# CONFIG_X86_PLATFORM_DRIVERS_HP is not set +# CONFIG_WIRELESS_HOTKEY is not set +# CONFIG_IBM_RTL is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_INTEL_ATOMISP2_LED is not set +# CONFIG_INTEL_ATOMISP2_PM is not set +# CONFIG_INTEL_IFS is not set +# CONFIG_INTEL_SAR_INT1092 is not set +# CONFIG_INTEL_SKL_INT3472 is not set +# CONFIG_INTEL_PMC_CORE is not set + +# +# Intel Speed Select Technology interface support +# +# CONFIG_INTEL_SPEED_SELECT_INTERFACE is not set +# end of Intel Speed Select Technology interface support + +# +# Intel Uncore Frequency Control +# +# CONFIG_INTEL_UNCORE_FREQ_CONTROL is not set +# end of Intel Uncore Frequency Control + +# CONFIG_INTEL_HID_EVENT is not set +# CONFIG_INTEL_VBTN is not set +# CONFIG_INTEL_INT0002_VGPIO is not set +# CONFIG_INTEL_PUNIT_IPC is not set +# CONFIG_INTEL_RST is not set +# CONFIG_INTEL_SMARTCONNECT is not set +# CONFIG_INTEL_TURBO_MAX_3 is not set +# CONFIG_INTEL_VSEC is not set +# CONFIG_PCENGINES_APU2 is not set +# CONFIG_BARCO_P50_GPIO is not set +# CONFIG_SAMSUNG_Q10 is not set +# CONFIG_TOSHIBA_BT_RFKILL is not set +# CONFIG_TOSHIBA_HAPS is not set +# CONFIG_ACPI_CMPC is not set +# CONFIG_TOPSTAR_LAPTOP is not set +# CONFIG_MLX_PLATFORM is not set +# CONFIG_INTEL_IPS is not set +# CONFIG_INTEL_SCU_PCI is not set +# CONFIG_INTEL_SCU_PLATFORM is not set +# CONFIG_SIEMENS_SIMATIC_IPC is not set +# CONFIG_WINMATE_FM07_KEYS is not set +# CONFIG_SEL3350_PLATFORM is not set +CONFIG_P2SB=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y +# CONFIG_COMMON_CLK_MAX9485 is not set +# CONFIG_COMMON_CLK_SI5341 is not set +# CONFIG_COMMON_CLK_SI5351 is not set +# CONFIG_COMMON_CLK_SI544 is not set +# CONFIG_COMMON_CLK_CDCE706 is not set +# CONFIG_COMMON_CLK_CS2000_CP is not set +# CONFIG_XILINX_VCU is not set +# CONFIG_HWSPINLOCK is not set + +# +# Clock Source drivers +# +CONFIG_CLKEVT_I8253=y +CONFIG_I8253_LOCK=y +CONFIG_CLKBLD_I8253=y +# end of Clock Source drivers + +CONFIG_MAILBOX=y +CONFIG_PCC=y +# CONFIG_ALTERA_MBOX is not set +CONFIG_IOMMU_IOVA=y +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +CONFIG_IOMMU_IO_PGTABLE=y +# end of Generic IOMMU Pagetable Support + +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set +CONFIG_IOMMU_DEFAULT_DMA_LAZY=y +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_IOMMU_DMA=y +CONFIG_IOMMU_SVA=y +CONFIG_AMD_IOMMU=y +CONFIG_AMD_IOMMU_V2=y +CONFIG_DMAR_TABLE=y +CONFIG_INTEL_IOMMU=y +CONFIG_INTEL_IOMMU_SVM=y +# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set +CONFIG_INTEL_IOMMU_FLOPPY_WA=y +# CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON is not set +CONFIG_INTEL_IOMMU_PERF_EVENTS=y +# CONFIG_IOMMUFD is not set +CONFIG_IRQ_REMAP=y +CONFIG_HYPERV_IOMMU=y +# CONFIG_VIRTIO_IOMMU is not set + +# +# Remoteproc drivers +# +# CONFIG_REMOTEPROC is not set +# end of Remoteproc drivers + +# +# Rpmsg drivers +# +# CONFIG_RPMSG_QCOM_GLINK_RPM is not set +# CONFIG_RPMSG_VIRTIO is not set +# end of Rpmsg drivers + +# CONFIG_SOUNDWIRE is not set + +# +# SOC (System On Chip) specific Drivers +# + +# +# Amlogic SoC drivers +# +# end of Amlogic SoC drivers + +# +# Broadcom SoC drivers +# +# end of Broadcom SoC drivers + +# +# NXP/Freescale QorIQ SoC drivers +# +# end of NXP/Freescale QorIQ SoC drivers + +# +# fujitsu SoC drivers +# +# end of fujitsu SoC drivers + +# +# i.MX SoC drivers +# +# end of i.MX SoC drivers + +# +# Enable LiteX SoC Builder specific drivers +# +# end of Enable LiteX SoC Builder specific drivers + +# CONFIG_WPCM450_SOC is not set + +# +# Qualcomm SoC drivers +# +# end of Qualcomm SoC drivers + +# CONFIG_SOC_TI is not set + +# +# Xilinx SoC drivers +# +# end of Xilinx SoC drivers +# end of SOC (System On Chip) specific Drivers + +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=m +# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +# CONFIG_DEVFREQ_GOV_USERSPACE is not set +# CONFIG_DEVFREQ_GOV_PASSIVE is not set + +# +# DEVFREQ Drivers +# +# CONFIG_PM_DEVFREQ_EVENT is not set +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_NTB is not set +# CONFIG_PWM is not set + +# +# IRQ chip support +# +# end of IRQ chip support + +# CONFIG_IPACK_BUS is not set +CONFIG_RESET_CONTROLLER=y +# CONFIG_RESET_SIMPLE is not set +# CONFIG_RESET_TI_SYSCON is not set +# CONFIG_RESET_TI_TPS380X is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +# CONFIG_USB_LGM_PHY is not set +# CONFIG_PHY_CAN_TRANSCEIVER is not set + +# +# PHY drivers for Broadcom platforms +# +# CONFIG_BCM_KONA_USB2_PHY is not set +# end of PHY drivers for Broadcom platforms + +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_PHY_INTEL_LGM_EMMC is not set +# end of PHY Subsystem + +CONFIG_POWERCAP=y +CONFIG_INTEL_RAPL_CORE=m +# CONFIG_INTEL_RAPL is not set +CONFIG_IDLE_INJECT=y +# CONFIG_MCB is not set + +# +# Performance monitor support +# +# end of Performance monitor support + +CONFIG_RAS=y +# CONFIG_RAS_CEC is not set +CONFIG_USB4=m +# CONFIG_USB4_DEBUGFS_WRITE is not set +# CONFIG_USB4_DMA_TEST is not set + +# +# Android +# +# CONFIG_ANDROID_BINDER_IPC is not set +# end of Android + +CONFIG_LIBNVDIMM=m +CONFIG_BLK_DEV_PMEM=m +CONFIG_ND_CLAIM=y +CONFIG_ND_BTT=m +CONFIG_BTT=y +CONFIG_DAX=y +# CONFIG_DEV_DAX is not set +CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y + +# +# Layout Types +# +# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set +# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set +# end of Layout Types + +# CONFIG_NVMEM_RMEM is not set + +# +# HW tracing support +# +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set +# end of HW tracing support + +# CONFIG_FPGA is not set +# CONFIG_TEE is not set +CONFIG_PM_OPP=y +# CONFIG_SIOX is not set +# CONFIG_SLIMBUS is not set +# CONFIG_INTERCONNECT is not set +# CONFIG_COUNTER is not set +# CONFIG_MOST is not set +# CONFIG_PECI is not set +# CONFIG_HTE is not set +# end of Device Drivers + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +# CONFIG_VALIDATE_FS_PARSER is not set +CONFIG_FS_IOMAP=y +CONFIG_BUFFER_HEAD=y +CONFIG_LEGACY_DIRECT_IO=y +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=m +CONFIG_EXT4_USE_FOR_EXT2=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=m +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_F2FS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +# CONFIG_EXPORTFS_BLOCK_OPS is not set +CONFIG_FILE_LOCKING=y +# CONFIG_FS_ENCRYPTION is not set +# CONFIG_FS_VERITY is not set +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=m +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_VIRTIO_FS=m +CONFIG_OVERLAY_FS=m +# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set +CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y +# CONFIG_OVERLAY_FS_INDEX is not set +# CONFIG_OVERLAY_FS_XINO_AUTO is not set +# CONFIG_OVERLAY_FS_METACOPY is not set +# CONFIG_OVERLAY_FS_DEBUG is not set + +# +# Caches +# +CONFIG_NETFS_SUPPORT=m +CONFIG_NETFS_STATS=y +CONFIG_FSCACHE=m +CONFIG_FSCACHE_STATS=y +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_CACHEFILES is not set +# end of Caches + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +# end of CD-ROM/DVD Filesystems + +# +# DOS/FAT/EXFAT/NT Filesystems +# +CONFIG_FAT_FS=m +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_FAT_DEFAULT_UTF8=y +CONFIG_EXFAT_FS=m +CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS3_FS is not set +# end of DOS/FAT/EXFAT/NT Filesystems + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PROC_CHILDREN=y +CONFIG_PROC_PID_ARCH_STATUS=y +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_TMPFS_INODE64 is not set +# CONFIG_TMPFS_QUOTA is not set +CONFIG_HUGETLBFS=y +# CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON is not set +CONFIG_HUGETLB_PAGE=y +CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y +CONFIG_ARCH_HAS_GIGANTIC_PAGE=y +CONFIG_CONFIGFS_FS=m +CONFIG_EFIVAR_FS=m +# end of Pseudo filesystems + +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ORANGEFS_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_FILE_CACHE=y +# CONFIG_SQUASHFS_FILE_DIRECT is not set +CONFIG_SQUASHFS_DECOMP_SINGLE=y +# CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT is not set +CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE=y +# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI is not set +# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU is not set +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_ZSTD=y +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_PSTORE=y +CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 +CONFIG_PSTORE_COMPRESS=y +# CONFIG_PSTORE_CONSOLE is not set +# CONFIG_PSTORE_PMSG is not set +# CONFIG_PSTORE_RAM is not set +# CONFIG_PSTORE_BLK is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_EROFS_FS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set +# CONFIG_UNICODE is not set +# end of File systems + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_REQUEST_CACHE is not set +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_TRUSTED_KEYS is not set +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_KEY_DH_OPERATIONS is not set +CONFIG_SECURITY_DMESG_RESTRICT=y +CONFIG_PROC_MEM_ALWAYS_FORCE=y +# CONFIG_PROC_MEM_FORCE_PTRACE is not set +# CONFIG_PROC_MEM_NO_FORCE is not set +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +# CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_INFINIBAND is not set +# CONFIG_SECURITY_PATH is not set +# CONFIG_INTEL_TXT is not set +# CONFIG_HARDENED_USERCOPY is not set +CONFIG_FORTIFY_SOURCE=y +# CONFIG_STATIC_USERMODEHELPER is not set +# CONFIG_SECURITY_SMACK is not set +# CONFIG_SECURITY_TOMOYO is not set +# CONFIG_SECURITY_APPARMOR is not set +# CONFIG_SECURITY_LOADPIN is not set +# CONFIG_SECURITY_YAMA is not set +# CONFIG_SECURITY_SAFESETID is not set +CONFIG_SECURITY_LOCKDOWN_LSM=y +CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y +CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y +# CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set +# CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set +# CONFIG_SECURITY_LANDLOCK is not set +# CONFIG_INTEGRITY is not set +# CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" + +# +# Kernel hardening options +# + +# +# Memory initialization +# +CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y +CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y +CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y +CONFIG_INIT_STACK_NONE=y +# CONFIG_INIT_STACK_ALL_PATTERN is not set +# CONFIG_INIT_STACK_ALL_ZERO is not set +# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y +# CONFIG_ZERO_CALL_USED_REGS is not set +# end of Memory initialization + +# +# Hardening of kernel data structures +# +CONFIG_LIST_HARDENED=y +CONFIG_BUG_ON_DATA_CORRUPTION=y +# end of Hardening of kernel data structures + +CONFIG_RANDSTRUCT_NONE=y +# end of Kernel hardening options +# end of Security options + +CONFIG_XOR_BLOCKS=y +CONFIG_ASYNC_CORE=y +CONFIG_ASYNC_MEMCPY=y +CONFIG_ASYNC_XOR=y +CONFIG_ASYNC_PQ=y +CONFIG_ASYNC_RAID6_RECOV=y +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_SIG=y +CONFIG_CRYPTO_SIG2=y +CONFIG_CRYPTO_SKCIPHER=y +CONFIG_CRYPTO_SKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=m +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_AKCIPHER=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_KPP=m +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_PCRYPT=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_SIMD=m +CONFIG_CRYPTO_ENGINE=m +# end of Crypto core or helper + +# +# Public-key cryptography +# +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_DH=m +# CONFIG_CRYPTO_DH_RFC7919_GROUPS is not set +CONFIG_CRYPTO_ECC=m +CONFIG_CRYPTO_ECDH=m +CONFIG_CRYPTO_ECDSA=m +CONFIG_CRYPTO_ECRDSA=m +# CONFIG_CRYPTO_SM2 is not set +# CONFIG_CRYPTO_CURVE25519 is not set +# end of Public-key cryptography + +# +# Block ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_AES_TI=m +CONFIG_CRYPTO_ANUBIS=m +# CONFIG_CRYPTO_ARIA is not set +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_BLOWFISH_COMMON=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST_COMMON=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +# CONFIG_CRYPTO_SM4_GENERIC is not set +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +# end of Block ciphers + +# +# Length-preserving ciphers and modes +# +CONFIG_CRYPTO_ADIANTUM=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_CHACHA20=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CFB=m +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_HCTR2 is not set +CONFIG_CRYPTO_KEYWRAP=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_OFB=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_NHPOLY1305=m +# end of Length-preserving ciphers and modes + +# +# AEAD (authenticated encryption with associated data) ciphers +# +CONFIG_CRYPTO_AEGIS128=m +CONFIG_CRYPTO_CHACHA20POLY1305=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=y +CONFIG_CRYPTO_GENIV=m +CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_ECHAINIV=m +CONFIG_CRYPTO_ESSIV=y +# end of AEAD (authenticated encryption with associated data) ciphers + +# +# Hashes, digests, and MACs +# +# CONFIG_CRYPTO_BLAKE2B is not set +CONFIG_CRYPTO_CMAC=m +CONFIG_CRYPTO_GHASH=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_POLY1305=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SHA3=m +# CONFIG_CRYPTO_SM3_GENERIC is not set +CONFIG_CRYPTO_STREEBOG=m +CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XXHASH=m +# end of Hashes, digests, and MACs + +# +# CRCs (cyclic redundancy checks) +# +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC32=m +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_CRC64_ROCKSOFT=y +# end of CRCs (cyclic redundancy checks) + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_842=m +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m +CONFIG_CRYPTO_ZSTD=m +# end of Compression + +# +# Random number generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_DRBG_MENU=m +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=m +CONFIG_CRYPTO_JITTERENTROPY=m +# CONFIG_CRYPTO_JITTERENTROPY_TESTINTERFACE is not set +# end of Random number generation + +# +# Userspace interface +# +CONFIG_CRYPTO_USER_API=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set +CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y +CONFIG_CRYPTO_STATS=y +# end of Userspace interface + +CONFIG_CRYPTO_HASH_INFO=y + +# +# Accelerated Cryptographic Algorithms for CPU (x86) +# +CONFIG_CRYPTO_CURVE25519_X86=m +CONFIG_CRYPTO_AES_NI_INTEL=m +CONFIG_CRYPTO_BLOWFISH_X86_64=m +CONFIG_CRYPTO_CAMELLIA_X86_64=m +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=m +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=m +CONFIG_CRYPTO_CAST5_AVX_X86_64=m +CONFIG_CRYPTO_CAST6_AVX_X86_64=m +CONFIG_CRYPTO_DES3_EDE_X86_64=m +CONFIG_CRYPTO_SERPENT_SSE2_X86_64=m +CONFIG_CRYPTO_SERPENT_AVX_X86_64=m +CONFIG_CRYPTO_SERPENT_AVX2_X86_64=m +# CONFIG_CRYPTO_SM4_AESNI_AVX_X86_64 is not set +# CONFIG_CRYPTO_SM4_AESNI_AVX2_X86_64 is not set +CONFIG_CRYPTO_TWOFISH_X86_64=m +CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m +CONFIG_CRYPTO_TWOFISH_AVX_X86_64=m +# CONFIG_CRYPTO_ARIA_AESNI_AVX_X86_64 is not set +# CONFIG_CRYPTO_ARIA_AESNI_AVX2_X86_64 is not set +# CONFIG_CRYPTO_ARIA_GFNI_AVX512_X86_64 is not set +CONFIG_CRYPTO_CHACHA20_X86_64=m +CONFIG_CRYPTO_AEGIS128_AESNI_SSE2=m +CONFIG_CRYPTO_NHPOLY1305_SSE2=m +CONFIG_CRYPTO_NHPOLY1305_AVX2=m +CONFIG_CRYPTO_BLAKE2S_X86=y +# CONFIG_CRYPTO_POLYVAL_CLMUL_NI is not set +CONFIG_CRYPTO_POLY1305_X86_64=m +CONFIG_CRYPTO_SHA1_SSSE3=m +CONFIG_CRYPTO_SHA256_SSSE3=m +CONFIG_CRYPTO_SHA512_SSSE3=m +# CONFIG_CRYPTO_SM3_AVX_X86_64 is not set +CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m +CONFIG_CRYPTO_CRC32C_INTEL=m +CONFIG_CRYPTO_CRC32_PCLMUL=m +CONFIG_CRYPTO_CRCT10DIF_PCLMUL=m +# end of Accelerated Cryptographic Algorithms for CPU (x86) + +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_DEV_PADLOCK=m +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_DEV_ATMEL_I2C=m +CONFIG_CRYPTO_DEV_ATMEL_ECC=m +CONFIG_CRYPTO_DEV_ATMEL_SHA204A=m +CONFIG_CRYPTO_DEV_CCP=y +CONFIG_CRYPTO_DEV_CCP_DD=m +CONFIG_CRYPTO_DEV_SP_CCP=y +CONFIG_CRYPTO_DEV_CCP_CRYPTO=m +CONFIG_CRYPTO_DEV_SP_PSP=y +# CONFIG_CRYPTO_DEV_CCP_DEBUGFS is not set +# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set +# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set +# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set +# CONFIG_CRYPTO_DEV_QAT_C62X is not set +# CONFIG_CRYPTO_DEV_QAT_4XXX is not set +# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set +# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set +# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set +# CONFIG_CRYPTO_DEV_CHELSIO is not set +CONFIG_CRYPTO_DEV_VIRTIO=m +# CONFIG_CRYPTO_DEV_SAFEXCEL is not set +# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_X509_CERTIFICATE_PARSER=y +# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS7_TEST_KEY is not set +CONFIG_SIGNED_PE_FILE_VERIFICATION=y +# CONFIG_FIPS_SIGNATURE_SELFTEST is not set + +# +# Certificates for signature checking +# +CONFIG_MODULE_SIG_KEY="certs/signing_key.pem" +CONFIG_MODULE_SIG_KEY_TYPE_RSA=y +# CONFIG_MODULE_SIG_KEY_TYPE_ECDSA is not set +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_SYSTEM_TRUSTED_KEYS="" +# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set +# CONFIG_SECONDARY_TRUSTED_KEYRING is not set +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set +# end of Certificates for signature checking + +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=y +CONFIG_RAID6_PQ_BENCHMARK=y +CONFIG_LINEAR_RANGES=y +# CONFIG_PACKING is not set +CONFIG_BITREVERSE=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_CORDIC=m +# CONFIG_PRIME_NUMBERS is not set +CONFIG_RATIONAL=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IOMAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_HAS_FAST_MULTIPLIER=y +CONFIG_ARCH_USE_SYM_ANNOTATIONS=y + +# +# Crypto library routines +# +CONFIG_CRYPTO_LIB_UTILS=y +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_ARC4=m +CONFIG_CRYPTO_LIB_GF128MUL=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m +CONFIG_CRYPTO_LIB_CHACHA=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m +CONFIG_CRYPTO_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_DES=m +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11 +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m +CONFIG_CRYPTO_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y +# end of Crypto library routines + +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC_T10DIF=y +CONFIG_CRC64_ROCKSOFT=y +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +CONFIG_CRC64=y +# CONFIG_CRC4 is not set +CONFIG_CRC7=m +CONFIG_LIBCRC32C=y +CONFIG_CRC8=m +CONFIG_XXHASH=y +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_842_COMPRESS=m +CONFIG_842_DECOMPRESS=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_COMPRESS=m +CONFIG_LZ4HC_COMPRESS=m +CONFIG_LZ4_DECOMPRESS=m +CONFIG_ZSTD_COMMON=y +CONFIG_ZSTD_COMPRESS=m +CONFIG_ZSTD_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_ARM is not set +# CONFIG_XZ_DEC_ARMTHUMB is not set +# CONFIG_XZ_DEC_SPARC is not set +# CONFIG_XZ_DEC_MICROLZMA is not set +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_ZSTD=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_BTREE=y +CONFIG_INTERVAL_TREE=y +CONFIG_XARRAY_MULTI=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_DMA_OPS=y +CONFIG_NEED_SG_DMA_FLAGS=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_SWIOTLB=y +# CONFIG_SWIOTLB_DYNAMIC is not set +# CONFIG_DMA_CMA is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_DMA_MAP_BENCHMARK is not set +CONFIG_SGL_ALLOC=y +CONFIG_IOMMU_HELPER=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_GLOB=y +# CONFIG_GLOB_SELFTEST is not set +CONFIG_NLATTR=y +CONFIG_CLZ_TAB=y +CONFIG_IRQ_POLL=y +CONFIG_MPILIB=y +CONFIG_DIMLIB=y +CONFIG_OID_REGISTRY=y +CONFIG_UCS2_STRING=y +CONFIG_HAVE_GENERIC_VDSO=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_VDSO_TIME_NS=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_SG_POOL=y +CONFIG_ARCH_HAS_PMEM_API=y +CONFIG_MEMREGION=y +CONFIG_ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION=y +CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y +CONFIG_ARCH_HAS_COPY_MC=y +CONFIG_ARCH_STACKWALK=y +CONFIG_SBITMAP=y +CONFIG_PARMAN=m +CONFIG_OBJAGG=m +# end of Library routines + +CONFIG_PLDMFW=y + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_CALLER is not set +# CONFIG_STACKTRACE_BUILD_ID is not set +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 +CONFIG_CONSOLE_LOGLEVEL_QUIET=4 +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +CONFIG_BOOT_PRINTK_DELAY=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DYNAMIC_DEBUG_CORE=y +CONFIG_SYMBOLIC_ERRNAME=y +CONFIG_DEBUG_BUGVERBOSE=y +# end of printk and dmesg options + +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_MISC is not set + +# +# Compile-time checks and compiler options +# +CONFIG_AS_HAS_NON_CONST_LEB128=y +CONFIG_DEBUG_INFO_NONE=y +# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +# CONFIG_DEBUG_INFO_DWARF5 is not set +CONFIG_FRAME_WARN=2048 +CONFIG_STRIP_ASM_SYMS=y +# CONFIG_READABLE_ASM is not set +# CONFIG_HEADERS_INSTALL is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set +CONFIG_OBJTOOL=y +# CONFIG_VMLINUX_MAP is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# end of Compile-time checks and compiler options + +# +# Generic Kernel Debugging Instruments +# +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x01b6 +CONFIG_MAGIC_SYSRQ_SERIAL=y +CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_FS_ALLOW_ALL=y +# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set +# CONFIG_DEBUG_FS_ALLOW_NONE is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y +# CONFIG_UBSAN is not set +CONFIG_HAVE_ARCH_KCSAN=y +CONFIG_HAVE_KCSAN_COMPILER=y +# CONFIG_KCSAN is not set +# end of Generic Kernel Debugging Instruments + +# +# Networking Debugging +# +# CONFIG_NET_DEV_REFCNT_TRACKER is not set +# CONFIG_NET_NS_REFCNT_TRACKER is not set +# CONFIG_DEBUG_NET is not set +# end of Networking Debugging + +# +# Memory Debugging +# +CONFIG_PAGE_EXTENSION=y +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_SLUB_DEBUG is not set +# CONFIG_PAGE_OWNER is not set +# CONFIG_PAGE_TABLE_CHECK is not set +CONFIG_PAGE_POISONING=y +# CONFIG_DEBUG_PAGE_REF is not set +# CONFIG_DEBUG_RODATA_TEST is not set +CONFIG_ARCH_HAS_DEBUG_WX=y +CONFIG_DEBUG_WX=y +CONFIG_GENERIC_PTDUMP=y +CONFIG_PTDUMP_CORE=y +# CONFIG_PTDUMP_DEBUGFS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_PER_VMA_LOCK_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SHRINKER_DEBUG is not set +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_SCHED_STACK_END_CHECK=y +CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VM_PGTABLE is not set +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP=y +# CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP is not set +CONFIG_HAVE_ARCH_KASAN=y +CONFIG_HAVE_ARCH_KASAN_VMALLOC=y +CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y +# CONFIG_KASAN is not set +CONFIG_HAVE_ARCH_KFENCE=y +# CONFIG_KFENCE is not set +CONFIG_HAVE_ARCH_KMSAN=y +# end of Memory Debugging + +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Oops, Lockups and Hangs +# +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_HAVE_HARDLOCKUP_DETECTOR_BUDDY=y +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_HARDLOCKUP_DETECTOR_PREFER_BUDDY is not set +CONFIG_HARDLOCKUP_DETECTOR_PERF=y +# CONFIG_HARDLOCKUP_DETECTOR_BUDDY is not set +# CONFIG_HARDLOCKUP_DETECTOR_ARCH is not set +CONFIG_HARDLOCKUP_DETECTOR_COUNTS_HRTIMER=y +CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +# CONFIG_WQ_WATCHDOG is not set +# CONFIG_WQ_CPU_INTENSIVE_REPORT is not set +# CONFIG_TEST_LOCKUP is not set +# end of Debug Oops, Lockups and Hangs + +# +# Scheduler Debugging +# +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_INFO=y +CONFIG_SCHEDSTATS=y +# end of Scheduler Debugging + +# CONFIG_DEBUG_TIMEKEEPING is not set + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +CONFIG_LOCK_DEBUGGING_SUPPORT=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +# CONFIG_WW_MUTEX_SELFTEST is not set +# CONFIG_SCF_TORTURE_TEST is not set +# CONFIG_CSD_LOCK_WAIT_DEBUG is not set +# end of Lock Debugging (spinlocks, mutexes, etc...) + +# CONFIG_NMI_CHECK_CPU is not set +# CONFIG_DEBUG_IRQFLAGS is not set +CONFIG_STACKTRACE=y +# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set +# CONFIG_DEBUG_KOBJECT is not set + +# +# Debug kernel data structures +# +CONFIG_DEBUG_LIST=y +# CONFIG_DEBUG_PLIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_MAPLE_TREE is not set +# end of Debug kernel data structures + +# +# RCU Debugging +# +# CONFIG_RCU_SCALE_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_REF_SCALE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 +# CONFIG_RCU_CPU_STALL_CPUTIME is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# end of RCU Debugging + +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_LATENCYTOP is not set +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_NOP_TRACER=y +CONFIG_HAVE_RETHOOK=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y +CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_FENTRY=y +CONFIG_HAVE_OBJTOOL_MCOUNT=y +CONFIG_HAVE_OBJTOOL_NOP_MCOUNT=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_BOOTTIME_TRACING is not set +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_HWLAT_TRACER is not set +# CONFIG_OSNOISE_TRACER is not set +# CONFIG_TIMERLAT_TRACER is not set +# CONFIG_MMIOTRACE is not set +# CONFIG_FTRACE_SYSCALLS is not set +# CONFIG_TRACER_SNAPSHOT is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_UPROBE_EVENTS=y +CONFIG_BPF_EVENTS=y +CONFIG_DYNAMIC_EVENTS=y +CONFIG_PROBE_EVENTS=y +# CONFIG_SYNTH_EVENTS is not set +# CONFIG_USER_EVENTS is not set +# CONFIG_HIST_TRIGGERS is not set +# CONFIG_TRACE_EVENT_INJECT is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_TRACE_EVAL_MAP_FILE is not set +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set +# CONFIG_PREEMPTIRQ_DELAY_TEST is not set +# CONFIG_RV is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y +CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y +CONFIG_STRICT_DEVMEM=y +CONFIG_IO_STRICT_DEVMEM=y + +# +# x86 Debugging +# +# CONFIG_X86_VERBOSE_BOOTUP is not set +# CONFIG_EARLY_PRINTK is not set +# CONFIG_EFI_PGT_DUMP is not set +# CONFIG_DEBUG_TLBFLUSH is not set +# CONFIG_IOMMU_DEBUG is not set +CONFIG_HAVE_MMIOTRACE_SUPPORT=y +# CONFIG_X86_DECODER_SELFTEST is not set +CONFIG_IO_DELAY_0X80=y +# CONFIG_IO_DELAY_0XED is not set +# CONFIG_IO_DELAY_UDELAY is not set +# CONFIG_IO_DELAY_NONE is not set +# CONFIG_DEBUG_BOOT_PARAMS is not set +# CONFIG_CPA_DEBUG is not set +# CONFIG_DEBUG_ENTRY is not set +# CONFIG_DEBUG_NMI_SELFTEST is not set +# CONFIG_X86_DEBUG_FPU is not set +# CONFIG_PUNIT_ATOM_DEBUG is not set +CONFIG_UNWINDER_ORC=y +# CONFIG_UNWINDER_FRAME_POINTER is not set +# CONFIG_UNWINDER_GUESS is not set +# end of x86 Debugging + +# +# Kernel Testing and Coverage +# +# CONFIG_KUNIT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_ARCH_HAS_KCOV=y +CONFIG_CC_HAS_SANCOV_TRACE_PC=y +# CONFIG_KCOV is not set +# CONFIG_RUNTIME_TESTING_MENU is not set +CONFIG_ARCH_USE_MEMTEST=y +# CONFIG_MEMTEST is not set +# CONFIG_HYPERV_TESTING is not set +# end of Kernel Testing and Coverage + +# +# Rust hacking +# +# end of Rust hacking +# end of Kernel hacking diff --git a/scripts/package-build/linux-kernel/build-accel-ppp.sh b/scripts/package-build/linux-kernel/build-accel-ppp.sh index 1685ff8d..a2f8df52 100755 --- a/scripts/package-build/linux-kernel/build-accel-ppp.sh +++ b/scripts/package-build/linux-kernel/build-accel-ppp.sh @@ -13,6 +13,10 @@ if [ ! -f ${KERNEL_VAR_FILE} ]; then exit 1 fi +cd ${ACCEL_SRC} +git reset --hard HEAD +git clean --force -d -x + PATCH_DIR=${CWD}/patches/accel-ppp if [ -d $PATCH_DIR ]; then cd ${ACCEL_SRC} @@ -36,6 +40,10 @@ cmake -DBUILD_IPOE_DRIVER=TRUE \ -DMODULES_KDIR=${KERNEL_VERSION}${KERNEL_SUFFIX} \ -DCPACK_TYPE=Debian12 .. make + +# Sign generated Kernel modules +${CWD}/sign-modules.sh . + cpack -G DEB # rename resulting Debian package according git description diff --git a/scripts/package-build/linux-kernel/build-intel-ixgbe.sh b/scripts/package-build/linux-kernel/build-intel-ixgbe.sh deleted file mode 100755 index 5f45c62a..00000000 --- a/scripts/package-build/linux-kernel/build-intel-ixgbe.sh +++ /dev/null @@ -1,107 +0,0 @@ -#!/bin/sh -CWD=$(pwd) -KERNEL_VAR_FILE=${CWD}/kernel-vars - -if ! dpkg-architecture -iamd64; then - echo "Intel ixgbe is only buildable on amd64 platforms" - exit 0 -fi - -if [ ! -f ${KERNEL_VAR_FILE} ]; then - echo "Kernel variable file '${KERNEL_VAR_FILE}' does not exist, run ./build_kernel.sh first" - exit 1 -fi - -. ${KERNEL_VAR_FILE} - -url="https://sourceforge.net/projects/e1000/files/ixgbe%20stable/5.20.3/ixgbe-5.20.3.tar.gz" - -cd ${CWD} - -DRIVER_FILE=$(basename ${url} | sed -e s/tar_0/tar/) -DRIVER_DIR="${DRIVER_FILE%.tar.gz}" -DRIVER_NAME="ixgbe" -DRIVER_VERSION=$(echo ${DRIVER_DIR} | awk -F${DRIVER_NAME} '{print $2}' | sed 's/^-//') -DRIVER_VERSION_EXTRA="" - -# Build up Debian related variables required for packaging -DEBIAN_ARCH=$(dpkg --print-architecture) -DEBIAN_DIR="${CWD}/vyos-intel-${DRIVER_NAME}_${DRIVER_VERSION}_${DEBIAN_ARCH}" -DEBIAN_CONTROL="${DEBIAN_DIR}/DEBIAN/control" -DEBIAN_POSTINST="${CWD}/vyos-intel-ixgbe.postinst" - -# Fetch Intel driver source from SourceForge -if [ -e ${DRIVER_FILE} ]; then - rm -f ${DRIVER_FILE} -fi -curl -L -o ${DRIVER_FILE} ${url} -if [ "$?" -ne "0" ]; then - exit 1 -fi - -# Unpack archive -if [ -d ${DRIVER_DIR} ]; then - rm -rf ${DRIVER_DIR} -fi -mkdir -p ${DRIVER_DIR} -tar -C ${DRIVER_DIR} --strip-components=1 -xf ${DRIVER_FILE} - -cd ${DRIVER_DIR}/src -if [ -z $KERNEL_DIR ]; then - echo "KERNEL_DIR not defined" - exit 1 -fi - -# See https://lore.kernel.org/lkml/f90837d0-810e-5772-7841-28d47c44d260@intel.com/ -echo "I: remove pci_enable_pcie_error_reporting() code no longer present in Kernel" -sed -i '/.*pci_disable_pcie_error_reporting(pdev);/d' ixgbe_main.c -sed -i '/.*pci_enable_pcie_error_reporting(pdev);/d' ixgbe_main.c - -# See https://vyos.dev/T6155 -echo "I: always enable allow_unsupported_sfp for all NICs by default" -patch -l -p1 < ../../patches/ixgbe/allow_unsupported_sfp.patch - -# See https://vyos.dev/T6162 -echo "I: add 1000BASE-BX support" -patch -l -p1 < ../../patches/ixgbe/add_1000base-bx_support.patch - -echo "I: Compile Kernel module for Intel ${DRIVER_NAME} driver" -make KSRC=${KERNEL_DIR} INSTALL_MOD_PATH=${DEBIAN_DIR} INSTALL_FW_PATH=${DEBIAN_DIR} -j $(getconf _NPROCESSORS_ONLN) install - -if [ "x$?" != "x0" ]; then - exit 1 -fi - -if [ -f ${DEBIAN_DIR}.deb ]; then - rm ${DEBIAN_DIR}.deb -fi - -# build Debian package -echo "I: Building Debian package vyos-intel-${DRIVER_NAME}" -cd ${CWD} - -# delete non required files which are also present in the kernel package -# und thus lead to duplicated files -find ${DEBIAN_DIR} -name "modules.*" | xargs rm -f - -echo "#!/bin/sh" > ${DEBIAN_POSTINST} -echo "/sbin/depmod -a ${KERNEL_VERSION}${KERNEL_SUFFIX}" >> ${DEBIAN_POSTINST} - -fpm --input-type dir --output-type deb --name vyos-intel-${DRIVER_NAME} \ - --version ${DRIVER_VERSION} --deb-compression gz \ - --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \ - --description "Vendor based driver for Intel ${DRIVER_NAME}" \ - --depends linux-image-${KERNEL_VERSION}${KERNEL_SUFFIX} \ - --license "GPL2" -C ${DEBIAN_DIR} --after-install ${DEBIAN_POSTINST} - -echo "I: Cleanup ${DRIVER_NAME} source" -cd ${CWD} -if [ -e ${DRIVER_FILE} ]; then - rm -f ${DRIVER_FILE} -fi -if [ -d ${DRIVER_DIR} ]; then - rm -rf ${DRIVER_DIR} -fi -if [ -d ${DEBIAN_DIR} ]; then - rm -rf ${DEBIAN_DIR} -fi diff --git a/scripts/package-build/linux-kernel/build-intel-ixgbevf.sh b/scripts/package-build/linux-kernel/build-intel-nic.sh index a965e0de..3e8bbb37 100755 --- a/scripts/package-build/linux-kernel/build-intel-ixgbevf.sh +++ b/scripts/package-build/linux-kernel/build-intel-nic.sh @@ -3,7 +3,7 @@ CWD=$(pwd) KERNEL_VAR_FILE=${CWD}/kernel-vars if ! dpkg-architecture -iamd64; then - echo "Intel ixgbevf is only buildable on amd64 platforms" + echo "Intel drivers only buildable on amd64 platforms" exit 0 fi @@ -14,51 +14,39 @@ fi . ${KERNEL_VAR_FILE} -url="https://sourceforge.net/projects/e1000/files/ixgbevf%20stable/4.18.9/ixgbevf-4.18.9.tar.gz" +if [ -z $KERNEL_DIR ]; then + echo "KERNEL_DIR not defined" + exit 1 +fi -cd ${CWD} +DRIVER_NAME=$1 +cd ${CWD}/ethernet-linux-${DRIVER_NAME} +if [ -d .git ]; then + git clean --force -d -x + git reset --hard origin/main +fi -DRIVER_FILE=$(basename ${url} | sed -e s/tar_0/tar/) -DRIVER_DIR="${DRIVER_FILE%.tar.gz}" -DRIVER_NAME="ixgbevf" -DRIVER_VERSION=$(echo ${DRIVER_DIR} | awk -F${DRIVER_NAME} '{print $2}' | sed 's/^-//') -DRIVER_VERSION_EXTRA="" +DRIVER_VERSION=$(git describe | sed s/^v//) # Build up Debian related variables required for packaging DEBIAN_ARCH=$(dpkg --print-architecture) DEBIAN_DIR="${CWD}/vyos-intel-${DRIVER_NAME}_${DRIVER_VERSION}_${DEBIAN_ARCH}" DEBIAN_CONTROL="${DEBIAN_DIR}/DEBIAN/control" -DEBIAN_POSTINST="${CWD}/vyos-intel-ixgbevf.postinst" - -# Fetch Intel driver source from SourceForge -if [ -e ${DRIVER_FILE} ]; then - rm -f ${DRIVER_FILE} -fi -curl -L -o ${DRIVER_FILE} ${url} -if [ "$?" -ne "0" ]; then - exit 1 -fi - -# Unpack archive -if [ -d ${DRIVER_DIR} ]; then - rm -rf ${DRIVER_DIR} -fi -mkdir -p ${DRIVER_DIR} -tar -C ${DRIVER_DIR} --strip-components=1 -xf ${DRIVER_FILE} - -cd ${DRIVER_DIR}/src -if [ -z $KERNEL_DIR ]; then - echo "KERNEL_DIR not defined" - exit 1 +DEBIAN_POSTINST="${CWD}/vyos-intel-${DRIVER_NAME}.postinst" + +# See https://vyos.dev/T6155 +# See https://vyos.dev/T6162 +PATCH_DIR=${CWD}/patches/${DRIVER_NAME} +if [ -d $PATCH_DIR ]; then + for patch in $(ls ${PATCH_DIR}) + do + echo "I: Apply patch: ${PATCH_DIR}/${patch}" + patch -p1 < ${PATCH_DIR}/${patch} + done fi -# See https://lore.kernel.org/lkml/f90837d0-810e-5772-7841-28d47c44d260@intel.com/ -echo "I: remove pci_enable_pcie_error_reporting() code no longer present in Kernel" -sed -i '/.*pci_disable_pcie_error_reporting(pdev);/d' ixgbevf_main.c -sed -i '/.*pci_enable_pcie_error_reporting(pdev);/d' ixgbevf_main.c - echo "I: Compile Kernel module for Intel ${DRIVER_NAME} driver" -make KSRC=${KERNEL_DIR} INSTALL_MOD_PATH=${DEBIAN_DIR} INSTALL_FW_PATH=${DEBIAN_DIR} -j $(getconf _NPROCESSORS_ONLN) install +make KSRC=${KERNEL_DIR} INSTALL_MOD_PATH=${DEBIAN_DIR} INSTALL_FW_PATH=${DEBIAN_DIR} -j $(getconf _NPROCESSORS_ONLN) -C src install if [ "x$?" != "x0" ]; then exit 1 @@ -72,6 +60,9 @@ fi echo "I: Building Debian package vyos-intel-${DRIVER_NAME}" cd ${CWD} +# Sign generated Kernel modules +${CWD}/sign-modules.sh ${DEBIAN_DIR} + # delete non required files which are also present in the kernel package # und thus lead to duplicated files find ${DEBIAN_DIR} -name "modules.*" | xargs rm -f @@ -85,16 +76,3 @@ fpm --input-type dir --output-type deb --name vyos-intel-${DRIVER_NAME} \ --description "Vendor based driver for Intel ${DRIVER_NAME}" \ --depends linux-image-${KERNEL_VERSION}${KERNEL_SUFFIX} \ --license "GPL2" -C ${DEBIAN_DIR} --after-install ${DEBIAN_POSTINST} - -echo "I: Cleanup ${DRIVER_NAME} source" -cd ${CWD} -if [ -e ${DRIVER_FILE} ]; then - rm -f ${DRIVER_FILE} -fi -if [ -d ${DRIVER_DIR} ]; then - rm -rf ${DRIVER_DIR} -fi -if [ -d ${DEBIAN_DIR} ]; then - rm -rf ${DEBIAN_DIR} -fi - diff --git a/scripts/package-build/linux-kernel/build-intel-qat.sh b/scripts/package-build/linux-kernel/build-intel-qat.sh index 765cea3f..c2c364a9 100755 --- a/scripts/package-build/linux-kernel/build-intel-qat.sh +++ b/scripts/package-build/linux-kernel/build-intel-qat.sh @@ -14,7 +14,7 @@ fi . ${KERNEL_VAR_FILE} -url="https://dev.packages.vyos.net/source-mirror/QAT.L.4.24.0-00005.tar.gz" +url="https://packages.vyos.net/source-mirror/QAT.L.4.24.0-00005.tar.gz" cd ${CWD} @@ -84,6 +84,9 @@ fi echo "I: Building Debian package vyos-intel-${DRIVER_NAME}" cd ${CWD} +# Sign generated Kernel modules +${CWD}/sign-modules.sh ${DEBIAN_DIR} + # delete non required files which are also present in the kernel package # und thus lead to duplicated files find ${DEBIAN_DIR} -name "modules.*" | xargs rm -f @@ -98,14 +101,17 @@ fpm --input-type dir --output-type deb --name vyos-intel-${DRIVER_NAME} \ --depends linux-image-${KERNEL_VERSION}${KERNEL_SUFFIX} \ --license "GPL2" -C ${DEBIAN_DIR} --after-install ${DEBIAN_POSTINST} -echo "I: Cleanup ${DRIVER_NAME} source" -cd ${CWD} -if [ -e ${DRIVER_FILE} ]; then - rm -f ${DRIVER_FILE} -fi -if [ -d ${DRIVER_DIR} ]; then - rm -rf ${DRIVER_DIR} -fi -if [ -d ${DEBIAN_DIR} ]; then - rm -rf ${DEBIAN_DIR} -fi +# echo "I: Cleanup ${DRIVER_NAME} source" +# cd ${CWD} +# if [ -e ${DRIVER_FILE} ]; then +# rm -f ${DRIVER_FILE} +# fi +# if [ -d ${DRIVER_DIR} ]; then +# rm -rf ${DRIVER_DIR} +# fi +# if [ -d ${DEBIAN_DIR} ]; then +# rm -rf ${DEBIAN_DIR} +# fi +# if [ -f ${DEBIAN_POSTINST} ]; then +# rm -f ${DEBIAN_POSTINST} +# fi diff --git a/scripts/package-build/linux-kernel/build-ipt-netflow.sh b/scripts/package-build/linux-kernel/build-ipt-netflow.sh new file mode 100755 index 00000000..9245a416 --- /dev/null +++ b/scripts/package-build/linux-kernel/build-ipt-netflow.sh @@ -0,0 +1,69 @@ +#!/bin/sh +CWD=$(pwd) +KERNEL_VAR_FILE=${CWD}/kernel-vars + +IPT_NETFLOW_SRC=${CWD}/ipt-netflow +if [ ! -d ${IPT_NETFLOW_SRC} ]; then + echo "ipt_NETFLOW source not found" + exit 1 +fi + +if [ ! -f ${KERNEL_VAR_FILE} ]; then + echo "Kernel variable file '${KERNEL_VAR_FILE}' does not exist, run ./build_kernel.sh first" + exit 1 +fi + +cd ${IPT_NETFLOW_SRC} +if [ -d .git ]; then + git reset --hard HEAD + git clean --force -d -x +fi + +. ${KERNEL_VAR_FILE} + +DRIVER_VERSION=$(git describe | sed s/^v//) + +# Build up Debian related variables required for packaging +DEBIAN_ARCH=$(dpkg --print-architecture) +DEBIAN_DIR="tmp/" +DEBIAN_CONTROL="${DEBIAN_DIR}/DEBIAN/control" +DEBIAN_POSTINST="${CWD}/vyos-ipt-netflow.postinst" + +./configure --enable-aggregation --kdir=${KERNEL_DIR} +make all + +if [ "x$?" != "x0" ]; then + exit 1 +fi + +if [ -f ${DEBIAN_DIR}.deb ]; then + rm ${DEBIAN_DIR}.deb +fi + +if [ ! -d ${DEBIAN_DIR} ]; then + mkdir -p ${DEBIAN_DIR} +fi + +# build Debian package +echo "I: Building Debian package vyos-ipt-netflow" +cp ipt_NETFLOW.ko ${DEBIAN_DIR} +cp libipt_NETFLOW.so ${DEBIAN_DIR} +cp libip6t_NETFLOW.so ${DEBIAN_DIR} + +# Sign generated Kernel modules +${CWD}/sign-modules.sh ${DEBIAN_DIR} + +echo "#!/bin/sh" > ${DEBIAN_POSTINST} +echo "/sbin/depmod -a ${KERNEL_VERSION}${KERNEL_SUFFIX}" >> ${DEBIAN_POSTINST} + +cd ${CWD} + +fpm --input-type dir --output-type deb --name vyos-ipt-netflow \ + --version ${DRIVER_VERSION} --deb-compression gz \ + --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \ + --description "ipt_NETFLOW module" \ + --depends linux-image-${KERNEL_VERSION}${KERNEL_SUFFIX} \ + --license "GPL2" -C ${IPT_NETFLOW_SRC}/tmp --after-install ${DEBIAN_POSTINST} \ + ipt_NETFLOW.ko=/lib/modules/${KERNEL_VERSION}${KERNEL_SUFFIX}/extra/ipt_NETFLOW.ko \ + libipt_NETFLOW.so=/lib/$(uname -m)-linux-gnu/xtables/libipt_NETFLOW.so \ + libip6t_NETFLOW.so=/lib/$(uname -m)-linux-gnu/xtables/libip6t_NETFLOW.so diff --git a/scripts/package-build/linux-kernel/build-jool.py b/scripts/package-build/linux-kernel/build-jool.py index 570293f5..3d2c3d6a 100755 --- a/scripts/package-build/linux-kernel/build-jool.py +++ b/scripts/package-build/linux-kernel/build-jool.py @@ -29,9 +29,8 @@ def add_depends(package_dir: str, package_name: str, # find kernel version and source path arch: str = find_arch() defaults_file: str = Path('../../../data/defaults.toml').read_text() -architecture_file: str = Path(f'../../../data/architectures/{arch}.toml').read_text() KERNEL_VER: str = toml_loads(defaults_file).get('kernel_version') -KERNEL_FLAVOR: str = toml_loads(architecture_file).get('kernel_flavor') +KERNEL_FLAVOR: str = toml_loads(defaults_file).get('kernel_flavor') KERNEL_SRC: str = Path.cwd().as_posix() + '/linux' # define variables @@ -66,7 +65,7 @@ MODULES_DIR := extra # main packaging script based on dh7 syntax %: - dh $@ + dh $@ override_dh_clean: dh_clean --exclude=debian/{PACKAGE_NAME}.substvars @@ -88,7 +87,7 @@ override_dh_auto_install: install -D -m 644 src/mod/common/jool_common.ko ${{PACKAGE_BUILD_DIR}}/lib/modules/${{KVER}}/${{MODULES_DIR}}/jool_common.ko install -D -m 644 src/mod/nat64/jool.ko ${{PACKAGE_BUILD_DIR}}/lib/modules/${{KVER}}/${{MODULES_DIR}}/jool.ko install -D -m 644 src/mod/siit/jool_siit.ko ${{PACKAGE_BUILD_DIR}}/lib/modules/${{KVER}}/${{MODULES_DIR}}/jool_siit.ko - + ${{KERNEL_DIR}}/../sign-modules.sh ${{PACKAGE_BUILD_DIR}}/lib ''' bild_rules = Path(f'{PACKAGE_DIR}/debian/rules') bild_rules.write_text(build_rules_text) diff --git a/scripts/package-build/linux-kernel/build-kernel.sh b/scripts/package-build/linux-kernel/build-kernel.sh index 2c02f5c3..62dd7829 100755 --- a/scripts/package-build/linux-kernel/build-kernel.sh +++ b/scripts/package-build/linux-kernel/build-kernel.sh @@ -9,16 +9,20 @@ if [ ! -d ${KERNEL_SRC} ]; then exit 1 fi -echo "I: Copy Kernel config (x86_64_vyos_defconfig) to Kernel Source" -cp -rv arch/ ${KERNEL_SRC}/ - cd ${KERNEL_SRC} -echo "I: clean modified files" -git reset --hard HEAD +if [ -d .git ]; then + echo "I: Clean modified files - reset Git repo" + git reset --hard HEAD + git clean --force -d -x +fi + +echo "I: Copy Kernel config (x86_64_vyos_defconfig) to Kernel Source" +cp -rv ${CWD}/arch/ . KERNEL_VERSION=$(make kernelversion) -KERNEL_SUFFIX=-$(dpkg --print-architecture)-vyos +KERNEL_SUFFIX=-$(awk -F "= " '/kernel_flavor/ {print $2}' ../../../../data/defaults.toml | tr -d \") +KERNEL_CONFIG=arch/x86/configs/vyos_defconfig # VyOS requires some small Kernel Patches - apply them here # It's easier to habe them here and make use of the upstream @@ -31,26 +35,54 @@ do patch -p1 < ${PATCH_DIR}/${patch} done +# Change name of Signing Cert +sed -i -e "s/CN =.*/CN=VyOS Networks build time autogenerated Kernel key/" certs/default_x509.genkey + +TRUSTED_KEYS_FILE=trusted_keys.pem +# start with empty key file +echo -n "" > $TRUSTED_KEYS_FILE +GIT_ROOT=$(git rev-parse --show-toplevel) +CERTS=$(find ${GIT_ROOT}/data/certificates -name "*.pem" -type f || true) +if [ ! -z "${CERTS}" ]; then + # add known public keys to Kernel certificate chain + for file in $CERTS; do + cat $file >> $TRUSTED_KEYS_FILE + done + # Force Kernel module signing and embed public keys + echo "CONFIG_SYSTEM_TRUSTED_KEYRING" >> $KERNEL_CONFIG + echo "CONFIG_SYSTEM_TRUSTED_KEYS=\"$TRUSTED_KEYS_FILE\"" >> $KERNEL_CONFIG +fi + echo "I: make vyos_defconfig" # Select Kernel configuration - currently there is only one make vyos_defconfig echo "I: Generate environment file containing Kernel variable" +EPHEMERAL_KEY="/tmp/ephemeral.key" +EPHEMERAL_PEM="/tmp/ephemeral.pem" cat << EOF >${CWD}/kernel-vars #!/bin/sh export KERNEL_VERSION=${KERNEL_VERSION} export KERNEL_SUFFIX=${KERNEL_SUFFIX} export KERNEL_DIR=${CWD}/${KERNEL_SRC} +export EPHEMERAL_KEY=${EPHEMERAL_KEY} +export EPHEMERAL_CERT=${EPHEMERAL_PEM} EOF echo "I: Build Debian Kernel package" touch .scmversion make bindeb-pkg BUILD_TOOLS=1 LOCALVERSION=${KERNEL_SUFFIX} KDEB_PKGVERSION=${KERNEL_VERSION}-1 -j $(getconf _NPROCESSORS_ONLN) +# Back to the old Kernel build-scripts directory cd $CWD -if [[ $? == 0 ]]; then - for package in $(ls linux-*.deb) - do - ln -sf linux-kernel/$package .. - done +EPHEMERAL_KERNEL_KEY=$(grep -E "^CONFIG_MODULE_SIG_KEY=" ${KERNEL_SRC}/$KERNEL_CONFIG | awk -F= '{print $2}' | tr -d \") +if test -f "${EPHEMERAL_KEY}"; then + rm -f ${EPHEMERAL_KEY} +fi +if test -f "${EPHEMERAL_PEM}"; then + rm -f ${EPHEMERAL_PEM} +fi +if test -f "${KERNEL_SRC}/${EPHEMERAL_KERNEL_KEY}"; then + openssl rsa -in ${KERNEL_SRC}/${EPHEMERAL_KERNEL_KEY} -out ${EPHEMERAL_KEY} + openssl x509 -in ${KERNEL_SRC}/${EPHEMERAL_KERNEL_KEY} -out ${EPHEMERAL_PEM} fi diff --git a/scripts/package-build/linux-kernel/build-mellanox-ofed.sh b/scripts/package-build/linux-kernel/build-mellanox-ofed.sh new file mode 100755 index 00000000..3f8a50f0 --- /dev/null +++ b/scripts/package-build/linux-kernel/build-mellanox-ofed.sh @@ -0,0 +1,140 @@ +#!/bin/sh +DROP_DEV_DBG_DEBS=1 +DEB_DISTRO='debian12.1' +CWD=$(pwd) +KERNEL_VAR_FILE=${CWD}/kernel-vars + +if [ $(id -u) -ne 0 ]; then + echo "Mellanox OFED script needs to be run as root" + exit +fi + +if ! dpkg-architecture -iamd64; then + echo "Mellanox OFED is only buildable on amd64 platforms" + exit 0 +fi + +if [ ! -f ${KERNEL_VAR_FILE} ]; then + echo "Kernel variable file '${KERNEL_VAR_FILE}' does not exist, run ./build_kernel.sh first" + exit 1 +fi + +. ${KERNEL_VAR_FILE} + +mlxver="24.07-0.6.1.0" +url="https://www.mellanox.com/downloads/ofed/MLNX_OFED-${mlxver}/MLNX_OFED_SRC-debian-${mlxver}.tgz" + +cd ${CWD} + +DRIVER_FILE=$(basename ${url} | sed -e s/tar_0/tar/) +DRIVER_SHA1="c64defa8fb38dcbce153adc09834ab5cdcecd791" + +DRIVER_DIR="${DRIVER_FILE%.tgz}" +DRIVER_NAME="ofed" +DRIVER_PRFX="MLNX_OFED" +DRIVER_VERSION=$(echo ${DRIVER_DIR} | awk -F${DRIVER_PRFX} '{print $2}' | sed 's/^-//;s|_SRC-debian-||') +DRIVER_VERSION_EXTRA="" + +# Build up Debian related variables required for packaging +DEBIAN_ARCH=$(dpkg --print-architecture) +DEBIAN_DIR="${CWD}/vyos-mellanox-${DRIVER_NAME}_${DRIVER_VERSION}_${DEBIAN_ARCH}" +DEBIAN_CONTROL="${DEBIAN_DIR}/DEBIAN/control" +DEBIAN_POSTINST="${CWD}/vyos-mellanox-ofed.postinst" + +# Fetch OFED driver source from Nvidia +if [ -e ${DRIVER_FILE} ]; then + rm -f ${DRIVER_FILE} +fi +curl -L -o ${DRIVER_FILE} ${url} +if [ "$?" -ne "0" ]; then + exit 1 +fi + +# Verify integrity +echo "${DRIVER_SHA1} ${DRIVER_FILE}" | sha1sum -c - +if [ $? != 0 ]; then + echo SHA1 checksum missmatch + exit 1 +fi + +# Unpack archive +if [ -d ${DRIVER_DIR} ]; then + rm -rf ${DRIVER_DIR} +fi +mkdir -p ${DRIVER_DIR} +tar -C ${DRIVER_DIR} --strip-components=1 -xf ${DRIVER_FILE} + +# Build/install debs +cd ${DRIVER_DIR} +if [ -z $KERNEL_DIR ]; then + echo "KERNEL_DIR not defined" + exit 1 +fi + +rm -f SOURCES/ibarr_*.tar.gz +rm -f SOURCES/ibdump_*.tar.gz +rm -f SOURCES/ibsim_*.tar.gz +rm -f SOURCES/iser_*.tar.gz +rm -f SOURCES/isert_*.tar.gz +rm -f SOURCES/kernel-mft_*.tar.gz +rm -f SOURCES/knem_*.tar.gz +rm -f SOURCES/libvma_*.tar.gz +rm -f SOURCES/libxlio_*.tar.gz +rm -f SOURCES/mlnx-ethtool_*.tar.gz +rm -f SOURCES/mlnx-iproute2_*.tar.gz +rm -f SOURCES/mlnx-nfsrdma_*.tar.gz +rm -f SOURCES/mlnx-nvme_*.tar.gz +rm -f SOURCES/mlx-steering-dump_*.tar.gz +rm -f SOURCES/mpitests_*.tar.gz +rm -f SOURCES/mstflint_*.tar.gz +rm -f SOURCES/ofed-scripts_*.tar.gz +rm -f SOURCES/openmpi_*.tar.gz +rm -f SOURCES/openvswitch_*.tar.gz +rm -f SOURCES/perftest_*.tar.gz +rm -f SOURCES/rdma-core_*.tar.gz +rm -f SOURCES/rshim_*.tar.gz +rm -f SOURCES/sockperf_*.tar.gz +rm -f SOURCES/srp_*.tar.gz +rm -f SOURCES/ucx_*.tar.gz + +./install.pl \ + --basic --dpdk \ + --without-dkms \ + --without-mlnx-nvme-modules \ + --with-vma --vma-vpi --vma-eth \ + --guest --hypervisor \ + --builddir ${DEBIAN_DIR}/mlx \ + --distro ${DEB_DISTRO} \ + --kernel-sources ${KERNEL_DIR} \ + --kernel ${KERNEL_VERSION}${KERNEL_SUFFIX} + +if [ $DROP_DEV_DBG_DEBS -eq 1 ]; then + echo "I: Removing development and debug packages" + rm -f $(find $CWD/$DRIVER_DIR/DEBS/$DEB_DISTRO -type f | grep -E '\-dev|\-dbg') +fi + +cp $(find $CWD/$DRIVER_DIR/DEBS/$DEB_DISTRO -type f | grep '\.deb$') "$CWD/" + +echo "I: Cleanup ${DRIVER_NAME} source" +cd ${CWD} + +# Sign modules +DEB_NAME=$(ls mlnx-ofed-kernel-modules_*) +TMP_DIR="tmp-ofed-sign" +dpkg-deb --raw-extract ${DEB_NAME} ${TMP_DIR} +# Sign generated Kernel modules +${CWD}/sign-modules.sh ${TMP_DIR} +# Cleanup and repack DEB +rm -f ${DEB_NAME} +dpkg-deb --build ${TMP_DIR} ${DEB_NAME} +rm -rf ${TMP_DIR} + +if [ -f ${DRIVER_FILE} ]; then + rm -f ${DRIVER_FILE} +fi +if [ -d ${DRIVER_DIR} ]; then + rm -rf ${DRIVER_DIR} +fi +if [ -d ${DEBIAN_DIR} ]; then + rm -rf ${DEBIAN_DIR} +fi diff --git a/scripts/package-build/linux-kernel/build-nat-rtsp.sh b/scripts/package-build/linux-kernel/build-nat-rtsp.sh index ec7d19a6..33f1311d 100755 --- a/scripts/package-build/linux-kernel/build-nat-rtsp.sh +++ b/scripts/package-build/linux-kernel/build-nat-rtsp.sh @@ -15,7 +15,10 @@ fi . ${KERNEL_VAR_FILE} -cd ${SRC} && make KERNELDIR=$KERNEL_DIR +cd ${SRC} +git reset --hard HEAD +git clean --force -d -x +make KERNELDIR=$KERNEL_DIR # Copy binary to package directory DEBIAN_DIR=tmp/lib/modules/${KERNEL_VERSION}${KERNEL_SUFFIX}/extra @@ -26,6 +29,9 @@ DEBIAN_POSTINST="${CWD}/vyos-nat-rtsp.postinst" echo "#!/bin/sh" > ${DEBIAN_POSTINST} echo "/sbin/depmod -a ${KERNEL_VERSION}${KERNEL_SUFFIX}" >> ${DEBIAN_POSTINST} +# Sign generated Kernel modules +${CWD}/sign-modules.sh ${DEBIAN_DIR} + # Build Debian Package fpm --input-type dir --output-type deb --name nat-rtsp \ --version $(git describe --tags --always) --deb-compression gz \ @@ -36,3 +42,7 @@ fpm --input-type dir --output-type deb --name nat-rtsp \ --license "GPL2" --chdir tmp mv *.deb .. + +if [ -f ${DEBIAN_POSTINST} ]; then + rm -f ${DEBIAN_POSTINST} +fi diff --git a/scripts/package-build/linux-kernel/build-openvpn-dco.sh b/scripts/package-build/linux-kernel/build-openvpn-dco.sh index fd427825..518729ee 100755 --- a/scripts/package-build/linux-kernel/build-openvpn-dco.sh +++ b/scripts/package-build/linux-kernel/build-openvpn-dco.sh @@ -15,13 +15,19 @@ fi . ${KERNEL_VAR_FILE} -cd ${SRC} && make KERNEL_SRC=$KERNEL_DIR +cd ${SRC} +git reset --hard HEAD +git clean --force -d -x +make KERNEL_SRC=$KERNEL_DIR # Copy binary to package directory DEBIAN_DIR=tmp/lib/modules/${KERNEL_VERSION}${KERNEL_SUFFIX}/extra mkdir -p ${DEBIAN_DIR} cp drivers/net/ovpn-dco/ovpn-dco-v2.ko ${DEBIAN_DIR} +# Sign generated Kernel modules +${CWD}/sign-modules.sh ${DEBIAN_DIR} + # Build Debian Package fpm --input-type dir --output-type deb --name openvpn-dco \ --version $(git describe | sed s/^v//) --deb-compression gz \ diff --git a/scripts/package-build/linux-kernel/build-realtek-r8152.py b/scripts/package-build/linux-kernel/build-realtek-r8152.py new file mode 100755 index 00000000..0113eafc --- /dev/null +++ b/scripts/package-build/linux-kernel/build-realtek-r8152.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 + +import os +from tomllib import loads as toml_loads +from requests import get +from pathlib import Path +from subprocess import run + +CWD = os.getcwd() + +# dependency modifier +def add_depends(package_dir: str, package_name: str, + depends: list[str]) -> None: + """Add dependencies to a package + Args: + package_dir (str): a directory where package sources are located + package_name (str): a name of package + depends (list[str]): a list of dependencies to add + """ + depends_list: str = ', '.join(depends) + depends_line: str = f'misc:Depends={depends_list}\n' + + substvars_file = Path(f'{package_dir}/debian/{package_name}.substvars') + substvars_file.write_text(depends_line) + + +# find kernel version and source path +defaults_file: str = Path('../../../data/defaults.toml').read_text() +architecture_file: str = Path('../../../data/architectures/amd64.toml').read_text() +KERNEL_VER: str = toml_loads(defaults_file).get('kernel_version') +KERNEL_FLAVOR: str = toml_loads(defaults_file).get('kernel_flavor') +KERNEL_SRC: str = Path.cwd().as_posix() + '/linux' +# define variables +PACKAGE_NAME: str = 'vyos-drivers-realtek-r8152' +PACKAGE_VERSION: str = '2.18.1' +PACKAGE_DIR: str = f'{PACKAGE_NAME}-{PACKAGE_VERSION}' +SOURCES_ARCHIVE: str = 'r8152-2.18.1.tar.bz2' +SOURCES_URL: str = f'https://packages.vyos.net/source-mirror/r8152-2.18.1.tar.bz2' + +# download sources +sources_archive = Path(SOURCES_ARCHIVE) +sources_archive.write_bytes(get(SOURCES_URL).content) + +# prepare sources +debmake_cmd: list[str] = [ + 'debmake', '-e', 'support@vyos.io', '-f', 'VyOS Support', '-p', + PACKAGE_NAME, '-u', PACKAGE_VERSION, '-a', SOURCES_ARCHIVE +] +run(debmake_cmd) + +# add kernel to dependencies +add_depends(PACKAGE_DIR, PACKAGE_NAME, + [f'linux-image-{KERNEL_VER}-{KERNEL_FLAVOR}']) + +# configure build rules +build_rules_text: str = '''#!/usr/bin/make -f +# config +export KERNELDIR := {KERNEL_SRC} +PACKAGE_BUILD_DIR := debian/{PACKAGE_NAME} +KVER := {KERNEL_VER}-{KERNEL_FLAVOR} +MODULES_DIR := updates/drivers/net/usb +# main packaging script based on dh7 syntax +%: +\tdh $@ + +override_dh_clean: +\tdh_clean --exclude=debian/{PACKAGE_NAME}.substvars + +override_dh_prep: +\tdh_prep --exclude=debian/{PACKAGE_NAME}.substvars + +override_dh_auto_clean: +\tmake clean + +override_dh_auto_build: +\techo "KERNELDIR=${{KERNELDIR}}" +\techo "CURDIR=${{CURDIR}}" +\tmake -C ${{KERNELDIR}} M=${{CURDIR}} modules + +override_dh_auto_install: +\tinstall -D -m 644 r8152.ko ${{PACKAGE_BUILD_DIR}}/lib/modules/${{KVER}}/${{MODULES_DIR}}/r8152.ko +\t${{KERNELDIR}}/../sign-modules.sh ${{PACKAGE_BUILD_DIR}}/lib +\tinstall -D -m 644 50-usb-realtek-net.rules ${{PACKAGE_BUILD_DIR}}/etc/udev/rules.d/50-usb-realtek-net.rules +'''.format(KERNEL_SRC=KERNEL_SRC, PACKAGE_NAME=PACKAGE_NAME, KERNEL_VER=KERNEL_VER, KERNEL_FLAVOR=KERNEL_FLAVOR) + +build_rules_path = Path(f'{PACKAGE_DIR}/debian/rules') +build_rules_path.write_text(build_rules_text, encoding='utf-8') + +# build a package +debuild_cmd: list[str] = ['debuild'] +run(debuild_cmd, cwd=PACKAGE_DIR, check=True) + +# Sign generated Kernel modules +clean_cmd: list[str] = ['rm', '-rf', PACKAGE_DIR] +run(clean_cmd, cwd=CWD, check=True) diff --git a/scripts/package-build/linux-kernel/build.py b/scripts/package-build/linux-kernel/build.py index 1bcab686..af610079 100755 --- a/scripts/package-build/linux-kernel/build.py +++ b/scripts/package-build/linux-kernel/build.py @@ -63,6 +63,40 @@ def clone_or_update_repo(repo_dir: Path, scm_url: str, commit_id: str) -> None: run(['git', 'checkout', commit_id], cwd=repo_dir, check=True) +def create_tarball(package_name, source_dir=None): + """Creates a .tar.gz archive of the specified directory. + + Args: + package_name (str): The name of the package. This will also be the name of the output tarball. + source_dir (str, optional): The directory to be archived. If not provided, defaults to `package_name`. + + Raises: + FileNotFoundError: If the specified `source_dir` does not exist. + Exception: If an error occurs during tarball creation. + + Example: + >>> create_tarball("linux-6.6.56") + I: Tarball created: linux-6.6.56.tar.gz + + >>> create_tarball("my-package", "/path/to/source") + I: Tarball created: my-package.tar.gz + """ + # Use package_name as the source directory if source_dir is not provided + source_dir = source_dir or package_name + output_tarball = f"{package_name}.tar.gz" + + # Check if the source directory exists + if not os.path.isdir(source_dir): + raise FileNotFoundError(f"Directory '{source_dir}' does not exist.") + + # Create the tarball + try: + shutil.make_archive(base_name=output_tarball.replace('.tar.gz', ''), format='gztar', root_dir=source_dir) + print(f"I: Tarball created: {output_tarball}") + except Exception as e: + print(f"I: Failed to create tarball for {package_name}: {e}") + + def build_package(package: dict, dependencies: list) -> None: """Build a package from the repository @@ -88,20 +122,32 @@ def build_package(package: dict, dependencies: list) -> None: # Execute the build command if package['build_cmd'] == 'build_kernel': build_kernel(package['kernel_version']) + create_tarball(f'{package["name"]}-{package["kernel_version"]}', f'linux-{package["kernel_version"]}') elif package['build_cmd'] == 'build_linux_firmware': build_linux_firmware(package['commit_id'], package['scm_url']) + create_tarball(f'{package["name"]}-{package["commit_id"]}', f'{package["name"]}') elif package['build_cmd'] == 'build_accel_ppp': build_accel_ppp(package['commit_id'], package['scm_url']) + create_tarball(f'{package["name"]}-{package["commit_id"]}', f'{package["name"]}') elif package['build_cmd'] == 'build_intel_qat': build_intel_qat() + elif package['build_cmd'] == 'build_intel_igb': + build_intel(package['name'], package['commit_id'], package['scm_url']) elif package['build_cmd'] == 'build_intel_ixgbe': - build_intel_ixgbe() + build_intel(package['name'], package['commit_id'], package['scm_url']) elif package['build_cmd'] == 'build_intel_ixgbevf': - build_intel_ixgbevf() + build_intel(package['name'], package['commit_id'], package['scm_url']) + elif package['build_cmd'] == 'build_mellanox_ofed': + build_mellanox_ofed() + elif package['build_cmd'] == 'build_realtek_r8152': + build_realtek_r8152() elif package['build_cmd'] == 'build_jool': build_jool() + elif package['build_cmd'] == 'build_ipt_netflow': + build_ipt_netflow(package['commit_id'], package['scm_url']) elif package['build_cmd'] == 'build_openvpn_dco': build_openvpn_dco(package['commit_id'], package['scm_url']) + create_tarball(f'{package["name"]}-{package["commit_id"]}', f'{package["name"]}') elif package['build_cmd'] == 'build_nat_rtsp': build_nat_rtsp(package['commit_id'], package['scm_url']) else: @@ -173,20 +219,32 @@ def build_intel_qat(): run(['./build-intel-qat.sh'], check=True) -def build_intel_ixgbe(): - """Build Intel IXGBE""" - run(['./build-intel-ixgbe.sh'], check=True) +def build_intel(driver_name: str, commit_id: str, scm_url: str): + """Build Intel driver from Git repository""" + repo_dir = Path(f'ethernet-linux-{driver_name}') + clone_or_update_repo(repo_dir, scm_url, commit_id) + run(['./build-intel-nic.sh', driver_name], check=True) + +def build_mellanox_ofed(): + """Build Mellanox OFED""" + run(['sudo', './build-mellanox-ofed.sh'], check=True) -def build_intel_ixgbevf(): - """Build Intel IXGBEVF""" - run(['./build-intel-ixgbevf.sh'], check=True) + +def build_realtek_r8152(): + """Build Realtek r8152""" + run(['sudo', './build-realtek-r8152.py'], check=True) def build_jool(): """Build Jool""" run(['echo y | ./build-jool.py'], check=True, shell=True) +def build_ipt_netflow(commit_id, scm_url): + """Build ipt_NETFLOW""" + repo_dir = Path('ipt-netflow') + clone_or_update_repo(repo_dir, scm_url, commit_id) + run(['./build-ipt-netflow.sh'], check=True, shell=True) def build_openvpn_dco(commit_id, scm_url): """Build OpenVPN DCO""" diff --git a/scripts/package-build/linux-kernel/package.toml b/scripts/package-build/linux-kernel/package.toml index 8b030da0..0bbd6785 100644 --- a/scripts/package-build/linux-kernel/package.toml +++ b/scripts/package-build/linux-kernel/package.toml @@ -22,7 +22,6 @@ commit_id = "1.13.0" scm_url = "https://github.com/accel-ppp/accel-ppp.git" build_cmd = "build_accel_ppp" - [[packages]] name = "ovpn-dco" commit_id = "v0.2.20231117" @@ -35,7 +34,6 @@ commit_id = "475af0a" scm_url = "https://github.com/maru-sama/rtsp-linux.git" build_cmd = "build_nat_rtsp" - [[packages]] name = "qat" commit_id = "" @@ -43,15 +41,21 @@ scm_url = "" build_cmd = "build_intel_qat" [[packages]] +name = "igb" +commit_id = "v5.18.7" +scm_url = "https://github.com/intel/ethernet-linux-igb" +build_cmd = "build_intel_igb" + +[[packages]] name = "ixgbe" -commit_id = "" -scm_url = "" +commit_id = "v6.0.5" +scm_url = "https://github.com/intel/ethernet-linux-ixgbe" build_cmd = "build_intel_ixgbe" [[packages]] name = "ixgbevf" -commit_id = "" -scm_url = "" +commit_id = "v5.0.2" +scm_url = "http://github.com/intel/ethernet-linux-ixgbevf" build_cmd = "build_intel_ixgbevf" [[packages]] @@ -60,3 +64,20 @@ commit_id = "" scm_url = "" build_cmd = "build_jool" +[[packages]] +name = "mlnx" +commit_id = "" +scm_url = "" +build_cmd = "build_mellanox_ofed" + +[[packages]] +name = "realtek-r8152" +commit_id = "" +scm_url = "" +build_cmd = "build_realtek_r8152" + +[[packages]] +name = "ipt-netflow" +commit_id = "0eb2092e93" +scm_url = "https://github.com/aabc/ipt-netflow" +build_cmd = "build_ipt_netflow" diff --git a/scripts/package-build/linux-kernel/patches b/scripts/package-build/linux-kernel/patches deleted file mode 120000 index fd016d35..00000000 --- a/scripts/package-build/linux-kernel/patches +++ /dev/null @@ -1 +0,0 @@ -../../../packages/linux-kernel/patches
\ No newline at end of file diff --git a/scripts/package-build/linux-kernel/patches/accel-ppp/0001-L2TP-Include-Calling-Number-to-Calling-Station-ID-RA.patch b/scripts/package-build/linux-kernel/patches/accel-ppp/0001-L2TP-Include-Calling-Number-to-Calling-Station-ID-RA.patch new file mode 100644 index 00000000..0c3141a0 --- /dev/null +++ b/scripts/package-build/linux-kernel/patches/accel-ppp/0001-L2TP-Include-Calling-Number-to-Calling-Station-ID-RA.patch @@ -0,0 +1,183 @@ +From 12778d1e9296b6dbf190a80dcf407b24f9821f95 Mon Sep 17 00:00:00 2001 +From: zsdc <taras@vyos.io> +Date: Tue, 4 Apr 2023 11:15:26 +0300 +Subject: [PATCH] L2TP: Include Calling-Number to Calling-Station-ID RADIUS + attribute + +Patch authored by Alexander Serkin from +https://phabricator.accel-ppp.org/T59 +--- + accel-pppd/ctrl/l2tp/l2tp.c | 112 ++++++++++++++++++++++++++++++------ + 1 file changed, 93 insertions(+), 19 deletions(-) + +diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c +index 027d710..c541c60 100644 +--- a/accel-pppd/ctrl/l2tp/l2tp.c ++++ b/accel-pppd/ctrl/l2tp/l2tp.c +@@ -123,6 +123,11 @@ struct l2tp_sess_t + struct l2tp_conn_t *paren_conn; + uint16_t sid; + uint16_t peer_sid; ++/* We will keep l2tp attributes Calling-Number/Called-Number and their length while the session exists */ ++ char *calling_num; ++ int calling_num_len; ++ char *called_num; ++ int called_num_len; + + unsigned int ref_count; + int state1; +@@ -979,6 +984,10 @@ static void __session_destroy(struct l2tp_sess_t *sess) + _free(sess->ctrl.calling_station_id); + if (sess->ctrl.called_station_id) + _free(sess->ctrl.called_station_id); ++ if (sess->calling_num) ++ _free(sess->calling_num); ++ if (sess->called_num) ++ _free(sess->called_num); + + log_session(log_info2, sess, "session destroyed\n"); + +@@ -1771,25 +1780,52 @@ static int l2tp_session_start_data_channel(struct l2tp_sess_t *sess) + sess->ctrl.max_mtu = conf_ppp_max_mtu; + sess->ctrl.mppe = conf_mppe; + +- sess->ctrl.calling_station_id = _malloc(17); +- if (sess->ctrl.calling_station_id == NULL) { +- log_session(log_error, sess, +- "impossible to start data channel:" +- " allocation of calling station ID failed\n"); +- goto err; ++ /* If l2tp calling number avp exists, we use it, otherwise we use lac ip */ ++ if (sess->calling_num != NULL) { ++ sess->ctrl.calling_station_id = _malloc(sess->calling_num_len+1); ++ if (sess->ctrl.calling_station_id == NULL) { ++ log_session(log_error, sess, ++ "impossible to start data channel:" ++ " allocation of calling station ID failed\n"); ++ goto err; ++ }else { ++ strcpy(sess->ctrl.calling_station_id, sess->calling_num); ++ } ++ } else { ++ sess->ctrl.calling_station_id = _malloc(17); ++ if (sess->ctrl.calling_station_id == NULL) { ++ log_session(log_error, sess, ++ "impossible to start data channel:" ++ " allocation of calling station ID failed\n"); ++ goto err; ++ } else { ++ u_inet_ntoa(sess->paren_conn->peer_addr.sin_addr.s_addr, ++ sess->ctrl.calling_station_id); ++ } + } +- u_inet_ntoa(sess->paren_conn->peer_addr.sin_addr.s_addr, +- sess->ctrl.calling_station_id); +- +- sess->ctrl.called_station_id = _malloc(17); +- if (sess->ctrl.called_station_id == NULL) { +- log_session(log_error, sess, +- "impossible to start data channel:" +- " allocation of called station ID failed\n"); +- goto err; ++ /* If l2tp called number avp exists, we use it, otherwise we use my ip */ ++ if (sess->called_num != NULL) { ++ sess->ctrl.called_station_id = _malloc(sess->called_num_len+1); ++ if (sess->ctrl.called_station_id == NULL) { ++ log_session(log_error, sess, ++ "impossible to start data channel:" ++ " allocation of called station ID failed\n"); ++ goto err; ++ } else { ++ strcpy(sess->ctrl.called_station_id, sess->called_num); ++ } ++ } else { ++ sess->ctrl.called_station_id = _malloc(17); ++ if (sess->ctrl.called_station_id == NULL) { ++ log_session(log_error, sess, ++ "impossible to start data channel:" ++ " allocation of called station ID failed\n"); ++ goto err; ++ } else { ++ u_inet_ntoa(sess->paren_conn->host_addr.sin_addr.s_addr, ++ sess->ctrl.called_station_id); ++ } + } +- u_inet_ntoa(sess->paren_conn->host_addr.sin_addr.s_addr, +- sess->ctrl.called_station_id); + + if (conf_ip_pool) { + sess->ppp.ses.ipv4_pool_name = _strdup(conf_ip_pool); +@@ -3295,6 +3331,10 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn, + uint16_t sid = 0; + uint16_t res = 0; + uint16_t err = 0; ++ uint8_t *calling[254] = {0}; ++ uint8_t *called[254] = {0}; ++ int n = 0; ++ int m = 0; + + if (conn->state != STATE_ESTB && conn->lns_mode) { + log_tunnel(log_warn, conn, "discarding unexpected ICRQ\n"); +@@ -3332,7 +3372,17 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn, + case Call_Serial_Number: + case Bearer_Type: + case Calling_Number: ++ /* Save Calling-Number L2TP attribute locally */ ++ if (attr->attr->id == Calling_Number) { ++ n = attr->length; ++ memcpy(calling,attr->val.octets,n); ++ } + case Called_Number: ++ /* Save Called-Number L2TP attribute locally */ ++ if (attr->attr->id == Called_Number) { ++ m = attr->length; ++ memcpy(called,attr->val.octets,m); ++ } + case Sub_Address: + case Physical_Channel_ID: + break; +@@ -3371,6 +3421,30 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn, + sess->peer_sid = peer_sid; + sid = sess->sid; + ++ /* Allocate memory for Calling-Number if exists, and put it to l2tp_sess_t structure */ ++ if (calling != NULL && n > 0) { ++ sess->calling_num = _malloc(n+1); ++ if (sess->calling_num == NULL) { ++ log_tunnel(log_warn, conn, "can't allocate memory for Calling Number attribute. Will use LAC IP instead\n"); ++ }else{ ++ memcpy(sess->calling_num, calling, n); ++ sess->calling_num[n] = '\0'; ++ sess->calling_num_len = n; ++ } ++ } ++ ++ /* Allocate memory for Called-Number if exists, and put it to l2tp_sess_t structure */ ++ if (called != NULL && m > 1) { ++ sess->called_num = _malloc(m+1); ++ if (sess->called_num == NULL) { ++ log_tunnel(log_warn, conn, "can't allocate memory for Called Number attribute. Will use my IP instead\n"); ++ } else { ++ memcpy(sess->called_num, called, m); ++ sess->called_num[m] = '\0'; ++ sess->called_num_len = m; ++ } ++ } ++ + if (unknown_attr) { + log_tunnel(log_error, conn, "impossible to handle ICRQ:" + " unknown mandatory attribute type %i," +@@ -3390,8 +3464,8 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn, + goto out_reject; + } + +- log_tunnel(log_info1, conn, "new session %hu-%hu created following" +- " reception of ICRQ\n", sid, peer_sid); ++ log_tunnel(log_info1, conn, "new session %hu-%hu with calling num %s len %d, called num %s len %d created following" ++ " reception of ICRQ\n", sid, peer_sid, sess->calling_num, sess->calling_num_len, sess->called_num, sess->called_num_len); + + return 0; + +-- +2.34.1 + diff --git a/scripts/package-build/linux-kernel/patches/accel-ppp/0002-Radius-Dns-Server-IPv6-Address.patch b/scripts/package-build/linux-kernel/patches/accel-ppp/0002-Radius-Dns-Server-IPv6-Address.patch new file mode 100644 index 00000000..a8991801 --- /dev/null +++ b/scripts/package-build/linux-kernel/patches/accel-ppp/0002-Radius-Dns-Server-IPv6-Address.patch @@ -0,0 +1,195 @@ +From: Ben Hardill <ben@hardill.me.uk> +Date: Tue, 13 Mar 2025 05:00:00 +0000 +Subject: [PATCH] PPPoE: IPv6 DNS from Radius - managing the DNS-Server-IPv6-Address attribute + +Patch authored by Ben Hardill from +https://github.com/accel-ppp/accel-ppp/pull/69 +--- +diff --git a/accel-pppd/include/ap_session.h b/accel-pppd/include/ap_session.h +index 70515133..507eae04 100644 +--- a/accel-pppd/include/ap_session.h ++++ b/accel-pppd/include/ap_session.h +@@ -84,6 +84,7 @@ struct ap_session + struct ipv4db_item_t *ipv4; + struct ipv6db_item_t *ipv6; + struct ipv6db_prefix_t *ipv6_dp; ++ struct ipv6db_item_t *ipv6_dns; + char *ipv4_pool_name; + char *ipv6_pool_name; + char *dpv6_pool_name; +diff --git a/accel-pppd/ipv6/dhcpv6.c b/accel-pppd/ipv6/dhcpv6.c +index 158771b1..1ef48132 100644 +--- a/accel-pppd/ipv6/dhcpv6.c ++++ b/accel-pppd/ipv6/dhcpv6.c +@@ -214,19 +214,41 @@ static void insert_status(struct dhcpv6_packet *pkt, struct dhcpv6_option *opt, + status->code = htons(code); + } + +-static void insert_oro(struct dhcpv6_packet *reply, struct dhcpv6_option *opt) ++static void insert_oro(struct dhcpv6_packet *reply, struct dhcpv6_option *opt, struct ap_session *ses) + { + struct dhcpv6_option *opt1; +- int i, j; ++ int i = 0, j = 0, k = 0; + uint16_t *ptr; + struct in6_addr addr, *addr_ptr; ++ struct ipv6db_addr_t *dns; + + for (i = ntohs(opt->hdr->len) / 2, ptr = (uint16_t *)opt->hdr->data; i; i--, ptr++) { + if (ntohs(*ptr) == D6_OPTION_DNS_SERVERS) { +- if (conf_dns_count) { +- opt1 = dhcpv6_option_alloc(reply, D6_OPTION_DNS_SERVERS, conf_dns_count * sizeof(addr)); +- for (j = 0, addr_ptr = (struct in6_addr *)opt1->hdr->data; j < conf_dns_count; j++, addr_ptr++) +- memcpy(addr_ptr, conf_dns + j, sizeof(addr)); ++ if (ses->ipv6_dns && !list_empty(&ses->ipv6_dns->addr_list)) { ++ list_for_each_entry(dns, &ses->ipv6_dns->addr_list, entry) { ++ j++; ++ } ++ if (j >= 3) { ++ j = 3; ++ } ++ opt1 = dhcpv6_option_alloc(reply, D6_OPTION_DNS_SERVERS, j * sizeof(addr)); ++ addr_ptr = (struct in6_addr *)opt1->hdr->data; ++ list_for_each_entry(dns, &ses->ipv6_dns->addr_list, entry) { ++ if (k < j) { ++ memcpy(addr_ptr, &dns->addr, sizeof(addr)); ++ k++; ++ addr_ptr++; ++ } else { ++ break; ++ } ++ } ++ ++ } else { ++ if (conf_dns_count) { ++ opt1 = dhcpv6_option_alloc(reply, D6_OPTION_DNS_SERVERS, conf_dns_count * sizeof(addr)); ++ for (j = 0, addr_ptr = (struct in6_addr *)opt1->hdr->data; j < conf_dns_count; j++, addr_ptr++) ++ memcpy(addr_ptr, conf_dns + j, sizeof(addr)); ++ } + } + } else if (ntohs(*ptr) == D6_OPTION_DOMAIN_LIST) { + if (conf_dnssl_size) { +@@ -434,7 +456,10 @@ static void dhcpv6_send_reply(struct dhcpv6_packet *req, struct dhcpv6_pd *pd, i + + // Option Request + } else if (ntohs(opt->hdr->code) == D6_OPTION_ORO) { +- insert_oro(reply, opt); ++ if (ses->ipv6_dns &&!list_empty(&ses->ipv6_dns->addr_list)) { ++ log_ppp_info2("User specific IPv6 DNS entries\n"); ++ } ++ insert_oro(reply, opt, ses); + + } else if (ntohs(opt->hdr->code) == D6_OPTION_RAPID_COMMIT) { + if (req->hdr->type == D6_SOLICIT) +@@ -594,7 +619,7 @@ static void dhcpv6_send_reply2(struct dhcpv6_packet *req, struct dhcpv6_pd *pd, + } + // Option Request + } else if (ntohs(opt->hdr->code) == D6_OPTION_ORO) +- insert_oro(reply, opt); ++ insert_oro(reply, opt, ses); + } + + opt1 = dhcpv6_option_alloc(reply, D6_OPTION_PREFERENCE, 1); +diff --git a/accel-pppd/ipv6/nd.c b/accel-pppd/ipv6/nd.c +index 297e4d63..b3054274 100644 +--- a/accel-pppd/ipv6/nd.c ++++ b/accel-pppd/ipv6/nd.c +@@ -174,7 +174,32 @@ static void ipv6_nd_send_ra(struct ipv6_nd_handler_t *h, struct sockaddr_in6 *ds + rinfo++; + }*/ + +- if (conf_dns_count) { ++ if (ses->ipv6_dns && !list_empty(&ses->ipv6_dns->addr_list)) { ++ int i = 0, j = 0; ++ struct ipv6db_addr_t *dns; ++ ++ list_for_each_entry(dns, &ses->ipv6_dns->addr_list, entry) { ++ i++; ++ } ++ if (i >= 3) { ++ i = 3; ++ } ++ rdnssinfo = (struct nd_opt_rdnss_info_local *)pinfo; ++ memset(rdnssinfo, 0, sizeof(*rdnssinfo)); ++ rdnssinfo->nd_opt_rdnssi_type = ND_OPT_RDNSS_INFORMATION; ++ rdnssinfo->nd_opt_rdnssi_len = 1 + 2 * i; ++ rdnssinfo->nd_opt_rdnssi_lifetime = htonl(conf_rdnss_lifetime); ++ rdnss_addr = (struct in6_addr *)rdnssinfo->nd_opt_rdnssi; ++ list_for_each_entry(dns, &ses->ipv6_dns->addr_list, entry) { ++ if (j < i) { ++ memcpy(rdnss_addr, &dns->addr, sizeof(*rdnss_addr)); ++ j++; ++ rdnss_addr++; ++ } else { ++ break; ++ } ++ } ++ } else if (conf_dns_count) { + rdnssinfo = (struct nd_opt_rdnss_info_local *)pinfo; + memset(rdnssinfo, 0, sizeof(*rdnssinfo)); + rdnssinfo->nd_opt_rdnssi_type = ND_OPT_RDNSS_INFORMATION; +diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c +index 786faa56..1379b0b2 100644 +--- a/accel-pppd/radius/radius.c ++++ b/accel-pppd/radius/radius.c +@@ -403,6 +403,12 @@ int rad_proc_attrs(struct rad_req_t *req) + case Framed_IPv6_Route: + rad_add_framed_ipv6_route(attr->val.string, rpd); + break; ++ case DNS_Server_IPv6_Address: ++ a = _malloc(sizeof(*a)); ++ memset(a, 0, sizeof(*a)); ++ a->addr = attr->val.ipv6addr; ++ list_add_tail(&a->entry, &rpd->ipv6_dns.addr_list); ++ break; + } + } + +@@ -420,6 +426,9 @@ int rad_proc_attrs(struct rad_req_t *req) + if (!rpd->ses->ipv6_dp && !list_empty(&rpd->ipv6_dp.prefix_list)) + rpd->ses->ipv6_dp = &rpd->ipv6_dp; + ++ if (!rpd->ses->ipv6_dns && !list_empty(&rpd->ipv6_dns.addr_list)) ++ rpd->ses->ipv6_dns = &rpd->ipv6_dns; ++ + return res; + } + +@@ -584,10 +593,12 @@ static void ses_starting(struct ap_session *ses) + INIT_LIST_HEAD(&rpd->plugin_list); + INIT_LIST_HEAD(&rpd->ipv6_addr.addr_list); + INIT_LIST_HEAD(&rpd->ipv6_dp.prefix_list); ++ INIT_LIST_HEAD(&rpd->ipv6_dns.addr_list); + + rpd->ipv4_addr.owner = &ipdb; + rpd->ipv6_addr.owner = &ipdb; + rpd->ipv6_dp.owner = &ipdb; ++ rpd->ipv6_dns.owner = &ipdb; + + list_add_tail(&rpd->pd.entry, &ses->pd_list); + +@@ -764,6 +775,12 @@ static void ses_finished(struct ap_session *ses) + _free(a); + } + ++ while (!list_empty(&rpd->ipv6_dns.addr_list)) { ++ a = list_entry(rpd->ipv6_dns.addr_list.next, typeof(*a), entry); ++ list_del(&a->entry); ++ _free(a); ++ } ++ + fr6 = rpd->fr6; + while (fr6) { + struct framed_ip6_route *next = fr6->next; +diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h +index 988f154f..eaa5acb0 100644 +--- a/accel-pppd/radius/radius_p.h ++++ b/accel-pppd/radius/radius_p.h +@@ -65,6 +65,7 @@ struct radius_pd_t { + struct ipv4db_item_t ipv4_addr; + struct ipv6db_item_t ipv6_addr; + struct ipv6db_prefix_t ipv6_dp; ++ struct ipv6db_item_t ipv6_dns; + int acct_interim_interval; + int acct_interim_jitter; + diff --git a/scripts/package-build/linux-kernel/patches/ixgbe/0001-ixgbe-always-enable-support-for-unsupported-SFP-modu.patch b/scripts/package-build/linux-kernel/patches/ixgbe/0001-ixgbe-always-enable-support-for-unsupported-SFP-modu.patch new file mode 100644 index 00000000..3f2cbb4f --- /dev/null +++ b/scripts/package-build/linux-kernel/patches/ixgbe/0001-ixgbe-always-enable-support-for-unsupported-SFP-modu.patch @@ -0,0 +1,48 @@ +From a3ebb453f4a8c95fe3674d09646edb93946d450a Mon Sep 17 00:00:00 2001 +From: Christian Breunig <christian@breunig.cc> +Date: Sat, 15 Feb 2025 09:17:10 +0100 +Subject: [PATCH] ixgbe: always enable support for unsupported SFP+ modules + +--- + src/ixgbe_param.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/ixgbe_param.c b/src/ixgbe_param.c +index bba03ae..3f29492 100644 +--- a/src/ixgbe_param.c ++++ b/src/ixgbe_param.c +@@ -307,7 +307,7 @@ IXGBE_PARAM(LRO, "Large Receive Offload (0,1), default 0 = off"); + * Default Value: 0 + */ + IXGBE_PARAM(allow_unsupported_sfp, "Allow unsupported and untested " +- "SFP+ modules on 82599 based adapters, default 0 = Disable"); ++ "SFP+ modules on 82599 based adapters, default 1 = Enable"); + + /* Enable/disable support for DMA coalescing + * +@@ -1135,8 +1135,8 @@ void ixgbe_check_options(struct ixgbe_adapter *adapter) + struct ixgbe_option opt = { + .type = enable_option, + .name = "allow_unsupported_sfp", +- .err = "defaulting to Disabled", +- .def = OPTION_DISABLED ++ .err = "defaulting to Enabled", ++ .def = OPTION_ENABLED + }; + #ifdef module_param_array + if (num_allow_unsupported_sfp > bd) { +@@ -1152,7 +1152,11 @@ void ixgbe_check_options(struct ixgbe_adapter *adapter) + } + #ifdef module_param_array + } else { ++ if (opt.def == OPTION_ENABLED) { ++ adapter->hw.allow_unsupported_sfp = true; ++ } else { + adapter->hw.allow_unsupported_sfp = false; ++ } + } + #endif + } +-- +2.39.5 + diff --git a/scripts/package-build/linux-kernel/patches/ixgbe/0002-BACKPORT-linux-v6.9-PATCH-ixgbe-Add-1000BASE-BX-supp.patch b/scripts/package-build/linux-kernel/patches/ixgbe/0002-BACKPORT-linux-v6.9-PATCH-ixgbe-Add-1000BASE-BX-supp.patch new file mode 100644 index 00000000..924c248b --- /dev/null +++ b/scripts/package-build/linux-kernel/patches/ixgbe/0002-BACKPORT-linux-v6.9-PATCH-ixgbe-Add-1000BASE-BX-supp.patch @@ -0,0 +1,259 @@ +From 0ef6088d0d93fcda7adee59fe675f96bcae36c13 Mon Sep 17 00:00:00 2001 +From: Christian Breunig <christian@breunig.cc> +Date: Sat, 15 Feb 2025 09:17:35 +0100 +Subject: [PATCH] [BACKPORT linux v6.9] [PATCH] ixgbe: Add 1000BASE-BX support + +Added support for 1000BASE-BX, i.e. Gigabit Ethernet over single strand +of single-mode fiber. +The initialization of a 1000BASE-BX SFP is the same as 1000BASE-SX/LX +with the only difference that the Bit Rate Nominal Value must be +checked to make sure it is a Gigabit Ethernet transceiver, as described +by the SFF-8472 specification. + +This was tested with the FS.com SFP-GE-BX 1310/1490nm 10km transceiver: +$ ethtool -m eth4 + Identifier : 0x03 (SFP) + Extended identifier : 0x04 (GBIC/SFP defined by 2-wire interface ID) + Connector : 0x07 (LC) + Transceiver codes : 0x00 0x00 0x00 0x40 0x00 0x00 0x00 0x00 0x00 + Transceiver type : Ethernet: BASE-BX10 + Encoding : 0x01 (8B/10B) + BR, Nominal : 1300MBd + Rate identifier : 0x00 (unspecified) + Length (SMF,km) : 10km + Length (SMF) : 10000m + Length (50um) : 0m + Length (62.5um) : 0m + Length (Copper) : 0m + Length (OM3) : 0m + Laser wavelength : 1310nm + Vendor name : FS + Vendor OUI : 64:9d:99 + Vendor PN : SFP-GE-BX + Vendor rev : + Option values : 0x20 0x0a + Option : RX_LOS implemented + Option : TX_FAULT implemented + Option : Power level 3 requirement + BR margin, max : 0% + BR margin, min : 0% + Vendor SN : S2202359108 + Date code : 220307 + Optical diagnostics support : Yes + Laser bias current : 17.650 mA + Laser output power : 0.2132 mW / -6.71 dBm + Receiver signal average optical power : 0.2740 mW / -5.62 dBm + Module temperature : 47.30 degrees C / 117.13 degrees F + Module voltage : 3.2576 V + Alarm/warning flags implemented : Yes + Laser bias current high alarm : Off + Laser bias current low alarm : Off + Laser bias current high warning : Off + Laser bias current low warning : Off + Laser output power high alarm : Off + Laser output power low alarm : Off + Laser output power high warning : Off + Laser output power low warning : Off + Module temperature high alarm : Off + Module temperature low alarm : Off + Module temperature high warning : Off + Module temperature low warning : Off + Module voltage high alarm : Off + Module voltage low alarm : Off + Module voltage high warning : Off + Module voltage low warning : Off + Laser rx power high alarm : Off + Laser rx power low alarm : Off + Laser rx power high warning : Off + Laser rx power low warning : Off + Laser bias current high alarm threshold : 110.000 mA + Laser bias current low alarm threshold : 1.000 mA + Laser bias current high warning threshold : 100.000 mA + Laser bias current low warning threshold : 1.000 mA + Laser output power high alarm threshold : 0.7079 mW / -1.50 dBm + Laser output power low alarm threshold : 0.0891 mW / -10.50 dBm + Laser output power high warning threshold : 0.6310 mW / -2.00 dBm + Laser output power low warning threshold : 0.1000 mW / -10.00 dBm + Module temperature high alarm threshold : 90.00 degrees C / 194.00 degrees F + Module temperature low alarm threshold : -45.00 degrees C / -49.00 degrees F + Module temperature high warning threshold : 85.00 degrees C / 185.00 degrees F + Module temperature low warning threshold : -40.00 degrees C / -40.00 degrees F + Module voltage high alarm threshold : 3.7950 V + Module voltage low alarm threshold : 2.8050 V + Module voltage high warning threshold : 3.4650 V + Module voltage low warning threshold : 3.1350 V + Laser rx power high alarm threshold : 0.7079 mW / -1.50 dBm + Laser rx power low alarm threshold : 0.0028 mW / -25.53 dBm + Laser rx power high warning threshold : 0.6310 mW / -2.00 dBm + Laser rx power low warning threshold : 0.0032 mW / -24.95 dBm + +Signed-off-by: Ernesto Castellotti <ernesto@castellotti.net> +Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> +Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com> (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> +Link: https://lore.kernel.org/r/20240301184806.2634508-3-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +--- + src/ixgbe_82599.c | 4 +++- + src/ixgbe_ethtool.c | 4 ++++ + src/ixgbe_phy.c | 33 +++++++++++++++++++++++++++++---- + src/ixgbe_phy.h | 2 ++ + src/ixgbe_type.h | 2 ++ + 5 files changed, 40 insertions(+), 5 deletions(-) + +diff --git a/src/ixgbe_82599.c b/src/ixgbe_82599.c +index c95fc4f..a5c74df 100644 +--- a/src/ixgbe_82599.c ++++ b/src/ixgbe_82599.c +@@ -395,7 +395,9 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || +- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) { ++ hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1 || ++ hw->phy.sfp_type == ixgbe_sfp_type_1g_bx_core0 || ++ hw->phy.sfp_type == ixgbe_sfp_type_1g_bx_core1) { + *speed = IXGBE_LINK_SPEED_1GB_FULL; + *autoneg = true; + goto out; +diff --git a/src/ixgbe_ethtool.c b/src/ixgbe_ethtool.c +index e983035..7dc9343 100644 +--- a/src/ixgbe_ethtool.c ++++ b/src/ixgbe_ethtool.c +@@ -412,6 +412,8 @@ static int ixgbe_get_link_ksettings(struct net_device *netdev, + case ixgbe_sfp_type_1g_sx_core1: + case ixgbe_sfp_type_1g_lx_core0: + case ixgbe_sfp_type_1g_lx_core1: ++ case ixgbe_sfp_type_1g_bx_core0: ++ case ixgbe_sfp_type_1g_bx_core1: + ethtool_link_ksettings_add_link_mode(cmd, supported, + FIBRE); + ethtool_link_ksettings_add_link_mode(cmd, advertising, +@@ -642,6 +644,8 @@ static int ixgbe_get_settings(struct net_device *netdev, + case ixgbe_sfp_type_1g_sx_core1: + case ixgbe_sfp_type_1g_lx_core0: + case ixgbe_sfp_type_1g_lx_core1: ++ case ixgbe_sfp_type_1g_bx_core0: ++ case ixgbe_sfp_type_1g_bx_core1: + ecmd->supported |= SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_FIBRE; + ecmd->port = PORT_FIBRE; +diff --git a/src/ixgbe_phy.c b/src/ixgbe_phy.c +index 3d99a88..3632234 100644 +--- a/src/ixgbe_phy.c ++++ b/src/ixgbe_phy.c +@@ -1268,6 +1268,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) + u8 comp_codes_1g = 0; + u8 comp_codes_10g = 0; + u8 oui_bytes[3] = {0, 0, 0}; ++ u8 bitrate_nominal = 0; + u8 cable_tech = 0; + u8 cable_spec = 0; + u16 enforce_sfp = 0; +@@ -1311,6 +1312,12 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) + IXGBE_SFF_CABLE_TECHNOLOGY, + &cable_tech); + ++ if (status != IXGBE_SUCCESS) ++ goto err_read_i2c_eeprom; ++ ++ status = hw->phy.ops.read_i2c_eeprom(hw, ++ IXGBE_SFF_BITRATE_NOMINAL, ++ &bitrate_nominal); + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + +@@ -1393,6 +1400,18 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) + else + hw->phy.sfp_type = + ixgbe_sfp_type_1g_lx_core1; ++ /* Support only Ethernet 1000BASE-BX10, checking the Bit Rate ++ * Nominal Value as per SFF-8472 by convention 1.25 Gb/s should ++ * be rounded up to 0Dh (13 in units of 100 MBd) for 1000BASE-BX ++ */ ++ } else if ((comp_codes_1g & IXGBE_SFF_BASEBX10_CAPABLE) && ++ (bitrate_nominal == 0xD)) { ++ if (hw->bus.lan_id == 0) ++ hw->phy.sfp_type = ++ ixgbe_sfp_type_1g_bx_core0; ++ else ++ hw->phy.sfp_type = ++ ixgbe_sfp_type_1g_bx_core1; + } else { + hw->phy.sfp_type = ixgbe_sfp_type_unknown; + } +@@ -1483,7 +1502,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || +- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { ++ hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1 || ++ hw->phy.sfp_type == ixgbe_sfp_type_1g_bx_core0 || ++ hw->phy.sfp_type == ixgbe_sfp_type_1g_bx_core1)) { + hw->phy.type = ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + goto out; +@@ -1502,7 +1523,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || +- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { ++ hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1 || ++ hw->phy.sfp_type == ixgbe_sfp_type_1g_bx_core0 || ++ hw->phy.sfp_type == ixgbe_sfp_type_1g_bx_core1)) { + /* Make sure we're a supported PHY type */ + if (hw->phy.type == ixgbe_phy_sfp_intel) { + status = IXGBE_SUCCESS; +@@ -1821,12 +1844,14 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, + if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 || + sfp_type == ixgbe_sfp_type_1g_lx_core0 || + sfp_type == ixgbe_sfp_type_1g_cu_core0 || +- sfp_type == ixgbe_sfp_type_1g_sx_core0) ++ sfp_type == ixgbe_sfp_type_1g_sx_core0 || ++ sfp_type == ixgbe_sfp_type_1g_bx_core0) + sfp_type = ixgbe_sfp_type_srlr_core0; + else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 || + sfp_type == ixgbe_sfp_type_1g_lx_core1 || + sfp_type == ixgbe_sfp_type_1g_cu_core1 || +- sfp_type == ixgbe_sfp_type_1g_sx_core1) ++ sfp_type == ixgbe_sfp_type_1g_sx_core1 || ++ sfp_type == ixgbe_sfp_type_1g_bx_core1) + sfp_type = ixgbe_sfp_type_srlr_core1; + + /* Read offset to PHY init contents */ +diff --git a/src/ixgbe_phy.h b/src/ixgbe_phy.h +index b6ddb2e..29c4645 100644 +--- a/src/ixgbe_phy.h ++++ b/src/ixgbe_phy.h +@@ -18,6 +18,7 @@ + #define IXGBE_SFF_1GBE_COMP_CODES 0x6 + #define IXGBE_SFF_10GBE_COMP_CODES 0x3 + #define IXGBE_SFF_CABLE_TECHNOLOGY 0x8 ++#define IXGBE_SFF_BITRATE_NOMINAL 0xC + #define IXGBE_SFF_CABLE_SPEC_COMP 0x3C + #define IXGBE_SFF_SFF_8472_SWAP 0x5C + #define IXGBE_SFF_SFF_8472_COMP 0x5E +@@ -40,6 +41,7 @@ + #define IXGBE_SFF_1GBASESX_CAPABLE 0x1 + #define IXGBE_SFF_1GBASELX_CAPABLE 0x2 + #define IXGBE_SFF_1GBASET_CAPABLE 0x8 ++#define IXGBE_SFF_BASEBX10_CAPABLE 0x64 + #define IXGBE_SFF_10GBASESR_CAPABLE 0x10 + #define IXGBE_SFF_10GBASELR_CAPABLE 0x20 + #define IXGBE_SFF_SOFT_RS_SELECT_MASK 0x8 +diff --git a/src/ixgbe_type.h b/src/ixgbe_type.h +index 1700599..403687c 100644 +--- a/src/ixgbe_type.h ++++ b/src/ixgbe_type.h +@@ -3722,6 +3722,8 @@ enum ixgbe_sfp_type { + ixgbe_sfp_type_1g_sx_core1 = 12, + ixgbe_sfp_type_1g_lx_core0 = 13, + ixgbe_sfp_type_1g_lx_core1 = 14, ++ ixgbe_sfp_type_1g_bx_core0 = 15, ++ ixgbe_sfp_type_1g_bx_core1 = 16, + ixgbe_sfp_type_not_present = 0xFFFE, + ixgbe_sfp_type_unknown = 0xFFFF + }; +-- +2.39.5 + diff --git a/scripts/package-build/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch b/scripts/package-build/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch new file mode 100644 index 00000000..7bd0b04b --- /dev/null +++ b/scripts/package-build/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch @@ -0,0 +1,158 @@ +From 81d38c4a32e059ad7835f7dc254e7627642afbe9 Mon Sep 17 00:00:00 2001 +From: Stephen Hemminger <stephen@networkplumber.org> +Date: Mon, 29 Apr 2013 18:50:15 -0700 +Subject: [PATCH] VyOS: Add linkstate IP device attribute + +Backport of earlier Vyatta patch. + +(cherry picked from commit 7c5a851086686be14ae937c80d6cee34814dbefc) +--- + Documentation/networking/ip-sysctl.rst | 11 +++++++++++ + include/linux/inetdevice.h | 1 + + include/linux/ipv6.h | 1 + + include/uapi/linux/ip.h | 1 + + include/uapi/linux/ipv6.h | 1 + + net/ipv4/devinet.c | 1 + + net/ipv6/addrconf.c | 8 ++++++++ + net/ipv6/route.c | 10 ++++++++++ + 8 files changed, 34 insertions(+) + +diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst +index a66054d0763a..53440098fa98 100644 +--- a/Documentation/networking/ip-sysctl.rst ++++ b/Documentation/networking/ip-sysctl.rst +@@ -1734,6 +1734,17 @@ src_valid_mark - BOOLEAN + + Default value is 0. + ++link_filter - INTEGER ++ 0 - Allow packets to be received for the address on this interface ++ even if interface is disabled or no carrier. ++ 1 - Ignore packets received if interface associated with the incoming ++ address is down. ++ 2 - Ignore packets received if interface associated with the incoming ++ address is down or has no carrier. ++ ++ Default value is 0. Note that some distributions enable it ++ in startup scripts. ++ + arp_filter - BOOLEAN + - 1 - Allows you to have multiple network interfaces on the same + subnet, and have the ARPs for each interface be answered +diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h +index ddb27fc0ee8c..8ee3191d9558 100644 +--- a/include/linux/inetdevice.h ++++ b/include/linux/inetdevice.h +@@ -137,6 +137,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev) + #define IN_DEV_ARP_NOTIFY(in_dev) IN_DEV_MAXCONF((in_dev), ARP_NOTIFY) + #define IN_DEV_ARP_EVICT_NOCARRIER(in_dev) IN_DEV_ANDCONF((in_dev), \ + ARP_EVICT_NOCARRIER) ++#define IN_DEV_LINKFILTER(in_dev) IN_DEV_MAXCONF((in_dev), LINKFILTER) + + struct in_ifaddr { + struct hlist_node hash; +diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h +index af8a771a053c..ece8ac89d317 100644 +--- a/include/linux/ipv6.h ++++ b/include/linux/ipv6.h +@@ -84,6 +84,7 @@ struct ipv6_devconf { + __u8 ndisc_evict_nocarrier; + + struct ctl_table_header *sysctl_header; ++ __s32 link_filter; + }; + + struct ipv6_params { +diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h +index 283dec7e3645..8067941a635e 100644 +--- a/include/uapi/linux/ip.h ++++ b/include/uapi/linux/ip.h +@@ -173,6 +173,7 @@ enum + IPV4_DEVCONF_DROP_GRATUITOUS_ARP, + IPV4_DEVCONF_BC_FORWARDING, + IPV4_DEVCONF_ARP_EVICT_NOCARRIER, ++ IPV4_DEVCONF_LINKFILTER, + __IPV4_DEVCONF_MAX + }; + +diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h +index cf592d7b630f..e8915701aa73 100644 +--- a/include/uapi/linux/ipv6.h ++++ b/include/uapi/linux/ipv6.h +@@ -199,6 +199,7 @@ enum { + DEVCONF_NDISC_EVICT_NOCARRIER, + DEVCONF_ACCEPT_UNTRACKED_NA, + DEVCONF_ACCEPT_RA_MIN_LFT, ++ DEVCONF_LINK_FILTER, + DEVCONF_MAX + }; + +diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c +index c33b1ecc591e..7576d51cd16d 100644 +--- a/net/ipv4/devinet.c ++++ b/net/ipv4/devinet.c +@@ -2609,6 +2609,7 @@ static struct devinet_sysctl_table { + "route_localnet"), + DEVINET_SYSCTL_FLUSHING_ENTRY(DROP_UNICAST_IN_L2_MULTICAST, + "drop_unicast_in_l2_multicast"), ++ DEVINET_SYSCTL_RW_ENTRY(LINKFILTER, "link_filter"), + }, + }; + +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 8360939acf85..b13832a08d28 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -5674,6 +5674,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, + array[DEVCONF_NDISC_EVICT_NOCARRIER] = cnf->ndisc_evict_nocarrier; + array[DEVCONF_ACCEPT_UNTRACKED_NA] = cnf->accept_untracked_na; + array[DEVCONF_ACCEPT_RA_MIN_LFT] = cnf->accept_ra_min_lft; ++ array[DEVCONF_LINK_FILTER] = cnf->link_filter; + } + + static inline size_t inet6_ifla6_size(void) +@@ -7103,6 +7104,13 @@ static const struct ctl_table addrconf_sysctl[] = { + .extra1 = (void *)SYSCTL_ZERO, + .extra2 = (void *)SYSCTL_ONE, + }, ++ { ++ .procname = "link_filter", ++ .data = &ipv6_devconf.link_filter, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec, ++ }, + { + .procname = "ioam6_id", + .data = &ipv6_devconf.ioam6_id, +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 5715d54f3d0b..e88971b512ba 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -682,6 +682,14 @@ static inline void rt6_probe(struct fib6_nh *fib6_nh) + } + #endif + ++static inline int rt6_link_filter(const struct fib6_nh *nh) ++{ ++ const struct net_device *dev = nh->fib_nh_dev; ++ int linkf = __in6_dev_get(dev)->cnf.link_filter; ++ return (linkf && !netif_running(dev)) ++ || (linkf > 1 && !netif_carrier_ok(dev)); ++} ++ + /* + * Default Router Selection (RFC 2461 6.3.6) + */ +@@ -723,6 +731,8 @@ static int rt6_score_route(const struct fib6_nh *nh, u32 fib6_flags, int oif, + + if (!m && (strict & RT6_LOOKUP_F_IFACE)) + return RT6_NUD_FAIL_HARD; ++ if (rt6_link_filter(nh)) ++ return -1; + #ifdef CONFIG_IPV6_ROUTER_PREF + m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(fib6_flags)) << 2; + #endif +-- +2.39.5 + diff --git a/scripts/package-build/linux-kernel/patches/kernel/0002-inotify-support-for-stackable-filesystems.patch b/scripts/package-build/linux-kernel/patches/kernel/0002-inotify-support-for-stackable-filesystems.patch new file mode 100644 index 00000000..b19a8d25 --- /dev/null +++ b/scripts/package-build/linux-kernel/patches/kernel/0002-inotify-support-for-stackable-filesystems.patch @@ -0,0 +1,298 @@ +From 1d625d2f745b61a718ce52cd1729f467c17defa6 Mon Sep 17 00:00:00 2001 +From: Alex Harpin <development@landsofshadow.co.uk> +Date: Wed, 31 Dec 2014 10:33:38 +0000 +Subject: [PATCH] VyOS: add inotify support for stackable filesystems + (overlayfs) + +As it stands at the moment, overlayfs doesn't have full support for +inotify, and as such anything that relies on inotify currently has +issues. The simplest method of demonstrating this is to tail a file +(so tail -f /var/log/messages) and see that it doesn't follow changes +in that file. This has been reported in a number of places, including +Bug #882147 in Ubuntu. This patch is based on the version proposed by +Li Jianguo in response to this bug, adding support for inotify in +stackable filesystems. + +This commit provides a complete fix for the workaround implemented +for bug #303, and will allow that commit to be reverted. + +Bug #425 http://bugzilla.vyos.net/show_bug.cgi?id=425 + +(cherry picked from commit a93f1128bc83b5a6628da242e71c18ef05e81ea2) +--- + fs/notify/inotify/Kconfig | 9 +++ + fs/notify/inotify/inotify_user.c | 114 ++++++++++++++++++++++++++++++- + fs/overlayfs/super.c | 27 ++++++-- + include/linux/inotify.h | 28 ++++++++ + 4 files changed, 172 insertions(+), 6 deletions(-) + +diff --git a/fs/notify/inotify/Kconfig b/fs/notify/inotify/Kconfig +index 1cc8be25df7e..bc4acd1a6ea4 100644 +--- a/fs/notify/inotify/Kconfig ++++ b/fs/notify/inotify/Kconfig +@@ -15,3 +15,12 @@ config INOTIFY_USER + For more information, see <file:Documentation/filesystems/inotify.rst> + + If unsure, say Y. ++ ++config INOTIFY_STACKFS ++ bool "Inotify support for stackable filesystem" ++ select INOTIFY_USER ++ default y ++ help ++ Say Y here to enable inotify support for stackable filesystem. ++ ++ If unsure, say N. +diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c +index 1c4bfdab008d..cf567cc33679 100644 +--- a/fs/notify/inotify/inotify_user.c ++++ b/fs/notify/inotify/inotify_user.c +@@ -15,6 +15,7 @@ + + #include <linux/file.h> + #include <linux/fs.h> /* struct inode */ ++#include <linux/mount.h> + #include <linux/fsnotify_backend.h> + #include <linux/idr.h> + #include <linux/init.h> /* fs_initcall */ +@@ -97,6 +98,93 @@ static void __init inotify_sysctls_init(void) + #define inotify_sysctls_init() do { } while (0) + #endif /* CONFIG_SYSCTL */ + ++#ifdef CONFIG_INOTIFY_STACKFS ++ ++static DEFINE_RWLOCK(inotify_fs_lock); ++static LIST_HEAD(inotify_fs_list); ++ ++static inline struct file_system_type* peek_fs_type(struct path *path) ++{ ++ return path->mnt->mnt_sb->s_type; ++} ++ ++static struct inotify_stackfs* inotify_get_stackfs(struct path *path) ++{ ++ struct file_system_type *fs; ++ struct inotify_stackfs *fse, *ret = NULL; ++ ++ fs = peek_fs_type(path); ++ ++ read_lock(&inotify_fs_lock); ++ list_for_each_entry(fse, &inotify_fs_list, list) { ++ if (fse->fs_type == fs) { ++ ret = fse; ++ break; ++ } ++ } ++ read_unlock(&inotify_fs_lock); ++ ++ return ret; ++} ++ ++static inline void inotify_put_stackfs(struct inotify_stackfs *fs) ++{ ++} ++ ++int inotify_register_stackfs(struct inotify_stackfs *fs) ++{ ++ int ret = 0; ++ struct inotify_stackfs *fse; ++ ++ BUG_ON(IS_ERR_OR_NULL(fs->fs_type)); ++ BUG_ON(IS_ERR_OR_NULL(fs->func)); ++ ++ INIT_LIST_HEAD(&fs->list); ++ ++ write_lock(&inotify_fs_lock); ++ list_for_each_entry(fse, &inotify_fs_list, list) { ++ if (fse->fs_type == fs->fs_type) { ++ write_unlock(&inotify_fs_lock); ++ ret = -EBUSY; ++ goto out; ++ } ++ } ++ list_add_tail(&fs->list, &inotify_fs_list); ++ write_unlock(&inotify_fs_lock); ++ ++out: ++ return ret; ++} ++EXPORT_SYMBOL_GPL(inotify_register_stackfs); ++ ++void inotify_unregister_stackfs(struct inotify_stackfs *fs) ++{ ++ struct inotify_stackfs *fse, *n; ++ ++ write_lock(&inotify_fs_lock); ++ list_for_each_entry_safe(fse, n, &inotify_fs_list, list) { ++ if (fse == fs) { ++ list_del(&fse->list); ++ break; ++ } ++ } ++ write_unlock(&inotify_fs_lock); ++} ++EXPORT_SYMBOL_GPL(inotify_unregister_stackfs); ++ ++#else ++ ++static inline struct inotify_stackfs* inotify_get_stackfs(struct path *path) ++{ ++ return NULL; ++} ++ ++static inline void inotify_put_stackfs(struct inotify_stackfs *fs) ++{ ++} ++ ++#endif /* CONFIG_INOTIFY_STACKFS */ ++ + static inline __u32 inotify_arg_to_mask(struct inode *inode, u32 arg) + { + __u32 mask; +@@ -370,8 +458,8 @@ static const struct file_operations inotify_fops = { + /* + * find_inode - resolve a user-given path to a specific inode + */ +-static int inotify_find_inode(const char __user *dirname, struct path *path, +- unsigned int flags, __u64 mask) ++static inline int __inotify_find_inode(const char __user *dirname, struct path *path, ++ unsigned int flags, __u64 mask) + { + int error; + +@@ -392,6 +480,28 @@ static int inotify_find_inode(const char __user *dirname, struct path *path, + return error; + } + ++static int inotify_find_inode(const char __user *dirname, struct path *path, ++ unsigned int flags, __u64 mask) ++{ ++ int ret; ++ struct path tpath; ++ struct inotify_stackfs *fse; ++ ++ ret = __inotify_find_inode(dirname, &tpath, flags, mask); ++ if (ret) ++ return ret; ++ fse = inotify_get_stackfs(&tpath); ++ if (fse == NULL) { ++ *path = tpath; ++ return 0; ++ } ++ ret = fse->func(path, &tpath); ++ inotify_put_stackfs(fse); ++ path_put(&tpath); ++ ++ return ret; ++} ++ + static int inotify_add_to_idr(struct idr *idr, spinlock_t *idr_lock, + struct inotify_inode_mark *i_mark) + { +diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c +index 2c056d737c27..2cb1f0024e70 100644 +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -15,6 +15,7 @@ + #include <linux/seq_file.h> + #include <linux/posix_acl_xattr.h> + #include <linux/exportfs.h> ++#include <linux/inotify.h> + #include <linux/file.h> + #include <linux/fs_context.h> + #include <linux/fs_parser.h> +@@ -1528,6 +1529,18 @@ static void ovl_inode_init_once(void *foo) + inode_init_once(&oi->vfs_inode); + } + ++static int ovl_inotify_path(struct path *dst, struct path *src) ++{ ++ ovl_path_real(src->dentry, dst); ++ path_get(dst); ++ return 0; ++} ++ ++static struct inotify_stackfs ovl_inotify = { ++ .fs_type = &ovl_fs_type, ++ .func = ovl_inotify_path, ++}; ++ + static int __init ovl_init(void) + { + int err; +@@ -1543,18 +1556,24 @@ static int __init ovl_init(void) + err = ovl_aio_request_cache_init(); + if (!err) { + err = register_filesystem(&ovl_fs_type); +- if (!err) +- return 0; ++ if (err) ++ goto err; ++ err = inotify_register_stackfs(&ovl_inotify); ++ if (err) ++ goto err; ++ return 0; + +- ovl_aio_request_cache_destroy(); + } ++err: + kmem_cache_destroy(ovl_inode_cachep); +- ++ unregister_filesystem(&ovl_fs_type); ++ ovl_aio_request_cache_destroy(); + return err; + } + + static void __exit ovl_exit(void) + { ++ inotify_unregister_stackfs(&ovl_inotify); + unregister_filesystem(&ovl_fs_type); + + /* +diff --git a/include/linux/inotify.h b/include/linux/inotify.h +index 8d20caa1b268..c126e2f93a73 100644 +--- a/include/linux/inotify.h ++++ b/include/linux/inotify.h +@@ -8,6 +8,8 @@ + #define _LINUX_INOTIFY_H + + #include <uapi/linux/inotify.h> ++#include <linux/list.h> ++#include <linux/fs.h> + + #define ALL_INOTIFY_BITS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \ + IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \ +@@ -17,4 +19,30 @@ + IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_MASK_ADD | \ + IN_MASK_CREATE | IN_ISDIR | IN_ONESHOT) + ++typedef int (*inotify_path_proc)(struct path *dst, struct path *src); ++ ++struct inotify_stackfs { ++ struct list_head list; /* entry in inotify_fs_list */ ++ struct file_system_type *fs_type; /* registed file_system_type */ ++ inotify_path_proc func; /* registed callback function */ ++}; ++ ++#ifdef CONFIG_INOTIFY_STACKFS ++ ++extern int inotify_register_stackfs(struct inotify_stackfs *fs); ++extern void inotify_unregister_stackfs(struct inotify_stackfs *fs); ++ ++#else ++ ++static inline int inotify_register_stackfs(struct inotify_stackfs *fs) ++{ ++ return 0; ++} ++ ++static inline void inotify_unregister_stackfs(struct inotify_stackfs *fs) ++{ ++} ++ ++#endif /* CONFIG_INOTIFY_STACKFS */ ++ + #endif /* _LINUX_INOTIFY_H */ +-- +2.39.2 + diff --git a/scripts/package-build/linux-kernel/sign-modules.sh b/scripts/package-build/linux-kernel/sign-modules.sh new file mode 100755 index 00000000..cfb368eb --- /dev/null +++ b/scripts/package-build/linux-kernel/sign-modules.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +BASE_DIR=$(dirname $0) +MODULE_DIR=$1 +. ${BASE_DIR}/kernel-vars + +SIGN_FILE="${KERNEL_DIR}/scripts/sign-file" + +if [ -f ${EPHEMERAL_KEY} ] && [ -f ${EPHEMERAL_CERT} ]; then + find ${MODULE_DIR} -type f -name \*.ko | while read MODULE; do + echo "I: Signing ${MODULE} ..." + ${SIGN_FILE} sha512 ${EPHEMERAL_KEY} ${EPHEMERAL_CERT} ${MODULE} + done +fi + diff --git a/scripts/package-build/ndppd/.gitignore b/scripts/package-build/ndppd/.gitignore index 2b71e9fb..4983088e 100644 --- a/scripts/package-build/ndppd/.gitignore +++ b/scripts/package-build/ndppd/.gitignore @@ -1,7 +1 @@ -ndppd/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc - +/ndppd/ diff --git a/scripts/package-build/ndppd/patches/0001-skip-route-table-if-there-is-no-auto-rule.patch b/scripts/package-build/ndppd/patches/ndppd/0001-skip-route-table-if-there-is-no-auto-rule.patch index df6d2e5c..df6d2e5c 100644 --- a/scripts/package-build/ndppd/patches/0001-skip-route-table-if-there-is-no-auto-rule.patch +++ b/scripts/package-build/ndppd/patches/ndppd/0001-skip-route-table-if-there-is-no-auto-rule.patch diff --git a/scripts/package-build/ndppd/patches/0002-set-vyos-version.patch b/scripts/package-build/ndppd/patches/ndppd/0002-set-vyos-version.patch index 3fef87c4..3fef87c4 100644 --- a/scripts/package-build/ndppd/patches/0002-set-vyos-version.patch +++ b/scripts/package-build/ndppd/patches/ndppd/0002-set-vyos-version.patch diff --git a/scripts/package-build/net-snmp/.gitignore b/scripts/package-build/net-snmp/.gitignore index 67811e63..ce30b515 100644 --- a/scripts/package-build/net-snmp/.gitignore +++ b/scripts/package-build/net-snmp/.gitignore @@ -1,6 +1 @@ -net-snmp/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc +/net-snmp/ diff --git a/scripts/package-build/net-snmp/patches/add-linux-6.7-compatibility-parsing.patch b/scripts/package-build/net-snmp/patches/net-snmp/add-linux-6.7-compatibility-parsing.patch index b6dcd77a..b6dcd77a 100644 --- a/scripts/package-build/net-snmp/patches/add-linux-6.7-compatibility-parsing.patch +++ b/scripts/package-build/net-snmp/patches/net-snmp/add-linux-6.7-compatibility-parsing.patch diff --git a/scripts/package-build/netfilter/.gitignore b/scripts/package-build/netfilter/.gitignore index 9bf39f82..ea401bf3 100644 --- a/scripts/package-build/netfilter/.gitignore +++ b/scripts/package-build/netfilter/.gitignore @@ -1,8 +1,2 @@ /pkg-libnftnl/ /pkg-nftables/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc - diff --git a/scripts/package-build/netfilter/build.py b/scripts/package-build/netfilter/build.py index 9737b7d3..3c76af73 100755..120000 --- a/scripts/package-build/netfilter/build.py +++ b/scripts/package-build/netfilter/build.py @@ -1,189 +1 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2024 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 or later as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# - -import glob -import shutil -import toml -import os - -from argparse import ArgumentParser -from pathlib import Path -from subprocess import run, CalledProcessError - - -def ensure_dependencies(dependencies: list) -> None: - """Ensure Debian build dependencies are met""" - if not dependencies: - print("I: No additional dependencies to install") - return - - print("I: Ensure Debian build dependencies are met") - run(['sudo', 'apt-get', 'update'], check=True) - run(['sudo', 'apt-get', 'install', '-y'] + dependencies, check=True) - - -def apply_patches(repo_dir: Path, patch_dir: Path, package_name: str) -> None: - """Apply patches from the patch directory to the repository""" - package_patch_dir = patch_dir / package_name - if package_patch_dir.exists() and package_patch_dir.is_dir(): - patches = list(package_patch_dir.glob('*')) - else: - print(f"I: No patch directory found for {package_name} in {patch_dir}") - return - - # Filter out directories from patches list - patches = [patch for patch in patches if patch.is_file()] - - if not patches: - print(f"I: No patches found in {package_patch_dir}") - return - - debian_patches_dir = repo_dir / 'debian/patches' - debian_patches_dir.mkdir(parents=True, exist_ok=True) - - series_file = debian_patches_dir / 'series' - with series_file.open('a') as series: - for patch in patches: - patch_dest = debian_patches_dir / patch.name - try: - # Ensure the patch file exists before copying - if patch.exists(): - shutil.copy(patch, patch_dest) - series.write(patch.name + '\n') - print(f"I: Applied patch: {patch.name}") - else: - print(f"W: Patch file {patch} not found, skipping") - except FileNotFoundError: - print(f"W: Patch file {patch} not found, skipping") - - -def prepare_package(repo_dir: Path, install_data: str) -> None: - """Prepare a package""" - if not install_data: - print("I: No install data provided, skipping package preparation") - return - - try: - install_file = repo_dir / 'debian/install' - install_file.parent.mkdir(parents=True, exist_ok=True) - install_file.write_text(install_data) - print("I: Prepared package") - except Exception as e: - print(f"Failed to prepare package: {e}") - raise - - -def build_package(package: dict, dependencies: list, patch_dir: Path) -> None: - """Build a package from the repository - - Args: - package (dict): Package information - dependencies (list): List of additional dependencies - patch_dir (Path): Directory containing patches - """ - repo_name = package['name'] - repo_dir = Path(repo_name) - - try: - # Clone the repository if it does not exist - if not repo_dir.exists(): - run(['git', 'clone', package['scm_url'], str(repo_dir)], check=True) - - # Check out the specific commit - run(['git', 'checkout', package['commit_id']], cwd=repo_dir, check=True) - - # Ensure dependencies - ensure_dependencies(dependencies) - - # Apply patches if any - apply_patches(repo_dir, patch_dir, repo_name) - - # Prepare the package if required - if package.get('prepare_package', False): - prepare_package(repo_dir, package.get('install_data', '')) - - # Build dependency package and install it - if (repo_dir / 'debian/control').exists(): - try: - run('sudo mk-build-deps --install --tool "apt-get --yes --no-install-recommends"', cwd=repo_dir, check=True, shell=True) - run('sudo dpkg -i *build-deps*.deb', cwd=repo_dir, check=True, shell=True) - except CalledProcessError as e: - print(f"Failed to build package {repo_name}: {e}") - - # Build the package, check if we have build_cmd in the package.toml - build_cmd = package.get('build_cmd', 'dpkg-buildpackage -uc -us -tc -b') - run(build_cmd, cwd=repo_dir, check=True, shell=True) - - except CalledProcessError as e: - print(f"Failed to build package {repo_name}: {e}") - finally: - # Clean up repository directory - # shutil.rmtree(repo_dir, ignore_errors=True) - pass - - -def cleanup_build_deps(repo_dir: Path) -> None: - """Clean up build dependency packages""" - try: - if repo_dir.exists(): - for file in glob.glob(str(repo_dir / '*build-deps*.deb')): - os.remove(file) - print("Cleaned up build dependency packages") - except Exception as e: - print(f"Error cleaning up build dependencies: {e}") - - -def copy_packages(repo_dir: Path) -> None: - """Copy generated .deb packages to the parent directory""" - try: - deb_files = glob.glob(str(repo_dir / '*.deb')) - for deb_file in deb_files: - shutil.copy(deb_file, repo_dir.parent) - print(f'I: copy generated "{deb_file}" package') - except Exception as e: - print(f"Error copying packages: {e}") - - -if __name__ == '__main__': - # Prepare argument parser - arg_parser = ArgumentParser() - arg_parser.add_argument('--config', - default='package.toml', - help='Path to the package configuration file') - arg_parser.add_argument('--patch-dir', - default='patches', - help='Path to the directory containing patches') - args = arg_parser.parse_args() - - # Load package configuration - with open(args.config, 'r') as file: - config = toml.load(file) - - packages = config['packages'] - patch_dir = Path(args.patch_dir) - - for package in packages: - dependencies = package.get('dependencies', {}).get('packages', []) - - # Build the package - build_package(package, dependencies, patch_dir) - - # Clean up build dependency packages after build - cleanup_build_deps(Path(package['name'])) - - # Copy generated .deb packages to parent directory - copy_packages(Path(package['name'])) +../build.py
\ No newline at end of file diff --git a/scripts/package-build/node_exporter/.gitignore b/scripts/package-build/node_exporter/.gitignore new file mode 100644 index 00000000..25d6ffd3 --- /dev/null +++ b/scripts/package-build/node_exporter/.gitignore @@ -0,0 +1 @@ +node_exporter/ diff --git a/scripts/package-build/node_exporter/build.py b/scripts/package-build/node_exporter/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/node_exporter/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/node_exporter/package.toml b/scripts/package-build/node_exporter/package.toml new file mode 100644 index 00000000..4540bc82 --- /dev/null +++ b/scripts/package-build/node_exporter/package.toml @@ -0,0 +1,21 @@ +[[packages]] +name = "node_exporter" +commit_id = "v1.9.1" +scm_url = "https://github.com/prometheus/node_exporter" + +build_cmd = """ + +# Create the install directory +mkdir -p debian/usr/sbin +make build + +# Move the node_exporter binary to the install directory +mv node_exporter debian/usr/sbin + +# Build the Debian package +fpm --input-type dir --output-type deb --name node-exporter \ + --version $(git describe --tags --always | cut -c2-) --deb-compression gz \ + --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \ + --description "Prometheus exporter for machine metrics" \ + --license Apache-2.0 -C debian --package .. +""" diff --git a/scripts/package-build/opennhrp/package.toml b/scripts/package-build/opennhrp/package.toml deleted file mode 100644 index d647c072..00000000 --- a/scripts/package-build/opennhrp/package.toml +++ /dev/null @@ -1,21 +0,0 @@ -[[packages]] -name = "opennhrp" -commit_id = "613277f" -scm_url = "https://git.code.sf.net/p/opennhrp/code" - -build_cmd = """ -make clean -make - -install --directory debian/etc debian/usr/sbin -install --mode 0644 etc/racoon-ph1dead.sh debian/etc -install --mode 0644 etc/racoon-ph1down.sh debian/etc -install --strip --mode 0755 nhrp/opennhrp debian/usr/sbin -install --strip --mode 0755 nhrp/opennhrpctl debian/usr/sbin - -fpm --input-type dir --output-type deb --name opennhrp \ - --version $(git describe --always | cut -c2-) --deb-compression gz \ - --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \ - --description "NBMA Next Hop Resolution Protocol daemon" \ - --license "MIT" -C debian --package .. -""" diff --git a/scripts/package-build/openvpn-otp/.gitignore b/scripts/package-build/openvpn-otp/.gitignore index 7f89da2b..90268525 100644 --- a/scripts/package-build/openvpn-otp/.gitignore +++ b/scripts/package-build/openvpn-otp/.gitignore @@ -1,6 +1 @@ -openvpn-otp/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc +/openvpn-otp/ diff --git a/scripts/package-build/openvpn-otp/package.toml b/scripts/package-build/openvpn-otp/package.toml index 72209ad1..bdbc6d9d 100644 --- a/scripts/package-build/openvpn-otp/package.toml +++ b/scripts/package-build/openvpn-otp/package.toml @@ -1,6 +1,6 @@ [[packages]] name = "openvpn-otp" -commit_id = "master" +commit_id = "9781ff1" scm_url = "https://github.com/evgeny-gridasov/openvpn-otp" # build_cmd = "cd ..; ./build-openvpn-otp.sh" diff --git a/scripts/package-build/owamp/.gitignore b/scripts/package-build/owamp/.gitignore index 4a97524e..c6efde63 100644 --- a/scripts/package-build/owamp/.gitignore +++ b/scripts/package-build/owamp/.gitignore @@ -1,6 +1 @@ -owamp/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc +/owamp/ diff --git a/scripts/package-build/pam_tacplus/.gitignore b/scripts/package-build/pam_tacplus/.gitignore deleted file mode 100644 index 04e8d4e9..00000000 --- a/scripts/package-build/pam_tacplus/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -pam_tacplus/ -pam_tacplus-debian/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc diff --git a/scripts/package-build/pam_tacplus/package.toml b/scripts/package-build/pam_tacplus/package.toml deleted file mode 100644 index 79b28544..00000000 --- a/scripts/package-build/pam_tacplus/package.toml +++ /dev/null @@ -1,19 +0,0 @@ -[[packages]] -name = "pam_tacplus-debian" -commit_id = "50c6fd7" -scm_url = "https://github.com/kravietz/pam_tacplus-debian" -build_cmd = "/bin/true" - -[[packages]] -name = "pam_tacplus" -#commit_id = "4f91b0d" # This commit cannot build the package -commit_id = "b839c44" -scm_url = "https://github.com/kravietz/pam_tacplus" - -#build_cmd = "sudo mk-build-deps --install --tool 'apt-get --yes --no-install-recommends'; cd ..; ./build.sh" -build_cmd = """ -cp -a ../pam_tacplus-debian debian -rm -f debian/compat -sudo mk-build-deps --install --tool 'apt-get --yes --no-install-recommends' -dpkg-buildpackage -uc -us -tc -b -d -""" diff --git a/scripts/package-build/pmacct/.gitignore b/scripts/package-build/pmacct/.gitignore index 7007417a..65042174 100644 --- a/scripts/package-build/pmacct/.gitignore +++ b/scripts/package-build/pmacct/.gitignore @@ -1,6 +1 @@ -pmacct/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc +/pmacct/ diff --git a/scripts/package-build/pmacct/patches/0001-fix-pmacctd-SEGV-when-ICMP-ICMPv6-traffic-was-proces.patch b/scripts/package-build/pmacct/patches/pmacct/0001-fix-pmacctd-SEGV-when-ICMP-ICMPv6-traffic-was-proces.patch index cb5f7399..cb5f7399 100644 --- a/scripts/package-build/pmacct/patches/0001-fix-pmacctd-SEGV-when-ICMP-ICMPv6-traffic-was-proces.patch +++ b/scripts/package-build/pmacct/patches/pmacct/0001-fix-pmacctd-SEGV-when-ICMP-ICMPv6-traffic-was-proces.patch diff --git a/scripts/package-build/podman/.gitignore b/scripts/package-build/podman/.gitignore index 22c40b0e..dfba60a6 100644 --- a/scripts/package-build/podman/.gitignore +++ b/scripts/package-build/podman/.gitignore @@ -1,7 +1 @@ -podman/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc - +/podman/ diff --git a/scripts/package-build/podman/package.toml b/scripts/package-build/podman/package.toml index 952af518..707f3d7e 100644 --- a/scripts/package-build/podman/package.toml +++ b/scripts/package-build/podman/package.toml @@ -20,7 +20,7 @@ fpm --input-type dir --output-type deb --name podman \ --license "Apache License 2.0" -C podman-v$VERSION --package .. """ -[packages.dependencies] +[dependencies] packages = [ "libseccomp-dev", "libgpgme-dev" diff --git a/scripts/package-build/pyhumps/.gitignore b/scripts/package-build/pyhumps/.gitignore index 6a90d1c9..27979294 100644 --- a/scripts/package-build/pyhumps/.gitignore +++ b/scripts/package-build/pyhumps/.gitignore @@ -1,7 +1 @@ -humps/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc - +/humps/ diff --git a/scripts/package-build/radvd/.gitignore b/scripts/package-build/radvd/.gitignore index 9c37832b..b3761965 100644 --- a/scripts/package-build/radvd/.gitignore +++ b/scripts/package-build/radvd/.gitignore @@ -1,6 +1 @@ -radvd/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc +/radvd/ diff --git a/scripts/package-build/radvd/package.toml b/scripts/package-build/radvd/package.toml index e44afa18..83b9936b 100644 --- a/scripts/package-build/radvd/package.toml +++ b/scripts/package-build/radvd/package.toml @@ -1,6 +1,6 @@ [[packages]] name = "radvd" -commit_id = "f2de4764559" +commit_id = "v2.20" scm_url = "https://github.com/radvd-project/radvd" #build_cmd = "cd ..; ./build.sh" diff --git a/scripts/package-build/strongswan/.gitignore b/scripts/package-build/strongswan/.gitignore index ec612740..e4c36e8f 100644 --- a/scripts/package-build/strongswan/.gitignore +++ b/scripts/package-build/strongswan/.gitignore @@ -1,6 +1 @@ -strongswan/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc +/strongswan/ diff --git a/scripts/package-build/strongswan/build-vici.sh b/scripts/package-build/strongswan/build-vici.sh index 5ad0ee80..75b180f0 100755 --- a/scripts/package-build/strongswan/build-vici.sh +++ b/scripts/package-build/strongswan/build-vici.sh @@ -4,7 +4,7 @@ set -e SRC="strongswan/src/libcharon/plugins/vici/python" if [ ! -d ${SRC} ]; then - echo "Source directory does not exists, please 'git clone'" + echo "Source directory does not exist, please 'git clone'" exit 1 fi @@ -28,30 +28,31 @@ Depends: \${misc:Depends}, \${python3:Depends} Description: Native Python interface for strongSwan's VICI protocol EOF - # Create rules file -echo "I: create $SRC/rules" +echo "I: create $SRC/debian/rules" cat <<EOF > debian/rules #!/usr/bin/make -f %: dh \$@ --with python3 EOF -# Make the rules file executable chmod +x debian/rules echo '10' > debian/compat +# Add the 'install' file to copy the vici package to the correct directory +echo "I: create $SRC/debian/install" +cat <<EOF > debian/install +vici /usr/lib/python3/dist-packages/ +EOF + # Copy changelog cp ../../../../../debian/changelog debian/ - -ls -la -pwd - - +# Build the package echo "I: Build Debian Package" dpkg-buildpackage -uc -us -tc -b -d +# Copy the resulting .deb packages echo "I: copy packages" -cp ../*.deb ../../../../../../ +cp ../*.deb ../../../../../../ diff --git a/scripts/package-build/strongswan/package.toml b/scripts/package-build/strongswan/package.toml index 8cedd4ac..a5722062 100644 --- a/scripts/package-build/strongswan/package.toml +++ b/scripts/package-build/strongswan/package.toml @@ -13,7 +13,7 @@ dpkg-buildpackage -uc -us -tc -b -d cd ..; ./build-vici.sh """ -[packages.dependencies] +[dependencies] packages = [ "bison", "bzip2", diff --git a/scripts/package-build/strongswan/patches/0001-charon-add-optional-source-and-remote-overrides-for-.patch b/scripts/package-build/strongswan/patches/strongswan/0001-charon-add-optional-source-and-remote-overrides-for-.patch index ceb47350..ceb47350 100644 --- a/scripts/package-build/strongswan/patches/0001-charon-add-optional-source-and-remote-overrides-for-.patch +++ b/scripts/package-build/strongswan/patches/strongswan/0001-charon-add-optional-source-and-remote-overrides-for-.patch diff --git a/scripts/package-build/strongswan/patches/0002-vici-send-certificates-for-ike-sa-events.patch b/scripts/package-build/strongswan/patches/strongswan/0002-vici-send-certificates-for-ike-sa-events.patch index 13e657e9..13e657e9 100644 --- a/scripts/package-build/strongswan/patches/0002-vici-send-certificates-for-ike-sa-events.patch +++ b/scripts/package-build/strongswan/patches/strongswan/0002-vici-send-certificates-for-ike-sa-events.patch diff --git a/scripts/package-build/strongswan/patches/0003-vici-add-support-for-individual-sa-state-changes.patch b/scripts/package-build/strongswan/patches/strongswan/0003-vici-add-support-for-individual-sa-state-changes.patch index 45aadc72..45aadc72 100644 --- a/scripts/package-build/strongswan/patches/0003-vici-add-support-for-individual-sa-state-changes.patch +++ b/scripts/package-build/strongswan/patches/strongswan/0003-vici-add-support-for-individual-sa-state-changes.patch diff --git a/scripts/package-build/strongswan/patches/0004-VyOS-disable-options-enabled-by-Debian-that-are-unus.patch b/scripts/package-build/strongswan/patches/strongswan/0004-VyOS-disable-options-enabled-by-Debian-that-are-unus.patch index 57a622e8..57a622e8 100644 --- a/scripts/package-build/strongswan/patches/0004-VyOS-disable-options-enabled-by-Debian-that-are-unus.patch +++ b/scripts/package-build/strongswan/patches/strongswan/0004-VyOS-disable-options-enabled-by-Debian-that-are-unus.patch diff --git a/scripts/package-build/tacacs/.gitignore b/scripts/package-build/tacacs/.gitignore new file mode 100644 index 00000000..3579fc4d --- /dev/null +++ b/scripts/package-build/tacacs/.gitignore @@ -0,0 +1,3 @@ +/libnss-tacplus/ +/libpam-tacplus/ +/libtacplus-map/ diff --git a/scripts/package-build/tacacs/build.py b/scripts/package-build/tacacs/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/tacacs/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/tacacs/package.toml b/scripts/package-build/tacacs/package.toml new file mode 100644 index 00000000..fde9df6e --- /dev/null +++ b/scripts/package-build/tacacs/package.toml @@ -0,0 +1,24 @@ +[[packages]] +name = "libtacplus-map" +commit_id = "master" +scm_url = "https://github.com/vyos/libtacplus-map.git" +build_cmd = "dpkg-buildpackage -us -uc -tc -b" + +[[packages]] +name = "libpam-tacplus" +commit_id = "master" +scm_url = "https://github.com/vyos/libpam-tacplus.git" +build_cmd = "sudo dpkg -i ../libtacplus-map*.deb; dpkg-buildpackage -us -uc -tc -b" + +[[packages]] +name = "libnss-tacplus" +commit_id = "master" +scm_url = "https://github.com/vyos/libnss-tacplus.git" +build_cmd = "sudo dpkg -i ../libtac*.deb ../libpam-tacplus*.deb; dpkg-buildpackage -us -uc -tc -b" + +[dependencies] +packages = [ + "libpam-dev", + "autoconf-archive", + "libaudit-dev" +] diff --git a/scripts/package-build/telegraf/.gitignore b/scripts/package-build/telegraf/.gitignore index bf2fcf43..f634da68 100644 --- a/scripts/package-build/telegraf/.gitignore +++ b/scripts/package-build/telegraf/.gitignore @@ -1,6 +1 @@ -telegraf/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc +/telegraf/ diff --git a/scripts/package-build/vpp/.gitignore b/scripts/package-build/vpp/.gitignore new file mode 100644 index 00000000..38768675 --- /dev/null +++ b/scripts/package-build/vpp/.gitignore @@ -0,0 +1,2 @@ +/vpp/ +/vyos-vpp-patches/ diff --git a/scripts/package-build/vpp/build.py b/scripts/package-build/vpp/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/vpp/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/vpp/package.toml b/scripts/package-build/vpp/package.toml new file mode 100644 index 00000000..1104e184 --- /dev/null +++ b/scripts/package-build/vpp/package.toml @@ -0,0 +1,35 @@ +[[packages]] +name = "vyos-vpp-patches" +commit_id = "current" +scm_url = "https://github.com/vyos/vyos-vpp-patches" +build_cmd = "/bin/true" +apply_patches = false + +[[packages]] +name = "vpp" +commit_id = "stable/2410" +scm_url = "https://github.com/FDio/vpp" +# Skip apply patches by build.py as we use them in build_cmd +apply_patches = false + +pre_build_hook = """ +mkdir -p ../patches/vpp/ +rsync -av ../vyos-vpp-patches/patches/vpp/ ../patches/vpp/ +""" + +build_cmd = """ +# Patches for vpp should applied here +for patch in ../patches/vpp/*.patch; do + echo "I: build_cmd applying patch $patch..." + git -c user.email=maintainers@vyos.net -c user.name=vyos am "$patch" || { echo "Failed to apply patch $patch"; exit 1; } +done + +make UNATTENDED=yes install-dep +make pkg-deb +cp build-root/*.deb ../ +""" + +[dependencies] +packages = [ + "llvm" +] diff --git a/scripts/package-build/vyos-1x/.gitignore b/scripts/package-build/vyos-1x/.gitignore new file mode 100644 index 00000000..990c6351 --- /dev/null +++ b/scripts/package-build/vyos-1x/.gitignore @@ -0,0 +1,2 @@ +/vyos-1x/ +/vyos-vpp/ diff --git a/scripts/package-build/vyos-1x/build.py b/scripts/package-build/vyos-1x/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/vyos-1x/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/vyos-1x/package.toml b/scripts/package-build/vyos-1x/package.toml new file mode 100644 index 00000000..6dcbadb3 --- /dev/null +++ b/scripts/package-build/vyos-1x/package.toml @@ -0,0 +1,11 @@ +[[packages]] +name = "vyos-vpp" +commit_id = "current" +scm_url = "https://github.com/vyos/vyos-vpp.git" +build_cmd = "/bin/true" + +[[packages]] +name = "vyos-1x" +commit_id = "current" +scm_url = "https://github.com/vyos/vyos-1x.git" +build_cmd = "rsync -av --exclude='.git' --exclude='.github' --exclude='README*' --exclude='LICENSE' --exclude='*.md' ../vyos-vpp/ ./; dpkg-buildpackage -us -uc -F" diff --git a/scripts/package-build/waagent/.gitignore b/scripts/package-build/waagent/.gitignore index 80401271..a91839ef 100644 --- a/scripts/package-build/waagent/.gitignore +++ b/scripts/package-build/waagent/.gitignore @@ -1,8 +1 @@ -waagent/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc -*.tar.gz -*.tar.xz +/waagent/ diff --git a/scripts/package-build/waagent/package.toml b/scripts/package-build/waagent/package.toml index d7343a7a..1a382baa 100644 --- a/scripts/package-build/waagent/package.toml +++ b/scripts/package-build/waagent/package.toml @@ -3,5 +3,5 @@ name = "waagent" commit_id = "debian/2.9.1.1-2" scm_url = "https://salsa.debian.org/cloud-team/waagent.git" -[packages.dependencies] +[dependencies] packages = ["dpkg-source-gitarchive"] diff --git a/scripts/package-build/wide-dhcpv6/.gitignore b/scripts/package-build/wide-dhcpv6/.gitignore index 990f3c6c..b7f6e063 100644 --- a/scripts/package-build/wide-dhcpv6/.gitignore +++ b/scripts/package-build/wide-dhcpv6/.gitignore @@ -1,7 +1 @@ -wide-dhcpv6/ -*.buildinfo -*.build -*.changes -*.deb -*.dsc -*.udeb +/wide-dhcpv6/ diff --git a/scripts/package-build/wide-dhcpv6/patches/0023-dhcpc6-support-per-interface-client-DUIDs.patch b/scripts/package-build/wide-dhcpv6/patches/wide-dhcpv6/0023-dhcpc6-support-per-interface-client-DUIDs.patch index c1e71f0c..c1e71f0c 100644 --- a/scripts/package-build/wide-dhcpv6/patches/0023-dhcpc6-support-per-interface-client-DUIDs.patch +++ b/scripts/package-build/wide-dhcpv6/patches/wide-dhcpv6/0023-dhcpc6-support-per-interface-client-DUIDs.patch diff --git a/scripts/package-build/wide-dhcpv6/patches/0024-bind-to-single-socket.patch b/scripts/package-build/wide-dhcpv6/patches/wide-dhcpv6/0024-bind-to-single-socket.patch index b5751325..b5751325 100644 --- a/scripts/package-build/wide-dhcpv6/patches/0024-bind-to-single-socket.patch +++ b/scripts/package-build/wide-dhcpv6/patches/wide-dhcpv6/0024-bind-to-single-socket.patch diff --git a/scripts/package-build/wide-dhcpv6/patches/0025-option-to-prevent-ia-release.patch b/scripts/package-build/wide-dhcpv6/patches/wide-dhcpv6/0025-option-to-prevent-ia-release.patch index 32c15814..32c15814 100644 --- a/scripts/package-build/wide-dhcpv6/patches/0025-option-to-prevent-ia-release.patch +++ b/scripts/package-build/wide-dhcpv6/patches/wide-dhcpv6/0025-option-to-prevent-ia-release.patch diff --git a/scripts/package-build/xen-guest-agent/.gitignore b/scripts/package-build/xen-guest-agent/.gitignore new file mode 100644 index 00000000..d34885ab --- /dev/null +++ b/scripts/package-build/xen-guest-agent/.gitignore @@ -0,0 +1 @@ +/xen-guest-agent/ diff --git a/scripts/package-build/xen-guest-agent/build.py b/scripts/package-build/xen-guest-agent/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/xen-guest-agent/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/xen-guest-agent/package.toml b/scripts/package-build/xen-guest-agent/package.toml new file mode 100644 index 00000000..213425df --- /dev/null +++ b/scripts/package-build/xen-guest-agent/package.toml @@ -0,0 +1,34 @@ +[[packages]] +name = "xen-guest-agent" +commit_id = "0.4.0" +scm_url = "https://gitlab.com/xen-project/xen-guest-agent" + + +build_cmd = """ +# changelog +cat <<EOF > debian/changelog +xen-guest-agent (0.4.0) UNRELEASED; urgency=medium + + * Upstream package + + -- VyOS Maintainers <maintainers@vyos.io> Thu, 26 Sep 2024 12:35:47 +0000 + +EOF + +# Apply the patch to modify the debian/rules file +sed -i 's|../xen-guest-agent-$(UPSTREAM_VERSION)-linux-$(DEB_TARGET_GNU_CPU)|target/release/xen-guest-agent|' debian/rules + +sudo apt-get -y install --no-install-recommends libclang-dev libxen-dev +# Install rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y --default-toolchain stable --profile default --no-modify-path + +# Set PATH for Cargo +export PATH="$HOME/.cargo/bin:$PATH" +rustup update +cd xen-guest-agent +cargo update + +# Build deb +cargo build -F static --profile release +dpkg-buildpackage -b -us -uc +""" |