Skip to content

gluon-setup-mode: allow network-triggered activation #2778

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/output
/site
/tmp
/tools
/packages
.bash_history
.subversion
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,18 @@ container: FORCE
@scripts/container.sh


tools:
mkdir -p tools
gcc -o tools/enter-network-config-mode package/gluon-setup-mode/src/send-network-request.c

all: config
+@
$(GLUON_ENV) $(LUA) scripts/clean_output.lua
$(OPENWRTMAKE)
$(GLUON_ENV) $(LUA) scripts/copy_output.lua

clean download: config
rm -rf tools
+@$(OPENWRTMAKE) $@

dirclean: FORCE
Expand Down
21 changes: 21 additions & 0 deletions docs/features/configmode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,27 @@ If you have access to the console of the node, there is the
``gluon-enter-setup-mode`` command, which reboots a node into Config Mode.


Network-Activated Config Mode
-----------------------------

Some models lack a physical button for activating Config Mode. In this case,
Gluon supports Network-Activated Config Mode. A Linux-utility for activation
can be built by invoking ``make tools``.

To enter Config Mode on a device supporting this method, start the
``enter-network-config-mode`` application in the ``tools`` subdirectory. Start
this tool with the name of the network-interface connected to the target
device as argument. Connect to the LAN-Port (or WAN port if the device has
only a signle interface) and power-cycle the device.

Make sure your computer and the target device are directly connected without
an intermediate switch.

This feature is supported for the following list of devices

* ZyXEL NWA55AXE


Port Configuration
------------------

Expand Down
8 changes: 8 additions & 0 deletions package/gluon-autoupdater/files/lib/gluon/autoupdater/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@ start_enabled() {
/etc/init.d/"$1" start
fi
}

