diff options
author | Viacheslav Hletenko <v.gletenko@vyos.io> | 2024-09-06 10:45:27 +0000 |
---|---|---|
committer | Viacheslav Hletenko <v.gletenko@vyos.io> | 2024-09-06 11:34:08 +0000 |
commit | c9a5a93834fce33f1e999dd50381cb7ff9e5fabb (patch) | |
tree | 26d03e228ca55acc5fc29d4ad18e8331b79e8605 | |
parent | 70122746469e930a6775e0c42c4d1fd30bc6d514 (diff) | |
download | vyos-build-c9a5a93834fce33f1e999dd50381cb7ff9e5fabb.tar.gz vyos-build-c9a5a93834fce33f1e999dd50381cb7ff9e5fabb.zip |
T6674: Add build-scrips for packages without Jenkins
Add build scripts for .deb packages without Jenkins.
To exclude Jenkins we need some place where we can put new
builds-scripts to run in parallel (old/new) during meantime.
We will deprecate old Jenkins package builds in the future.
117 files changed, 4852 insertions, 0 deletions
diff --git a/.github/workflows/trigger_rebuild_packages.yml b/.github/workflows/trigger_rebuild_packages.yml new file mode 100644 index 00000000..0ca9cc28 --- /dev/null +++ b/.github/workflows/trigger_rebuild_packages.yml @@ -0,0 +1,198 @@ +name: Trigger to build package + +on: + push: + branches: + - circinus + +jobs: + changes: + runs-on: ubuntu-latest + + env: + REF: main # Used for curl to trigger build package + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.ref_name }} + + - uses: dorny/paths-filter@v3 + id: changes + with: + base: ${{ github.ref_name }} + filters: | + aws-gwlbtun: + - 'scripts/package-build/aws-gwlbtun/**' + ddclient: + - 'scripts/package-build/ddclient/**' + dropbear: + - 'scripts/package-build/dropbear/**' + ethtool: + - 'scripts/package-build/ethtool/**' + frr: + - 'scripts/package-build/frr/**' + hostap: + - 'scripts/package-build/hostap/**' + hsflowd: + - 'scripts/package-build/hsflowd/**' + isc-dhcp: + - 'scripts/package-build/isc-dhcp/**' + kea: + - 'scripts/package-build/kea/**' + keepalived: + - 'scripts/package-build/keepalived/**' + linux-kernel: + - 'data/defaults.toml' + - 'scripts/package-build/linux-kernel/**' + ndppd: + - 'scripts/package-build/ndppd/**' + net-snmp: + - 'scripts/package-build/net-snmp/**' + netfilter: + - 'scripts/package-build/netfilter/**' + opennhrp: + - 'scripts/package-build/opennhrp/**' + openvpn-otp: + - 'scripts/package-build/openvpn-otp/**' + owamp: + - 'scripts/package-build/owamp/**' + pam_tacplus: + - 'scripts/package-build/pam_tacplus/**' + pmacct: + - 'scripts/package-build/pmacct/**' + podman: + - 'scripts/package-build/podman/**' + pyhumps: + - 'scripts/package-build/pyhumps/**' + radvd: + - 'scripts/package-build/radvd/**' + strongswan: + - 'scripts/package-build/strongswan/**' + telegraf: + - 'scripts/package-build/telegraf/**' + waagent: + - 'scripts/package-build/waagent/**' + wide-dhcpv6: + - 'scripts/package-build/wide-dhcpv6/**' + + - name: Trigger builds for changed packages + run: | + set -eux + function trigger_build() { + PACKAGE_NAME=$1 + echo "${PACKAGE_NAME} change detected!" + curl -L \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.PAT }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ secrets.REMOTE_OWNER }}/${{ secrets.REMOTE_REUSE_REPO }}/actions/workflows/build-package.yml/dispatches \ + -d '{"ref": "${{ env.REF }}", "inputs":{"package_name":"'"$PACKAGE_NAME"'", "gpg_key_id": "${{ secrets.GPG_KEY_ID }}", "package_branch": "${{ github.ref_name }}"}}' + } + + # Trigger builds based on detected changes + if [ "${{ steps.changes.outputs.aws-gwlbtun }}" == "true" ]; then + trigger_build "aws-gwlbtun" + fi + + if [ "${{ steps.changes.outputs.ddclient }}" == "true" ]; then + trigger_build "ddclient" + fi + + if [ "${{ steps.changes.outputs.dropbear }}" == "true" ]; then + trigger_build "dropbear" + fi + + if [ "${{ steps.changes.outputs.ethtool }}" == "true" ]; then + trigger_build "ethtool" + fi + + if [ "${{ steps.changes.outputs.frr }}" == "true" ]; then + trigger_build "frr" + fi + + if [ "${{ steps.changes.outputs.hostap }}" == "true" ]; then + trigger_build "hostap" + fi + + if [ "${{ steps.changes.outputs.hsflowd }}" == "true" ]; then + trigger_build "hsflowd" + fi + + if [ "${{ steps.changes.outputs.isc-dhcp }}" == "true" ]; then + trigger_build "isc-dhcp" + fi + + if [ "${{ steps.changes.outputs.kea }}" == "true" ]; then + trigger_build "kea" + fi + + if [ "${{ steps.changes.outputs.keepalived }}" == "true" ]; then + trigger_build "keepalived" + fi + + if [ "${{ steps.changes.outputs.linux-kernel }}" == "true" ]; then + trigger_build "linux-kernel" + fi + + if [ "${{ steps.changes.outputs.ndppd }}" == "true" ]; then + trigger_build "ndppd" + fi + + if [ "${{ steps.changes.outputs.net-snmp }}" == "true" ]; then + trigger_build "net-snmp" + fi + + if [ "${{ steps.changes.outputs.netfilter }}" == "true" ]; then + trigger_build "netfilter" + fi + + if [ "${{ steps.changes.outputs.opennhrp }}" == "true" ]; then + trigger_build "opennhrp" + fi + + if [ "${{ steps.changes.outputs.openvpn-otp }}" == "true" ]; then + trigger_build "openvpn-otp" + fi + + if [ "${{ steps.changes.outputs.owamp }}" == "true" ]; then + trigger_build "owamp" + fi + + if [ "${{ steps.changes.outputs.pam_tacplus }}" == "true" ]; then + trigger_build "pam_tacplus" + fi + + if [ "${{ steps.changes.outputs.pmacct }}" == "true" ]; then + trigger_build "pmacct" + fi + + if [ "${{ steps.changes.outputs.podman }}" == "true" ]; then + trigger_build "podman" + fi + + if [ "${{ steps.changes.outputs.pyhumps }}" == "true" ]; then + trigger_build "pyhumps" + fi + + if [ "${{ steps.changes.outputs.radvd }}" == "true" ]; then + trigger_build "radvd" + fi + + if [ "${{ steps.changes.outputs.strongswan }}" == "true" ]; then + trigger_build "strongswan" + fi + + if [ "${{ steps.changes.outputs.telegraf }}" == "true" ]; then + trigger_build "telegraf" + fi + + if [ "${{ steps.changes.outputs.waagent }}" == "true" ]; then + trigger_build "waagent" + fi + + if [ "${{ steps.changes.outputs.wide-dhcpv6 }}" == "true" ]; then + trigger_build "ethtool" + fi diff --git a/scripts/package-build/aws-gwlbtun/.gitignore b/scripts/package-build/aws-gwlbtun/.gitignore new file mode 100644 index 00000000..0fe7946f --- /dev/null +++ b/scripts/package-build/aws-gwlbtun/.gitignore @@ -0,0 +1,8 @@ +aws-gwlbtun*/ +*.tar.gz +*.tar.xz +*.deb +*.dsc +*.buildinfo +*.build +*.changes
\ No newline at end of file diff --git a/scripts/package-build/aws-gwlbtun/build.py b/scripts/package-build/aws-gwlbtun/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/aws-gwlbtun/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/aws-gwlbtun/package.toml b/scripts/package-build/aws-gwlbtun/package.toml new file mode 100644 index 00000000..1c4e53f6 --- /dev/null +++ b/scripts/package-build/aws-gwlbtun/package.toml @@ -0,0 +1,59 @@ +[[packages]] +name = "aws-gwlbtun" +commit_id = "f78058a" +scm_url = "https://github.com/aws-samples/aws-gateway-load-balancer-tunnel-handler" + + +## Build cmd start +build_cmd = '''\ +mkdir -p debian +echo 'obj-*-linux-gnu/gwlbtun usr/sbin' > debian/install + +# changelog +cat <<EOF > debian/changelog +aws-gwlbtun (1.0-1) unstable; urgency=low + + * Initial release + + -- Your Name <your.email@example.com> Wed, 29 Aug 2024 09:00:00 +0000 + +EOF + +# control +/bin/bash -c "cat <<EOF > debian/control +Source: aws-gwlbtun +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/aws-samples/aws-gateway-load-balancer-tunnel-handler + +Package: aws-gwlbtun +Architecture: any +Depends: \${shlibs:Depends}, \${misc:Depends} +Description: AWS Gateway Load Balancer Tunnel Handler + This is a simple package that handles tunneling for the AWS Gateway Load Balancer. +EOF +" + +# rules +cat <<EOF > debian/rules +#!/usr/bin/make -f + +%: dh $@ + +build: + dh build + +binary: + dh binary + +clean: + dh clean +EOF + +chmod +x debian/rules +debuild -us -uc -b +''' +## Build cmd end diff --git a/scripts/package-build/build.py b/scripts/package-build/build.py new file mode 100755 index 00000000..99180e17 --- /dev/null +++ b/scripts/package-build/build.py @@ -0,0 +1,184 @@ +#!/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) -> None: + """Apply patches from the patch directory to the repository""" + if not patch_dir.exists() or not patch_dir.is_dir(): + print(f"I: Patch directory {patch_dir} does not exist, skipping patch application") + return + + patches = sorted(patch_dir.glob('*')) + if not patches: + print(f"I: No patches found in {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 + shutil.copy(patch, patch_dest) + 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: + 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: list, dependencies: 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'] + 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 + if (repo_dir / 'patches'): + apply_patches(repo_dir, patch_dir) + + # 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 + try: + build_cmd = package.get('build_cmd', 'dpkg-buildpackage -uc -us -tc -F') + run(build_cmd, cwd=repo_dir, check=True, shell=True) + except CalledProcessError as e: + print(e) + print("I: Source packages build failed, ignoring - building binaries only") + 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("I: 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'])) diff --git a/scripts/package-build/ddclient/.gitignore b/scripts/package-build/ddclient/.gitignore new file mode 100644 index 00000000..aeb8af66 --- /dev/null +++ b/scripts/package-build/ddclient/.gitignore @@ -0,0 +1,7 @@ +ddclient/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc + diff --git a/scripts/package-build/ddclient/build.py b/scripts/package-build/ddclient/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/ddclient/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/ddclient/package.toml b/scripts/package-build/ddclient/package.toml new file mode 100644 index 00000000..e2cd3f0a --- /dev/null +++ b/scripts/package-build/ddclient/package.toml @@ -0,0 +1,4 @@ +[[packages]] +name = "ddclient" +commit_id = "debian/3.11.2-1" +scm_url = "https://salsa.debian.org/debian/ddclient" diff --git a/scripts/package-build/dropbear/.gitignore b/scripts/package-build/dropbear/.gitignore new file mode 100644 index 00000000..6e8cff9c --- /dev/null +++ b/scripts/package-build/dropbear/.gitignore @@ -0,0 +1,7 @@ +dropbear/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc + diff --git a/scripts/package-build/dropbear/build.py b/scripts/package-build/dropbear/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/dropbear/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/dropbear/package.toml b/scripts/package-build/dropbear/package.toml new file mode 100644 index 00000000..cbb885ee --- /dev/null +++ b/scripts/package-build/dropbear/package.toml @@ -0,0 +1,7 @@ +[[packages]] +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 diff --git a/scripts/package-build/dropbear/patches/0001-Enable-PAM-support.patch b/scripts/package-build/dropbear/patches/0001-Enable-PAM-support.patch new file mode 100644 index 00000000..fa6cf620 --- /dev/null +++ b/scripts/package-build/dropbear/patches/0001-Enable-PAM-support.patch @@ -0,0 +1,61 @@ +From 861bfb53de5909e25a952a83654c63de61af02b5 Mon Sep 17 00:00:00 2001 +From: Christian Breunig <christian@breunig.cc> +Date: Sun, 28 May 2023 15:45:32 +0200 +Subject: [PATCH] Enable PAM support + +--- + debian/control | 1 + + debian/rules | 2 +- + default_options.h | 4 ++-- + 3 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/debian/control b/debian/control +index 77ea036..b252b97 100644 +--- a/debian/control ++++ b/debian/control +@@ -6,6 +6,7 @@ Build-Depends: debhelper, + debhelper-compat (= 13), + libtomcrypt-dev (>= 1.18.2~), + libtommath-dev (>= 1.2.0~), ++ libpam0g-dev, + libz-dev + Rules-Requires-Root: no + Standards-Version: 4.6.1 +diff --git a/debian/rules b/debian/rules +index 7dab64c..ce11aa4 100755 +--- a/debian/rules ++++ b/debian/rules +@@ -24,7 +24,7 @@ endif + dh $@ + + override_dh_auto_configure: +- dh_auto_configure -- --disable-bundled-libtom \ ++ dh_auto_configure -- --disable-bundled-libtom --enable-pam \ + CC='$(CC)' CFLAGS='$(CFLAGS)' $(CONFFLAGS) + + execute_before_dh_auto_build: +diff --git a/default_options.h b/default_options.h +index 5132775..e7d274c 100644 +--- a/default_options.h ++++ b/default_options.h +@@ -223,7 +223,7 @@ group1 in Dropbear server too */ + + /* Authentication Types - at least one required. + RFC Draft requires pubkey auth, and recommends password */ +-#define DROPBEAR_SVR_PASSWORD_AUTH 1 ++#define DROPBEAR_SVR_PASSWORD_AUTH 0 + + /* Note: PAM auth is quite simple and only works for PAM modules which just do + * a simple "Login: " "Password: " (you can edit the strings in svr-authpam.c). +@@ -231,7 +231,7 @@ group1 in Dropbear server too */ + * but there's an interface via a PAM module. It won't work for more complex + * PAM challenge/response. + * You can't enable both PASSWORD and PAM. */ +-#define DROPBEAR_SVR_PAM_AUTH 0 ++#define DROPBEAR_SVR_PAM_AUTH 1 + + /* ~/.ssh/authorized_keys authentication. + * You must define DROPBEAR_SVR_PUBKEY_AUTH in order to use plugins. */ +-- +2.30.2 + diff --git a/scripts/package-build/ethtool/.gitignore b/scripts/package-build/ethtool/.gitignore new file mode 100644 index 00000000..f964bd07 --- /dev/null +++ b/scripts/package-build/ethtool/.gitignore @@ -0,0 +1,7 @@ +ethtool/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc + diff --git a/scripts/package-build/ethtool/build.py b/scripts/package-build/ethtool/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/ethtool/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/ethtool/package.toml b/scripts/package-build/ethtool/package.toml new file mode 100644 index 00000000..9468ed82 --- /dev/null +++ b/scripts/package-build/ethtool/package.toml @@ -0,0 +1,4 @@ +[[packages]] +name = "ethtool" +commit_id = "debian/1%6.6-1" +scm_url = "https://salsa.debian.org/kernel-team/ethtool" diff --git a/scripts/package-build/frr/.gitignore b/scripts/package-build/frr/.gitignore new file mode 100644 index 00000000..590895c0 --- /dev/null +++ b/scripts/package-build/frr/.gitignore @@ -0,0 +1,8 @@ +frr/ +rtrlib/ +libyang/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/frr/build.py b/scripts/package-build/frr/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/frr/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/frr/package.toml b/scripts/package-build/frr/package.toml new file mode 100644 index 00000000..48d51ae6 --- /dev/null +++ b/scripts/package-build/frr/package.toml @@ -0,0 +1,36 @@ +[[packages]] +name = "libyang" +commit_id = "v2.1.148" +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 .. {} +" + +[[packages]] +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" +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" + +[packages.dependencies] +packages = [ + "chrpath", + "gawk", + "install-info", + "libcap-dev", + "libjson-c-dev", + "librtr-dev", + "libpam-dev", + "libprotobuf-c-dev", + "libpython3-dev:native", + "python3-sphinx:native", + "libsnmp-dev", + "protobuf-c-compiler", + "python3-dev:native", + "texinfo", + "lua5.3" +] diff --git a/scripts/package-build/hostap/.gitignore b/scripts/package-build/hostap/.gitignore new file mode 100644 index 00000000..f9c7eb32 --- /dev/null +++ b/scripts/package-build/hostap/.gitignore @@ -0,0 +1,7 @@ +hostap/ +wpa/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/hostap/README.md b/scripts/package-build/hostap/README.md new file mode 100644 index 00000000..63119c0c --- /dev/null +++ b/scripts/package-build/hostap/README.md @@ -0,0 +1,4 @@ +# build +``` +python3 build.py +``` diff --git a/scripts/package-build/hostap/build.py b/scripts/package-build/hostap/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/hostap/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/hostap/build.sh b/scripts/package-build/hostap/build.sh new file mode 100755 index 00000000..c356672a --- /dev/null +++ b/scripts/package-build/hostap/build.sh @@ -0,0 +1,38 @@ +#!/bin/bash +CWD=$(pwd) +set -e + +SRC=hostap +SRC_DEB=wpa + +if [ ! -d ${SRC} ]; then + echo "${SRC} directory does not exists, please 'git clone'" + exit 1 +fi +if [ ! -d ${SRC_DEB} ]; then + echo "${SRC_DEB} directory does not exists, please 'git clone'" + exit 1 +fi + +echo "I: Copy Debian build instructions" +cp -a ${SRC_DEB}/debian ${SRC} +# Preserve Debian's default of allowing TLSv1.0 and legacy renegotiation for +# compatibility with networks that use legacy crypto +cat > ${SRC}/debian/patches/series << EOF +allow-tlsv1.patch +allow-legacy-renegotiation.patch +EOF + +# Build Debian package +cd ${SRC} + +echo "I: Ensure Debian build dependencies are met" +sudo mk-build-deps --install --tool "apt-get --yes --no-install-recommends" -Ppkg.wpa.nogui,noudeb + +echo "I: Create new Debian Package version" +version="$(git describe --tags | tr _ .)" +dch -v ${version:7} "New version to support AES-GCM-256 for MACsec" -b + +echo "I: Build Debian hostap Package" +DEB_CPPFLAGS_SET="-Wno-use-after-free -Wno-deprecated-declarations" \ + dpkg-buildpackage -us -uc -tc -b -Ppkg.wpa.nogui,noudeb diff --git a/scripts/package-build/hostap/package.toml b/scripts/package-build/hostap/package.toml new file mode 100644 index 00000000..cb40710b --- /dev/null +++ b/scripts/package-build/hostap/package.toml @@ -0,0 +1,12 @@ +[[packages]] +name = "wpa" +commit_id = "debian/2%2.10-12" +scm_url = "https://salsa.debian.org/debian/wpa" +build_cmd = "/bin/true" + +[[packages]] +name = "hostap" +commit_id = "e7172e26d" +scm_url = "git://w1.fi/srv/git/hostap.git" +build_cmd = "cd ..; y | ./build.sh" + diff --git a/scripts/package-build/hsflowd/.gitignore b/scripts/package-build/hsflowd/.gitignore new file mode 100644 index 00000000..d0964b29 --- /dev/null +++ b/scripts/package-build/hsflowd/.gitignore @@ -0,0 +1,6 @@ +host-sflow/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/hsflowd/build.py b/scripts/package-build/hsflowd/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/hsflowd/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/hsflowd/package.toml b/scripts/package-build/hsflowd/package.toml new file mode 100644 index 00000000..75d320a7 --- /dev/null +++ b/scripts/package-build/hsflowd/package.toml @@ -0,0 +1,8 @@ +[[packages]] +name = "host-sflow" +commit_id = "v2.0.55-1" +scm_url = "https://github.com/sflow/host-sflow.git" +build_cmd = "make deb FEATURES='PCAP DROPMON DBUS'" + +[packages.dependencies] +packages = ["libpcap0.8-dev"] diff --git a/scripts/package-build/isc-dhcp/.gitignore b/scripts/package-build/isc-dhcp/.gitignore new file mode 100644 index 00000000..66d17cc8 --- /dev/null +++ b/scripts/package-build/isc-dhcp/.gitignore @@ -0,0 +1,7 @@ +isc-dhcp/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc + diff --git a/scripts/package-build/isc-dhcp/build.py b/scripts/package-build/isc-dhcp/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/isc-dhcp/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/isc-dhcp/package.toml b/scripts/package-build/isc-dhcp/package.toml new file mode 100644 index 00000000..76a0e4a1 --- /dev/null +++ b/scripts/package-build/isc-dhcp/package.toml @@ -0,0 +1,7 @@ +[[packages]] +name = "isc-dhcp" +commit_id = "debian/4.4.3-P1-4" +scm_url = "https://salsa.debian.org/debian/isc-dhcp" + +[packages.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/0001-Add-support-for-raw-IP-interface-type.patch new file mode 100644 index 00000000..c13569ad --- /dev/null +++ b/scripts/package-build/isc-dhcp/patches/0001-Add-support-for-raw-IP-interface-type.patch @@ -0,0 +1,248 @@ +From 8d9e8ace96ad9e2dba9f2d4069228dee5daf6772 Mon Sep 17 00:00:00 2001 +From: Loic Poulain <loic.poulain@linaro.org> +Date: Mon, 2 Nov 2020 06:42:12 -0500 +Subject: [PATCH 1/4] Add support for raw IP interface type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Under linux some devices can expose raw IP interfaces, such as WWAN +modems. In that case IP data is not encapsulated in any lower level +protocol. + +dhclient does not support this currently and this patch adds support +for such pure IP interfaces. + +The original patch comes from Bjørn Mork on Network-Manage mailing list: +https://mail.gnome.org/archives/networkmanager-list/2015-December/msg00044.html + +--- + common/bpf.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++- + common/lpf.c | 59 +++++++++++++++++++++++++++++++++++++----------- + common/packet.c | 7 ++++++ + includes/dhcp.h | 1 + + 4 files changed, 113 insertions(+), 14 deletions(-) + +diff --git a/common/bpf.c b/common/bpf.c +index 658e5db..0c08574 100644 +--- a/common/bpf.c ++++ b/common/bpf.c +@@ -198,6 +198,34 @@ struct bpf_insn dhcp_bpf_filter [] = { + BPF_STMT (BPF_RET + BPF_K, 0), + }; + ++int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn); ++ ++struct bpf_insn dhcp_bpf_pureip_filter [] = { ++ /* Make sure it's a UDP packet... */ ++ BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 9), ++ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6), ++ ++ /* Make sure this isn't a fragment... */ ++ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6), ++ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0), ++ ++ /* Get the IP header length... */ ++ BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 0), ++ ++ /* Make sure it's to the right port... */ ++ BPF_STMT (BPF_LD + BPF_H + BPF_IND, 2), ++ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 37, 0, 1), /* patch */ ++ ++ /* If we passed all the tests, ask for the whole packet. */ ++ BPF_STMT(BPF_RET+BPF_K, (u_int)-1), ++ ++ /* Otherwise, drop it. */ ++ BPF_STMT(BPF_RET+BPF_K, 0), ++}; ++ ++int dhcp_bpf_pureip_filter_len = ++ sizeof dhcp_bpf_pureip_filter / sizeof (struct bpf_insn); ++ + #if defined(RELAY_PORT) + /* + * For relay port extension +@@ -235,13 +263,43 @@ struct bpf_insn dhcp_bpf_relay_filter [] = { + + int dhcp_bpf_relay_filter_len = + sizeof dhcp_bpf_relay_filter / sizeof (struct bpf_insn); ++ ++struct bpf_insn dhcp_bpf_pureip_relay_filter [] = { ++ /* Make sure it's a UDP packet... */ ++ BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 9), ++ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 8), ++ ++ /* Make sure this isn't a fragment... */ ++ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6), ++ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 6, 0), ++ ++ /* Get the IP header length... */ ++ BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 0), ++ ++ /* Make sure it's to the right port... */ ++ BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16), ++ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 37, 2, 0), /* patch */ ++ ++ /* relay can have an alternative port... */ ++ BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16), ++ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 37, 0, 1), /* patch */ ++ ++ /* If we passed all the tests, ask for the whole packet. */ ++ BPF_STMT (BPF_RET + BPF_K, (u_int)-1), ++ ++ /* Otherwise, drop it. */ ++ BPF_STMT (BPF_RET + BPF_K, 0), ++}; ++ ++int dhcp_bpf_pureip_relay_filter_len = ++ sizeof dhcp_bpf_pureip_relay_filter / sizeof (struct bpf_insn); ++ + #endif + + #if defined (DEC_FDDI) + struct bpf_insn *bpf_fddi_filter = NULL; + #endif + +-int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn); + #if defined (HAVE_TR_SUPPORT) + struct bpf_insn dhcp_bpf_tr_filter [] = { + /* accept all token ring packets due to variable length header */ +diff --git a/common/lpf.c b/common/lpf.c +index bb8822a..d8f34a4 100644 +--- a/common/lpf.c ++++ b/common/lpf.c +@@ -177,9 +177,15 @@ void if_deregister_send (info) + extern struct sock_filter dhcp_bpf_filter []; + extern int dhcp_bpf_filter_len; + ++extern struct sock_filter dhcp_bpf_pureip_filter []; ++extern int dhcp_bpf_pureip_filter_len; ++ + #if defined(RELAY_PORT) + extern struct sock_filter dhcp_bpf_relay_filter []; + extern int dhcp_bpf_relay_filter_len; ++ ++extern struct sock_filter dhcp_bpf_pureip_relay_filter []; ++extern int dhcp_bpf_pureip_relay_filter_len; + #endif + + #if defined (HAVE_TR_SUPPORT) +@@ -249,31 +255,52 @@ void if_deregister_receive (info) + static void lpf_gen_filter_setup (info) + struct interface_info *info; + { ++ int pure_ip = info -> hw_address.hbuf [0] == HTYPE_PUREIP; + struct sock_fprog p; + + memset(&p, 0, sizeof(p)); + +- /* Set up the bpf filter program structure. This is defined in +- bpf.c */ +- p.len = dhcp_bpf_filter_len; +- p.filter = dhcp_bpf_filter; ++ /* Set up the bpf filter program structure and patch port(s). ++ * ++ * This is defined in bpf.c, XXX changes to filter program may ++ * require changes to the insn number(s) used below! XXX ++ */ ++ ++ if (pure_ip) { ++ p.len = dhcp_bpf_pureip_filter_len; ++ p.filter = dhcp_bpf_pureip_filter; ++ ++ /* patch port */ ++ dhcp_bpf_pureip_filter [6].k = ntohs (local_port); ++ } else { ++ p.len = dhcp_bpf_filter_len; ++ p.filter = dhcp_bpf_filter; ++ ++ /* patch port */ ++ dhcp_bpf_filter [8].k = ntohs (local_port); ++ } + +- /* Patch the server port into the LPF program... +- XXX changes to filter program may require changes +- to the insn number(s) used below! XXX */ + #if defined(RELAY_PORT) +- if (relay_port) { +- /* +- * If user defined relay UDP port, we need to filter +- * also on the user UDP port. +- */ ++ /* ++ * If user defined relay UDP port, we need to filter ++ * also on the user UDP port. ++ */ ++ if (relay_port && pure_ip) { ++ p.len = dhcp_bpf_pureip_relay_filter_len; ++ p.filter = dhcp_bpf_pureip_relay_filter; ++ ++ /* patch ports */ ++ dhcp_bpf_pureip_relay_filter [6].k = ntohs (local_port); ++ dhcp_bpf_pureip_relay_filter [8].k = ntohs (relay_port); ++ } else if (relay_port) { + p.len = dhcp_bpf_relay_filter_len; + p.filter = dhcp_bpf_relay_filter; + ++ /* patch ports */ ++ dhcp_bpf_relay_filter [8].k = ntohs (local_port); + dhcp_bpf_relay_filter [10].k = ntohs (relay_port); + } + #endif +- dhcp_bpf_filter [8].k = ntohs (local_port); + + if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p, + sizeof p) < 0) { +@@ -578,6 +605,12 @@ get_hw_addr(const char *name, struct hardware *hw) { + hw->hbuf[3] = 0xbe; + hw->hbuf[4] = 0xef; + break; ++#endif ++#ifdef ARPHRD_RAWIP ++ case ARPHRD_RAWIP: ++ hw->hlen = 1; ++ hw->hbuf[0] = HTYPE_PUREIP; ++ break; + #endif + default: + log_fatal("Unsupported device type %ld for \"%s\"", +diff --git a/common/packet.c b/common/packet.c +index 49795c4..6745db7 100644 +--- a/common/packet.c ++++ b/common/packet.c +@@ -119,6 +119,10 @@ void assemble_hw_header (interface, buf, bufix, to) + case HTYPE_INFINIBAND: + log_error("Attempt to assemble hw header for infiniband"); + break; ++ case HTYPE_PUREIP: ++ /* Nothing to do, there is no hw header */ ++ *bufix = 0; ++ break; + case HTYPE_ETHER: + default: + assemble_ethernet_header(interface, buf, bufix, to); +@@ -219,6 +223,9 @@ ssize_t decode_hw_header (interface, buf, bufix, from) + case HTYPE_INFINIBAND: + log_error("Attempt to decode hw header for infiniband"); + return (0); ++ case HTYPE_PUREIP: ++ /* Nothing to do, there is no hw header */ ++ return 0; + case HTYPE_ETHER: + default: + return (decode_ethernet_header(interface, buf, bufix, from)); +diff --git a/includes/dhcp.h b/includes/dhcp.h +index d519821..75be1fb 100644 +--- a/includes/dhcp.h ++++ b/includes/dhcp.h +@@ -76,6 +76,7 @@ struct dhcp_packet { + #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */ + #define HTYPE_FDDI 8 /* FDDI... */ + #define HTYPE_INFINIBAND 32 /* IP over Infiniband */ ++#define HTYPE_PUREIP 35 /* Pure IP */ + #define HTYPE_IPMP 255 /* IPMP - random hw address - there + * is no standard for this so we + * just steal a type */ +-- +2.39.2 + diff --git a/scripts/package-build/isc-dhcp/patches/0002-Checkpoint-improved-patch.patch b/scripts/package-build/isc-dhcp/patches/0002-Checkpoint-improved-patch.patch new file mode 100644 index 00000000..60b693f6 --- /dev/null +++ b/scripts/package-build/isc-dhcp/patches/0002-Checkpoint-improved-patch.patch @@ -0,0 +1,170 @@ +From e67d1b6b4178f412084459c4cb7e54a8c0019bd2 Mon Sep 17 00:00:00 2001 +From: Francis Dupont <fdupont@isc.org> +Date: Fri, 6 Nov 2020 10:46:09 +0100 +Subject: [PATCH 2/4] Checkpoint: improved patch + +--- + common/bpf.c | 10 +++--- + common/lpf.c | 89 +++++++++++++++++++++++++++++++++++----------------- + 2 files changed, 65 insertions(+), 34 deletions(-) + +diff --git a/common/bpf.c b/common/bpf.c +index 0c08574..30dcaa5 100644 +--- a/common/bpf.c ++++ b/common/bpf.c +@@ -214,13 +214,13 @@ struct bpf_insn dhcp_bpf_pureip_filter [] = { + + /* Make sure it's to the right port... */ + BPF_STMT (BPF_LD + BPF_H + BPF_IND, 2), +- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 37, 0, 1), /* patch */ ++ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), /* patch */ + + /* If we passed all the tests, ask for the whole packet. */ +- BPF_STMT(BPF_RET+BPF_K, (u_int)-1), ++ BPF_STMT(BPF_RET + BPF_K, (u_int)-1), + + /* Otherwise, drop it. */ +- BPF_STMT(BPF_RET+BPF_K, 0), ++ BPF_STMT(BPF_RET + BPF_K, 0), + }; + + int dhcp_bpf_pureip_filter_len = +@@ -278,11 +278,11 @@ struct bpf_insn dhcp_bpf_pureip_relay_filter [] = { + + /* Make sure it's to the right port... */ + BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16), +- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 37, 2, 0), /* patch */ ++ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 2, 0), /* patch */ + + /* relay can have an alternative port... */ + BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16), +- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 37, 0, 1), /* patch */ ++ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), /* patch */ + + /* If we passed all the tests, ask for the whole packet. */ + BPF_STMT (BPF_RET + BPF_K, (u_int)-1), +diff --git a/common/lpf.c b/common/lpf.c +index d8f34a4..75609f5 100644 +--- a/common/lpf.c ++++ b/common/lpf.c +@@ -221,6 +221,9 @@ void if_register_receive (info) + lpf_tr_filter_setup (info); + else + #endif ++ if (info -> hw_address.hbuf [0] == HTYPE_PUREIP) ++ lpf_pureip_filter_setup (info); ++ else + lpf_gen_filter_setup (info); + + if (!quiet_interface_discovery) +@@ -255,50 +258,78 @@ void if_deregister_receive (info) + static void lpf_gen_filter_setup (info) + struct interface_info *info; + { +- int pure_ip = info -> hw_address.hbuf [0] == HTYPE_PUREIP; + struct sock_fprog p; + + memset(&p, 0, sizeof(p)); + +- /* Set up the bpf filter program structure and patch port(s). +- * +- * This is defined in bpf.c, XXX changes to filter program may +- * require changes to the insn number(s) used below! XXX +- */ ++ /* Set up the bpf filter program structure. This is defined in ++ bpf.c */ ++ p.len = dhcp_bpf_filter_len; ++ p.filter = dhcp_bpf_filter; ++ ++ dhcp_bpf_filter [8].k = ntohs (local_port); + +- if (pure_ip) { +- p.len = dhcp_bpf_pureip_filter_len; +- p.filter = dhcp_bpf_pureip_filter; ++ /* Patch the server port into the LPF program... ++ XXX changes to filter program may require changes ++ to the insn number(s) used below! XXX */ ++#if defined(RELAY_PORT) ++ if (relay_port) { ++ /* ++ * If user defined relay UDP port, we need to filter ++ * also on the user UDP port. ++ */ ++ p.len = dhcp_bpf_relay_filter_len; ++ p.filter = dhcp_bpf_relay_filter; + +- /* patch port */ +- dhcp_bpf_pureip_filter [6].k = ntohs (local_port); +- } else { +- p.len = dhcp_bpf_filter_len; +- p.filter = dhcp_bpf_filter; ++ dhcp_bpf_relay_filter [8].k = ntohs (local_port); ++ dhcp_bpf_relay_filter [10].k = ntohs (relay_port); ++ } ++#endif + +- /* patch port */ +- dhcp_bpf_filter [8].k = ntohs (local_port); ++ if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p, ++ sizeof p) < 0) { ++ if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT || ++ errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT || ++ errno == EAFNOSUPPORT) { ++ log_error ("socket: %m - make sure"); ++ log_error ("CONFIG_PACKET (Packet socket) %s", ++ "and CONFIG_FILTER"); ++ log_error ("(Socket Filtering) are enabled %s", ++ "in your kernel"); ++ log_fatal ("configuration!"); ++ } ++ log_fatal ("Can't install packet filter program: %m"); + } ++} ++ ++static void lpf_pureip_gen_filter_setup (info) ++ struct interface_info *info; ++{ ++ struct sock_fprog p; ++ ++ memset(&p, 0, sizeof(p)); ++ ++ /* Set up the bpf filter program structure. This is defined in ++ bpf.c */ ++ p.len = dhcp_bpf_pureip_filter_len; ++ p.filter = dhcp_bpf_pureip_filter; ++ ++ dhcp_bpf_pureip_filter [6].k = ntohs (local_port); + ++ /* Patch the server port into the LPF program... ++ XXX changes to filter program may require changes ++ to the insn number(s) used below! XXX */ + #if defined(RELAY_PORT) +- /* +- * If user defined relay UDP port, we need to filter +- * also on the user UDP port. +- */ +- if (relay_port && pure_ip) { ++ if (relay_port) { ++ /* ++ * If user defined relay UDP port, we need to filter ++ * also on the user UDP port. ++ */ + p.len = dhcp_bpf_pureip_relay_filter_len; + p.filter = dhcp_bpf_pureip_relay_filter; + +- /* patch ports */ + dhcp_bpf_pureip_relay_filter [6].k = ntohs (local_port); + dhcp_bpf_pureip_relay_filter [8].k = ntohs (relay_port); +- } else if (relay_port) { +- p.len = dhcp_bpf_relay_filter_len; +- p.filter = dhcp_bpf_relay_filter; +- +- /* patch ports */ +- dhcp_bpf_relay_filter [8].k = ntohs (local_port); +- dhcp_bpf_relay_filter [10].k = ntohs (relay_port); + } + #endif + +-- +2.39.2 + diff --git a/scripts/package-build/isc-dhcp/patches/0003-fix-compilation-errors.patch b/scripts/package-build/isc-dhcp/patches/0003-fix-compilation-errors.patch new file mode 100644 index 00000000..c66e0c7c --- /dev/null +++ b/scripts/package-build/isc-dhcp/patches/0003-fix-compilation-errors.patch @@ -0,0 +1,48 @@ +From 58e0d3317795987b2f1ca788645196d0e3543f88 Mon Sep 17 00:00:00 2001 +From: Adam Smith <zero1three@gmail.com> +Date: Tue, 23 Jan 2024 21:47:00 -0500 +Subject: [PATCH 3/4] fix compilation errors + +--- + common/lpf.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/common/lpf.c b/common/lpf.c +index 75609f5..1561d71 100644 +--- a/common/lpf.c ++++ b/common/lpf.c +@@ -195,6 +195,7 @@ static void lpf_tr_filter_setup (struct interface_info *); + #endif + + static void lpf_gen_filter_setup (struct interface_info *); ++static void lpf_pureip_gen_filter_setup (struct interface_info *); + + void if_register_receive (info) + struct interface_info *info; +@@ -215,14 +216,13 @@ void if_register_receive (info) + } + #endif + +- + #if defined (HAVE_TR_SUPPORT) + if (info -> hw_address.hbuf [0] == HTYPE_IEEE802) + lpf_tr_filter_setup (info); + else + #endif + if (info -> hw_address.hbuf [0] == HTYPE_PUREIP) +- lpf_pureip_filter_setup (info); ++ lpf_pureip_gen_filter_setup (info); + else + lpf_gen_filter_setup (info); + +@@ -349,6 +349,7 @@ static void lpf_pureip_gen_filter_setup (info) + } + } + ++ + #if defined (HAVE_TR_SUPPORT) + static void lpf_tr_filter_setup (info) + struct interface_info *info; +-- +2.39.2 + 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/0004-add-support-for-ARPHRD_NONE-interface-type.patch new file mode 100644 index 00000000..32089b4d --- /dev/null +++ b/scripts/package-build/isc-dhcp/patches/0004-add-support-for-ARPHRD_NONE-interface-type.patch @@ -0,0 +1,29 @@ +From fd96a11b31cd05aae450ec65fde0b5c6e0b718c2 Mon Sep 17 00:00:00 2001 +From: Adam Smith <zero1three@gmail.com> +Date: Tue, 23 Jan 2024 22:35:54 -0500 +Subject: [PATCH 4/4] add support for ARPHRD_NONE interface type + +--- + common/lpf.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/common/lpf.c b/common/lpf.c +index 1561d71..f7e84b1 100644 +--- a/common/lpf.c ++++ b/common/lpf.c +@@ -643,6 +643,12 @@ get_hw_addr(const char *name, struct hardware *hw) { + hw->hlen = 1; + hw->hbuf[0] = HTYPE_PUREIP; + break; ++#endif ++#ifdef ARPHRD_NONE ++ case ARPHRD_NONE: ++ hw->hlen = 1; ++ hw->hbuf[0] = HTYPE_PUREIP; ++ break; + #endif + default: + log_fatal("Unsupported device type %ld for \"%s\"", +-- +2.39.2 + diff --git a/scripts/package-build/kea/.gitignore b/scripts/package-build/kea/.gitignore new file mode 100644 index 00000000..1f9d42c9 --- /dev/null +++ b/scripts/package-build/kea/.gitignore @@ -0,0 +1,7 @@ +isc-kea/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc + diff --git a/scripts/package-build/kea/build.py b/scripts/package-build/kea/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/kea/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/kea/package.toml b/scripts/package-build/kea/package.toml new file mode 100644 index 00000000..0bfce21e --- /dev/null +++ b/scripts/package-build/kea/package.toml @@ -0,0 +1,4 @@ +[[packages]] +name = "isc-kea" +commit_id = "debian/2.4.1-3" +scm_url = "https://salsa.debian.org/debian/isc-kea" diff --git a/scripts/package-build/keepalived/.gitignore b/scripts/package-build/keepalived/.gitignore new file mode 100644 index 00000000..fa96cd3f --- /dev/null +++ b/scripts/package-build/keepalived/.gitignore @@ -0,0 +1,7 @@ +keepalived/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc + diff --git a/scripts/package-build/keepalived/build.py b/scripts/package-build/keepalived/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/keepalived/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/keepalived/package.toml b/scripts/package-build/keepalived/package.toml new file mode 100644 index 00000000..ad1008e6 --- /dev/null +++ b/scripts/package-build/keepalived/package.toml @@ -0,0 +1,4 @@ +[[packages]] +name = "keepalived" +commit_id = "debian/1%2.2.8-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 new file mode 100644 index 00000000..b099dc7b --- /dev/null +++ b/scripts/package-build/keepalived/patches/0001-vrrp-Set-sysctl-arp_ignore-to-1-on-IPv6-VMACs.patch @@ -0,0 +1,129 @@ +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/linux-kernel/.gitignore b/scripts/package-build/linux-kernel/.gitignore new file mode 100644 index 00000000..0a18ea8c --- /dev/null +++ b/scripts/package-build/linux-kernel/.gitignore @@ -0,0 +1,32 @@ +/linux* +/wireguard +/wireguard-linux-compat +/accel-ppp +/intel-qat +/linux-firmware +/vyos-drivers-intel* +/vyos-drivers-realtek* +/ovpn-dco +/nat-rtsp* +/jool* +/qat* +/QAT* +*.tar.gz +*.tar.xz +/*.postinst + +# Intel Driver source +i40e-*/ +igb-*/ +ixgbe-*/ +ixgbevf-*/ +vyos-intel-*/ +vyos-linux-firmware*/ +kernel-vars +r8152-*.tar.bz2 + +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/linux-kernel/README.md b/scripts/package-build/linux-kernel/README.md new file mode 100644 index 00000000..56954e5a --- /dev/null +++ b/scripts/package-build/linux-kernel/README.md @@ -0,0 +1,41 @@ +# Build +``` +./build.py --config package.toml --packages linux-kernel accel-ppp xxx +``` + +# 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 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. +On the other hand we ship additional not mainlined features as WireGuard VPN. + +## Kernel + +The Kernel is build from the vanilla repositories hosted at https://git.kernel.org. +VyOS requires two additional patches to work which are stored in the patches/kernel +folder. + +### Config + +The Kernel configuration used is [x86_64_vyos_defconfig](x86_64_vyos_defconfig) +which will be copied on demand during the Pipeline run into the `arch/x86/configs`i +direcotry of the Kernel source tree. + +Other configurations can be added in the future easily. + +### Modules + +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 new file mode 120000 index 00000000..f5f81fdc --- /dev/null +++ b/scripts/package-build/linux-kernel/arch @@ -0,0 +1 @@ +../../../packages/linux-kernel/arch
\ No newline at end of file diff --git a/scripts/package-build/linux-kernel/build-accel-ppp.sh b/scripts/package-build/linux-kernel/build-accel-ppp.sh new file mode 100755 index 00000000..1685ff8d --- /dev/null +++ b/scripts/package-build/linux-kernel/build-accel-ppp.sh @@ -0,0 +1,42 @@ +#!/bin/sh +CWD=$(pwd) +KERNEL_VAR_FILE=${CWD}/kernel-vars + +ACCEL_SRC=${CWD}/accel-ppp +if [ ! -d ${ACCEL_SRC} ]; then + echo "Accel-PPP 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 + +PATCH_DIR=${CWD}/patches/accel-ppp +if [ -d $PATCH_DIR ]; then + cd ${ACCEL_SRC} + for patch in $(ls ${PATCH_DIR}) + do + echo "I: Apply patch: ${PATCH_DIR}/${patch}" + patch -p1 < ${PATCH_DIR}/${patch} + done +fi + +. ${KERNEL_VAR_FILE} +mkdir -p ${ACCEL_SRC}/build +cd ${ACCEL_SRC}/build + +echo "I: Build Accel-PPP Debian package" +cmake -DBUILD_IPOE_DRIVER=TRUE \ + -DBUILD_VLAN_MON_DRIVER=TRUE \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DKDIR=${KERNEL_DIR} \ + -DLUA=5.3 \ + -DMODULES_KDIR=${KERNEL_VERSION}${KERNEL_SUFFIX} \ + -DCPACK_TYPE=Debian12 .. +make +cpack -G DEB + +# rename resulting Debian package according git description +mv accel-ppp*.deb ${CWD}/accel-ppp_$(git describe --always --tags)_$(dpkg --print-architecture).deb diff --git a/scripts/package-build/linux-kernel/build-intel-ixgbe.sh b/scripts/package-build/linux-kernel/build-intel-ixgbe.sh new file mode 100755 index 00000000..5f45c62a --- /dev/null +++ b/scripts/package-build/linux-kernel/build-intel-ixgbe.sh @@ -0,0 +1,107 @@ +#!/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-ixgbevf.sh new file mode 100755 index 00000000..a965e0de --- /dev/null +++ b/scripts/package-build/linux-kernel/build-intel-ixgbevf.sh @@ -0,0 +1,100 @@ +#!/bin/sh +CWD=$(pwd) +KERNEL_VAR_FILE=${CWD}/kernel-vars + +if ! dpkg-architecture -iamd64; then + echo "Intel ixgbevf 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/ixgbevf%20stable/4.18.9/ixgbevf-4.18.9.tar.gz" + +cd ${CWD} + +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="" + +# 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 +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 + +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-qat.sh b/scripts/package-build/linux-kernel/build-intel-qat.sh new file mode 100755 index 00000000..765cea3f --- /dev/null +++ b/scripts/package-build/linux-kernel/build-intel-qat.sh @@ -0,0 +1,111 @@ +#!/bin/sh +CWD=$(pwd) +KERNEL_VAR_FILE=${CWD}/kernel-vars + +if ! dpkg-architecture -iamd64; then + echo "Intel-QAT 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://dev.packages.vyos.net/source-mirror/QAT.L.4.24.0-00005.tar.gz" + +cd ${CWD} + +DRIVER_FILE=$(basename ${url} | sed -e s/tar_0/tar/) +DRIVER_DIR="${DRIVER_FILE%.tar.gz}" +DRIVER_NAME="QAT" +DRIVER_NAME_EXTRA="L." +DRIVER_VERSION=$(echo ${DRIVER_DIR} | awk -F${DRIVER_NAME} '{print $2}' | awk -F${DRIVER_NAME_EXTRA} '{print $2}') +DRIVER_VERSION_EXTRA="-0" + +# Build up Debian related variables required for packaging +DEBIAN_ARCH=$(dpkg --print-architecture) +DEBIAN_DIR="${CWD}/vyos-intel-${DRIVER_NAME}_${DRIVER_VERSION}${DRIVER_VERSION_EXTRA}_${DEBIAN_ARCH}" +DEBIAN_CONTROL="${DEBIAN_DIR}/DEBIAN/control" +DEBIAN_POSTINST="${CWD}/vyos-intel-qat.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} -xf ${DRIVER_FILE} + +cd ${DRIVER_DIR} +if [ -z $KERNEL_DIR ]; then + echo "KERNEL_DIR not defined" + exit 1 +fi + +echo "I: Compile Kernel module for Intel ${DRIVER_NAME} driver" +mkdir -p \ + ${DEBIAN_DIR}/lib/firmware \ + ${DEBIAN_DIR}/usr/sbin \ + ${DEBIAN_DIR}/usr/lib/x86_64-linux-gnu \ + ${DEBIAN_DIR}/etc/init.d +KERNEL_SOURCE_ROOT=${KERNEL_DIR} ./configure --enable-kapi --enable-qat-lkcf +make -j $(getconf _NPROCESSORS_ONLN) all +make INSTALL_MOD_PATH=${DEBIAN_DIR} INSTALL_FW_PATH=${DEBIAN_DIR} \ + qat-driver-install adf-ctl-all + +if [ "x$?" != "x0" ]; then + exit 1 +fi + +cp quickassist/qat/fw/*.bin ${DEBIAN_DIR}/lib/firmware +cp build/*.so ${DEBIAN_DIR}/usr/lib/x86_64-linux-gnu +cp build/adf_ctl ${DEBIAN_DIR}/usr/sbin +cp quickassist/build_system/build_files/qat_service ${DEBIAN_DIR}/etc/init.d +cp build/usdm_drv.ko ${DEBIAN_DIR}/lib/modules/${KERNEL_VERSION}${KERNEL_SUFFIX}/updates/drivers +chmod 644 ${DEBIAN_DIR}/lib/firmware/* +chmod 755 ${DEBIAN_DIR}/etc/init.d/* ${DEBIAN_DIR}/usr/local/bin/* + +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}${DRIVER_VERSION_EXTRA} --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-jool.py b/scripts/package-build/linux-kernel/build-jool.py new file mode 100755 index 00000000..570293f5 --- /dev/null +++ b/scripts/package-build/linux-kernel/build-jool.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 + +from tomllib import loads as toml_loads +from requests import get +from pathlib import Path +from subprocess import run + +def find_arch() -> str: + tmp=run(['dpkg-architecture', '-q', 'DEB_HOST_ARCH'], capture_output=True) + return tmp.stdout.decode().strip() + +# 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 +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_SRC: str = Path.cwd().as_posix() + '/linux' + +# define variables +PACKAGE_NAME: str = 'jool' +PACKAGE_VERSION: str = '4.1.9+bf4c7e3669' +PACKAGE_DIR: str = f'{PACKAGE_NAME}-{PACKAGE_VERSION}' +SOURCES_ARCHIVE: str = 'jool-4.1.9+bf4c7e3669.tar.gz' +SOURCES_URL: str = f'https://github.com/NICMx/Jool/archive/7f08c42c615ed63cf0fdc1522d91aa0809f6d990.tar.gz' + +# 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 = f'''#!/usr/bin/make -f +# config +export KERNEL_DIR := {KERNEL_SRC} +PACKAGE_BUILD_DIR := debian/{PACKAGE_NAME} +KVER := {KERNEL_VER}-{KERNEL_FLAVOR} +MODULES_DIR := extra + +# main packaging script based on dh7 syntax +%: + dh $@ + +override_dh_clean: + dh_clean --exclude=debian/{PACKAGE_NAME}.substvars + +override_dh_prep: + dh_prep --exclude=debian/{PACKAGE_NAME}.substvars + +# override_dh_auto_clean: +# make -C src/mod clean + +override_dh_auto_build: + dh_auto_build $@ + make -C ${{KERNEL_DIR}} M=$$PWD/src/mod/common modules + make -C ${{KERNEL_DIR}} M=$$PWD/src/mod/nat64 modules + make -C ${{KERNEL_DIR}} M=$$PWD/src/mod/siit modules + +override_dh_auto_install: + 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 + +''' +bild_rules = Path(f'{PACKAGE_DIR}/debian/rules') +bild_rules.write_text(build_rules_text) + +# build a package +debuild_cmd: list[str] = ['debuild'] +run(debuild_cmd, cwd=PACKAGE_DIR) diff --git a/scripts/package-build/linux-kernel/build-kernel.sh b/scripts/package-build/linux-kernel/build-kernel.sh new file mode 100755 index 00000000..2c02f5c3 --- /dev/null +++ b/scripts/package-build/linux-kernel/build-kernel.sh @@ -0,0 +1,56 @@ +#!/bin/bash +CWD=$(pwd) +KERNEL_SRC=linux + +set -e + +if [ ! -d ${KERNEL_SRC} ]; then + echo "Linux Kernel source directory does not exists, please 'git clone'" + 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 + +KERNEL_VERSION=$(make kernelversion) +KERNEL_SUFFIX=-$(dpkg --print-architecture)-vyos + +# VyOS requires some small Kernel Patches - apply them here +# It's easier to habe them here and make use of the upstream +# repository instead of maintaining a full Kernel Fork. +# Saving time/resources is essential :-) +PATCH_DIR=${CWD}/patches/kernel +for patch in $(ls ${PATCH_DIR}) +do + echo "I: Apply Kernel patch: ${PATCH_DIR}/${patch}" + patch -p1 < ${PATCH_DIR}/${patch} +done + +echo "I: make vyos_defconfig" +# Select Kernel configuration - currently there is only one +make vyos_defconfig + +echo "I: Generate environment file containing Kernel variable" +cat << EOF >${CWD}/kernel-vars +#!/bin/sh +export KERNEL_VERSION=${KERNEL_VERSION} +export KERNEL_SUFFIX=${KERNEL_SUFFIX} +export KERNEL_DIR=${CWD}/${KERNEL_SRC} +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) + +cd $CWD +if [[ $? == 0 ]]; then + for package in $(ls linux-*.deb) + do + ln -sf linux-kernel/$package .. + done +fi diff --git a/scripts/package-build/linux-kernel/build-linux-firmware.sh b/scripts/package-build/linux-kernel/build-linux-firmware.sh new file mode 100755 index 00000000..2b1fa7b7 --- /dev/null +++ b/scripts/package-build/linux-kernel/build-linux-firmware.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +# All selected drivers are then precomfiled "make drivers/foo/bar.i" and we grep for +# the magic word "UNIQUE_ID_firmware" which identifies firmware files. + +CWD=$(pwd) +LINUX_SRC="linux" +LINUX_FIRMWARE="linux-firmware" +KERNEL_VAR_FILE=${CWD}/kernel-vars + +if [ ! -d ${LINUX_SRC} ]; then + echo "Kernel source missing" + exit 1 +fi + +if [ ! -d ${LINUX_FIRMWARE} ]; then + echo "Linux firmware repository missing" + exit 1 +fi + +. ${KERNEL_VAR_FILE} + +result=() +# Retrieve firmware blobs from source files +FW_FILES=$(find ${LINUX_SRC}/debian/linux-image/lib/modules/${KERNEL_VERSION}${KERNEL_SUFFIX}/kernel/drivers/net -name *.ko | xargs modinfo | grep "^firmware:" | awk '{print $2}') + +# Debian package will use the descriptive Git commit as version +GIT_COMMIT=$(cd ${CWD}/${LINUX_FIRMWARE}; git describe --always) +VYOS_FIRMWARE_NAME="vyos-linux-firmware" +VYOS_FIRMWARE_DIR="${VYOS_FIRMWARE_NAME}_${GIT_COMMIT}-0_all" +if [ -d ${VYOS_FIRMWARE_DIR} ]; then + # remove Debian package folder and deb file from previous runs + rm -rf ${VYOS_FIRMWARE_DIR}* +fi +mkdir -p ${VYOS_FIRMWARE_DIR} + +# Install firmware files to build directory +LINUX_FIRMWARE_BUILD_DIR="${LINUX_FIRMWARE}_${GIT_COMMIT}" + +if [ -d ${LINUX_FIRMWARE_BUILD_DIR} ]; then + rm -rf "${LINUX_FIRMWARE_BUILD_DIR}" +fi + +mkdir -p "${LINUX_FIRMWARE_BUILD_DIR}" + +( + cd ${LINUX_FIRMWARE} + ./copy-firmware.sh "${CWD}/${LINUX_FIRMWARE_BUILD_DIR}" +) + +# Copy firmware file from linux firmware build directory into +# assembly folder for the vyos-firmware package +SED_REPLACE="s@${CWD}/${LINUX_FIRMWARE}/@@" +for FILE_PATTERN in ${FW_FILES}; do + find "${LINUX_FIRMWARE_BUILD_DIR}" -path "*/${FILE_PATTERN}" -print0 | while IFS= read -r -d $'\0' FILE; do + TARGET="$(echo "${FILE}" | sed "s/${LINUX_FIRMWARE_BUILD_DIR}\///g")" + TARGET_DIR="${VYOS_FIRMWARE_DIR}/lib/firmware/$(dirname "${TARGET}")" + # If file is a symlink install the symlink target as well + if [ -h "${FILE}" ]; then + if [ ! -f "${TARGET_DIR}/$(basename "${TARGET}")" ]; then + if [ -f "${LINUX_FIRMWARE_BUILD_DIR}/${TARGET}" ]; then + mkdir -p "${TARGET_DIR}" + + echo "I: install firmware: ${TARGET}" + cp "${CWD}/${LINUX_FIRMWARE_BUILD_DIR}/${TARGET}" "${TARGET_DIR}" + # If file links to other folder which this script not cover. Create folder and copy together. + if [ -L "${LINUX_FIRMWARE_BUILD_DIR}/${TARGET}" ]; then + REALPATH_TARGET=$(realpath --relative-to="${CWD}/${LINUX_FIRMWARE_BUILD_DIR}" "${CWD}/${LINUX_FIRMWARE_BUILD_DIR}/${TARGET}") + REALPATH_TARGET_DIR="${VYOS_FIRMWARE_DIR}/lib/firmware/$(dirname "${REALPATH_TARGET}")" + mkdir -p "${REALPATH_TARGET_DIR}" + echo "I: install firmware: ${REALPATH_TARGET}" + cp "${CWD}/${LINUX_FIRMWARE_BUILD_DIR}/${REALPATH_TARGET}" "${REALPATH_TARGET_DIR}" + fi + else + echo "I: firmware file not found: ${TARGET}" + fi + fi + fi + + if [ -f "${FILE}" ]; then + mkdir -p "${TARGET_DIR}" + echo "I: install firmware: ${TARGET}" + cp -P "${CWD}/${LINUX_FIRMWARE_BUILD_DIR}/${TARGET}" "${TARGET_DIR}" + else + echo "I: firmware file not found: ${TARGET}" + fi + done +done + +echo "I: Create linux-firmware package" +rm -f ${VYOS_FIRMWARE_NAME}_*.deb +fpm --input-type dir --output-type deb --name ${VYOS_FIRMWARE_NAME} \ + --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \ + --description "Binary firmware for various drivers in the Linux kernel" \ + --architecture all --version ${GIT_COMMIT} --deb-compression gz -C ${VYOS_FIRMWARE_DIR} + +rm -rf "${LINUX_FIRMWARE_BUILD_DIR}" +rm -rf ${VYOS_FIRMWARE_DIR} diff --git a/scripts/package-build/linux-kernel/build-nat-rtsp.sh b/scripts/package-build/linux-kernel/build-nat-rtsp.sh new file mode 100755 index 00000000..ec7d19a6 --- /dev/null +++ b/scripts/package-build/linux-kernel/build-nat-rtsp.sh @@ -0,0 +1,38 @@ +#!/bin/sh +CWD=$(pwd) +KERNEL_VAR_FILE=${CWD}/kernel-vars + +SRC=${CWD}/nat-rtsp +if [ ! -d ${SRC} ]; then + echo "nat-rtsp 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 + +. ${KERNEL_VAR_FILE} + +cd ${SRC} && make KERNELDIR=$KERNEL_DIR + +# Copy binary to package directory +DEBIAN_DIR=tmp/lib/modules/${KERNEL_VERSION}${KERNEL_SUFFIX}/extra +mkdir -p ${DEBIAN_DIR} +cp nf_conntrack_rtsp.ko nf_nat_rtsp.ko ${DEBIAN_DIR} + +DEBIAN_POSTINST="${CWD}/vyos-nat-rtsp.postinst" +echo "#!/bin/sh" > ${DEBIAN_POSTINST} +echo "/sbin/depmod -a ${KERNEL_VERSION}${KERNEL_SUFFIX}" >> ${DEBIAN_POSTINST} + +# Build Debian Package +fpm --input-type dir --output-type deb --name nat-rtsp \ + --version $(git describe --tags --always) --deb-compression gz \ + --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \ + --description "Connection tracking and NAT support for RTSP" \ + --depends linux-image-${KERNEL_VERSION}${KERNEL_SUFFIX} \ + --after-install ${DEBIAN_POSTINST} \ + --license "GPL2" --chdir tmp + +mv *.deb .. diff --git a/scripts/package-build/linux-kernel/build-openvpn-dco.sh b/scripts/package-build/linux-kernel/build-openvpn-dco.sh new file mode 100755 index 00000000..fd427825 --- /dev/null +++ b/scripts/package-build/linux-kernel/build-openvpn-dco.sh @@ -0,0 +1,33 @@ +#!/bin/sh +CWD=$(pwd) +KERNEL_VAR_FILE=${CWD}/kernel-vars + +SRC=${CWD}/ovpn-dco +if [ ! -d ${SRC} ]; then + echo "OpenVPN DCO 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 + +. ${KERNEL_VAR_FILE} + +cd ${SRC} && 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} + +# Build Debian Package +fpm --input-type dir --output-type deb --name openvpn-dco \ + --version $(git describe | sed s/^v//) --deb-compression gz \ + --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \ + --description "OpenVPN Data Channel Offload" \ + --depends linux-image-${KERNEL_VERSION}${KERNEL_SUFFIX} \ + --license "GPL2" --chdir tmp + +mv *.deb .. diff --git a/scripts/package-build/linux-kernel/build.py b/scripts/package-build/linux-kernel/build.py new file mode 100755 index 00000000..1bcab686 --- /dev/null +++ b/scripts/package-build/linux-kernel/build.py @@ -0,0 +1,239 @@ +#!/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 datetime +import glob +import shutil +import toml +import os +import subprocess + +from argparse import ArgumentParser +from pathlib import Path +from subprocess import run, CalledProcessError + +# Relative path to defaults.toml +defaults_path = "../../../data/defaults.toml" + + +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', 'install', '-y'] + dependencies, check=True) + + +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 + + 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") + + +def clone_or_update_repo(repo_dir: Path, scm_url: str, commit_id: str) -> None: + """Clone the repository if it does not exist, otherwise update it""" + if repo_dir.exists(): + #run(['git', 'fetch'], cwd=repo_dir, check=True) + run(['git', 'checkout', commit_id], cwd=repo_dir, check=True) + #run(['git', 'pull'], cwd=repo_dir, check=True) + else: + run(['git', 'clone', scm_url, str(repo_dir)], check=True) + run(['git', 'checkout', commit_id], cwd=repo_dir, check=True) + + +def build_package(package: dict, dependencies: list) -> None: + """Build a package from the repository + + Args: + package (dict): Package information + dependencies (list): List of additional dependencies + """ + timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S') + repo_name = package['name'] + repo_dir = Path(repo_name) + + try: + # Clone or update the repository + #clone_or_update_repo(repo_dir, package['scm_url'], package['commit_id']) + + # Ensure dependencies + #ensure_dependencies(dependencies) + + # Prepare the package if required + #if package.get('prepare_package', False): + # prepare_package(repo_dir, package.get('install_data', '')) + + # Execute the build command + if package['build_cmd'] == 'build_kernel': + build_kernel(package['kernel_version']) + elif package['build_cmd'] == 'build_linux_firmware': + build_linux_firmware(package['commit_id'], package['scm_url']) + elif package['build_cmd'] == 'build_accel_ppp': + build_accel_ppp(package['commit_id'], package['scm_url']) + elif package['build_cmd'] == 'build_intel_qat': + build_intel_qat() + elif package['build_cmd'] == 'build_intel_ixgbe': + build_intel_ixgbe() + elif package['build_cmd'] == 'build_intel_ixgbevf': + build_intel_ixgbevf() + elif package['build_cmd'] == 'build_jool': + build_jool() + elif package['build_cmd'] == 'build_openvpn_dco': + build_openvpn_dco(package['commit_id'], package['scm_url']) + elif package['build_cmd'] == 'build_nat_rtsp': + build_nat_rtsp(package['commit_id'], package['scm_url']) + else: + run(package['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("Copied generated .deb packages") + except Exception as e: + print(f"Error copying packages: {e}") + + +def merge_dicts(defaults, package): + return {**defaults, **package} + + +def build_kernel(kernel_version): + """Build the Linux kernel""" + run(['gpg2', '--locate-keys', 'torvalds@kernel.org', 'gregkh@kernel.org'], check=True) + run(['curl', '-OL', f'https://www.kernel.org/pub/linux/kernel/v6.x/linux-{kernel_version}.tar.xz'], check=True) + run(['curl', '-OL', f'https://www.kernel.org/pub/linux/kernel/v6.x/linux-{kernel_version}.tar.sign'], check=True) + # Using pipes to handle decompression and verification + with subprocess.Popen(['xz', '-cd', f'linux-{kernel_version}.tar.xz'], stdout=subprocess.PIPE) as proc_xz: + run(['gpg2', '--verify', f'linux-{kernel_version}.tar.sign', '-'], stdin=proc_xz.stdout, check=True) + run(['tar', 'xf', f'linux-{kernel_version}.tar.xz'], check=True) + os.symlink(f'linux-{kernel_version}', 'linux') + run(['./build-kernel.sh'], check=True) + + +def build_linux_firmware(commit_id, scm_url): + """Build Linux firmware""" + repo_dir = Path('linux-firmware') + clone_or_update_repo(repo_dir, scm_url, commit_id) + run(['./build-linux-firmware.sh'], check=True) + + +def build_accel_ppp(commit_id, scm_url): + """Build accel-ppp""" + repo_dir = Path('accel-ppp') + clone_or_update_repo(repo_dir, scm_url, commit_id) + run(['./build-accel-ppp.sh'], check=True) + + +def build_intel_qat(): + """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_ixgbevf(): + """Build Intel IXGBEVF""" + run(['./build-intel-ixgbevf.sh'], check=True) + + +def build_jool(): + """Build Jool""" + run(['echo y | ./build-jool.py'], check=True, shell=True) + + +def build_openvpn_dco(commit_id, scm_url): + """Build OpenVPN DCO""" + repo_dir = Path('ovpn-dco') + clone_or_update_repo(repo_dir, scm_url, commit_id) + run(['./build-openvpn-dco.sh'], check=True) + + +def build_nat_rtsp(commit_id, scm_url): + """Build RTSP netfilter helper""" + repo_dir = Path('nat-rtsp') + clone_or_update_repo(repo_dir, scm_url, commit_id) + run(['./build-nat-rtsp.sh'], check=True) + + +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('--packages', nargs='+', help='Names of packages to build (default: all)', default=[]) + args = arg_parser.parse_args() + + # Load package configuration + with open(args.config, 'r') as file: + config = toml.load(file) + + # Extract defaults and packages + with open(defaults_path, 'r') as file: + defaults = toml.load(file) + + packages = config['packages'] + + # Filter packages if specific packages are specified in the arguments + if args.packages: + packages = [pkg for pkg in packages if pkg['name'] in args.packages] + + # Merge defaults into each package + packages = [merge_dicts(defaults, pkg) for pkg in packages] + + for package in packages: + dependencies = package.get('dependencies', {}).get('packages', []) + + # Build the package + build_package(package, dependencies) + + # 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'])) diff --git a/scripts/package-build/linux-kernel/package.toml b/scripts/package-build/linux-kernel/package.toml new file mode 100644 index 00000000..8b030da0 --- /dev/null +++ b/scripts/package-build/linux-kernel/package.toml @@ -0,0 +1,62 @@ +# [defaults] +# We get the kernel_version from vyos-build/data/defaults.toml +# kernel_version = "6.6.47" +# kernel_flavor = "amd64-vyos" + + +[[packages]] +name = "linux-kernel" +commit_id = "" # Uses defaults.kernel_version +scm_url = "" +build_cmd = "build_kernel" + +[[packages]] +name = "linux-firmware" +commit_id = "20240610" +scm_url = "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git" +build_cmd = "build_linux_firmware" + +[[packages]] +name = "accel-ppp" +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" +scm_url = "https://github.com/OpenVPN/ovpn-dco" +build_cmd = "build_openvpn_dco" + +[[packages]] +name = "nat-rtsp" +commit_id = "475af0a" +scm_url = "https://github.com/maru-sama/rtsp-linux.git" +build_cmd = "build_nat_rtsp" + + +[[packages]] +name = "qat" +commit_id = "" +scm_url = "" +build_cmd = "build_intel_qat" + +[[packages]] +name = "ixgbe" +commit_id = "" +scm_url = "" +build_cmd = "build_intel_ixgbe" + +[[packages]] +name = "ixgbevf" +commit_id = "" +scm_url = "" +build_cmd = "build_intel_ixgbevf" + +[[packages]] +name = "jool" +commit_id = "" +scm_url = "" +build_cmd = "build_jool" + diff --git a/scripts/package-build/linux-kernel/patches b/scripts/package-build/linux-kernel/patches new file mode 120000 index 00000000..fd016d35 --- /dev/null +++ b/scripts/package-build/linux-kernel/patches @@ -0,0 +1 @@ +../../../packages/linux-kernel/patches
\ No newline at end of file diff --git a/scripts/package-build/ndppd/.gitignore b/scripts/package-build/ndppd/.gitignore new file mode 100644 index 00000000..2b71e9fb --- /dev/null +++ b/scripts/package-build/ndppd/.gitignore @@ -0,0 +1,7 @@ +ndppd/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc + diff --git a/scripts/package-build/ndppd/build.py b/scripts/package-build/ndppd/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/ndppd/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/ndppd/package.toml b/scripts/package-build/ndppd/package.toml new file mode 100644 index 00000000..58ce6511 --- /dev/null +++ b/scripts/package-build/ndppd/package.toml @@ -0,0 +1,4 @@ +[[packages]] +name = "ndppd" +commit_id = "debian/0.2.5-6" +scm_url = "https://salsa.debian.org/debian/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/0001-skip-route-table-if-there-is-no-auto-rule.patch new file mode 100644 index 00000000..df6d2e5c --- /dev/null +++ b/scripts/package-build/ndppd/patches/0001-skip-route-table-if-there-is-no-auto-rule.patch @@ -0,0 +1,83 @@ +From b148ba055245cec5007ee91dd3ffbfeb58d49c5a Mon Sep 17 00:00:00 2001 +From: Henning Surmeier <me@hensur.de> +Date: Sun, 9 Jan 2022 20:35:15 +0100 +Subject: [PATCH 1/2] skip route table if there is no auto rule + +--- + src/ndppd.cc | 3 ++- + src/rule.cc | 8 ++++++++ + src/rule.h | 4 ++++ + 3 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/src/ndppd.cc b/src/ndppd.cc +index bec9656..b303721 100644 +--- a/src/ndppd.cc ++++ b/src/ndppd.cc +@@ -304,7 +304,8 @@ int main(int argc, char* argv[], char* env[]) + t1.tv_sec = t2.tv_sec; + t1.tv_usec = t2.tv_usec; + +- route::update(elapsed_time); ++ if (rule::any_auto()) ++ route::update(elapsed_time); + session::update_all(elapsed_time); + } + +diff --git a/src/rule.cc b/src/rule.cc +index 9e72480..a1e8376 100644 +--- a/src/rule.cc ++++ b/src/rule.cc +@@ -24,6 +24,8 @@ + + NDPPD_NS_BEGIN + ++bool rule::_any_aut = false; ++ + rule::rule() + { + } +@@ -49,6 +51,7 @@ ptr<rule> rule::create(const ptr<proxy>& pr, const address& addr, bool aut) + ru->_pr = pr; + ru->_addr = addr; + ru->_aut = aut; ++ _any_aut = _any_aut || aut; + + logger::debug() + << "rule::create() if=" << pr->ifa()->name().c_str() << ", addr=" << addr +@@ -57,6 +60,11 @@ ptr<rule> rule::create(const ptr<proxy>& pr, const address& addr, bool aut) + return ru; + } + ++bool rule::any_auto() ++{ ++ return _any_aut; ++} ++ + const address& rule::addr() const + { + return _addr; +diff --git a/src/rule.h b/src/rule.h +index 6663066..ca2aa36 100644 +--- a/src/rule.h ++++ b/src/rule.h +@@ -42,6 +42,8 @@ public: + + bool check(const address& addr) const; + ++ static bool any_auto(); ++ + private: + weak_ptr<rule> _ptr; + +@@ -53,6 +55,8 @@ private: + + bool _aut; + ++ static bool _any_aut; ++ + rule(); + }; + +-- +2.34.1 + diff --git a/scripts/package-build/ndppd/patches/0002-set-vyos-version.patch b/scripts/package-build/ndppd/patches/0002-set-vyos-version.patch new file mode 100644 index 00000000..3fef87c4 --- /dev/null +++ b/scripts/package-build/ndppd/patches/0002-set-vyos-version.patch @@ -0,0 +1,25 @@ +From b0789cf679b0179d37e22f5a936af273d982abeb Mon Sep 17 00:00:00 2001 +From: Henning Surmeier <me@hensur.de> +Date: Tue, 11 Jan 2022 13:05:47 +0100 +Subject: [PATCH 2/2] set -vyos version + +--- + src/ndppd.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ndppd.h b/src/ndppd.h +index 008726c..61ed950 100644 +--- a/src/ndppd.h ++++ b/src/ndppd.h +@@ -21,7 +21,7 @@ + #define NDPPD_NS_BEGIN namespace ndppd { + #define NDPPD_NS_END } + +-#define NDPPD_VERSION "0.2.4" ++#define NDPPD_VERSION "0.2.5-vyos" + + #include <assert.h> + +-- +2.34.1 + diff --git a/scripts/package-build/net-snmp/.gitignore b/scripts/package-build/net-snmp/.gitignore new file mode 100644 index 00000000..67811e63 --- /dev/null +++ b/scripts/package-build/net-snmp/.gitignore @@ -0,0 +1,6 @@ +net-snmp/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/net-snmp/build.py b/scripts/package-build/net-snmp/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/net-snmp/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/net-snmp/package.toml b/scripts/package-build/net-snmp/package.toml new file mode 100644 index 00000000..414f5e24 --- /dev/null +++ b/scripts/package-build/net-snmp/package.toml @@ -0,0 +1,5 @@ +[[packages]] +name = "net-snmp" +commit_id = "debian/5.9.4+dfsg-1" +scm_url = "https://salsa.debian.org/debian/net-snmp" +build_cmd = "dpkg-buildpackage -us -uc -tc -b || true" diff --git a/scripts/package-build/net-snmp/patches/add-linux-6.7-compatibility-parsing.patch b/scripts/package-build/net-snmp/patches/add-linux-6.7-compatibility-parsing.patch new file mode 100644 index 00000000..b6dcd77a --- /dev/null +++ b/scripts/package-build/net-snmp/patches/add-linux-6.7-compatibility-parsing.patch @@ -0,0 +1,119 @@ +From f5ae6baf0018abda9dedc368fe6d52c0d7a8ab8f Mon Sep 17 00:00:00 2001 +From: Philippe Troin <phil+github-commits@fifi.org> +Date: Sat, 3 Feb 2024 10:30:30 -0800 +Subject: [PATCH] Add Linux 6.7 compatibility parsing /proc/net/snmp + +Linux 6.7 adds a new OutTransmits field to Ip in /proc/net/snmp. +This breaks the hard-coded assumptions about the Ip line length. +Add compatibility to parse Linux 6.7 Ip header while keep support +for previous versions. +--- + .../ip-mib/data_access/systemstats_linux.c | 46 +++++++++++++++---- + 1 file changed, 37 insertions(+), 9 deletions(-) + +diff --git a/agent/mibgroup/ip-mib/data_access/systemstats_linux.c b/agent/mibgroup/ip-mib/data_access/systemstats_linux.c +index 49e0a34d5c..f04e828a94 100644 +--- a/agent/mibgroup/ip-mib/data_access/systemstats_linux.c ++++ b/agent/mibgroup/ip-mib/data_access/systemstats_linux.c +@@ -36,7 +36,7 @@ netsnmp_access_systemstats_arch_init(void) + } + + /* +- /proc/net/snmp ++ /proc/net/snmp - Linux 6.6 and lower + + Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates + Ip: 2 64 7083534 0 0 0 0 0 6860233 6548963 0 0 1 286623 63322 1 259920 0 0 +@@ -49,6 +49,26 @@ netsnmp_access_systemstats_arch_init(void) + + Udp: InDatagrams NoPorts InErrors OutDatagrams + Udp: 1491094 122 0 1466178 ++* ++ /proc/net/snmp - Linux 6.7 and higher ++ ++ Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates OutTransmits ++ Ip: 1 64 50859058 496 0 37470604 0 0 20472980 7515791 1756 0 0 7264 3632 0 3548 0 7096 44961424 ++ ++ Icmp: InMsgs InErrors InCsumErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutRateLimitGlobal OutRateLimitHost OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps ++ Icmp: 114447 2655 0 17589 0 0 0 0 66905 29953 0 0 0 0 143956 0 0 572 16610 484 0 0 0 59957 66905 0 0 0 0 ++ ++ IcmpMsg: InType0 InType3 InType8 OutType0 OutType3 OutType8 OutType11 ++ IcmpMsg: 29953 17589 66905 66905 16610 59957 484 ++ ++ Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts InCsumErrors ++ Tcp: 1 200 120000 -1 17744 13525 307 3783 6 18093137 9277788 3499 8 7442 0 ++ ++ Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors IgnoredMulti MemErrors ++ Udp: 2257832 1422 0 2252835 0 0 0 84 0 ++ ++ UdpLite: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors IgnoredMulti MemErrors ++ UdpLite: 0 0 0 0 0 0 0 0 0 + */ + + +@@ -101,10 +121,10 @@ _systemstats_v4(netsnmp_container* container, u_int load_flags) + FILE *devin; + char line[1024]; + netsnmp_systemstats_entry *entry = NULL; +- int scan_count; ++ int scan_count, expected_scan_count; + char *stats, *start = line; + int len; +- unsigned long long scan_vals[19]; ++ unsigned long long scan_vals[20]; + + DEBUGMSGTL(("access:systemstats:container:arch", "load v4 (flags %x)\n", + load_flags)); +@@ -126,10 +146,17 @@ _systemstats_v4(netsnmp_container* container, u_int load_flags) + */ + NETSNMP_IGNORE_RESULT(fgets(line, sizeof(line), devin)); + len = strlen(line); +- if (224 != len) { ++ switch (len) { ++ case 224: ++ expected_scan_count = 19; ++ break; ++ case 237: ++ expected_scan_count = 20; ++ break; ++ default: + fclose(devin); + snmp_log(LOG_ERR, "systemstats_linux: unexpected header length in /proc/net/snmp." +- " %d != 224\n", len); ++ " %d not in { 224, 237 } \n", len); + return -4; + } + +@@ -178,20 +205,20 @@ _systemstats_v4(netsnmp_container* container, u_int load_flags) + memset(scan_vals, 0x0, sizeof(scan_vals)); + scan_count = sscanf(stats, + "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu" +- "%llu %llu %llu %llu %llu %llu %llu %llu %llu", ++ "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", + &scan_vals[0],&scan_vals[1],&scan_vals[2], + &scan_vals[3],&scan_vals[4],&scan_vals[5], + &scan_vals[6],&scan_vals[7],&scan_vals[8], + &scan_vals[9],&scan_vals[10],&scan_vals[11], + &scan_vals[12],&scan_vals[13],&scan_vals[14], + &scan_vals[15],&scan_vals[16],&scan_vals[17], +- &scan_vals[18]); ++ &scan_vals[18],&scan_vals[19]); + DEBUGMSGTL(("access:systemstats", " read %d values\n", scan_count)); + +- if(scan_count != 19) { ++ if(scan_count != expected_scan_count) { + snmp_log(LOG_ERR, + "error scanning systemstats data (expected %d, got %d)\n", +- 19, scan_count); ++ expected_scan_count, scan_count); + netsnmp_access_systemstats_entry_free(entry); + return -4; + } +@@ -223,6 +250,7 @@ _systemstats_v4(netsnmp_container* container, u_int load_flags) + entry->stats.HCOutFragFails.high = scan_vals[17] >> 32; + entry->stats.HCOutFragCreates.low = scan_vals[18] & 0xffffffff; + entry->stats.HCOutFragCreates.high = scan_vals[18] >> 32; ++ /* entry->stats. = scan_vals[19]; / * OutTransmits */ + + entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINRECEIVES] = 1; + entry->stats.columnAvail[IPSYSTEMSTATSTABLE_INHDRERRORS] = 1; diff --git a/scripts/package-build/netfilter/.gitignore b/scripts/package-build/netfilter/.gitignore new file mode 100644 index 00000000..8518afb9 --- /dev/null +++ b/scripts/package-build/netfilter/.gitignore @@ -0,0 +1,3 @@ +/pkg-libnftnl/ +/pkg-nftables/ + diff --git a/scripts/package-build/netfilter/build.py b/scripts/package-build/netfilter/build.py new file mode 100755 index 00000000..9737b7d3 --- /dev/null +++ b/scripts/package-build/netfilter/build.py @@ -0,0 +1,189 @@ +#!/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'])) diff --git a/scripts/package-build/netfilter/package.toml b/scripts/package-build/netfilter/package.toml new file mode 100644 index 00000000..45752d08 --- /dev/null +++ b/scripts/package-build/netfilter/package.toml @@ -0,0 +1,11 @@ +[[packages]] +name = "pkg-libnftnl" +commit_id = "debian/1.2.6-2" +scm_url = "https://salsa.debian.org/pkg-netfilter-team/pkg-libnftnl.git" +build_cmd = "sudo mk-build-deps --install --tool 'apt-get --yes --no-install-recommends'; dpkg-buildpackage -uc -us -tc -b" + +[[packages]] +name = "pkg-nftables" +commit_id = "debian/1.0.9-1" +scm_url = "https://salsa.debian.org/pkg-netfilter-team/pkg-nftables.git" +build_cmd = "sudo dpkg -i ../libnftnl*.deb; dpkg-buildpackage -uc -us -tc -b" diff --git a/scripts/package-build/netfilter/patches/pkg-nftables/0001-meta-fix-hour-decoding.patch b/scripts/package-build/netfilter/patches/pkg-nftables/0001-meta-fix-hour-decoding.patch new file mode 100644 index 00000000..dd466f1a --- /dev/null +++ b/scripts/package-build/netfilter/patches/pkg-nftables/0001-meta-fix-hour-decoding.patch @@ -0,0 +1,118 @@ +From d392ddf243dcbf8a34726c777d2c669b1e8bfa85 Mon Sep 17 00:00:00 2001 +From: Florian Westphal <fw@strlen.de> +Date: Thu, 2 Nov 2023 15:34:13 +0100 +Subject: meta: fix hour decoding when timezone offset is negative + +Brian Davidson says: + + meta hour rules don't display properly after being created when the + hour is on or after 00:00 UTC. The netlink debug looks correct for + seconds past midnight UTC, but displaying the rules looks like an + overflow or a byte order problem. I am in UTC-0400, so today, 20:00 + and later exhibits the problem, while 19:00 and earlier hours are + fine. + +meta.c only ever worked when the delta to UTC is positive. +We need to add in case the second counter turns negative after +offset adjustment. + +Also add a test case for this. + +Fixes: f8f32deda31d ("meta: Introduce new conditions 'time', 'day' and 'hour'") +Reported-by: Brian Davidson <davidson.brian@gmail.com> +Signed-off-by: Florian Westphal <fw@strlen.de> +--- + src/meta.c | 11 ++++- + .../shell/testcases/listing/dumps/meta_time.nodump | 0 + tests/shell/testcases/listing/meta_time | 52 ++++++++++++++++++++++ + 3 files changed, 61 insertions(+), 2 deletions(-) + create mode 100644 tests/shell/testcases/listing/dumps/meta_time.nodump + create mode 100755 tests/shell/testcases/listing/meta_time + +diff --git a/src/meta.c b/src/meta.c +index b578d5e2..7846aefe 100644 +--- a/src/meta.c ++++ b/src/meta.c +@@ -495,9 +495,16 @@ static void hour_type_print(const struct expr *expr, struct output_ctx *octx) + + /* Obtain current tm, so that we can add tm_gmtoff */ + ts = time(NULL); +- if (ts != ((time_t) -1) && localtime_r(&ts, &cur_tm)) +- seconds = (seconds + cur_tm.tm_gmtoff) % SECONDS_PER_DAY; ++ if (ts != ((time_t) -1) && localtime_r(&ts, &cur_tm)) { ++ int32_t adj = seconds + cur_tm.tm_gmtoff; + ++ if (adj < 0) ++ adj += SECONDS_PER_DAY; ++ else if (adj >= SECONDS_PER_DAY) ++ adj -= SECONDS_PER_DAY; ++ ++ seconds = adj; ++ } + minutes = seconds / 60; + seconds %= 60; + hours = minutes / 60; +diff --git a/tests/shell/testcases/listing/dumps/meta_time.nodump b/tests/shell/testcases/listing/dumps/meta_time.nodump +new file mode 100644 +index 00000000..e69de29b +diff --git a/tests/shell/testcases/listing/meta_time b/tests/shell/testcases/listing/meta_time +new file mode 100755 +index 00000000..a9761998 +--- /dev/null ++++ b/tests/shell/testcases/listing/meta_time +@@ -0,0 +1,52 @@ ++#!/bin/bash ++ ++set -e ++ ++TMP1=$(mktemp) ++TMP2=$(mktemp) ++ ++cleanup() ++{ ++ rm -f "$TMP1" ++ rm -f "$TMP2" ++} ++ ++check_decode() ++{ ++ TZ=$1 $NFT list chain t c | grep meta > "$TMP2" ++ diff -u "$TMP1" "$TMP2" ++} ++ ++trap cleanup EXIT ++ ++$NFT -f - <<EOF ++table t { ++ chain c { ++ } ++} ++EOF ++ ++for i in $(seq -w 0 23); do ++ TZ=UTC $NFT add rule t c meta hour "$i:00"-"$i:59" ++done ++ ++# Check decoding in UTC, this mirrors 1:1 what should have been added. ++for i in $(seq 0 23); do ++ printf "\t\tmeta hour \"%02d:%02d\"-\"%02d:%02d\"\n" $i 0 $i 59 >> "$TMP1" ++done ++ ++check_decode UTC ++ ++printf "\t\tmeta hour \"%02d:%02d\"-\"%02d:%02d\"\n" 23 0 23 59 > "$TMP1" ++for i in $(seq 0 22); do ++ printf "\t\tmeta hour \"%02d:%02d\"-\"%02d:%02d\"\n" $i 0 $i 59 >> "$TMP1" ++done ++check_decode UTC+1 ++ ++printf "\t\tmeta hour \"%02d:%02d\"-\"%02d:%02d\"\n" 1 0 1 59 > "$TMP1" ++for i in $(seq 2 23); do ++ printf "\t\tmeta hour \"%02d:%02d\"-\"%02d:%02d\"\n" $i 0 $i 59 >> "$TMP1" ++done ++printf "\t\tmeta hour \"%02d:%02d\"-\"%02d:%02d\"\n" 0 0 0 59 >> "$TMP1" ++ ++check_decode UTC-1 +-- +cgit v1.2.3 + diff --git a/scripts/package-build/opennhrp/.gitignore b/scripts/package-build/opennhrp/.gitignore new file mode 100644 index 00000000..65d0752b --- /dev/null +++ b/scripts/package-build/opennhrp/.gitignore @@ -0,0 +1,6 @@ +opennhrp/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/opennhrp/build.py b/scripts/package-build/opennhrp/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/opennhrp/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/opennhrp/package.toml b/scripts/package-build/opennhrp/package.toml new file mode 100644 index 00000000..d647c072 --- /dev/null +++ b/scripts/package-build/opennhrp/package.toml @@ -0,0 +1,21 @@ +[[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 new file mode 100644 index 00000000..7f89da2b --- /dev/null +++ b/scripts/package-build/openvpn-otp/.gitignore @@ -0,0 +1,6 @@ +openvpn-otp/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/openvpn-otp/build.py b/scripts/package-build/openvpn-otp/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/openvpn-otp/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/openvpn-otp/package.toml b/scripts/package-build/openvpn-otp/package.toml new file mode 100644 index 00000000..72209ad1 --- /dev/null +++ b/scripts/package-build/openvpn-otp/package.toml @@ -0,0 +1,19 @@ +[[packages]] +name = "openvpn-otp" +commit_id = "master" +scm_url = "https://github.com/evgeny-gridasov/openvpn-otp" + +# build_cmd = "cd ..; ./build-openvpn-otp.sh" +build_cmd = """ +./autogen.sh +./configure --prefix=/usr +make +mkdir -p usr/lib/openvpn +cp src/.libs/openvpn-otp.so usr/lib/openvpn + +fpm --input-type dir --output-type deb --name openvpn-otp \ + --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \ + --description "OpenVPN OTP Authentication support." \ + --depends openvpn --architecture $(dpkg --print-architecture) \ + --version $(git describe --tags --always | cut -c2-) --deb-compression gz usr +""" diff --git a/scripts/package-build/owamp/.gitignore b/scripts/package-build/owamp/.gitignore new file mode 100644 index 00000000..4a97524e --- /dev/null +++ b/scripts/package-build/owamp/.gitignore @@ -0,0 +1,6 @@ +owamp/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/owamp/build.py b/scripts/package-build/owamp/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/owamp/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/owamp/package.toml b/scripts/package-build/owamp/package.toml new file mode 100644 index 00000000..8bc78afa --- /dev/null +++ b/scripts/package-build/owamp/package.toml @@ -0,0 +1,4 @@ +[[packages]] +name = "owamp" +commit_id = "v4.4.6" +scm_url = "https://github.com/perfsonar/owamp" diff --git a/scripts/package-build/pam_tacplus/.gitignore b/scripts/package-build/pam_tacplus/.gitignore new file mode 100644 index 00000000..04e8d4e9 --- /dev/null +++ b/scripts/package-build/pam_tacplus/.gitignore @@ -0,0 +1,7 @@ +pam_tacplus/ +pam_tacplus-debian/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/pam_tacplus/build.py b/scripts/package-build/pam_tacplus/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/pam_tacplus/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/pam_tacplus/package.toml b/scripts/package-build/pam_tacplus/package.toml new file mode 100644 index 00000000..79b28544 --- /dev/null +++ b/scripts/package-build/pam_tacplus/package.toml @@ -0,0 +1,19 @@ +[[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 new file mode 100644 index 00000000..7007417a --- /dev/null +++ b/scripts/package-build/pmacct/.gitignore @@ -0,0 +1,6 @@ +pmacct/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/pmacct/build.py b/scripts/package-build/pmacct/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/pmacct/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/pmacct/package.toml b/scripts/package-build/pmacct/package.toml new file mode 100644 index 00000000..6f5961be --- /dev/null +++ b/scripts/package-build/pmacct/package.toml @@ -0,0 +1,4 @@ +[[packages]] +name = "pmacct" +commit_id = "debian/1.7.7-1" +scm_url = "https://salsa.debian.org/debian/pmacct.git" 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/0001-fix-pmacctd-SEGV-when-ICMP-ICMPv6-traffic-was-proces.patch new file mode 100644 index 00000000..cb5f7399 --- /dev/null +++ b/scripts/package-build/pmacct/patches/0001-fix-pmacctd-SEGV-when-ICMP-ICMPv6-traffic-was-proces.patch @@ -0,0 +1,49 @@ +From 58900c9d0f98f224577c28dc2323061d33823f39 Mon Sep 17 00:00:00 2001 +From: Paolo Lucente <pl+github@pmacct.net> +Date: Fri, 4 Mar 2022 22:07:29 +0000 +Subject: [PATCH] * fix, pmacctd: SEGV when ICMP/ICMPv6 traffic was processed + and 'flows' primitive was enabled. To address Issue #586 + +--- + src/nl.c | 12 +++--------- + 1 file changed, 3 insertions(+), 9 deletions(-) + +diff --git a/src/nl.c b/src/nl.c +index c42689ed..6a3da94b 100644 +--- a/src/nl.c ++++ b/src/nl.c +@@ -1,6 +1,6 @@ + /* + pmacct (Promiscuous mode IP Accounting package) +- pmacct is Copyright (C) 2003-2021 by Paolo Lucente ++ pmacct is Copyright (C) 2003-2022 by Paolo Lucente + */ + + /* +@@ -293,10 +293,7 @@ int ip_handler(register struct packet_ptrs *pptrs) + } + } + else { +- if (pptrs->l4_proto != IPPROTO_ICMP) { +- pptrs->tlh_ptr = dummy_tlhdr; +- } +- ++ pptrs->tlh_ptr = dummy_tlhdr; + if (off < caplen) pptrs->payload_ptr = ptr; + } + +@@ -479,10 +476,7 @@ int ip6_handler(register struct packet_ptrs *pptrs) + } + } + else { +- if (pptrs->l4_proto != IPPROTO_ICMPV6) { +- pptrs->tlh_ptr = dummy_tlhdr; +- } +- ++ pptrs->tlh_ptr = dummy_tlhdr; + if (off < caplen) pptrs->payload_ptr = ptr; + } + +-- +2.34.1 + diff --git a/scripts/package-build/podman/.gitignore b/scripts/package-build/podman/.gitignore new file mode 100644 index 00000000..22c40b0e --- /dev/null +++ b/scripts/package-build/podman/.gitignore @@ -0,0 +1,7 @@ +podman/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc + diff --git a/scripts/package-build/podman/build.py b/scripts/package-build/podman/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/podman/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/podman/package.toml b/scripts/package-build/podman/package.toml new file mode 100644 index 00000000..952af518 --- /dev/null +++ b/scripts/package-build/podman/package.toml @@ -0,0 +1,27 @@ +[[packages]] +name = "podman" +commit_id = "v4.9.5" +scm_url = "https://github.com/containers/podman" + +#build_cmd = "cd ..; ./build.sh" +build_cmd = """ +make install.tools +make podman-release + +tar xf podman-release-$(dpkg --print-architecture).tar.gz +VERSION=$(ls -d podman-v* | cut -c9-) + +fpm --input-type dir --output-type deb --name podman \ + --version $VERSION --deb-compression gz \ + --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \ + --description "Engine to run OCI-based containers in Pods" \ + --depends conmon --depends crun --depends netavark --depends libgpgme11 \ + --depends fuse-overlayfs --depends golang-github-containers-common \ + --license "Apache License 2.0" -C podman-v$VERSION --package .. +""" + +[packages.dependencies] +packages = [ + "libseccomp-dev", + "libgpgme-dev" +] diff --git a/scripts/package-build/pyhumps/.gitignore b/scripts/package-build/pyhumps/.gitignore new file mode 100644 index 00000000..6a90d1c9 --- /dev/null +++ b/scripts/package-build/pyhumps/.gitignore @@ -0,0 +1,7 @@ +humps/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc + diff --git a/scripts/package-build/pyhumps/build.py b/scripts/package-build/pyhumps/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/pyhumps/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/pyhumps/package.toml b/scripts/package-build/pyhumps/package.toml new file mode 100644 index 00000000..a358d128 --- /dev/null +++ b/scripts/package-build/pyhumps/package.toml @@ -0,0 +1,5 @@ +[[packages]] +name = "humps" +commit_id = "v3.8.0" +scm_url = "https://github.com/nficano/humps.git" +build_cmd = "python3 setup.py --command-packages=stdeb.command bdist_deb; cp deb_dist/*.deb .." diff --git a/scripts/package-build/radvd/.gitignore b/scripts/package-build/radvd/.gitignore new file mode 100644 index 00000000..9c37832b --- /dev/null +++ b/scripts/package-build/radvd/.gitignore @@ -0,0 +1,6 @@ +radvd/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/radvd/build.py b/scripts/package-build/radvd/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/radvd/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/radvd/package.toml b/scripts/package-build/radvd/package.toml new file mode 100644 index 00000000..e44afa18 --- /dev/null +++ b/scripts/package-build/radvd/package.toml @@ -0,0 +1,23 @@ +[[packages]] +name = "radvd" +commit_id = "f2de4764559" +scm_url = "https://github.com/radvd-project/radvd" + +#build_cmd = "cd ..; ./build.sh" +build_cmd = """ +./autogen.sh +./configure +make + +install --directory debian/lib/systemd/system debian/usr/sbin +install --mode 0644 radvd.service debian/lib/systemd/system +install --strip --mode 0755 radvd debian/usr/sbin + +# Version' field value 'v0.14-20-g613277f': version number does not start with digit +# "cut" first character from version string +fpm --input-type dir --output-type deb --name radvd \ + --version $(git describe --always | cut -c2- | tr _ -) --deb-compression gz \ + --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \ + --description "RADVD router advertisement daemon" \ + --license "RADVD" -C debian --package .. +""" diff --git a/scripts/package-build/strongswan/.gitignore b/scripts/package-build/strongswan/.gitignore new file mode 100644 index 00000000..ec612740 --- /dev/null +++ b/scripts/package-build/strongswan/.gitignore @@ -0,0 +1,6 @@ +strongswan/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/strongswan/build-vici.sh b/scripts/package-build/strongswan/build-vici.sh new file mode 100755 index 00000000..5ad0ee80 --- /dev/null +++ b/scripts/package-build/strongswan/build-vici.sh @@ -0,0 +1,57 @@ +#!/bin/sh +CWD=$(pwd) +set -e + +SRC="strongswan/src/libcharon/plugins/vici/python" +if [ ! -d ${SRC} ]; then + echo "Source directory does not exists, please 'git clone'" + exit 1 +fi + +cd ${SRC} + +mkdir -p debian + +# Create control file +echo "I: create $SRC/debian/control" +cat <<EOF > debian/control +Source: strongswan +Section: python +Priority: optional +Maintainer: VyOS Package Maintainers <maintainers@vyos.net> +Build-Depends: debhelper (>= 9), python3, python3-setuptools +Standards-Version: 3.9.6 + +Package: python3-vici +Architecture: all +Depends: \${misc:Depends}, \${python3:Depends} +Description: Native Python interface for strongSwan's VICI protocol +EOF + + +# Create rules file +echo "I: create $SRC/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 + +# Copy changelog +cp ../../../../../debian/changelog debian/ + + +ls -la +pwd + + +echo "I: Build Debian Package" +dpkg-buildpackage -uc -us -tc -b -d + +echo "I: copy packages" +cp ../*.deb ../../../../../../ diff --git a/scripts/package-build/strongswan/build.py b/scripts/package-build/strongswan/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/strongswan/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/strongswan/package.toml b/scripts/package-build/strongswan/package.toml new file mode 100644 index 00000000..8cedd4ac --- /dev/null +++ b/scripts/package-build/strongswan/package.toml @@ -0,0 +1,45 @@ +[[packages]] +name = "strongswan" +commit_id = "debian/5.9.11-2" +scm_url = "https://salsa.debian.org/debian/strongswan.git" + +# build_cmd = "cd ..; yes | ./build.sh; ./build-vici.sh" +build_cmd = """ +export DEBEMAIL="maintainers@vyos.net" +export DEBFULLNAME="VyOS Package Maintainers" + +dch -v "5.9.11-2+vyos0" "Patchset for DMVPN support" -b +dpkg-buildpackage -uc -us -tc -b -d +cd ..; ./build-vici.sh +""" + +[packages.dependencies] +packages = [ + "bison", + "bzip2", + "debhelper-compat", + "dh-apparmor", + "dpkg-dev", + "flex", + "gperf", + "libiptc-dev", + "libcap-dev", + "libcurl3-dev", + "libgcrypt20-dev", + "libgmp3-dev", + "libkrb5-dev", + "libldap2-dev", + "libnm-dev", + "libpam0g-dev", + "libsqlite3-dev", + "libssl-dev", + "libsystemd-dev", + "libtool", + "libtss2-dev", + "libxml2-dev", + "pkg-config", + "po-debconf", + "systemd", + "libsystemd-dev", + "tzdata" +] diff --git a/scripts/package-build/strongswan/patches/0001-charon-add-optional-source-and-remote-overrides-for-.patch b/scripts/package-build/strongswan/patches/0001-charon-add-optional-source-and-remote-overrides-for-.patch new file mode 100644 index 00000000..ceb47350 --- /dev/null +++ b/scripts/package-build/strongswan/patches/0001-charon-add-optional-source-and-remote-overrides-for-.patch @@ -0,0 +1,579 @@ +From db627ec8a8e72bc6b23dc8ab00f4e6b4f448d01c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> +Date: Mon, 21 Sep 2015 13:41:58 +0300 +Subject: [PATCH 1/3] charon: add optional source and remote overrides for + initiate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This introduces support for specifying optional IKE SA specific +source and remote address for child sa initiation. This allows +to initiate wildcard connection for known address via vici. + +In addition this allows impler implementation of trap-any patches +and is a prerequisite for dmvpn support. + +Signed-off-by: Timo Teräs <timo.teras@iki.fi> +--- + src/charon-cmd/cmd/cmd_connection.c | 2 +- + src/libcharon/control/controller.c | 42 +++++++++++- + src/libcharon/control/controller.h | 3 + + src/libcharon/plugins/stroke/stroke_control.c | 5 +- + src/libcharon/plugins/vici/vici_config.c | 2 +- + src/libcharon/plugins/vici/vici_control.c | 64 ++++++++++++++++--- + .../processing/jobs/start_action_job.c | 2 +- + src/libcharon/sa/ike_sa_manager.c | 50 ++++++++++++++- + src/libcharon/sa/ike_sa_manager.h | 8 ++- + src/libcharon/sa/trap_manager.c | 44 +++++-------- + src/swanctl/commands/initiate.c | 40 +++++++++++- + 11 files changed, 215 insertions(+), 47 deletions(-) + +diff --git a/src/charon-cmd/cmd/cmd_connection.c b/src/charon-cmd/cmd/cmd_connection.c +index 2e2cb3c..b9369a8 100644 +--- a/src/charon-cmd/cmd/cmd_connection.c ++++ b/src/charon-cmd/cmd/cmd_connection.c +@@ -439,7 +439,7 @@ static job_requeue_t initiate(private_cmd_connection_t *this) + child_cfg = create_child_cfg(this, peer_cfg); + + if (charon->controller->initiate(charon->controller, peer_cfg, child_cfg, +- controller_cb_empty, NULL, LEVEL_SILENT, 0, FALSE) != SUCCESS) ++ NULL, NULL, controller_cb_empty, NULL, LEVEL_SILENT, 0, FALSE) != SUCCESS) + { + terminate(pid); + } +diff --git a/src/libcharon/control/controller.c b/src/libcharon/control/controller.c +index 027f48e..4ce8616 100644 +--- a/src/libcharon/control/controller.c ++++ b/src/libcharon/control/controller.c +@@ -15,6 +15,28 @@ + * for more details. + */ + ++/* ++ * Copyright (C) 2014 Timo Teräs <timo.teras@iki.fi> ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ + #include "controller.h" + + #include <sys/types.h> +@@ -107,6 +129,16 @@ struct interface_listener_t { + */ + ike_sa_t *ike_sa; + ++ /** ++ * Our host hint. ++ */ ++ host_t *my_host; ++ ++ /** ++ * Other host hint. ++ */ ++ host_t *other_host; ++ + /** + * unique ID, used for various methods + */ +@@ -417,10 +449,15 @@ METHOD(job_t, initiate_execute, job_requeue_t, + ike_sa_t *ike_sa; + interface_listener_t *listener = &job->listener; + peer_cfg_t *peer_cfg = listener->peer_cfg; ++ host_t *my_host = listener->my_host; ++ host_t *other_host = listener->other_host; + + ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager, +- peer_cfg); ++ peer_cfg, my_host, other_host); + peer_cfg->destroy(peer_cfg); ++ DESTROY_IF(my_host); ++ DESTROY_IF(other_host); ++ + if (!ike_sa) + { + DESTROY_IF(listener->child_cfg); +@@ -499,6 +536,7 @@ METHOD(job_t, initiate_execute, job_requeue_t, + + METHOD(controller_t, initiate, status_t, + private_controller_t *this, peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, ++ host_t *my_host, host_t *other_host, + controller_cb_t callback, void *param, level_t max_level, u_int timeout, + bool limits) + { +@@ -523,6 +561,8 @@ METHOD(controller_t, initiate, status_t, + .status = FAILED, + .child_cfg = child_cfg, + .peer_cfg = peer_cfg, ++ .my_host = my_host ? my_host->clone(my_host) : NULL, ++ .other_host = other_host ? other_host->clone(other_host) : NULL, + .lock = spinlock_create(), + .options.limits = limits, + }, +diff --git a/src/libcharon/control/controller.h b/src/libcharon/control/controller.h +index 36a1d46..a130fbb 100644 +--- a/src/libcharon/control/controller.h ++++ b/src/libcharon/control/controller.h +@@ -81,6 +81,8 @@ struct controller_t { + * + * @param peer_cfg peer_cfg to use for IKE_SA setup + * @param child_cfg optional child_cfg to set up CHILD_SA from ++ * @param my_host optional address hint for source ++ * @param other_host optional address hint for destination + * @param cb logging callback + * @param param parameter to include in each call of cb + * @param max_level maximum log level for which cb is invoked +@@ -95,6 +97,7 @@ struct controller_t { + */ + status_t (*initiate)(controller_t *this, + peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, ++ host_t *my_host, host_t *other_host, + controller_cb_t callback, void *param, + level_t max_level, u_int timeout, bool limits); + +diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c +index 2824c93..21ff6b3 100644 +--- a/src/libcharon/plugins/stroke/stroke_control.c ++++ b/src/libcharon/plugins/stroke/stroke_control.c +@@ -109,7 +109,7 @@ static void charon_initiate(private_stroke_control_t *this, peer_cfg_t *peer_cfg + if (msg->output_verbosity < 0) + { + charon->controller->initiate(charon->controller, peer_cfg, child_cfg, +- NULL, NULL, 0, 0, FALSE); ++ NULL, NULL, NULL, NULL, 0, 0, FALSE); + } + else + { +@@ -117,7 +117,8 @@ static void charon_initiate(private_stroke_control_t *this, peer_cfg_t *peer_cfg + status_t status; + + status = charon->controller->initiate(charon->controller, +- peer_cfg, child_cfg, (controller_cb_t)stroke_log, ++ peer_cfg, child_cfg, NULL, NULL, ++ (controller_cb_t)stroke_log, + &info, msg->output_verbosity, this->timeout, FALSE); + switch (status) + { +diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c +index 5221225..b1486e3 100644 +--- a/src/libcharon/plugins/vici/vici_config.c ++++ b/src/libcharon/plugins/vici/vici_config.c +@@ -2252,7 +2252,7 @@ static void run_start_action(private_vici_config_t *this, peer_cfg_t *peer_cfg, + DBG1(DBG_CFG, "initiating '%s'", child_cfg->get_name(child_cfg)); + charon->controller->initiate(charon->controller, + peer_cfg->get_ref(peer_cfg), child_cfg->get_ref(child_cfg), +- NULL, NULL, 0, 0, FALSE); ++ NULL, NULL, NULL, NULL, 0, 0, FALSE); + } + } + +diff --git a/src/libcharon/plugins/vici/vici_control.c b/src/libcharon/plugins/vici/vici_control.c +index 1c236d2..811d8db 100644 +--- a/src/libcharon/plugins/vici/vici_control.c ++++ b/src/libcharon/plugins/vici/vici_control.c +@@ -15,6 +15,28 @@ + * for more details. + */ + ++/* ++ * Copyright (C) 2014 Timo Teräs <timo.teras@iki.fi> ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ + #include "vici_control.h" + #include "vici_builder.h" + +@@ -173,9 +195,11 @@ static child_cfg_t* find_child_cfg(char *name, char *pname, peer_cfg_t **out) + CALLBACK(initiate, vici_message_t*, + private_vici_control_t *this, char *name, u_int id, vici_message_t *request) + { ++ vici_message_t* msg; + peer_cfg_t *peer_cfg = NULL; + child_cfg_t *child_cfg; +- char *child, *ike, *type, *sa; ++ host_t *my_host = NULL, *other_host = NULL; ++ char *child, *ike, *type, *sa, *my_host_str, *other_host_str; + int timeout; + bool limits; + controller_cb_t log_cb = NULL; +@@ -189,6 +213,8 @@ CALLBACK(initiate, vici_message_t*, + timeout = request->get_int(request, 0, "timeout"); + limits = request->get_bool(request, FALSE, "init-limits"); + log.level = request->get_int(request, 1, "loglevel"); ++ my_host_str = request->get_str(request, NULL, "my-host"); ++ other_host_str = request->get_str(request, NULL, "other-host"); + + if (!child && !ike) + { +@@ -199,31 +225,52 @@ CALLBACK(initiate, vici_message_t*, + log_cb = (controller_cb_t)log_vici; + } + ++ if (my_host_str) ++ { ++ my_host = host_create_from_string(my_host_str, 0); ++ } ++ if (other_host_str) ++ { ++ other_host = host_create_from_string(other_host_str, 0); ++ } ++ ++ + type = child ? "CHILD_SA" : "IKE_SA"; + sa = child ?: ike; + + child_cfg = find_child_cfg(child, ike, &peer_cfg); + +- DBG1(DBG_CFG, "vici initiate %s '%s'", type, sa); ++ DBG1(DBG_CFG, "vici initiate %s '%s', me %H, other %H, limits %d", type, sa, my_host, other_host, limits); + if (!peer_cfg) + { +- return send_reply(this, "%s config '%s' not found", type, sa); ++ msg = send_reply(this, "%s config '%s' not found", type, sa); ++ goto ret; + } +- switch (charon->controller->initiate(charon->controller, peer_cfg, child_cfg, +- log_cb, &log, log.level, timeout, limits)) ++ switch (charon->controller->initiate(charon->controller, ++ peer_cfg, child_cfg, ++ my_host, other_host, ++ log_cb, &log, log.level, timeout, limits)) + { + case SUCCESS: +- return send_reply(this, NULL); ++ msg = send_reply(this, NULL); ++ break; + case OUT_OF_RES: +- return send_reply(this, "%s '%s' not established after %dms", type, ++ msg = send_reply(this, "%s '%s' not established after %dms", type, + sa, timeout); ++ break; + case INVALID_STATE: +- return send_reply(this, "establishing %s '%s' not possible at the " ++ msg = send_reply(this, "establishing %s '%s' not possible at the " + "moment due to limits", type, sa); ++ break; + case FAILED: + default: +- return send_reply(this, "establishing %s '%s' failed", type, sa); ++ msg = send_reply(this, "establishing %s '%s' failed", type, sa); ++ break; + } ++ret: ++ if (my_host) my_host->destroy(my_host); ++ if (other_host) other_host->destroy(other_host); ++ return msg; + } + + /** +diff --git a/src/libcharon/processing/jobs/start_action_job.c b/src/libcharon/processing/jobs/start_action_job.c +index 122e5ce..dec458c 100644 +--- a/src/libcharon/processing/jobs/start_action_job.c ++++ b/src/libcharon/processing/jobs/start_action_job.c +@@ -84,7 +84,7 @@ METHOD(job_t, execute, job_requeue_t, + charon->controller->initiate(charon->controller, + peer_cfg->get_ref(peer_cfg), + child_cfg->get_ref(child_cfg), +- NULL, NULL, 0, 0, FALSE); ++ NULL, NULL, NULL, NULL, 0, 0, FALSE); + } + } + children->destroy(children); +diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c +index fc31c2a..51e28bc 100644 +--- a/src/libcharon/sa/ike_sa_manager.c ++++ b/src/libcharon/sa/ike_sa_manager.c +@@ -16,6 +16,28 @@ + * for more details. + */ + ++/* ++ * Copyright (C) 2014 Timo Teräs <timo.teras@iki.fi> ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ + #include <string.h> + #include <inttypes.h> + +@@ -1497,7 +1519,8 @@ typedef struct { + } config_entry_t; + + METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*, +- private_ike_sa_manager_t *this, peer_cfg_t *peer_cfg) ++ private_ike_sa_manager_t *this, peer_cfg_t *peer_cfg, ++ host_t *my_host, host_t *other_host) + { + enumerator_t *enumerator; + entry_t *entry; +@@ -1508,7 +1531,17 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*, + u_int segment; + int i; + +- DBG2(DBG_MGR, "checkout IKE_SA by config"); ++ if (my_host && my_host->get_port(my_host) == 0) ++ { ++ my_host->set_port(my_host, IKEV2_UDP_PORT); ++ } ++ if (other_host && other_host->get_port(other_host) == 0) ++ { ++ other_host->set_port(other_host, IKEV2_UDP_PORT); ++ } ++ ++ DBG2(DBG_MGR, "checkout IKE_SA by config '%s', me %H, other %H", ++ peer_cfg->get_name(peer_cfg), my_host, other_host); + + if (!this->reuse_ikesa && peer_cfg->get_ike_version(peer_cfg) != IKEV1) + { /* IKE_SA reuse disabled by config (not possible for IKEv1) */ +@@ -1566,6 +1599,15 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*, + continue; + } + ++ if (my_host && !my_host->ip_equals(my_host, entry->ike_sa->get_my_host(entry->ike_sa))) ++ { ++ continue; ++ } ++ if (other_host && !other_host->ip_equals(other_host, entry->ike_sa->get_other_host(entry->ike_sa))) ++ { ++ continue; ++ } ++ + current_peer = entry->ike_sa->get_peer_cfg(entry->ike_sa); + if (current_peer && current_peer->equals(current_peer, peer_cfg)) + { +@@ -1592,6 +1634,10 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*, + { + ike_sa->set_peer_cfg(ike_sa, peer_cfg); + checkout_new(this, ike_sa); ++ if (my_host || other_host) ++ { ++ ike_sa->update_hosts(ike_sa, my_host, other_host, TRUE); ++ } + } + } + charon->bus->set_sa(charon->bus, ike_sa); +diff --git a/src/libcharon/sa/ike_sa_manager.h b/src/libcharon/sa/ike_sa_manager.h +index 004cc22..50f8246 100644 +--- a/src/libcharon/sa/ike_sa_manager.h ++++ b/src/libcharon/sa/ike_sa_manager.h +@@ -123,7 +123,8 @@ struct ike_sa_manager_t { + ike_sa_t* (*checkout_by_message) (ike_sa_manager_t* this, message_t *message); + + /** +- * Checkout an IKE_SA for initiation by a peer_config. ++ * Checkout an IKE_SA for initiation by a peer_config and optional ++ * source and remote host addresses. + * + * To initiate, a CHILD_SA may be established within an existing IKE_SA. + * This call checks for an existing IKE_SA by comparing the configuration. +@@ -136,9 +137,12 @@ struct ike_sa_manager_t { + * @note The peer_config is always set on the returned IKE_SA. + * + * @param peer_cfg configuration used to find an existing IKE_SA ++ * @param my_host source host address for wildcard peer_cfg ++ * @param other_host remote host address for wildcard peer_cfg + * @return checked out/created IKE_SA + */ +- ike_sa_t *(*checkout_by_config)(ike_sa_manager_t* this, peer_cfg_t *peer_cfg); ++ ike_sa_t *(*checkout_by_config)(ike_sa_manager_t* this, peer_cfg_t *peer_cfg, ++ host_t *my_host, host_t *other_host); + + /** + * Reset initiator SPI. +diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c +index d8d8a42..e7c906e 100644 +--- a/src/libcharon/sa/trap_manager.c ++++ b/src/libcharon/sa/trap_manager.c +@@ -523,7 +523,7 @@ METHOD(trap_manager_t, acquire, void, + peer_cfg_t *peer; + child_cfg_t *child; + ike_sa_t *ike_sa; +- host_t *host; ++ host_t *host, *my_host = NULL, *other_host = NULL; + bool wildcard, ignore = FALSE; + + this->lock->read_lock(this->lock); +@@ -600,37 +600,27 @@ METHOD(trap_manager_t, acquire, void, + this->lock->unlock(this->lock); + + if (wildcard) +- { /* the peer config would match IKE_SAs with other peers */ +- ike_sa = charon->ike_sa_manager->create_new(charon->ike_sa_manager, +- peer->get_ike_version(peer), TRUE); +- if (ike_sa) +- { +- ike_cfg_t *ike_cfg; +- uint16_t port; +- uint8_t mask; +- +- ike_sa->set_peer_cfg(ike_sa, peer); +- ike_cfg = ike_sa->get_ike_cfg(ike_sa); +- +- port = ike_cfg->get_other_port(ike_cfg); +- data->dst->to_subnet(data->dst, &host, &mask); +- host->set_port(host, port); +- ike_sa->set_other_host(ike_sa, host); +- +- port = ike_cfg->get_my_port(ike_cfg); +- data->src->to_subnet(data->src, &host, &mask); +- host->set_port(host, port); +- ike_sa->set_my_host(ike_sa, host); +- +- charon->bus->set_sa(charon->bus, ike_sa); +- } +- } +- else + { +- ike_sa = charon->ike_sa_manager->checkout_by_config( +- charon->ike_sa_manager, peer); ++ ike_cfg_t *ike_cfg; ++ uint16_t port; ++ uint8_t mask; ++ ++ ike_cfg = peer->get_ike_cfg(peer); ++ ++ port = ike_cfg->get_other_port(ike_cfg); ++ data->dst->to_subnet(data->dst, &other_host, &mask); ++ other_host->set_port(other_host, port); ++ ++ port = ike_cfg->get_my_port(ike_cfg); ++ data->src->to_subnet(data->src, &my_host, &mask); ++ my_host->set_port(my_host, port); + } ++ ike_sa = charon->ike_sa_manager->checkout_by_config( ++ charon->ike_sa_manager, peer, ++ my_host, other_host); + peer->destroy(peer); ++ DESTROY_IF(my_host); ++ DESTROY_IF(other_host); + + if (ike_sa) + { +diff --git a/src/swanctl/commands/initiate.c b/src/swanctl/commands/initiate.c +index e0fffb9..dcaded5 100644 +--- a/src/swanctl/commands/initiate.c ++++ b/src/swanctl/commands/initiate.c +@@ -14,6 +14,28 @@ + * for more details. + */ + ++/* ++ * Copyright (C) 2014 Timo Teräs <timo.teras@iki.fi> ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ + #include "command.h" + + #include <errno.h> +@@ -38,7 +60,7 @@ static int initiate(vici_conn_t *conn) + vici_req_t *req; + vici_res_t *res; + command_format_options_t format = COMMAND_FORMAT_NONE; +- char *arg, *child = NULL, *ike = NULL; ++ char *arg, *child = NULL, *ike = NULL, *my_host = NULL, *other_host = NULL; + int ret = 0, timeout = 0, level = 1; + + while (TRUE) +@@ -65,6 +87,12 @@ static int initiate(vici_conn_t *conn) + case 'l': + level = atoi(arg); + continue; ++ case 'S': ++ my_host = arg; ++ continue; ++ case 'R': ++ other_host = arg; ++ continue; + case EOF: + break; + default: +@@ -88,6 +116,14 @@ static int initiate(vici_conn_t *conn) + { + vici_add_key_valuef(req, "ike", "%s", ike); + } ++ if (my_host) ++ { ++ vici_add_key_valuef(req, "my-host", "%s", my_host); ++ } ++ if (other_host) ++ { ++ vici_add_key_valuef(req, "other-host", "%s", other_host); ++ } + if (timeout) + { + vici_add_key_valuef(req, "timeout", "%d", timeout * 1000); +@@ -134,6 +170,8 @@ static void __attribute__ ((constructor))reg() + {"help", 'h', 0, "show usage information"}, + {"child", 'c', 1, "initiate a CHILD_SA configuration"}, + {"ike", 'i', 1, "initiate an IKE_SA, or name of child's parent"}, ++ {"source", 'S', 1, "override source address"}, ++ {"remote", 'R', 1, "override remote address"}, + {"timeout", 't', 1, "timeout in seconds before detaching"}, + {"raw", 'r', 0, "dump raw response message"}, + {"pretty", 'P', 0, "dump raw response message in pretty print"}, diff --git a/scripts/package-build/strongswan/patches/0002-vici-send-certificates-for-ike-sa-events.patch b/scripts/package-build/strongswan/patches/0002-vici-send-certificates-for-ike-sa-events.patch new file mode 100644 index 00000000..13e657e9 --- /dev/null +++ b/scripts/package-build/strongswan/patches/0002-vici-send-certificates-for-ike-sa-events.patch @@ -0,0 +1,140 @@ +From 39d537b875e907c63a54d5de8ba6d2ea0ede4604 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> +Date: Mon, 21 Sep 2015 13:42:05 +0300 +Subject: [PATCH 2/3] vici: send certificates for ike-sa events +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Timo Teräs <timo.teras@iki.fi> +--- + src/libcharon/plugins/vici/vici_query.c | 50 +++++++++++++++++++++---- + 1 file changed, 42 insertions(+), 8 deletions(-) + +diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c +index bacb7b101..19acc0789 100644 +--- a/src/libcharon/plugins/vici/vici_query.c ++++ b/src/libcharon/plugins/vici/vici_query.c +@@ -402,7 +402,7 @@ static void list_vips(private_vici_query_t *this, vici_builder_t *b, + * List details of an IKE_SA + */ + static void list_ike(private_vici_query_t *this, vici_builder_t *b, +- ike_sa_t *ike_sa, time_t now) ++ ike_sa_t *ike_sa, time_t now, bool add_certs) + { + time_t t; + ike_sa_id_t *id; +@@ -411,6 +411,8 @@ static void list_ike(private_vici_query_t *this, vici_builder_t *b, + uint32_t if_id; + uint16_t alg, ks; + host_t *host; ++ auth_cfg_t *auth_cfg; ++ enumerator_t *enumerator; + + b->add_kv(b, "uniqueid", "%u", ike_sa->get_unique_id(ike_sa)); + b->add_kv(b, "version", "%u", ike_sa->get_version(ike_sa)); +@@ -420,11 +422,43 @@ static void list_ike(private_vici_query_t *this, vici_builder_t *b, + b->add_kv(b, "local-host", "%H", host); + b->add_kv(b, "local-port", "%d", host->get_port(host)); + b->add_kv(b, "local-id", "%Y", ike_sa->get_my_id(ike_sa)); ++ if (add_certs) ++ { ++ enumerator = ike_sa->create_auth_cfg_enumerator(ike_sa, TRUE); ++ if (enumerator->enumerate(enumerator, &auth_cfg)) ++ { ++ certificate_t *cert = auth_cfg->get(auth_cfg, AUTH_RULE_SUBJECT_CERT); ++ chunk_t encoding; ++ ++ if (cert && cert->get_encoding(cert, CERT_ASN1_DER, &encoding)) ++ { ++ b->add(b, VICI_KEY_VALUE, "local-cert-data", encoding); ++ free(encoding.ptr); ++ } ++ } ++ enumerator->destroy(enumerator); ++ } + + host = ike_sa->get_other_host(ike_sa); + b->add_kv(b, "remote-host", "%H", host); + b->add_kv(b, "remote-port", "%d", host->get_port(host)); + b->add_kv(b, "remote-id", "%Y", ike_sa->get_other_id(ike_sa)); ++ if (add_certs) ++ { ++ enumerator = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE); ++ if (enumerator->enumerate(enumerator, &auth_cfg)) ++ { ++ certificate_t *cert = auth_cfg->get(auth_cfg, AUTH_RULE_SUBJECT_CERT); ++ chunk_t encoding; ++ ++ if (cert && cert->get_encoding(cert, CERT_ASN1_DER, &encoding)) ++ { ++ b->add(b, VICI_KEY_VALUE, "remote-cert-data", encoding); ++ free(encoding.ptr); ++ } ++ } ++ enumerator->destroy(enumerator); ++ } + + eap = ike_sa->get_other_eap_id(ike_sa); + +@@ -556,7 +590,7 @@ CALLBACK(list_sas, vici_message_t*, + b = vici_builder_create(); + b->begin_section(b, ike_sa->get_name(ike_sa)); + +- list_ike(this, b, ike_sa, now); ++ list_ike(this, b, ike_sa, now, TRUE); + + b->begin_section(b, "child-sas"); + csas = ike_sa->create_child_sa_enumerator(ike_sa); +@@ -1774,7 +1808,7 @@ METHOD(listener_t, ike_updown, bool, + } + + b->begin_section(b, ike_sa->get_name(ike_sa)); +- list_ike(this, b, ike_sa, now); ++ list_ike(this, b, ike_sa, now, up); + b->end_section(b); + + this->dispatcher->raise_event(this->dispatcher, +@@ -1799,10 +1833,10 @@ METHOD(listener_t, ike_rekey, bool, + b = vici_builder_create(); + b->begin_section(b, old->get_name(old)); + b->begin_section(b, "old"); +- list_ike(this, b, old, now); ++ list_ike(this, b, old, now, TRUE); + b->end_section(b); + b->begin_section(b, "new"); +- list_ike(this, b, new, now); ++ list_ike(this, b, new, now, TRUE); + b->end_section(b); + b->end_section(b); + +@@ -1833,7 +1867,7 @@ METHOD(listener_t, ike_update, bool, + b->add_kv(b, "remote-port", "%d", remote->get_port(remote)); + + b->begin_section(b, ike_sa->get_name(ike_sa)); +- list_ike(this, b, ike_sa, now); ++ list_ike(this, b, ike_sa, now, TRUE); + b->end_section(b); + + this->dispatcher->raise_event(this->dispatcher, +@@ -1863,7 +1897,7 @@ METHOD(listener_t, child_updown, bool, + } + + b->begin_section(b, ike_sa->get_name(ike_sa)); +- list_ike(this, b, ike_sa, now); ++ list_ike(this, b, ike_sa, now, up); + b->begin_section(b, "child-sas"); + + snprintf(buf, sizeof(buf), "%s-%u", child_sa->get_name(child_sa), +@@ -1898,7 +1932,7 @@ METHOD(listener_t, child_rekey, bool, + b = vici_builder_create(); + + b->begin_section(b, ike_sa->get_name(ike_sa)); +- list_ike(this, b, ike_sa, now); ++ list_ike(this, b, ike_sa, now, TRUE); + b->begin_section(b, "child-sas"); + + b->begin_section(b, old->get_name(old)); +-- +2.38.1 + diff --git a/scripts/package-build/strongswan/patches/0003-vici-add-support-for-individual-sa-state-changes.patch b/scripts/package-build/strongswan/patches/0003-vici-add-support-for-individual-sa-state-changes.patch new file mode 100644 index 00000000..45aadc72 --- /dev/null +++ b/scripts/package-build/strongswan/patches/0003-vici-add-support-for-individual-sa-state-changes.patch @@ -0,0 +1,159 @@ +From df6b501ed29b838efde0f1cb1c906ab9befc7b45 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> +Date: Mon, 21 Sep 2015 13:42:11 +0300 +Subject: [PATCH 3/3] vici: add support for individual sa state changes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Useful for monitoring and tracking full SA. + +Signed-off-by: Timo Teräs <timo.teras@iki.fi> +--- + src/libcharon/plugins/vici/vici_query.c | 105 ++++++++++++++++++++++++ + 1 file changed, 105 insertions(+) + +diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c +index 19acc0789..e008885f7 100644 +--- a/src/libcharon/plugins/vici/vici_query.c ++++ b/src/libcharon/plugins/vici/vici_query.c +@@ -1774,8 +1774,16 @@ static void manage_commands(private_vici_query_t *this, bool reg) + this->dispatcher->manage_event(this->dispatcher, "ike-updown", reg); + this->dispatcher->manage_event(this->dispatcher, "ike-rekey", reg); + this->dispatcher->manage_event(this->dispatcher, "ike-update", reg); ++ this->dispatcher->manage_event(this->dispatcher, "ike-state-established", reg); ++ this->dispatcher->manage_event(this->dispatcher, "ike-state-destroying", reg); + this->dispatcher->manage_event(this->dispatcher, "child-updown", reg); + this->dispatcher->manage_event(this->dispatcher, "child-rekey", reg); ++ this->dispatcher->manage_event(this->dispatcher, "child-state-installing", reg); ++ this->dispatcher->manage_event(this->dispatcher, "child-state-installed", reg); ++ this->dispatcher->manage_event(this->dispatcher, "child-state-updating", reg); ++ this->dispatcher->manage_event(this->dispatcher, "child-state-rekeying", reg); ++ this->dispatcher->manage_event(this->dispatcher, "child-state-rekeyed", reg); ++ this->dispatcher->manage_event(this->dispatcher, "child-state-destroying", reg); + manage_command(this, "list-sas", list_sas, reg); + manage_command(this, "list-policies", list_policies, reg); + manage_command(this, "list-conns", list_conns, reg); +@@ -1876,6 +1884,45 @@ METHOD(listener_t, ike_update, bool, + return TRUE; + } + ++METHOD(listener_t, ike_state_change, bool, ++ private_vici_query_t *this, ike_sa_t *ike_sa, ike_sa_state_t state) ++{ ++ char *event; ++ vici_builder_t *b; ++ time_t now; ++ ++ switch (state) ++ { ++ case IKE_ESTABLISHED: ++ event = "ike-state-established"; ++ break; ++ case IKE_DESTROYING: ++ event = "ike-state-destroying"; ++ break; ++ default: ++ return TRUE; ++ } ++ ++ if (!this->dispatcher->has_event_listeners(this->dispatcher, event)) ++ { ++ return TRUE; ++ } ++ ++ now = time_monotonic(NULL); ++ ++ b = vici_builder_create(); ++ b->begin_section(b, ike_sa->get_name(ike_sa)); ++ list_ike(this, b, ike_sa, now, state != IKE_DESTROYING); ++ b->begin_section(b, "child-sas"); ++ b->end_section(b); ++ b->end_section(b); ++ ++ this->dispatcher->raise_event(this->dispatcher, ++ event, 0, b->finalize(b)); ++ ++ return TRUE; ++} ++ + METHOD(listener_t, child_updown, bool, + private_vici_query_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, bool up) + { +@@ -1955,6 +2002,62 @@ METHOD(listener_t, child_rekey, bool, + return TRUE; + } + ++METHOD(listener_t, child_state_change, bool, ++ private_vici_query_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, child_sa_state_t state) ++{ ++ char *event; ++ vici_builder_t *b; ++ time_t now; ++ ++ switch (state) ++ { ++ case CHILD_INSTALLING: ++ event = "child-state-installing"; ++ break; ++ case CHILD_INSTALLED: ++ event = "child-state-installed"; ++ break; ++ case CHILD_UPDATING: ++ event = "child-state-updating"; ++ break; ++ case CHILD_REKEYING: ++ event = "child-state-rekeying"; ++ break; ++ case CHILD_REKEYED: ++ event = "child-state-rekeyed"; ++ break; ++ case CHILD_DESTROYING: ++ event = "child-state-destroying"; ++ break; ++ default: ++ return TRUE; ++ } ++ ++ if (!this->dispatcher->has_event_listeners(this->dispatcher, event)) ++ { ++ return TRUE; ++ } ++ ++ now = time_monotonic(NULL); ++ ++ b = vici_builder_create(); ++ b->begin_section(b, ike_sa->get_name(ike_sa)); ++ list_ike(this, b, ike_sa, now, state != CHILD_DESTROYING); ++ b->begin_section(b, "child-sas"); ++ ++ b->begin_section(b, child_sa->get_name(child_sa)); ++ list_child(this, b, child_sa, now); ++ b->end_section(b); ++ ++ b->end_section(b); ++ b->end_section(b); ++ ++ this->dispatcher->raise_event(this->dispatcher, ++ event, 0, b->finalize(b)); ++ ++ return TRUE; ++} ++ + METHOD(vici_query_t, destroy, void, + private_vici_query_t *this) + { +@@ -1975,8 +2078,10 @@ vici_query_t *vici_query_create(vici_dispatcher_t *dispatcher) + .ike_updown = _ike_updown, + .ike_rekey = _ike_rekey, + .ike_update = _ike_update, ++ .ike_state_change = _ike_state_change, + .child_updown = _child_updown, + .child_rekey = _child_rekey, ++ .child_state_change = _child_state_change, + }, + .destroy = _destroy, + }, +-- +2.38.1 + 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/0004-VyOS-disable-options-enabled-by-Debian-that-are-unus.patch new file mode 100644 index 00000000..57a622e8 --- /dev/null +++ b/scripts/package-build/strongswan/patches/0004-VyOS-disable-options-enabled-by-Debian-that-are-unus.patch @@ -0,0 +1,115 @@ +From ee6c0b3ff6e3df5c7aef628621e19a813ff308ed Mon Sep 17 00:00:00 2001 +From: Christian Poessinger <christian@poessinger.com> +Date: Tue, 27 Dec 2022 13:36:43 +0000 +Subject: [PATCH] VyOS: disable options enabled by Debian that are unused + +VyOS does not implement CLI options for all options exposed by Debian. + +The following options need to be disabled for the DMVPN patchset: + - mediation + - nm + +In addition we have no LED, LDAP and SQL configuration knows, thus we spare +the plugins. +--- + debian/libcharon-extra-plugins.install | 3 --- + debian/libstrongswan-extra-plugins.install | 3 --- + debian/rules | 11 ++++++++++- + debian/strongswan-nm.install | 2 -- + 4 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/debian/libcharon-extra-plugins.install b/debian/libcharon-extra-plugins.install +index 94fbabd88..068708ecb 100644 +--- a/debian/libcharon-extra-plugins.install ++++ b/debian/libcharon-extra-plugins.install +@@ -13,7 +13,6 @@ usr/lib/ipsec/plugins/libstrongswan-error-notify.so + usr/lib/ipsec/plugins/libstrongswan-forecast.so + usr/lib/ipsec/plugins/libstrongswan-ha.so + usr/lib/ipsec/plugins/libstrongswan-kernel-libipsec.so +-usr/lib/ipsec/plugins/libstrongswan-led.so + usr/lib/ipsec/plugins/libstrongswan-lookip.so + #usr/lib/ipsec/plugins/libstrongswan-medsrv.so + #usr/lib/ipsec/plugins/libstrongswan-medcli.so +@@ -36,7 +35,6 @@ usr/share/strongswan/templates/config/plugins/error-notify.conf + usr/share/strongswan/templates/config/plugins/forecast.conf + usr/share/strongswan/templates/config/plugins/ha.conf + usr/share/strongswan/templates/config/plugins/kernel-libipsec.conf +-usr/share/strongswan/templates/config/plugins/led.conf + usr/share/strongswan/templates/config/plugins/lookip.conf + #usr/share/strongswan/templates/config/plugins/medsrv.conf + #usr/share/strongswan/templates/config/plugins/medcli.conf +@@ -60,7 +58,6 @@ etc/strongswan.d/charon/error-notify.conf + etc/strongswan.d/charon/forecast.conf + etc/strongswan.d/charon/ha.conf + etc/strongswan.d/charon/kernel-libipsec.conf +-etc/strongswan.d/charon/led.conf + etc/strongswan.d/charon/lookip.conf + #etc/strongswan.d/charon/medsrv.conf + #etc/strongswan.d/charon/medcli.conf +diff --git a/debian/libstrongswan-extra-plugins.install b/debian/libstrongswan-extra-plugins.install +index 2846e2155..00cd0a146 100644 +--- a/debian/libstrongswan-extra-plugins.install ++++ b/debian/libstrongswan-extra-plugins.install +@@ -8,7 +8,6 @@ usr/lib/ipsec/plugins/libstrongswan-ctr.so + usr/lib/ipsec/plugins/libstrongswan-curl.so + usr/lib/ipsec/plugins/libstrongswan-curve25519.so + usr/lib/ipsec/plugins/libstrongswan-gcrypt.so +-usr/lib/ipsec/plugins/libstrongswan-ldap.so + usr/lib/ipsec/plugins/libstrongswan-pkcs11.so + usr/lib/ipsec/plugins/libstrongswan-test-vectors.so + usr/lib/ipsec/plugins/libstrongswan-tpm.so +@@ -20,7 +19,6 @@ usr/share/strongswan/templates/config/plugins/ctr.conf + usr/share/strongswan/templates/config/plugins/curl.conf + usr/share/strongswan/templates/config/plugins/curve25519.conf + usr/share/strongswan/templates/config/plugins/gcrypt.conf +-usr/share/strongswan/templates/config/plugins/ldap.conf + usr/share/strongswan/templates/config/plugins/pkcs11.conf + usr/share/strongswan/templates/config/plugins/test-vectors.conf + usr/share/strongswan/templates/config/plugins/tpm.conf +@@ -31,7 +29,6 @@ etc/strongswan.d/charon/ctr.conf + etc/strongswan.d/charon/curl.conf + etc/strongswan.d/charon/curve25519.conf + etc/strongswan.d/charon/gcrypt.conf +-etc/strongswan.d/charon/ldap.conf + etc/strongswan.d/charon/pkcs11.conf + etc/strongswan.d/charon/test-vectors.conf + etc/strongswan.d/charon/tpm.conf +diff --git a/debian/rules b/debian/rules +index 2fed1f10f..fa0d21a0c 100755 +--- a/debian/rules ++++ b/debian/rules +@@ -3,6 +3,15 @@ export DEB_LDFLAGS_MAINT_APPEND=-Wl,-O1 + #export DEB_LDFLAGS_MAINT_APPEND=-Wl,--as-needed -Wl,-O1 -Wl,-z,defs + export DEB_BUILD_MAINT_OPTIONS=hardening=+all + ++CONFIGUREARGS_VYOS := --disable-warnings \ ++ --disable-ldap \ ++ --disable-led \ ++ --disable-nm \ ++ --disable-mediation \ ++ --disable-mysql \ ++ --disable-sqlite \ ++ --disable-sql ++ + CONFIGUREARGS := --libdir=/usr/lib --libexecdir=/usr/lib \ + --enable-addrblock \ + --enable-agent \ +@@ -88,7 +97,7 @@ ifeq ($(DEB_HOST_ARCH_OS),kfreebsd) + deb_systemdsystemunitdir = $(shell pkg-config --variable=systemdsystemunitdir systemd | sed s,^/,,) + + override_dh_auto_configure: +- dh_auto_configure -- $(CONFIGUREARGS) ++ dh_auto_configure -- $(CONFIGUREARGS) $(CONFIGUREARGS_VYOS) + + override_dh_auto_clean: + dh_auto_clean +diff --git a/debian/strongswan-nm.install b/debian/strongswan-nm.install +index b0c05d94f..e69de29bb 100644 +--- a/debian/strongswan-nm.install ++++ b/debian/strongswan-nm.install +@@ -1,2 +0,0 @@ +-usr/lib/ipsec/charon-nm +-usr/share/dbus-1/system.d/nm-strongswan-service.conf +-- +2.30.2 + diff --git a/scripts/package-build/telegraf/.gitignore b/scripts/package-build/telegraf/.gitignore new file mode 100644 index 00000000..bf2fcf43 --- /dev/null +++ b/scripts/package-build/telegraf/.gitignore @@ -0,0 +1,6 @@ +telegraf/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc diff --git a/scripts/package-build/telegraf/README.md b/scripts/package-build/telegraf/README.md new file mode 100644 index 00000000..63119c0c --- /dev/null +++ b/scripts/package-build/telegraf/README.md @@ -0,0 +1,4 @@ +# build +``` +python3 build.py +``` diff --git a/scripts/package-build/telegraf/build.py b/scripts/package-build/telegraf/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/telegraf/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/telegraf/build.sh b/scripts/package-build/telegraf/build.sh new file mode 100755 index 00000000..2ba511d0 --- /dev/null +++ b/scripts/package-build/telegraf/build.sh @@ -0,0 +1,27 @@ +#!/bin/sh +CWD=$(pwd) +set -e + +BUILD_ARCH=$(dpkg-architecture -qDEB_TARGET_ARCH) + +SRC=telegraf +if [ ! -d ${SRC} ]; then + echo "Source directory does not exists, please 'git clone'" + exit 1 +fi + +PLUGIN_DIR=${CWD}/plugins + +echo "I: Selecting Input plugins" +cp ${PLUGIN_DIR}/inputs/all/all.go ${SRC}/plugins/inputs/all/all.go + +echo "I: Selecting Output plugins" +cp ${PLUGIN_DIR}/outputs/all/all.go ${SRC}/plugins/outputs/all/all.go + +echo "I: Build Debian ${BUILD_ARCH} package" +cd ${SRC} +export PATH=/opt/go/bin:$PATH + +# Generate default telegraf config +go run ./cmd/telegraf config > etc/telegraf.conf +LDFLAGS=-w make "${BUILD_ARCH}.deb" diff --git a/scripts/package-build/telegraf/package.toml b/scripts/package-build/telegraf/package.toml new file mode 100644 index 00000000..c255c43d --- /dev/null +++ b/scripts/package-build/telegraf/package.toml @@ -0,0 +1,5 @@ +[[packages]] +name = "telegraf" +commit_id = "v1.28.3" +scm_url = "https://github.com/influxdata/telegraf.git" +build_cmd = "cd ..; ./build.sh; cp telegraf/build/dist/*.deb ." diff --git a/scripts/package-build/telegraf/plugins/inputs/all/all.go b/scripts/package-build/telegraf/plugins/inputs/all/all.go new file mode 100644 index 00000000..8265681b --- /dev/null +++ b/scripts/package-build/telegraf/plugins/inputs/all/all.go @@ -0,0 +1,72 @@ +package all + +import ( + //Blank imports for plugins to register themselves + _ "github.com/influxdata/telegraf/plugins/inputs/azure_storage_queue" + _ "github.com/influxdata/telegraf/plugins/inputs/bond" + _ "github.com/influxdata/telegraf/plugins/inputs/cgroup" + _ "github.com/influxdata/telegraf/plugins/inputs/chrony" + _ "github.com/influxdata/telegraf/plugins/inputs/conntrack" + _ "github.com/influxdata/telegraf/plugins/inputs/cpu" + _ "github.com/influxdata/telegraf/plugins/inputs/disk" + _ "github.com/influxdata/telegraf/plugins/inputs/diskio" + _ "github.com/influxdata/telegraf/plugins/inputs/disque" + _ "github.com/influxdata/telegraf/plugins/inputs/dmcache" + _ "github.com/influxdata/telegraf/plugins/inputs/dns_query" + _ "github.com/influxdata/telegraf/plugins/inputs/docker" + _ "github.com/influxdata/telegraf/plugins/inputs/docker_log" + _ "github.com/influxdata/telegraf/plugins/inputs/ethtool" + _ "github.com/influxdata/telegraf/plugins/inputs/exec" + _ "github.com/influxdata/telegraf/plugins/inputs/execd" + _ "github.com/influxdata/telegraf/plugins/inputs/file" + _ "github.com/influxdata/telegraf/plugins/inputs/filecount" + _ "github.com/influxdata/telegraf/plugins/inputs/filestat" + _ "github.com/influxdata/telegraf/plugins/inputs/fireboard" + _ "github.com/influxdata/telegraf/plugins/inputs/hddtemp" + _ "github.com/influxdata/telegraf/plugins/inputs/hugepages" + _ "github.com/influxdata/telegraf/plugins/inputs/influxdb" + _ "github.com/influxdata/telegraf/plugins/inputs/influxdb_listener" + _ "github.com/influxdata/telegraf/plugins/inputs/influxdb_v2_listener" + _ "github.com/influxdata/telegraf/plugins/inputs/intel_pmu" + _ "github.com/influxdata/telegraf/plugins/inputs/intel_powerstat" + _ "github.com/influxdata/telegraf/plugins/inputs/intel_rdt" + _ "github.com/influxdata/telegraf/plugins/inputs/internal" + _ "github.com/influxdata/telegraf/plugins/inputs/internet_speed" + _ "github.com/influxdata/telegraf/plugins/inputs/interrupts" + _ "github.com/influxdata/telegraf/plugins/inputs/ipmi_sensor" + _ "github.com/influxdata/telegraf/plugins/inputs/ipset" + _ "github.com/influxdata/telegraf/plugins/inputs/iptables" + _ "github.com/influxdata/telegraf/plugins/inputs/ipvs" + _ "github.com/influxdata/telegraf/plugins/inputs/kernel" + _ "github.com/influxdata/telegraf/plugins/inputs/kernel_vmstat" + _ "github.com/influxdata/telegraf/plugins/inputs/mdstat" + _ "github.com/influxdata/telegraf/plugins/inputs/mem" + _ "github.com/influxdata/telegraf/plugins/inputs/net" + _ "github.com/influxdata/telegraf/plugins/inputs/netstat" + _ "github.com/influxdata/telegraf/plugins/inputs/nstat" + _ "github.com/influxdata/telegraf/plugins/inputs/ping" + _ "github.com/influxdata/telegraf/plugins/inputs/powerdns_recursor" + _ "github.com/influxdata/telegraf/plugins/inputs/processes" + _ "github.com/influxdata/telegraf/plugins/inputs/procstat" + _ "github.com/influxdata/telegraf/plugins/inputs/sensors" + _ "github.com/influxdata/telegraf/plugins/inputs/sflow" + _ "github.com/influxdata/telegraf/plugins/inputs/slab" + _ "github.com/influxdata/telegraf/plugins/inputs/smart" + _ "github.com/influxdata/telegraf/plugins/inputs/snmp" + _ "github.com/influxdata/telegraf/plugins/inputs/snmp_legacy" + _ "github.com/influxdata/telegraf/plugins/inputs/snmp_trap" + _ "github.com/influxdata/telegraf/plugins/inputs/socket_listener" + _ "github.com/influxdata/telegraf/plugins/inputs/socketstat" + _ "github.com/influxdata/telegraf/plugins/inputs/syslog" + _ "github.com/influxdata/telegraf/plugins/inputs/sysstat" + _ "github.com/influxdata/telegraf/plugins/inputs/system" + _ "github.com/influxdata/telegraf/plugins/inputs/systemd_units" + _ "github.com/influxdata/telegraf/plugins/inputs/tail" + _ "github.com/influxdata/telegraf/plugins/inputs/tcp_listener" + _ "github.com/influxdata/telegraf/plugins/inputs/temp" + _ "github.com/influxdata/telegraf/plugins/inputs/twemproxy" + _ "github.com/influxdata/telegraf/plugins/inputs/udp_listener" + _ "github.com/influxdata/telegraf/plugins/inputs/wireguard" + _ "github.com/influxdata/telegraf/plugins/inputs/wireless" + _ "github.com/influxdata/telegraf/plugins/inputs/x509_cert" +) diff --git a/scripts/package-build/telegraf/plugins/outputs/all/all.go b/scripts/package-build/telegraf/plugins/outputs/all/all.go new file mode 100644 index 00000000..49f7e63d --- /dev/null +++ b/scripts/package-build/telegraf/plugins/outputs/all/all.go @@ -0,0 +1,9 @@ +package all + +import ( + //Blank imports for plugins to register themselves + _ "github.com/influxdata/telegraf/plugins/outputs/azure_data_explorer" + _ "github.com/influxdata/telegraf/plugins/outputs/http" + _ "github.com/influxdata/telegraf/plugins/outputs/influxdb_v2" + _ "github.com/influxdata/telegraf/plugins/outputs/prometheus_client" +) diff --git a/scripts/package-build/waagent/.gitignore b/scripts/package-build/waagent/.gitignore new file mode 100644 index 00000000..80401271 --- /dev/null +++ b/scripts/package-build/waagent/.gitignore @@ -0,0 +1,8 @@ +waagent/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc +*.tar.gz +*.tar.xz diff --git a/scripts/package-build/waagent/build.py b/scripts/package-build/waagent/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/waagent/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/waagent/package.toml b/scripts/package-build/waagent/package.toml new file mode 100644 index 00000000..d7343a7a --- /dev/null +++ b/scripts/package-build/waagent/package.toml @@ -0,0 +1,7 @@ +[[packages]] +name = "waagent" +commit_id = "debian/2.9.1.1-2" +scm_url = "https://salsa.debian.org/cloud-team/waagent.git" + +[packages.dependencies] +packages = ["dpkg-source-gitarchive"] diff --git a/scripts/package-build/wide-dhcpv6/.gitignore b/scripts/package-build/wide-dhcpv6/.gitignore new file mode 100644 index 00000000..990f3c6c --- /dev/null +++ b/scripts/package-build/wide-dhcpv6/.gitignore @@ -0,0 +1,7 @@ +wide-dhcpv6/ +*.buildinfo +*.build +*.changes +*.deb +*.dsc +*.udeb diff --git a/scripts/package-build/wide-dhcpv6/build.py b/scripts/package-build/wide-dhcpv6/build.py new file mode 120000 index 00000000..3c76af73 --- /dev/null +++ b/scripts/package-build/wide-dhcpv6/build.py @@ -0,0 +1 @@ +../build.py
\ No newline at end of file diff --git a/scripts/package-build/wide-dhcpv6/package.toml b/scripts/package-build/wide-dhcpv6/package.toml new file mode 100644 index 00000000..77d6239b --- /dev/null +++ b/scripts/package-build/wide-dhcpv6/package.toml @@ -0,0 +1,4 @@ +[[packages]] +name = "wide-dhcpv6" +commit_id = "debian/20080615-23" +scm_url = "https://salsa.debian.org/debian/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/0023-dhcpc6-support-per-interface-client-DUIDs.patch new file mode 100644 index 00000000..c1e71f0c --- /dev/null +++ b/scripts/package-build/wide-dhcpv6/patches/0023-dhcpc6-support-per-interface-client-DUIDs.patch @@ -0,0 +1,230 @@ +From 1e4a9a7b61090043924f2aa9359dcbc9f5e11bfc Mon Sep 17 00:00:00 2001 +From: Brandon Stepler <brandon@stepler.net> +Date: Mon, 25 Jan 2021 14:18:57 +0000 +Subject: [PATCH] dhcpc6: support per-interface client DUIDs + +--- + cfparse.y | 13 +++++++++++-- + cftoken.l | 10 ++++++++++ + config.c | 27 +++++++++++++++++++++++++++ + config.h | 3 ++- + dhcp6c.c | 11 ++++++++--- + dhcp6c.conf.5 | 6 ++++++ + 6 files changed, 64 insertions(+), 6 deletions(-) + +diff --git a/cfparse.y b/cfparse.y +index 9e685f4..244987c 100644 +--- a/cfparse.y ++++ b/cfparse.y +@@ -116,6 +116,7 @@ static void cleanup_cflist __P((struct cf_list *)); + %token BCMCS_SERVERS BCMCS_NAME + %token INFO_ONLY + %token SCRIPT DELAYEDKEY ++%token CLIENT_ID CLIENT_ID_DUID + %token AUTHENTICATION PROTOCOL ALGORITHM DELAYED RECONFIG HMACMD5 MONOCOUNTER + %token AUTHNAME RDM KEY + %token KEYINFO REALM KEYID SECRET KEYNAME EXPIRE +@@ -134,8 +135,8 @@ static void cleanup_cflist __P((struct cf_list *)); + struct dhcp6_poolspec *pool; + } + +-%type <str> IFNAME HOSTNAME AUTHNAME KEYNAME DUID_ID STRING QSTRING IAID +-%type <str> POOLNAME PROFILENAME ++%type <str> IFNAME HOSTNAME CLIENT_ID_DUID AUTHNAME KEYNAME DUID_ID ++%type <str> STRING QSTRING IAID POOLNAME PROFILENAME + %type <num> NUMBER duration authproto authalg authrdm + %type <list> declaration declarations dhcpoption ifparam ifparams + %type <list> address_list address_list_ent dhcpoption_list +@@ -639,6 +640,14 @@ dhcpoption: + /* no value */ + $$ = l; + } ++ | CLIENT_ID CLIENT_ID_DUID ++ { ++ struct cf_list *l; ++ ++ MAKE_CFLIST(l, DHCPOPT_CLIENT_ID, NULL, NULL); ++ l->ptr = $2; ++ $$ = l; ++ } + | AUTHENTICATION AUTHNAME + { + struct cf_list *l; +diff --git a/cftoken.l b/cftoken.l +index e266ac2..d7edd1f 100644 +--- a/cftoken.l ++++ b/cftoken.l +@@ -119,6 +119,7 @@ ecl \} + %s S_HOST + %s S_DUID + %s S_IA ++%s S_CID + %s S_AUTH + %s S_KEY + %s S_SECRET +@@ -249,6 +250,15 @@ ecl \} + /* duration */ + <S_CNF>infinity { DECHO; return (INFINITY); } + ++ /* client-id option */ ++<S_CNF>client-id { DECHO; BEGIN S_CID; return (CLIENT_ID); } ++<S_CID>{duid} { ++ DECHO; ++ yylval.str = strdup(yytext); ++ BEGIN S_CNF; ++ return (CLIENT_ID_DUID); ++} ++ + /* authentication option */ + <S_CNF>authentication { DECHO; BEGIN S_AUTH; return (AUTHENTICATION); } + <S_AUTH>{string} { +diff --git a/config.c b/config.c +index 70f6287..0cbe631 100644 +--- a/config.c ++++ b/config.c +@@ -100,6 +100,7 @@ struct dhcp6_ifconf { + struct dhcp6_ifconf *next; + + char *ifname; ++ struct duid duid; + + /* configuration flags */ + u_long send_flags; +@@ -1366,6 +1367,7 @@ configure_commit() + /* commit interface configuration */ + for (ifp = dhcp6_if; ifp; ifp = ifp->next) { + /* re-initialization */ ++ duidfree(&ifp->duid); + ifp->send_flags = 0; + ifp->allow_flags = 0; + dhcp6_clear_list(&ifp->reqopt_list); +@@ -1395,6 +1397,8 @@ configure_commit() + } + + /* copy new configuration */ ++ ifp->duid = ifc->duid; ++ ifc->duid.duid_id = NULL; + ifp->send_flags = ifc->send_flags; + ifp->allow_flags = ifc->allow_flags; + dhcp6_copy_list(&ifp->reqopt_list, &ifc->reqopt_list); +@@ -1505,6 +1509,7 @@ clear_ifconf(iflist) + ifc_next = ifc->next; + + free(ifc->ifname); ++ duidfree(&ifc->duid); + dhcp6_clear_list(&ifc->reqopt_list); + + clear_iaconf(&ifc->iaconf_list); +@@ -1635,6 +1640,28 @@ add_options(opcode, ifc, cfl0) + return (-1); + } + break; ++ case DHCPOPT_CLIENT_ID: ++ if (opcode != DHCPOPTCODE_SEND) { ++ debug_printf(LOG_ERR, FNAME, ++ "invalid operation (%d) " ++ "for option type (%d)", ++ opcode, cfl->type); ++ return (-1); ++ } ++ if (ifc->duid.duid_id != NULL) { ++ debug_printf(LOG_ERR, FNAME, "%s:%d " ++ "client-id is doubly specified on %s", ++ configfilename, cfl->line, ifc->ifname); ++ return (-1); ++ } ++ if ((configure_duid((char *)cfl->ptr, ++ &ifc->duid)) != 0) { ++ debug_printf(LOG_ERR, FNAME, "%s:%d " ++ "failed to configure DUID for %s", ++ configfilename, cfl->line, ifc->ifname); ++ return (-1); ++ } ++ break; + case DHCPOPT_AUTHINFO: + if (opcode != DHCPOPTCODE_SEND) { + debug_printf(LOG_ERR, FNAME, +diff --git a/config.h b/config.h +index 36a5aa3..cfcfdd5 100644 +--- a/config.h ++++ b/config.h +@@ -69,6 +69,7 @@ struct dhcp6_if { + u_int32_t linkid; /* to send link-local packets */ + /* multiple global address configuration is not supported now */ + struct in6_addr addr; /* global address */ ++ struct duid duid; + + /* configuration parameters */ + u_long send_flags; +@@ -267,7 +268,7 @@ enum { DECL_SEND, DECL_ALLOW, DECL_INFO_ONLY, DECL_REQUEST, DECL_DUID, + DECL_ADDRESS, + DECL_RANGE, DECL_ADDRESSPOOL, + IFPARAM_SLA_ID, IFPARAM_SLA_LEN, IFPARAM_IFID, IFPARAM_IFID_RAND, +- DHCPOPT_RAPID_COMMIT, DHCPOPT_AUTHINFO, ++ DHCPOPT_RAPID_COMMIT, DHCPOPT_CLIENT_ID, DHCPOPT_AUTHINFO, + DHCPOPT_DNS, DHCPOPT_DNSNAME, + DHCPOPT_IA_PD, DHCPOPT_IA_NA, DHCPOPT_NTP, + DHCPOPT_REFRESHTIME, +diff --git a/dhcp6c.c b/dhcp6c.c +index 849835e..875a147 100644 +--- a/dhcp6c.c ++++ b/dhcp6c.c +@@ -433,6 +433,11 @@ client6_start(ifp) + } + dhcp6_reset_timer(ev); + ++ if (!ifp->duid.duid_id && duidcpy(&ifp->duid, &client_duid)) { ++ debug_printf(LOG_ERR, FNAME, "failed to copy client DUID"); ++ return (-1); ++ } ++ + return (0); + } + +@@ -1249,7 +1254,7 @@ client6_send(ev) + } + + /* client ID */ +- if (duidcpy(&optinfo.clientID, &client_duid)) { ++ if (duidcpy(&optinfo.clientID, &ifp->duid)) { + debug_printf(LOG_ERR, FNAME, "failed to copy client ID"); + goto end; + } +@@ -1533,7 +1538,7 @@ client6_recvadvert(ifp, dh6, len, optinfo) + debug_printf(LOG_INFO, FNAME, "no client ID option"); + return (-1); + } +- if (duidcmp(&optinfo->clientID, &client_duid)) { ++ if (duidcmp(&optinfo->clientID, &ifp->duid)) { + debug_printf(LOG_INFO, FNAME, "client DUID mismatch"); + return (-1); + } +@@ -1805,7 +1810,7 @@ client6_recvreply(ifp, dh6, len, optinfo) + debug_printf(LOG_INFO, FNAME, "no client ID option"); + return (-1); + } +- if (duidcmp(&optinfo->clientID, &client_duid)) { ++ if (duidcmp(&optinfo->clientID, &ifp->duid)) { + debug_printf(LOG_INFO, FNAME, "client DUID mismatch"); + return (-1); + } +diff --git a/dhcp6c.conf.5 b/dhcp6c.conf.5 +index 5693fb8..589510a 100644 +--- a/dhcp6c.conf.5 ++++ b/dhcp6c.conf.5 +@@ -139,6 +139,12 @@ An + statement for + .Ar authname + must be provided. ++.It Ic client-id Ar ID ++means the client's DHCP unique identifier ++.Pq DUID . ++.Ar ID ++is a colon-separated hexadecimal sequence where each separated part ++must be composed of two hexadecimal values. + .El + .\" + .Sh Interface statement +-- +2.20.1 + diff --git a/scripts/package-build/wide-dhcpv6/patches/0024-bind-to-single-socket.patch b/scripts/package-build/wide-dhcpv6/patches/0024-bind-to-single-socket.patch new file mode 100644 index 00000000..b5751325 --- /dev/null +++ b/scripts/package-build/wide-dhcpv6/patches/0024-bind-to-single-socket.patch @@ -0,0 +1,17 @@ +diff --git a/dhcp6c.c b/dhcp6c.c +index 1caaaa5..04ce9c5 100644 +--- a/dhcp6c.c ++++ b/dhcp6c.c +@@ -217,6 +217,12 @@ main(argc, argv) + argv[0]); + exit(1); + } ++ ++ if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, argv[0], strlen(argv[0])) != 0) { ++ debug_printf(LOG_ERR, FNAME, "failed to bind %s", argv[0]); ++ exit(1); ++ } ++ + argv++; + } + diff --git a/scripts/package-build/wide-dhcpv6/patches/0025-option-to-prevent-ia-release.patch b/scripts/package-build/wide-dhcpv6/patches/0025-option-to-prevent-ia-release.patch new file mode 100644 index 00000000..32c15814 --- /dev/null +++ b/scripts/package-build/wide-dhcpv6/patches/0025-option-to-prevent-ia-release.patch @@ -0,0 +1,155 @@ +From: 1vivy <1vivy@tutanota.com> +Date: Sat, 22 Jul 2023 13:07:10 -0600 +Subject: wide-dhcpv6: T5387: Add a no release option '-n'. + +This prevents a release signal from being sent to the ISP causing a new PD or address to be allocated. + +Co-authored-by: MrLenin <909621+MrLenin@users.noreply.github.com> +Co-authored-by: marjohn56 <martin@queens-park.com> +--- wide-dhcpv6.orig/common.h ++++ wide-dhcpv6/common.h +@@ -120,6 +120,7 @@ sysdep_sa_len (const struct sockaddr *sa + extern int foreground; + extern int debug_thresh; + extern char *device; ++extern int opt_norelease; + + /* search option for dhcp6_find_listval() */ + #define MATCHLIST_PREFIXLEN 0x1 +--- wide-dhcpv6.orig/dhcp6c.8 ++++ wide-dhcpv6/dhcp6c.8 +@@ -88,6 +88,10 @@ is terminated. (suits for a use in shel + Since the configuration is internally generated, you cannot provide a configuration in this mode. If you want to have different actions for the stateless DHCPv6 information, you should write an appropriate configuration and invoke + .Nm + without this option. ++.It Fl n ++Prevent Release message from being sent to DHCPv6 server when ++.Nm ++stops. This is useful for preventing a new address from being configured by the DHCPv6 server when restarting the DHCPv6 client. + .It Fl p Ar pid-file + Use + .Ar pid-file +@@ -109,18 +113,22 @@ or + .Fl i + option is specified. + .Pp +-Upon receipt of the +-.Dv SIGHUP ++Upon receipt of a ++.Dv SIGHUP , ++.Dv SIGTERM , + or +-.Dv SIGTERM +-signals, +-.Nm +-will remove all stateful resources from the system. +-In the former case the daemon will then reinvoke itself, +-while it will stop running in the latter case. +-In either case, ++.Dv SIGUSR1 ++signal, + .Nm +-will send DHCPv6 Release messages to release resources assigned from servers. ++will remove all stateful resources from the system. After that, ++.Dv SIGHUP ++reinitializes the daemon, and ++.Dv SIGTERM ++stops the daemon. In both cases, DHCPv6 Release message will be sent to release resources assigned from servers. ++.Dv SIGUSR1 ++stops the daemon as ++.Dv SIGTERM ++does though DHCPv6 Release message will not be sent. + .\" + .Sh FILES + .Bl -tag -width /etc/wide-dhcpv6/dhcp6c.conf -compact +--- wide-dhcpv6.orig/dhcp6c.c ++++ wide-dhcpv6/dhcp6c.c +@@ -84,6 +84,7 @@ static int exit_ok = 0; + static sig_atomic_t sig_flags = 0; + #define SIGF_TERM 0x1 + #define SIGF_HUP 0x2 ++#define SIGF_USR1 0x4 + + const dhcp6_mode_t dhcp6_mode = DHCP6_MODE_CLIENT; + +@@ -108,6 +109,8 @@ static int ctldigestlen; + + static int infreq_mode = 0; + ++int opt_norelease; ++ + static inline int get_val32 __P((char **, int *, u_int32_t *)); + static inline int get_ifname __P((char **, int *, char *, int)); + +@@ -170,7 +173,7 @@ main(argc, argv) + else + progname++; + +- while ((ch = getopt(argc, argv, "c:dDfik:p:P:")) != -1) { ++ while ((ch = getopt(argc, argv, "c:dDfik:np:P:")) != -1) { + switch (ch) { + case 'c': + conffile = optarg; +@@ -190,6 +193,9 @@ main(argc, argv) + case 'k': + ctlkeyfile = optarg; + break; ++ case 'n': ++ opt_norelease = 1; ++ break; + case 'p': + pid_file = optarg; + break; +@@ -395,6 +401,11 @@ client6_init() + strerror(errno)); + exit(1); + } ++ if (signal(SIGUSR1, client6_signal) == SIG_ERR) { ++ debug_printf(LOG_WARNING, FNAME, "failed to set signal: %s", ++ strerror(errno)); ++ exit(1); ++ } + } + + int +@@ -525,6 +536,13 @@ process_signals() + free_resources(NULL); + client6_startall(1); + } ++ if ((sig_flags & SIGF_USR1)) { ++ debug_printf(LOG_INFO, FNAME, "exit without release"); ++ exit_ok = 1; ++ opt_norelease = 1; ++ free_resources(NULL); ++ check_exit(); ++ } + + sig_flags = 0; + } +@@ -1171,6 +1189,9 @@ client6_signal(sig) + case SIGHUP: + sig_flags |= SIGF_HUP; + break; ++ case SIGUSR1: ++ sig_flags |= SIGF_USR1; ++ break; + } + } + +--- wide-dhcpv6.orig/dhcp6c_ia.c ++++ wide-dhcpv6/dhcp6c_ia.c +@@ -420,7 +420,13 @@ release_all_ia(ifp) + for (ia = TAILQ_FIRST(&iac->iadata); ia; ia = ia_next) { + ia_next = TAILQ_NEXT(ia, link); + +- (void)release_ia(ia); ++ if (opt_norelease == 0) { ++ debug_printf(LOG_INFO, FNAME, "Start address " ++ "release"); ++ (void)release_ia(ia); ++ } else ++ debug_printf(LOG_INFO, FNAME, "Bypassing address " ++ "release because of -n flag"); + + /* + * The client MUST stop using all of the addresses |