Full Code of kiddin9/Kwrt for AI

25.12 9e3fbbcf5a8e cached
198 files
449.9 KB
170.4k tokens
1 requests
Download .txt
Showing preview only (501K chars total). Download the full file or copy to clipboard to get everything.
Repository: kiddin9/Kwrt
Branch: 25.12
Commit: 9e3fbbcf5a8e
Files: 198
Total size: 449.9 KB

Directory structure:
gitextract_7kdwm0il/

├── .github/
│   └── workflows/
│       ├── Openwrt-AutoBuild.yml
│       └── repo-dispatcher.yml
├── LICENSE
├── README.md
└── devices/
    ├── airoha_an7581/
    │   ├── .config
    │   ├── diy/
    │   │   └── target/
    │   │       └── linux/
    │   │           └── airoha/
    │   │               └── dts/
    │   │                   └── an7581-xg-040g-md.dts
    │   ├── diy.sh
    │   └── patches/
    │       └── xg-040g-md.patch
    ├── amlogic_meson/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       └── fix.patch
    ├── amlogic_meson8b/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       ├── BRCMFMAC_SDIO.patch
    │       └── onecloud.patch
    ├── armsr_armv8/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       └── rootfs.patch
    ├── ath79_nand/
    │   ├── .config
    │   └── diy.sh
    ├── bcm27xx_bcm2708/
    │   ├── .config
    │   └── diy.sh
    ├── bcm27xx_bcm2709/
    │   ├── .config
    │   └── diy.sh
    ├── bcm27xx_bcm2710/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       └── Zero-2.patch
    ├── bcm27xx_bcm2711/
    │   ├── .config
    │   └── diy.sh
    ├── bcm27xx_bcm2712/
    │   ├── .config
    │   └── diy.sh
    ├── bcm53xx/
    │   ├── .config
    │   └── diy.sh
    ├── common/
    │   ├── .config
    │   ├── diy/
    │   │   ├── feeds/
    │   │   │   └── luci/
    │   │   │       └── modules/
    │   │   │           └── luci-base/
    │   │   │               └── htdocs/
    │   │   │                   └── luci-static/
    │   │   │                       └── resources/
    │   │   │                           └── tools/
    │   │   │                               └── github.js
    │   │   └── package/
    │   │       ├── base-files/
    │   │       │   └── files/
    │   │       │       └── etc/
    │   │       │           └── banner
    │   │       ├── network/
    │   │       │   └── config/
    │   │       │       ├── firewall/
    │   │       │       │   ├── files/
    │   │       │       │   │   └── firewall.exwan
    │   │       │       │   └── patches/
    │   │       │       │       └── fullconenat.patch
    │   │       │       └── firewall4/
    │   │       │           ├── files/
    │   │       │           │   ├── firewall.exwan
    │   │       │           │   └── firewall.include
    │   │       │           └── patches/
    │   │       │               ├── 001-firewall4-add-support-for-fullcone-nat.patch
    │   │       │               ├── 100-fw4-support-script.patch
    │   │       │               └── 200-fw4-hotplug-fork.patch
    │   │       └── system/
    │   │           └── opkg/
    │   │               └── patches/
    │   │                   ├── 010-opkg-force-depends.patch
    │   │                   ├── ignore_error.patch
    │   │                   ├── pkg_hash.patch
    │   │                   └── zh-cn.patch
    │   ├── diy.sh
    │   ├── patches/
    │   │   ├── LINUX_VERSION.patch
    │   │   ├── autoreconf.patch
    │   │   ├── base-files.patch
    │   │   ├── china_mirrors.patch.b
    │   │   ├── cmake.patch
    │   │   ├── compressed-memory.patch.b
    │   │   ├── crontab.patch
    │   │   ├── curl.patch
    │   │   ├── default-packages.patch
    │   │   ├── disable-seccomp-ujail.patch
    │   │   ├── dnsmasq.patch
    │   │   ├── feeds.patch
    │   │   ├── firewall.patch
    │   │   ├── getcwd-fix.patch
    │   │   ├── imagebuilder.patch
    │   │   ├── kernel-defaults.patch
    │   │   ├── luci-base.patch
    │   │   ├── luci-dhcp.patch
    │   │   ├── luci-mod-system.patch
    │   │   ├── luci_mk.patch
    │   │   ├── netfilter.patch.b
    │   │   ├── netsupport.patch
    │   │   ├── nftables.patch
    │   │   ├── nginx-fancyindex.patch.bak
    │   │   ├── nonshared.patch
    │   │   ├── opkginstall.patch
    │   │   ├── package.patch
    │   │   ├── rootfs.patch
    │   │   ├── status.patch
    │   │   ├── use_json_object_new_int64.patch.b
    │   │   ├── wifi-scripts.patch
    │   │   └── wireless.patch
    │   └── settings.ini
    ├── ipq40xx_generic/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       ├── ap4220.patch
    │       ├── cm520.patch
    │       └── target.patch
    ├── ipq806x_generic/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       └── xiaomi_r3d.patch
    ├── mediatek_filogic/
    │   ├── .config
    │   ├── diy/
    │   │   └── target/
    │   │       └── linux/
    │   │           └── mediatek/
    │   │               └── dts/
    │   │                   ├── mt7981b-aigo-ags21.dts
    │   │                   ├── mt7981b-bt-r320.dts
    │   │                   ├── mt7981b-cmcc-a10.dts
    │   │                   ├── mt7981b-cmcc-mr3000d-ciq-256m.dts
    │   │                   ├── mt7981b-cmcc-rax3000m-emmc.dts
    │   │                   ├── mt7981b-cmcc-rax3000m-nand.dts
    │   │                   ├── mt7981b-cmcc-xr30-emmc.dts
    │   │                   ├── mt7981b-cmcc-xr30.dts
    │   │                   ├── mt7981b-cmcc-xr30.dtsi
    │   │                   ├── mt7981b-cudy-tr3000-mod.dts
    │   │                   ├── mt7981b-ikuai-q3000.dts
    │   │                   ├── mt7981b-konka-komi-a31.dts
    │   │                   ├── mt7981b-newland-nl-wr8103.dts
    │   │                   ├── mt7981b-nradio-c8-660.dts
    │   │                   ├── mt7981b-nradio-c8-668gl.dts
    │   │                   ├── mt7981b-philips-hy3000.dts
    │   │                   ├── mt7981b-sl-3000-emmc.dts
    │   │                   ├── mt7981b-sl-3000.dts
    │   │                   ├── mt7981b-umi-uax3000e.dts
    │   │                   ├── mt7981b-xiaomi-mi-router-wr30u.dts
    │   │                   └── mt7987a-glinet-gl-mt3600be.dts
    │   ├── diy.sh
    │   └── patches/
    │       ├── 01-360t7.patch
    │       ├── 02-ax6000.patch
    │       ├── 03-nx30.patch
    │       ├── 08-cmcc_rax3000m.patch
    │       ├── 09-jcg_q30-pro.patch
    │       ├── 12-asr3000.patch
    │       ├── 16-komi-a31.patch
    │       ├── 17-lc-hx3001.patch
    │       ├── 19-ct3003.patch
    │       ├── 20-ea0326gmp.patch
    │       ├── 22-netcore-n60-pro.patch
    │       ├── 22-netcore-n60.patch
    │       ├── 23-ax3000t.patch
    │       ├── 25-platform.patch
    │       ├── 26-ruijie-rg-x60-pro.patch
    │       ├── 99-bpi-r4-lite.patch.b
    │       ├── Winbond-NMBM-fix.patch
    │       ├── ags21.patch
    │       ├── ax6s.patch
    │       └── tr3000-mod.patch
    ├── mediatek_mt7622/
    │   ├── .config
    │   └── diy.sh
    ├── mvebu_cortexa9/
    │   ├── .config
    │   └── diy.sh
    ├── qualcommax_ipq50xx/
    │   ├── .config
    │   ├── diy/
    │   │   ├── package/
    │   │   │   └── firmware/
    │   │   │       └── ipq-wifi/
    │   │   │           └── files/
    │   │   │               ├── board-cmcc_pz-l8.ipq5018
    │   │   │               └── board-cmcc_pz-l8.qcn6122
    │   │   └── target/
    │   │       └── linux/
    │   │           └── qualcommax/
    │   │               └── files/
    │   │                   └── arch/
    │   │                       └── arm64/
    │   │                           └── boot/
    │   │                               └── dts/
    │   │                                   └── qcom/
    │   │                                       └── ipq5018-re-cs-03.dts
    │   ├── diy.sh
    │   └── patches/
    │       ├── ath11k-smallbuffers.patch
    │       ├── fix.patch
    │       └── pz-l8-enable-wifi.patch
    ├── qualcommax_ipq60xx/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       └── ax6600.patch
    ├── qualcommax_ipq807x/
    │   ├── .config
    │   ├── diy/
    │   │   └── target/
    │   │       └── linux/
    │   │           └── qualcommax/
    │   │               ├── files/
    │   │               │   └── arch/
    │   │               │       └── arm64/
    │   │               │           └── boot/
    │   │               │               └── dts/
    │   │               │                   └── qcom/
    │   │               │                       ├── ipq8071-ax3600.dts
    │   │               │                       ├── ipq8071-ax6.dts
    │   │               │                       ├── ipq8072-ax9000.dts
    │   │               │                       └── ipq8074-nss.dtsi
    │   │               └── patches-6.12/
    │   │                   └── 0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch
    │   ├── diy.sh
    │   └── patches/
    │       └── 04-stock.patch
    ├── ramips_mt7620/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       ├── mir3.patch
    │       └── tblsection.patch
    ├── ramips_mt7621/
    │   ├── .config
    │   ├── diy/
    │   │   └── target/
    │   │       └── linux/
    │   │           └── ramips/
    │   │               └── dts/
    │   │                   ├── mt7621_ht-jsh_0211.dts
    │   │                   ├── mt7621_zte_e8820s.dts
    │   │                   └── mt7621_zte_e8820v2.dts
    │   ├── diy.sh
    │   └── patches/
    │       ├── 02-cr660x.patch
    │       ├── ht-jsh_0211.patch
    │       ├── jcg_q20-pb-boot.patch
    │       ├── k2p_32m.patch
    │       ├── luban.patch
    │       ├── tblsection.patch
    │       └── zte_e8820s.patch
    ├── ramips_mt76x8/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       └── tblsection.patch
    ├── rockchip_armv8/
    │   ├── .config
    │   ├── README.md
    │   ├── diy.sh
    │   └── patches/
    │       ├── 55-xgp.patch.b
    │       ├── Photonicat_wireless.patch
    │       ├── add_extra_CPU_FLAGS.b
    │       ├── nanopi-zero2.patch
    │       └── r4s-fan.patch
    ├── siflower_sf21/
    │   ├── .config
    │   └── diy.sh
    ├── sunxi_cortexa53/
    │   ├── .config
    │   └── diy.sh
    ├── sunxi_cortexa7/
    │   ├── .config
    │   └── diy.sh
    ├── x86_64/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       ├── Intel_gpu.patch
    │       ├── def_set_interfaces_lan_wan.patch
    │       ├── image-commands.patch
    │       └── image.patch
    └── x86_generic/
        ├── .config
        ├── diy.sh
        └── patches/
            ├── image-commands.patch
            └── image.patch

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/Openwrt-AutoBuild.yml
================================================
#=================================================
# https://github.com/P3TERX/Actions-OpenWrt
# Description: Build OpenWrt using GitHub Actions
# Lisence: MIT
# Author: P3TERX
# Blog: https://p3terx.com
#=================================================

name: Build OpenWrt

on: 
  repository_dispatch:

env:
  REPO_TOKEN: ${{ secrets.TOKEN_KIDDIN9 }}
  PPPOE_USERNAME: ${{ secrets.PPPOE_USERNAME }}
  PPPOE_PASSWD: ${{ secrets.PPPOE_PASSWD }}
  SCKEY: ${{ secrets.SCKEY }}
  TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
  TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
  SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
  DOCKER_ID: ${{ secrets.DOCKER_ID }}
  DOCKER_PASSWD: ${{ secrets.DOCKER_PASSWD }}
  TZ: Asia/Shanghai

