Compare commits

...

18 Commits

Author SHA1 Message Date
jaspreetsachdev
eebe021780 Merge pull request #459 from Telecominfraproject/main
ucentral-client: update to latest HEAD
2022-06-23 15:02:37 -04:00
John Crispin
c6e0384f21 ucentral-client: update to latest HEAD
68fe6c2 fix the ping command

Signed-off-by: John Crispin <john@phrozen.org>
2022-06-23 14:06:26 +02:00
jaspreetsachdev
23ae850f72 Merge pull request #458 from Telecominfraproject/main
Fixes for WIFI-7687, WIFI-9620
2022-06-22 08:59:02 -04:00
John Crispin
708cf2dec6 ucentral-schema: update to latest HEAD
fc8fdcf point radsec proxy at the correct radius accounting server
886a650 Add missing paramters to uC state schema
c8b15b7 chain the radius vendor attributes inside a single AVP

Fixes: WIFI-7687
Fixes: WIFI-9620
Signed-off-by: John Crispin <john@phrozen.org>
2022-06-22 11:06:35 +02:00
John Crispin
a95745d95b ucentral-client: update to latest HEAD
62efd45 add radius-proxy RX path

Fixes: WIFI-9620
Signed-off-by: John Crispin <john@phrozen.org>
2022-06-22 11:06:21 +02:00
John Crispin
83ccea0abf radius-gw-proxy: add RX path support
Fixes: WIFI-9620
Signed-off-by: John Crispin <john@phrozen.org>
2022-06-22 11:02:16 +02:00
John Crispin
bfeaf89238 ucentral-schema: update to latest HEAD
548ce37 point radsec proxy at the correct radius accounting server
c49ce29 Add missing paramters to uC state schema
1c55872 chain the radius vendor attributes inside a single AVP

Signed-off-by: John Crispin <john@phrozen.org>
2022-06-20 19:24:29 +02:00
jaspreetsachdev
7439217b3c Merge pull request #456 from Telecominfraproject/main
Merging Fixes for WIFI-9630 and others
2022-06-17 09:32:12 -04:00
John Crispin
ae2377f4d2 ucentral-schema: update to latest HEAD
4df0373 renderer: quote wireless encryption key

Fixes: WIFI-9630
Signed-off-by: John Crispin <john@phrozen.org>
2022-06-16 16:37:37 +02:00
John Crispin
b81d0aaf0e ipq40xx: add dual boot support for ecw5211
Fixes: WIFI-7712
Signed-off-by: John Crispin <john@phrozen.org>
2022-06-16 12:47:13 +02:00
John Crispin
1546bef93f ucentral-schema: update to latest HEAD
1d7e565 optimize the bridge/uci config for gre tunnels

Signed-off-by: John Crispin <john@phrozen.org>
2022-06-16 12:44:53 +02:00
Stijn Tintel
32b1aade42 ipq807x: force ext4 creation in emmc_do_upgrade
Running mkfs.ext4 on a partition that already contains an ext4
filesystem asks for input:

  mke2fs 1.45.6 (20-Mar-2020)
  /dev/mmcblk0p9 contains a ext4 file system
          created on Sat Jun 11 12:23:42 2022
  Proceed anyway? (y,N) y

This breaks the ability to run sysupgrade non-interactively. Add the -F
switch to force ext4 creation to fix this.

Fixes: WIFI-9419
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2022-06-15 12:42:34 +02:00
Stijn Tintel
2a92b75fe1 ipq807x: silence dd errors in do_flash_emmc
Running dd if=/dev/zero to a partition will always throw an ENOSPC error
when reaching the end of the partition. Silence those errors to avoid
confusion.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2022-06-15 12:42:34 +02:00
John Crispin
cb30d9e20a ipq807x: add motorola q14 support
Fixes: WIFI-8040
Signed-off-by: John Crispin <john@phrozen.org>
2022-06-15 12:42:34 +02:00
John Crispin
588206b93b ucentral-schema: update to latest HEAD
417fcc4 fix selection of radius proxy ip

Fixes: WIFI-9461
Signed-off-by: John Crispin <john@phrozen.org>
2022-06-13 14:57:48 +02:00
John Crispin
6399649038 ipq807x: improve dual boot on eap101/2
inverse the logic that figures out if we want to set upgrade_available.

Fixes: WIFI-7712
Signed-off-by: John Crispin <john@phrozen.org>
2022-06-13 14:57:48 +02:00
John Crispin
aa3cb95233 wireguard-tools: do not select the kernel module
unetd will select the correct kernel module.

Fixes: WIFI-7571
Signed-off-by: John Crispin <john@phrozen.org>
2022-06-13 14:57:48 +02:00
John Crispin
3ea06dac40 dhcpsnoop: update code
* Update to latest version of dhcpsnoop
* always snoop all upstream interfaces
* add snooped leases to state

Fixes: WIFI-7838
Signed-off-by: John Crispin <john@phrozen.org>
2022-06-13 14:57:21 +02:00
34 changed files with 2393 additions and 220 deletions

View File

@@ -11,7 +11,7 @@ boot() {
edgecore,eap101|\
edgecore,eap102)
avail=$(fw_printenv -n upgrade_available)
[ ${avail} -eq 0 ] && fw_setenv upgrade_available 1
[ "${avail}" -eq 1 ] || fw_setenv upgrade_available 1
fw_setenv bootcount 0
;;
esac

View File

