Merge branch 'master' into lantiq-avm3370
This commit is contained in:
commit
3003157272
@ -7,6 +7,10 @@ insert_final_newline = true
|
||||
indent_style = tab
|
||||
charset = utf-8
|
||||
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.py]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
29
.github/workflows/lint.yml
vendored
Normal file
29
.github/workflows/lint.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
name: Lint
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
jobs:
|
||||
lua:
|
||||
name: Lua
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Install Dependencies
|
||||
run: sudo apt install lua-check
|
||||
- name: Install example site
|
||||
run: ln -s ./docs/site-example ./site
|
||||
- name: Lint Lua code
|
||||
run: make lint-lua
|
||||
|
||||
sh:
|
||||
name: Shell
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Install Dependencies
|
||||
run: sudo apt install shellcheck
|
||||
- name: Install example site
|
||||
run: ln -s ./docs/site-example ./site
|
||||
- name: Lint shell code
|
||||
run: make lint-sh
|
@ -12,6 +12,7 @@ include_files = {
|
||||
"**/*.lua",
|
||||
"package/**/luasrc/**/*",
|
||||
"targets/*",
|
||||
"package/features",
|
||||
}
|
||||
|
||||
exclude_files = {
|
||||
@ -104,3 +105,11 @@ files["targets/*"] = {
|
||||
"try_config",
|
||||
},
|
||||
}
|
||||
|
||||
files["package/features"] = {
|
||||
read_globals = {
|
||||
"_",
|
||||
"feature",
|
||||
"when",
|
||||
},
|
||||
}
|
||||
|
31
Makefile
31
Makefile
@ -28,6 +28,14 @@ GLUON_RELEASE ?= $(error GLUON_RELEASE not set. GLUON_RELEASE can be set in site
|
||||
|
||||
GLUON_DEPRECATED ?= $(error GLUON_DEPRECATED not set. Please consult the documentation)
|
||||
|
||||
ifneq ($(GLUON_BRANCH),)
|
||||
$(warning *** Warning: GLUON_BRANCH has been deprecated, please set GLUON_AUTOUPDATER_BRANCH and GLUON_AUTOUPDATER_ENABLED instead.)
|
||||
GLUON_AUTOUPDATER_BRANCH ?= $(GLUON_BRANCH)
|
||||
GLUON_AUTOUPDATER_ENABLED ?= 1
|
||||
endif
|
||||
|
||||
GLUON_AUTOUPDATER_ENABLED ?= 0
|
||||
|
||||
# initialize (possibly already user set) directory variables
|
||||
GLUON_TMPDIR ?= tmp
|
||||
GLUON_OUTPUTDIR ?= output
|
||||
@ -58,7 +66,7 @@ endef
|
||||
GLUON_VARS = \
|
||||
GLUON_RELEASE GLUON_REGION GLUON_MULTIDOMAIN GLUON_AUTOREMOVE GLUON_DEBUG GLUON_MINIFY GLUON_DEPRECATED \
|
||||
GLUON_DEVICES GLUON_TARGETSDIR GLUON_PATCHESDIR GLUON_TMPDIR GLUON_IMAGEDIR GLUON_PACKAGEDIR GLUON_DEBUGDIR \
|
||||
GLUON_SITEDIR GLUON_RELEASE GLUON_BRANCH GLUON_LANGS GLUON_BASE_FEEDS \
|
||||
GLUON_SITEDIR GLUON_RELEASE GLUON_AUTOUPDATER_BRANCH GLUON_AUTOUPDATER_ENABLED GLUON_LANGS GLUON_BASE_FEEDS \
|
||||
GLUON_TARGET BOARD SUBTARGET
|
||||
|
||||
unexport $(GLUON_VARS)
|
||||
@ -114,13 +122,6 @@ define CheckTarget
|
||||
fi
|
||||
endef
|
||||
|
||||
define CheckExternal
|
||||
if [ ! -d openwrt ]; then
|
||||
echo "You don't seem to have obtained the external repositories needed by Gluon; please call \`make update\` first!"
|
||||
exit 1
|
||||
fi
|
||||
endef
|
||||
|
||||
define CheckSite
|
||||
if ! GLUON_SITEDIR='$(GLUON_SITEDIR)' GLUON_SITE_CONFIG='$(1).conf' $(LUA) -e 'assert(dofile("scripts/site_config.lua")(os.getenv("GLUON_SITE_CONFIG")))'; then
|
||||
echo 'Your site configuration ($(1).conf) did not pass validation'
|
||||
@ -147,7 +148,7 @@ LUA := openwrt/staging_dir/hostpkg/bin/lua
|
||||
$(LUA):
|
||||
+@
|
||||
|
||||
$(CheckExternal)
|
||||
scripts/module_check.sh
|
||||
|
||||
[ -e openwrt/.config ] || $(OPENWRTMAKE) defconfig
|
||||
$(OPENWRTMAKE) tools/install
|
||||
@ -157,7 +158,7 @@ $(LUA):
|
||||
config: $(LUA) FORCE
|
||||
+@
|
||||
|
||||
$(CheckExternal)
|
||||
scripts/module_check.sh
|
||||
$(CheckTarget)
|
||||
$(foreach conf,site $(patsubst $(GLUON_SITEDIR)/%.conf,%,$(wildcard $(GLUON_SITEDIR)/domains/*.conf)),\
|
||||
$(call CheckSite,$(conf)); \
|
||||
@ -185,23 +186,23 @@ dirclean: FORCE
|
||||
|
||||
manifest: $(LUA) FORCE
|
||||
@
|
||||
[ '$(GLUON_BRANCH)' ] || (echo 'Please set GLUON_BRANCH to create a manifest.'; false)
|
||||
[ '$(GLUON_AUTOUPDATER_BRANCH)' ] || (echo 'Please set GLUON_AUTOUPDATER_BRANCH to create a manifest.'; false)
|
||||
echo '$(GLUON_PRIORITY)' | grep -qE '^([0-9]*\.)?[0-9]+$$' || (echo 'Please specify a numeric value for GLUON_PRIORITY to create a manifest.'; false)
|
||||
$(CheckExternal)
|
||||
scripts/module_check.sh
|
||||
|
||||
(
|
||||
export $(GLUON_ENV)
|
||||
echo 'BRANCH=$(GLUON_BRANCH)'
|
||||
echo 'BRANCH=$(GLUON_AUTOUPDATER_BRANCH)'
|
||||
echo "DATE=$$($(LUA) scripts/rfc3339date.lua)"
|
||||
echo 'PRIORITY=$(GLUON_PRIORITY)'
|
||||
echo
|
||||
for target in $(GLUON_TARGETS); do
|
||||
$(LUA) scripts/generate_manifest.lua "$$target"
|
||||
done
|
||||
) > 'tmp/$(GLUON_BRANCH).manifest.tmp'
|
||||
) > 'tmp/$(GLUON_AUTOUPDATER_BRANCH).manifest.tmp'
|
||||
|
||||
mkdir -p '$(GLUON_IMAGEDIR)/sysupgrade'
|
||||
mv 'tmp/$(GLUON_BRANCH).manifest.tmp' '$(GLUON_IMAGEDIR)/sysupgrade/$(GLUON_BRANCH).manifest'
|
||||
mv 'tmp/$(GLUON_AUTOUPDATER_BRANCH).manifest.tmp' '$(GLUON_IMAGEDIR)/sysupgrade/$(GLUON_AUTOUPDATER_BRANCH).manifest'
|
||||
|
||||
FORCE: ;
|
||||
|
||||
|
@ -21,7 +21,7 @@ the future development of Gluon.
|
||||
|
||||
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`
|
||||
and switch to one by running `git checkout v2020.1.3 && make update`.
|
||||
and switch to one by running `git checkout v2020.2.1 && make update`.
|
||||
|
||||
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.
|
||||
|
45
docs/_static/css/custom.css
vendored
Normal file
45
docs/_static/css/custom.css
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
This fixes the vertical position of list markers when the first
|
||||
element in the <li> is a <pre> block
|
||||
|
||||
Scrolling inside the <pre> block is still working as expected
|
||||
*/
|
||||
.rst-content pre.literal-block,
|
||||
.rst-content div[class^='highlight'] pre {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This fixes the bottom margin of paragraphs inside lists, where margins inside
|
||||
a single list item would incorrectly be displayed larger than margins between
|
||||
the list items.
|
||||
|
||||
Upstream fix (not fixed on readthedocs.io yet):
|
||||
https://github.com/readthedocs/sphinx_rtd_theme/commit/ac20ce75d426efeb40fe2af1f89ea9bad285a45b
|
||||
*/
|
||||
.rst-content .section ol li > p,
|
||||
.rst-content .section ol li > p:last-child,
|
||||
.rst-content .section ul li > p,
|
||||
.rst-content .section ul li > p:last-child {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.rst-content .section ol li > p:only-child,
|
||||
.rst-content .section ol li > p:only-child:last-child,
|
||||
.rst-content .section ul li > p:only-child,
|
||||
.rst-content .section ul li > p:only-child:last-child {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
/*
|
||||
This fixes the bottom margin of nested lists
|
||||
|
||||
Based on upstream fix (not on readthedocs.io yet):
|
||||
https://github.com/readthedocs/sphinx_rtd_theme/commit/6f0de13baff93f25204aa2cdf0308aae47d71312
|
||||
*/
|
||||
.rst-content .section ul li > ul,
|
||||
.rst-content .section ul li > ol,
|
||||
.rst-content .section ol li > ul,
|
||||
.rst-content .section ol li > ol {
|
||||
margin-bottom: 12px;
|
||||
}
|
@ -24,7 +24,7 @@ copyright = '2015-2020, Project Gluon'
|
||||
author = 'Project Gluon'
|
||||
|
||||
# The short X.Y version
|
||||
version = '2020.1+'
|
||||
version = '2020.2+'
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = version
|
||||
|
||||
@ -89,7 +89,7 @@ html_theme = 'sphinx_rtd_theme'
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
#
|
||||
# html_static_path = ['_static']
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
@ -101,6 +101,10 @@ html_theme = 'sphinx_rtd_theme'
|
||||
#
|
||||
# html_sidebars = {}
|
||||
|
||||
# These paths are either relative to html_static_path
|
||||
# or fully qualified paths (eg. https://...)
|
||||
html_css_files = ['css/custom.css']
|
||||
|
||||
|
||||
# -- Options for HTMLHelp output ---------------------------------------------
|
||||
|
||||
|
@ -23,7 +23,7 @@ GLUON_SITE_FEED
|
||||
List of site feeds; defined in file *modules* in site config
|
||||
|
||||
\*_REPO, \*_BRANCH, \*_COMMIT
|
||||
Git repository URL, branch and and
|
||||
Git repository URL, branch and
|
||||
commit ID of the feeds to use. The branch name may be omitted; the default
|
||||
branch will be used in this case.
|
||||
|
||||
@ -79,7 +79,7 @@ patch.sh
|
||||
- updating all git submodules
|
||||
|
||||
This solution with a temporary clone ensures that the timestamps of checked
|
||||
out files are not changed by any intermedidate patch steps, but only when
|
||||
out files are not changed by any intermediate patch steps, but only when
|
||||
updating the checkout with the final result. This avoids triggering unnecessary
|
||||
rebuilds.
|
||||
|
||||
|
@ -7,7 +7,7 @@ Debugging
|
||||
Kernel Oops
|
||||
-----------
|
||||
|
||||
Sometimes a running Linux kernel detects an error during runtime that canot
|
||||
Sometimes a running Linux kernel detects an error during runtime that can't
|
||||
be corrected.
|
||||
This usually generates a stack trace that points to the location in the code
|
||||
that caused the oops.
|
||||
|
@ -71,44 +71,62 @@ Feature flags
|
||||
=============
|
||||
|
||||
Feature flags provide a convenient way to define package selections without
|
||||
making it necessary to list each package explicitly.
|
||||
making it necessary to list each package explicitly. The list of features to
|
||||
enable for a Gluon build is set by the *GLUON_FEATURES* variable in *site.mk*.
|
||||
|
||||
The main feature flag definition file is ``package/features``, but each package
|
||||
feed can provide additional definitions in a file called ``features`` at the root
|
||||
of the feed repository.
|
||||
|
||||
Each flag *$flag* without any explicit definition will simply include the package
|
||||
with the name *gluon-$flag* by default. The feature definition file can modify
|
||||
the package selection in two ways:
|
||||
Each flag *$flag* will include the package the name *gluon-$flag* by default.
|
||||
The feature definition file can modify the package selection by adding or removing
|
||||
packages when certain combinations of flags are set.
|
||||
|
||||
* The *nodefault* function suppresses default of including the *gluon-$flag*
|
||||
package
|
||||
* The *packages* function adds a list of packages (or removes, when package
|
||||
names are prepended with minus signs) when a given logical expression
|
||||
is satisfied
|
||||
Feature definitions use Lua syntax. Two basic functions are defined:
|
||||
|
||||
* *feature(name, pkgs)*: Defines a new feature. *feature()* expects a feature
|
||||
(flag) name and a list of packages to add or remove when the feature is
|
||||
enabled.
|
||||
|
||||
* Defining a feature using *feature* replaces the default definition of
|
||||
just including *gluon-$flag*.
|
||||
* A package is removed when the package name is prefixed with a ``-`` (after
|
||||
the opening quotation mark).
|
||||
|
||||
* *when(expr, pkgs)*: Adds or removes packages when a given logical expression
|
||||
of feature flags is satisfied.
|
||||
|
||||
* *expr* is a logical expression composed of feature flag names (each prefixed
|
||||
with an underscore before the opening quotation mark), logical operators
|
||||
(*and*, *or*, *not*) and parentheses.
|
||||
* Referencing a feature flag in *expr* has no effect on the default handling
|
||||
of the flag. When no *feature()* entry for a flag exists, it will still
|
||||
add *gluon-$flag* by default.
|
||||
* *pkgs* is handled as for *feature()*.
|
||||
|
||||
Example::
|
||||
|
||||
nodefault 'web-wizard'
|
||||
feature('web-wizard', {
|
||||
'gluon-config-mode-hostname',
|
||||
'gluon-config-mode-geo-location',
|
||||
'gluon-config-mode-contact-info',
|
||||
'gluon-config-mode-outdoor',
|
||||
})
|
||||
|
||||
packages 'web-wizard' \
|
||||
'gluon-config-mode-hostname' \
|
||||
'gluon-config-mode-geo-location' \
|
||||
'gluon-config-mode-contact-info'
|
||||
when(_'web-wizard' and (_'mesh-vpn-fastd' or _'mesh-vpn-tunneldigger'), {
|
||||
'gluon-config-mode-mesh-vpn',
|
||||
})
|
||||
|
||||
feature('no-radvd', {
|
||||
'-gluon-radvd',
|
||||
})
|
||||
|
||||
packages 'web-wizard & (mesh-vpn-fastd | mesh-vpn-tunneldigger)' \
|
||||
'gluon-config-mode-mesh-vpn'
|
||||
|
||||
This will
|
||||
|
||||
* disable the inclusion of a (non-existent) package called *gluon-web-wizard*
|
||||
* enable three config mode packages when the *web-wizard* feature is enabled
|
||||
* disable the inclusion of the (non-existent) packages *gluon-web-wizard* and *gluon-no-radvd* when their
|
||||
corresponding feature flags appear in *GLUON_FEATURES*
|
||||
* enable four additional config mode packages when the *web-wizard* feature is enabled
|
||||
* enable *gluon-config-mode-mesh-vpn* when both *web-wizard* and one
|
||||
of *mesh-vpn-fastd* and *mesh-vpn-tunneldigger* are enabled
|
||||
|
||||
Supported syntax elements of logical expressions are:
|
||||
|
||||
* \& (and)
|
||||
* \| (or)
|
||||
* \! (not)
|
||||
* parentheses
|
||||
* disable the *gluon-radvd* package when *gluon-no-radvd* is enabled
|
||||
|
@ -13,7 +13,7 @@ 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.
|
||||
Devices, which feature a "hybrid" port (labelled as WAN/LAN), this port is used as WAN.
|
||||
|
||||
This behavior can be reversed using the ``single_as_lan`` site.conf option.
|
||||
|
||||
|
@ -7,8 +7,11 @@ Building Images
|
||||
---------------
|
||||
|
||||
By default, the autoupdater is disabled (as it is usually not helpful to have unexpected updates
|
||||
during development), but it can be enabled by setting the variable GLUON_BRANCH when building
|
||||
to override the default branch set in the site configuration.
|
||||
during development), but it can be enabled by setting the variable ``GLUON_AUTOUPDATER_ENABLED`` to ``1`` when building.
|
||||
It is also possible to override the default branch during build using the variable ``GLUON_AUTOUPDATER_BRANCH``.
|
||||
|
||||
If a default branch is set neither in *site.conf* nor via ``GLUON_AUTOUPDATER_BRANCH``, the default branch is
|
||||
implementation-defined. Currently, the branch with the first name in alphabetical order is chosen.
|
||||
|
||||
A manifest file for the updater can be generated with `make manifest`. A signing script (using
|
||||
``ecdsautils``) can be found in the `contrib` directory. When creating the manifest, the
|
||||
@ -32,15 +35,16 @@ Automated nightly builds
|
||||
|
||||
A fully automated nightly build could use the following commands:
|
||||
|
||||
::
|
||||
.. code-block:: sh
|
||||
|
||||
git pull
|
||||
(git -C site pull)
|
||||
# git -C site pull
|
||||
make update
|
||||
make clean GLUON_TARGET=ar71xx-generic
|
||||
NUM_CORES_PLUS_ONE=$(expr $(nproc) + 1)
|
||||
make -j$NUM_CORES_PLUS_ONE GLUON_TARGET=ar71xx-generic GLUON_BRANCH=experimental GLUON_RELEASE=$GLUON_RELEASE
|
||||
make manifest GLUON_BRANCH=experimental GLUON_RELEASE=$GLUON_RELEASE
|
||||
make -j$NUM_CORES_PLUS_ONE GLUON_TARGET=ar71xx-generic GLUON_RELEASE=$GLUON_RELEASE \
|
||||
GLUON_AUTOUPDATER_BRANCH=experimental GLUON_AUTOUPDATER_ENABLED=1
|
||||
make manifest GLUON_RELEASE=$GLUON_RELEASE GLUON_AUTOUPDATER_BRANCH=experimental
|
||||
contrib/sign.sh $SECRETKEY output/images/sysupgrade/experimental.manifest
|
||||
|
||||
rm -rf /where/to/put/this/experimental
|
||||
|
@ -88,18 +88,25 @@ domain of a router, if and only if one of the above conditions matches.
|
||||
Switching the domain
|
||||
--------------------
|
||||
|
||||
**via commandline**:
|
||||
Via commandline
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
::
|
||||
|
||||
uci set gluon.core.domain="newdomaincode"
|
||||
gluon-reconfigure
|
||||
reboot
|
||||
gluon-switch-domain 'newdomaincode'
|
||||
|
||||
**via config mode:**
|
||||
When the node is not in config mode, ``gluon-switch-domain`` will automatically
|
||||
reboot the node by default. This can be suppressed by passing ``--no-reboot``::
|
||||
|
||||
To allow switching the domain via config mode, ``config-mode-domain-select``
|
||||
has to be added to GLUON_FEATURES in the site.mk.
|
||||
gluon-switch-domain --no-reboot 'newdomaincode'
|
||||
|
||||
Switching the domain without reboot is currently **experimental**.
|
||||
|
||||
Via config mode
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
To allow switching the domain via config mode, add ``config-mode-domain-select``
|
||||
to GLUON_FEATURES in site.mk.
|
||||
|
||||
|image0|
|
||||
|
||||
|
@ -47,7 +47,7 @@ The resulting firmware will allow users to choose between secure (encrypted) and
|
||||
.. image:: fastd_mode.gif
|
||||
|
||||
**Unix socket:**
|
||||
To confirm whether the correct cipher is being used, fastds unix
|
||||
To confirm whether the correct cipher is being used, fastd's unix
|
||||
socket can be interrogated, after installing for example `socat`.
|
||||
|
||||
::
|
||||
|
@ -21,4 +21,6 @@ you can configure this via the uci section ``gluon-core.wireless``::
|
||||
|
||||
uci set gluon-core.@wireless[0].preserve_channels='1'
|
||||
|
||||
When channels should be preserved, toggling the outdoor mode will have no effect on the channel settings.
|
||||
Therefore, the Outdoor mode settings won't be displayed in config mode.
|
||||
Keep in mind that nodes running wifi interfaces on custom channels can't mesh with default nodes anymore!
|
||||
|
@ -78,6 +78,9 @@ Several Freifunk communities in Germany use Gluon as the foundation of their Fre
|
||||
:caption: Releases
|
||||
:maxdepth: 1
|
||||
|
||||
releases/v2020.2.1
|
||||
releases/v2020.2
|
||||
releases/v2020.1.4
|
||||
releases/v2020.1.3
|
||||
releases/v2020.1.2
|
||||
releases/v2020.1.1
|
||||
|
@ -66,7 +66,7 @@ and others which contain shapes.
|
||||
|
||||
* **default domain**
|
||||
|
||||
The default domain doesn’t hold any shapes and represents the inverted area of
|
||||
The default domain doesn't hold any shapes and represents the inverted area of
|
||||
all other shapes held by other domains with geo coordinates. It will only be
|
||||
entered if a node could not be matched to a geo domain. A suggested approach is
|
||||
to define the "old" network as default domain and gradually migrate nodes from
|
||||
|
@ -19,7 +19,7 @@ ar71xx-generic
|
||||
|
||||
- DIR-615 (C1)
|
||||
|
||||
* GL-Inet
|
||||
* GL.iNet
|
||||
|
||||
- 6408A (v1)
|
||||
- 6416A (v1)
|
||||
|
@ -21,7 +21,7 @@ ramips-mt7620
|
||||
ramips-mt76x8
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
* Gl.iNet
|
||||
* GL.iNet
|
||||
|
||||
- MT300N (v2) [#noibss]_
|
||||
|
||||
|
@ -10,7 +10,7 @@ Bugfixes
|
||||
- Fixed non-working LEDs on TP-Link Archer C5 v1 and Archer C7 v2 after an upgrade to Gluon 2020.1.
|
||||
|
||||
- Fixed an issue which leads to AVM FRITZ!WLAN Repeater 450E devices being stuck in failsafe mode
|
||||
ater an upgrade to Gluon 2020.1.
|
||||
after an upgrade to Gluon 2020.1.
|
||||
|
||||
Other changes
|
||||
-------------
|
||||
|
@ -37,7 +37,7 @@ Other changes
|
||||
Internals
|
||||
---------
|
||||
|
||||
- OpenWrt 19.07 introduced the urgnd entropy daemon that serves the same function as the haveged service, which we have been recommending. To not have two redundant entropy daemons in this release we remove urngd in favor of haveged in the v2020.1 release series.
|
||||
- OpenWrt 19.07 introduced the urngd entropy daemon that serves the same function as the haveged service, which we have been recommending. To not have two redundant entropy daemons in this release we remove urngd in favor of haveged in the v2020.1 release series.
|
||||
|
||||
Known issues
|
||||
------------
|
||||
|
47
docs/releases/v2020.1.4.rst
Normal file
47
docs/releases/v2020.1.4.rst
Normal file
@ -0,0 +1,47 @@
|
||||
Gluon 2020.1.4
|
||||
==============
|
||||
|
||||
Added hardware support
|
||||
----------------------
|
||||
|
||||
- Added support for TP-Link CPE210 3.20 (`#2080 <https://github.com/freifunk-gluon/gluon/issues/2080>`_)
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fixed a rare race-condition during mesh interface teardown (`#2057 <https://github.com/freifunk-gluon/gluon/pull/2057>`_)
|
||||
|
||||
- Fixed handling of mesh interfaces together with outdoor mode, site.conf defaults and config mode (`#2049 <https://github.com/freifunk-gluon/gluon/pull/2049>`_) (`#2054 <https://github.com/freifunk-gluon/gluon/pull/2054>`_)
|
||||
|
||||
Other changes
|
||||
-------------
|
||||
|
||||
- Linux kernel has been updated to 4.14.193
|
||||
- Backports of batman-adv bugfixes
|
||||
|
||||
Known issues
|
||||
------------
|
||||
|
||||
* Upgrading EdgeRouter-X from versions before v2020.1.x may lead to a soft-bricked state due to bad blocks on the
|
||||
NAND flash which the NAND driver before this release does not handle well.
|
||||
(`#1937 <https://github.com/freifunk-gluon/gluon/issues/1937>`_)
|
||||
|
||||
* 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).
|
47
docs/releases/v2020.2.1.rst
Normal file
47
docs/releases/v2020.2.1.rst
Normal file
@ -0,0 +1,47 @@
|
||||
Gluon 2020.2.1
|
||||
==============
|
||||
|
||||
Added hardware support
|
||||
----------------------
|
||||
|
||||
- Added support for TP-Link CPE210 3.20 (`#2080 <https://github.com/freifunk-gluon/gluon/issues/2080>`_)
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fixed handling of *mesh_on_lan* enabled in site configuration (`#2090 <https://github.com/freifunk-gluon/gluon/issues/2090>`_)
|
||||
|
||||
- Fixed build issues with lantiq-xrx200 target by removing unsupported DSL modem packages (`#2087 <https://github.com/freifunk-gluon/gluon/pull/2087>`_)
|
||||
|
||||
Other changes
|
||||
-------------
|
||||
|
||||
- Linux kernel has been updated to 4.14.193
|
||||
- Backports of batman-adv bugfixes
|
||||
|
||||
Known issues
|
||||
------------
|
||||
|
||||
* Upgrading EdgeRouter-X from versions before v2020.1.x may lead to a soft-bricked state due to bad blocks on the
|
||||
NAND flash which the NAND driver before this release does not handle well.
|
||||
(`#1937 <https://github.com/freifunk-gluon/gluon/issues/1937>`_)
|
||||
|
||||
* 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.
|
||||
|
||||
* In configurations not using VXLAN, 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).
|
198
docs/releases/v2020.2.rst
Normal file
198
docs/releases/v2020.2.rst
Normal file
@ -0,0 +1,198 @@
|
||||
Gluon 2020.2
|
||||
============
|
||||
|
||||
Added hardware support
|
||||
----------------------
|
||||
|
||||
ath79-generic
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* GL.iNet
|
||||
|
||||
- GL-AR750S
|
||||
|
||||
* TP-Link
|
||||
|
||||
- CPE220 (v3)
|
||||
|
||||
ipq40xx-generic
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
* EnGenius
|
||||
|
||||
- ENS620EXT [#outdoor]_
|
||||
|
||||
* Linksys
|
||||
|
||||
- EA6350 (v3)
|
||||
|
||||
lantiq-xrx200
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* TP-Link
|
||||
|
||||
- TD-W8970
|
||||
|
||||
lantiq-xway
|
||||
~~~~~~~~~~~
|
||||
|
||||
* NETGEAR
|
||||
|
||||
- DGN3500B
|
||||
|
||||
ramips-mt76x8
|
||||
~~~~~~~~~~~~~
|
||||
* Cudy
|
||||
|
||||
- WR1000
|
||||
|
||||
|
||||
x86-legacy [#newtarget]_
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Devices older than the Pentium 4
|
||||
|
||||
|
||||
.. [#newtarget]
|
||||
This is a new target.
|
||||
|
||||
.. [#outdoor]
|
||||
This device is supposed to be set up outdoors and will therefore have its outdoor mode flag automatically enabled.
|
||||
|
||||
|
||||
Major changes
|
||||
-------------
|
||||
|
||||
Device Classes
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Devices are now categorized into device classes. This device class can determine which features
|
||||
as well as packages are installed on the device when building images.
|
||||
|
||||
Currently there are two classes used in Gluon, *tiny* and *standard*. All devices with less than 64M of RAM or
|
||||
less than 7M of usable firmware space are assigned to the tiny class.
|
||||
|
||||
WPA3 support for Private WLAN
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The private WLAN now supports WPA3-SAE key exchange as well as management frame protection (802.11w).
|
||||
For this to work, the firmware needs to be built with the *wireless-encryption-wpa3* feature.
|
||||
|
||||
OWE on Client Network
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Gluon now allows to configure a VAP for the client network which supports opportunistic encryption on the
|
||||
client network for devices which support the OWE security type (also known as Enhanced Open).
|
||||
|
||||
This encrypted VAP can be the only available access point or be configured in addition to an unencrypted VAP.
|
||||
In the latter case, the transition mode can be enabled, which enables compatible devices to automatically
|
||||
connect to the encrypted VAP while legacy devices continue to use the unencrypted connection.
|
||||
|
||||
There are issues with some devices running Android 9 when connecting to a transition mode enabled network. See the site documentation for more information.
|
||||
|
||||
SAE Encrypted Mesh Links
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Mesh links can now be operated in an encrypted mode using SAE authentication. For this to work, a common shared secret
|
||||
has to be distributed to all participating nodes using the site.conf.
|
||||
|
||||
Responsive status page
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The status page design is now responsive and reflows better on mobile devices.
|
||||
|
||||
Primary domain code
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The primary domain code is now visible on the node status page as well as in the respondd information
|
||||
emitted by the node.
|
||||
|
||||
Logging
|
||||
~~~~~~~
|
||||
|
||||
The new *gluon-logging* package allows to configure a remote syslog server using the site.conf.
|
||||
This package can only be included when *gluon-web-logging* is excluded.
|
||||
|
||||
Peer cleanup in fastd
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
fastd peers and groups are now removed on update in case they do not exist in the new site configuration.
|
||||
To preserve a custom peer across updates, add the *preserve* key to the peer's UCI configuration and set it to ``1``.
|
||||
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- The WAN MAC address now matches the one defined in OpenWrt if VXLAN is enabled for the selected domain.
|
||||
|
||||
- *gluon-reload* now reloads all relevant services.
|
||||
|
||||
- Disabling outdoor mode and enabling meshing in the config mode can now be performed in a single step.
|
||||
|
||||
- Fixed section visibility with enabled outdoor mode in config mode.
|
||||
|
||||
|
||||
Site changes
|
||||
------------
|
||||
|
||||
site.mk
|
||||
~~~~~~~
|
||||
|
||||
Starting with version 19.07 OpenWrt ships the urngd entropy daemon by default.
|
||||
It replaces the haveged daemon, for which we removed the support in Gluon. Remove ``haveged`` from your package selection.
|
||||
|
||||
|
||||
Internal
|
||||
--------
|
||||
|
||||
Editorconfig
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Gluon now ships a *editorconfig* file to allow compatible editors to automatically apply key aspects of Gluon's code style.
|
||||
|
||||
Continuous Integration
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Jenkins
|
||||
|
||||
- The CI now has a test stage to verify Gluons runtime functionality.
|
||||
|
||||
* GitHub Actions
|
||||
|
||||
- GitHub actions is now enabled for the Gluon project, build-testing all available targets.
|
||||
|
||||
Build system
|
||||
~~~~~~~~~~~~
|
||||
|
||||
- Source code minification can now be skipped by enabling the GLUON_MINIFY flag.
|
||||
|
||||
- Enabling the GLUON_AUTOREMOVE flag will remove package build directories after they are built.
|
||||
This reduces space consumption at the expense of subsequent builds being slower.
|
||||
|
||||
|
||||
Known issues
|
||||
------------
|
||||
|
||||
* Upgrading EdgeRouter-X from versions before v2020.1.x may lead to a soft-bricked state due to bad blocks on the
|
||||
NAND flash which the NAND driver before this release does not handle well.
|
||||
(`#1937 <https://github.com/freifunk-gluon/gluon/issues/1937>`_)
|
||||
|
||||
* 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.
|
||||
|
||||
* In configurations not using VXLAN, 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).
|
@ -1,4 +1,4 @@
|
||||
-- This is an example site configuration for Gluon v2020.1.3
|
||||
-- This is an example site configuration for Gluon v2020.2.1
|
||||
--
|
||||
-- Take a look at the documentation located at
|
||||
-- https://gluon.readthedocs.io/ for details.
|
||||
@ -164,7 +164,8 @@
|
||||
},
|
||||
|
||||
autoupdater = {
|
||||
-- Default branch. Don't forget to set GLUON_BRANCH when building!
|
||||
-- Default branch (optional), can be overridden by setting GLUON_AUTOUPDATER_BRANCH when building.
|
||||
-- Set GLUON_AUTOUPDATER_ENABLED to enable the autoupdater by default for newly installed nodes.
|
||||
branch = 'stable',
|
||||
|
||||
-- List of branches. You may define multiple branches.
|
||||
|
@ -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.
|
||||
|
||||
Take a look at the `list of gluon releases`_ and notice the latest release,
|
||||
e.g. *v2020.1.3*. Always get Gluon using git and don't try to download it
|
||||
e.g. *v2020.2.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.
|
||||
|
||||
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
|
||||
version you'd like to checkout, e.g. *v2020.1.3*.
|
||||
version you'd like to checkout, e.g. *v2020.2.1*.
|
||||
|
||||
::
|
||||
|
||||
@ -171,10 +171,12 @@ usually be set on the command line or in ``site.mk``.
|
||||
Common variables
|
||||
................
|
||||
|
||||
GLUON_BRANCH
|
||||
Sets the default branch of the autoupdater. If unset, the autoupdater is disabled
|
||||
by default. For the ``make manifest`` command, GLUON_BRANCH defines the branch to
|
||||
generate a manifest for.
|
||||
GLUON_AUTOUPDATER_BRANCH
|
||||
Overrides the default branch of the autoupdater set in ``site.conf``. For the ``make manifest`` command,
|
||||
``GLUON_AUTOUPDATER_BRANCH`` defines the branch to generate a manifest for.
|
||||
|
||||
GLUON_AUTOUPDATER_ENABLED
|
||||
Set to ``1`` to enable the autoupdater by default for newly installed nodes.
|
||||
|
||||
GLUON_DEPRECATED
|
||||
Controls whether images for deprecated devices should be built. The following
|
||||
@ -225,7 +227,7 @@ GLUON_DEBUG
|
||||
similar tools. Requires a device or target with at least 16 MB of flash space, e.g. `x86-64`. Unset by default.
|
||||
|
||||
GLUON_MINIFY
|
||||
Setting ``GLUON_MINIFY=0`` will omit the minification of scripts during the build process. By
|
||||
Setting ``GLUON_MINIFY=0`` will omit the minification of scripts during the build process. By
|
||||
default the flag is set to ``1``. Disabling the flag is handy if human readable scripts on the
|
||||
devices are desired for development purposes. Be aware that this will increase the size of the
|
||||
resulting images and is therefore not suitable for devices with small flash chips.
|
||||
|
@ -176,7 +176,7 @@ wifi24 \: optional
|
||||
.. _user-site-wifi5:
|
||||
|
||||
wifi5 \: optional
|
||||
Same as `wifi24` but for the 5Ghz radio.
|
||||
Same as `wifi24` but for the 5 GHz radio.
|
||||
|
||||
Additionally a range of channels that are safe to use outsides on the 5 GHz band can
|
||||
be set up through ``outdoor_chanlist``, which allows for a space-separated list of
|
||||
@ -326,7 +326,7 @@ mesh_vpn
|
||||
implementation.
|
||||
|
||||
**Note:** It may be interesting to include the package *gluon-iptables-clamp-mss-to-pmtu*
|
||||
in the build when using *gluon-mesh-babel* to work around icmp blackholes on the internet.
|
||||
in the build when using *gluon-mesh-babel* to work around ICMP blackholes on the internet.
|
||||
|
||||
::
|
||||
|
||||
@ -418,12 +418,16 @@ poe_passthrough \: optional
|
||||
autoupdater \: package
|
||||
Configuration for the autoupdater feature of Gluon.
|
||||
|
||||
Specifying a default branch in *site.conf* is optional. See
|
||||
:doc:`../features/autoupdater` for information how to change the behaviour
|
||||
of the autoupdater during image build.
|
||||
|
||||
The mirrors are checked in random order until the manifest could be downloaded
|
||||
successfully or all mirrors have been tried.
|
||||
::
|
||||
|
||||
autoupdater = {
|
||||
branch = 'stable',
|
||||
branch = 'stable', -- optional
|
||||
branches = {
|
||||
stable = {
|
||||
name = 'stable',
|
||||
@ -464,9 +468,14 @@ config_mode \: optional
|
||||
The *geo_location.osm* section is only relevant when the *gluon-config-mode-geo-location-osm*
|
||||
package is used. The *center.lon* and *center.lat* values are mandatory in this case and
|
||||
define the default center of the map when no position has been picked yet. The *zoom* level
|
||||
defaults to 12 in this case. *openlayers_url* allows to override the base URL of the
|
||||
defaults to 12 in this case.
|
||||
|
||||
*openlayers_url* allows to override the base URL of the
|
||||
*build/ol.js* and *css/ol.css* files (the default is
|
||||
``https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.2.0``).
|
||||
It is also possible to replace the default tile layer (which is OpenStreetMap)
|
||||
with a custom one using the *tile_layer* section. Only XYZ layers are supported
|
||||
at this point.
|
||||
|
||||
The remote login page only shows SSH key configuration by default. A
|
||||
password form can be displayed by setting *remote_login.show_password_form*
|
||||
@ -488,6 +497,11 @@ config_mode \: optional
|
||||
},
|
||||
zoom = 13,
|
||||
-- openlayers_url = 'http://ffac.example.org/openlayer',
|
||||
-- tile_layer = {
|
||||
-- type = 'XYZ',
|
||||
-- url = 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
-- attributions = '© <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors.',
|
||||
-- },
|
||||
},
|
||||
},
|
||||
remote_login = {
|
||||
|
@ -44,6 +44,7 @@ ar71xx-generic
|
||||
- GL-AR150
|
||||
- GL-AR300M
|
||||
- GL-AR750
|
||||
- GL-USB150 (Microuter)
|
||||
|
||||
* Linksys
|
||||
|
||||
@ -107,9 +108,9 @@ ar71xx-generic
|
||||
- Nanostation M2/M5 [#device-class-tiny]_
|
||||
- Nanostation M2/M5 XW
|
||||
- Picostation M2 [#device-class-tiny]_
|
||||
- Rocket M2/M5
|
||||
- Rocket M2/M5 Ti
|
||||
- Rocket M2/M5 XW
|
||||
- Rocket M2
|
||||
- Rocket M2 Ti
|
||||
- Rocket M2 XW
|
||||
- UniFi AC Mesh
|
||||
- UniFi AC Mesh Pro
|
||||
- UniFi AP
|
||||
@ -229,6 +230,7 @@ ipq40xx-generic
|
||||
* AVM
|
||||
|
||||
- FRITZ!Box 4040 [#avmflash]_
|
||||
- FRITZ!Box 7530 [#eva_ramboot]_
|
||||
- FRITZ!Repeater 1200 [#eva_ramboot]_
|
||||
|
||||
* EnGenius
|
||||
@ -317,6 +319,11 @@ ramips-mt7620
|
||||
- GL-MT300N
|
||||
- GL-MT750
|
||||
|
||||
* NETGEAR
|
||||
|
||||
- EX3700
|
||||
- EX3800
|
||||
|
||||
* Nexx
|
||||
|
||||
- WT3020AD/F/H
|
||||
|
6
modules
6
modules
@ -2,15 +2,15 @@ GLUON_FEEDS='packages routing gluon'
|
||||
|
||||
OPENWRT_REPO=https://github.com/openwrt/openwrt.git
|
||||
OPENWRT_BRANCH=openwrt-19.07
|
||||
OPENWRT_COMMIT=9cafcbe0bdd601d07ed55bee0136f5d8393c37a8
|
||||
OPENWRT_COMMIT=29b4104d69bf91db17764dd885e9e111a373f08c
|
||||
|
||||
PACKAGES_PACKAGES_REPO=https://github.com/openwrt/packages.git
|
||||
PACKAGES_PACKAGES_BRANCH=openwrt-19.07
|
||||
PACKAGES_PACKAGES_COMMIT=e76090945523c71c2406276f6d42b2e7f078a2d8
|
||||
PACKAGES_PACKAGES_COMMIT=03425a0d2f5967639d15a3ef1f0407859768917d
|
||||
|
||||
PACKAGES_ROUTING_REPO=https://github.com/openwrt-routing/packages.git
|
||||
PACKAGES_ROUTING_BRANCH=openwrt-19.07
|
||||
PACKAGES_ROUTING_COMMIT=9b42e24a54f03ebb6f58224b49036e8f739b175f
|
||||
PACKAGES_ROUTING_COMMIT=b77498bd56d5e45ab4577a1f4ad6ffc55b4a86b7
|
||||
|
||||
PACKAGES_GLUON_REPO=https://github.com/freifunk-gluon/packages.git
|
||||
PACKAGES_GLUON_COMMIT=12e41d0ff07ec54bbd67a31ab50d12ca04f2238c
|
||||
|
@ -1,37 +1,52 @@
|
||||
nodefault 'web-wizard'
|
||||
|
||||
packages 'web-wizard' \
|
||||
'gluon-config-mode-hostname' \
|
||||
'gluon-config-mode-geo-location' \
|
||||
'gluon-config-mode-contact-info' \
|
||||
'gluon-config-mode-outdoor'
|
||||
|
||||
packages 'web-wizard & autoupdater' \
|
||||
'gluon-config-mode-autoupdater'
|
||||
|
||||
packages 'web-wizard & (mesh-vpn-fastd | mesh-vpn-tunneldigger)' \
|
||||
'gluon-config-mode-mesh-vpn'
|
||||
-- GLUON_FEATURES definition file
|
||||
--
|
||||
-- See the page `dev/packages` (Developer Documentation / Package development)
|
||||
-- in the `docs` directory or on gluon.readthedocs.io for information on the
|
||||
-- file format
|
||||
|
||||
|
||||
nodefault 'web-advanced'
|
||||
feature('web-wizard', {
|
||||
'gluon-config-mode-hostname',
|
||||
'gluon-config-mode-geo-location',
|
||||
'gluon-config-mode-contact-info',
|
||||
'gluon-config-mode-outdoor',
|
||||
})
|
||||
|
||||
packages 'web-advanced' \
|
||||
'gluon-web-admin' \
|
||||
'gluon-web-network' \
|
||||
'gluon-web-wifi-config'
|
||||
when(_'web-wizard' and _'autoupdater', {
|
||||
'gluon-config-mode-autoupdater',
|
||||
})
|
||||
|
||||
packages 'web-advanced & autoupdater' \
|
||||
'gluon-web-autoupdater'
|
||||
when(_'web-wizard' and (_'mesh-vpn-fastd' or _'mesh-vpn-tunneldigger'), {
|
||||
'gluon-config-mode-mesh-vpn',
|
||||
})
|
||||
|
||||
packages 'status-page & mesh-batman-adv-15' \
|
||||
'gluon-status-page-mesh-batman-adv'
|
||||
|
||||
packages 'mesh-batman-adv-15' \
|
||||
'gluon-ebtables-limit-arp' \
|
||||
'gluon-radvd'
|
||||
feature('web-advanced', {
|
||||
'gluon-web-admin',
|
||||
'gluon-web-network',
|
||||
'gluon-web-wifi-config',
|
||||
})
|
||||
|
||||
packages 'mesh-babel' \
|
||||
'gluon-radvd'
|
||||
when(_'web-advanced' and _'autoupdater', {
|
||||
'gluon-web-autoupdater',
|
||||
})
|
||||
|
||||
packages '!wireless-encryption-wpa3' \
|
||||
'hostapd-mini'
|
||||
|
||||
when(_'mesh-batman-adv-15', {
|
||||
'gluon-ebtables-limit-arp',
|
||||
'gluon-radvd',
|
||||
})
|
||||
|
||||
when(_'status-page' and _'mesh-batman-adv-15', {
|
||||
'gluon-status-page-mesh-batman-adv',
|
||||
})
|
||||
|
||||
|
||||
when(_'mesh-babel', {
|
||||
'gluon-radvd',
|
||||
})
|
||||
|
||||
|
||||
when(not _'wireless-encryption-wpa3', {
|
||||
'hostapd-mini',
|
||||
})
|
||||
|
10
package/gluon-autoupdater/Config.in
Normal file
10
package/gluon-autoupdater/Config.in
Normal file
@ -0,0 +1,10 @@
|
||||
if PACKAGE_gluon-autoupdater
|
||||
|
||||
config GLUON_AUTOUPDATER_BRANCH
|
||||
string "Autoupdater branch"
|
||||
default ""
|
||||
|
||||
config GLUON_AUTOUPDATER_ENABLED
|
||||
bool "Enable autoupdater by default"
|
||||
|
||||
endif
|
@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk
|
||||
PKG_NAME:=gluon-autoupdater
|
||||
PKG_VERSION:=4
|
||||
|
||||
PKG_CONFIG_DEPENDS := CONFIG_GLUON_BRANCH
|
||||
PKG_CONFIG_DEPENDS := CONFIG_GLUON_AUTOUPDATER_BRANCH CONFIG_GLUON_AUTOUPDATER_ENABLED
|
||||
|
||||
include ../gluon.mk
|
||||
|
||||
@ -13,19 +13,19 @@ define Package/gluon-autoupdater
|
||||
endef
|
||||
|
||||
define Package/gluon-autoupdater/config
|
||||
config GLUON_BRANCH
|
||||
string "Gluon autoupdater branch"
|
||||
depends on PACKAGE_gluon-autoupdater
|
||||
default ""
|
||||
source "$(SOURCE)/Config.in"
|
||||
endef
|
||||
|
||||
define Package/gluon-autoupdater/install
|
||||
$(Gluon/Build/Install)
|
||||
|
||||
ifneq ($(CONFIG_GLUON_BRANCH),"")
|
||||
$(INSTALL_DIR) $(1)/lib/gluon/autoupdater
|
||||
echo '$(call qstrip,$(CONFIG_GLUON_BRANCH))' > $(1)/lib/gluon/autoupdater/default_branch
|
||||
endif
|
||||
ifneq ($(CONFIG_GLUON_AUTOUPDATER_BRANCH),"")
|
||||
echo '$(call qstrip,$(CONFIG_GLUON_AUTOUPDATER_BRANCH))' > $(1)/lib/gluon/autoupdater/default_branch
|
||||
endif
|
||||
ifneq ($(CONFIG_GLUON_AUTOUPDATER_ENABLED),)
|
||||
touch $(1)/lib/gluon/autoupdater/default_enabled
|
||||
endif
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackageGluon,gluon-autoupdater))
|
||||
|
@ -1,4 +1,4 @@
|
||||
need_string(in_site({'autoupdater', 'branch'}))
|
||||
need_string(in_site({'autoupdater', 'branch'}), false)
|
||||
|
||||
need_table({'autoupdater', 'branches'}, function(branch)
|
||||
need_alphanumeric_key(branch)
|
||||
|
@ -2,8 +2,11 @@
|
||||
|
||||
local site = require 'gluon.site'
|
||||
local uci = require('simple-uci').cursor()
|
||||
local unistd = require 'posix.unistd'
|
||||
|
||||
|
||||
local min_branch
|
||||
|
||||
for name, config in pairs(site.autoupdater.branches()) do
|
||||
uci:delete('autoupdater', name)
|
||||
uci:section('autoupdater', 'branch', name, {
|
||||
@ -12,19 +15,26 @@ for name, config in pairs(site.autoupdater.branches()) do
|
||||
good_signatures = config.good_signatures,
|
||||
pubkey = config.pubkeys,
|
||||
})
|
||||
|
||||
if not min_branch or (name < min_branch) then
|
||||
min_branch = name
|
||||
end
|
||||
end
|
||||
|
||||
if not uci:get('autoupdater', 'settings') then
|
||||
local enabled = false
|
||||
local branch = site.autoupdater.branch()
|
||||
local enabled = unistd.access('/lib/gluon/autoupdater/default_enabled') ~= nil
|
||||
|
||||
local branch = site.autoupdater.branch(min_branch)
|
||||
local f = io.open('/lib/gluon/autoupdater/default_branch')
|
||||
if f then
|
||||
enabled = true
|
||||
branch = f:read('*line')
|
||||
f:close()
|
||||
end
|
||||
|
||||
if not branch then
|
||||
enabled = false
|
||||
end
|
||||
|
||||
uci:section('autoupdater', 'autoupdater', 'settings', {
|
||||
enabled = enabled,
|
||||
branch = branch,
|
||||
|
@ -40,9 +40,6 @@ uci:section('network', 'interface', 'client', {
|
||||
|
||||
uci:save('network')
|
||||
|
||||
-- TODO: remove this line and the next in 2019. Firewall zones have been renamed in 2017.
|
||||
uci:delete('firewall', 'client')
|
||||
|
||||
uci:section('firewall', 'zone', 'drop', {
|
||||
name = 'drop',
|
||||
network = {'client'},
|
||||
@ -51,9 +48,9 @@ uci:section('firewall', 'zone', 'drop', {
|
||||
forward = 'DROP',
|
||||
})
|
||||
|
||||
local networks = uci:get_list('firewall', 'local_client', 'network')
|
||||
local networks = uci:get_list('firewall', 'loc_client', 'network')
|
||||
util.add_to_set(networks, 'local_node')
|
||||
uci:set_list('firewall', 'local_client', 'network', networks)
|
||||
uci:set_list('firewall', 'loc_client', 'network', networks)
|
||||
|
||||
|
||||
local dnsmasq = uci:get_first('dhcp', 'dnsmasq')
|
||||
@ -61,10 +58,6 @@ uci:set('dhcp', dnsmasq, 'boguspriv', false)
|
||||
uci:set('dhcp', dnsmasq, 'localise_queries', false)
|
||||
uci:set('dhcp', dnsmasq, 'rebind_protection', false)
|
||||
|
||||
-- TODO: remove this line and the next two in 2019 the zones were removed in 2017
|
||||
uci:delete('dhcp', 'client')
|
||||
uci:delete('firewall', 'local_node')
|
||||
|
||||
uci:section('dhcp', 'dhcp', 'local_client', {
|
||||
interface = 'client',
|
||||
ignore = true,
|
||||
|
@ -2,3 +2,9 @@ need_number(in_site({'config_mode', 'geo_location', 'osm', 'center', 'lon'}))
|
||||
need_number(in_site({'config_mode', 'geo_location', 'osm', 'center', 'lat'}))
|
||||
need_number(in_site({'config_mode', 'geo_location', 'osm', 'zoom'}), false)
|
||||
need_string(in_site({'config_mode', 'geo_location', 'osm', 'openlayers_url'}), false)
|
||||
|
||||
if need_table(in_site({'config_mode', 'geo_location', 'osm', 'tile_layer'}), nil, false) then
|
||||
need_one_of(in_site({'config_mode', 'geo_location', 'osm', 'tile_layer', 'type'}), {'XYZ'})
|
||||
need_string(in_site({'config_mode', 'geo_location', 'osm', 'tile_layer', 'url'}))
|
||||
need_string(in_site({'config_mode', 'geo_location', 'osm', 'tile_layer', 'attributions'}))
|
||||
end
|
||||
|
@ -19,6 +19,7 @@ function M.options()
|
||||
|
||||
return {
|
||||
openlayers_url = config.openlayers_url(),
|
||||
tile_layer = config.tile_layer(),
|
||||
zoom = config.zoom(12),
|
||||
pos = config.center(),
|
||||
}
|
||||
|
@ -1,11 +1,17 @@
|
||||
return function(form, uci)
|
||||
local platform = require 'gluon.platform'
|
||||
local wireless = require 'gluon.wireless'
|
||||
|
||||
if not (platform.is_outdoor_device() and platform.device_uses_11a(uci)) then
|
||||
-- only visible on wizard for outdoor devices
|
||||
return
|
||||
end
|
||||
|
||||
if wireless.preserve_channels(uci) then
|
||||
-- Don't show if channel should be preserved
|
||||
return
|
||||
end
|
||||
|
||||
local pkg_i18n = i18n 'gluon-config-mode-outdoor'
|
||||
|
||||
local section = form:section(Section, nil, pkg_i18n.translate(
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,13 +1,13 @@
|
||||
/*
|
||||
ATTENTION: This file is not compiled when building gluon.
|
||||
The compiled version is at ../files/lib/gluon/config-mode/www/static/gluon.css
|
||||
ATTENTION: This file is not compiled when building gluon.
|
||||
The compiled version is at ../files/lib/gluon/config-mode/www/static/gluon.css
|
||||
|
||||
Use sass like this to update it:
|
||||
Use sass like this to update it:
|
||||
|
||||
sass --sourcemap=none -C -t compressed sass/gluon.scss files/lib/gluon/config-mode/www/static/gluon.css
|
||||
sass --sourcemap=none -C -t compressed sass/gluon.scss files/lib/gluon/config-mode/www/static/gluon.css
|
||||
|
||||
When commiting changes to this file make sure to commit the respective
|
||||
changes to the compilid version within the same commit!
|
||||
When commiting changes to this file make sure to commit the respective
|
||||
changes to the compilid version within the same commit!
|
||||
*/
|
||||
|
||||
@charset "utf-8";
|
||||
@ -18,624 +18,530 @@ $ffzusatz: #009ee0;
|
||||
$red: #ee3300;
|
||||
|
||||
@mixin button {
|
||||
&::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
&::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
display: inline-block;
|
||||
zoom: 1;
|
||||
line-height: normal;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
display: inline-block;
|
||||
line-height: normal;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
|
||||
font-size: 100%;
|
||||
padding: 0.5em 1em;
|
||||
color: rgba(0, 0, 0, 0.80);
|
||||
border: none rgba(0, 0, 0, 0);
|
||||
background-color: #E6E6E6;
|
||||
text-decoration: none;
|
||||
border-radius: 2px;
|
||||
font-size: 100%;
|
||||
padding: 0.5em 1em;
|
||||
color: rgba(0, 0, 0, 0.80);
|
||||
background-color: #E6E6E6;
|
||||
border: none;
|
||||
text-decoration: none;
|
||||
border-radius: 2px;
|
||||
|
||||
/* Transitions */
|
||||
transition: 0.1s linear box-shadow;
|
||||
/* Transitions */
|
||||
transition: 0.1s linear box-shadow;
|
||||
|
||||
&:active {
|
||||
box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 6px rgba(0,0,0, 0.20) inset;
|
||||
}
|
||||
&:active {
|
||||
box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 6px rgba(0,0,0, 0.20) inset;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
&:hover, &:focus {
|
||||
background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));
|
||||
}
|
||||
&:hover, &:focus {
|
||||
background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
border: none;
|
||||
background-image: none;
|
||||
opacity: 0.40;
|
||||
cursor: not-allowed;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin button-primary {
|
||||
background-color: $ffzusatz;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.lang_he {
|
||||
direction: RTL;
|
||||
unicode-bidi: embed;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
&[disabled] {
|
||||
border: none;
|
||||
background-image: none;
|
||||
opacity: 0.40;
|
||||
cursor: not-allowed;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
min-height: 100%;
|
||||
height: auto;
|
||||
position:relative;
|
||||
min-height: 100%;
|
||||
height: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
body, input, select, option {
|
||||
font-family: 'Open Sans', Arial, sans-serif;
|
||||
font-size: 12pt;
|
||||
font-family: 'Open Sans', Arial, sans-serif;
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(77, 78, 83);
|
||||
line-height: 1.5em;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
|
||||
a img {
|
||||
border: none;
|
||||
text-decoration: none;
|
||||
color: rgb(77, 78, 83);
|
||||
line-height: 1.5em;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
|
||||
.tabmenu1 {
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
ul.tabmenu {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 2em 0;
|
||||
display: inline-flex;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 2em 0;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
ul.tabmenu li {
|
||||
white-space: nowrap;
|
||||
margin: 0 0.5em;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
margin: 0 0.5em;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
padding: 1em;
|
||||
margin: 0;
|
||||
color: #333;
|
||||
border-radius: 2em;
|
||||
a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
padding: 1em;
|
||||
margin: 0;
|
||||
color: #333;
|
||||
border-radius: 2em;
|
||||
|
||||
&:hover {
|
||||
background: lighten($ffyellow, 35);
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background: lighten($ffyellow, 35);
|
||||
}
|
||||
}
|
||||
|
||||
&.active a {
|
||||
font-weight: bold;
|
||||
background: white;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
abbr,
|
||||
acronym {
|
||||
font-style: normal;
|
||||
font-variant: normal;
|
||||
}
|
||||
|
||||
abbr[title],
|
||||
acronym[title] {
|
||||
border-bottom: 1px dotted;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
a:link abbr[title],
|
||||
a:visited abbr[title],
|
||||
a:link acronym[title],
|
||||
a:visited acronym[title] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
&.active a {
|
||||
font-weight: bold;
|
||||
background: white;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
#maincontent ul {
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #ff0000;
|
||||
background-color: white;
|
||||
color: #ff0000;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#menubar {
|
||||
display: flex;
|
||||
background: $ffmagenta;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
background: $ffmagenta;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#menubar a:link.topcat,
|
||||
#menubar a:visited.topcat {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 0.5em;
|
||||
text-decoration: none;
|
||||
font-size: 80%;
|
||||
font-weight: normal;
|
||||
color: white;
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 0.5em;
|
||||
text-decoration: none;
|
||||
font-size: 80%;
|
||||
font-weight: normal;
|
||||
color: white;
|
||||
|
||||
&:hover, &:focus {
|
||||
background: $ffyellow;
|
||||
color: black;
|
||||
}
|
||||
&:hover, &:focus {
|
||||
background: $ffyellow;
|
||||
color: black;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: $ffyellow;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
&.active {
|
||||
background: $ffyellow;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
#menubar div.hostinfo {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 0.5em;
|
||||
flex: 1;
|
||||
font-weight: bold;
|
||||
font-size: 80%;
|
||||
#menubar .hostinfo {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 0.5em;
|
||||
flex: 1;
|
||||
font-weight: bold;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
#menubar div.hostinfo a {
|
||||
&:link, &:visited {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
#menubar .hostinfo a {
|
||||
&:link, &:visited {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
|
||||
&:hover, &:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
&:hover, &:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#topmenu {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#topmenu li {
|
||||
display: inline-block;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#maincontent {
|
||||
padding: 0 1em 2em;
|
||||
max-width: 60em;
|
||||
min-width: 40em;
|
||||
margin: 1em auto;
|
||||
padding: 0 1em 2em;
|
||||
max-width: 60em;
|
||||
min-width: 40em;
|
||||
margin: 1em auto;
|
||||
}
|
||||
|
||||
#maincontent p {
|
||||
margin-bottom: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.gluon-section {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
margin-bottom: 1.3em;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
margin-bottom: 1.3em;
|
||||
}
|
||||
|
||||
.gluon-section:last-child {
|
||||
margin-bottom: 0.7em;
|
||||
margin-bottom: 0.7em;
|
||||
}
|
||||
|
||||
.gluon-section legend {
|
||||
font-size: 1.4em;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5em;
|
||||
font-size: 1.4em;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.gluon-section h2 {
|
||||
margin: 0em 0 0.5em -0.5em !important;
|
||||
margin: 0em 0 0.5em -0.5em;
|
||||
}
|
||||
|
||||
.gluon-section h3 {
|
||||
text-decoration: none !important;
|
||||
font-weight: bold !important;
|
||||
color: #555555 !important;
|
||||
margin: 0.25em !important;
|
||||
font-size: 100% !important;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: #555555;
|
||||
margin: 0.25em;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
.gluon-section-descr {
|
||||
margin-bottom: 2em;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.gluon-osm-map {
|
||||
width: 100%;
|
||||
height: 40em;
|
||||
margin-bottom: 1em;
|
||||
width: 100%;
|
||||
height: 40em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
input:placeholder {
|
||||
color: #aaaaaa;
|
||||
input::placeholder {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
input:-webkit-input-placeholder {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
input:-moz-placeholder {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
input:-ms-input-placeholder {
|
||||
color: #aaaaaa;
|
||||
input::-webkit-input-placeholder {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
input[type=checkbox] {
|
||||
display: none;
|
||||
display: none;
|
||||
|
||||
& + label {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin: 0;
|
||||
}
|
||||
& + label {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&:checked + label:after {
|
||||
content: '✔';
|
||||
color: $ffmagenta;
|
||||
vertical-align: middle;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
margin-top: -0.5em;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 1.7em;
|
||||
}
|
||||
&:checked + label::after {
|
||||
content: '✔';
|
||||
color: $ffmagenta;
|
||||
vertical-align: middle;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
margin-top: -0.5em;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 1.7em;
|
||||
}
|
||||
}
|
||||
|
||||
input[type=radio] {
|
||||
display: none;
|
||||
display: none;
|
||||
|
||||
& + label {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
padding: 0.5em;
|
||||
margin: 0.2em 0.2em 0.2em 0.1em;
|
||||
border: none;
|
||||
background: lighten($ffyellow, 30);
|
||||
vertical-align: middle;
|
||||
border-radius: 50%;
|
||||
}
|
||||
& + label {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
padding: 0.5em;
|
||||
margin: 0.2em 0.2em 0.2em 0.1em;
|
||||
border: none;
|
||||
background: lighten($ffyellow, 30);
|
||||
vertical-align: middle;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&:checked + label:after {
|
||||
content: '•';
|
||||
color: $ffmagenta;
|
||||
vertical-align: middle;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
margin-top: -0.4em;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
}
|
||||
&:checked + label::after {
|
||||
content: '•';
|
||||
color: $ffmagenta;
|
||||
vertical-align: middle;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
margin-top: -0.4em;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
input[type=submit],
|
||||
input[type=reset],
|
||||
input[type=image],
|
||||
input[type=button] {
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select,
|
||||
input,
|
||||
textarea,
|
||||
input[type=checkbox] + label {
|
||||
color: darken($ffzusatz, 30);
|
||||
border: none;
|
||||
background: lighten($ffyellow, 30);
|
||||
border-radius: 3pt;
|
||||
padding: 0.5em;
|
||||
margin-top: 1px;
|
||||
margin-bottom: 2px;
|
||||
box-sizing: content-box;
|
||||
outline: 0;
|
||||
color: darken($ffzusatz, 30);
|
||||
border: none;
|
||||
background: lighten($ffyellow, 30);
|
||||
border-radius: 3pt;
|
||||
padding: 0.5em;
|
||||
margin-top: 1px;
|
||||
margin-bottom: 2px;
|
||||
box-sizing: content-box;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.select-wrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
right: 0.05em;
|
||||
top: calc(2px + 0.1em);
|
||||
bottom: calc(2px + 0.1em);
|
||||
width: 1.4em;
|
||||
border-left: 0.05em solid rgba(0, 0, 0, 0.25);
|
||||
pointer-events: none;
|
||||
background:
|
||||
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="8" height="5"><path fill="none" stroke="black" stroke-linejoin="bevel" d="M1,1L4,4L7,1"/></svg>')
|
||||
center / 0.8em 0.5em
|
||||
no-repeat
|
||||
;
|
||||
content: '';
|
||||
}
|
||||
|
||||
select {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
color: darken($ffzusatz, 30);
|
||||
background: lighten($ffyellow, 30);
|
||||
}
|
||||
|
||||
input[type=image] {
|
||||
border: none;
|
||||
color: darken($ffzusatz, 30);
|
||||
background: lighten($ffyellow, 30);
|
||||
}
|
||||
|
||||
select,
|
||||
input[type=text],
|
||||
input[type=password] {
|
||||
min-width: 20em;
|
||||
min-width: 20em;
|
||||
}
|
||||
|
||||
input.gluon-button {
|
||||
@include button;
|
||||
.gluon-button {
|
||||
@include button;
|
||||
|
||||
margin-left: 0.5em;
|
||||
background-repeat: no-repeat;
|
||||
margin-left: 0.5em;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
input.gluon-button-reset {
|
||||
background-color: $red;
|
||||
color: #fff;
|
||||
}
|
||||
input.gluon-button-submit {
|
||||
@include button-primary;
|
||||
.gluon-button-reset {
|
||||
background-color: $red;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
input.gluon-button-submit:active {
|
||||
background: grey;
|
||||
.gluon-button-submit {
|
||||
background-color: $ffzusatz;
|
||||
color: #fff;
|
||||
}
|
||||
.gluon-button-submit:active {
|
||||
background: grey;
|
||||
}
|
||||
|
||||
.gluon-input-invalid {
|
||||
background: $red !important;
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.gluon-section-remove input {
|
||||
border-bottom: none;
|
||||
background: $red !important;
|
||||
color: white;
|
||||
}
|
||||
|
||||
textarea {
|
||||
margin-left: -1px;
|
||||
margin-bottom: 0.5em;
|
||||
margin-left: -1px;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.gluon-section .gluon-rowstyle-1 h3 {
|
||||
background-color: #eeeeff;
|
||||
color: #555555;
|
||||
}
|
||||
|
||||
.gluon-rowstyle-2 {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
div.gluon-value {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 0.5em;
|
||||
.gluon-value {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.gluon-section-node .gluon-value:last-child {
|
||||
margin-bottom: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.gluon-value-title {
|
||||
flex: 2;
|
||||
text-align: right;
|
||||
padding-top: 0.39em;
|
||||
padding-right: 1em;
|
||||
font-weight: bold;
|
||||
flex: 2;
|
||||
text-align: right;
|
||||
padding-top: 0.39em;
|
||||
padding-right: 1em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.gluon-value-field {
|
||||
flex: 3;
|
||||
position: relative;
|
||||
.gluon-value-field {
|
||||
flex: 3;
|
||||
position: relative;
|
||||
|
||||
input, select, input + label {
|
||||
position: relative;
|
||||
}
|
||||
input, select, input + label {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
div.gluon-value-field-text {
|
||||
flex: 3;
|
||||
padding-top: 0.39em;
|
||||
.gluon-value-field-text {
|
||||
flex: 3;
|
||||
padding-top: 0.39em;
|
||||
}
|
||||
|
||||
div.gluon-value-field-long {
|
||||
flex: 10;
|
||||
position: relative;
|
||||
margin-top: 0.65em;
|
||||
.gluon-value-field-long {
|
||||
flex: 10;
|
||||
position: relative;
|
||||
margin-top: 0.65em;
|
||||
|
||||
input, select, input + label {
|
||||
position: relative;
|
||||
}
|
||||
input, select, input + label {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
div.gluon-value-field-long-after {
|
||||
flex: 2;
|
||||
.gluon-value-field-long-after {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
div.gluon-value-description {
|
||||
font-size: 8pt;
|
||||
.gluon-value-description {
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
div.gluon-section-create {
|
||||
clear: left;
|
||||
white-space: nowrap;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
div.gluon-section-create .gluon-button {
|
||||
margin: 0.25em;
|
||||
}
|
||||
|
||||
input.gluon-section-create-name {
|
||||
margin-right: -0.25em;
|
||||
}
|
||||
|
||||
div.gluon-form-descr {
|
||||
margin-bottom: 1em;
|
||||
.gluon-form-descr {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.gluon-form-descr:empty, .gluon-section-descr:empty {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.gluon-form-descr, .gluon-section-descr, .gluon-page-actions {
|
||||
padding: 1em;
|
||||
background: #ececec;
|
||||
padding: 1em;
|
||||
background: #ececec;
|
||||
}
|
||||
|
||||
.gluon-page-actions {
|
||||
text-align: right;
|
||||
display: flex;
|
||||
flex-flow: row-reverse;
|
||||
}
|
||||
|
||||
div.gluon-optionals {
|
||||
padding: 0.25em;
|
||||
border-bottom: 1px dotted #bbbbbb;
|
||||
}
|
||||
|
||||
div.gluon-section-remove {
|
||||
float: right;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
flex-flow: row-reverse;
|
||||
}
|
||||
|
||||
.gluon-section-node {
|
||||
clear: both;
|
||||
position: relative;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.gluon-section-node-tabbed {
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
|
||||
div.gluon-error {
|
||||
font-size: 95%;
|
||||
font-weight: bold;
|
||||
color: #ff0000;
|
||||
background-color: #ffffff;
|
||||
clear: both;
|
||||
position: relative;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.gluon-value-error input,
|
||||
.gluon-value-error select {
|
||||
background-color: #ffcccc;
|
||||
background-color: #ffcccc;
|
||||
}
|
||||
|
||||
.gluon-value-field var {
|
||||
color: #2222FF;
|
||||
}
|
||||
|
||||
.gluon-add:after, .gluon-remove:after {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
font-size: 180%;
|
||||
width: 1.2em;
|
||||
height: 1em;
|
||||
.gluon-add::after, .gluon-remove::after {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
font-size: 180%;
|
||||
width: 1.2em;
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.gluon-add {
|
||||
color: #008000;
|
||||
color: #008000;
|
||||
|
||||
position: relative;
|
||||
left: 21em;
|
||||
position: relative;
|
||||
left: 21em;
|
||||
|
||||
input + & {
|
||||
left: 0;
|
||||
top: 0.04em;
|
||||
}
|
||||
input + & {
|
||||
left: 0;
|
||||
top: 0.04em;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
top: 0.53em;
|
||||
left: -0.08em;
|
||||
}
|
||||
&:first-child {
|
||||
top: 0.53em;
|
||||
left: -0.08em;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: '+';
|
||||
}
|
||||
&::after {
|
||||
content: '+';
|
||||
}
|
||||
}
|
||||
|
||||
.gluon-remove {
|
||||
color: #800000;
|
||||
color: #800000;
|
||||
|
||||
position: relative;
|
||||
top: -0.03em;
|
||||
position: relative;
|
||||
top: -0.03em;
|
||||
|
||||
&:after {
|
||||
content: '–';
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.right {
|
||||
text-align: right !important;
|
||||
}
|
||||
|
||||
.inline {
|
||||
display: inline;
|
||||
&::after {
|
||||
content: '–';
|
||||
}
|
||||
}
|
||||
|
||||
.error500 {
|
||||
border: 1px dotted #ff0000;
|
||||
background-color: #ffffff;
|
||||
color: #000000;
|
||||
padding: 0.5em;
|
||||
border: 1px dotted #ff0000;
|
||||
background-color: #ffffff;
|
||||
color: #000000;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.errorbox {
|
||||
border: 1px solid #FF0000;
|
||||
background-color: #FFCCCC;
|
||||
padding: 5px;
|
||||
margin-bottom: 5px;
|
||||
border: 1px solid #FF0000;
|
||||
background-color: #FFCCCC;
|
||||
padding: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.errorbox a {
|
||||
color: #000000 !important;
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
|
||||
.the-key {
|
||||
text-align: left;
|
||||
font-size: 1.4em;
|
||||
background: lighten($ffyellow, 35);
|
||||
border: 3pt dashed $ffmagenta;
|
||||
margin-bottom: 0.5em;
|
||||
padding: 0.5em
|
||||
text-align: left;
|
||||
font-size: 1.4em;
|
||||
background: lighten($ffyellow, 35);
|
||||
border: 3pt dashed $ffmagenta;
|
||||
margin-bottom: 0.5em;
|
||||
padding: 0.5em
|
||||
}
|
||||
|
12
package/gluon-core/files/etc/init.d/gluon-core-reconfigure
Executable file
12
package/gluon-core/files/etc/init.d/gluon-core-reconfigure
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
# Start right after S10boot
|
||||
START=10
|
||||
|
||||
start() {
|
||||
config_load gluon
|
||||
config_get_bool reconfigure core reconfigure 0
|
||||
if [ "$reconfigure" = 1 ]; then
|
||||
gluon-reconfigure
|
||||
fi
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
/etc/init.d/gluon-core-reconfigure start
|
@ -1,8 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script can be removed after Gluon v2018.2
|
||||
|
||||
# Check for a random line that always was in /etc/sysctl.conf
|
||||
if grep -qxF 'net.ipv4.ip_forward=1' /etc/sysctl.conf; then
|
||||
echo '# Defaults are configured in /etc/sysctl.d/* and can be customized in this file' >/etc/sysctl.conf
|
||||
fi
|
@ -1,3 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec uci commit
|
||||
uci -q batch <<-EOF
|
||||
delete gluon.core.reconfigure
|
||||
commit
|
||||
EOF
|
||||
|
48
package/gluon-core/luasrc/lib/gluon/upgrade/005-set-domain
Executable file
48
package/gluon-core/luasrc/lib/gluon/upgrade/005-set-domain
Executable file
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
local unistd = require 'posix.unistd'
|
||||
|
||||
|
||||
if not unistd.access('/lib/gluon/domains/') then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local function domain_exists(domain)
|
||||
return unistd.access('/lib/gluon/domains/' .. domain .. '.json') == 0
|
||||
end
|
||||
|
||||
|
||||
local uci = require('simple-uci').cursor()
|
||||
|
||||
local domain = uci:get('gluon', 'core', 'switch_domain')
|
||||
if domain and not domain_exists(domain) then
|
||||
io.stderr:write(
|
||||
string.format("Warning: invalid mesh domain switch to '%s' configured, not switching\n", domain)
|
||||
)
|
||||
domain = nil
|
||||
end
|
||||
|
||||
if not domain then
|
||||
domain = uci:get('gluon', 'core', 'domain')
|
||||
end
|
||||
if domain and not domain_exists(domain) then
|
||||
io.stderr:write(
|
||||
string.format("Warning: invalid mesh domain '%s' configured, resetting to default...\n", domain)
|
||||
)
|
||||
domain = nil
|
||||
end
|
||||
|
||||
if not domain then
|
||||
|
||||
-- We can't use gluon.site yet, as it depends on gluon.core.domain to be set
|
||||
local json = require 'jsonc'
|
||||
local site = assert(json.load('/lib/gluon/site.json'))
|
||||
|
||||
domain = site.default_domain
|
||||
|
||||
end
|
||||
|
||||
uci:set('gluon', 'core', 'domain', domain)
|
||||
uci:delete('gluon', 'core', 'switch_domain')
|
||||
uci:save('gluon')
|
@ -1,27 +0,0 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
local unistd = require 'posix.unistd'
|
||||
|
||||
|
||||
if not unistd.access('/lib/gluon/domains/') then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local uci = require('simple-uci').cursor()
|
||||
|
||||
local domain = uci:get('gluon', 'core', 'domain')
|
||||
if domain and not unistd.access('/lib/gluon/domains/' .. domain .. '.json') then
|
||||
io.stderr:write(string.format("Warning: invalid mesh domain '%s' configured, resetting to default...\n", domain))
|
||||
domain = nil
|
||||
end
|
||||
|
||||
if domain then return end
|
||||
|
||||
|
||||
-- We can't use gluon.site yet, as it depends on gluon.core.domain to be set
|
||||
local json = require 'jsonc'
|
||||
local site = assert(json.load('/lib/gluon/site.json'))
|
||||
|
||||
uci:set('gluon', 'core', 'domain', site.default_domain)
|
||||
uci:commit('gluon')
|
@ -111,6 +111,7 @@ local primary_addrs = {
|
||||
'c20i',
|
||||
'c50',
|
||||
'tplink,c2-v1',
|
||||
'ex3700'
|
||||
}},
|
||||
{'x86'},
|
||||
}},
|
||||
|
@ -11,9 +11,12 @@ end
|
||||
local platform = require 'gluon.platform'
|
||||
local site = require 'gluon.site'
|
||||
|
||||
local json = require 'jsonc'
|
||||
local uci = require('simple-uci').cursor()
|
||||
local unistd = require 'posix.unistd'
|
||||
|
||||
local board_data = json.load('/etc/board.json')
|
||||
local network_data = (board_data or {}).network
|
||||
|
||||
local function iface_exists(ifaces)
|
||||
if not ifaces then return nil end
|
||||
@ -26,8 +29,8 @@ local function iface_exists(ifaces)
|
||||
end
|
||||
|
||||
|
||||
local lan_ifname = iface_exists(uci:get('network', 'lan', 'ifname'))
|
||||
local wan_ifname = iface_exists(uci:get('network', 'wan', 'ifname'))
|
||||
local lan_ifname = iface_exists((network_data.lan or {}).ifname)
|
||||
local wan_ifname = iface_exists((network_data.wan or {}).ifname)
|
||||
|
||||
if platform.match('ar71xx', 'generic', {
|
||||
'cpe210',
|
||||
@ -42,6 +45,16 @@ if platform.match('ar71xx', 'generic', {
|
||||
'unifiac-pro',
|
||||
}) then
|
||||
lan_ifname, wan_ifname = wan_ifname, lan_ifname
|
||||
elseif platform.match('lantiq') then
|
||||
local switch_data = board_data.switch or {}
|
||||
local switch0_data = switch_data.switch0 or {}
|
||||
local roles_data = switch0_data.roles or {}
|
||||
for _, role_data in ipairs(roles_data) do
|
||||
if role_data.role == 'wan' then
|
||||
wan_ifname = iface_exists(role_data.device)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if wan_ifname and lan_ifname then
|
||||
|
@ -54,7 +54,7 @@ end
|
||||
|
||||
local function get_channel(radio, config)
|
||||
local channel
|
||||
if uci:get_first('gluon-core', 'wireless', 'preserve_channels') then
|
||||
if wireless.preserve_channels(uci) then
|
||||
-- preserved channel always wins
|
||||
channel = radio.channel
|
||||
elseif (radio.hwmode == '11a' or radio.hwmode == '11na') and is_outdoor() then
|
||||
@ -82,20 +82,20 @@ local function get_htmode(radio)
|
||||
end
|
||||
|
||||
local function is_disabled(name)
|
||||
if uci:get('wireless', name) then
|
||||
return uci:get_bool('wireless', name, 'disabled')
|
||||
else
|
||||
if not uci:get('wireless', name) then
|
||||
return nil
|
||||
end
|
||||
|
||||
return uci:get_bool('wireless', name, 'disabled')
|
||||
end
|
||||
|
||||
-- Returns the first argument that is not nil; don't call without any non-nil arguments!
|
||||
local function first_non_nil(first, ...)
|
||||
if first ~= nil then
|
||||
return first
|
||||
else
|
||||
return first_non_nil(...)
|
||||
end
|
||||
|
||||
return first_non_nil(...)
|
||||
end
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ end
|
||||
|
||||
uci:foreach('firewall', 'zone', reject_input_on_wan)
|
||||
|
||||
for _, zone in ipairs({'mesh', 'local_client', 'wired_mesh'}) do
|
||||
for _, zone in ipairs({'mesh', 'loc_client', 'wired_mesh'}) do
|
||||
-- Other packages assign interfaces to these zones
|
||||
uci:section('firewall', 'zone', zone, {
|
||||
name = zone,
|
||||
@ -52,13 +52,16 @@ for _, zone in ipairs({'mesh', 'local_client', 'wired_mesh'}) do
|
||||
family = 'ipv6',
|
||||
target = 'ACCEPT',
|
||||
})
|
||||
|
||||
-- Can be removed soon: was never in a release
|
||||
uci:delete('firewall', zone .. '_ICMPv6_out')
|
||||
end
|
||||
|
||||
uci:section('firewall', 'rule', 'local_client_ICMPv4_in', {
|
||||
src = 'local_client',
|
||||
-- ToDo Remove in v2022.x
|
||||
uci:delete('firewall', 'local_client')
|
||||
uci:delete('firewall', 'local_client_ssh')
|
||||
uci:delete('firewall', 'local_client_ICMPv4_in')
|
||||
uci:delete('firewall', 'local_client_ICMPv6_in')
|
||||
|
||||
uci:section('firewall', 'rule', 'loc_client_ICMPv4_in', {
|
||||
src = 'loc_client',
|
||||
proto = 'icmp',
|
||||
icmp_type = {
|
||||
'echo-request',
|
||||
@ -67,9 +70,8 @@ uci:section('firewall', 'rule', 'local_client_ICMPv4_in', {
|
||||
target = 'ACCEPT',
|
||||
})
|
||||
|
||||
|
||||
-- allow inbound SSH from anywhere
|
||||
for _, zone in ipairs({ 'wan', 'local_client', 'mesh' }) do
|
||||
for _, zone in ipairs({ 'wan', 'loc_client', 'mesh' }) do
|
||||
uci:section('firewall', 'rule', zone .. '_ssh', {
|
||||
name = zone .. '_ssh',
|
||||
src = zone,
|
@ -18,7 +18,7 @@ uci:delete('firewall', 'client_dns')
|
||||
if dns.servers then
|
||||
-- allow inbound traffic for dns from client zone
|
||||
uci:section('firewall', 'rule', 'client_dns', {
|
||||
src = 'local_client',
|
||||
src = 'loc_client',
|
||||
dest_port = '53',
|
||||
proto = 'tcpudp',
|
||||
target = 'ACCEPT',
|
||||
|
56
package/gluon-core/luasrc/usr/bin/gluon-switch-domain
Executable file
56
package/gluon-core/luasrc/usr/bin/gluon-switch-domain
Executable file
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
local unistd = require 'posix.unistd'
|
||||
|
||||
|
||||
local function shift()
|
||||
table.remove(arg, 1)
|
||||
end
|
||||
|
||||
local reboot = true
|
||||
if arg[1] == '--no-reboot' then
|
||||
reboot = false
|
||||
shift()
|
||||
end
|
||||
|
||||
local setup_mode = unistd.access('/var/gluon/setup-mode') == 0
|
||||
|
||||
if #arg ~= 1 then
|
||||
io.stderr:write('Usage: gluon-switch-domain [--no-reboot] <domain>\n')
|
||||
os.exit(1)
|
||||
end
|
||||
local domain = arg[1]
|
||||
|
||||
|
||||
if not unistd.access('/lib/gluon/domains/') then
|
||||
io.stderr:write('This Gluon firmware does not support multiple mesh domains.\n')
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
|
||||
local function domain_exists(dom)
|
||||
return unistd.access('/lib/gluon/domains/' .. dom .. '.json') == 0
|
||||
end
|
||||
|
||||
if not domain_exists(domain) then
|
||||
io.stderr:write(string.format("Error: invalid mesh domain '%s'\n", domain))
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
|
||||
local uci = require('simple-uci').cursor()
|
||||
uci:set('gluon', 'core', 'switch_domain', domain)
|
||||
uci:set('gluon', 'core', 'reconfigure', true)
|
||||
uci:save('gluon')
|
||||
|
||||
local cmd
|
||||
if setup_mode then
|
||||
cmd = 'gluon-reconfigure'
|
||||
elseif reboot then
|
||||
uci:commit('gluon')
|
||||
cmd = 'reboot'
|
||||
else
|
||||
cmd = 'gluon-reload'
|
||||
end
|
||||
|
||||
unistd.execp(cmd, {[0] = cmd})
|
@ -66,7 +66,7 @@ end
|
||||
|
||||
function M.device_supports_wpa3()
|
||||
-- rt2x00 crashes when enabling WPA3 personal / OWE VAP
|
||||
if M.match('ramips', 'rt305x') or M.match('ramips', 'mt7620') then
|
||||
if M.match('ramips', 'rt305x') then
|
||||
return false
|
||||
end
|
||||
|
||||
|
@ -96,4 +96,8 @@ function M.foreach_radio(uci, f)
|
||||
end
|
||||
end
|
||||
|
||||
function M.preserve_channels(uci)
|
||||
return uci:get_first('gluon-core', 'wireless', 'preserve_channels')
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -0,0 +1 @@
|
||||
rule 'MULTICAST_OUT -p IPv6 --ip6-protocol udp --ip6-destination-port 1001 --ip6-dst ff05::2:1001 -j RETURN'
|
@ -67,9 +67,7 @@ end
|
||||
|
||||
function M.set_domain_config(domain)
|
||||
if uci:get('gluon', 'core', 'domain') ~= domain.domain_code then
|
||||
uci:set('gluon', 'core', 'domain', domain.domain_code)
|
||||
uci:commit('gluon')
|
||||
os.execute('gluon-reconfigure')
|
||||
os.execute(string.format("exec gluon-switch-domain --no-reboot '%s'", domain.domain_code))
|
||||
M.log('Set domain "'..domain.domain.domain_names[domain.domain_code]..'"')
|
||||
return true
|
||||
end
|
||||
|
@ -40,7 +40,6 @@ if geo.lat ~= nil and geo.lon ~= nil then
|
||||
local geo_base_domain = hoodutil.get_domain_by_geo(jdomains, geo)
|
||||
if geo_base_domain ~= nil then
|
||||
if hoodutil.set_domain_config(geo_base_domain) then
|
||||
os.execute("gluon-reload")
|
||||
hoodutil.log('Domain set by geolocation mode.\n')
|
||||
end
|
||||
return
|
||||
@ -51,6 +50,4 @@ else
|
||||
end
|
||||
|
||||
-- default domain mode
|
||||
if hoodutil.set_domain_config(hoodutil.get_default_domain(hoodutil.get_domains())) then
|
||||
os.execute("gluon-reload")
|
||||
end
|
||||
hoodutil.set_domain_config(hoodutil.get_default_domain(hoodutil.get_domains()))
|
||||
|
@ -23,18 +23,18 @@ uci:section('firewall', 'zone', 'mmfd', {
|
||||
|
||||
-- forwardings and respective rules
|
||||
uci:section('firewall', 'forwarding', 'fcc', {
|
||||
src = 'local_client',
|
||||
dest = 'local_client',
|
||||
src = 'loc_client',
|
||||
dest = 'loc_client',
|
||||
})
|
||||
|
||||
uci:section('firewall', 'forwarding', 'fcm', {
|
||||
src = 'local_client',
|
||||
src = 'loc_client',
|
||||
dest = 'mesh',
|
||||
})
|
||||
|
||||
uci:section('firewall', 'forwarding', 'fmc', {
|
||||
src = 'mesh',
|
||||
dest = 'local_client',
|
||||
dest = 'loc_client',
|
||||
})
|
||||
|
||||
uci:section('firewall', 'forwarding', 'fmm', {
|
||||
@ -44,11 +44,11 @@ uci:section('firewall', 'forwarding', 'fmm', {
|
||||
|
||||
uci:section('firewall', 'forwarding', 'flc', {
|
||||
src = 'l3roamd',
|
||||
dest = 'local_client',
|
||||
dest = 'loc_client',
|
||||
})
|
||||
|
||||
uci:section('firewall', 'forwarding', 'fcl', {
|
||||
src = 'local_client',
|
||||
src = 'loc_client',
|
||||
dest = 'l3roamd',
|
||||
})
|
||||
|
@ -62,38 +62,40 @@
|
||||
|
||||
static struct babelhelper_ctx bhelper_ctx = {};
|
||||
|
||||
static void obtain_if_addr(const char *ifname, char *lladdr) {
|
||||
static bool get_linklocal_address(const char *ifname, char lladdr[INET6_ADDRSTRLEN]) {
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
int family, n;
|
||||
bool ret = false;
|
||||
|
||||
if (getifaddrs(&ifaddr) == -1) {
|
||||
perror("getifaddrs");
|
||||
exit(EXIT_FAILURE);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
|
||||
if (ifa->ifa_addr == NULL)
|
||||
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
if (!ifa->ifa_addr)
|
||||
continue;
|
||||
|
||||
family = ifa->ifa_addr->sa_family;
|
||||
if (ifa->ifa_addr->sa_family != AF_INET6)
|
||||
continue;
|
||||
|
||||
if ( (family == AF_INET6) && ( ! strncmp(ifname, ifa->ifa_name, strlen(ifname)) ) ) {
|
||||
char lhost[INET6_ADDRSTRLEN];
|
||||
struct in6_addr *address = &((struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr;
|
||||
if (inet_ntop(AF_INET6, address, lhost, INET6_ADDRSTRLEN) == NULL) {
|
||||
fprintf(stderr, "obtain_if_addr: could not convert ip to string\n");
|
||||
goto cleanup;
|
||||
}
|
||||
if (strcmp(ifname, ifa->ifa_name) != 0)
|
||||
continue;
|
||||
|
||||
if (! strncmp("fe80:", lhost, 5) ) {
|
||||
snprintf( lladdr, NI_MAXHOST, "%s", lhost );
|
||||
goto cleanup;
|
||||
}
|
||||
const struct in6_addr *address = &((const struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
|
||||
if (!IN6_IS_ADDR_LINKLOCAL(address))
|
||||
continue;
|
||||
|
||||
if (!inet_ntop(AF_INET6, address, lladdr, INET6_ADDRSTRLEN)) {
|
||||
perror("inet_ntop");
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
freeifaddrs(ifaddr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -154,29 +156,32 @@ free:
|
||||
return retval;
|
||||
}
|
||||
|
||||
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)+1];
|
||||
snprintf(path, sizeof(path), format, ifname, name);
|
||||
|
||||
return !access(path, F_OK);
|
||||
}
|
||||
|
||||
static void mesh_add_if(const char *ifname, struct json_object *wireless,
|
||||
struct json_object *tunnel, struct json_object *other) {
|
||||
char str_ip[NI_MAXHOST] = {};
|
||||
char str_ip[INET6_ADDRSTRLEN];
|
||||
|
||||
obtain_if_addr(ifname, str_ip);
|
||||
if (!get_linklocal_address(ifname, str_ip))
|
||||
return;
|
||||
|
||||
struct json_object *address = json_object_new_string(str_ip);
|
||||
|
||||
if (interface_file_exists(ifname, "wireless"))
|
||||
json_object_array_add(wireless, address);
|
||||
else if (interface_file_exists(ifname, "tun_flags"))
|
||||
json_object_array_add(tunnel, address);
|
||||
else
|
||||
json_object_array_add(other, address);
|
||||
/* In case of VLAN and bridge interfaces, we want the lower interface
|
||||
* to determine the interface type (but not for the interface address) */
|
||||
char lowername[IF_NAMESIZE];
|
||||
gluonutil_get_interface_lower(lowername, ifname);
|
||||
|
||||
switch(gluonutil_get_interface_type(lowername)) {
|
||||
case GLUONUTIL_INTERFACE_TYPE_WIRELESS:
|
||||
json_object_array_add(wireless, address);
|
||||
break;
|
||||
|
||||
case GLUONUTIL_INTERFACE_TYPE_TUNNEL:
|
||||
json_object_array_add(tunnel, address);
|
||||
break;
|
||||
|
||||
default:
|
||||
json_object_array_add(other, address);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -193,24 +198,26 @@ static bool handle_neighbour(char **data, void *obj) {
|
||||
if (data[REACH])
|
||||
json_object_object_add(neigh, "reachability", json_object_new_double(strtod(data[REACH], NULL)));
|
||||
|
||||
struct json_object *nif = 0;
|
||||
if (data[IF] && !json_object_object_get_ex(obj, data[IF], &nif)) {
|
||||
char str_ip[NI_MAXHOST] = {};
|
||||
obtain_if_addr( (const char*)data[IF], str_ip );
|
||||
if (!data[IF])
|
||||
return true;
|
||||
|
||||
struct json_object *nif;
|
||||
if (!json_object_object_get_ex(obj, data[IF], &nif)) {
|
||||
char str_ip[INET6_ADDRSTRLEN];
|
||||
|
||||
nif = json_object_new_object();
|
||||
|
||||
json_object_object_add(nif, "ll-addr", json_object_new_string(str_ip));
|
||||
if (get_linklocal_address(data[IF], str_ip))
|
||||
json_object_object_add(nif, "ll-addr", json_object_new_string(str_ip));
|
||||
|
||||
json_object_object_add(nif, "protocol", json_object_new_string("babel"));
|
||||
json_object_object_add(obj, data[IF], nif);
|
||||
|
||||
}
|
||||
struct json_object *neighborcollector = 0;
|
||||
if (!json_object_object_get_ex(nif, "neighbours", &neighborcollector)) {
|
||||
neighborcollector = json_object_new_object();
|
||||
json_object_object_add(nif, "neighbours", neighborcollector);
|
||||
json_object_object_add(nif, "neighbours", json_object_new_object());
|
||||
}
|
||||
|
||||
struct json_object *neighborcollector;
|
||||
json_object_object_get_ex(nif, "neighbours", &neighborcollector);
|
||||
json_object_object_add(neighborcollector, data[ADDRESS], neigh);
|
||||
|
||||
}
|
||||
@ -277,6 +284,13 @@ static void blobmsg_handle_list(struct blob_attr *attr, int len, bool array, str
|
||||
free(proto);
|
||||
}
|
||||
|
||||
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 void receive_call_result_data(struct ubus_request *req, int type, struct blob_attr *msg) {
|
||||
struct json_object *ret = json_object_new_object();
|
||||
struct json_object *wireless = json_object_new_array();
|
||||
@ -298,9 +312,9 @@ static void receive_call_result_data(struct ubus_request *req, int type, struct
|
||||
|
||||
blobmsg_handle_list(blobmsg_data(msg), blobmsg_data_len(msg), false, wireless, tunnel, other);
|
||||
|
||||
json_object_object_add(ret, "wireless", wireless);
|
||||
json_object_object_add(ret, "tunnel", tunnel);
|
||||
json_object_object_add(ret, "other", other);
|
||||
add_if_not_empty(ret, "wireless", wireless);
|
||||
add_if_not_empty(ret, "tunnel", tunnel);
|
||||
add_if_not_empty(ret, "other", other);
|
||||
|
||||
*((struct json_object**)(req->priv)) = ret;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
lock /var/lock/gluon_bat0.lock
|
||||
batctl interface del "$IFNAME" 2>/dev/null
|
||||
batctl interface -M del "$IFNAME" 2>/dev/null
|
||||
lock -u /var/lock/gluon_bat0.lock
|
||||
|
@ -131,35 +131,23 @@ 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);
|
||||
char lowername[IF_NAMESIZE];
|
||||
gluonutil_get_interface_lower(lowername, ifname);
|
||||
|
||||
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"))
|
||||
switch(gluonutil_get_interface_type(lowername)) {
|
||||
case GLUONUTIL_INTERFACE_TYPE_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);
|
||||
break;
|
||||
|
||||
case GLUONUTIL_INTERFACE_TYPE_TUNNEL:
|
||||
json_object_array_add(tunnel, address);
|
||||
break;
|
||||
|
||||
default:
|
||||
json_object_array_add(other, address);
|
||||
}
|
||||
}
|
||||
|
||||
static struct json_object * get_mesh_subifs(const char *ifname) {
|
||||
|
@ -7,7 +7,7 @@ include ../gluon.mk
|
||||
|
||||
define Package/gluon-mesh-wireless-sae
|
||||
TITLE:=Encryption of 802.11s Mesh Links through SAE
|
||||
DEPENDS:=+gluon-core +wpa-supplicant-openssl
|
||||
DEPENDS:=+gluon-core +wpa-supplicant-mesh-wolfssl
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackageGluon,gluon-mesh-wireless-sae))
|
||||
|
@ -559,14 +559,13 @@ static int parse_tt_local(struct nl_msg *msg,
|
||||
}
|
||||
|
||||
static void update_tqs(void) {
|
||||
static const struct ether_addr unspec = {};
|
||||
struct router *router;
|
||||
bool update_originators = false;
|
||||
struct ether_addr unspec;
|
||||
struct batadv_nlquery_opts opts;
|
||||
int ret;
|
||||
|
||||
// reset TQs
|
||||
memset(&unspec, 0, sizeof(unspec));
|
||||
foreach(router, G.routers) {
|
||||
router->tq = 0;
|
||||
if (ether_addr_equal(router->originator, unspec))
|
||||
@ -609,12 +608,12 @@ static void update_tqs(void) {
|
||||
foreach(router, G.routers) {
|
||||
if (router->tq == 0) {
|
||||
if (ether_addr_equal(router->originator, unspec))
|
||||
fprintf(stderr,
|
||||
"Unable to find router " F_MAC " in transtable_{global,local}\n",
|
||||
DEBUG_MSG(
|
||||
"Unable to find router " F_MAC " in transtable_{global,local}",
|
||||
F_MAC_VAR(router->src));
|
||||
else
|
||||
fprintf(stderr,
|
||||
"Unable to find TQ for originator " F_MAC " (router " F_MAC ")\n",
|
||||
DEBUG_MSG(
|
||||
"Unable to find TQ for originator " F_MAC " (router " F_MAC ")",
|
||||
F_MAC_VAR(router->originator),
|
||||
F_MAC_VAR(router->src));
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#define F_MAC "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
|
||||
|
@ -18,7 +18,7 @@ uci:section('firewall', 'rule', 'wan_respondd', {
|
||||
-- Allow respondd-access for local clients
|
||||
uci:section('firewall', 'rule', 'client_respondd', {
|
||||
name = 'client_respondd',
|
||||
src = 'local_client',
|
||||
src = 'loc_client',
|
||||
src_ip = 'fe80::/64',
|
||||
dest_port = '1001',
|
||||
proto = 'udp',
|
||||
|
@ -60,8 +60,5 @@ if not switch_after_min_reached() and not switch_time_passed() then
|
||||
os.exit(0)
|
||||
end
|
||||
|
||||
uci:set("gluon", "core", "domain", target_domain)
|
||||
uci:commit("gluon")
|
||||
|
||||
os.execute("gluon-reconfigure")
|
||||
os.execute("reboot")
|
||||
local cmd = {[0] = 'gluon-switch-domain', target_domain}
|
||||
unistd.execp(cmd[0], cmd)
|
@ -14,5 +14,5 @@ end
|
||||
-- Only in case domain switch is scheduled
|
||||
local f = io.open(cronfile, "w")
|
||||
f:write("* * * * * /usr/bin/gluon-check-connection\n")
|
||||
f:write("*/5 * * * * /usr/bin/gluon-switch-domain\n")
|
||||
f:write("*/5 * * * * /lib/gluon/scheduled-domain-switch/switch-domain\n")
|
||||
f:close()
|
||||
|
@ -17,4 +17,26 @@ define Package/gluon-setup-mode/description
|
||||
Offline mode to perform basic setup in a secure manner.
|
||||
endef
|
||||
|
||||
init_links := \
|
||||
K89log \
|
||||
K98boot \
|
||||
K99umount \
|
||||
S00sysfixtime \
|
||||
S10boot \
|
||||
S10gluon-core-reconfigure \
|
||||
S10system \
|
||||
S11sysctl \
|
||||
S12log \
|
||||
S95done
|
||||
|
||||
define Package/gluon-setup-mode/install
|
||||
$(Gluon/Build/Install)
|
||||
|
||||
$(LN) S20network $(1)/lib/gluon/setup-mode/rc.d/K90network
|
||||
|
||||
for link in $(init_links); do \
|
||||
$(LN) "/etc/init.d/$$$${link:3}" "$(1)/lib/gluon/setup-mode/rc.d/$$$${link}"; \
|
||||
done
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackageGluon,gluon-setup-mode))
|
||||
|
@ -1 +0,0 @@
|
||||
/etc/init.d/log
|
@ -1 +0,0 @@
|
||||
S20network
|
@ -1 +0,0 @@
|
||||
/etc/init.d/boot
|
@ -1 +0,0 @@
|
||||
/etc/init.d/umount
|
@ -1 +0,0 @@
|
||||
/etc/init.d/sysfixtime
|
@ -1 +0,0 @@
|
||||
/etc/init.d/boot
|
@ -1 +0,0 @@
|
||||
/etc/init.d/system
|
@ -1 +0,0 @@
|
||||
/etc/init.d/sysctl
|
@ -1 +0,0 @@
|
||||
/etc/init.d/log
|
@ -1 +0,0 @@
|
||||
/etc/init.d/done
|
@ -7,6 +7,10 @@ setup_mode_enable() {
|
||||
|
||||
if [ "$enabled" = 1 ] || [ "$configured" != 1 ]; then
|
||||
echo '/lib/gluon/setup-mode/rc.d' > /tmp/rc_d_path
|
||||
|
||||
# This directory is a marker for scripts to know that we're
|
||||
# in config mode, but it is also used for temporary files
|
||||
mkdir -p /var/gluon/setup-mode
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,14 @@ define Build/Compile
|
||||
rm -rf $(PKG_BUILD_DIR)/domains
|
||||
mkdir -p $(PKG_BUILD_DIR)/domains
|
||||
$(foreach domain,$(patsubst $(GLUON_SITEDIR)/domains/%.conf,%,$(wildcard $(GLUON_SITEDIR)/domains/*.conf)),
|
||||
[ ! -e '$(PKG_BUILD_DIR)/domains/$(domain).json' ]
|
||||
@if [ -e '$(PKG_BUILD_DIR)/domains/$(domain).json' ]; then \
|
||||
link='$(PKG_BUILD_DIR)/domains/$(domain).json'; \
|
||||
other="$$$$(basename $$$$(readlink -f "$$$$link") .json)"; \
|
||||
if [ "$$$$other" ]; then \
|
||||
echo >&2 "Error: Failed to install domain '"'$(domain)'"', name already taken by domain '$$$$other'."; \
|
||||
fi; \
|
||||
exit 1; \
|
||||
fi
|
||||
$(call GenerateJSON,domains/$(domain))
|
||||
@lua ../../scripts/domain_aliases.lua '$(PKG_BUILD_DIR)/domains/$(domain).json' | while read alias; do \
|
||||
[ "$$$${alias}" != '$(domain)' ] || continue; \
|
||||
@ -57,7 +64,7 @@ define Build/Compile
|
||||
if ! ln -s '$(domain).json' "$$$$link"; then \
|
||||
other="$$$$(basename $$$$(readlink -f "$$$$link") .json)"; \
|
||||
if [ "$$$$other" ]; then \
|
||||
echo >&2 "Failed to alias domain '"'$(domain)'"' as '$$$$alias', name already taken by domain '$$$$other'."; \
|
||||
echo >&2 "Error: Failed to alias domain '"'$(domain)'"' as '$$$$alias', name already taken by domain '$$$$other'."; \
|
||||
fi; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
|
@ -142,7 +142,13 @@
|
||||
<tr><th><%:RAM%></th><td><%= statistics('memory', 'memory') %></td></tr>
|
||||
<tr><th><%:Filesystem%></th><td><%= statistics('rootfs_usage', 'percent') %></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>
|
||||
</table>
|
||||
|
||||
<h3><%:Clients%></h3>
|
||||
<table>
|
||||
<tr><th><%:Total%></th><td><%= statistics('clients/total') %></td></tr>
|
||||
<tr><th><%:Wireless 2.4 GHz%></th><td><%= statistics('clients/wifi24') %></td></tr>
|
||||
<tr><th><%:Wireless 5 GHz%></th><td><%= statistics('clients/wifi5') %></td></tr>
|
||||
</table>
|
||||
|
||||
<h3><%:Traffic%></h3>
|
||||
|
@ -55,9 +55,6 @@ msgstr "Weitergeleitet"
|
||||
msgid "Gateway"
|
||||
msgstr "Gateway"
|
||||
|
||||
msgid "Gateway Nexthop"
|
||||
msgstr "Gateway Nexthop"
|
||||
|
||||
msgid "IP address"
|
||||
msgstr "IP-Adresse"
|
||||
|
||||
@ -106,6 +103,9 @@ msgstr "Site"
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
msgid "Total"
|
||||
msgstr "Gesamt"
|
||||
|
||||
msgid "Traffic"
|
||||
msgstr ""
|
||||
|
||||
@ -115,6 +115,12 @@ msgstr "Gesendet"
|
||||
msgid "Uptime"
|
||||
msgstr "Laufzeit"
|
||||
|
||||
msgid "Wireless 2.4 GHz"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wireless 5 GHz"
|
||||
msgstr ""
|
||||
|
||||
msgid "connected"
|
||||
msgstr "verbunden"
|
||||
|
||||
@ -126,3 +132,6 @@ msgstr "aktiviert"
|
||||
|
||||
msgid "not connected"
|
||||
msgstr "nicht verbunden"
|
||||
|
||||
#~ msgid "Gateway Nexthop"
|
||||
#~ msgstr "Gateway Nexthop"
|
||||
|
@ -46,9 +46,6 @@ msgstr ""
|
||||
msgid "Gateway"
|
||||
msgstr ""
|
||||
|
||||
msgid "Gateway Nexthop"
|
||||
msgstr ""
|
||||
|
||||
msgid "IP address"
|
||||
msgstr ""
|
||||
|
||||
@ -97,6 +94,9 @@ msgstr ""
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
msgid "Total"
|
||||
msgstr ""
|
||||
|
||||
msgid "Traffic"
|
||||
msgstr ""
|
||||
|
||||
@ -106,6 +106,12 @@ msgstr ""
|
||||
msgid "Uptime"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wireless 2.4 GHz"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wireless 5 GHz"
|
||||
msgstr ""
|
||||
|
||||
msgid "connected"
|
||||
msgstr ""
|
||||
|
||||
|
@ -27,7 +27,7 @@ uci:section('uhttpd', 'uhttpd', 'main', {
|
||||
uci:save('uhttpd')
|
||||
|
||||
|
||||
for _, zone in ipairs({'mesh', 'local_client'}) do
|
||||
for _, zone in ipairs({'mesh', 'loc_client'}) do
|
||||
uci:section('firewall', 'rule', zone .. '_http', {
|
||||
src = zone,
|
||||
dest_port = '80',
|
||||
@ -35,4 +35,8 @@ for _, zone in ipairs({'mesh', 'local_client'}) do
|
||||
target = 'ACCEPT',
|
||||
})
|
||||
end
|
||||
|
||||
-- ToDo remove in v2022.x
|
||||
uci:delete('firewall', 'local_client_http')
|
||||
|
||||
uci:save('firewall')
|
||||
|
@ -0,0 +1,2 @@
|
||||
wan6
|
||||
wan
|
@ -16,6 +16,19 @@ local function append_server(server)
|
||||
end
|
||||
|
||||
|
||||
local function handled_interfaces()
|
||||
local interfaces = {}
|
||||
|
||||
for _, path in ipairs(util.glob('/lib/gluon/wan-dnsmasq/interface.d/*')) do
|
||||
for interface in io.lines(path) do
|
||||
table.insert(interfaces, interface)
|
||||
end
|
||||
end
|
||||
|
||||
return interfaces
|
||||
end
|
||||
|
||||
|
||||
local function handle_interface(status)
|
||||
local ifname = status.device
|
||||
local servers = status.inactive['dns-server']
|
||||
@ -41,8 +54,9 @@ if type(static) == 'table' and #static > 0 then
|
||||
append_server(server)
|
||||
end
|
||||
else
|
||||
pcall(append_interface_servers, 'wan6')
|
||||
pcall(append_interface_servers, 'wan')
|
||||
for _, interface in ipairs(handled_interfaces()) do
|
||||
pcall(append_interface_servers, interface)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ $Id$
|
||||
<%:Firmware image%>
|
||||
</label>
|
||||
<div class="gluon-value-field">
|
||||
<input class="gluon-input-file" type="file" name="image" />
|
||||
<input type="file" name="image" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -36,13 +36,13 @@ $Id$
|
||||
</label>
|
||||
|
||||
<div class="gluon-value-field">
|
||||
<input id="keepcfg" class="gluon-input-checkbox" type="checkbox" name="keepcfg" value="1" checked="checked" />
|
||||
<input id="keepcfg" type="checkbox" name="keepcfg" value="1" checked="checked" />
|
||||
<label for="keepcfg"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gluon-page-actions right">
|
||||
<div class="gluon-page-actions">
|
||||
<input type="hidden" name="step" value="2" />
|
||||
<input type="hidden" name="token" value="<%=token%>" />
|
||||
<input class="gluon-button gluon-button-submit" type="submit" value="<%:Upload image%>" />
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="gluon-value">
|
||||
<div class="gluon-value-title">
|
||||
<input class="gluon-input-radio" data-update="change" type="radio" value="security"<%= attr("id", id..'.1') .. attr("name", id) .. attr("checked", ((self:cfgvalue() or self.default) == "security") and "checked") %> />
|
||||
<input data-update="change" type="radio" value="security"<%= attr("id", id..'.1') .. attr("name", id) .. attr("checked", ((self:cfgvalue() or self.default) == "security") and "checked") %> />
|
||||
<label<%= attr("for", id..'.1')%>></label>
|
||||
</div>
|
||||
<div class="gluon-value-field-long">
|
||||
@ -18,7 +18,7 @@
|
||||
|
||||
<div class="gluon-value gluon-value-last">
|
||||
<div class="gluon-value-title">
|
||||
<input class="gluon-input-radio" data-update="change" type="radio" value="performance"<%= attr("id", id..'.2') .. attr("name", id) .. attr("checked", ((self:cfgvalue() or self.default) == "performance") and "checked") %> />
|
||||
<input data-update="change" type="radio" value="performance"<%= attr("id", id..'.2') .. attr("name", id) .. attr("checked", ((self:cfgvalue() or self.default) == "performance") and "checked") %> />
|
||||
<label<%= attr("for", id..'.2')%>></label>
|
||||
</div>
|
||||
<div class="gluon-value-field-long">
|
||||
|
@ -10,7 +10,7 @@
|
||||
<%
|
||||
for i, val in ipairs(self:cfgvalue()) do
|
||||
%>
|
||||
<input class="gluon-input-text" value="<%|val%>" data-update="change" type="text"<%=
|
||||
<input value="<%|val%>" data-update="change" type="text"<%=
|
||||
attr("id", id .. "." .. i) ..
|
||||
attr("name", id) ..
|
||||
attr("size", self.size) ..
|
||||
|
@ -1,4 +1,4 @@
|
||||
<input class="gluon-input-checkbox" data-update="click change" type="checkbox" value="1"<%=
|
||||
<input data-update="click change" type="checkbox" value="1"<%=
|
||||
attr("id", id) .. attr("name", id) ..
|
||||
attr("checked", self:cfgvalue() and "checked")
|
||||
%> />
|
||||
|
@ -4,23 +4,25 @@
|
||||
%>
|
||||
|
||||
<% if self.widget == "select" then %>
|
||||
<select class="gluon-input-select" data-update="change"<%=
|
||||
attr("id", id) ..
|
||||
attr("name", id) ..
|
||||
attr("size", self.size) ..
|
||||
attr("data-type", "minlength(1)") ..
|
||||
attr("data-optional", self.optional)
|
||||
%>>
|
||||
<% for i, entry in pairs(entries) do -%>
|
||||
<option<%=
|
||||
attr("id", id.."."..entry.key) ..
|
||||
attr("value", entry.key) ..
|
||||
attr("data-index", i) ..
|
||||
attr("data-depends", self:deplist(entry.deps)) ..
|
||||
attr("selected", (self:cfgvalue() == entry.key) and "selected")
|
||||
%>><%|entry.value%></option>
|
||||
<%- end %>
|
||||
</select>
|
||||
<div class="select-wrapper">
|
||||
<select data-update="change"<%=
|
||||
attr("id", id) ..
|
||||
attr("name", id) ..
|
||||
attr("size", self.size) ..
|
||||
attr("data-type", "minlength(1)") ..
|
||||
attr("data-optional", self.optional)
|
||||
%>>
|
||||
<% for i, entry in pairs(entries) do -%>
|
||||
<option<%=
|
||||
attr("id", id.."."..entry.key) ..
|
||||
attr("value", entry.key) ..
|
||||
attr("data-index", i) ..
|
||||
attr("data-depends", self:deplist(entry.deps)) ..
|
||||
attr("selected", (self:cfgvalue() == entry.key) and "selected")
|
||||
%>><%|entry.value%></option>
|
||||
<%- end %>
|
||||
</select>
|
||||
</div>
|
||||
<% elseif self.widget == "radio" then %>
|
||||
<div>
|
||||
<% for i, entry in pairs(entries) do %>
|
||||
@ -28,7 +30,7 @@
|
||||
attr("data-index", i) ..
|
||||
attr("data-depends", self:deplist(entry.deps))
|
||||
%>>
|
||||
<input class="gluon-input-radio" data-update="click change" type="radio"<%=
|
||||
<input data-update="click change" type="radio"<%=
|
||||
attr("id", id.."."..entry.key) ..
|
||||
attr("name", id) ..
|
||||
attr("value", entry.key) ..
|
||||
|
@ -1,3 +1,3 @@
|
||||
<textarea class="gluon-input-textarea" <% if not self.size then %> style="width: 100%"<% else %> cols="<%=self.size%>"<% end %> data-update="change"<%= attr("name", id) .. attr("id", id) .. attr("rows", self.rows) .. attr("wrap", self.wrap) %>>
|
||||
<textarea <% if not self.size then %> style="width: 100%"<% else %> cols="<%=self.size%>"<% end %> data-update="change"<%= attr("name", id) .. attr("id", id) .. attr("rows", self.rows) .. attr("wrap", self.wrap) %>>
|
||||
<%-|self:cfgvalue()-%>
|
||||
</textarea>
|
||||
|
@ -2,7 +2,6 @@
|
||||
attr("id", id) ..
|
||||
attr("name", id) ..
|
||||
attr("type", self.password and "password" or "text") ..
|
||||
attr("class", self.password and "gluon-input-password" or "gluon-input-text") ..
|
||||
attr("value", self:cfgvalue()) ..
|
||||
attr("size", self.size) ..
|
||||
attr("placeholder", self.placeholder) ..
|
||||
|
File diff suppressed because one or more lines are too long
@ -276,7 +276,6 @@
|
||||
t.value = values[i-1];
|
||||
t.type = 'text';
|
||||
t.index = i;
|
||||
t.className = 'gluon-input-text';
|
||||
|
||||
if (attr.size)
|
||||
t.size = attr.size;
|
||||
|
@ -15,7 +15,7 @@
|
||||
<%- end %>
|
||||
}, {once: true});
|
||||
|
||||
initOSM(<%=json(self.openlayers_url)%>, function(createMap) {
|
||||
initOSM(<%=json(self.options)%>, function(createMap) {
|
||||
elMap.style.display = '';
|
||||
|
||||
var pos = <%=json(self:cfgvalue().pos)%>;
|
||||
|
@ -1 +1 @@
|
||||
"use strict";function initOSM(e,o){var t=document.createElement("link");t.rel="stylesheet",t.type="text/css",t.href=e+"/css/ol.css",document.head.appendChild(t);var n=document.createElement("script"),r=!1;n.onload=n.onreadystatechange=function(){if(!(r||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)){r=!0;var t=new Image;t.onload=function(){var e=new ol.style.Style({image:new ol.style.Icon({img:t,imgSize:[30,45],anchor:[.5,1]})}),c=new ol.Feature;c.setStyle(e),o(function(e,t,o,n,r){var a=new ol.Map({target:e,layers:[new ol.layer.Tile({source:new ol.source.OSM}),new ol.layer.Vector({source:new ol.source.Vector({features:[c]})})],view:new ol.View({center:ol.proj.fromLonLat(t),zoom:o})}),l=function(e){c.setGeometry(new ol.geom.Point(e))};return a.addEventListener("click",function(e){l(e.coordinate),r(ol.proj.toLonLat(e.coordinate))}),n&&l(ol.proj.fromLonLat(t)),a})},t.src="data:image/svg+xml,"+escape('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="45"><path d="M2,15A13,13,0,0,1,28,13Q28,28,15,45Q2,28,2,15" fill="#48b" stroke="#369" stroke-width="1.5" /><circle cx="15" cy="15" r="6" fill="#fff" /></svg>')}},n.src=e+"/build/ol.js",document.head.appendChild(n)}
|
||||
"use strict";function initOSM(o,r){var e=document.createElement("link");e.rel="stylesheet",e.type="text/css",e.href=o.openlayers_url+"/css/ol.css",document.head.appendChild(e);var t=document.createElement("script"),l=!1;t.onload=t.onreadystatechange=function(){if(!(l||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)){l=!0;var t=new Image;t.onload=function(){var i,e=new ol.style.Style({image:new ol.style.Icon({img:t,imgSize:[30,45],anchor:[.5,1]})}),s=new ol.Feature;s.setStyle(e),i=o.tile_layer&&"XYZ"===o.tile_layer.type?new ol.source.XYZ({url:o.tile_layer.url,attributions:o.tile_layer.attributions}):new ol.source.OSM,r(function(e,t,o,r,l){function n(e){s.setGeometry(new ol.geom.Point(e))}var a=new ol.Map({target:e,layers:[new ol.layer.Tile({source:i}),new ol.layer.Vector({source:new ol.source.Vector({features:[s]})})],view:new ol.View({center:ol.proj.fromLonLat(t),zoom:o})});return a.addEventListener("click",function(e){n(e.coordinate),l(ol.proj.toLonLat(e.coordinate))}),r&&n(ol.proj.fromLonLat(t)),a})},t.src="data:image/svg+xml,"+escape('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="45"><path d="M2,15A13,13,0,0,1,28,13Q28,28,15,45Q2,28,2,15" fill="#48b" stroke="#369" stroke-width="1.5" /><circle cx="15" cy="15" r="6" fill="#fff" /></svg>')}},t.src=o.openlayers_url+"/build/ol.js",document.head.appendChild(t)}
|
@ -6,7 +6,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
function initOSM(openlayers_url, ready) {
|
||||
function initOSM(options, ready) {
|
||||
var markerSvg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="45">'
|
||||
+ '<path d="M2,15A13,13,0,0,1,28,13Q28,28,15,45Q2,28,2,15" fill="#48b" stroke="#369" stroke-width="1.5" />'
|
||||
+ '<circle cx="15" cy="15" r="6" fill="#fff" />'
|
||||
@ -15,7 +15,7 @@ function initOSM(openlayers_url, ready) {
|
||||
var style = document.createElement('link');
|
||||
style.rel = 'stylesheet';
|
||||
style.type = 'text/css';
|
||||
style.href = openlayers_url + '/css/ol.css';
|
||||
style.href = options.openlayers_url + '/css/ol.css';
|
||||
document.head.appendChild(style);
|
||||
|
||||
var script = document.createElement('script');
|
||||
@ -42,12 +42,22 @@ function initOSM(openlayers_url, ready) {
|
||||
var marker = new ol.Feature();
|
||||
marker.setStyle(markerStyle);
|
||||
|
||||
var source;
|
||||
if (options.tile_layer && options.tile_layer.type === 'XYZ') {
|
||||
source = new ol.source.XYZ({
|
||||
url: options.tile_layer.url,
|
||||
attributions: options.tile_layer.attributions,
|
||||
});
|
||||
} else {
|
||||
source = new ol.source.OSM();
|
||||
}
|
||||
|
||||
ready(function(elMap, pos, zoom, set, onUpdate) {
|
||||
var map = new ol.Map({
|
||||
target: elMap,
|
||||
layers: [
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
source: source
|
||||
}),
|
||||
new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
@ -79,6 +89,6 @@ function initOSM(openlayers_url, ready) {
|
||||
|
||||
markerImg.src = 'data:image/svg+xml,' + escape(markerSvg);
|
||||
};
|
||||
script.src = openlayers_url + '/build/ol.js';
|
||||
script.src = options.openlayers_url + '/build/ol.js';
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
@ -15,7 +15,10 @@ M.MapValue = MapValue
|
||||
function MapValue:__init__(title, options)
|
||||
classes.AbstractValue.__init__(self, title)
|
||||
self.subtemplate = "model/osm/map"
|
||||
self.openlayers_url = options.openlayers_url or DEFAULT_URL
|
||||
self.options = {
|
||||
openlayers_url = options.openlayers_url or DEFAULT_URL,
|
||||
tile_layer = options.tile_layer,
|
||||
}
|
||||
self.lon = options.lon
|
||||
self.lat = options.lat
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user