mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-31 02:17:58 +00:00 
			
		
		
		
	Compare commits
	
		
			25 Commits
		
	
	
		
			v2.6.0-rc2
			...
			v2.6.0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 4c21f5c4b6 | ||
|   | cf657dbd94 | ||
|   | 33c9876760 | ||
|   | 4d6d7405d6 | ||
|   | e249701c34 | ||
|   | 0d50975152 | ||
|   | 6d87847d15 | ||
|   | eebe021780 | ||
|   | c6e0384f21 | ||
|   | 23ae850f72 | ||
|   | 708cf2dec6 | ||
|   | a95745d95b | ||
|   | 83ccea0abf | ||
|   | bfeaf89238 | ||
|   | 7439217b3c | ||
|   | ae2377f4d2 | ||
|   | b81d0aaf0e | ||
|   | 1546bef93f | ||
|   | 32b1aade42 | ||
|   | 2a92b75fe1 | ||
|   | cb30d9e20a | ||
|   | 588206b93b | ||
|   | 6399649038 | ||
|   | aa3cb95233 | ||
|   | 3ea06dac40 | 
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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"; | ||||
| 	}; | ||||
| }; | ||||
							
								
								
									
										886
									
								
								feeds/ipq807x/ipq807x/files/arch/arm64/boot/dts/qcom/qcom-ipq5018-q14.dts
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										886
									
								
								feeds/ipq807x/ipq807x/files/arch/arm64/boot/dts/qcom/qcom-ipq5018-q14.dts
									
									
									
									
									
										Executable 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"; | ||||
