diff options
44 files changed, 1345 insertions, 241 deletions
diff --git a/.github/workflows/build-and-run.yml b/.github/workflows/build-and-run.yml index fb6dd798..16e6629e 100644 --- a/.github/workflows/build-and-run.yml +++ b/.github/workflows/build-and-run.yml @@ -14,9 +14,6 @@ jobs: fail-fast: false matrix: include: - - distro: ubuntu-20.04 - pkg-distro: ubuntu20.04 - cpack-type: Ubuntu20 - distro: ubuntu-22.04 pkg-distro: ubuntu22.04 cpack-type: Ubuntu22 @@ -34,7 +31,7 @@ jobs: sudo apt update && NEEDRESTART_SUSPEND=1 DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true sudo -E apt -y install git build-essential cmake gcc linux-headers-`uname -r` - libpcre3-dev libssl-dev liblua5.1-0-dev kmod + libpcre2-dev libssl-dev liblua5.1-0-dev kmod - name: Check out repository code uses: actions/checkout@v3 with: @@ -90,7 +87,8 @@ jobs: "debian:trixie", "ubuntu:20.04", "ubuntu:22.04", - "ubuntu:24.04" + "ubuntu:24.04", + "ubuntu:devel" ] runs-on: ubuntu-24.04 container: @@ -104,6 +102,7 @@ jobs: debian:trixie) DISTRO=debian13; CPACK_TYPE=Debian13 ;; debian:12) DISTRO=debian12; CPACK_TYPE=Debian12 ;; debian:11) CPACK_TYPE=Debian11 ;; + ubuntu:devel) CPACK_TYPE=Ubuntu24 ; HEADERS_SUFFIX=generic ;; ubuntu:24.04) CPACK_TYPE=Ubuntu24 ; HEADERS_SUFFIX=generic ;; ubuntu:22.04) CPACK_TYPE=Ubuntu22 ; HEADERS_SUFFIX=generic ;; ubuntu:20.04) CPACK_TYPE=Ubuntu20 ; HEADERS_SUFFIX=generic ;; @@ -118,7 +117,7 @@ jobs: apt update && apt -y upgrade && apt -y dist-upgrade && NEEDRESTART_SUSPEND=1 DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true apt -y install git build-essential cmake gcc linux-headers-${{ env.HEADERS_SUFFIX }} - libpcre3-dev libssl-dev liblua5.1-0-dev kmod + libpcre2-dev libssl-dev liblua5.1-0-dev kmod - name: Get kernel name from headers run: > echo KERNEL_NAME=`ls -1 /usr/src/ | grep 'linux-headers.*${{ env.HEADERS_SUFFIX }}' | @@ -177,7 +176,7 @@ jobs: run: > apt update && apt -y upgrade && apt -y dist-upgrade && DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true apt -y install git build-essential cmake gcc - linux-headers-generic libpcre3-dev libssl-dev liblua5.1-0-dev kmod software-properties-common + linux-headers-generic libpcre2-dev libssl-dev liblua5.1-0-dev kmod software-properties-common pkexec dbus linux-base && add-apt-repository -y ppa:cappelikan/ppa && apt update && service dbus start && @@ -222,7 +221,7 @@ jobs: steps: - name: Install build tools run: > - apk update && apk add --no-cache git cmake make g++ pcre-dev libressl-dev linux-headers libucontext-dev lua5.1-dev + apk update && apk add --no-cache git cmake make g++ pcre2-dev libressl-dev linux-headers libucontext-dev lua5.1-dev - name: Check out repository code uses: actions/checkout@v3 with: @@ -248,4 +247,41 @@ jobs: run: sleep 1 - name: Check accel-ppp stat run: accel-cmd show stat -
\ No newline at end of file + + Build-in-Container-Gentoo: + runs-on: ubuntu-24.04 + container: + image: gentoo/stage3 + steps: + - name: Prepare gentoo + run: getuto && emerge --sync + - name: Install build tools + run: | + emerge -g --autounmask-write sys-kernel/gentoo-kernel-bin || (etc-update --verbose --automode -5 && emerge -g sys-kernel/gentoo-kernel-bin) + emerge -g dev-vcs/git dev-libs/libpcre2 dev-build/cmake dev-lang/lua:5.1 + - name: Check out repository code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: mkdir build + run: mkdir build + - name: Disable git security warnings + run: git config --global --add safe.directory '*' + - name: cmake + working-directory: ./build + run: > + cmake -DBUILD_IPOE_DRIVER=TRUE -DBUILD_VLAN_MON_DRIVER=TRUE -DCMAKE_INSTALL_PREFIX=/usr + -DCMAKE_INSTALL_SYSCONFDIR=/etc + -DKDIR=/usr/src/linux + -DLUA=TRUE -DSHAPER=TRUE -DRADIUS=TRUE .. + - name: make and install + working-directory: ./build + run: make && make install + - name: Copy default config + run: cp accel-pppd/accel-ppp.conf /etc/accel-ppp.conf + - name: Start accel-ppp with default config + run: accel-pppd -d -c /etc/accel-ppp.conf + - name: Sleep for 1 sec + run: sleep 1 + - name: Check accel-ppp stat + run: accel-cmd show stat diff --git a/.github/workflows/run-tests-32bit.yml b/.github/workflows/run-tests-32bit.yml new file mode 100644 index 00000000..94d158ab --- /dev/null +++ b/.github/workflows/run-tests-32bit.yml @@ -0,0 +1,162 @@ +name: Run tests (x86_32) + +on: + workflow_dispatch: + pull_request: + push: + branches: + - master + +jobs: + Test-in-Alpine-x86-32: + #if: ${{ false }} # disable for now + runs-on: ubuntu-24.04 + name: Test in Qemu (x86_32 Alpine) + strategy: + fail-fast: false + matrix: + distro: [v3.20] + + steps: + - name: Check out repository code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + path: "accel-ppp" + - name: Install build tools for qemu and required tools + run: > + sudo apt update && + NEEDRESTART_SUSPEND=1 DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true + sudo -E apt -y install qemu-system-x86 qemu-utils wget openssh-client screen + - name: Prepare qemu files + run: | + ssh-keygen -t ed25519 -q -N "" -f ssh-key + qemu-img create -f raw disk.raw 5G + wget -nv https://dl-cdn.alpinelinux.org/alpine/${{ matrix.distro }}/releases/x86/netboot/vmlinuz-lts + wget -nv https://dl-cdn.alpinelinux.org/alpine/${{ matrix.distro }}/releases/x86/netboot/initramfs-lts + - name: Run http server for ssh-key + run: | + sudo ip addr add 192.0.2.1/32 dev lo # stable ip for http server + screen -dmS httpserver python3 -m http.server 8000 + - name: Run target OS first time (for setup actions) + run: > + sudo screen -dmS qemu + qemu-system-i386 -accel kvm -M q35 + -m 2048 -smp 2 -nographic + -net nic -net user,hostfwd=tcp::2222-:22 + -drive format=raw,file=disk.raw + -kernel vmlinuz-lts + -initrd initramfs-lts + -append "ip=dhcp alpine_repo=https://dl-cdn.alpinelinux.org/alpine/${{ matrix.distro }}/main + modloop=https://dl-cdn.alpinelinux.org/alpine/${{ matrix.distro }}/releases/x86/netboot/modloop-lts + ssh_key=http://192.0.2.1:8000/ssh-key.pub" + - name: Check that target OS is running + run: | + sleep 1 + sudo screen -ls + - name: Wait for ssh connection + timeout-minutes: 30 + run: > + while ! ssh -o StrictHostKeyChecking=accept-new -p2222 -o ConnectTimeout=5 -i ssh-key root@localhost "exit 0"; + do + echo "Trying to establish ssh connection"; + sleep 5; + done; + cat ~/.ssh/known_hosts + - name: Setup alpine to disk + run: > + ssh -i ssh-key -p2222 root@localhost "setup-alpine -c setup_alpine_conf && + sed -i '/^ROOTSSHKEY\|^DISKOPTS\|^APKREPOSOPTS=/d' setup_alpine_conf && + echo '' >> setup_alpine_conf && + echo 'DISKOPTS=\"-m sys /dev/sda\"' >> setup_alpine_conf && + echo 'ROOTSSHKEY=\"http://192.0.2.1:8000/ssh-key.pub\"' >> setup_alpine_conf && + echo 'APKREPOSOPTS=\"https://dl-cdn.alpinelinux.org/alpine/${{ matrix.distro }}/main\"' >> setup_alpine_conf && + cat setup_alpine_conf && + yes | setup-alpine -e -f setup_alpine_conf" + - name: Poweroff the VM + timeout-minutes: 30 + run: > + ssh -i ssh-key -p2222 root@localhost "poweroff" && + while sudo screen -ls; + do + echo "Waiting for poweroff"; + sleep 5; + done; + - name: Run target OS + run: > + sudo screen -dmS qemu + qemu-system-i386 -accel kvm -M q35 + -m 2048 -smp 2 -nographic + -net nic -net user,hostfwd=tcp::2222-:22 + -drive format=raw,file=disk.raw + - name: Check that target OS is running + run: | + sleep 1 + sudo screen -ls + - name: Wait for ssh connection + timeout-minutes: 30 + run: > + while ! ssh -o StrictHostKeyChecking=accept-new -p2222 -o ConnectTimeout=5 -i ssh-key root@localhost "exit 0"; + do + echo "Trying to establish ssh connection"; + sleep 5; + done; + cat ~/.ssh/known_hosts + - name: Display free space, current dir, kernel version and users + run: | + ssh -i ssh-key -p2222 root@localhost "df -h" + ssh -i ssh-key -p2222 root@localhost "pwd" + ssh -i ssh-key -p2222 root@localhost "uname -a" + ssh -i ssh-key -p2222 root@localhost "cat /etc/passwd" + - name: Install build tools (on target OS) + run: > + ssh -i ssh-key -p2222 root@localhost "setup-apkrepos -o && apk add --no-cache git cmake make g++ pcre2-dev openssl-dev linux-headers libucontext-dev lua5.1-dev linux-lts-dev py3-pip + ppp ppp-pppoe iproute2 dhclient && + (pip3 install pytest pytest-dependency pytest-order || pip3 install --break-system-packages pytest pytest-dependency pytest-order)" + - name: Copy source code to target OS + run: | + tar -Jcf accel-ppp.tar.xz accel-ppp + scp -i ssh-key -P2222 accel-ppp.tar.xz root@localhost: + ssh -i ssh-key -p2222 root@localhost "tar -xf accel-ppp.tar.xz" + - name: Build accel-ppp + run: > + ssh -i ssh-key -p2222 root@localhost "cd accel-ppp && git config --global --add safe.directory '*' && + mkdir build && cd build && + cmake -DBUILD_IPOE_DRIVER=TRUE -DBUILD_VLAN_MON_DRIVER=TRUE -DCMAKE_INSTALL_PREFIX=/usr + -DKDIR=/usr/src/linux-headers-\`uname -r\` + -DLUA=TRUE -DSHAPER=TRUE -DRADIUS=TRUE .. && + make && make install" + - name: Run tests (not related to ipoe and vlan_mon drivers) + timeout-minutes: 5 + run: > + ssh -i ssh-key -p2222 root@localhost "cd accel-ppp/tests && + python3 -m pytest -Wall --order-dependencies -v -m \"not ipoe_driver and not vlan_mon_driver and not chap_secrets\"" + - name: Display processes and dmesg after tests + if: ${{ always() }} + run: ssh -i ssh-key -p2222 -o ConnectTimeout=5 root@localhost "ps aux | grep accel- && dmesg" + - name: Insert ipoe kernel module + run: > + ssh -i ssh-key -p2222 root@localhost "cd accel-ppp && + insmod build/drivers/ipoe/driver/ipoe.ko && + lsmod | grep ipoe" + - name: Run tests (not related to vlan_mon drivers) + timeout-minutes: 5 + run: > + ssh -i ssh-key -p2222 root@localhost "cd accel-ppp/tests && + python3 -m pytest -Wall --order-dependencies -v -m \"not vlan_mon_driver and not chap_secrets\"" + - name: Display processes and dmesg after tests + if: ${{ always() }} + run: ssh -i ssh-key -p2222 -o ConnectTimeout=5 root@localhost "ps aux | grep accel- && dmesg" + - name: Insert vlan_mon kernel module + run: > + ssh -i ssh-key -p2222 root@localhost "cd accel-ppp && + insmod build/drivers/vlan_mon/driver/vlan_mon.ko && + lsmod | grep vlan_mon" + - name: Run tests (all) + timeout-minutes: 5 + run: > + ssh -i ssh-key -p2222 root@localhost "cd accel-ppp/tests && + python3 -m pytest -Wall --order-dependencies -v -m \"not chap_secrets\"" + - name: Display processes and dmesg after tests + if: ${{ always() }} + run: ssh -i ssh-key -p2222 -o ConnectTimeout=5 root@localhost "ps aux | grep accel- && dmesg" diff --git a/.github/workflows/run-tests-bigendian.yml b/.github/workflows/run-tests-bigendian.yml new file mode 100644 index 00000000..d5dce83b --- /dev/null +++ b/.github/workflows/run-tests-bigendian.yml @@ -0,0 +1,169 @@ +name: Run tests (big-endian) + +on: + workflow_dispatch: + pull_request: + push: + branches: + - master + +jobs: + + Test-in-Alpine-s390x: + #if: ${{ false }} # disable for now + runs-on: ubuntu-24.04 + name: Test in Qemu (s390x Alpine) + + steps: + - name: Check out repository code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + path: "accel-ppp" + - name: Install build tools for qemu and required tools + run: > + sudo apt update && + NEEDRESTART_SUSPEND=1 DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true + sudo -E apt -y install wget openssh-client screen + libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev libslirp-dev ninja-build + - name: Build Qemu 9.1.2 + # Qemu 8.2 from Ubuntu24.04 has critical s390x-related bugs so Qemu9 is required + run: | + wget -nv https://github.com/qemu/qemu/archive/refs/tags/v9.1.2.tar.gz + tar -xf v9.1.2.tar.gz + cd qemu-9.1.2 + ./configure --target-list=s390x-softmmu --enable-slirp + make -j + sudo make install + - name: Prepare qemu files + run: | + ssh-keygen -t ed25519 -q -N "" -f ssh-key + qemu-img create -f raw disk.raw 5G + wget -nv https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/s390x/netboot/vmlinuz-lts + wget -nv https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/s390x/netboot/initramfs-lts + - name: Run http server for ssh-key + run: | + sudo ip addr add 192.0.2.1/32 dev lo # stable ip for http server + screen -dmS httpserver python3 -m http.server 8000 + - name: Run target OS first time (for setup actions) + run: > + sudo screen -dmS qemu + qemu-system-s390x -M s390-ccw-virtio + -m 4096 -smp 2 -nographic + -net nic -net user,hostfwd=tcp::2222-:22 + -drive format=raw,file=disk.raw + -kernel vmlinuz-lts + -initrd initramfs-lts + -append "ip=dhcp alpine_repo=https://dl-cdn.alpinelinux.org/alpine/v3.20/main + modloop=https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/s390x/netboot/modloop-lts + ssh_key=http://192.0.2.1:8000/ssh-key.pub" + - name: Check that target OS is running + run: | + sleep 1 + sudo screen -ls + - name: Wait for ssh connection + timeout-minutes: 30 + run: > + while ! ssh -o StrictHostKeyChecking=accept-new -p2222 -o ConnectTimeout=5 -i ssh-key root@localhost "exit 0"; + do + echo "Trying to establish ssh connection"; + sleep 5; + done; + cat ~/.ssh/known_hosts + - name: Setup alpine to disk + run: > + ssh -i ssh-key -p2222 root@localhost "setup-alpine -c setup_alpine_conf && + sed -i '/^ROOTSSHKEY\|^DISKOPTS\|^APKREPOSOPTS=/d' setup_alpine_conf && + echo '' >> setup_alpine_conf && + echo 'DISKOPTS=\"-m sys /dev/vda\"' >> setup_alpine_conf && + echo 'ROOTSSHKEY=\"http://192.0.2.1:8000/ssh-key.pub\"' >> setup_alpine_conf && + echo 'APKREPOSOPTS=\"https://dl-cdn.alpinelinux.org/alpine/v3.20/main\"' >> setup_alpine_conf && + cat setup_alpine_conf && + yes | setup-alpine -e -f setup_alpine_conf" + - name: Poweroff the VM + timeout-minutes: 30 + run: > + ssh -i ssh-key -p2222 root@localhost "poweroff" && + while sudo screen -ls; + do + echo "Waiting for poweroff"; + sleep 5; + done; + - name: Run target OS + run: > + sudo screen -dmS qemu + qemu-system-s390x -M s390-ccw-virtio + -m 4096 -smp 2 -nographic + -net nic -net user,hostfwd=tcp::2222-:22 + -drive format=raw,file=disk.raw + - name: Check that target OS is running + run: | + sleep 1 + sudo screen -ls + - name: Wait for ssh connection + timeout-minutes: 30 + run: > + while ! ssh -o StrictHostKeyChecking=accept-new -p2222 -o ConnectTimeout=5 -i ssh-key root@localhost "exit 0"; + do + echo "Trying to establish ssh connection"; + sleep 5; + done; + cat ~/.ssh/known_hosts + - name: Display free space, current dir, kernel version and users + run: | + ssh -i ssh-key -p2222 root@localhost "df -h" + ssh -i ssh-key -p2222 root@localhost "pwd" + ssh -i ssh-key -p2222 root@localhost "uname -a" + ssh -i ssh-key -p2222 root@localhost "cat /etc/passwd" + - name: Install build tools (on target OS) + run: > + ssh -i ssh-key -p2222 root@localhost "setup-apkrepos -o && apk add --no-cache git cmake make g++ pcre2-dev openssl-dev linux-headers libucontext-dev lua5.1-dev linux-lts-dev py3-pip + ppp ppp-pppoe iproute2 dhclient && + (pip3 install pytest pytest-dependency pytest-order || pip3 install --break-system-packages pytest pytest-dependency pytest-order)" + - name: Copy source code to target OS + run: | + tar -Jcf accel-ppp.tar.xz accel-ppp + scp -i ssh-key -P2222 accel-ppp.tar.xz root@localhost: + ssh -i ssh-key -p2222 root@localhost "tar -xf accel-ppp.tar.xz" + - name: Build accel-ppp + run: > + ssh -i ssh-key -p2222 root@localhost "cd accel-ppp && git config --global --add safe.directory '*' && + mkdir build && cd build && + cmake -DBUILD_IPOE_DRIVER=TRUE -DBUILD_VLAN_MON_DRIVER=TRUE -DCMAKE_INSTALL_PREFIX=/usr + -DKDIR=/usr/src/linux-headers-\`uname -r\` + -DLUA=TRUE -DSHAPER=TRUE -DRADIUS=TRUE .. && + make && make install" + - name: Run tests (not related to ipoe and vlan_mon drivers) + timeout-minutes: 5 + run: > + ssh -i ssh-key -p2222 root@localhost "cd accel-ppp/tests && + python3 -m pytest -Wall --order-dependencies -v -m \"not ipoe_driver and not vlan_mon_driver and not chap_secrets\"" + - name: Display processes and dmesg after tests + if: ${{ always() }} + run: ssh -i ssh-key -p2222 -o ConnectTimeout=5 root@localhost "ps aux | grep accel- && dmesg" + - name: Insert ipoe kernel module + run: > + ssh -i ssh-key -p2222 root@localhost "cd accel-ppp && + insmod build/drivers/ipoe/driver/ipoe.ko && + lsmod | grep ipoe" + - name: Run tests (not related to vlan_mon drivers) + timeout-minutes: 5 + run: > + ssh -i ssh-key -p2222 root@localhost "cd accel-ppp/tests && + python3 -m pytest -Wall --order-dependencies -v -m \"not vlan_mon_driver and not chap_secrets\"" + - name: Display processes and dmesg after tests + if: ${{ always() }} + run: ssh -i ssh-key -p2222 -o ConnectTimeout=5 root@localhost "ps aux | grep accel- && dmesg" + - name: Insert vlan_mon kernel module + run: > + ssh -i ssh-key -p2222 root@localhost "cd accel-ppp && + insmod build/drivers/vlan_mon/driver/vlan_mon.ko && + lsmod | grep vlan_mon" + - name: Run tests (all) + timeout-minutes: 5 + run: > + ssh -i ssh-key -p2222 root@localhost "cd accel-ppp/tests && + python3 -m pytest -Wall --order-dependencies -v -m \"not chap_secrets\"" + - name: Display processes and dmesg after tests + if: ${{ always() }} + run: ssh -i ssh-key -p2222 -o ConnectTimeout=5 root@localhost "ps aux | grep accel- && dmesg" diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 3f8016a8..319cc0bc 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -56,8 +56,8 @@ jobs: run: > sudo apt update && NEEDRESTART_SUSPEND=1 DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true sudo -E apt -y install qemu-system-x86 qemu-utils cloud-image-utils cpu-checker cloud-image-utils wget openssh-client screen - - name: Check kvm support (fail is ok) - run: sudo kvm-ok || exit 0 + - name: Check kvm support + run: sudo kvm-ok - name: Prepare cloud-init image disk run: | ssh-keygen -t ed25519 -q -N "" -f ssh-key @@ -91,9 +91,9 @@ jobs: wget -nv ${{ matrix.image }} -O img/image qemu-img resize -f ${{ matrix.format }} img/`ls -1 img` +2G - name: Run target OS first time (for cloud-init actions) - run: sudo qemu-system-x86_64 -m 4096 -nographic -drive format=${{ matrix.format }},file=img/`ls -1 img` -drive format=raw,file=init.img + run: sudo qemu-system-x86_64 -enable-kvm -cpu host -m 4096 -nographic -drive format=${{ matrix.format }},file=img/`ls -1 img` -drive format=raw,file=init.img - name: Run target OS - run: sudo screen -dmS qemu qemu-system-x86_64 -net nic -net user,hostfwd=tcp::2222-:22 -m 4096 -nographic -drive format=${{ matrix.format }},file=img/`ls -1 img` + run: sudo screen -dmS qemu qemu-system-x86_64 -enable-kvm -cpu host -net nic -net user,hostfwd=tcp::2222-:22 -m 4096 -nographic -drive format=${{ matrix.format }},file=img/`ls -1 img` - name: Check that target OS is running run: | sleep 1 @@ -117,10 +117,12 @@ jobs: run: > ssh -i ssh-key -p2222 user@localhost "sudo apt -y install git build-essential cmake gcc linux-headers-\`uname -r\` - libpcre3-dev libssl-dev liblua5.1-0-dev kmod python3-pip + libpcre2-dev libssl-dev liblua5.1-0-dev kmod python3-pip libxml2-dev libxslt1-dev zlib1g-dev iproute2 ppp pppoe isc-dhcp-client timelimit && - (sudo pip3 install pytest pytest-dependency || sudo pip3 install --break-system-packages pytest pytest-dependency)" + (sudo apt -y install python3-pytest python3-pytest-dependency python3-pytest-order || + sudo pip3 install pytest pytest-dependency pytest-order || + sudo pip3 install --break-system-packages pytest pytest-dependency pytest-order)" - name: Copy source code to target OS run: | tar -Jcf accel-ppp.tar.xz accel-ppp @@ -139,7 +141,7 @@ jobs: timeout-minutes: 5 run: > ssh -i ssh-key -p2222 user@localhost "cd accel-ppp/tests && - sudo python3 -m pytest -Wall -v -m \"not ipoe_driver and not vlan_mon_driver\"" + sudo python3 -m pytest -Wall --order-dependencies -v -m \"not ipoe_driver and not vlan_mon_driver\"" - name: Display processes and dmesg after tests if: ${{ always() }} run: > @@ -157,7 +159,7 @@ jobs: if: ${{ always() }} run: > ssh -i ssh-key -p2222 user@localhost "cd accel-ppp/tests && - sudo python3 -m pytest -Wall -v -m \"not vlan_mon_driver\"" + sudo python3 -m pytest -Wall --order-dependencies -v -m \"not vlan_mon_driver\"" - name: Display processes and dmesg after tests if: ${{ always() }} run: > @@ -174,19 +176,149 @@ jobs: timeout-minutes: 5 run: > ssh -i ssh-key -p2222 user@localhost "cd accel-ppp/tests && - sudo python3 -m pytest -Wall -v" + sudo python3 -m pytest -Wall --order-dependencies -v" - name: Display processes and dmesg after tests if: ${{ always() }} run: > ssh -i ssh-key -p2222 user@localhost "ps aux | grep accel- && sudo dmesg" + Test-in-Alpine: + #if: ${{ false }} # disable for now + runs-on: ubuntu-24.04 + name: Test in Qemu (Alpine) + + steps: + - name: Check out repository code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + path: "accel-ppp" + - name: Install qemu and required tools + run: > + sudo apt update && + NEEDRESTART_SUSPEND=1 DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true sudo -E apt -y install qemu-system-x86 qemu-utils cloud-image-utils cpu-checker cloud-image-utils wget openssh-client screen + - name: Check kvm support + run: sudo kvm-ok + - name: Prepare cloud-init image disk + run: | + ssh-keygen -t ed25519 -q -N "" -f ssh-key + echo "instance-id: $(uuidgen || echo i-abcdefg)" > init-meta + echo "#cloud-config" > init-data + echo "package_update: true" >> init-data + echo "package_upgrade: true" >> init-data + echo "package_reboot_if_required: false" >> init-data + echo "users:" >> init-data + echo " - default" >> init-data + echo " - name: alpine" >> init-data + echo " shell: /bin/bash" >> init-data + echo " ssh_authorized_keys:" >> init-data + echo " - "`cat ssh-key.pub` >> init-data + echo "power_state:">> init-data + echo " mode: poweroff">> init-data + cat init-data + cloud-localds init.img init-data init-meta + - name: Download and resize target OS cloud image + run: | + mkdir img + # we need to use metal image because virt image doesn't provide pppoe driver (https://gitlab.alpinelinux.org/alpine/aports/-/issues/13739) + wget -nv https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/cloud/nocloud_alpine-3.20.3-x86_64-bios-cloudinit-metal-r0.qcow2 -O img/image + qemu-img resize -f qcow2 img/`ls -1 img` +2G + - name: Run target OS first time (for cloud-init actions) + run: sudo qemu-system-x86_64 -enable-kvm -cpu host -m 4096 -nographic -drive format=qcow2,file=img/`ls -1 img` -drive format=raw,file=init.img + - name: Run target OS + run: sudo screen -dmS qemu qemu-system-x86_64 -enable-kvm -cpu host -net nic -net user,hostfwd=tcp::2222-:22 -m 4096 -nographic -drive format=qcow2,file=img/`ls -1 img` + - name: Check that target OS is running + run: | + sleep 1 + sudo screen -ls + - name: Wait for ssh connection + timeout-minutes: 30 + run: > + while ! ssh -o StrictHostKeyChecking=accept-new -p2222 -o ConnectTimeout=5 -i ssh-key alpine@localhost "exit 0"; + do + echo "Trying to establish ssh connection"; + sleep 5; + done; + cat ~/.ssh/known_hosts + - name: Display free space, current dir, kernel version and test doas + run: | + ssh -i ssh-key -p2222 alpine@localhost "df -h" + ssh -i ssh-key -p2222 alpine@localhost "pwd" + ssh -i ssh-key -p2222 alpine@localhost "uname -a" + ssh -i ssh-key -p2222 alpine@localhost "doas cat /etc/passwd" + - name: Install build tools (on target OS) + run: > + ssh -i ssh-key -p2222 alpine@localhost "doas apk add --no-cache git cmake make g++ pcre2-dev libressl-dev linux-headers libucontext-dev lua5.1-dev linux-lts-dev py3-pip + ppp ppp-pppoe && + (doas pip3 install pytest pytest-dependency pytest-order || doas pip3 install --break-system-packages pytest pytest-dependency pytest-order)" + - name: Copy source code to target OS + run: | + tar -Jcf accel-ppp.tar.xz accel-ppp + scp -i ssh-key -P2222 accel-ppp.tar.xz alpine@localhost: + ssh -i ssh-key -p2222 alpine@localhost "tar -xf accel-ppp.tar.xz" + - name: Build accel-ppp + run: > + ssh -i ssh-key -p2222 alpine@localhost "cd accel-ppp && + mkdir build && cd build && + cmake -DBUILD_IPOE_DRIVER=TRUE -DBUILD_VLAN_MON_DRIVER=TRUE -DCMAKE_INSTALL_PREFIX=/usr + -DKDIR=/usr/src/linux-headers-\`uname -r\` + -DLUA=TRUE -DSHAPER=TRUE -DRADIUS=TRUE .. && + make && doas make install" + + - name: Run tests (not related to ipoe and vlan_mon drivers) + timeout-minutes: 5 + run: > + ssh -i ssh-key -p2222 alpine@localhost "cd accel-ppp/tests && + doas python3 -m pytest -Wall --order-dependencies -v -m \"not ipoe_driver and not vlan_mon_driver and not chap_secrets\"" + - name: Display processes and dmesg after tests + if: ${{ always() }} + run: > + ssh -i ssh-key -p2222 alpine@localhost "ps aux | grep accel- && + doas dmesg" + + - name: Insert ipoe kernel module + run: > + ssh -i ssh-key -p2222 alpine@localhost "cd accel-ppp && + doas insmod build/drivers/ipoe/driver/ipoe.ko && + lsmod | grep ipoe " + + - name: Run tests (not related to vlan_mon drivers) + timeout-minutes: 5 + if: ${{ always() }} + run: > + ssh -i ssh-key -p2222 alpine@localhost "cd accel-ppp/tests && + doas python3 -m pytest -Wall --order-dependencies -v -m \"not vlan_mon_driver and not chap_secrets\"" + - name: Display processes and dmesg after tests + if: ${{ always() }} + run: > + ssh -i ssh-key -p2222 alpine@localhost "ps aux | grep accel- && + doas dmesg" + + - name: Insert vlan_mon kernel module + run: > + ssh -i ssh-key -p2222 alpine@localhost "cd accel-ppp && + doas insmod build/drivers/vlan_mon/driver/vlan_mon.ko && + lsmod | grep vlan_mon" + + - name: Run tests (all) + timeout-minutes: 5 + run: > + ssh -i ssh-key -p2222 alpine@localhost "cd accel-ppp/tests && + doas python3 -m pytest -Wall --order-dependencies -v -m \"not chap_secrets\"" + - name: Display processes and dmesg after tests + if: ${{ always() }} + run: > + ssh -i ssh-key -p2222 alpine@localhost "ps aux | grep accel- && + doas dmesg" + + Test-in-GH: #if: ${{ false }} # disable for now strategy: fail-fast: false matrix: - distro: ["ubuntu-24.04", "ubuntu-22.04", "ubuntu-20.04"] + distro: ["ubuntu-24.04", "ubuntu-22.04"] runs-on: ${{ matrix.distro }} steps: @@ -195,12 +327,14 @@ jobs: sudo apt update && NEEDRESTART_SUSPEND=1 DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true sudo -E apt -y install git build-essential cmake gcc linux-headers-`uname -r` - libpcre3-dev libssl-dev liblua5.1-0-dev kmod python3-pip + libpcre2-dev libssl-dev liblua5.1-0-dev kmod python3-pip iproute2 ppp pppoe isc-dhcp-client - name: Install testing tools (using pip) run: > - sudo pip3 install pytest pytest-dependency || sudo pip3 install --break-system-packages pytest pytest-dependency + sudo apt -y install python3-pytest python3-pytest-dependency python3-pytest-order || + sudo pip3 install pytest pytest-dependency pytest-order || + sudo pip3 install --break-system-packages pytest pytest-dependency pytest-order - name: Check out repository code uses: actions/checkout@v4 @@ -232,14 +366,14 @@ jobs: - name: Run tests timeout-minutes: 5 working-directory: ./tests - run: sudo python3 -m pytest -Wall -v + run: sudo python3 -m pytest -Wall --order-dependencies -v Test-in-GH-Coverage: #if: ${{ false }} # disable for now strategy: fail-fast: false matrix: - distro: ["ubuntu-24.04", "ubuntu-22.04", "ubuntu-20.04"] + distro: ["ubuntu-24.04", "ubuntu-22.04"] runs-on: ${{ matrix.distro }} steps: @@ -248,12 +382,14 @@ jobs: sudo apt update && NEEDRESTART_SUSPEND=1 DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true sudo -E apt -y install git build-essential cmake gcc linux-headers-`uname -r` - libpcre3-dev libssl-dev liblua5.1-0-dev kmod python3-pip + libpcre2-dev libssl-dev liblua5.1-0-dev kmod python3-pip iproute2 ppp pppoe isc-dhcp-client - - name: Install testing tools (using pip) + - name: Install testing tools run: > - sudo pip3 install pytest pytest-dependency gcovr || sudo pip3 install --break-system-packages pytest pytest-dependency gcovr + sudo apt -y install python3-pytest python3-pytest-dependency python3-pytest-order gcovr || + sudo pip3 install pytest pytest-dependency pytest-order gcovr || + sudo pip3 install --break-system-packages pytest pytest-dependency pytest-order gcovr - name: Check out repository code uses: actions/checkout@v4 @@ -286,7 +422,7 @@ jobs: - name: Run tests (for coverage report) (fail is ok) timeout-minutes: 5 working-directory: ./tests - run: sudo python3 -m pytest -Wall -v || exit 0 + run: sudo python3 -m pytest -Wall --order-dependencies -v || exit 0 - name: Generate coverage reports (default(txt), csv, html) run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index 128b75a9..b606898a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,15 +23,15 @@ ENDIF (NOT DEFINED LIB_SUFFIX) #color console example message(FATAL_ERROR "${Esc}[31m Red Text ${Esc}[m Restore Normal Text") string(ASCII 27 Esc) -#Check libpcre -find_library(PCRE_LIBRARY pcre +#Check libpcre2 +find_library(PCRE2_LIBRARY pcre2-8 HINTS ${CMAKE_SOURCE_DIR}/lib/linux/gcc/${BIT}/lib PATHS ${CMAKE_SOURCE_DIR}/lib/linux/gcc/${BIT}/lib ) -IF(NOT PCRE_LIBRARY) - message(FATAL_ERROR "${Esc}[31mRequired libpcre not found.\n Install libpcre3-dev and run cmake again${Esc}[m") -ENDIF(NOT PCRE_LIBRARY) +IF(NOT PCRE2_LIBRARY) + message(FATAL_ERROR "${Esc}[31mRequired libpcre not found.\n Install libpcre2-dev and run cmake again${Esc}[m") +ENDIF(NOT PCRE2_LIBRARY) IF (EXISTS ${CMAKE_HOME_DIRECTORY}/.git AND NOT IGNORE_GIT) @@ -34,7 +34,7 @@ Requirment 4. cmake-2.6 or later 5. libnl-2.0 or probably later (required for builtin shaper) 6. libcrypto-0.9.8 or probably later (openssl-0.9.8) -7. libpcre +7. libpcre2 8. net-snmp-5.x 9. libssl-0.9.8 or probably later (openssl-0.9.8) diff --git a/accel-pppd/CMakeLists.txt b/accel-pppd/CMakeLists.txt index cd7186ba..b274d856 100644 --- a/accel-pppd/CMakeLists.txt +++ b/accel-pppd/CMakeLists.txt @@ -60,6 +60,7 @@ ENDIF (HAVE_FREE_FN_T) INCLUDE (CheckCSourceCompiles) CHECK_C_SOURCE_COMPILES(" +#include <sys/socket.h> #include <linux/if_arp.h> #include <net/ethernet.h> int main(void) @@ -71,6 +72,19 @@ IF (HAVE_GOOD_IFARP) ADD_DEFINITIONS(-DHAVE_GOOD_IFARP) ENDIF (HAVE_GOOD_IFARP) +INCLUDE (CheckCSourceCompiles) +CHECK_C_SOURCE_COMPILES(" +#include <utmp.h> +int main(void) +{ + logwtmp(\"\", \"\", \"\"); + return 0; +}" HAVE_LOGWTMP) + +IF (HAVE_LOGWTMP) + ADD_DEFINITIONS(-DHAVE_LOGWTMP) +ENDIF (HAVE_LOGWTMP) + ADD_SUBDIRECTORY(triton) ADD_SUBDIRECTORY(vlan-mon) @@ -163,9 +177,9 @@ CHECK_FUNCTION_EXISTS(getcontext HAVE_GETCONTEXT) CHECK_FUNCTION_EXISTS(setcontext HAVE_SETCONTEXT) IF (HAVE_GETCONTEXT AND HAVE_SETCONTEXT) - TARGET_LINK_LIBRARIES(accel-pppd triton rt pthread ${crypto_lib} pcre) + TARGET_LINK_LIBRARIES(accel-pppd triton rt pthread ${crypto_lib} pcre2-8) ELSE (HAVE_GETCONTEXT AND HAVE_SETCONTEXT) - TARGET_LINK_LIBRARIES(accel-pppd triton rt pthread ${crypto_lib} pcre ucontext) + TARGET_LINK_LIBRARIES(accel-pppd triton rt pthread ${crypto_lib} pcre2-8 ucontext) ENDIF (HAVE_GETCONTEXT AND HAVE_SETCONTEXT) set_property(TARGET accel-pppd PROPERTY CMAKE_SKIP_BUILD_RPATH FALSE) diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf index abfd1ac9..99d35c79 100644 --- a/accel-pppd/accel-ppp.conf +++ b/accel-pppd/accel-ppp.conf @@ -6,6 +6,9 @@ log_file connlimit +radius +#chap-secrets + pptp l2tp #sstp @@ -17,9 +20,6 @@ auth_mschap_v1 auth_chap_md5 auth_pap -radius -#chap-secrets - ippool pppd_compat diff --git a/accel-pppd/cli/cli.c b/accel-pppd/cli/cli.c index 7d440727..6b71cb04 100644 --- a/accel-pppd/cli/cli.c +++ b/accel-pppd/cli/cli.c @@ -63,51 +63,6 @@ void __export cli_register_simple_cmd2( va_end(ap); } -void __export cli_register_regexp_cmd(struct cli_regexp_cmd_t *cmd) -{ - int err; - int erroffset; - const char *errptr; - - if (cmd->exec == NULL) { - log_emerg("cli: impossible to register regexp command" - " without an execution callback function\n"); - _exit(EXIT_FAILURE); - } - if (cmd->pattern == NULL) { - log_emerg("cli: impossible to register regexp command" - " without pattern\n"); - _exit(EXIT_FAILURE); - } - cmd->re = pcre_compile2(cmd->pattern, cmd->options, &err, - &errptr, &erroffset, NULL); - if (!cmd->re) { - log_emerg("cli: failed to compile regexp \"%s\": %s (error %i)" - " at positon %i (unprocessed characters: \"%s\")\n", - cmd->pattern, errptr, err, erroffset, - cmd->pattern + erroffset); - _exit(EXIT_FAILURE); - } - - if (cmd->h_pattern) { - cmd->h_re = pcre_compile2(cmd->h_pattern, cmd->h_options, &err, - &errptr, &erroffset, NULL); - if (!cmd->h_re) { - log_emerg("cli: failed to compile help regexp \"%s\":" - " %s (error %i) at position %i (unprocessed" - " characters: \"%s\")\n", - cmd->h_pattern, errptr, err, erroffset, - cmd->h_pattern + erroffset); - _exit(EXIT_FAILURE); - } - } else { - cmd->h_re = NULL; - cmd->h_pattern = NULL; - } - - list_add_tail(&cmd->entry, ®exp_cmd_list); -} - int __export cli_send(void *client, const char *data) { struct cli_client_t *cln = (struct cli_client_t *)client; @@ -189,13 +144,15 @@ static int cli_process_help_cmd(struct cli_client_t *cln) cmd_found = 1; list_for_each_entry(recmd, ®exp_cmd_list, entry) { + pcre2_match_data *match_data = pcre2_match_data_create(0, NULL); if (cmd[0] == '\0' - || pcre_exec(recmd->h_re, NULL, cmd, strlen(cmd), - 0, 0, NULL, 0) >= 0) { + || pcre2_match(recmd->h_re, (PCRE2_SPTR)cmd, strlen(cmd), + 0, 0, match_data, NULL) >= 0) { cmd_found = 1; if (recmd->help) recmd->help(cmd, cln); } + pcre2_match_data_free(match_data); } nb_items = split(cmd, items); @@ -230,14 +187,19 @@ static int cli_process_regexp_cmd(struct cli_client_t *cln, int *err) int res; cmd = skip_space(cmd); - list_for_each_entry(recmd, ®exp_cmd_list, entry) - if (pcre_exec(recmd->re, NULL, cmd, strlen(cmd), - 0, 0, NULL, 0) >= 0) { + list_for_each_entry(recmd, ®exp_cmd_list, entry) { + pcre2_match_data *match_data = pcre2_match_data_create(0, NULL); + if (pcre2_match(recmd->re, (PCRE2_SPTR)cmd, strlen(cmd), + 0, 0, match_data, NULL) >= 0) { found = 1; res = recmd->exec(cmd, cln); - if (res != CLI_CMD_OK) + if (res != CLI_CMD_OK) { + pcre2_match_data_free(match_data); break; + } } + pcre2_match_data_free(match_data); + } if (found) *err = res; diff --git a/accel-pppd/cli/cli.h b/accel-pppd/cli/cli.h index 6eda5d3f..3d8069b3 100644 --- a/accel-pppd/cli/cli.h +++ b/accel-pppd/cli/cli.h @@ -1,7 +1,8 @@ #ifndef __CLI_H #define __CLI_H -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "list.h" @@ -23,11 +24,11 @@ struct cli_simple_cmd_t struct cli_regexp_cmd_t { struct list_head entry; - pcre *re; + pcre2_code *re; const char *pattern; int options; int (*exec)(const char *cmd, void *client); - pcre *h_re; + pcre2_code *h_re; const char *h_pattern; int h_options; int (*help)(const char *cmd, void *client); @@ -42,7 +43,6 @@ void cli_register_simple_cmd2( int hdr_len, ... ); -void cli_register_regexp_cmd(struct cli_regexp_cmd_t *cmd); void cli_show_ses_register(const char *name, const char *desc, void (*print)(struct ap_session *ses, char *buf)); int cli_send(void *client, const char *data); diff --git a/accel-pppd/cli/show_sessions.c b/accel-pppd/cli/show_sessions.c index 22f5318a..ca2ec68d 100644 --- a/accel-pppd/cli/show_sessions.c +++ b/accel-pppd/cli/show_sessions.c @@ -128,9 +128,9 @@ static int show_ses_exec(const char *cmd, char * const *f, int f_cnt, void *cli) struct column_t *match_key = NULL; char *match_pattern = NULL; struct column_t *order_key = NULL; - pcre *re = NULL; - const char *pcre_err; - int pcre_offset; + pcre2_code *re = NULL; + int pcre_err; + PCRE2_SIZE pcre_offset; struct column_t *column; struct col_t *col; struct row_t *row; @@ -169,9 +169,11 @@ static int show_ses_exec(const char *cmd, char * const *f, int f_cnt, void *cli) } if (match_key) { - re = pcre_compile2(match_pattern, 0, NULL, &pcre_err, &pcre_offset, NULL); + re = pcre2_compile((PCRE2_SPTR)match_pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL); if (!re) { - cli_sendv(cli, "match: %s at %i\r\n", pcre_err, pcre_offset); + PCRE2_UCHAR err_msg[64]; + pcre2_get_error_message(pcre_err, err_msg, sizeof(err_msg)); + cli_sendv(cli, "match: %s at %i\r\n", err_msg, (int)pcre_offset); return CLI_CMD_OK; } } @@ -262,10 +264,13 @@ static int show_ses_exec(const char *cmd, char * const *f, int f_cnt, void *cli) row = list_entry(t_list.next, typeof(*row), entry); list_del(&row->entry); if (match_key) { - if (pcre_exec(re, NULL, row->match_key, strlen(row->match_key), 0, 0, NULL, 0) < 0) { + pcre2_match_data *match_data = pcre2_match_data_create(0, NULL); + if (pcre2_match(re, (PCRE2_SPTR)row->match_key, strlen(row->match_key), 0, 0, match_data, NULL) < 0) { free_row(row); + pcre2_match_data_free(match_data); continue; } + pcre2_match_data_free(match_data); } if (order_key) insert_row(&r_list, row); @@ -362,7 +367,7 @@ out: } if (re) - pcre_free(re); + pcre2_code_free(re); return CLI_CMD_OK; diff --git a/accel-pppd/cli/std_cmd.c b/accel-pppd/cli/std_cmd.c index fc073526..ace48391 100644 --- a/accel-pppd/cli/std_cmd.c +++ b/accel-pppd/cli/std_cmd.c @@ -123,9 +123,9 @@ static int terminate_exec1(char * const *f, int f_cnt, void *cli) { struct ap_session *ses; int hard = 0; - pcre *re; - const char *pcre_err; - int pcre_offset; + pcre2_code *re; + int pcre_err; + PCRE2_SIZE pcre_offset; if (f_cnt == 5) { if (!strcmp(f[4], "hard")) @@ -135,9 +135,11 @@ static int terminate_exec1(char * const *f, int f_cnt, void *cli) } else if (f_cnt != 4) return CLI_CMD_SYNTAX; - re = pcre_compile2(f[3], 0, NULL, &pcre_err, &pcre_offset, NULL); + re = pcre2_compile((PCRE2_SPTR)f[3], PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL); if (!re) { - cli_sendv(cli, "match: %s at %i\r\n", pcre_err, pcre_offset); + PCRE2_UCHAR err_msg[64]; + pcre2_get_error_message(pcre_err, err_msg, sizeof(err_msg)); + cli_sendv(cli, "match: %s at %i\r\n", err_msg, (int)pcre_offset); return CLI_CMD_OK; } @@ -145,8 +147,12 @@ static int terminate_exec1(char * const *f, int f_cnt, void *cli) list_for_each_entry(ses, &ses_list, entry) { if (!ses->username) continue; - if (pcre_exec(re, NULL, ses->username, strlen(ses->username), 0, 0, NULL, 0) < 0) + pcre2_match_data *match_data = pcre2_match_data_create(0, NULL); + if (pcre2_match(re, (PCRE2_SPTR)ses->username, strlen(ses->username), 0, 0, match_data, NULL) < 0) { + pcre2_match_data_free(match_data); continue; + } + pcre2_match_data_free(match_data); if (hard) triton_context_call(ses->ctrl->ctx, (triton_event_func)__terminate_hard, ses); else @@ -154,7 +160,7 @@ static int terminate_exec1(char * const *f, int f_cnt, void *cli) } pthread_rwlock_unlock(&ses_lock); - pcre_free(re); + pcre2_code_free(re); return CLI_CMD_OK; } diff --git a/accel-pppd/ctrl/ipoe/dhcpv4.c b/accel-pppd/ctrl/ipoe/dhcpv4.c index 466dfee6..1f77b418 100644 --- a/accel-pppd/ctrl/ipoe/dhcpv4.c +++ b/accel-pppd/ctrl/ipoe/dhcpv4.c @@ -161,7 +161,7 @@ struct dhcpv4_serv *dhcpv4_create(struct triton_context_t *ctx, const char *ifna goto out_err; } - if (bind(sock, &addr, sizeof(addr))) { + if (bind(sock, (struct sockaddr*)&addr, sizeof(addr))) { log_error("bind: %s\n", strerror(errno)); goto out_err; } @@ -1012,12 +1012,12 @@ struct dhcpv4_relay *dhcpv4_relay_create(const char *_addr, in_addr_t giaddr, st if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &f, sizeof(f))) log_error("dhcpv4: setsockopt(SO_REUSEADDR): %s\n", strerror(errno)); - if (bind(sock, &laddr, sizeof(laddr))) { + if (bind(sock, (struct sockaddr*)&laddr, sizeof(laddr))) { log_error("dhcpv4: relay: %s: bind: %s\n", _addr, strerror(errno)); goto out_err_unlock; } - if (connect(sock, &raddr, sizeof(raddr))) { + if (connect(sock, (struct sockaddr*)&raddr, sizeof(raddr))) { log_error("dhcpv4: relay: %s: connect: %s\n", _addr, strerror(errno)); goto out_err_unlock; } diff --git a/accel-pppd/ctrl/ipoe/dhcpv4_options.c b/accel-pppd/ctrl/ipoe/dhcpv4_options.c index b5f2b3bf..0175dee7 100644 --- a/accel-pppd/ctrl/ipoe/dhcpv4_options.c +++ b/accel-pppd/ctrl/ipoe/dhcpv4_options.c @@ -46,7 +46,7 @@ static struct known_option options[] = { { 26, 2, 2, 2, "MTU", print_int }, { 28, 4, 4, 4, "Broadcast", print_ip }, { 33, 8, 255, 8, "Route", print_route }, - { 42, 4, 4, 4, "NTP", print_ip }, + { 42, 4, 255, 4, "NTP", print_ip }, { 43, 1, 255, 1, "Vendor-Specific", print_hex }, { 50, 4, 4, 4, "Request-IP", print_ip }, { 51, 4, 4, 4, "Lease-Time", print_uint }, diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index 95ff8568..52c4526b 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -20,8 +20,6 @@ #endif #include <linux/route.h> -#include <pcre.h> - #include "events.h" #include "list.h" #include "triton.h" @@ -56,7 +54,7 @@ #define SESSION_TERMINATED "Session was terminated" struct iplink_arg { - pcre *re; + pcre2_code *re; const char *opt; long *arg1; }; @@ -2804,10 +2802,10 @@ void ipoe_vlan_mon_notify(int ifindex, int vid, int vlan_ifindex) struct ifreq ifr; char *ptr; int len, r, svid; - pcre *re = NULL; - const char *pcre_err; + pcre2_code *re = NULL; + int pcre_err; char *pattern; - int pcre_offset; + PCRE2_SIZE pcre_offset; char ifname[IFNAMSIZ]; if (!sect) @@ -2905,15 +2903,17 @@ void ipoe_vlan_mon_notify(int ifindex, int vid, int vlan_ifindex) memcpy(pattern, opt->val + 3, ptr - (opt->val + 3)); pattern[ptr - (opt->val + 3)] = 0; - re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL); + re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL); _free(pattern); if (!re) continue; - r = pcre_exec(re, NULL, ifname, len, 0, 0, NULL, 0); - pcre_free(re); + pcre2_match_data *match_data = pcre2_match_data_create(0, NULL); + r = pcre2_match(re, (PCRE2_SPTR)ifname, len, 0, 0, match_data, NULL); + pcre2_match_data_free(match_data); + pcre2_code_free(re); if (r < 0) continue; @@ -3109,12 +3109,12 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (connect(sock, &addr, sizeof(addr))) { + if (connect(sock, (struct sockaddr*)&addr, sizeof(addr))) { log_error("dhcpv4: relay: %s: connect: %s\n", opt_relay, strerror(errno)); goto out_err; } - getsockname(sock, &addr, &len); + getsockname(sock, (struct sockaddr*)&addr, &len); opt_giaddr = addr.sin_addr.s_addr; close(sock); @@ -3358,8 +3358,12 @@ static void load_interface(const char *opt) static int __load_interface_re(int index, int flags, const char *name, int iflink, int vid, struct iplink_arg *arg) { - if (pcre_exec(arg->re, NULL, name, strlen(name), 0, 0, NULL, 0) < 0) + pcre2_match_data *match_data = pcre2_match_data_create(0, NULL); + if (pcre2_match(arg->re, (PCRE2_SPTR)name, strlen(name), 0, 0, match_data, NULL) < 0) { + pcre2_match_data_free(match_data); return 0; + } + pcre2_match_data_free(match_data); add_interface(name, index, arg->opt, iflink, vid, 0); @@ -3368,11 +3372,11 @@ static int __load_interface_re(int index, int flags, const char *name, int iflin static void load_interface_re(const char *opt) { - pcre *re = NULL; - const char *pcre_err; + pcre2_code *re = NULL; + int pcre_err; char *pattern; const char *ptr; - int pcre_offset; + PCRE2_SIZE pcre_offset; struct iplink_arg arg; struct ipoe_serv *serv; @@ -3382,10 +3386,12 @@ static void load_interface_re(const char *opt) memcpy(pattern, opt + 3, ptr - (opt + 3)); pattern[ptr - (opt + 3)] = 0; - re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL); + re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL); if (!re) { - log_error("ipoe: '%s': %s at %i\r\n", pattern, pcre_err, pcre_offset); + PCRE2_UCHAR err_msg[64]; + pcre2_get_error_message(pcre_err, err_msg, sizeof(err_msg)); + log_error("ipoe: '%s': %s at %i\r\n", pattern, err_msg, (int)pcre_offset); return; } @@ -3398,11 +3404,13 @@ static void load_interface_re(const char *opt) if (serv->active) continue; - if (pcre_exec(re, NULL, serv->ifname, strlen(serv->ifname), 0, 0, NULL, 0) >= 0) + pcre2_match_data *match_data = pcre2_match_data_create(0, NULL); + if (pcre2_match(re, (PCRE2_SPTR)serv->ifname, strlen(serv->ifname), 0, 0, match_data, NULL) >= 0) add_interface(serv->ifname, serv->ifindex, opt, 0, 0, 0); + pcre2_match_data_free(match_data); } - pcre_free(re); + pcre2_code_free(re); _free(pattern); } @@ -3670,8 +3678,12 @@ static int __load_vlan_mon_re(int index, int flags, const char *name, int iflink long mask1[4096/8/sizeof(long)]; struct ipoe_serv *serv; - if (pcre_exec(arg->re, NULL, name, strlen(name), 0, 0, NULL, 0) < 0) + pcre2_match_data *match_data = pcre2_match_data_create(0, NULL); + if (pcre2_match(arg->re, (PCRE2_SPTR)name, strlen(name), 0, 0, match_data, NULL) < 0) { + pcre2_match_data_free(match_data); return 0; + } + pcre2_match_data_free(match_data); if (!(flags & IFF_UP)) { memset(&ifr, 0, sizeof(ifr)); @@ -3701,11 +3713,11 @@ static int __load_vlan_mon_re(int index, int flags, const char *name, int iflink static void load_vlan_mon_re(const char *opt, long *mask, int len) { - pcre *re = NULL; - const char *pcre_err; + pcre2_code *re = NULL; + int pcre_err; char *pattern; const char *ptr; - int pcre_offset; + PCRE2_SIZE pcre_offset; struct iplink_arg arg; for (ptr = opt; *ptr && *ptr != ','; ptr++); @@ -3714,10 +3726,12 @@ static void load_vlan_mon_re(const char *opt, long *mask, int len) memcpy(pattern, opt + 3, ptr - (opt + 3)); pattern[ptr - (opt + 3)] = 0; - re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL); + re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL); if (!re) { - log_error("ipoe: '%s': %s at %i\r\n", pattern, pcre_err, pcre_offset); + PCRE2_UCHAR err_msg[64]; + pcre2_get_error_message(pcre_err, err_msg, sizeof(err_msg)); + log_error("ipoe: '%s': %s at %i\r\n", pattern, err_msg, (int)pcre_offset); return; } @@ -3727,7 +3741,7 @@ static void load_vlan_mon_re(const char *opt, long *mask, int len) iplink_list((iplink_list_func)__load_vlan_mon_re, &arg); - pcre_free(re); + pcre2_code_free(re); _free(pattern); } diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c index bb1d1699..19cd9077 100644 --- a/accel-pppd/ctrl/l2tp/l2tp.c +++ b/accel-pppd/ctrl/l2tp/l2tp.c @@ -123,6 +123,11 @@ struct l2tp_sess_t struct l2tp_conn_t *paren_conn; uint16_t sid; uint16_t peer_sid; +/* We will keep l2tp attributes Calling-Number/Called-Number and their length while the session exists */ + char *calling_num; + int calling_num_len; + char *called_num; + int called_num_len; unsigned int ref_count; int state1; @@ -983,6 +988,10 @@ static void __session_destroy(struct l2tp_sess_t *sess) _free(sess->ctrl.calling_station_id); if (sess->ctrl.called_station_id) _free(sess->ctrl.called_station_id); + if (sess->calling_num) + _free(sess->calling_num); + if (sess->called_num) + _free(sess->called_num); log_session(log_info2, sess, "session destroyed\n"); @@ -1613,7 +1622,7 @@ static struct l2tp_conn_t *l2tp_tunnel_alloc(const struct sockaddr_in *peer, strerror(errno)); goto err_conn_fd; } - if (bind(conn->hnd.fd, host, sizeof(*host))) { + if (bind(conn->hnd.fd, (struct sockaddr*)host, sizeof(*host))) { log_error("l2tp: impossible to allocate new tunnel:" " bind() failed: %s\n", strerror(errno)); goto err_conn_fd; @@ -1646,7 +1655,7 @@ static struct l2tp_conn_t *l2tp_tunnel_alloc(const struct sockaddr_in *peer, goto err_conn_fd; } - if (getsockname(conn->hnd.fd, &conn->host_addr, &hostaddrlen) < 0) { + if (getsockname(conn->hnd.fd, (struct sockaddr*)&conn->host_addr, &hostaddrlen) < 0) { log_error("l2tp: impossible to allocate new tunnel:" " getsockname() failed: %s\n", strerror(errno)); goto err_conn_fd; @@ -1747,7 +1756,7 @@ static inline int l2tp_tunnel_update_peerport(struct l2tp_conn_t *conn, int res; conn->peer_addr.sin_port = port_nbo; - res = connect(conn->hnd.fd, &conn->peer_addr, sizeof(conn->peer_addr)); + res = connect(conn->hnd.fd, (struct sockaddr*)&conn->peer_addr, sizeof(conn->peer_addr)); if (res < 0) { log_tunnel(log_error, conn, "impossible to update peer port from %hu to %hu:" @@ -1775,25 +1784,52 @@ static int l2tp_session_start_data_channel(struct l2tp_sess_t *sess) sess->ctrl.max_mtu = conf_ppp_max_mtu; sess->ctrl.mppe = conf_mppe; - sess->ctrl.calling_station_id = _malloc(17); - if (sess->ctrl.calling_station_id == NULL) { - log_session(log_error, sess, - "impossible to start data channel:" - " allocation of calling station ID failed\n"); - goto err; + /* If l2tp calling number avp exists, we use it, otherwise we use lac ip */ + if (sess->calling_num != NULL) { + sess->ctrl.calling_station_id = _malloc(sess->calling_num_len+1); + if (sess->ctrl.calling_station_id == NULL) { + log_session(log_error, sess, + "impossible to start data channel:" + " allocation of calling station ID failed\n"); + goto err; + }else { + strcpy(sess->ctrl.calling_station_id, sess->calling_num); + } + } else { + sess->ctrl.calling_station_id = _malloc(17); + if (sess->ctrl.calling_station_id == NULL) { + log_session(log_error, sess, + "impossible to start data channel:" + " allocation of calling station ID failed\n"); + goto err; + } else { + u_inet_ntoa(sess->paren_conn->peer_addr.sin_addr.s_addr, + sess->ctrl.calling_station_id); + } } - u_inet_ntoa(sess->paren_conn->peer_addr.sin_addr.s_addr, - sess->ctrl.calling_station_id); - - sess->ctrl.called_station_id = _malloc(17); - if (sess->ctrl.called_station_id == NULL) { - log_session(log_error, sess, - "impossible to start data channel:" - " allocation of called station ID failed\n"); - goto err; + /* If l2tp called number avp exists, we use it, otherwise we use my ip */ + if (sess->called_num != NULL) { + sess->ctrl.called_station_id = _malloc(sess->called_num_len+1); + if (sess->ctrl.called_station_id == NULL) { + log_session(log_error, sess, + "impossible to start data channel:" + " allocation of called station ID failed\n"); + goto err; + } else { + strcpy(sess->ctrl.called_station_id, sess->called_num); + } + } else { + sess->ctrl.called_station_id = _malloc(17); + if (sess->ctrl.called_station_id == NULL) { + log_session(log_error, sess, + "impossible to start data channel:" + " allocation of called station ID failed\n"); + goto err; + } else { + u_inet_ntoa(sess->paren_conn->host_addr.sin_addr.s_addr, + sess->ctrl.called_station_id); + } } - u_inet_ntoa(sess->paren_conn->host_addr.sin_addr.s_addr, - sess->ctrl.called_station_id); if (conf_ip_pool) { sess->ppp.ses.ipv4_pool_name = _strdup(conf_ip_pool); @@ -3299,6 +3335,10 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn, uint16_t sid = 0; uint16_t res = 0; uint16_t err = 0; + uint8_t *calling[254] = {0}; + uint8_t *called[254] = {0}; + int n = 0; + int m = 0; if (conn->state != STATE_ESTB && conn->lns_mode) { log_tunnel(log_warn, conn, "discarding unexpected ICRQ\n"); @@ -3336,7 +3376,17 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn, case Call_Serial_Number: case Bearer_Type: case Calling_Number: + /* Save Calling-Number L2TP attribute locally */ + if (attr->attr->id == Calling_Number) { + n = attr->length; + memcpy(calling,attr->val.octets,n); + } case Called_Number: + /* Save Called-Number L2TP attribute locally */ + if (attr->attr->id == Called_Number) { + m = attr->length; + memcpy(called,attr->val.octets,m); + } case Sub_Address: case Physical_Channel_ID: break; @@ -3375,6 +3425,30 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn, sess->peer_sid = peer_sid; sid = sess->sid; + /* Allocate memory for Calling-Number if exists, and put it to l2tp_sess_t structure */ + if (calling != NULL && n > 0) { + sess->calling_num = _malloc(n+1); + if (sess->calling_num == NULL) { + log_tunnel(log_warn, conn, "can't allocate memory for Calling Number attribute. Will use LAC IP instead\n"); + }else{ + memcpy(sess->calling_num, calling, n); + sess->calling_num[n] = '\0'; + sess->calling_num_len = n; + } + } + + /* Allocate memory for Called-Number if exists, and put it to l2tp_sess_t structure */ + if (called != NULL && m > 1) { + sess->called_num = _malloc(m+1); + if (sess->called_num == NULL) { + log_tunnel(log_warn, conn, "can't allocate memory for Called Number attribute. Will use my IP instead\n"); + } else { + memcpy(sess->called_num, called, m); + sess->called_num[m] = '\0'; + sess->called_num_len = m; + } + } + if (unknown_attr) { log_tunnel(log_error, conn, "impossible to handle ICRQ:" " unknown mandatory attribute type %i," @@ -3394,8 +3468,8 @@ static int l2tp_recv_ICRQ(struct l2tp_conn_t *conn, goto out_reject; } - log_tunnel(log_info1, conn, "new session %hu-%hu created following" - " reception of ICRQ\n", sid, peer_sid); + log_tunnel(log_info1, conn, "new session %hu-%hu with calling num %s len %d, called num %s len %d created following" + " reception of ICRQ\n", sid, peer_sid, sess->calling_num, sess->calling_num_len, sess->called_num, sess->called_num_len); return 0; diff --git a/accel-pppd/ctrl/l2tp/packet.c b/accel-pppd/ctrl/l2tp/packet.c index 97e205f3..e2756a7e 100644 --- a/accel-pppd/ctrl/l2tp/packet.c +++ b/accel-pppd/ctrl/l2tp/packet.c @@ -280,7 +280,7 @@ int l2tp_recv(int fd, struct l2tp_packet_t **p, struct in_pktinfo *pkt_info, ptr = (uint8_t *)(hdr + 1); addr_len = sizeof(addr); - n = recvfrom(fd, buf, L2TP_MAX_PACKET_SIZE, 0, &addr, &addr_len); + n = recvfrom(fd, buf, L2TP_MAX_PACKET_SIZE, 0, (struct sockaddr*)&addr, &addr_len); if (n < 0) { mempool_free(buf); if (errno == EAGAIN) { @@ -552,7 +552,7 @@ int l2tp_packet_send(int sock, struct l2tp_packet_t *pack) memcpy(buf, &pack->hdr, sizeof(pack->hdr)); hdr->flags = htons(pack->hdr.flags); - n = sendto(sock, buf, len, 0, &pack->addr, sizeof(pack->addr)); + n = sendto(sock, buf, len, 0, (struct sockaddr*)&pack->addr, sizeof(pack->addr)); mempool_free(buf); if (n < 0) { diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c index dd623acc..c8007414 100644 --- a/accel-pppd/ctrl/pppoe/pppoe.c +++ b/accel-pppd/ctrl/pppoe/pppoe.c @@ -83,7 +83,7 @@ struct padi_t }; struct iplink_arg { - pcre *re; + pcre2_code *re; const char *opt; void *cli; long *arg1; @@ -1368,8 +1368,12 @@ out_err: static int __pppoe_add_interface_re(int index, int flags, const char *name, int iflink, int vid, struct iplink_arg *arg) { - if (pcre_exec(arg->re, NULL, name, strlen(name), 0, 0, NULL, 0) < 0) + pcre2_match_data *match_data = pcre2_match_data_create(0, NULL); + if (pcre2_match(arg->re, (PCRE2_SPTR)name, strlen(name), 0, 0, match_data, NULL) < 0) { + pcre2_match_data_free(match_data); return 0; + } + pcre2_match_data_free(match_data); __pppoe_server_start(name, arg->opt, arg->cli, iflink, vid, 0); @@ -1378,11 +1382,11 @@ static int __pppoe_add_interface_re(int index, int flags, const char *name, int static void pppoe_add_interface_re(const char *opt, void *cli) { - pcre *re = NULL; - const char *pcre_err; + pcre2_code *re = NULL; + int pcre_err; char *pattern; const char *ptr; - int pcre_offset; + PCRE2_SIZE pcre_offset; struct iplink_arg arg; for (ptr = opt; *ptr && *ptr != ','; ptr++); @@ -1391,10 +1395,14 @@ static void pppoe_add_interface_re(const char *opt, void *cli) memcpy(pattern, opt + 3, ptr - (opt + 3)); pattern[ptr - (opt + 3)] = 0; - re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL); + re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL); if (!re) { - log_error("pppoe: %s at %i\r\n", pcre_err, pcre_offset); + PCRE2_UCHAR err_msg[64]; + pcre2_get_error_message(pcre_err, err_msg, sizeof(err_msg)); + if (cli) + cli_sendv(cli, "pppoe: %s at %i\r\n", err_msg, (int)pcre_offset); + log_error("pppoe: %s at %i\r\n", err_msg, (int)pcre_offset); return; } @@ -1404,7 +1412,7 @@ static void pppoe_add_interface_re(const char *opt, void *cli) iplink_list((iplink_list_func)__pppoe_add_interface_re, &arg); - pcre_free(re); + pcre2_code_free(re); _free(pattern); } @@ -1676,10 +1684,10 @@ void pppoe_vlan_mon_notify(int ifindex, int vid, int vlan_ifindex) struct ifreq ifr; char *ptr; int len, r, svid; - pcre *re = NULL; - const char *pcre_err; + pcre2_code *re = NULL; + int pcre_err; char *pattern; - int pcre_offset; + PCRE2_SIZE pcre_offset; char ifname[IFNAMSIZ]; if (!sect) @@ -1777,15 +1785,17 @@ void pppoe_vlan_mon_notify(int ifindex, int vid, int vlan_ifindex) memcpy(pattern, opt->val + 3, ptr - (opt->val + 3)); pattern[ptr - (opt->val + 3)] = 0; - re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL); + re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL); _free(pattern); if (!re) continue; - r = pcre_exec(re, NULL, ifr.ifr_name, len, 0, 0, NULL, 0); - pcre_free(re); + pcre2_match_data *match_data = pcre2_match_data_create(0, NULL); + r = pcre2_match(re, (PCRE2_SPTR)ifr.ifr_name, len, 0, 0, match_data, NULL); + pcre2_match_data_free(match_data); + pcre2_code_free(re); if (r < 0) continue; @@ -1860,8 +1870,12 @@ static int __load_vlan_mon_re(int index, int flags, const char *name, int iflink long mask1[4096/8/sizeof(long)]; struct pppoe_serv_t *serv; - if (pcre_exec(arg->re, NULL, name, strlen(name), 0, 0, NULL, 0) < 0) + pcre2_match_data *match_data = pcre2_match_data_create(0, NULL); + if (pcre2_match(arg->re, (PCRE2_SPTR)name, strlen(name), 0, 0, match_data, NULL) < 0) { + pcre2_match_data_free(match_data); return 0; + } + pcre2_match_data_free(match_data); memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, name); @@ -1894,11 +1908,11 @@ static int __load_vlan_mon_re(int index, int flags, const char *name, int iflink static void load_vlan_mon_re(const char *opt, long *mask, int len) { - pcre *re = NULL; - const char *pcre_err; + pcre2_code *re = NULL; + int pcre_err; char *pattern; const char *ptr; - int pcre_offset; + PCRE2_SIZE pcre_offset; struct iplink_arg arg; for (ptr = opt; *ptr && *ptr != ','; ptr++); @@ -1907,10 +1921,12 @@ static void load_vlan_mon_re(const char *opt, long *mask, int len) memcpy(pattern, opt + 3, ptr - (opt + 3)); pattern[ptr - (opt + 3)] = 0; - re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL); + re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &pcre_err, &pcre_offset, NULL); if (!re) { - log_error("pppoe: '%s': %s at %i\r\n", pattern, pcre_err, pcre_offset); + PCRE2_UCHAR err_msg[64]; + pcre2_get_error_message(pcre_err, err_msg, sizeof(err_msg)); + log_error("pppoe: '%s': %s at %i\r\n", pattern, err_msg, (int)pcre_offset); return; } @@ -1920,7 +1936,7 @@ static void load_vlan_mon_re(const char *opt, long *mask, int len) iplink_list((iplink_list_func)__load_vlan_mon_re, &arg); - pcre_free(re); + pcre2_code_free(re); _free(pattern); } diff --git a/accel-pppd/ctrl/pptp/pptp.c b/accel-pppd/ctrl/pptp/pptp.c index a95fe8ae..24984db8 100644 --- a/accel-pppd/ctrl/pptp/pptp.c +++ b/accel-pppd/ctrl/pptp/pptp.c @@ -142,8 +142,8 @@ again: if (errno != EPIPE) { if (conf_verbose) log_ppp_info2("pptp: write: %s\n", strerror(errno)); - return -1; } + return -1; } } @@ -708,7 +708,7 @@ static int pptp_connect(struct triton_md_handler_t *h) conn->ctrl.calling_station_id = _malloc(17); conn->ctrl.called_station_id = _malloc(17); u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.calling_station_id); - getsockname(sock, &addr, &size); + getsockname(sock, (struct sockaddr*)&addr, &size); u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.called_station_id); ppp_init(&conn->ppp); diff --git a/accel-pppd/ctrl/sstp/sstp.c b/accel-pppd/ctrl/sstp/sstp.c index 2e2c4d3b..2a9ddae3 100644 --- a/accel-pppd/ctrl/sstp/sstp.c +++ b/accel-pppd/ctrl/sstp/sstp.c @@ -187,6 +187,7 @@ static unsigned int stat_active; static inline void sstp_queue(struct sstp_conn_t *conn, struct buffer_t *buf); static int sstp_send(struct sstp_conn_t *conn, struct buffer_t *buf); static inline void sstp_queue_deferred(struct sstp_conn_t *conn, struct buffer_t *buf); +static int sstp_write(struct triton_md_handler_t *h); static int sstp_read_deferred(struct sstp_conn_t *conn); static int sstp_abort(struct sstp_conn_t *conn, int disconnect); static void sstp_disconnect(struct sstp_conn_t *conn); @@ -858,7 +859,7 @@ static int http_send_response(struct sstp_conn_t *conn, char *proto, char *statu } } - return sstp_send(conn, buf); + return sstp_send(conn, buf) || sstp_write(&conn->hnd); } static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len) @@ -937,7 +938,7 @@ static int http_handler(struct sstp_conn_t *conn, struct buffer_t *buf) static const char *table[] = { "\n\r\n", "\r\r\n", NULL }; const char **pptr; uint8_t *ptr, *end = NULL; - int n; + int n, r; if (conn->sstp_state != STATE_SERVER_CALL_DISCONNECTED) return -1; @@ -963,8 +964,11 @@ static int http_handler(struct sstp_conn_t *conn, struct buffer_t *buf) } else n = end - buf->head; - if (http_recv_request(conn, buf->head, n) < 0) + r = http_recv_request(conn, buf->head, n); + if (r < 0) return -1; + else if (r > 0) + return 1; buf_pull(buf, n); conn->sstp_state = STATE_SERVER_CONNECT_REQUEST_PENDING; @@ -1950,6 +1954,8 @@ static int sstp_read(struct triton_md_handler_t *h) n = conn->handler(conn, buf); if (n < 0) goto drop; + else if (n > 0) + return 1; buf_expand_tail(buf, SSTP_MAX_PACKET_SIZE); } diff --git a/accel-pppd/extra/logwtmp.c b/accel-pppd/extra/logwtmp.c index f95b62c4..f66e6403 100644 --- a/accel-pppd/extra/logwtmp.c +++ b/accel-pppd/extra/logwtmp.c @@ -14,6 +14,7 @@ #include "memdebug.h" +#ifdef HAVE_LOGWTMP static void ev_ses_started(struct ap_session *ses) { logwtmp(ses->ifname, ses->username ?: "", ses->ctrl->calling_station_id); @@ -29,5 +30,11 @@ static void init(void) triton_event_register_handler(EV_SES_STARTED, (triton_event_func)ev_ses_started); triton_event_register_handler(EV_SES_FINISHED, (triton_event_func)ev_ses_finished); } +#else +static void init(void) +{ + log_warn("logwtmp is not supported on your platfrom, check libc doc\n"); +} +#endif DEFINE_INIT(200, init); diff --git a/accel-pppd/extra/pppd_compat.c b/accel-pppd/extra/pppd_compat.c index 040e7d90..12363cd4 100644 --- a/accel-pppd/extra/pppd_compat.c +++ b/accel-pppd/extra/pppd_compat.c @@ -518,6 +518,10 @@ static void write_radattr(struct pppd_compat_pd *pd, struct rad_packet_t *pack) int fd, i; in_addr_t addr; char ip_str[50]; + union { + uint64_t ifid; + uint16_t u16[4]; + } ifid_u; if (ses->state == AP_STATE_ACTIVE) { sprintf(fname1, "%s.%s", conf_radattr_prefix, ses->ifname); @@ -572,6 +576,10 @@ static void write_radattr(struct pppd_compat_pd *pd, struct rad_packet_t *pack) inet_ntop(AF_INET6, &attr->val.ipv6addr, ip_str, sizeof(ip_str)); fprintf(f, "%s\n", ip_str); break; + case ATTR_TYPE_IFID: + ifid_u.ifid = attr->val.ifid; + fprintf(f, "%x:%x:%x:%x\n", ntohs(ifid_u.u16[0]), ntohs(ifid_u.u16[1]), ntohs(ifid_u.u16[2]), ntohs(ifid_u.u16[3])); + break; } } fclose(f); diff --git a/accel-pppd/ipv6/dhcpv6.c b/accel-pppd/ipv6/dhcpv6.c index 77fc32f7..85863e0c 100644 --- a/accel-pppd/ipv6/dhcpv6.c +++ b/accel-pppd/ipv6/dhcpv6.c @@ -752,6 +752,32 @@ static void dhcpv6_recv_rebind(struct dhcpv6_packet *req) dhcpv6_send_reply2(req, pd, D6_REPLY); } +static void dhcpv6_recv_confirm(struct dhcpv6_packet *req) +{ + struct dhcpv6_pd *pd = req->pd; + + if (!req->clientid) { + log_ppp_error("dhcpv6: no Client-ID option\n"); + return; + } + + if (req->serverid) { + log_ppp_error("dhcpv6: unexcpected Server-ID option\n"); + return; + } + + if (!pd->clientid) + return; + else if (pd->clientid->hdr.len != req->clientid->hdr.len || memcmp(pd->clientid, req->clientid, sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len))) { + log_ppp_error("dhcpv6: unmatched Client-ID option\n"); + return; + } + + req->serverid = conf_serverid; + + dhcpv6_send_reply(req, pd, D6_REPLY); +} + static void dhcpv6_recv_release(struct dhcpv6_packet *pkt) { // don't answer @@ -783,6 +809,9 @@ static void dhcpv6_recv_packet(struct dhcpv6_packet *pkt) case D6_REBIND: dhcpv6_recv_rebind(pkt); break; + case D6_CONFIRM: + dhcpv6_recv_confirm(pkt); + break; case D6_RELEASE: dhcpv6_recv_release(pkt); break; diff --git a/accel-pppd/libnetlink/iputils.c b/accel-pppd/libnetlink/iputils.c index 23325fcd..4bf7fd01 100644 --- a/accel-pppd/libnetlink/iputils.c +++ b/accel-pppd/libnetlink/iputils.c @@ -213,7 +213,8 @@ int __export iplink_vlan_add(const char *ifname, int ifindex, int vid) data = NLMSG_TAIL(&req.n); addattr_l(&req.n, 4096, IFLA_INFO_DATA, NULL, 0); - addattr_l(&req.n, 4096, IFLA_VLAN_ID, &vid, 2); + uint16_t vid_16b = (uint16_t)vid; + addattr_l(&req.n, 4096, IFLA_VLAN_ID, &vid_16b, 2); data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo; diff --git a/accel-pppd/logs/log_tcp.c b/accel-pppd/logs/log_tcp.c index e0663d34..ca803a7e 100644 --- a/accel-pppd/logs/log_tcp.c +++ b/accel-pppd/logs/log_tcp.c @@ -163,7 +163,7 @@ static int log_tcp_connect(struct triton_md_handler_t *h) { struct tcp_target_t *t = container_of(h, typeof(*t), hnd); - if (connect(t->hnd.fd, &t->addr, sizeof(t->addr))) { + if (connect(t->hnd.fd, (struct sockaddr*)&t->addr, sizeof(t->addr))) { if (errno == EAGAIN) return 0; if (errno == EINPROGRESS) @@ -216,7 +216,7 @@ static void start_connect(struct tcp_target_t *t) return; } - if (connect(t->hnd.fd, &t->addr, sizeof(t->addr))) { + if (connect(t->hnd.fd, (struct sockaddr*)&t->addr, sizeof(t->addr))) { if (errno != EINPROGRESS) { log_emerg("log-tcp: connect: %s\n", strerror(errno)); close(t->hnd.fd); diff --git a/accel-pppd/ppp/ppp_lcp.c b/accel-pppd/ppp/ppp_lcp.c index 10babec8..c5f9f2de 100644 --- a/accel-pppd/ppp/ppp_lcp.c +++ b/accel-pppd/ppp/ppp_lcp.c @@ -16,6 +16,10 @@ #include "memdebug.h" +#ifndef min +#define min(x,y) ((x)<(y)?(x):(y)) +#endif + struct recv_opt_t { struct list_head entry; @@ -615,7 +619,7 @@ static void send_echo_reply(struct ppp_lcp_t *lcp) if (conf_ppp_verbose) log_ppp_debug("send [LCP EchoRep id=%x <magic %08x>]\n", hdr->id, lcp->magic); - ppp_chan_send(lcp->ppp, hdr, ntohs(hdr->len) + 2); + ppp_chan_send(lcp->ppp, hdr, min(ntohs(hdr->len), lcp->ppp->mtu) + 2); } static void send_echo_request(struct triton_timer_t *t) diff --git a/accel-pppd/radius/packet.c b/accel-pppd/radius/packet.c index 79007036..3c2ef99d 100644 --- a/accel-pppd/radius/packet.c +++ b/accel-pppd/radius/packet.c @@ -139,7 +139,7 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr) while (1) { if (addr) - n = recvfrom(fd, pack->buf, REQ_LENGTH_MAX, 0, addr, &addr_len); + n = recvfrom(fd, pack->buf, REQ_LENGTH_MAX, 0, (struct sockaddr *)addr, &addr_len); else n = read(fd, pack->buf, REQ_LENGTH_MAX); if (n < 0) { @@ -813,7 +813,7 @@ int rad_packet_send(struct rad_packet_t *pack, int fd, struct sockaddr_in *addr) while (1) { if (addr) - n = sendto(fd, pack->buf, pack->len, 0, addr, sizeof(*addr)); + n = sendto(fd, pack->buf, pack->len, 0, (struct sockaddr *)addr, sizeof(*addr)); else n = write(fd, pack->buf, pack->len); if (n < 0) { diff --git a/accel-pppd/session.c b/accel-pppd/session.c index c01417f3..74b39475 100644 --- a/accel-pppd/session.c +++ b/accel-pppd/session.c @@ -30,6 +30,14 @@ #define SID_SOURCE_SEQ 0 #define SID_SOURCE_URANDOM 1 +#ifndef __WORDSIZE +#if defined(__GLIBC__) || defined(__UCLIBC__) +#include <bits/wordsize.h> +#else +#include <bits/reg.h> +#endif +#endif + static int conf_sid_ucase; static int conf_single_session = -1; static int conf_single_session_ignore_case; diff --git a/cmake/cpack.cmake b/cmake/cpack.cmake index 3dfc2750..c004075c 100644 --- a/cmake/cpack.cmake +++ b/cmake/cpack.cmake @@ -20,73 +20,53 @@ SET(CPACK_PACKAGE_VENDOR "Dmitry Kozlov") SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README") SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") -IF(CPACK_TYPE STREQUAL Debian5) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.7), libssl0.9.8 (>= 0.9.8), libpcre3 (>= 7.6)") - INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) -ENDIF(CPACK_TYPE STREQUAL Debian5) - -IF(CPACK_TYPE STREQUAL Debian6) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libssl0.9.8 (>= 0.9.8), libpcre3 (>= 8.02)") - INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) -ENDIF(CPACK_TYPE STREQUAL Debian6) - -IF(CPACK_TYPE STREQUAL Debian7) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.13), libssl1.0.0 (>= 1.0.0), libpcre3 (>= 8.30)") - INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) -ENDIF(CPACK_TYPE STREQUAL Debian7) - -IF(CPACK_TYPE STREQUAL Debian8) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.19), libssl1.0.0 (>= 1.0.1k), libpcre3 (>= 8.35)") - INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) -ENDIF(CPACK_TYPE STREQUAL Debian8) - IF(CPACK_TYPE STREQUAL Debian9) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.24), libssl1.0.2 (>= 1.0.2l), libpcre3 (>= 8.39)") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.24), libssl1.0.2 (>= 1.0.2l), libpcre2-8-0 (>= 10.22)") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) ENDIF(CPACK_TYPE STREQUAL Debian9) IF(CPACK_TYPE STREQUAL Debian10) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.28), libssl1.1 (>= 1.1.1c), libpcre3 (>= 8.39)") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.28), libssl1.1 (>= 1.1.1c), libpcre2-8-0 (>= 10.32)") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) ENDIF(CPACK_TYPE STREQUAL Debian10) IF(CPACK_TYPE STREQUAL Debian11) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.31), libssl1.1 (>= 1.1.1k), libpcre3 (>= 8.39)") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.31), libssl1.1 (>= 1.1.1k), libpcre2-8-0 (>= 10.36)") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) ENDIF(CPACK_TYPE STREQUAL Debian11) IF(CPACK_TYPE STREQUAL Debian12) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.34), libssl3 (>= 3.0.5), libpcre3 (>= 8.39)") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.34), libssl3 (>= 3.0.5), libpcre2-8-0 (>= 10.42)") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) ENDIF(CPACK_TYPE STREQUAL Debian12) IF(CPACK_TYPE STREQUAL Debian13) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.37), libssl3 (>= 3.0.9), libpcre3 (>= 8.39)") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.37), libssl3 (>= 3.0.9), libpcre2-8-0 (>= 10.42)") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) ENDIF(CPACK_TYPE STREQUAL Debian13) IF(CPACK_TYPE STREQUAL Ubuntu16) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.23), libssl1.0.0 (>= 1.0.0), libpcre3 (>= 8.39)") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.23), libssl1.0.0 (>= 1.0.0), libpcre2-8-0 (>= 10.21)") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) ENDIF(CPACK_TYPE STREQUAL Ubuntu16) IF(CPACK_TYPE STREQUAL Ubuntu18) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.24), libssl1.0.0 (>= 1.0.2n), libpcre3 (>= 8.39)") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.24), libssl1.0.0 (>= 1.0.2n), libpcre2-8-0 (>= 10.31)") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) ENDIF(CPACK_TYPE STREQUAL Ubuntu18) IF(CPACK_TYPE STREQUAL Ubuntu20) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.31), libssl1.1 (>= 1.1.1d), libpcre3 (>= 8.39)") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.31), libssl1.1 (>= 1.1.1d), libpcre2-8-0 (>= 10.34)") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) ENDIF(CPACK_TYPE STREQUAL Ubuntu20) IF(CPACK_TYPE STREQUAL Ubuntu22) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.35), libssl3 (>= 3.0.2), libpcre3 (>= 8.39)") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.35), libssl3 (>= 3.0.2), libpcre2-8-0 (>= 10.39)") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) ENDIF(CPACK_TYPE STREQUAL Ubuntu22) IF(CPACK_TYPE STREQUAL Ubuntu24) - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.35), libssl3 (>= 3.0.2), libpcre3 (>= 8.39)") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.35), libssl3 (>= 3.0.2), libpcre2-8-0 (>= 10.42)") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/debian/debian.cmake) ENDIF(CPACK_TYPE STREQUAL Ubuntu24) @@ -94,7 +74,7 @@ IF(CPACK_TYPE STREQUAL Centos7) SET(CPACK_RPM_PACKAGE_LICENSE "GPL") SET(CPACK_RPM_PACKAGE_URL "http://accel-ppp.org") SET(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/usr/sbin") - SET(CPACK_RPM_PACKAGE_REQUIRES "glibc >= 2.17, openssl-libs >= 1.0.2k, pcre >= 8.32") + SET(CPACK_RPM_PACKAGE_REQUIRES "glibc >= 2.17, openssl-libs >= 1.0.2k, pcre2 >= 10.23") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/centos/centos.cmake) ENDIF() @@ -102,7 +82,7 @@ IF(CPACK_TYPE STREQUAL Centos8) SET(CPACK_RPM_PACKAGE_LICENSE "GPL") SET(CPACK_RPM_PACKAGE_URL "http://accel-ppp.org") SET(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/usr/sbin") - SET(CPACK_RPM_PACKAGE_REQUIRES "glibc >= 2.28, openssl-libs >= 1.1.1, pcre >= 8.42") + SET(CPACK_RPM_PACKAGE_REQUIRES "glibc >= 2.28, openssl-libs >= 1.1.1, pcre2 >= 10.32") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/centos/centos.cmake) ENDIF() @@ -110,7 +90,7 @@ IF(CPACK_TYPE STREQUAL Centos9) SET(CPACK_RPM_PACKAGE_LICENSE "GPL") SET(CPACK_RPM_PACKAGE_URL "http://accel-ppp.org") SET(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/usr/sbin") - SET(CPACK_RPM_PACKAGE_REQUIRES "glibc >= 2.34, openssl-libs >= 3.0.1, pcre >= 8.44") + SET(CPACK_RPM_PACKAGE_REQUIRES "glibc >= 2.34, openssl-libs >= 3.0.1, pcre2 >= 10.40") INCLUDE(${CMAKE_HOME_DIRECTORY}/cmake/centos/centos.cmake) ENDIF() diff --git a/drivers/ipoe/ipoe.c b/drivers/ipoe/ipoe.c index fa7dec3f..c6b88620 100644 --- a/drivers/ipoe/ipoe.c +++ b/drivers/ipoe/ipoe.c @@ -1105,7 +1105,11 @@ static void ipoe_netdev_setup(struct net_device *dev) dev->iflink = 0; #endif dev->addr_len = ETH_ALEN; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,12,0) + dev->netns_local = true; +#else dev->features |= NETIF_F_NETNS_LOCAL; +#endif dev->features &= ~(NETIF_F_HW_VLAN_FILTER | NETIF_F_LRO); dev->header_ops = &ipoe_hard_header_ops; dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; diff --git a/tests/README.md b/tests/README.md index d062ed46..689a16d8 100644 --- a/tests/README.md +++ b/tests/README.md @@ -6,7 +6,7 @@ These tests are done for Ubuntu and Debian distros. Please use latest stable Deb Install pytest -Using apt: `sudo apt install python3-pytest python3-pytest-dependency` or using pip: `sudo pip3 install pytest pytest-dependency`. +Using apt: `sudo apt install python3-pytest python3-pytest-dependency python3-pytest-order` or using pip: `sudo pip3 install pytest pytest-dependency pytest-order`. pytest-dependency version must be >= 0.5 (with 'scope' support) @@ -43,13 +43,13 @@ sudo insmod build/drivers/ipoe/driver/ipoe.ko ```bash # from this dir (tests) -sudo python3 -m pytest -Wall -v +sudo python3 -m pytest -Wall --order-dependencies -v ``` To skip tests related to ipoe and vlan_mon kernel modules: ```bash # from this dir (tests) -sudo python3 -m pytest -Wall -v -m "not ipoe_driver and not vlan_mon_driver" +sudo python3 -m pytest -Wall --order-dependencies -v -m "not ipoe_driver and not vlan_mon_driver" ``` ## Preparations (for coverage report) @@ -83,7 +83,7 @@ Then insert kernel modules (ipoe.ko and vlan-mon.ko) ```bash # from root dir (parent for this dir) -sudo python3 -m pytest -Wall tests -v # execute tests to collect coverage data +sudo python3 -m pytest -Wall --order-dependencies tests -v # execute tests to collect coverage data mkdir tests/report gcovr --config=tests/gcovr.conf # default report gcovr --config=tests/gcovr.conf --csv # csv report diff --git a/tests/accel-pppd/test_basic.py b/tests/accel-pppd/general/test_basic.py index 2b2c6f71..9652ee0b 100644 --- a/tests/accel-pppd/test_basic.py +++ b/tests/accel-pppd/general/test_basic.py @@ -19,9 +19,11 @@ def accel_pppd_config(): log_tcp #log_pgsql + connlimit pptp l2tp sstp + radius pppoe ipoe @@ -30,7 +32,6 @@ def accel_pppd_config(): auth_chap_md5 auth_pap - radius chap-secrets ippool @@ -39,7 +40,6 @@ def accel_pppd_config(): shaper #net-snmp logwtmp - connlimit ipv6_nd ipv6_dhcp diff --git a/tests/accel-pppd/general/test_pcre_negative_cases.py b/tests/accel-pppd/general/test_pcre_negative_cases.py new file mode 100644 index 00000000..698c83ab --- /dev/null +++ b/tests/accel-pppd/general/test_pcre_negative_cases.py @@ -0,0 +1,65 @@ +import pytest +from common import process + + +@pytest.fixture() +def accel_pppd_config(): + return """ + [modules] + radius + pppoe + + [core] + log-error=/dev/stderr + + [log] + log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr + level=5 + + [cli] + tcp=127.0.0.1:2001 + + [radius] + + [pppoe] + """ + + +# test pcre-related negative cases +def test_pcre_negative_cases(accel_pppd_instance, accel_cmd): + + # test that accel-pppd started successfully + assert accel_pppd_instance + + (exit_sh_sess, out_sh_sess, err_sh_sess) = process.run([accel_cmd, "show sessions match username 00("]) + # test that 'show sessions' with invalid regexp reports the issue and error position + assert ( + exit_sh_sess == 0 + and len(out_sh_sess) > 0 + and err_sh_sess == "" + and "match: " in out_sh_sess + and "at 3" in out_sh_sess + ) + + + (exit_iface_add, out_iface_add, err_iface_add) = process.run([accel_cmd, "pppoe interface add re:000("]) + # test that 'pppoe interface add' with invalid regexp reports the issue and error position + assert ( + exit_iface_add == 0 + and len(out_iface_add) > 0 + and err_iface_add == "" + and "pppoe: " in out_iface_add + and "at 4" in out_iface_add + ) + + (exit_term, out_term, err_term) = process.run([accel_cmd, "terminate match username 00("]) + # test that 'terminate' with invalid regexp reports the issue and error position + assert ( + exit_term == 0 + and len(out_term) > 0 + and err_term == "" + and "match: " in out_term + and "at 3" in out_term + ) diff --git a/tests/accel-pppd/ipoe/conftest.py b/tests/accel-pppd/ipoe/conftest.py index 3db8dd60..353ed270 100644 --- a/tests/accel-pppd/ipoe/conftest.py +++ b/tests/accel-pppd/ipoe/conftest.py @@ -1,5 +1,5 @@ import pytest -from common import dhclient_process +from common import dhclient_process, config import tempfile, os # dhclient executable file name @@ -44,3 +44,21 @@ def dhclient_instance(accel_pppd_instance, veth_pair_netns, dhclient, dhclient_a # test teardown: dhclient_process.end(dhclient_thread, dhclient_control) + +# lua script as string (should be redefined by specific test) +@pytest.fixture() +def lua_script(): + return "" + + +# lua script file name +@pytest.fixture() +def lua_script_file(lua_script): + # test setup: + filename = config.make_tmp(lua_script) + + # test execution + yield filename + + # test teardown: + config.delete_tmp(filename) diff --git a/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_chap_secrets.py b/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_chap_secrets.py new file mode 100644 index 00000000..80c559da --- /dev/null +++ b/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_chap_secrets.py @@ -0,0 +1,92 @@ +import pytest +from common import process +import time + + +@pytest.fixture() +def chap_secrets_config(veth_pair_netns): + return veth_pair_netns["veth_a"] + " * pass123 192.0.2.57" + + +@pytest.fixture() +def accel_pppd_config(veth_pair_netns, chap_secrets_config_file): + print( + "accel_pppd_config veth_pair_netns: " + + str(veth_pair_netns) + + "chap_secrets_config_file: " + + str(chap_secrets_config_file) + ) + return ( + """ + [modules] + connlimit + chap-secrets + ipoe + + [cli] + tcp=127.0.0.1:2001 + + [core] + log-error=/dev/stderr + + [log] + log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr + level=5 + + [ipoe] + username=ifname + password=pass123 + verbose=5 + start=dhcpv4 + shared=1 + gw-ip-address=192.0.2.1/24 + interface=re:.""" + + veth_pair_netns["veth_a"][1:] + + """ + [chap-secrets] + chap-secrets=""" + + chap_secrets_config_file + ) + + +# test dhcpv4 shared session without auth check +@pytest.mark.dependency(depends=["ipoe_driver_loaded"], scope="session") +@pytest.mark.ipoe_driver +@pytest.mark.chap_secrets +def test_ipoe_shared_session_chap_secrets( + dhclient_instance, accel_cmd, veth_pair_netns +): + + # test that dhclient (with accel-pppd) started successfully + assert dhclient_instance["is_started"] + + # wait until session is started + max_wait_time = 10.0 + sleep_time = 0.0 + is_started = False # is session started + while sleep_time < max_wait_time: + (exit, out, err) = process.run( + [ + accel_cmd, + "show sessions called-sid,ip,state", + ] + ) + assert exit == 0 # accel-cmd fails + # print(out) + if veth_pair_netns["veth_a"] in out and "192.0.2.57" in out and "active" in out: + # session is found + print( + "test_ipoe_session_chap_secrets: session found in (sec): " + + str(sleep_time) + ) + is_started = True + break + time.sleep(0.1) + sleep_time += 0.1 + + print("test_ipoe_shared_session_chap_secrets: last accel-cmd out: " + out) + + # test that session is started + assert is_started == True diff --git a/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_lua_chap_secrets.py b/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_lua_chap_secrets.py new file mode 100644 index 00000000..fdee7c4a --- /dev/null +++ b/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_lua_chap_secrets.py @@ -0,0 +1,112 @@ +import pytest +from common import process +import time + + +# create vlan 335 on both interfaces of pair +@pytest.fixture() +def veth_pair_vlans_config(): + return {"vlans_a": [335], "vlans_b": [335]} + + +# use vlan as a username +@pytest.fixture() +def chap_secrets_config(veth_pair_netns): + return "335 * pass123 192.0.2.67" + + +# return vlan as a username +@pytest.fixture() +def lua_script(): + return """#!lua + function vlan_func(pkt) + return pkt:vlan() + end""" + + +@pytest.fixture() +def accel_pppd_config(veth_pair_netns, chap_secrets_config_file, lua_script_file): + print( + "accel_pppd_config veth_pair_netns: " + + str(veth_pair_netns) + + "chap_secrets_config_file: " + + str(chap_secrets_config_file) + ) + return ( + """ + [modules] + connlimit + chap-secrets + ipoe + + [cli] + tcp=127.0.0.1:2001 + + [core] + log-error=/dev/stderr + + [log] + log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr + level=5 + + [ipoe] + lua-file=""" + + lua_script_file + + """ + username=lua:vlan_func + password=pass123 + verbose=5 + start=dhcpv4 + shared=1 + gw-ip-address=192.0.2.1/24 + interface=re:.""" + + veth_pair_netns["veth_a"][1:] + + "\\.335" + + """ + [chap-secrets] + chap-secrets=""" + + chap_secrets_config_file + ) + + +# test dhcpv4 shared session without auth check +@pytest.mark.dependency(depends=["ipoe_driver_loaded"], scope="session") +@pytest.mark.ipoe_driver +@pytest.mark.chap_secrets +def test_ipoe_shared_session_lua_chap_secrets( + dhclient_instance, accel_cmd, veth_pair_netns +): + + # test that dhclient (with accel-pppd) started successfully + assert dhclient_instance["is_started"] + + # wait until session is started + max_wait_time = 10.0 + sleep_time = 0.0 + is_started = False # is session started + while sleep_time < max_wait_time: + (exit, out, err) = process.run( + [ + accel_cmd, + "show sessions called-sid,ip,state", + ] + ) + assert exit == 0 # accel-cmd fails + # print(out) + if veth_pair_netns["veth_a"] in out and "192.0.2.67" in out and "active" in out: + # session is found + print( + "test_ipoe_session_lua_chap_secrets: session found in (sec): " + + str(sleep_time) + ) + is_started = True + break + time.sleep(0.1) + sleep_time += 0.1 + + print("test_ipoe_shared_session_lua_chap_secrets: last accel-cmd out: " + out) + + # test that session is started + assert is_started == True diff --git a/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_wo_auth.py b/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_wo_auth.py index 104e4e9b..7ebb420a 100644 --- a/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_wo_auth.py +++ b/tests/accel-pppd/ipoe/dhcpv4/test_ipoe_shared_session_wo_auth.py @@ -9,7 +9,8 @@ def accel_pppd_config(veth_pair_netns): return ( """ [modules] - pppoe + connlimit + radius ipoe ippool @@ -20,16 +21,23 @@ def accel_pppd_config(veth_pair_netns): [cli] tcp=127.0.0.1:2001 + [core] + log-error=/dev/stderr + [log] log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr level=5 + [radius] + [ipoe] noauth=1 shared=1 gw-ip-address=192.0.2.1/24 - interface=""" - + veth_pair_netns["veth_a"] + interface=re:.""" + + veth_pair_netns["veth_a"][1:] ) diff --git a/tests/accel-pppd/pppoe/conftest.py b/tests/accel-pppd/pppoe/conftest.py index 8ebaaed3..b3893200 100644 --- a/tests/accel-pppd/pppoe/conftest.py +++ b/tests/accel-pppd/pppoe/conftest.py @@ -1,5 +1,6 @@ -import pytest +import pytest, subprocess, re from common import pppd_process +from packaging.version import Version # pppd executable file name @pytest.fixture() @@ -13,11 +14,21 @@ def pppd(pytestconfig): def pppd_config(): return "" +# determines which plugin is required - pppoe.so (pppd 2.5.0+) or rp-pppoe.so (pppd <2.5.0) +def pppd_plugin_so(pppd): + command = [pppd, "--version"] + result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + pppd_version = Version(re.search(r'\d+\.\d+\.\d+', result.stdout + result.stderr).group()) + ref_version = Version("2.5.0") + if pppd_version >= ref_version: + return "pppoe.so" + else: + return "rp-pppoe.so" # pppd configuration as command line args @pytest.fixture() -def pppd_args(pppd_config): - return pppd_config.split() +def pppd_args(pppd_config, pppd): + return ("plugin " + pppd_plugin_so(pppd) + "\n" + pppd_config).split() # setup and teardown for tests that required running pppd (after accel-pppd) diff --git a/tests/accel-pppd/pppoe/test_pppoe_disc.py b/tests/accel-pppd/pppoe/test_pppoe_disc.py index eb069c42..64a0d295 100644 --- a/tests/accel-pppd/pppoe/test_pppoe_disc.py +++ b/tests/accel-pppd/pppoe/test_pppoe_disc.py @@ -8,15 +8,23 @@ def accel_pppd_config(veth_pair_netns): return ( """ [modules] + radius pppoe + [core] + log-error=/dev/stderr + [log] log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr level=5 [cli] tcp=127.0.0.1:2001 + [radius] + [pppoe] ac-name=test-accel interface=""" diff --git a/tests/accel-pppd/pppoe/test_pppoe_pado_delay.py b/tests/accel-pppd/pppoe/test_pppoe_pado_delay.py index 96c73bf8..3a93d920 100644 --- a/tests/accel-pppd/pppoe/test_pppoe_pado_delay.py +++ b/tests/accel-pppd/pppoe/test_pppoe_pado_delay.py @@ -30,15 +30,23 @@ def accel_pppd_config(veth_pair_netns): return ( """ [modules] + radius pppoe + [core] + log-error=/dev/stderr + [log] log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr level=5 [cli] tcp=127.0.0.1:2001 + [radius] + [pppoe] ac-name=test-accel pado-delay=1500 diff --git a/tests/accel-pppd/pppoe/test_pppoe_session_chap_secrets.py b/tests/accel-pppd/pppoe/test_pppoe_session_chap_secrets.py new file mode 100644 index 00000000..05d19701 --- /dev/null +++ b/tests/accel-pppd/pppoe/test_pppoe_session_chap_secrets.py @@ -0,0 +1,104 @@ +import pytest +from common import process +import time + + +@pytest.fixture() +def chap_secrets_config(): + return "loginCSAB * pass123 192.0.2.37" + + +@pytest.fixture() +def accel_pppd_config(veth_pair_netns, chap_secrets_config_file): + print( + "accel_pppd_config veth_pair_netns: " + + str(veth_pair_netns) + + "chap_secrets_config_file" + + str(chap_secrets_config_file) + ) + return ( + """ + [modules] + chap-secrets + pppoe + auth_pap + + [core] + log-error=/dev/stderr + + [log] + log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr + level=5 + + [cli] + tcp=127.0.0.1:2001 + + [pppoe] + interface=""" + + veth_pair_netns["veth_a"] + + """ + [chap-secrets] + gw-ip-address=192.0.2.1 + chap-secrets=""" + + chap_secrets_config_file + ) + + +@pytest.fixture() +def pppd_config(veth_pair_netns): + print("pppd_config veth_pair_netns: " + str(veth_pair_netns)) + return ( + """ + nodetach + noipdefault + defaultroute + connect /bin/true + noauth + persist + mtu 1492 + noaccomp + default-asyncmap + user loginCSAB + password pass123 + nic-""" + + veth_pair_netns["veth_b"] + ) + + +# test pppoe session without auth check +@pytest.mark.chap_secrets +def test_pppoe_session_chap_secrets(pppd_instance, accel_cmd): + + # test that pppd (with accel-pppd) started successfully + assert pppd_instance["is_started"] + + # wait until session is started + max_wait_time = 10.0 + sleep_time = 0.0 + is_started = False # is session started + while sleep_time < max_wait_time: + (exit, out, err) = process.run( + [ + accel_cmd, + "show sessions match username log.nCSAB username,ip,state", + ] + ) + assert exit == 0 # accel-cmd fails + # print(out) + if "loginCSAB" in out and "192.0.2.37" in out and "active" in out: + # session is found + print( + "test_pppoe_session_chap_secrets: session found in (sec): " + + str(sleep_time) + ) + is_started = True + break + time.sleep(0.1) + sleep_time += 0.1 + + print("test_pppoe_session_chap_secrets: last accel-cmd out: " + out) + + # test that session is started + assert is_started == True diff --git a/tests/accel-pppd/pppoe/test_pppoe_session_wo_auth.py b/tests/accel-pppd/pppoe/test_pppoe_session_wo_auth.py index 0c8aa2c0..960b7c94 100644 --- a/tests/accel-pppd/pppoe/test_pppoe_session_wo_auth.py +++ b/tests/accel-pppd/pppoe/test_pppoe_session_wo_auth.py @@ -9,12 +9,18 @@ def accel_pppd_config(veth_pair_netns): return ( """ [modules] + radius pppoe auth_pap ippool + [core] + log-error=/dev/stderr + [log] log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr level=5 [auth] @@ -27,6 +33,8 @@ def accel_pppd_config(veth_pair_netns): [cli] tcp=127.0.0.1:2001 + [radius] + [pppoe] interface=""" + veth_pair_netns["veth_a"] @@ -47,7 +55,6 @@ def pppd_config(veth_pair_netns): mtu 1492 noaccomp default-asyncmap - plugin rp-pppoe.so user loginAB password pass123 nic-""" @@ -69,7 +76,7 @@ def test_pppoe_session_wo_auth(pppd_instance, accel_cmd): (exit, out, err) = process.run( [ accel_cmd, - "show sessions match username loginAB username,ip,state", + "show sessions match username log.nAB username,ip,state", ] ) assert exit == 0 # accel-cmd fails diff --git a/tests/accel-pppd/pppoe/test_pppoe_vlan_mon.py b/tests/accel-pppd/pppoe/test_pppoe_vlan_mon.py index 670abc33..b73189c3 100644 --- a/tests/accel-pppd/pppoe/test_pppoe_vlan_mon.py +++ b/tests/accel-pppd/pppoe/test_pppoe_vlan_mon.py @@ -13,15 +13,23 @@ def accel_pppd_config(veth_pair_netns): print(veth_pair_netns) return """ [modules] + radius pppoe + [core] + log-error=/dev/stderr + [log] log-debug=/dev/stdout + log-file=/dev/stdout + log-emerg=/dev/stderr level=5 [cli] tcp=127.0.0.1:2001 + [radius] + [pppoe] ac-name=test-accel vlan-mon=%s,10-20 diff --git a/tests/conftest.py b/tests/conftest.py index d3733409..da1f40f4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -26,6 +26,10 @@ def pytest_configure(config): "markers", "vlan_mon_driver: marks tests as related to ipoe kernel module (deselect with '-m \"not vlan_mon_driver\"')", ) + config.addinivalue_line( + "markers", + "chap_secrets: marks tests as related to chap-secrets module (deselect with '-m \"not chap_secrets\"')", + ) # accel-pppd executable file name @@ -97,3 +101,21 @@ def veth_pair_netns(veth_pair_vlans_config): # test teardown: veth.delete_veth_pair_netns(veth_pair_netns_instance) + +# chap-secrets configuration as string (should be redefined by specific test) +@pytest.fixture() +def chap_secrets_config(): + return "" + + +# chap-secrets configuration file name +@pytest.fixture() +def chap_secrets_config_file(chap_secrets_config): + # test setup: + filename = config.make_tmp(chap_secrets_config) + + # test execution + yield filename + + # test teardown: + config.delete_tmp(filename) |