jobs:
  build:
    runs-on: ubuntu-latest
    
    name: Build ${{matrix.target}}
    strategy:
      fail-fast: false
      matrix:
        target: ["${{ github.event.client_payload.target }}"]
        
    steps:
    - name: Checkout
      uses: actions/checkout@main
      with:
          fetch-depth: 0

    # - name: Set up secret file
      # run: |
        # echo ${{ secrets.TELEGRAM_CHAT_ID }} | sed 's/./& /g'
        # echo ${{ secrets.TELEGRAM_TOKEN }} | sed 's/./& /g'

    - name: Load Settings.ini
      run: |
        echo ${{matrix.target}}
        source "${{ github.workspace }}/devices/common/settings.ini"
        if [ -f "devices/${{matrix.target}}/settings.ini" ]; then
          source "${{ github.workspace }}/devices/${{matrix.target}}/settings.ini"
        fi
        echo "REPO_URL=${REPO_URL}" >> $GITHUB_ENV
        echo "REPO_BRANCH=${REPO_BRANCH}" >> $GITHUB_ENV
        echo "CONFIG_FILE=${CONFIG_FILE}" >> $GITHUB_ENV
        echo "DIY_SH=${DIY_SH}" >> $GITHUB_ENV
        echo "FREE_UP_DISK=${FREE_UP_DISK}" >> $GITHUB_ENV
        echo "UPLOAD_BIN_DIR_FOR_ARTIFACT=${UPLOAD_BIN_DIR_FOR_ARTIFACT}" >> $GITHUB_ENV
        echo "UPLOAD_FIRMWARE_FOR_ARTIFACT=${UPLOAD_FIRMWARE_FOR_ARTIFACT}" >> $GITHUB_ENV
        echo "UPLOAD_FIRMWARE_FOR_RELEASE=${UPLOAD_FIRMWARE_FOR_RELEASE}" >> $GITHUB_ENV
        echo "UPLOAD_FIRMWARE_TO_COWTRANSFER=${UPLOAD_FIRMWARE_TO_COWTRANSFER}" >> $GITHUB_ENV
        echo "UPLOAD_FIRMWARE_TO_WETRANSFER=${UPLOAD_FIRMWARE_TO_WETRANSFER}" >> $GITHUB_ENV
        sed -i "1a REPO_TOKEN=${{ secrets.TOKEN_KIDDIN9 }}" ${{ github.workspace }}/devices/common/diy.sh
        sed -i "1a TARGET=${{matrix.target}}" ${{ github.workspace }}/devices/common/diy.sh

    - name: Trigger Packages Update
      continue-on-error: true
      if: contains(github.event.action, 'pkg')
      run: |
        status=$(curl -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" -s "https://api.github.com/repos/kiddin9/op-packages/actions/runs" | jq -r '.workflow_runs[0].status')
        if [[ "$status" == "completed" ]]; then
          curl -X POST https://api.github.com/repos/kiddin9/op-packages/dispatches \
            -H "Accept: application/vnd.github.everest-preview+json" \
            -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          --data '{"event_type": "update"}'
        fi

    - name: Free disk space
      uses: coder-xiaomo/free-disk-space@main
      with:
        tool-cache: false
        android: true
        dotnet: true
        haskell: true
        large-packages: true
        docker-images: true
        swap-storage: true

    - name: Initialization environment
      env:
        DEBIAN_FRONTEND: noninteractive
      run: |
        sudo -E apt-get -qq update
        sudo -E apt-get -qq install build-essential clang flex bison g++ gawk \
        gcc-multilib g++-multilib gettext git libncurses5-dev libssl-dev \
        python3-setuptools rsync swig unzip zlib1g-dev file wget \
        llvm python3-pyelftools libpython3-dev aria2 jq qemu-utils ccache rename \
        libelf-dev device-tree-compiler libgmp3-dev libmpc-dev libfuse-dev
        sudo -E apt-get -qq autoremove --purge
        sudo -E apt-get -qq clean
        sudo timedatectl set-timezone "Asia/Shanghai"
        git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
        git config --global user.name "github-actions[bot]"

    - name: Get current date
      id: date
      run: |
        echo "date=$(date +'%m/%d_%Y_%H/%M')" >> $GITHUB_ENV
        echo "date2=$(date +'%m/%d %Y')" >> $GITHUB_ENV
        VERSION="$(echo "${{github.event.action}}" | grep -Eo " [0-9.]+" | sed -e 's/ //')" || true
        [ "$VERSION" ] && echo "VERSION=$VERSION" >> $GITHUB_ENV || echo "VERSION=$(date +'%m.%d')" >> $GITHUB_ENV

    - name: Clone source code
      run: |
        set -x
        TAG_INFO="$(curl -gs -H 'Content-Type: application/json' \
           -H "Authorization: Bearer ${{ secrets.TOKEN_KIDDIN9 }}" \
           -X POST -d '{ "query": "query {repository(owner: \"openwrt\", name: \"openwrt\") {refs(refPrefix: \"refs/tags/\", first: 4, orderBy: {field: TAG_COMMIT_DATE, direction: DESC}) {nodes {name target { ... on Tag {tagger {date}}}}}}}"}' https://api.github.com/graphql)"
        TAG_DATE="$( echo ${TAG_INFO} | jq -r '.data.repository.refs.nodes[] | select(.name | startswith("v25")) | .target.tagger.date' | head -n 1)"
        if [[ $(( ($(date +%s) - $(date -d "$TAG_DATE" +%s)) / 86400 )) -lt 10 || "${{ contains(github.event.action, 'tags') }}" == "true" ]]; then
        REPO_BRANCH="$( echo ${TAG_INFO} | jq -r '.data.repository.refs.nodes[].name' | grep v25 | head -n 1)"
        #REPO_BRANCH="openwrt-25.12"
        else
        REPO_BRANCH="openwrt-25.12"
        fi
        #echo "CONFIG_VERSION_REPO=\"https://dl.openwrt.ai/releases/`echo $REPO_BRANCH  | cut -d . -f 1,2 | sed -e 's/^v//'`\"">>devices/common/.config
        echo "CONFIG_VERSION_REPO=\"https://dl.openwrt.ai/releases/25.12\"">>devices/common/.config
        if [[ ! "${{ env.REPO_BRANCH }}" && "$REPO_URL" == "https://github.com/openwrt/openwrt" ]]; then
            git clone $REPO_URL -b $REPO_BRANCH openwrt
        elif [[ ! "${{ env.REPO_BRANCH }}" ]]; then
            git clone $REPO_URL openwrt
        else
            REPO_BRANCH="${{env.REPO_BRANCH}}"
            if [[ ${#REPO_BRANCH} -lt 10 ]]; then
                git clone $REPO_URL -b ${REPO_BRANCH} openwrt
            else
                git clone $REPO_URL openwrt
                cd openwrt
                git checkout ${REPO_BRANCH}
            fi
        fi

    - name: Free up disk space
      env:
        DEBIAN_FRONTEND: noninteractive
      run: |
        sudo mkdir -p -m 777 /mnt/openwrt/build_dir openwrt/staging_dir
        ln -sf /mnt/openwrt/build_dir openwrt/build_dir
        sudo ln -sf openwrt/staging_dir /mnt/openwrt/staging_dir

    - name: Load custom configuration
      run: |
        function git_clone_path() {
          trap 'rm -rf "$tmpdir"' EXIT
          branch="$1" rurl="$2" mv="$3"
          [[ "$mv" != "mv" ]] && shift 2 || shift 3
          rootdir="$PWD"
          tmpdir="$(mktemp -d)" || exit 1
          if [ ${#branch} -lt 10 ]; then
          git clone -b "$branch" --depth 1 --filter=blob:none --sparse "$rurl" "$tmpdir"
          cd "$tmpdir"
          else
          git clone --filter=blob:none --sparse "$rurl" "$tmpdir"
          cd "$tmpdir"
          git checkout $branch
          fi
          if [ "$?" != 0 ]; then
            echo "error on $rurl"
            exit 1
          fi
          git sparse-checkout init --cone
          git sparse-checkout set $@
          [[ "$mv" != "mv" ]] && cp -rn ./* $rootdir/ || mv -n $@/* $rootdir/$@/
          cd $rootdir
          }
        export -f git_clone_path
        cp -rf devices/common/. openwrt/
        cp -rf devices/${{matrix.target}}/. openwrt/
        cp -rf devices openwrt/
        cd openwrt
        chmod +x devices/common/$DIY_SH
        /bin/bash "devices/common/$DIY_SH"
        cp -f devices/common/$CONFIG_FILE .config
        if [ -f "devices/${{matrix.target}}/$CONFIG_FILE" ]; then
          echo >> .config
          cat devices/${{matrix.target}}/$CONFIG_FILE >> .config
        fi
        if [ -f "devices/${{matrix.target}}/$DIY_SH" ]; then
          chmod +x devices/${{matrix.target}}/$DIY_SH
          echo "/bin/bash devices/${{matrix.target}}/$DIY_SH"
          /bin/bash "devices/${{matrix.target}}/$DIY_SH"
        fi
        cp -Rf ./diy/* ./ || true

    - name: Apply patches
      run: |
        cd openwrt
        cp -rn devices/common/patches devices/${{matrix.target}}/
          if [ -n "$(ls -A devices/${{matrix.target}}/*.bin.patch 2>/dev/null)" ]; then
            git apply devices/${{matrix.target}}/patches/*.bin.patch
          fi
          find "devices/${{matrix.target}}/patches" -maxdepth 1 -type f -name '*.revert.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "patch -d './' -R --no-backup-if-mismatch -p1 -F 1 --ignore-whitespace -i '%'"
          find "devices/${{matrix.target}}/patches" -maxdepth 1 -type f -name '*.patch' ! -name '*.revert.patch' ! -name '*.bin.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "patch -d './' --no-backup-if-mismatch -p1 -F 1 --ignore-whitespace -i '%'"

    - name: Defconfig
      run: |
        cd openwrt
        make defconfig
        if [[ ! "${{matrix.target}}" =~ (amlogic_meson8b|armsr_armv8|bcm27xx_*|rockchip_armv8|sunxi_*|x86_*|siflower_*) ]]; then
        sed -n '/# Wireless Drivers/,/# end of Wireless Drivers/p' .config | sed -e 's/=m/=n/' >>.config
        sed -i "s/\(kmod-qca.*\)=m/\1=n/" .config
        make defconfig
        fi
        cat .config

    - name: Cache
      uses: stupidloud/cachewrtbuild@main
      with:
        ccache: 'false'
        mixkey: ${{ matrix.target }}
        clean: ${{ contains(github.event.action, 'nocache') }}
        prefix: ${{ github.workspace }}/openwrt

    - name: SSH connection to Actions
      uses: kiddin9/debugger-action@master
      if: contains(github.event.action, 'ssh')

    - name: Compile the firmware
      id: compile
      run: |
        shopt -s extglob
        df -hT
        cd openwrt
        echo -e "$(($(nproc)+1)) thread compile"
        make -j$(($(nproc)+1)) || { log=$(mktemp);make V=s &>$log; } || { tail -50 $log; curl -k --data chat_id="${{ env.TELEGRAM_CHAT_ID }}" --data "text=❌ OpenWrt ${{ env.VERSION }} ${{matrix.target}} 编译失败 😂" "https://api.telegram.org/bot${{ env.TELEGRAM_TOKEN }}/sendMessage";df -hT;exit 1; }
        rm -rf staging_dir/toolchain-*/bin/*openwrt-linux-musl-lto-dump
        rm -rf staging_dir/toolchain-*/initial
        df -hT

    - name: Organize files
      id: organize
      continue-on-error: true
      run: |
        shopt -s extglob
        cd openwrt/bin/targets/*/*/
        cp $GITHUB_WORKSPACE/openwrt/.config ${{matrix.target}}.config || true
        cp $GITHUB_WORKSPACE/openwrt/build_dir/target-*/linux-*/linux-*/.config ${{matrix.target}}_kernel.config || true
        Emoji=("🎉" "🤞" "✨" "🎁" "🎈" "🎄" "🎨" "💋" "🍓" "🍕" "🍉" "💐" "🌴" "🚀" "🛸" "🗽" "⛅" "🌈" "🔥" "⛄" "🐶" "🏅" "🦄" "🐤")
        echo "EMOJI=${Emoji[$[$RANDOM % ${#Emoji[@]}]]}" >> $GITHUB_ENV

    - name: Deploy imagebuilder to server
      uses: easingthemes/ssh-deploy@main
      if: env.SSH_PRIVATE_KEY && ! contains(github.event.action, 'noser')
      with:
        SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
        ARGS: "-avr --timeout=600 --include='kwrt-imagebuilder-*' --include='kwrt-*-initramfs*' --exclude='kwrt-*'"
        SSH_CMD_ARGS: "-o ServerAliveInterval=30 -o ServerAliveCountMax=10 -o StrictHostKeyChecking=no"
        SOURCE: openwrt/bin/targets
        REMOTE_HOST: ${{ secrets.SERVER_HOST }}
        REMOTE_USER: ${{ secrets.SERVER_USERNAME }}
        REMOTE_PORT: ${{ secrets.SERVER_PORT }}
        TARGET: "/www/wwwroot/dl.openwrt.ai/releases/tmp/"

    - name: Upload firmware for artifact
      uses: actions/upload-artifact@main
      if: env.UPLOAD_FIRMWARE_FOR_ARTIFACT == 'true'
      with:
        name: ${{ env.VERSION }}_${{matrix.target}}
        path: |
          openwrt/bin/targets/

    - name: Create release
      id: create_release
      if: env.REPO_TOKEN && env.UPLOAD_FIRMWARE_FOR_RELEASE == 'true'
      continue-on-error: true
      run: |
        echo -e "墙内加速下载 🚀:\n" >> release.txt
        echo -e "[腾讯云] (https://dl.openwrt.ai/firmware/${{matrix.target}}/ ☁)\n" >> release.txt
        [ ${{ env.WETRANS }} ] && echo -e "[WeTransfer] (${{ env.WETRANS }} 🗽)\n" >> release.txt
        [ ${{ env.COWURL }} ] && echo -e "[奶牛上传] (${{ env.COWURL }} 🐮)\n" >> release.txt
        [ ${{ env.NOTICE }} ] && echo -e "${{ env.NOTICE }}" >> release.txt || true

    - name: Upload firmware for release
      uses: softprops/action-gh-release@master
      continue-on-error: true
      if: env.REPO_TOKEN && env.UPLOAD_FIRMWARE_FOR_RELEASE == 'true'
      env:
        GITHUB_TOKEN: ${{ secrets.TOKEN_KIDDIN9 }}
      with:
        files: "${{ env.FIRMWARE }}/*"
        name: ${{ env.date2 }} ${{matrix.target}} ${{ env.EMOJI }}
        tag_name: ${{ env.date }}_${{matrix.target}}
        body_path: release.txt
    
    - name: WeChat notification
      continue-on-error: true
      if: env.SCKEY
      run: |
        # [ steps.compile.outputs.status == 'success' ] && curl https://sctapi.ftqq.com/${{ secrets.SCKEY }}.send?text=🎉OpenWrt_${{ env.VERSION }}_${{matrix.target}}编译完成😋|| curl https://sctapi.ftqq.com/${{ secrets.SCKEY }}.send?text=❌OpenWrt_${{ env.VERSION }}_${{matrix.target}}编译失败😂

    - name: Telegram notification
      if: env.TELEGRAM_TOKEN && ! contains(github.event.action, 'notg')
      continue-on-error: true
      run: |
        curl -k --data chat_id="${{ env.TELEGRAM_CHAT_ID }}" --data "text=🎉 OpenWrt ${{ env.VERSION }} ${{matrix.target}} 编译成功 😋  https://dl.openwrt.ai/firmware/${{matrix.target}}/  ${{ env.COWURL }}   ${{ env.WETRANS }} 🚀" "https://api.telegram.org/bot${{ env.TELEGRAM_TOKEN }}/sendMessage"

    - name: Delete workflow runs
      uses: GitRML/delete-workflow-runs@main
      continue-on-error: true
      with:
        token: ${{ secrets.TOKEN_KIDDIN9 }}
        retain_days: 100
        keep_minimum_runs: 0

    - name: Remove old Releases
      uses: dev-drprasad/delete-older-releases@master
      continue-on-error: true
      if: env.UPLOAD_FIRMWARE_FOR_RELEASE == 'true' && !cancelled()
      with:
        keep_latest: 15
        delete_tags: true
      env:
        GITHUB_TOKEN: ${{ secrets.TOKEN_KIDDIN9 }}


================================================
FILE: .github/workflows/repo-dispatcher.yml
================================================
#=================================================
# https://github.com/P3TERX/Actions-OpenWrt
# Description: Build OpenWrt using GitHub Actions
# Lisence: MIT
# Author: P3TERX
# Blog: https://p3terx.com
#=================================================

name: Repo Dispatcher

on: 
  # push: 
  #   branches:
  #     - master
  #schedule:
  #  - cron: 30 18 * * *
  workflow_dispatch:
    inputs:
      param:
        description: 'parameter'
        required: false
        default: ''

env:
  TOKEN_KIDDIN9: ${{ secrets.TOKEN_KIDDIN9 }}
  TZ: Asia/Shanghai

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@main

    - name: cancel running workflows
      uses: styfle/cancel-workflow-action@main
      if: contains(github.event.inputs.param, 'cw')
      with:
        workflow_id: all
        access_token: ${{ secrets.TOKEN_KIDDIN9 }}

    - name: Load Settings.ini
      run: |
        source "${GITHUB_WORKSPACE}/devices/common/settings.ini"
        if [ -f "devices/${{matrix.target}}/settings.ini" ]; then
          source "${GITHUB_WORKSPACE}/devices/${{matrix.target}}/settings.ini"
        fi
        echo "REPO_URL=${REPO_URL}" >> $GITHUB_ENV
        echo "REPO_BRANCH=${REPO_BRANCH}" >> $GITHUB_ENV

    - name: Trigger Packages Update
      continue-on-error: true
      run: |
        gitdate=$(curl -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" -s "https://api.github.com/repos/kiddin9/op-packages/actions/runs" | jq -r '.workflow_runs[0].created_at')
        gitdate=$(date -d "$gitdate" +%s)
        now=$(date -d "$(date)" +%s)
        if [[ $(expr $gitdate + 120) < $now ]]; then
        curl -X POST https://api.github.com/repos/kiddin9/op-packages/dispatches \
        -H "Accept: application/vnd.github.everest-preview+json" \
        -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
        --data '{"event_type": "update"}'
        fi

    - name: Trigger Compile
      run: |
        sudo timedatectl set-timezone "$TZ"
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "x86_64 ${{ github.event.inputs.param }}", "client_payload": {"target": "x86_64"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "x86_generic ${{ github.event.inputs.param }}", "client_payload": {"target": "x86_generic"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "rockchip_armv8 ${{ github.event.inputs.param }}", "client_payload": {"target": "rockchip_armv8"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "bcm27xx_bcm2712 ${{ github.event.inputs.param }}", "client_payload": {"target": "bcm27xx_bcm2712"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "bcm27xx_bcm2711 ${{ github.event.inputs.param }}", "client_payload": {"target": "bcm27xx_bcm2711"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "bcm27xx_bcm2710 ${{ github.event.inputs.param }}", "client_payload": {"target": "bcm27xx_bcm2710"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "bcm27xx_bcm2709 ${{ github.event.inputs.param }}", "client_payload": {"target": "bcm27xx_bcm2709"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "bcm27xx_bcm2708 ${{ github.event.inputs.param }}", "client_payload": {"target": "bcm27xx_bcm2708"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "armsr_armv8 ${{ github.event.inputs.param }}", "client_payload": {"target": "armsr_armv8"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "mediatek_mt7622 ${{ github.event.inputs.param }}", "client_payload": {"target": "mediatek_mt7622"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "mediatek_filogic ${{ github.event.inputs.param }}", "client_payload": {"target": "mediatek_filogic"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "qualcommax_ipq50xx ${{ github.event.inputs.param }}", "client_payload": {"target": "qualcommax_ipq50xx"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "ramips_mt7621 ${{ github.event.inputs.param }}", "client_payload": {"target": "ramips_mt7621"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "ramips_mt7620 ${{ github.event.inputs.param }}", "client_payload": {"target": "ramips_mt7620"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "ramips_mt76x8 ${{ github.event.inputs.param }}", "client_payload": {"target": "ramips_mt76x8"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "qualcommax_ipq807x ${{ github.event.inputs.param }}", "client_payload": {"target": "qualcommax_ipq807x"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "ipq40xx_generic ${{ github.event.inputs.param }}", "client_payload": {"target": "ipq40xx_generic"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "ipq806x_generic ${{ github.event.inputs.param }}", "client_payload": {"target": "ipq806x_generic"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "amlogic_meson8b ${{ github.event.inputs.param }}", "client_payload": {"target": "amlogic_meson8b"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "qualcommax_ipq60xx ${{ github.event.inputs.param }}", "client_payload": {"target": "qualcommax_ipq60xx"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "mvebu_cortexa9 ${{ github.event.inputs.param }}", "client_payload": {"target": "mvebu_cortexa9"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "bcm53xx ${{ github.event.inputs.param }}", "client_payload": {"target": "bcm53xx"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "sunxi_cortexa53 ${{ github.event.inputs.param }}", "client_payload": {"target": "sunxi_cortexa53"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "sunxi_cortexa7 ${{ github.event.inputs.param }}", "client_payload": {"target": "sunxi_cortexa7"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "ath79_nand ${{ github.event.inputs.param }}", "client_payload": {"target": "ath79_nand"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "amlogic_meson ${{ github.event.inputs.param }}", "client_payload": {"target": "amlogic_meson"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "airoha_an7581 ${{ github.event.inputs.param }}", "client_payload": {"target": "airoha_an7581"}}'
          curl \
          -X POST https://api.github.com/repos/${{ github.repository }}/dispatches \
          -H "Accept: application/vnd.github.everest-preview+json" \
          -H "Authorization: token ${{ secrets.TOKEN_KIDDIN9 }}" \
          -d '{"event_type": "siflower_sf21 ${{ github.event.inputs.param }}", "client_payload": {"target": "siflower_sf21"}}'


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2019 P3TERX

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.


================================================
FILE: README.md
================================================
#### 一分钟在线编译定制专属固件: [openwrt.ai](https://openwrt.ai)

### openwrt 软路由固件

## Acknowledgments

- [OpenWrt](https://github.com/openwrt/openwrt)
- [Lean's OpenWrt](https://github.com/coolsnowwolf/lede)
- [ImmortalWrt](https://github.com/immortalwrt/immortalwrt)
- [unifreq](https://github.com/unifreq/openwrt_packit)
- [ophub](https://github.com/ophub/amlogic-s9xxx-openwrt)
- [hanwckf](https://github.com/hanwckf/immortalwrt-mt798x)
- [P3TERX](https://github.com/P3TERX/Actions-OpenWrt)
- [aparcar](https://github.com/openwrt/asu)
- [GitHub](https://github.com)
- [GitHub Actions](https://github.com/features/actions)


================================================
FILE: devices/airoha_an7581/.config
================================================

CONFIG_TARGET_airoha=y
CONFIG_TARGET_airoha_an7581=y

CONFIG_TARGET_DEVICE_airoha_an7581_DEVICE_airoha_an7581-evb-emmc=n
CONFIG_TARGET_DEVICE_airoha_an7581_DEVICE_airoha_an7581-evb=n

CONFIG_PACKAGE_kmod-sound-midi2=n
CONFIG_PACKAGE_kmod-sound-midi2-seq=n


================================================
FILE: devices/airoha_an7581/diy/target/linux/airoha/dts/an7581-xg-040g-md.dts
================================================
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/dts-v1/;

#include <dt-bindings/leds/common.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "an7581.dtsi"

/ {
    model = "Nokia Bell XG-040G-MD";
    compatible = "bell,xg-040g-md", "airoha,an7581";

    efuse-banks {
        compatible = "airoha,an7581-efuses";
        #address-cells = <0x01>;
        #size-cells = <0x00>;

        bank@0 {
            reg = <0x00>;
        };

        bank@1 {
            reg = <0x01>;
        };
    };

    aliases {
        serial0 = &uart1;
    };

    chosen {
        bootargs = "console=ttyS0,115200n8 loglevel=7  earlycon";
        stdout-path = "serial0:115200n8";
        bootargs-append = " ubi.mtd=rootfs,2048 rootfstype=squashfs loglevel=8 ubi.block=0,rootfs ro init=/etc/preinit";
    };

    memory@80000000 {
        device_type = "memory";
        reg = <0x0 0x80000000 0x2 0x00000000>;
    };

	leds {
		compatible = "gpio-leds";

		led-0 {
			label = "pwr";
			color = <0x01>;
			function = "power";
			gpios = <0x24 0x11 0x01>;
			default-state = "on";
		};

		led-2 {
			label = "pon";
			color = <0x02>;
			function = "status";
			gpios = <0x24 0x13 0x01>;
			default-state = "off";
		};

		led-3 {
			label = "internet";
			color = <0x02>;
			function = "status";
			gpios = <0x24 0x14 0x01>;
			default-state = "on";
		};
	};
};

&en7581_pinctrl {
    gpio-ranges = <&en7581_pinctrl 0 13 47>;

    mdio_pins: mdio-pins {
        mux {
            function = "mdio";
            groups = "mdio";
        };

        conf {
            pins = "gpio2";
            output-high;
        };
    };

    pcie0_rst_pins: pcie0-rst-pins {
        conf {
            pins = "pcie_reset0";
            drive-open-drain = <1>;
        };
    };

    pcie1_rst_pins: pcie1-rst-pins {
        conf {
            pins = "pcie_reset1";
            drive-open-drain = <1>;
        };
    };

    gswp1_led0_pins: gswp1-led0-pins {
        mux {
            function = "phy1_led0";
            pins = "gpio33";
        };
    };

    gswp2_led0_pins: gswp2-led0-pins {
        mux {
            function = "phy2_led0";
            pins = "gpio34";
        };
    };

    gswp3_led0_pins: gswp3-led0-pins {
        mux {
            function = "phy3_led0";
            pins = "gpio35";
        };
    };

    gswp4_led0_pins: gswp4-led0-pins {
        mux {
            function = "phy4_led0";
            pins = "gpio42";
        };
    };

    pwm_gpio18_idx10_pins: pwm-gpio18-idx10-pins {
        function = "pwm";
        pins = "gpio18";
        output-enable;
    };
};

&snfi {
	status = "okay";
};


&spi_nand {
	#address-cells = <1>;
	#size-cells = <1>;
        partitions {
        compatible = "fixed-partitions";
		    #address-cells = <1>;
		    #size-cells = <1>;

            partition@0 {
                label = "bootloader";
                reg = <0x0  0x00080000>;
                read-only;
            };

            partition@80000  {
                label = "env";
                reg = <0x00080000 0x00080000>;
            };

            partition@100000 {
                label = "ubi";
                reg = <0x00100000  0x00>;
    		};
     };
};

&i2c0 {
    status = "okay";
};

&npu {
	status = "okay";
};

&eth {
	status = "okay";
};

&gdm1 {
	status = "okay";
};

&gdm4 {
	status = "okay";
	phy-handle = <&phy15>;
	phy-mode = "2500base-x";
	label = "lan1";
};

&switch {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&mdio_pins>;

	ports {
		port@2 {
			status = "okay";
			label = "lan2";
		};

		port@3 {
			status = "okay";
			label = "lan3";
		};

		port@4 {
			status = "okay";
			label = "lan4";
		};
	};

	mdio {
		ethernet-phy@1 {
			status = "okay";
			pinctrl-names = "gbe-led";
			pinctrl-0 = <&gswp2_led0_pins>;

			leds {
				gsw-phy1-led0@0 {
					reg = <0x00>;
					function = LED_FUNCTION_LAN;
					status = "okay";
					active-low;
				};
			};
		};

		ethernet-phy@2 {
			status = "okay";
			pinctrl-names = "gbe-led";
			pinctrl-0 = <&gswp3_led0_pins>;

			leds {
				gsw-phy2-led0@0 {
					reg = <0x00>;
					function = LED_FUNCTION_LAN;
					status = "okay";
					active-low;
				};
			};
		};

		ethernet-phy@3 {
			status = "okay";
			pinctrl-names = "gbe-led";
			pinctrl-0 = <&gswp4_led0_pins>;

			leds {
				gsw-phy3-led0@0 {
					reg = <0x00>;
					function = LED_FUNCTION_LAN;
					status = "okay";
					active-low;
				};
			};
		};

		phy15: ethernet-phy@f {
			/* Airoha EN8811H */
			compatible = "ethernet-phy-id03a2.a411", "ethernet-phy-ieee802.3-c45";
			reg = <15>;
            phy-mode = "2500base-x";
			phandle = <0x38>;
		};
	};
};


================================================
FILE: devices/airoha_an7581/diy.sh
================================================
#!/bin/bash


================================================
FILE: devices/airoha_an7581/patches/xg-040g-md.patch
================================================
--- a/target/linux/airoha/image/an7581.mk
+++ b/target/linux/airoha/image/an7581.mk
@@ -42,3 +42,25 @@ define Device/airoha_an7581-evb-emmc
   ARTIFACTS := preloader.bin bl31-uboot.fip
 endef
 TARGET_DEVICES += airoha_an7581-evb-emmc
+
+define Device/bell_xg-040g-md
+  $(call Device/FitImageLzma)
+  DEVICE_VENDOR := Nokia Bell
+  DEVICE_MODEL := XG-040G-MD
+  DEVICE_DTS := an7581-xg-040g-md
+  DEVICE_DTS_CONFIG := config@1
+  KERNEL_LOADADDR := 0x80088000
+  UBINIZE_OPTS := -E 5
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  KERNEL_SIZE := 10240k
+  IMAGE_SIZE := 261120k
+  KERNEL_IN_UBI := 1
+  UBINIZE_OPTS := -m 2048 -p 128KiB -s 2048
+  DEVICE_PACKAGES := airoha-en7581-npu-firmware kmod-phy-airoha-en8811h kmod-i2c-an7581 kmod-input-gpio-keys-polled
+  IMAGES += factory.bin sysupgrade.bin
+  IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+  SOC := an7581
+endef
+TARGET_DEVICES += bell_xg-040g-md

--- a/target/linux/airoha/an7581/base-files/etc/board.d/02_network
+++ b/target/linux/airoha/an7581/base-files/etc/board.d/02_network
@@ -14,6 +14,9 @@ an7581_setup_interfaces()
 	airoha,an7581-evb)
 		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "eth1"
 		;;
+	bell,xg-040g-md)
+		ucidef_set_interfaces_lan_wan "lan2 lan3 lan4" "eth1"
+		;;
 	*)
 		echo "Unsupported hardware. Network interfaces not initialized"
 		;;

new file mode 100644
index 00000000000000..556caa19fe6d14
--- /dev/null
+++ b/target/linux/airoha/an7581/base-files/lib/upgrade/platform.sh
@@ -0,0 +1,15 @@
+REQUIRE_IMAGE_METADATA=1
+
+platform_do_upgrade() {
+    local board=$(board_name)
+
+    case "$board" in
+    *)
+        nand_do_upgrade "$1"
+        ;;
+    esac
+}
+
+platform_check_image() {
+    return 0
+}


================================================
FILE: devices/amlogic_meson/.config
================================================

CONFIG_TARGET_amlogic=y
CONFIG_TARGET_amlogic_meson=y
CONFIG_TARGET_MULTI_PROFILE=y
CONFIG_TARGET_ALL_PROFILES=y

CONFIG_PACKAGE_kmod-pcie_mhi=n


================================================
FILE: devices/amlogic_meson/diy.sh
================================================
#!/bin/bash

shopt -s extglob

git_clone_path istoreos-24.10 https://github.com/istoreos/istoreos target/linux/amlogic package/boot/uboot-amlogic-prebuilt

mv -f target/linux/amlogic/patches-6.6 target/linux/amlogic/patches-6.12
mv -f target/linux/amlogic/meson/config-6.6 target/linux/amlogic/meson/config-6.12

sed -i "s/KERNEL_PATCHVER:=6.6/KERNEL_PATCHVER:=6.12/" target/linux/amlogic/Makefile

rm -rf package/kernel/r81*





================================================
FILE: devices/amlogic_meson/patches/fix.patch
================================================
--- a/package/kernel/mac80211/broadcom.mk
+++ b/package/kernel/mac80211/broadcom.mk
@@ -432,6 +432,7 @@ define KernelPackage/brcmfmac/config
 
 	config BRCMFMAC_SDIO
 		bool "Enable SDIO bus interface support"
+		default y if TARGET_amlogic
 		default y if TARGET_bcm27xx
 		default y if TARGET_imx_cortexa7
 		default y if TARGET_starfive


================================================
FILE: devices/amlogic_meson8b/.config
================================================

CONFIG_TARGET_amlogic=y
CONFIG_TARGET_amlogic_meson8b=y
CONFIG_TARGET_amlogic_meson8b_DEVICE_thunder-onecloud=y

CONFIG_TARGET_ROOTFS_SQUASHFS=n
CONFIG_TARGET_ROOTFS_EXT4FS=y



================================================
FILE: devices/amlogic_meson8b/diy.sh
================================================
#!/bin/bash

shopt -s extglob

SHELL_FOLDER=$(dirname $(readlink -f "$0"))

#bash $SHELL_FOLDER/../common/kernel_6.1.sh

#rm -rf package/kernel/mac80211

#git_clone_path c640f7b93736621b4d56627e4f6ab824093f9c3d https://github.com/openwrt/openwrt package/kernel/mac80211


git_clone_path main https://github.com/lxiaya/openwrt-onecloud target/linux/amlogic

mv -f target/linux/amlogic/patches-6.6 target/linux/amlogic/patches-6.12
mv -f target/linux/amlogic/meson8b/config-6.6 target/linux/amlogic/meson8b/config-6.12

sed -i "s/KERNEL_PATCHVER:=6.6/KERNEL_PATCHVER:=6.12/" target/linux/amlogic/Makefile

sed -i "s/wpad-openssl/wpad-basic-mbedtls/" target/linux/amlogic/image/Makefile

sed -i "s/neon-vfpv4/vfpv4/" target/linux/amlogic/meson8b/target.mk




================================================
FILE: devices/amlogic_meson8b/patches/BRCMFMAC_SDIO.patch
================================================
--- a/package/kernel/mac80211/broadcom.mk
+++ b/package/kernel/mac80211/broadcom.mk
@@ -432,6 +432,7 @@ define KernelPackage/brcmfmac/config
 
 	config BRCMFMAC_SDIO
 		bool "Enable SDIO bus interface support"
+		default y if TARGET_amlogic
 		default y if TARGET_bcm27xx
 		default y if TARGET_imx_cortexa7
 		default y if TARGET_starfive


================================================
FILE: devices/amlogic_meson8b/patches/onecloud.patch
================================================
--- a/target/linux/amlogic/image/Makefile
+++ b/target/linux/amlogic/image/Makefile
@@ -36,7 +36,7 @@ endef
 ### Devices ###
 define Device/Default
   FILESYSTEMS := ext4
-  IMAGES := emmc.img
+  IMAGES := emmc_burn.img
   KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts)
   KERNEL_LOADADDR := 0x01080000
   KERNEL_NAME := Image
@@ -46,12 +46,19 @@ endef
 
 define Device/thunder-onecloud
   DEVICE_DTS := amlogic/meson8b-onecloud
-  DEVICE_TITLE := Thunder OneCloud
+  DEVICE_TITLE := OneCloud 玩客云
+  DEVICE_PACKAGES += kmod-usb-net-rtl8152
   KERNEL_LOADADDR := 0x00208000
-  IMAGE/emmc.img := boot-script onecloud | emmc-common $$(DEVICE_NAME)
+  IMAGE/emmc_burn.img := boot-script onecloud | emmc-common $$(DEVICE_NAME)
 endef
 ifeq ($(SUBTARGET),meson8b)
   TARGET_DEVICES += thunder-onecloud
 endif
 
+define Image/Build
+  export BIN_DIR=$(BIN_DIR); \
+  cd /data/packit/openwrt-onecloud; \
+  . ~/packit/packit_onecloud1.sh
+endef
+
 $(eval $(call BuildImage))


================================================
FILE: devices/armsr_armv8/.config
================================================
CONFIG_TARGET_armsr=y
CONFIG_TARGET_armsr_armv8=y
CCONFIG_TARGET_DEVICE_armsr_armv8_DEVICE_generic=y
CONFIG_TARGET_DEVICE_armsr_armv8_DEVICE_box=y
CONFIG_PACKAGE_kmod-brcmfmac=y
CONFIG_BRCMFMAC_SDIO=y
CONFIG_TARGET_ROOTFS_TARGZ=y

CONFIG_TARGET_ROOTFS_EXT4FS=y
CONFIG_TARGET_ROOTFS_SQUASHFS=n

CONFIG_PACKAGE_kmod-switch-ar8xxx=n





================================================
FILE: devices/armsr_armv8/diy.sh
================================================


SHELL_FOLDER=$(dirname $(readlink -f "$0"))

rm -rf package/feeds/kiddin9/rtl8188eu package/feeds/kiddin9/rtl8192eu package/feeds/kiddin9/rtl8812au-ac




================================================
FILE: devices/armsr_armv8/patches/rootfs.patch
================================================
--- a/target/linux/armsr/image/Makefile
+++ b/target/linux/armsr/image/Makefile
@@ -81,10 +81,8 @@ define Device/efi-default
   IMAGE/combined-efi.img.gz := grub-config efi | combined efi | grub-install efi | gzip | append-metadata
   IMAGE/combined-efi.vmdk := grub-config efi | combined efi | grub-install efi | qemu-image vmdk
  ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y)
-    IMAGES-y := rootfs.img.gz
     IMAGES-y += combined-efi.img.gz
   else
-    IMAGES-y := rootfs.img
     IMAGES-y += combined-efi.img
   endif
   ifeq ($(CONFIG_VMDK_IMAGES),y)
@@ -116,4 +114,24 @@ define Device/generic
 endef
 TARGET_DEVICES += generic
 
+define Device/box
+  DEVICE_TITLE := N1/电视盒子全系列
+  DEVICE_PACKAGES := perlbase-base perlbase-utf8 perlbase-time perlbase-xsloader perlbase-file btrfs-progs luci-app-amlogic kmod-brcmfmac wpad-basic-mbedtls iw fdisk lsblk automount
+  IMAGE/rootfs.tar.gz := append-rootfs | gzip
+  IMAGES := rootfs.tar.gz
+  KERNEL := kernel-bin
+endef
+TARGET_DEVICES += box
+
+define Image/Build
+  if [ "$(PROFILE_SANITIZED)" == "box" ]; then \
+  	export BIN_DIR=$(BIN_DIR); \
+  	export DATE=$(DATE); \
+  	export MORE="$(MORE)"; \
+	export ROOTFS_PARTSIZE=$(shell echo $$(($(ROOTFS_PARTSIZE)/1024/1024))); \
+  	cd /data/packit/amlogic-s9xxx-openwrt; \
+  	. ~/packit/packit_amlogic.sh; \
+  fi
+endef
+
 $(eval $(call BuildImage))


================================================
FILE: devices/ath79_nand/.config
================================================

CONFIG_TARGET_ath79=y
CONFIG_TARGET_ath79_nand=y

CONFIG_TARGET_DEVICE_ath79_nand_DEVICE_meraki_mr18=n








================================================
FILE: devices/ath79_nand/diy.sh
================================================
#!/bin/bash

shopt -s extglob

SHELL_FOLDER=$(dirname $(readlink -f "$0"))

sed -i '/# start dockerd/,/# end dockerd/d' .config

rm -rf feeds/kiddin9/xtables-wgobfs


================================================
FILE: devices/bcm27xx_bcm2708/.config
================================================

CONFIG_TARGET_bcm27xx=y
CONFIG_TARGET_bcm27xx_bcm2708=y

CONFIG_TARGET_DEVICE_bcm27xx_bcm2708_DEVICE_rpi=y

CONFIG_PACKAGE_kmod-codec-bcm2835=n
CONFIG_PACKAGE_kmod-isp-bcm2835=n






================================================
FILE: devices/bcm27xx_bcm2708/diy.sh
================================================
#!/bin/bash

SHELL_FOLDER=$(dirname $(readlink -f "$0"))

#bash $SHELL_FOLDER/../common/kernel_6.1.sh

sed -i 's/DEFAULT_PACKAGES +=/DEFAULT_PACKAGES += fdisk lsblk kmod-usb-net-asix-ax88179 kmod-usb-net-rtl8152/' target/linux/bcm27xx/Makefile





================================================
FILE: devices/bcm27xx_bcm2709/.config
================================================

CONFIG_TARGET_bcm27xx=y
CONFIG_TARGET_bcm27xx_bcm2709=y
CONFIG_TARGET_bcm27xx_bcm2709_DEVICE_rpi-2=y

CONFIG_PACKAGE_kmod-codec-bcm2835=n
CONFIG_PACKAGE_kmod-isp-bcm2835=n


================================================
FILE: devices/bcm27xx_bcm2709/diy.sh
================================================
#!/bin/bash
SHELL_FOLDER=$(dirname $(readlink -f "$0"))

#bash $SHELL_FOLDER/../common/kernel_6.1.sh

sed -i 's/DEFAULT_PACKAGES +=/DEFAULT_PACKAGES += fdisk lsblk kmod-usb-net-asix-ax88179 kmod-usb-net-rtl8152/' target/linux/bcm27xx/Makefile

sed -i 's/ factory.img.gz / /' target/linux/bcm27xx/image/Makefile





================================================
FILE: devices/bcm27xx_bcm2710/.config
================================================

CONFIG_TARGET_bcm27xx=y
CONFIG_TARGET_bcm27xx_bcm2710=y
CONFIG_TARGET_bcm27xx_bcm2710_DEVICE_rpi-3=y

CONFIG_PACKAGE_kmod-codec-bcm2835=n
CONFIG_PACKAGE_kmod-isp-bcm2835=n





================================================
FILE: devices/bcm27xx_bcm2710/diy.sh
================================================
#!/bin/bash

SHELL_FOLDER=$(dirname $(readlink -f "$0"))

#bash $SHELL_FOLDER/../common/kernel_6.1.sh

sed -i 's/DEFAULT_PACKAGES +=/DEFAULT_PACKAGES += fdisk lsblk kmod-usb-net-asix-ax88179 kmod-usb-net-rtl8152/' target/linux/bcm27xx/Makefile

wget -N https://github.com/RPi-Distro/firmware-nonfree/raw/bullseye/debian/config/brcm80211/brcm/brcmfmac43436-sdio.bin -P files/lib/firmware/brcm/
wget -N https://github.com/RPi-Distro/firmware-nonfree/raw/bullseye/debian/config/brcm80211/brcm/brcmfmac43436-sdio.txt -P files/lib/firmware/brcm/
wget -N https://github.com/RPi-Distro/firmware-nonfree/raw/bullseye/debian/config/brcm80211/brcm/brcmfmac43436s-sdio.bin -P files/lib/firmware/brcm/
wget -N https://github.com/RPi-Distro/firmware-nonfree/raw/bullseye/debian/config/brcm80211/brcm/brcmfmac43436s-sdio.txt -P files/lib/firmware/brcm/


================================================
FILE: devices/bcm27xx_bcm2710/patches/Zero-2.patch
================================================
--- a/target/linux/bcm27xx/image/Makefile
+++ b/target/linux/bcm27xx/image/Makefile
@@ -122,7 +122,7 @@ define Device/rpi-3
   DEVICE_MODEL := 3B/3B+/CM3
   DEVICE_VARIANT := (64bit)
   DEVICE_ALT0_VENDOR := Raspberry Pi
-  DEVICE_ALT0_MODEL := 2B-1.2
+  DEVICE_ALT0_MODEL := 2B-1.2/Zero 2/Zero 2W
   DEVICE_ALT0_VARIANT := (64bit)
   KERNEL_IMG := kernel8.img
   DEVICE_DTS := \

================================================
FILE: devices/bcm27xx_bcm2711/.config
================================================

CONFIG_TARGET_bcm27xx=y
CONFIG_TARGET_bcm27xx_bcm2711=y
CONFIG_TARGET_bcm27xx_bcm2711_DEVICE_rpi-4=y

CONFIG_PACKAGE_kmod-codec-bcm2835=n
CONFIG_PACKAGE_kmod-isp-bcm2835=n




================================================
FILE: devices/bcm27xx_bcm2711/diy.sh
================================================
#!/bin/bash

SHELL_FOLDER=$(dirname $(readlink -f "$0"))

#bash $SHELL_FOLDER/../common/kernel_6.1.sh

sed -i 's/DEFAULT_PACKAGES +=/DEFAULT_PACKAGES += fdisk lsblk kmod-usb-net-asix-ax88179 kmod-usb-net-rtl8152/' target/linux/bcm27xx/Makefile




================================================
FILE: devices/bcm27xx_bcm2712/.config
================================================

CONFIG_TARGET_bcm27xx=y
CONFIG_TARGET_bcm27xx_bcm2712=y
CONFIG_TARGET_bcm27xx_bcm2712_DEVICE_rpi-5=y

CONFIG_PACKAGE_kmod-of-mdio=n

CONFIG_PACKAGE_kmod-codec-bcm2835=n
CONFIG_PACKAGE_kmod-isp-bcm2835=n



================================================
FILE: devices/bcm27xx_bcm2712/diy.sh
================================================
#!/bin/bash

SHELL_FOLDER=$(dirname $(readlink -f "$0"))

#bash $SHELL_FOLDER/../common/kernel_6.6.sh

sed -i 's/DEFAULT_PACKAGES +=/DEFAULT_PACKAGES += fdisk lsblk kmod-usb-net-asix-ax88179 kmod-usb-net-rtl8152/' target/linux/bcm27xx/Makefile


================================================
FILE: devices/bcm53xx/.config
================================================

CONFIG_TARGET_bcm53xx=y
CONFIG_TARGET_bcm53xx_generic=y

CONFIG_TARGET_DEVICE_bcm53xx_generic_DEVICE_phicomm_k3=y
CONFIG_TARGET_DEVICE_bcm53xx_generic_DEVICE_asus_rt-ac88u=y
CONFIG_TARGET_DEVICE_bcm53xx_generic_DEVICE_dlink_dir-885l=y

CONFIG_KERNEL_DEVMEM=y
CONFIG_BUSYBOX_CONFIG_ARPING=y

CONFIG_PACKAGE_kmod-pcie_mhi=n






================================================
FILE: devices/bcm53xx/diy.sh
================================================
#!/bin/bash

shopt -s extglob

SHELL_FOLDER=$(dirname $(readlink -f "$0"))

sed -i "s/^TARGET_DEVICES /# TARGET_DEVICES /" target/linux/bcm53xx/image/Makefile
sed -i "s/# TARGET_DEVICES += phicomm_k3/TARGET_DEVICES += phicomm_k3/" target/linux/bcm53xx/image/Makefile
sed -i "s/# TARGET_DEVICES += asus_rt-ac88u/TARGET_DEVICES += asus_rt-ac88u/" target/linux/bcm53xx/image/Makefile
sed -i "s/# TARGET_DEVICES += dlink_dir-885l/TARGET_DEVICES += dlink_dir-885l/" target/linux/bcm53xx/image/Makefile
sed -i "s/DEVICE_PACKAGES := \$(BRCMFMAC_4366C0) \$(USB3_PACKAGES)/DEVICE_PACKAGES := \$(BRCMFMAC_4366C0) \$(USB3_PACKAGES) -brcmfmac-firmware-4366c0-pcie k3wifi luci-app-k3screenctrl/" target/linux/bcm53xx/image/Makefile



================================================
FILE: devices/common/.config
================================================

CONFIG_GRUB_TIMEOUT="0"
CONFIG_GRUB_CONSOLE=n
CONFIG_TARGET_ROOTFS_EXT4FS=n

CONFIG_TARGET_ROOTFS_CPIOGZ=n
CONFIG_LUCI_CSSTIDY=n
CONFIG_SIGNED_PACKAGES=n
CONFIG_SIGNATURE_CHECK=n

CONFIG_TARGET_MULTI_PROFILE=y
CONFIG_TARGET_ALL_PROFILES=y

# 设置固件大小:
CONFIG_TARGET_ROOTFS_PARTSIZE=1004

CONFIG_ALL_NONSHARED=y

CONFIG_USE_APK=n

CONFIG_BUILD_PATENTED=y

CONFIG_IB=y
CONFIG_IB_STANDALONE=y
CONFIG_JSON_OVERVIEW_IMAGE_INFO=y

CONFIG_FEED_telephony=n

CONFIG_KERNEL_WERROR=n

# IPv6支持:
CONFIG_IPV6=y

# Applications


# Themes

CONFIG_PACKAGE_luci-theme-bootstrap=y

# 其他需要安装的软件包:

CONFIG_PACKAGE_dnsmasq=n
CONFIG_PACKAGE_dnsmasq-full=y
CONFIG_PACKAGE_dnsmasq_full_dhcp=y
CONFIG_PACKAGE_dnsmasq_full_ipset=y

CONFIG_PACKAGE_firewall=m
CONFIG_PACKAGE_miniupnpd-iptables=m

CONFIG_NGINX_DAV=y
CONFIG_PACKAGE_luci-base=y
CONFIG_PACKAGE_luci-compat=y
CONFIG_PACKAGE_luci-lib-ipkg=y
CONFIG_LUCI_LANG_zh_Hans=y
CONFIG_LUCI_LANG_en=y
CONFIG_PACKAGE_coremark=y
CONFIG_DEVEL=y
CONFIG_CCACHE=y
CONFIG_TOOLCHAINOPTS=y
CONFIG_COREMARK_OPTIMIZE_O3=y
CONFIG_COREMARK_ENABLE_MULTITHREADING=y
CONFIG_COREMARK_NUMBER_OF_THREADS=16
CONFIG_PACKAGE_zoneinfo-asia=y
CONFIG_PACKAGE_my-default-settings=y
CONFIG_PACKAGE_wget-ssl=y
CONFIG_PACKAGE_curl=y
CONFIG_PACKAGE_htop=y
CONFIG_PACKAGE_nano=y
CONFIG_XRAY_PROVIDE_V2RAY=y
CONFIG_V2RAY_CORE_COMPRESS_UPX=n
CONFIG_XRAY_CORE_COMPRESS_UPX=n
CONFIG_PACKAGE_zram-swap=y
CONFIG_PACKAGE_kmod-lib-lz4=y
CONFIG_PACKAGE_kmod-lib-zstd=y
CONFIG_NODEJS_14=y

CONFIG_BUSYBOX_CUSTOM=y
CONFIG_BUSYBOX_CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR=y
CONFIG_BUSYBOX_CONFIG_FEATURE_CROND_SPECIAL_TIMES=y
CONFIG_BUSYBOX_CONFIG_FEATURE_SYSLOG_INFO=y

CONFIG_PACKAGE_luci-ssl=y # uhttpd服务

CONFIG_PACKAGE_bash=y
CONFIG_PACKAGE_ca-bundle=y

CONFIG_PACKAGE_wifi-scripts=m

# CONFIG_PACKAGE_netdata=m

CONFIG_IMAGEOPT=y
CONFIG_VERSIONOPT=y

CONFIG_VERSION_MANUFACTURER="Kiddin'"
CONFIG_VERSION_FILENAMES=n
CONFIG_VERSION_CODE_FILENAMES=n
CONFIG_VERSION_HOME_URL="https://openwrt.ai/"

CONFIG_KERNEL_XDP_SOCKETS=y

CONFIG_ZLIB_OPTIMIZE_SPEED=y
CONFIG_ZSTD_OPTIMIZE_O3=y

CONFIG_BUILD_PATENTED=y


# start dockerd
CONFIG_KERNEL_CGROUP_DEVICE=y
CONFIG_KERNEL_CGROUP_FREEZER=y
CONFIG_KERNEL_NET_CLS_CGROUP=y
CONFIG_KERNEL_CGROUP_NET_PRIO=y
CONFIG_KERNEL_MEMCG_SWAP_ENABLED=y
CONFIG_KERNEL_CFQ_GROUP_IOSCHED=y
CONFIG_KERNEL_CGROUP_PERF=y
CONFIG_KERNEL_CGROUP_HUGETLB=y
CONFIG_KERNEL_EXT4_FS_POSIX_ACL=y
CONFIG_KERNEL_EXT4_FS_SECURITY=y
CONFIG_KERNEL_BTRFS_FS_POSIX_ACL=y
# end dockerd



================================================
FILE: devices/common/diy/feeds/luci/modules/luci-base/htdocs/luci-static/resources/tools/github.js
================================================
'use strict';

return L.Class.extend({
    desc: function(description, username, project) {
        var luci_project = 'luci-app-' + project;
        var title = _('if you have any problem, please click to view the project on GitHub : ') + project;
        var luci_title = _('if you have any problem, please click to view the luci ui project on GitHub : ') + luci_project;
        var package_label = 'package-' + project.replace(/-/g, '_') + '-default';
        var luci_label = 'luci-' + project.replace(/-/g, '_') + '-default';

        return "<table style='border: 0; table-layout: auto;'>" +
                    "<tr>" +
                        "<td style='border: 0;'>" + _(description) + "</td>" +
                        "<td style='border: 0;'>" +
                            "<table style='border: 0; table-layout: auto;'>" +
                                "<tr>" +
                                    "<td style='border: 0;'>" +
                                        "<a href='https://github.com/" + username + "/" + project + "' target='_blank' title='" + title + "'>" +
                                            "<img alt='" + project + "' src='https://img.shields.io/badge/" + package_label +  "' />" +
                                            "<img alt='" + project + "' src='https://img.shields.io/github/stars/" + username + "/" + project + "?style=social' />" +
                                        "</a>" +
                                        "<a href='https://github.com/" + username + "/" + luci_project + "' target='_blank' title='" + luci_title + "'>" +
                                            "<img alt='" + luci_project + "' src='https://img.shields.io/badge/" + luci_label + "' />" +
                                            "<img alt='" + luci_project + "' src='https://img.shields.io/github/stars/" + username + "/" + luci_project + "?style=social' />" +
                                        "</a>" +
                                    "</td>" +
                                "</tr>" +
                            "</table>" +
                        "</td>" +
                    "</tr>" +
                "</table>";
    },

    luci_desc: function(description, username, project) {
        var luci_label = 'luci-' + project.replace(/-/g, '_') + '-default';
        project = 'luci-app-' + project;
        var luci_title = _('if you have any problem, please click to view the luci ui project on GitHub : ') + project;
        
        return "<table style='border: 0; table-layout: auto;'>" +
                    "<tr>" +
                        "<td style='border: 0;'>" + _(description) + "</td>" +
                        "<td style='border: 0;'>" +
                            "<a href='https://github.com/" + username + "/" + project + "' target='_blank' title='" + luci_title + "'>" +
                                "<img alt='" + project + "' src='https://img.shields.io/badge/" + luci_label + "' />" +
                                "<img alt='" + project + "' src='https://img.shields.io/github/stars/" + username + "/" + project + "?style=social' />" +
                            "</a>" +
                        "</td>" +
                    "</tr>" +
                "</table>";
    }
});

================================================
FILE: devices/common/diy/package/base-files/files/etc/banner
================================================

                       |\__/,|   (`\
                     _.|o o  |_   ) )
       -------------(((---(((-------------------
              %D %C by Kiddin'
       -----------------------------------------


================================================
FILE: devices/common/diy/package/network/config/firewall/files/firewall.exwan
================================================
#!/bin/sh

# UCI 配置操作函数
config_get() { uci -q get "$1"; }
config_set() { uci set "$1=$2"; }
config_add_list() { uci add_list "$1=$2"; }
config_delete() { uci -q delete "$1"; }
config_commit() { uci commit "$1"; }

# 检查列表是否包含元素
list_contains() {
    local value="$1"; shift
    echo "$@" | grep -q -w "$value"
}

# 从列表中移除元素
list_remove() {
    local value="$1"
    local list="$2"
    echo "$list" | sed "s/\<$value\>//g" | xargs
}

# 更新 SSH 和 TTYD 配置
update_ssh_ttyd() {
    if [ "$(config_get "firewall.@defaults[0].ex_ssh")" = "1" ]; then
        if [ -n "$(config_get "dropbear.@dropbear[0].GatewayPorts")" ]; then
            config_set "dropbear.@dropbear[0].GatewayPorts" "on"
            config_commit "dropbear"
            service dropbear reload &
        fi
        if command -v ttyd >/dev/null 2>&1; then
            [ "$(config_get "ttyd.@ttyd[0].interface")" != "@lan" ] && config_set "ttyd.@ttyd[0].interface" "@lan"
            if [ "$(config_get "firewall.@defaults[0].family")" = "ipv4" ]; then
                config_set "ttyd.@ttyd[0].ipv6" "0"
            else
                config_set "ttyd.@ttyd[0].ipv6" "1"
            fi
            config_commit "ttyd"
            service ttyd reload &
        fi
    fi
}

# 更新防火墙规则
update_firewall_rule() {
    local port="$1"
    local is_backend_port="$2"
    local rule="firewall.ex_$port"
    local family=$(config_get "firewall.@defaults[0].family")
    local proto=$(config_get "firewall.@defaults[0].proto")

    config_set "$rule" "rule"
    config_set "$rule.name" "ex_$port"
    config_set "$rule.src" "wan"
    config_set "$rule.dest_port" "$port"
    config_set "$rule.target" "ACCEPT"

    [ "$family" = "ipv4" ] && config_set "$rule.family" "ipv4" || config_set "$rule.family" "ipv6"

    if [ "$is_backend_port" = "1" ]; then
        config_add_list "$rule.proto" "tcp"
    else
        case "$proto" in
            udp) config_add_list "$rule.proto" "udp" ;;
            tudp)
                config_add_list "$rule.proto" "tcp"
                config_add_list "$rule.proto" "udp"
                ;;
            *)  config_add_list "$rule.proto" "tcp" ;;
        esac
    fi
}

# 删除所有以前生成的 config rule
remove_all_ex_rules() {
    local rules=$(uci show firewall | grep "\.name='ex_" | cut -d. -f2)
    for rule in $rules; do
        config_delete "firewall.$rule"
    done
}

# 更新 export 配置
update_export() {
    local export=$(config_get "firewall.@defaults[0].export")
    local ex_ssh=$(config_get "firewall.@defaults[0].ex_ssh")
    local sshport=$(config_get "dropbear.@dropbear[0].Port")
    
    # 处理 SSH 端口
    if [ "$ex_ssh" = "1" ]; then
        if ! list_contains "$sshport" $export; then
            export="$export $sshport"
        fi
    else
        export=$(list_remove "$sshport" "$export")
    fi
    
    config_set "firewall.@defaults[0].export" "$export"
    
    remove_all_ex_rules
    
    # 添加新的规则
    for port in $export; do
        update_firewall_rule "$port" "0"
    done
}

# 更新 uhttpd 配置
update_uhttpd() {
    local backend_port="$1"
    local old_backend_port="$2"
    local use_https=$(config_get "uhttpd.main.redirect_https")

    uci -q del_list uhttpd.main.listen_http="0.0.0.0:$old_backend_port"
    uci -q del_list uhttpd.main.listen_http="[::]:$old_backend_port"
    uci -q del_list uhttpd.main.listen_https="0.0.0.0:$old_backend_port"
    uci -q del_list uhttpd.main.listen_https="[::]:$old_backend_port"

    if [ -n "$backend_port" ]; then
        if [ "$use_https" = "1" ]; then
            config_add_list "uhttpd.main.listen_https" "0.0.0.0:$backend_port"
            config_add_list "uhttpd.main.listen_https" "[::]:$backend_port"
        else
            config_add_list "uhttpd.main.listen_http" "0.0.0.0:$backend_port"
            config_add_list "uhttpd.main.listen_http" "[::]:$backend_port"
        fi
    fi
    config_commit "uhttpd"
}

# 更新 nginx 配置
update_nginx() {
    local backend_port="$1"
    local old_backend_port="$2"
    local use_https=$(uci show nginx | grep -q "_redirect2ssl" && echo "1" || echo "0")

    config_delete "nginx.ex_$old_backend_port"

    if [ -n "$backend_port" ]; then
        config_set "nginx.ex_$backend_port" "server"
        config_set "nginx.ex_$backend_port.server_name" "ex_$backend_port"
        config_add_list "nginx.ex_$backend_port.include" "conf.d/*.locations"
        config_set "nginx.ex_$backend_port.access_log" "off"
        if [ "$use_https" = "1" ]; then
            config_add_list "nginx.ex_$backend_port.listen" "$backend_port ssl"
            config_add_list "nginx.ex_$backend_port.listen" "[::]:$backend_port ssl"
            if [ ! "$(config_get "nginx.ex_$backend_port.ssl_certificate")" ]; then
                config_set "nginx.ex_$backend_port.ssl_certificate" "/etc/nginx/conf.d/_lan.crt"
                config_set "nginx.ex_$backend_port.ssl_certificate_key" "/etc/nginx/conf.d/_lan.key"
            fi
        else
            config_add_list "nginx.ex_$backend_port.listen" "$backend_port"
            config_add_list "nginx.ex_$backend_port.listen" "[::]:$backend_port"
        fi
    fi

    config_commit "nginx"
}

# 主逻辑
main() {
    local backend_port=$(config_get "firewall.@defaults[0].backend_port")
    local old_backend_port=$(config_get "firewall.@defaults[0].old_backend_port")

    update_ssh_ttyd
    update_export

    if [ "$backend_port" != "$old_backend_port" ]; then
        if pgrep nginx >/dev/null; then
            update_nginx "$backend_port" "$old_backend_port"
            /etc/init.d/nginx reload &
        elif pgrep uhttpd >/dev/null; then
            update_uhttpd "$backend_port" "$old_backend_port"
            /etc/init.d/uhttpd reload &
        fi
        config_set "firewall.@defaults[0].old_backend_port" "$backend_port"
    fi

    [ -n "$backend_port" ] && update_firewall_rule "$backend_port" "1"

    config_commit "firewall"
}

main


================================================
FILE: devices/common/diy/package/network/config/firewall/patches/fullconenat.patch
================================================
index 85a3750..9fac9b1 100644
--- a/defaults.c
+++ b/defaults.c
@@ -46,7 +46,9 @@ const struct fw3_option fw3_flag_opts[] = {
 	FW3_OPT("synflood_protect",    bool,     defaults, syn_flood),
 	FW3_OPT("synflood_rate",       limit,    defaults, syn_flood_rate),
 	FW3_OPT("synflood_burst",      int,      defaults, syn_flood_rate.burst),
-
+	
+	FW3_OPT("fullcone",           bool,     defaults, fullcone),
+	
 	FW3_OPT("tcp_syncookies",      bool,     defaults, tcp_syncookies),
 	FW3_OPT("tcp_ecn",             int,      defaults, tcp_ecn),
 	FW3_OPT("tcp_window_scaling",  bool,     defaults, tcp_window_scaling),
diff --git a/options.h b/options.h
index 6edd174..c02eb97 100644
--- a/options.h
+++ b/options.h
@@ -267,6 +267,7 @@ struct fw3_defaults
 	bool drop_invalid;
 
 	bool syn_flood;
+	bool fullcone;
 	struct fw3_limit syn_flood_rate;
 
 	bool tcp_syncookies;
diff --git a/zones.c b/zones.c
index 2aa7473..57eead0 100644
--- a/zones.c
+++ b/zones.c
@@ -627,6 +627,7 @@ print_zone_rule(struct fw3_ipt_handle *h
 	struct fw3_address *msrc;
 	struct fw3_address *mdest;
 	struct fw3_ipt_rule *r;
+	struct fw3_defaults *defs = &state->defaults;
 
 	if (!fw3_is_family(zone, handle->family))
 		return;
@@ -712,8 +713,22 @@ print_zone_rule(struct fw3_ipt_handle *h
 				{
 					r = fw3_ipt_rule_new(handle);
 					fw3_ipt_rule_src_dest(r, msrc, mdest);
-					fw3_ipt_rule_target(r, "MASQUERADE");
-					fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name);
+					/*FIXME: Workaround for FULLCONE-NAT*/
+					if(defs->fullcone)
+					{
+						warn("%s will enable FULLCONE-NAT", zone->name);
+						fw3_ipt_rule_target(r, "FULLCONENAT");
+						fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name);
+						r = fw3_ipt_rule_new(handle);
+						fw3_ipt_rule_src_dest(r, msrc, mdest);
+						fw3_ipt_rule_target(r, "FULLCONENAT");
+						fw3_ipt_rule_append(r, "zone_%s_prerouting", zone->name);
+					}
+					else
+					{
+						fw3_ipt_rule_target(r, "MASQUERADE");
+						fw3_ipt_rule_append(r, "zone_%s_postrouting", zone->name);
+					}
 				}
 			}
 		}


================================================
FILE: devices/common/diy/package/network/config/firewall4/files/firewall.exwan
================================================
#!/bin/sh

# UCI 配置操作函数
config_get() { uci -q get "$1"; }
config_set() { uci set "$1=$2"; }
config_add_list() { uci add_list "$1=$2"; }
config_delete() { uci -q delete "$1"; }
config_commit() { uci commit "$1"; }

# 检查列表是否包含元素
list_contains() {
    local value="$1"; shift
    echo "$@" | grep -q -w "$value"
}

# 从列表中移除元素
list_remove() {
    local value="$1"
    local list="$2"
    echo "$list" | sed "s/\<$value\>//g" | xargs
}

# 更新 SSH 和 TTYD 配置
update_ssh_ttyd() {
    if [ "$(config_get "firewall.@defaults[0].ex_ssh")" = "1" ]; then
        if [ -n "$(config_get "dropbear.@dropbear[0].GatewayPorts")" ]; then
            config_set "dropbear.@dropbear[0].GatewayPorts" "on"
            config_commit "dropbear"
            service dropbear reload &
        fi
        if command -v ttyd >/dev/null 2>&1; then
            [ "$(config_get "ttyd.@ttyd[0].interface")" != "@lan" ] && config_set "ttyd.@ttyd[0].interface" "@lan"
            if [ "$(config_get "firewall.@defaults[0].family")" = "ipv4" ]; then
                config_set "ttyd.@ttyd[0].ipv6" "0"
            else
                config_set "ttyd.@ttyd[0].ipv6" "1"
            fi
            config_commit "ttyd"
            service ttyd reload &
        fi
    fi
}

# 更新防火墙规则
update_firewall_rule() {
    local port="$1"
    local is_backend_port="$2"
    local rule="firewall.ex_$port"
    local family=$(config_get "firewall.@defaults[0].family")
    local proto=$(config_get "firewall.@defaults[0].proto")

    config_set "$rule" "rule"
    config_set "$rule.name" "ex_$port"
    config_set "$rule.src" "wan"
    config_set "$rule.dest_port" "$port"
    config_set "$rule.target" "ACCEPT"

    [ "$family" = "ipv4" ] && config_set "$rule.family" "ipv4" || config_set "$rule.family" "ipv6"

    if [ "$is_backend_port" = "1" ]; then
        config_add_list "$rule.proto" "tcp"
    else
        case "$proto" in
            udp) config_add_list "$rule.proto" "udp" ;;
            tudp)
                config_add_list "$rule.proto" "tcp"
                config_add_list "$rule.proto" "udp"
                ;;
            *)  config_add_list "$rule.proto" "tcp" ;;
        esac
    fi
}

# 删除所有以前生成的 config rule
remove_all_ex_rules() {
    local rules=$(uci show firewall | grep "\.name='ex_" | cut -d. -f2)
    for rule in $rules; do
        config_delete "firewall.$rule"
    done
}

# 更新 export 配置
update_export() {
    local export=$(config_get "firewall.@defaults[0].export")
    local ex_ssh=$(config_get "firewall.@defaults[0].ex_ssh")
    local sshport=$(config_get "dropbear.@dropbear[0].Port")
    
    # 处理 SSH 端口
    if [ "$ex_ssh" = "1" ]; then
        if ! list_contains "$sshport" $export; then
            export="$export $sshport"
        fi
    else
        export=$(list_remove "$sshport" "$export")
    fi
    
    config_set "firewall.@defaults[0].export" "$export"
    
    remove_all_ex_rules
    
    # 添加新的规则
    for port in $export; do
        update_firewall_rule "$port" "0"
    done
}

# 更新 uhttpd 配置
update_uhttpd() {
    local backend_port="$1"
    local old_backend_port="$2"
    local use_https=$(config_get "uhttpd.main.redirect_https")

    uci -q del_list uhttpd.main.listen_http="0.0.0.0:$old_backend_port"
    uci -q del_list uhttpd.main.listen_http="[::]:$old_backend_port"
    uci -q del_list uhttpd.main.listen_https="0.0.0.0:$old_backend_port"
    uci -q del_list uhttpd.main.listen_https="[::]:$old_backend_port"

    if [ -n "$backend_port" ]; then
        if [ "$use_https" = "1" ]; then
            config_add_list "uhttpd.main.listen_https" "0.0.0.0:$backend_port"
            config_add_list "uhttpd.main.listen_https" "[::]:$backend_port"
        else
            config_add_list "uhttpd.main.listen_http" "0.0.0.0:$backend_port"
            config_add_list "uhttpd.main.listen_http" "[::]:$backend_port"
        fi
    fi
    config_commit "uhttpd"
}

# 更新 nginx 配置
update_nginx() {
    local backend_port="$1"
    local old_backend_port="$2"
    local use_https=$(uci show nginx | grep -q "_redirect2ssl" && echo "1" || echo "0")

    config_delete "nginx.ex_$old_backend_port"

    if [ -n "$backend_port" ]; then
        config_set "nginx.ex_$backend_port" "server"
        config_set "nginx.ex_$backend_port.server_name" "ex_$backend_port"
        config_add_list "nginx.ex_$backend_port.include" "conf.d/*.locations"
        config_set "nginx.ex_$backend_port.access_log" "off"
        if [ "$use_https" = "1" ]; then
            config_add_list "nginx.ex_$backend_port.listen" "$backend_port ssl"
            config_add_list "nginx.ex_$backend_port.listen" "[::]:$backend_port ssl"
            if [ ! "$(config_get "nginx.ex_$backend_port.ssl_certificate")" ]; then
                config_set "nginx.ex_$backend_port.ssl_certificate" "/etc/nginx/conf.d/_lan.crt"
                config_set "nginx.ex_$backend_port.ssl_certificate_key" "/etc/nginx/conf.d/_lan.key"
            fi
        else
            config_add_list "nginx.ex_$backend_port.listen" "$backend_port"
            config_add_list "nginx.ex_$backend_port.listen" "[::]:$backend_port"
        fi
    fi

    config_commit "nginx"
}

# 主逻辑
main() {
    local backend_port=$(config_get "firewall.@defaults[0].backend_port")
    local old_backend_port=$(config_get "firewall.@defaults[0].old_backend_port")

    update_ssh_ttyd
    update_export

    if [ "$backend_port" != "$old_backend_port" ]; then
        if pgrep nginx >/dev/null; then
            update_nginx "$backend_port" "$old_backend_port"
            /etc/init.d/nginx reload &
        elif pgrep uhttpd >/dev/null; then
            update_uhttpd "$backend_port" "$old_backend_port"
            /etc/init.d/uhttpd reload &
        fi
        config_set "firewall.@defaults[0].old_backend_port" "$backend_port"
    fi

    [ -n "$backend_port" ] && update_firewall_rule "$backend_port" "1"

    config_commit "firewall"
}

main


================================================
FILE: devices/common/diy/package/network/config/firewall4/files/firewall.include
================================================



================================================
FILE: devices/common/diy/package/network/config/firewall4/patches/001-firewall4-add-support-for-fullcone-nat.patch
================================================
From aa3b56e289fba7425e649a608c333622ffd9c367 Mon Sep 17 00:00:00 2001
From: Syrone Wong <wong.syrone@gmail.com>
Date: Sat, 9 Apr 2022 13:24:19 +0800
Subject: [PATCH] firewall4: add fullcone support

fullcone is drop-in replacement of masq for non-udp traffic

add runtime fullcone rule check, disable it globally if fullcone expr is
invalid

defaults.fullcone and defaults.fullcone6 are switches for IPv4 and IPv6
respectively, most IPv6 traffic do NOT need this FullCone NAT functionality.

Renew: ZiMing Mo <msylgj@immortalwrt.org>
---
 root/etc/config/firewall                      |  2 ++
 root/usr/share/firewall4/templates/ruleset.uc | 16 ++++++++++++++--
 .../firewall4/templates/zone-fullcone.uc      |  4 ++++
 root/usr/share/ucode/fw4.uc                   | 69 ++++++++++++++++++-
 4 files changed, 89 insertions(+), 4 deletions(-)
 create mode 100644 root/usr/share/firewall4/templates/zone-fullcone.uc

--- a/root/etc/config/firewall
+++ b/root/etc/config/firewall
@@ -5,6 +5,10 @@ config defaults
 	option forward		REJECT
 # Uncomment this line to disable ipv6 rules
 #	option disable_ipv6	1
+	option flow_offloading	1
+	option flow_offloading_hw	1
+	option fullcone		1
+	option fullcone6	0
 
 config zone
 	option name		lan
--- a/root/usr/share/firewall4/templates/ruleset.uc
+++ b/root/usr/share/firewall4/templates/ruleset.uc
@@ -327,6 +327,12 @@ table inet fw4 {
 {%   for (let redirect in fw4.redirects(`dstnat_${zone.name}`)): %}
 		{%+ include("redirect.uc", { fw4, zone, redirect }) %}
 {%   endfor %}
+{%   if (zone.masq && fw4.default_option("fullcone")): %}
+		{%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "dstnat" }) %}
+{%   endif %}
+{%   if (zone.masq6 && fw4.default_option("fullcone6")): %}
+		{%+ include("zone-fullcone.uc", { fw4, zone, family: 6, direction: "dstnat" }) %}
+{%   endif %}
 {%   fw4.includes('chain-append', `dstnat_${zone.name}`) %}
 	}
 
@@ -337,20 +343,26 @@ table inet fw4 {
 {%   for (let redirect in fw4.redirects(`srcnat_${zone.name}`)): %}
 		{%+ include("redirect.uc", { fw4, zone, redirect }) %}
 {%   endfor %}
-{%   if (zone.masq): %}
+{%   if (zone.masq && !fw4.default_option("fullcone")): %}
 {%    for (let saddrs in zone.masq4_src_subnets): %}
 {%     for (let daddrs in zone.masq4_dest_subnets): %}
 		{%+ include("zone-masq.uc", { fw4, zone, family: 4, saddrs, daddrs }) %}
 {%     endfor %}
 {%    endfor %}
 {%   endif %}
-{%   if (zone.masq6): %}
+{%   if (zone.masq6 && !fw4.default_option("fullcone6")): %}
 {%    for (let saddrs in zone.masq6_src_subnets): %}
 {%     for (let daddrs in zone.masq6_dest_subnets): %}
 		{%+ include("zone-masq.uc", { fw4, zone, family: 6, saddrs, daddrs }) %}
 {%     endfor %}
 {%    endfor %}
 {%   endif %}
+{%   if (zone.masq && fw4.default_option("fullcone")): %}
+		{%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "srcnat" }) %}
+{%   endif %}
+{%   if (zone.masq6 && fw4.default_option("fullcone6")): %}
+		{%+ include("zone-fullcone.uc", { fw4, zone, family: 6, direction: "srcnat" }) %}
+{%   endif %}
 {%   fw4.includes('chain-append', `srcnat_${zone.name}`) %}
 	}
 
--- /dev/null
+++ b/root/usr/share/firewall4/templates/zone-fullcone.uc
@@ -0,0 +1,4 @@
+{# /usr/share/firewall4/templates/zone-fullcone.uc #}
+		meta nfproto {{ fw4.nfproto(family) }} fullcone comment "!fw4: Handle {{
+		zone.name
+}} {{ fw4.nfproto(family, true) }} fullcone NAT {{ direction }} traffic"
--- a/root/usr/share/ucode/fw4.uc
+++ b/root/usr/share/ucode/fw4.uc
@@ -1,3 +1,5 @@
+// /usr/share/ucode/fw4.uc
+
 const fs = require("fs");
 const uci = require("uci");
 const ubus = require("ubus");
@@ -489,6 +491,25 @@ function nft_try_hw_offload(devices) {
 	return (rc == 0);
 }
 
+function nft_try_fullcone() {
+	let nft_test =
+		'add table inet fw4-fullcone-test; ' +
+		'add chain inet fw4-fullcone-test dstnat { ' +
+			'type nat hook prerouting priority -100; policy accept; ' +
+			'fullcone; ' +
+		'}; ' +
+		'add chain inet fw4-fullcone-test srcnat { ' +
+			'type nat hook postrouting priority -100; policy accept; ' +
+			'fullcone; ' +
+		'}; ';
+	let cmd = sprintf("/usr/sbin/nft -c '%s' 2>/dev/null", replace(nft_test, "'", "'\\''"));
+	let ok = system(cmd) == 0;
+	if (!ok) {
+		warn("nft_try_fullcone: cmd "+ cmd + "\n");
+	}
+	return ok;
+}
+
 
 return {
 	read_kernel_version: function() {
@@ -855,6 +876,18 @@ return {
 			warn(`[!] ${msg}\n`);
 	},
 
+	myinfo: function(fmt, ...args) {
+		if (getenv("QUIET"))
+			return;
+
+		let msg = sprintf(fmt, ...args);
+
+		if (getenv("TTY"))
+			warn(`\033[32m${msg}\033[m\n`);
+		else
+			warn(`[I] ${msg}\n`);
+	},
+
 	get: function(sid, opt) {
 		return this.cursor.get("firewall", sid, opt);
 	},
@@ -1036,6 +1069,21 @@ return {
 		}
 	},
 
+	myinfo_section: function(s, msg) {
+		if (s[".name"]) {
+			if (s.name)
+				this.myinfo("Section %s (%s) %s", this.section_id(s[".name"]), s.name, msg);
+			else
+				this.myinfo("Section %s %s", this.section_id(s[".name"]), msg);
+		}
+		else {
+			if (s.name)
+				this.myinfo("ubus %s (%s) %s", s.type || "rule", s.name, msg);
+			else
+				this.myinfo("ubus %s %s", s.type || "rule", msg);
+		}
+	},
+
 	parse_policy: function(val) {
 		return this.parse_enum(val, [
 			"accept",
@@ -1475,6 +1523,7 @@ return {
 			"dnat",
 			"snat",
 			"masquerade",
+			"fullcone",
 			"accept",
 			"reject",
 			"drop"
@@ -1946,6 +1995,8 @@ return {
 		}
 
 		let defs = this.parse_options(data, {
+			fullcone: [ "bool", "0" ],
+			fullcone6: [ "bool", "0" ],
 			input: [ "policy", "drop" ],
 			output: [ "policy", "drop" ],
 			forward: [ "policy", "drop" ],
@@ -1980,6 +2031,11 @@ return {
 
 		delete defs.syn_flood;
 
+		if (!nft_try_fullcone()) {
+			delete defs.fullcone;
+			warn("nft_try_fullcone failed, disable fullcone globally\n");
+		}
+
 		this.state.defaults = defs;
 	},
 
@@ -2205,10 +2261,23 @@ return {
 		zone.related_subnets = related_subnets;
 		zone.related_physdevs = related_physdevs;
 
-		if (zone.masq || zone.masq6)
+		if (zone.masq) {
 			zone.dflags.snat = true;
+			if (this.state.defaults.fullcone) {
+				zone.dflags.dnat = true;
+				this.myinfo_section(data, "IPv4 fullcone enabled for zone '" + zone.name + "'");
+			}
+		}
+
+		if (zone.masq6) {
+			zone.dflags.snat = true;
+			if (this.state.defaults.fullcone6) {
+				zone.dflags.dnat = true;
+				this.myinfo_section(data, "IPv6 fullcone enabled for zone '" + zone.name + "'");
+			}
+		}
 
-		if ((zone.auto_helper && !(zone.masq || zone.masq6)) || length(zone.helper)) {
+		if ((zone.auto_helper && !(zone.masq || zone.masq6 || this.state.defaults.fullcone || this.state.defaults.fullcone6)) || length(zone.helper)) {
 			zone.dflags.helper = true;
 
 			for (let helper in (length(zone.helper) ? zone.helper : this.state.helpers)) {


================================================
FILE: devices/common/diy/package/network/config/firewall4/patches/100-fw4-support-script.patch
================================================
diff --git a/root/sbin/fw4 b/root/sbin/fw4
index c3e95c2..8fa6c6e 100755
--- a/root/sbin/fw4
+++ b/root/sbin/fw4
@@ -20,6 +20,7 @@ start() {
 	{
 		flock -x 1000
 
+		test -f /etc/firewall.exwan && sh /etc/firewall.exwan
 		case "$1" in
 			start)
 				[ -f $STATE ] && die "The fw4 firewall appears to be already loaded."
@@ -38,6 +39,7 @@ start() {
 		ACTION=includes \
 			utpl -S $MAIN
 	} 1000>$LOCK
+	test -f /etc/firewall.include && sh /etc/firewall.include
 }
 
 print() {


================================================
FILE: devices/common/diy/package/network/config/firewall4/patches/200-fw4-hotplug-fork.patch
================================================
diff --git a/root/etc/hotplug.d/iface/20-firewall b/root/etc/hotplug.d/iface/20-firewall
index d0f030b..9a8132c 100644
--- a/root/etc/hotplug.d/iface/20-firewall
+++ b/root/etc/hotplug.d/iface/20-firewall
@@ -14,4 +14,4 @@ has_zone() {
 has_zone || exit 0
 
 logger -t firewall "Reloading firewall due to $ACTION of $INTERFACE ($DEVICE)"
-fw4 -q reload
+fw4 -q reload &


================================================
FILE: devices/common/diy/package/system/opkg/patches/010-opkg-force-depends.patch
================================================
--- a/src/opkg-cl.c
+++ b/src/opkg-cl.c
@@ -255,6 +255,10 @@ static int args_parse(int argc, char *argv[])
 		}
 	}
 
+	conf->force_depends = 1;
+	conf->force_checksum = 1;
+	conf->force_overwrite = 1;
+
 	if (!conf->conf_file && !conf->offline_root)
 		conf->conf_file = xstrdup("/etc/opkg.conf");



================================================
FILE: devices/common/diy/package/system/opkg/patches/ignore_error.patch
================================================
--- a/libopkg/pkg.c
+++ b/libopkg/pkg.c
@@ -1422,5 +1422,4 @@
 			 "package \"%s\" %s script returned status %d.\n",
 			 pkg->name, script, err);
-		return err;
 	}
 


================================================
FILE: devices/common/diy/package/system/opkg/patches/pkg_hash.patch
================================================
--- a/libopkg/pkg_hash.c
+++ b/libopkg/pkg_hash.c
@@ -263,5 +263,5 @@
 
 	if (unresolved) {
-		res = 1;
+		// res = 1;
 		tmp = unresolved;
 		while (*tmp) {


================================================
FILE: devices/common/diy/package/system/opkg/patches/zh-cn.patch
================================================
---  a/libopkg/opkg_download.c
+++  b/libopkg/opkg_download.c
@@ -174,9 +174,9 @@
 		if (res) {
 			opkg_msg(ERROR,
-				 "Failed to download %s, wget returned %d.\n",
+				 "下载失败 %s, wget returned %d.\n",
 				 src, res);
 			if (res == 4)
 				opkg_msg(ERROR,
-					 "Check your network settings and connectivity.\n\n");
+					 "请检查网络设置, 确保本设备网络可用.\n\n");
 			free(tmp_file_location);
 			return -1;

---  a/libopkg/opkg.c
+++  b/libopkg/opkg.c
@@ -225,5 +225,5 @@
 	new = pkg_hash_fetch_best_installation_candidate_by_name(package_name);
 	if (!new) {
-		opkg_msg(ERROR, "Couldn't find package %s\n", package_name);
+		opkg_msg(ERROR, "找不到软件包 %s\n", package_name);
 		return -1;
 	}
@@ -242,5 +242,5 @@
 	if (unresolved) {
 		char **tmp = unresolved;
-		opkg_msg(ERROR, "Couldn't satisfy the following dependencies"
+		opkg_msg(ERROR, "无法满足以下依赖"
 			 " for %s:\n", package_name);
 		while (*tmp) {
@@ -271,5 +271,5 @@
 
 		if (pkg->src == NULL) {
-			opkg_msg(ERROR, "Package %s not available from any "
+			opkg_msg(ERROR, "在以下仓库未找到可用的 %s 软件包"
 				 "configured src\n", package_name);
 			return -1;

--- a/libopkg/opkg_install.c
+++ b/libopkg/opkg_install.c
@@ -222,6 +222,6 @@
 
 	if (pkg_size_kbs >= kbs_available) {
-		opkg_msg(ERROR, "Only have %ldkb available on filesystem %s, "
-			 "pkg %s needs %ld\n",
+		opkg_msg(ERROR, "剩余可用容量不足, 文件系统 %s 当前剩余 %ldkb 可用,"
+			 "软件包 %s 需要 %ld\n",
 			 kbs_available, root_dir, pkg->name, pkg_size_kbs);
 		return -1;
@@ -1319,6 +1319,6 @@
 		}
 		if (err) {
-			opkg_msg(ERROR, "Failed to download %s. "
-				 "Perhaps you need to run 'opkg update'?\n",
+			opkg_msg(ERROR, "下载 %s 失败. "
+				 "请更新列表后重试\n",
 				 pkg->name);
 			return -1;

--- a/libopkg/opkg_conf.c
+++ b/libopkg/opkg_conf.c
@@ -497,10 +497,10 @@
 	lock_fd = creat(lock_file, S_IRUSR | S_IWUSR | S_IRGRP);
 	if (lock_fd == -1) {
-		opkg_perror(ERROR, "Could not create lock file %s", lock_file);
+		opkg_perror(ERROR, "有任务在执行中, 请稍后再试.", lock_file);
 		goto err2;
 	}
 
 	if (lockf(lock_fd, F_TLOCK, (off_t) 0) == -1) {
-		opkg_perror(ERROR, "Could not lock %s", lock_file);
+		opkg_perror(ERROR, "有任务在执行中, 请稍后再试.", lock_file);
 		if (close(lock_fd) == -1)
 			opkg_perror(ERROR, "Couldn't close descriptor %d (%s)",


================================================
FILE: devices/common/diy.sh
================================================
#!/bin/bash
#=================================================
shopt -s extglob

sed -i '$a src-git kiddin9 https://github.com/kiddin9/op-packages.git;main' feeds.conf.default
sed -i "/telephony/d" feeds.conf.default

sed -i "s?targets/%S/packages?targets/%S/\$(LINUX_VERSION)?" include/feeds.mk

sed -i '/	refresh_config();/d' scripts/feeds

sed -i "s?git.openwrt.org/\(project\|feed\)?github.com/openwrt?g" feeds.conf.default

./scripts/feeds update -a
./scripts/feeds install -a -p kiddin9 -f
./scripts/feeds install -a

sed --follow-symlinks -i "s#%C\"#%C by Kiddin'\"#" package/base-files/files/etc/os-release
sed -i -e '$a /etc/bench.log' \
        -e '/\/etc\/profile/d' \
        -e '/\/etc\/shinit/d' \
        package/base-files/files/lib/upgrade/keep.d/base-files-essential
sed -i -e '/^\/etc\/profile/d' \
        -e '/^\/etc\/shinit/d' \
        package/base-files/Makefile
sed -i "s/192.168.1/10.0.0/" package/base-files/files/bin/config_generate

sed -i "s#false; \\\#true; \\\#" include/download.mk

wget -N https://github.com/immortalwrt/immortalwrt/raw/refs/heads/openwrt-25.12/package/kernel/linux/modules/video.mk -P package/kernel/linux/modules/
wget -N https://github.com/immortalwrt/immortalwrt/raw/refs/heads/openwrt-25.12/package/network/utils/nftables/patches/002-nftables-add-fullcone-expression-support.patch -P package/network/utils/nftables/patches/
wget -N https://github.com/immortalwrt/immortalwrt/raw/refs/heads/openwrt-25.12/package/libs/libnftnl/patches/001-libnftnl-add-fullcone-expression-support.patch -P package/libs/libnftnl/patches/
wget -N https://github.com/immortalwrt/immortalwrt/raw/refs/heads/openwrt-25.12/package/firmware/wireless-regdb/patches/600-custom-change-txpower-and-dfs.patch -P package/firmware/wireless-regdb/patches/
wget -N  https://github.com/coolsnowwolf/lede/raw/refs/heads/master/package/system/fstools/patches/0200-ntfs3-with-utf8.patch -P package/system/fstools/patches/
wget -N https://github.com/immortalwrt/immortalwrt/raw/refs/heads/openwrt-25.12/config/Config-kernel.in -P config/

rm -rf package/libs/openssl package/network/services/ppp
git_clone_path openwrt-25.12 https://github.com/immortalwrt/immortalwrt package/libs/openssl package/network/services/ppp 

echo "$(date +"%s")" >version.date
sed -i '/$(curdir)\/compile:/c\$(curdir)/compile: package/opkg/host/compile' package/Makefile
sed -i "s/DEFAULT_PACKAGES:=/DEFAULT_PACKAGES:=luci-app-advancedplus luci-app-firewall luci-app-package-manager luci-app-upnp luci-app-syscontrol luci-proto-wireguard \
luci-app-wizard luci-base luci-compat luci-lib-ipkg luci-lib-fs \
coremark wget-ssl curl autocore htop nano zram-swap kmod-lib-zstd kmod-tcp-bbr bash openssh-sftp-server block-mount resolveip ds-lite swconfig luci-app-fan luci-app-filemanager luci-app-wifihistory /" include/target.mk

sed -i "s/^.*vermagic$/\techo '1' > \$(LINUX_DIR)\/.vermagic/" include/kernel-defaults.mk

status=$(curl -H "Authorization: token $REPO_TOKEN" -s "https://api.github.com/repos/kiddin9/op-packages/actions/runs" | jq -r '.workflow_runs[0].status')
echo "$status"
while [[ "$status" == "in_progress" || "$status" == "queued" ]];do
	echo "wait 5s"
	sleep 5
	status=$(curl -H "Authorization: token $REPO_TOKEN" -s "https://api.github.com/repos/kiddin9/op-packages/actions/runs" | jq -r '.workflow_runs[0].status')
done

wget -N https://raw.githubusercontent.com/openwrt/packages/master/lang/golang/golang/Makefile -P feeds/packages/lang/golang/golang/

#sed -i "/call Build\/check-size,\$\$(KERNEL_SIZE)/d" include/image.mk

sed -i "/+= targz/d" include/image.mk

git_clone_path master https://github.com/coolsnowwolf/lede mv target/linux/generic/hack-6.12

rm -rf target/linux/generic/hack-6.12/767-net-phy-realtek-add-led*
wget -N https://raw.githubusercontent.com/coolsnowwolf/lede/master/target/linux/generic/pending-6.12/613-netfilter_optional_tcp_window_check.patch -P target/linux/generic/pending-6.12/

# find target/linux/x86 -name "config*" -exec bash -c 'cat kernel.conf >> "{}"' \;
sed -i 's/max_requests 3/max_requests 20/g' package/network/services/uhttpd/files/uhttpd.config
#rm -rf ./feeds/packages/lang/{golang,node}
sed -i "s/tty\(0\|1\)::askfirst/tty\1::respawn/g" target/linux/*/base-files/etc/inittab

date=`date +%m.%d.%Y`
sed -i -e "/\(# \)\?REVISION:=/c\REVISION:=$date" -e '/VERSION_CODE:=/c\VERSION_CODE:=$(REVISION)' include/version.mk

sed -i 's/option timeout 30/option timeout 60/g' package/system/rpcd/files/rpcd.config
sed -i 's#20) \* 1000#60) \* 1000#g' feeds/luci/modules/luci-base/htdocs/luci-static/resources/rpc.js

sed -i \
	-e "s/+\(luci\|luci-ssl\|uhttpd\)\( \|$\)/\2/" \
	-e "s/+nginx\( \|$\)/+nginx-ssl\1/" \
	-e 's/+python\( \|$\)/+python3/' \
	-e 's?../../lang?$(TOPDIR)/feeds/packages/lang?' \
	package/feeds/kiddin9/*/Makefile

sed -i "s/OpenWrt/Kwrt/g" package/base-files/files/bin/config_generate package/base-files/image-config.in package/network/config/wifi-scripts/files/lib/wifi/mac80211.uc config/Config-images.in Config.in include/u-boot.mk include/version.mk || true

sed -i -e "s/set \${s}.country='\${country || ''}'/set \${s}.country='\${country || \"CN\"}'/g" -e "s/set \${s}.disabled=.*/set \${s}.disabled='0'/" package/network/config/wifi-scripts/files/lib/wifi/mac80211.uc

rm -rf package/feeds/packages/jool

================================================
FILE: devices/common/patches/LINUX_VERSION.patch
================================================
--- a/Makefile
+++ b/Makefile
@@ -33,6 +33,7 @@ ifneq ($(OPENWRT_BUILD),1)
   include $(TOPDIR)/include/toplevel.mk
 else
   include rules.mk
+  include $(INCLUDE_DIR)/target.mk
   include $(INCLUDE_DIR)/depends.mk
   include $(INCLUDE_DIR)/subdir.mk
   include target/Makefile
@@ -131,6 +132,10 @@ world: prepare $(target/stamp-compile) $(package/stamp-compile) $(package/stamp-
 	$(_SINGLE)$(SUBMAKE) -r package/index
 	$(_SINGLE)$(SUBMAKE) -r json_overview_image_info
 	$(_SINGLE)$(SUBMAKE) -r checksum
+	cp -f $(BIN_DIR)/packages/Packages.manifest $(BIN_DIR)/
+	rm -rf $(BIN_DIR)/$(LINUX_VERSION)
+	mv -f $(BIN_DIR)/packages $(BIN_DIR)/$(LINUX_VERSION) 2>/dev/null
+	mv -f $(BIN_DIR)/profiles.json $(BIN_DIR)/profiles.json.b 2>/dev/null
 ifneq ($(CONFIG_CCACHE),)
 	$(STAGING_DIR_HOST)/bin/ccache -s
 endif


================================================
FILE: devices/common/patches/autoreconf.patch
================================================
--- a/package/libs/libnftnl/Makefile
+++ b/package/libs/libnftnl/Makefile
@@ -19,6 +19,7 @@
 PKG_MAINTAINER:=Steven Barth <steven@midlink.org>
 PKG_LICENSE:=GPL-2.0-or-later
 PKG_LICENSE_FILES:=COPYING
+PKG_FIXUP:=autoreconf
 
 PKG_INSTALL:=1
 PKG_BUILD_PARALLEL:=1

================================================
FILE: devices/common/patches/base-files.patch
================================================
--- a/package/base-files/files/lib/functions.sh
+++ b/package/base-files/files/lib/functions.sh
@@ -395,10 +395,13 @@ default_postinst() {
 			if [ "$PKG_UPGRADE" != "1" ]; then
 				"$i" enable
 			fi
-			"$i" start
+			if "$i" enabled; then
+				"$i" start
+			fi
 		fi
 	done
 
+	[ -x /etc/init.d/ucitrack ] && /etc/init.d/ucitrack reload
 	return $ret
 }
 

--- a/package/base-files/files/etc/shinit
+++ b/package/base-files/files/etc/shinit
@@ -2,6 +2,8 @@
 [ -x /usr/bin/vim ] && alias vi=vim || alias vim=vi
 
 alias ll='ls -alF --color=auto'
+alias reboot='(/bin/busybox reboot &);sleep 3;/bin/busybox reboot -f'
+PS1='\[\e[32m\][\[\e[m\]\[\e[31m\]\u\[\e[m\]\[\e[33m\]@\[\e[m\]\[\e[32m\]\h\[\e[m\]:\[\e[m\]\[\e[32m\]\[\e[1;32m\]\@\[\e[36m\] \w\[\e[m\]\[\e[32m\]]\[\e[0m\] \$\[\e[m\] '
 
 [ -z "$KSH_VERSION" -o \! -s /etc/mkshrc ] || . /etc/mkshrc

--- a/package/base-files/files/sbin/sysupgrade
+++ b/package/base-files/files/sbin/sysupgrade
@@ -287,11 +287,7 @@ create_backup_archive() {
 				# Format: pkg-name<TAB>{rom,overlay,unknown}
 				# rom is used for pkgs in /rom, even if updated later
 				if [ -d "/usr/lib/opkg/info" ]; then
-					tar_print_member "$INSTALLED_PACKAGES" "$(find /usr/lib/opkg/info -name "*.control" \( \
-						\( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \
-						\( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \
-						\( -exec echo {} unknown \; \) \
-						\) | sed -e 's,.*/,,;s/\.control /\t/')" || ret=1
+					. /etc/profile.d/opkg.sh && opkg save
 				elif [ -d "/lib/apk/packages" ]; then
 					tar_print_member "$INSTALLED_PACKAGES" "$(find /lib/apk/packages -name "*.list" \( \
 						\( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \
@@ -299,6 +295,10 @@ create_backup_archive() {
 						\( -exec echo {} unknown \; \) \
 						\) | sed -e 's,.*/,,;s/\.list /\t/')" || ret=1
 				fi
+			else
+				uci -q del opkg.auto
+				uci -q del opkg.custom
+				uci commit opkg
 			fi
 		fi
 

--- a/package/base-files/files/etc/profile
+++ b/package/base-files/files/etc/profile
@@ -33,7 +33,11 @@ esac
 if [ -z "$FAILSAFE" ] ; then
 	for FILE in /etc/profile.d/*.sh ; do
 		[ -f "${FILE%.sh}.hush" ] && continue
-		[ -f "$FILE" ] && . "$FILE"
+		if [ "$FILE" == "/etc/profile.d/30-sysinfo.sh" ]; then
+		 [ "$(which bash)" ] && env -i bash "$FILE"
+		else
+		 [ -f "$FILE" ] && . "$FILE"
+		fi
 	done
 	unset FILE
 fi

--- a/package/base-files/files/lib/preinit/02_sysinfo
+++ b/package/base-files/files/lib/preinit/02_sysinfo
@@ -5,6 +5,7 @@ do_sysinfo_generic() {
 		echo "$(strings /proc/device-tree/compatible | head -1)" > /tmp/sysinfo/board_name
 	[ ! -e /tmp/sysinfo/model -a -e /proc/device-tree/model ] && \
 		echo "$(cat /proc/device-tree/model)" > /tmp/sysinfo/model
+	sed -i "s/friendlyelec/friendlyarm/" /tmp/sysinfo/board_name
 }
 
 boot_hook_add preinit_main do_sysinfo_generic



================================================
FILE: devices/common/patches/china_mirrors.patch.b
================================================
--- a/scripts/download.pl
+++ b/scripts/download.pl
@@ -201,6 +201,10 @@ sub cleanup
 		push @mirrors, "https://mirror.leaseweb.com/debian/$1";
 		push @mirrors, "https://mirror.netcologne.de/debian/$1";
 	} elsif ($mirror =~ /^\@APACHE\/(.+)$/) {
+		push @mirrors, "https://mirrors.tencent.com/apache/$1";
+		push @mirrors, "https://mirrors.aliyun.com/apache/$1";
+		push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/apache/$1";
+		push @mirrors, "https://mirrors.ustc.edu.cn/apache/$1";
 		push @mirrors, "https://mirror.netcologne.de/apache.org/$1";
 		push @mirrors, "https://mirror.aarnet.edu.au/pub/apache/$1";
 		push @mirrors, "https://mirror.csclub.uwaterloo.ca/apache/$1";
@@ -211,11 +215,35 @@ sub cleanup
 		push @mirrors, "ftp://apache.cs.utah.edu/apache.org/$1";
 		push @mirrors, "ftp://apache.mirrors.ovh.net/ftp.apache.org/dist/$1";
 	} elsif ($mirror =~ /^\@GITHUB\/(.+)$/) {
+		my $dir = $1;
+		my $i = 0;
+		# replace the 2nd '/' with '@' for jsDelivr mirror
+		push @mirrors, "https://cdn.jsdelivr.net/gh/". $dir =~ s{\/}{++$i == 2 ? '@' : $&}ger;
+		push @mirrors, "https://raw.sevencdn.com/$dir";
+		push @mirrors, "https://raw.fastgit.org/$dir";
+		push @mirrors, "https://pd.zwc365.com/seturl/https://raw.githubusercontent.com/$dir";
+		push @mirrors, "https://ghproxy.com/https://raw.githubusercontent.com/$dir";
+		push @mirrors, "https://pd.zwc365.com/cfworker/https://raw.githubusercontent.com/$dir";
 		# give github a few more tries (different mirrors)
 		for (1 .. 5) {
-			push @mirrors, "https://raw.githubusercontent.com/$1";
+			push @mirrors, "https://raw.githubusercontent.com/$dir";
 		}
+	} elsif ($mirror =~ /^\@GHCODELOAD\/(.+)$/) {
+		push @mirrors, "https://pd.zwc365.com/seturl/https://codeload.github.com/$1";
+		push @mirrors, "https://ghproxy.com/https://codeload.github.com/$1";
+		push @mirrors, "https://pd.zwc365.com/cfworker/https://codeload.github.com/$1";
+		push @mirrors, "https://codeload.github.com/$1";
+	} elsif ($mirror =~ /^\@GHREPO\/(.+)$/) {
+		push @mirrors, "https://pd.zwc365.com/seturl/https://github.com/$1";
+		push @mirrors, "https://github.com.cnpmjs.org/$1";
+		push @mirrors, "https://ghproxy.com/https://github.com/$1";
+		push @mirrors, "https://hub.fastgit.org/$1";
+		push @mirrors, "https://github.com/$1";
 	} elsif ($mirror =~ /^\@GNU\/(.+)$/) {
+		push @mirrors, "https://mirrors.tencent.com/gnu/$1";
+		push @mirrors, "https://mirrors.tuna.tsinghua.edu.cn/gnu/$1";
+		push @mirrors, "https://mirrors.cqu.edu.cn/gnu/$1";
+		push @mirrors, "https://mirrors.ustc.edu.cn/gnu/$1";
 		push @mirrors, "https://mirror.csclub.uwaterloo.ca/gnu/$1";
 		push @mirrors, "https://mirror.netcologne.de/gnu/$1";
 		push @mirrors, "http://ftp.kddilabs.jp/GNU/gnu/$1";
@@ -240,6 +268,8 @@ sub cleanup
 			push @extra, "$extra[0]/longterm/v$1";
 		}
 		foreach my $dir (@extra) {
+			push @mirrors, "https://mirrors.cqu.edu.cn/kernel/$dir";
+			push @mirrors, "https://mirrors.ustc.edu.cn/kernel.org/$dir";
 			push @mirrors, "https://cdn.kernel.org/pub/$dir";
 			push @mirrors, "https://download.xs4all.nl/ftp.kernel.org/pub/$dir";
 			push @mirrors, "https://mirrors.mit.edu/kernel/$dir";
@@ -250,6 +280,7 @@ sub cleanup
 		}
 	} elsif ($mirror =~ /^\@GNOME\/(.+)$/) {
 		push @mirrors, "https://download.gnome.org/sources/$1";
+		push @mirrors, "https://mirrors.ustc.edu.cn/gnome/sources/$1";
 		push @mirrors, "https://mirror.csclub.uwaterloo.ca/gnome/sources/$1";
 		push @mirrors, "http://ftp.acc.umu.se/pub/GNOME/sources/$1";
 		push @mirrors, "http://ftp.kaist.ac.kr/gnome/sources/$1";
@@ -263,6 +294,7 @@ sub cleanup
 	}
 }
 
+unshift @mirrors, "http://182.140.223.146";
 push @mirrors, 'https://sources.cdn.openwrt.org';
 push @mirrors, 'https://sources.openwrt.org';
 push @mirrors, 'https://mirror2.openwrt.org/sources';
@@ -296,4 +328,3 @@ sub cleanup
 }
 
 $SIG{INT} = \&cleanup;
-


================================================
FILE: devices/common/patches/cmake.patch
================================================
--- a/include/cmake.mk
+++ b/include/cmake.mk
@@ -127,6 +127,7 @@ define Build/Configure/Default
 			-DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=TRUE \
 			-DCMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY=FALSE \
 			-DCMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY=TRUE \
+			-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
 			$(CMAKE_OPTIONS) \
 		$(CMAKE_SOURCE_DIR) \
 	)

================================================
FILE: devices/common/patches/compressed-memory.patch.b
================================================
--- a/package/kernel/linux/modules/crypto.mk
+++ b/package/kernel/linux/modules/crypto.mk
@@ -809,3 +809,18 @@ endef
 
 $(eval $(call KernelPackage,crypto-xts))
 
+
+define KernelPackage/crypto-zstd
+  TITLE:=zstd compression CryptoAPI module
+  DEPENDS:=+kmod-lib-zstd +kmod-crypto-acompress
+  KCONFIG:=CONFIG_CRYPTO_ZSTD
+  FILES:=$(LINUX_DIR)/crypto/zstd.ko
+  AUTOLOAD:=$(call AutoLoad,09,zstd)
+  $(call AddDepends/crypto)
+endef
+
+define KernelPackage/crypto-zstd/description
+ Kernel module for the CryptoAPI to support Zstandard
+endef
+
+$(eval $(call KernelPackage,crypto-zstd))

--- a/package/kernel/linux/modules/lib.mk
+++ b/package/kernel/linux/modules/lib.mk
@@ -166,6 +166,27 @@ endef
 $(eval $(call KernelPackage,lib-lz4))
 
 
+define KernelPackage/lib-lz4hc
+  SUBMENU:=$(LIB_MENU)
+  TITLE:=LZ4HC support
+  DEPENDS:=+kmod-lib-lz4 +kmod-crypto-acompress
+  HIDDEN:=1
+  KCONFIG:= \
+	CONFIG_CRYPTO_LZ4HC \
+	CONFIG_LZ4HC_COMPRESS
+  FILES:= \
+	$(LINUX_DIR)/crypto/lz4hc.ko \
+	$(LINUX_DIR)/lib/lz4/lz4hc_compress.ko
+  AUTOLOAD:=$(call AutoProbe,lz4hc lz4hc_compress)
+endef
+
+define KernelPackage/lib-lz4hc/description
+ Kernel module for LZ4HC compression/decompression support
+endef
+
+$(eval $(call KernelPackage,lib-lz4hc))
+
+
 define KernelPackage/lib-raid6
   SUBMENU:=$(LIB_MENU)
   TITLE:=RAID6 algorithm support

--- a/package/kernel/linux/modules/other.mk
+++ b/package/kernel/linux/modules/other.mk
@@ -869,6 +869,85 @@ endef
 $(eval $(call KernelPackage,zram))
 
 
+define KernelPackage/zsmalloc
+  SUBMENU:=$(OTHER_MENU)
+  TITLE:=ZSMALLOC support
+  DEPENDS:=+kmod-crypto-deflate \
+	+kmod-lib-lz4 \
+	@!PACKAGE_kmod-zram
+  KCONFIG:= \
+	CONFIG_ZSMALLOC \
+	CONFIG_ZSMALLOC_STAT=n
+  FILES:= $(LINUX_DIR)/mm/zsmalloc.ko
+  AUTOLOAD:=$(call AutoLoad,19,zsmalloc)
+endef
+
+define KernelPackage/zsmalloc/description
+ Special purpose memory allocator for compressed memory pages
+endef
+
+define KernelPackage/zsmalloc/config
+	if PACKAGE_kmod-zsmalloc
+		config KERNEL_PGTABLE_MAPPING
+			bool "zsmalloc: enable CONFIG_PGTABLE_MAPPING"
+			default y if arm
+			default n
+			help
+	  Enable CONFIG_PGTABLE_MAPPING in the kernel for faster memory
+	  allocations when using ZSMALLOC, in some architectures. Enabled
+	  by default for the ARM architecture because it may be a huge
+	  performance boost.
+	endif
+endef
+
+$(eval $(call KernelPackage,zsmalloc))
+
+
+define KernelPackage/zram-writeback
+  SUBMENU:=$(OTHER_MENU)
+  TITLE:=zram with writeback support
+  DEPENDS:=+kmod-zsmalloc
+  KCONFIG:= \
+	CONFIG_ZRAM \
+	CONFIG_ZRAM_DEBUG=n \
+	CONFIG_ZRAM_MEMORY_TRACKING=n \
+	CONFIG_ZRAM_WRITEBACK=y
+  FILES:= \
+	$(LINUX_DIR)/drivers/block/zram/zram.ko
+  AUTOLOAD:=$(call AutoLoad,20,zram)
+endef
+
+define KernelPackage/zram-writeback/description
+ Compressed RAM disk with support for page writeback
+endef
+
+$(eval $(call KernelPackage,zram-writeback))
+
+
+define KernelPackage/zswap
+  SUBMENU:=$(OTHER_MENU)
+  TITLE:=zswap compressed swapping cache
+  DEPENDS:=+kmod-zsmalloc
+  KCONFIG:= \
+	CONFIG_FRONTSWAP=y \
+	CONFIG_Z3FOLD \
+	CONFIG_ZBUD \
+	CONFIG_ZPOOL \
+	CONFIG_ZSWAP=y
+  FILES:= \
+	$(LINUX_DIR)/mm/z3fold.ko \
+	$(LINUX_DIR)/mm/zbud.ko \
+	$(LINUX_DIR)/mm/zpool.ko
+  AUTOLOAD:=$(call AutoLoad,20,z3fold zbud zpool)
+endef
+
+define KernelPackage/zswap/description
+ Compressed swap cache and compressed memory allocator support
+endef
+
+$(eval $(call KernelPackage,zswap))
+
+
 define KernelPackage/pps
   SUBMENU:=$(OTHER_MENU)
   TITLE:=PPS support


================================================
FILE: devices/common/patches/crontab.patch
================================================
From 388238b9baf8375e5474167c987a4a8a3358b559 Mon Sep 17 00:00:00 2001
From: Paul Donald <newtwen+github@gmail.com>
Date: Wed, 23 Apr 2025 00:03:25 +0200
Subject: [PATCH] luci-mod-system: give crontab a helper page

Reference: https://github.com/openwrt/luci/pull/7495

Signed-off-by: Paul Donald <newtwen+github@gmail.com>
---
 .../resources/view/system/crontabhelper.js    | 334 ++++++++++++++++++
 .../share/luci/menu.d/luci-mod-system.json    |  14 +-
 2 files changed, 347 insertions(+), 1 deletion(-)
 create mode 100644 feeds/luci/modules/luci-mod-system/htdocs/luci-static/resources/view/system/crontabhelper.js

diff --git a/feeds/luci/modules/luci-mod-system/htdocs/luci-static/resources/view/system/crontabhelper.js b/feeds/luci/modules/luci-mod-system/htdocs/luci-static/resources/view/system/crontabhelper.js
new file mode 100644
index 000000000000..861d4d1f77a5
--- /dev/null
+++ b/feeds/luci/modules/luci-mod-system/htdocs/luci-static/resources/view/system/crontabhelper.js
@@ -0,0 +1,334 @@
+'use strict';
+'require view';
+'require fs';
+'require ui';
+
+var isReadonlyView = !L.hasViewPermission() || null;
+
+
+const yearly  = { minute: '@yearly',  command: '', comment: '', };
+const monthly = { minute: '@monthly', command: '', comment: '', };
+const weekly  = { minute: '@weekly',  command: '', comment: '', };
+const daily   = { minute: '@daily',   command: '', comment: '', };
+const hourly  = { minute: '@hourly',  command: '', comment: '', };
+const a_task  = { minute: '*', hour: '*', day: '*', month: '*', weekday: '*', command: '', comment: '', };
+const alias   = { minute: '@', hour: '*', day: '*', month: '*', weekday: '*', command: '', comment: '', };
+
+const width = 'width:100px;';
+const double_width = 'width:300px';
+const padding = 'padding:3px;';
+const centre = 'text-align:center;';
+
+return view.extend({
+	load() {
+		return L.resolveDefault(fs.read('/etc/crontabs/root'), '');
+	},
+
+	handleSave(ev) {
+		const tasks = Array.from(document.querySelectorAll('.crontab-row')).map(row => {
+			const getFieldValue = (fieldName) => {
+				const mode = row.querySelector(`.${fieldName}-mode`)?.value;
+
+				switch (mode) {
+				case 'custom':
+					const custom = row.querySelector(`.${fieldName}-custom`)?.value?.trim();
+					return custom;
+				case 'ignore':
+					return '*';
+				case 'interval':
+					const interval = row.querySelector(`.${fieldName}-interval`)?.value?.trim();
+					return interval ? `*/${interval}` : '*'; // Every Xth unit
+				case 'specific':
+					const specific = row.querySelector(`.${fieldName}-specific`)?.value?.trim();
+					return specific || '*'; // Specific units
+				}
+			};
+
+			const comment = row.querySelector('.comment')?.value?.trim();
+			const minute  = row.querySelector('.minute')?.value?.trim();
+
+			// if it's a # comment row, just stuff the comment and return
+			if (minute == comment)
+				return { iscomment: true, comment: comment };
+			else
+				return {
+					minute: getFieldValue('minute') || '*',
+					hour: getFieldValue('hour') || '*',
+					day: getFieldValue('day') || '*',
+					month: getFieldValue('month') || '*',
+					weekday: getFieldValue('weekday') || '*',
+					command: row.querySelector('.command')?.value?.trim(),
+					comment: comment ? `# ${comment}` : '',
+				};
+		});
+
+		const value = tasks.map(task => {
+			if (task.iscomment)
+				return `${task.comment}`;
+			else if (task.minute[0] !== '@')
+				return `${task.minute} ${task.hour} ${task.day} ${task.month} ${task.weekday} ${task.command} ${task.comment}`;
+			else
+				return `${task.minute} ${task.command} ${task.comment}`;
+		}).join('\n') + '\n';
+
+		return fs.write('/etc/crontabs/root', value).then(() => {
+			ui.addTimeLimitedNotification(null, E('p', _('Contents have been saved.')), 5000, 'info');
+			return fs.exec('/etc/init.d/cron', [ 'reload' ]);
+		}).catch(e => {
+			ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
+		});
+	},
+
+	render(crontab) {
+		const tasks = (crontab || '').split('\n').filter(line => line.trim()).map(line => {
+			if (line.startsWith('#'))
+				return {
+					// stash comment lines for saving later
+					minute:  line,
+					comment: line,
+				};
+			const parts = line.split(/\s+/);
+			const commentIndex = parts.findIndex(part => part.startsWith('#'));
+			// exclude the '#' character from comments existing in valid command rows:
+			if (commentIndex !== -1) parts[commentIndex] = parts[commentIndex].substring(1)?.trim();
+			const comment = commentIndex !== -1 ? parts.slice(commentIndex).join(' ') : '';
+
+			if(parts[0][0] == '@') {
+				const updatedTask = { ...alias };
+				updatedTask.minute = parts[0];
+				updatedTask.command = commentIndex !== -1 ? parts.slice(1, commentIndex).join(' ') : parts.slice(1).join(' ');
+				updatedTask.comment = comment;
+				return updatedTask;
+			}
+
+			return {
+				minute:  parts[0] || '',
+				hour:    parts[1] || '',
+				day:     parts[2] || '',
+				month:   parts[3] || '',
+				weekday: parts[4] || '',
+				command: commentIndex !== -1 ? parts.slice(5, commentIndex).join(' ') : parts.slice(5).join(' ') || '',
+				comment: comment || '',
+			};
+		});
+
+		return E([
+			E('h2', _('Scheduled Tasks')),
+			E('p', { 'class': 'cbi-section-descr' }, _('Define your scheduled tasks for root below.') + '<br/>' + 
+				_('CSV - Comma Separated Value(s)')),
+			E('a', { 'href': 'https://openwrt.org/docs/guide-user/base-system/cron', 'target':'_blank' }, _('Crontab help wiki')),
+			E('table', { 'class': 'table', }, [
+				E('thead', {}, [
+					E('tr', {}, [
+						E('th', {}, _('Minute / Alias', 'minute or crontab alias field')),
+						E('th', {}, _('Hour')),
+						E('th', {}, _('Day')),
+						E('th', {}, _('Month')),
+						E('th', {}, _('Weekday')),
+						E('th', {}, _('Command')),
+						E('th', {}, _('Comment')),
+						E('th', {}, _('Action'))
+					])
+				]),
+				E('tbody', { 'id': 'crontab-rows' }, this.renderTaskRows(tasks)),
+				E('hr', {}),
+				E('tfoot', {}, [
+					E('tr', {}, [
+						E('td', { 'colspan': 1, 'style': padding }, [
+							E('button', { 'class': 'btn', 'click': ui.createHandlerFn(this, 'addTask', alias   ) }, _('Add alias'))
+						]),
+						E('td', { 'colspan': 1, 'style': padding }, [
+							E('button', { 'class': 'btn', 'click': ui.createHandlerFn(this, 'addTask', yearly  ) }, _('Yearly task'))
+						]),
+						E('td', { 'colspan': 1, 'style': padding }, [
+							E('button', { 'class': 'btn', 'click': ui.createHandlerFn(this, 'addTask', monthly ) }, _('Monthly task'))
+						]),
+						E('td', { 'colspan': 1, 'style': padding }, [
+							E('button', { 'class': 'btn', 'click': ui.createHandlerFn(this, 'addTask', weekly  ) }, _('Weekly task'))
+						]),
+						E('td', { 'colspan': 1, 'style': padding }, [
+							E('button', { 'class': 'btn', 'click': ui.createHandlerFn(this, 'addTask', daily   ) }, _('Daily task'))
+						]),
+						E('td', { 'colspan': 1, 'style': padding }, [
+							E('button', { 'class': 'btn', 'click': ui.createHandlerFn(this, 'addTask', hourly  ) }, _('Hourly task'))
+						]),
+						E('td', { 'colspan': 1, 'style': padding }, [
+							E('button', { 'class': 'btn', 'click': ui.createHandlerFn(this, 'addTask') }, _('Add custom task'))
+						]),
+					])
+				])
+			])
+		]);
+	},
+
+	renderTaskRows(tasks) {
+		const rows = [];
+
+		tasks.forEach((task, index) => {
+			if (task?.minute.startsWith('#') && task?.comment){
+				rows.push(this.renderCommentRow(task));
+				return;
+			}
+			rows.push(E('tr', { 'class': 'crontab-hr' }, E('td', { 'colspan': 8 }, E('hr', { 'style': 'margin: 10px 0;' }))));
+			if (task.minute[0] == '@')
+				rows.push(this.renderAliasRow(task));
+			else
+				rows.push(this.renderTaskRow(task));
+		});
+
+		return rows;
+	},
+
+	renderAliasRow(task) {
+		return E('tr', { 'class': 'crontab-row', 'style': padding }, [
+					this.createTimeDropdown('minute', task.minute, 'Minute'),
+					E('td', { 'style': padding + centre }, _('-')), // Hour - empty
+					E('td', { 'style': padding + centre }, _('-')), // Day - empty
+					E('td', { 'style': padding + centre }, _('-')), // Month - empty
+					E('td', { 'style': padding + centre }, _('-')), // Weekday - empty
+					E('td', { 'style': padding + centre },
+						E('div', {}, [
+							E('label', {}, _('Command')),
+							E('input', { 'type': 'text', 'class': 'command', 'style': double_width, 'value': task.command, 'disabled': isReadonlyView }),
+						]),
+					),
+					E('td', { 'style': padding },
+						E('div', {}, [
+							E('label', {}, _('Comment')),
+							E('input', { 'type': 'text', 'class': 'comment', 'style': width, 'value': task.comment, 'disabled': isReadonlyView }),
+						]),
+					),
+					E('td', { 'style': padding }, [
+						E('button', { 'class': 'btn remove-task cbi-button-negative', 'click': ui.createHandlerFn(this, 'removeTask') }, _('Remove'))
+					])
+				]);
+	},
+
+	renderTaskRow(task) {
+		return E('tr', { 'class': 'crontab-row' }, [
+					this.createTimeDropdown('minute', task.minute, 'Minute', 0, 59),
+					this.createTimeDropdown('hour', task.hour, 'Hour', 0, 23),
+					this.createTimeDropdown('day', task.day, 'Day', 0, 31),
+					this.createTimeDropdown('month', task.month, 'Month', 0, 12),
+					this.createTimeDropdown('weekday', task.weekday, 'Weekday', 0, 6),
+					E('td', { 'style': padding }, E('input', { 'type': 'text', 'class': 'command', 'style': double_width, 'value': task.command, 'disabled': isReadonlyView })),
+					E('td', { 'style': padding }, E('input', { 'type': 'text', 'class': 'comment', 'style': width, 'value': task.comment, 'disabled': isReadonlyView })),
+					E('td', { 'style': padding }, [
+						E('button', { 'class': 'btn remove-task cbi-button-negative', 'click': ui.createHandlerFn(this, 'removeTask') }, _('Remove'))
+					])
+				]);
+	},
+
+	/* 
+	hide the comment rows in valid fields, but don't display them.
+	*/
+	renderCommentRow(task) {
+		// 
+		return E('tr', { 'class': 'crontab-row', 'style': 'display: none; ' }, [
+			E('td', { 'style': padding },
+				E('div', {}, [
+					E('label', {}, _('Minute')),
+					E('input', { 'type': 'text', 'class': 'minute', 'style': width, 'value': task.comment, 'disabled': isReadonlyView }),
+				]),
+			),
+			E('td', { 'style': padding },
+				E('div', {}, [
+					E('label', {}, _('Comment')),
+					E('input', { 'type': 'text', 'class': 'comment', 'style': width, 'value': task.comment, 'disabled': isReadonlyView }),
+				]),
+			),
+		]);
+	},
+
+	/* 
+	creates a block of entry fields customisable to the time interval type
+	*/
+	createTimeDropdown(fieldName, value, label, min, max) {
+		const mode = value.includes(',') || parseInt(value, 10) >= 0 || value.startsWith('@')
+			? (value.split(',').filter(v => v.startsWith('*/')).length > 1 || value.startsWith('@') ? 'custom' : 'specific')
+			: value.startsWith('*/')
+			? 'interval'
+			: 'ignore';
+
+		const intervalValue = mode === 'interval' ? value.substring(2) : '';
+		const specificValue = mode === 'specific' ? value : '';
+		const customValue = mode === 'custom' ? value : '';
+
+		return E('td', { 'style': padding }, [
+			E('div', { 'class': 'dropdown-container' }, [
+				E('select', { 
+					'class': `${fieldName}-mode`,
+					'style': width,
+					'change': ev => this.updateDropdownMode(ev, fieldName) 
+				}, [
+					E('option', { 'value': 'ignore', 'style': width,
+						...(mode === 'ignore' ? { 'selected': 'true' } : {})
+					}, _('-')),
+					E('option', { 'value': 'interval', 'style': width,
+						...(mode === 'interval' ? { 'selected': 'true' } : {}) 
+					}, _('Every Xth')),
+					E('option', { 'value': 'specific', 'style': width,
+						...(mode === 'specific' ? { 'selected': 'true' } : {}) 
+					}, _('Specific')),
+					E('option', { 'value': 'custom', 'style': width,
+						...(mode === 'custom' ? { 'selected': 'true' } : {}) 
+					}, _('Custom'))
+				]),
+				E('div', { 'class': `${fieldName}-input ignore-input`, 'style': mode === 'ignore' ? '' : 'display:none;' }, [
+					E('input', { 'type': 'text', 'class': fieldName, 'value': '*', 'style': mode === 'ignore' ? 'display:none;': width,
+					})
+				]),
+				E('div', { 'class': `${fieldName}-input interval-input`, 'style': mode === 'interval' ? width : 'display:none;' }, [
+					E('label', {}, _('Every')),
+					E('input', { 'type': 'number', 'min': min, 'max': max, 'class': `${fieldName}-interval`, 'value': intervalValue, 'style': width }),
+					E('span', {}, _(label.toLowerCase()))
+				]),
+				E('div', { 'class': `${fieldName}-input specific-input`, 'style': mode === 'specific' ? width : 'display:none;' }, [
+					E('label', {}, _('At')),
+					E('input', { 'type': 'text', 'class': `${fieldName}-specific`, 'value': specificValue, 'style': width, 'placeholder': '0,5,10,...' }),
+					E('span', {}, _(label.toLowerCase() + _('s (CSV)', 'pluralisation for hours, minutes, etc')))
+				]),
+				E('div', { 'class': `${fieldName}-input custom-input`, 'style': mode === 'custom' ? width : 'display:none;' }, [
+					E('label', {}, _('Value')),
+					E('input', { 'type': 'text', 'class': `${fieldName}-custom`, 'value': customValue, 'style': width })
+				]),
+			])
+		]);
+	},
+
+	updateDropdownMode(ev, fieldName) {
+		const dropdown = ev.target.closest('.dropdown-container');
+		const mode = ev.target.value;
+
+		dropdown.querySelectorAll(`.${fieldName}-input`).forEach(input => {
+			input.style.display = 'none';
+		});
+
+		dropdown.querySelector(`.${fieldName}-input.${mode}-input`).style.display = '';
+	},
+
+	addTask(param) {
+		const tbody = document.getElementById('crontab-rows');
+
+		let newTask
+		if (param?.type !== 'click') {
+			newTask = param;
+		} else {
+			newTask = a_task; 
+		}
+		const newRows = this.renderTaskRows([newTask]);
+		newRows.forEach(row => {
+			tbody.appendChild(row);
+		})
+	},
+
+	removeTask(ev) {
+		const row = ev.target.closest('.crontab-row');
+		const hr = row.previousElementSibling;
+		if (hr)	hr.remove();
+		if (row) row.remove();
+	},
+
+	handleSaveApply: null,
+	handleReset: null
+});
diff --git a/feeds/luci/modules/luci-mod-system/root/usr/share/luci/menu.d/luci-mod-system.json b/feeds/luci/modules/luci-mod-system/root/usr/share/luci/menu.d/luci-mod-system.json
index ebae989d0e00..b4eba7862444 100644
--- a/feeds/luci/modules/luci-mod-system/root/usr/share/luci/menu.d/luci-mod-system.json
+++ b/feeds/luci/modules/luci-mod-system/root/usr/share/luci/menu.d/luci-mod-system.json
@@ -98,6 +98,16 @@
 		}
 	},
 
+	"admin/system/crontabhelper": {
+		"action": {
+			"type": "view",
+			"path": "system/crontabhelper"
+		},
+		"depends": {
+			"acl": [ "luci-mod-system-cron" ]
+		}
+	},
+
 	"admin/system/mounts": {
 		"title": "Mount Points",
 		"order": 50,

--- a/feeds/luci/modules/luci-mod-system/htdocs/luci-static/resources/view/system/crontab.js
+++ b/feeds/luci/modules/luci-mod-system/htdocs/luci-static/resources/view/system/crontab.js
@@ -27,6 +27,7 @@ return view.extend({
 		return E([
 			E('h2', _('Scheduled Tasks')),
 			E('p', { 'class': 'cbi-section-descr' }, _('This is the system crontab in which scheduled tasks can be defined.')),
+			E('p', { 'class': 'cbi-section-descr' }, _('<a href="/cgi-bin/luci/admin/system/crontabhelper"> Scheduled Tasks Helper</a>')),
 			E('p', {}, E('textarea', { 'style': 'width:100%', 'rows': 25, 'disabled': isReadonlyView }, [ crontab != null ? crontab : '' ]))
 		]);
 	},


================================================
FILE: devices/common/patches/curl.patch
================================================
--- a/package/feeds/packages/curl/Config.in
+++ b/package/feeds/packages/curl/Config.in
@@ -4,7 +4,7 @@ comment "SSL support"
 
 choice
 	prompt "Selected SSL library"
-	default LIBCURL_MBEDTLS
+	default LIBCURL_OPENSSL
 
 	config LIBCURL_MBEDTLS
 		bool "mbed TLS"


================================================
FILE: devices/common/patches/default-packages.patch
================================================
--- a/include/target.mk
+++ b/include/target.mk
@@ -50,10 +50,8 @@ DEFAULT_PACKAGES.nas:=\
 # @brief Default packages for @DEVICE_TYPE router.
 ##
 DEFAULT_PACKAGES.router:=\
-	dnsmasq \
+	dnsmasq-full \
 	firewall4 \
-	nftables \
-	kmod-nft-offload \
 	odhcp6c \
 	odhcpd-ipv6only \
 	ppp \


================================================
FILE: devices/common/patches/disable-seccomp-ujail.patch
================================================
--- a/config/Config-kernel.in
+++ b/config/Config-kernel.in
@@ -1185,13 +1185,13 @@ config KERNEL_POSIX_MQUEUE
 
 config KERNEL_SECCOMP_FILTER
 	bool
-	default y if !SMALL_FLASH
+	default n
 
 config KERNEL_SECCOMP
 	bool "Enable seccomp support"
 		depends on !(TARGET_uml)
 		select KERNEL_SECCOMP_FILTER
-		default y if !SMALL_FLASH
+		default n
 		help
 		  Build kernel with support for seccomp.
 
--- a/include/target.mk
+++ b/include/target.mk
@@ -88,11 +88,6 @@ else
   endif
 endif
 
-# include ujail on systems with enough storage
-ifeq ($(filter small_flash,$(FEATURES)),)
-  DEFAULT_PACKAGES+=procd-ujail
-endif
-
 # Add device specific packages (here below to allow device type set from subtarget)
 DEFAULT_PACKAGES += $(DEFAULT_PACKAGES.$(DEVICE_TYPE))
 


================================================
FILE: devices/common/patches/dnsmasq.patch
================================================
--- a/package/network/services/dnsmasq/Makefile
+++ b/package/network/services/dnsmasq/Makefile
@@ -22,6 +22,8 @@ PKG_CPE_ID:=cpe:/a:thekelleys:dnsmasq
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_UPSTREAM_VERSION)
 
+PKG_BUILD_DEPENDS:=nftables
+
 PKG_INSTALL:=1
 PKG_BUILD_PARALLEL:=1
 PKG_BUILD_FLAGS:=lto
@@ -66,8 +68,7 @@ $(call Package/dnsmasq/Default)
   TITLE += (with DNSSEC, DHCPv6, Auth DNS, IPset, Nftset, Conntrack, NO_ID enabled by default)
   DEPENDS+=+PACKAGE_dnsmasq_full_dnssec:libnettle \
 	+PACKAGE_dnsmasq_full_ipset:kmod-ipt-ipset \
-	+PACKAGE_dnsmasq_full_conntrack:libnetfilter-conntrack \
-	+PACKAGE_dnsmasq_full_nftset:nftables-json
+	+PACKAGE_dnsmasq_full_conntrack:libnetfilter-conntrack
   VARIANT:=full
   PROVIDES:=dnsmasq
 endef
@@ -187,6 +188,11 @@ define Package/dnsmasq/install
 	$(INSTALL_DIR) $(1)/etc/uci-defaults
 	$(INSTALL_BIN) ./files/50-dnsmasq-migrate-resolv-conf-auto.sh $(1)/etc/uci-defaults
 	$(INSTALL_BIN) ./files/50-dnsmasq-migrate-ipset.sh $(1)/etc/uci-defaults
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_BIN) $(STAGING_DIR)/usr/lib/libnftables.so.1 $(1)/usr/lib/libnftables.so.1
+	$(INSTALL_BIN) $(STAGING_DIR)/usr/lib/libjansson.so.4 $(1)/usr/lib/libjansson.so.4
+	$(INSTALL_BIN) $(STAGING_DIR)/usr/lib/libnftnl.so.11 $(1)/usr/lib/libnftnl.so.11
+	$(INSTALL_BIN) $(STAGING_DIR)/usr/lib/libmnl.so.0 $(1)/usr/lib/libmnl.so.0
 endef
 
 Package/dnsmasq-dhcpv6/install = $(Package/dnsmasq/install)


--- a/package/network/services/dnsmasq/files/dnsmasq.init
+++ b/package/network/services/dnsmasq/files/dnsmasq.init
@@ -1204,7 +1204,6 @@ dnsmasq_start()
 	[ -n "$instance_ifc" ] && network_get_device instance_netdev "$instance_ifc" &&
 		[ -n "$instance_netdev" ] && procd_set_param netdev $instance_netdev
 
-	procd_add_jail dnsmasq ubus log
 	procd_add_jail_mount $CONFIGFILE $DHCPBOGUSHOSTNAMEFILE $DHCPSCRIPT $DHCPSCRIPT_DEPENDS
 	procd_add_jail_mount $EXTRA_MOUNT $RFC6761FILE $TRUSTANCHORSFILE
 	procd_add_jail_mount $dnsmasqconffile $dnsmasqconfdir $resolvdir $user_dhcpscript
@@ -1217,6 +1216,20 @@ dnsmasq_start()
 	[ -e "$hostsfile" ] && procd_add_jail_mount $hostsfile
 
 	procd_close_instance
+	config_get_bool dns_redirect "$cfg" dns_redirect 0
+	config_get dns_port "$cfg" port 53
+	if [ "$dns_redirect" = 1 ]; then
+	if [ -n "$(command -v nft)" ]; then
+		nft add table inet dnsmasq
+		nft add chain inet dnsmasq prerouting "{ type nat hook prerouting priority -105; policy accept; }"
+		nft add rule inet dnsmasq prerouting "meta nfproto { ipv4, ipv6 } udp dport 53 counter redirect to :$dns_port comment \"DNSMASQ HIJACK\""
+	else
+		iptables -t nat -A PREROUTING -m comment --comment "DNSMASQ" -p udp --dport 53 -j REDIRECT --to-ports $dns_port
+		iptables -t nat -A PREROUTING -m comment --comment "DNSMASQ" -p tcp --dport 53 -j REDIRECT --to-ports $dns_port
+		[ -n "$(command -v ip6tables)" ] && ip6tables -t nat -A PREROUTING -m comment --comment "DNSMASQ" -p udp --dport 53 -j REDIRECT --to-ports $dns_port
+		[ -n "$(command -v ip6tables)" ] && ip6tables -t nat -A PREROUTING -m comment --comment "DNSMASQ" -p tcp --dport 53 -j REDIRECT --to-ports $dns_port
+	fi
+	fi
 }
 
 dnsmasq_stop()
@@ -1234,6 +1247,21 @@ dnsmasq_stop()
 	rm -f ${BASEDHCPSTAMPFILE}.${cfg}.*.dhcp
 }
 
+iptables_clear()
+{
+	config_get dns_port "$cfg" port 53
+	iptables -t nat -D PREROUTING -m comment --comment "DNSMASQ" -p udp --dport 53 -j REDIRECT --to-ports $dns_port 2>"/dev/null"
+	iptables -t nat -D PREROUTING -m comment --comment "DNSMASQ" -p tcp --dport 53 -j REDIRECT --to-ports $dns_port 2>"/dev/null"
+	[ -n "$(command -v ip6tables)" ] && ip6tables -t nat -D PREROUTING -m comment --comment "DNSMASQ" -p udp --dport 53 -j REDIRECT --to-ports $dns_port 2>"/dev/null"
+	[ -n "$(command -v ip6tables)" ] && ip6tables -t nat -D PREROUTING -m comment --comment "DNSMASQ" -p tcp --dport 53 -j REDIRECT --to-ports $dns_port 2>"/dev/null"
+}
+
+nftables_clear()
+{
+	! nft --check list table inet dnsmasq > "/dev/null" 2>&1 || \
+		nft delete table inet dnsmasq
+}
+
 add_interface_trigger()
 {
 	local interface ignore
@@ -1304,6 +1332,7 @@ start_service() {
 }
 
 reload_service() {
+	[ -n "$(command -v nft)" ] && nftables_clear || iptables_clear
 	rc_procd start_service "$@"
 	procd_send_signal dnsmasq "$@"
 }
@@ -1330,4 +1359,5 @@ stop_service() {
 	else
 		config_foreach dnsmasq_stop dnsmasq
 	fi
+	[ -n "$(command -v nft)" ] && nftables_clear || iptables_clear
 }


================================================
FILE: devices/common/patches/feeds.patch
================================================
--- a/include/feeds.mk
+++ b/include/feeds.mk
@@ -6,7 +6,7 @@
 -include $(TMP_DIR)/.packageauxvars
 
 FEEDS_INSTALLED:=$(notdir $(wildcard $(TOPDIR)/package/feeds/*))
-FEEDS_AVAILABLE:=$(sort $(FEEDS_INSTALLED) $(shell $(SCRIPT_DIR)/feeds list -n 2>/dev/null))
+FEEDS_AVAILABLE:=$(shell $(SCRIPT_DIR)/feeds list -n 2>/dev/null)
 
 PACKAGE_SUBDIRS=$(PACKAGE_DIR)
 ifneq ($(CONFIG_PER_FEED_REPO),)



================================================
FILE: devices/common/patches/firewall.patch
================================================
--- a/package/network/config/firewall4/Makefile
+++ b/package/network/config/firewall4/Makefile
@@ -25,7 +25,8 @@ define Package/firewall4
 	+kmod-nft-core +kmod-nft-fib +kmod-nft-offload \
 	+kmod-nft-nat \
 	+nftables-json \
-	+ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-uci
+	+ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-uci \
+	+iptables +ip6tables +kmod-nft-fullcone +kmod-nft-socket +kmod-nft-tproxy
   EXTRA_DEPENDS:=ucode (>=2022.03.22)
   PROVIDES:=uci-firewall
 endef
@@ -38,10 +39,14 @@ endef
 define Package/firewall4/conffiles
 /etc/config/firewall
 /etc/nftables.d/
+/etc/firewall.user
 endef
 
 define Package/firewall4/install
 	$(CP) -a $(PKG_BUILD_DIR)/root/* $(1)/
+	$(INSTALL_DIR) $(1)/etc/
+	$(INSTALL_CONF) ./files/firewall.include $(1)/etc/firewall.user
+	$(INSTALL_CONF) ./files/firewall.exwan $(1)/etc/firewall.exwan
 endef
 
 define Build/Compile

--- a/package/network/config/firewall/Makefile
+++ b/package/network/config/firewall/Makefile
@@ -30,9 +30,10 @@ define Package/firewall
   SECTION:=net
   CATEGORY:=Base system
   TITLE:=OpenWrt C Firewall
-  DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libiptext +IPV6:libiptext6 +libxtables +kmod-ipt-core +kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat
+  DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libiptext +IPV6:libiptext6 +libxtables +kmod-ipt-core +kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat \
+	+iptables-mod-fullconenat +ip6tables-mod-fullconenat +iptables-legacy +ip6tables-legacy +kmod-ipt-nat6 +kmod-ipt-offload \
+	+ipset +iptables-mod-conntrack-extra +iptables-mod-iprange +iptables-mod-socket +iptables-mod-tproxy
   PROVIDES:=uci-firewall
-  CONFLICTS:=firewall4
 endef
 
 define Package/firewall/description
 

 define Package/package/network/config/firewall/description
@@ -59,6 +59,7 @@ define Package/package/network/config/firewall/install
 	$(INSTALL_CONF) ./files/firewall.config $(1)/etc/config/firewall
 	$(INSTALL_DIR) $(1)/etc/
 	$(INSTALL_CONF) ./files/firewall.user $(1)/etc/firewall.user
+	$(INSTALL_CONF) ./files/firewall.exwan $(1)/etc/firewall.exwan
 	$(INSTALL_DIR) $(1)/usr/share/fw3
 	$(INSTALL_CONF) $(PKG_BUILD_DIR)/helpers.conf $(1)/usr/share/fw3
 endef

--- a/package/feeds/luci/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js
+++ b/package/feeds/luci/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js
@@ -58,6 +58,50 @@ return view.extend({
 
 		o = s.option(form.Flag, 'drop_invalid', _('Drop invalid packets'));
 
+		if (L.hasSystemFeature('fullcone')) {
+			o = s.option(form.Flag, 'fullcone', _('Enable FullCone NAT'));
+			if (fw4)
+				o = s.option(form.Flag, 'fullcone6', _('Enable FullCone NAT6'));
+				o.depends('fullcone', '1');
+		}
+
+		o = s.option(form.Flag, 'expose_wan', _('Expose WAN'), _('Danger! Proceed at your own risk.'));
+
+		o = s.option(form.Value, 'export', _('Ports to Expose'), _('Multiple ports can be, separated by spaces, format: 80 81 82'));
+		o.depends('expose_wan', '1');
+		o.validate = function(section_id, value) {
+		if (value.match(/^(\d+\s*)+$/)) {
+			return true;
+		}
+		 return _('Please enter valid format.');
+		};
+
+		o = s.option(form.ListValue, 'family', _('Restrict to address family'));
+		o.modalonly = true;
+		o.rmempty = true;
+		o.depends('expose_wan', '1');
+		o.value('', _('IPv4 and IPv6'));
+		o.value('ipv4', _('IPv4 only'));
+		o.value('ipv6', _('IPv6 only'));
+
+		o = s.option(form.ListValue, 'proto', _('Protocol'));
+		o.modalonly = true;
+		o.rmempty = true;
+		o.default = 'tcp';
+		o.depends('expose_wan', '1');
+		o.value('tcp', _('TCP'));
+		o.value('udp', _('UDP'));
+		o.value('tudp', _('TCP+UDP'));
+
+		o = s.option(form.Flag, 'ex_ssh', _('Expose SSH'));
+		o.depends('expose_wan', '1');
+		o = s.option(form.Flag, 'ex_backend', _('Expose Backend'));
+		o.depends('expose_wan', '1');
+		o = s.option(form.Value, 'backend_port', _('Backend Port'), _('国内请使用除80,443外的端口'));
+		o.depends('ex_backend', '1');
+		o.rmempty = false;
+		o.datatype = 'integer';
+
 		let p = [
 			s.option(form.ListValue, 'input', _('Input')),
 			s.option(form.ListValue, 'output', _('Output')),

--- a/package/network/config/firewall/files/firewall.init
+++ b/package/network/config/firewall/files/firewall.init
@@ -38,10 +38,12 @@ service_triggers() {
 }
 
 restart() {
+	test -f /etc/firewall.exwan && sh /etc/firewall.exwan
 	fw3 restart
 }
 
 start_service() {
+	test -f /etc/firewall.exwan && sh /etc/firewall.exwan
 	fw3 ${QUIET} start
 }
 
@@ -50,6 +52,7 @@ stop_service() {
 }
 
 reload_service() {
+	test -f /etc/firewall.exwan && sh /etc/firewall.exwan
 	fw3 reload
 }


================================================
FILE: devices/common/patches/getcwd-fix.patch
================================================
--- a/include/host-build.mk
+++ b/include/host-build.mk
@@ -61,7 +61,8 @@ HOST_CONFIGURE_VARS = \
 	CPPFLAGS="$(HOST_CPPFLAGS)" \
 	CXXFLAGS="$(HOST_CXXFLAGS)" \
 	LDFLAGS="$(HOST_LDFLAGS)" \
-	CONFIG_SHELL="$(SHELL)"
+	CONFIG_SHELL="$(SHELL)" \
+	gl_cv_func_getcwd_path_max=yes
 
 HOST_CONFIGURE_ARGS = \
 	--target=$(GNU_HOST_NAME) \


================================================
FILE: devices/common/patches/imagebuilder.patch
================================================
--- a/include/image.mk
+++ b/include/image.mk
@@ -717,7 +717,7 @@ define Device/Build/kernel
 endef
 
 define Device/Build/image
-  GZ_SUFFIX := $(if $(filter %dtb %gz,$(2)),,$(if $(and $(findstring ext4,$(1)),$(CONFIG_TARGET_IMAGES_GZIP)),.gz))
+  GZ_SUFFIX := $(if $(filter %dtb %gz,$(2)),,$(if $(and $(findstring ext4,$(1)),$(findstring img,$(2)),$(CONFIG_TARGET_IMAGES_GZIP)),.gz))
   $$(_TARGET): $(if $(CONFIG_JSON_OVERVIEW_IMAGE_INFO), \
 	  $(BUILD_DIR)/json_info_files/$(call DEVICE_IMG_NAME,$(1),$(2)).json, \
 	  $(BIN_DIR)/$(call DEVICE_IMG_NAME,$(1),$(2))$$(GZ_SUFFIX))
@@ -755,6 +755,7 @@ define Device/Build/image
 	FILE_TYPE=$(word 1,$(subst ., ,$(2))) \
 	FILE_FILESYSTEM="$(1)" \
 	DEVICE_IMG_PREFIX="$(DEVICE_IMG_PREFIX)" \
+	IMAGE_SIZE="$(shell echo $$(($(call exp_units,$(IMAGE_SIZE)))))" \
 	DEVICE_VENDOR="$(DEVICE_VENDOR)" \
 	DEVICE_MODEL="$(DEVICE_MODEL)" \
 	DEVICE_VARIANT="$(DEVICE_VARIANT)" \
@@ -861,6 +862,7 @@ define Device/DumpInfo
 Target-Profile: DEVICE_$(1)
 Target-Profile-Name: $(DEVICE_DISPLAY)
 Target-Profile-Packages: $(DEVICE_PACKAGES)
+Target-Profile-ImageSize: $(shell echo $$(( $(call exp_units,$(IMAGE_SIZE)) / 1024 )))
 Target-Profile-hasImageMetadata: $(if $(foreach image,$(IMAGES),$(findstring append-metadata,$(IMAGE/$(image)))),1,0)
 Target-Profile-SupportedDevices: $(SUPPORTED_DEVICES)
 $(if $(BROKEN),Target-Profile-Broken: $(BROKEN))

--- a/scripts/json_add_image_info.py
+++ b/scripts/json_add_image_info.py
@@ -72,6 +72,7 @@ def get_titles():
             "device_packages": getenv("DEVICE_PACKAGES").split(),
             "supported_devices": getenv("SUPPORTED_DEVICES").split(),
             "titles": get_titles(),
+            "image_size": getenv("IMAGE_SIZE"),
         }
     },
 }

--- a/scripts/target-metadata.pl
+++ b/scripts/target-metadata.pl
@@ -437,6 +437,7 @@ ()
 		print "PROFILE_NAMES = ".join(" ", @profile_ids_unique)."\n";
 		foreach my $profile (@{$cur->{profiles}}) {
 			print $profile->{id}.'_NAME:='.$profile->{name}."\n";
+			print $profile->{id}.'_IMAGE_SIZE:='.$profile->{image_size}."\n";
 			print $profile->{id}.'_HAS_IMAGE_METADATA:='.$profile->{has_image_metadata}."\n";
 			if (defined($profile->{supported_devices}) and @{$profile->{supported_devices}} > 0) {
 				print $profile->{id}.'_SUPPORTED_DEVICES:='.join(' ', @{$profile->{supported_devices}})."\n";

--- a/scripts/metadata.pm
+++ b/scripts/metadata.pm
@@ -150,6 +150,7 @@ sub parse_target_metadata($) {
 			push @{$target->{profiles}}, $profile;
 		};
 		/^Target-Profile-Name:\s*(.+)\s*$/ and $profile->{name} = $1;
+		/^Target-Profile-ImageSize:\s*(.*)\s*/ and $profile->{image_size} = $1;
 		/^Target-Profile-hasImageMetadata:\s*(\d+)\s*$/ and $profile->{has_image_metadata} = $1;
 		/^Target-Profile-SupportedDevices:\s*(.+)\s*$/ and $profile->{supported_devices} = [ split(/\s+/, $1) ];
 		/^Target-Profile-Priority:\s*(\d+)\s*$/ and do {

--- a/target/imagebuilder/Makefile
+++ b/target/imagebuilder/Makefile
@@ -39,7 +39,8 @@ $(BIN_DIR)/$(IB_NAME).tar.zst: clean
 		./files/Makefile \
 		$(TMP_DIR)/.targetinfo \
 		$(TMP_DIR)/.packageinfo \
-		$(PKG_BUILD_DIR)/
+		$(TOPDIR)/files \
+		$(PKG_BUILD_DIR)/ || true
 
 	$(INSTALL_DIR) $(PKG_BUILD_DIR)/packages
 
@@ -52,12 +53,13 @@ ifneq ($(CONFIG_USE_APK),)
 
 	$(INSTALL_DATA) ./files/README.apk.md $(PKG_BUILD_DIR)/packages/README.md
 else
-  ifeq ($(CONFIG_IB_STANDALONE),)
 	echo '## Remote package repositories' >> $(PKG_BUILD_DIR)/repositories.conf
 	$(call FeedSourcesAppendOPKG,$(PKG_BUILD_DIR)/repositories.conf)
 	$(VERSION_SED_SCRIPT) $(PKG_BUILD_DIR)/repositories.conf
 
-  endif
+	$(SED) 's/^src\/gz \(.*\) https.*ai\/\(.*packages.*\)/src \1 file:\/\/www\/wwwroot\/dl.openwrt.ai\/\2/' $(PKG_BUILD_DIR)/repositories.conf
+	$(SED) 's/^src\/gz \(.*\) https.*ai\/\(.*targets.*\)/src \1 file:\/\/www\/wwwroot\/dl.openwrt.ai\/\2/' $(PKG_BUILD_DIR)/repositories.conf
+	$(SED) '/openwrt_core/d' $(PKG_BUILD_DIR)/repositories.conf
 
 	# create an empty package index so `opkg` doesn't report an error
 	touch $(PKG_BUILD_DIR)/packages/Packages

--- a/target/imagebuilder/files/Makefile
+++ b/target/imagebuilder/files/Makefile
@@ -144,6 +144,33 @@ BUILD_PACKAGES:=$(sort $(DEFAULT_PACKAGES) $($(USER_PROFILE)_PACKAGES) kernel)
 # "-pkgname" in the package list means remove "pkgname" from the package list
 BUILD_PACKAGES:=$(filter-out $(filter -%,$(BUILD_PACKAGES)) $(patsubst -%,%,$(filter -%,$(BUILD_PACKAGES))),$(BUILD_PACKAGES))
 BUILD_PACKAGES:=$(USER_PACKAGES) $(BUILD_PACKAGES)
+IMAGE_SIZE_VALUE := $($(USER_PROFILE)_IMAGE_SIZE)
+ifdef IMAGE_SIZE_VALUE
+	ifeq ($(shell test $(IMAGE_SIZE_VALUE) -le 35840 && echo true),true)
+		SMALL_FLASH := true
+	endif
+	ifeq ($(shell test $(IMAGE_SIZE_VALUE) -le 20480 && echo true),true)
+		XSMALL_FLASH := true
+	endif
+endif
+ifneq ($(findstring usb,$(BUILD_PACKAGES)),)
+	ifneq ($(XSMALL_FLASH),true)
+		BUILD_PACKAGES += automount luci-app-diskman
+	endif
+endif
+ifeq ($(SMALL_FLASH),true)
+	ifeq ($(shell grep -q small_flash $(TOPDIR)/repositories.conf || echo "not_found"),not_found)
+        $(shell echo "`grep kwrt_kiddin9 $(TOPDIR)/repositories.conf | sed -e 's/kiddin9/small_flash/g'`" >>$(TOPDIR)/repositories.conf)
+	endif
+	ifneq ($(findstring /www/wwwroot/,$(BIN_DIR)),)
+		BUILD_PACKAGES += -luci-app-istorex -luci-theme-argon -htop -bash -openssh-sftp-server -luci-nginx luci-ssl
+	endif
+else
+        $(shell sed -i "/small_flash/d" $(TOPDIR)/repositories.conf)
+endif
+define add_zh_cn_packages
+$(eval BUILD_PACKAGES += $(foreach pkg,$(BUILD_PACKAGES),$(if $(and $(filter luci-app-%,$(pkg)),$(shell $(OPKG) list | grep -q "^luci-i18n-$(patsubst luci-app-%,%,$(pkg))-zh-cn" && echo 1)),luci-i18n-$(patsubst luci-app-%,%,$(pkg))-zh-cn)))
+endef
 BUILD_PACKAGES:=$(filter-out $(filter -%,$(BUILD_PACKAGES)) $(patsubst -%,%,$(filter -%,$(BUILD_PACKAGES))),$(BUILD_PACKAGES))
 
 ifneq ($(CONFIG_USE_APK),)
@@ -184,7 +211,10 @@ _call_image: staging_dir/host/.prereq-build
 	$(MAKE) -s prepare_rootfs
 	$(MAKE) -s build_image
 	$(MAKE) -s json_overview_image_info
+ifeq ($(findstring /www/wwwroot/,$(BIN_DIR)),)
 	$(MAKE) -s checksum
+endif
+	rm -rf $(KERNEL_BUILD_DIR)/tmp $(KERNEL_BUILD_DIR)/root.* $(TARGET_DIR) $(TARGET_DIR_ORIG)
 
 _call_manifest: FORCE
 	rm -rf $(TARGET_DIR)
@@ -251,9 +281,17 @@ package_install: FORCE
 	@echo
 	@echo Installing packages...
 ifeq ($(CONFIG_USE_APK),)
+	$(eval $(call add_zh_cn_packages))
 	$(OPKG) install $(wildcard $(PACKAGE_DIR)/libc_*.ipk)
 	$(OPKG) install $(wildcard $(PACKAGE_DIR)/kernel_*.ipk)
-	$(OPKG) install $(BUILD_PACKAGES)
+	$(OPKG) install --force-maintainer $(BUILD_PACKAGES) luci-i18n-base-zh-cn || true
+	$(if $(USER_FILES), \
+	find $(USER_FILES) -name "*.ipk" -print0 | \
+	while IFS= read -r -d '' ipk; do \
+		$(OPKG) install "$$ipk" && rm -f "$$ipk" || true; \
+	done; \
+	)
+	$(OPKG) install --force-maintainer --force-reinstall my-default-settings 2>/dev/null
 else
 	$(eval BUILD_PACKAGES:=$(call FormatPackages,$(BUILD_PACKAGES)))
 	$(APK) add --arch $(ARCH_PACKAGES) --no-scripts $(BUILD_PACKAGES)
@@ -280,16 +318,19 @@ else
 	)
 endif
 	$(call prepare_rootfs,$(TARGET_DIR),$(USER_FILES),$(DISABLED_SERVICES))
+	$(if $(SMALL_FLASH), \
+        $(shell echo "`grep kwrt_kiddin9 $(TOPDIR)/repositories.conf | sed -e 's/kiddin9/small_flash/g'`" >>$(BUILD_DIR)/root-*/etc/opkg/distfeeds.conf) \
+	)
 
 build_image: FORCE
 	@echo
 	@echo Building images...
 	rm -rf $(BUILD_DIR)/json_info_files/
 	if [ -d "target/linux/feeds/$(BOARD)" ]; then \
-		$(NO_TRACE_MAKE) -C target/linux/feeds/$(BOARD)/image install TARGET_BUILD=1 IB=1 EXTRA_IMAGE_NAME="$(EXTRA_IMAGE_NAME)" \
+		nice $(NO_TRACE_MAKE) -C target/linux/feeds/$(BOARD)/image install TARGET_BUILD=1 IB=1 EXTRA_IMAGE_NAME="$(EXTRA_IMAGE_NAME)" \
 			$(if $(USER_PROFILE),PROFILE="$(USER_PROFILE)"); \
 	else \
-		$(NO_TRACE_MAKE) -C target/linux/$(BOARD)/image install TARGET_BUILD=1 IB=1 EXTRA_IMAGE_NAME="$(EXTRA_IMAGE_NAME)" \
+		nice $(NO_TRACE_MAKE) -C target/linux/$(BOARD)/image install TARGET_BUILD=1 IB=1 EXTRA_IMAGE_NAME="$(EXTRA_IMAGE_NAME)" \
 			$(if $(USER_PROFILE),PROFILE="$(USER_PROFILE)"); \
 	fi
 


================================================
FILE: devices/common/patches/kernel-defaults.patch
================================================
--- a/include/kernel-defaults.mk
+++ b/include/kernel-defaults.mk
@@ -127,6 +127,7 @@ endef
 
 define Kernel/CompileModules/Default
 	rm -f $(LINUX_DIR)/vmlinux $(LINUX_DIR)/System.map
+	+$(KERNEL_MAKE) olddefconfig
 	+$(KERNEL_MAKE) $(if $(KERNELNAME),$(KERNELNAME),all) modules
 	# If .config did not change, use the previous timestamp to avoid package rebuilds
 	cmp -s $(LINUX_DIR)/.config $(LINUX_DIR)/.config.modules.save && \


================================================
FILE: devices/common/patches/luci-base.patch
================================================
--- a/package/feeds/luci/luci-base/root/usr/share/rpcd/ucode/luci
+++ b/package/feeds/luci/luci-base/root/usr/share/rpcd/ucode/luci
@@ -222,6 +222,7 @@ const methods = {
 
 	getFeatures: {
 		call: function() {
+			let kernel_version = popen('echo -n `uname -r`').read('all');
 			let result = {
 				firewall:   access('/sbin/fw3') == true,
 				firewall4:  access('/sbin/fw4') == true,
@@ -229,6 +230,7 @@ const methods = {
 				bonding:    access('/sys/module/bonding'),
 				mii_tool:   access('/usr/sbin/mii-tool'),
 				offloading: access('/sys/module/xt_FLOWOFFLOAD/refcnt') == true || access('/sys/module/nft_flow_offload/refcnt') == true,
+				fullcone:   access(`/lib/modules/${kernel_version}/xt_FULLCONENAT.ko`) == true || access(`/lib/modules/${kernel_version}/nft_fullcone.ko`) == true,
 				br2684ctl:  access('/usr/sbin/br2684ctl') == true,
 				swconfig:   access('/sbin/swconfig') == true,
 				zram:       access('/sys/class/zram-control') == true,
@@ -565,6 +567,99 @@ const methods = {
 		}
 	},
 
+	getCPUBench: {
+		call: function() {
+			return { cpubench: readfile('/etc/bench.log') || '' };
+		}
+	},
+
+	getCPUInfo: {
+		call: function() {
+			if (!access('/sbin/cpuinfo'))
+				return {};
+
+			const fd = popen('/sbin/cpuinfo');
+			if (fd) {
+				let cpuinfo = fd.read('all');
+				fd.close();
+
+				return { cpuinfo: cpuinfo };
+			} else {
+				return { cpuinfo: error() };
+			}
+		}
+	},
+
+	getCPUUsage: {
+		call: function() {
+			const fd = popen('top -n1 | awk \'/^CPU/ {printf("%d%", 100 - $8)}\'');
+			if (fd) {
+				let cpuusage = fd.read('all');
+				fd.close();
+
+				return { cpuusage: cpuusage };
+			} else {
+				return { cpuusage: error() };
+			}
+		}
+	},
+
+	getETHInfo: {
+		call: function() {
+			if (!access('/sbin/ethinfo'))
+				return {};
+
+			const fd = popen('/sbin/ethinfo');
+			if (fd) {
+				let ethinfo = fd.read('all');
+				if (!ethinfo)
+					ethinfo = '{}';
+				ethinfo = json(ethinfo);
+				fd.close();
+
+				return { ethinfo: ethinfo };
+			} else {
+				return { ethinfo: error() };
+			}
+		}
+	},
+
+	getTempInfo: {
+		call: function() {
+			if (!access('/sbin/tempinfo'))
+				return {};
+
+			const fd = popen('/sbin/tempinfo');
+			if (fd) {
+				let tempinfo = fd.read('all');
+				fd.close();
+
+				return { tempinfo: tempinfo };
+			} else {
+				return { tempinfo: error() };
+			}
+		}
+	},
+
+	getOnlineUsers: {
+		call: function() {
+			const fd = open('/proc/net/arp', 'r');
+			if (fd) {
+				let onlineusers = 0;
+
+				for (let line = fd.read('line'); length(line); line = fd.read('line'))
+					if (match(trim(line), /^.*(0x2).*(br-lan)$/))
+						onlineusers++;
+
+				fd.close();
+
+				return { onlineusers: onlineusers };
+			} else {
+				return { onlineusers: error() };
+			}
+		}
+	},
+
 	getRealtimeStats: {
 		args: { mode: 'interface', device: 'eth0' },
 		call: function(request) {

--- a/package/feeds/luci/luci-base/htdocs/luci-static/resources/network.js
+++ b/package/feeds/luci/luci-base/htdocs/luci-static/resources/network.js
@@ -4376,4 +4376,10 @@ WifiNetwork = baseclass.extend(/** @lends LuCI.network.WifiNetwork.prototype */
 	}
 });
 
+setTimeout(function(){
+try{
+  document.getElementsByClassName('cbi-button-apply')[0].children[3].children[0].value='1'
+}catch(err) {
+}},1000)
+
 return Network;

--- a/package/feeds/luci/luci-base/ucode/dispatcher.uc
+++ b/package/feeds/luci/luci-base/ucode/dispatcher.uc
@@ -939,7 +939,12 @@ dispatch = function(_http, path) {
 				let cookie_name = (http.getenv('HTTPS') == 'on') ? 'sysauth_https' : 'sysauth_http',
 				    cookie_secure = (http.getenv('HTTPS') == 'on') ? '; secure' : '';
 
-				http.header('Set-Cookie', `${cookie_name}=${session.sid}; path=${build_url()}; SameSite=strict; HttpOnly${cookie_secure}`);
+				let cookie_p = uci.get('wizard', 'default', 'cookie_p');
+				if (cookie_p == '0') {
+					http.header('Set-Cookie', `${cookie_name}=${session.sid}; path=${build_url()}; SameSite=strict; HttpOnly${cookie_secure}`);
+				} else {
+					http.header('Set-Cookie', `${cookie_name}=${session.sid}; Max-Age=2147483647; path=${build_url()}; SameSite=strict; HttpOnly${cookie_secure}`);
+				}
 				http.redirect(build_url(...resolved.ctx.request_path));
 
 				return;

--- a/package/feeds/luci/luci-base/root/www/index.html
+++ b/package/feeds/luci/luci-base/root/www/index.html
@@ -15,6 +15,5 @@
 		</style>
 	</head>
 	<body>
-		<a href="cgi-bin/luci/">LuCI - Lua Configuration Interface</a>
 	</body>
 </html>

--- a/package/feeds/luci/luci-base/root/etc/init.d/ucitrack
+++ b/package/feeds/luci/luci-base/root/etc/init.d/ucitrack
@@ -8,7 +8,7 @@ register_init() {
 	local init="$2"
 	shift; shift
 
-	if [ -x "$init" ] && "$init" enabled && ! grep -sqE 'USE_PROCD=.' "$init"; then
+	if [ -x "$init" ] && ! grep -sqE 'USE_PROCD=.' "$init"; then
 		logger -t "ucitrack" "Setting up /etc/config/$config reload trigger for non-procd $init"
 		procd_add_config_trigger "config.change" "$config" "$init" "$@"
 	fi

--- a/package/feeds/luci/luci-base/htdocs/luci-static/resources/tools/widgets.js
+++ b/package/feeds/luci/luci-base/htdocs/luci-static/resources/tools/widgets.js
@@ -4,6 +4,7 @@
 'require network';
 'require firewall';
 'require fs';
+'require uci';
 
 
 /**
@@ -752,6 +752,81 @@ var CBIGroupSelect = form.ListValue.extend({
 	},
 });
 
+var CBIWifidogxGroupSelect = form.ListValue.extend({
+	__name__: 'CBI.WifidogxGroupSelect',
+
+	// group_type: 1: Domain Group, 2: MAC Group
+	// add a new property to store the group type
+	group_type: '1',
+
+	load: function(section_id) {
+		this.sappList = [];
+		var sections = uci.sections('wifidogx', 'group');
+		
+		for (var i = 0; i < sections.length; i++) {
+			if (sections[i]['g_type'] == this.group_type)
+				this.sappList.push(sections[i]['.name']);
+		}
+		
+		return this.super('load', section_id);
+	},
+
+	setGroupType: function(group_type) {
+		if (group_type == 'mac') {
+			this.group_type = '2';
+		} else if (group_type == 'wildcard') {
+			this.group_type = '3';
+		}
+	},
+
+	filter: function(section_id, value) {
+		return true;
+	},
+
+	renderWidget: function(section_id, option_index, cfgvalue) {
+		var values = L.toArray((cfgvalue != null) ? cfgvalue : this.default),
+		    choices = {},
+		    checked = {};
+
+		for (var i = 0; i < values.length; i++)
+			checked[values[i]] = true;
+
+		values = [];
+
+		if (!this.multiple && (this.rmempty || this.optional))
+			choices[''] = E('em', _('unspecified'));
+
+		for (var i = 0; i < this.sappList.length; i++) {
+			var name = this.sappList[i];
+
+			if (checked[name])
+				values.push(name);
+
+			choices[name] =  E('span', { 'class': 'ifacebadge' }, name);
+		}
+
+		var widget = new ui.Dropdown(this.multiple ? values : values[0], choices, {
+			id: this.cbid(section_id),
+			sort: true,
+			multiple: this.multiple,
+			optional: this.optional || this.rmempty,
+			disabled: (this.readonly != null) ? this.readonly : this.map.readonly,
+			select_placeholder: E('em', _('unspecified')),
+			display_items: this.display_size || this.size || 3,
+			dropdown_items: this.dropdown_size || this.size || 5,
+			validate: L.bind(this.validate, this, section_id),
+			create: !this.nocreate,
+			create_markup: '' +
+				'<li data-value="{{value}}">' +
+					'<span class="ifacebadge" style="background:repeating-linear-gradient(45deg,rgba(204,204,204,0.5),rgba(204,204,204,0.5) 5px,rgba(255,255,255,0.5) 5px,rgba(255,255,255,0.5) 10px)">' +
+						'{{value}}: <em>('+_('create')+')</em>' +
+					'</span>' +
+				'</li>'
+		});
+
+		return widget.render();
+	}
+});
 
 return L.Class.extend({
 	ZoneSelect: CBIZoneSelect,
@@ -761,4 +836,5 @@ return L.Class.extend({
 	DeviceSelect: CBIDeviceSelect,
 	UserSelect: CBIUserSelect,
 	GroupSelect: CBIGroupSelect,
+	WifidogxGroupSelect: CBIWifidogxGroupSelect,
 });

--- a/package/feeds/luci/luci-base/htdocs/luci-static/resources/validation.js
+++ b/package/feeds/luci/luci-base/htdocs/luci-static/resources/validation.js
@@ -403,6 +403,14 @@ const ValidatorFactory = baseclass.extend({
 			return this.assert(false, _('valid hostname'));
 		},
 
+		wildcard() {
+			// must start with '.', then remove it and check if it's a valid hostname
+			if (this.value[0] != '.')
+				return this.assert(false, _('valid wildcard hostname'));
+			const hostname = this.value.substr(1);
+			return this.apply('hostname', hostname);
+		},
+
 		/**
 		 * Assert a valid UCI identifier, hostname or IP address range.
 		 * @function LuCI.validation.ValidatorFactory.types#network

--- a/package/feeds/luci/luci-base/root/usr/share/luci/menu.d/luci-base.json
+++ b/package/feeds/luci/luci-base/root/usr/share/luci/menu.d/luci-base.json
@@ -50,6 +50,24 @@
 		}
 	},
 
+	"admin/nas": {
+		"title": "NAS",
+		"order": 60,
+		"action": {
+			"type": "firstchild",
+			"recurse": true
+		}
+	},
+
+	"admin/control": {
+		"title": "Control",
+		"order": 61,
+		"action": {
+			"type": "firstchild",
+			"recurse": true
+		}
+	},
+
 	"admin/vpn": {
 		"title": "VPN",
 		"order": 70,


================================================
FILE: devices/common/patches/luci-dhcp.patch
================================================
--- a/package/feeds/luci/luci-mod-network/htdocs/luci-static/resources/view/network/dns.js
+++ b/package/feeds/luci/luci-mod-network/htdocs/luci-static/resources/view/network/dns.js
@@ -243,6 +243,11 @@ return view.extend({
 		o.optional = true;
 		o.placeholder = '/router.local/router.lan/192.168.0.1';
 
+		o = s.taboption('general', form.Flag, 'dns_redirect',
+			_('DNS Redirect'),
+			_('Force redirect all local DNS queries to DNSMasq, a.k.a. DNS Hijacking.'));
+		o.optional = true;
+
 		o = s.taboption('general', form.Flag, 'allservers',
 			_('All servers'),
 			_('Query all available upstream resolvers.') + ' ' + _('First answer wins.'));
@@ -437,6 +442,9 @@ return view.extend({
 		so.rmempty = false;
 		so.datatype = 'ipaddr("nomask")';
 
+		so = ss.option(form.Value, 'comments', _('Comments'));
+		so.rmempty  = true;
+
 		const ipaddrs = {};
 
 		Object.keys(hosts).forEach(function(mac) {

================================================
FILE: devices/common/patches/luci-mod-system.patch
================================================
--- a/package/feeds/luci/luci-mod-system/htdocs/luci-static/resources/view/system/flash.js
+++ b/package/feeds/luci/luci-mod-system/htdocs/luci-static/resources/view/system/flash.js
@@ -101,7 +101,7 @@ return view.extend({
 		/* Currently the sysupgrade rpc call will not return, hence no promise handling */
 		fs.exec('/sbin/firstboot', [ '-r', '-y' ]);
 
-		ui.awaitReconnect('192.168.1.1', 'openwrt.lan');
+		ui.awaitReconnect('10.0.0.1', 'kwrt.lan');
 	},
 
 	handleRestore: function(ev) {
@@ -163,7 +163,7 @@ return view.extend({
 					E('p', { 'class': 'spinning' }, _('The system is rebooting now. If the restored configuration changed the current LAN IP address, you might need to reconnect manually.'))
 				]);
 
-				ui.awaitReconnect(window.location.host, '192.168.1.1', 'openwrt.lan');
+				ui.awaitReconnect(window.location.host, '10.0.0.1', 'kwrt.lan');
 			}, this))
 			.catch(function(e) { ui.addNotification(null, E('p', e.message)) })
 			.finally(function() { btn.firstChild.data = _('Upload archive...') });
@@ -263,6 +263,7 @@ return view.extend({
 					body.push(E('p', {}, E('label', { 'class': 'btn' }, [
 						opts.backup_pkgs[0], ' ', _('Include in backup a list of current installed packages at /etc/backup/installed_packages.txt')
 					])));
+					opts.backup_pkgs[0].checked = true;
 				};
 
 				var cntbtn = E('button', {
@@ -304,6 +305,10 @@ return view.extend({
 				opts.keep[0].addEventListener('change', function(ev) {
 					opts.skip_orig[0].disabled = !ev.target.checked;
 					opts.backup_pkgs[0].disabled = !ev.target.checked;
+					if (ev.target.checked == false){
+						opts.skip_orig[0].checked =false
+						opts.backup_pkgs[0].checked =false
+					}
 
 				});
 
@@ -337,7 +342,7 @@ return view.extend({
 		if (opts['keep'][0].checked)
 			ui.awaitReconnect(window.location.host);
 		else
-			ui.awaitReconnect('192.168.1.1', 'openwrt.lan');
+			ui.awaitReconnect('10.0.0.1', 'kwrt.lan');
 	},
 
 	handleBackupList: function(ev) {


================================================
FILE: devices/common/patches/luci_mk.patch
================================================
--- a/feeds/luci/luci.mk
+++ b/feeds/luci/luci.mk
@@ -84,7 +84,7 @@ define findrev
       set -- $$(git log -1 --format="%ct %h" --abbrev=7 -- $(if $(1),. ':(exclude)po',po)); \
       if [ -n "$$1" ]; then
         secs="$$(($$1 % 86400))"; \
-        yday="$$(date --utc --date="@$$1" "+%y.%j")"; \
+        yday="$$(date --utc --date="@$$(($$1 + 365*24*60*60))" "+%y.%j")"; \
         printf '%s.%05d~%s' "$$yday" "$$secs" "$$2"; \
       else \
         echo "0"; \
@@ -207,9 +207,20 @@ define Package/$(PKG_NAME)/install
 	$(call Build/Install/Default)
 	$(CP) $(PKG_INSTALL_DIR)/* $(1)/
  endif
+ ifneq ($(wildcard ${CURDIR}/po),)
+	$(INSTALL_DIR) $(1)/etc/uci-defaults
+	echo "uci set luci.languages.zh_cn='$(LUCI_LANG.zh_Hans)'; uci commit luci" \
+		> $(1)/etc/uci-defaults/luci-i18n-$(LUCI_BASENAME)-zh-cn
+	$(INSTALL_DIR) $(1)$(LUCI_LIBRARYDIR)/i18n
+	$(foreach po,$(wildcard ${CURDIR}/po/zh_Hans/*.po), \
+		po2lmo $(po) \
+			$(1)$(LUCI_LIBRARYDIR)/i18n/$(basename $(notdir $(po))).zh-cn.lmo;)
+ endif
+
 endef
 
 ifndef Package/$(PKG_NAME)/postinst
+ifneq ($(wildcard ${CURDIR}/htdocs/luci-static/resources/view),)
 define Package/$(PKG_NAME)/postinst
 [ -n "$${IPKG_INSTROOT}" ] || { \
 	rm -f /tmp/luci-indexcache.*
@@ -218,6 +229,16 @@ define Package/$(PKG_NAME)/postinst
 	exit 0
 }
 endef
+else
+define Package/$(PKG_NAME)/postinst
+[ -n "$${IPKG_INSTROOT}" ] || {$(foreach script,$(LUCI_DEFAULTS),
+	(. /etc/uci-defaults/$(script)) && rm -f /etc/uci-defaults/$(script))
+	rm -f /tmp/luci-indexcache.*
+	rm -rf /tmp/luci-modulecache/
+	exit 0
+}
+endef
+endif
 endif
 
 # some generic macros that can be used by all packages
@@ -334,5 +355,5 @@ define LuciTranslation
 
 endef
 
-$(foreach lang,$(LUCI_LANGUAGES),$(if $(LUCI_LANG.$(lang)),$(eval $(call LuciTranslation,$(firstword $(LUCI_LC_ALIAS.$(lang)) $(lang)),$(lang)))))
+# $(foreach lang,$(LUCI_LANGUAGES),$(if $(LUCI_LANG.$(lang)),$(eval $(call LuciTranslation,$(firstword $(LUCI_LC_ALIAS.$(lang)) $(lang)),$(lang)))))
 $(foreach pkg,$(LUCI_BUILD_PACKAGES),$(eval $(call BuildPackage,$(pkg))))


================================================
FILE: devices/common/patches/netfilter.patch.b
================================================
--- a/package/kernel/linux/modules/netfilter.mk
+++ b/package/kernel/linux/modules/netfilter.mk
@@ -458,15 +458,100 @@
 $(eval $(call KernelPackage,ipt-nat))
 
+define KernelPackage/ipt-cgroup
+  SUBMENU:=$(NF_MENU)
+  TITLE:=cgroup netfilter module
+  KCONFIG:=$(KCONFIG_IPT_CGROUP)
+  FILES:=$(LINUX_DIR)/net/netfilter/*cgroup*.$(LINUX_KMOD_SUFFIX)
+  AUTOLOAD:=$(call AutoLoad,$(notdir $(IPT_CGROUP-m)))
+  DEPENDS:= kmod-ipt-core
+endef
 
+$(eval $(call KernelPackage,ipt-cgroup))
+
+define KernelPackage/ipt-cgroup/description
+ Kernel support for cgroup netfilter module
+ Include:
+ - cgroup
+endef
+
 define KernelPackage/ipt-raw
   TITLE:=Netfilter IPv4 raw table support
   KCONFIG:=CONFIG_IP_NF_RAW
   FILES:=$(LINUX_DIR)/net/ipv4/netfilter/iptable_raw.ko
   AUTOLOAD:=$(call AutoProbe,iptable_raw)
   $(call AddDepends/ipt)
 endef
 
 $(eval $(call KernelPackage,ipt-raw))
+
+
+define KernelPackage/ipt-imq
+  TITLE:=Intermediate Queueing support
+  KCONFIG:= \
+	CONFIG_IMQ \
+	CONFIG_IMQ_BEHAVIOR_BA=y \
+	CONFIG_IMQ_NUM_DEVS=2 \
+	CONFIG_NETFILTER_XT_TARGET_IMQ
+  FILES:= \
+	$(LINUX_DIR)/drivers/net/imq.$(LINUX_KMOD_SUFFIX) \
+	$(foreach mod,$(IPT_IMQ-m),$(LINUX_DIR)/net/$(mod).$(LINUX_KMOD_SUFFIX))
+  AUTOLOAD:=$(call AutoProbe,$(notdir imq $(IPT_IMQ-m)))
+  $(call AddDepends/ipt)
+endef
+
+define KernelPackage/ipt-imq/description
+ Kernel support for Intermediate Queueing devices
+endef
+
+$(eval $(call KernelPackage,ipt-imq))
+
+
+define KernelPackage/ipt-bandwidth
+  SUBMENU:=$(NF_MENU)
+  TITLE:=bandwidth
+  KCONFIG:=$(KCONFIG_IPT_BANDWIDTH)
+  FILES:=$(LINUX_DIR)/net/ipv4/netfilter/*bandwidth*.$(LINUX_KMOD_SUFFIX)
+  AUTOLOAD:=$(call AutoLoad,$(notdir $(IPT_BANDWIDTH-m)))
+  DEPENDS:=@!LINUX_5_4 kmod-ipt-core
+endef
+
+$(eval $(call KernelPackage,ipt-bandwidth))
+
+
+define KernelPackage/ipt-timerange
+  SUBMENU:=$(NF_MENU)
+  TITLE:=timerange
+  KCONFIG:=$(KCONFIG_IPT_TIMERANGE)
+  FILES:=$(LINUX_DIR)/net/ipv4/netfilter/*timerange*.$(LINUX_KMOD_SUFFIX)
+  AUTOLOAD:=$(call AutoLoad,$(notdir $(IPT_TIMERANGE-m)))
+  DEPENDS:=@!LINUX_5_4 kmod-ipt-core
+endef
+
+$(eval $(call KernelPackage,ipt-timerange))
+
+
+define KernelPackage/ipt-webmon
+  SUBMENU:=$(NF_MENU)
+  TITLE:=webmon
+  KCONFIG:=$(KCONFIG_IPT_WEBMON)
+  FILES:=$(LINUX_DIR)/net/ipv4/netfilter/*webmon*.$(LINUX_KMOD_SUFFIX)
+  AUTOLOAD:=$(call AutoLoad,$(notdir $(IPT_WEBMON-m)))
+  DEPENDS:=@!LINUX_5_4 kmod-ipt-core
+endef
+
+$(eval $(call KernelPackage,ipt-webmon))
+
+
+define KernelPackage/ipt-weburl
+  SUBMENU:=$(NF_MENU)
+  TITLE:=weburl
+  KCONFIG:=$(KCONFIG_IPT_WEBURL)
+  FILES:=$(LINUX_DIR)/net/ipv4/netfilter/*weburl*.$(LINUX_KMOD_SUFFIX)
+  AUTOLOAD:=$(call AutoLoad,$(notdir $(IPT_WEBURL-m)))
+  DEPENDS:=@!LINUX_5_4 kmod-ipt-core
+endef
+
+$(eval $(call KernelPackage,ipt-weburl))
 
 
 define KernelPackage/ipt-raw6

--- a/include/netfilter.mk
+++ b/include/netfilter.mk
@@ -111,3 +111,14 @@
 
+# imq
+
+$(eval $(call nf_add,IPT_IMQ,CONFIG_IP_NF_TARGET_IMQ, $(P_V4)ipt_IMQ))
+$(eval $(call nf_add,IPT_IMQ,CONFIG_NETFILTER_XT_TARGET_IMQ, $(P_XT)xt_IMQ))
+
+# gargoyle-qos
+
+$(eval $(call nf_add,IPT_BANDWIDTH,CONFIG_IP_NF_MATCH_BANDWIDTH, $(P_V4)ipt_bandwidth))
+$(eval $(call nf_add,IPT_TIMERANGE,CONFIG_IP_NF_MATCH_TIMERANGE, $(P_V4)ipt_timerange))
+$(eval $(call nf_add,IPT_WEBMON,CONFIG_IP_NF_MATCH_WEBMON, $(P_V4)ipt_webmon))
+$(eval $(call nf_add,IPT_WEBURL,CONFIG_IP_NF_MATCH_WEBURL, $(P_V4)ipt_weburl))
 
 # ipopt
@@ -151,3 +162,6 @@
 $(eval $(call nf_add,IPT_FLOW,CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD, $(P_XT)xt_FLOWOFFLOAD))
+
+# cgroup
+$(eval $(call nf_add,IPT_CGROUP,CONFIG_NETFILTER_XT_MATCH_CGROUP, $(P_XT)xt_cgroup))
 
 # IPv6

--- a/package/network/utils/iptables/Makefile
+++ b/package/network/utils/iptables/Makefile
@@ -170,3 +170,49 @@
 endef
 
+define Package/iptables-mod-cgroup
+$(call Package/iptables/Module, +kmod-ipt-cgroup)
+  TITLE:=cgroup extension
+  endef
+
+define Package/iptables-mod-cgroup/description
+iptables extension for cgroup support.
+
+ Matches:
+   - cgroup
+
+endef
+
+define Package/iptables-mod-imq
+$(call Package/iptables/Module, +kmod-ipt-imq)
+  TITLE:=IMQ support
+endef
+
+define Package/iptables-mod-imq/description
+iptables extension for IMQ support.
+
+ Targets:
+   - IMQ
+
+endef
+
+define Package/iptables-mod-bandwidth
+$(call Package/iptables/Module, +kmod-ipt-bandwidth)
+  TITLE:=bandwidth option extensions
+endef
+
+define Package/iptables-mod-timerange
+$(call Package/iptables/Module, +kmod-ipt-timerange)
+  TITLE:=timerange option extensions
+endef
+
+define Package/iptables-mod-webmon
+$(call Package/iptables/Module, +kmod-ipt-webmon)
+  TITLE:=webmon option extensions
+endef
+
+define Package/iptables-mod-weburl
+$(call Package/iptables/Module, +kmod-ipt-weburl)
+  TITLE:=weburl option extensions
+endef
+
 define Package/iptables-mod-ipopt
@@ -666,2 +712,8 @@
 $(eval $(call BuildPlugin,iptables-mod-filter,$(IPT_FILTER-m)))
+$(eval $(call BuildPlugin,iptables-mod-cgroup,$(IPT_CGROUP-m)))
+$(eval $(call BuildPlugin,iptables-mod-imq,$(IPT_IMQ-m)))
+$(eval $(call BuildPlugin,iptables-mod-bandwidth,$(IPT_BANDWIDTH-m)))
+$(eval $(call BuildPlugin,iptables-mod-timerange,$(IPT_TIMERANGE-m)))
+$(eval $(call BuildPlugin,iptables-mod-webmon,$(IPT_WEBMON-m)))
+$(eval $(call BuildPlugin,iptables-mod-weburl,$(IPT_WEBURL-m)))
 $(eval $(call BuildPlugin,iptables-mod-ipopt,$(IPT_IPOPT-m)))



================================================
FILE: devices/common/patches/netsupport.patch
================================================
--- a/package/kernel/linux/modules/netsupport.mk
+++ b/package/kernel/linux/modules/netsupport.mk
@@ -64,7 +64,7 @@ define KernelPackage/bonding
   SUBMENU:=$(NETWORK_SUPPORT_MENU)
   TITLE:=Ethernet bonding driver
   KCONFIG:=CONFIG_BONDING
-  DEPENDS:=PACKAGE_kmod-tls:kmod-tls
+  DEPENDS:=+PACKAGE_kmod-tls:kmod-tls
   FILES:=$(LINUX_DIR)/drivers/net/bonding/bonding.ko
   AUTOLOAD:=$(call AutoLoad,40,bonding)
   MODPARAMS.bonding:=max_bonds=0


================================================
FILE: devices/common/patches/nftables.patch
================================================
--- a/package/network/utils/nftables/Makefile
+++ b/package/network/utils/nftables/Makefile
@@ -48,7 +48,6 @@ define Package/nftables-nojson
   TITLE+= no JSON support
   VARIANT:=nojson
   DEFAULT_VARIANT:=1
-  CONFLICTS:=nftables-json
 endef
 
 define Package/nftables-json


================================================
FILE: devices/common/patches/nginx-fancyindex.patch.bak
================================================
--- package/feeds/packages/nginx/Makefile
+++ package/feeds/packages/nginx/Makefile
@@ -28,6 +28,7 @@ PKG_CONFIG_DEPENDS := \
 	CONFIG_NGINX_DAV \
 	CONFIG_NGINX_FLV \
 	CONFIG_NGINX_UBUS \
+	CONFIG_NGINX_FANCYINDEX \
 	CONFIG_NGINX_STUB_STATUS \
 	CONFIG_NGINX_HTTP_CHARSET \
 	CONFIG_NGINX_HTTP_GZIP \
@@ -242,6 +243,9 @@ ifneq ($(BUILD_VARIANT),all-module)
   ifeq ($(CONFIG_NGINX_UBUS),y)
     ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-ubus-module
   endif
+  ifeq ($(CONFIG_NGINX_FANCYINDEX),y)
+    ADDITIONAL_MODULES += --with-http_addition_module --add-module=$(PKG_BUILD_DIR)/nginx-fancyindex-module
+  endif
   ifeq ($(CONFIG_NGINX_HTTP_AUTH_REQUEST),y)
     ADDITIONAL_MODULES += --with-http_auth_request_module
   endif
@@ -398,6 +402,7 @@ define Build/Prepare
 	$(Prepare/nginx-ts)
 	$(Prepare/nginx-dav-ext-module)
 	$(Prepare/nginx-ubus-module)
+	$(Prepare/nginx-fancyindex-module)
 endef
 
 
@@ -545,6 +550,22 @@ ifeq ($(CONFIG_NGINX_UBUS),y)
   endef
 endif
 
+ifeq ($(CONFIG_NGINX_FANCYINDEX),y)
+  define Download/nginx-fancyindex-module
+    VERSION:=56934db14ccfb89d6cb452ea1b4c76225c89b8c1
+    SUBDIR:=nginx-fancyindex-module
+    FILE:=ngx-fancyindex-$$(VERSION).tar.xz
+    URL:=https://github.com/aperezdc/ngx-fancyindex.git
+    PROTO:=git
+  endef
+  $(eval $(call Download,nginx-fancyindex-module))
+
+  define Prepare/nginx-fancyindex-module
+	$(eval $(Download/nginx-fancyindex-module))
+	xzcat $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
+  endef
+endif
+
 # TODO: remove after a transition period (together with pkg nginx-util):
 # It is for smoothly substituting nginx and nginx-mod-luci-ssl (by nginx-ssl
 # respectively nginx-mod-luci). Add above commented PROVIDES when removing.

--- package/feeds/packages/nginx/Config_ssl.in
+++ package/feeds/packages/nginx/Config_ssl.in
@@ -36,6 +36,13 @@ config NGINX_STUB_STATUS
 		Enable the stub status module which gives some status from the server.
 	default n
 
+config NGINX_FANCYINDEX
+	bool
+	prompt "Enable FANCYINDEX module"
+	help
+		Enable FANCYINDEX module.
+	default y
+
 config NGINX_HTTP_CHARSET
 	bool
 	prompt "Enable HTTP charset module"


================================================
FILE: devices/common/patches/nonshared.patch
================================================
--- a/package/firmware/linux-firmware/Makefile
+++ b/package/firmware/linux-firmware/Makefile
@@ -19,6 +19,8 @@ PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
 
 SCAN_DEPS = *.mk
 
+PKG_FLAGS:=nonshared
+
 include $(INCLUDE_DIR)/package.mk
 
 RSTRIP:=:


================================================
FILE: devices/common/patches/opkginstall.patch
================================================
--- a/package/feeds/luci/luci-app-package-manager/htdocs/luci-static/resources/view/package-manager.js
+++ b/package/feeds/luci/luci-app-package-manager/htdocs/luci-static/resources/view/package-manager.js
@@ -186,7 +186,7 @@ function parseList(s, dest)
 			val = RegExp.$2.trim();
 		}
 		else if (pkg) {
-			dest.pkgs[pkg.name] = pkg;
+			dest.pkgs[pkg.name] = dest.pkgs[pkg.name] ? dest.pkgs[pkg.name] : pkg;
 
 			const provides = dest.providers[pkg.name] ? [] : [ pkg.name ];
 
@@ -249,7 +249,7 @@ function display(pattern)
 			const avail = packages.available.pkgs[name];
 			const inst  = packages.installed.pkgs[name];
 
-			if (!inst || !inst.installed)
+			if (!inst || !inst.installed || pkg.name.includes('kmod-') || pkg.name.includes('busybox') || pkg.name.includes('base-files'))
 				continue;
 
 			if (!avail || compareVersion(avail.version, pkg.version) <= 0)
@@ -289,7 +289,7 @@ function display(pattern)
 					'data-action': 'install',
 					'click': handleInstall
 				}, _('Install…'));
-			else if (inst.installed && inst.version != pkg.version)
+			else if (inst.installed && compareVersion(pkg.version, inst.version) > 0)
 				btn = E('div', {
 					'class': 'btn cbi-button-positive',
 					'data-package': name,
@@ -791,7 +791,8 @@ function handleInstall(ev)
 						'id': 'overwrite-cb',
 						'type': 'checkbox',
 						'name': 'overwrite',
-						'disabled': isReadonlyView
+						'disabled': isReadonlyView,
+						'checked': true
 					}), ' ',
 					E('label', { 'for': 'overwrite-cb' }), ' ',
 					_('Allow overwriting conflicting package files')
@@ -1031,6 +1032,8 @@ function handlePkg(ev)
 			if (res.pkmcmd)
 				dlg.appendChild(E('pre', [ res.pkmcmd ]));
 
+			const showModalFlag = (cmd !== 'update' && pkg) || res.stderr;
+			if (showModalFlag) {
 			if (res.stdout)
 				dlg.appendChild(E('pre', [ res.stdout ]));
 
@@ -1058,6 +1061,10 @@ function handlePkg(ev)
 							resolveFn(res);
 					}, this, res)
 				}, _('Dismiss'))));
+				} else {
+				ui.hideModal();
+				updateLists();
+				}
 		}).catch(function(err) {
 			ui.addNotification(null, E('p', _('Unable to execute <em>%s %s</em> command: %s').format(L.hasSystemFeature('apk') ? 'apk' : 'opkg', cmd, err)));
 			ui.hideModal();
@@ -1152,6 +1159,36 @@ return view.extend({
 	},
 
 	render(listData) {
+			const checkUpdateNeeded = function() {
+            return Promise.all([
+                L.resolveDefault(fs.stat('/tmp/opkg-lists/kwrt_kiddin9'), null),
+                L.resolveDefault(fs.read('/tmp/resolv.conf.d/resolv.conf.auto'), '')
+            ]).then(function(results) {
+                const stat = results[0];
+                const resolvContent = results[1];
+
+                let needUpdate = false;
+
+                if (stat) {
+                    const currentDate = new Date();
+                    const lastUpdateDate = new Date(stat.mtime * 1000);  // Convert seconds to milliseconds
+                    // 检查是否在今天的零点之后更新过
+                    const today = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
+                    needUpdate = lastUpdateDate < today;
+                } else {
+                    needUpdate = true;
+                }
+
+                // 检查 resolv.conf.auto 文件内容
+                const hasResolvContent = resolvContent && resolvContent.trim().length > 0;
+
+                // 只有当需要更新且 resolv.conf.auto 不为空时,才返回 true
+                return needUpdate && hasResolvContent;
+            }).catch(function(error) {
+                console.error('Error checking update status:', error);
+                return false; // 如果出错,不执行更新
+            });
+        };
 		const query = decodeURIComponent(L.toArray(location.search.match(/\bquery=([^=]+)\b/))[1] || '');
 
 		const view = E([], [
@@ -1193,6 +1230,7 @@ return view.extend({
 					E('label', {}, _('Actions') + ':'), ' ',
 					E('span', { 'class': 'control-group' }, [
 						E('button', { 'class': 'btn cbi-button-positive', 'data-command': 'update', 'click': handlePkg, 'disabled': isReadonlyView }, [ _('Update lists…') ]), ' ',
+						E('button', { 'class': 'btn cbi-button-negative', 'data-command': 'upgradeall', 'click': handlePkg, 'disabled': isReadonlyView }, [ _('Upgrade all…') ]), ' ',
 						E('button', { 'class': 'btn cbi-button-action', 'click': handleUpload, 'disabled': isReadonlyView }, [ _('Upload Package…') ]), ' ',
 						E('button', { 'class': 'btn cbi-button-neutral', 'click': handleConfig }, [ _('Configure %s').format(L.hasSystemFeature('apk') ? 'apk' : 'opkg') ])
 					])
@@ -1278,7 +1316,17 @@ return view.extend({
 		]);
 
 		requestAnimationFrame(function() {
-			updateLists(listData)
+			updateLists(listData);
+            checkUpdateNeeded().then(function(needUpdate) {
+                if (needUpdate) {
+		setTimeout(function() {
+                    const updateButton = document.querySelector('button[data-command="update"]');
+                    if (updateButton) {
+                        updateButton.click();
+                    }
+		}, 10)
+                }
+            });
 		});
 
 		return view;

--- a/package/feeds/luci/luci-app-package-manager/root/usr/libexec/package-manager-call
+++ b/package/feeds/luci/luci-app-package-manager/root/usr/libexec/package-manager-call
@@ -27,7 +27,7 @@ case "$action" in
 			find "${lists_dir:-/usr/lib/opkg/lists}" -type f '!' -name '*.sig' | xargs -r gzip -cd
 		fi
 	;;
-	install|update|upgrade|remove)
+	install|update|upgrade|upgradeall|remove)
 		(
 			cmd="$ipkg_bin"
 
@@ -89,10 +89,45 @@ case "$action" in
 
 			if flock -x 200; then
 				pkmcmd="$cmd $action $@"
-				$cmd $action "$@" </dev/null >/tmp/ipkg.out 2>/tmp/ipkg.err
-				code=$?
-				stdout=$(cat /tmp/ipkg.out)
+				if [ $action == "upgradeall" ]; then
+					$cmd update </dev/null >/tmp/ipkg.out 2>/tmp/ipkg.err
+					code=$?
+					if [ $code == 0 ]; then
+						. /etc/profile.d/opkg.sh
+						if [[ "$(cat `opkg export au`)" ]] && lock -n /var/lock/opkg-upgrade; then
+						 opkg upgr </dev/null >>/tmp/ipkg.out 2>>/tmp/ipkg.err
+						 code=$?
+						 lock -u /var/lock/opkg-upgrade
+						else
+							echo "🎉 所有软件包已是最新~" >>/tmp/ipkg.out
+							code=0
+						fi
+					fi
+				else
+					$cmd $action "$@" </dev/null >/tmp/ipkg.out 2>/tmp/ipkg.err
+					code=$?
+				fi
+				pkgn="$(echo $@ | cut -d - -f 3-)"
+				case "$action" in
+					install|upgrade)
+					if [ "$(opkg list-installed | cut -f 1 -d ' ' | grep -w $@)" ]; then
+							rm -f /tmp/ipkg.err
+							([ -f /etc/profile.d/opkg.sh ] && . /etc/profile.d/opkg.sh && opkg save) &
+					fi
+					;;
+					remove)
+						if [ ! "$(opkg list-installed | cut -f 1 -d ' ' | grep -w $@)" ]; then
+							rm -f /tmp/ipkg.err
+							([ -f /etc/profile.d/opkg.sh ] && . /etc/profile.d/opkg.sh && opkg save) &
+						fi
+					;;
+				esac
 				stderr=$(cat /tmp/ipkg.err)
+				[ -n "$stderr" ] || {
+					echo "🎉 已完成, 请关闭本窗口~" >>/tmp/ipkg.out
+					code=0
+				}
+				stdout=$(cat /tmp/ipkg.out)
 			else
 				code=255
 				stderr="Failed to acquire lock"
@@ -110,7 +145,7 @@ case "$action" in
 	;;
 	*)
 		echo "Usage: $0 {list-installed|list-available|update}" >&2
-		echo "       $0 {install|upgrade|remove} pkg[ pkg...]" >&2
+		echo "       $0 {install|upgrade|upgradeall|remove} pkg[ pkg...]" >&2
 		exit 1
 	;;
 esac


--- a/package/feeds/luci/luci-app-package-manager/root/usr/share/rpcd/acl.d/luci-app-package-manager.json
+++ b/package/feeds/luci/luci-app-package-manager/root/usr/share/rpcd/acl.d/luci-app-package-manager.json
@@ -8,6 +8,7 @@
 				"/usr/libexec/package-manager-call list-available": [ "exec" ],
 				"/etc/opkg.conf": [ "read" ],
 				"/etc/opkg/*.conf": [ "read" ],
+				"/tmp/resolv.conf.d/resolv.conf.auto": [ "read" ],
 				"/etc/apk/repositories": [ "read" ],
 				"/etc/apk/repositories.d/distfeeds.list": [ "read" ],
 				"/etc/apk/repositories.d/customfeeds.list": [ "read" ]
@@ -24,6 +25,7 @@
 				"/usr/libexec/package-manager-call update": [ "exec" ],
 				"/usr/libexec/package-manager-call upgrade": [ "exec" ],
 				"/usr/libexec/package-manager-call upgrade *": [ "exec" ],
+				"/usr/libexec/package-manager-call upgradeall": [ "exec" ],
 				"/etc/opkg.conf": [ "write" ],
 				"/etc/opkg/*.conf": [ "write" ],
 				"/etc/apk/repositories": [ "write" ],


================================================
FILE: devices/common/patches/package.patch
================================================
--- a/include/package.mk
+++ b/include/package.mk
@@ -354,3 +354,11 @@ dist:
 
 distcheck:
 	$(Build/DistCheck)
+
+ifndef Package/$(PKG_NAME)/conffiles
+define Package/$(PKG_NAME)/conffiles
+/etc/config/
+/etc/$(PKG_NAME)/
+endef
+endif
+

--- a/package/Makefile
+++ b/package/Makefile
@@ -118,8 +118,11 @@ endif
 
 	$(call prepare_rootfs,$(TARGET_DIR),$(TOPDIR)/files)
 
+PACKAGE_SUFFIX:=$(if $(CONFIG_USE_APK),apk,ipk)
 $(curdir)/index: FORCE
 	@echo Generating package index...
+	$(FIND) $(wildcard $(PACKAGE_SUBDIRS)) -path $(PACKAGE_DIR) -prune -o \
+    -type f -name '*.$(PACKAGE_SUFFIX)' -exec $(CP) -t $(PACKAGE_DIR)/ {} +
 ifneq ($(CONFIG_USE_APK),)
 	@for d in $(PACKAGE_SUBDIRS); do \
 		mkdir -p $$d; \


================================================
FILE: devices/common/patches/rootfs.patch
================================================
--- a/include/rootfs.mk
+++ b/include/rootfs.mk
@@ -88,7 +88,6 @@ define prepare_rootfs
 			ret=$$?; \
 			if [ $$ret -ne 0 ]; then \
 				echo "postinst script $$script has failed with exit code $$ret" >&2; \
-				exit 1; \
 			fi; \
 			[ -n "$(CONFIG_USE_APK)" ] && $(STAGING_DIR_HOST)/bin/tar --delete -f ./lib/apk/db/scripts.tar $$(basename $$script); \
 		done; \

================================================
FILE: devices/common/patches/status.patch
================================================
--- a/package/feeds/luci/luci-mod-status/htdocs/luci-static/resources/view/status/include/20_memory.js
+++ b/package/feeds/luci/luci-mod-status/htdocs/luci-static/resources/view/status/include/20_memory.js
@@ -32,8 +32,7 @@ return baseclass.extend({
 		    swap = L.isObject(systeminfo.swap) ? systeminfo.swap : {};
 
 		var fields = [
-			_('Total Available'), (mem.available) ? mem.available : (mem.total && mem.free && mem.buffered) ? mem.free + mem.buffered : null, mem.total,
-			_('Used'),            (mem.total && mem.free) ? (mem.total - mem.free) : null, mem.total,
+			_('Used'),            (mem.total && mem.available) ? (mem.total - mem.free - mem.buffered - mem.cached) : null, mem.total,
 		];
 
 		if (mem.buffered)
@@ -43,9 +42,9 @@ return baseclass.extend({
 			fields.push(_('Cached'), mem.cached, mem.total);
 
 		if (swap.total > 0)
-			fields.push(_('Swap free'), swap.free, swap.total);
+			fields.push(_('Swap used'), swap.total - swap.free, swap.total);
 
-		var table = E('table', { 'class': 'table' });
+		var table = E('table', { 'class': 'table memory' });
 
 		for (var i = 0; i < fields.length; i += 3) {
 			table.appendChild(E('tr', { 'class': 'tr' }, [

--- a/package/feeds/luci/luci-mod-status/root/usr/share/rpcd/acl.d/luci-mod-status.json
+++ b/package/feeds/luci/luci-mod-status/root/usr/share/rpcd/acl.d/luci-mod-status.json
@@ -6,7 +6,7 @@
 				"/etc/services": [ "read" ]
 			},
 			"ubus": {
-				"luci": [ "getConntrackList", "getRealtimeStats" ],
+				"luci": [ "getConntrackList", "getRealtimeStats", "getCPUBench", "getCPUUsage", "getOnlineUsers" ],
 				"luci-rpc": [ "getHostHints", "getNetworkDevices", "getDHCPLeases" ],
 				"network.rrdns": [ "lookup" ]
 			}

--- a/package/feeds/luci/luci-mod-status/htdocs/luci-static/resources/view/status/include/10_system.js
+++ b/package/feeds/luci/luci-mod-status/htdocs/luci-static/resources/view/status/include/10_system.js
@@ -18,6 +18,21 @@ var callSystemInfo = rpc.declare({
 	method: 'info'
 });
 
+var callCPUBench = rpc.declare({
+	object: 'luci',
+	method: 'getCPUBench'
+});
+
+var callCPUInfo = rpc.declare({
+	object: 'luci',
+	method: 'getCPUInfo'
+});
+
+var callTempInfo = rpc.declare({
+	object: 'luci',
+	method: 'getTempInfo'
+});
+
 return baseclass.extend({
 	title: _('System'),
 
@@ -25,6 +45,9 @@ return baseclass.extend({
 		return Promise.all([
 			L.resolveDefault(callSystemBoard(), {}),
 			L.resolveDefault(callSystemInfo(), {}),
+			L.resolveDefault(callCPUBench(), {}),
+			L.resolveDefault(callCPUInfo(), {}),
+			L.resolveDefault(callTempInfo(), {}),
 			L.resolveDefault(callLuciVersion(), { revision: _('unknown version'), branch: 'LuCI' }),
 			L.resolveDefault(callGetUnixtime(), 0),
 			uci.load('system')
@@ -32,7 +56,10 @@ return baseclass.extend({
 	render: function(data) {
 		var boardinfo   = data[0],
 		    systeminfo  = data[1],
-		    luciversion = data[2],
-		    unixtime    = data[3];
+		    cpubench    = data[2],
+		    cpuinfo     = data[3],
+		    tempinfo    = data[4],
+		    luciversion = data[5],
+		    unixtime    = data[6];
 
 		luciversion = luciversion.branch + ' ' + luciversion.revision;
 
@@ -53,8 +81,6 @@ return baseclass.extend({
 
 		var fields = [
 			_('Hostname'),         boardinfo.hostname,
-			_('Model'),            boardinfo.model,
-			_('Architecture'),     boardinfo.system,
 			_('Target Platform'),  (L.isObject(boardinfo.release) ? boardinfo.release.target : ''),
 			_('Firmware Version'), (L.isObject(boardinfo.release) ? boardinfo.release.description + ' / ' : '') + (luciversion || ''),
 			_('Kernel Version'),   boardinfo.kernel,
@@ -67,6 +93,24 @@ return baseclass.extend({
 			) : null
 		];
 
+		if (tempinfo.tempinfo) {
+			fields.splice(6, 0, _('Temperature'));
+			fields.splice(7, 0, tempinfo.tempinfo);
+		}
+		if (boardinfo.model == "Default string Default string") {
+			if (cpuinfo.cpuinfo) {
+			fields.splice(2, 0, _('Architecture'));
+			fields.splice(3, 0, cpuinfo.cpuinfo + cpubench.cpubench);
+			}
+		} else {
+			fields.splice(2, 0, _('Model'));
+			fields.splice(3, 0, boardinfo.model + cpubench.cpubench);
+			if (cpuinfo.cpuinfo) {
+			fields.splice(4, 0, _('Architecture'));
+			fields.splice(5, 0, cpuinfo.cpuinfo);
+			}
+		}
+
 		var table = E('table', { 'class': 'table' });
 
 		for (var i = 0; i < fields.length; i += 2) {

--- a/package/feeds/luci/luci-mod-status/htdocs/luci-static/resources/view/status/nftables.js
+++ b/package/feeds/luci/luci-mod-status/htdocs/luci-static/resources/view/status/nftables.js
@@ -675,7 +675,6 @@ return view.extend({
 	checkLegacyRules: function(ipt4save, ipt6save) {
 		if (ipt4save.match(/\n-A /) || ipt6save.match(/\n-A /)) {
 			ui.addNotification(_('Legacy rules detected'), [
-				E('p', _('There are legacy iptables rules present on the system. Mixing iptables and nftables rules is discouraged and may lead to incomplete traffic filtering.')),
 				E('button', {
 					'class': 'btn cbi-button',
 					'click': function() { location.href = 'nftables/iptables' }

--- a/package/feeds/luci/luci-mod-status/htdocs/luci-static/resources/view/status/include/29_ports.js
+++ b/package/feeds/luci/luci-mod-status/htdocs/luci-static/resources/view/status/include/29_ports.js
@@ -309,8 +309,6 @@ return baseclass.extend({
 	},
 
 	render(data) {
-		if (L.hasSystemFeature('swconfig'))
-			return null;
 
 		const board = JSON.parse(data[1]),
 		    known_ports = [],


================================================
FILE: devices/common/patches/use_json_object_new_int64.patch.b
================================================
--- a/package/feeds/luci/luci-lib-jsonc/src/jsonc.c
+++ b/package/feeds/luci/luci-lib-jsonc/src/jsonc.c
@@ -366,9 +366,7 @@
 	case LUA_TNUMBER:
 		nd = lua_tonumber(L, index);
-		ni = lua_tointeger(L, index);
-
-		if (nd == ni)
-			return json_object_new_int(nd);
-
+		if(nd >= INT64_MIN && nd <= INT64_MAX)
+			return json_object_new_int64(nd);
+		else
 		return json_object_new_double(nd);
 


================================================
FILE: devices/common/patches/wifi-scripts.patch
================================================
--- a/package/network/config/wifi-scripts/files/lib/netifd/hostapd.sh
+++ b/package/network/config/wifi-scripts/files/lib/netifd/hostapd.sh
@@ -122,6 +122,7 @@ hostapd_common_add_device_config() {
 	config_add_int maxassoc
 	config_add_int reg_power_type
 	config_add_boolean stationary_ap
+	config_add_boolean vendor_vht
 
 	config_add_string acs_chan_bias
 	config_add_array hostapd_options
@@ -141,7 +142,7 @@ hostapd_prepare_device_config() {
 	json_get_vars country country3 country_ie beacon_int:100 doth require_mode legacy_rates \
 		acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \
 		rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_reject_assoc_timeout rssi_ignore_probe_request \
-		maxassoc mbssid:0 band reg_power_type stationary_ap
+		maxassoc mbssid:0 band reg_power_type stationary_ap vendor_vht
 
 	hostapd_set_log_options base_cfg
 
@@ -210,6 +211,7 @@ hostapd_prepare_device_config() {
 				set_default rate_list "24000 36000 48000 54000"
 				set_default basic_rate_list "24000"
 			fi
+			[ -n "$vendor_vht" ] && append base_cfg "vendor_vht=$vendor_vht" "$N"
 		;;
 		a)
 			if [ "$cell_density" -eq 1 ]; then


================================================
FILE: devices/common/patches/wireless.patch
================================================
--- a/package/feeds/luci/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js
+++ b/package/feeds/luci/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js
@@ -1026,6 +1026,12 @@ return view.extend({
 					o.placeholder = 100;
 					o.rmempty = true;
 
+					o = ss.taboption("advanced", form.Flag, 'mu_beamformer', _('MU-MIMO'));
+					o.default = '1';
+
+					o = ss.taboption('advanced', form.Flag, 'vendor_vht', _('Enable 256-QAM'), _('802.11n 2.4Ghz Only'));
+					o.default = o.disabled;
+
 					o = ss.taboption('advanced', form.Flag, 'rxldpc', _('Rx LDPC'), _('Low-Density Parity-Check'));
 					o.default = '1';
 


================================================
FILE: devices/common/settings.ini
================================================
REPO_URL="https://github.com/openwrt/openwrt"
REPO_BRANCH=""
CONFIG_FILE=".config"
DIY_SH="diy.sh"
FREE_UP_DISK="false"
UPLOAD_BIN_DIR_FOR_ARTIFACT="false"
UPLOAD_FIRMWARE_FOR_ARTIFACT="true"
UPLOAD_FIRMWARE_FOR_RELEASE="false"
UPLOAD_FIRMWARE_TO_COWTRANSFER="false"
UPLOAD_FIRMWARE_TO_WETRANSFER="true"


================================================
FILE: devices/ipq40xx_generic/.config
================================================

CONFIG_TARGET_ipq40xx=y
CONFIG_TARGET_ipq40xx_generic=y

CONFIG_TARGET_DEVICE_ipq40xx_generic_DEVICE_dlink_dap-2610=n
CONFIG_TARGET_DEVICE_ipq40xx_generic_DEVICE_eagle-pro-ai-m32-a1=n
CONFIG_TARGET_DEVICE_ipq40xx_generic_DEVICE_eagle-pro-ai-r32-a1=n
CONFIG_TARGET_DEVICE_ipq40xx_generic_DEVICE_extreme-networks_ws-ap391x=n
CONFIG_TARGET_DEVICE_ipq40xx_generic_DEVICE_netgear_ex6100v2=n
CONFIG_TARGET_DEVICE_ipq40xx_generic_DEVICE_netgear_ex6150v2=n
CONFIG_TARGET_DEVICE_ipq40xx_generic_DEVICE_zyxel_nbg6617=n







================================================
FILE: devices/ipq40xx_generic/diy.sh
================================================
#!/bin/bash

shopt -s extglob

SHELL_FOLDER=$(dirname $(readlink -f "$0"))

#sh -c "curl -sfL https://patch-diff.githubusercontent.com/raw/openwrt/openwrt/pull/10778.patch | git apply -p1"

wget -N https://github.com/immortalwrt/immortalwrt/raw/refs/heads/openwrt-25.12/target/linux/ipq40xx/patches-6.12/991-ipq40xx-unlock-cpu-frequency.patch -P target/linux/ipq40xx/patches-6.12/




================================================
FILE: devices/ipq40xx_generic/patches/ap4220.patch
================================================
From 901be81149fd7c97fb5c7fdabe6e05e470fada00 Mon Sep 17 00:00:00 2001
From: Willem Lee <1980490718@qq.com>
Date: Fri, 18 Apr 2025 05:30:01 +0800
Subject: [PATCH] ipq40xx: add support for Aliyun AP4220

Hardware specifications
-------------
- SoC       : Qualcomm IPQ4018
- RAM       : 256 MiB DDR3
- Flash     : 4 MiB SPI NOR (Winbond) + 128 MiB SPI NAND (Winbond)
- WLAN      : IPQ4018 built-in
  - 2.4 GHz : 2x2 MIMO WiFi4
  - 5 GHz   : 2x2 MIMO WiFi5
- Ethernet  : QCA8072 10/100/1000 Mbps 1x WAN (PoE); 1x LAN
- USB       : 1x 2.0
- UART      : 1x Rj45 port, 115200n8
- Buttons   : 1x Reset
- LEDs      : 1x Power (green)
              1x WiFi 2.4 GHz (green)
              1x WiFi 5 GHz (green)
- Power     : 802.3at PoE

Flash instructions
-------------
  1. Connect the router via serial port
  2. Keep pressing "@" until uboot is interrupted
  3. Download the initramfs image, rename it to
     initramfs.bin, host it with tftp server
  4. Run these commands:
     "tftpboot initramfs.bin && bootm"
  5. After openwrt boots up, use scp or luci
     to upload sysupgrade.bin to upgrade.

Signed-off-by: Willem Lee <1980490718@qq.com>
---
 .../uboot-tools/uboot-envtools/files/ipq40xx  |   1 +
 package/firmware/ipq-wifi/Makefile            |   2 +
 .../ipq40xx/base-files/etc/board.d/02_network |   6 +
 .../etc/hotplug.d/firmware/11-ath10k-caldata  |   8 +
 .../base-files/lib/upgrade/platform.sh        |   3 +-
 .../arm/boot/dts/qcom/qcom-ipq4018-ap4220.dts | 369 ++++++++++++++++++
 target/linux/ipq40xx/image/generic.mk         |  12 +
 7 files changed, 400 insertions(+), 1 deletion(-)
 create mode 100644 target/linux/ipq40xx/files-6.12/arch/arm/boot/dts/qcom/qcom-ipq4018-ap4220.dts

diff --git a/package/boot/uboot-tools/uboot-envtools/files/ipq40xx b/package/boot/uboot-tools/uboot-envtools/files/ipq40xx
index 717158b0425ea5..481722a7e7c66a 100644
--- a/package/boot/uboot-tools/uboot-envtools/files/ipq40xx
+++ b/package/boot/uboot-tools/uboot-envtools/files/ipq40xx
@@ -32,6 +32,7 @@ ubootenv_mtdinfo () {
 
 case "$board" in
 alfa-network,ap120c-ac|\
+aliyun,ap4220|\
 devolo,magic-2-wifi-next|\
 edgecore,ecw5211|\
 glinet,gl-a1300 |\
diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile
index 72e397443888c9..1f0b611c9ed584 100644
--- a/package/firmware/ipq-wifi/Makefile
+++ b/package/firmware/ipq-wifi/Makefile
@@ -28,6 +28,7 @@ endef
 	8devices_kiwi \
 	8devices_mango \
 	alfa-network_ap120c-ax \
+	aliyun_ap4220 \
 	aliyun_ap8220 \
 	arcadyan_aw1000 \
 	asus_rt-ax89x \
@@ -177,6 +178,7 @@ endef
 $(eval $(call generate-ipq-wifi-package,8devices_kiwi,8devices Kiwi))
 $(eval $(call generate-ipq-wifi-package,8devices_mango,8devices Mango))
 $(eval $(call generate-ipq-wifi-package,alfa-network_ap120c-ax,ALFA Network AP120C-AX))
+$(eval $(call generate-ipq-wifi-package,aliyun_ap4220,Aliyun AP4220))
 $(eval $(call generate-ipq-wifi-package,aliyun_ap8220,Aliyun AP8220))
 $(eval $(call generate-ipq-wifi-package,arcadyan_aw1000,Arcadyan AW1000))
 $(eval $(call generate-ipq-wifi-package,asus_rt-ax89x,Asus RT-AX89X))
diff --git a/target/linux/ipq40xx/base-files/etc/board.d/02_network b/target/linux/ipq40xx/base-files/etc/board.d/02_network
index 57dca0e1a2a93a..27f5aefd002286 100644
--- a/target/linux/ipq40xx/base-files/etc/board.d/02_network
+++ b/target/linux/ipq40xx/base-files/etc/board.d/02_network
@@ -31,6 +31,7 @@ ipq40xx_setup_interfaces()
 	8dev,jalapeno|\
 	alfa-network,ap120c-ac|\
 	asus,map-ac1300|\
+	aliyun,ap4220|\
 	asus,map-ac2200|\
 	cilab,meshpoint-one|\
 	edgecore,ecw5211|\
@@ -171,6 +172,11 @@ ipq40xx_setup_macs()
 	8dev,habanero-dvk)
 		label_mac=$(mtd_get_mac_binary "ART" 0x1006)
 		;;
+	aliyun,ap4220)
+		wan_mac=$(mtd_get_mac_text product_info 0x40)
+		lan_mac=$(macaddr_add "$wan_mac" 1)
+		label_mac="$wan_mac"
+		;;
 	asus,rt-ac42u)
 		label_mac=$(mtd_get_mac_binary_ubi Factory 0x1006)
 		;;
diff --git a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
index 4a1a0ff31118a3..beb8aed58cfb2f 100644
--- a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
+++ b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
@@ -57,6 +57,10 @@ case "$FIRMWARE" in
 	;;
 "ath10k/pre-cal-ahb-a000000.wifi.bin")
 	case "$board" in
+	aliyun,ap4220)
+		caldata_extract "ART" 0x1000 0x2f20
+		ath10k_patch_mac $(macaddr_add "$(mtd_get_mac_text product_info 0x40)" 2)
+		;;
 	asus,rt-ac42u)
 		caldata_extract_ubi "Factory" 0x1000 0x2f20
 		;;
@@ -157,6 +161,10 @@ case "$FIRMWARE" in
 	;;
 "ath10k/pre-cal-ahb-a800000.wifi.bin")
 	case "$board" in
+	aliyun,ap4220)
+		caldata_extract "ART" 0x5000 0x2f20
+		ath10k_patch_mac $(macaddr_add "$(mtd_get_mac_text product_info 0x40)" 3)
+		;;
 	avm,fritzbox-4040)
 		/usr/bin/fritz_cal_extract -i 1 -s 0x400 -e 0x208 -l 12064 -o /lib/firmware/$FIRMWARE $(find_mtd_chardev "urlader_config")
 		;;
diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
index 53a95611487b50..8f4f002dbea61d 100644
--- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
@@ -132,7 +132,8 @@ platform_do_upgrade() {
 	wallys,dr40x9)
 		nand_do_upgrade "$1"
 		;;
-	alfa-network,ap120c-ac)
+	alfa-network,ap120c-ac|\
+	aliyun,ap4220)
 		part="$(awk -F 'ubi.mtd=' '{printf $2}' /proc/cmdline | sed -e 's/ .*$//')"
 		if [ "$part" = "rootfs1" ]; then
 			fw_setenv active 2 || exit 1
diff --git a/target/linux/ipq40xx/files-6.12/arch/arm/boot/dts/qcom/qcom-ipq4018-ap4220.dts b/target/linux/ipq40xx/files-6.12/arch/arm/boot/dts/qcom/qcom-ipq4018-ap4220.dts
new file mode 100644
index 00000000000000..4f9ab7f61627b0
--- /dev/null
+++ b/target/linux/ipq40xx/files-6.12/arch/arm/boot/dts/qcom/qcom-ipq4018-ap4220.dts
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "qcom-ipq4019.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/soc/qcom,tcsr.h>
+
+/ {
+	compatible = "aliyun,ap4220", "qcom,ipq4019";
+	model = "Aliyun AP4220";
+
+	aliases {
+		label-mac-device = &gmac;
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	chosen {
+		bootargs-append = " root=/dev/ubiblock0_1";
+		stdout-path = "serial:115200n8";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		button-reset {
+			label = "reset";
+			gpios = <&tlmm 63 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_WLAN_5GHZ;
+			gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		led-1 {
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_WLAN_2GHZ;
+			gpios = <&tlmm 3 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		led_status: led-2 {
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_POWER;
+			gpios = <&tlmm 5 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+	};
+
+	reg_usb: regulator-usb {
+		compatible = "regulator-fixed";
+		gpios = <&tlmm 1 GPIO_ACTIVE_LOW>;
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-name = "reg_usb";
+	};
+
+	soc {
+		tcsr@1949000 {
+			compatible = "qcom,tcsr";
+			reg = <0x1949000 0x100>;
+			qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
+		};
+
+		tcsr@194b000 {
+			compatible = "qcom,tcsr";
+			reg = <0x194b000 0x100>;
+			qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
+		};
+
+		ess_tcsr@1953000 {
+			compatible = "qcom,tcsr";
+			reg = <0x1953000 0x1000>;
+			qcom,ess-interface-select = <TCSR_ESS_PSGMII>;
+		};
+
+		tcsr@1957000 {
+			compatible = "qcom,tcsr";
+			reg = <0x1957000 0x100>;
+			qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
+		};
+	};
+};
+
+&blsp_dma {
+	status = "okay";
+};
+
+&blsp1_spi1 {
+	status = "okay";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+	num-cs = <2>;
+	pinctrl-0 = <&spi0_pins>;
+	pinctrl-names = "default";
+	cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>, <&tlmm 4 GPIO_ACTIVE_HIGH>;
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <24000000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "SBL1";
+				reg = <0x0 0x40000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "MIBIB";
+				reg = <0x40000 0x20000>;
+				read-only;
+			};
+
+			partition@60000 {
+				label = "QSEE";
+				reg = <0x60000 0x60000>;
+				read-only;
+			};
+
+			partition@c0000 {
+				label = "CDT";
+				reg = <0xc0000 0x10000>;
+				read-only;
+			};
+
+			partition@d0000 {
+				label = "DDRPARAMS";
+				reg = <0xd0000 0x10000>;
+				read-only;
+			};
+
+			partition@e0000 {
+				compatible = "u-boot,env";
+				label = "APPSBLENV";
+				reg = <0xe0000 0x10000>;
+			};
+
+			partition@f0000 {
+				label = "APPSBL";
+				reg = <0xf0000 0x80000>;
+				read-only;
+			};
+
+			partition@170000 {
+				label = "ART";
+				reg = <0x170000 0x10000>;
+				read-only;
+			};
+
+			partition@180000 {
+				label = "product_info";
+				reg = <0x180000 0x10000>;
+				read-only;
+			};
+
+			partition@190000 {
+				label = "mtdoops";
+				reg = <0x190000 0x20000>;
+			};
+
+			partition@1b0000 {
+				label = "priv_data1";
+				reg = <0x1b0000 0x10000>;
+				read-only;
+			};
+
+			partition@1c0000 {
+				label = "priv_data2";
+				reg = <0x1c0000 0x10000>;
+				read-only;
+			};
+
+			partition@1d0000 {
+				label = "priv_data3";
+				reg = <0x1d0000 0x200000>;
+				read-only;
+			};
+		};
+	};
+
+	spi-nand@1 {
+		compatible = "spi-nand";
+		reg = <1>;
+		spi-max-frequency = <24000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "rootfs1";
+				reg = <0x0 0x3000000>;
+			};
+
+			partition@3000000 {
+				label = "rootfs2";
+				reg = <0x3000000 0x3000000>;
+			};
+
+			partition@6000000 {
+				label = "usrdata";
+				reg = <0x6000000 0x2000000>;
+			};
+		};
+	};
+};
+
+&blsp1_uart1 {
+	status = "okay";
+
+	pinctrl-0 = <&serial_pins>;
+	pinctrl-names = "default";
+};
+
+&crypto {
+	status = "okay";
+};
+
+&cryptobam {
+	status = "okay";
+};
+
+&ethphy0 {
+	status = "disabled";
+};
+
+&ethphy1 {
+	status = "disabled";
+};
+
+&ethphy2 {
+	status = "disabled";
+};
+
+&ethphy3 {
+	status = "okay";
+};
+
+&ethphy4 {
+	status = "okay";
+};
+
+&gmac {
+	status = "okay";
+};
+
+&mdio {
+	status = "okay";
+
+	pinctrl-0 = <&mdio_pins>;
+	pinctrl-names = "default";
+};
+
+&prng {
+	status = "okay";
+};
+
+&switch {
+	status = "okay";
+};
+
+&swport4 {
+	status = "okay";
+
+	label = "wan";
+};
+
+&swport5 {
+	status = "okay";
+
+	label = "lan";
+};
+
+&tlmm {
+	mdio_pins: mdio_pinmux {
+		mdc {
+			pins = "gpio52";
+			function = "mdc";
+			drive-strength = <4>;
+			bias-pull-up;
+		};
+
+		mdio {
+			pins = "gpio53";
+			function = "mdio";
+			drive-strength = <4>;
+			bias-pull-up;
+		};
+	};
+
+	serial_pins: serial_pinmux {
+		blsp_uart0 {
+			pins = "gpio60", "gpio61";
+			function = "blsp_uart0";
+			drive-strength = <8>;
+			bias-disable;
+		};
+	};
+
+	spi0_pins: spi0_pinmux {
+		blsp_spi0 {
+			pins = "gpio55", "gpio56", "gpio57";
+			function = "blsp_spi0";
+			drive-strength = <12>;
+			bias-disable;
+		};
+
+		gpio {
+			pins = "gpio54", "gpio4";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-disable;
+			output-high;
+		};
+	};
+};
+
+&usb3 {
+	status = "okay";
+};
+
+&usb3_hs_phy {
+	status = "okay";
+
+	phy-supply = <&reg_usb>;
+};
+
+&usb3_ss_phy {
+	status = "okay";
+
+	phy-supply = <&reg_usb>;
+};
+
+&watchdog {
+	status = "okay";
+};
+
+&wifi0 {
+	status = "okay";
+
+	qcom,ath10k-calibration-variant = "Aliyun-AP4220";
+};
+
+&wifi1 {
+	status = "okay";
+
+	qcom,ath10k-calibration-variant = "Aliyun-AP4220";
+};
diff --git a/target/linux/ipq40xx/image/generic.mk b/target/linux/ipq40xx/image/generic.mk
index 393bb991f11e6a..475a05188a8231 100644
--- a/target/linux/ipq40xx/image/generic.mk
+++ b/target/linux/ipq40xx/image/generic.mk
@@ -170,6 +170,18 @@ define Device/alfa-network_ap120c-ac
 endef
 TARGET_DEVICES += alfa-network_ap120c-ac
 
+define Device/aliyun_ap4220
+	$(call Device/FitImage)
+	$(call Device/UbiFit)
+	DEVICE_VENDOR := Aliyun
+	DEVICE_MODEL := AP4220
+	SOC := qcom-ipq4018
+	BLOCKSIZE := 128k
+	PAGESIZE := 2048
+	DEVICE_PACKAGES := ipq-wifi-aliyun_ap4220
+endef
+TARGET_DEVICES += aliyun_ap4220
+
 define Device/aruba_glenmorangie
 	$(call Device/FitImageLzma)
 	DEVICE_VENDOR := Aruba


================================================
FILE: devices/ipq40xx_generic/patches/cm520.patch
================================================
--- a/target/linux/ipq40xx/files-6.12/arch/arm/boot/dts/qcom/qcom-ipq4019-cm520-79f.dts
+++ b/target/linux/ipq40xx/files-6.12/arch/arm/boot/dts/qcom/qcom-ipq4019-cm520-79f.dts
@@ -19,6 +19,10 @@
 		led-upgrade = &led_sys;
 	};
 
+	chosen {
+		bootargs-append = " ubi.block=0,1 root=/dev/ubiblock0_1";
+	};
+
 	soc {
 		tcsr@1949000 {
 			compatible = "qcom,tcsr";
@@ -160,65 +164,8 @@
 			#size-cells = <1>;
 
 			partition@0 {
-				label = "SBL1";
-				reg = <0x0 0x100000>;
-				read-only;
-			};
-
-			partition@100000 {
-				label = "MIBIB";
-				reg = <0x100000 0x100000>;
-				read-only;
-			};
-
-			partition@200000 {
-				label = "BOOTCONFIG";
-				reg = <0x200000 0x100000>;
-			};
-
-			partition@300000 {
-				label = "QSEE";
-				reg = <0x300000 0x100000>;
-				read-only;
-			};
-
-			partition@400000 {
-				label = "QSEE_1";
-				reg = <0x400000 0x100000>;
-				read-only;
-			};
-
-			partition@500000 {
-				label = "CDT";
-				reg = <0x500000 0x80000>;
-				read-only;
-			};
-
-			partition@580000 {
-				label = "CDT_1";
-				reg = <0x580000 0x80000>;
-				read-only;
-			};
-
-			partition@600000 {
-				label = "BOOTCONFIG1";
-				reg = <0x600000 0x80000>;
-			};
-
-			partition@680000 {
-				label = "APPSBLENV";
-				reg = <0x680000 0x80000>;
-			};
-
-			partition@700000 {
-				label = "APPSBL";
-				reg = <0x700000 0x200000>;
-				read-only;
-			};
-
-			partition@900000 {
-				label = "APPSBL_1";
-				reg = <0x900000 0x200000>;
+				label = "Bootloader";
+				reg = <0x0 0xb00000>;
 				read-only;
 			};
 
@@ -251,7 +198,7 @@
 			};
 
 			partition@b80000 {
-				label = "ubi";
+				label = "rootfs";
 				reg = <0xb80000 0x7480000>;
 			};
 		};

================================================
FILE: devices/ipq40xx_generic/patches/target.patch
================================================
--- a/target/linux/ipq40xx/image/generic.mk
+++ b/target/linux/ipq40xx/image/generic.mk
@@ -694,7 +694,7 @@ TARGET_DEVICES += meraki_mr33
 define Device/mobipromo_cm520-79f
 	$(call Device/FitzImage)
 	$(call Device/UbiFit)
-	DEVICE_VENDOR := MobiPromo
+	DEVICE_VENDOR := MobiPromo星际宝盒
 	DEVICE_MODEL := CM520-79F
 	SOC := qcom-ipq4019
 	BLOCKSIZE := 128k
@@ -834,7 +834,7 @@ TARGET_DEVICES += openmesh_a62
 define Device/p2w_r619ac
 	$(call Device/FitzImage)
 	$(call Device/UbiFit)
-	DEVICE_VENDOR := P&W
+	DEVICE_VENDOR := P&W竞斗云
 	DEVICE_MODEL := R619AC
 	SOC := qcom-ipq4019
 	DEVICE_DTS_CONFIG := config@10

================================================
FILE: devices/ipq806x_generic/.config
================================================

CONFIG_TARGET_ipq806x=y
CONFIG_TARGET_ipq806x_generic=y

CONFIG_TARGET_DEVICE_ipq806x_generic_DEVICE_tplink_ad7200=n
CONFIG_TARGET_DEVICE_ipq806x_generic_DEVICE_tplink_c2600=n
CONFIG_TARGET_DEVICE_ipq806x_generic_DEVICE_ubnt_unifi-ac-hd=n


CONFIG_PACKAGE_MAC80211_NSS_SUPPORT=y

CONFIG_PACKAGE_kmod-ipsec=n






================================================
FILE: devices/ipq806x_generic/diy.sh
================================================
#!/bin/bash

shopt -s extglob

SHELL_FOLDER=$(dirname $(readlink -f "$0"))







================================================
FILE: devices/ipq806x_generic/patches/xiaomi_r3d.patch
================================================
From c433730d889d0dfb31bdcf4f102ca47939606c46 Mon Sep 17 00:00:00 2001
From: remittor <remittor@gmail.com>
Date: Fri, 11 Aug 2023 12:08:30 +0300
Subject: [PATCH] ipq806x: Add support for Xiaomi Mi Router HD (R3D)

Xiaomi R3D is a 2.4/5 GHz band 11ac router, based on IPQ8064.

Specification:
* SoC: Qualcomm IPQ8064
* RAM: 512MB DDR3
* Flash: 256MB NAND (Macronix MX30UF2G18AC-TI)
* Ethernet: 4x 10/100/1000 Mbps (1x WAN, 3x LAN)
* WiFi: Qualcomm QCA9984 (5GHz, 4T4R, n/ac)
* WiFi: Qualcomm QCA9980 (2.4GHz, 4T4R, b/g/n)
* USB: 1x 3.0
* SATA: 1x SATA 3.1 (only for internal HDD 3.5")
* BTN: Power, Reset
* LEDS: Status(Green/Blue/Red)
* UART: present as 4-pads on the PCB (3.3V, 115200-8-N-1)

MAC addresses as verified by stock firmware:

| Interface   |       MAC         |  ART    | Format |
|-------------+-------------------+---------+--------|
| WAN (label) | xx:xx:xx:xx:xx:B2 | 0x0     | binary |
| LAN         | xx:xx:xx:xx:xx:B3 | 0x6     | binary |
| WiFi 2g     | xx:xx:xx:xx:xx:B4 | 0x1006  | binary |
| WiFi 5g     | xx:xx:xx:xx:xx:B5 | 0x5006  | binary |
---
 package/boot/uboot-tools/uboot-envtools/files/ipq806x     |   6 +-
 .../ipq806x/base-files/etc/board.d/02_network |   4 +
 .../etc/hotplug.d/firmware/11-ath10k-caldata  |   6 +
 .../ipq806x/base-files/etc/init.d/bootcount   |   8 +
 .../base-files/lib/upgrade/platform.sh        |   3 +
 .../ipq806x/base-files/lib/upgrade/xiaomi.sh  | 441 ++++++++++++++++
 .../arch/arm/boot/dts/qcom-ipq8064-r3d.dts    | 479 ++++++++++++++++++
 target/linux/ipq806x/image/generic.mk         |  17 +
 8 files changed, 963 insertions(+), 1 deletion(-)
 create mode 100644 target/linux/ipq806x/base-files/lib/upgrade/xiaomi.sh
 create mode 100644 target/linux/ipq806x/files-6.12/arch/arm/boot/dts/qcom-ipq8064-r3d.dts

diff --git a/package/boot/uboot-tools/uboot-envtools/files/ipq806x b/package/boot/uboot-tools/uboot-envtools/files/ipq806x
index 01a86c7b19fca..c0a781c1e21b4 100644
--- a/package/boot/uboot-tools/uboot-envtools/files/ipq806x
+++ b/package/boot/uboot-tools/uboot-envtools/files/ipq806x
@@ -52,6 +52,10 @@ qcom,ipq8064-ap148|\
 nokia,ac400i)
 	ubootenv_add_uci_config "/dev/mtd20" "0x0" "0x040000" "0x20000"
 	;;
+xiaomi,r3d)
+	ubootenv_add_uci_config "/dev/mtd9" "0x0" "0x10000" "0x10000"
+	ubootenv_add_uci_sys_config "/dev/mtd12" "0x0" "0x10000" "0x10000"
+	;;
 ubnt,unifi-ac-hd|\
 zyxel,nbg6817)
 	ubootenv_add_uci_config "/dev/mtdblock9" "0x0" "0x10000" "0x10000"
@@ -59,6 +63,6 @@ zyxel,nbg6817)
 esac
 
 config_load ubootenv
-config_foreach ubootenv_add_app_config ubootenv
+config_foreach ubootenv_add_app_config
 
 exit 0
diff --git a/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
index 4c5019cf5bd24..aa8ed06aae4b3 100644
--- a/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
+++ b/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
@@ -56,6 +56,9 @@ case "$FIRMWARE" in
 		caldata_extract "0:art" 0x1000 0x2f20
 		ath10k_patch_mac $(macaddr_add $(mtd_get_mac_ascii 0:appsblenv ethaddr) +2)
 		;;
+	xiaomi,r3d)
+		caldata_extract "ART" 0x1000 0x2f20
+		;;
 	zyxel,nbg6817)
 		caldata_extract "0:art" 0x1000 0x2f20
 		ath10k_patch_mac $(macaddr_add $(mtd_get_mac_ascii 0:appsblenv ethaddr) 1)
@@ -92,6 +95,9 @@ case "$FIRMWARE" in
 		caldata_extract "0:art" 0x5000 0x2f20
 		ath10k_patch_mac $(macaddr_add $(mtd_get_mac_ascii 0:appsblenv ethaddr) +3)
 		;;
+	xiaomi,r3d)
+		caldata_extract "ART" 0x5000
Download .txt
gitextract_7kdwm0il/

├── .github/
│   └── workflows/
│       ├── Openwrt-AutoBuild.yml
│       └── repo-dispatcher.yml
├── LICENSE
├── README.md
└── devices/
    ├── airoha_an7581/
    │   ├── .config
    │   ├── diy/
    │   │   └── target/
    │   │       └── linux/
    │   │           └── airoha/
    │   │               └── dts/
    │   │                   └── an7581-xg-040g-md.dts
    │   ├── diy.sh
    │   └── patches/
    │       └── xg-040g-md.patch
    ├── amlogic_meson/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       └── fix.patch
    ├── amlogic_meson8b/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       ├── BRCMFMAC_SDIO.patch
    │       └── onecloud.patch
    ├── armsr_armv8/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       └── rootfs.patch
    ├── ath79_nand/
    │   ├── .config
    │   └── diy.sh
    ├── bcm27xx_bcm2708/
    │   ├── .config
    │   └── diy.sh
    ├── bcm27xx_bcm2709/
    │   ├── .config
    │   └── diy.sh
    ├── bcm27xx_bcm2710/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       └── Zero-2.patch
    ├── bcm27xx_bcm2711/
    │   ├── .config
    │   └── diy.sh
    ├── bcm27xx_bcm2712/
    │   ├── .config
    │   └── diy.sh
    ├── bcm53xx/
    │   ├── .config
    │   └── diy.sh
    ├── common/
    │   ├── .config
    │   ├── diy/
    │   │   ├── feeds/
    │   │   │   └── luci/
    │   │   │       └── modules/
    │   │   │           └── luci-base/
    │   │   │               └── htdocs/
    │   │   │                   └── luci-static/
    │   │   │                       └── resources/
    │   │   │                           └── tools/
    │   │   │                               └── github.js
    │   │   └── package/
    │   │       ├── base-files/
    │   │       │   └── files/
    │   │       │       └── etc/
    │   │       │           └── banner
    │   │       ├── network/
    │   │       │   └── config/
    │   │       │       ├── firewall/
    │   │       │       │   ├── files/
    │   │       │       │   │   └── firewall.exwan
    │   │       │       │   └── patches/
    │   │       │       │       └── fullconenat.patch
    │   │       │       └── firewall4/
    │   │       │           ├── files/
    │   │       │           │   ├── firewall.exwan
    │   │       │           │   └── firewall.include
    │   │       │           └── patches/
    │   │       │               ├── 001-firewall4-add-support-for-fullcone-nat.patch
    │   │       │               ├── 100-fw4-support-script.patch
    │   │       │               └── 200-fw4-hotplug-fork.patch
    │   │       └── system/
    │   │           └── opkg/
    │   │               └── patches/
    │   │                   ├── 010-opkg-force-depends.patch
    │   │                   ├── ignore_error.patch
    │   │                   ├── pkg_hash.patch
    │   │                   └── zh-cn.patch
    │   ├── diy.sh
    │   ├── patches/
    │   │   ├── LINUX_VERSION.patch
    │   │   ├── autoreconf.patch
    │   │   ├── base-files.patch
    │   │   ├── china_mirrors.patch.b
    │   │   ├── cmake.patch
    │   │   ├── compressed-memory.patch.b
    │   │   ├── crontab.patch
    │   │   ├── curl.patch
    │   │   ├── default-packages.patch
    │   │   ├── disable-seccomp-ujail.patch
    │   │   ├── dnsmasq.patch
    │   │   ├── feeds.patch
    │   │   ├── firewall.patch
    │   │   ├── getcwd-fix.patch
    │   │   ├── imagebuilder.patch
    │   │   ├── kernel-defaults.patch
    │   │   ├── luci-base.patch
    │   │   ├── luci-dhcp.patch
    │   │   ├── luci-mod-system.patch
    │   │   ├── luci_mk.patch
    │   │   ├── netfilter.patch.b
    │   │   ├── netsupport.patch
    │   │   ├── nftables.patch
    │   │   ├── nginx-fancyindex.patch.bak
    │   │   ├── nonshared.patch
    │   │   ├── opkginstall.patch
    │   │   ├── package.patch
    │   │   ├── rootfs.patch
    │   │   ├── status.patch
    │   │   ├── use_json_object_new_int64.patch.b
    │   │   ├── wifi-scripts.patch
    │   │   └── wireless.patch
    │   └── settings.ini
    ├── ipq40xx_generic/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       ├── ap4220.patch
    │       ├── cm520.patch
    │       └── target.patch
    ├── ipq806x_generic/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       └── xiaomi_r3d.patch
    ├── mediatek_filogic/
    │   ├── .config
    │   ├── diy/
    │   │   └── target/
    │   │       └── linux/
    │   │           └── mediatek/
    │   │               └── dts/
    │   │                   ├── mt7981b-aigo-ags21.dts
    │   │                   ├── mt7981b-bt-r320.dts
    │   │                   ├── mt7981b-cmcc-a10.dts
    │   │                   ├── mt7981b-cmcc-mr3000d-ciq-256m.dts
    │   │                   ├── mt7981b-cmcc-rax3000m-emmc.dts
    │   │                   ├── mt7981b-cmcc-rax3000m-nand.dts
    │   │                   ├── mt7981b-cmcc-xr30-emmc.dts
    │   │                   ├── mt7981b-cmcc-xr30.dts
    │   │                   ├── mt7981b-cmcc-xr30.dtsi
    │   │                   ├── mt7981b-cudy-tr3000-mod.dts
    │   │                   ├── mt7981b-ikuai-q3000.dts
    │   │                   ├── mt7981b-konka-komi-a31.dts
    │   │                   ├── mt7981b-newland-nl-wr8103.dts
    │   │                   ├── mt7981b-nradio-c8-660.dts
    │   │                   ├── mt7981b-nradio-c8-668gl.dts
    │   │                   ├── mt7981b-philips-hy3000.dts
    │   │                   ├── mt7981b-sl-3000-emmc.dts
    │   │                   ├── mt7981b-sl-3000.dts
    │   │                   ├── mt7981b-umi-uax3000e.dts
    │   │                   ├── mt7981b-xiaomi-mi-router-wr30u.dts
    │   │                   └── mt7987a-glinet-gl-mt3600be.dts
    │   ├── diy.sh
    │   └── patches/
    │       ├── 01-360t7.patch
    │       ├── 02-ax6000.patch
    │       ├── 03-nx30.patch
    │       ├── 08-cmcc_rax3000m.patch
    │       ├── 09-jcg_q30-pro.patch
    │       ├── 12-asr3000.patch
    │       ├── 16-komi-a31.patch
    │       ├── 17-lc-hx3001.patch
    │       ├── 19-ct3003.patch
    │       ├── 20-ea0326gmp.patch
    │       ├── 22-netcore-n60-pro.patch
    │       ├── 22-netcore-n60.patch
    │       ├── 23-ax3000t.patch
    │       ├── 25-platform.patch
    │       ├── 26-ruijie-rg-x60-pro.patch
    │       ├── 99-bpi-r4-lite.patch.b
    │       ├── Winbond-NMBM-fix.patch
    │       ├── ags21.patch
    │       ├── ax6s.patch
    │       └── tr3000-mod.patch
    ├── mediatek_mt7622/
    │   ├── .config
    │   └── diy.sh
    ├── mvebu_cortexa9/
    │   ├── .config
    │   └── diy.sh
    ├── qualcommax_ipq50xx/
    │   ├── .config
    │   ├── diy/
    │   │   ├── package/
    │   │   │   └── firmware/
    │   │   │       └── ipq-wifi/
    │   │   │           └── files/
    │   │   │               ├── board-cmcc_pz-l8.ipq5018
    │   │   │               └── board-cmcc_pz-l8.qcn6122
    │   │   └── target/
    │   │       └── linux/
    │   │           └── qualcommax/
    │   │               └── files/
    │   │                   └── arch/
    │   │                       └── arm64/
    │   │                           └── boot/
    │   │                               └── dts/
    │   │                                   └── qcom/
    │   │                                       └── ipq5018-re-cs-03.dts
    │   ├── diy.sh
    │   └── patches/
    │       ├── ath11k-smallbuffers.patch
    │       ├── fix.patch
    │       └── pz-l8-enable-wifi.patch
    ├── qualcommax_ipq60xx/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       └── ax6600.patch
    ├── qualcommax_ipq807x/
    │   ├── .config
    │   ├── diy/
    │   │   └── target/
    │   │       └── linux/
    │   │           └── qualcommax/
    │   │               ├── files/
    │   │               │   └── arch/
    │   │               │       └── arm64/
    │   │               │           └── boot/
    │   │               │               └── dts/
    │   │               │                   └── qcom/
    │   │               │                       ├── ipq8071-ax3600.dts
    │   │               │                       ├── ipq8071-ax6.dts
    │   │               │                       ├── ipq8072-ax9000.dts
    │   │               │                       └── ipq8074-nss.dtsi
    │   │               └── patches-6.12/
    │   │                   └── 0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch
    │   ├── diy.sh
    │   └── patches/
    │       └── 04-stock.patch
    ├── ramips_mt7620/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       ├── mir3.patch
    │       └── tblsection.patch
    ├── ramips_mt7621/
    │   ├── .config
    │   ├── diy/
    │   │   └── target/
    │   │       └── linux/
    │   │           └── ramips/
    │   │               └── dts/
    │   │                   ├── mt7621_ht-jsh_0211.dts
    │   │                   ├── mt7621_zte_e8820s.dts
    │   │                   └── mt7621_zte_e8820v2.dts
    │   ├── diy.sh
    │   └── patches/
    │       ├── 02-cr660x.patch
    │       ├── ht-jsh_0211.patch
    │       ├── jcg_q20-pb-boot.patch
    │       ├── k2p_32m.patch
    │       ├── luban.patch
    │       ├── tblsection.patch
    │       └── zte_e8820s.patch
    ├── ramips_mt76x8/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       └── tblsection.patch
    ├── rockchip_armv8/
    │   ├── .config
    │   ├── README.md
    │   ├── diy.sh
    │   └── patches/
    │       ├── 55-xgp.patch.b
    │       ├── Photonicat_wireless.patch
    │       ├── add_extra_CPU_FLAGS.b
    │       ├── nanopi-zero2.patch
    │       └── r4s-fan.patch
    ├── siflower_sf21/
    │   ├── .config
    │   └── diy.sh
    ├── sunxi_cortexa53/
    │   ├── .config
    │   └── diy.sh
    ├── sunxi_cortexa7/
    │   ├── .config
    │   └── diy.sh
    ├── x86_64/
    │   ├── .config
    │   ├── diy.sh
    │   └── patches/
    │       ├── Intel_gpu.patch
    │       ├── def_set_interfaces_lan_wan.patch
    │       ├── image-commands.patch
    │       └── image.patch
    └── x86_generic/
        ├── .config
        ├── diy.sh
        └── patches/
            ├── image-commands.patch
            └── image.patch
Condensed preview — 198 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (521K chars).
[
  {
    "path": ".github/workflows/Openwrt-AutoBuild.yml",
    "chars": 14304,
    "preview": "#=================================================\n# https://github.com/P3TERX/Actions-OpenWrt\n# Description: Build Open"
  },
  {
    "path": ".github/workflows/repo-dispatcher.yml",
    "chars": 12281,
    "preview": "#=================================================\n# https://github.com/P3TERX/Actions-OpenWrt\n# Description: Build Open"
  },
  {
    "path": "LICENSE",
    "chars": 1063,
    "preview": "MIT License\n\nCopyright (c) 2019 P3TERX\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
  },
  {
    "path": "README.md",
    "chars": 615,
    "preview": "#### 一分钟在线编译定制专属固件: [openwrt.ai](https://openwrt.ai)\n\n### openwrt 软路由固件\n\n## Acknowledgments\n\n- [OpenWrt](https://github."
  },
  {
    "path": "devices/airoha_an7581/.config",
    "chars": 257,
    "preview": "\nCONFIG_TARGET_airoha=y\nCONFIG_TARGET_airoha_an7581=y\n\nCONFIG_TARGET_DEVICE_airoha_an7581_DEVICE_airoha_an7581-evb-emmc="
  },
  {
    "path": "devices/airoha_an7581/diy/target/linux/airoha/dts/an7581-xg-040g-md.dts",
    "chars": 4665,
    "preview": "// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)\n/dts-v1/;\n\n#include <dt-bindings/leds/common.h>\n#include <dt-"
  },
  {
    "path": "devices/airoha_an7581/diy.sh",
    "chars": 12,
    "preview": "#!/bin/bash\n"
  },
  {
    "path": "devices/airoha_an7581/patches/xg-040g-md.patch",
    "chars": 1798,
    "preview": "--- a/target/linux/airoha/image/an7581.mk\n+++ b/target/linux/airoha/image/an7581.mk\n@@ -42,3 +42,25 @@ define Device/air"
  },
  {
    "path": "devices/amlogic_meson/.config",
    "chars": 146,
    "preview": "\nCONFIG_TARGET_amlogic=y\nCONFIG_TARGET_amlogic_meson=y\nCONFIG_TARGET_MULTI_PROFILE=y\nCONFIG_TARGET_ALL_PROFILES=y\n\nCONFI"
  },
  {
    "path": "devices/amlogic_meson/diy.sh",
    "chars": 429,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\ngit_clone_path istoreos-24.10 https://github.com/istoreos/istoreos target/linux/amlogic p"
  },
  {
    "path": "devices/amlogic_meson/patches/fix.patch",
    "chars": 340,
    "preview": "--- a/package/kernel/mac80211/broadcom.mk\n+++ b/package/kernel/mac80211/broadcom.mk\n@@ -432,6 +432,7 @@ define KernelPac"
  },
  {
    "path": "devices/amlogic_meson8b/.config",
    "chars": 177,
    "preview": "\nCONFIG_TARGET_amlogic=y\nCONFIG_TARGET_amlogic_meson8b=y\nCONFIG_TARGET_amlogic_meson8b_DEVICE_thunder-onecloud=y\n\nCONFIG"
  },
  {
    "path": "devices/amlogic_meson8b/diy.sh",
    "chars": 755,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#bash $SHELL_FOLDER/../common/kernel_6.1.sh\n"
  },
  {
    "path": "devices/amlogic_meson8b/patches/BRCMFMAC_SDIO.patch",
    "chars": 340,
    "preview": "--- a/package/kernel/mac80211/broadcom.mk\n+++ b/package/kernel/mac80211/broadcom.mk\n@@ -432,6 +432,7 @@ define KernelPac"
  },
  {
    "path": "devices/amlogic_meson8b/patches/onecloud.patch",
    "chars": 980,
    "preview": "--- a/target/linux/amlogic/image/Makefile\n+++ b/target/linux/amlogic/image/Makefile\n@@ -36,7 +36,7 @@ endef\n ### Devices"
  },
  {
    "path": "devices/armsr_armv8/.config",
    "chars": 333,
    "preview": "CONFIG_TARGET_armsr=y\nCONFIG_TARGET_armsr_armv8=y\nCCONFIG_TARGET_DEVICE_armsr_armv8_DEVICE_generic=y\nCONFIG_TARGET_DEVIC"
  },
  {
    "path": "devices/armsr_armv8/diy.sh",
    "chars": 155,
    "preview": "\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\nrm -rf package/feeds/kiddin9/rtl8188eu package/feeds/kiddin9/rtl8192eu pa"
  },
  {
    "path": "devices/armsr_armv8/patches/rootfs.patch",
    "chars": 1352,
    "preview": "--- a/target/linux/armsr/image/Makefile\n+++ b/target/linux/armsr/image/Makefile\n@@ -81,10 +81,8 @@ define Device/efi-def"
  },
  {
    "path": "devices/ath79_nand/.config",
    "chars": 110,
    "preview": "\nCONFIG_TARGET_ath79=y\nCONFIG_TARGET_ath79_nand=y\n\nCONFIG_TARGET_DEVICE_ath79_nand_DEVICE_meraki_mr18=n\n\n\n\n\n\n\n"
  },
  {
    "path": "devices/ath79_nand/diy.sh",
    "chars": 165,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\nsed -i '/# start dockerd/,/# end dockerd/d' "
  },
  {
    "path": "devices/bcm27xx_bcm2708/.config",
    "chars": 183,
    "preview": "\nCONFIG_TARGET_bcm27xx=y\nCONFIG_TARGET_bcm27xx_bcm2708=y\n\nCONFIG_TARGET_DEVICE_bcm27xx_bcm2708_DEVICE_rpi=y\n\nCONFIG_PACK"
  },
  {
    "path": "devices/bcm27xx_bcm2708/diy.sh",
    "chars": 247,
    "preview": "#!/bin/bash\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#bash $SHELL_FOLDER/../common/kernel_6.1.sh\n\nsed -i 's/DEFAULT"
  },
  {
    "path": "devices/bcm27xx_bcm2709/.config",
    "chars": 173,
    "preview": "\nCONFIG_TARGET_bcm27xx=y\nCONFIG_TARGET_bcm27xx_bcm2709=y\nCONFIG_TARGET_bcm27xx_bcm2709_DEVICE_rpi-2=y\n\nCONFIG_PACKAGE_km"
  },
  {
    "path": "devices/bcm27xx_bcm2709/diy.sh",
    "chars": 314,
    "preview": "#!/bin/bash\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#bash $SHELL_FOLDER/../common/kernel_6.1.sh\n\nsed -i 's/DEFAULT_"
  },
  {
    "path": "devices/bcm27xx_bcm2710/.config",
    "chars": 176,
    "preview": "\nCONFIG_TARGET_bcm27xx=y\nCONFIG_TARGET_bcm27xx_bcm2710=y\nCONFIG_TARGET_bcm27xx_bcm2710_DEVICE_rpi-3=y\n\nCONFIG_PACKAGE_km"
  },
  {
    "path": "devices/bcm27xx_bcm2710/diy.sh",
    "chars": 839,
    "preview": "#!/bin/bash\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#bash $SHELL_FOLDER/../common/kernel_6.1.sh\n\nsed -i 's/DEFAULT"
  },
  {
    "path": "devices/bcm27xx_bcm2710/patches/Zero-2.patch",
    "chars": 379,
    "preview": "--- a/target/linux/bcm27xx/image/Makefile\n+++ b/target/linux/bcm27xx/image/Makefile\n@@ -122,7 +122,7 @@ define Device/rp"
  },
  {
    "path": "devices/bcm27xx_bcm2711/.config",
    "chars": 175,
    "preview": "\nCONFIG_TARGET_bcm27xx=y\nCONFIG_TARGET_bcm27xx_bcm2711=y\nCONFIG_TARGET_bcm27xx_bcm2711_DEVICE_rpi-4=y\n\nCONFIG_PACKAGE_km"
  },
  {
    "path": "devices/bcm27xx_bcm2711/diy.sh",
    "chars": 246,
    "preview": "#!/bin/bash\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#bash $SHELL_FOLDER/../common/kernel_6.1.sh\n\nsed -i 's/DEFAULT"
  },
  {
    "path": "devices/bcm27xx_bcm2712/.config",
    "chars": 205,
    "preview": "\nCONFIG_TARGET_bcm27xx=y\nCONFIG_TARGET_bcm27xx_bcm2712=y\nCONFIG_TARGET_bcm27xx_bcm2712_DEVICE_rpi-5=y\n\nCONFIG_PACKAGE_km"
  },
  {
    "path": "devices/bcm27xx_bcm2712/diy.sh",
    "chars": 244,
    "preview": "#!/bin/bash\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#bash $SHELL_FOLDER/../common/kernel_6.6.sh\n\nsed -i 's/DEFAULT"
  },
  {
    "path": "devices/bcm53xx/.config",
    "chars": 327,
    "preview": "\nCONFIG_TARGET_bcm53xx=y\nCONFIG_TARGET_bcm53xx_generic=y\n\nCONFIG_TARGET_DEVICE_bcm53xx_generic_DEVICE_phicomm_k3=y\nCONFI"
  },
  {
    "path": "devices/bcm53xx/diy.sh",
    "chars": 720,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\nsed -i \"s/^TARGET_DEVICES /# TARGET_DEVICES "
  },
  {
    "path": "devices/common/.config",
    "chars": 2474,
    "preview": "\nCONFIG_GRUB_TIMEOUT=\"0\"\nCONFIG_GRUB_CONSOLE=n\nCONFIG_TARGET_ROOTFS_EXT4FS=n\n\nCONFIG_TARGET_ROOTFS_CPIOGZ=n\nCONFIG_LUCI_"
  },
  {
    "path": "devices/common/diy/feeds/luci/modules/luci-base/htdocs/luci-static/resources/tools/github.js",
    "chars": 3265,
    "preview": "'use strict';\n\nreturn L.Class.extend({\n    desc: function(description, username, project) {\n        var luci_project = '"
  },
  {
    "path": "devices/common/diy/package/base-files/files/etc/banner",
    "chars": 205,
    "preview": "\n                       |\\__/,|   (`\\\n                     _.|o o  |_   ) )\n       -------------(((---(((---------------"
  },
  {
    "path": "devices/common/diy/package/network/config/firewall/files/firewall.exwan",
    "chars": 5881,
    "preview": "#!/bin/sh\n\n# UCI 配置操作函数\nconfig_get() { uci -q get \"$1\"; }\nconfig_set() { uci set \"$1=$2\"; }\nconfig_add_list() { uci add_"
  },
  {
    "path": "devices/common/diy/package/network/config/firewall/patches/fullconenat.patch",
    "chars": 2071,
    "preview": "index 85a3750..9fac9b1 100644\n--- a/defaults.c\n+++ b/defaults.c\n@@ -46,7 +46,9 @@ const struct fw3_option fw3_flag_opts["
  },
  {
    "path": "devices/common/diy/package/network/config/firewall4/files/firewall.exwan",
    "chars": 5881,
    "preview": "#!/bin/sh\n\n# UCI 配置操作函数\nconfig_get() { uci -q get \"$1\"; }\nconfig_set() { uci set \"$1=$2\"; }\nconfig_add_list() { uci add_"
  },
  {
    "path": "devices/common/diy/package/network/config/firewall4/files/firewall.include",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "devices/common/diy/package/network/config/firewall4/patches/001-firewall4-add-support-for-fullcone-nat.patch",
    "chars": 6771,
    "preview": "From aa3b56e289fba7425e649a608c333622ffd9c367 Mon Sep 17 00:00:00 2001\nFrom: Syrone Wong <wong.syrone@gmail.com>\nDate: S"
  },
  {
    "path": "devices/common/diy/package/network/config/firewall4/patches/100-fw4-support-script.patch",
    "chars": 481,
    "preview": "diff --git a/root/sbin/fw4 b/root/sbin/fw4\nindex c3e95c2..8fa6c6e 100755\n--- a/root/sbin/fw4\n+++ b/root/sbin/fw4\n@@ -20,"
  },
  {
    "path": "devices/common/diy/package/network/config/firewall4/patches/200-fw4-hotplug-fork.patch",
    "chars": 370,
    "preview": "diff --git a/root/etc/hotplug.d/iface/20-firewall b/root/etc/hotplug.d/iface/20-firewall\nindex d0f030b..9a8132c 100644\n-"
  },
  {
    "path": "devices/common/diy/package/system/opkg/patches/010-opkg-force-depends.patch",
    "chars": 300,
    "preview": "--- a/src/opkg-cl.c\n+++ b/src/opkg-cl.c\n@@ -255,6 +255,10 @@ static int args_parse(int argc, char *argv[])\n \t\t}\n \t}\n \n+\t"
  },
  {
    "path": "devices/common/diy/package/system/opkg/patches/ignore_error.patch",
    "chars": 168,
    "preview": "--- a/libopkg/pkg.c\n+++ b/libopkg/pkg.c\n@@ -1422,5 +1422,4 @@\n \t\t\t \"package \\\"%s\\\" %s script returned status %d.\\n\",\n \t\t"
  },
  {
    "path": "devices/common/diy/package/system/opkg/patches/pkg_hash.patch",
    "chars": 158,
    "preview": "--- a/libopkg/pkg_hash.c\n+++ b/libopkg/pkg_hash.c\n@@ -263,5 +263,5 @@\n \n \tif (unresolved) {\n-\t\tres = 1;\n+\t\t// res = 1;\n "
  },
  {
    "path": "devices/common/diy/package/system/opkg/patches/zh-cn.patch",
    "chars": 2232,
    "preview": "---  a/libopkg/opkg_download.c\n+++  b/libopkg/opkg_download.c\n@@ -174,9 +174,9 @@\n \t\tif (res) {\n \t\t\topkg_msg(ERROR,\n-\t\t\t"
  },
  {
    "path": "devices/common/diy.sh",
    "chars": 5287,
    "preview": "#!/bin/bash\n#=================================================\nshopt -s extglob\n\nsed -i '$a src-git kiddin9 https://gith"
  },
  {
    "path": "devices/common/patches/LINUX_VERSION.patch",
    "chars": 811,
    "preview": "--- a/Makefile\n+++ b/Makefile\n@@ -33,6 +33,7 @@ ifneq ($(OPENWRT_BUILD),1)\n   include $(TOPDIR)/include/toplevel.mk\n els"
  },
  {
    "path": "devices/common/patches/autoreconf.patch",
    "chars": 265,
    "preview": "--- a/package/libs/libnftnl/Makefile\n+++ b/package/libs/libnftnl/Makefile\n@@ -19,6 +19,7 @@\n PKG_MAINTAINER:=Steven Bart"
  },
  {
    "path": "devices/common/patches/base-files.patch",
    "chars": 2877,
    "preview": "--- a/package/base-files/files/lib/functions.sh\n+++ b/package/base-files/files/lib/functions.sh\n@@ -395,10 +395,13 @@ de"
  },
  {
    "path": "devices/common/patches/china_mirrors.patch.b",
    "chars": 3865,
    "preview": "--- a/scripts/download.pl\n+++ b/scripts/download.pl\n@@ -201,6 +201,10 @@ sub cleanup\n \t\tpush @mirrors, \"https://mirror.l"
  },
  {
    "path": "devices/common/patches/cmake.patch",
    "chars": 353,
    "preview": "--- a/include/cmake.mk\n+++ b/include/cmake.mk\n@@ -127,6 +127,7 @@ define Build/Configure/Default\n \t\t\t-DCMAKE_FIND_PACKAG"
  },
  {
    "path": "devices/common/patches/compressed-memory.patch.b",
    "chars": 3525,
    "preview": "--- a/package/kernel/linux/modules/crypto.mk\n+++ b/package/kernel/linux/modules/crypto.mk\n@@ -809,3 +809,18 @@ endef\n \n "
  },
  {
    "path": "devices/common/patches/crontab.patch",
    "chars": 15457,
    "preview": "From 388238b9baf8375e5474167c987a4a8a3358b559 Mon Sep 17 00:00:00 2001\nFrom: Paul Donald <newtwen+github@gmail.com>\nDate"
  },
  {
    "path": "devices/common/patches/curl.patch",
    "chars": 266,
    "preview": "--- a/package/feeds/packages/curl/Config.in\n+++ b/package/feeds/packages/curl/Config.in\n@@ -4,7 +4,7 @@ comment \"SSL sup"
  },
  {
    "path": "devices/common/patches/default-packages.patch",
    "chars": 292,
    "preview": "--- a/include/target.mk\n+++ b/include/target.mk\n@@ -50,10 +50,8 @@ DEFAULT_PACKAGES.nas:=\\\n # @brief Default packages fo"
  },
  {
    "path": "devices/common/patches/disable-seccomp-ujail.patch",
    "chars": 769,
    "preview": "--- a/config/Config-kernel.in\n+++ b/config/Config-kernel.in\n@@ -1185,13 +1185,13 @@ config KERNEL_POSIX_MQUEUE\n \n config"
  },
  {
    "path": "devices/common/patches/dnsmasq.patch",
    "chars": 4459,
    "preview": "--- a/package/network/services/dnsmasq/Makefile\n+++ b/package/network/services/dnsmasq/Makefile\n@@ -22,6 +22,8 @@ PKG_CP"
  },
  {
    "path": "devices/common/patches/feeds.patch",
    "chars": 397,
    "preview": "--- a/include/feeds.mk\n+++ b/include/feeds.mk\n@@ -6,7 +6,7 @@\n -include $(TMP_DIR)/.packageauxvars\n \n FEEDS_INSTALLED:=$"
  },
  {
    "path": "devices/common/patches/firewall.patch",
    "chars": 4661,
    "preview": "--- a/package/network/config/firewall4/Makefile\n+++ b/package/network/config/firewall4/Makefile\n@@ -25,7 +25,8 @@ define"
  },
  {
    "path": "devices/common/patches/getcwd-fix.patch",
    "chars": 336,
    "preview": "--- a/include/host-build.mk\n+++ b/include/host-build.mk\n@@ -61,7 +61,8 @@ HOST_CONFIGURE_VARS = \\\n \tCPPFLAGS=\"$(HOST_CPP"
  },
  {
    "path": "devices/common/patches/imagebuilder.patch",
    "chars": 8116,
    "preview": "--- a/include/image.mk\n+++ b/include/image.mk\n@@ -717,7 +717,7 @@ define Device/Build/kernel\n endef\n \n define Device/Bui"
  },
  {
    "path": "devices/common/patches/kernel-defaults.patch",
    "chars": 433,
    "preview": "--- a/include/kernel-defaults.mk\n+++ b/include/kernel-defaults.mk\n@@ -127,6 +127,7 @@ endef\n \n define Kernel/CompileModu"
  },
  {
    "path": "devices/common/patches/luci-base.patch",
    "chars": 9023,
    "preview": "--- a/package/feeds/luci/luci-base/root/usr/share/rpcd/ucode/luci\n+++ b/package/feeds/luci/luci-base/root/usr/share/rpcd"
  },
  {
    "path": "devices/common/patches/luci-dhcp.patch",
    "chars": 909,
    "preview": "--- a/package/feeds/luci/luci-mod-network/htdocs/luci-static/resources/view/network/dns.js\n+++ b/package/feeds/luci/luci"
  },
  {
    "path": "devices/common/patches/luci-mod-system.patch",
    "chars": 1983,
    "preview": "--- a/package/feeds/luci/luci-mod-system/htdocs/luci-static/resources/view/system/flash.js\n+++ b/package/feeds/luci/luci"
  },
  {
    "path": "devices/common/patches/luci_mk.patch",
    "chars": 2071,
    "preview": "--- a/feeds/luci/luci.mk\n+++ b/feeds/luci/luci.mk\n@@ -84,7 +84,7 @@ define findrev\n       set -- $$(git log -1 --format="
  },
  {
    "path": "devices/common/patches/netfilter.patch.b",
    "chars": 5387,
    "preview": "--- a/package/kernel/linux/modules/netfilter.mk\n+++ b/package/kernel/linux/modules/netfilter.mk\n@@ -458,15 +458,100 @@\n "
  },
  {
    "path": "devices/common/patches/netsupport.patch",
    "chars": 448,
    "preview": "--- a/package/kernel/linux/modules/netsupport.mk\n+++ b/package/kernel/linux/modules/netsupport.mk\n@@ -64,7 +64,7 @@ defi"
  },
  {
    "path": "devices/common/patches/nftables.patch",
    "chars": 276,
    "preview": "--- a/package/network/utils/nftables/Makefile\n+++ b/package/network/utils/nftables/Makefile\n@@ -48,7 +48,6 @@ define Pac"
  },
  {
    "path": "devices/common/patches/nginx-fancyindex.patch.bak",
    "chars": 2165,
    "preview": "--- package/feeds/packages/nginx/Makefile\n+++ package/feeds/packages/nginx/Makefile\n@@ -28,6 +28,7 @@ PKG_CONFIG_DEPENDS"
  },
  {
    "path": "devices/common/patches/nonshared.patch",
    "chars": 251,
    "preview": "--- a/package/firmware/linux-firmware/Makefile\n+++ b/package/firmware/linux-firmware/Makefile\n@@ -19,6 +19,8 @@ PKG_MAIN"
  },
  {
    "path": "devices/common/patches/opkginstall.patch",
    "chars": 8284,
    "preview": "--- a/package/feeds/luci/luci-app-package-manager/htdocs/luci-static/resources/view/package-manager.js\n+++ b/package/fee"
  },
  {
    "path": "devices/common/patches/package.patch",
    "chars": 716,
    "preview": "--- a/include/package.mk\n+++ b/include/package.mk\n@@ -354,3 +354,11 @@ dist:\n \n distcheck:\n \t$(Build/DistCheck)\n+\n+ifnde"
  },
  {
    "path": "devices/common/patches/rootfs.patch",
    "chars": 369,
    "preview": "--- a/include/rootfs.mk\n+++ b/include/rootfs.mk\n@@ -88,7 +88,6 @@ define prepare_rootfs\n \t\t\tret=$$?; \\\n \t\t\tif [ $$ret -n"
  },
  {
    "path": "devices/common/patches/status.patch",
    "chars": 5413,
    "preview": "--- a/package/feeds/luci/luci-mod-status/htdocs/luci-static/resources/view/status/include/20_memory.js\n+++ b/package/fee"
  },
  {
    "path": "devices/common/patches/use_json_object_new_int64.patch.b",
    "chars": 394,
    "preview": "--- a/package/feeds/luci/luci-lib-jsonc/src/jsonc.c\n+++ b/package/feeds/luci/luci-lib-jsonc/src/jsonc.c\n@@ -366,9 +366,7"
  },
  {
    "path": "devices/common/patches/wifi-scripts.patch",
    "chars": 1174,
    "preview": "--- a/package/network/config/wifi-scripts/files/lib/netifd/hostapd.sh\n+++ b/package/network/config/wifi-scripts/files/li"
  },
  {
    "path": "devices/common/patches/wireless.patch",
    "chars": 659,
    "preview": "--- a/package/feeds/luci/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js\n+++ b/package/feeds/luci"
  },
  {
    "path": "devices/common/settings.ini",
    "chars": 304,
    "preview": "REPO_URL=\"https://github.com/openwrt/openwrt\"\nREPO_BRANCH=\"\"\nCONFIG_FILE=\".config\"\nDIY_SH=\"diy.sh\"\nFREE_UP_DISK=\"false\"\n"
  },
  {
    "path": "devices/ipq40xx_generic/.config",
    "chars": 515,
    "preview": "\nCONFIG_TARGET_ipq40xx=y\nCONFIG_TARGET_ipq40xx_generic=y\n\nCONFIG_TARGET_DEVICE_ipq40xx_generic_DEVICE_dlink_dap-2610=n\nC"
  },
  {
    "path": "devices/ipq40xx_generic/diy.sh",
    "chars": 383,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#sh -c \"curl -sfL https://patch-diff.githubu"
  },
  {
    "path": "devices/ipq40xx_generic/patches/ap4220.patch",
    "chars": 12826,
    "preview": "From 901be81149fd7c97fb5c7fdabe6e05e470fada00 Mon Sep 17 00:00:00 2001\nFrom: Willem Lee <1980490718@qq.com>\nDate: Fri, 1"
  },
  {
    "path": "devices/ipq40xx_generic/patches/cm520.patch",
    "chars": 1769,
    "preview": "--- a/target/linux/ipq40xx/files-6.12/arch/arm/boot/dts/qcom/qcom-ipq4019-cm520-79f.dts\r\n+++ b/target/linux/ipq40xx/file"
  },
  {
    "path": "devices/ipq40xx_generic/patches/target.patch",
    "chars": 612,
    "preview": "--- a/target/linux/ipq40xx/image/generic.mk\n+++ b/target/linux/ipq40xx/image/generic.mk\n@@ -694,7 +694,7 @@ TARGET_DEVIC"
  },
  {
    "path": "devices/ipq806x_generic/.config",
    "chars": 313,
    "preview": "\nCONFIG_TARGET_ipq806x=y\nCONFIG_TARGET_ipq806x_generic=y\n\nCONFIG_TARGET_DEVICE_ipq806x_generic_DEVICE_tplink_ad7200=n\nCO"
  },
  {
    "path": "devices/ipq806x_generic/diy.sh",
    "chars": 80,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n\n\n\n\n"
  },
  {
    "path": "devices/ipq806x_generic/patches/xiaomi_r3d.patch",
    "chars": 27356,
    "preview": "From c433730d889d0dfb31bdcf4f102ca47939606c46 Mon Sep 17 00:00:00 2001\nFrom: remittor <remittor@gmail.com>\nDate: Fri, 11"
  },
  {
    "path": "devices/mediatek_filogic/.config",
    "chars": 390,
    "preview": "\nCONFIG_TARGET_mediatek=y\nCONFIG_TARGET_mediatek_filogic=y\n\nCONFIG_TARGET_DEVICE_mediatek_filogic_DEVICE_cudy_re3000-v1="
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-aigo-ags21.dts",
    "chars": 4273,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n/*\n * Author:dailook\n */\n\n/dts-v1/;\n#include <dt-bindings/gpio/gpio."
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-bt-r320.dts",
    "chars": 3604,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n#include <dt-bindings/gpio/gpio.h>\n#include <dt-bindings/"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-cmcc-a10.dts",
    "chars": 364,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n#include \"mt7981b-cmcc-a10.dtsi\"\n\n/ {\n\tmodel = \"CMCC A10\""
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-cmcc-mr3000d-ciq-256m.dts",
    "chars": 4415,
    "preview": "/dts-v1/;\n\n#include \"mt7981b.dtsi\"\n\n/ {\n\tmodel = \"CMCC MR3000D-CIq (256M)\";\n\tcompatible = \"cmcc,mr3000d-ciq-256m\", \"medi"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-emmc.dts",
    "chars": 1438,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n#include \"mt7981b-cmcc-rax3000m.dts\"\n\n/ {\n\tmodel = \"CMCC "
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-nand.dts",
    "chars": 2050,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n#include \"mt7981b-cmcc-rax3000m.dts\"\n\n/ {\n\tmodel = \"CMCC "
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-cmcc-xr30-emmc.dts",
    "chars": 1447,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n#include \"mt7981b-cmcc-xr30.dtsi\"\n\n/ {\n\tmodel = \"CMCC XR3"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-cmcc-xr30.dts",
    "chars": 2019,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n#include \"mt7981b-cmcc-xr30.dtsi\"\n\n/ {\n\tmodel = \"CMCC XR3"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-cmcc-xr30.dtsi",
    "chars": 2095,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n/*\n * Copyright (C) 2023 Tianling Shen <cnsztl@immortalwrt.org>\n */\n"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-cudy-tr3000-mod.dts",
    "chars": 320,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n#include \"mt7981b-cudy-tr3000-v1.dts\"\n\n/ {\n\tmodel = \"Cudy"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-ikuai-q3000.dts",
    "chars": 5063,
    "preview": "/dts-v1/;\n#include \"mt7981b.dtsi\"\n/ {\n\tcompatible = \"ikuai,q3000\", \"mediatek,mt7981-spim-snand-rfb\";\n\tmodel = \"q3000\";\n\n"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-konka-komi-a31.dts",
    "chars": 4696,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n#include <dt-bindings/gpio/gpio.h>\n#include <dt-bindings/"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-newland-nl-wr8103.dts",
    "chars": 4415,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n#include <dt-bindings/gpio/gpio.h>\n#include <dt-bindings/"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-nradio-c8-660.dts",
    "chars": 4619,
    "preview": "/dts-v1/;\n\n#include \"mt7981b.dtsi\"\n\n/ {\n\tmodel = \"NRadio C8-660\";\n\tcompatible = \"nradio,c8-660\", \"mediatek,mt7981\";\n\n\tal"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-nradio-c8-668gl.dts",
    "chars": 4476,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n\n#include \"mt7981b.dtsi\"\n\n/ {\n\tmodel = \"NRadio C8-668GL\";"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-philips-hy3000.dts",
    "chars": 3477,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n/*\n * Copyright (C) 2023 Tianling Shen <cnsztl@immortalwrt.org>\n */\n"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-sl-3000-emmc.dts",
    "chars": 3801,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n#include <dt-bindings/gpio/gpio.h>\n#include <dt-bindings/"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-sl-3000.dts",
    "chars": 5564,
    "preview": "/dts-v1/;\n\n#include \"mt7981b.dtsi\"\n\n/ {\n\tmodel = \"SL-3000\";\n\tcompatible = \"sl,3000\", \"mediatek,mt7981\";\n\n\taliases {\n\t\tle"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-umi-uax3000e.dts",
    "chars": 3524,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n#include <dt-bindings/gpio/gpio.h>\n#include <dt-bindings/"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-wr30u.dts",
    "chars": 405,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n/dts-v1/;\n#include \"mt7981b-xiaomi-mi-router-wr30u.dtsi\"\n\n/ {\n\tmode"
  },
  {
    "path": "devices/mediatek_filogic/diy/target/linux/mediatek/dts/mt7987a-glinet-gl-mt3600be.dts",
    "chars": 5634,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n/*\n * Copyright (C) 2026 Tianling Shen <cnsztl@immortalwrt.org>\n */\n"
  },
  {
    "path": "devices/mediatek_filogic/diy.sh",
    "chars": 382,
    "preview": "#!/bin/bash\n\nshopt -s extglob\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#bash $SHELL_FOLDER/../common/kernel_6.6.sh\n\n"
  },
  {
    "path": "devices/mediatek_filogic/patches/01-360t7.patch",
    "chars": 26185,
    "preview": "--- a/target/linux/mediatek/dts/mt7981b-qihoo-360t7.dts\n+++ b/target/linux/mediatek/dts/mt7981b-qihoo-360t7.dts\n@@ -105,"
  },
  {
    "path": "devices/mediatek_filogic/patches/02-ax6000.patch",
    "chars": 1279,
    "preview": "new file mode 100644\nindex 0000000000000..759baae3aeb18\n--- /dev/null\n+++ b/target/linux/mediatek/dts/mt7986a-xiaomi-red"
  },
  {
    "path": "devices/mediatek_filogic/patches/03-nx30.patch",
    "chars": 379,
    "preview": "--- a/target/linux/mediatek/dts/mt7981b-h3c-magic-nx30-pro.dts\n+++ b/target/linux/mediatek/dts/mt7981b-h3c-magic-nx30-pr"
  },
  {
    "path": "devices/mediatek_filogic/patches/08-cmcc_rax3000m.patch",
    "chars": 4952,
    "preview": "--- a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network\n+++ b/target/linux/mediatek/filogic/base-files/etc"
  },
  {
    "path": "devices/mediatek_filogic/patches/09-jcg_q30-pro.patch",
    "chars": 647,
    "preview": "--- a/target/linux/mediatek/dts/mt7981b-jcg-q30-pro.dts\n+++ b/target/linux/mediatek/dts/mt7981b-jcg-q30-pro.dts\n@@ -103,"
  },
  {
    "path": "devices/mediatek_filogic/patches/12-asr3000.patch",
    "chars": 681,
    "preview": "--- a/target/linux/mediatek/dts/mt7981b-abt-asr3000.dts\n+++ b/target/linux/mediatek/dts/mt7981b-abt-asr3000.dts\n@@ -155,"
  },
  {
    "path": "devices/mediatek_filogic/patches/16-komi-a31.patch",
    "chars": 2354,
    "preview": "--- a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac\n+++ b/target/linux/mediatek/filog"
  },
  {
    "path": "devices/mediatek_filogic/patches/17-lc-hx3001.patch",
    "chars": 6706,
    "preview": "--- /dev/null\n+++ b/target/linux/mediatek/dts/mt7981b-imou-lc-hx3001.dts\n@@ -0,0 +1,239 @@\n+// SPDX-License-Identifier: "
  },
  {
    "path": "devices/mediatek_filogic/patches/19-ct3003.patch",
    "chars": 463,
    "preview": "--- a/target/linux/mediatek/dts/mt7981b-cetron-ct3003.dts\n+++ b/target/linux/mediatek/dts/mt7981b-cetron-ct3003.dts\n@@ -"
  },
  {
    "path": "devices/mediatek_filogic/patches/20-ea0326gmp.patch",
    "chars": 647,
    "preview": "--- a/target/linux/mediatek/dts/mt7981b-nokia-ea0326gmp.dts\n+++ b/target/linux/mediatek/dts/mt7981b-nokia-ea0326gmp.dts\n"
  },
  {
    "path": "devices/mediatek_filogic/patches/22-netcore-n60-pro.patch",
    "chars": 778,
    "preview": "--- a/target/linux/mediatek/dts/mt7986a-netcore-n60-pro.dts\n+++ b/target/linux/mediatek/dts/mt7986a-netcore-n60-pro.dts\n"
  },
  {
    "path": "devices/mediatek_filogic/patches/22-netcore-n60.patch",
    "chars": 510,
    "preview": "--- a/target/linux/mediatek/dts/mt7986a-netcore-n60.dts\n+++ b/target/linux/mediatek/dts/mt7986a-netcore-n60.dts\n@@ -175,"
  },
  {
    "path": "devices/mediatek_filogic/patches/23-ax3000t.patch",
    "chars": 588,
    "preview": "--- a/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-ax3000t.dts\n+++ b/target/linux/mediatek/dts/mt7981b-xiaomi-mi-r"
  },
  {
    "path": "devices/mediatek_filogic/patches/25-platform.patch",
    "chars": 3755,
    "preview": "--- a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh\n+++ b/target/linux/mediatek/filogic/base-files/li"
  },
  {
    "path": "devices/mediatek_filogic/patches/26-ruijie-rg-x60-pro.patch",
    "chars": 415,
    "preview": "--- a/target/linux/mediatek/dts/mt7986a-ruijie-rg-x60-pro.dts\n+++ b/target/linux/mediatek/dts/mt7986a-ruijie-rg-x60-pro."
  },
  {
    "path": "devices/mediatek_filogic/patches/99-bpi-r4-lite.patch.b",
    "chars": 6263,
    "preview": "--- a/target/linux/mediatek/base-files/etc/uci-defaults/99_fwenv-store-ethaddr.sh\n+++ b/target/linux/mediatek/base-files"
  },
  {
    "path": "devices/mediatek_filogic/patches/Winbond-NMBM-fix.patch",
    "chars": 807,
    "preview": "--- a/target/linux/generic/files/drivers/mtd/nand/mtk_bmt_nmbm.c\n+++ b/target/linux/generic/files/drivers/mtd/nand/mtk_b"
  },
  {
    "path": "devices/mediatek_filogic/patches/ags21.patch",
    "chars": 1262,
    "preview": "--- a/package/boot/uboot-tools/uboot-envtools/files/mediatek_filogic\n+++ b/package/boot/uboot-tools/uboot-envtools/files"
  },
  {
    "path": "devices/mediatek_filogic/patches/ax6s.patch",
    "chars": 2283,
    "preview": "--- a/target/linux/mediatek/image/mt7622.mk\n+++ b/target/linux/mediatek/image/mt7622.mk\n@@ -438,18 +438,10 @@ define Dev"
  },
  {
    "path": "devices/mediatek_filogic/patches/tr3000-mod.patch",
    "chars": 368,
    "preview": "--- a/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface\n+++ b/target/linux/mediatek/base-files/lib/prein"
  },
  {
    "path": "devices/mediatek_mt7622/.config",
    "chars": 272,
    "preview": "\nCONFIG_TARGET_mediatek=y\nCONFIG_TARGET_mediatek_mt7622=y\n\nCONFIG_TARGET_DEVICE_mediatek_mt7622_DEVICE_dlink_eagle-pro-a"
  },
  {
    "path": "devices/mediatek_mt7622/diy.sh",
    "chars": 323,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n\n#curl -sfL https://raw.githubusercontent.co"
  },
  {
    "path": "devices/mvebu_cortexa9/.config",
    "chars": 339,
    "preview": "\nCONFIG_TARGET_mvebu=y\nCONFIG_TARGET_mvebu_cortexa9=y\n\nCONFIG_TARGET_DEVICE_mvebu_cortexa9_DEVICE_plathome_openblocks-ax"
  },
  {
    "path": "devices/mvebu_cortexa9/diy.sh",
    "chars": 77,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n\n"
  },
  {
    "path": "devices/qualcommax_ipq50xx/.config",
    "chars": 65,
    "preview": "\nCONFIG_TARGET_qualcommax=y\nCONFIG_TARGET_qualcommax_ipq50xx=y\n\n\n"
  },
  {
    "path": "devices/qualcommax_ipq50xx/diy/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-re-cs-03.dts",
    "chars": 7921,
    "preview": "// SPDX-License-Identifier: GPL-2.0-only\n\n/dts-v1/;\n\n#include \"ipq5018.dtsi\"\n#include \"ipq5018-ess.dtsi\"\n#include \"ipq50"
  },
  {
    "path": "devices/qualcommax_ipq50xx/diy.sh",
    "chars": 76,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n"
  },
  {
    "path": "devices/qualcommax_ipq50xx/patches/ath11k-smallbuffers.patch",
    "chars": 6124,
    "preview": "From 2858400d263dae0d476f88a7cb7c4540eeb7783f Mon Sep 17 00:00:00 2001\nFrom: Ziyang Huang <hzyitc@outlook.com>\nDate: Fri"
  },
  {
    "path": "devices/qualcommax_ipq50xx/patches/fix.patch",
    "chars": 1982,
    "preview": "diff --git a/target/linux/qualcommax/patches-6.12/999-fix-netdev-cacheline-size.patch b/target/linux/qualcommax/patches-"
  },
  {
    "path": "devices/qualcommax_ipq50xx/patches/pz-l8-enable-wifi.patch",
    "chars": 4884,
    "preview": "--- a/package/firmware/ipq-wifi/Makefile\n+++ b/package/firmware/ipq-wifi/Makefile\n@@ -14,6 +14,8 @@ PKG_FLAGS:=nonshared"
  },
  {
    "path": "devices/qualcommax_ipq60xx/.config",
    "chars": 65,
    "preview": "\nCONFIG_TARGET_qualcommax=y\nCONFIG_TARGET_qualcommax_ipq60xx=y\n\n\n"
  },
  {
    "path": "devices/qualcommax_ipq60xx/diy.sh",
    "chars": 1202,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\nrm -rf package/boot package/firmware/ipq-wif"
  },
  {
    "path": "devices/qualcommax_ipq60xx/patches/ax6600.patch",
    "chars": 1048,
    "preview": "--- a/target/linux/qualcommax/image/ipq60xx.mk\n+++ b/target/linux/qualcommax/image/ipq60xx.mk\n@@ -360,7 +360,7 @@ define"
  },
  {
    "path": "devices/qualcommax_ipq807x/.config",
    "chars": 263,
    "preview": "CONFIG_TARGET_qualcommax=y\nCONFIG_TARGET_qualcommax_ipq807x=y\n\nCONFIG_TARGET_DEVICE_qualcommax_ipq807x_DEVICE_asus_rt-ax"
  },
  {
    "path": "devices/qualcommax_ipq807x/diy/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dts",
    "chars": 2072,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n/* Copyright (c) 2021, Robert Marko <robimarko@gmail.com> */\n\n/dts-v"
  },
  {
    "path": "devices/qualcommax_ipq807x/diy/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax6.dts",
    "chars": 1551,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n/* Copyright (c) 2021, Zhijun You <hujy652@gmail.com> */\n\n/dts-v1/;\n"
  },
  {
    "path": "devices/qualcommax_ipq807x/diy/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts",
    "chars": 9865,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n/* Copyright (c) 2021, Robert Marko <robimarko@gmail.com> */\n\n/dts-v"
  },
  {
    "path": "devices/qualcommax_ipq807x/diy/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nss.dtsi",
    "chars": 7486,
    "preview": "// SPDX-License-Identifier: GPL-2.0-only\n\n/ {\n\tnss_dummy_reg: nss-regulator {\n\t\tcompatible = \"regulator-fixed\";\n\t\tregula"
  },
  {
    "path": "devices/qualcommax_ipq807x/diy/target/linux/qualcommax/patches-6.12/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch",
    "chars": 1573,
    "preview": "From ad2d07f71739351eeea1d8a120c0918e2c4b265f Mon Sep 17 00:00:00 2001\nFrom: Robert Marko <robimarko@gmail.com>\nDate: We"
  },
  {
    "path": "devices/qualcommax_ipq807x/diy.sh",
    "chars": 28,
    "preview": "#!/bin/bash\nshopt -s extglob"
  },
  {
    "path": "devices/qualcommax_ipq807x/patches/04-stock.patch",
    "chars": 2237,
    "preview": "--- a/target/linux/qualcommax/ipq807x/base-files/etc/init.d/bootcount\n+++ b/target/linux/qualcommax/ipq807x/base-files/e"
  },
  {
    "path": "devices/ramips_mt7620/.config",
    "chars": 4882,
    "preview": "\nCONFIG_TARGET_ramips=y\nCONFIG_TARGET_ramips_mt7620=y\n\nCONFIG_TARGET_DEVICE_ramips_mt7620_DEVICE_aigale_ai-br100=n\nCONFI"
  },
  {
    "path": "devices/ramips_mt7620/diy.sh",
    "chars": 232,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nsh -c \"curl -sfL https://github.com/openwrt/openwrt/commit/2e6d19ee32399e37c7545aefc57d41"
  },
  {
    "path": "devices/ramips_mt7620/patches/mir3.patch",
    "chars": 8224,
    "preview": "From aa2cc7b9d5124216f0ea377f9ffe28e494da20c6 Mon Sep 17 00:00:00 2001\nFrom: Chen Minqiang <ptpt52@gmail.com>\nDate: Sat,"
  },
  {
    "path": "devices/ramips_mt7620/patches/tblsection.patch",
    "chars": 506,
    "preview": "--- a/package/feeds/luci/luci-compat/luasrc/view/cbi/tblsection.htm\n+++ b/package/feeds/luci/luci-compat/luasrc/view/cbi"
  },
  {
    "path": "devices/ramips_mt7621/.config",
    "chars": 1714,
    "preview": "\nCONFIG_TARGET_ramips=y\nCONFIG_TARGET_ramips_mt7621=y\n\nCONFIG_TARGET_DEVICE_ramips_mt7621_DEVICE_dna_valokuitu-plus-ex40"
  },
  {
    "path": "devices/ramips_mt7621/diy/target/linux/ramips/dts/mt7621_ht-jsh_0211.dts",
    "chars": 1353,
    "preview": "// SPDX-License-Identifier: GPL-2.0-only\n\n#include \"mt7621.dtsi\"\n\n#include <dt-bindings/gpio/gpio.h>\n#include <dt-bindin"
  },
  {
    "path": "devices/ramips_mt7621/diy/target/linux/ramips/dts/mt7621_zte_e8820s.dts",
    "chars": 2604,
    "preview": "// SPDX-License-Identifier: GPL-2.0-or-later OR MIT\n\n#include \"mt7621.dtsi\"\n\n#include <dt-bindings/gpio/gpio.h>\n#include"
  },
  {
    "path": "devices/ramips_mt7621/diy/target/linux/ramips/dts/mt7621_zte_e8820v2.dts",
    "chars": 3125,
    "preview": "/dts-v1/;\n\n#include \"mt7621.dtsi\"\n\n#include <dt-bindings/gpio/gpio.h>\n#include <dt-bindings/input/input.h>\n\n/ {\n    comp"
  },
  {
    "path": "devices/ramips_mt7621/diy.sh",
    "chars": 318,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n\nsed -i \"s/DEVICE_MODEL := HC5962$/DEVICE_MO"
  },
  {
    "path": "devices/ramips_mt7621/patches/02-cr660x.patch",
    "chars": 5314,
    "preview": "--- a/target/linux/ramips/image/mt7621.mk\n+++ b/target/linux/ramips/image/mt7621.mk\n@@ -157,6 +157,55 @@ define Device/n"
  },
  {
    "path": "devices/ramips_mt7621/patches/ht-jsh_0211.patch",
    "chars": 1038,
    "preview": "diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk\nindex 1908f60bc37bc..bc6a3ac05ae3"
  },
  {
    "path": "devices/ramips_mt7621/patches/jcg_q20-pb-boot.patch",
    "chars": 1810,
    "preview": "--- a/target/linux/ramips/dts/mt7621_jcg_q20.dts\n+++ b/target/linux/ramips/dts/mt7621_jcg_q20.dts\n@@ -50,22 +50,6 @@\n \t\t"
  },
  {
    "path": "devices/ramips_mt7621/patches/k2p_32m.patch",
    "chars": 2349,
    "preview": "diff --git a/target/linux/ramips/dts/mt7621_phicomm_k2p.dts b/target/linux/ramips/dts/mt7621_phicomm_k2p.dtsi\nsimilarity"
  },
  {
    "path": "devices/ramips_mt7621/patches/luban.patch",
    "chars": 3009,
    "preview": "diff --git a/target/linux/ramips/dts/mt7621_jdcloud_luban.dts b/target/linux/ramips/dts/mt7621_jdcloud_luban.dts\nnew fil"
  },
  {
    "path": "devices/ramips_mt7621/patches/tblsection.patch",
    "chars": 506,
    "preview": "--- a/package/feeds/luci/luci-compat/luasrc/view/cbi/tblsection.htm\n+++ b/package/feeds/luci/luci-compat/luasrc/view/cbi"
  },
  {
    "path": "devices/ramips_mt7621/patches/zte_e8820s.patch",
    "chars": 915,
    "preview": "diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds b/target/linux/ramips/mt7621/base-files/etc/board"
  },
  {
    "path": "devices/ramips_mt76x8/.config",
    "chars": 4104,
    "preview": "\nCONFIG_TARGET_ramips=y\nCONFIG_TARGET_ramips_mt76x8=y\n\nCONFIG_TARGET_DEVICE_ramips_mt76x8_DEVICE_7links_wlr-1230=n\nCONFI"
  },
  {
    "path": "devices/ramips_mt76x8/diy.sh",
    "chars": 933,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\nsh -c \"curl -sfL https://github.com/openwrt/"
  },
  {
    "path": "devices/ramips_mt76x8/patches/tblsection.patch",
    "chars": 506,
    "preview": "--- a/package/feeds/luci/luci-compat/luasrc/view/cbi/tblsection.htm\n+++ b/package/feeds/luci/luci-compat/luasrc/view/cbi"
  },
  {
    "path": "devices/rockchip_armv8/.config",
    "chars": 154,
    "preview": "\nCONFIG_TARGET_rockchip=y\nCONFIG_TARGET_rockchip_armv8=y\n\nCONFIG_TARGET_DEVICE_rockchip_armv8_DEVICE_radxa_rock-pi-4a=n\n"
  },
  {
    "path": "devices/rockchip_armv8/README.md",
    "chars": 53,
    "preview": "Kernel等部分源码来源 https://github.com/coolsnowwolf/lede 感谢"
  },
  {
    "path": "devices/rockchip_armv8/diy.sh",
    "chars": 1279,
    "preview": "#!/bin/bash\n\nshopt -s extglob\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#bash $SHELL_FOLDER/../common/kernel_6.6.sh\n\n"
  },
  {
    "path": "devices/rockchip_armv8/patches/55-xgp.patch.b",
    "chars": 2154,
    "preview": "--- a/target/linux/rockchip/image/Makefile\n+++ b/target/linux/rockchip/image/Makefile\n@@ -20,6 +20,23 @@ define Build/bo"
  },
  {
    "path": "devices/rockchip_armv8/patches/Photonicat_wireless.patch",
    "chars": 5050,
    "preview": "diff --git a/package/firmware/linux-firmware/qca_ath10k.mk b/package/firmware/linux-firmware/qca_ath10k.mk\nindex b3bfe8a"
  },
  {
    "path": "devices/rockchip_armv8/patches/add_extra_CPU_FLAGS.b",
    "chars": 913,
    "preview": "--- a/include/target.mk\n+++ b/include/target.mk\n@@ -259,9 +259,18 @@ ifeq ($(DUMP),1)\n     CPU_CFLAGS_arc700 = -mcpu=arc"
  },
  {
    "path": "devices/rockchip_armv8/patches/nanopi-zero2.patch",
    "chars": 2053,
    "preview": "--- a/target/linux/rockchip/image/armv8.mk\n+++ b/target/linux/rockchip/image/armv8.mk\n@@ -264,6 +264,17 @@ define Device"
  },
  {
    "path": "devices/rockchip_armv8/patches/r4s-fan.patch",
    "chars": 1963,
    "preview": "diff --git a/target/linux/rockchip/patches-6.12/304-r4s-pwm-fan.patch b/target/linux/rockchip/patches-6.12/304-r4s-pwm-f"
  },
  {
    "path": "devices/siflower_sf21/.config",
    "chars": 56,
    "preview": "CONFIG_TARGET_siflower=y\nCONFIG_TARGET_siflower_sf21=y\n\n"
  },
  {
    "path": "devices/siflower_sf21/diy.sh",
    "chars": 28,
    "preview": "#!/bin/bash\nshopt -s extglob"
  },
  {
    "path": "devices/sunxi_cortexa53/.config",
    "chars": 623,
    "preview": "\nCONFIG_TARGET_sunxi=y\nCONFIG_TARGET_sunxi_cortexa53=y\n\nCONFIG_TARGET_DEVICE_sunxi_cortexa53_DEVICE_friendlyarm_nanopi-n"
  },
  {
    "path": "devices/sunxi_cortexa53/diy.sh",
    "chars": 279,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#bash $SHELL_FOLDER/../common/kernel_6.6.sh\n"
  },
  {
    "path": "devices/sunxi_cortexa7/.config",
    "chars": 1267,
    "preview": "\nCONFIG_TARGET_sunxi=y\nCONFIG_TARGET_sunxi_cortexa7=y\n\nCONFIG_TARGET_DEVICE_sunxi_cortexa7_DEVICE_friendlyarm_nanopi-m1-"
  },
  {
    "path": "devices/sunxi_cortexa7/diy.sh",
    "chars": 279,
    "preview": "#!/bin/bash\n\nshopt -s extglob\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#bash $SHELL_FOLDER/../common/kernel_6.1.sh\n"
  },
  {
    "path": "devices/x86_64/.config",
    "chars": 152,
    "preview": "\nCONFIG_TARGET_x86=y\nCONFIG_TARGET_x86_64=y\nCONFIG_TARGET_ROOTFS_TARGZ=y\n\n# EFI支持:\nCONFIG_GRUB_IMAGES=y\nCONFIG_GRUB_EFI_"
  },
  {
    "path": "devices/x86_64/diy.sh",
    "chars": 900,
    "preview": "#!/bin/bash\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#bash $SHELL_FOLDER/../common/kernel_6.6.sh\n\ngit_clone_path ma"
  },
  {
    "path": "devices/x86_64/patches/Intel_gpu.patch",
    "chars": 1782,
    "preview": "diff --git a/package/kernel/linux/modules/virt.mk b/package/kernel/linux/modules/virt.mk\nindex 5ed0d5dbbf2..a853a8c7980 "
  },
  {
    "path": "devices/x86_64/patches/def_set_interfaces_lan_wan.patch",
    "chars": 577,
    "preview": "--- a/target/linux/x86/base-files/etc/board.d/02_network\n+++ b/target/linux/x86/base-files/etc/board.d/02_network\n@@ -39"
  },
  {
    "path": "devices/x86_64/patches/image-commands.patch",
    "chars": 601,
    "preview": "--- a/include/image-commands.mk\n+++ b/include/image-commands.mk\n@@ -419,6 +419,17 @@ endef\n \n # Convert a raw image into"
  },
  {
    "path": "devices/x86_64/patches/image.patch",
    "chars": 2818,
    "preview": "From c7bc056650227ba6003414356f57b33cdb2603b7 Mon Sep 17 00:00:00 2001\nFrom: kiddin9 <48883331+kiddin9@users.noreply.git"
  },
  {
    "path": "devices/x86_generic/.config",
    "chars": 156,
    "preview": "\nCONFIG_TARGET_x86=y\nCONFIG_TARGET_x86_generic=y\nCONFIG_TARGET_ROOTFS_TARGZ=y\n\n# EFI支持:\nCONFIG_GRUB_IMAGES=y\nCONFIG_GRUB"
  },
  {
    "path": "devices/x86_generic/diy.sh",
    "chars": 825,
    "preview": "#!/bin/bash\n\nSHELL_FOLDER=$(dirname $(readlink -f \"$0\"))\n\n#bash $SHELL_FOLDER/../common/kernel_6.6.sh\n\ngit_clone_path ma"
  },
  {
    "path": "devices/x86_generic/patches/image-commands.patch",
    "chars": 601,
    "preview": "--- a/include/image-commands.mk\n+++ b/include/image-commands.mk\n@@ -419,6 +419,17 @@ endef\n \n # Convert a raw image into"
  },
  {
    "path": "devices/x86_generic/patches/image.patch",
    "chars": 2818,
    "preview": "From c7bc056650227ba6003414356f57b33cdb2603b7 Mon Sep 17 00:00:00 2001\nFrom: kiddin9 <48883331+kiddin9@users.noreply.git"
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the kiddin9/Kwrt GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 198 files (449.9 KB), approximately 170.4k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!