Merge branch 'master' of https://github.com/freifunk-gluon/gluon
(and removed trailing whitespace)
This commit is contained in:
commit
90ba3608ec
7
Makefile
7
Makefile
@ -103,6 +103,13 @@ endef
|
|||||||
list-targets: FORCE
|
list-targets: FORCE
|
||||||
@$(foreach target,$(GLUON_TARGETS),echo '$(target)';)
|
@$(foreach target,$(GLUON_TARGETS),echo '$(target)';)
|
||||||
|
|
||||||
|
lint: lint-lua lint-sh
|
||||||
|
|
||||||
|
lint-lua: FORCE
|
||||||
|
@scripts/lint-lua.sh
|
||||||
|
|
||||||
|
lint-sh: FORCE
|
||||||
|
@scripts/lint-sh.sh
|
||||||
|
|
||||||
GLUON_DEFAULT_PACKAGES := hostapd-mini
|
GLUON_DEFAULT_PACKAGES := hostapd-mini
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ the future development of Gluon.
|
|||||||
|
|
||||||
Please refrain from using the `master` branch for anything else but development purposes!
|
Please refrain from using the `master` branch for anything else but development purposes!
|
||||||
Use the most recent release instead. You can list all releases by running `git tag`
|
Use the most recent release instead. You can list all releases by running `git tag`
|
||||||
and switch to one by running `git checkout v2019.1 && make update`.
|
and switch to one by running `git checkout v2020.1 && make update`.
|
||||||
|
|
||||||
If you're using the autoupdater, do not autoupdate nodes with anything but releases.
|
If you're using the autoupdater, do not autoupdate nodes with anything but releases.
|
||||||
If you upgrade using random master commits the nodes *will break* eventually.
|
If you upgrade using random master commits the nodes *will break* eventually.
|
||||||
|
@ -17,6 +17,7 @@ RUN apt update && apt install -y --no-install-recommends \
|
|||||||
time \
|
time \
|
||||||
ecdsautils \
|
ecdsautils \
|
||||||
lua-check \
|
lua-check \
|
||||||
|
shellcheck \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN useradd -d /gluon gluon
|
RUN useradd -d /gluon gluon
|
||||||
|
75
contrib/ci/Jenkinsfile
vendored
75
contrib/ci/Jenkinsfile
vendored
@ -1,27 +1,52 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent { label 'gluon-docker' }
|
agent none
|
||||||
environment {
|
environment {
|
||||||
GLUON_SITEDIR = "contrib/ci/minimal-site"
|
GLUON_SITEDIR = "contrib/ci/minimal-site"
|
||||||
GLUON_TARGET = "x86-64"
|
GLUON_TARGET = "x86-64"
|
||||||
BUILD_LOG = "1"
|
BUILD_LOG = "1"
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
stage('lint') {
|
stage('lint') {
|
||||||
steps {
|
parallel {
|
||||||
sh 'luacheck package scripts targets'
|
stage('lint-lua') {
|
||||||
}
|
agent { label 'gluon-docker' }
|
||||||
}
|
steps {
|
||||||
stage('docs') {
|
sh 'make lint-lua'
|
||||||
steps {
|
}
|
||||||
sh 'make -C docs html'
|
}
|
||||||
}
|
stage('lint-sh') {
|
||||||
}
|
agent { label 'gluon-docker-v1' }
|
||||||
stage('build') {
|
steps {
|
||||||
steps {
|
sh 'make lint-sh'
|
||||||
sh 'make update'
|
}
|
||||||
sh 'test -d /dl_cache && ln -s /dl_cache openwrt/dl || true'
|
}
|
||||||
sh 'make -j$(nproc) V=s'
|
}
|
||||||
}
|
}
|
||||||
}
|
stage('docs') {
|
||||||
}
|
agent { label 'gluon-docker' }
|
||||||
|
steps {
|
||||||
|
sh 'make -C docs html'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('build') {
|
||||||
|
agent { label 'gluon-docker' }
|
||||||
|
steps {
|
||||||
|
sh 'make update'
|
||||||
|
sh 'test -d /dl_cache && ln -s /dl_cache openwrt/dl || true'
|
||||||
|
sh 'make -j$(nproc) V=s'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
api-history:
|
||||||
|
|
||||||
|
Every time the build dependencies of gluon change, the version
|
||||||
|
every container has to be rebuilt. Therefore, we use Jenkins
|
||||||
|
labels which intoduce a version number which is documented here.
|
||||||
|
As soon, as you properly rebuilt your docker container, you
|
||||||
|
can notify lemoer, that you have updated your node.
|
||||||
|
|
||||||
|
- gluon-docker-v1: add shellcheck binary to the build environment
|
||||||
|
*/
|
||||||
|
@ -26,7 +26,7 @@ docker run --detach --restart always \
|
|||||||
- Your node should appear [here](https://build.ffh.zone/label/gluon-docker/).
|
- Your node should appear [here](https://build.ffh.zone/label/gluon-docker/).
|
||||||
- When clicking on it, Jenkins should state "Agent is connected." like here:
|
- When clicking on it, Jenkins should state "Agent is connected." like here:
|
||||||

|

|
||||||
5. **Your docker container needs to be rebuilt, when the build dependencies of gluon change. So please be aware of that and update your docker container in that case.**
|
5. **Your docker container needs to be rebuilt, when the build dependencies of gluon change. As soon as build dependencies have changed, the build dependency api level has to be raised.** After you rebuilt your docker container, notifiy @lemoer, so he can bump the versioning number.
|
||||||
|
|
||||||
## Backoff
|
## Backoff
|
||||||
- If @lemoer is not reachable, please be patient at first if possible. Otherwise contact info@hannover.freifunk.net or join the channel `#freifunkh` on hackint.
|
- If @lemoer is not reachable, please be patient at first if possible. Otherwise contact info@hannover.freifunk.net or join the channel `#freifunkh` on hackint.
|
||||||
|
@ -5,8 +5,7 @@
|
|||||||
# * Works only if directory names and package names are the same (true for all Gluon packages)
|
# * Works only if directory names and package names are the same (true for all Gluon packages)
|
||||||
# * Doesn't show dependencies through virtual packages correctly
|
# * Doesn't show dependencies through virtual packages correctly
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
# Script to list all upgrade scripts in a clear manner
|
# Script to list all upgrade scripts in a clear manner
|
||||||
# Limitations:
|
# Limitations:
|
||||||
# * Does only show scripts of packages whose `files'/`luasrc' directories represent the whole image filesystem (which are all Gluon packages)
|
# * Does only show scripts of packages whose `files'/`luasrc' directories represent the whole image filesystem (which are all Gluon packages)
|
||||||
@ -27,7 +28,7 @@ fi
|
|||||||
|
|
||||||
pushd "$(dirname "$0")/.." >/dev/null
|
pushd "$(dirname "$0")/.." >/dev/null
|
||||||
|
|
||||||
find ./package packages -name Makefile | while read makefile; do
|
find ./package packages -name Makefile | while read -r makefile; do
|
||||||
dir="$(dirname "$makefile")"
|
dir="$(dirname "$makefile")"
|
||||||
|
|
||||||
pushd "$dir" >/dev/null
|
pushd "$dir" >/dev/null
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ $# -ne 2 -o "-h" = "$1" -o "--help" = "$1" -o ! -r "$1" -o ! -r "$2" ]; then
|
if [ $# -ne 2 ] || [ "-h" = "$1" ] || [ "--help" = "$1" ] || [ ! -r "$1" ] || [ ! -r "$2" ]; then
|
||||||
cat <<EOHELP
|
cat <<EOHELP
|
||||||
Usage: $0 <secret> <manifest>
|
Usage: $0 <secret> <manifest>
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if [ $# -eq 0 -o "-h" = "$1" -o "-help" = "$1" -o "--help" = "$1" ]; then
|
if [ $# -eq 0 ] || [ "-h" = "$1" ] || [ "-help" = "$1" ] || [ "--help" = "$1" ]; then
|
||||||
cat <<EOHELP
|
cat <<EOHELP
|
||||||
Usage: $0 <public> <signed manifest>
|
Usage: $0 <public> <signed manifest>
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ awk "BEGIN { sep=0 }
|
|||||||
else print > \"$lower\"}" \
|
else print > \"$lower\"}" \
|
||||||
"$manifest"
|
"$manifest"
|
||||||
|
|
||||||
while read line
|
while read -r line
|
||||||
do
|
do
|
||||||
if ecdsaverify -s "$line" -p "$public" "$upper"; then
|
if ecdsaverify -s "$line" -p "$public" "$upper"; then
|
||||||
ret=0
|
ret=0
|
||||||
|
@ -20,11 +20,11 @@
|
|||||||
# -- Project information -----------------------------------------------------
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
project = 'Gluon'
|
project = 'Gluon'
|
||||||
copyright = '2015-2019, Project Gluon'
|
copyright = '2015-2020, Project Gluon'
|
||||||
author = 'Project Gluon'
|
author = 'Project Gluon'
|
||||||
|
|
||||||
# The short X.Y version
|
# The short X.Y version
|
||||||
version = '2019.1+'
|
version = '2020.1+'
|
||||||
# The full version, including alpha/beta/rc tags
|
# The full version, including alpha/beta/rc tags
|
||||||
release = version
|
release = version
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ for new hardware to Gluon.
|
|||||||
|
|
||||||
Hardware requirements
|
Hardware requirements
|
||||||
---------------------
|
---------------------
|
||||||
Having an ath9k (or ath10k) based WLAN adapter is highly recommended,
|
Having an ath9k, ath10k or mt76 based WLAN adapter is highly recommended,
|
||||||
although other chipsets may also work. VAP (multiple SSID) support
|
although other chipsets may also work. VAP (multiple SSID) support
|
||||||
is a requirement.
|
is a requirement.
|
||||||
|
|
||||||
|
@ -11,6 +11,11 @@ There are two cases in which the WAN port is used:
|
|||||||
After the VPN connection has been established, the node should be able to reach
|
After the VPN connection has been established, the node should be able to reach
|
||||||
the mesh's DNS servers and use these for all other name resolution.
|
the mesh's DNS servers and use these for all other name resolution.
|
||||||
|
|
||||||
|
If the device does not feature a WAN port, the LAN port is configured as WAN port.
|
||||||
|
In case such a device has multiple LAN ports, all these can be used as WAN.
|
||||||
|
Devices, which feature a "hybrid" port (labled as WAN/LAN), this port is used as WAN.
|
||||||
|
|
||||||
|
This behavior can be reversed using the ``single_as_lan`` site.conf option.
|
||||||
|
|
||||||
Routing tables
|
Routing tables
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
@ -74,7 +74,11 @@ Several Freifunk communities in Germany use Gluon as the foundation of their Fre
|
|||||||
:caption: Releases
|
:caption: Releases
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
releases/v2020.1
|
||||||
|
releases/v2019.1.2
|
||||||
|
releases/v2019.1.1
|
||||||
releases/v2019.1
|
releases/v2019.1
|
||||||
|
releases/v2018.2.4
|
||||||
releases/v2018.2.3
|
releases/v2018.2.3
|
||||||
releases/v2018.2.2
|
releases/v2018.2.2
|
||||||
releases/v2018.2.1
|
releases/v2018.2.1
|
||||||
|
@ -13,29 +13,32 @@ Selected router
|
|||||||
The router selection mechanism is independent from the batman-adv gateway mode.
|
The router selection mechanism is independent from the batman-adv gateway mode.
|
||||||
In contrast, the device originating the router advertisement could be any router
|
In contrast, the device originating the router advertisement could be any router
|
||||||
or client connected to the mesh, as radv-filterd captures all router
|
or client connected to the mesh, as radv-filterd captures all router
|
||||||
advertisements originating from it. All nodes announcing router advertisement
|
advertisements originating from it. All nodes announcing router advertisement
|
||||||
**with** a default lifetime greater than 0 are being considered as candidates.
|
**with** a default lifetime greater than 0 are being considered as candidates.
|
||||||
|
|
||||||
In case a router is not a batman-adv originator itself, its TQ is defined by
|
In case a router is not a batman-adv originator itself, its TQ is defined by
|
||||||
the originator it is connected to. This lookup uses the batman-adv global
|
the originator it is connected to. This lookup uses the batman-adv global
|
||||||
translation table.
|
translation table.
|
||||||
|
|
||||||
Initially the router is the selected by choosing the candidate with the
|
Initially the router is selected by choosing the candidate with the strongest
|
||||||
strongest TQ. When another candidate can provide a better TQ metric it is not
|
TQ. When another candidate can provide a better TQ metric, that outperforms the
|
||||||
picked up as the selected router until it will outperform the currently
|
currently selected router by X metric units, it will be picked as the new
|
||||||
selected router by X metric units. The hysteresis threshold is configurable
|
selected router. The hysteresis threshold is configurable and prevents excessive
|
||||||
and prevents excessive flapping of the gateway.
|
flapping of the gateway.
|
||||||
|
|
||||||
"Local" routers
|
Local routers
|
||||||
---------------
|
-------------
|
||||||
|
|
||||||
The package has functionality to select "local" routers, i.e. those connected
|
Local routers (i.e. local internet gateways connected to some nodes) that are
|
||||||
via cable or WLAN instead of via the mesh (technically: appearing in the
|
connected to the client interface via cable or WLAN instead of via the mesh
|
||||||
``transtable_local``), a fake TQ of 512 so that they are always preferred.
|
(technically: appearing in the transtable_local) are taken into account with a
|
||||||
However, if used together with the :doc:`gluon-ebtables-filter-ra-dhcp`
|
fake TQ of 512, so that they are always preferred.
|
||||||
package, these router advertisements are filtered anyway and reach neither the
|
|
||||||
node nor any other client. You currently have to disable the package or insert
|
Be aware of problems if you plan to use local routers together with the
|
||||||
custom ebtables rules in order to use local routers.
|
:doc:`gluon-ebtables-filter-ra-dhcp` package. These router advertisements are
|
||||||
|
filtered anyway and reach neither the node nor any other client. Therefore the
|
||||||
|
use of local routers is not possible as long as the package
|
||||||
|
``gluon-radv-filterd`` is used.
|
||||||
|
|
||||||
respondd module
|
respondd module
|
||||||
---------------
|
---------------
|
||||||
|
53
docs/releases/v2018.2.4.rst
Normal file
53
docs/releases/v2018.2.4.rst
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
Gluon 2018.2.4
|
||||||
|
==============
|
||||||
|
|
||||||
|
End of life
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This will be the final release of the v2018.2.x series. Updating to the v2019.1.x release series is the recommended course of action, which should be fairly easy.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
* Fixes device alias for Ubiquiti UniFi AC LR. (`#1834 <https://github.com/freifunk-gluon/gluon/issues/1834>`_)
|
||||||
|
Autoupdates on this model were impossible before, since we were missing the proper device alias.
|
||||||
|
|
||||||
|
* Add correct ath10k firmware package for OCEDO Koala. (`#1838 <https://github.com/freifunk-gluon/gluon/pull/1838>`_)
|
||||||
|
|
||||||
|
* Fixes various batman-adv bugs with backports from 2019.4 and 2019.5 by updating the openwrt-routing packages feed
|
||||||
|
|
||||||
|
Other changes
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
* Linux kernel has been updated to either
|
||||||
|
|
||||||
|
- 4.9.207 (ar71xx, brcm2708, mpc85xx) or
|
||||||
|
- 4.14.160 (ipq40xx, ipq806x, mvebu, ramips, sunxi, x86).
|
||||||
|
|
||||||
|
Known issues
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
* Default TX power on many Ubiquiti devices is too high, correct offsets are
|
||||||
|
unknown (`#94 <https://github.com/freifunk-gluon/gluon/issues/94>`_)
|
||||||
|
|
||||||
|
Reducing the TX power in the Advanced Settings is recommended.
|
||||||
|
|
||||||
|
* The MAC address of the WAN interface is modified even when Mesh-on-WAN is
|
||||||
|
disabled (`#496 <https://github.com/freifunk-gluon/gluon/issues/496>`_)
|
||||||
|
|
||||||
|
This may lead to issues in environments where a fixed MAC address is expected
|
||||||
|
(like VMware when promiscuous mode is disallowed).
|
||||||
|
|
||||||
|
* Inconsistent respondd API
|
||||||
|
(`#522 <https://github.com/freifunk-gluon/gluon/issues/522>`_)
|
||||||
|
|
||||||
|
The current API is inconsistent and will be replaced eventually. The old API
|
||||||
|
will still be supported for a while.
|
||||||
|
|
||||||
|
* Frequent reboots due to out-of-memory or high load due to memory pressure on
|
||||||
|
weak hardware especially in larger meshes
|
||||||
|
(`#1243 <https://github.com/freifunk-gluon/gluon/issues/1243>`_)
|
||||||
|
|
||||||
|
Optimizations in Gluon 2018.1 have significantly improved memory usage.
|
||||||
|
There are still known bugs leading to unreasonably high load that we hope to
|
||||||
|
solve in future releases.
|
62
docs/releases/v2019.1.1.rst
Normal file
62
docs/releases/v2019.1.1.rst
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
Gluon 2019.1.1
|
||||||
|
##############
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
********
|
||||||
|
|
||||||
|
* Fixes device alias for Ubiquiti UniFi AC LR. (`#1834 <https://github.com/freifunk-gluon/gluon/issues/1834>`_)
|
||||||
|
Autoupdates on this model were impossible before, since we were missing the proper device alias.
|
||||||
|
|
||||||
|
* Add correct ath10k firmware package for OCEDO Koala. (`#1838 <https://github.com/freifunk-gluon/gluon/pull/1838>`_)
|
||||||
|
|
||||||
|
* Fixes various batman-adv bugs with backports from 2019.4 and 2019.5 by updating the openwrt-routing packages feed.
|
||||||
|
|
||||||
|
* Fixes node role list. (`#1851 <https://github.com/freifunk-gluon/gluon/issues/1851>`_)
|
||||||
|
With Gluon v2019.1 it became impossible to change the role of a node via the config mode.
|
||||||
|
|
||||||
|
Other Changes
|
||||||
|
*************
|
||||||
|
|
||||||
|
* Linux kernel has been updated to either
|
||||||
|
|
||||||
|
- 4.9.207 (ar71xx, brcm2708, mpc85xx) or
|
||||||
|
- 4.14.160 (ipq40xx, ipq806x, mvebu, ramips, sunxi, x86).
|
||||||
|
|
||||||
|
Known issues
|
||||||
|
************
|
||||||
|
|
||||||
|
* Out of memory situations with high client count on ath9k.
|
||||||
|
(`#1768 <https://github.com/freifunk-gluon/gluon/issues/1768>`_)
|
||||||
|
|
||||||
|
* The integration of the BATMAN_V routing algorithm is incomplete.
|
||||||
|
|
||||||
|
- | Mesh neighbors don't appear on the status page. (`#1726 <https://github.com/freifunk-gluon/gluon/issues/1726>`_)
|
||||||
|
| Many tools have the BATMAN_IV metric hardcoded, these need to be updated to account for the new throughput
|
||||||
|
| metric.
|
||||||
|
|
||||||
|
- | Throughput values are not correctly acquired for different interface types.
|
||||||
|
| (`#1728 <https://github.com/freifunk-gluon/gluon/issues/1728>`_)
|
||||||
|
| This affects virtual interface types like bridges and VXLAN.
|
||||||
|
|
||||||
|
* Default TX power on many Ubiquiti devices is too high, correct offsets are unknown
|
||||||
|
(`#94 <https://github.com/freifunk-gluon/gluon/issues/94>`_)
|
||||||
|
|
||||||
|
Reducing the TX power in the Advanced Settings is recommended.
|
||||||
|
|
||||||
|
* The MAC address of the WAN interface is modified even when Mesh-on-WAN is disabled
|
||||||
|
(`#496 <https://github.com/freifunk-gluon/gluon/issues/496>`_)
|
||||||
|
|
||||||
|
This may lead to issues in environments where a fixed MAC address is expected (like VMware when promiscuous mode is
|
||||||
|
disallowed).
|
||||||
|
|
||||||
|
* Inconsistent respondd API (`#522 <https://github.com/freifunk-gluon/gluon/issues/522>`_)
|
||||||
|
|
||||||
|
The current API is inconsistent and will be replaced eventually. The old API will still be supported for a while.
|
||||||
|
|
||||||
|
* Frequent reboots due to out-of-memory or high load due to memory pressure on weak hardware especially in larger
|
||||||
|
meshes (`#1243 <https://github.com/freifunk-gluon/gluon/issues/1243>`_)
|
||||||
|
|
||||||
|
Optimizations in Gluon 2018.1 have significantly improved memory usage.
|
||||||
|
There are still known bugs leading to unreasonably high load that we hope to
|
||||||
|
solve in future releases.
|
||||||
|
|
58
docs/releases/v2019.1.2.rst
Normal file
58
docs/releases/v2019.1.2.rst
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
Gluon 2019.1.2
|
||||||
|
##############
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
********
|
||||||
|
|
||||||
|
* Fixes a buffer-overflow vulnerability in libubox, a core component of OpenWrt
|
||||||
|
(CVE-2020-7248)
|
||||||
|
|
||||||
|
* Fixes a vulnerability in the OpenWrt package manager (opkg). By using this vulnerability,
|
||||||
|
an attacker could bypass the integrity check of the package artifacts. (CVE-2020-7982)
|
||||||
|
|
||||||
|
Other Changes
|
||||||
|
*************
|
||||||
|
|
||||||
|
* Linux kernel has been updated to either
|
||||||
|
|
||||||
|
- 4.9.211 (ar71xx, brcm2708, mpc85xx) or
|
||||||
|
- 4.14.167 (ipq40xx, ipq806x, mvebu, ramips, sunxi, x86).
|
||||||
|
|
||||||
|
Known issues
|
||||||
|
************
|
||||||
|
|
||||||
|
* Out of memory situations with high client count on ath9k.
|
||||||
|
(`#1768 <https://github.com/freifunk-gluon/gluon/issues/1768>`_)
|
||||||
|
|
||||||
|
* The integration of the BATMAN_V routing algorithm is incomplete.
|
||||||
|
|
||||||
|
- | Mesh neighbors don't appear on the status page. (`#1726 <https://github.com/freifunk-gluon/gluon/issues/1726>`_)
|
||||||
|
| Many tools have the BATMAN_IV metric hardcoded, these need to be updated to account for the new throughput
|
||||||
|
| metric.
|
||||||
|
|
||||||
|
- | Throughput values are not correctly acquired for different interface types.
|
||||||
|
| (`#1728 <https://github.com/freifunk-gluon/gluon/issues/1728>`_)
|
||||||
|
| This affects virtual interface types like bridges and VXLAN.
|
||||||
|
|
||||||
|
* Default TX power on many Ubiquiti devices is too high, correct offsets are unknown
|
||||||
|
(`#94 <https://github.com/freifunk-gluon/gluon/issues/94>`_)
|
||||||
|
|
||||||
|
Reducing the TX power in the Advanced Settings is recommended.
|
||||||
|
|
||||||
|
* The MAC address of the WAN interface is modified even when Mesh-on-WAN is disabled
|
||||||
|
(`#496 <https://github.com/freifunk-gluon/gluon/issues/496>`_)
|
||||||
|
|
||||||
|
This may lead to issues in environments where a fixed MAC address is expected (like VMware when promiscuous mode is
|
||||||
|
disallowed).
|
||||||
|
|
||||||
|
* Inconsistent respondd API (`#522 <https://github.com/freifunk-gluon/gluon/issues/522>`_)
|
||||||
|
|
||||||
|
The current API is inconsistent and will be replaced eventually. The old API will still be supported for a while.
|
||||||
|
|
||||||
|
* Frequent reboots due to out-of-memory or high load due to memory pressure on weak hardware especially in larger
|
||||||
|
meshes (`#1243 <https://github.com/freifunk-gluon/gluon/issues/1243>`_)
|
||||||
|
|
||||||
|
Optimizations in Gluon 2018.1 have significantly improved memory usage.
|
||||||
|
There are still known bugs leading to unreasonably high load that we hope to
|
||||||
|
solve in future releases.
|
||||||
|
|
@ -15,6 +15,7 @@ possible.
|
|||||||
With Gluon v2019.1, nodes will not answer respondd queries on ``[ff02::2:1001]:1001`` anymore. Respondd
|
With Gluon v2019.1, nodes will not answer respondd queries on ``[ff02::2:1001]:1001`` anymore. Respondd
|
||||||
querier setups still using this address must be updated to the new address ``[ff05::2:1001]:1001``
|
querier setups still using this address must be updated to the new address ``[ff05::2:1001]:1001``
|
||||||
(supported since Gluon v2017.1). This change was required due to cross-domain leakage of respondd data.
|
(supported since Gluon v2017.1). This change was required due to cross-domain leakage of respondd data.
|
||||||
|
If you are using hopglass-server to query respondd data, you need to update it to at least commit f0e2c0a5.
|
||||||
|
|
||||||
If you are upgrading from a version prior to v2018.1, please note that the flash layout on some
|
If you are upgrading from a version prior to v2018.1, please note that the flash layout on some
|
||||||
devices (TP-Link CPE/WBS 210/510) was changed. To avoid upgrade failures, make sure to upgrade
|
devices (TP-Link CPE/WBS 210/510) was changed. To avoid upgrade failures, make sure to upgrade
|
||||||
|
191
docs/releases/v2020.1.rst
Normal file
191
docs/releases/v2020.1.rst
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
Gluon 2020.1
|
||||||
|
============
|
||||||
|
|
||||||
|
This is the first release of Gluon in 2020, based on OpenWrt 19.07. It
|
||||||
|
introduces the ath79 target, which will replace ar71xx in the short
|
||||||
|
term.
|
||||||
|
|
||||||
|
Added hardware support
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
ath79-generic
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- devolo WiFi pro 1200e
|
||||||
|
- devolo WiFi pro 1200i
|
||||||
|
- devolo WiFi pro 1750c
|
||||||
|
- devolo WiFi pro 1750e
|
||||||
|
- devolo WiFi pro 1750i
|
||||||
|
- devolo WiFi pro 1750x
|
||||||
|
- GL.iNet GL-AR300M-Lite
|
||||||
|
- OCEDO Raccoon
|
||||||
|
- TP-Link Archer C6 v2
|
||||||
|
|
||||||
|
ipq40xx-generic
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- Aruba AP-303
|
||||||
|
- Aruba Instant On AP11
|
||||||
|
- AVM FRITZ!Repeater 1200
|
||||||
|
|
||||||
|
ipq806x-generic
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- Netgear R7800
|
||||||
|
|
||||||
|
lantiq-xway
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
- AVM FRITZ!Box 7312
|
||||||
|
- AVM FRITZ!Box 7320
|
||||||
|
- AVM FRITZ!Box 7330
|
||||||
|
- AVM FRITZ!Box 7330 SL
|
||||||
|
|
||||||
|
lantiq-xrx200
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- AVM FRITZ!Box 7360 (v1, v2)
|
||||||
|
- AVM FRITZ!Box 7360 SL
|
||||||
|
- AVM FRITZ!Box 7362 SL
|
||||||
|
- AVM FRITZ!Box 7412
|
||||||
|
|
||||||
|
mpc85xx-p1020
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- Enterasys WS-AP3710i
|
||||||
|
- OCEDO Panda
|
||||||
|
|
||||||
|
ramips-mt7620
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- TP-Link Archer C2 (v1)
|
||||||
|
- TP-Link Archer C20 (v1)
|
||||||
|
- TP-Link Archer C20i
|
||||||
|
- TP-Link Archer C50 (v1)
|
||||||
|
- Xiaomi MiWifi Mini
|
||||||
|
|
||||||
|
ramips-mt7621
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- Netgear EX6150 (v1)
|
||||||
|
- Netgear R6220
|
||||||
|
|
||||||
|
ramips-mt76x8
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- GL.iNet VIXMINI
|
||||||
|
- TP-Link TL-MR3020 (v3)
|
||||||
|
- TP-Link TL-WA801ND (v5)
|
||||||
|
- TP-Link TL-WR902AC (v3)
|
||||||
|
|
||||||
|
Removed hardware support
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
- ALFA Network Hornet-UB [#kernelpartition_too_small]_
|
||||||
|
- ALFA Network Tube2H [#kernelpartition_too_small]_
|
||||||
|
- ALFA Network N2 [#kernelpartition_too_small]_
|
||||||
|
- ALFA Network N5 [#kernelpartition_too_small]_
|
||||||
|
|
||||||
|
.. [#kernelpartition_too_small]
|
||||||
|
The kernel partition on this device is too small to build a working image.
|
||||||
|
|
||||||
|
Major changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
OpenWrt 19.07
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Gluon v2020.1 is the first release to use OpenWrt 19.07. All targets
|
||||||
|
therefore use Linux 4.14.166.
|
||||||
|
|
||||||
|
batman-adv compat v14 removal
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Support for the long deprecated compat 14 version of batman-adv has been
|
||||||
|
dropped. Communities still using this version should migrate to batman-adv
|
||||||
|
using the scheduled domain switch.
|
||||||
|
|
||||||
|
IBSS wireless mesh removal
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Support for the IBSS wireless protocol has been dropped. Communities
|
||||||
|
still using IBSS are suggested to migrate to 802.11s using the scheduled
|
||||||
|
domain switch.
|
||||||
|
|
||||||
|
Performance enhancements
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
We install zram-swap by default on ``ar71xx`` devices with 8MB of flash
|
||||||
|
and 32MB of RAM.
|
||||||
|
|
||||||
|
Renamed targets
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- The ``ipq40xx`` target was renamed to ``ipq40xx-generic``.
|
||||||
|
- The ``ipq806x`` target was renamed to ``ipq806x-generic``.
|
||||||
|
|
||||||
|
Status Page
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
- Gateway nexthop information has been added to the statuspage when batman-adv
|
||||||
|
is used. This includes its MAC address and prettyname as well as the interface
|
||||||
|
name towards the selected gateway.
|
||||||
|
- The site name has been added to the statuspage. If the node is in a multidomain
|
||||||
|
setup it will also show the domain name.
|
||||||
|
|
||||||
|
DECT button to enter config mode
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Many AVM devices don't feature a separate RESET/WPS button, therefore
|
||||||
|
starting this release we support entering the config mode via DECT buttons.
|
||||||
|
|
||||||
|
X86 partition size
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The x86 partition size has been reduced to fit on disks with a capacity of 128 MB.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
Autoupdater aliases
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
We have added several new aliases for autoupdater compatibility on
|
||||||
|
the following devices:
|
||||||
|
|
||||||
|
- Ubiquiti UniFi AC LR
|
||||||
|
- Raspberry Pi
|
||||||
|
|
||||||
|
Site changes
|
||||||
|
------------
|
||||||
|
|
||||||
|
site.mk
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
- The ``GLUON_WLAN_MESH`` variable can be dropped, as 802.11s is
|
||||||
|
the only supported wireless transport from now on.
|
||||||
|
|
||||||
|
Internals
|
||||||
|
---------
|
||||||
|
|
||||||
|
Linting Targets
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Support for linter make targets was added.
|
||||||
|
|
||||||
|
- ``make lint``
|
||||||
|
- ``make lint-sh`` to only check shell scripts
|
||||||
|
- ``make lint-lua`` to only check lua scripts
|
||||||
|
|
||||||
|
These require the shellcheck and luacheck tools. The docker image has
|
||||||
|
been updated accordingly.
|
||||||
|
|
||||||
|
Continuous integration
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
We have implemented continuous integration testing using Jenkins and thereby
|
||||||
|
ensure that all lua and shell scripts are linted, that the documentation
|
||||||
|
still builds and warnings are highlighted, and that Gluon still
|
||||||
|
compiles, by testing a build on the ``x86_64`` target. We expect this to
|
||||||
|
significantly improve the feedback cycle and quality of contributions.
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
-- This is an example site configuration for Gluon v2019.1
|
-- This is an example site configuration for Gluon v2020.1
|
||||||
--
|
--
|
||||||
-- Take a look at the documentation located at
|
-- Take a look at the documentation located at
|
||||||
-- https://gluon.readthedocs.io/ for details.
|
-- https://gluon.readthedocs.io/ for details.
|
||||||
|
@ -8,7 +8,7 @@ Gluon's releases are managed using `Git tags`_. If you are just getting
|
|||||||
started with Gluon we recommend to use the latest stable release of Gluon.
|
started with Gluon we recommend to use the latest stable release of Gluon.
|
||||||
|
|
||||||
Take a look at the `list of gluon releases`_ and notice the latest release,
|
Take a look at the `list of gluon releases`_ and notice the latest release,
|
||||||
e.g. *v2019.1*. Always get Gluon using git and don't try to download it
|
e.g. *v2020.1*. Always get Gluon using git and don't try to download it
|
||||||
as a Zip archive as the archive will be missing version information.
|
as a Zip archive as the archive will be missing version information.
|
||||||
|
|
||||||
Please keep in mind that there is no "default Gluon" build; a site configuration
|
Please keep in mind that there is no "default Gluon" build; a site configuration
|
||||||
@ -44,7 +44,7 @@ Building the images
|
|||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
To build Gluon, first check out the repository. Replace *RELEASE* with the
|
To build Gluon, first check out the repository. Replace *RELEASE* with the
|
||||||
version you'd like to checkout, e.g. *v2019.1*.
|
version you'd like to checkout, e.g. *v2020.1*.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ There are two levels of `make clean`::
|
|||||||
|
|
||||||
make clean GLUON_TARGET=ar71xx-generic
|
make clean GLUON_TARGET=ar71xx-generic
|
||||||
|
|
||||||
will ensure all packages are rebuilt for a single target. This normally not
|
will ensure all packages are rebuilt for a single target. This is usually not
|
||||||
necessary, but may fix certain kinds of build failures.
|
necessary, but may fix certain kinds of build failures.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
@ -37,13 +37,13 @@ ar71xx-generic
|
|||||||
- DIR-505 (A1, A2)
|
- DIR-505 (A1, A2)
|
||||||
- DIR-825 (B1)
|
- DIR-825 (B1)
|
||||||
|
|
||||||
* GL Innovations
|
* GL.iNet
|
||||||
|
|
||||||
|
- 6408A
|
||||||
|
- 6416A
|
||||||
- GL-AR150
|
- GL-AR150
|
||||||
- GL-AR300M
|
- GL-AR300M
|
||||||
- GL-AR750
|
- GL-AR750
|
||||||
- GL-iNet 6408A (v1)
|
|
||||||
- GL-iNet 6416A (v1)
|
|
||||||
|
|
||||||
* Linksys
|
* Linksys
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ ar71xx-generic
|
|||||||
- CPE220 (v1.1)
|
- CPE220 (v1.1)
|
||||||
- CPE510 (v1.0, v1.1)
|
- CPE510 (v1.0, v1.1)
|
||||||
- CPE520 (v1.1)
|
- CPE520 (v1.1)
|
||||||
- RE450
|
- RE450 (v1)
|
||||||
- TL-WDR3500 (v1)
|
- TL-WDR3500 (v1)
|
||||||
- TL-WDR3600 (v1)
|
- TL-WDR3600 (v1)
|
||||||
- TL-WDR4300 (v1)
|
- TL-WDR4300 (v1)
|
||||||
@ -183,6 +183,23 @@ ar71xx-tiny [#deprecated]_
|
|||||||
ath79-generic
|
ath79-generic
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
* devolo
|
||||||
|
|
||||||
|
- WiFi pro 1200e [#lan_as_wan]_
|
||||||
|
- WiFi pro 1200i
|
||||||
|
- WiFi pro 1750c
|
||||||
|
- WiFi pro 1750e [#lan_as_wan]_
|
||||||
|
- WiFi pro 1750i
|
||||||
|
- WiFi pro 1750x
|
||||||
|
|
||||||
|
* GL.iNet
|
||||||
|
|
||||||
|
- GL-AR300M-Lite
|
||||||
|
|
||||||
|
* OCEDO
|
||||||
|
|
||||||
|
- Raccoon
|
||||||
|
|
||||||
* TP-Link
|
* TP-Link
|
||||||
|
|
||||||
- Archer C6 (v2)
|
- Archer C6 (v2)
|
||||||
@ -212,8 +229,8 @@ ipq40xx-generic
|
|||||||
|
|
||||||
* NETGEAR
|
* NETGEAR
|
||||||
|
|
||||||
- EX6100v2
|
- EX6100 (v2)
|
||||||
- EX6150v2
|
- EX6150 (v2)
|
||||||
|
|
||||||
* OpenMesh
|
* OpenMesh
|
||||||
|
|
||||||
@ -237,6 +254,9 @@ lantiq-xrx200
|
|||||||
|
|
||||||
* AVM
|
* AVM
|
||||||
|
|
||||||
|
- FRITZ!Box 7360 (v1, v2) [#avmflash]_ [#lan_as_wan]_
|
||||||
|
- FRITZ!Box 7360 SL [#avmflash]_ [#lan_as_wan]_
|
||||||
|
- FRITZ!Box 7362 SL [#eva_ramboot]_ [#lan_as_wan]_
|
||||||
- FRITZ!Box 7412 [#eva_ramboot]_
|
- FRITZ!Box 7412 [#eva_ramboot]_
|
||||||
|
|
||||||
lantiq-xway
|
lantiq-xway
|
||||||
@ -245,6 +265,9 @@ lantiq-xway
|
|||||||
* AVM
|
* AVM
|
||||||
|
|
||||||
- FRITZ!Box 7312 [#avmflash]_
|
- FRITZ!Box 7312 [#avmflash]_
|
||||||
|
- FRITZ!Box 7320 [#avmflash]_ [#lan_as_wan]_
|
||||||
|
- FRITZ!Box 7330 [#avmflash]_ [#lan_as_wan]_
|
||||||
|
- FRITZ!Box 7330 SL [#avmflash]_ [#lan_as_wan]_
|
||||||
|
|
||||||
mpc85xx-generic
|
mpc85xx-generic
|
||||||
---------------
|
---------------
|
||||||
@ -260,6 +283,10 @@ mpc85xx-p1020
|
|||||||
|
|
||||||
- HiveAP 330
|
- HiveAP 330
|
||||||
|
|
||||||
|
* Enterasys
|
||||||
|
|
||||||
|
- WS-AP3710i
|
||||||
|
|
||||||
* OCEDO
|
* OCEDO
|
||||||
|
|
||||||
- Panda
|
- Panda
|
||||||
@ -267,7 +294,7 @@ mpc85xx-p1020
|
|||||||
ramips-mt7620
|
ramips-mt7620
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
* GL Innovations
|
* GL.iNet
|
||||||
|
|
||||||
- GL-MT300A
|
- GL-MT300A
|
||||||
- GL-MT300N
|
- GL-MT300N
|
||||||
@ -277,6 +304,17 @@ ramips-mt7620
|
|||||||
|
|
||||||
- WT3020AD/F/H
|
- WT3020AD/F/H
|
||||||
|
|
||||||
|
* TP-Link
|
||||||
|
|
||||||
|
- Archer C2 v1
|
||||||
|
- Archer C20 (v1)
|
||||||
|
- Archer C20i
|
||||||
|
- Archer C50 v1
|
||||||
|
|
||||||
|
* Xiaomi
|
||||||
|
|
||||||
|
- MiWiFi Mini
|
||||||
|
|
||||||
ramips-mt7621
|
ramips-mt7621
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
@ -290,6 +328,7 @@ ramips-mt7621
|
|||||||
|
|
||||||
* NETGEAR
|
* NETGEAR
|
||||||
|
|
||||||
|
- EX6150 (v1)
|
||||||
- R6220
|
- R6220
|
||||||
|
|
||||||
* Ubiquiti
|
* Ubiquiti
|
||||||
@ -316,10 +355,13 @@ ramips-mt76x8
|
|||||||
|
|
||||||
* TP-Link
|
* TP-Link
|
||||||
|
|
||||||
- TL-MR3420 v5
|
|
||||||
- TL-WR841N v13
|
|
||||||
- Archer C50 v3
|
- Archer C50 v3
|
||||||
- Archer C50 v4
|
- Archer C50 v4
|
||||||
|
- TL-MR3020 v3
|
||||||
|
- TL-MR3420 v5
|
||||||
|
- TL-WA801ND v5
|
||||||
|
- TL-WR841N v13
|
||||||
|
- TL-WR902AC v3
|
||||||
|
|
||||||
* VoCore
|
* VoCore
|
||||||
|
|
||||||
@ -382,4 +424,7 @@ Footnotes
|
|||||||
|
|
||||||
.. [#eva_ramboot]
|
.. [#eva_ramboot]
|
||||||
For instructions on how to flash AVM NAND devices, see the respective
|
For instructions on how to flash AVM NAND devices, see the respective
|
||||||
commit which added support in OpenWrt.
|
commit which added support in OpenWrt.
|
||||||
|
|
||||||
|
.. [#lan_as_wan]
|
||||||
|
All LAN ports on this device are used as WAN.
|
||||||
|
14
modules
14
modules
@ -1,20 +1,16 @@
|
|||||||
GLUON_FEEDS='packages routing luci gluon'
|
GLUON_FEEDS='packages routing gluon'
|
||||||
|
|
||||||
OPENWRT_REPO=https://git.openwrt.org/openwrt/openwrt.git
|
OPENWRT_REPO=https://git.openwrt.org/openwrt/openwrt.git
|
||||||
OPENWRT_BRANCH=openwrt-19.07
|
OPENWRT_BRANCH=openwrt-19.07
|
||||||
OPENWRT_COMMIT=a8b293598f181f358ba8ac988ef75a97064792e0
|
OPENWRT_COMMIT=17137076732b18442202e75c7edf10bccbc5f2a2
|
||||||
|
|
||||||
PACKAGES_PACKAGES_REPO=https://github.com/openwrt/packages.git
|
PACKAGES_PACKAGES_REPO=https://github.com/openwrt/packages.git
|
||||||
PACKAGES_PACKAGES_BRANCH=openwrt-19.07
|
PACKAGES_PACKAGES_BRANCH=openwrt-19.07
|
||||||
PACKAGES_PACKAGES_COMMIT=702c655874db358706b7858445b06dba09c90cd6
|
PACKAGES_PACKAGES_COMMIT=99efce0cd27adfcc53384fba93f37e5ee2e517de
|
||||||
|
|
||||||
PACKAGES_ROUTING_REPO=https://github.com/openwrt-routing/packages.git
|
PACKAGES_ROUTING_REPO=https://github.com/openwrt-routing/packages.git
|
||||||
PACKAGES_ROUTING_BRANCH=openwrt-19.07
|
PACKAGES_ROUTING_BRANCH=openwrt-19.07
|
||||||
PACKAGES_ROUTING_COMMIT=8d5ee29f088e9dfaa49dc74573edb1919f14dbf4
|
PACKAGES_ROUTING_COMMIT=efa6e5445adda9c6545f551808829ec927cbade8
|
||||||
|
|
||||||
PACKAGES_LUCI_REPO=https://github.com/openwrt/luci.git
|
|
||||||
PACKAGES_LUCI_BRANCH=openwrt-19.07
|
|
||||||
PACKAGES_LUCI_COMMIT=7542d02cd23208ca2ed89ea5341d323ca3dc4e58
|
|
||||||
|
|
||||||
PACKAGES_GLUON_REPO=https://github.com/freifunk-gluon/packages.git
|
PACKAGES_GLUON_REPO=https://github.com/freifunk-gluon/packages.git
|
||||||
PACKAGES_GLUON_COMMIT=de7b228cae72e87f2dfb3eed5b0354bd7cec4ca7
|
PACKAGES_GLUON_COMMIT=12e41d0ff07ec54bbd67a31ab50d12ca04f2238c
|
||||||
|
@ -14,6 +14,7 @@ xor2() {
|
|||||||
echo -n "${1:1:1}" | tr '0123456789abcdef' '23016745ab89efcd'
|
echo -n "${1:1:1}" | tr '0123456789abcdef' '23016745ab89efcd'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2086
|
||||||
interface_linklocal() {
|
interface_linklocal() {
|
||||||
local macaddr="$(ubus call network.device status '{"name": "'"$1"'"}' | jsonfilter -e '@.macaddr')"
|
local macaddr="$(ubus call network.device status '{"name": "'"$1"'"}' | jsonfilter -e '@.macaddr')"
|
||||||
local oldIFS="$IFS"; IFS=':'; set -- $macaddr; IFS="$oldIFS"
|
local oldIFS="$IFS"; IFS=':'; set -- $macaddr; IFS="$oldIFS"
|
||||||
|
@ -50,6 +50,8 @@ elseif platform.match('ar71xx', 'generic', {'archer-c5', 'archer-c58-v1',
|
|||||||
table.insert(try_files, 1, '/sys/class/net/eth1/address')
|
table.insert(try_files, 1, '/sys/class/net/eth1/address')
|
||||||
elseif platform.match('ar71xx', 'nand', {'hiveap-121'}) then
|
elseif platform.match('ar71xx', 'nand', {'hiveap-121'}) then
|
||||||
table.insert(try_files, 1, '/sys/class/net/eth0/address')
|
table.insert(try_files, 1, '/sys/class/net/eth0/address')
|
||||||
|
elseif platform.match('ath79', 'generic', {'ocedo,raccoon'}) then
|
||||||
|
table.insert(try_files, 1, '/sys/class/net/eth0/address')
|
||||||
elseif platform.match('ipq40xx', 'generic', {'avm,fritzbox-4040',
|
elseif platform.match('ipq40xx', 'generic', {'avm,fritzbox-4040',
|
||||||
'openmesh,a42', 'openmesh,a62'}) then
|
'openmesh,a42', 'openmesh,a62'}) then
|
||||||
table.insert(try_files, 1, '/sys/class/net/eth0/address')
|
table.insert(try_files, 1, '/sys/class/net/eth0/address')
|
||||||
@ -59,7 +61,7 @@ elseif platform.match('mpc85xx', 'p1020', {'aerohive,hiveap-330'}) then
|
|||||||
table.insert(try_files, 1, '/sys/class/net/eth0/address')
|
table.insert(try_files, 1, '/sys/class/net/eth0/address')
|
||||||
elseif platform.match('mpc85xx', 'p1020', {'ocedo,panda'}) then
|
elseif platform.match('mpc85xx', 'p1020', {'ocedo,panda'}) then
|
||||||
table.insert(try_files, 1, '/sys/class/net/eth1/address')
|
table.insert(try_files, 1, '/sys/class/net/eth1/address')
|
||||||
elseif platform.match('ramips', 'mt7620', {'miwifi-mini'}) then
|
elseif platform.match('ramips', 'mt7620', {'miwifi-mini', 'tplink,c2-v1', 'c20-v1', 'c20i', 'c50'}) then
|
||||||
table.insert(try_files, 1, '/sys/class/net/eth0/address')
|
table.insert(try_files, 1, '/sys/class/net/eth0/address')
|
||||||
elseif platform.match('ramips', 'mt7621', {'dir-860l-b1'}) then
|
elseif platform.match('ramips', 'mt7621', {'dir-860l-b1'}) then
|
||||||
table.insert(try_files, 1, '/sys/class/ieee80211/phy1/macaddress')
|
table.insert(try_files, 1, '/sys/class/ieee80211/phy1/macaddress')
|
||||||
|
@ -44,6 +44,9 @@ function M.is_outdoor_device()
|
|||||||
elseif M.match('ar71xx', 'generic', {'unifiac-pro'}) and
|
elseif M.match('ar71xx', 'generic', {'unifiac-pro'}) and
|
||||||
M.get_model() == 'Ubiquiti UniFi-AC-MESH-PRO' then
|
M.get_model() == 'Ubiquiti UniFi-AC-MESH-PRO' then
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
elseif M.match('ath79', 'generic', {'devolo,dvl1750x'}) then
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
@ -10,7 +10,7 @@ include ../gluon.mk
|
|||||||
|
|
||||||
define Package/gluon-mesh-babel
|
define Package/gluon-mesh-babel
|
||||||
TITLE:=Babel mesh
|
TITLE:=Babel mesh
|
||||||
DEPENDS:=+gluon-core +babeld +mmfd +libiwinfo +libgluonutil +firewall +libjson-c +libnl-tiny +libubus +libubox +libblobmsg-json +libbabelhelper +luabitop +gluon-l3roamd
|
DEPENDS:=+gluon-core +babeld +gluon-mmfd +libiwinfo +libgluonutil +firewall +libjson-c +libnl-tiny +libubus +libubox +libblobmsg-json +libbabelhelper +luabitop
|
||||||
PROVIDES:=gluon-mesh-provider
|
PROVIDES:=gluon-mesh-provider
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/lua
|
#!/usr/bin/lua
|
||||||
|
|
||||||
local site = require 'gluon.site'
|
local site = require 'gluon.site'
|
||||||
|
local uci = require('simple-uci').cursor()
|
||||||
|
local nodeip = uci:get('network', 'loopback', 'ip6addr'):match('^[^/]+')
|
||||||
local babelconf='/etc/gluon-babeld.conf'
|
local babelconf='/etc/gluon-babeld.conf'
|
||||||
|
|
||||||
local file = io.open(babelconf, "w")
|
local file = io.open(babelconf, "w")
|
||||||
@ -15,7 +17,7 @@ file:write("redistribute ip " .. site.prefix6() .. " eq 128 allow\n")
|
|||||||
file:write("redistribute ip " .. site.node_client_prefix6() .. " eq 128 allow\n")
|
file:write("redistribute ip " .. site.node_client_prefix6() .. " eq 128 allow\n")
|
||||||
file:write("redistribute ip " .. site.node_prefix6() .. " eq 128 allow\n")
|
file:write("redistribute ip " .. site.node_prefix6() .. " eq 128 allow\n")
|
||||||
file:write("redistribute ip 2000::/3 allow\n")
|
file:write("redistribute ip 2000::/3 allow\n")
|
||||||
|
|
||||||
file:write("redistribute local if br-wan deny\n")
|
file:write("redistribute local if br-wan deny\n")
|
||||||
file:write("redistribute local ip 0.0.0.0/0 deny\n")
|
file:write("redistribute local ip 0.0.0.0/0 deny\n")
|
||||||
|
file:write("install pref-src " .. nodeip .."\n")
|
||||||
file:close()
|
file:close()
|
||||||
|
@ -25,7 +25,7 @@ LDFLAGS_JSONC = $(shell pkg-config --libs json-c)
|
|||||||
|
|
||||||
|
|
||||||
respondd.so: respondd.c handle_neighbour.c
|
respondd.so: respondd.c handle_neighbour.c
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -shared $(LDFLAGS_JSONC) -o $@ $^ -lgluonutil -lblobmsg_json -lubox -lubus -liwinfo -luci
|
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -shared $(LDFLAGS_JSONC) -o $@ $^ -lgluonutil -lblobmsg_json -lubox -lubus -luci
|
||||||
|
|
||||||
neighbours-babel: neighbours-babel.c handle_neighbour.c
|
neighbours-babel: neighbours-babel.c handle_neighbour.c
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_JSONC) $(LDFLAGS) $(LDLIBS) $(LDFLAGS_JSONC) -o $@ $^
|
$(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_JSONC) $(LDFLAGS) $(LDLIBS) $(LDFLAGS_JSONC) -o $@ $^
|
||||||
|
@ -26,17 +26,15 @@
|
|||||||
|
|
||||||
#include <respondd.h>
|
#include <respondd.h>
|
||||||
|
|
||||||
#include <iwinfo.h>
|
|
||||||
#include <json-c/json.h>
|
#include <json-c/json.h>
|
||||||
#include <libgluonutil.h>
|
#include <libgluonutil.h>
|
||||||
#include <uci.h>
|
#include <uci.h>
|
||||||
|
|
||||||
#include <alloca.h>
|
|
||||||
#include <glob.h>
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@ -49,33 +47,18 @@
|
|||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
|
|
||||||
#include <linux/ethtool.h>
|
|
||||||
#include <linux/if_addr.h>
|
|
||||||
#include <linux/sockios.h>
|
|
||||||
|
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include "errno.h"
|
#include <errno.h>
|
||||||
#include <libbabelhelper/babelhelper.h>
|
#include <libbabelhelper/babelhelper.h>
|
||||||
|
|
||||||
#include <libubox/blobmsg_json.h>
|
#include <libubox/blobmsg_json.h>
|
||||||
#include "libubus.h"
|
#include <libubus.h>
|
||||||
|
|
||||||
#define _STRINGIFY(s) #s
|
|
||||||
#define STRINGIFY(s) _STRINGIFY(s)
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define MAX_INACTIVITY 60000
|
|
||||||
|
|
||||||
#define SOCKET_INPUT_BUFFER_SIZE 255
|
#define SOCKET_INPUT_BUFFER_SIZE 255
|
||||||
#define BABEL_PORT 33123
|
|
||||||
#define VPN_INTERFACE "mesh-vpn"
|
|
||||||
#define l3rdctl "/var/run/l3roamd.sock"
|
|
||||||
|
|
||||||
#define IFNAMELEN 32
|
|
||||||
#define PROTOLEN 32
|
#define PROTOLEN 32
|
||||||
|
|
||||||
#define UBUS_TIMEOUT 30
|
#define UBUS_TIMEOUT 30000
|
||||||
#define UBUS_SOCKET "/var/run/ubus.sock"
|
|
||||||
|
|
||||||
static struct babelhelper_ctx bhelper_ctx = {};
|
static struct babelhelper_ctx bhelper_ctx = {};
|
||||||
|
|
||||||
@ -241,7 +224,7 @@ static struct json_object * get_babel_neighbours(void) {
|
|||||||
if (!neighbours)
|
if (!neighbours)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
babelhelper_readbabeldata(&bhelper_ctx, (void*)neighbours, handle_neighbour);
|
babelhelper_readbabeldata(&bhelper_ctx, "dump", (void*)neighbours, handle_neighbour);
|
||||||
|
|
||||||
return(neighbours);
|
return(neighbours);
|
||||||
}
|
}
|
||||||
@ -258,9 +241,9 @@ static void blobmsg_handle_element(struct blob_attr *attr, bool head, char **ifn
|
|||||||
|
|
||||||
switch (blob_id(attr)) {
|
switch (blob_id(attr)) {
|
||||||
case BLOBMSG_TYPE_STRING:
|
case BLOBMSG_TYPE_STRING:
|
||||||
if (!strncmp(blobmsg_name(attr),"device", 6)) {
|
if (!strncmp(blobmsg_name(attr), "device", 6)) {
|
||||||
free(*ifname);
|
free(*ifname);
|
||||||
*ifname = strndup(data, IFNAMELEN);
|
*ifname = strndup(data, IF_NAMESIZE);
|
||||||
} else if (!strncmp(blobmsg_name(attr), "proto", 5)) {
|
} else if (!strncmp(blobmsg_name(attr), "proto", 5)) {
|
||||||
free(*proto);
|
free(*proto);
|
||||||
*proto = strndup(data, PROTOLEN);
|
*proto = strndup(data, PROTOLEN);
|
||||||
@ -330,7 +313,7 @@ static struct json_object * get_mesh_ifs() {
|
|||||||
|
|
||||||
unsigned int id=8;
|
unsigned int id=8;
|
||||||
|
|
||||||
ubus_ctx = ubus_connect(UBUS_SOCKET);
|
ubus_ctx = ubus_connect(NULL);
|
||||||
if (!ubus_ctx) {
|
if (!ubus_ctx) {
|
||||||
fprintf(stderr,"could not connect to ubus, not providing mesh-data\n");
|
fprintf(stderr,"could not connect to ubus, not providing mesh-data\n");
|
||||||
goto end;
|
goto end;
|
||||||
@ -338,7 +321,7 @@ static struct json_object * get_mesh_ifs() {
|
|||||||
|
|
||||||
blob_buf_init(&b, 0);
|
blob_buf_init(&b, 0);
|
||||||
ubus_lookup_id(ubus_ctx, "network.interface", &id);
|
ubus_lookup_id(ubus_ctx, "network.interface", &id);
|
||||||
int uret = ubus_invoke(ubus_ctx, id, "dump", b.head, receive_call_result_data, &ret, UBUS_TIMEOUT * 1000);
|
int uret = ubus_invoke(ubus_ctx, id, "dump", b.head, receive_call_result_data, &ret, UBUS_TIMEOUT);
|
||||||
|
|
||||||
if (uret > 0)
|
if (uret > 0)
|
||||||
fprintf(stderr, "ubus command failed: %s\n", ubus_strerror(uret));
|
fprintf(stderr, "ubus command failed: %s\n", ubus_strerror(uret));
|
||||||
@ -386,34 +369,40 @@ static struct json_object * respondd_provider_nodeinfo(void) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t getnumber(const char *ifname, const char *stat) {
|
static struct json_object * read_number(const char *ifname, const char *stat) {
|
||||||
const char *format = "/sys/class/net/%s/statistics/%s";
|
const char *format = "/sys/class/net/%s/statistics/%s";
|
||||||
|
|
||||||
|
struct json_object *ret = NULL;
|
||||||
|
int64_t i;
|
||||||
|
|
||||||
char path[strlen(format) + strlen(ifname) + strlen(stat) + 1];
|
char path[strlen(format) + strlen(ifname) + strlen(stat) + 1];
|
||||||
snprintf(path, sizeof(path), format, ifname, stat);
|
snprintf(path, sizeof(path), format, ifname, stat);
|
||||||
if (! access(path, F_OK)) {
|
|
||||||
char *line=gluonutil_read_line(path);
|
FILE *f = fopen(path, "r");
|
||||||
long long i = atoll(line);
|
if (!f)
|
||||||
free(line);
|
return NULL;
|
||||||
return(i);
|
|
||||||
}
|
if (fscanf(f, "%"SCNd64, &i) == 1)
|
||||||
return 0;
|
ret = json_object_new_int64(i);
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct json_object * get_traffic(void) {
|
static struct json_object * get_traffic(void) {
|
||||||
char ifname[16];
|
const char *ifname = "br-client";
|
||||||
|
|
||||||
strncpy(ifname, "br-client", 16);
|
|
||||||
|
|
||||||
struct json_object *ret = NULL;
|
struct json_object *ret = NULL;
|
||||||
struct json_object *rx = json_object_new_object();
|
struct json_object *rx = json_object_new_object();
|
||||||
struct json_object *tx = json_object_new_object();
|
struct json_object *tx = json_object_new_object();
|
||||||
|
|
||||||
json_object_object_add(rx, "packets", json_object_new_int64(getnumber(ifname, "rx_packets")));
|
json_object_object_add(rx, "packets", read_number(ifname, "rx_packets"));
|
||||||
json_object_object_add(rx, "bytes", json_object_new_int64(getnumber(ifname, "rx_bytes")));
|
json_object_object_add(rx, "bytes", read_number(ifname, "rx_bytes"));
|
||||||
json_object_object_add(rx, "dropped", json_object_new_int64(getnumber(ifname, "rx_dropped")));
|
json_object_object_add(rx, "dropped", read_number(ifname, "rx_dropped"));
|
||||||
json_object_object_add(tx, "packets", json_object_new_int64(getnumber(ifname, "tx_packets")));
|
json_object_object_add(tx, "packets", read_number(ifname, "tx_packets"));
|
||||||
json_object_object_add(tx, "dropped", json_object_new_int64(getnumber(ifname, "tx_dropped")));
|
json_object_object_add(tx, "dropped", read_number(ifname, "tx_dropped"));
|
||||||
json_object_object_add(tx, "bytes", json_object_new_int64(getnumber(ifname, "tx_bytes")));
|
json_object_object_add(tx, "bytes", read_number(ifname, "tx_bytes"));
|
||||||
|
|
||||||
ret = json_object_new_object();
|
ret = json_object_new_object();
|
||||||
json_object_object_add(ret, "rx", rx);
|
json_object_object_add(ret, "rx", rx);
|
||||||
@ -422,72 +411,6 @@ static struct json_object * get_traffic(void) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void count_iface_stations(size_t *wifi24, size_t *wifi5, const char *ifname) {
|
|
||||||
const struct iwinfo_ops *iw = iwinfo_backend(ifname);
|
|
||||||
if (!iw)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int freq;
|
|
||||||
if (iw->frequency(ifname, &freq) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
size_t *wifi;
|
|
||||||
if (freq >= 2400 && freq < 2500)
|
|
||||||
wifi = wifi24;
|
|
||||||
else if (freq >= 5000 && freq < 6000)
|
|
||||||
wifi = wifi5;
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
int len;
|
|
||||||
char buf[IWINFO_BUFSIZE];
|
|
||||||
if (iw->assoclist(ifname, buf, &len) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
struct iwinfo_assoclist_entry *entry;
|
|
||||||
for (entry = (struct iwinfo_assoclist_entry *)buf; (char*)(entry+1) <= buf + len; entry++) {
|
|
||||||
if (entry->inactive > MAX_INACTIVITY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
(*wifi)++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void count_stations(size_t *wifi24, size_t *wifi5) {
|
|
||||||
struct uci_context *ctx = uci_alloc_context();
|
|
||||||
ctx->flags &= ~UCI_FLAG_STRICT;
|
|
||||||
|
|
||||||
|
|
||||||
struct uci_package *p;
|
|
||||||
if (uci_load(ctx, "wireless", &p))
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
|
|
||||||
struct uci_element *e;
|
|
||||||
uci_foreach_element(&p->sections, e) {
|
|
||||||
struct uci_section *s = uci_to_section(e);
|
|
||||||
if (strcmp(s->type, "wifi-iface"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *network = uci_lookup_option_string(ctx, s, "network");
|
|
||||||
if (!network || strcmp(network, "client"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *mode = uci_lookup_option_string(ctx, s, "mode");
|
|
||||||
if (!mode || strcmp(mode, "ap"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *ifname = uci_lookup_option_string(ctx, s, "ifname");
|
|
||||||
if (!ifname)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
count_iface_stations(wifi24, wifi5, ifname);
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
uci_free_context(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool handle_route_addgw_nexthop(char **data, void *arg) {
|
static bool handle_route_addgw_nexthop(char **data, void *arg) {
|
||||||
struct json_object *obj = (struct json_object*) arg;
|
struct json_object *obj = (struct json_object*) arg;
|
||||||
if (data[PREFIX] && data[FROM] && data[VIA] && data[IF]) {
|
if (data[PREFIX] && data[FROM] && data[VIA] && data[IF]) {
|
||||||
@ -569,21 +492,12 @@ end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct json_object * get_clients(void) {
|
static struct json_object * get_clients(void) {
|
||||||
size_t wifi24 = 0, wifi5 = 0;
|
|
||||||
|
|
||||||
count_stations(&wifi24, &wifi5);
|
|
||||||
|
|
||||||
int total = ask_l3roamd_for_client_count();
|
|
||||||
|
|
||||||
size_t wifi = wifi24 + wifi5;
|
|
||||||
struct json_object *ret = json_object_new_object();
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
int total = ask_l3roamd_for_client_count();
|
||||||
if (total >= 0)
|
if (total >= 0)
|
||||||
json_object_object_add(ret, "total", json_object_new_int(total));
|
json_object_object_add(ret, "total", json_object_new_int(total));
|
||||||
|
|
||||||
json_object_object_add(ret, "wifi", json_object_new_int(wifi));
|
|
||||||
json_object_object_add(ret, "wifi24", json_object_new_int(wifi24));
|
|
||||||
json_object_object_add(ret, "wifi5", json_object_new_int(wifi5));
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -593,94 +507,11 @@ static struct json_object * respondd_provider_statistics(void) {
|
|||||||
json_object_object_add(ret, "clients", get_clients());
|
json_object_object_add(ret, "clients", get_clients());
|
||||||
json_object_object_add(ret, "traffic", get_traffic());
|
json_object_object_add(ret, "traffic", get_traffic());
|
||||||
|
|
||||||
babelhelper_readbabeldata(&bhelper_ctx, (void*)ret, handle_route_addgw_nexthop );
|
babelhelper_readbabeldata(&bhelper_ctx, "dump", (void*)ret, handle_route_addgw_nexthop );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct json_object * get_wifi_neighbours(const char *ifname) {
|
|
||||||
const struct iwinfo_ops *iw = iwinfo_backend(ifname);
|
|
||||||
if (!iw)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
int len;
|
|
||||||
char buf[IWINFO_BUFSIZE];
|
|
||||||
if (iw->assoclist(ifname, buf, &len) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
struct json_object *neighbours = json_object_new_object();
|
|
||||||
|
|
||||||
struct iwinfo_assoclist_entry *entry;
|
|
||||||
for (entry = (struct iwinfo_assoclist_entry *)buf; (char*)(entry+1) <= buf + len; entry++) {
|
|
||||||
if (entry->inactive > MAX_INACTIVITY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
struct json_object *obj = json_object_new_object();
|
|
||||||
|
|
||||||
json_object_object_add(obj, "signal", json_object_new_int(entry->signal));
|
|
||||||
json_object_object_add(obj, "noise", json_object_new_int(entry->noise));
|
|
||||||
json_object_object_add(obj, "inactive", json_object_new_int(entry->inactive));
|
|
||||||
|
|
||||||
char mac[18];
|
|
||||||
snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
||||||
entry->mac[0], entry->mac[1], entry->mac[2],
|
|
||||||
entry->mac[3], entry->mac[4], entry->mac[5]);
|
|
||||||
|
|
||||||
json_object_object_add(neighbours, mac, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
|
|
||||||
if (json_object_object_length(neighbours))
|
|
||||||
json_object_object_add(ret, "neighbours", neighbours);
|
|
||||||
else
|
|
||||||
json_object_put(neighbours);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_wifi(void) {
|
|
||||||
|
|
||||||
struct uci_context *ctx = uci_alloc_context();
|
|
||||||
ctx->flags &= ~UCI_FLAG_STRICT;
|
|
||||||
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
|
|
||||||
struct uci_package *p;
|
|
||||||
if (uci_load(ctx, "network", &p))
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
|
|
||||||
struct uci_element *e;
|
|
||||||
uci_foreach_element(&p->sections, e) {
|
|
||||||
struct uci_section *s = uci_to_section(e);
|
|
||||||
if (strcmp(s->type, "interface"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *proto = uci_lookup_option_string(ctx, s, "proto");
|
|
||||||
if (!proto || strcmp(proto, "gluon_mesh"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *ifname = uci_lookup_option_string(ctx, s, "ifname");
|
|
||||||
if (!ifname)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
char *ifaddr = gluonutil_get_interface_address(ifname);
|
|
||||||
if (!ifaddr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
struct json_object *neighbours = get_wifi_neighbours(ifname);
|
|
||||||
if (neighbours)
|
|
||||||
json_object_object_add(ret, ifaddr, neighbours);
|
|
||||||
|
|
||||||
free(ifaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
uci_free_context(ctx);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * respondd_provider_neighbours(void) {
|
static struct json_object * respondd_provider_neighbours(void) {
|
||||||
struct json_object *ret = json_object_new_object();
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
@ -689,10 +520,6 @@ static struct json_object * respondd_provider_neighbours(void) {
|
|||||||
json_object_object_add(ret, "babel", babel);
|
json_object_object_add(ret, "babel", babel);
|
||||||
|
|
||||||
|
|
||||||
struct json_object *wifi = get_wifi();
|
|
||||||
if (wifi)
|
|
||||||
json_object_object_add(ret, "wifi", wifi);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
lock /var/lock/gluon_bat0.lock
|
lock /var/lock/gluon_bat0.lock
|
||||||
(echo 'none' > "/sys/class/net/$IFNAME/batman_adv/mesh_iface") 2>/dev/null
|
batctl interface del "$IFNAME" 2>/dev/null
|
||||||
lock -u /var/lock/gluon_bat0.lock
|
lock -u /var/lock/gluon_bat0.lock
|
||||||
|
@ -22,20 +22,9 @@ proto_gluon_bat0_renew() {
|
|||||||
|
|
||||||
lock /var/lock/gluon_bat0.lock
|
lock /var/lock/gluon_bat0.lock
|
||||||
|
|
||||||
local ifdump="$(ubus call network.interface dump)"
|
ubus call network.interface dump | jsonfilter \
|
||||||
|
-e "@.interface[@.proto='gluon_mesh' && @.up=true].device" \
|
||||||
echo "$ifdump" | jsonfilter \
|
| xargs -r -n 1 batctl interface add
|
||||||
-e "@.interface[@.proto='gluon_mesh' && @.up=true]['device','data']" \
|
|
||||||
| while read dev; do
|
|
||||||
read data
|
|
||||||
|
|
||||||
echo bat0 > "/sys/class/net/$dev/batman_adv/mesh_iface"
|
|
||||||
|
|
||||||
! [ "$(echo "$data" | jsonfilter -e "@.transitive")" = 'true' ]
|
|
||||||
transitive=$?
|
|
||||||
|
|
||||||
(echo "$transitive" > "/sys/class/net/$dev/batman_adv/no_rebroadcast") 2>/dev/null
|
|
||||||
done
|
|
||||||
|
|
||||||
lock -u /var/lock/gluon_bat0.lock
|
lock -u /var/lock/gluon_bat0.lock
|
||||||
}
|
}
|
||||||
|
@ -31,5 +31,8 @@ endif
|
|||||||
CFLAGS += $(LIBBATADV_CFLAGS)
|
CFLAGS += $(LIBBATADV_CFLAGS)
|
||||||
LDLIBS += $(LIBBATADV_LDLIBS)
|
LDLIBS += $(LIBBATADV_LDLIBS)
|
||||||
|
|
||||||
respondd.so: respondd.c
|
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -o $@ $^ $(LDLIBS) -lgluonutil -liwinfo -luci
|
SOURCES = respondd.c respondd-nodeinfo.c respondd-statistics.c respondd-neighbours.c
|
||||||
|
|
||||||
|
respondd.so: $(SOURCES) respondd-common.h
|
||||||
|
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -fvisibility=hidden -D_GNU_SOURCE -o $@ $(SOURCES) $(LDLIBS) -lgluonutil
|
||||||
|
30
package/gluon-mesh-batman-adv/src/respondd-common.h
Normal file
30
package/gluon-mesh-batman-adv/src/respondd-common.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct json_object * respondd_provider_nodeinfo(void);
|
||||||
|
struct json_object * respondd_provider_statistics(void);
|
||||||
|
struct json_object * respondd_provider_neighbours(void);
|
176
package/gluon-mesh-batman-adv/src/respondd-neighbours.c
Normal file
176
package/gluon-mesh-batman-adv/src/respondd-neighbours.c
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "respondd-common.h"
|
||||||
|
|
||||||
|
#include <batadv-genl.h>
|
||||||
|
#include <libgluonutil.h>
|
||||||
|
|
||||||
|
#include <json-c/json.h>
|
||||||
|
|
||||||
|
#include <netlink/netlink.h>
|
||||||
|
#include <netlink/genl/genl.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct neigh_netlink_opts {
|
||||||
|
struct json_object *interfaces;
|
||||||
|
struct batadv_nlquery_opts query_opts;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct json_object * ifnames2addrs(struct json_object *interfaces) {
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_foreach(interfaces, ifname, interface) {
|
||||||
|
char *ifaddr = gluonutil_get_interface_address(ifname);
|
||||||
|
if (!ifaddr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
struct json_object *obj = json_object_new_object();
|
||||||
|
json_object_object_add(obj, "neighbours", json_object_get(interface));
|
||||||
|
json_object_object_add(ret, ifaddr, obj);
|
||||||
|
|
||||||
|
free(ifaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_put(interfaces);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const enum batadv_nl_attrs parse_orig_list_mandatory[] = {
|
||||||
|
BATADV_ATTR_ORIG_ADDRESS,
|
||||||
|
BATADV_ATTR_NEIGH_ADDRESS,
|
||||||
|
BATADV_ATTR_TQ,
|
||||||
|
BATADV_ATTR_HARD_IFINDEX,
|
||||||
|
BATADV_ATTR_LAST_SEEN_MSECS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int parse_orig_list_netlink_cb(struct nl_msg *msg, void *arg)
|
||||||
|
{
|
||||||
|
struct nlattr *attrs[BATADV_ATTR_MAX+1];
|
||||||
|
struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
||||||
|
struct batadv_nlquery_opts *query_opts = arg;
|
||||||
|
struct genlmsghdr *ghdr;
|
||||||
|
uint8_t *orig;
|
||||||
|
uint8_t *dest;
|
||||||
|
uint8_t tq;
|
||||||
|
uint32_t hardif;
|
||||||
|
uint32_t lastseen;
|
||||||
|
char ifname_buf[IF_NAMESIZE], *ifname;
|
||||||
|
struct neigh_netlink_opts *opts;
|
||||||
|
char mac1[18];
|
||||||
|
|
||||||
|
opts = batadv_container_of(query_opts, struct neigh_netlink_opts,
|
||||||
|
query_opts);
|
||||||
|
|
||||||
|
if (!genlmsg_valid_hdr(nlh, 0))
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
ghdr = nlmsg_data(nlh);
|
||||||
|
|
||||||
|
if (ghdr->cmd != BATADV_CMD_GET_ORIGINATORS)
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
|
||||||
|
genlmsg_len(ghdr), batadv_genl_policy))
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
if (batadv_genl_missing_attrs(attrs, parse_orig_list_mandatory,
|
||||||
|
BATADV_ARRAY_SIZE(parse_orig_list_mandatory)))
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]);
|
||||||
|
dest = nla_data(attrs[BATADV_ATTR_NEIGH_ADDRESS]);
|
||||||
|
tq = nla_get_u8(attrs[BATADV_ATTR_TQ]);
|
||||||
|
hardif = nla_get_u32(attrs[BATADV_ATTR_HARD_IFINDEX]);
|
||||||
|
lastseen = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]);
|
||||||
|
|
||||||
|
if (memcmp(orig, dest, 6) != 0)
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
ifname = if_indextoname(hardif, ifname_buf);
|
||||||
|
if (!ifname)
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
sprintf(mac1, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
orig[0], orig[1], orig[2], orig[3], orig[4], orig[5]);
|
||||||
|
|
||||||
|
struct json_object *obj = json_object_new_object();
|
||||||
|
if (!obj)
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
struct json_object *interface;
|
||||||
|
if (!json_object_object_get_ex(opts->interfaces, ifname, &interface)) {
|
||||||
|
interface = json_object_new_object();
|
||||||
|
json_object_object_add(opts->interfaces, ifname, interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_object_add(obj, "tq", json_object_new_int(tq));
|
||||||
|
json_object_object_add(obj, "lastseen", json_object_new_double(lastseen / 1000.));
|
||||||
|
json_object_object_add(obj, "best", json_object_new_boolean(!!attrs[BATADV_ATTR_FLAG_BEST]));
|
||||||
|
json_object_object_add(interface, mac1, obj);
|
||||||
|
|
||||||
|
return NL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object * get_batadv(void) {
|
||||||
|
struct neigh_netlink_opts opts = {
|
||||||
|
.query_opts = {
|
||||||
|
.err = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
opts.interfaces = json_object_new_object();
|
||||||
|
if (!opts.interfaces)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ret = batadv_genl_query("bat0", BATADV_CMD_GET_ORIGINATORS,
|
||||||
|
parse_orig_list_netlink_cb, NLM_F_DUMP,
|
||||||
|
&opts.query_opts);
|
||||||
|
if (ret < 0) {
|
||||||
|
json_object_put(opts.interfaces);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ifnames2addrs(opts.interfaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct json_object * respondd_provider_neighbours(void) {
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
struct json_object *batadv = get_batadv();
|
||||||
|
if (batadv)
|
||||||
|
json_object_object_add(ret, "batadv", batadv);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
219
package/gluon-mesh-batman-adv/src/respondd-nodeinfo.c
Normal file
219
package/gluon-mesh-batman-adv/src/respondd-nodeinfo.c
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "respondd-common.h"
|
||||||
|
|
||||||
|
#include <libgluonutil.h>
|
||||||
|
|
||||||
|
#include <json-c/json.h>
|
||||||
|
|
||||||
|
#include <netlink/netlink.h>
|
||||||
|
#include <netlink/msg.h>
|
||||||
|
|
||||||
|
#include <glob.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <linux/if_addr.h>
|
||||||
|
#include <linux/rtnetlink.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct ip_address_information {
|
||||||
|
unsigned int ifindex;
|
||||||
|
struct json_object *addresses;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int get_addresses_cb(struct nl_msg *msg, void *arg) {
|
||||||
|
struct ip_address_information *info = (struct ip_address_information*) arg;
|
||||||
|
|
||||||
|
struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
||||||
|
struct ifaddrmsg *msg_content = NLMSG_DATA(nlh);
|
||||||
|
int remaining = nlh->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg));
|
||||||
|
struct rtattr *hdr;
|
||||||
|
|
||||||
|
for (hdr = IFA_RTA(msg_content); RTA_OK(hdr, remaining); hdr = RTA_NEXT(hdr, remaining)) {
|
||||||
|
char addr_str_buf[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
|
/* We are only interested in IP-addresses of br-client */
|
||||||
|
if (hdr->rta_type != IFA_ADDRESS ||
|
||||||
|
msg_content->ifa_index != info->ifindex ||
|
||||||
|
msg_content->ifa_flags & (IFA_F_TENTATIVE|IFA_F_DEPRECATED)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inet_ntop(AF_INET6, (struct in6_addr *) RTA_DATA(hdr), addr_str_buf, INET6_ADDRSTRLEN)) {
|
||||||
|
json_object_array_add(info->addresses, json_object_new_string(addr_str_buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object *get_addresses(void) {
|
||||||
|
struct ip_address_information info = {
|
||||||
|
.ifindex = if_nametoindex("br-client"),
|
||||||
|
.addresses = json_object_new_array(),
|
||||||
|
};
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* Open socket */
|
||||||
|
struct nl_sock *socket = nl_socket_alloc();
|
||||||
|
if (!socket) {
|
||||||
|
return info.addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = nl_connect(socket, NETLINK_ROUTE);
|
||||||
|
if (err < 0) {
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send message */
|
||||||
|
struct ifaddrmsg rt_hdr = { .ifa_family = AF_INET6, };
|
||||||
|
err = nl_send_simple(socket, RTM_GETADDR, NLM_F_REQUEST | NLM_F_ROOT, &rt_hdr, sizeof(struct ifaddrmsg));
|
||||||
|
if (err < 0) {
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve answer. Message is handled by get_addresses_cb */
|
||||||
|
nl_socket_modify_cb(socket, NL_CB_VALID, NL_CB_CUSTOM, get_addresses_cb, &info);
|
||||||
|
nl_recvmsgs_default(socket);
|
||||||
|
|
||||||
|
out_free:
|
||||||
|
nl_socket_free(socket);
|
||||||
|
return info.addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_if_not_empty(struct json_object *obj, const char *key, struct json_object *val) {
|
||||||
|
if (json_object_array_length(val))
|
||||||
|
json_object_object_add(obj, key, val);
|
||||||
|
else
|
||||||
|
json_object_put(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool interface_file_exists(const char *ifname, const char *name) {
|
||||||
|
const char *format = "/sys/class/net/%s/%s";
|
||||||
|
char path[strlen(format) + strlen(ifname) + strlen(name)];
|
||||||
|
snprintf(path, sizeof(path), format, ifname, name);
|
||||||
|
|
||||||
|
return !access(path, F_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mesh_add_subif(const char *ifname, struct json_object *wireless,
|
||||||
|
struct json_object *tunnel, struct json_object *other) {
|
||||||
|
struct json_object *address = gluonutil_wrap_and_free_string(gluonutil_get_interface_address(ifname));
|
||||||
|
|
||||||
|
char lowername[IFNAMSIZ];
|
||||||
|
strncpy(lowername, ifname, sizeof(lowername)-1);
|
||||||
|
lowername[sizeof(lowername)-1] = 0;
|
||||||
|
|
||||||
|
const char *format = "/sys/class/net/%s/lower_*";
|
||||||
|
char pattern[strlen(format) + IFNAMSIZ];
|
||||||
|
|
||||||
|
/* In case of VLAN and bridge interfaces, we want the lower interface
|
||||||
|
* to determine the interface type (but not for the interface address) */
|
||||||
|
while (true) {
|
||||||
|
snprintf(pattern, sizeof(pattern), format, lowername);
|
||||||
|
size_t pattern_len = strlen(pattern);
|
||||||
|
|
||||||
|
glob_t lower;
|
||||||
|
if (glob(pattern, GLOB_NOSORT, NULL, &lower))
|
||||||
|
break;
|
||||||
|
|
||||||
|
strncpy(lowername, lower.gl_pathv[0] + pattern_len - 1, sizeof(lowername)-1);
|
||||||
|
|
||||||
|
globfree(&lower);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interface_file_exists(lowername, "wireless"))
|
||||||
|
json_object_array_add(wireless, address);
|
||||||
|
else if (interface_file_exists(lowername, "tun_flags"))
|
||||||
|
json_object_array_add(tunnel, address);
|
||||||
|
else
|
||||||
|
json_object_array_add(other, address);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object * get_mesh_subifs(const char *ifname) {
|
||||||
|
struct json_object *wireless = json_object_new_array();
|
||||||
|
struct json_object *tunnel = json_object_new_array();
|
||||||
|
struct json_object *other = json_object_new_array();
|
||||||
|
|
||||||
|
const char *format = "/sys/class/net/%s/lower_*";
|
||||||
|
char pattern[strlen(format) + strlen(ifname) - 1];
|
||||||
|
snprintf(pattern, sizeof(pattern), format, ifname);
|
||||||
|
|
||||||
|
size_t pattern_len = strlen(pattern);
|
||||||
|
|
||||||
|
glob_t lower;
|
||||||
|
if (!glob(pattern, GLOB_NOSORT, NULL, &lower)) {
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < lower.gl_pathc; i++) {
|
||||||
|
mesh_add_subif(lower.gl_pathv[i] + pattern_len - 1,
|
||||||
|
wireless, tunnel, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
globfree(&lower);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
add_if_not_empty(ret, "wireless", wireless);
|
||||||
|
add_if_not_empty(ret, "tunnel", tunnel);
|
||||||
|
add_if_not_empty(ret, "other", other);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object * get_mesh(void) {
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
struct json_object *bat0_interfaces = json_object_new_object();
|
||||||
|
json_object_object_add(bat0_interfaces, "interfaces", get_mesh_subifs("bat0"));
|
||||||
|
json_object_object_add(ret, "bat0", bat0_interfaces);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct json_object * respondd_provider_nodeinfo(void) {
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
struct json_object *network = json_object_new_object();
|
||||||
|
json_object_object_add(network, "addresses", get_addresses());
|
||||||
|
json_object_object_add(network, "mesh", get_mesh());
|
||||||
|
json_object_object_add(ret, "network", network);
|
||||||
|
|
||||||
|
struct json_object *software = json_object_new_object();
|
||||||
|
struct json_object *software_batman_adv = json_object_new_object();
|
||||||
|
json_object_object_add(software_batman_adv, "version",
|
||||||
|
gluonutil_wrap_and_free_string(gluonutil_read_line("/sys/module/batman_adv/version")));
|
||||||
|
json_object_object_add(software_batman_adv, "compat", json_object_new_int(15));
|
||||||
|
json_object_object_add(software, "batman-adv", software_batman_adv);
|
||||||
|
json_object_object_add(ret, "software", software);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
322
package/gluon-mesh-batman-adv/src/respondd-statistics.c
Normal file
322
package/gluon-mesh-batman-adv/src/respondd-statistics.c
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "respondd-common.h"
|
||||||
|
|
||||||
|
#include <batadv-genl.h>
|
||||||
|
|
||||||
|
#include <json-c/json.h>
|
||||||
|
|
||||||
|
#include <netlink/netlink.h>
|
||||||
|
#include <netlink/genl/genl.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include <linux/ethtool.h>
|
||||||
|
#include <linux/sockios.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_INACTIVITY 60000
|
||||||
|
|
||||||
|
|
||||||
|
struct clients_netlink_opts {
|
||||||
|
size_t clients;
|
||||||
|
struct batadv_nlquery_opts query_opts;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gw_netlink_opts {
|
||||||
|
struct json_object *obj;
|
||||||
|
struct batadv_nlquery_opts query_opts;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const enum batadv_nl_attrs gateways_mandatory[] = {
|
||||||
|
BATADV_ATTR_ORIG_ADDRESS,
|
||||||
|
BATADV_ATTR_ROUTER,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int parse_gw_list_netlink_cb(struct nl_msg *msg, void *arg)
|
||||||
|
{
|
||||||
|
struct nlattr *attrs[BATADV_ATTR_MAX+1];
|
||||||
|
struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
||||||
|
struct batadv_nlquery_opts *query_opts = arg;
|
||||||
|
struct genlmsghdr *ghdr;
|
||||||
|
uint8_t *orig;
|
||||||
|
uint8_t *router;
|
||||||
|
struct gw_netlink_opts *opts;
|
||||||
|
char addr[18];
|
||||||
|
|
||||||
|
opts = batadv_container_of(query_opts, struct gw_netlink_opts,
|
||||||
|
query_opts);
|
||||||
|
|
||||||
|
if (!genlmsg_valid_hdr(nlh, 0))
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
ghdr = nlmsg_data(nlh);
|
||||||
|
|
||||||
|
if (ghdr->cmd != BATADV_CMD_GET_GATEWAYS)
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
|
||||||
|
genlmsg_len(ghdr), batadv_genl_policy))
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
if (batadv_genl_missing_attrs(attrs, gateways_mandatory,
|
||||||
|
BATADV_ARRAY_SIZE(gateways_mandatory)))
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
if (!attrs[BATADV_ATTR_FLAG_BEST])
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]);
|
||||||
|
router = nla_data(attrs[BATADV_ATTR_ROUTER]);
|
||||||
|
|
||||||
|
sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
orig[0], orig[1], orig[2], orig[3], orig[4], orig[5]);
|
||||||
|
|
||||||
|
json_object_object_add(opts->obj, "gateway", json_object_new_string(addr));
|
||||||
|
|
||||||
|
sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
router[0], router[1], router[2], router[3], router[4], router[5]);
|
||||||
|
|
||||||
|
json_object_object_add(opts->obj, "gateway_nexthop", json_object_new_string(addr));
|
||||||
|
|
||||||
|
return NL_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_gateway(struct json_object *obj) {
|
||||||
|
struct gw_netlink_opts opts = {
|
||||||
|
.obj = obj,
|
||||||
|
.query_opts = {
|
||||||
|
.err = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
batadv_genl_query("bat0", BATADV_CMD_GET_GATEWAYS,
|
||||||
|
parse_gw_list_netlink_cb, NLM_F_DUMP,
|
||||||
|
&opts.query_opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool ethtool_ioctl(int fd, struct ifreq *ifr, void *data) {
|
||||||
|
ifr->ifr_data = data;
|
||||||
|
|
||||||
|
return (ioctl(fd, SIOCETHTOOL, ifr) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t ethtool_get_stats_length(int fd, struct ifreq *ifr) {
|
||||||
|
struct {
|
||||||
|
struct ethtool_sset_info info;
|
||||||
|
uint32_t buf;
|
||||||
|
} sset = {};
|
||||||
|
|
||||||
|
sset.info.cmd = ETHTOOL_GSSET_INFO;
|
||||||
|
sset.info.sset_mask = (uint64_t)1 << ETH_SS_STATS;
|
||||||
|
|
||||||
|
if (!ethtool_ioctl(fd, ifr, &sset.info))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return sset.info.sset_mask ? sset.info.data[0] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ethtool_gstrings * ethtool_get_stats_strings(int fd, struct ifreq *ifr) {
|
||||||
|
uint32_t n_stats = ethtool_get_stats_length(fd, ifr);
|
||||||
|
|
||||||
|
if (!n_stats)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct ethtool_gstrings *strings = calloc(1, sizeof(*strings) + n_stats * ETH_GSTRING_LEN);
|
||||||
|
|
||||||
|
strings->cmd = ETHTOOL_GSTRINGS;
|
||||||
|
strings->string_set = ETH_SS_STATS;
|
||||||
|
strings->len = n_stats;
|
||||||
|
|
||||||
|
if (!ethtool_ioctl(fd, ifr, strings)) {
|
||||||
|
free(strings);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct json_object * get_traffic(void) {
|
||||||
|
struct ethtool_gstrings *strings = NULL;
|
||||||
|
struct ethtool_stats *stats = NULL;
|
||||||
|
|
||||||
|
struct ifreq ifr = {};
|
||||||
|
strncpy(ifr.ifr_name, "bat0", IF_NAMESIZE);
|
||||||
|
|
||||||
|
struct json_object *ret = NULL;
|
||||||
|
|
||||||
|
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
strings = ethtool_get_stats_strings(fd, &ifr);
|
||||||
|
if (!strings)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
stats = calloc(1, sizeof(struct ethtool_stats) + strings->len * sizeof(uint64_t));
|
||||||
|
stats->cmd = ETHTOOL_GSTATS;
|
||||||
|
stats->n_stats = strings->len;
|
||||||
|
|
||||||
|
if (!ethtool_ioctl(fd, &ifr, stats))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
struct json_object *rx = json_object_new_object();
|
||||||
|
struct json_object *tx = json_object_new_object();
|
||||||
|
struct json_object *forward = json_object_new_object();
|
||||||
|
struct json_object *mgmt_rx = json_object_new_object();
|
||||||
|
struct json_object *mgmt_tx = json_object_new_object();
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < strings->len; i++) {
|
||||||
|
if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "rx", ETH_GSTRING_LEN))
|
||||||
|
json_object_object_add(rx, "packets", json_object_new_int64(stats->data[i]));
|
||||||
|
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "rx_bytes", ETH_GSTRING_LEN))
|
||||||
|
json_object_object_add(rx, "bytes", json_object_new_int64(stats->data[i]));
|
||||||
|
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "tx", ETH_GSTRING_LEN))
|
||||||
|
json_object_object_add(tx, "packets", json_object_new_int64(stats->data[i]));
|
||||||
|
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "tx_dropped", ETH_GSTRING_LEN))
|
||||||
|
json_object_object_add(tx, "dropped", json_object_new_int64(stats->data[i]));
|
||||||
|
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "tx_bytes", ETH_GSTRING_LEN))
|
||||||
|
json_object_object_add(tx, "bytes", json_object_new_int64(stats->data[i]));
|
||||||
|
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "forward", ETH_GSTRING_LEN))
|
||||||
|
json_object_object_add(forward, "packets", json_object_new_int64(stats->data[i]));
|
||||||
|
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "forward_bytes", ETH_GSTRING_LEN))
|
||||||
|
json_object_object_add(forward, "bytes", json_object_new_int64(stats->data[i]));
|
||||||
|
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "mgmt_rx", ETH_GSTRING_LEN))
|
||||||
|
json_object_object_add(mgmt_rx, "packets", json_object_new_int64(stats->data[i]));
|
||||||
|
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "mgmt_rx_bytes", ETH_GSTRING_LEN))
|
||||||
|
json_object_object_add(mgmt_rx, "bytes", json_object_new_int64(stats->data[i]));
|
||||||
|
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "mgmt_tx", ETH_GSTRING_LEN))
|
||||||
|
json_object_object_add(mgmt_tx, "packets", json_object_new_int64(stats->data[i]));
|
||||||
|
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "mgmt_tx_bytes", ETH_GSTRING_LEN))
|
||||||
|
json_object_object_add(mgmt_tx, "bytes", json_object_new_int64(stats->data[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = json_object_new_object();
|
||||||
|
json_object_object_add(ret, "rx", rx);
|
||||||
|
json_object_object_add(ret, "tx", tx);
|
||||||
|
json_object_object_add(ret, "forward", forward);
|
||||||
|
json_object_object_add(ret, "mgmt_rx", mgmt_rx);
|
||||||
|
json_object_object_add(ret, "mgmt_tx", mgmt_tx);
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(stats);
|
||||||
|
free(strings);
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const enum batadv_nl_attrs clients_mandatory[] = {
|
||||||
|
BATADV_ATTR_TT_FLAGS,
|
||||||
|
/* Entries without the BATADV_TT_CLIENT_NOPURGE flag do not have a
|
||||||
|
* BATADV_ATTR_LAST_SEEN_MSECS attribute. We can still make this attr
|
||||||
|
* mandatory here, as entries without BATADV_TT_CLIENT_NOPURGE are
|
||||||
|
* ignored anyways.
|
||||||
|
*/
|
||||||
|
BATADV_ATTR_LAST_SEEN_MSECS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int parse_clients_list_netlink_cb(struct nl_msg *msg, void *arg)
|
||||||
|
{
|
||||||
|
struct nlattr *attrs[BATADV_ATTR_MAX+1];
|
||||||
|
struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
||||||
|
struct batadv_nlquery_opts *query_opts = arg;
|
||||||
|
struct genlmsghdr *ghdr;
|
||||||
|
struct clients_netlink_opts *opts;
|
||||||
|
uint32_t flags, lastseen;
|
||||||
|
|
||||||
|
opts = batadv_container_of(query_opts, struct clients_netlink_opts,
|
||||||
|
query_opts);
|
||||||
|
|
||||||
|
if (!genlmsg_valid_hdr(nlh, 0))
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
ghdr = nlmsg_data(nlh);
|
||||||
|
|
||||||
|
if (ghdr->cmd != BATADV_CMD_GET_TRANSTABLE_LOCAL)
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
|
||||||
|
genlmsg_len(ghdr), batadv_genl_policy))
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
if (batadv_genl_missing_attrs(attrs, clients_mandatory,
|
||||||
|
BATADV_ARRAY_SIZE(clients_mandatory)))
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
flags = nla_get_u32(attrs[BATADV_ATTR_TT_FLAGS]);
|
||||||
|
|
||||||
|
if (flags & (BATADV_TT_CLIENT_NOPURGE))
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
lastseen = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]);
|
||||||
|
if (lastseen > MAX_INACTIVITY)
|
||||||
|
return NL_OK;
|
||||||
|
|
||||||
|
opts->clients++;
|
||||||
|
|
||||||
|
return NL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object * get_clients(void) {
|
||||||
|
struct clients_netlink_opts opts = {
|
||||||
|
.clients = 0,
|
||||||
|
.query_opts = {
|
||||||
|
.err = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
batadv_genl_query("bat0", BATADV_CMD_GET_TRANSTABLE_LOCAL,
|
||||||
|
parse_clients_list_netlink_cb, NLM_F_DUMP,
|
||||||
|
&opts.query_opts);
|
||||||
|
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_add(ret, "total", json_object_new_int(opts.clients));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct json_object * respondd_provider_statistics(void) {
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_add(ret, "clients", get_clients());
|
||||||
|
json_object_object_add(ret, "traffic", get_traffic());
|
||||||
|
|
||||||
|
add_gateway(ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2016, Matthias Schiffer <mschiffer@universe-factory.net>
|
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@ -23,780 +23,12 @@
|
|||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "respondd-common.h"
|
||||||
|
|
||||||
#include <respondd.h>
|
#include <respondd.h>
|
||||||
|
|
||||||
#include <ifaddrs.h>
|
|
||||||
#include <iwinfo.h>
|
|
||||||
#include <json-c/json.h>
|
|
||||||
#include <libgluonutil.h>
|
|
||||||
#include <uci.h>
|
|
||||||
|
|
||||||
#include <alloca.h>
|
|
||||||
#include <glob.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
|
|
||||||
#include <netlink/netlink.h>
|
|
||||||
#include <netlink/genl/genl.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
#include <linux/ethtool.h>
|
|
||||||
#include <linux/if_addr.h>
|
|
||||||
#include <linux/rtnetlink.h>
|
|
||||||
#include <linux/sockios.h>
|
|
||||||
|
|
||||||
#include <batadv-genl.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define _STRINGIFY(s) #s
|
|
||||||
#define STRINGIFY(s) _STRINGIFY(s)
|
|
||||||
|
|
||||||
#define MAX_INACTIVITY 60000
|
|
||||||
|
|
||||||
|
|
||||||
struct neigh_netlink_opts {
|
|
||||||
struct json_object *interfaces;
|
|
||||||
struct batadv_nlquery_opts query_opts;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gw_netlink_opts {
|
|
||||||
struct json_object *obj;
|
|
||||||
struct batadv_nlquery_opts query_opts;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct clients_netlink_opts {
|
|
||||||
size_t non_wifi;
|
|
||||||
struct batadv_nlquery_opts query_opts;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ip_address_information {
|
|
||||||
unsigned int ifindex;
|
|
||||||
struct json_object *addresses;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int get_addresses_cb(struct nl_msg *msg, void *arg) {
|
|
||||||
struct ip_address_information *info = (struct ip_address_information*) arg;
|
|
||||||
|
|
||||||
struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
|
||||||
struct ifaddrmsg *msg_content = NLMSG_DATA(nlh);
|
|
||||||
int remaining = nlh->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg));
|
|
||||||
struct rtattr *hdr;
|
|
||||||
|
|
||||||
for (hdr = IFA_RTA(msg_content); RTA_OK(hdr, remaining); hdr = RTA_NEXT(hdr, remaining)) {
|
|
||||||
char addr_str_buf[INET6_ADDRSTRLEN];
|
|
||||||
|
|
||||||
/* We are only interested in IP-addresses of br-client */
|
|
||||||
if (hdr->rta_type != IFA_ADDRESS ||
|
|
||||||
msg_content->ifa_index != info->ifindex ||
|
|
||||||
msg_content->ifa_flags & (IFA_F_TENTATIVE|IFA_F_DEPRECATED)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inet_ntop(AF_INET6, (struct in6_addr *) RTA_DATA(hdr), addr_str_buf, INET6_ADDRSTRLEN)) {
|
|
||||||
json_object_array_add(info->addresses, json_object_new_string(addr_str_buf));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object *get_addresses(void) {
|
|
||||||
struct ip_address_information info = {
|
|
||||||
.ifindex = if_nametoindex("br-client"),
|
|
||||||
.addresses = json_object_new_array(),
|
|
||||||
};
|
|
||||||
int err;
|
|
||||||
|
|
||||||
/* Open socket */
|
|
||||||
struct nl_sock *socket = nl_socket_alloc();
|
|
||||||
if (!socket) {
|
|
||||||
return info.addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = nl_connect(socket, NETLINK_ROUTE);
|
|
||||||
if (err < 0) {
|
|
||||||
goto out_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send message */
|
|
||||||
struct ifaddrmsg rt_hdr = { .ifa_family = AF_INET6, };
|
|
||||||
err = nl_send_simple(socket, RTM_GETADDR, NLM_F_REQUEST | NLM_F_ROOT, &rt_hdr, sizeof(struct ifaddrmsg));
|
|
||||||
if (err < 0) {
|
|
||||||
goto out_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Retrieve answer. Message is handled by get_addresses_cb */
|
|
||||||
nl_socket_modify_cb(socket, NL_CB_VALID, NL_CB_CUSTOM, get_addresses_cb, &info);
|
|
||||||
nl_recvmsgs_default(socket);
|
|
||||||
|
|
||||||
out_free:
|
|
||||||
nl_socket_free(socket);
|
|
||||||
return info.addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_if_not_empty(struct json_object *obj, const char *key, struct json_object *val) {
|
|
||||||
if (json_object_array_length(val))
|
|
||||||
json_object_object_add(obj, key, val);
|
|
||||||
else
|
|
||||||
json_object_put(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool interface_file_exists(const char *ifname, const char *name) {
|
|
||||||
const char *format = "/sys/class/net/%s/%s";
|
|
||||||
char path[strlen(format) + strlen(ifname) + strlen(name)];
|
|
||||||
snprintf(path, sizeof(path), format, ifname, name);
|
|
||||||
|
|
||||||
return !access(path, F_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mesh_add_subif(const char *ifname, struct json_object *wireless,
|
|
||||||
struct json_object *tunnel, struct json_object *other) {
|
|
||||||
struct json_object *address = gluonutil_wrap_and_free_string(gluonutil_get_interface_address(ifname));
|
|
||||||
|
|
||||||
char lowername[IFNAMSIZ];
|
|
||||||
strncpy(lowername, ifname, sizeof(lowername)-1);
|
|
||||||
lowername[sizeof(lowername)-1] = 0;
|
|
||||||
|
|
||||||
const char *format = "/sys/class/net/%s/lower_*";
|
|
||||||
char pattern[strlen(format) + IFNAMSIZ];
|
|
||||||
|
|
||||||
/* In case of VLAN and bridge interfaces, we want the lower interface
|
|
||||||
* to determine the interface type (but not for the interface address) */
|
|
||||||
while (true) {
|
|
||||||
snprintf(pattern, sizeof(pattern), format, lowername);
|
|
||||||
size_t pattern_len = strlen(pattern);
|
|
||||||
|
|
||||||
glob_t lower;
|
|
||||||
if (glob(pattern, GLOB_NOSORT, NULL, &lower))
|
|
||||||
break;
|
|
||||||
|
|
||||||
strncpy(lowername, lower.gl_pathv[0] + pattern_len - 1, sizeof(lowername)-1);
|
|
||||||
|
|
||||||
globfree(&lower);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interface_file_exists(lowername, "wireless"))
|
|
||||||
json_object_array_add(wireless, address);
|
|
||||||
else if (interface_file_exists(lowername, "tun_flags"))
|
|
||||||
json_object_array_add(tunnel, address);
|
|
||||||
else
|
|
||||||
json_object_array_add(other, address);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_mesh_subifs(const char *ifname) {
|
|
||||||
struct json_object *wireless = json_object_new_array();
|
|
||||||
struct json_object *tunnel = json_object_new_array();
|
|
||||||
struct json_object *other = json_object_new_array();
|
|
||||||
|
|
||||||
const char *format = "/sys/class/net/%s/lower_*";
|
|
||||||
char pattern[strlen(format) + strlen(ifname) - 1];
|
|
||||||
snprintf(pattern, sizeof(pattern), format, ifname);
|
|
||||||
|
|
||||||
size_t pattern_len = strlen(pattern);
|
|
||||||
|
|
||||||
glob_t lower;
|
|
||||||
if (!glob(pattern, GLOB_NOSORT, NULL, &lower)) {
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < lower.gl_pathc; i++) {
|
|
||||||
mesh_add_subif(lower.gl_pathv[i] + pattern_len - 1,
|
|
||||||
wireless, tunnel, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
globfree(&lower);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
add_if_not_empty(ret, "wireless", wireless);
|
|
||||||
add_if_not_empty(ret, "tunnel", tunnel);
|
|
||||||
add_if_not_empty(ret, "other", other);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_mesh(void) {
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
struct json_object *bat0_interfaces = json_object_new_object();
|
|
||||||
json_object_object_add(bat0_interfaces, "interfaces", get_mesh_subifs("bat0"));
|
|
||||||
json_object_object_add(ret, "bat0", bat0_interfaces);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * respondd_provider_nodeinfo(void) {
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
|
|
||||||
struct json_object *network = json_object_new_object();
|
|
||||||
json_object_object_add(network, "addresses", get_addresses());
|
|
||||||
json_object_object_add(network, "mesh", get_mesh());
|
|
||||||
json_object_object_add(ret, "network", network);
|
|
||||||
|
|
||||||
struct json_object *software = json_object_new_object();
|
|
||||||
struct json_object *software_batman_adv = json_object_new_object();
|
|
||||||
json_object_object_add(software_batman_adv, "version",
|
|
||||||
gluonutil_wrap_and_free_string(gluonutil_read_line("/sys/module/batman_adv/version")));
|
|
||||||
json_object_object_add(software_batman_adv, "compat", json_object_new_int(15));
|
|
||||||
json_object_object_add(software, "batman-adv", software_batman_adv);
|
|
||||||
json_object_object_add(ret, "software", software);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const enum batadv_nl_attrs gateways_mandatory[] = {
|
|
||||||
BATADV_ATTR_ORIG_ADDRESS,
|
|
||||||
BATADV_ATTR_ROUTER,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int parse_gw_list_netlink_cb(struct nl_msg *msg, void *arg)
|
|
||||||
{
|
|
||||||
struct nlattr *attrs[BATADV_ATTR_MAX+1];
|
|
||||||
struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
|
||||||
struct batadv_nlquery_opts *query_opts = arg;
|
|
||||||
struct genlmsghdr *ghdr;
|
|
||||||
uint8_t *orig;
|
|
||||||
uint8_t *router;
|
|
||||||
struct gw_netlink_opts *opts;
|
|
||||||
char addr[18];
|
|
||||||
|
|
||||||
opts = batadv_container_of(query_opts, struct gw_netlink_opts,
|
|
||||||
query_opts);
|
|
||||||
|
|
||||||
if (!genlmsg_valid_hdr(nlh, 0))
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
ghdr = nlmsg_data(nlh);
|
|
||||||
|
|
||||||
if (ghdr->cmd != BATADV_CMD_GET_GATEWAYS)
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
|
|
||||||
genlmsg_len(ghdr), batadv_genl_policy))
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
if (batadv_genl_missing_attrs(attrs, gateways_mandatory,
|
|
||||||
BATADV_ARRAY_SIZE(gateways_mandatory)))
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
if (!attrs[BATADV_ATTR_FLAG_BEST])
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]);
|
|
||||||
router = nla_data(attrs[BATADV_ATTR_ROUTER]);
|
|
||||||
|
|
||||||
sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
||||||
orig[0], orig[1], orig[2], orig[3], orig[4], orig[5]);
|
|
||||||
|
|
||||||
json_object_object_add(opts->obj, "gateway", json_object_new_string(addr));
|
|
||||||
|
|
||||||
sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
||||||
router[0], router[1], router[2], router[3], router[4], router[5]);
|
|
||||||
|
|
||||||
json_object_object_add(opts->obj, "gateway_nexthop", json_object_new_string(addr));
|
|
||||||
|
|
||||||
return NL_STOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_gateway(struct json_object *obj) {
|
|
||||||
struct gw_netlink_opts opts = {
|
|
||||||
.obj = obj,
|
|
||||||
.query_opts = {
|
|
||||||
.err = 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
batadv_genl_query("bat0", BATADV_CMD_GET_GATEWAYS,
|
|
||||||
parse_gw_list_netlink_cb, NLM_F_DUMP,
|
|
||||||
&opts.query_opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool ethtool_ioctl(int fd, struct ifreq *ifr, void *data) {
|
|
||||||
ifr->ifr_data = data;
|
|
||||||
|
|
||||||
return (ioctl(fd, SIOCETHTOOL, ifr) >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t ethtool_get_stats_length(int fd, struct ifreq *ifr) {
|
|
||||||
const size_t sset_info_len = sizeof(struct ethtool_sset_info) + sizeof(uint32_t);
|
|
||||||
struct ethtool_sset_info *sset_info = alloca(sset_info_len);
|
|
||||||
memset(sset_info, 0, sset_info_len);
|
|
||||||
|
|
||||||
sset_info->cmd = ETHTOOL_GSSET_INFO;
|
|
||||||
sset_info->sset_mask = 1ull << ETH_SS_STATS;
|
|
||||||
|
|
||||||
if (!ethtool_ioctl(fd, ifr, sset_info))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return sset_info->sset_mask ? sset_info->data[0] : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ethtool_gstrings * ethtool_get_stats_strings(int fd, struct ifreq *ifr) {
|
|
||||||
uint32_t n_stats = ethtool_get_stats_length(fd, ifr);
|
|
||||||
|
|
||||||
if (!n_stats)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
struct ethtool_gstrings *strings = calloc(1, sizeof(*strings) + n_stats * ETH_GSTRING_LEN);
|
|
||||||
|
|
||||||
strings->cmd = ETHTOOL_GSTRINGS;
|
|
||||||
strings->string_set = ETH_SS_STATS;
|
|
||||||
strings->len = n_stats;
|
|
||||||
|
|
||||||
if (!ethtool_ioctl(fd, ifr, strings)) {
|
|
||||||
free(strings);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct json_object * get_traffic(void) {
|
|
||||||
struct ethtool_gstrings *strings = NULL;
|
|
||||||
struct ethtool_stats *stats = NULL;
|
|
||||||
|
|
||||||
struct ifreq ifr = {};
|
|
||||||
strncpy(ifr.ifr_name, "bat0", IF_NAMESIZE);
|
|
||||||
|
|
||||||
struct json_object *ret = NULL;
|
|
||||||
|
|
||||||
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (fd < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
strings = ethtool_get_stats_strings(fd, &ifr);
|
|
||||||
if (!strings)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
stats = calloc(1, sizeof(struct ethtool_stats) + strings->len * sizeof(uint64_t));
|
|
||||||
stats->cmd = ETHTOOL_GSTATS;
|
|
||||||
stats->n_stats = strings->len;
|
|
||||||
|
|
||||||
if (!ethtool_ioctl(fd, &ifr, stats))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
struct json_object *rx = json_object_new_object();
|
|
||||||
struct json_object *tx = json_object_new_object();
|
|
||||||
struct json_object *forward = json_object_new_object();
|
|
||||||
struct json_object *mgmt_rx = json_object_new_object();
|
|
||||||
struct json_object *mgmt_tx = json_object_new_object();
|
|
||||||
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < strings->len; i++) {
|
|
||||||
if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "rx", ETH_GSTRING_LEN))
|
|
||||||
json_object_object_add(rx, "packets", json_object_new_int64(stats->data[i]));
|
|
||||||
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "rx_bytes", ETH_GSTRING_LEN))
|
|
||||||
json_object_object_add(rx, "bytes", json_object_new_int64(stats->data[i]));
|
|
||||||
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "tx", ETH_GSTRING_LEN))
|
|
||||||
json_object_object_add(tx, "packets", json_object_new_int64(stats->data[i]));
|
|
||||||
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "tx_dropped", ETH_GSTRING_LEN))
|
|
||||||
json_object_object_add(tx, "dropped", json_object_new_int64(stats->data[i]));
|
|
||||||
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "tx_bytes", ETH_GSTRING_LEN))
|
|
||||||
json_object_object_add(tx, "bytes", json_object_new_int64(stats->data[i]));
|
|
||||||
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "forward", ETH_GSTRING_LEN))
|
|
||||||
json_object_object_add(forward, "packets", json_object_new_int64(stats->data[i]));
|
|
||||||
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "forward_bytes", ETH_GSTRING_LEN))
|
|
||||||
json_object_object_add(forward, "bytes", json_object_new_int64(stats->data[i]));
|
|
||||||
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "mgmt_rx", ETH_GSTRING_LEN))
|
|
||||||
json_object_object_add(mgmt_rx, "packets", json_object_new_int64(stats->data[i]));
|
|
||||||
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "mgmt_rx_bytes", ETH_GSTRING_LEN))
|
|
||||||
json_object_object_add(mgmt_rx, "bytes", json_object_new_int64(stats->data[i]));
|
|
||||||
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "mgmt_tx", ETH_GSTRING_LEN))
|
|
||||||
json_object_object_add(mgmt_tx, "packets", json_object_new_int64(stats->data[i]));
|
|
||||||
else if (!strncmp((const char*)&strings->data[i * ETH_GSTRING_LEN], "mgmt_tx_bytes", ETH_GSTRING_LEN))
|
|
||||||
json_object_object_add(mgmt_tx, "bytes", json_object_new_int64(stats->data[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = json_object_new_object();
|
|
||||||
json_object_object_add(ret, "rx", rx);
|
|
||||||
json_object_object_add(ret, "tx", tx);
|
|
||||||
json_object_object_add(ret, "forward", forward);
|
|
||||||
json_object_object_add(ret, "mgmt_rx", mgmt_rx);
|
|
||||||
json_object_object_add(ret, "mgmt_tx", mgmt_tx);
|
|
||||||
|
|
||||||
out:
|
|
||||||
free(stats);
|
|
||||||
free(strings);
|
|
||||||
close(fd);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void count_iface_stations(size_t *wifi24, size_t *wifi5, const char *ifname) {
|
|
||||||
const struct iwinfo_ops *iw = iwinfo_backend(ifname);
|
|
||||||
if (!iw)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int freq;
|
|
||||||
if (iw->frequency(ifname, &freq) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
size_t *wifi;
|
|
||||||
if (freq >= 2400 && freq < 2500)
|
|
||||||
wifi = wifi24;
|
|
||||||
else if (freq >= 5000 && freq < 6000)
|
|
||||||
wifi = wifi5;
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
int len;
|
|
||||||
char buf[IWINFO_BUFSIZE];
|
|
||||||
if (iw->assoclist(ifname, buf, &len) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
struct iwinfo_assoclist_entry *entry;
|
|
||||||
for (entry = (struct iwinfo_assoclist_entry *)buf; (char*)(entry+1) <= buf + len; entry++) {
|
|
||||||
if (entry->inactive > MAX_INACTIVITY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
(*wifi)++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void count_stations(size_t *wifi24, size_t *wifi5) {
|
|
||||||
struct uci_context *ctx = uci_alloc_context();
|
|
||||||
if (!ctx)
|
|
||||||
return;
|
|
||||||
ctx->flags &= ~UCI_FLAG_STRICT;
|
|
||||||
|
|
||||||
|
|
||||||
struct uci_package *p;
|
|
||||||
if (uci_load(ctx, "wireless", &p))
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
|
|
||||||
struct uci_element *e;
|
|
||||||
uci_foreach_element(&p->sections, e) {
|
|
||||||
struct uci_section *s = uci_to_section(e);
|
|
||||||
if (strcmp(s->type, "wifi-iface"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *network = uci_lookup_option_string(ctx, s, "network");
|
|
||||||
if (!network || strcmp(network, "client"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *mode = uci_lookup_option_string(ctx, s, "mode");
|
|
||||||
if (!mode || strcmp(mode, "ap"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *ifname = uci_lookup_option_string(ctx, s, "ifname");
|
|
||||||
if (!ifname)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
count_iface_stations(wifi24, wifi5, ifname);
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
uci_free_context(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const enum batadv_nl_attrs clients_mandatory[] = {
|
|
||||||
BATADV_ATTR_TT_FLAGS,
|
|
||||||
/* Entries without the BATADV_TT_CLIENT_NOPURGE flag do not have a
|
|
||||||
* BATADV_ATTR_LAST_SEEN_MSECS attribute. We can still make this attr
|
|
||||||
* mandatory here, as entries without BATADV_TT_CLIENT_NOPURGE are
|
|
||||||
* ignored anyways.
|
|
||||||
*/
|
|
||||||
BATADV_ATTR_LAST_SEEN_MSECS,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int parse_clients_list_netlink_cb(struct nl_msg *msg, void *arg)
|
|
||||||
{
|
|
||||||
struct nlattr *attrs[BATADV_ATTR_MAX+1];
|
|
||||||
struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
|
||||||
struct batadv_nlquery_opts *query_opts = arg;
|
|
||||||
struct genlmsghdr *ghdr;
|
|
||||||
struct clients_netlink_opts *opts;
|
|
||||||
uint32_t flags, lastseen;
|
|
||||||
|
|
||||||
opts = batadv_container_of(query_opts, struct clients_netlink_opts,
|
|
||||||
query_opts);
|
|
||||||
|
|
||||||
if (!genlmsg_valid_hdr(nlh, 0))
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
ghdr = nlmsg_data(nlh);
|
|
||||||
|
|
||||||
if (ghdr->cmd != BATADV_CMD_GET_TRANSTABLE_LOCAL)
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
|
|
||||||
genlmsg_len(ghdr), batadv_genl_policy))
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
if (batadv_genl_missing_attrs(attrs, clients_mandatory,
|
|
||||||
BATADV_ARRAY_SIZE(clients_mandatory)))
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
flags = nla_get_u32(attrs[BATADV_ATTR_TT_FLAGS]);
|
|
||||||
|
|
||||||
if (flags & (BATADV_TT_CLIENT_NOPURGE | BATADV_TT_CLIENT_WIFI))
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
lastseen = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]);
|
|
||||||
if (lastseen > MAX_INACTIVITY)
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
opts->non_wifi++;
|
|
||||||
|
|
||||||
return NL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_clients(void) {
|
|
||||||
size_t wifi24 = 0, wifi5 = 0;
|
|
||||||
size_t total;
|
|
||||||
size_t wifi;
|
|
||||||
struct clients_netlink_opts opts = {
|
|
||||||
.non_wifi = 0,
|
|
||||||
.query_opts = {
|
|
||||||
.err = 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
batadv_genl_query("bat0", BATADV_CMD_GET_TRANSTABLE_LOCAL,
|
|
||||||
parse_clients_list_netlink_cb, NLM_F_DUMP,
|
|
||||||
&opts.query_opts);
|
|
||||||
|
|
||||||
count_stations(&wifi24, &wifi5);
|
|
||||||
wifi = wifi24 + wifi5;
|
|
||||||
total = wifi + opts.non_wifi;
|
|
||||||
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
json_object_object_add(ret, "total", json_object_new_int(total));
|
|
||||||
json_object_object_add(ret, "wifi", json_object_new_int(wifi));
|
|
||||||
json_object_object_add(ret, "wifi24", json_object_new_int(wifi24));
|
|
||||||
json_object_object_add(ret, "wifi5", json_object_new_int(wifi5));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct json_object * respondd_provider_statistics(void) {
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
|
|
||||||
json_object_object_add(ret, "clients", get_clients());
|
|
||||||
json_object_object_add(ret, "traffic", get_traffic());
|
|
||||||
|
|
||||||
add_gateway(ret);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct json_object * ifnames2addrs(struct json_object *interfaces) {
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
|
|
||||||
json_object_object_foreach(interfaces, ifname, interface) {
|
|
||||||
char *ifaddr = gluonutil_get_interface_address(ifname);
|
|
||||||
if (!ifaddr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
struct json_object *obj = json_object_new_object();
|
|
||||||
json_object_object_add(obj, "neighbours", json_object_get(interface));
|
|
||||||
json_object_object_add(ret, ifaddr, obj);
|
|
||||||
|
|
||||||
free(ifaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
json_object_put(interfaces);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const enum batadv_nl_attrs parse_orig_list_mandatory[] = {
|
|
||||||
BATADV_ATTR_ORIG_ADDRESS,
|
|
||||||
BATADV_ATTR_NEIGH_ADDRESS,
|
|
||||||
BATADV_ATTR_TQ,
|
|
||||||
BATADV_ATTR_HARD_IFINDEX,
|
|
||||||
BATADV_ATTR_LAST_SEEN_MSECS,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int parse_orig_list_netlink_cb(struct nl_msg *msg, void *arg)
|
|
||||||
{
|
|
||||||
struct nlattr *attrs[BATADV_ATTR_MAX+1];
|
|
||||||
struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
|
||||||
struct batadv_nlquery_opts *query_opts = arg;
|
|
||||||
struct genlmsghdr *ghdr;
|
|
||||||
uint8_t *orig;
|
|
||||||
uint8_t *dest;
|
|
||||||
uint8_t tq;
|
|
||||||
uint32_t hardif;
|
|
||||||
uint32_t lastseen;
|
|
||||||
char ifname_buf[IF_NAMESIZE], *ifname;
|
|
||||||
struct neigh_netlink_opts *opts;
|
|
||||||
char mac1[18];
|
|
||||||
|
|
||||||
opts = batadv_container_of(query_opts, struct neigh_netlink_opts,
|
|
||||||
query_opts);
|
|
||||||
|
|
||||||
if (!genlmsg_valid_hdr(nlh, 0))
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
ghdr = nlmsg_data(nlh);
|
|
||||||
|
|
||||||
if (ghdr->cmd != BATADV_CMD_GET_ORIGINATORS)
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
|
|
||||||
genlmsg_len(ghdr), batadv_genl_policy))
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
if (batadv_genl_missing_attrs(attrs, parse_orig_list_mandatory,
|
|
||||||
BATADV_ARRAY_SIZE(parse_orig_list_mandatory)))
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]);
|
|
||||||
dest = nla_data(attrs[BATADV_ATTR_NEIGH_ADDRESS]);
|
|
||||||
tq = nla_get_u8(attrs[BATADV_ATTR_TQ]);
|
|
||||||
hardif = nla_get_u32(attrs[BATADV_ATTR_HARD_IFINDEX]);
|
|
||||||
lastseen = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]);
|
|
||||||
|
|
||||||
if (memcmp(orig, dest, 6) != 0)
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
ifname = if_indextoname(hardif, ifname_buf);
|
|
||||||
if (!ifname)
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
sprintf(mac1, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
||||||
orig[0], orig[1], orig[2], orig[3], orig[4], orig[5]);
|
|
||||||
|
|
||||||
struct json_object *obj = json_object_new_object();
|
|
||||||
if (!obj)
|
|
||||||
return NL_OK;
|
|
||||||
|
|
||||||
struct json_object *interface;
|
|
||||||
if (!json_object_object_get_ex(opts->interfaces, ifname, &interface)) {
|
|
||||||
interface = json_object_new_object();
|
|
||||||
json_object_object_add(opts->interfaces, ifname, interface);
|
|
||||||
}
|
|
||||||
|
|
||||||
json_object_object_add(obj, "tq", json_object_new_int(tq));
|
|
||||||
json_object_object_add(obj, "lastseen", json_object_new_double(lastseen / 1000.));
|
|
||||||
json_object_object_add(obj, "best", json_object_new_boolean(attrs[BATADV_ATTR_FLAG_BEST]));
|
|
||||||
json_object_object_add(interface, mac1, obj);
|
|
||||||
|
|
||||||
return NL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_batadv(void) {
|
|
||||||
struct neigh_netlink_opts opts = {
|
|
||||||
.query_opts = {
|
|
||||||
.err = 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
opts.interfaces = json_object_new_object();
|
|
||||||
if (!opts.interfaces)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ret = batadv_genl_query("bat0", BATADV_CMD_GET_ORIGINATORS,
|
|
||||||
parse_orig_list_netlink_cb, NLM_F_DUMP,
|
|
||||||
&opts.query_opts);
|
|
||||||
if (ret < 0) {
|
|
||||||
json_object_put(opts.interfaces);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ifnames2addrs(opts.interfaces);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_wifi_neighbours(const char *ifname) {
|
|
||||||
const struct iwinfo_ops *iw = iwinfo_backend(ifname);
|
|
||||||
if (!iw)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
int len;
|
|
||||||
char buf[IWINFO_BUFSIZE];
|
|
||||||
if (iw->assoclist(ifname, buf, &len) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
struct json_object *neighbours = json_object_new_object();
|
|
||||||
|
|
||||||
struct iwinfo_assoclist_entry *entry;
|
|
||||||
for (entry = (struct iwinfo_assoclist_entry *)buf; (char*)(entry+1) <= buf + len; entry++) {
|
|
||||||
if (entry->inactive > MAX_INACTIVITY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
struct json_object *obj = json_object_new_object();
|
|
||||||
|
|
||||||
json_object_object_add(obj, "signal", json_object_new_int(entry->signal));
|
|
||||||
json_object_object_add(obj, "noise", json_object_new_int(entry->noise));
|
|
||||||
json_object_object_add(obj, "inactive", json_object_new_int(entry->inactive));
|
|
||||||
|
|
||||||
char mac[18];
|
|
||||||
snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
||||||
entry->mac[0], entry->mac[1], entry->mac[2],
|
|
||||||
entry->mac[3], entry->mac[4], entry->mac[5]);
|
|
||||||
|
|
||||||
json_object_object_add(neighbours, mac, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
|
|
||||||
if (json_object_object_length(neighbours))
|
|
||||||
json_object_object_add(ret, "neighbours", neighbours);
|
|
||||||
else
|
|
||||||
json_object_put(neighbours);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_wifi(void) {
|
|
||||||
const char *mesh = "bat0";
|
|
||||||
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
|
|
||||||
const char *format = "/sys/class/net/%s/lower_*";
|
|
||||||
char pattern[strlen(format) + strlen(mesh)];
|
|
||||||
snprintf(pattern, sizeof(pattern), format, mesh);
|
|
||||||
|
|
||||||
size_t pattern_len = strlen(pattern);
|
|
||||||
|
|
||||||
glob_t lower;
|
|
||||||
if (!glob(pattern, GLOB_NOSORT, NULL, &lower)) {
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < lower.gl_pathc; i++) {
|
|
||||||
const char *ifname = lower.gl_pathv[i] + pattern_len - 1;
|
|
||||||
char *ifaddr = gluonutil_get_interface_address(ifname);
|
|
||||||
if (!ifaddr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
struct json_object *neighbours = get_wifi_neighbours(ifname);
|
|
||||||
if (neighbours)
|
|
||||||
json_object_object_add(ret, ifaddr, neighbours);
|
|
||||||
|
|
||||||
free(ifaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
globfree(&lower);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * respondd_provider_neighbours(void) {
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
|
|
||||||
struct json_object *batadv = get_batadv();
|
|
||||||
if (batadv)
|
|
||||||
json_object_object_add(ret, "batadv", batadv);
|
|
||||||
|
|
||||||
struct json_object *wifi = get_wifi();
|
|
||||||
if (wifi)
|
|
||||||
json_object_object_add(ret, "wifi", wifi);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__ ((visibility ("default")))
|
||||||
const struct respondd_provider_info respondd_providers[] = {
|
const struct respondd_provider_info respondd_providers[] = {
|
||||||
{"nodeinfo", respondd_provider_nodeinfo},
|
{"nodeinfo", respondd_provider_nodeinfo},
|
||||||
{"statistics", respondd_provider_statistics},
|
{"statistics", respondd_provider_statistics},
|
||||||
|
@ -37,8 +37,8 @@
|
|||||||
|
|
||||||
void usage() {
|
void usage() {
|
||||||
puts("Usage: gluon-neighbour-info [-h] [-s] [-l] [-c <count>] [-t <sec>] -d <dest> -p <port> -i <if0> -r <request>");
|
puts("Usage: gluon-neighbour-info [-h] [-s] [-l] [-c <count>] [-t <sec>] -d <dest> -p <port> -i <if0> -r <request>");
|
||||||
puts(" -p <int> UDP port");
|
puts(" -p <int> UDP port (default: 1001)");
|
||||||
puts(" -d <ip6> destination address (unicast ip6 or multicast group, e.g. ff02:0:0:0:0:0:2:1001)");
|
puts(" -d <ip6> destination address (unicast ip6 or multicast group, e.g. ff02:0:0:0:0:0:2:1001, default: ::1)");
|
||||||
puts(" -i <string> interface, e.g. eth0 ");
|
puts(" -i <string> interface, e.g. eth0 ");
|
||||||
puts(" -r <string> request, e.g. nodeinfo");
|
puts(" -r <string> request, e.g. nodeinfo");
|
||||||
puts(" -t <sec> timeout in seconds (default: 3)");
|
puts(" -t <sec> timeout in seconds (default: 3)");
|
||||||
@ -144,6 +144,8 @@ int main(int argc, char **argv) {
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client_addr.sin6_addr = in6addr_loopback;
|
||||||
|
client_addr.sin6_port = htons(1001);
|
||||||
client_addr.sin6_family = AF_INET6;
|
client_addr.sin6_family = AF_INET6;
|
||||||
|
|
||||||
opterr = 0;
|
opterr = 0;
|
||||||
|
@ -2,5 +2,7 @@ all: respondd.so
|
|||||||
|
|
||||||
CFLAGS += -Wall
|
CFLAGS += -Wall
|
||||||
|
|
||||||
respondd.so: respondd.c
|
SOURCES = respondd.c respondd-nodeinfo.c respondd-statistics.c respondd-neighbours.c
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -o $@ $^ $(LDLIBS) -lgluonutil -lplatforminfo -luci
|
|
||||||
|
respondd.so: $(SOURCES) respondd-common.h
|
||||||
|
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -fvisibility=hidden -D_GNU_SOURCE -o $@ $(SOURCES) $(LDLIBS) -lgluonutil -lplatforminfo -luci -liwinfo
|
||||||
|
32
package/gluon-respondd/src/respondd-common.h
Normal file
32
package/gluon-respondd/src/respondd-common.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define MAX_INACTIVITY 60000
|
||||||
|
|
||||||
|
struct json_object * respondd_provider_nodeinfo(void);
|
||||||
|
struct json_object * respondd_provider_statistics(void);
|
||||||
|
struct json_object * respondd_provider_neighbours(void);
|
130
package/gluon-respondd/src/respondd-neighbours.c
Normal file
130
package/gluon-respondd/src/respondd-neighbours.c
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "respondd-common.h"
|
||||||
|
|
||||||
|
#include <libgluonutil.h>
|
||||||
|
|
||||||
|
#include <iwinfo.h>
|
||||||
|
#include <json-c/json.h>
|
||||||
|
|
||||||
|
|
||||||
|
static struct json_object * get_wifi_neighbours(const char *ifname) {
|
||||||
|
const struct iwinfo_ops *iw = iwinfo_backend(ifname);
|
||||||
|
if (!iw)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
int len;
|
||||||
|
char buf[IWINFO_BUFSIZE];
|
||||||
|
if (iw->assoclist(ifname, buf, &len) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct json_object *neighbours = json_object_new_object();
|
||||||
|
|
||||||
|
struct iwinfo_assoclist_entry *entry;
|
||||||
|
for (entry = (struct iwinfo_assoclist_entry *)buf; (char*)(entry+1) <= buf + len; entry++) {
|
||||||
|
if (entry->inactive > MAX_INACTIVITY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
struct json_object *obj = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_add(obj, "signal", json_object_new_int(entry->signal));
|
||||||
|
json_object_object_add(obj, "noise", json_object_new_int(entry->noise));
|
||||||
|
json_object_object_add(obj, "inactive", json_object_new_int(entry->inactive));
|
||||||
|
|
||||||
|
char mac[18];
|
||||||
|
snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
entry->mac[0], entry->mac[1], entry->mac[2],
|
||||||
|
entry->mac[3], entry->mac[4], entry->mac[5]);
|
||||||
|
|
||||||
|
json_object_object_add(neighbours, mac, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
if (json_object_object_length(neighbours))
|
||||||
|
json_object_object_add(ret, "neighbours", neighbours);
|
||||||
|
else
|
||||||
|
json_object_put(neighbours);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object * get_wifi(void) {
|
||||||
|
struct uci_context *ctx = uci_alloc_context();
|
||||||
|
if (!ctx)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ctx->flags &= ~UCI_FLAG_STRICT;
|
||||||
|
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
struct uci_package *p;
|
||||||
|
if (uci_load(ctx, "network", &p))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
|
||||||
|
struct uci_element *e;
|
||||||
|
uci_foreach_element(&p->sections, e) {
|
||||||
|
struct uci_section *s = uci_to_section(e);
|
||||||
|
if (strcmp(s->type, "interface"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const char *proto = uci_lookup_option_string(ctx, s, "proto");
|
||||||
|
if (!proto || strcmp(proto, "gluon_mesh"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const char *ifname = uci_lookup_option_string(ctx, s, "ifname");
|
||||||
|
if (!ifname)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char *ifaddr = gluonutil_get_interface_address(ifname);
|
||||||
|
if (!ifaddr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
struct json_object *neighbours = get_wifi_neighbours(ifname);
|
||||||
|
if (neighbours)
|
||||||
|
json_object_object_add(ret, ifaddr, neighbours);
|
||||||
|
|
||||||
|
free(ifaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
uci_free_context(ctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct json_object * respondd_provider_neighbours(void) {
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_add(ret, "node_id", gluonutil_wrap_and_free_string(gluonutil_get_node_id()));
|
||||||
|
|
||||||
|
struct json_object *wifi = get_wifi();
|
||||||
|
if (wifi)
|
||||||
|
json_object_object_add(ret, "wifi", wifi);
|
||||||
|
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
132
package/gluon-respondd/src/respondd-nodeinfo.c
Normal file
132
package/gluon-respondd/src/respondd-nodeinfo.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "respondd-common.h"
|
||||||
|
|
||||||
|
#include <libgluonutil.h>
|
||||||
|
#include <libplatforminfo.h>
|
||||||
|
|
||||||
|
#include <json-c/json.h>
|
||||||
|
#include <uci.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
static struct json_object * gluon_version(void) {
|
||||||
|
char *version = gluonutil_read_line("/lib/gluon/gluon-version");
|
||||||
|
if (!version)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char full_version[6 + strlen(version) + 1];
|
||||||
|
snprintf(full_version, sizeof(full_version), "gluon-%s", version);
|
||||||
|
|
||||||
|
free(version);
|
||||||
|
|
||||||
|
|
||||||
|
return json_object_new_string(full_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object * get_site_code(void) {
|
||||||
|
struct json_object *site = gluonutil_load_site_config();
|
||||||
|
if (!site)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct json_object *ret = NULL;
|
||||||
|
json_object_object_get_ex(site, "site_code", &ret);
|
||||||
|
if (ret)
|
||||||
|
json_object_get(ret);
|
||||||
|
|
||||||
|
json_object_put(site);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object * get_domain_code(void) {
|
||||||
|
return gluonutil_wrap_and_free_string(gluonutil_get_domain());
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object * get_hostname(void) {
|
||||||
|
struct json_object *ret = NULL;
|
||||||
|
|
||||||
|
struct uci_context *ctx = uci_alloc_context();
|
||||||
|
if (!ctx)
|
||||||
|
return NULL;
|
||||||
|
ctx->flags &= ~UCI_FLAG_STRICT;
|
||||||
|
|
||||||
|
char section[] = "system.@system[0]";
|
||||||
|
struct uci_ptr ptr;
|
||||||
|
if (uci_lookup_ptr(ctx, &ptr, section, true))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
struct uci_section *s = ptr.s;
|
||||||
|
|
||||||
|
const char *hostname = uci_lookup_option_string(ctx, s, "pretty_hostname");
|
||||||
|
|
||||||
|
if (!hostname)
|
||||||
|
hostname = uci_lookup_option_string(ctx, s, "hostname");
|
||||||
|
|
||||||
|
ret = gluonutil_wrap_string(hostname);
|
||||||
|
|
||||||
|
error:
|
||||||
|
uci_free_context(ctx);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct json_object * respondd_provider_nodeinfo(void) {
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_add(ret, "node_id", gluonutil_wrap_and_free_string(gluonutil_get_node_id()));
|
||||||
|
json_object_object_add(ret, "hostname", get_hostname());
|
||||||
|
|
||||||
|
struct json_object *hardware = json_object_new_object();
|
||||||
|
|
||||||
|
const char *model = platforminfo_get_model();
|
||||||
|
if (model)
|
||||||
|
json_object_object_add(hardware, "model", json_object_new_string(model));
|
||||||
|
|
||||||
|
json_object_object_add(hardware, "nproc", json_object_new_int(sysconf(_SC_NPROCESSORS_ONLN)));
|
||||||
|
json_object_object_add(ret, "hardware", hardware);
|
||||||
|
|
||||||
|
struct json_object *network = json_object_new_object();
|
||||||
|
json_object_object_add(network, "mac", gluonutil_wrap_and_free_string(gluonutil_get_sysconfig("primary_mac")));
|
||||||
|
json_object_object_add(ret, "network", network);
|
||||||
|
|
||||||
|
struct json_object *software = json_object_new_object();
|
||||||
|
struct json_object *software_firmware = json_object_new_object();
|
||||||
|
json_object_object_add(software_firmware, "base", gluon_version());
|
||||||
|
json_object_object_add(software_firmware, "release", gluonutil_wrap_and_free_string(gluonutil_read_line("/lib/gluon/release")));
|
||||||
|
json_object_object_add(software, "firmware", software_firmware);
|
||||||
|
json_object_object_add(ret, "software", software);
|
||||||
|
|
||||||
|
struct json_object *system = json_object_new_object();
|
||||||
|
json_object_object_add(system, "site_code", get_site_code());
|
||||||
|
if (gluonutil_has_domains())
|
||||||
|
json_object_object_add(system, "domain_code", get_domain_code());
|
||||||
|
json_object_object_add(ret, "system", system);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
309
package/gluon-respondd/src/respondd-statistics.c
Normal file
309
package/gluon-respondd/src/respondd-statistics.c
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "respondd-common.h"
|
||||||
|
|
||||||
|
#include <libgluonutil.h>
|
||||||
|
|
||||||
|
#include <iwinfo.h>
|
||||||
|
#include <json-c/json.h>
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <sys/vfs.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void add_uptime(struct json_object *obj) {
|
||||||
|
FILE *f = fopen("/proc/uptime", "r");
|
||||||
|
struct json_object* jso;
|
||||||
|
if (!f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
double uptime, idletime;
|
||||||
|
if (fscanf(f, "%lf %lf", &uptime, &idletime) == 2) {
|
||||||
|
jso = json_object_new_double(uptime);
|
||||||
|
json_object_set_serializer(jso, json_object_double_to_json_string, "%.2f", NULL);
|
||||||
|
json_object_object_add(obj, "uptime", jso);
|
||||||
|
jso = json_object_new_double(idletime);
|
||||||
|
json_object_set_serializer(jso, json_object_double_to_json_string, "%.2f", NULL);
|
||||||
|
json_object_object_add(obj, "idletime", jso);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_loadavg(struct json_object *obj) {
|
||||||
|
FILE *f = fopen("/proc/loadavg", "r");
|
||||||
|
if (!f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
double loadavg;
|
||||||
|
unsigned proc_running, proc_total;
|
||||||
|
if (fscanf(f, "%lf %*f %*f %u/%u", &loadavg, &proc_running, &proc_total) == 3) {
|
||||||
|
struct json_object *jso = json_object_new_double(loadavg);
|
||||||
|
json_object_set_serializer(jso, json_object_double_to_json_string, "%.2f", NULL);
|
||||||
|
json_object_object_add(obj, "loadavg", jso);
|
||||||
|
|
||||||
|
struct json_object *processes = json_object_new_object();
|
||||||
|
json_object_object_add(processes, "running", json_object_new_int(proc_running));
|
||||||
|
json_object_object_add(processes, "total", json_object_new_int(proc_total));
|
||||||
|
json_object_object_add(obj, "processes", processes);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object * get_memory(void) {
|
||||||
|
FILE *f = fopen("/proc/meminfo", "r");
|
||||||
|
if (!f)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
while (getline(&line, &len, f) >= 0) {
|
||||||
|
char label[32];
|
||||||
|
unsigned value;
|
||||||
|
|
||||||
|
if (sscanf(line, "%31[^:]: %u", label, &value) != 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strcmp(label, "MemTotal"))
|
||||||
|
json_object_object_add(ret, "total", json_object_new_int(value));
|
||||||
|
else if (!strcmp(label, "MemFree"))
|
||||||
|
json_object_object_add(ret, "free", json_object_new_int(value));
|
||||||
|
else if (!strcmp(label, "MemAvailable"))
|
||||||
|
json_object_object_add(ret, "available", json_object_new_int(value));
|
||||||
|
else if (!strcmp(label, "Buffers"))
|
||||||
|
json_object_object_add(ret, "buffers", json_object_new_int(value));
|
||||||
|
else if (!strcmp(label, "Cached"))
|
||||||
|
json_object_object_add(ret, "cached", json_object_new_int(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
free(line);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object * get_stat(void) {
|
||||||
|
FILE *f = fopen("/proc/stat", "r");
|
||||||
|
if (!f)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct json_object *stat = json_object_new_object();
|
||||||
|
struct json_object *ret = NULL;
|
||||||
|
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
while (getline(&line, &len, f) >= 0) {
|
||||||
|
char label[32];
|
||||||
|
|
||||||
|
if (sscanf(line, "%31s", label) != 1){
|
||||||
|
goto invalid_stat_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(label, "cpu")) {
|
||||||
|
int64_t user, nice, system, idle, iowait, irq, softirq;
|
||||||
|
if (sscanf(line, "%*s %"SCNd64" %"SCNd64" %"SCNd64" %"SCNd64" %"SCNd64" %"SCNd64" %"SCNd64,
|
||||||
|
&user, &nice, &system, &idle, &iowait, &irq, &softirq) != 7)
|
||||||
|
goto invalid_stat_format;
|
||||||
|
|
||||||
|
struct json_object *cpu = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_add(cpu, "user", json_object_new_int64(user));
|
||||||
|
json_object_object_add(cpu, "nice", json_object_new_int64(nice));
|
||||||
|
json_object_object_add(cpu, "system", json_object_new_int64(system));
|
||||||
|
json_object_object_add(cpu, "idle", json_object_new_int64(idle));
|
||||||
|
json_object_object_add(cpu, "iowait", json_object_new_int64(iowait));
|
||||||
|
json_object_object_add(cpu, "irq", json_object_new_int64(irq));
|
||||||
|
json_object_object_add(cpu, "softirq", json_object_new_int64(softirq));
|
||||||
|
|
||||||
|
json_object_object_add(stat, "cpu", cpu);
|
||||||
|
} else if (!strcmp(label, "ctxt")) {
|
||||||
|
int64_t ctxt;
|
||||||
|
if (sscanf(line, "%*s %"SCNd64, &ctxt) != 1)
|
||||||
|
goto invalid_stat_format;
|
||||||
|
|
||||||
|
json_object_object_add(stat, "ctxt", json_object_new_int64(ctxt));
|
||||||
|
} else if (!strcmp(label, "intr")) {
|
||||||
|
int64_t total_intr;
|
||||||
|
if (sscanf(line, "%*s %"SCNd64, &total_intr) != 1)
|
||||||
|
goto invalid_stat_format;
|
||||||
|
|
||||||
|
json_object_object_add(stat, "intr", json_object_new_int64(total_intr));
|
||||||
|
} else if (!strcmp(label, "softirq")) {
|
||||||
|
int64_t total_softirq;
|
||||||
|
if (sscanf(line, "%*s %"SCNd64, &total_softirq) != 1)
|
||||||
|
goto invalid_stat_format;
|
||||||
|
|
||||||
|
json_object_object_add(stat, "softirq", json_object_new_int64(total_softirq));
|
||||||
|
} else if (!strcmp(label, "processes")) {
|
||||||
|
int64_t processes;
|
||||||
|
if (sscanf(line, "%*s %"SCNd64, &processes) != 1)
|
||||||
|
goto invalid_stat_format;
|
||||||
|
|
||||||
|
json_object_object_add(stat, "processes", json_object_new_int64(processes));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = stat;
|
||||||
|
|
||||||
|
invalid_stat_format:
|
||||||
|
if (!ret)
|
||||||
|
json_object_put(stat);
|
||||||
|
|
||||||
|
free(line);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct json_object * get_rootfs_usage(void) {
|
||||||
|
struct statfs s;
|
||||||
|
if (statfs("/", &s))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct json_object *jso = json_object_new_double(1 - (double)s.f_bfree / s.f_blocks);
|
||||||
|
json_object_set_serializer(jso, json_object_double_to_json_string, "%.4f", NULL);
|
||||||
|
return jso;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object * get_time(void) {
|
||||||
|
struct timespec now;
|
||||||
|
|
||||||
|
if (clock_gettime(CLOCK_REALTIME, &now) != 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return json_object_new_int64(now.tv_sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void count_iface_stations(size_t *wifi24, size_t *wifi5, const char *ifname) {
|
||||||
|
const struct iwinfo_ops *iw = iwinfo_backend(ifname);
|
||||||
|
if (!iw)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int freq;
|
||||||
|
if (iw->frequency(ifname, &freq) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t *wifi;
|
||||||
|
if (freq >= 2400 && freq < 2500)
|
||||||
|
wifi = wifi24;
|
||||||
|
else if (freq >= 5000 && freq < 6000)
|
||||||
|
wifi = wifi5;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
int len;
|
||||||
|
char buf[IWINFO_BUFSIZE];
|
||||||
|
if (iw->assoclist(ifname, buf, &len) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct iwinfo_assoclist_entry *entry;
|
||||||
|
for (entry = (struct iwinfo_assoclist_entry *)buf; (char*)(entry+1) <= buf + len; entry++) {
|
||||||
|
if (entry->inactive > MAX_INACTIVITY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
(*wifi)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void count_stations(size_t *wifi24, size_t *wifi5) {
|
||||||
|
struct uci_context *ctx = uci_alloc_context();
|
||||||
|
if (!ctx)
|
||||||
|
return;
|
||||||
|
ctx->flags &= ~UCI_FLAG_STRICT;
|
||||||
|
|
||||||
|
|
||||||
|
struct uci_package *p;
|
||||||
|
if (uci_load(ctx, "wireless", &p))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
|
||||||
|
struct uci_element *e;
|
||||||
|
uci_foreach_element(&p->sections, e) {
|
||||||
|
struct uci_section *s = uci_to_section(e);
|
||||||
|
if (strcmp(s->type, "wifi-iface"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const char *network = uci_lookup_option_string(ctx, s, "network");
|
||||||
|
if (!network || strcmp(network, "client"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const char *mode = uci_lookup_option_string(ctx, s, "mode");
|
||||||
|
if (!mode || strcmp(mode, "ap"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const char *ifname = uci_lookup_option_string(ctx, s, "ifname");
|
||||||
|
if (!ifname)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
count_iface_stations(wifi24, wifi5, ifname);
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
uci_free_context(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct json_object * get_clients(void) {
|
||||||
|
size_t wifi24 = 0, wifi5 = 0;
|
||||||
|
|
||||||
|
count_stations(&wifi24, &wifi5);
|
||||||
|
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_add(ret, "wifi", json_object_new_int(wifi24 + wifi5));
|
||||||
|
json_object_object_add(ret, "wifi24", json_object_new_int(wifi24));
|
||||||
|
json_object_object_add(ret, "wifi5", json_object_new_int(wifi5));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct json_object * respondd_provider_statistics(void) {
|
||||||
|
struct json_object *ret = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_add(ret, "node_id", gluonutil_wrap_and_free_string(gluonutil_get_node_id()));
|
||||||
|
|
||||||
|
json_object_object_add(ret, "time", get_time());
|
||||||
|
json_object_object_add(ret, "rootfs_usage", get_rootfs_usage());
|
||||||
|
json_object_object_add(ret, "memory", get_memory());
|
||||||
|
json_object_object_add(ret, "stat", get_stat());
|
||||||
|
|
||||||
|
json_object_object_add(ret, "clients", get_clients());
|
||||||
|
|
||||||
|
add_uptime(ret);
|
||||||
|
add_loadavg(ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2016, Matthias Schiffer <mschiffer@universe-factory.net>
|
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@ -23,316 +23,12 @@
|
|||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "respondd-common.h"
|
||||||
|
|
||||||
#include <respondd.h>
|
#include <respondd.h>
|
||||||
|
|
||||||
#include <json-c/json.h>
|
|
||||||
#include <libgluonutil.h>
|
|
||||||
#include <libplatforminfo.h>
|
|
||||||
#include <uci.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#include <sys/vfs.h>
|
|
||||||
|
|
||||||
|
|
||||||
static struct json_object * gluon_version(void) {
|
|
||||||
char *version = gluonutil_read_line("/lib/gluon/gluon-version");
|
|
||||||
if (!version)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
char full_version[6 + strlen(version) + 1];
|
|
||||||
snprintf(full_version, sizeof(full_version), "gluon-%s", version);
|
|
||||||
|
|
||||||
free(version);
|
|
||||||
|
|
||||||
|
|
||||||
return json_object_new_string(full_version);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_site_code(void) {
|
|
||||||
struct json_object *site = gluonutil_load_site_config();
|
|
||||||
if (!site)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
struct json_object *ret = NULL;
|
|
||||||
json_object_object_get_ex(site, "site_code", &ret);
|
|
||||||
if (ret)
|
|
||||||
json_object_get(ret);
|
|
||||||
|
|
||||||
json_object_put(site);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_domain_code(void) {
|
|
||||||
return gluonutil_wrap_and_free_string(gluonutil_get_domain());
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_hostname(void) {
|
|
||||||
struct json_object *ret = NULL;
|
|
||||||
|
|
||||||
struct uci_context *ctx = uci_alloc_context();
|
|
||||||
if (!ctx)
|
|
||||||
return NULL;
|
|
||||||
ctx->flags &= ~UCI_FLAG_STRICT;
|
|
||||||
|
|
||||||
char section[] = "system.@system[0]";
|
|
||||||
struct uci_ptr ptr;
|
|
||||||
if (uci_lookup_ptr(ctx, &ptr, section, true))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
struct uci_section *s = ptr.s;
|
|
||||||
|
|
||||||
const char *hostname = uci_lookup_option_string(ctx, s, "pretty_hostname");
|
|
||||||
|
|
||||||
if (!hostname)
|
|
||||||
hostname = uci_lookup_option_string(ctx, s, "hostname");
|
|
||||||
|
|
||||||
ret = gluonutil_wrap_string(hostname);
|
|
||||||
|
|
||||||
error:
|
|
||||||
uci_free_context(ctx);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * respondd_provider_nodeinfo(void) {
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
|
|
||||||
json_object_object_add(ret, "node_id", gluonutil_wrap_and_free_string(gluonutil_get_node_id()));
|
|
||||||
json_object_object_add(ret, "hostname", get_hostname());
|
|
||||||
|
|
||||||
struct json_object *hardware = json_object_new_object();
|
|
||||||
|
|
||||||
const char *model = platforminfo_get_model();
|
|
||||||
if (model)
|
|
||||||
json_object_object_add(hardware, "model", json_object_new_string(model));
|
|
||||||
|
|
||||||
json_object_object_add(hardware, "nproc", json_object_new_int(sysconf(_SC_NPROCESSORS_ONLN)));
|
|
||||||
json_object_object_add(ret, "hardware", hardware);
|
|
||||||
|
|
||||||
struct json_object *network = json_object_new_object();
|
|
||||||
json_object_object_add(network, "mac", gluonutil_wrap_and_free_string(gluonutil_get_sysconfig("primary_mac")));
|
|
||||||
json_object_object_add(ret, "network", network);
|
|
||||||
|
|
||||||
struct json_object *software = json_object_new_object();
|
|
||||||
struct json_object *software_firmware = json_object_new_object();
|
|
||||||
json_object_object_add(software_firmware, "base", gluon_version());
|
|
||||||
json_object_object_add(software_firmware, "release", gluonutil_wrap_and_free_string(gluonutil_read_line("/lib/gluon/release")));
|
|
||||||
json_object_object_add(software, "firmware", software_firmware);
|
|
||||||
json_object_object_add(ret, "software", software);
|
|
||||||
|
|
||||||
struct json_object *system = json_object_new_object();
|
|
||||||
json_object_object_add(system, "site_code", get_site_code());
|
|
||||||
if (gluonutil_has_domains())
|
|
||||||
json_object_object_add(system, "domain_code", get_domain_code());
|
|
||||||
json_object_object_add(ret, "system", system);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void add_uptime(struct json_object *obj) {
|
|
||||||
FILE *f = fopen("/proc/uptime", "r");
|
|
||||||
struct json_object* jso;
|
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
double uptime, idletime;
|
|
||||||
if (fscanf(f, "%lf %lf", &uptime, &idletime) == 2) {
|
|
||||||
jso = json_object_new_double(uptime);
|
|
||||||
json_object_set_serializer(jso, json_object_double_to_json_string, "%.2f", NULL);
|
|
||||||
json_object_object_add(obj, "uptime", jso);
|
|
||||||
jso = json_object_new_double(idletime);
|
|
||||||
json_object_set_serializer(jso, json_object_double_to_json_string, "%.2f", NULL);
|
|
||||||
json_object_object_add(obj, "idletime", jso);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_loadavg(struct json_object *obj) {
|
|
||||||
FILE *f = fopen("/proc/loadavg", "r");
|
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
double loadavg;
|
|
||||||
unsigned proc_running, proc_total;
|
|
||||||
if (fscanf(f, "%lf %*f %*f %u/%u", &loadavg, &proc_running, &proc_total) == 3) {
|
|
||||||
struct json_object *jso = json_object_new_double(loadavg);
|
|
||||||
json_object_set_serializer(jso, json_object_double_to_json_string, "%.2f", NULL);
|
|
||||||
json_object_object_add(obj, "loadavg", jso);
|
|
||||||
|
|
||||||
struct json_object *processes = json_object_new_object();
|
|
||||||
json_object_object_add(processes, "running", json_object_new_int(proc_running));
|
|
||||||
json_object_object_add(processes, "total", json_object_new_int(proc_total));
|
|
||||||
json_object_object_add(obj, "processes", processes);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_memory(void) {
|
|
||||||
FILE *f = fopen("/proc/meminfo", "r");
|
|
||||||
if (!f)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
|
|
||||||
char *line = NULL;
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
while (getline(&line, &len, f) >= 0) {
|
|
||||||
char label[32];
|
|
||||||
unsigned value;
|
|
||||||
|
|
||||||
if (sscanf(line, "%31[^:]: %u", label, &value) != 2)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!strcmp(label, "MemTotal"))
|
|
||||||
json_object_object_add(ret, "total", json_object_new_int(value));
|
|
||||||
else if (!strcmp(label, "MemFree"))
|
|
||||||
json_object_object_add(ret, "free", json_object_new_int(value));
|
|
||||||
else if (!strcmp(label, "MemAvailable"))
|
|
||||||
json_object_object_add(ret, "available", json_object_new_int(value));
|
|
||||||
else if (!strcmp(label, "Buffers"))
|
|
||||||
json_object_object_add(ret, "buffers", json_object_new_int(value));
|
|
||||||
else if (!strcmp(label, "Cached"))
|
|
||||||
json_object_object_add(ret, "cached", json_object_new_int(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
free(line);
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_stat(void) {
|
|
||||||
FILE *f = fopen("/proc/stat", "r");
|
|
||||||
if (!f)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
struct json_object *stat = json_object_new_object();
|
|
||||||
struct json_object *ret = NULL;
|
|
||||||
|
|
||||||
char *line = NULL;
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
while (getline(&line, &len, f) >= 0) {
|
|
||||||
char label[32];
|
|
||||||
|
|
||||||
if (sscanf(line, "%31s", label) != 1){
|
|
||||||
goto invalid_stat_format;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(label, "cpu")) {
|
|
||||||
unsigned long long user, nice, system, idle, iowait, irq, softirq;
|
|
||||||
if (sscanf(line, "%*s %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64,
|
|
||||||
&user, &nice, &system, &idle, &iowait, &irq, &softirq) != 7)
|
|
||||||
goto invalid_stat_format;
|
|
||||||
|
|
||||||
struct json_object *cpu = json_object_new_object();
|
|
||||||
|
|
||||||
json_object_object_add(cpu, "user", json_object_new_int64(user));
|
|
||||||
json_object_object_add(cpu, "nice", json_object_new_int64(nice));
|
|
||||||
json_object_object_add(cpu, "system", json_object_new_int64(system));
|
|
||||||
json_object_object_add(cpu, "idle", json_object_new_int64(idle));
|
|
||||||
json_object_object_add(cpu, "iowait", json_object_new_int64(iowait));
|
|
||||||
json_object_object_add(cpu, "irq", json_object_new_int64(irq));
|
|
||||||
json_object_object_add(cpu, "softirq", json_object_new_int64(softirq));
|
|
||||||
|
|
||||||
json_object_object_add(stat, "cpu", cpu);
|
|
||||||
} else if (!strcmp(label, "ctxt")) {
|
|
||||||
unsigned long long ctxt;
|
|
||||||
if (sscanf(line, "%*s %"SCNu64, &ctxt) != 1)
|
|
||||||
goto invalid_stat_format;
|
|
||||||
|
|
||||||
json_object_object_add(stat, "ctxt", json_object_new_int64(ctxt));
|
|
||||||
} else if (!strcmp(label, "intr")) {
|
|
||||||
unsigned long long total_intr;
|
|
||||||
if (sscanf(line, "%*s %"SCNu64, &total_intr) != 1)
|
|
||||||
goto invalid_stat_format;
|
|
||||||
|
|
||||||
json_object_object_add(stat, "intr", json_object_new_int64(total_intr));
|
|
||||||
} else if (!strcmp(label, "softirq")) {
|
|
||||||
unsigned long long total_softirq;
|
|
||||||
if (sscanf(line, "%*s %"SCNu64, &total_softirq) != 1)
|
|
||||||
goto invalid_stat_format;
|
|
||||||
|
|
||||||
json_object_object_add(stat, "softirq", json_object_new_int64(total_softirq));
|
|
||||||
} else if (!strcmp(label, "processes")) {
|
|
||||||
unsigned long long processes;
|
|
||||||
if (sscanf(line, "%*s %"SCNu64, &processes) != 1)
|
|
||||||
goto invalid_stat_format;
|
|
||||||
|
|
||||||
json_object_object_add(stat, "processes", json_object_new_int64(processes));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = stat;
|
|
||||||
|
|
||||||
invalid_stat_format:
|
|
||||||
if (!ret)
|
|
||||||
json_object_put(stat);
|
|
||||||
|
|
||||||
free(line);
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct json_object * get_rootfs_usage(void) {
|
|
||||||
struct statfs s;
|
|
||||||
if (statfs("/", &s))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
struct json_object *jso = json_object_new_double(1 - (double)s.f_bfree / s.f_blocks);
|
|
||||||
json_object_set_serializer(jso, json_object_double_to_json_string, "%.4f", NULL);
|
|
||||||
return jso;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * get_time(void) {
|
|
||||||
struct timespec now;
|
|
||||||
|
|
||||||
if (clock_gettime(CLOCK_REALTIME, &now) != 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return json_object_new_int64(now.tv_sec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct json_object * respondd_provider_statistics(void) {
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
|
|
||||||
json_object_object_add(ret, "node_id", gluonutil_wrap_and_free_string(gluonutil_get_node_id()));
|
|
||||||
|
|
||||||
json_object *time = get_time();
|
|
||||||
if (time != NULL)
|
|
||||||
json_object_object_add(ret, "time", time);
|
|
||||||
|
|
||||||
json_object_object_add(ret, "rootfs_usage", get_rootfs_usage());
|
|
||||||
json_object_object_add(ret, "memory", get_memory());
|
|
||||||
json_object_object_add(ret, "stat", get_stat());
|
|
||||||
|
|
||||||
add_uptime(ret);
|
|
||||||
add_loadavg(ret);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct json_object * respondd_provider_neighbours(void) {
|
|
||||||
struct json_object *ret = json_object_new_object();
|
|
||||||
json_object_object_add(ret, "node_id", gluonutil_wrap_and_free_string(gluonutil_get_node_id()));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__ ((visibility ("default")))
|
||||||
const struct respondd_provider_info respondd_providers[] = {
|
const struct respondd_provider_info respondd_providers[] = {
|
||||||
{"nodeinfo", respondd_provider_nodeinfo},
|
{"nodeinfo", respondd_provider_nodeinfo},
|
||||||
{"statistics", respondd_provider_statistics},
|
{"statistics", respondd_provider_statistics},
|
||||||
|
@ -12,7 +12,7 @@ wait_setup_mode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if [ "$BUTTON" = wps -o "$BUTTON" = reset -o "$BUTTON" = phone ]; then
|
if [ "$BUTTON" = wps ] || [ "$BUTTON" = reset ] || [ "$BUTTON" = phone ]; then
|
||||||
case "$ACTION" in
|
case "$ACTION" in
|
||||||
pressed)
|
pressed)
|
||||||
wait_setup_mode &
|
wait_setup_mode &
|
||||||
@ -21,7 +21,7 @@ if [ "$BUTTON" = wps -o "$BUTTON" = reset -o "$BUTTON" = phone ]; then
|
|||||||
;;
|
;;
|
||||||
released)
|
released)
|
||||||
if [ -r /tmp/.wait_setup_mode ]; then
|
if [ -r /tmp/.wait_setup_mode ]; then
|
||||||
kill $(cat /tmp/.wait_setup_mode)
|
kill "$(cat /tmp/.wait_setup_mode)"
|
||||||
rm /tmp/.wait_setup_mode
|
rm /tmp/.wait_setup_mode
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
@ -5,7 +5,7 @@ setup_mode_enable() {
|
|||||||
local enabled="$(uci -q get 'gluon-setup-mode.@setup_mode[0].enabled')"
|
local enabled="$(uci -q get 'gluon-setup-mode.@setup_mode[0].enabled')"
|
||||||
local configured="$(uci -q get 'gluon-setup-mode.@setup_mode[0].configured')"
|
local configured="$(uci -q get 'gluon-setup-mode.@setup_mode[0].configured')"
|
||||||
|
|
||||||
if [ "$enabled" = 1 -o "$configured" != 1 ]; then
|
if [ "$enabled" = 1 ] || [ "$configured" != 1 ]; then
|
||||||
echo '/lib/gluon/setup-mode/rc.d' > /tmp/rc_d_path
|
echo '/lib/gluon/setup-mode/rc.d' > /tmp/rc_d_path
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ PKG_VERSION:=$(if $(DUMP),x,$(GLUON_SITE_VERSION))
|
|||||||
|
|
||||||
PKG_CONFIG_DEPENDS := CONFIG_GLUON_RELEASE CONFIG_GLUON_SITEDIR CONFIG_GLUON_MULTIDOMAIN
|
PKG_CONFIG_DEPENDS := CONFIG_GLUON_RELEASE CONFIG_GLUON_SITEDIR CONFIG_GLUON_MULTIDOMAIN
|
||||||
PKG_FILE_DEPENDS := $(GLUON_SITEDIR)/site.conf $(GLUON_SITEDIR)/domains/ $(GLUON_SITEDIR)/i18n/
|
PKG_FILE_DEPENDS := $(GLUON_SITEDIR)/site.conf $(GLUON_SITEDIR)/domains/ $(GLUON_SITEDIR)/i18n/
|
||||||
PKG_BUILD_DEPENDS := lua-cjson/host
|
PKG_BUILD_DEPENDS := lua-cjson/host gluon-web/host
|
||||||
|
|
||||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@
|
|||||||
<tr><th><%:Load average%></th><td><%= statistics('loadavg', 'decimal') %></td></tr>
|
<tr><th><%:Load average%></th><td><%= statistics('loadavg', 'decimal') %></td></tr>
|
||||||
<tr><th><%:RAM%></th><td><%= statistics('memory', 'memory') %></td></tr>
|
<tr><th><%:RAM%></th><td><%= statistics('memory', 'memory') %></td></tr>
|
||||||
<tr><th><%:Filesystem%></th><td><%= statistics('rootfs_usage', 'percent') %></td></tr>
|
<tr><th><%:Filesystem%></th><td><%= statistics('rootfs_usage', 'percent') %></td></tr>
|
||||||
<tr><th><%:Gateway%></th><td><%= statistics('gateway') %></td></tr>
|
<tr><th><%:Gateway%></th><td><%= statistics('gateway') %><br /><%= statistics('gateway_nexthop', 'neighbour') %></td></tr>
|
||||||
<tr><th><%:Clients%></th><td><%= statistics('clients/total') %></td></tr>
|
<tr><th><%:Clients%></th><td><%= statistics('clients/total') %></td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -55,6 +55,9 @@ msgstr "Weitergeleitet"
|
|||||||
msgid "Gateway"
|
msgid "Gateway"
|
||||||
msgstr "Gateway"
|
msgstr "Gateway"
|
||||||
|
|
||||||
|
msgid "Gateway Nexthop"
|
||||||
|
msgstr "Gateway Nexthop"
|
||||||
|
|
||||||
msgid "IP address"
|
msgid "IP address"
|
||||||
msgstr "IP-Adresse"
|
msgstr "IP-Adresse"
|
||||||
|
|
||||||
|
@ -46,6 +46,9 @@ msgstr ""
|
|||||||
msgid "Gateway"
|
msgid "Gateway"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Gateway Nexthop"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "IP address"
|
msgid "IP address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -112,6 +112,20 @@
|
|||||||
'bytes': function(bytes) {
|
'bytes': function(bytes) {
|
||||||
return prettyBytes(bytes);
|
return prettyBytes(bytes);
|
||||||
},
|
},
|
||||||
|
'neighbour': function(addr) {
|
||||||
|
if (!addr)
|
||||||
|
return '';
|
||||||
|
|
||||||
|
for (var i in interfaces) {
|
||||||
|
var iface = interfaces[i];
|
||||||
|
var neigh = iface.lookup_neigh(addr);
|
||||||
|
if (!neigh)
|
||||||
|
continue;
|
||||||
|
return 'via ' + neigh.get_hostname() + ' (' + i + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'via ' + addr + ' (unknown iface)';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -582,6 +596,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
'get_hostname': function() {
|
||||||
|
return hostname.textContent;
|
||||||
|
},
|
||||||
'update_nodeinfo': function(nodeinfo) {
|
'update_nodeinfo': function(nodeinfo) {
|
||||||
var addr = choose_address(nodeinfo.network.addresses);
|
var addr = choose_address(nodeinfo.network.addresses);
|
||||||
if (addr) {
|
if (addr) {
|
||||||
@ -711,6 +728,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function lookup_neigh(addr) {
|
||||||
|
return neighs[addr];
|
||||||
|
}
|
||||||
|
|
||||||
function get_neigh(addr) {
|
function get_neigh(addr) {
|
||||||
var neigh = neighs[addr];
|
var neigh = neighs[addr];
|
||||||
@ -738,6 +758,7 @@
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
'get_neigh': get_neigh,
|
'get_neigh': get_neigh,
|
||||||
|
'lookup_neigh': lookup_neigh
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ PKG_VERSION:=1
|
|||||||
PKG_INSTALL:=1
|
PKG_INSTALL:=1
|
||||||
|
|
||||||
include ../gluon.mk
|
include ../gluon.mk
|
||||||
|
include $(INCLUDE_DIR)/host-build.mk
|
||||||
|
|
||||||
define Package/gluon-web
|
define Package/gluon-web
|
||||||
TITLE:=Minimal Lua web framework derived from LuCI
|
TITLE:=Minimal Lua web framework derived from LuCI
|
||||||
@ -24,4 +25,18 @@ define Package/gluon-web/config
|
|||||||
$(foreach lang,$(GLUON_SUPPORTED_LANGS),$(call lang-config,$(lang)))
|
$(foreach lang,$(GLUON_SUPPORTED_LANGS),$(call lang-config,$(lang)))
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Host/Prepare
|
||||||
|
$(CP) ./src/* $(HOST_BUILD_DIR)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Host/Compile
|
||||||
|
$(call Host/Compile/Default,gluon-po2lmo)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Host/Install
|
||||||
|
$(INSTALL_DIR) $(1)/bin
|
||||||
|
$(INSTALL_BIN) $(HOST_BUILD_DIR)/gluon-po2lmo $(1)/bin/
|
||||||
|
endef
|
||||||
|
|
||||||
$(eval $(call BuildPackageGluon,gluon-web))
|
$(eval $(call BuildPackageGluon,gluon-web))
|
||||||
|
$(eval $(call HostBuild))
|
||||||
|
@ -9,6 +9,8 @@ clean:
|
|||||||
parser.so: template_parser.o template_utils.o template_lmo.o template_lualib.o
|
parser.so: template_parser.o template_utils.o template_lmo.o template_lualib.o
|
||||||
$(CC) $(LDFLAGS) -shared -o $@ $^
|
$(CC) $(LDFLAGS) -shared -o $@ $^
|
||||||
|
|
||||||
|
gluon-po2lmo: gluon-po2lmo.o template_lmo.o
|
||||||
|
|
||||||
compile: parser.so
|
compile: parser.so
|
||||||
|
|
||||||
install: compile
|
install: compile
|
||||||
|
256
package/gluon-web/src/gluon-po2lmo.c
Normal file
256
package/gluon-web/src/gluon-po2lmo.c
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
/*
|
||||||
|
* lmo - Lua Machine Objects - PO to LMO conversion tool
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009-2012 Jo-Philipp Wich <jow@openwrt.org>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "template_lmo.h"
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__((noreturn))
|
||||||
|
static void die(const char *msg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: %s\n", msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((noreturn))
|
||||||
|
static void usage(const char *name)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s input.po output.lmo\n", name);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print(const void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||||
|
{
|
||||||
|
if( fwrite(ptr, size, nmemb, stream) == 0 )
|
||||||
|
die("Failed to write stdout");
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t extract_string(const char *src, char *dest, size_t len)
|
||||||
|
{
|
||||||
|
size_t pos = 0;
|
||||||
|
int esc = 0;
|
||||||
|
int off = -1;
|
||||||
|
|
||||||
|
for( pos = 0; (pos < strlen(src)) && (pos < len); pos++ )
|
||||||
|
{
|
||||||
|
if( (off == -1) && (src[pos] == '"') )
|
||||||
|
{
|
||||||
|
off = pos + 1;
|
||||||
|
}
|
||||||
|
else if( off >= 0 )
|
||||||
|
{
|
||||||
|
if( esc == 1 )
|
||||||
|
{
|
||||||
|
switch (src[pos])
|
||||||
|
{
|
||||||
|
case '"':
|
||||||
|
case '\\':
|
||||||
|
off++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dest[pos-off] = src[pos];
|
||||||
|
esc = 0;
|
||||||
|
}
|
||||||
|
else if( src[pos] == '\\' )
|
||||||
|
{
|
||||||
|
dest[pos-off] = src[pos];
|
||||||
|
esc = 1;
|
||||||
|
}
|
||||||
|
else if( src[pos] != '"' )
|
||||||
|
{
|
||||||
|
dest[pos-off] = src[pos];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dest[pos-off] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (off > -1) ? (ssize_t) strlen(dest) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmp_index(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
uint32_t x = ((const lmo_entry_t *)a)->key_id;
|
||||||
|
uint32_t y = ((const lmo_entry_t *)b)->key_id;
|
||||||
|
|
||||||
|
if (x < y)
|
||||||
|
return -1;
|
||||||
|
else if (x > y)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_uint32(uint32_t x, FILE *out)
|
||||||
|
{
|
||||||
|
uint32_t y = htonl(x);
|
||||||
|
print(&y, sizeof(uint32_t), 1, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_index(void *array, int n, FILE *out)
|
||||||
|
{
|
||||||
|
lmo_entry_t *e;
|
||||||
|
|
||||||
|
qsort(array, n, sizeof(*e), cmp_index);
|
||||||
|
|
||||||
|
for (e = array; n > 0; n--, e++)
|
||||||
|
{
|
||||||
|
print_uint32(e->key_id, out);
|
||||||
|
print_uint32(e->val_id, out);
|
||||||
|
print_uint32(e->offset, out);
|
||||||
|
print_uint32(e->length, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char line[4096];
|
||||||
|
char key[4096];
|
||||||
|
char val[4096];
|
||||||
|
char tmp[4096];
|
||||||
|
int state = 0;
|
||||||
|
int offset = 0;
|
||||||
|
int length = 0;
|
||||||
|
int n_entries = 0;
|
||||||
|
void *array = NULL;
|
||||||
|
lmo_entry_t *entry = NULL;
|
||||||
|
uint32_t key_id, val_id;
|
||||||
|
|
||||||
|
FILE *in;
|
||||||
|
FILE *out;
|
||||||
|
|
||||||
|
if( (argc != 3) || ((in = fopen(argv[1], "r")) == NULL) || ((out = fopen(argv[2], "w")) == NULL) )
|
||||||
|
usage(argv[0]);
|
||||||
|
|
||||||
|
memset(line, 0, sizeof(key));
|
||||||
|
memset(key, 0, sizeof(val));
|
||||||
|
memset(val, 0, sizeof(val));
|
||||||
|
|
||||||
|
while( (NULL != fgets(line, sizeof(line), in)) || (state >= 2 && feof(in)) )
|
||||||
|
{
|
||||||
|
if( state == 0 && strstr(line, "msgid \"") == line )
|
||||||
|
{
|
||||||
|
switch(extract_string(line, key, sizeof(key)))
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
die("Syntax error in msgid");
|
||||||
|
case 0:
|
||||||
|
state = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( state == 1 || state == 2 )
|
||||||
|
{
|
||||||
|
if( strstr(line, "msgstr \"") == line || state == 2 )
|
||||||
|
{
|
||||||
|
switch(extract_string(line, val, sizeof(val)))
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
state = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(extract_string(line, tmp, sizeof(tmp)))
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
state = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
strcat(key, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( state == 3 )
|
||||||
|
{
|
||||||
|
switch(extract_string(line, tmp, sizeof(tmp)))
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
state = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
strcat(val, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( state == 4 )
|
||||||
|
{
|
||||||
|
if( strlen(key) > 0 && strlen(val) > 0 )
|
||||||
|
{
|
||||||
|
key_id = sfh_hash(key, strlen(key));
|
||||||
|
val_id = sfh_hash(val, strlen(val));
|
||||||
|
|
||||||
|
if( key_id != val_id )
|
||||||
|
{
|
||||||
|
n_entries++;
|
||||||
|
array = realloc(array, n_entries * sizeof(lmo_entry_t));
|
||||||
|
entry = (lmo_entry_t *)array + n_entries - 1;
|
||||||
|
|
||||||
|
if (!array)
|
||||||
|
die("Out of memory");
|
||||||
|
|
||||||
|
entry->key_id = key_id;
|
||||||
|
entry->val_id = val_id;
|
||||||
|
entry->offset = offset;
|
||||||
|
entry->length = strlen(val);
|
||||||
|
|
||||||
|
length = strlen(val) + ((4 - (strlen(val) % 4)) % 4);
|
||||||
|
|
||||||
|
print(val, length, 1, out);
|
||||||
|
offset += length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state = 0;
|
||||||
|
memset(key, 0, sizeof(key));
|
||||||
|
memset(val, 0, sizeof(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(line, 0, sizeof(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
print_index(array, n_entries, out);
|
||||||
|
|
||||||
|
if( offset > 0 )
|
||||||
|
{
|
||||||
|
print_uint32(offset, out);
|
||||||
|
fsync(fileno(out));
|
||||||
|
fclose(out);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fclose(out);
|
||||||
|
unlink(argv[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(in);
|
||||||
|
return(0);
|
||||||
|
}
|
@ -25,20 +25,11 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
struct lmo_entry {
|
|
||||||
uint32_t key_id;
|
|
||||||
uint32_t val_id;
|
|
||||||
uint32_t offset;
|
|
||||||
uint32_t length;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
|
|
||||||
static inline uint16_t get_le16(const void *data) {
|
static inline uint16_t get_le16(const void *data) {
|
||||||
const uint8_t *d = data;
|
const uint8_t *d = data;
|
||||||
return (((uint16_t)d[1]) << 8) | d[0];
|
return (((uint16_t)d[1]) << 8) | d[0];
|
||||||
@ -56,7 +47,7 @@ static inline uint32_t get_be32(const void *data) {
|
|||||||
* Hash function from http://www.azillionmonkeys.com/qed/hash.html
|
* Hash function from http://www.azillionmonkeys.com/qed/hash.html
|
||||||
* Copyright (C) 2004-2008 by Paul Hsieh
|
* Copyright (C) 2004-2008 by Paul Hsieh
|
||||||
*/
|
*/
|
||||||
static uint32_t sfh_hash(const void *input, size_t len)
|
uint32_t sfh_hash(const void *input, size_t len)
|
||||||
{
|
{
|
||||||
const uint8_t *data = input;
|
const uint8_t *data = input;
|
||||||
uint32_t hash = len, tmp;
|
uint32_t hash = len, tmp;
|
||||||
|
@ -22,8 +22,15 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct lmo_entry {
|
||||||
|
uint32_t key_id;
|
||||||
|
uint32_t val_id;
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t length;
|
||||||
|
} __attribute__((packed));
|
||||||
typedef struct lmo_entry lmo_entry_t;
|
typedef struct lmo_entry lmo_entry_t;
|
||||||
|
|
||||||
|
|
||||||
@ -37,6 +44,8 @@ struct lmo_catalog {
|
|||||||
typedef struct lmo_catalog lmo_catalog_t;
|
typedef struct lmo_catalog lmo_catalog_t;
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t sfh_hash(const void *input, size_t len);
|
||||||
|
|
||||||
bool lmo_load(lmo_catalog_t *cat, const char *file);
|
bool lmo_load(lmo_catalog_t *cat, const char *file);
|
||||||
void lmo_unload(lmo_catalog_t *cat);
|
void lmo_unload(lmo_catalog_t *cat);
|
||||||
bool lmo_translate(const lmo_catalog_t *cat, const char *key, size_t keylen, const char **out, size_t *outlen);
|
bool lmo_translate(const lmo_catalog_t *cat, const char *key, size_t keylen, const char **out, size_t *outlen);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
GLUON_MK := $(abspath $(lastword $(MAKEFILE_LIST)))
|
GLUON_MK := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||||
PKG_FILE_DEPENDS += $(GLUON_MK)
|
PKG_FILE_DEPENDS += $(GLUON_MK)
|
||||||
|
|
||||||
# Dependencies for LuaSrcDiet
|
PKG_BUILD_DEPENDS += luasrcdiet/host
|
||||||
PKG_BUILD_DEPENDS += luci-base/host
|
|
||||||
|
|
||||||
ifneq ($(wildcard ./src/respondd.c),)
|
ifneq ($(wildcard ./src/respondd.c),)
|
||||||
PKG_BUILD_DEPENDS += respondd
|
PKG_BUILD_DEPENDS += respondd
|
||||||
@ -31,6 +30,7 @@ GLUON_I18N_CONFIG := $(foreach lang,$(GLUON_SUPPORTED_LANGS),CONFIG_GLUON_WEB_LA
|
|||||||
GLUON_ENABLED_LANGS := en $(foreach lang,$(GLUON_SUPPORTED_LANGS),$(if $(CONFIG_GLUON_WEB_LANG_$(lang)),$(lang)))
|
GLUON_ENABLED_LANGS := en $(foreach lang,$(GLUON_SUPPORTED_LANGS),$(if $(CONFIG_GLUON_WEB_LANG_$(lang)),$(lang)))
|
||||||
|
|
||||||
ifneq ($(wildcard ./i18n/.),)
|
ifneq ($(wildcard ./i18n/.),)
|
||||||
|
PKG_BUILD_DEPENDS += gluon-web/host
|
||||||
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
|
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ define GluonBuildI18N
|
|||||||
for lang in $$(GLUON_ENABLED_LANGS); do \
|
for lang in $$(GLUON_ENABLED_LANGS); do \
|
||||||
if [ -e $(1)/$$$$lang.po ]; then \
|
if [ -e $(1)/$$$$lang.po ]; then \
|
||||||
rm -f $$(PKG_BUILD_DIR)/i18n/$$$$lang.lmo; \
|
rm -f $$(PKG_BUILD_DIR)/i18n/$$$$lang.lmo; \
|
||||||
po2lmo $(1)/$$$$lang.po $$(PKG_BUILD_DIR)/i18n/$$$$lang.lmo; \
|
gluon-po2lmo $(1)/$$$$lang.po $$(PKG_BUILD_DIR)/i18n/$$$$lang.lmo; \
|
||||||
fi; \
|
fi; \
|
||||||
done
|
done
|
||||||
endef
|
endef
|
||||||
|
@ -4,10 +4,10 @@ Subject: procd: add support for alternative rc.d directories
|
|||||||
|
|
||||||
diff --git a/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch b/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch
|
diff --git a/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch b/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..bc2434200364b46f1db4c2eec22c4e8b973844d5
|
index 0000000000000000000000000000000000000000..16d3179f05c64b7178f883745294c64a27127775
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch
|
+++ b/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch
|
||||||
@@ -0,0 +1,97 @@
|
@@ -0,0 +1,80 @@
|
||||||
+From 03a2bc70e4260ec9f669391c47b9a7a9ecd0b75d Mon Sep 17 00:00:00 2001
|
+From 03a2bc70e4260ec9f669391c47b9a7a9ecd0b75d Mon Sep 17 00:00:00 2001
|
||||||
+Message-Id: <03a2bc70e4260ec9f669391c47b9a7a9ecd0b75d.1407329621.git.mschiffer@universe-factory.net>
|
+Message-Id: <03a2bc70e4260ec9f669391c47b9a7a9ecd0b75d.1407329621.git.mschiffer@universe-factory.net>
|
||||||
+From: Matthias Schiffer <mschiffer@universe-factory.net>
|
+From: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
@ -19,21 +19,10 @@ index 0000000000000000000000000000000000000000..bc2434200364b46f1db4c2eec22c4e8b
|
|||||||
+ rcS.c | 2 +-
|
+ rcS.c | 2 +-
|
||||||
+ 2 files changed, 39 insertions(+), 1 deletion(-)
|
+ 2 files changed, 39 insertions(+), 1 deletion(-)
|
||||||
+
|
+
|
||||||
+diff --git a/initd/preinit.c b/initd/preinit.c
|
|
||||||
+index fb94527..8b832a7 100644
|
|
||||||
+--- a/initd/preinit.c
|
+--- a/initd/preinit.c
|
||||||
++++ b/initd/preinit.c
|
++++ b/initd/preinit.c
|
||||||
+@@ -12,6 +12,8 @@
|
+@@ -87,12 +87,42 @@ fail:
|
||||||
+ * GNU General Public License for more details.
|
+ free(command);
|
||||||
+ */
|
|
||||||
+
|
|
||||||
++#define _GNU_SOURCE
|
|
||||||
++
|
|
||||||
+ #include <sys/stat.h>
|
|
||||||
+ #include <sys/types.h>
|
|
||||||
+ #include <sys/mount.h>
|
|
||||||
+@@ -46,6 +48,35 @@ check_dbglvl(void)
|
|
||||||
+ debug = lvl;
|
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
++static char*
|
++static char*
|
||||||
@ -68,15 +57,14 @@ index 0000000000000000000000000000000000000000..bc2434200364b46f1db4c2eec22c4e8b
|
|||||||
+ static void
|
+ static void
|
||||||
+ spawn_procd(struct uloop_process *proc, int ret)
|
+ spawn_procd(struct uloop_process *proc, int ret)
|
||||||
+ {
|
+ {
|
||||||
+@@ -53,6 +84,7 @@ spawn_procd(struct uloop_process *proc, int ret)
|
+ char *wdt_fd = watchdog_fd();
|
||||||
+ char *argv[] = { "/sbin/procd", NULL};
|
+ char *argv[] = { "/sbin/procd", NULL};
|
||||||
+ struct stat s;
|
|
||||||
+ char dbg[2];
|
+ char dbg[2];
|
||||||
++ char *rc_d_path;
|
++ char *rc_d_path;
|
||||||
+
|
+
|
||||||
+ if (plugd_proc.pid > 0)
|
+ if (plugd_proc.pid > 0)
|
||||||
+ kill(plugd_proc.pid, SIGKILL);
|
+ kill(plugd_proc.pid, SIGKILL);
|
||||||
+@@ -72,6 +104,12 @@ spawn_procd(struct uloop_process *proc, int ret)
|
+@@ -112,6 +142,12 @@ spawn_procd(struct uloop_process *proc,
|
||||||
+ setenv("DBGLVL", dbg, 1);
|
+ setenv("DBGLVL", dbg, 1);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
@ -89,11 +77,9 @@ index 0000000000000000000000000000000000000000..bc2434200364b46f1db4c2eec22c4e8b
|
|||||||
+ execvp(argv[0], argv);
|
+ execvp(argv[0], argv);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+diff --git a/rcS.c b/rcS.c
|
|
||||||
+index 0e1b0ba..1b00831 100644
|
|
||||||
+--- a/rcS.c
|
+--- a/rcS.c
|
||||||
++++ b/rcS.c
|
++++ b/rcS.c
|
||||||
+@@ -150,7 +150,7 @@ int rcS(char *pattern, char *param, void (*q_empty)(struct runqueue *))
|
+@@ -184,7 +184,7 @@ int rcS(char *pattern, char *param, void
|
||||||
+ q.empty_cb = q_empty;
|
+ q.empty_cb = q_empty;
|
||||||
+ q.max_running_tasks = 1;
|
+ q.max_running_tasks = 1;
|
||||||
+
|
+
|
||||||
@ -102,6 +88,3 @@ index 0000000000000000000000000000000000000000..bc2434200364b46f1db4c2eec22c4e8b
|
|||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ int rc(const char *file, char *param)
|
+ int rc(const char *file, char *param)
|
||||||
+--
|
|
||||||
+2.0.4
|
|
||||||
+
|
|
||||||
|
@ -4,10 +4,10 @@ Subject: libjson-c: Add support for custom format strings for doubles
|
|||||||
|
|
||||||
diff --git a/package/libs/libjson-c/patches/002-custom-format-string.patch b/package/libs/libjson-c/patches/002-custom-format-string.patch
|
diff --git a/package/libs/libjson-c/patches/002-custom-format-string.patch b/package/libs/libjson-c/patches/002-custom-format-string.patch
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..2f454c560ff78c1edd4654b9651f0e6299bd5e6f
|
index 0000000000000000000000000000000000000000..b67433a7baf37654a17fa5036c4266b33bdda9f2
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/package/libs/libjson-c/patches/002-custom-format-string.patch
|
+++ b/package/libs/libjson-c/patches/002-custom-format-string.patch
|
||||||
@@ -0,0 +1,98 @@
|
@@ -0,0 +1,91 @@
|
||||||
+From 21dc5dc92bd56f5f4dc2c90b9ea6bf1e1407714e Mon Sep 17 00:00:00 2001
|
+From 21dc5dc92bd56f5f4dc2c90b9ea6bf1e1407714e Mon Sep 17 00:00:00 2001
|
||||||
+From: Jan-Philipp Litza <janphilipp@litza.de>
|
+From: Jan-Philipp Litza <janphilipp@litza.de>
|
||||||
+Date: Fri, 6 May 2016 16:12:44 +0200
|
+Date: Fri, 6 May 2016 16:12:44 +0200
|
||||||
@ -20,11 +20,9 @@ index 0000000000000000000000000000000000000000..2f454c560ff78c1edd4654b9651f0e62
|
|||||||
+ json_object.h | 28 ++++++++++++++++++++++++++++
|
+ json_object.h | 28 ++++++++++++++++++++++++++++
|
||||||
+ 2 files changed, 34 insertions(+), 6 deletions(-)
|
+ 2 files changed, 34 insertions(+), 6 deletions(-)
|
||||||
+
|
+
|
||||||
+diff --git a/json_object.c b/json_object.c
|
|
||||||
+index 7d60884..46701e7 100644
|
|
||||||
+--- a/json_object.c
|
+--- a/json_object.c
|
||||||
++++ b/json_object.c
|
++++ b/json_object.c
|
||||||
+@@ -55,7 +55,6 @@ static struct json_object* json_object_new(enum json_type o_type);
|
+@@ -55,7 +55,6 @@ static struct json_object* json_object_n
|
||||||
+ static json_object_to_json_string_fn json_object_object_to_json_string;
|
+ static json_object_to_json_string_fn json_object_object_to_json_string;
|
||||||
+ static json_object_to_json_string_fn json_object_boolean_to_json_string;
|
+ static json_object_to_json_string_fn json_object_boolean_to_json_string;
|
||||||
+ static json_object_to_json_string_fn json_object_int_to_json_string;
|
+ static json_object_to_json_string_fn json_object_int_to_json_string;
|
||||||
@ -32,7 +30,7 @@ index 0000000000000000000000000000000000000000..2f454c560ff78c1edd4654b9651f0e62
|
|||||||
+ static json_object_to_json_string_fn json_object_string_to_json_string;
|
+ static json_object_to_json_string_fn json_object_string_to_json_string;
|
||||||
+ static json_object_to_json_string_fn json_object_array_to_json_string;
|
+ static json_object_to_json_string_fn json_object_array_to_json_string;
|
||||||
+
|
+
|
||||||
+@@ -644,10 +643,10 @@ int64_t json_object_get_int64(const struct json_object *jso)
|
+@@ -560,10 +559,10 @@ int64_t json_object_get_int64(struct jso
|
||||||
+
|
+
|
||||||
+ /* json_object_double */
|
+ /* json_object_double */
|
||||||
+
|
+
|
||||||
@ -47,7 +45,7 @@ index 0000000000000000000000000000000000000000..2f454c560ff78c1edd4654b9651f0e62
|
|||||||
+ {
|
+ {
|
||||||
+ char buf[128], *p, *q;
|
+ char buf[128], *p, *q;
|
||||||
+ int size;
|
+ int size;
|
||||||
+@@ -663,7 +662,8 @@ static int json_object_double_to_json_string(struct json_object* jso,
|
+@@ -579,7 +578,8 @@ static int json_object_double_to_json_st
|
||||||
+ else
|
+ else
|
||||||
+ size = snprintf(buf, sizeof(buf), "-Infinity");
|
+ size = snprintf(buf, sizeof(buf), "-Infinity");
|
||||||
+ else
|
+ else
|
||||||
@ -57,11 +55,9 @@ index 0000000000000000000000000000000000000000..2f454c560ff78c1edd4654b9651f0e62
|
|||||||
+
|
+
|
||||||
+ p = strchr(buf, ',');
|
+ p = strchr(buf, ',');
|
||||||
+ if (p) {
|
+ if (p) {
|
||||||
+diff --git a/json_object.h b/json_object.h
|
|
||||||
+index 2bce454..a89de44 100644
|
|
||||||
+--- a/json_object.h
|
+--- a/json_object.h
|
||||||
++++ b/json_object.h
|
++++ b/json_object.h
|
||||||
+@@ -614,6 +614,9 @@ extern int64_t json_object_get_int64(const struct json_object *obj);
|
+@@ -515,6 +515,9 @@ extern int64_t json_object_get_int64(str
|
||||||
+ /* double type methods */
|
+ /* double type methods */
|
||||||
+
|
+
|
||||||
+ /** Create a new empty json_object of type json_type_double
|
+ /** Create a new empty json_object of type json_type_double
|
||||||
@ -71,7 +67,7 @@ index 0000000000000000000000000000000000000000..2f454c560ff78c1edd4654b9651f0e62
|
|||||||
+ * @param d the double
|
+ * @param d the double
|
||||||
+ * @returns a json_object of type json_type_double
|
+ * @returns a json_object of type json_type_double
|
||||||
+ */
|
+ */
|
||||||
+@@ -642,6 +645,31 @@ extern struct json_object* json_object_new_double(double d);
|
+@@ -543,6 +546,31 @@ extern struct json_object* json_object_n
|
||||||
+ */
|
+ */
|
||||||
+ extern struct json_object* json_object_new_double_s(double d, const char *ds);
|
+ extern struct json_object* json_object_new_double_s(double d, const char *ds);
|
||||||
+
|
+
|
||||||
@ -103,6 +99,3 @@ index 0000000000000000000000000000000000000000..2f454c560ff78c1edd4654b9651f0e62
|
|||||||
+ /** Get the double floating point value of a json_object
|
+ /** Get the double floating point value of a json_object
|
||||||
+ *
|
+ *
|
||||||
+ * The type is coerced to a double if the passed object is not a double.
|
+ * The type is coerced to a double if the passed object is not a double.
|
||||||
+--
|
|
||||||
+2.7.4
|
|
||||||
+
|
|
||||||
|
@ -6,10 +6,10 @@ Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
|||||||
|
|
||||||
diff --git a/target/linux/generic/backport-4.14/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch b/target/linux/generic/backport-4.14/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch
|
diff --git a/target/linux/generic/backport-4.14/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch b/target/linux/generic/backport-4.14/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..9e4d90fb3b8e2c91e4adf0e0efdb3f4575b5027d
|
index 0000000000000000000000000000000000000000..fe9c479338a7b597be649c761c70a63085b51c5f
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/target/linux/generic/backport-4.14/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch
|
+++ b/target/linux/generic/backport-4.14/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch
|
||||||
@@ -0,0 +1,141 @@
|
@@ -0,0 +1,134 @@
|
||||||
+From: Matthias Schiffer <mschiffer@universe-factory.net>
|
+From: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
+Date: Sat, 3 Mar 2018 11:55:21 +0100
|
+Date: Sat, 3 Mar 2018 11:55:21 +0100
|
||||||
+Subject: [PATCH 1/2] ebtables: add support for matching ICMP type and code
|
+Subject: [PATCH 1/2] ebtables: add support for matching ICMP type and code
|
||||||
@ -23,8 +23,6 @@ index 0000000000000000000000000000000000000000..9e4d90fb3b8e2c91e4adf0e0efdb3f45
|
|||||||
+ net/bridge/netfilter/ebt_ip.c | 43 +++++++++++++++++++++-------
|
+ net/bridge/netfilter/ebt_ip.c | 43 +++++++++++++++++++++-------
|
||||||
+ 2 files changed, 43 insertions(+), 13 deletions(-)
|
+ 2 files changed, 43 insertions(+), 13 deletions(-)
|
||||||
+
|
+
|
||||||
+diff --git a/include/uapi/linux/netfilter_bridge/ebt_ip.h b/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
|
||||||
+index 8e462fb1983f..4ed7fbb0a482 100644
|
|
||||||
+--- a/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
+--- a/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
||||||
++++ b/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
++++ b/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
||||||
+@@ -24,8 +24,9 @@
|
+@@ -24,8 +24,9 @@
|
||||||
@ -55,8 +53,6 @@ index 0000000000000000000000000000000000000000..9e4d90fb3b8e2c91e4adf0e0efdb3f45
|
|||||||
+ };
|
+ };
|
||||||
+
|
+
|
||||||
+ #endif
|
+ #endif
|
||||||
+diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c
|
|
||||||
+index 2b46c50abce0..8cb8f8395768 100644
|
|
||||||
+--- a/net/bridge/netfilter/ebt_ip.c
|
+--- a/net/bridge/netfilter/ebt_ip.c
|
||||||
++++ b/net/bridge/netfilter/ebt_ip.c
|
++++ b/net/bridge/netfilter/ebt_ip.c
|
||||||
+@@ -19,9 +19,15 @@
|
+@@ -19,9 +19,15 @@
|
||||||
@ -78,7 +74,7 @@ index 0000000000000000000000000000000000000000..9e4d90fb3b8e2c91e4adf0e0efdb3f45
|
|||||||
+ };
|
+ };
|
||||||
+
|
+
|
||||||
+ static bool
|
+ static bool
|
||||||
+@@ -30,8 +36,8 @@ ebt_ip_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
+@@ -30,8 +36,8 @@ ebt_ip_mt(const struct sk_buff *skb, str
|
||||||
+ const struct ebt_ip_info *info = par->matchinfo;
|
+ const struct ebt_ip_info *info = par->matchinfo;
|
||||||
+ const struct iphdr *ih;
|
+ const struct iphdr *ih;
|
||||||
+ struct iphdr _iph;
|
+ struct iphdr _iph;
|
||||||
@ -89,7 +85,7 @@ index 0000000000000000000000000000000000000000..9e4d90fb3b8e2c91e4adf0e0efdb3f45
|
|||||||
+
|
+
|
||||||
+ ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
|
+ ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
|
||||||
+ if (ih == NULL)
|
+ if (ih == NULL)
|
||||||
+@@ -50,29 +56,38 @@ ebt_ip_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
+@@ -50,29 +56,38 @@ ebt_ip_mt(const struct sk_buff *skb, str
|
||||||
+ if (info->bitmask & EBT_IP_PROTO) {
|
+ if (info->bitmask & EBT_IP_PROTO) {
|
||||||
+ if (NF_INVF(info, EBT_IP_PROTO, info->protocol != ih->protocol))
|
+ if (NF_INVF(info, EBT_IP_PROTO, info->protocol != ih->protocol))
|
||||||
+ return false;
|
+ return false;
|
||||||
@ -133,7 +129,7 @@ index 0000000000000000000000000000000000000000..9e4d90fb3b8e2c91e4adf0e0efdb3f45
|
|||||||
+ }
|
+ }
|
||||||
+ return true;
|
+ return true;
|
||||||
+ }
|
+ }
|
||||||
+@@ -101,6 +116,14 @@ static int ebt_ip_mt_check(const struct xt_mtchk_param *par)
|
+@@ -101,6 +116,14 @@ static int ebt_ip_mt_check(const struct
|
||||||
+ return -EINVAL;
|
+ return -EINVAL;
|
||||||
+ if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
|
+ if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
|
||||||
+ return -EINVAL;
|
+ return -EINVAL;
|
||||||
@ -148,15 +144,12 @@ index 0000000000000000000000000000000000000000..9e4d90fb3b8e2c91e4adf0e0efdb3f45
|
|||||||
+ return 0;
|
+ return 0;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+--
|
|
||||||
+2.16.2
|
|
||||||
+
|
|
||||||
diff --git a/target/linux/generic/backport-4.14/096-0002-ebtables-add-support-for-matching-IGMP-type.patch b/target/linux/generic/backport-4.14/096-0002-ebtables-add-support-for-matching-IGMP-type.patch
|
diff --git a/target/linux/generic/backport-4.14/096-0002-ebtables-add-support-for-matching-IGMP-type.patch b/target/linux/generic/backport-4.14/096-0002-ebtables-add-support-for-matching-IGMP-type.patch
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..35b93adc802c2850cd6ee218c3d7d6f6c53bba29
|
index 0000000000000000000000000000000000000000..4c8144834d87c58ff90363cdc2f2933194e54fdc
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/target/linux/generic/backport-4.14/096-0002-ebtables-add-support-for-matching-IGMP-type.patch
|
+++ b/target/linux/generic/backport-4.14/096-0002-ebtables-add-support-for-matching-IGMP-type.patch
|
||||||
@@ -0,0 +1,95 @@
|
@@ -0,0 +1,88 @@
|
||||||
+From: Matthias Schiffer <mschiffer@universe-factory.net>
|
+From: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
+Date: Sat, 3 Mar 2018 12:02:21 +0100
|
+Date: Sat, 3 Mar 2018 12:02:21 +0100
|
||||||
+Subject: [PATCH 2/2] ebtables: add support for matching IGMP type
|
+Subject: [PATCH 2/2] ebtables: add support for matching IGMP type
|
||||||
@ -171,8 +164,6 @@ index 0000000000000000000000000000000000000000..35b93adc802c2850cd6ee218c3d7d6f6
|
|||||||
+ net/bridge/netfilter/ebt_ip.c | 19 +++++++++++++++++--
|
+ net/bridge/netfilter/ebt_ip.c | 19 +++++++++++++++++--
|
||||||
+ 2 files changed, 20 insertions(+), 3 deletions(-)
|
+ 2 files changed, 20 insertions(+), 3 deletions(-)
|
||||||
+
|
+
|
||||||
+diff --git a/include/uapi/linux/netfilter_bridge/ebt_ip.h b/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
|
||||||
+index 4ed7fbb0a482..46d6261370b0 100644
|
|
||||||
+--- a/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
+--- a/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
||||||
++++ b/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
++++ b/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
||||||
+@@ -25,8 +25,9 @@
|
+@@ -25,8 +25,9 @@
|
||||||
@ -194,8 +185,6 @@ index 0000000000000000000000000000000000000000..35b93adc802c2850cd6ee218c3d7d6f6
|
|||||||
+ };
|
+ };
|
||||||
+ union {
|
+ union {
|
||||||
+ __u16 dport[2];
|
+ __u16 dport[2];
|
||||||
+diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c
|
|
||||||
+index 8cb8f8395768..ffaa8ce2e724 100644
|
|
||||||
+--- a/net/bridge/netfilter/ebt_ip.c
|
+--- a/net/bridge/netfilter/ebt_ip.c
|
||||||
++++ b/net/bridge/netfilter/ebt_ip.c
|
++++ b/net/bridge/netfilter/ebt_ip.c
|
||||||
+@@ -28,6 +28,9 @@ union pkthdr {
|
+@@ -28,6 +28,9 @@ union pkthdr {
|
||||||
@ -208,7 +197,7 @@ index 0000000000000000000000000000000000000000..35b93adc802c2850cd6ee218c3d7d6f6
|
|||||||
+ };
|
+ };
|
||||||
+
|
+
|
||||||
+ static bool
|
+ static bool
|
||||||
+@@ -57,12 +60,12 @@ ebt_ip_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
+@@ -57,12 +60,12 @@ ebt_ip_mt(const struct sk_buff *skb, str
|
||||||
+ if (NF_INVF(info, EBT_IP_PROTO, info->protocol != ih->protocol))
|
+ if (NF_INVF(info, EBT_IP_PROTO, info->protocol != ih->protocol))
|
||||||
+ return false;
|
+ return false;
|
||||||
+ if (!(info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT |
|
+ if (!(info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT |
|
||||||
@ -223,7 +212,7 @@ index 0000000000000000000000000000000000000000..35b93adc802c2850cd6ee218c3d7d6f6
|
|||||||
+ pptr = skb_header_pointer(skb, ih->ihl*4,
|
+ pptr = skb_header_pointer(skb, ih->ihl*4,
|
||||||
+ sizeof(_pkthdr), &_pkthdr);
|
+ sizeof(_pkthdr), &_pkthdr);
|
||||||
+ if (pptr == NULL)
|
+ if (pptr == NULL)
|
||||||
+@@ -88,6 +91,11 @@ ebt_ip_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
+@@ -88,6 +91,11 @@ ebt_ip_mt(const struct sk_buff *skb, str
|
||||||
+ pptr->icmphdr.code < info->icmp_code[0] ||
|
+ pptr->icmphdr.code < info->icmp_code[0] ||
|
||||||
+ pptr->icmphdr.code > info->icmp_code[1]))
|
+ pptr->icmphdr.code > info->icmp_code[1]))
|
||||||
+ return false;
|
+ return false;
|
||||||
@ -235,7 +224,7 @@ index 0000000000000000000000000000000000000000..35b93adc802c2850cd6ee218c3d7d6f6
|
|||||||
+ }
|
+ }
|
||||||
+ return true;
|
+ return true;
|
||||||
+ }
|
+ }
|
||||||
+@@ -124,6 +132,13 @@ static int ebt_ip_mt_check(const struct xt_mtchk_param *par)
|
+@@ -124,6 +132,13 @@ static int ebt_ip_mt_check(const struct
|
||||||
+ info->icmp_code[0] > info->icmp_code[1])
|
+ info->icmp_code[0] > info->icmp_code[1])
|
||||||
+ return -EINVAL;
|
+ return -EINVAL;
|
||||||
+ }
|
+ }
|
||||||
@ -249,254 +238,3 @@ index 0000000000000000000000000000000000000000..35b93adc802c2850cd6ee218c3d7d6f6
|
|||||||
+ return 0;
|
+ return 0;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+--
|
|
||||||
+2.16.2
|
|
||||||
+
|
|
||||||
diff --git a/target/linux/generic/backport-4.9/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch b/target/linux/generic/backport-4.9/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..db82fd6b69b3c4e279f39db7ca4b415498457e75
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/target/linux/generic/backport-4.9/096-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch
|
|
||||||
@@ -0,0 +1,141 @@
|
|
||||||
+From: Matthias Schiffer <mschiffer@universe-factory.net>
|
|
||||||
+Date: Sat, 3 Mar 2018 11:55:21 +0100
|
|
||||||
+Subject: [PATCH 1/2] ebtables: add support for matching ICMP type and code
|
|
||||||
+
|
|
||||||
+We already have ICMPv6 type/code matches. This adds support for IPv4 ICMP
|
|
||||||
+matches in the same way.
|
|
||||||
+
|
|
||||||
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
|
||||||
+---
|
|
||||||
+ include/uapi/linux/netfilter_bridge/ebt_ip.h | 13 +++++++--
|
|
||||||
+ net/bridge/netfilter/ebt_ip.c | 43 +++++++++++++++++++++-------
|
|
||||||
+ 2 files changed, 43 insertions(+), 13 deletions(-)
|
|
||||||
+
|
|
||||||
+diff --git a/include/uapi/linux/netfilter_bridge/ebt_ip.h b/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
|
||||||
+index c4bbc41b0ea4..63a2860ae1e3 100644
|
|
||||||
+--- a/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
|
||||||
++++ b/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
|
||||||
+@@ -23,8 +23,9 @@
|
|
||||||
+ #define EBT_IP_PROTO 0x08
|
|
||||||
+ #define EBT_IP_SPORT 0x10
|
|
||||||
+ #define EBT_IP_DPORT 0x20
|
|
||||||
++#define EBT_IP_ICMP 0x40
|
|
||||||
+ #define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\
|
|
||||||
+- EBT_IP_SPORT | EBT_IP_DPORT )
|
|
||||||
++ EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP)
|
|
||||||
+ #define EBT_IP_MATCH "ip"
|
|
||||||
+
|
|
||||||
+ /* the same values are used for the invflags */
|
|
||||||
+@@ -37,8 +38,14 @@ struct ebt_ip_info {
|
|
||||||
+ __u8 protocol;
|
|
||||||
+ __u8 bitmask;
|
|
||||||
+ __u8 invflags;
|
|
||||||
+- __u16 sport[2];
|
|
||||||
+- __u16 dport[2];
|
|
||||||
++ union {
|
|
||||||
++ __u16 sport[2];
|
|
||||||
++ __u8 icmp_type[2];
|
|
||||||
++ };
|
|
||||||
++ union {
|
|
||||||
++ __u16 dport[2];
|
|
||||||
++ __u8 icmp_code[2];
|
|
||||||
++ };
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ #endif
|
|
||||||
+diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c
|
|
||||||
+index d06968bdf5ec..e4fc77072b27 100644
|
|
||||||
+--- a/net/bridge/netfilter/ebt_ip.c
|
|
||||||
++++ b/net/bridge/netfilter/ebt_ip.c
|
|
||||||
+@@ -19,9 +19,15 @@
|
|
||||||
+ #include <linux/netfilter_bridge/ebtables.h>
|
|
||||||
+ #include <linux/netfilter_bridge/ebt_ip.h>
|
|
||||||
+
|
|
||||||
+-struct tcpudphdr {
|
|
||||||
+- __be16 src;
|
|
||||||
+- __be16 dst;
|
|
||||||
++union pkthdr {
|
|
||||||
++ struct {
|
|
||||||
++ __be16 src;
|
|
||||||
++ __be16 dst;
|
|
||||||
++ } tcpudphdr;
|
|
||||||
++ struct {
|
|
||||||
++ u8 type;
|
|
||||||
++ u8 code;
|
|
||||||
++ } icmphdr;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ static bool
|
|
||||||
+@@ -30,8 +36,8 @@ ebt_ip_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|
||||||
+ const struct ebt_ip_info *info = par->matchinfo;
|
|
||||||
+ const struct iphdr *ih;
|
|
||||||
+ struct iphdr _iph;
|
|
||||||
+- const struct tcpudphdr *pptr;
|
|
||||||
+- struct tcpudphdr _ports;
|
|
||||||
++ const union pkthdr *pptr;
|
|
||||||
++ union pkthdr _pkthdr;
|
|
||||||
+
|
|
||||||
+ ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
|
|
||||||
+ if (ih == NULL)
|
|
||||||
+@@ -50,29 +56,38 @@ ebt_ip_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|
||||||
+ if (info->bitmask & EBT_IP_PROTO) {
|
|
||||||
+ if (NF_INVF(info, EBT_IP_PROTO, info->protocol != ih->protocol))
|
|
||||||
+ return false;
|
|
||||||
+- if (!(info->bitmask & EBT_IP_DPORT) &&
|
|
||||||
+- !(info->bitmask & EBT_IP_SPORT))
|
|
||||||
++ if (!(info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT |
|
|
||||||
++ EBT_IP_ICMP)))
|
|
||||||
+ return true;
|
|
||||||
+ if (ntohs(ih->frag_off) & IP_OFFSET)
|
|
||||||
+ return false;
|
|
||||||
++
|
|
||||||
++ /* min icmp headersize is 4, so sizeof(_pkthdr) is ok. */
|
|
||||||
+ pptr = skb_header_pointer(skb, ih->ihl*4,
|
|
||||||
+- sizeof(_ports), &_ports);
|
|
||||||
++ sizeof(_pkthdr), &_pkthdr);
|
|
||||||
+ if (pptr == NULL)
|
|
||||||
+ return false;
|
|
||||||
+ if (info->bitmask & EBT_IP_DPORT) {
|
|
||||||
+- u32 dst = ntohs(pptr->dst);
|
|
||||||
++ u32 dst = ntohs(pptr->tcpudphdr.dst);
|
|
||||||
+ if (NF_INVF(info, EBT_IP_DPORT,
|
|
||||||
+ dst < info->dport[0] ||
|
|
||||||
+ dst > info->dport[1]))
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+ if (info->bitmask & EBT_IP_SPORT) {
|
|
||||||
+- u32 src = ntohs(pptr->src);
|
|
||||||
++ u32 src = ntohs(pptr->tcpudphdr.src);
|
|
||||||
+ if (NF_INVF(info, EBT_IP_SPORT,
|
|
||||||
+ src < info->sport[0] ||
|
|
||||||
+ src > info->sport[1]))
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
++ if ((info->bitmask & EBT_IP_ICMP) &&
|
|
||||||
++ NF_INVF(info, EBT_IP_ICMP,
|
|
||||||
++ pptr->icmphdr.type < info->icmp_type[0] ||
|
|
||||||
++ pptr->icmphdr.type > info->icmp_type[1] ||
|
|
||||||
++ pptr->icmphdr.code < info->icmp_code[0] ||
|
|
||||||
++ pptr->icmphdr.code > info->icmp_code[1]))
|
|
||||||
++ return false;
|
|
||||||
+ }
|
|
||||||
+ return true;
|
|
||||||
+ }
|
|
||||||
+@@ -101,6 +116,14 @@ static int ebt_ip_mt_check(const struct xt_mtchk_param *par)
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
|
|
||||||
+ return -EINVAL;
|
|
||||||
++ if (info->bitmask & EBT_IP_ICMP) {
|
|
||||||
++ if ((info->invflags & EBT_IP_PROTO) ||
|
|
||||||
++ info->protocol != IPPROTO_ICMP)
|
|
||||||
++ return -EINVAL;
|
|
||||||
++ if (info->icmp_type[0] > info->icmp_type[1] ||
|
|
||||||
++ info->icmp_code[0] > info->icmp_code[1])
|
|
||||||
++ return -EINVAL;
|
|
||||||
++ }
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+--
|
|
||||||
+2.16.2
|
|
||||||
+
|
|
||||||
diff --git a/target/linux/generic/backport-4.9/096-0002-ebtables-add-support-for-matching-IGMP-type.patch b/target/linux/generic/backport-4.9/096-0002-ebtables-add-support-for-matching-IGMP-type.patch
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..5750b612fc0f322e0a257f3229b5b698328b428b
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/target/linux/generic/backport-4.9/096-0002-ebtables-add-support-for-matching-IGMP-type.patch
|
|
||||||
@@ -0,0 +1,95 @@
|
|
||||||
+From: Matthias Schiffer <mschiffer@universe-factory.net>
|
|
||||||
+Date: Sat, 3 Mar 2018 12:02:21 +0100
|
|
||||||
+Subject: [PATCH 2/2] ebtables: add support for matching IGMP type
|
|
||||||
+
|
|
||||||
+We already have ICMPv6 type/code matches (which can be used to distinguish
|
|
||||||
+different types of MLD packets). Add support for IPv4 IGMP matches in the
|
|
||||||
+same way.
|
|
||||||
+
|
|
||||||
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
|
||||||
+---
|
|
||||||
+ include/uapi/linux/netfilter_bridge/ebt_ip.h | 4 +++-
|
|
||||||
+ net/bridge/netfilter/ebt_ip.c | 19 +++++++++++++++++--
|
|
||||||
+ 2 files changed, 20 insertions(+), 3 deletions(-)
|
|
||||||
+
|
|
||||||
+diff --git a/include/uapi/linux/netfilter_bridge/ebt_ip.h b/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
|
||||||
+index 63a2860ae1e3..ae5d4d108418 100644
|
|
||||||
+--- a/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
|
||||||
++++ b/include/uapi/linux/netfilter_bridge/ebt_ip.h
|
|
||||||
+@@ -24,8 +24,9 @@
|
|
||||||
+ #define EBT_IP_SPORT 0x10
|
|
||||||
+ #define EBT_IP_DPORT 0x20
|
|
||||||
+ #define EBT_IP_ICMP 0x40
|
|
||||||
++#define EBT_IP_IGMP 0x80
|
|
||||||
+ #define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\
|
|
||||||
+- EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP)
|
|
||||||
++ EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP | EBT_IP_IGMP)
|
|
||||||
+ #define EBT_IP_MATCH "ip"
|
|
||||||
+
|
|
||||||
+ /* the same values are used for the invflags */
|
|
||||||
+@@ -41,6 +42,7 @@ struct ebt_ip_info {
|
|
||||||
+ union {
|
|
||||||
+ __u16 sport[2];
|
|
||||||
+ __u8 icmp_type[2];
|
|
||||||
++ __u8 igmp_type[2];
|
|
||||||
+ };
|
|
||||||
+ union {
|
|
||||||
+ __u16 dport[2];
|
|
||||||
+diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c
|
|
||||||
+index e4fc77072b27..57fbb13cb8e0 100644
|
|
||||||
+--- a/net/bridge/netfilter/ebt_ip.c
|
|
||||||
++++ b/net/bridge/netfilter/ebt_ip.c
|
|
||||||
+@@ -28,6 +28,9 @@ union pkthdr {
|
|
||||||
+ u8 type;
|
|
||||||
+ u8 code;
|
|
||||||
+ } icmphdr;
|
|
||||||
++ struct {
|
|
||||||
++ u8 type;
|
|
||||||
++ } igmphdr;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ static bool
|
|
||||||
+@@ -57,12 +60,12 @@ ebt_ip_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|
||||||
+ if (NF_INVF(info, EBT_IP_PROTO, info->protocol != ih->protocol))
|
|
||||||
+ return false;
|
|
||||||
+ if (!(info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT |
|
|
||||||
+- EBT_IP_ICMP)))
|
|
||||||
++ EBT_IP_ICMP | EBT_IP_IGMP)))
|
|
||||||
+ return true;
|
|
||||||
+ if (ntohs(ih->frag_off) & IP_OFFSET)
|
|
||||||
+ return false;
|
|
||||||
+
|
|
||||||
+- /* min icmp headersize is 4, so sizeof(_pkthdr) is ok. */
|
|
||||||
++ /* min icmp/igmp headersize is 4, so sizeof(_pkthdr) is ok. */
|
|
||||||
+ pptr = skb_header_pointer(skb, ih->ihl*4,
|
|
||||||
+ sizeof(_pkthdr), &_pkthdr);
|
|
||||||
+ if (pptr == NULL)
|
|
||||||
+@@ -88,6 +91,11 @@ ebt_ip_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|
||||||
+ pptr->icmphdr.code < info->icmp_code[0] ||
|
|
||||||
+ pptr->icmphdr.code > info->icmp_code[1]))
|
|
||||||
+ return false;
|
|
||||||
++ if ((info->bitmask & EBT_IP_IGMP) &&
|
|
||||||
++ NF_INVF(info, EBT_IP_IGMP,
|
|
||||||
++ pptr->igmphdr.type < info->igmp_type[0] ||
|
|
||||||
++ pptr->igmphdr.type > info->igmp_type[1]))
|
|
||||||
++ return false;
|
|
||||||
+ }
|
|
||||||
+ return true;
|
|
||||||
+ }
|
|
||||||
+@@ -124,6 +132,13 @@ static int ebt_ip_mt_check(const struct xt_mtchk_param *par)
|
|
||||||
+ info->icmp_code[0] > info->icmp_code[1])
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
++ if (info->bitmask & EBT_IP_IGMP) {
|
|
||||||
++ if ((info->invflags & EBT_IP_PROTO) ||
|
|
||||||
++ info->protocol != IPPROTO_IGMP)
|
|
||||||
++ return -EINVAL;
|
|
||||||
++ if (info->igmp_type[0] > info->igmp_type[1])
|
|
||||||
++ return -EINVAL;
|
|
||||||
++ }
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+--
|
|
||||||
+2.16.2
|
|
||||||
+
|
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
From: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
Date: Sat, 21 Sep 2019 13:21:36 +0200
|
||||||
|
Subject: build: set TARGET_ROOTFS_PARTSIZE to make combined image fit in 128MB
|
||||||
|
|
||||||
|
Change TARGET_ROOTFS_PARTSIZE from 128 to 104 MiB, so the whole image
|
||||||
|
(bootloader + boot + root) will fit on a 128MB CF card by default.
|
||||||
|
|
||||||
|
With these settings, the generated images (tested on x86-generic and
|
||||||
|
x86-64) have 126,353,408 bytes; the smallest CF card marketed as "128MB"
|
||||||
|
that I found a datasheet for (a Transcend TS128MCF80) has 126,959,616
|
||||||
|
bytes.
|
||||||
|
|
||||||
|
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
|
|
||||||
|
diff --git a/config/Config-images.in b/config/Config-images.in
|
||||||
|
index 8548c7cd24742daad4fb1c64e58bad82590795c2..dc7a9cbd54ffbe3c78a7fdbd124f389c102ef6c1 100644
|
||||||
|
--- a/config/Config-images.in
|
||||||
|
+++ b/config/Config-images.in
|
||||||
|
@@ -274,7 +274,7 @@ menu "Target Images"
|
||||||
|
config TARGET_ROOTFS_PARTSIZE
|
||||||
|
int "Root filesystem partition size (in MB)"
|
||||||
|
depends on GRUB_IMAGES || USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS || TARGET_omap || TARGET_rb532 || TARGET_sunxi || TARGET_uml
|
||||||
|
- default 256
|
||||||
|
+ default 104
|
||||||
|
help
|
||||||
|
Select the root filesystem partition size.
|
||||||
|
|
@ -1,87 +0,0 @@
|
|||||||
From: David Bauer <mail@david-bauer.net>
|
|
||||||
Date: Sat, 21 Sep 2019 18:59:28 +0200
|
|
||||||
Subject: ipq-wifi: add AVM FRITZ!Repeater 1200 bdf
|
|
||||||
|
|
||||||
Signed-off-by: David Bauer <mail@david-bauer.net>
|
|
||||||
|
|
||||||
diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile
|
|
||||||
index 922064b7f78b80670cdb1ec7e9f86ede224cb7fb..eb7c2df1aa36ded7774a772c8a7e02b2acb81b40 100644
|
|
||||||
--- a/package/firmware/ipq-wifi/Makefile
|
|
||||||
+++ b/package/firmware/ipq-wifi/Makefile
|
|
||||||
@@ -27,6 +27,7 @@ ALLWIFIBOARDS:= \
|
|
||||||
alfa-network_ap120c-ac \
|
|
||||||
asus_map-ac2200 \
|
|
||||||
avm_fritzbox-7530 \
|
|
||||||
+ avm_fritzrepeater-1200 \
|
|
||||||
avm_fritzrepeater-3000 \
|
|
||||||
engenius_eap1300 \
|
|
||||||
engenius_ens620ext \
|
|
||||||
@@ -98,6 +99,7 @@ endef
|
|
||||||
$(eval $(call generate-ipq-wifi-package,alfa-network_ap120c-ac,ALFA Network AP120C-AC))
|
|
||||||
$(eval $(call generate-ipq-wifi-package,asus_map-ac2200,ASUS MAP-AC2200))
|
|
||||||
$(eval $(call generate-ipq-wifi-package,avm_fritzbox-7530,AVM FRITZ!Box 7530))
|
|
||||||
+$(eval $(call generate-ipq-wifi-package,avm_fritzrepeater-1200,AVM FRITZRepeater 1200))
|
|
||||||
$(eval $(call generate-ipq-wifi-package,avm_fritzrepeater-3000,AVM FRITZ!Repeater 3000))
|
|
||||||
$(eval $(call generate-ipq-wifi-package,engenius_eap1300,EnGenius EAP1300))
|
|
||||||
$(eval $(call generate-ipq-wifi-package,engenius_ens620ext,EnGenius ENS620EXT))
|
|
||||||
diff --git a/package/firmware/ipq-wifi/board-avm_fritzrepeater-1200.qca4019 b/package/firmware/ipq-wifi/board-avm_fritzrepeater-1200.qca4019
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..d78a49d4dbf3fc22c40a83d052fc7c55542ff8e3
|
|
||||||
GIT binary patch
|
|
||||||
literal 24332
|
|
||||||
zcmeHPTTl~O8a_d8Dk`0XTL?`^xFjwK5Lk^61wv#JXn|o7A-XOgC<!pcfLx4IQVuF&
|
|
||||||
zL`Ib1VgxBv<kIUZ<?4*e?CQAAmZsc&nKxhdZ62h`+S>AEojsjSAdzHD5LPbzhtuaj
|
|
||||||
zf1m&S|M|L;bocql=Nak3^a4dfe6~=Qo1QNRH8nK=N_`x$1wal<*^#>KrIlr|Wi@Ky
|
|
||||||
zfl9Sjs4m|gZ*G;<mg>rhrZ_&fp;V_X{i1$*df_f%X1=mOm0zK)D6Oy12@}Ne@iaIN
|
|
||||||
z2ad^!oA9U6z?$Rqq(Wl+&4a)LlmM{K$De2dxaB6o+84eYi9nD@3<W@9V&cEwya7_C
|
|
||||||
zH+cK6^QqRdhUv)b!!{0}J$=7dCm9L+0_FXE&fA-2cKO5E5HG6`Ia>AEI@MvulP*S_
|
|
||||||
z?YC}bNDd%hGX{&oq}y5?$9?ExTw)|*X10X^+eBeo3as3c_3Jlobj!g(XRZU=r!Z+d
|
|
||||||
z#);F$BK8@)8kuNs*Qk}M)K?SzZO!GXY~{8`qy4Abb?VQRTON%;txlb<{OwyPx9<vK
|
|
||||||
z!0XY8lkHXNU8=NKWBsR^D^-|M`sgOnO{G*ypu^erMrcbR9bz_v*TWOXnu}D)%2?>y
|
|
||||||
z+I&DIhuyCCw?o%#3IEYV|Al6)Dqj+Bafq?c?*px7C?DuzzngNf$HQ@JC7|SZX3NX^
|
|
||||||
zWU%VXEKU5Lz|`?8b!}VAqjs~hAC4aG%{<N51()=W?d{!mnp4Lpy?<GKEW3)gD=_W;
|
|
||||||
zQ0=LdN<ncb_Vi}+H@T-pbzuj-9c%2}bynEOKKSH{_E=^GSIJ0zJY3tFRU5rKP=4dO
|
|
||||||
zx<}Feo5s+}`x6ZVamT~8jFRPr5|ynL0WY7m>o;sd7y&^cp<&_HPyE@M_>7$utCw93
|
|
||||||
zFNgr3(L6jnXvB8S8ZR#|Z;SYhbT*YJo}I|!Gb1B;@GpuR5y9g|aJhw^zQA&YVmBJq
|
|
||||||
zSX2Z$I~y7b3b0HGSij!en+zopMDe)XaM)n_{O9evcL7i%ZG<t*&&R{l^S|b<G~mde
|
|
||||||
z9A)vg+HrV20*BWg?-(Zv5s7b+=tx4ioUp*?NG_LyvRT1Uo4*Zu@_0OAAULXJypORt
|
|
||||||
zLIpt)Bppph63_%hd*tZx)-xSlJ#!Txwa5dv6go;5(Vx>17RnN_Fn`n^2}Wh8OeA|Q
|
|
||||||
zL$c5;Q5KelrXdPcjEY6#=VBxoO%^3%@n}3EL1&UM4mnn5a*|4CvZB;E$Hx^&7%1a4
|
|
||||||
z0|`Y#MWI**n(;aV$wsq9*;pc)_&O0uK~qF27<mwEx8_hJ^ozbF&Ry*p<G5{!`be4m
|
|
||||||
zW^t@JdcVxqwi2#MsX4fE^eL1ml$;<yof=Mnu`{nql<W|o8WaK)0u%xi0u%xi0;?E-
|
|
||||||
zAaM{9PXA2&8InuiD&C5u(tWK0^2;s^-F|Glwch%>SI>>H)+!4YV-+7lYU(Qm0asTD
|
|
||||||
zT<y2aaKZLf8YW)=0P7~h;N*+<YxtxZKBGq2Axs{RLq7b5+S0Lcp_uavHY>!#dFE2G
|
|
||||||
zML^+%L;QlE0&60_rDR*`r|U%@1f(SaV4x$kKq#G-`l6-g`yxOJq@HO20e^oiXaOJr
|
|
||||||
z@DRwOg2Wpx<nvgI6xwB8f|oKM!9QRjYIE`TM1W6=7iR?SfA#Wb@Y7E}n`=TR3MDHS
|
|
||||||
zfnRR<F+DuW;R*x*G!IYTZ=hU-Vx93lC?8|Pir|Oq;N*|a>X_)L$WK|wl{<2+j$EC?
|
|
||||||
z@(POfm6TT+IxqHI9vmJSzcqR9;a`6E@rC<4Y}WDIyK-GNy@7ch6r;CUS3=EepqQ-9
|
|
||||||
zx(aGu|HQ;?))i3qL3HY|^3h#3r@_if)Ri^koWlJFJG!r2$L~)4&6&QkP??<#^Bogm
|
|
||||||
zqihiyV*>d*If9{>2*czc>0J^cMWrGsmb75^*RxUG(E`PR2ujZsXCgWDE#fW64!Ww3
|
|
||||||
zc+DNd`aNf@m&+}VyWIN(m$~;?H;o2~_f4H<CU}5_dmrFKA_Olhc?9<!08dZSV!!46
|
|
||||||
zZZ7v8au8CjWxm{d80CBWNB}G}_nyd+h=JM#a?F9B<<#4Cp3|7^=K}ZM&f9TZcewX}
|
|
||||||
z!C*KnY&IJZ#m~>row9cAVsh`(n1jrh4*$==4i=}4v9U3y`{wR|$J$2b?swI)DwlMr
|
|
||||||
zNxO1-EJ2i9Nt^0JAwVHOA+TH#C@E1DlH7Yb-G2i)3pcs<C8Ym`4IXbu|APmuW3pKA
|
|
||||||
znrgv?;@(^C%pO?p(0)y!xc4*YxI%%qLi&I2>&kN!Th=|Po6{vHxaeErjcm)iC-je`
|
|
||||||
z-bZ0Y!~^e#FKliv?9>l^cub!$RpXd3!N8twGgaZ)MzJAm>aMX{f4DeP5;b)jA2#SU
|
|
||||||
z#S%90|6-SWV)$UX%hZgkjA;hp^d*xX-)oc^;_yl1phi=iBZ-~*v+;tyrdTH75Dv!P
|
|
||||||
zm>4kKXF7==GUge!PY;;R;MK<6dLjO;p<AO<$R%Rv(50`oI$Y_E5dhfj9IiFwYqm^Z
|
|
||||||
zGj-ujh9Zp=pEC4o>J>Zr!R826n!RL7#y%n?qp2OQ(#wk@r-w}Eah+keW(WSAp;yzO
|
|
||||||
zQ1C;i?inwcQwk?iy3)so5qeBt;Rp0P6fEf4hO6~5MJWC!<AA0{kuHfdeTNSjnl*bQ
|
|
||||||
zEW%-+PY?~JyG<>4i9T5oGTm!x#mn_lMF>o!SAV29TOu&s#rq68O|Bx6j39t1oi{b%
|
|
||||||
zMS8J<IsLWiD6WDUV!DrCg;=IZ&{ub+E*l#)8Hx}x0-S?8vIH;nsgztffD}p;N=^`1
|
|
||||||
z38#jWsZr)ti@@D8$9}&vLC6mAzSdT~Z>u;WY@=^|cV?^LFssZj^ZVh7bKCX2LqWxV
|
|
||||||
z?P^k`3Znypz3yB(R+S|a$At!;A1v%hILgs%%6WRT`a)VuR87eKXMO6ttufI-06ZEv
|
|
||||||
zTCK<s3B$tfjU4VyJ0Z}~cRwCgccr%Qs)P4G8K^6fZHZzB`#rc;eMq4|x&918f6mE-
|
|
||||||
z`hYzfcHX~Pb|LvVrz&9YLu2*6Jb7#+;yF3gpxde7@&j1yy}7578iI@c6nDn{a7l6^
|
|
||||||
zye44(WKaD8<&Ib$!+X@&P^ZMil7P_30bNJNvDlix{AYj6Ivd*@a?pRzt?r|mT)BWt
|
|
||||||
z_a5%8{UWbGm=wyr(W`FTab)u$M)viQ+P;)lo{qWy#(8a-JcY+*GyA?Suh^LtD-K|t
|
|
||||||
z>)7*Ul7_pNo_2e*?sCpKeq(UOsy%V2iBkxy00chvmpFWE#Q`3JZCZt-NhKBYqoN|=
|
|
||||||
zAN&;#4lg2t8&T-BWPXWbE-&6nz4u+Pb^Ez7tknCp3l_rx{FI48V15X=O8i*pe)G$A
|
|
||||||
z#duNNd&rAlMBe^V;@LaOWvQRYBal;1a^Mj&kDlPzuWJ>w$RSsL^EPfeS;7x*-exXW
|
|
||||||
z{XG-RTzY~}@6)ml7NYjzn7Q`^-`-2`PcsLf<l(<u>hoXC`4QZBPsoig>KXZAF}U%I
|
|
||||||
zjjc1zz199HdG|zYihDo1G&c{8;@-~#G|FXZBjC!Ku`|BCt$k_Fa{k#--227;*8KJH
|
|
||||||
F{|7QKi|GIW
|
|
||||||
|
|
||||||
literal 0
|
|
||||||
HcmV?d00001
|
|
||||||
|
|
92
patches/openwrt/0007-ipq-wifi-add-BDF-for-Aruba-AP-303.patch
Normal file
92
patches/openwrt/0007-ipq-wifi-add-BDF-for-Aruba-AP-303.patch
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
From: David Bauer <mail@david-bauer.net>
|
||||||
|
Date: Sun, 15 Dec 2019 23:02:54 +0100
|
||||||
|
Subject: ipq-wifi: add BDF for Aruba AP-303
|
||||||
|
|
||||||
|
The BDF originates from the vendor-firmware.
|
||||||
|
|
||||||
|
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||||
|
(cherry picked from commit 4113d8a2554adf5ecee55cc07956eafad378eaff)
|
||||||
|
|
||||||
|
diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile
|
||||||
|
index eb7c2df1aa36ded7774a772c8a7e02b2acb81b40..cc0505b97c6a04bafd88972cf6ce7890a637c33b 100644
|
||||||
|
--- a/package/firmware/ipq-wifi/Makefile
|
||||||
|
+++ b/package/firmware/ipq-wifi/Makefile
|
||||||
|
@@ -25,6 +25,7 @@ endef
|
||||||
|
|
||||||
|
ALLWIFIBOARDS:= \
|
||||||
|
alfa-network_ap120c-ac \
|
||||||
|
+ aruba_ap-303 \
|
||||||
|
asus_map-ac2200 \
|
||||||
|
avm_fritzbox-7530 \
|
||||||
|
avm_fritzrepeater-1200 \
|
||||||
|
@@ -97,6 +98,7 @@ endef
|
||||||
|
# Add $(eval $(call generate-ipq-wifi-package,<devicename>,<display name>))
|
||||||
|
|
||||||
|
$(eval $(call generate-ipq-wifi-package,alfa-network_ap120c-ac,ALFA Network AP120C-AC))
|
||||||
|
+$(eval $(call generate-ipq-wifi-package,aruba_ap-303,Aruba AP-303))
|
||||||
|
$(eval $(call generate-ipq-wifi-package,asus_map-ac2200,ASUS MAP-AC2200))
|
||||||
|
$(eval $(call generate-ipq-wifi-package,avm_fritzbox-7530,AVM FRITZ!Box 7530))
|
||||||
|
$(eval $(call generate-ipq-wifi-package,avm_fritzrepeater-1200,AVM FRITZRepeater 1200))
|
||||||
|
diff --git a/package/firmware/ipq-wifi/board-aruba_ap-303.qca4019 b/package/firmware/ipq-wifi/board-aruba_ap-303.qca4019
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..4848115cfbe3a4a0ed6b17cac929731ecbd7968c
|
||||||
|
GIT binary patch
|
||||||
|
literal 24316
|
||||||
|
zcmeHPdr(tX8b1l)p-UHTNDu)pAp}Se0tBi-!W$`%6c7~&un1I<M58<m4?`F1_@EFG
|
||||||
|
zfm#qEXc?48Q$)t%1F%?IJEP40v48CBA8luLw|}fVw5!gvGrOyM?hO}02ql3q<#9ha
|
||||||
|
z=X~e8-#O<yzk5jTz30c>6BFeZwJ$y}AjvN}B`Pfz$mMbX<(NN~1F#FGd_`$kUSYm(
|
||||||
|
zzFg|}UZJ$ePkJaU0I%hr$SXO7RRsaQWqBpiyyGXsqDmC`d45r;enA02aybRIXTiQ$
|
||||||
|
z{(Fv6D8Qnc9-NN#>(d1&AQynm*7jHxFaWR*!ZjM6>t{S38|w;yprD{vFJ4eY3@h-<
|
||||||
|
z-!4WF$pUt;M0u#+u2DM@cmo9<o32e4-TK}{-42{)MS-YT8nB=KA&y`%68dZzvGj;%
|
||||||
|
zJAvBfnQ>V_`vZ+ET^9yjw-&*$wzjskw6xF>07kKy8YxWZr<)vMT{juo&5WBJl$pvJ
|
||||||
|
zSBe@2uw^qXb0;%4&|Y78I5R0hICi_exl*3FFCluYul;;oiF8lGj<J5Il}ghR-u?y3
|
||||||
|
z<F9$%VC>WOy2|{_1bA?;y|Gf7nVJwj){D78n-DgruPe_KCxqe+o_PC!v0LpI;0W&~
|
||||||
|
zgp7R#8_4hmJ+PC)%p@TfcGpx{l$j<Bm~P-bH@-z`l~5LOnR}RQFc%NQwe^6K;hC*1
|
||||||
|
zYj=HKdB|b!bl0Sb=920-IsYItdbF>&E$%$G#3{F}KdUX|Jgd|puct0g5t8q<cU!`P
|
||||||
|
z#^Y7HrM_9r@UMC+KTbK%FWvUuz5epHckBJiT?>XU6jp>E=A|Pc_n}{`jGyHYexpa)
|
||||||
|
z8eg})+@<jDr)8b~)ow)&xoZn0GFk!wOY2R)d&>@SU~bv!vW@t_*D0~j*k2Ra54<44
|
||||||
|
zGAfly!Ey@=__b^`E!H<{G6I~Qyq_vSIUEo8>&bR^_h7rT+37SJ;+lkrg)CPdfsBl_
|
||||||
|
zWH#Fk4)pWSFMfRe8oL4#@;p7Xw*UV4*B^9knBz8EYbuTQKj>!%PuOhxmoH!ZTkE^h
|
||||||
|
zQ5Oxs>k&9eQFX%rmay^oy5hs-a5%Vu>&0fVaLp_>UjzM_W;28hf+9#18ifR+fk=_!
|
||||||
|
zRP~t;8=70^D?l_Y4@^?%D4kD#N=KYgXTG!89<@iD&}cN8AN@2MNkkL*iQ-5!5{X9z
|
||||||
|
zsDLkcDnNFjyZF1r0cZdsL}!9fUpK7I#3T~UL`ACe&W|yWIG_$w4u}it!gmqJpfOW1
|
||||||
|
zND`XFPZ9^AK~q6UC>qKS6>Cp|ZjKM7g?`0zZ0#0(s2<Qwp34-SuNH%<p}&`<+SbE0
|
||||||
|
zDLDsY&OV6}iP8cHkV|6$VCI-NBuaA-AS)ySBmyJ?BmyJ?Bmx^4fh~e9h#UPK!8=F_
|
||||||
|
zeWze25<#~i1f=CRT_1X+n-jPGrj_%@*hGlg#@N88kes@S2)vvpCU&q=?$dOIMY}iF
|
||||||
|
zZ_$ocmxDOFP&NDv09aP2x`v<WmwZ28Utjp7n}x1U4F>1q!}Wsktx^q!Hyz)q)K=GO
|
||||||
|
zoF7djK!C#!ycz%kffr-~xxvJNR46t~SlLJq1Z=jeD_c)mpnblT&CYJ-0FjUaUY!7-
|
||||||
|
z#TubR1_QvgL4XK|Xt`DhpfahOvtem(k8e884~Vp^8wB1A+A^rrLvRNI?k-blHXlQ|
|
||||||
|
z28Ed52$bd6#2N6zwQKmBg-UNPPtI?dv^#g&y*lmgoH%t~Mt1I@LRDi+Ye!f2&4Iz;
|
||||||
|
zk<l+6fAh@r13LS7rd_$N8E=5^gNo_3#7-!_2P%%PC3Zpa{ZFx=me>I`9mEA&tbcUZ
|
||||||
|
z%raPCff}=CoSdFh&~W)`kLJ$!*9+<E3zgZ~FkUkdSJaj7DrSJ#*RhBg74ya7SP=X=
|
||||||
|
z7!jc&zDOKww)^YZQBBbt1&#<xj}ycp$@Cq99Y{Dm^9uGezYpSjjwsj4Esm+2`@lsx
|
||||||
|
z_pP233MAZDG~x_!W*4x)IQLBJ8XOwPV6wwG_mF@_V5M8~BrC?bzpXnCrvEDEUf+49
|
||||||
|
zzBuO|MP{6#qUF9@TUl7rX4vll48Jjsia$KVkvGV>*BuD^e+C^f1J|FyU;r!;;^^oI
|
||||||
|
zutbQ7^|zo9O_y4-fz<*{BN<(cKQSIMS&pfWHI9R`Q7+)GZ~m87zSOtRt#@=xPIh$J
|
||||||
|
z+RmlJ%=Iy)wjsB2$w?ctL{=e6#)NGiAEXw5z3>BC;Y0;D{!GEsIar?io&qX3RM0m-
|
||||||
|
z1^qu!!LtzyFeRb^yHOg52(ttT)56l)JRy+1kO+_nY&ZmFIrD}%_y76l-@pIvyT3qG
|
||||||
|
z!a_rK!Uv_0b8llsqdtHB4`|cp+)q8%a_-ajrKM^)`>$U7G-ZAsz9G)NzdxUkC2X$&
|
||||||
|
zduq<ccO90m`EJJ_!n5Hnfmt*|3ykF4Yws{0%-(2jK-HM%C%SBVt&T&cMQg=#Z0+ju
|
||||||
|
z?J<3slzUHc2KJzP^x51yjM<u@zZYHGw?pGC>M~`z#Q)p7<L&AyWsXERen)*-SuBYY
|
||||||
|
zdX5iix>ZV<MCgkBpV)(k-dq41G^-WL{SyA<pyrb5ge*-W)C{Y;WHL#z(0BZEb(2yq
|
||||||
|
zi59Z32BQ<+-T-%#DbtndllL?oDuryXWT)ny>awgPK2|7z4Vsn5hz4U5-aIh*Kyy`9
|
||||||
|
z2K#+`d{Fa=s!Ar2h&1D>cG=1J-CQSpgrl-7ZAjx2Fr>-5ns)VRm0Y%a{Fdgrx(+r@
|
||||||
|
z*4$UM$;#s6xh~@)>W}b{+^~=yKH~BKoNA}$qFSNKg(0ccXH~^YiRPBNQznm(68cZx
|
||||||
|
z*IZXs$_@yfwGDV)*c_VFr&I;XWO(qZszR13@rQx5DHW0=A#d`I=8CFBmJ-jw8hkOq
|
||||||
|
zgDBk|Z&R15a+I-?Bk*9UGFz4i!@LHuj1;2qXotF778Ab}Z}1q-!4z4Am-=K##+*PB
|
||||||
|
zB@(3t5LgdOV}YrW<_(KL>(KEV5iNeTE@js=e`t@r=v}q-_{qz0XL!ZV`L=NnyANLo
|
||||||
|
zQ+gcPBDpqn@<w#Cf31sRXs|$?cxn3|T~1u=N^b}}#gf@2f7N@eDYC{>zBNZRxW7|)
|
||||||
|
z$*qbmtL@F{5S&95^!$;V#g`*L;FZw#KkAb<N7Q&6bIPge-+$Gw*17EWd3}TBpF}or
|
||||||
|
ztF{!X+LO-)o@5?)YxmvW{H9&itfS1VFYhY*Qrf*wJIXb;6xT!R*k$yCb!{o<g3FvF
|
||||||
|
zw(+<74}K*4z)jA~>Cs3#V=uB4NN#U`sakZFU2HEI?ks7Dsq&ROrak#AvEH|GYk~cN
|
||||||
|
z-oYbXaZQ|4jDps_<5wf<yeb%ZH`=7N;R>H44oN*XPh1H-<59xMxzd~07FF+FO3!KO
|
||||||
|
zkzNs<^C)%5zR+;s{a_h8iyk@DSK5($fm`l$c*8Cna^fTc>i~h}zJUY22WwUg;4xU6
|
||||||
|
zE40Voz~Sl1fxqzW8!QiZceZ;vST%3pn9qkNDEBsI+pnKL20^*sWVSI3z)zY;1PmfD
|
||||||
|
zk8=M~&&^oEhq?Xq!q{llMLGBQ>t)~ra4xR!eZAQ1X^ph;*FG+*f4xJlJ!C>*eEV+r
|
||||||
|
z#z~GXOppZ=2|4(iyLmNON}QN2ao#+YHqDy{lvv2w_X*(?ul{+G5$Yp=apGx^6Q9v~
|
||||||
|
z^YKb>;`PTfcYPtQJz@VX`S#e@B<CLA>so3?a_*Ok9NBKwB4Es(@j^U%UHht?;4%Xv
|
||||||
|
NIrrxNmNc!u{{!hMI2Hf^
|
||||||
|
|
||||||
|
literal 0
|
||||||
|
HcmV?d00001
|
||||||
|
|
@ -1,374 +0,0 @@
|
|||||||
From: David Bauer <mail@david-bauer.net>
|
|
||||||
Date: Tue, 10 Sep 2019 21:07:23 +0200
|
|
||||||
Subject: ipq40xx: add support for AVM FRITZ!Repeater 1200
|
|
||||||
|
|
||||||
Signed-off-by: David Bauer <mail@david-bauer.net>
|
|
||||||
|
|
||||||
diff --git a/target/linux/ipq40xx/base-files/etc/board.d/02_network b/target/linux/ipq40xx/base-files/etc/board.d/02_network
|
|
||||||
index 6a7b09cc603a245e98c37305c1f25c2cc11694ae..01825b8bac46eec6325de00396d96307c946f975 100755
|
|
||||||
--- a/target/linux/ipq40xx/base-files/etc/board.d/02_network
|
|
||||||
+++ b/target/linux/ipq40xx/base-files/etc/board.d/02_network
|
|
||||||
@@ -39,10 +39,7 @@ ipq40xx_setup_interfaces()
|
|
||||||
ucidef_add_switch "switch0" \
|
|
||||||
"0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan"
|
|
||||||
;;
|
|
||||||
- avm,fritzrepeater-3000|\
|
|
||||||
- compex,wpj428)
|
|
||||||
- ucidef_set_interface_lan "eth0 eth1"
|
|
||||||
- ;;
|
|
||||||
+ avm,fritzrepeater-1200|\
|
|
||||||
engenius,eap1300|\
|
|
||||||
meraki,mr33|\
|
|
||||||
netgear,ex6100v2|\
|
|
||||||
@@ -50,6 +47,10 @@ ipq40xx_setup_interfaces()
|
|
||||||
zyxel,wre6606)
|
|
||||||
ucidef_set_interface_lan "eth0"
|
|
||||||
;;
|
|
||||||
+ avm,fritzrepeater-3000|\
|
|
||||||
+ compex,wpj428)
|
|
||||||
+ ucidef_set_interface_lan "eth0 eth1"
|
|
||||||
+ ;;
|
|
||||||
glinet,gl-b1300)
|
|
||||||
ucidef_set_interfaces_lan_wan "eth0" "eth1"
|
|
||||||
ucidef_add_switch "switch0" \
|
|
||||||
diff --git a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
|
|
||||||
index 5f7e5f4923f19ecd78a981be55230cfcd3779146..b0035ce8a394b6e87d7d89b9f55a6ec7c66e448e 100644
|
|
||||||
--- a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
|
|
||||||
+++ b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
|
|
||||||
@@ -148,6 +148,7 @@ case "$FIRMWARE" in
|
|
||||||
/usr/bin/fritz_cal_extract -i 1 -s 0x400 -e 0x207 -l 12064 -o /lib/firmware/$FIRMWARE $(find_mtd_chardev "urlader_config")
|
|
||||||
;;
|
|
||||||
avm,fritzbox-7530 |\
|
|
||||||
+ avm,fritzrepeater-1200 |\
|
|
||||||
avm,fritzrepeater-3000)
|
|
||||||
/usr/bin/fritz_cal_extract -i 1 -s 0x3C000 -e 0x207 -l 12064 -o /lib/firmware/$FIRMWARE $(find_mtd_chardev "urlader0") || \
|
|
||||||
/usr/bin/fritz_cal_extract -i 1 -s 0x3C800 -e 0x207 -l 12064 -o /lib/firmware/$FIRMWARE $(find_mtd_chardev "urlader0") || \
|
|
||||||
@@ -209,6 +210,7 @@ case "$FIRMWARE" in
|
|
||||||
/usr/bin/fritz_cal_extract -i 1 -s 0x400 -e 0x208 -l 12064 -o /lib/firmware/$FIRMWARE $(find_mtd_chardev "urlader_config")
|
|
||||||
;;
|
|
||||||
avm,fritzbox-7530 |\
|
|
||||||
+ avm,fritzrepeater-1200 |\
|
|
||||||
avm,fritzrepeater-3000)
|
|
||||||
/usr/bin/fritz_cal_extract -i 1 -s 0x3C800 -e 0x208 -l 12064 -o /lib/firmware/$FIRMWARE $(find_mtd_chardev "urlader0") || \
|
|
||||||
/usr/bin/fritz_cal_extract -i 1 -s 0x3D000 -e 0x208 -l 12064 -o /lib/firmware/$FIRMWARE $(find_mtd_chardev "urlader0") || \
|
|
||||||
diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
|
|
||||||
index 2abafabbd0589c07bcd2ceee766d3d7675ba9716..a7b7da1bf378f7cc19e960c497bc52efb3bae4fb 100644
|
|
||||||
--- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
|
|
||||||
+++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
|
|
||||||
@@ -49,6 +49,7 @@ platform_do_upgrade() {
|
|
||||||
8dev,jalapeno |\
|
|
||||||
alfa-network,ap120c-ac |\
|
|
||||||
avm,fritzbox-7530 |\
|
|
||||||
+ avm,fritzrepeater-1200 |\
|
|
||||||
avm,fritzrepeater-3000 |\
|
|
||||||
qxwlan,e2600ac-c2)
|
|
||||||
nand_do_upgrade "$1"
|
|
||||||
diff --git a/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4019-fritzrepeater-1200.dts b/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4019-fritzrepeater-1200.dts
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..4d02f8a8384f386c92c70ef24b677ee95058a1bf
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4019-fritzrepeater-1200.dts
|
|
||||||
@@ -0,0 +1,262 @@
|
|
||||||
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
|
|
||||||
+
|
|
||||||
+#include "qcom-ipq4019.dtsi"
|
|
||||||
+#include <dt-bindings/gpio/gpio.h>
|
|
||||||
+#include <dt-bindings/input/input.h>
|
|
||||||
+#include <dt-bindings/soc/qcom,tcsr.h>
|
|
||||||
+
|
|
||||||
+/ {
|
|
||||||
+ model = "AVM FRITZ!Repeater 1200";
|
|
||||||
+ compatible = "avm,fritzrepeater-1200";
|
|
||||||
+
|
|
||||||
+ aliases {
|
|
||||||
+ led-boot = &power_green;
|
|
||||||
+ led-failsafe = &power_red;
|
|
||||||
+ led-running = &power_green;
|
|
||||||
+ led-upgrade = &power_red;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ soc {
|
|
||||||
+ mdio@90000 {
|
|
||||||
+ status = "okay";
|
|
||||||
+ pinctrl-0 = <&mdio_pins>;
|
|
||||||
+ pinctrl-names = "default";
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ tcsr@1949000 {
|
|
||||||
+ compatible = "qcom,tcsr";
|
|
||||||
+ reg = <0x1949000 0x100>;
|
|
||||||
+ qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ ess_tcsr@1953000 {
|
|
||||||
+ compatible = "qcom,tcsr";
|
|
||||||
+ reg = <0x1953000 0x1000>;
|
|
||||||
+ qcom,ess-interface-select = <TCSR_ESS_PSGMII_RGMII5>;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ tcsr@1957000 {
|
|
||||||
+ compatible = "qcom,tcsr";
|
|
||||||
+ reg = <0x1957000 0x100>;
|
|
||||||
+ qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ crypto@8e3a000 {
|
|
||||||
+ status = "okay";
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ watchdog@b017000 {
|
|
||||||
+ status = "okay";
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ ess-switch@c000000 {
|
|
||||||
+ switch_mac_mode = <0x3>; /* mac mode for RGMII RMII */
|
|
||||||
+ switch_lan_bmp = <0x0>; /* lan port bitmap */
|
|
||||||
+ switch_wan_bmp = <0x10>; /* wan port bitmap */
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ edma@c080000 {
|
|
||||||
+ status = "okay";
|
|
||||||
+ phy-mode = "rgmii-rxid";
|
|
||||||
+ qcom,num_gmac = <1>;
|
|
||||||
+ qcom,single-phy;
|
|
||||||
+ };
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ key {
|
|
||||||
+ compatible = "gpio-keys";
|
|
||||||
+
|
|
||||||
+ wps {
|
|
||||||
+ label = "WPS button";
|
|
||||||
+ gpios = <&tlmm 10 GPIO_ACTIVE_LOW>;
|
|
||||||
+ linux,code = <KEY_WPS_BUTTON>;
|
|
||||||
+ };
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ leds {
|
|
||||||
+ compatible = "gpio-leds";
|
|
||||||
+
|
|
||||||
+ power_red: power_red {
|
|
||||||
+ label = "fritzwlan-1200:red:power";
|
|
||||||
+ gpios = <&tlmm 50 GPIO_ACTIVE_LOW>;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ power_green: power_green {
|
|
||||||
+ label = "fritzwlan-1200:green:power";
|
|
||||||
+ gpios = <&tlmm 45 GPIO_ACTIVE_HIGH>;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ power_yellow {
|
|
||||||
+ label = "fritzwlan-1200:yellow:power";
|
|
||||||
+ gpios = <&tlmm 49 GPIO_ACTIVE_LOW>;
|
|
||||||
+ };
|
|
||||||
+ };
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+&tlmm {
|
|
||||||
+ serial_0_pins: serial_pinmux {
|
|
||||||
+ mux {
|
|
||||||
+ pins = "gpio16", "gpio17";
|
|
||||||
+ function = "blsp_uart0";
|
|
||||||
+ bias-disable;
|
|
||||||
+ };
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ nand_pins: nand_pins {
|
|
||||||
+ pullups {
|
|
||||||
+ pins = "gpio53", "gpio58", "gpio59";
|
|
||||||
+ function = "qpic";
|
|
||||||
+ bias-pull-up;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ pulldowns {
|
|
||||||
+ pins = "gpio54", "gpio55", "gpio56",
|
|
||||||
+ "gpio57", "gpio60", "gpio61",
|
|
||||||
+ "gpio62", "gpio63", "gpio64",
|
|
||||||
+ "gpio65", "gpio66", "gpio67",
|
|
||||||
+ "gpio68", "gpio69";
|
|
||||||
+ function = "qpic";
|
|
||||||
+ bias-pull-down;
|
|
||||||
+ };
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ mdio_pins: mdio_pinmux {
|
|
||||||
+ mux_1 {
|
|
||||||
+ pins = "gpio6";
|
|
||||||
+ function = "mdio";
|
|
||||||
+ bias-pull-up;
|
|
||||||
+ };
|
|
||||||
+ mux_2 {
|
|
||||||
+ pins = "gpio7";
|
|
||||||
+ function = "mdc";
|
|
||||||
+ bias-pull-up;
|
|
||||||
+ };
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ phy-reset {
|
|
||||||
+ line-name = "PHY-reset";
|
|
||||||
+ gpios = <19 GPIO_ACTIVE_HIGH>;
|
|
||||||
+ gpio-hog;
|
|
||||||
+ output-high;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ phy-reset-2 {
|
|
||||||
+ line-name = "PHY-reset-2";
|
|
||||||
+ gpios = <47 GPIO_ACTIVE_HIGH>;
|
|
||||||
+ gpio-hog;
|
|
||||||
+ output-high;
|
|
||||||
+ };
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+&nand {
|
|
||||||
+ pinctrl-0 = <&nand_pins>;
|
|
||||||
+ pinctrl-names = "default";
|
|
||||||
+ status = "okay";
|
|
||||||
+
|
|
||||||
+ nand@0 {
|
|
||||||
+ partitions {
|
|
||||||
+ compatible = "fixed-partitions";
|
|
||||||
+ #address-cells = <1>;
|
|
||||||
+ #size-cells = <1>;
|
|
||||||
+
|
|
||||||
+ partition@0 {
|
|
||||||
+ label = "SBL1";
|
|
||||||
+ reg = <0x000000 0x80000>;
|
|
||||||
+ read-only;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ partition@80000 {
|
|
||||||
+ label = "MIBIB";
|
|
||||||
+ reg = <0x080000 0x80000>;
|
|
||||||
+ read-only;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ partition@100000 {
|
|
||||||
+ label = "QSEE";
|
|
||||||
+ reg = <0x100000 0x80000>;
|
|
||||||
+ read-only;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ partition@180000 {
|
|
||||||
+ label = "CDT";
|
|
||||||
+ reg = <0x180000 0x40000>;
|
|
||||||
+ read-only;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ partition@1c0000 {
|
|
||||||
+ label = "QSEE_B";
|
|
||||||
+ reg = <0x1c0000 0x80000>;
|
|
||||||
+ read-only;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ partition@240000 {
|
|
||||||
+ label = "urlader0";
|
|
||||||
+ reg = <0x240000 0x40000>;
|
|
||||||
+ read-only;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ partition@280000 {
|
|
||||||
+ label = "urlader1";
|
|
||||||
+ reg = <0x280000 0x40000>;
|
|
||||||
+ read-only;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ partition@2c0000 {
|
|
||||||
+ label = "nand-tffs";
|
|
||||||
+ reg = <0x2c0000 0x840000>;
|
|
||||||
+ read-only;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ partition@b00000 {
|
|
||||||
+ /* 'kernel1' in AVM firmware */
|
|
||||||
+ label = "uboot0";
|
|
||||||
+ reg = <0xb00000 0x400000>;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ partition@f00000 {
|
|
||||||
+ /* 'kernel2' in AVM firmware */
|
|
||||||
+ label = "uboot1";
|
|
||||||
+ reg = <0xf00000 0x400000>;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ partition@1300000 {
|
|
||||||
+ label = "ubi";
|
|
||||||
+ reg = <0x1300000 0x6d00000>;
|
|
||||||
+ };
|
|
||||||
+ };
|
|
||||||
+ };
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+&cryptobam {
|
|
||||||
+ status = "okay";
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+&blsp_dma {
|
|
||||||
+ status = "okay";
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+&blsp1_uart1 {
|
|
||||||
+ pinctrl-0 = <&serial_0_pins>;
|
|
||||||
+ pinctrl-names = "default";
|
|
||||||
+ status = "okay";
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+&qpic_bam {
|
|
||||||
+ status = "okay";
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+&wifi0 {
|
|
||||||
+ status = "okay";
|
|
||||||
+ qcom,ath10k-calibration-variant = "AVM-FRITZRepeater-1200";
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+&wifi1 {
|
|
||||||
+ status = "okay";
|
|
||||||
+ qcom,ath10k-calibration-variant = "AVM-FRITZRepeater-1200";
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+&gmac0 {
|
|
||||||
+ qcom,phy_mdio_addr = <0>;
|
|
||||||
+ qcom,poll_required = <1>;
|
|
||||||
+ vlan_tag = <0 0x20>;
|
|
||||||
+};
|
|
||||||
diff --git a/target/linux/ipq40xx/image/Makefile b/target/linux/ipq40xx/image/Makefile
|
|
||||||
index 3a9b58de4f01f17ac9df368729035d630eb32b04..bdbbcbe851e60ee5a445c576a870a87a46c57fee 100644
|
|
||||||
--- a/target/linux/ipq40xx/image/Makefile
|
|
||||||
+++ b/target/linux/ipq40xx/image/Makefile
|
|
||||||
@@ -138,6 +138,15 @@ define Device/avm_fritzbox-7530
|
|
||||||
endef
|
|
||||||
TARGET_DEVICES += avm_fritzbox-7530
|
|
||||||
|
|
||||||
+define Device/avm_fritzrepeater-1200
|
|
||||||
+ $(call Device/FitImageLzma)
|
|
||||||
+ DEVICE_DTS := qcom-ipq4019-fritzrepeater-1200
|
|
||||||
+ DEVICE_TITLE := AVM Fritz!Repeater 1200
|
|
||||||
+ DEVICE_PACKAGES := fritz-caldata fritz-tffs-nand ipq-wifi-avm_fritzrepeater-1200
|
|
||||||
+ IMAGES := sysupgrade.bin
|
|
||||||
+endef
|
|
||||||
+TARGET_DEVICES += avm_fritzrepeater-1200
|
|
||||||
+
|
|
||||||
define Device/avm_fritzrepeater-3000
|
|
||||||
$(call Device/FitImageLzma)
|
|
||||||
DEVICE_DTS := qcom-ipq4019-fritzrepeater-3000
|
|
||||||
diff --git a/target/linux/ipq40xx/patches-4.14/901-arm-boot-add-dts-files.patch b/target/linux/ipq40xx/patches-4.14/901-arm-boot-add-dts-files.patch
|
|
||||||
index bb539155e98b75df5dd88e39f6405af5a82e0320..f7efd415f1f1c000867793b3b133e44b3e50b0fd 100644
|
|
||||||
--- a/target/linux/ipq40xx/patches-4.14/901-arm-boot-add-dts-files.patch
|
|
||||||
+++ b/target/linux/ipq40xx/patches-4.14/901-arm-boot-add-dts-files.patch
|
|
||||||
@@ -10,7 +10,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
|
||||||
|
|
||||||
--- a/arch/arm/boot/dts/Makefile
|
|
||||||
+++ b/arch/arm/boot/dts/Makefile
|
|
||||||
-@@ -697,7 +697,30 @@ dtb-$(CONFIG_ARCH_QCOM) += \
|
|
||||||
+@@ -697,7 +697,31 @@ dtb-$(CONFIG_ARCH_QCOM) += \
|
|
||||||
qcom-apq8074-dragonboard.dtb \
|
|
||||||
qcom-apq8084-ifc6540.dtb \
|
|
||||||
qcom-apq8084-mtp.dtb \
|
|
||||||
@@ -30,6 +30,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
|
||||||
+ qcom-ipq4019-a62.dtb \
|
|
||||||
+ qcom-ipq4019-ap.dk04.1-c1.dtb \
|
|
||||||
+ qcom-ipq4019-fritzbox-7530.dtb \
|
|
||||||
++ qcom-ipq4019-fritzrepeater-1200.dtb \
|
|
||||||
+ qcom-ipq4019-fritzrepeater-3000.dtb \
|
|
||||||
+ qcom-ipq4019-linksys_ea8300.dtb \
|
|
||||||
+ qcom-ipq4019-map-ac2200.dtb \
|
|
646
patches/openwrt/0008-ipq40xx-add-support-for-Aruba-AP-303.patch
Normal file
646
patches/openwrt/0008-ipq40xx-add-support-for-Aruba-AP-303.patch
Normal file
@ -0,0 +1,646 @@
|
|||||||
|
From: David Bauer <mail@david-bauer.net>
|
||||||
|
Date: Wed, 23 Oct 2019 22:25:14 +0200
|
||||||
|
Subject: ipq40xx: add support for Aruba AP-303
|
||||||
|
|
||||||
|
Hardware
|
||||||
|
--------
|
||||||
|
|
||||||
|
SoC: Qualcomm IPQ4029
|
||||||
|
RAM: 512M DDR3
|
||||||
|
FLASH: - 128MB NAND (Macronix MX30LF1G18AC)
|
||||||
|
- 4MB SPI-NOR (Macronix MX25R3235F)
|
||||||
|
TPM: Atmel AT97SC3203
|
||||||
|
BLE: Texas Instruments CC2540T
|
||||||
|
attached to ttyMSM0
|
||||||
|
ETH: Atheros AR8035
|
||||||
|
LED: WiFi (amber / green)
|
||||||
|
System (red / green)
|
||||||
|
BTN: Reset
|
||||||
|
|
||||||
|
To connect to the serial console, you can solder to the labled pads next
|
||||||
|
to the USB port or use your Aruba supplied UARt adapter.
|
||||||
|
|
||||||
|
Do NOT plug a standard USB cable into the Console labled USB-port!
|
||||||
|
Aruba/HPE simply put UART on the micro-USB pins. You can solder yourself
|
||||||
|
an adapter cable:
|
||||||
|
|
||||||
|
VCC - NC
|
||||||
|
D+ - TX
|
||||||
|
D- - RX
|
||||||
|
GND - GND
|
||||||
|
|
||||||
|
The console setting in bootloader and OS is 9600 8N1. Voltage level is
|
||||||
|
3.3V.
|
||||||
|
|
||||||
|
To enable a full list of commands in the U-Boot "help" command, execute
|
||||||
|
the literal "diag" command.
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
1. Get the OpenWrt initramfs image. Rename it to ipq40xx.ari and put it
|
||||||
|
into the TFTP server root directory. Configure the TFTP server to
|
||||||
|
be reachable at 192.168.1.75/24. Connect the machine running the TFTP
|
||||||
|
server to the ethernet port of the access point.
|
||||||
|
|
||||||
|
2. Connect to the serial console. Interrupt autobooting by pressing
|
||||||
|
Enter when prompted.
|
||||||
|
|
||||||
|
3. Configure the bootargs and bootcmd for OpenWrt.
|
||||||
|
$ setenv bootargs_openwrt "setenv bootargs console=ttyMSM1,9600n8"
|
||||||
|
$ setenv nandboot_openwrt "run bootargs_openwrt; ubi part aos1;
|
||||||
|
ubi read 0x85000000 kernel; bootm 0x85000000"
|
||||||
|
$ setenv ramboot_openwrt "run bootargs_openwrt;
|
||||||
|
setenv ipaddr 192.168.1.105; setenv serverip 192.168.1.75;
|
||||||
|
netget; set fdt_high 0x87000000; bootm"
|
||||||
|
$ setenv bootcmd "run nandboot_openwrt"
|
||||||
|
$ saveenv
|
||||||
|
|
||||||
|
4. Load OpenWrt into RAM:
|
||||||
|
$ run ramboot_openwrt
|
||||||
|
|
||||||
|
5. After OpenWrt booted, transfer the OpenWrt sysupgrade image to the
|
||||||
|
/tmp folder on the device.
|
||||||
|
|
||||||
|
6. Flash OpenWrt:
|
||||||
|
$ ubidetach -p /dev/mtd1
|
||||||
|
$ ubiformat /dev/mtd1
|
||||||
|
$ sysupgrade -n /tmp/openwrt-sysupgrade.bin
|
||||||
|
|
||||||
|
To go back to the stock firmware, simply reset the bootcmd in the
|
||||||
|
bootloader to the original value:
|
||||||
|
|
||||||
|
$ setenv bootcmd "boot"
|
||||||
|
$ saveenv
|
||||||
|
|
||||||
|
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||||
|
(cherry picked from commit 102c8c55f217606cdbdc9a449667e034676b3e75)
|
||||||
|
|
||||||
|
diff --git a/target/linux/ipq40xx/base-files/etc/board.d/02_network b/target/linux/ipq40xx/base-files/etc/board.d/02_network
|
||||||
|
index 01825b8bac46eec6325de00396d96307c946f975..49dd570242533068adf2c9df89e78560ba5f70eb 100755
|
||||||
|
--- a/target/linux/ipq40xx/base-files/etc/board.d/02_network
|
||||||
|
+++ b/target/linux/ipq40xx/base-files/etc/board.d/02_network
|
||||||
|
@@ -39,6 +39,7 @@ ipq40xx_setup_interfaces()
|
||||||
|
ucidef_add_switch "switch0" \
|
||||||
|
"0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan"
|
||||||
|
;;
|
||||||
|
+ aruba,ap-303|\
|
||||||
|
avm,fritzrepeater-1200|\
|
||||||
|
engenius,eap1300|\
|
||||||
|
meraki,mr33|\
|
||||||
|
diff --git a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
|
||||||
|
index b0035ce8a394b6e87d7d89b9f55a6ec7c66e448e..15a2f2c09f8a92cc0accfbf9a977dbeb3355570d 100644
|
||||||
|
--- a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
|
||||||
|
+++ b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
|
||||||
|
@@ -137,6 +137,10 @@ case "$FIRMWARE" in
|
||||||
|
qcom,ap-dk01.1-c1)
|
||||||
|
ath10kcal_extract "ART" 4096 12064
|
||||||
|
;;
|
||||||
|
+ aruba,ap-303)
|
||||||
|
+ ath10kcal_extract "ART" 4096 12064
|
||||||
|
+ ath10kcal_patch_mac_crc $(mtd_get_mac_binary mfginfo 29)
|
||||||
|
+ ;;
|
||||||
|
asus,map-ac2200)
|
||||||
|
ath10kcal_ubi_extract "Factory" 4096 12064
|
||||||
|
;;
|
||||||
|
@@ -199,6 +203,10 @@ case "$FIRMWARE" in
|
||||||
|
qcom,ap-dk01.1-c1)
|
||||||
|
ath10kcal_extract "ART" 20480 12064
|
||||||
|
;;
|
||||||
|
+ aruba,ap-303)
|
||||||
|
+ ath10kcal_extract "ART" 20480 12064
|
||||||
|
+ ath10kcal_patch_mac_crc $(macaddr_add $(mtd_get_mac_binary mfginfo 29) +1)
|
||||||
|
+ ;;
|
||||||
|
asus,map-ac2200)
|
||||||
|
ath10kcal_ubi_extract "Factory" 20480 12064
|
||||||
|
;;
|
||||||
|
diff --git a/target/linux/ipq40xx/base-files/etc/inittab b/target/linux/ipq40xx/base-files/etc/inittab
|
||||||
|
index 809bba5e5ff49869429c91cf791cea73ab67d14e..3181021a0592720657b815c3eac803a57f4ea438 100644
|
||||||
|
--- a/target/linux/ipq40xx/base-files/etc/inittab
|
||||||
|
+++ b/target/linux/ipq40xx/base-files/etc/inittab
|
||||||
|
@@ -2,3 +2,4 @@
|
||||||
|
::sysinit:/etc/init.d/rcS S boot
|
||||||
|
::shutdown:/etc/init.d/rcS K shutdown
|
||||||
|
ttyMSM0::askfirst:/usr/libexec/login.sh
|
||||||
|
+ttyMSM1::askfirst:/usr/libexec/login.sh
|
||||||
|
diff --git a/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh b/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh
|
||||||
|
index be4b6322cb6a91f489dfec237ac6b79ce079e0eb..a0dec1042a3dd7416ece3307666c8ecf9d15d277 100644
|
||||||
|
--- a/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh
|
||||||
|
+++ b/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh
|
||||||
|
@@ -4,6 +4,7 @@ set_preinit_iface() {
|
||||||
|
. /lib/functions.sh
|
||||||
|
|
||||||
|
case $(board_name) in
|
||||||
|
+ aruba,ap-303| \
|
||||||
|
asus,rt-ac58u| \
|
||||||
|
avm,fritzbox-4040| \
|
||||||
|
glinet,gl-b1300| \
|
||||||
|
diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
|
||||||
|
index a7b7da1bf378f7cc19e960c497bc52efb3bae4fb..7253139497a8a8b9fab49cef3fce5eabe98d8002 100644
|
||||||
|
--- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
|
||||||
|
+++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
|
||||||
|
@@ -48,6 +48,7 @@ platform_do_upgrade() {
|
||||||
|
case "$(board_name)" in
|
||||||
|
8dev,jalapeno |\
|
||||||
|
alfa-network,ap120c-ac |\
|
||||||
|
+ aruba,ap-303 |\
|
||||||
|
avm,fritzbox-7530 |\
|
||||||
|
avm,fritzrepeater-1200 |\
|
||||||
|
avm,fritzrepeater-3000 |\
|
||||||
|
diff --git a/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4029-ap-303.dts b/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4029-ap-303.dts
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..7929494d027aca5c696910232a36d484f5ce6562
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4029-ap-303.dts
|
||||||
|
@@ -0,0 +1,418 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||||
|
+
|
||||||
|
+#include "qcom-ipq4019.dtsi"
|
||||||
|
+#include <dt-bindings/gpio/gpio.h>
|
||||||
|
+#include <dt-bindings/input/input.h>
|
||||||
|
+#include <dt-bindings/soc/qcom,tcsr.h>
|
||||||
|
+
|
||||||
|
+/ {
|
||||||
|
+ model = "Aruba AP-303";
|
||||||
|
+ compatible = "aruba,ap-303";
|
||||||
|
+
|
||||||
|
+ aliases {
|
||||||
|
+ led-boot = &led_system_green;
|
||||||
|
+ led-failsafe = &led_system_red;
|
||||||
|
+ led-running = &led_system_green;
|
||||||
|
+ led-upgrade = &led_system_red;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ memory {
|
||||||
|
+ device_type = "memory";
|
||||||
|
+ reg = <0x80000000 0x10000000>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ soc {
|
||||||
|
+ mdio@90000 {
|
||||||
|
+ status = "okay";
|
||||||
|
+ pinctrl-0 = <&mdio_pins>;
|
||||||
|
+ pinctrl-names = "default";
|
||||||
|
+
|
||||||
|
+ /delete-node/ ethernet-phy@0;
|
||||||
|
+ /delete-node/ ethernet-phy@2;
|
||||||
|
+ /delete-node/ ethernet-phy@3;
|
||||||
|
+ /delete-node/ ethernet-phy@4;
|
||||||
|
+
|
||||||
|
+ ethernet-phy@5 {
|
||||||
|
+ reg = <0x5>;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ counter@4a1000 {
|
||||||
|
+ compatible = "qcom,qca-gcnt";
|
||||||
|
+ reg = <0x4a1000 0x4>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ ess_tcsr@1953000 {
|
||||||
|
+ compatible = "qcom,tcsr";
|
||||||
|
+ reg = <0x1953000 0x1000>;
|
||||||
|
+ qcom,ess-interface-select = <TCSR_ESS_PSGMII_RGMII5>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ tcsr@1949000 {
|
||||||
|
+ compatible = "qcom,tcsr";
|
||||||
|
+ reg = <0x1949000 0x100>;
|
||||||
|
+ qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ tcsr@1957000 {
|
||||||
|
+ compatible = "qcom,tcsr";
|
||||||
|
+ reg = <0x1957000 0x100>;
|
||||||
|
+ qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ blsp1_uart2: serial@78b0000 {
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ crypto@8e3a000 {
|
||||||
|
+ status = "okay";
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ watchdog@b017000 {
|
||||||
|
+ status = "okay";
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ ess-switch@c000000 {
|
||||||
|
+ switch_mac_mode = <0x3>; /* mac mode for RGMII RMII */
|
||||||
|
+ switch_lan_bmp = <0x0>; /* lan port bitmap */
|
||||||
|
+ switch_wan_bmp = <0x10>; /* wan port bitmap */
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ edma@c080000 {
|
||||||
|
+ qcom,single-phy;
|
||||||
|
+ qcom,num_gmac = <1>;
|
||||||
|
+ phy-mode = "rgmii-id";
|
||||||
|
+ status = "okay";
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ i2c_0: i2c@78b7000 {
|
||||||
|
+ pinctrl-0 = <&i2c_0_pins>;
|
||||||
|
+ pinctrl-names = "default";
|
||||||
|
+ status = "ok";
|
||||||
|
+
|
||||||
|
+ tpm@29 {
|
||||||
|
+ /* No Driver */
|
||||||
|
+ compatible = "atmel,at97sc3203";
|
||||||
|
+ reg = <0x29>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ leds {
|
||||||
|
+ compatible = "gpio-leds";
|
||||||
|
+
|
||||||
|
+ wifi_green {
|
||||||
|
+ label = "ap-303:green:wifi";
|
||||||
|
+ gpios = <&tlmm 39 GPIO_ACTIVE_HIGH>;
|
||||||
|
+ linux,default-trigger = "phy0tpt";
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ wifi_amber {
|
||||||
|
+ label = "ap-303:amber:wifi";
|
||||||
|
+ gpios = <&tlmm 40 GPIO_ACTIVE_HIGH>;
|
||||||
|
+ linux,default-trigger = "phy1tpt";
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ led_system_red: system_red {
|
||||||
|
+ label = "ap-303:red:system";
|
||||||
|
+ gpios = <&tlmm 46 GPIO_ACTIVE_HIGH>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ led_system_green: system_green {
|
||||||
|
+ label = "ap-303:green:system";
|
||||||
|
+ gpios = <&tlmm 47 GPIO_ACTIVE_HIGH>;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ keys {
|
||||||
|
+ compatible = "gpio-keys";
|
||||||
|
+
|
||||||
|
+ reset {
|
||||||
|
+ label = "Reset button";
|
||||||
|
+ gpios = <&tlmm 50 GPIO_ACTIVE_LOW>;
|
||||||
|
+ linux,code = <KEY_RESTART>;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+&blsp_dma {
|
||||||
|
+ status = "okay";
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+&blsp1_uart1 {
|
||||||
|
+ /* Texas Instruments CC2540T BLE radio */
|
||||||
|
+ pinctrl-0 = <&serial_0_pins>;
|
||||||
|
+ pinctrl-names = "default";
|
||||||
|
+ status = "okay";
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+&blsp1_uart2 {
|
||||||
|
+ pinctrl-0 = <&serial_1_pins>;
|
||||||
|
+ pinctrl-names = "default";
|
||||||
|
+ status = "okay";
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+&cryptobam {
|
||||||
|
+ status = "okay";
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+&gmac0 {
|
||||||
|
+ qcom,phy_mdio_addr = <5>;
|
||||||
|
+ qcom,poll_required = <1>;
|
||||||
|
+ vlan_tag = <0 0x20>;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+&qpic_bam {
|
||||||
|
+ status = "okay";
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+&tlmm {
|
||||||
|
+ /*
|
||||||
|
+ * In addition to the Pins listed below,
|
||||||
|
+ * the following GPIOs have "features":
|
||||||
|
+ * 54 - out - active low to force HW reset
|
||||||
|
+ * 41 - out - active low to reset TPM
|
||||||
|
+ * 43 - out - active low to reset BLE radio
|
||||||
|
+ * 19 - in - active high when DC powered
|
||||||
|
+ */
|
||||||
|
+ mdio_pins: mdio_pinmux {
|
||||||
|
+ mux_1 {
|
||||||
|
+ pins = "gpio6";
|
||||||
|
+ function = "mdio";
|
||||||
|
+ bias-pull-up;
|
||||||
|
+ };
|
||||||
|
+ mux_2 {
|
||||||
|
+ pins = "gpio7";
|
||||||
|
+ function = "mdc";
|
||||||
|
+ bias-pull-up;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ nand_pins: nand_pins {
|
||||||
|
+ pullups {
|
||||||
|
+ pins = "gpio53", "gpio58", "gpio59";
|
||||||
|
+ function = "qpic";
|
||||||
|
+ bias-pull-up;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ pulldowns {
|
||||||
|
+ pins = "gpio54", "gpio55", "gpio56",
|
||||||
|
+ "gpio57", "gpio60", "gpio61",
|
||||||
|
+ "gpio62", "gpio63", "gpio64",
|
||||||
|
+ "gpio65", "gpio66", "gpio67",
|
||||||
|
+ "gpio68", "gpio69";
|
||||||
|
+ function = "qpic";
|
||||||
|
+ bias-pull-down;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ spi_0_pins: spi_0_pinmux {
|
||||||
|
+ pin {
|
||||||
|
+ function = "blsp_spi0";
|
||||||
|
+ pins = "gpio13", "gpio14", "gpio15";
|
||||||
|
+ drive-strength = <12>;
|
||||||
|
+ bias-disable;
|
||||||
|
+ };
|
||||||
|
+ pin_cs {
|
||||||
|
+ function = "gpio";
|
||||||
|
+ pins = "gpio12";
|
||||||
|
+ drive-strength = <2>;
|
||||||
|
+ bias-disable;
|
||||||
|
+ output-high;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ i2c_0_pins: i2c_0_pinmux {
|
||||||
|
+ mux {
|
||||||
|
+ pins = "gpio10", "gpio11";
|
||||||
|
+ function = "blsp_i2c0";
|
||||||
|
+ drive-strength = <4>;
|
||||||
|
+ bias-disable;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ serial_0_pins: serial_0_pinmux {
|
||||||
|
+ mux {
|
||||||
|
+ pins = "gpio16", "gpio17";
|
||||||
|
+ function = "blsp_uart0";
|
||||||
|
+ bias-disable;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ serial_1_pins: serial_1_pinmux {
|
||||||
|
+ mux {
|
||||||
|
+ pins = "gpio8", "gpio9";
|
||||||
|
+ function = "blsp_uart1";
|
||||||
|
+ bias-disable;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ phy-reset {
|
||||||
|
+ line-name = "PHY-reset";
|
||||||
|
+ gpios = <42 GPIO_ACTIVE_HIGH>;
|
||||||
|
+ gpio-hog;
|
||||||
|
+ output-high;
|
||||||
|
+ };
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+&nand {
|
||||||
|
+ pinctrl-0 = <&nand_pins>;
|
||||||
|
+ pinctrl-names = "default";
|
||||||
|
+ status = "okay";
|
||||||
|
+
|
||||||
|
+ nand@0 {
|
||||||
|
+ partitions {
|
||||||
|
+ compatible = "fixed-partitions";
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <1>;
|
||||||
|
+
|
||||||
|
+ partition@0 {
|
||||||
|
+ /* 'aos0' in Aruba firmware */
|
||||||
|
+ label = "aos0";
|
||||||
|
+ reg = <0x0 0x2000000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@2000000 {
|
||||||
|
+ /* 'aos1' in AVM firmware */
|
||||||
|
+ label = "ubi";
|
||||||
|
+ reg = <0x2000000 0x2000000>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@4000000 {
|
||||||
|
+ label = "aruba-ubifs";
|
||||||
|
+ reg = <0x4000000 0x4000000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+&blsp1_spi1 {
|
||||||
|
+ pinctrl-0 = <&spi_0_pins>;
|
||||||
|
+ pinctrl-names = "default";
|
||||||
|
+ status = "okay";
|
||||||
|
+ cs-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
|
||||||
|
+
|
||||||
|
+ flash@0 {
|
||||||
|
+ compatible = "jedec,spi-nor";
|
||||||
|
+ reg = <0>;
|
||||||
|
+ spi-max-frequency = <24000000>;
|
||||||
|
+
|
||||||
|
+ partitions {
|
||||||
|
+ compatible = "fixed-partitions";
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <1>;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * There is no partition map for the NOR flash
|
||||||
|
+ * in the stock firmware.
|
||||||
|
+ *
|
||||||
|
+ * All partitions here are based on offsets
|
||||||
|
+ * found in the U-Boot GPL code and information
|
||||||
|
+ * from smem.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ partition@0 {
|
||||||
|
+ label = "sbl1";
|
||||||
|
+ reg = <0x0 0x40000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@40000 {
|
||||||
|
+ label = "mibib";
|
||||||
|
+ reg = <0x40000 0x20000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@60000 {
|
||||||
|
+ label = "qsee";
|
||||||
|
+ reg = <0x60000 0x60000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@c0000 {
|
||||||
|
+ label = "cdt";
|
||||||
|
+ reg = <0xc0000 0x10000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@d0000 {
|
||||||
|
+ label = "ddrparams";
|
||||||
|
+ reg = <0xd0000 0x10000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@e0000 {
|
||||||
|
+ label = "ART";
|
||||||
|
+ reg = <0xe0000 0x10000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@f0000 {
|
||||||
|
+ label = "appsbl";
|
||||||
|
+ reg = <0xf0000 0xf0000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@1e0000 {
|
||||||
|
+ label = "mfginfo";
|
||||||
|
+ reg = <0x1e0000 0x10000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@1f0000 {
|
||||||
|
+ label = "apcd";
|
||||||
|
+ reg = <0x1f0000 0x10000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@200000 {
|
||||||
|
+ label = "osss";
|
||||||
|
+ reg = <0x200000 0x180000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@380000 {
|
||||||
|
+ /* This is empty */
|
||||||
|
+ label = "appsblenv";
|
||||||
|
+ reg = <0x380000 0x10000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@390000 {
|
||||||
|
+ label = "pds";
|
||||||
|
+ reg = <0x390000 0x10000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@3a0000 {
|
||||||
|
+ label = "fcache";
|
||||||
|
+ reg = <0x3a0000 0x10000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@3b0000 {
|
||||||
|
+ /* Called osss1 in smem */
|
||||||
|
+ label = "u-boot-env-bak";
|
||||||
|
+ reg = <0x3b0000 0x10000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@3f0000 {
|
||||||
|
+ label = "u-boot-env";
|
||||||
|
+ reg = <0x3f0000 0x10000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+&wifi0 {
|
||||||
|
+ status = "okay";
|
||||||
|
+ qcom,ath10k-calibration-variant = "Aruba-AP-303";
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+&wifi1 {
|
||||||
|
+ status = "okay";
|
||||||
|
+ qcom,ath10k-calibration-variant = "Aruba-AP-303";
|
||||||
|
+};
|
||||||
|
diff --git a/target/linux/ipq40xx/image/Makefile b/target/linux/ipq40xx/image/Makefile
|
||||||
|
index 98c81726d9c12bd466df2150c3e98a76cfb46f78..68dcbc59a42f6d8360b87c7b4e74cd34f697b465 100644
|
||||||
|
--- a/target/linux/ipq40xx/image/Makefile
|
||||||
|
+++ b/target/linux/ipq40xx/image/Makefile
|
||||||
|
@@ -85,6 +85,15 @@ define Device/alfa-network_ap120c-ac
|
||||||
|
endef
|
||||||
|
TARGET_DEVICES += alfa-network_ap120c-ac
|
||||||
|
|
||||||
|
+define Device/aruba_ap-303
|
||||||
|
+ $(call Device/FitImageLzma)
|
||||||
|
+ DEVICE_TITLE := Aruba AP-303
|
||||||
|
+ DEVICE_DTS := qcom-ipq4029-ap-303
|
||||||
|
+ DEVICE_PACKAGES := ipq-wifi-aruba_ap-303
|
||||||
|
+ IMAGES := sysupgrade.bin
|
||||||
|
+endef
|
||||||
|
+TARGET_DEVICES += aruba_ap-303
|
||||||
|
+
|
||||||
|
define Device/asus_map-ac2200
|
||||||
|
$(call Device/FitImageLzma)
|
||||||
|
DEVICE_DTS := qcom-ipq4019-map-ac2200
|
||||||
|
diff --git a/target/linux/ipq40xx/patches-4.14/304-mtd-spi-nor-Add-support-for-mx25r3235f.patch b/target/linux/ipq40xx/patches-4.14/304-mtd-spi-nor-Add-support-for-mx25r3235f.patch
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..d95923a1610d4764538e79bb783702903edcdcad
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/target/linux/ipq40xx/patches-4.14/304-mtd-spi-nor-Add-support-for-mx25r3235f.patch
|
||||||
|
@@ -0,0 +1,26 @@
|
||||||
|
+From 158acdbf0336f601971637f988b57a6a67a0869b Mon Sep 17 00:00:00 2001
|
||||||
|
+From: David Bauer <mail@david-bauer.net>
|
||||||
|
+Date: Sun, 15 Dec 2019 13:10:50 +0100
|
||||||
|
+Subject: [PATCH] mtd: spi-nor: Add support for mx25r3235f
|
||||||
|
+
|
||||||
|
+Add MTD support for the Macronix MX25R3235F SPI NOR chip from Macronix.
|
||||||
|
+The chip has 4MB of total capacity, divided into a total of 64 sectors,
|
||||||
|
+each 64KB sized. The chip also supports 4KB large sectors.
|
||||||
|
+Additionally, it supports dual and quad read modes.
|
||||||
|
+
|
||||||
|
+Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||||
|
+---
|
||||||
|
+ drivers/mtd/spi-nor/spi-nor.c | 2 ++
|
||||||
|
+ 1 file changed, 2 insertions(+)
|
||||||
|
+
|
||||||
|
+--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||||
|
++++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||||
|
+@@ -1024,6 +1024,8 @@ static const struct flash_info spi_nor_i
|
||||||
|
+ { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) },
|
||||||
|
+ { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) },
|
||||||
|
+ { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
|
||||||
|
++ { "mx25r3235f", INFO(0xc22816, 0, 64 * 1024, 64,
|
||||||
|
++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||||
|
+ { "mx25u3235f", INFO(0xc22536, 0, 64 * 1024, 64, 0) },
|
||||||
|
+ { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4, SECT_4K) },
|
||||||
|
+ { "mx25u4035", INFO(0xc22533, 0, 64 * 1024, 8, SECT_4K) },
|
||||||
|
diff --git a/target/linux/ipq40xx/patches-4.14/901-arm-boot-add-dts-files.patch b/target/linux/ipq40xx/patches-4.14/901-arm-boot-add-dts-files.patch
|
||||||
|
index f7efd415f1f1c000867793b3b133e44b3e50b0fd..fc8a88336491c2ac7c2a93fafb1f2b6fd38695be 100644
|
||||||
|
--- a/target/linux/ipq40xx/patches-4.14/901-arm-boot-add-dts-files.patch
|
||||||
|
+++ b/target/linux/ipq40xx/patches-4.14/901-arm-boot-add-dts-files.patch
|
||||||
|
@@ -10,7 +10,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
||||||
|
|
||||||
|
--- a/arch/arm/boot/dts/Makefile
|
||||||
|
+++ b/arch/arm/boot/dts/Makefile
|
||||||
|
-@@ -697,7 +697,31 @@ dtb-$(CONFIG_ARCH_QCOM) += \
|
||||||
|
+@@ -697,7 +697,32 @@ dtb-$(CONFIG_ARCH_QCOM) += \
|
||||||
|
qcom-apq8074-dragonboard.dtb \
|
||||||
|
qcom-apq8084-ifc6540.dtb \
|
||||||
|
qcom-apq8084-mtp.dtb \
|
||||||
|
@@ -37,6 +37,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
||||||
|
+ qcom-ipq4019-qxwlan-e2600ac-c1.dtb \
|
||||||
|
+ qcom-ipq4019-qxwlan-e2600ac-c2.dtb \
|
||||||
|
+ qcom-ipq4028-wpj428.dtb \
|
||||||
|
++ qcom-ipq4029-ap-303.dtb \
|
||||||
|
+ qcom-ipq4029-gl-b1300.dtb \
|
||||||
|
+ qcom-ipq4029-mr33.dtb \
|
||||||
|
qcom-ipq8064-ap148.dtb \
|
@ -31,14 +31,14 @@ sanitize() {
|
|||||||
echo -n "$v"
|
echo -n "$v"
|
||||||
}
|
}
|
||||||
|
|
||||||
vars=
|
vars=()
|
||||||
|
|
||||||
for feature in $1; do
|
for feature in $1; do
|
||||||
if [ "$(type -t gluon_feature_nodefault_${feature})" != 'function' ]; then
|
if [ "$(type -t "gluon_feature_nodefault_${feature}")" != 'function' ]; then
|
||||||
echo "gluon-${feature}"
|
echo "gluon-${feature}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
vars="$vars $(sanitize "$feature")=1"
|
vars+=("$(sanitize "$feature")=1")
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
@ -46,18 +46,19 @@ nodefault() {
|
|||||||
:
|
:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2086
|
||||||
packages() {
|
packages() {
|
||||||
local cond="$(sanitize "$1")"
|
local cond="$(sanitize "$1")"
|
||||||
shift
|
shift
|
||||||
|
|
||||||
# We only allow variable names, parentheses and the operators: & | !
|
# We only allow variable names, parentheses and the operators: & | !
|
||||||
if [ "$(expr match "$cond" '.*[^A-Za-z0-9_()&|! ].*')" -gt 0 ]; then
|
if grep -q '[^A-Za-z0-9_()&|! ]' <<< "$cond"; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Let will return false when the result of the passed expression is 0,
|
# Let will return false when the result of the passed expression is 0,
|
||||||
# so we always add 1. This way false is only returned for syntax errors.
|
# so we always add 1. This way false is only returned for syntax errors.
|
||||||
local ret="$(env -i $vars bash --norc -ec "let _result_='1+($cond)'; echo -n \"\$_result_\"" 2>/dev/null)"
|
local ret="$(env -i "${vars[@]}" bash --norc -ec "let _result_='1+($cond)'; echo -n \"\$_result_\"" 2>/dev/null)"
|
||||||
case "$ret" in
|
case "$ret" in
|
||||||
2)
|
2)
|
||||||
for pkg in "$@"; do
|
for pkg in "$@"; do
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
check_command() {
|
check_command() {
|
||||||
which "$1" >/dev/null 2>&1
|
command -v "$1" >/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
if check_command gnustat; then
|
if check_command gnustat; then
|
||||||
|
5
scripts/lint-lua.sh
Executable file
5
scripts/lint-lua.sh
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
luacheck package scripts targets
|
28
scripts/lint-sh.sh
Executable file
28
scripts/lint-sh.sh
Executable file
@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
is_scriptfile() {
|
||||||
|
echo "$1" | grep -qE '.*\.sh$' || head -n1 "$1" | grep -qE '^#.*(sh|bash)$'
|
||||||
|
}
|
||||||
|
|
||||||
|
find contrib -type f | while read -r file; do
|
||||||
|
is_scriptfile "$file" || continue
|
||||||
|
|
||||||
|
echo "Checking $file"
|
||||||
|
shellcheck -f gcc "$file"
|
||||||
|
done
|
||||||
|
|
||||||
|
find package -type f | while read -r file; do
|
||||||
|
is_scriptfile "$file" || continue
|
||||||
|
|
||||||
|
echo "Checking $file"
|
||||||
|
shellcheck -f gcc -x -s sh -e SC2039,SC1091,SC2155,SC2034 "$file"
|
||||||
|
done
|
||||||
|
|
||||||
|
find scripts -type f | while read -r file; do
|
||||||
|
is_scriptfile "$file" || continue
|
||||||
|
|
||||||
|
echo "Checking $file"
|
||||||
|
shellcheck -f gcc -x -e SC2154,SC1090,SC2181,SC2155,SC2148,SC2034,SC2148 "$file"
|
||||||
|
done
|
@ -1,6 +1,7 @@
|
|||||||
. ./modules
|
. ./modules
|
||||||
[ ! -f "$GLUON_SITEDIR"/modules ] || . "$GLUON_SITEDIR"/modules
|
[ ! -f "$GLUON_SITEDIR"/modules ] || . "$GLUON_SITEDIR"/modules
|
||||||
|
|
||||||
|
# shellcheck disable=SC2086
|
||||||
FEEDS="$(echo $GLUON_FEEDS $GLUON_SITE_FEEDS | tr ' ' '\n')"
|
FEEDS="$(echo $GLUON_FEEDS $GLUON_SITE_FEEDS | tr ' ' '\n')"
|
||||||
|
|
||||||
GLUON_MODULES=openwrt
|
GLUON_MODULES=openwrt
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
set -e
|
set -e
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
|
|
||||||
[ "$GLUON_TMPDIR" -a "$GLUON_PATCHESDIR" ] || exit 1
|
[ "$GLUON_TMPDIR" ] && [ "$GLUON_PATCHESDIR" ] || exit 1
|
||||||
|
|
||||||
. scripts/modules.sh
|
. scripts/modules.sh
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
check_command() {
|
check_command() {
|
||||||
which "$1" >/dev/null 2>&1
|
command -v "$1" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
if check_command sha256sum; then
|
if check_command sha256sum; then
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
check_command() {
|
check_command() {
|
||||||
which "$1" >/dev/null 2>&1
|
command -v "$1" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
if check_command sha512sum; then
|
if check_command sha512sum; then
|
||||||
|
@ -13,13 +13,13 @@ GLUONDIR="$(pwd)"
|
|||||||
for module in $GLUON_MODULES; do
|
for module in $GLUON_MODULES; do
|
||||||
echo "--- Updating patches for module '$module' ---"
|
echo "--- Updating patches for module '$module' ---"
|
||||||
|
|
||||||
rm -rf "${GLUON_PATCHESDIR}/$module"
|
rm -rf "${GLUON_PATCHESDIR:?}/$module"
|
||||||
|
|
||||||
cd "$GLUONDIR"/"$module"
|
cd "$GLUONDIR"/"$module"
|
||||||
|
|
||||||
n=0
|
n=0
|
||||||
for commit in $(git rev-list --reverse --no-merges base..patched); do
|
for commit in $(git rev-list --reverse --no-merges base..patched); do
|
||||||
let n=n+1
|
(( ++n ))
|
||||||
mkdir -p "${GLUON_PATCHESDIR}/$module"
|
mkdir -p "${GLUON_PATCHESDIR}/$module"
|
||||||
git -c core.abbrev=40 show --pretty=format:'From: %an <%ae>%nDate: %aD%nSubject: %B' --no-renames --binary "$commit" > "${GLUON_PATCHESDIR}/$module/$(printf '%04u' $n)-$(git show -s --pretty=format:%f "$commit").patch"
|
git -c core.abbrev=40 show --pretty=format:'From: %an <%ae>%nDate: %aD%nSubject: %B' --no-renames --binary "$commit" > "${GLUON_PATCHESDIR}/$module/$(printf '%04u' $n)-$(git show -s --pretty=format:%f "$commit").patch"
|
||||||
done
|
done
|
||||||
|
@ -10,9 +10,9 @@ GLUONDIR="$(pwd)"
|
|||||||
for module in $GLUON_MODULES; do
|
for module in $GLUON_MODULES; do
|
||||||
echo "--- Updating module '$module' ---"
|
echo "--- Updating module '$module' ---"
|
||||||
var=$(echo "$module" | tr '[:lower:]/' '[:upper:]_')
|
var=$(echo "$module" | tr '[:lower:]/' '[:upper:]_')
|
||||||
eval repo=\${${var}_REPO}
|
eval 'repo=${'"${var}"'_REPO}'
|
||||||
eval branch=\${${var}_BRANCH}
|
eval 'branch=${'"${var}"'_BRANCH}'
|
||||||
eval commit=\${${var}_COMMIT}
|
eval 'commit=${'"${var}"'_COMMIT}'
|
||||||
|
|
||||||
mkdir -p "$GLUONDIR/$module"
|
mkdir -p "$GLUONDIR/$module"
|
||||||
cd "$GLUONDIR/$module"
|
cd "$GLUONDIR/$module"
|
||||||
|
@ -4,18 +4,21 @@ config 'CONFIG_TARGET_SQUASHFS_BLOCK_SIZE=64'
|
|||||||
local ATH10K_PACKAGES = {
|
local ATH10K_PACKAGES = {
|
||||||
'kmod-ath10k',
|
'kmod-ath10k',
|
||||||
'-kmod-ath10k-ct',
|
'-kmod-ath10k-ct',
|
||||||
|
'-kmod-ath10k-ct-smallbuffers',
|
||||||
'ath10k-firmware-qca988x',
|
'ath10k-firmware-qca988x',
|
||||||
'-ath10k-firmware-qca988x-ct',
|
'-ath10k-firmware-qca988x-ct',
|
||||||
}
|
}
|
||||||
local ATH10K_PACKAGES_QCA9887 = {
|
local ATH10K_PACKAGES_QCA9887 = {
|
||||||
'kmod-ath10k',
|
'kmod-ath10k',
|
||||||
'-kmod-ath10k-ct',
|
'-kmod-ath10k-ct',
|
||||||
|
'-kmod-ath10k-ct-smallbuffers',
|
||||||
'ath10k-firmware-qca9887',
|
'ath10k-firmware-qca9887',
|
||||||
'-ath10k-firmware-qca9887-ct',
|
'-ath10k-firmware-qca9887-ct',
|
||||||
}
|
}
|
||||||
local ATH10K_PACKAGES_QCA9888 = {
|
local ATH10K_PACKAGES_QCA9888 = {
|
||||||
'kmod-ath10k',
|
'kmod-ath10k',
|
||||||
'-kmod-ath10k-ct',
|
'-kmod-ath10k-ct',
|
||||||
|
'-kmod-ath10k-ct-smallbuffers',
|
||||||
'ath10k-firmware-qca9888',
|
'ath10k-firmware-qca9888',
|
||||||
'-ath10k-firmware-qca9888-ct',
|
'-ath10k-firmware-qca9888-ct',
|
||||||
}
|
}
|
||||||
@ -99,7 +102,7 @@ device('d-link-dir-825-rev-b1', 'dir-825-b1', {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
-- GL Innovations
|
-- GL.iNet
|
||||||
|
|
||||||
device('gl-inet-6408a-v1', 'gl-inet-6408A-v1')
|
device('gl-inet-6408a-v1', 'gl-inet-6408A-v1')
|
||||||
|
|
||||||
@ -154,6 +157,7 @@ device('netgear-wndr3700v2', 'wndr3700v2', {
|
|||||||
})
|
})
|
||||||
|
|
||||||
device('netgear-wndr3800', 'wndr3800', {
|
device('netgear-wndr3800', 'wndr3800', {
|
||||||
|
aliases = {'netgear-wndr3800chmychart'},
|
||||||
factory_ext = '.img',
|
factory_ext = '.img',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,10 +1,63 @@
|
|||||||
|
local ATH10K_PACKAGES_QCA9880 = {
|
||||||
|
'kmod-ath10k',
|
||||||
|
'-kmod-ath10k-ct',
|
||||||
|
'-kmod-ath10k-ct-smallbuffers',
|
||||||
|
'ath10k-firmware-qca988x',
|
||||||
|
'-ath10k-firmware-qca988x-ct',
|
||||||
|
}
|
||||||
|
|
||||||
local ATH10K_PACKAGES_QCA9888 = {
|
local ATH10K_PACKAGES_QCA9888 = {
|
||||||
'kmod-ath10k',
|
'kmod-ath10k',
|
||||||
'-kmod-ath10k-ct',
|
'-kmod-ath10k-ct',
|
||||||
|
'-kmod-ath10k-ct-smallbuffers',
|
||||||
'ath10k-firmware-qca9888',
|
'ath10k-firmware-qca9888',
|
||||||
'-ath10k-firmware-qca9888-ct',
|
'-ath10k-firmware-qca9888-ct',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- devolo
|
||||||
|
|
||||||
|
device('devolo-wifi-pro-1200e', 'devolo_dvl1200e', {
|
||||||
|
packages = ATH10K_PACKAGES_QCA9880,
|
||||||
|
factory = false,
|
||||||
|
})
|
||||||
|
|
||||||
|
device('devolo-wifi-pro-1200i', 'devolo_dvl1200i', {
|
||||||
|
packages = ATH10K_PACKAGES_QCA9880,
|
||||||
|
factory = false,
|
||||||
|
})
|
||||||
|
|
||||||
|
device('devolo-wifi-pro-1750c', 'devolo_dvl1750c', {
|
||||||
|
packages = ATH10K_PACKAGES_QCA9880,
|
||||||
|
factory = false,
|
||||||
|
})
|
||||||
|
|
||||||
|
device('devolo-wifi-pro-1750e', 'devolo_dvl1750e', {
|
||||||
|
packages = ATH10K_PACKAGES_QCA9880,
|
||||||
|
factory = false,
|
||||||
|
})
|
||||||
|
|
||||||
|
device('devolo-wifi-pro-1750i', 'devolo_dvl1750i', {
|
||||||
|
packages = ATH10K_PACKAGES_QCA9880,
|
||||||
|
factory = false,
|
||||||
|
})
|
||||||
|
|
||||||
|
device('devolo-wifi-pro-1750x', 'devolo_dvl1750x', {
|
||||||
|
packages = ATH10K_PACKAGES_QCA9880,
|
||||||
|
factory = false,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- GL.iNet
|
||||||
|
|
||||||
|
device('gl.inet-gl-ar300m-lite', 'glinet_gl-ar300m-lite', {
|
||||||
|
factory = false,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- OCEDO
|
||||||
|
|
||||||
|
device('ocedo-raccoon', 'ocedo_raccoon', {
|
||||||
|
factory = false,
|
||||||
|
})
|
||||||
|
|
||||||
-- TP-Link
|
-- TP-Link
|
||||||
|
|
||||||
device('tp-link-archer-c6-v2', 'tplink_archer-c6-v2', {
|
device('tp-link-archer-c6-v2', 'tplink_archer-c6-v2', {
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
include 'brcm2708.inc'
|
include 'brcm2708.inc'
|
||||||
|
|
||||||
device('raspberry-pi', 'rpi', {
|
device('raspberrypi-model-b', 'rpi', {
|
||||||
manifest_aliases = {
|
manifest_aliases = {
|
||||||
|
'raspberrypi-model-b-plus',
|
||||||
|
'raspberrypi-model-b-rev2',
|
||||||
|
|
||||||
|
-- from Gluon 2019.1 and older
|
||||||
'raspberry-pi-model-b-rev-2',
|
'raspberry-pi-model-b-rev-2',
|
||||||
'raspberry-pi-model-b-plus-rev-1.2',
|
'raspberry-pi-model-b-plus-rev-1.2',
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
include 'brcm2708.inc'
|
include 'brcm2708.inc'
|
||||||
|
|
||||||
device('raspberry-pi-2', 'rpi-2', {
|
device('raspberrypi-2-model-b', 'rpi-2', {
|
||||||
manifest_aliases = {
|
manifest_aliases = {
|
||||||
|
-- from Gluon 2019.1 and older
|
||||||
'raspberry-pi-2-model-b-rev-1.1',
|
'raspberry-pi-2-model-b-rev-1.1',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
include 'brcm2708.inc'
|
include 'brcm2708.inc'
|
||||||
|
|
||||||
device('raspberry-pi-3', 'rpi-3')
|
device('raspberrypi-3-model-b', 'rpi-3', {
|
||||||
|
manifest_aliases = {
|
||||||
|
'raspberrypi-3-model-b-plus',
|
||||||
|
|
||||||
|
-- from Gluon 2019.1 and older
|
||||||
|
'raspberry-pi-3-model-b-rev-1.2',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
@ -56,6 +56,8 @@ if envtrue.GLUON_DEBUG then
|
|||||||
config 'CONFIG_NO_STRIP=y'
|
config 'CONFIG_NO_STRIP=y'
|
||||||
config '# CONFIG_USE_STRIP is not set'
|
config '# CONFIG_USE_STRIP is not set'
|
||||||
config '# CONFIG_USE_SSTRIP is not set'
|
config '# CONFIG_USE_SSTRIP is not set'
|
||||||
|
|
||||||
|
try_config 'CONFIG_TARGET_ROOTFS_PARTSIZE=500'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
local ATH10K_PACKAGES_IPQ40XX = {
|
local ATH10K_PACKAGES_IPQ40XX = {
|
||||||
'kmod-ath10k',
|
'kmod-ath10k',
|
||||||
'-kmod-ath10k-ct',
|
'-kmod-ath10k-ct',
|
||||||
|
'-kmod-ath10k-ct-smallbuffers',
|
||||||
'ath10k-firmware-qca4019',
|
'ath10k-firmware-qca4019',
|
||||||
'-ath10k-firmware-qca4019-ct',
|
'-ath10k-firmware-qca4019-ct',
|
||||||
}
|
}
|
||||||
local ATH10K_PACKAGES_IPQ40XX_QCA9888 = {
|
local ATH10K_PACKAGES_IPQ40XX_QCA9888 = {
|
||||||
'kmod-ath10k',
|
'kmod-ath10k',
|
||||||
'-kmod-ath10k-ct',
|
'-kmod-ath10k-ct',
|
||||||
|
'-kmod-ath10k-ct-smallbuffers',
|
||||||
'ath10k-firmware-qca4019',
|
'ath10k-firmware-qca4019',
|
||||||
'-ath10k-firmware-qca4019-ct',
|
'-ath10k-firmware-qca4019-ct',
|
||||||
'ath10k-firmware-qca9888',
|
'ath10k-firmware-qca9888',
|
||||||
@ -19,6 +21,14 @@ defaults {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-- Aruba
|
||||||
|
|
||||||
|
device('aruba-ap-303', 'aruba_ap-303', {
|
||||||
|
factory = false,
|
||||||
|
aliases = {'aruba-instant-on-ap11'},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
-- AVM
|
-- AVM
|
||||||
|
|
||||||
device('avm-fritz-box-4040', 'avm_fritzbox-4040', {
|
device('avm-fritz-box-4040', 'avm_fritzbox-4040', {
|
||||||
|
@ -1,15 +1,24 @@
|
|||||||
|
device('avm-fritz-box-7360-sl', 'avm_fritz7360sl', {
|
||||||
|
factory = false,
|
||||||
|
aliases = {'avm-fritz-box-7360-v1', 'avm-fritz-box-7360-v2'},
|
||||||
|
})
|
||||||
|
|
||||||
|
device('avm-fritz-box-7362-sl', 'avm_fritz7362sl', {
|
||||||
|
factory = false,
|
||||||
|
})
|
||||||
|
|
||||||
device('avm-fritz-box-7412', 'avm_fritz7412', {
|
device('avm-fritz-box-7412', 'avm_fritz7412', {
|
||||||
factory = false,
|
factory = false,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- TP-Link
|
-- TP-Link
|
||||||
|
|
||||||
-- CAVEAT: These devices don't have a dedicated WAN port.
|
-- CAVEAT: These devices don't have a dedicated WAN port.
|
||||||
-- All ethernet ports on the device are bridged and
|
-- All ethernet ports on the device are bridged and
|
||||||
-- used as WAN ports. Clients connected to these
|
-- used as WAN ports. Clients connected to these
|
||||||
-- ports will be connected to your private network.
|
-- ports will be connected to your private network.
|
||||||
|
|
||||||
device('tp-link-td-w8970', 'tplink_tdw8970')
|
device('tp-link-td-w8970', 'tplink_tdw8970')
|
||||||
|
|
||||||
device('tp-link-td-w8980', 'tplink_tdw8980', {
|
device('tp-link-td-w8980', 'tplink_tdw8980', {
|
||||||
aliases = {'tp-link-td-w9980'},
|
aliases = {'tp-link-td-w9980'},
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
device('avm-fritz-box-7312', 'avm_fritz7312', {
|
device('avm-fritz-box-7312', 'avm_fritz7312', {
|
||||||
factory = false,
|
factory = false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
device('avm-fritz-box-7320', 'avm_fritz7320', {
|
||||||
|
factory = false,
|
||||||
|
aliases = {'avm-fritz-box-7330', 'avm-fritz-box-7330-sl'},
|
||||||
|
})
|
||||||
|
@ -4,6 +4,14 @@ device('aerohive-hiveap-330', 'hiveap-330', {
|
|||||||
factory = false,
|
factory = false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
-- Enterasys
|
||||||
|
|
||||||
|
device('enterasys-ws-ap3710i', 'ws-ap3710i', {
|
||||||
|
factory = false,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
-- OCEDO
|
-- OCEDO
|
||||||
|
|
||||||
device('ocedo-panda', 'panda', {
|
device('ocedo-panda', 'panda', {
|
||||||
|
@ -6,7 +6,7 @@ device('asus-rt-ac51u', 'rt-ac51u', {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
-- GL Innovations
|
-- GL.iNet
|
||||||
|
|
||||||
device('gl-mt300a', 'gl-mt300a', {
|
device('gl-mt300a', 'gl-mt300a', {
|
||||||
factory = false,
|
factory = false,
|
||||||
@ -31,10 +31,28 @@ device('nexx-wt3020-8m', 'wt3020-8M', {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- TP-Link
|
||||||
|
|
||||||
|
local tplink_region_suffix = ''
|
||||||
|
if (env.GLUON_REGION or '') ~= '' then
|
||||||
|
tplink_region_suffix = '-' .. env.GLUON_REGION
|
||||||
|
end
|
||||||
|
|
||||||
|
device('tp-link-archer-c2-v1', 'tplink_c2-v1', {
|
||||||
|
factory = false,
|
||||||
|
})
|
||||||
|
|
||||||
|
device('tp-link-archer-c20-v1', 'tplink_c20-v1')
|
||||||
|
|
||||||
|
device('tp-link-archer-c20i', 'ArcherC20i')
|
||||||
|
|
||||||
|
device('tp-link-archer-c50', 'ArcherC50v1', {
|
||||||
|
factory = '-squashfs-factory' .. tplink_region_suffix,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
-- Xiaomi
|
-- Xiaomi
|
||||||
|
|
||||||
device('xiaomi-miwifi-mini', 'miwifi-mini', {
|
device('xiaomi-miwifi-mini', 'miwifi-mini', {
|
||||||
factory = false,
|
factory = false,
|
||||||
broken = true, -- 2.4GHz WiFi is unstable
|
|
||||||
})
|
})
|
||||||
|
@ -12,6 +12,10 @@ device('d-link-dir-860l-b1', 'dir-860l-b1')
|
|||||||
|
|
||||||
-- Netgear
|
-- Netgear
|
||||||
|
|
||||||
|
device('netgear-ex6150', 'netgear_ex6150', {
|
||||||
|
factory_ext = '.chk',
|
||||||
|
})
|
||||||
|
|
||||||
device('netgear-r6220', 'r6220', {
|
device('netgear-r6220', 'r6220', {
|
||||||
factory_ext = '.img',
|
factory_ext = '.img',
|
||||||
})
|
})
|
||||||
|
@ -29,6 +29,13 @@ device('tp-link-archer-c50-v4', 'tplink_c50-v4', {
|
|||||||
factory = false,
|
factory = false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
device('tp-link-tl-mr3020-v3', 'tplink_tl-mr3020-v3', {
|
||||||
|
factory = false,
|
||||||
|
extra_images = {
|
||||||
|
{'-squashfs-tftp-recovery', '-bootloader', '.bin'},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
device('tp-link-tl-mr3420-v5', 'tplink_tl-mr3420-v5', {
|
device('tp-link-tl-mr3420-v5', 'tplink_tl-mr3420-v5', {
|
||||||
factory = false,
|
factory = false,
|
||||||
extra_images = {
|
extra_images = {
|
||||||
@ -36,6 +43,13 @@ device('tp-link-tl-mr3420-v5', 'tplink_tl-mr3420-v5', {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
device('tp-link-tl-wa801nd-v5', 'tplink_tl-wa801nd-v5', {
|
||||||
|
factory = false,
|
||||||
|
extra_images = {
|
||||||
|
{'-squashfs-tftp-recovery', '-bootloader', '.bin'},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
device('tp-link-tl-wr841n-v13', 'tl-wr841n-v13', {
|
device('tp-link-tl-wr841n-v13', 'tl-wr841n-v13', {
|
||||||
factory = false,
|
factory = false,
|
||||||
extra_images = {
|
extra_images = {
|
||||||
@ -43,6 +57,12 @@ device('tp-link-tl-wr841n-v13', 'tl-wr841n-v13', {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
device('tp-link-tl-wr902ac-v3', 'tplink_tl-wr902ac-v3', {
|
||||||
|
factory = false,
|
||||||
|
extra_images = {
|
||||||
|
{'-squashfs-tftp-recovery', '-bootloader', '.bin'},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
-- VoCore 2
|
-- VoCore 2
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user