| }; | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| /* SPDX-License-Identifier: BSD-3-Clause */ | ||||
|  | ||||
| #define _GNU_SOURCE | ||||
|  | ||||
| #include <sys/types.h> | ||||
| @@ -13,25 +15,16 @@ | ||||
|  | ||||
| #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_NAS_IP		4 | ||||
| #define TLV_PROXY_STATE		33 | ||||
|  | ||||
| struct radius_socket { | ||||
| 	struct uloop_fd fd; | ||||
| @@ -52,53 +45,53 @@ 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 struct radius_socket *sock_dae; | ||||
|  | ||||
| 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 +107,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); | ||||
| @@ -132,12 +136,14 @@ radius_forward(char *buf, char *server, enum socket_type type) | ||||
| 	case RADIUS_ACCT: | ||||
| 		blobmsg_add_string(&b, "radius", "acct"); | ||||
| 		break; | ||||
| 	case RADIUS_DAS: | ||||
| 		blobmsg_add_string(&b, "radius", "coa"); | ||||
| 		break; | ||||
| 	default: | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	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 +152,21 @@ 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); | ||||
| 	uint8_t localhost[] = { 0x7f, 0, 0, 1 }; | ||||
|  | ||||
| 	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 +174,105 @@ 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 (tlv->id == TLV_PROXY_STATE) | ||||
| 			proxy_state = tlv; | ||||
|  | ||||
| 			if (vendor->id == TLV_TIP_SERVER_V4) | ||||
| 				strncpy(server_ip_str, vendor->data, vendor->len - 2); | ||||
| 		} | ||||
| 		if (type == RADIUS_DAS && tlv->id == TLV_NAS_IP && tlv->len == 6) | ||||
| 			memcpy(tlv->data, &localhost, 4); | ||||
|  | ||||
| 		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"); | ||||
| 		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); | ||||
| 	if (type == RADIUS_DAS) { | ||||
| 		if (tx) { | ||||
| 			radius_forward_gw(buf, type); | ||||
| 		} else { | ||||
| 			struct sockaddr_in dest; | ||||
|  | ||||
| 	radius_forward(buf, server_ip_str, type); | ||||
| 			memset(&dest, 0, sizeof(dest)); | ||||
| 			dest.sin_family = AF_INET; | ||||
| 			dest.sin_port = htons(3799); | ||||
| 			inet_pton(AF_INET, "127.0.0.1", &(dest.sin_addr.s_addr)); | ||||
|  | ||||
| 			if (sendto(sock_dae->fd.fd, buf, len_orig, | ||||
| 				   MSG_DONTWAIT, (struct sockaddr*)&dest, sizeof(dest)) < 0) | ||||
| 				ULOG_ERR("failed to deliver DAS frame to localhost\n"); | ||||
| 		} | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!proxy_state) { | ||||
| 		ULOG_ERR("no proxy_state found\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	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; | ||||
|  | ||||
| 		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 +292,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 +310,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 +320,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 +334,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 +343,21 @@ 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); | ||||
| 	sock_dae = sock_open("1814", RADIUS_DAS); | ||||
|  | ||||
| 	uloop_run(); | ||||
| 	uloop_end(); | ||||
| 	ubus_deinit(); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
							
								
								
									
										124
									
								
								feeds/ucentral/radius-gw-proxy/src/ubus.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								feeds/ucentral/radius-gw-proxy/src/ubus.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | ||||
| /* 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 if (!strcmp(radius, "coa")) | ||||
| 		type = RADIUS_DAS; | ||||
| 	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); | ||||
| } | ||||
							
								
								
									
										13
									
								
								feeds/ucentral/radius-gw-proxy/src/ubus.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								feeds/ucentral/radius-gw-proxy/src/ubus.h
									
									
									
									
									
										Normal 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); | ||||
|  | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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:=3603ddd26026d3a5b0febe7fbae22fd28fd6d7370793ecf979561d8886be2af4 | ||||
| PKG_SOURCE_PROTO:=git | ||||
| PKG_SOURCE_DATE:=2022-05-29 | ||||
| PKG_SOURCE_VERSION:=96324e2f7443cb3ae70f8fca10f37548f673e3f8 | ||||
| PKG_SOURCE_VERSION:=9691cc6860c25ba7d62142846da44bd09c17acc0 | ||||
|  | ||||
| PKG_MAINTAINER:=John Crispin <john@phrozen.org> | ||||
| PKG_LICENSE:=BSD-3-Clause | ||||
|   | ||||
| @@ -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 | ||||
| 					} | ||||
| 				} | ||||
| 			] | ||||
|   | ||||
| @@ -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 | ||||
| 					} | ||||
| 				} | ||||
| 			] | ||||
|   | ||||
| @@ -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)) | ||||
|   | ||||
							
								
								
									
										6
									
								
								feeds/ucentral/udhcpsnoop/files/dhcpsnoop.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								feeds/ucentral/udhcpsnoop/files/dhcpsnoop.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| #config device | ||||
| #	option disabled 1 | ||||
| #	option name eth0 | ||||
| #	option ingress 1 | ||||
| #	option egress 1 | ||||
|  | ||||
							
								
								
									
										2
									
								
								feeds/ucentral/udhcpsnoop/files/dhcpsnoop.hotplug
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								feeds/ucentral/udhcpsnoop/files/dhcpsnoop.hotplug
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| #!/bin/sh | ||||
| ubus call dhcpsnoop check_devices | ||||
							
								
								
									
										60
									
								
								feeds/ucentral/udhcpsnoop/files/dhcpsnoop.init
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								feeds/ucentral/udhcpsnoop/files/dhcpsnoop.init
									
									
									
									
									
										Normal 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 | ||||
| } | ||||
| @@ -1,4 +0,0 @@ | ||||
| config snooping | ||||
| 	option enable 0 | ||||
| 	#list network lan | ||||
| 	#list network wan | ||||
| @@ -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 | ||||
| } | ||||
							
								
								
									
										16
									
								
								feeds/ucentral/udhcpsnoop/src/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								feeds/ucentral/udhcpsnoop/src/CMakeLists.txt
									
									
									
									
									
										Normal 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} | ||||
| ) | ||||
							
								
								
									
										77
									
								
								feeds/ucentral/udhcpsnoop/src/cache.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								feeds/ucentral/udhcpsnoop/src/cache.c
									
									
									
									
									
										Normal 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); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										425
									
								
								feeds/ucentral/udhcpsnoop/src/dev.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										425
									
								
								feeds/ucentral/udhcpsnoop/src/dev.c
									
									
									
									
									
										Normal 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); | ||||
| } | ||||
							
								
								
									
										90
									
								
								feeds/ucentral/udhcpsnoop/src/dhcp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								feeds/ucentral/udhcpsnoop/src/dhcp.c
									
									
									
									
									
										Normal 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; | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										32
									
								
								feeds/ucentral/udhcpsnoop/src/dhcpsnoop.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								feeds/ucentral/udhcpsnoop/src/dhcpsnoop.h
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										84
									
								
								feeds/ucentral/udhcpsnoop/src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								feeds/ucentral/udhcpsnoop/src/main.c
									
									
									
									
									
										Normal 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; | ||||
| } | ||||
|  | ||||
							
								
								
									
										88
									
								
								feeds/ucentral/udhcpsnoop/src/msg.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								feeds/ucentral/udhcpsnoop/src/msg.h
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										117
									
								
								feeds/ucentral/udhcpsnoop/src/ubus.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								feeds/ucentral/udhcpsnoop/src/ubus.c
									
									
									
									
									
										Normal 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); | ||||
| } | ||||
| @@ -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 += \ | ||||
|   | ||||
| @@ -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)) | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								feeds/wifi-ax/ath11k-wifi/board-2-motorol-q14.bin.QCN6122
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								feeds/wifi-ax/ath11k-wifi/board-2-motorol-q14.bin.QCN6122
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								feeds/wifi-ax/ath11k-wifi/board-motorol-q14.bin.IPQ5018
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								feeds/wifi-ax/ath11k-wifi/board-motorol-q14.bin.IPQ5018
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -355,6 +355,7 @@ hostapd_common_add_bss_config() { | ||||
| 	config_add_int sae_pwe | ||||
|  | ||||
| 	config_add_string 'owe_transition_bssid:macaddr' 'owe_transition_ssid:string' | ||||
| 	config_add_string owe_transition_ifname | ||||
|  | ||||
| 	config_add_boolean iw_enabled iw_internet iw_asra iw_esr iw_uesa | ||||
| 	config_add_int iw_access_network_type iw_venue_group iw_venue_type | ||||
| @@ -718,10 +719,11 @@ hostapd_set_bss_options() { | ||||
|  | ||||
| 	case "$auth_type" in | ||||
| 		none|owe) | ||||
| 			json_get_vars owe_transition_bssid owe_transition_ssid | ||||
| 			json_get_vars owe_transition_bssid owe_transition_ssid owe_transition_ifname | ||||
|  | ||||
| 			[ -n "$owe_transition_ssid" ] && append bss_conf "owe_transition_ssid=\"$owe_transition_ssid\"" "$N" | ||||
| 			[ -n "$owe_transition_bssid" ] && append bss_conf "owe_transition_bssid=$owe_transition_bssid" "$N" | ||||
| 			[ -n "$owe_transition_ifname" ] && append bss_conf "owe_transition_ifname=$owe_transition_ifname" "$N" | ||||
|  | ||||
| 			wps_possible=1 | ||||
| 			# Here we make the assumption that if we're in open mode | ||||
|   | ||||
							
								
								
									
										24
									
								
								feeds/wifi-ax/hostapd/patches/900-coa.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								feeds/wifi-ax/hostapd/patches/900-coa.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| Index: hostapd-2021-02-20-59e9794c/src/radius/radius_das.c | ||||
| =================================================================== | ||||
| --- hostapd-2021-02-20-59e9794c.orig/src/radius/radius_das.c | ||||
| +++ hostapd-2021-02-20-59e9794c/src/radius/radius_das.c | ||||
| @@ -48,6 +48,8 @@ static struct radius_msg * radius_das_di | ||||
|  		RADIUS_ATTR_EVENT_TIMESTAMP, | ||||
|  		RADIUS_ATTR_MESSAGE_AUTHENTICATOR, | ||||
|  		RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, | ||||
| +		RADIUS_ATTR_VENDOR_SPECIFIC, | ||||
| +		RADIUS_ATTR_CALLED_STATION_ID, | ||||
|  #ifdef CONFIG_IPV6 | ||||
|  		RADIUS_ATTR_NAS_IPV6_ADDRESS, | ||||
|  #endif /* CONFIG_IPV6 */ | ||||
| @@ -205,9 +207,8 @@ static struct radius_msg * radius_das_co | ||||
|  		RADIUS_ATTR_EVENT_TIMESTAMP, | ||||
|  		RADIUS_ATTR_MESSAGE_AUTHENTICATOR, | ||||
|  		RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, | ||||
| -#ifdef CONFIG_HS20 | ||||
|  		RADIUS_ATTR_VENDOR_SPECIFIC, | ||||
| -#endif /* CONFIG_HS20 */ | ||||
| +		RADIUS_ATTR_CALLED_STATION_ID, | ||||
|  #ifdef CONFIG_IPV6 | ||||
|  		RADIUS_ATTR_NAS_IPV6_ADDRESS, | ||||
|  #endif /* CONFIG_IPV6 */ | ||||
| @@ -0,0 +1,66 @@ | ||||
| From 574539ee2cdbb3dd54086423c6dfdd19bb1c06a6 Mon Sep 17 00:00:00 2001 | ||||
| From: David Bauer <mail@david-bauer.net> | ||||
| Date: Thu, 16 Jun 2022 01:55:26 +0200 | ||||
| Subject: [PATCH] hostapd: add owe_transition_ifname | ||||
|  | ||||
| Add the owe_transition_ifname config option to wifi-ifaces. | ||||
|  | ||||
| This allows to configure OWE transition VAPs without adding SSID / BSSID | ||||
| to the uci conifg but instead autodiscovering these parameters from | ||||
| other networks on the same PHY. | ||||
|  | ||||
| The following configuration creates a OWE transition mode network | ||||
| constellation. | ||||
|  | ||||
| config wifi-iface 'open0' | ||||
| 	option device 'radio0' | ||||
| 	option ifname 'open0' | ||||
| 	option network 'lan' | ||||
| 	option mode 'ap' | ||||
| 	option ssid 'FreeNet' | ||||
| 	option encryption 'none' | ||||
| 	option owe_transition_ifname 'owe0' | ||||
|  | ||||
| config wifi-iface 'owe0' | ||||
| 	option device 'radio0' | ||||
| 	option ifname 'owe0' | ||||
| 	option network 'lan' | ||||
| 	option mode 'ap' | ||||
| 	option ssid 'owe_tm.FreeNet' | ||||
| 	option encryption 'owe' | ||||
| 	option hidden '1' | ||||
| 	option owe_transition_ifname 'open0' | ||||
|  | ||||
| Signed-off-by: David Bauer <mail@david-bauer.net> | ||||
| --- | ||||
|  package/network/services/hostapd/files/hostapd.sh | 4 +++- | ||||
|  1 file changed, 3 insertions(+), 1 deletion(-) | ||||
|  | ||||
| diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh | ||||
| index e5f816a55b..fa344bd2dd 100644 | ||||
| --- a/package/network/services/hostapd/files/hostapd.sh | ||||
| +++ b/package/network/services/hostapd/files/hostapd.sh | ||||
| @@ -335,6 +335,7 @@ hostapd_common_add_bss_config() { | ||||
|  	config_add_int sae_pwe | ||||
|   | ||||
|  	config_add_string 'owe_transition_bssid:macaddr' 'owe_transition_ssid:string' | ||||
| +	config_add_string owe_transition_ifname | ||||
|   | ||||
|  	config_add_boolean iw_enabled iw_internet iw_asra iw_esr iw_uesa | ||||
|  	config_add_int iw_access_network_type iw_venue_group iw_venue_type | ||||
| @@ -635,10 +636,11 @@ hostapd_set_bss_options() { | ||||
|   | ||||
|  	case "$auth_type" in | ||||
|  		none|owe) | ||||
| -			json_get_vars owe_transition_bssid owe_transition_ssid | ||||
| +			json_get_vars owe_transition_bssid owe_transition_ssid owe_transition_ifname | ||||
|   | ||||
|  			[ -n "$owe_transition_ssid" ] && append bss_conf "owe_transition_ssid=\"$owe_transition_ssid\"" "$N" | ||||
|  			[ -n "$owe_transition_bssid" ] && append bss_conf "owe_transition_bssid=$owe_transition_bssid" "$N" | ||||
| +			[ -n "$owe_transition_ifname" ] && append bss_conf "owe_transition_ifname=$owe_transition_ifname" "$N" | ||||
|   | ||||
|  			wps_possible=1 | ||||
|  			# Here we make the assumption that if we're in open mode | ||||
| --  | ||||
| 2.25.1 | ||||
|  | ||||
| @@ -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 | ||||
|  | ||||
| @@ -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 | ||||
|  | ||||
| @@ -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 | ||||
|  | ||||
| @@ -17,6 +17,7 @@ packages: | ||||
|   - atfpolicy | ||||
|   - kmod-batman-adv | ||||
|   - batctl-default | ||||
|   - bind-dig | ||||
|   - cJSON | ||||
|   - curl | ||||
|   - dnsmasq-full | ||||
| @@ -52,6 +53,7 @@ packages: | ||||
|   - libustream-openssl | ||||
|   - udevmand | ||||
|   - umdns | ||||
|   - oping | ||||
|   - vxlan | ||||
|   - wpad-openssl | ||||
| diffconfig: | | ||||
|   | ||||
		Reference in New Issue
	
	Block a user