From ea21651a2c9cd8e7a7ceef5a4189ade11868b40f Mon Sep 17 00:00:00 2001 From: ducoterra Date: Mon, 8 Jul 2024 10:42:58 -0400 Subject: [PATCH] zsh and wireguard updates --- .gitignore | 3 +- arch/base.md | 22 + arch/gaming.md | 5 + arch/workstation.md | 97 +++- ath12k/ath12k-fw-repo | 1032 +++++++++++++++++++++++++++++++++++++++ ath12k/board.bin | Bin 0 -> 88896 bytes ath12k/regdb.bin | Bin 0 -> 24310 bytes fedora_server.md | 2 +- wireguard/README.md | 62 +++ wireguard/add_client.sh | 37 ++ 10 files changed, 1243 insertions(+), 17 deletions(-) create mode 100755 ath12k/ath12k-fw-repo create mode 100644 ath12k/board.bin create mode 100644 ath12k/regdb.bin create mode 100644 wireguard/README.md create mode 100644 wireguard/add_client.sh diff --git a/.gitignore b/.gitignore index b05ae27..73fc79c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .vscode/ -venv/ \ No newline at end of file +venv/ +secrets/ diff --git a/arch/base.md b/arch/base.md index 05a701d..79f51fd 100644 --- a/arch/base.md +++ b/arch/base.md @@ -55,6 +55,8 @@ I have instructions for building a: - [CUPS Printing](#cups-printing) - [Yubikey](#yubikey) - [Bashrc](#bashrc) + - [Colorized Prompt](#colorized-prompt) + - [Standard Bashrc](#standard-bashrc) ## Installation @@ -899,6 +901,12 @@ systemctl enable --now iscsid # Log out of all sessions iscsiadm -m node -u + + # Log out of a single session + iscsiadm -m node -T iqn.2023-01.driveripper.reeselink.com:2024-01-framework --logout + + # Remove session + iscsiadm -m node -o delete -T iqn.2023-01.driveripper.reeselink.com:2023-01-framework ``` ## Software Stores @@ -1001,6 +1009,20 @@ sudo systemctl enable --now pcscd ## Bashrc +### Colorized Prompt + + + +You can change the prompt color by setting PROMPT_COLOR at the top of your .bashrc + +Examples: + +Yellow: `PROMPT_COLOR=33;` +Orange: `PROMPT_COLOR=38;5;208;` +Red: `PROMPT_COLOR=38;5;160;` + +### Standard Bashrc + Don't do this if you installed `zsh` ~/.bashrc diff --git a/arch/gaming.md b/arch/gaming.md index 8153ee3..60d159c 100644 --- a/arch/gaming.md +++ b/arch/gaming.md @@ -167,6 +167,11 @@ network streaming to any device that can run moonlight. I used the Archlinux pkg. Follow the instructions (including the autostart instructions). +```bash +wget https://github.com/LizardByte/Sunshine/releases/latest/download/sunshine.pkg.tar.zst +pacman -U --noconfirm sunshine.pkg.tar.zst +``` + ### Install Moonlight diff --git a/arch/workstation.md b/arch/workstation.md index 9fa0750..1715ac8 100644 --- a/arch/workstation.md +++ b/arch/workstation.md @@ -2,10 +2,12 @@ - [Workstation](#workstation) - [Framework AMD Notes](#framework-amd-notes) - - [Wifi](#wifi) + - [ATH12K Wifi Drivers](#ath12k-wifi-drivers) - [Microcode](#microcode) + - [linux-git kernel](#linux-git-kernel) - [Base Tools](#base-tools) - [ZSH](#zsh) + - [Prompt Themes](#prompt-themes) - [Aliases](#aliases) - [Rollback Pacman Update](#rollback-pacman-update) - [Podman](#podman) @@ -31,6 +33,7 @@ - [Initialization](#initialization) - [Development](#development) - [Cura](#cura) + - [Creality Print](#creality-print) - [AWS CLI](#aws-cli) - [NSlookup](#nslookup) - [rpi-imager](#rpi-imager) @@ -40,7 +43,7 @@ ## Framework AMD Notes -### Wifi +### ATH12K Wifi Drivers Install the wireless-regdb to set the regulatory domain to US @@ -50,20 +53,21 @@ pacman -S wireless-regdb Edit `/etc/conf.d/wireless-regdom` to set the domain -Switch to iwd for the NetworkManager backend. + -```bash -pacman -S iwd -``` +1. `git clone https://git.codelinaro.org/clo/ath-firmware/ath12k-firmware` +2. `cd ath12k-firmware` +3. Run the following: -Edit `/etc/NetworkManager/conf.d/wifi_backend.conf` + ```bash + wget https://github.com/qca/qca-swiss-army-knife/raw/master/tools/scripts/ath12k/ath12k-fw-repo + chmod 755 ath12k-fw-repo + sudo ./ath12k-fw-repo --install /lib/firmware + ``` -```conf -[device] -wifi.backend=iwd -``` - -Finally, reboot the machine for the changes to take effect. +4. `sudo cp ath12k/board.bin /lib/firmware/ath12k/WCN7850/hw2.0/` +5. `sudo cp ath12k/regdb.bin /lib/firmware/ath12k/WCN7850/hw2.0/` +6. Reboot ### Microcode @@ -81,10 +85,20 @@ initrd /initramfs-linux.img options ... ``` +### linux-git kernel + + + +1. `git clone https://aur.archlinux.org/linux-git.git` +2. `cd linux-git` +3. `makepkg` +4. `sudo pacman -U linux-git... linux-git-headers...` + ## Base Tools ```bash -pacman -S rsync which git iperf3 pwgen dosfstools exfatprogs +# gvfs and gvfs-dnssd are for webdav support +pacman -S rsync which git iperf3 pwgen dosfstools exfatprogs gvfs gvfs-dnssd ``` ## ZSH @@ -92,7 +106,43 @@ pacman -S rsync which git iperf3 pwgen dosfstools exfatprogs ```bash pacman -S zsh grml-zsh-config chsh -s $(which zsh) -echo "autoload -U compinit; compinit" > ~/.zshrc + +cat < ~/.zshrc +# Basic settings +autoload bashcompinit && bashcompinit +autoload -U compinit; compinit +zstyle ':completion:*' menu select + +# Prompt settings +autoload -Uz promptinit +promptinit +PROMPT_EOL_MARK= + +# Syntax Highlighting +source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh +source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh + +# Command Not Found Autocomplete +source /usr/share/doc/pkgfile/command-not-found.zsh + +### Custom Commands and Aliases ### +EOF +``` + +### Prompt Themes + +See: + +Use `prompt -l` to list prompts + +Use `prompt -p` to see previews + +In your `.zshrc` set the following: + +```bash +autoload -Uz promptinit +promptinit +prompt grml ``` ### Aliases @@ -444,6 +494,23 @@ Icon=/home/ducoterra/.icons/cura.png Type=Application ``` +## Creality Print + + + +```bash +mv ~/Downloads/Creality_Print*.AppImage ~/Applications/Creality_Print.AppImage +chmod +x ~/Applications/*.AppImage +``` + +```conf +[Desktop Entry] +Name=Creality Print +Exec=/home/ducoterra/Applications/Creality_Print.AppImage +Icon=/home/ducoterra/.icons/creality_print.png +Type=Application +``` + ## AWS CLI diff --git a/ath12k/ath12k-fw-repo b/ath12k/ath12k-fw-repo new file mode 100755 index 0000000..edec54c --- /dev/null +++ b/ath12k/ath12k-fw-repo @@ -0,0 +1,1032 @@ +#!/usr/bin/python3 +# +# Copyright (c) 2016 Qualcomm Atheros, Inc. +# Copyright (c) 2018,2020 The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import os +import logging +import re +import argparse +import shutil +import sys +import filecmp +import functools +import subprocess +import email + +# global variables +logger = None + +BRANCH_DEFAULT_PRIORITY = 1000 +BRANCH_PRIORITY_FILE = '.priority' +WHENCE_FILE = 'WHENCE' +NOTICE_FILE = 'Notice.txt' +NOTICE_FILE_LEN_MIN = 5000 +ATH12K_DIR = 'ath12k' +TESTING_BRANCH = 'testing' + +FIRMWARE_BLACKLIST = [ +] + +BRANCH_BLACKLIST = [ + 'msm', +] + + +@functools.total_ordering +class Hardware(): + def get_path(self): + return os.path.join(self.hw, self.hw_ver) + + def __eq__(self, other): + return self.name == other.name + + def __lt__(self, other): + return self.name < other.name + + def __repr__(self): + return self.__str__() + + def __str__(self): + return 'Hardware(\'%s\'): %s %s' % (self.name, self.board_files, + sorted(self.firmware_branches)) + + def __init__(self, hw, hw_ver): + # QCA6174 + self.hw = hw + + # hw3.0 + self.hw_ver = hw_ver + + self.name = '%s %s' % (hw, hw_ver) + + self.firmware_branches = [] + self.board_files = [] + + +@functools.total_ordering +class FirmwareBranch(): + # return the branch name without 'testing/' prefix + def get_clean_name(self): + if self.testing_branch: + return self.name[len(TESTING_BRANCH):] + + return self.name + + def __eq__(self, other): + return self.priority == other.priority and \ + self.get_clean_name() == other.get_clean_name() + + def __lt__(self, other): + # '.' is always of the lower priority + if self.name == '.': + return True + + if other.name == '.': + return False + + if self.priority != other.priority: + if self.priority < other.priority: + return True + else: + return False + + return self.get_clean_name() < other.get_clean_name() + + def __repr__(self): + return self.__str__() + + def __str__(self): + return 'FirmwareBranch(\'%s\'): %s' % (self.name, sorted(self.firmwares)) + + def __init__(self, name, path=None): + self.name = name + self.firmwares = [] + + if name.startswith(TESTING_BRANCH): + self.testing_branch = True + + # testing branches use lower priority by default so that + # they are ordered below normal branches + self.priority = 0 + else: + self.testing_branch = False + self.priority = BRANCH_DEFAULT_PRIORITY + + if path: + priority_path = os.path.join(path, BRANCH_PRIORITY_FILE) + if os.path.isfile(priority_path): + try: + f = open(priority_path, 'r') + buf = f.read() + f.close() + + self.priority = int(buf) + except Exception as e: + logger.error('Failed to read %s: %s' % (priority_path, e)) + + +class BoardFile(): + + @staticmethod + def create_from_path(path): + filename = os.path.basename(path) + + match = re.search(r'^board-(\d+).bin', filename) + if match is None: + match = re.search(r'^board.bin', filename) + if match is None: + return None + + if len(match.groups()) > 1: + bd_api = match.group(1) + else: + bd_api = None + + return BoardFile(path, bd_api) + + def get_basename(self): + return os.path.basename(self.path) + + def __repr__(self): + return self.__str__() + + def __str__(self): + return '%s' % (self.get_basename()) + + def __init__(self, path, bd_api): + # full path to the board file, including directories and filename + self.path = path + + # board api version, eg. '2' in board-2.bin + self.bd_api = bd_api + + +class Firmware(): + + @staticmethod + def create_from_path(path): + if not os.path.isdir(path): + raise Exception('Firmware path %s is not a directory') + + fw_ver = os.path.basename(path) + + return Firmware(fw_ver, path) + + def get_files_with_path(self): + result = [] + + for filename in self.filenames: + result.append(os.path.join(self.path, filename)) + return result + + def get_notice_path(self): + return os.path.join(self.path, self.notice_filename) + + def __eq__(self, other): + return self.fw_ver == other.fw_ver + + def __ne__(self, other): + return not self.__eq__(other) + + # FIXME: firmware-5.bin_10.4-3.2-00080 and + # firmware-5.bin_10.4-3.2.1-00028 are sorted incorrectly + def __lt__(self, other): + s = self.fw_ver + o = other.fw_ver + + # FIXME: An ugly hack that to make the comparison easier to + # implement. Just to get some sort of simple sorting working + # replace '-' with '.' in version string. But now for example + # '10.2.4.70.2 > 10.2.4.70-2' is not compared correctly. + + s = s.replace('-', '.') + o = o.replace('-', '.') + + s = s.split('.') + o = o.split('.') + + s2 = s + o2 = o + + s = [] + o = [] + + for t in s2: + try: + k = int(t) + except: + k = t + + s.append(k) + + for t in o2: + try: + k = int(t) + except: + k = t + + o.append(k) + + l = min(len(s), len(o)) + + for i in range(l): + + if s[i] < o[i]: + return True + elif s[i] > o[i]: + return False + + if len(s) > len(o): + return False + + return True + + def __le__(self, other): + return self.__lt__(other) or self.__eq__(other) + + def __gt__(self, other): + return not self.__le__(other) + + def __ge__(self, other): + return self.__gt__(other) or self.__eq__(other) + + def __repr__(self): + return self.__str__() + + def __str__(self): + return '%s' % (self.fw_ver) + + # path can be None with unittests + def __init__(self, fw_ver, path=None): + # path to the release directory, no filenames + self.path = path + + # filenames of all firmware files, excluding notice file + self.filenames = [] + + # filename of the notice file, excluding path + self.notice_filename = None + + # firmware version + self.fw_ver = fw_ver + + if path: + files = os.listdir(path) + files.sort() + + for filename in files: + if filename == NOTICE_FILE: + logger.debug('%s: %s' % (self.fw_ver, filename)) + self.notice_filename = filename + continue + + self.filenames.append(filename) + + logger.debug('%s: %s' % (self.fw_ver, self.filenames)) + + # check notice file + if self.notice_filename is None: + print('%s: missing %s' % (self.path, NOTICE_FILE)) + return + + notice_path = os.path.join(self.path, self.notice_filename) + f = open(notice_path, 'r') + try: + buf = f.read() + except UnicodeDecodeError as e: + print('%s: invalid utf-8: %s' % (notice_path, e)) + self.notice_filename = None + return + finally: + f.close() + + if len(buf) < NOTICE_FILE_LEN_MIN: + print('%s: too short: %d B' % (notice_path, len(buf))) + self.notice_filename = None + return + + +def scan_branch_dir(path): + fw_list = [] + + files = os.listdir(path) + files.sort() + + for f in files: + f_path = os.path.join(path, f) + + if not os.path.isdir(f_path): + continue + + firmware = Firmware.create_from_path(f_path) + if firmware: + if firmware.fw_ver in FIRMWARE_BLACKLIST: + logger.debug('Blacklisted firmware release: %s' % (firmware.fw_ver)) + continue + + logger.debug('Found firmware release: %s' % (firmware.fw_ver)) + fw_list.append(firmware) + continue + + logger.warning('Unknown file: %s' % (f_path)) + + return fw_list + + +# QCA988X/hw2.0 +def scan_hw_ver(hw): + path = hw.get_path() + files = os.listdir(path) + files.sort() + + for fw_branch in files: + if fw_branch == TESTING_BRANCH: + # scan all directories under testing branch, eg. testing/1.2.3.4 + dirs = os.listdir(os.path.join(path, fw_branch)) + fw_branches = [] + for d in dirs: + fw_branches.append(os.path.join(TESTING_BRANCH, d)) + else: + fw_branches = [fw_branch] + + for fw_branch in fw_branches: + fw_branch_path = os.path.join(path, fw_branch) + + if not os.path.isdir(fw_branch_path): + continue + + if os.path.basename(fw_branch_path) in BRANCH_BLACKLIST: + logger.debug('Blacklisted firmware branch: %s' % (fw_branch_path)) + continue + + logger.debug('Found firmware branch: %s' % (fw_branch)) + fb = FirmwareBranch(fw_branch, fw_branch_path) + hw.firmware_branches.append(fb) + + fw = scan_branch_dir(fw_branch_path) + fb.firmwares += fw + + files = os.listdir(path) + for f_path in files: + boardfile = BoardFile.create_from_path(os.path.join(path, f_path)) + if boardfile: + logger.debug('Found board file: %s' % (f_path)) + hw.board_files.append(boardfile) + continue + + +# QCA98XX +def scan_hw(path): + hws = [] + + files = os.listdir(path) + files.sort() + + for hw_ver in files: + hw_ver_path = os.path.join(path, hw_ver) + + if not os.path.isdir(hw_ver_path): + continue + + # skip symbolic links, for example WCN6855 hw2.1 + if os.path.islink(hw_ver_path): + continue + + logger.debug('Found hw version: %s' % (hw_ver)) + + hw = Hardware(path, hw_ver) + scan_hw_ver(hw) + + if len(hw.firmware_branches) == 0: + logger.debug('Skipping due to no firmware branches found: %s' % (hw.name)) + continue + + hws.append(hw) + + return hws + + +def scan_repository(directory): + hws = {} + + files = os.listdir(directory) + files.sort() + + for hw_name in files: + if not os.path.isdir(hw_name): + continue + + # skip hidden directories + if hw_name.startswith('.'): + continue + + logger.debug('Found hw: %s' % (hw_name)) + + hw_list = scan_hw(hw_name) + + for hw in hw_list: + hws[hw.name] = hw + + return hws + + +# srcpath: full pathname (directory + filename) where copy from +def install_file(args, srcpath, destdir, destfilename): + logger.debug('install_file(%s, %s, %s)' % (srcpath, destdir, destfilename)) + + if args.dry_run: + return + + destpath = os.path.join(destdir, destfilename) + + destdir = os.path.dirname(destpath) + if not os.path.isdir(destdir): + os.makedirs(destdir) + + logger.info('\t%s -> %s' % (srcpath, destpath)) + shutil.copyfile(srcpath, destpath) + + return destpath + + +def get_firmware_version(path): + cmd = ['ath12k-fwencoder', '--info', path] + info = subprocess.check_output(cmd, universal_newlines=True) + msg = email.message_from_string(info) + return msg['FirmwareVersion'] + + +def get_board_crc32(path): + cmd = ['ath12k-fwencoder', '--crc32', path] + return subprocess.check_output(cmd, universal_newlines=True).strip() + + +# print indent +def pi(level, msg): + print('%s%s' % (level * '\t', msg)) + + +# The WHENCE file update is implemented by using board-2.bin entry as +# an "anchor". All entries (including File, Version and License) for +# that hardware directory will be replaces by the new ones. As the +# filepaths is always sorted the changes visible in git-diff will be +# actually changed files. +# +# Only called during firmware updates. Board file updates don't need +# changes in WHENCE and that's why this function doesn't support board +# file changes. +def whence_update(linux_firmware, filepaths, version): + whencepath = os.path.join(linux_firmware, WHENCE_FILE) + license_relpath = None + + if not os.path.exists(whencepath): + return None + + f = open(whencepath, 'r') + buf = f.read() + f.close() + + dirname = os.path.dirname(os.path.relpath(filepaths[0], linux_firmware)) + + pattern = r'(File: %s/board-\d+.bin\n)(.*%s.*?\n)+' % (dirname, + dirname) + + # \g<1> is same as \1 but needed to separate from the version string + replace = r'\g<1>' + + for filepath in filepaths: + relpath = os.path.relpath(filepath, linux_firmware) + if relpath.endswith(NOTICE_FILE): + license_relpath = relpath + continue + + replace += r'File: %s\n' % (relpath) + + if version is not None: + replace += r'Version: %s\n' % (version) + + # license (or notice.txt to be exact) needs to be last + if license_relpath is not None: + replace += r'File: %s\n' % (license_relpath) + + (buf, sub_count) = re.subn(pattern, replace, buf, + flags=re.MULTILINE | re.DOTALL) + + if sub_count != 1: + logger.error('Failed to add %s to WHENCE: %d' % (version, sub_count)) + return None + + f = open(whencepath, 'w') + f.write(buf) + f.close() + + return whencepath + + +def whence_add(linux_firmware, filepaths, version=None): + whencepath = os.path.join(linux_firmware, WHENCE_FILE) + license_relpath = None + + if not os.path.exists(whencepath): + return None + + f = open(whencepath, 'r') + buf = f.read() + f.close() + + pattern = r'(Driver: ath12k.*?\n\n.*?)\n\n' + + # \g<1> is same as \1 but needed to separate from the version string + replace = r'\g<1>\n' + + for filepath in filepaths: + relpath = os.path.relpath(filepath, linux_firmware) + if relpath.endswith(NOTICE_FILE): + license_relpath = relpath + continue + + replace += r'File: %s\n' % (relpath) + + if version is not None: + replace += r'Version: %s\n' % (version) + + # license (or notice.txt to be exact) needs to be last + if license_relpath is not None: + replace += r'File: %s\n' % (license_relpath) + + # empty line before the 'Licence: Redistributable.' line + replace += r'\n' + + (buf, sub_count) = re.subn(pattern, replace, buf, + flags=re.MULTILINE | re.DOTALL) + + if sub_count != 1: + logger.error('Failed to add %s to WHENCE: %d' % (version, sub_count)) + return None + + f = open(whencepath, 'w') + f.write(buf) + f.close() + + return whencepath + + +def git_commit(args, msg, repodir, files): + if not args.commit: + # nothing to do + return + + cmd = ['git', '-C', repodir, 'commit', '--quiet', '--signoff', '-m', msg] + files + + logger.debug('Running: %r' % (cmd)) + subprocess.check_call(cmd) + + +def git_add(args, repodir, files): + if not args.commit: + # nothing to do + return + + cmd = ['git', '-C', repodir, 'add'] + files + + logger.debug('Running: %r' % (cmd)) + subprocess.check_call(cmd) + + +def git_rm(args, repodir, files): + if not args.commit: + # nothing to do + return + + cmd = ['git', '-C', repodir, 'rm', '--quiet'] + files + + logger.debug('Running: %r' % (cmd)) + subprocess.check_call(cmd) + + +def cmd_check(args): + scan_repository('.') + + +def cmd_list(args): + level = 0 + + hws = scan_repository('.') + for hw in sorted(hws.values()): + pi(level, '%s:' % (hw.name)) + level += 1 + + # print board files + if len(hw.board_files) > 0: + pi(level, 'board') + level += 1 + + for board_file in sorted(hw.board_files): + pi(level, board_file) + + level -= 1 + + # print firmware branches + for branch in sorted(hw.firmware_branches): + if len(branch.firmwares) == 0: + # don't print empty branches + continue + + pi(level, '%s' % (branch.name)) + level += 1 + + for fw in sorted(branch.firmwares): + pi(level, fw.fw_ver) + + level -= 1 + + level -= 1 + + +def cmd_list_hardware(args): + hws = scan_repository('.') + for hw in sorted(hws.values()): + print(hw.name) + + +def cmd_list_branches(args): + hw_name = args.list_branches[0] + hw_ver = args.list_branches[1] + + hws = scan_repository('.') + for hw in sorted(hws.values()): + if hw.name == '%s %s' % (hw_name, hw_ver): + for branch in sorted(hw.firmware_branches): + print(branch.name) + + return + + +def cmd_list_releases(args): + hw_name = args.list_releases[0] + hw_ver = args.list_releases[1] + fw_branch = args.list_releases[2] + + hws = scan_repository('.') + for hw in sorted(hws.values()): + if hw.name == '%s %s' % (hw_name, hw_ver): + for branch in sorted(hw.firmware_branches): + if fw_branch == branch.name: + for fw in branch.firmwares: + print(fw.fw_ver) + + return + + +def cmd_list_lib_dir(args): + fw_dir = args.list_lib_dir[0] + ath12k_dir = os.path.join(fw_dir, ATH12K_DIR) + + if not os.path.exists(ath12k_dir): + logger.error('directory %s does not exist, aborting' % (ath12k_dir)) + sys.exit(1) + + if not os.path.isdir(ath12k_dir): + logger.error('%s is not a directory, aborting' % (ath12k_dir)) + sys.exit(1) + + # sort the results based on dirpath + for (dirpath, dirnames, filenames) in sorted(os.walk(ath12k_dir)): + found = [] + for filename in sorted(filenames): + path = os.path.join(dirpath, filename) + + match = re.match(r'firmware.*\.bin', filename) + if match is not None: + # this is a firmware file + s = '%s\t%s' % (filename, get_firmware_version(path)) + found.append(s) + + match = re.match(r'board.*\.bin', filename) + if match is not None: + # this is a board file + s = '%s\t%s' % (filename, get_board_crc32(path)) + found.append(s) + + if len(found) > 0: + # Just show QCA1234/hw1.0 directories. I would have liked + # to use os.path functions here but just could not find + # anything sensible there. + pi(0, '%s:' % ('/'.join(dirpath.split('/')[-2:]))) + for line in found: + pi(1, line) + + +def cmd_get_latest_in_branch(args): + # As this command is mostly for scripts to parse, don't show + # warnings etc to clutter the output, unless we are debugging of + # course. + if not args.debug: + logger.setLevel(logging.ERROR) + + hws = scan_repository('.') + + args_hw = args.get_latest_in_branch[0] + args_hwver = args.get_latest_in_branch[1] + args_fwbranch = args.get_latest_in_branch[2] + + # TODO: hw is always in uppercase and hwver lower case, check that + hw_name = '%s %s' % (args_hw, args_hwver) + + if hw_name not in hws: + logger.error('Did not find hardware: %s' % (hw_name)) + sys.exit(1) + + hw = hws[hw_name] + + fw_branch = None + + for b in hw.firmware_branches: + if b.name == args_fwbranch: + fw_branch = b + break + + if fw_branch is None: + logger.error('Did not find firmware branch: %s' % (args_fwbranch)) + sys.exit(1) + + if len(fw_branch.firmwares) == 0: + # no firmware images in this branch, just use return value 0 with no output + sys.exit(0) + + print(sorted(fw_branch.firmwares)[-1].path) + + sys.exit(0) + + +def cmd_get_latest_in_hw(args): + # As this command is mostly for scripts to parse, don't show + # warnings etc to clutter the output, unless we are debugging of + # course. + if not args.debug: + logger.setLevel(logging.ERROR) + + hws = scan_repository('.') + + args_hw = args.get_latest[0] + args_hwver = args.get_latest[1] + + # TODO: hw is always in uppercase and hwver lower case, check that + hw_name = '%s %s' % (args_hw, args_hwver) + + if hw_name not in hws: + logger.error('Did not find hardware: %s' % (hw_name)) + sys.exit(1) + + hw = hws[hw_name] + + for branch in sorted(hw.firmware_branches, reverse=True): + if len(branch.firmwares) == 0: + # ignore an empty branch + continue + + print(sorted(branch.firmwares)[-1].path) + break + + sys.exit(0) + + +def cmd_install(args): + hws = scan_repository('.') + + linux_firmware = args.install[0] + ath12kdir = os.path.join(linux_firmware, ATH12K_DIR) + + if not os.path.exists(ath12kdir): + os.makedirs(ath12kdir) + + if not os.path.isdir(ath12kdir): + logger.error('%s is not a directory' % (ath12kdir)) + sys.exit(1) + + logger.debug('Installing to directory %s' % (ath12kdir)) + + for hw in sorted(hws.values()): + bd_list = hw.board_files + + # every Hardware() should have at least one firmware branch, the + # main '.' branch so no need to check the length + fw_list = sorted(sorted(hw.firmware_branches)[-1].firmwares) + + if len(fw_list) == 0: + logger.debug('no firmware images found for %s' % (hw)) + continue + + destdir = os.path.join(ath12kdir, hw.get_path()) + + # install board files first as that's used as an "anchor" for + # firmware files WHENCE updates + for bd in bd_list: + installed = [] + dest = os.path.join(ath12kdir, bd.path) + if not os.path.exists(dest) or not filecmp.cmp(bd.path, dest): + if os.path.exists(dest): + action = 'update' + else: + action = 'add' + + logger.info('Installing board file %s' % (bd.path)) + destpath = install_file(args, bd.path, destdir, + bd.get_basename()) + installed.append(destpath) + + if action == 'add': + whencepath = whence_add(linux_firmware, installed) + if whencepath is not None: + installed.append(whencepath) + + git_add(args, linux_firmware, installed) + + msg = 'ath12k: %s: %s %s' % (hw.name, + action, + bd.get_basename()) + git_commit(args, msg, linux_firmware, installed) + else: + logger.debug('No update needed for %s' % (bd.path)) + + # install latest firmware + fw = fw_list[-1] + + to_add = [] + to_update = [] + to_remove = [] + + # remove notice and board files from to_remove + if os.path.exists(destdir): + for filename in os.listdir(destdir): + if filename in [NOTICE_FILE, 'board-2.bin']: + continue + + to_remove.append(filename) + + # investigate what changes are needed + for filepath in fw.get_files_with_path(): + filename = os.path.basename(filepath) + dest = os.path.join(destdir, filename) + + if not os.path.exists(dest): + to_add.append(filename) + continue + + if not filecmp.cmp(filepath, dest): + to_update.append(filename) + + to_remove.remove(filename) + + if len(to_add) > 0 or len(to_update) > 0 or len(to_remove) > 0: + if len(to_update) > 0 or len(to_remove) > 0: + action = 'update' + else: + action = 'add' + + logger.info('Installing %s to %s' % (fw.fw_ver, destdir)) + installed = [] + + for filepath in fw.get_files_with_path(): + destpath = install_file(args, filepath, destdir, + os.path.basename(filepath)) + installed.append(destpath) + + # install notice file (every release must have a notice file) + destpath = install_file(args, fw.get_notice_path(), destdir, + fw.notice_filename) + installed.append(destpath) + + # TODO: whence is not working with ath12k + if action == 'update': + # updating an existing firmware file + whencepath = whence_update(linux_firmware, installed, fw.fw_ver) + else: + # adding a new firmware file + whencepath = whence_add(linux_firmware, installed, fw.fw_ver) + + if whencepath is not None: + installed.append(whencepath) + + git_add(args, linux_firmware, installed) + + for filename in to_remove: + filepath = os.path.join(ath12kdir, hw.get_path(), filename) + + if os.path.basename(filepath) == 'regdb.bin': + logger.debug('ignore %s so that it is not removed from target' % (filepath)) + continue + + logger.info('\trm %s' % (filepath)) + + # even git_rm() removes the file need to remove the + # file separately in case --commit is not used + os.remove(filepath) + + git_rm(args, linux_firmware, [filepath]) + installed.append(filepath) + + # "ath12k: QCA6390 hw2.0: update to WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1" + msg = 'ath12k: %s: %s to %s' % (hw.name, + action, + fw.fw_ver) + + git_commit(args, msg, linux_firmware, installed) + else: + logger.debug('No update needed in %s for %s' % (hw.name, fw.fw_ver)) + + +def main(): + global logger + + logger = logging.getLogger('ath12k-fw-repo') + + parser = argparse.ArgumentParser( + description='Install firmware images from the ath12k-firmware git repository. Run it from the top directory of the working tree.') + + parser.add_argument('--debug', action='store_true', + help='Enable debug messages.') + parser.add_argument('--dry-run', action='store_true', + help='Do not run any actual commands.') + + parser.add_argument('--check', action='store_true', + help='Check the ath12k-firmware repository content for validity.') + parser.add_argument('--list', action='store_true', + help='List all files found from the ath12k-firmware repository.') + + parser.add_argument('--list-hardware', action='store_true', + help='List all possible hardware versions found from the ath12k-firmware repository.') + + parser.add_argument('--list-branches', action='store', + nargs=2, + help='List all firmware branches for for this hardware version.') + + parser.add_argument('--list-releases', action='store', + nargs=3, + help='List all releases from a firmware branch.') + + parser.add_argument('--list-lib-dir', action='store', + nargs=1, metavar='LIB_FIRMWARE_DIRECTORY', + help='List all files found from the specified directory, which can either be a linux-firmware repository or /lib/firmware directory.') + + parser.add_argument('--install', action='store', nargs=1, metavar='DESTINATION', + help='Install all ath12k firmware images to DESTINATION folder, for example /lib/firmware.') + + parser.add_argument('--commit', action='store_true', + help='When installing files also git commit them, for example when updating linux-firmware.git.') + + parser.add_argument('--get-latest-in-branch', action='store', nargs=3, + metavar=('HW', 'HWVER', 'BRANCH'), + help='Show latest firmware version from a firmware branch. Just outputs the version for easy parsing in scripts.') + + parser.add_argument('--get-latest', action='store', nargs=2, + metavar=('HW', 'HWVER'), + help='Show latest firmware version for hardware version. Just outputs the version for easy parsing in scripts.') + + args = parser.parse_args() + + if args.debug: + logging.basicConfig(format='%(levelname)s: %(message)s') + logger.setLevel(logging.DEBUG) + else: + logging.basicConfig(format='%(message)s') + logger.setLevel(logging.INFO) + + # commands + if args.check: + cmd_check(args) + elif args.list: + cmd_list(args) + elif args.list_hardware: + cmd_list_hardware(args) + elif args.list_branches: + cmd_list_branches(args) + elif args.list_releases: + cmd_list_releases(args) + elif args.list_lib_dir: + cmd_list_lib_dir(args) + elif args.install: + cmd_install(args) + elif args.get_latest_in_branch: + cmd_get_latest_in_branch(args) + elif args.get_latest: + cmd_get_latest_in_hw(args) + else: + logger.error('No command defined') + parser.print_usage() + +if __name__ == "__main__": + main() diff --git a/ath12k/board.bin b/ath12k/board.bin new file mode 100644 index 0000000000000000000000000000000000000000..94a2152c3f8acf8bf552ee0d61359b1e2636b739 GIT binary patch literal 88896 zcmeHw3wTu5edoC|NN9u%gBVFOk^rISNPrMRZ(SkG8=IF6l3~o3Clpq;8tTBs}!maLP)^5w1&cKQ2a! zOou)K#ISm;#2mabF%-OS4ugO};F>_d5^n`*Xv_Bhn2A&HP;NuFGF%q^kCVxy8sqd7 z?gixi{(I@K)}_CFJ>AW<##)WmOsm~$vpTJ2Ts2#*mW}@#aKGLPTgB?j#<|di^?ZB| zhL%9vmX}!wTQCq5En`Hs74Gdt?;i6mUO0E29n;&1NhKl+U;21P@T;bvNQ@Ku<9l5(oxI1n@5~4)@04-Zoi0r@&&`*g`;*^zRoeJC#I29Zn zI5i?C@SGSUK7&nTj~FXfi43t9=Y2S@!TfG3*LprUF3=s!4Xg=70^NZ;(^tGfG}j*p z0`msmnk?GFx3*$>d>?ojr1db-1PfGB6>j+2n+=V@Hq5It*bG0*>s-KhrXB)kJs1R_Wb$FmnRY%H*Vj4C^8{CayZ+{&K5(_9I08tmKU=oI%9nv?w@-O ziSoeE_8F={K!|Kn?7(nX$glUtSk|2zk?#teQKH;Qxi9C8z~34lV+F*B;K-3fL1$Uf zykIaRqv-DF-LXxDn}(Vzgf+|~os_X@j)Qrp@;Ao5SM+-1>ycL?4@dlb2lF1wdoJ&r zdH(yN+<#}dr6&1uL|mSO!ucw7r477ugE%hXtqz35v(JXaa%;KLm2LTyX1ij}b1{B^ zLlfR}WW6F@5m{M691lGkdNDM(nB$T*WMl_tz9N(~csY6x=KY|^xw;6vkcy5B07kq% z#D^Wxcn#ahf%&EJdgYZ_)`tVH(c;{&@%XSz93xgOr!U(=4}|uF4upC`kA{wfo(wtN z;#BD6P*RNlVbd&`A9jw9XZxrA~;Z(Lyx*pQNb&UQ*QIe(8S){m((4FGO<*=wm?tSJ3|f^gm6C z^YZ@>@PA41PXd1!{Qn02{|f#;gM6GzzTngU3#A|TOEv!j==bt}-^V`>_D@&#k)QUF z{|w}R8S=@GjZ@QD=zkk@@_!L@oJ-(G>tOtEfc_VtFI4=fd&&Rbzzi6(pOzn}k?++5k?8oB!Vq5wp^*x{X zqXeFwbh=DnokrJINTt`8+|e=Oa+fqGNty)dYK=bz`;H*j7r{Po)R zQsOvp@y~lw;^LjB@$>sJP@aSHaOd5vk&-xnVt`)y@hIY!D(@3^Z+u6JA14z>_`INwCKaP zE?$oul;5cMPTu=@tMVVn|5g6)^5+yBD)?Bz8wDNF1<{wHV`8z`me?P~LWScBR~LS~ z@E-~ri#m%QE&98nfw_07keu)Y_VW9%7e!5RA3eHWh-ui@O+~%eV1H8hF||*-M~LvP zLge5%q4psmCZmq37hb#-6CuB7ztWHAgz!wIAN_DL_U%QmFCX*>_1~iOV_!dc9rR;; zz1U;?OZ|@Gt)^<$nX@L!a~?`%l_eNd3eI z_^0RxJ{NmT0KSFPPx;8N(a0~af5p%r1wIk<@-Xw$2E7;dVc%X2{n|d}Z=?%zh!65} z%I(Mz%qKtP7i<9?_=Qz`r-FYn@@G8bOZ>NjhWwNA$&dW2!FZzPhkVvYnEH34KGuQ% zreWxZe8yMm?^gDG1oCeKKjcgO>N!g4?@;zrKk`fJ*Zj1f`gcJ;>W})1l>O5Gm7uqP z&itT#$k*b>p&#-KkUx7UYHJ=cjZ^-KBG5Bbxy ze$%ENe%jCe0Djq@k$;S@#D7n} ze-dBjFZ(0oa|HSszk8MasDEi6<%3`L7eD?w|A4RCe_(GI@y{VY&o)J;|BCL7uj@bQ@IUq# z_!(d1Ul{X=?^NJ98TD7g`eS^UAIzUFpZrCjBR^gLXur0P@&FY}A|qkdBK z1E0||eflBaoByOw>ji$yfABNE^5K7EGi3YM{{eB}NG@@4*!4t;L_)%gc|WquPs$d~&c#-IF*|3c7#ugovVckAmR*w6g|@Q(uD ze9Vs^|Fr#6k)M+h?`qK9{G)!_ult|cUlf7AfcAO)r+(ni_0O&Udz60kk6Pxxs_(S= zVPA@Vum67ih>z5-{YU-F{HK2U|Ag|N`J?tvwHiOz7X^Pl`b{qL8~Kyd3j7h@$#;RD z`Ah#8UyQlFyZs0LSF8Rm<46Bd|2fnTdD8zyj(&IjVSi`>o%sWKtdD}nAbS_|WB)c9 z^_BzwrXb&I)<8b+cKe^kANAqp-y8>D>Hpo(&;Ad7xjxW7_~-hM_{#o>{F3^ikNt)I zOZ}9O`pRjCe)y~P%l#+%kKBJzKKNySg?;Y+oAIH3fBt*?&)*LH+W*7Kf6${x6#mq& z@OS-3e!Kc1pWmnU>zDn9`nP}|@s<1kgTNp8#r-$^ckx&KU#|ZO|0w7(|B)Zs{;9|h z=|AF;vj64!g8Fjz-}6;{u>LkHe%2qxZvDYO86Ws3`xo;IcuppM$S1e{X}`*^smy=O zm;1+$0VDQ5)-UZxe#!oe{AT>P{<-U~!k6p6TwmyaI{lzez771yFIj)UD?=!~JUv_Pg~1|Czti zf0e&nA5-$XP07dl!2ZPexchJFXMVDOvA;vUj6d*W|8()E{|bMXPW#mQKNWaPX8(YE znP04b)Qj$aGQQxa{}X{v5#(|ID)Sru$@*Y?h(GL0$v@yb74~TSHGXpc!2BY9=nu>v z?yueb2m2GoT;JsW5cY8YHSrN(2t2*~(_pXMegrnbGU(x?$f8hQ>%SU|q{2}Wf_Pfvjq|<-U&0!EQ2p9wm z0tSI=5rOy=y!W9P@2g2BMdv(x4tJ>#t-ni(X1qtC@pMvDO~v~vCg6P?aIRyv5N$>H znZJdfIsYsv8orslXqV$P&<~jv(AkOg+Ae|q_n`kr(EoMlp9cLCm449MU`xvg=>I3^ z|1Xz7e;wrKLVrMrnH|ty3H|V|`RC9N`SN`sh0qV1Iy!}D2fYPYHT@X+U%LeQrz`zI z=*Qlt9ayx&mS*@z{qlWH1q{Xc~MuU-QEz_)6m^S-K??eHIgZiRo% zKZSn8H$^}2X$QRpvASgX>Hj$Br~ky)=YLf#=sN$fpKL>Zv}7RuZ^Hk-Ns4OhN2_As ze;4@BKJx4Q`76-DABTUHi0Mr1C+!Nz$b^i4fe(MH{EIsH&P4vZ_#*!rz6QD{Ki&8+ zKU93Ae(+ajp*|QNO=`u`gC zO@{pO4xRPc&iX-B%KZJtF!VRWHsyZ@;_t?n`Az>l{XxbDx>^ydX5ill{Ns$zSm=k& z4#bE2F8y23kNtjC9_9dZi4Wt0{B4H(M&z%2Umf-T7V%4`-7NCD-68Tf1^GC-=;gjMY<3s;~@b8}?ANd!rhJMJbfXyBAKnK6fkGGuo zq~Pz>kN(f~&Aa~D$j>&$ANV!`{~50WU)Wa#{3?kb>ks+qtv|p2ZOAnjAL6I|%K(2G z{VDa~rK|O~8u4@cAN^zfL6**cnZN9>=ovQR+lKr>N;vB``a>M`srzpS^Aq(W>CFGr zprgO?eVr12O;4))c+Ka(7k~B#<`?T{DE;322Yzkip&#*+>pS?p{U3iK#Kpe}@oPZ- zc;j!w@DzNRf2cocKXTqCe(WCs$VYxOFh9Khp}yL%7m{=xf7oAv`sZ)W*qxvwf0|MM zjmYmAUxj}3Pg!5T@zlT0Z}vyZk2?6-l+XNuEa{(TeXT%FF+XK|*gw#}8qhzg5T6R* zR}M_nVP6~iQ#0l^qCd`H|3b_vVL$u7jr?ju{!02kf{yyA z()hz?8~M=+UCqe9M%4cd_9st&k^I0%_HW?B{#`X4@+Uz)_}dXb*M8(T@$>dSSs!JP zk61RMKhZwd{`X-Y^9S|Oj9%9GBhV3lxj&%)^v?#J`3t)2pI>wAuPjme;h!5n+7J8W z`py0X9$9}C;D;{Vf2)wc71%$NBY)e`Ut8fzGjgHvpTN)f>GhxbS>M#J`KjOQKkRRX zEzQV(oj>mS4xWx1!O#9H5P#x_{*a;{{_;USV{9ODQ zKjeQid}%~|$^7B^hM2+a{``l0xxa&aZ~nKV|GNBIzi0io=RrRLE&B)PtZz4dz^9%1 zX+QPr{MG#rn7H+gTx?|ieFgl$w-T6?BR-6OE3TV?RpXCA2fpt55Bt;V2mTdd6@TP^ zEAqdI`H%iJ1N|!{|K@-`7qck`3=!TMqUVg3anpZ+8Nn_x==>zDR3zjS|J z2>e;!z_00lVGjEr*EjYT=xk^HAU~nfsUPC!*?-t`6+H=jSReGC`%B~p!s_rdezaf5 zAJ3;%$T>d0+Vi2m0vI8_GJohF^CK5@#)tGO&@(~T_OUD2zu^knc=d|dhup&#p${5d-AR{VgDWO`q6hJanQamzCO0RpQG=SiC%kWd{eBe|K4z~ z`aYg`$i6?mA$ChYN8gi)hwWYQyJ9{4_lA4b*OxeCKM=n&wxXY-?-RJU1NN=#zc<_~ z$a_f2yS1Ogz30)y<|gd^Qg)rJpL}aX;eWmFL*JF$II2iA{D-d{GR0 z7k%{YO5AO)j^7-^^N>FJ9!c!6H^*;_-K_86cc>mq?6bGVZ;vhU+}oMhXm`gK#Q2b> zj=sH#E%t5kr7=7|>Z9+YiQV?y@zt?K`VQnhp4e}1i{FtV?}5afc2|61jGIz*^zDPZ zH9mQdK;GtfB6gFW<&n44b8m;VZ()jk`x5s^c{4rp9Dfr7?Az+IZx`@e6~8G(-h+v) z_U-XyF|WKw6MO9~KK!)5Ui?!;ZvK5s0w zeR!VM2V%K5jl2i#d*f?k%k(T@x+k$2v0M_vvz9*k_Dg@4$Gq|$SGnQ!?c?YX+vDp} zYMSyAkmt>fboLP|f36)#9Duy_De}_!yFX37IPqAMlFuJYr1O`xkS-p}Qv7w|ky;Bn zzTWzveg4`aeru2~Ui{LMHz?PI_4%G3SS+n?DJ{XLAiwhs2;*;*gy&jb6Z)9+LJb8ljYy)oVs z!*jnr`VJ{!rop`_6b*4A0s6fIQll8eiQb@Z78qwZ5g==j2*y zEDxlS=d1y#YpC|ui=X31YOOl?l4_r`hAv83Qw}F~+M9qCzQ>`DKCWdwSbMx{w~nQ^ z79L1!z#2L~#&4{sqwgb$`|J(zl`(wJLmz!yYrC=5dgY~yCFQMzJbdp)A5z}>_=*_5 zN2Cu|o_8;hZhdp?TaaR3y1deR6>r>j%e_i!f8HVY41RgrZQAF}Q*Dbkul_9Yl6^G( zIDe;2ANalcPuWkz55(@#cZPrNGxGR(2nN4lri{rK>;eu_L6x^+Han-v}48mm3H%z8{69!-#EK% z>704(OBc*#A!SxXl#n7i!eS+kd|?3lZFS?8jg7I!RM+BIwO;+|Q{maght zwq*6}mCL&4_AI$|cK7U6bGqlOn!9pd_xz;`m(9O*@okG1FY8{gV970WZoGMkZ7*8T z-nq29rE}?u=Fa7wZvhM+1pLgx90mb{!1aqjSd73=0r45LIith5k^F*atgxtf{Dg@m zlS<3VD=Mqv)isl+Os$<(H@$vFLt|5OOKV%Z-7&M%-;rMyPlni?Sd_r_)OlaP9B0P)=~`X-a~zf~6sutKKJkS3 zG`>zsJ7@{N&Lr_+Yp@~ev4S(TwVzJDoP0I;dh$&2t>nAOEX+%lm|m;7dpQwEB4QJv zK%aSaHb{*)kMwDN*Ehy6L);+nqh(Y}RNyTQ;wj%TYt|pV=Y5?)26&~g(gZTL1pl8+ zo=#?mttY&6XvolG+UPy{#}m%?vFlzobNwMjV66B<>Dji>w$Phz+L4L^@9XTFXW#tU zPk;8)58nA)@z;1~4YJ-n;&Izsi~fWhK7bZJ+7;*iIS=XZV7n=pqyx-;jT~R%by1Lq0=l|Lo|GB2T zytJf5-^IW)x|}q>Mm^R#^;lb^$Cry?w#N(B06~)Dc(I_II#u&=6w#RSZ;A4kF^ZC!3 z?{Z)}luT{MmBLl))BftQ)~|8CRJfZy<8;o!`h@OdIu3)yWiWo-SNwF-XPo|gK3p$# zz8l;>7~D;tF@0vJecJi@z~!c!K9hd`e68Vb`i$u_rq9$=`s;S6XPnDH)B5#uiyjZQ zf4pZseZXYqG7KA%4pe`8}*^rO-DqWI%Jg)8vaG<1C&Klb#olP|sW2Ri4w zSKf+B_>^<^C4IMN<*oSrlVeApdivx`Cr{|RT`PF^=<%b+PC$fvw|j-Wd+hj$6P~+0 zEAbmP$3AuJ*ohM-PwKhdtGd+P7f~C2_8w2Y+tVZO9-|E&-=xPn z%IAxRo@dTi7J-NuVcyksWg)*RwdIL4Z#cLrExq(c<%@-~21ezCvL__RI{)-HPn@r)Ev!PZ-uRJZa8;Rrj=!NjT>7!KQ~<8lPhMgE+2d6 zSWArMYaHI-lPkoe3-=gYzT>a<&&w61EAINvkp(jXrMvg|$ODEOBPa2Huli&y51HP{umE zd;S~V*HinSeVwoH?ib|iU#8Rx@9Te;&brI{l0vQ@*wT6$75%^Tfxjq^IVD2$zfWp} z{|~GCg~Y@*d25!3um#sU@%ji}v+&Y~_rAX8Jr8G*ER>&` ztM^bcnLIRY+O)Fi)62@rCbqQTNBIID9Dz4x+^z#dce`@NX`LoDBko}zR z=cg{e9_vI6Kt`~<-qxEFQb?j3sS zGeI${PW}b@Xx`lXG+?{z&dhmgtj{jlbAfm0S;E2}35?;xZUkTbN2WS{nIoAW@aHE?vS@G@ED0hvz)^P_hkBBV$7)bgS2%z8tC-tcy~@&OUqRBP;*>w2o&Qz{MX7cUi@dr z)bJ$!+8CY!e(!VrjJf#b;qav2?@TK)&fm`_h;@#=m+}9JqBwQ2^XPgsUwqmc^WEe( z)cJSnytRP$>&55P`RD39G3wmEO`ZRfI)7iC$HW}^&FcKPI)6)@lj@Amk(ToJs`D4s z`E7NcT;$O2R_9ad{7l69v>3BdJeKF2-&f}Y`5f1aU*SxTj^QNdX{*gL& z#hmfqtMj}u? zLgzfG$T>e831Z$9t2)YaWgt}OoZl!I0Xg$CRu}S|ncN?B&VLzm?jH{U2mC(Gvp8ex zDqfW5UnEb-^H+SoY2XR$HF9}6_?&oqgb=5Ln>z8E6*!-7ys7hB8JzzdJS>rXW;{3^ zKM6k3ITCoC4el0QU3ubs&fg#&KMB4g{`eID&4*o!mD}n!b;UE7x z_;x2hPxsfsFy@zwcZ2K2csYIs`2J?V*gyYt@czy_@QtI_f=>yqcdrGv&g{VWbnuw< z_ut9EcwL}D*2{^Gy?cL+@n=Pe949(UOMeEP=D6MwC{f?*xl%Yx5^?#Bm@B34_tkUq z5?Fb=(?Zjl@KyJDH7(iPGzb_33<3rLgMdN6AYc$M2wc?&{1!hM?!>2bgz;q#gTS?n zz+1t0&hrD$E8|_Mcm&@KGKWFHAYc&q;1DPiU;W^eUjohL_}sT^?Wn-d1BP={ieE&A zGtbO12p9wm0tNwtfI+|@U=T0}7z7Lg1_6VBLBJqj5HJWB1PlUKI|5bWxHK`D91}|( z5HX&u?CeN(c+9>L8NU^kcz?4#2A^|MPr+Z17)(z89Cz{%7jbchzd>vcgTRLlfogF& z=R@a|amXNG5HJWB1PlTO0fT@+z#w1{xV{ijZ&eTK&o|oWyzQ5tJtz-%tY)}xZMQ@Z zCn$Ot{PK;uo^dYeYCh?WzWMl|+7$j;j@3c74ZL3I*b^52o_vI3kNl^6V|+kF3jG$} z_you5bFaeqtfkL#=&?_fZxn0SZrHhV?ap26ckEibR;=ByW&8Ra``7N;bnpFhx9nKE zVdLIy>$lfUU%R2M!I?Dllug^UL|mO$-j)Y9dG+I3ac$bTe%E?Ig?DbnU5=D?QM+^h zy}QjB|MC5&udqKZr%jQ*k6+A9^0oDc?wfyb|2xx3&1988n9 zFg|Af>&UNrK7)^7D8CBA`kS@<+Q_%PelLE7{+ojN-=O{qEy4I4HpnZ2@xy46F9^nO z!9MbWVEiG~r?4Ryzg^=ilt5VjZS_~!6ij~?zDHgYjL(~Y8-dKyadAhpNb0PDY8Bw&ucwY z3xe?%G~Q}UF#cl1{k^&&82>!|U3CeB#rvZ1HmYHMzhv=OQB}RU-d|Gu+KOQO5XXz! zvS9ox>aVsg82|fd60WuZ!s7p9bT9R5g6UsTf3-FU(^nkVORXZ9{#DbTKuz<-{p*_+ zzlmB{&)-shwN=6FKg0dmZL~p{{pIKZ>Q4%$FDw3HO)&nJ`7fXr*8lg77f}nxlONi6 z>!^kG^dr-kPz&?*V{%t(fw2C5!u{9P@*s?#*YToO6Rf|qdmX6f1>=M6U&$MS@vLLK zdKHBE?-bA1K^Wg{`XcJekM+3T@%UWd6wLot$NJXGg7F2%{kPTtVfHt<4^zJ+nEsgg zuc996cemsISziQU_66&21@*9gq3eT{nqdCN9ryRfvS55k^=+&R##h|Gk>>^DYmV!u zQ5KA!G`@jGSdXX3GmR1m>;JU7oAwpK?9VeFG^&E}3(Bw224VIe)p#3C5XK*I*TJ30 zgE0P>?3*PJ#vfO_=89nPe#`OtqPZ#<{~gn>qZ!8Y35~x{6-@u6;=bp{$h&u>n*{~|IbO^stKllUiE9W1>-MJ zzrB?QVevk#{#tdx^q-Y~vn3dRN$asy7L4bpcde5k%>QNUZyBvHzkg$V39Ybxz9PPv z7tH@_@-MYOnEz$#zlm1ZU!TGwtjDro_TQC#>o^Fr|Do{`T48>EEMBaDF#R(+-?!HV z^Dm@sCf^i{|5W2?R|Mlw{n};0>NlwCwRT%D{iv=N+I7MBgpOzJreJ)x*%#3c^D!;H zS{6({lj8bZ%?rk}^zX};Kv=%VQV$|kE`TszNxg|^wFSa>N$YjB2EzDeir2%d8-m3< zrTkVm1>c|Mdu>%PeqU-oc}Xz-*N*jAs|$9%Yo-`~Z3%?MKc(xDwK53f7i@hkVm++K z-w@v@2^Q}$)nl_J82<;&=jOU#{E6t>JpVNWW%r@E)eiBEm2tHx0+9PtNU!%N#=rcOvEP zK`OHoX^bF)YtiFI(SsbeVG@1rGWvNpYan_PgZM7C^G@TCyA?a!9J0J?G|W3yJKYRM z+yQzY#HgFa81G)>cn4~nf0a+TU6~T5+#04bc}(>bu$y=7u5s_d9(N!1 zx(fEDi`cvEeoVU+W_SYo-6pPe>zHvHIN%<_LH7U-X5PS|%(rl;=R=syypHR5C-Hjs z9lR^^IBrOP5;vxvz>VqO#ZBpd!MoG1VJ`h`+?+m*BmM8?=L|o;io<>Hxxh~!wz;ojz%Anz-q}0KrzuC>_i;4y1KgT<7&8MO!EKp~xIOb> z+`&6L6PX8bjE_aGT)8?w@A&dfI=IRzaHj81`}o8Ld-#dv(Jpz$51+^XRi-zPt=5 z{^M+Kpcjf0%ZeY%>Nl2^o0rjL&p2H+TQPwd9?fHWW`i7ww=UG_eHJ;(gveP0<<&3!&zR&6hiN%nQSIQF+@qdHt1+u1e7gC_fYysWvq zIQH|7{m$H(TpT}^72nG~{<+*G+HfA{fmoJJERS}{`#Q3(ZEU0bV_9<@%gV>gejd-| ze$*Mem;G@`a)UYee!VdV{2HQY8H?~kDlZk+b<8jyWFUy?%{H%yy&zwqtQv+qClvGRQ_pJb zp+1yD{9wa=x8kty$(B?gsX$VJqyk9=k_sdhNGgz2AgMr7fp@q9ycOBg{nv-*d^8+3 z-7<{$%st-bDLC}>ck_tP-s8>Nr(+7ww{>`fQnx*CbCPdmAkM$m`eKK`dt-i@LU%rK zd-88mfnQXCY~*@UNM-K~O3%-p>*i@}%T2F)1L?chV-~K5>peDy^cmW}`!?Sso<>i% zKYx)ze&>n>^!jbNBlm>(T-|Bxn7lSbWPI|TEzWxt8JuLicI+SGts0+mj(cPO6yNp; zJfjHNKq0+DuO1`XHpi#IX{1N@zdvw3(Id~ki?7>hn{yfRzH6@2j%mD~d~nZA#h5F< z{;8S#+xelzEzStpgAe|?HK>2ZpIHieX5+9uShGK}2q77oc)sk7180PL;|4$8%CDG`M)m)-3kQyQgE^az^vIz~hclmn-PbP!ZuLtau7-F%emZ+J@cFc_@A<$r zKdkp&zHMfkcm}DlQ|}4$Z~W}|&3DXuJ?GEXL&@9wdh}174goaY6#90> ze3GyF@P)ycr)2+u58n7T-apmNX`Oai-!f182sgy;nCI%1|AEkQh4CGR?v4$_(-_*f z$=Cn2DW44I`vhM+(-yDa=}>WUKfb_&{rz*dzt8N$c<(>$DSvS#`}^K|rpw;eQ)fk( zTk@4uAgMr7fusUS1(FIR75Js8K$e$d^IL!3@_Go4&m%k6>t4TQFlY8%e?J@N6<*k+ zf7X7j=NmlV8>@N!hSYqteQ3v){o8of;^~)>ej{f-_R~pg@cPc554d9XW5HV2hZ+wb z#D>jt{rbyq-d?|;@|%x08PgC?zt;1cx1Wk>(C_|V{F?uhcNB?`R3NE9Qh}rbNd=M$ zToo12eOl*IcJah}TD;^L8rs3{6w}wcZT-Vntcy?`HZ2rmoLuo zt-*c_3=G;cjb23CX_MN{?>>8zBWu@c{lk10aajM;8!&*KBmA}a&JlhOBH~ZbQz^X! zvK_ik%Gt%y5Yo&fomM_Oe7{={Q4}QEk_sdhxGE~3JMJkS1N7XI_r7@?8sHPtQ66{3 z_;yW>$C+`q?BcOxirU>gj!a+(*YLQphex1EzQ?wg@1srgZRLIR+E1@*={0jz)Git1 zFRnnOm#&g6sX$VJqyqoX3S9b=xx0V*)TIYMz5nHV|8oB$Z+-4(U;e_KbJN2ExBcwz KK3aKl@P7bvcHdI~ literal 0 HcmV?d00001 diff --git a/fedora_server.md b/fedora_server.md index 06c1b0a..0411942 100644 --- a/fedora_server.md +++ b/fedora_server.md @@ -58,7 +58,7 @@ dnf install tpm2-tss # For machines where prioritizing a secure boot environment is important we need to # specify --tpm2-pcrs=0+7 -- 0 meaning the firmware has not changed and 7 meaning # secure boot is enabled -systemd-cryptenroll /dev/nvme0n1p3 --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs=7 +systemd-cryptenroll /dev/nvme0n1p3 --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs="" # Add tpm2-tss to dracut # Edit /etc/dracut.conf.d/tpm2.conf diff --git a/wireguard/README.md b/wireguard/README.md new file mode 100644 index 0000000..b9d7b73 --- /dev/null +++ b/wireguard/README.md @@ -0,0 +1,62 @@ +# Wireguard Setup + +## Fedora + +```bash +dnf install wireguard +``` + +/etc/sysctl.d/10-wireguard.conf + +```conf +net.ipv4.ip_forward=1 +net.ipv6.conf.all.forwarding=1 +``` + +```bash +sysctl -p +``` + +### Server + +```bash +wg genkey | tee /etc/wireguard/private.key +cat /etc/wireguard/private.key | wg pubkey | tee /etc/wireguard/public.key +``` + +```bash +cat < /etc/wireguard/wg0.conf +[Interface] +Address = 10.10.10.1/24,fd10:10:10::1/64 +ListenPort = 51820 +PrivateKey = $(cat /etc/wireguard/private.key) +SaveConfig = true +PostUp = iptables -t nat -I POSTROUTING -o bridge0 -j MASQUERADE +PostUp = ip6tables -t nat -I POSTROUTING -o bridge0 -j MASQUERADE +PreDown = iptables -t nat -D POSTROUTING -o bridge0 -j MASQUERADE +PreDown = ip6tables -t nat -D POSTROUTING -o bridge0 -j MASQUERADE +EOF +``` + +```bash +wg set wg0 peer ndUMratPyYXKiOlU6AT5lYI7v3iohBAimgZY3/jsWik= allowed-ips 10.10.10.2,fd10:10:10::2 +``` + +### Client + +```conf +[interface] +PrivateKey = KHgXS7zIqqfb46cfUVKvRZesswZcvib71hhYYcN39mQ= +Address = 10.10.10.2/32,fd10:10:10::2/32 + +[Peer] +PublicKey = kzbHUGzYk6Uyan/NFYY5mh3pxf2IX/WzWZtImeyp6Sw= +Endpoint = 2600:1700:1e6c:a81f:793d:7abf:e94d:9bc4:51820 +AllowedIPs = 0.0.0.0/0,::/0 +``` + +### Testing + +```bash +curl -6 icanhazip.com +``` diff --git a/wireguard/add_client.sh b/wireguard/add_client.sh new file mode 100644 index 0000000..2da340d --- /dev/null +++ b/wireguard/add_client.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +export CLIENT_NAME=$1 +export CLIENT_IP_SUFFIX=$2 + +if [ -z $CLIENT_NAME ]; + then echo 'Client name required. `./add_client.sh client_name 3`'; + exit 1; +fi + +if [ -z $CLIENT_IP_SUFFIX ]; + then echo 'Client IP suffix. `./add_client.sh client_name 3`'; + exit 1; +fi + +export SERVER_PUBKEY=$(cat /etc/wireguard/publickey) +mkdir /etc/wireguard/$CLIENT_NAME +cd /etc/wireguard/$CLIENT_NAME +export PRIVKEY=$(wg genkey) +echo $PRIVKEY | tee $CLIENT_NAME"_privkey" +export PUBKEY=$(echo $PRIVKEY | wg pubkey) +echo $PUBKEY | tee $CLIENT_NAME"_pubkey" + +cat > $CLIENT_NAME".conf" <