@@ -44,7 +44,7 @@ do_flash_emmc() {
}
echo erase $4
dd if=/dev/zero of=${emmcblock}
dd if=/dev/zero of=${emmcblock} 2> /dev/null
echo flash $4
tar Oxf $tar_file ${board_dir}/$part | dd of=${emmcblock}
}
@@ -59,7 +59,7 @@ emmc_do_upgrade() {
local emmcblock="$(find_mmc_part "rootfs_data")"
if [ -e "$emmcblock" ]; then
mkfs.ext4 "$emmcblock"
mkfs.ext4 -F "$emmcblock"
fi
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../../../arm64/boot/dts/qcom/qcom-ipq5018-q14.dts"
/ {
pmuv8: pmu {
compatible = "arm,cortex-a7-pmu";
};
};

View File

@@ -0,0 +1,886 @@
/dts-v1/;
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "qcom-ipq5018.dtsi"
/ {
#address-cells = <0x2>;
#size-cells = <0x2>;
model = "Motorola Q14";
compatible = "motorola,q14", "qcom,ipq5018-mp03.5-c1", "qcom,ipq5018";
interrupt-parent = <&intc>;
aliases {
sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
serial0 = &blsp1_uart1;
serial1 = &blsp1_uart2;
ethernet0 = "/soc/dp1";
ethernet1 = "/soc/dp2";
};
chosen {
bootargs = "console=ttyMSM0,115200,n8 rw init=/init";
#ifdef __IPQ_MEM_PROFILE_256_MB__
bootargs-append = " swiotlb=1";
#else
bootargs-append = " swiotlb=1 coherent_pool=2M";
#endif
stdout-path = "serial0";
};
reserved-memory {
#ifdef __IPQ_MEM_PROFILE_256_MB__
/* 256 MB Profile
* +==========+==============+=========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +----------+--------------+-------------------------+
* | NSS | 0x40000000 | 8MB |
* +----------+--------------+-------------------------+
* | Linux | 0x40800000 | Depends on total memory |
* +----------+--------------+-------------------------+
* | uboot | 0x4A600000 | 4MB |
* +----------+--------------+-------------------------+
* | SBL | 0x4AA00000 | 1MB |
* +----------+--------------+-------------------------+
* | smem | 0x4AB00000 | 1MB |
* +----------+--------------+-------------------------+
* | TZ | 0x4AC00000 | 4MB |
* +----------+--------------+-------------------------+
* | Q6 | | |
* | code/ | 0x4B000000 | 20MB |
* | data | | |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | data | 0x4C400000 | 13MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | M3 Dump | 0x4D100000 | 1MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | QDSS | 0x4D200000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | data | 0x4D300000 | 15MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | M3 Dump | 0x4E200000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | QDSS | 0x4E300000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | data | 0x4E400000 | 15MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | M3 Dump | 0x4F300000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | QDSS | 0x4F400000 | 1MB |
* +----------+--------------+-------------------------+
* | |
* | Rest of the memory for Linux |
* | |
* +===================================================+
*/
q6_mem_regions: q6_mem_regions@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 0x4500000>;
};
q6_code_data: q6_code_data@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 0x1400000>;
};
q6_ipq5018_data: q6_ipq5018_data@4C400000 {
no-map;
reg = <0x0 0x4C400000 0x0 0xD00000>;
};
m3_dump: m3_dump@4D100000 {
no-map;
reg = <0x0 0x4D100000 0x0 0x100000>;
};
q6_etr_region: q6_etr_dump@4D200000 {
no-map;
reg = <0x0 0x4D200000 0x0 0x100000>;
};
q6_qcn6122_data1: q6_qcn6122_data1@4D300000 {
no-map;
reg = <0x0 0x4D300000 0x0 0xF00000>;
};
m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E200000 {
no-map;
reg = <0x0 0x4E200000 0x0 0x100000>;
};
q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E300000 {
no-map;
reg = <0x0 0x4E300000 0x0 0x100000>;
};
q6_qcn6122_data2: q6_qcn6122_data2@4E400000 {
no-map;
reg = <0x0 0x4E400000 0x0 0xF00000>;
};
m3_dump_qcn6122_2: m3_dump_qcn6122_2@4F300000 {
no-map;
reg = <0x0 0x4F300000 0x0 0x100000>;
};
q6_qcn6122_etr_2: q6_qcn6122_etr_2@4F400000 {
no-map;
reg = <0x0 0x4F400000 0x0 0x100000>;
};
#else
/* 512MB/1GB Profiles
* +==========+==============+=========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +----------+--------------+-------------------------+
* | NSS | 0x40000000 | 16MB |
* +----------+--------------+-------------------------+
* | Linux | 0x41000000 | Depends on total memory |
* +----------+--------------+-------------------------+
* | uboot | 0x4A600000 | 4MB |
* +----------+--------------+-------------------------+
* | SBL | 0x4AA00000 | 1MB |
* +----------+--------------+-------------------------+
* | smem | 0x4AB00000 | 1MB |
* +----------+--------------+-------------------------+
* | TZ | 0x4AC00000 | 4MB |
* +----------+--------------+-------------------------+
* | Q6 | | |
* | code/ | 0x4B000000 | 20MB |
* | data | | |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | data | 0x4C400000 | 14MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | M3 Dump | 0x4D200000 | 1MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | QDSS | 0x4D300000 | 1MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | Caldb | 0x4D400000 | 2MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | data | 0x4D600000 | 16MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | M3 Dump | 0x4E600000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | QDSS | 0x4E700000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | Caldb | 0x4E800000 | 5MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | data | 0x4ED00000 | 16MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | M3 Dump | 0x4FD00000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | QDSS | 0x4FE00000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | Caldb | 0x4FF00000 | 5MB |
* +----------+--------------+-------------------------+
* | |
* | Rest of the memory for Linux |
* | |
* +===================================================+
*/
q6_mem_regions: q6_mem_regions@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 0x5400000>;
};
q6_code_data: q6_code_data@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 01400000>;
};
q6_ipq5018_data: q6_ipq5018_data@4C400000 {
no-map;
reg = <0x0 0x4C400000 0x0 0xE00000>;
};
m3_dump: m3_dump@4D200000 {
no-map;
reg = <0x0 0x4D200000 0x0 0x100000>;
};
q6_etr_region: q6_etr_dump@4D300000 {
no-map;
reg = <0x0 0x4D300000 0x0 0x100000>;
};
q6_caldb_region: q6_caldb_region@4D400000 {
no-map;
reg = <0x0 0x4D400000 0x0 0x200000>;
};
q6_qcn6122_data1: q6_qcn6122_data1@4D600000 {
no-map;
reg = <0x0 0x4D600000 0x0 0x1000000>;
};
m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E600000 {
no-map;
reg = <0x0 0x4E600000 0x0 0x100000>;
};
q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E700000 {
no-map;
reg = <0x0 0x4E700000 0x0 0x100000>;
};
q6_qcn6122_caldb_1: q6_qcn6122_caldb_1@4E800000 {
no-map;
reg = <0x0 0x4E800000 0x0 0x500000>;
};
q6_qcn6122_data2: q6_qcn6122_data2@4E900000 {
no-map;
reg = <0x0 0x4ED00000 0x0 0x1000000>;
};
m3_dump_qcn6122_2: m3_dump_qcn6122_2@4FD00000 {
no-map;
reg = <0x0 0x4FD00000 0x0 0x100000>;
};
q6_qcn6122_etr_2: q6_qcn6122_etr_2@4FE00000 {
no-map;
reg = <0x0 0x4FE00000 0x0 0x100000>;
};
q6_qcn6122_caldb_2: q6_qcn6122_caldb_2@4FF00000 {
no-map;
reg = <0x0 0x4FF00000 0x0 0x500000>;
};
#endif
};
soc {
serial@78af000 {
status = "ok";
};
blsp1_uart2: serial@78b0000 {
pinctrl-0 = <&blsp1_uart_pins>;
pinctrl-names = "default";
};
qpic_bam: dma@7984000{
status = "ok";
};
nand: qpic-nand@79b0000 {
status = "disabled";
};
spi_0: spi@78b5000 { /* BLSP1 QUP0 */
pinctrl-0 = <&blsp0_spi_pins>;
pinctrl-names = "default";
cs-select = <0>;
status = "ok";
m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
compatible = "n25q128a11";
linux,modalias = "m25p80", "n25q128a11";
spi-max-frequency = <50000000>;
use-default-sizes;
};
};
mdio0: mdio@88000 {
status = "ok";
ethernet-phy@0 {
reg = <7>;
};
};
mdio1: mdio@90000 {
status = "ok";
pinctrl-0 = <&mdio1_pins>;
pinctrl-names = "default";
phy-reset-gpio = <&tlmm 39 0>;
ethernet-phy@0 {
reg = <28>;
};
};
ess-instance {
num_devices = <0x1>;
ess-switch@0x39c00000 {
switch_mac_mode = <0xf>; /* mac mode for uniphy instance*/
cmnblk_clk = "internal_96MHz"; /* cmnblk clk*/
qcom,port_phyinfo {
port@0 {
port_id = <1>;
phy_address = <7>;
mdiobus = <&mdio0>;
};
port@1 {
port_id = <2>;
phy_address = <0x1c>;
mdiobus = <&mdio1>;
port_mac_sel = "QGMAC_PORT";
};
};
led_source@0 {
source = <0>;
mode = "normal";
speed = "all";
blink_en = "enable";
active = "high";
};
};
};
dp1 {
device_type = "network";
compatible = "qcom,nss-dp";
clocks = <&gcc GCC_SNOC_GMAC0_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,id = <1>;
reg = <0x39C00000 0x10000>;
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
qcom,mactype = <2>;
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <7>;
mdio-bus = <&mdio0>;
local-mac-address = [000000000000];
phy-mode = "sgmii";
};
dp2 {
device_type = "network";
compatible = "qcom,nss-dp";
clocks = <&gcc GCC_SNOC_GMAC1_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,id = <2>;
reg = <0x39D00000 0x10000>;
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
qcom,mactype = <2>;
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <28>;
mdio-bus = <&mdio1>;
local-mac-address = [000000000000];
phy-mode = "sgmii";
};
qcom,test@0 {
status = "ok";
};
nss-macsec1 {
compatible = "qcom,nss-macsec";
phy_addr = <0x1c>;
mdiobus = <&mdio1>;
};
lpass: lpass@0xA000000{
status = "disabled";
};
pcm: pcm@0xA3C0000{
pinctrl-0 = <&audio_pins>;
pinctrl-names = "default";
status = "disabled";
};
pcm_lb: pcm_lb@0 {
status = "disabled";
};
};
thermal-zones {
status = "ok";
};
};
&sdhc_1 {
pinctrl-0 = <&emmc_pins>;
pinctrl-names = "default";
qcom,clk-rates = <400000 25000000 50000000 100000000 \
192000000 384000000>;
qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
qcom,nonremovable;
status = "ok";
};
&tlmm {
pinctrl-0 = <&blsp0_uart_pins &phy_led_pins>;
pinctrl-names = "default";
blsp0_uart_pins: uart_pins {
blsp0_uart_rx_tx {
pins = "gpio20", "gpio21";
function = "blsp0_uart0";
bias-disable;
};
};
blsp1_uart_pins: blsp1_uart_pins {
blsp1_uart_rx_tx {
pins = "gpio23", "gpio25", "gpio24", "gpio26";
function = "blsp1_uart2";
bias-disable;
};
};
blsp0_spi_pins: blsp0_spi_pins {
mux {
pins = "gpio10", "gpio11", "gpio12", "gpio13";
function = "blsp0_spi";
drive-strength = <2>;
bias-disable;
};
};
emmc_pins: emmc_pins {
emmc_clk {
pins = "gpio9";
function = "sdc1_clk";
drive-strength = <8>;
bias-disable;
};
emmc_cmd {
pins = "gpio8";
function = "sdc1_cmd";
drive-strength = <8>;
bias-pull-up;
};
emmc_data_0 {
pins = "gpio7";
function = "sdc10";
drive-strength = <8>;
bias-disable;
};
emmc_data_1 {
pins = "gpio6";
function = "sdc11";
drive-strength = <8>;
bias-disable;
};
emmc_data_2 {
pins = "gpio5";
function = "sdc12";
drive-strength = <8>;
bias-disable;
};
emmc_data_3 {
pins = "gpio4";
function = "sdc13";
drive-strength = <8>;
bias-disable;
};
};
mdio1_pins: mdio_pinmux {
mux_0 {
pins = "gpio36";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mux_1 {
pins = "gpio37";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
};
phy_led_pins: phy_led_pins {
gephy_led_pin {
pins = "gpio46";
function = "led0";
drive-strength = <8>;
bias-pull-down;
};
};
i2c_pins: i2c_pins {
i2c_scl {
pins = "gpio25";
function = "blsp2_i2c1";
drive-strength = <8>;
bias-disable;
};
i2c_sda {
pins = "gpio26";
function = "blsp2_i2c1";
drive-strength = <8>;
bias-disable;
};
};
button_pins: button_pins {
wps_button {
pins = "gpio38";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
reset_button {
pins = "gpio31";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
audio_pins: audio_pinmux {
mux_1 {
pins = "gpio24";
function = "audio_rxbclk";
drive-strength = <8>;
bias-pull-down;
};
mux_2 {
pins = "gpio25";
function = "audio_rxfsync";
drive-strength = <8>;
bias-pull-down;
};
mux_3 {
pins = "gpio26";
function = "audio_rxd";
drive-strength = <8>;
bias-pull-down;
};
mux_4 {
pins = "gpio27";
function = "audio_txmclk";
drive-strength = <8>;
bias-pull-down;
};
mux_5 {
pins = "gpio28";
function = "audio_txbclk";
drive-strength = <8>;
bias-pull-down;
};
mux_6 {
pins = "gpio29";
function = "audio_txfsync";
drive-strength = <8>;
bias-pull-down;
};
mux_7 {
pins = "gpio30";
function = "audio_txd";
drive-strength = <8>;
bias-pull-down;
};
};
};
&soc {
gpio_keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
button@1 {
label = "wps";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
button@2 {
label = "reset";
linux,code = <KEY_RESTART>;
gpios = <&tlmm 31 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
};
};
&usb3 {
status = "ok";
device-power-gpio = <&tlmm 24 1>;
};
&eud {
status = "ok";
};
&pcie_x1 {
status = "ok";
perst-gpio = <&tlmm 18 1>;
};
&pcie_x2 {
status = "ok";
perst-gpio = <&tlmm 15 1>;
};
&dwc_0 {
/delete-property/ #phy-cells;
/delete-property/ phys;
/delete-property/ phy-names;
};
&hs_m31phy_0 {
status = "ok";
};
&pcie_x1phy {
status = "ok";
};
&pcie_x2phy {
status = "ok";
};
&pcie_x1_rp {
status = "ok";
mhi_0: qcom,mhi@0 {
reg = <0 0 0 0 0 >;
};
};
&pcie_x2_rp {
status = "ok";
mhi_1: qcom,mhi@1 {
reg = <0 0 0 0 0 >;
};
};
&qfprom {
status = "ok";
};
&tsens {
status = "ok";
};
&qcom_q6v5_wcss {
qcom,multipd_arch;
memory-region = <&q6_mem_regions>;
qcom,share_bootargs;
qcom,bootargs_smem = <507>;
boot-args = <0x1 0x4 0x3 0x0F 0x0 0x0>,
<0x2 0x4 0x2 0x12 0x0 0x0>;
/* IPQ5018 */
q6v5_wcss_userpd1 {
m3_firmware = "IPQ5018/m3_fw.mdt";
interrupts-extended = <&wcss_smp2p_in 8 0>,
<&wcss_smp2p_in 9 0>,
<&wcss_smp2p_in 12 0>,
<&wcss_smp2p_in 11 0>;
interrupt-names ="fatal",
"ready",
"spawn_ack",
"stop-ack";
qcom,smem-states = <&wcss_smp2p_out 8>,
<&wcss_smp2p_out 9>,
<&wcss_smp2p_out 10>;
qcom,smem-state-names = "shutdown",
"stop",
"spawn";
qca,asid = <1>;
qca,auto-restart;
qca,int_radio;
#ifdef __IPQ_MEM_PROFILE_256_MB__
memory-region = <&q6_ipq5018_data>, <&m3_dump>,
<&q6_etr_region>;
#else
memory-region = <&q6_ipq5018_data>, <&m3_dump>,
<&q6_etr_region>, <&q6_caldb_region>;
#endif
};
/* QCN6122 6G */
q6v5_wcss_userpd2 {
m3_firmware = "qcn6122/m3_fw.mdt";
interrupts-extended = <&wcss_smp2p_in 16 0>,
<&wcss_smp2p_in 17 0>,
<&wcss_smp2p_in 20 0>,
<&wcss_smp2p_in 19 0>;
interrupt-names ="fatal",
"ready",
"spawn_ack",
"stop-ack";
qcom,smem-states = <&wcss_smp2p_out 16>,
<&wcss_smp2p_out 17>,
<&wcss_smp2p_out 18>;
qcom,smem-state-names = "shutdown",
"stop",
"spawn";
qca,asid = <2>;
qca,auto-restart;
#ifdef __IPQ_MEM_PROFILE_256_MB__
memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>,
<&q6_qcn6122_etr_1>;
#else
memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>,
<&q6_qcn6122_etr_1>, <&q6_qcn6122_caldb_1>;
#endif
};
/* QCN6122 5G */
q6v5_wcss_userpd3 {
m3_firmware = "qcn6122/m3_fw.mdt";
interrupts-extended = <&wcss_smp2p_in 24 0>,
<&wcss_smp2p_in 25 0>,
<&wcss_smp2p_in 28 0>,
<&wcss_smp2p_in 27 0>;
interrupt-names ="fatal",
"ready",
"spawn_ack",
"stop-ack";
qcom,smem-states = <&wcss_smp2p_out 24>,
<&wcss_smp2p_out 25>,
<&wcss_smp2p_out 26>;
qcom,smem-state-names = "shutdown",
"stop",
"spawn";
qca,asid = <3>;
qca,auto-restart;
#ifdef __IPQ_MEM_PROFILE_256_MB__
memory-region = <&q6_qcn6122_data2>, <&m3_dump_qcn6122_2>,
<&q6_qcn6122_etr_2>;
#else
memory-region = <&q6_qcn6122_data2>, <&m3_dump_qcn6122_2>,
<&q6_qcn6122_etr_2>, <&q6_qcn6122_caldb_2>;
#endif
};
};
&i2c_0 {
pinctrl-0 = <&i2c_pins>;
pinctrl-names = "default";
status = "disabled";
};
&qgic_msi_0 {
status = "ok";
};
&qgic_msi_1 {
status = "ok";
};
&wifi0 {
/* IPQ5018 */
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
#ifdef __IPQ_MEM_PROFILE_256_MB__
qcom,tgt-mem-mode = <2>;
#else
qcom,tgt-mem-mode = <1>;
#endif
qcom,board_id = <0x24>;
qcom,bdf-addr = <0x4C400000 0x4C400000 0x4C400000 0x0 0x0>;
#ifdef __CNSS2__
qcom,caldb-addr = <0x4D400000 0x4D400000 0 0 0>;
#else
qcom,caldb-addr = <0x4D400000>;
m3-dump-addr = <0x4D200000>;
nss-radio-priority = <0>;
#endif
mem-region = <&q6_ipq5018_data>;
qcom,caldb-size = <0x200000>;
status = "ok";
};
&wifi1 {
/* QCN6122 5G */
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd2";
#ifdef __IPQ_MEM_PROFILE_256_MB__
qcom,tgt-mem-mode = <2>;
#else
qcom,tgt-mem-mode = <1>;
#endif
qcom,board_id = <0x60>;
qcom,bdf-addr = <0x4D600000 0x4D600000 0x4D300000 0x0 0x0>;
#ifdef __CNSS2__
qcom,caldb-addr = <0x4E800000 0x4E800000 0 0 0>;
#else
qcom,caldb-addr = <0x4E800000>;
m3-dump-addr = <0x4E600000>;
nss-radio-priority = <1>;
#endif
mem-region = <&q6_qcn6122_data1>;
qcom,caldb-size = <0x500000>;
status = "ok";
};
&wifi2 {
/* QCN6122 6G */
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd3";
#ifdef __IPQ_MEM_PROFILE_256_MB__
qcom,tgt-mem-mode = <2>;
#else
qcom,tgt-mem-mode = <1>;
#endif
qcom,board_id = <0xb0>;
qcom,bdf-addr = <0x4ED00000 0x4ED00000 0x4E400000 0x0 0x0>;
#ifdef __CNSS2__
qcom,caldb-addr = <0x4FF00000 0x4FF00000 0 0 0>;
#else
qcom,caldb-addr = <0x4FF00000>;
m3-dump-addr = <0x4FD00000>;
nss-radio-priority = <1>;
#endif
mem-region = <&q6_qcn6122_data2>;
qcom,caldb-size = <0x500000>;
status = "ok";
};

View File

@@ -27,7 +27,7 @@ define Device/motorola_q14
IMAGES := sysupgrade.tar mmc-factory.bin
IMAGE/mmc-factory.bin := append-ubi | qsdk-ipq-factory-mmc
endef
#TARGET_DEVICES += motorola_q14
TARGET_DEVICES += motorola_q14
define Device/qcom_mp03_1
DEVICE_TITLE := Qualcomm Maple 03.1

View File

@@ -11,7 +11,7 @@ ADD_DEFINITIONS(-Os -std=gnu99 -g3 -Wmissing-declarations -Wno-unused-parameter
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
SET(SOURCES main.c)
SET(SOURCES main.c ubus.c)
FIND_LIBRARY(ubus NAMES ubus)
FIND_LIBRARY(ubox NAMES ubox)

View File

@@ -1,3 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#define _GNU_SOURCE
#include <sys/types.h>
@@ -13,25 +15,15 @@
#include <libubox/uloop.h>
#include <libubox/usock.h>
#include <libubox/avl.h>
#include <libubox/avl-cmp.h>
#include <libubox/ulog.h>
#include <libubus.h>
#include "ubus.h"
#define RAD_PROX_BUFLEN (4 * 1024)
#define TLV_STATION_ID 30
#define TLV_VENDOR 26
#define TLV_TIP_SERVER_V4 2
#define TIP_VENDOR 58888
enum socket_type {
RADIUS_AUTH = 0,
RADIUS_ACCT,
RADIUS_DAS
};
#define TLV_PROXY_STATE 33
struct radius_socket {
struct uloop_fd fd;
@@ -52,53 +44,52 @@ struct radius_tlv {
char data[];
};
struct radius_station_id {
struct radius_proxy_state_key {
char id[256];
enum socket_type type;
};
struct radius_station {
struct radius_proxy_state {
struct avl_node avl;
struct radius_station_id key;
struct radius_proxy_state_key key;
int port;
};
static struct ubus_auto_conn conn;
static uint32_t ucentral;
static struct blob_buf b;
static struct radius_socket *sock_auth;
static struct radius_socket *sock_acct;
static int
avl_memcmp(const void *k1, const void *k2, void *ptr)
{
return memcmp(k1, k2, sizeof(struct radius_station_id));
return memcmp(k1, k2, sizeof(struct radius_proxy_state_key));
}
static AVL_TREE(radius_stations, avl_memcmp, false, NULL);
static AVL_TREE(radius_proxy_states, avl_memcmp, false, NULL);
static struct blob_buf b;
static void
radius_station_add(char *id, int port, enum socket_type type)
radius_proxy_state_add(char *id, int port, enum socket_type type)
{
struct radius_station *station;
struct radius_station_id key = { .type = type };
struct radius_proxy_state *station;
struct radius_proxy_state_key key = { .type = type };
strcpy(key.id, id);
station = avl_find_element(&radius_stations, &key, station, avl);
station = avl_find_element(&radius_proxy_states, &key, station, avl);
if (!station) {
printf("new station/port, adding to avl tree\n");
ULOG_INFO("new station/port, adding to avl tree\n");
station = malloc(sizeof(*station));
memset(station, 0, sizeof(*station));
strcpy(station->key.id, id);
station->key.type = type;
station->avl.key = &station->key;
avl_insert(&radius_stations, &station->avl);
avl_insert(&radius_proxy_states, &station->avl);
}
station->port = port;
}
static char *
b64(char *src, int len)
b64enc(char *src, int len)
{
char *dst;
int ret;
@@ -114,14 +105,25 @@ b64(char *src, int len)
return dst;
}
static char *
b64dec(char *src, int *ret)
{
int len = strlen(src);
char *dst = malloc(len);
*ret = b64_decode(src, dst, len);
if (*ret < 0)
return NULL;
return dst;
}
static void
radius_forward(char *buf, char *server, enum socket_type type)
radius_forward_gw(char *buf, enum socket_type type)
{
struct radius_header *hdr = (struct radius_header *) buf;
struct ubus_request async = { };
char *data = b64(buf, hdr->len);
char *data = b64enc(buf, ntohs(hdr->len));
if (!data)
if (!data || !ucentral)
return;
blob_buf_init(&b, 0);
@@ -137,7 +139,6 @@ radius_forward(char *buf, char *server, enum socket_type type)
}
blobmsg_add_string(&b, "data", data);
blobmsg_add_string(&b, "dst", server);
ubus_invoke_async(&conn.ctx, ucentral, "radius", b.head, &async);
ubus_abort_request(&conn.ctx, &async);
@@ -146,22 +147,20 @@ radius_forward(char *buf, char *server, enum socket_type type)
}
static int
radius_parse(char *buf, int len, int port, enum socket_type type)
radius_parse(char *buf, int len, int port, enum socket_type type, int tx)
{
struct radius_header *hdr = (struct radius_header *) buf;
struct radius_tlv *station_id = NULL;
char station_id_str[256] = {};
char server_ip_str[256] = {};
struct radius_tlv *proxy_state = NULL;
char proxy_state_str[256] = {};
void *avp = hdr->avp;
int len_orig = ntohs(hdr->len);
hdr->len = ntohs(hdr->len);
if (hdr->len != len) {
printf("invalid header length\n");
if (len_orig != len) {
ULOG_ERR("invalid header length, %d %d\n", len_orig, len);
return -1;
}
printf("\tcode:%d, id:%d, len:%d\n", hdr->code, hdr->id, hdr->len);
printf("\tcode:%d, id:%d, len:%d\n", hdr->code, hdr->id, len_orig);
len -= sizeof(*hdr);
@@ -169,41 +168,84 @@ radius_parse(char *buf, int len, int port, enum socket_type type)
struct radius_tlv *tlv = (struct radius_tlv *)avp;
if (len < tlv->len) {
printf("invalid TLV length\n");
ULOG_ERR("invalid TLV length\n");
return -1;
}
if (tlv->id == TLV_STATION_ID)
station_id = tlv;
if (tlv->id == TLV_VENDOR && ntohl(*(uint32_t *) tlv->data) == TIP_VENDOR) {
struct radius_tlv *vendor = (struct radius_tlv *) &tlv->data[6];
if (vendor->id == TLV_TIP_SERVER_V4)
strncpy(server_ip_str, vendor->data, vendor->len - 2);
}
if (tlv->id == TLV_PROXY_STATE)
proxy_state = tlv;
printf("\tID:%d, len:%d\n", tlv->id, tlv->len);
avp += tlv->len;
len -= tlv->len;
}
if (!station_id) {
printf("no station ID found\n");
if (!proxy_state) {
ULOG_ERR("no proxy_state found\n");
return -1;
}
if (!*server_ip_str) {
printf("no server ip found\n");
return -1;
}
memcpy(station_id_str, station_id->data, station_id->len - 2);
printf("\tcalling station id:%s, server ip:%s\n", station_id_str, server_ip_str);
radius_station_add(station_id_str, port, type);
memcpy(proxy_state_str, proxy_state->data, proxy_state->len - 2);
printf("\tfowarding to %s, prox_state:%s\n", tx ? "gateway" : "hostapd", proxy_state_str);
if (tx) {
radius_proxy_state_add(proxy_state_str, port, type);
radius_forward_gw(buf, type);
} else {
struct radius_proxy_state *proxy = avl_find_element(&radius_proxy_states, proxy_state, proxy, avl);
struct radius_proxy_state_key key = {};
struct sockaddr_in dest;
struct radius_socket *sock;
radius_forward(buf, server_ip_str, type);
switch(type) {
case RADIUS_AUTH:
sock = sock_auth;
break;
case RADIUS_ACCT:
sock = sock_acct;
break;
default:
ULOG_ERR("bad socket type\n");
return -1;
}
strcpy(key.id, proxy_state_str);
key.type = type;
proxy = avl_find_element(&radius_proxy_states, &key, proxy, avl);
if (!proxy) {
ULOG_ERR("unknown proxy_state, dropping frame\n");
return -1;
}
memset(&dest, 0, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = proxy->port;
inet_pton(AF_INET, "127.0.0.1", &(dest.sin_addr.s_addr));
if (sendto(sock->fd.fd, buf, len_orig,
MSG_DONTWAIT, (struct sockaddr*)&dest, sizeof(dest)) < 0)
ULOG_ERR("failed to deliver frame to localhost\n");
}
return 0;
}
void
gateway_recv(char *data, enum socket_type type)
{
int len = 0;
char *frame;
frame = b64dec(data, &len);
if (!frame) {
ULOG_ERR("failed to b64_decode frame\n");
return;
}
radius_parse(frame, len, 0, type, 0);
free(frame);
}
static void
sock_recv(struct uloop_fd *u, unsigned int events)
{
@@ -223,13 +265,10 @@ sock_recv(struct uloop_fd *u, unsigned int events)
.msg_control = cmsg_buf,
.msg_controllen = sizeof(cmsg_buf),
};
struct cmsghdr *cmsg;
struct radius_socket *sock = container_of(u, struct radius_socket, fd);
int len;
do {
struct in_pktinfo *pkti = NULL;
len = recvmsg(u->fd, &msg, 0);
if (len < 0) {
switch (errno) {
@@ -244,21 +283,9 @@ sock_recv(struct uloop_fd *u, unsigned int events)
}
}
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_type != IP_PKTINFO)
continue;
pkti = (struct in_pktinfo *) CMSG_DATA(cmsg);
}
if (!pkti) {
printf("Received packet without ifindex\n");
continue;
}
inet_ntop(AF_INET, &sin.sin_addr, addr_str, sizeof(addr_str));
printf("RX: src:%s:%d, len=%d\n", addr_str, sin.sin_port, len);
radius_parse(buf, len, sin.sin_port, sock->type);
radius_parse(buf, len, sin.sin_port, sock->type, 1);
} while (1);
}
@@ -266,7 +293,6 @@ static struct radius_socket *
sock_open(char *port, enum socket_type type)
{
struct radius_socket *sock = malloc(sizeof(*sock));
int yes = 1;
if (!sock)
return NULL;
@@ -281,8 +307,6 @@ sock_open(char *port, enum socket_type type)
free(sock);
return NULL;
}
if (setsockopt(sock->fd.fd, IPPROTO_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0)
perror("setsockopt(IP_PKTINFO)");
sock->type = type;
sock->fd.cb = sock_recv;
@@ -292,65 +316,20 @@ sock_open(char *port, enum socket_type type)
return sock;
}
static void
ubus_event_handler_cb(struct ubus_context *ctx, struct ubus_event_handler *ev,
const char *type, struct blob_attr *msg)
{
enum {
EVENT_ID,
EVENT_PATH,
__EVENT_MAX
};
static const struct blobmsg_policy status_policy[__EVENT_MAX] = {
[EVENT_ID] = { .name = "id", .type = BLOBMSG_TYPE_INT32 },
[EVENT_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
};
struct blob_attr *tb[__EVENT_MAX];
char *path;
uint32_t id;
blobmsg_parse(status_policy, __EVENT_MAX, tb, blob_data(msg), blob_len(msg));
if (!tb[EVENT_ID] || !tb[EVENT_PATH])
return;
path = blobmsg_get_string(tb[EVENT_PATH]);
id = blobmsg_get_u32(tb[EVENT_ID]);
if (strcmp(path, "ucentral"))
return;
if (!strcmp("ubus.object.remove", type))
ucentral = 0;
else
ucentral = id;
}
static struct ubus_event_handler ubus_event_handler = { .cb = ubus_event_handler_cb };
static void
ubus_connect_handler(struct ubus_context *ctx)
{
ubus_register_event_handler(ctx, &ubus_event_handler, "ubus.object.add");
ubus_register_event_handler(ctx, &ubus_event_handler, "ubus.object.remove");
ubus_lookup_id(ctx, "ucentral", &ucentral);
}
int main(int argc, char **argv)
{
ulog_open(ULOG_STDIO | ULOG_SYSLOG, LOG_DAEMON, "radius-gw-proxy");
uloop_init();
conn.cb = ubus_connect_handler;
ubus_auto_connect(&conn);
ubus_init();
sock_open("1812", RADIUS_AUTH);
sock_open("1813", RADIUS_ACCT);
sock_auth = sock_open("1812", RADIUS_AUTH);
sock_acct = sock_open("1813", RADIUS_ACCT);
uloop_run();
uloop_end();
ubus_deinit();
return 0;
}

View File

@@ -0,0 +1,122 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#include <string.h>
#include <libubox/ulog.h>
#include <libubus.h>
#include "ubus.h"
struct ubus_auto_conn conn;
uint32_t ucentral;
enum {
RADIUS_TYPE,
RADIUS_DATA,
__RADIUS_MAX,
};
static const struct blobmsg_policy frame_policy[__RADIUS_MAX] = {
[RADIUS_TYPE] = { .name = "radius", .type = BLOBMSG_TYPE_STRING },
[RADIUS_DATA] = { .name = "data", .type = BLOBMSG_TYPE_STRING },
};
static int ubus_frame_cb(struct ubus_context *ctx,
struct ubus_object *obj,
struct ubus_request_data *req,
const char *method, struct blob_attr *msg)
{
struct blob_attr *tb[__RADIUS_MAX] = {};
enum socket_type type;
char *radius, *data;
blobmsg_parse(frame_policy, __RADIUS_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg));
if (!tb[RADIUS_TYPE] || !tb[RADIUS_DATA])
return UBUS_STATUS_INVALID_ARGUMENT;
radius = blobmsg_get_string(tb[RADIUS_TYPE]);
data = blobmsg_get_string(tb[RADIUS_DATA]);
if (!strcmp(radius, "auth"))
type = RADIUS_AUTH;
else if (!strcmp(radius, "acct"))
type = RADIUS_ACCT;
else
return UBUS_STATUS_INVALID_ARGUMENT;
gateway_recv(data, type);
return UBUS_STATUS_OK;
}
static const struct ubus_method ucentral_methods[] = {
UBUS_METHOD("frame", ubus_frame_cb, frame_policy),
};
static struct ubus_object_type ubus_object_type =
UBUS_OBJECT_TYPE("radius.proxy", ucentral_methods);
struct ubus_object ubus_object = {
.name = "radius.proxy",
.type = &ubus_object_type,
.methods = ucentral_methods,
.n_methods = ARRAY_SIZE(ucentral_methods),
};
static void
ubus_event_handler_cb(struct ubus_context *ctx, struct ubus_event_handler *ev,
const char *type, struct blob_attr *msg)
{
enum {
EVENT_ID,
EVENT_PATH,
__EVENT_MAX
};
static const struct blobmsg_policy status_policy[__EVENT_MAX] = {
[EVENT_ID] = { .name = "id", .type = BLOBMSG_TYPE_INT32 },
[EVENT_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
};
struct blob_attr *tb[__EVENT_MAX];
char *path;
uint32_t id;
blobmsg_parse(status_policy, __EVENT_MAX, tb, blob_data(msg), blob_len(msg));
if (!tb[EVENT_ID] || !tb[EVENT_PATH])
return;
path = blobmsg_get_string(tb[EVENT_PATH]);
id = blobmsg_get_u32(tb[EVENT_ID]);
if (strcmp(path, "ucentral"))
return;
if (!strcmp("ubus.object.remove", type))
ucentral = 0;
else
ucentral = id;
}
static struct ubus_event_handler ubus_event_handler = { .cb = ubus_event_handler_cb };
static void
ubus_connect_handler(struct ubus_context *ctx)
{
ubus_add_object(ctx, &ubus_object);
ubus_register_event_handler(ctx, &ubus_event_handler, "ubus.object.add");
ubus_register_event_handler(ctx, &ubus_event_handler, "ubus.object.remove");
ubus_lookup_id(ctx, "ucentral", &ucentral);
}
void ubus_init(void)
{
memset(&conn, 0, sizeof(conn));
ucentral = 0;
conn.cb = ubus_connect_handler;
ubus_auto_connect(&conn);
}
void ubus_deinit(void)
{
ubus_auto_shutdown(&conn);
}

View File

@@ -0,0 +1,13 @@
enum socket_type {
RADIUS_AUTH = 0,
RADIUS_ACCT,
RADIUS_DAS
};
extern struct ubus_auto_conn conn;
extern uint32_t ucentral;
void ubus_init(void);
void ubus_deinit(void);
void gateway_recv(char *data, enum socket_type type);

View File

@@ -4,10 +4,10 @@ PKG_NAME:=ucentral-client
PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-client.git
PKG_MIRROR_HASH:=afcdce6a4ea24405b98147bac342a24c21ad6ba91e57a2a966018949ece9a294
PKG_MIRROR_HASH:=2fc20dd3b5c8a7d93e17a843a2feaa823a6f8e902fdca96df62aa3f12efdfbaa
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2022-05-29
PKG_SOURCE_VERSION:=a4671bbe7d30b1286b718e08573d73dae4df344a
PKG_SOURCE_DATE:=2022-06-22
PKG_SOURCE_VERSION:=68fe6c21f2c2643de79ecd5558a51ffb84168f75
PKG_LICENSE:=BSD-3-Clause
PKG_MAINTAINER:=John Crispin <john@phrozen.org>

View File

@@ -4,10 +4,10 @@ PKG_NAME:=ucentral-schema
PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-schema.git
PKG_MIRROR_HASH:=3ba2d66f8e52c784f136bf340ab2fb81568a1d8df8dbebfa487fc57652bea04f
PKG_MIRROR_HASH:=7ec098910bf4969da8ceb0f04aacd8af1cb0657dfb105bc8a499b98407a2c406
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2022-05-29
PKG_SOURCE_VERSION:=96324e2f7443cb3ae70f8fca10f37548f673e3f8
PKG_SOURCE_VERSION:=fc8fdcfed71e31e6def4d57d57acb2fa38d70253
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
PKG_LICENSE:=BSD-3-Clause

View File

@@ -1,23 +1,12 @@
{
"uuid": 2,
"radios": [
{
"band": "6G",
"country": "CA",
"channel-mode": "HE",
"channel-width": 80
},
{
"band": "5G",
"country": "CA",
"channel-mode": "HE",
"channel-width": 80
},
{
"band": "2G",
"country": "CA",
"channel-mode": "HE",
"channel-width": 80
"channel-width": 20,
"channel": 1
}
],
@@ -44,8 +33,27 @@
},
"tunnel": {
"proto": "gre",
"peer-address": "50.210.104.108"
}
"peer-address": "192.168.178.59"
},
"ipv4": {
"addressing": "static",
"subnet": "192.168.2.2/24",
"gateway": "192.168.2.1"
},
"ssids": [
{
"name": "OpenWifi-GRE",
"wifi-bands": [
"2G"
],
"bss-mode": "ap",
"encryption": {
"proto": "psk2",
"key": "OpenWifi",
"ieee80211w": "optional"
}
}
]
},
{
"name": "LAN",
@@ -69,19 +77,15 @@
},
"ssids": [
{
"name": "Maverick",
"name": "OpenWifi-GRE-NAT",
"wifi-bands": [
"5G",
"2G"
],
"bss-mode": "ap",
"encryption": {
"proto": "none",
"proto": "psk2",
"key": "OpenWifi",
"ieee80211w": "optional"
},
"roaming": {
"message-exchange": "ds",
"generate-psk": true
}
}
]

View File

@@ -1,23 +1,11 @@
{
"uuid": 2,
"radios": [
{
"band": "6G",
"country": "CA",
"channel-mode": "HE",
"channel-width": 80
},
{
"band": "5G",
"country": "CA",
"channel-mode": "HE",
"channel-width": 80
},
{
"band": "2G",
"country": "CA",
"channel-mode": "HE",
"channel-width": 80
"channel": 1
}
],
@@ -49,13 +37,31 @@
},
"ipv4": {
"addressing": "static",
"subnet": "10.0.0.1/24"
}
"subnet": "10.0.0.2/24",
"gateway": "10.0.0.1"
},
"ssids": [
{
"name": "OpenWifi-VXLAN",
"wifi-bands": [
"2G"
],
"bss-mode": "ap",
"encryption": {
"proto": "psk2",
"key": "OpenWifi",
"ieee80211w": "optional"
}
}
]
},
{
"name": "LAN",
"role": "downstream",
"services": [ "ssh" ],
"vlan": {
"id": 100
},
"ethernet": [
{
"select-ports": [
@@ -74,19 +80,15 @@
},
"ssids": [
{
"name": "Maverick",
"name": "OpenWifi-VXLAN",
"wifi-bands": [
"5G",
"2G"
],
"bss-mode": "ap",
"encryption": {
"proto": "none",
"proto": "psk2",
"key": "OpenWifi",
"ieee80211w": "optional"
},
"roaming": {
"message-exchange": "ds",
"generate-psk": true
}
}
]

View File

@@ -6,12 +6,6 @@ PKG_RELEASE:=1
PKG_LICENSE:=GPL-2.0
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
PKG_SOURCE_URL=https://github.com/blogic/udhcpsnoop.git
PKG_MIRROR_HASH:=721f005e51c46b9381f3e5a6576b8a31afd3903ddb0e7b569d7337a57ca33dd2
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2021-04-12
PKG_SOURCE_VERSION:=b86639904147a40be32ac43cd89c21109ffc3543
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
@@ -19,13 +13,20 @@ define Package/udhcpsnoop
SECTION:=net
CATEGORY:=Network
TITLE:=DHCP Snooping Daemon
DEPENDS:=+libubox +libubus +libuci
DEPENDS:=+libubox +libubus +kmod-ifb +tc
endef
define Package/udhcpsnoop/install
$(INSTALL_DIR) \
$(1)/usr/sbin \
$(1)/etc/init.d \
$(1)/etc/config \
$(1)/etc/hotplug.d/net
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/udhcpsnoop $(1)/usr/sbin/
$(CP) ./files/* $(1)
$(INSTALL_BIN) ./files/dhcpsnoop.init $(1)/etc/init.d/dhcpsnoop
$(INSTALL_DATA) ./files/dhcpsnoop.conf $(1)/etc/config/dhcpsnoop
$(INSTALL_DATA) ./files/dhcpsnoop.hotplug $(1)/etc/hotplug.d/net/10-dhcpsnoop
endef
$(eval $(call BuildPackage,udhcpsnoop))

View File

@@ -0,0 +1,6 @@
#config device
# option disabled 1
# option name eth0
# option ingress 1
# option egress 1

View File

@@ -0,0 +1,2 @@
#!/bin/sh
ubus call dhcpsnoop check_devices

View File

@@ -0,0 +1,60 @@
#!/bin/sh /etc/rc.common
# Copyright (c) 2021 OpenWrt.org
START=40
USE_PROCD=1
PROG=/usr/sbin/udhcpsnoop
add_option() {
local type="$1"
local name="$2"
local default="$3"
config_get val "$cfg" "$name"
[ -n "$val" ] && json_add_$type "$name" "${val:-$default}"
}
add_device() {
local cfg="$1"
config_get_bool disabled "$cfg" disabled 0
[ "$disabled" -gt 0 ] && return
config_get name "$cfg" name
json_add_object "$name"
add_option boolean ingress 1
add_option boolean egress 1
json_close_object
}
reload_service() {
json_init
config_load dhcpsnoop
json_add_object devices
config_foreach add_device device
json_close_object
ubus call dhcpsnoop config "$(json_dump)"
}
service_triggers() {
procd_add_reload_trigger dhcpsnoop
}
start_service() {
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn
procd_close_instance
}
service_started() {
ubus -t 10 wait_for dhcpsnoop
[ $? = 0 ] && reload_service
}

View File

@@ -1,4 +0,0 @@
config snooping
option enable 0
#list network lan
#list network wan

View File

@@ -1,22 +0,0 @@
#!/bin/sh /etc/rc.common
START=80
USE_PROCD=1
PROG=/usr/sbin/udhcpsnoop
service_triggers() {
procd_add_reload_trigger dhcpsnoop
}
start_service() {
[ "$(uci get dhcpsnoop.@snooping[-1].enable)" -eq 1 ] || return
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn
procd_close_instance
}
reload_service() {
restart
}

View File

@@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.10)
PROJECT(udhcpsnoop C)
INCLUDE(GNUInstallDirs)
ADD_DEFINITIONS(-Os -ggdb -Wall -Werror --std=gnu99 -Wmissing-declarations)
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
SET(SOURCES main.c ubus.c dev.c dhcp.c cache.c)
SET(LIBS ubox ubus)
ADD_EXECUTABLE(udhcpsnoop ${SOURCES})
TARGET_LINK_LIBRARIES(udhcpsnoop ${LIBS})
INSTALL(TARGETS udhcpsnoop
RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
)

View File

@@ -0,0 +1,77 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
*/
#include <libubox/avl.h>
#include "dhcpsnoop.h"
#include "msg.h"
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAC_VAR(x) x[0], x[1], x[2], x[3], x[4], x[5]
#define IP_FMT "%d.%d.%d.%d"
#define IP_VAR(x) x[0], x[1], x[2], x[3]
struct mac {
struct avl_node avl;
uint8_t mac[6];
uint8_t ip[4];
struct uloop_timeout rebind;
};
static int
avl_mac_cmp(const void *k1, const void *k2, void *ptr)
{
return memcmp(k1, k2, 6);
}
static struct avl_tree mac_tree = AVL_TREE_INIT(mac_tree, avl_mac_cmp, false, NULL);
static void
cache_expire(struct uloop_timeout *t)
{
struct mac *mac = container_of(t, struct mac, rebind);
avl_delete(&mac_tree, &mac->avl);
free(mac);
}
void
cache_entry(void *_msg, uint32_t rebind)
{
struct dhcpv4_message *msg = (struct dhcpv4_message *) _msg;
struct mac *mac;
mac = avl_find_element(&mac_tree, msg->chaddr, mac, avl);
if (!mac) {
mac = malloc(sizeof(*mac));
if (!mac)
return;
memset(mac, 0, sizeof(*mac));
memcpy(mac->mac, msg->chaddr, 6);
mac->avl.key = mac->mac;
mac->rebind.cb = cache_expire;
avl_insert(&mac_tree, &mac->avl);
}
memcpy(mac->ip, &msg->yiaddr.s_addr, 4);
uloop_timeout_set(&mac->rebind, rebind * 1000);
}
void
cache_dump(struct blob_buf *b)
{
struct mac *mac;
avl_for_each_element(&mac_tree, mac, avl) {
char addr[18];
char ip[16];
snprintf(addr, sizeof(addr), MAC_FMT, MAC_VAR(mac->mac));
snprintf(ip, sizeof(ip), IP_FMT, IP_VAR(mac->ip));
blobmsg_add_string(b, addr, ip);
}
}

View File

@@ -0,0 +1,425 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
*/
#include <netinet/if_ether.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/udp.h>
#include <netpacket/packet.h>
#include <net/if.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <libubox/vlist.h>
#include <libubox/avl-cmp.h>
#include "dhcpsnoop.h"
#define APPEND(_buf, _ofs, _format, ...) _ofs += snprintf(_buf + _ofs, sizeof(_buf) - _ofs, _format, ##__VA_ARGS__)
struct vlan_hdr {
uint16_t tci;
uint16_t proto;
};
struct packet {
void *buffer;
unsigned int len;
};
struct device {
struct vlist_node node;
char ifname[IFNAMSIZ + 1];
int ifindex;
bool ingress;
bool egress;
bool changed;
bool active;
};
static void dev_update_cb(struct vlist_tree *tree, struct vlist_node *node_new,
struct vlist_node *node_old);
static struct uloop_fd ufd;
static VLIST_TREE(devices, avl_strcmp, dev_update_cb, true, false);
static void *pkt_peek(struct packet *pkt, unsigned int len)
{
if (len > pkt->len)
return NULL;
return pkt->buffer;
}
static void *pkt_pull(struct packet *pkt, unsigned int len)
{
void *ret = pkt_peek(pkt, len);
if (!ret)
return NULL;
pkt->buffer += len;
pkt->len -= len;
return ret;
}
static bool
proto_is_vlan(uint16_t proto)
{
return proto == ETH_P_8021Q || proto == ETH_P_8021AD;
}
static void
dhcpsnoop_packet_cb(struct packet *pkt)
{
struct ethhdr *eth;
struct ip6_hdr *ip6;
struct ip *ip;
struct udphdr *udp;
uint16_t proto, port;
const char *type;
bool ipv6 = false;
uint32_t rebind = 0;
eth = pkt_pull(pkt, sizeof(*eth));
if (!eth)
return;
proto = be16_to_cpu(eth->h_proto);
if (proto_is_vlan(proto)) {
struct vlan_hdr *vlan;
vlan = pkt_pull(pkt, sizeof(*vlan));
if (!vlan)
return;
proto = be16_to_cpu(vlan->proto);
}
switch (proto) {
case ETH_P_IP:
ip = pkt_peek(pkt, sizeof(struct ip));
if (!ip)
return;
if (!pkt_pull(pkt, ip->ip_hl * 4))
return;
proto = ip->ip_p;
break;
case ETH_P_IPV6:
ip6 = pkt_pull(pkt, sizeof(*ip6));
if (!ip6)
return;
proto = ip6->ip6_nxt;
ipv6 = true;
break;
default:
return;
}
if (proto != IPPROTO_UDP)
return;
udp = pkt_pull(pkt, sizeof(struct udphdr));
if (!udp)
return;
port = ntohs(udp->uh_sport);
if (!ipv6)
type = dhcpsnoop_parse_ipv4(pkt->buffer, pkt->len, port, &rebind);
else
type = dhcpsnoop_parse_ipv6(pkt->buffer, pkt->len, port);
if (!type)
return;
dhcpsnoop_ubus_notify(type, pkt->buffer, pkt->len);
if (!ipv6 && !strcmp(type, "ack") && rebind)
cache_entry(pkt->buffer, rebind);
}
static void
dhcpsnoop_socket_cb(struct uloop_fd *fd, unsigned int events)
{
static uint8_t buf[8192];
struct packet pkt = {
.buffer = buf,
};
int len;
retry:
len = recvfrom(fd->fd, buf, sizeof(buf), MSG_DONTWAIT, NULL, NULL);
if (len < 0) {
if (errno == EINTR)
goto retry;
return;
}
if (!len)
return;
pkt.len = len;
dhcpsnoop_packet_cb(&pkt);
}
static int
dhcpsnoop_open_socket(void)
{
struct sockaddr_ll sll = {
.sll_family = AF_PACKET,
.sll_protocol = htons(ETH_P_ALL),
};
int sock;
sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (sock == -1) {
ULOG_ERR("failed to create raw socket: %s\n", strerror(errno));
return -1;
}
sll.sll_ifindex = if_nametoindex(DHCPSNOOP_IFB_NAME);
if (bind(sock, (struct sockaddr *)&sll, sizeof(sll))) {
ULOG_ERR("failed to bind socket to "DHCPSNOOP_IFB_NAME": %s\n",
strerror(errno));
goto error;
}
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK);
ufd.fd = sock;
ufd.cb = dhcpsnoop_socket_cb;
uloop_fd_add(&ufd, ULOOP_READ);
return 0;
error:
close(sock);
return -1;
}
static int
prepare_filter_cmd(char *buf, int len, const char *dev, int prio, bool add, bool egress)
{
return snprintf(buf, len, "tc filter %s dev '%s' %sgress prio %d",
add ? "add" : "del", dev, egress ? "e" : "in", prio);
}
static void
dhcpsnoop_dev_attach_filters(struct device *dev, bool egress)
{
int prio = DHCPSNOOP_PRIO_BASE;
char buf[256];
int ofs;
ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress);
APPEND(buf, ofs, " protocol ip u32 match ip sport 67 0xffff"
" flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME);
dhcpsnoop_run_cmd(buf, false);
ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress);
APPEND(buf, ofs, " protocol 802.1Q u32 offset plus 4 match ip sport 67 0xffff"
" flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME);
dhcpsnoop_run_cmd(buf, false);
ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress);
APPEND(buf, ofs, " protocol ip u32 match ip sport 68 0xffff"
" flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME);
dhcpsnoop_run_cmd(buf, false);
ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress);
APPEND(buf, ofs, " protocol 802.1Q u32 offset plus 4 match ip sport 68 0xffff"
" flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME);
dhcpsnoop_run_cmd(buf, false);
ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress);
APPEND(buf, ofs, " protocol ipv6 u32 match ip6 sport 546 0xfffe"
" flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME);
dhcpsnoop_run_cmd(buf, false);
ofs = prepare_filter_cmd(buf, sizeof(buf), dev->ifname, prio++, true, egress);
APPEND(buf, ofs, " protocol 802.1Q u32 offset plus 4 match ip6 sport 546 0xfffe"
" flowid 1:1 action mirred ingress mirror dev " DHCPSNOOP_IFB_NAME);
dhcpsnoop_run_cmd(buf, false);
}
static void
dhcpsnoop_dev_cleanup_filters(struct device *dev, bool egress)
{
char buf[128];
int i;
for (i = DHCPSNOOP_PRIO_BASE; i < DHCPSNOOP_PRIO_BASE + 6; i++) {
prepare_filter_cmd(buf, sizeof(buf), dev->ifname, i, false, egress);
dhcpsnoop_run_cmd(buf, true);
}
}
static void
dhcpsnoop_dev_attach(struct device *dev)
{
char buf[64];
dev->active = true;
snprintf(buf, sizeof(buf), "tc qdisc add dev '%s' clsact", dev->ifname);
dhcpsnoop_run_cmd(buf, true);
if (dev->ingress)
dhcpsnoop_dev_attach_filters(dev, false);
if (dev->egress)
dhcpsnoop_dev_attach_filters(dev, true);
}
static void
dhcpsnoop_dev_cleanup(struct device *dev)
{
dev->active = false;
dhcpsnoop_dev_cleanup_filters(dev, true);
dhcpsnoop_dev_cleanup_filters(dev, false);
}
static void
__dhcpsnoop_dev_check(struct device *dev)
{
int ifindex;
ifindex = if_nametoindex(dev->ifname);
if (ifindex != dev->ifindex) {
dev->ifindex = ifindex;
dev->changed = true;
}
if (!dev->changed)
return;
dev->changed = false;
dhcpsnoop_dev_cleanup(dev);
if (ifindex)
dhcpsnoop_dev_attach(dev);
}
static void dev_update_cb(struct vlist_tree *tree, struct vlist_node *node_new,
struct vlist_node *node_old)
{
struct device *dev = NULL, *dev_free = NULL;
if (node_old && node_new) {
dev = container_of(node_old, struct device, node);
dev_free = container_of(node_new, struct device, node);
if (dev->ingress != dev_free->ingress ||
dev->egress != dev_free->egress)
dev->changed = true;
dev->ingress = dev_free->ingress;
dev->egress = dev_free->egress;
} else if (node_old) {
dev_free = container_of(node_old, struct device, node);
if (dev_free->active)
dhcpsnoop_dev_cleanup(dev_free);
} else if (node_new) {
dev = container_of(node_new, struct device, node);
}
if (dev)
__dhcpsnoop_dev_check(dev);
if (dev_free)
free(dev_free);
}
static void
dhcpsnoop_dev_config_add(struct blob_attr *data)
{
enum {
DEV_ATTR_INGRESS,
DEV_ATTR_EGRESS,
__DEV_ATTR_MAX
};
static const struct blobmsg_policy policy[__DEV_ATTR_MAX] = {
[DEV_ATTR_INGRESS] = { "ingress", BLOBMSG_TYPE_BOOL },
[DEV_ATTR_EGRESS] = { "egress", BLOBMSG_TYPE_BOOL },
};
struct blob_attr *tb[__DEV_ATTR_MAX];
struct blob_attr *cur;
struct device *dev;
int len;
if (blobmsg_type(data) != BLOBMSG_TYPE_TABLE)
return;
dev = calloc(1, sizeof(*dev));
len = snprintf(dev->ifname, sizeof(dev->ifname), "%s", blobmsg_name(data));
if (!len || len > IFNAMSIZ)
goto free;
blobmsg_parse(policy, ARRAY_SIZE(tb), tb, blobmsg_data(data), blobmsg_len(data));
if ((cur = tb[DEV_ATTR_INGRESS]) != NULL)
dev->ingress = blobmsg_get_bool(cur);
if ((cur = tb[DEV_ATTR_EGRESS]) != NULL)
dev->egress = blobmsg_get_bool(cur);
if (!dev->ingress && !dev->egress)
goto free;
vlist_add(&devices, &dev->node, dev->ifname);
return;
free:
free(dev);
return;
}
void dhcpsnoop_dev_config_update(struct blob_attr *data)
{
struct blob_attr *cur;
int rem;
vlist_update(&devices);
blobmsg_for_each_attr(cur, data, rem)
dhcpsnoop_dev_config_add(cur);
vlist_flush(&devices);
}
void dhcpsnoop_dev_check(void)
{
struct device *dev;
vlist_for_each_element(&devices, dev, node)
__dhcpsnoop_dev_check(dev);
}
int dhcpsnoop_dev_init(void)
{
dhcpsnoop_dev_done();
if (dhcpsnoop_run_cmd("ip link add "DHCPSNOOP_IFB_NAME" type ifb", false) ||
dhcpsnoop_run_cmd("ip link set dev "DHCPSNOOP_IFB_NAME" up", false) ||
dhcpsnoop_open_socket())
return -1;
return 0;
}
void dhcpsnoop_dev_done(void)
{
if (ufd.registered) {
uloop_fd_delete(&ufd);
close(ufd.fd);
}
dhcpsnoop_run_cmd("ip link del "DHCPSNOOP_IFB_NAME, true);
vlist_flush_all(&devices);
}

View File

@@ -0,0 +1,90 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
*/
#include "dhcpsnoop.h"
#include "msg.h"
const char *dhcpsnoop_parse_ipv4(const void *buf, size_t len, uint16_t port, uint32_t *rebind)
{
const struct dhcpv4_message *msg = buf;
const uint8_t *pos, *end;
char type = 0;
if (port != 67 && port != 68)
return NULL;
if (len < sizeof(*msg))
return NULL;
if (ntohl(msg->magic) != DHCPV4_MAGIC)
return NULL;
pos = msg->options;
end = buf + len;
while (pos < end) {
const uint8_t *opt = pos++;
if (*opt == DHCPV4_OPT_END)
break;
if (*opt == DHCPV4_OPT_PAD)
continue;
if (pos >= end || 1 + *pos > end - pos)
break;
pos += *pos + 1;
if (pos >= end)
break;
switch (*opt) {
case DHCPV4_OPT_MSG_TYPE:
if (!opt[1])
continue;
type = opt[2];
break;
case DHCPV4_OPT_REBIND:
if (!rebind || opt[1] != 4)
continue;
*rebind = *((uint32_t *) &opt[2]);
break;
}
}
switch(type) {
case DHCPV4_MSG_ACK:
return "ack";
case DHCPV4_MSG_DISCOVER:
return "discover";
case DHCPV4_MSG_OFFER:
return "offer";
case DHCPV4_MSG_REQUEST:
return "request";
}
return NULL;
}
const char *dhcpsnoop_parse_ipv6(const void *buf, size_t len, uint16_t port)
{
const struct dhcpv6_message *msg = buf;
if (port != 546 && port != 547)
return NULL;
switch(msg->msg_type) {
case DHCPV6_MSG_SOLICIT:
return "solicit";
case DHCPV6_MSG_REPLY:
return "reply";
case DHCPV6_MSG_RENEW:
return "renew";
default:
return NULL;
}
}

View File

@@ -0,0 +1,32 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
*/
#ifndef __DHCPSNOOP_H
#define __DHCPSNOOP_H
#include <libubox/blobmsg.h>
#include <libubox/ulog.h>
#include <libubox/uloop.h>
#define DHCPSNOOP_IFB_NAME "ifb-dhcp"
#define DHCPSNOOP_PRIO_BASE 0x100
int dhcpsnoop_run_cmd(char *cmd, bool ignore_error);
int dhcpsnoop_dev_init(void);
void dhcpsnoop_dev_done(void);
void dhcpsnoop_dev_config_update(struct blob_attr *data);
void dhcpsnoop_dev_check(void);
void dhcpsnoop_ubus_init(void);
void dhcpsnoop_ubus_done(void);
void dhcpsnoop_ubus_notify(const char *type, const uint8_t *msg, size_t len);
const char *dhcpsnoop_parse_ipv4(const void *buf, size_t len, uint16_t port, uint32_t *rebind);
const char *dhcpsnoop_parse_ipv6(const void *buf, size_t len, uint16_t port);
void cache_entry(void *msg, uint32_t rebind);
void cache_dump(struct blob_buf *b);
#endif

View File

@@ -0,0 +1,84 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
*/
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include "dhcpsnoop.h"
int dhcpsnoop_run_cmd(char *cmd, bool ignore_error)
{
char *argv[] = { "sh", "-c", cmd, NULL };
bool first = true;
int status = -1;
char buf[512];
int fds[2];
FILE *f;
int pid;
if (pipe(fds))
return -1;
pid = fork();
if (!pid) {
close(fds[0]);
if (fds[1] != STDOUT_FILENO)
dup2(fds[1], STDOUT_FILENO);
if (fds[1] != STDERR_FILENO)
dup2(fds[1], STDERR_FILENO);
if (fds[1] > STDERR_FILENO)
close(fds[1]);
execv("/bin/sh", argv);
exit(1);
}
if (pid < 0)
return -1;
close(fds[1]);
f = fdopen(fds[0], "r");
if (!f) {
close(fds[0]);
goto out;
}
while (fgets(buf, sizeof(buf), f) != NULL) {
if (!strlen(buf))
break;
if (ignore_error)
continue;
if (first) {
ULOG_WARN("Command: %s\n", cmd);
first = false;
}
ULOG_WARN("%s%s", buf, strchr(buf, '\n') ? "" : "\n");
}
fclose(f);
out:
while (waitpid(pid, &status, 0) < 0)
if (errno != EINTR)
break;
return status;
}
int main(int argc, char **argv)
{
ulog_open(ULOG_STDIO | ULOG_SYSLOG, LOG_DAEMON, "udhcpsnoop");
uloop_init();
dhcpsnoop_ubus_init();
dhcpsnoop_dev_init();
uloop_run();
dhcpsnoop_ubus_done();
dhcpsnoop_dev_done();
uloop_done();
return 0;
}

View File

@@ -0,0 +1,88 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#ifndef __DHCPSNOOP_MSG_H
#define __DHCPSNOOP_MSG_H
#include <netinet/in.h>
#include <stdint.h>
enum dhcpv4_msg {
DHCPV4_MSG_DISCOVER = 1,
DHCPV4_MSG_OFFER = 2,
DHCPV4_MSG_REQUEST = 3,
DHCPV4_MSG_DECLINE = 4,
DHCPV4_MSG_ACK = 5,
DHCPV4_MSG_NAK = 6,
DHCPV4_MSG_RELEASE = 7,
DHCPV4_MSG_INFORM = 8,
DHCPV4_MSG_FORCERENEW = 9,
};
enum dhcpv4_opt {
DHCPV4_OPT_PAD = 0,
DHCPV4_OPT_NETMASK = 1,
DHCPV4_OPT_ROUTER = 3,
DHCPV4_OPT_DNSSERVER = 6,
DHCPV4_OPT_DOMAIN = 15,
DHCPV4_OPT_MTU = 26,
DHCPV4_OPT_BROADCAST = 28,
DHCPV4_OPT_NTPSERVER = 42,
DHCPV4_OPT_LEASETIME = 51,
DHCPV4_OPT_MESSAGE = 53,
DHCPV4_OPT_SERVERID = 54,
DHCPV4_OPT_REQOPTS = 55,
DHCPV4_OPT_RENEW = 58,
DHCPV4_OPT_REBIND = 59,
DHCPV4_OPT_IPADDRESS = 50,
DHCPV4_OPT_MSG_TYPE = 53,
DHCPV4_OPT_HOSTNAME = 12,
DHCPV4_OPT_REQUEST = 17,
DHCPV4_OPT_USER_CLASS = 77,
DHCPV4_OPT_AUTHENTICATION = 90,
DHCPV4_OPT_SEARCH_DOMAIN = 119,
DHCPV4_OPT_FORCERENEW_NONCE_CAPABLE = 145,
DHCPV4_OPT_END = 255,
};
struct dhcpv4_message {
uint8_t op;
uint8_t htype;
uint8_t hlen;
uint8_t hops;
uint32_t xid;
uint16_t secs;
uint16_t flags;
struct in_addr ciaddr;
struct in_addr yiaddr;
struct in_addr siaddr;
struct in_addr giaddr;
uint8_t chaddr[16];
char sname[64];
char file[128];
uint32_t magic;
uint8_t options[];
} __attribute__((packed));
#define DHCPV4_MAGIC 0x63825363
enum dhcpv6_opt {
DHCPV6_MSG_SOLICIT = 1,
DHCPV6_MSG_ADVERTISE = 2,
DHCPV6_MSG_REQUEST = 3,
DHCPV6_MSG_CONFIRM = 4,
DHCPV6_MSG_RENEW = 5,
DHCPV6_MSG_REBIND = 6,
DHCPV6_MSG_REPLY = 7,
DHCPV6_MSG_RELEASE = 8,
DHCPV6_MSG_DECLINE = 9,
DHCPV6_MSG_RECONFIGURE = 10,
DHCPV6_MSG_INFORMATION_REQUEST = 11,
DHCPV6_MSG_RELAY_FORW = 12,
DHCPV6_MSG_RELAY_REPL = 13,
};
struct dhcpv6_message {
uint8_t msg_type;
uint8_t transaction_id[3];
uint8_t options[];
} __attribute__((packed));
#endif

View File

@@ -0,0 +1,117 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
*/
#include <libubus.h>
#include "dhcpsnoop.h"
enum {
DS_CONFIG_DEVICES,
__DS_CONFIG_MAX
};
static const struct blobmsg_policy dhcpsnoop_config_policy[__DS_CONFIG_MAX] = {
[DS_CONFIG_DEVICES] = { "devices", BLOBMSG_TYPE_TABLE },
};
static struct blob_buf b;
static int
dhcpsnoop_ubus_config(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
struct blob_attr *tb[__DS_CONFIG_MAX];
blobmsg_parse(dhcpsnoop_config_policy, __DS_CONFIG_MAX, tb,
blobmsg_data(msg), blobmsg_len(msg));
dhcpsnoop_dev_config_update(tb[DS_CONFIG_DEVICES]);
dhcpsnoop_dev_check();
return 0;
}
static int
dhcpsnoop_ubus_check_devices(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
dhcpsnoop_dev_check();
return 0;
}
static int
dhcpsnoop_ubus_dump(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
blob_buf_init(&b, 0);
cache_dump(&b);
ubus_send_reply(ctx, req, b.head);
return 0;
}
static const struct ubus_method dhcpsnoop_methods[] = {
UBUS_METHOD("config", dhcpsnoop_ubus_config, dhcpsnoop_config_policy),
UBUS_METHOD_NOARG("check_devices", dhcpsnoop_ubus_check_devices),
UBUS_METHOD_NOARG("dump", dhcpsnoop_ubus_dump),
};
static struct ubus_object_type dhcpsnoop_object_type =
UBUS_OBJECT_TYPE("dhcpsnoop", dhcpsnoop_methods);
static struct ubus_object dhcpsnoop_object = {
.name = "dhcpsnoop",
.type = &dhcpsnoop_object_type,
.methods = dhcpsnoop_methods,
.n_methods = ARRAY_SIZE(dhcpsnoop_methods),
};
static void
ubus_connect_handler(struct ubus_context *ctx)
{
ubus_add_object(ctx, &dhcpsnoop_object);
}
static struct ubus_auto_conn conn;
void dhcpsnoop_ubus_init(void)
{
conn.cb = ubus_connect_handler;
ubus_auto_connect(&conn);
}
void dhcpsnoop_ubus_done(void)
{
ubus_auto_shutdown(&conn);
blob_buf_free(&b);
}
void dhcpsnoop_ubus_notify(const char *type, const uint8_t *msg, size_t len)
{
char *buf;
fprintf(stderr, "dhcp message type=%s\n", type);
if (!dhcpsnoop_object.has_subscribers)
return;
blob_buf_init(&b, 0);
buf = blobmsg_alloc_string_buffer(&b, "packet", 2 * len + 1);
while (len > 0) {
buf += sprintf(buf, "%02x", *msg);
msg++;
len--;
}
blobmsg_add_string_buffer(&b);
ubus_notify(&conn.ctx, &dhcpsnoop_object, type, b.head, -1);
}

View File

@@ -26,7 +26,7 @@ define Package/unetd
SECTION:=utils
CATEGORY:=Base system
TITLE:=Wireguard network configuration service
DEPENDS:=+libubox +libubus +libblobmsg-json +libnl-tiny +TARGET_ipq807x:kmod-wireguard-backport +!TARGET_ipq807x:kmod-wireguard
DEPENDS:=+libubox +libubus +libblobmsg-json +libnl-tiny +TARGET_ipq807x:kmod-wireguard-backport +!TARGET_ipq807x:kmod-wireguard +wireguard-tools
endef
TARGET_CFLAGS += \

View File

@@ -86,6 +86,11 @@ $(call Package/ath11k-wifi-default)
TITLE:=gl-ax1800 bdf
endef
define Package/ath11k-wifi-motorola-q14
$(call Package/ath11k-wifi-default)
TITLE:=motorola q14 bdf
endef
define ath11k-wifi-install-one-to
$(INSTALL_DIR) $(2)/lib/firmware/$(3)/
$(INSTALL_DATA) $(1) $(2)/lib/firmware/$(3)/board.bin
@@ -173,6 +178,13 @@ define Package/ath11k-wifi-gl-ax1800/install
$(INSTALL_DATA) ./board-gl-ax1800.bin.IPQ6018 $(1)/lib/firmware/ath11k/IPQ6018/hw1.0/board-2.bin
endef
define Package/ath11k-wifi-motorola-q14/install
$(INSTALL_DIR) $(1)/lib/firmware/ath11k/IPQ5018/hw1.0/
$(INSTALL_DIR) $(1)/lib/firmware/ath11k/qcn6122/hw1.0/
$(INSTALL_DATA) ./board-motorol-q14.bin.IPQ5018 $(1)/lib/firmware/ath11k/IPQ5018/hw1.0/board.bin
$(INSTALL_DATA) ./board-2-motorol-q14.bin.QCN6122 $(1)/lib/firmware/ath11k/qcn6122/hw1.0/board-2.bin
endef
$(eval $(call generate-ath11k-wifi-package,cig-wf188,Cigtech WF188))
$(eval $(call generate-ath11k-wifi-package,cig-wf188n,Cigtech WF188n))
$(eval $(call generate-ath11k-wifi-package,cig-wf194c,Cigtech WF194c))
@@ -196,3 +208,4 @@ $(eval $(call BuildPackage,ath11k-wifi-qcom-ipq8074))
$(eval $(call BuildPackage,ath11k-wifi-qcom-ipq6018))
$(eval $(call BuildPackage,ath11k-wifi-qcom-qcn9000))
$(eval $(call BuildPackage,ath11k-wifi-cig-wf196_6g))
$(eval $(call BuildPackage,ath11k-wifi-motorola-q14))

View File

@@ -0,0 +1,25 @@
From c5b68d334fa19e5fa0632d9d361cb613b1384b75 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Mon, 13 Jun 2022 13:33:31 +0200
Subject: [PATCH] dnsmasq: ignore dhcp on the ifb-dhcp interface
Signed-off-by: John Crispin <john@phrozen.org>
---
package/network/services/dnsmasq/files/dnsmasq.init | 1 +
1 file changed, 1 insertion(+)
diff --git a/package/network/services/dnsmasq/files/dnsmasq.init b/package/network/services/dnsmasq/files/dnsmasq.init
index dacd476cd4..d00485da90 100644
--- a/package/network/services/dnsmasq/files/dnsmasq.init
+++ b/package/network/services/dnsmasq/files/dnsmasq.init
@@ -1108,6 +1108,7 @@ dnsmasq_start()
[ -n "$BOOT" ] || config_foreach filter_dnsmasq dhcp dhcp_add "$cfg"
fi
+ xappend "except-interface=ifb-dhcp"
echo >> $CONFIGFILE_TMP
config_foreach filter_dnsmasq cname dhcp_cname_add "$cfg"
--
2.25.1

View File

@@ -0,0 +1,29 @@
From fcea0e786c9311e3fc6ff256ba320aaa07b6ae05 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Mon, 13 Jun 2022 13:37:17 +0200
Subject: [PATCH] wireguard-tools: do not select the kernel module
unetd will select the correct kernel module.
Signed-off-by: John Crispin <john@phrozen.org>
---
package/network/utils/wireguard-tools/Makefile | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/package/network/utils/wireguard-tools/Makefile b/package/network/utils/wireguard-tools/Makefile
index 5f8da147c1..e0df0a6c67 100644
--- a/package/network/utils/wireguard-tools/Makefile
+++ b/package/network/utils/wireguard-tools/Makefile
@@ -38,8 +38,7 @@ define Package/wireguard-tools
TITLE:=WireGuard userspace control program (wg)
DEPENDS:= \
+@BUSYBOX_CONFIG_IP \
- +@BUSYBOX_CONFIG_FEATURE_IP_LINK \
- +kmod-wireguard
+ +@BUSYBOX_CONFIG_FEATURE_IP_LINK
endef
define Package/wireguard-tools/description
--
2.25.1

View File

@@ -0,0 +1,105 @@
From 86dc0a3f51da3440bc216d988c04b225ba169247 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Thu, 16 Jun 2022 12:46:08 +0200
Subject: [PATCH] ipq40xx: add dual boot support for ecw5211
Signed-off-by: John Crispin <john@phrozen.org>
---
.../ipq40xx/base-files/etc/init.d/bootcount | 17 ++++++++++++++---
.../base-files/lib/upgrade/platform.sh | 19 ++++++++++++++++++-
.../arm/boot/dts/qcom-ipq4018-ecw5211.dts | 10 ++++++++++
3 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/target/linux/ipq40xx/base-files/etc/init.d/bootcount b/target/linux/ipq40xx/base-files/etc/init.d/bootcount
index 36b5d56d0c..5cda1fc245 100755
--- a/target/linux/ipq40xx/base-files/etc/init.d/bootcount
+++ b/target/linux/ipq40xx/base-files/etc/init.d/bootcount
@@ -13,13 +13,24 @@ boot() {
linksys,mr8300)
mtd resetbc s_env || true
;;
- edgecore,spw2ac1200|\
- edgecore,spw2ac1200-lan-poe|\
edgecore,ecw5211)
+ part="$(awk -F 'ubi.mtd=' '{printf $2}' /proc/cmdline | cut -d " " -f1)"
+ case "$part" in
+ rootfs1|\
+ rootfs2)
+ avail=$(fw_printenv -n upgrade_available)
+ [ ${avail} -ne 1 ] && fw_setenv upgrade_available 1
+ fw_setenv bootcount 0
+ ;;
+ esac
+ ;;
+ edgecore,spw2ac1200|\
+ edgecore,spw2ac1200-lan-poe)
avail=$(fw_printenv -n upgrade_available)
[ ${avail} -eq 0 ] || {
- fw_setenv bootcount 0
fw_setenv upgrade_available 0
+ fw_setenv bootcount 0
}
+ ;;
esac
}
diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
index d44a57c62a..6f2bff527c 100644
--- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
@@ -66,7 +66,6 @@ platform_do_upgrade() {
avm,fritzrepeater-3000 |\
buffalo,wtr-m2133hp |\
cilab,meshpoint-one |\
- edgecore,ecw5211 |\
edgecore,oap100 |\
engenius,eap2200 |\
glinet,gl-ap1300 |\
@@ -78,6 +77,24 @@ platform_do_upgrade() {
tp-link,ec420-g1)
nand_do_upgrade "$1"
;;
+ edgecore,ecw5211)
+ mkdir -p /var/lock/
+ part="$(awk -F 'ubi.mtd=' '{printf $2}' /proc/cmdline | cut -d " " -f 1)"
+ case "$part" in
+ rootfs1)
+ fw_setenv active 2 || exit 1
+ CI_UBIPART="rootfs2"
+ ;;
+ rootfs2)
+ fw_setenv active 1 || exit 1
+ CI_UBIPART="rootfs1"
+ ;;
+ *)
+ # legacy bootloader
+ ;;
+ esac
+ nand_do_upgrade "$1"
+ ;;
alfa-network,ap120c-ac)
mkdir -p /var/lock/
part="$(awk -F 'ubi.mtd=' '{printf $2}' /proc/cmdline | sed -e 's/ .*$//')"
diff --git a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-ecw5211.dts b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-ecw5211.dts
index 0ee8d1a52e..d8c0853c58 100644
--- a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-ecw5211.dts
+++ b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-ecw5211.dts
@@ -258,6 +258,16 @@
label = "rootfs";
reg = <0x00000000 0x04000000>;
};
+
+ partition@1 {
+ label = "rootfs1";
+ reg = <0x00000000 0x04000000>;
+ };
+
+ partition@4000000 {
+ label = "rootfs2";
+ reg = <0x04000000 0x04000000>;
+ };
};
};
};
--
2.25.1