flag_invocation() {
if [ "$1" -eq "0" ]; then
rm -f /lib/gluon/autoupdater/upgrade-invocation
else
echo "$1" > /lib/gluon/autoupdater/upgrade-invocation
fi
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

. /lib/gluon/autoupdater/lib.sh


autoupdater_invocation_remove() {
# flag_invocation 0
}

boot_hook_add preinit_main autoupdater_invocation_remove
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/lib/gluon/autoupdater/upgrade-invocation
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

. /lib/gluon/autoupdater/lib.sh

flag_invocation 0

start_enabled cron
start_enabled urngd
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

. /lib/gluon/autoupdater/lib.sh

flag_invocation 1

stop cron
stop urngd
Expand Down
3 changes: 3 additions & 0 deletions package/gluon-setup-mode/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ init_links := \
define Package/gluon-setup-mode/install
$(Gluon/Build/Install)

$(INSTALL_DIR) $(1)/lib/gluon/setup-mode
$(INSTALL_BIN) $(PKG_BUILD_DIR)/wait-network-request $(1)/lib/gluon/setup-mode

$(LN) S20network $(1)/lib/gluon/setup-mode/rc.d/K90network

for link in $(init_links); do \
Expand Down
55 changes: 55 additions & 0 deletions package/gluon-setup-mode/files/lib/preinit/89_network_setup_mode
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/sh

. /lib/functions.sh

device_supports_networked_setup_mode() {
local is_networked="$(lua -e 'print(require("gluon.setup-mode").supports_networked_activation())')"

if [ "${is_networked}" = "true" ]; then
return 0
fi

return 1
}

should_activate_networked() {
local setup_ifnames="$(lua -e 'print(require("gluon.sysconfig").setup_ifname)')"
local should_start=1

if ! device_supports_networked_setup_mode; then
return 1
fi

for iface in $setup_ifnames
do
ip link set dev "${iface}" up
done

# shellcheck disable=SC2086
if /lib/gluon/setup-mode/wait-network-request ${setup_ifnames}; then
should_start=0
fi

for iface in $setup_ifnames
do
ip link set dev "${iface}" down
done

return $should_start
}

network_setup_mode_enable() {
local enabled="$(uci -q get 'gluon-setup-mode.@setup_mode[0].enabled')"
local configured="$(uci -q get 'gluon-setup-mode.@setup_mode[0].configured')"

if [ "$enabled" = 1 ] || [ "$configured" != 1 ]; then
return 0
fi

if should_activate_networked; then
uci -q set 'gluon-setup-mode.@setup_mode[0].enabled=1'
fi
return 0
}

boot_hook_add preinit_main network_setup_mode_enable
1 change: 0 additions & 1 deletion package/gluon-setup-mode/files/lib/preinit/90_setup_mode
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/bin/sh


setup_mode_enable() {
local enabled="$(uci -q get 'gluon-setup-mode.@setup_mode[0].enabled')"
local configured="$(uci -q get 'gluon-setup-mode.@setup_mode[0].configured')"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,12 @@ function M.get_status_led()
end
end

function M.supports_networked_activation()
if platform.match('ramips', 'mt7621', {
'zyxel,nwa55axe',
}) then
return true
end
end

return M
2 changes: 2 additions & 0 deletions package/gluon-setup-mode/src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
enter-setup-mode
check-setup-mode
Comment on lines +1 to +2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be wait-network-request and send-network-request?

16 changes: 16 additions & 0 deletions package/gluon-setup-mode/src/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
CC:=gcc
CFLAGS:=
LDFLAGS:=

all: wait-network-request send-network-request

wait-network-request:
$(CC) $(CFLAGS) $(LDFLAGS) -o wait-network-request wait-network-request.c

send-network-request:
$(CC) $(CFLAGS) $(LDFLAGS) -o send-network-request send-network-request.c

clean:
rm -rf send-network-request wait-network-request

.PHONY: clean all
18 changes: 18 additions & 0 deletions package/gluon-setup-mode/src/gluon-remote-setup-mode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

/* Seconds*/
#define REMOTE_SETUP_MODE_RX_TIMEOUT 5
#define REMOTE_SETUP_MODE_TX_INTERVAL 1

#define REMOTE_SETUP_MODE_MAC_LEN 6
#define REMOTE_SETUP_MODE_DST_MAC_OFFSET 0
#define REMOTE_SETUP_MODE_DST_MAC 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e
#define REMOTE_SETUP_MODE_SRC_MAC_OFFSET 6
#define REMOTE_SETUP_MODE_SRC_MAC 0xda, 0xec, 0xe5, 0x8f, 0x60, 0x14

#define REMOTE_SETUP_MODE_ETHERTYPE_OFFSET (REMOTE_SETUP_MODE_MAC_LEN + REMOTE_SETUP_MODE_MAC_LEN)
#define REMOTE_SETUP_MODE_ETHERTYPE_LEN 2
#define REMOTE_SETUP_MODE_ETHERTYPE 0x23, 0x42

#define REMOTE_SETUP_MODE_DATA_CMD_OFFSET (REMOTE_SETUP_MODE_ETHERTYPE_OFFSET + REMOTE_SETUP_MODE_ETHERTYPE_LEN)
#define REMOTE_SETUP_MODE_DATA_CMD_SETUP "SETUP"
91 changes: 91 additions & 0 deletions package/gluon-setup-mode/src/send-network-request.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* SPDX-License-Identifier: GPL-2.0-only */

/*
* Utility for performing remote setup-mode activation
*
* Copyright (c) David Bauer <[email protected]>
*/

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <string.h>
#include <net/if.h>
#include <errno.h>
#include <sys/ioctl.h>

#include "gluon-remote-setup-mode.h"

#define LLDP_DELAY (REMOTE_SETUP_MODE_TX_INTERVAL * 1000)

char buf[] = {
/* Destination - LLDP Multicast */
REMOTE_SETUP_MODE_DST_MAC,
/* Source */
REMOTE_SETUP_MODE_SRC_MAC,
/* Type */
REMOTE_SETUP_MODE_ETHERTYPE,
/* Magic*/
'S', 'E', 'T', 'U', 'P',
/* Trail */
0x00,
};

int get_ifindex(int sock, const char *ifname)
{
struct ifreq ifr;

strncpy((char *)ifr.ifr_name, ifname, IFNAMSIZ);

if (ioctl(sock, SIOCGIFINDEX, &ifr)) {
printf("IOCTL error: %s\n", strerror(errno));
return -1;
}

return ifr.ifr_ifindex;
}

int main(int argc, char *argv[])
{
struct sockaddr_ll sll;
int ifindex;
int s_fd;

if (argc < 2 || !strcmp("help", argv[1])) {
printf("Usage: %s <ifname>\n", argv[0]);
return 1;
}

s_fd = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if (s_fd < 0) {
printf("Socket error: %s\n", strerror(errno));
return 1;
}

ifindex = get_ifindex(s_fd, argv[1]);
if (ifindex < 0) {
return 1;
}

memset(&sll, 0, sizeof(sll));
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifindex;

printf("Sending Reset command\n");
while (1) {
if (sendto(s_fd, buf, sizeof(buf), 0, (struct sockaddr *) &sll, sizeof(sll)) < 0) {
printf("Error sending packet: %s\n", strerror(errno));
return 1;
}

usleep(LLDP_DELAY);
}

close(s_fd);

return 0;
}
Loading