Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 0x4A6F-master
  • 0x4A6F-rpi4
  • autinerd/experimental-openwrt-24.10
  • experimental
  • feature/addMikrotikwAP
  • master
  • nrb/airmax-test
  • nrb/ar9344-reset-sequence
  • nrb/ex400-remove-wps
  • nrb/gluon-master-cpe510
  • nrb/test-radv-filter
  • nrbffs/fastd-remove-delay
  • nrbffs/netgear-ex6120
  • v2018.2.2-ffs
  • v2018.2.3-ffs
  • v2019.1-ffs
  • v2019.1.1-ffs
  • v2019.1.2-ffs
  • v2020.1-ffs
  • v2020.1.1-ffs
  • v2020.1.3-ffs
  • v2020.2-ffs
  • v2020.2.1-ffs
  • v2020.2.2-ffs
  • v2020.2.3-ffs
  • v2021.1-ffs
  • v2021.1.1-ffs
  • v2021.1.2-ffs
  • v2022.1.1-ffs
  • v2022.1.3-ffs
  • v2022.1.4-ffs
  • v2023.1-ffs
  • v2023.2-ffs
  • v2023.2.2-ffs
  • v2023.2.3-ffs
  • v2023.2.4-ffs
  • v2023.2.5-ffs
  • experimental-2022-09-24
  • experimental-2022-09-24-base
  • experimental-2023-03-11
  • experimental-2023-03-11-base
  • experimental-2023-03-12
  • experimental-2023-03-12-base
  • experimental-2023-03-16
  • experimental-2023-03-16-base
  • experimental-2023-03-20
  • experimental-2023-03-20-base
  • experimental-2023-03-23
  • experimental-2023-03-23-base
  • experimental-2023-03-25
  • experimental-2023-03-25-base
  • experimental-2023-03-26
  • experimental-2023-03-26-base
  • experimental-2023-03-30
  • experimental-2023-03-30-base
  • experimental-2023-03-31
  • experimental-2023-03-31-base
  • experimental-2023-04-01
  • experimental-2023-04-01-base
  • experimental-2023-04-08
  • experimental-2023-04-08-base
  • experimental-2023-04-10
  • experimental-2023-04-10-base
  • experimental-2023-04-13
  • experimental-2023-04-13-base
  • experimental-2023-04-15
  • experimental-2023-04-15-base
  • experimental-2023-04-16
  • experimental-2023-04-16-base
  • experimental-2023-04-18
  • experimental-2023-04-18-base
  • experimental-2023-04-20
  • experimental-2023-04-20-base
  • experimental-2023-04-26
  • experimental-2023-04-26-base
  • experimental-2023-04-28
  • experimental-2023-04-28-base
  • experimental-2023-04-30
  • experimental-2023-04-30-base
  • experimental-2023-05-02
  • experimental-2023-05-02-base
  • experimental-2023-05-03
  • experimental-2023-05-03-base
  • experimental-2023-05-12
  • experimental-2023-05-12-base
  • experimental-2023-05-21
  • experimental-2023-05-21-base
  • experimental-2023-05-25
  • experimental-2023-05-25-base
  • experimental-2023-07-02
  • experimental-2023-07-02-base
  • experimental-2023-07-04
  • experimental-2023-07-04-base
  • experimental-2023-07-12
  • experimental-2023-07-12-base
  • experimental-2023-07-16
  • experimental-2023-07-16-base
  • experimental-2023-08-04
  • experimental-2023-08-04-base
  • experimental-2023-08-10
  • experimental-2023-08-10-base
  • experimental-2023-09-08
  • experimental-2023-09-08-base
  • experimental-2023-09-09
  • experimental-2023-09-09-base
  • experimental-2023-09-10
  • experimental-2023-09-10-base
  • experimental-2023-09-11
  • experimental-2023-09-11-base
  • experimental-2023-09-12
  • experimental-2023-09-12-base
  • experimental-2023-09-13
  • experimental-2023-09-13-base
  • experimental-2023-09-15
  • experimental-2023-09-15-base
  • experimental-2023-09-16
  • experimental-2023-09-16-base
  • experimental-2023-09-18
  • experimental-2023-09-18-base
  • experimental-2023-09-20
  • experimental-2023-09-20-base
  • experimental-2023-09-27
  • experimental-2023-09-27-base
  • experimental-2023-09-28
  • experimental-2023-09-28-base
  • experimental-2023-09-29
  • experimental-2023-09-29-base
  • experimental-2023-10-02
  • experimental-2023-10-02-base
  • experimental-2023-10-13
  • experimental-2023-10-13-base
  • experimental-2023-10-14
  • experimental-2023-10-14-base
  • experimental-2023-10-16
  • experimental-2023-10-16-base
  • experimental-2023-10-23
  • experimental-2023-10-23-base
137 results

Target

Select target project
  • firmware/gluon
  • 0x4A6F/gluon
  • patrick/gluon
3 results
Select Git revision
  • 0x4A6F-master
  • 0x4A6F-rpi4
  • 2014.3.x
  • 2014.4.x
  • babel
  • hoodselector
  • master
  • radv-filterd
  • v2015.1.x
  • v2016.1.x
  • v2016.2.4-batmanbug
  • v2016.2.x
  • v2018.2.2-ffs
  • v2018.2.x
  • v2014.1
  • v2014.2
  • v2014.3
  • v2014.3.1
  • v2014.4
  • v2015.1
  • v2015.1.1
  • v2015.1.2
  • v2016.1
  • v2016.1.1
  • v2016.1.2
  • v2016.1.3
  • v2016.1.4
  • v2016.1.5
  • v2016.1.6
  • v2016.2
  • v2016.2.1
  • v2016.2.2
  • v2016.2.3
  • v2016.2.4
  • v2016.2.5
  • v2016.2.6
  • v2016.2.7
  • v2017.1
  • v2017.1.1
  • v2017.1.2
  • v2017.1.3
  • v2017.1.4
  • v2017.1.5
  • v2017.1.6
  • v2017.1.7
  • v2017.1.8
  • v2018.1
  • v2018.1.1
  • v2018.1.2
  • v2018.1.3
  • v2018.1.4
  • v2018.2
  • v2018.2-ffs0.1
  • v2018.2.1
  • v2018.2.1-ffs0.1
  • v2018.2.2-ffs0.1
56 results
Show changes
Showing
with 920 additions and 319 deletions
#!/bin/sh
# shellcheck disable=SC1091
. /lib/functions.sh
. ../netifd-proto.sh
init_proto "$@"
proto_gluon_wireguard_init_config() {
:
}
interface_linklocal_from_wg_public_key() {
# We generate a predictable v6 address
local macaddr
macaddr="$(printf "%s" "$1"|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/')"
local oldIFS="$IFS"; IFS=':';
# shellcheck disable=SC2086
set -- $macaddr; IFS="$oldIFS"
echo "fe80::$1$2:$3ff:fe$4:$5$6"
}
proto_gluon_wireguard_setup() {
local config="$1"
local ifname="$2"
local public_key
public_key="$(/lib/gluon/mesh-vpn/wireguard_pubkey.sh)"
# The wireguard proto itself can not be moved here, as the proto does not
# allow add_dynamic.
local wireguard_ip
wireguard_ip=$(interface_linklocal_from_wg_public_key "$public_key")
## Add IP
proto_add_host_dependency "$config" '' "$ifname"
proto_init_update "$ifname" 1
proto_add_data
json_add_string zone 'wired_mesh'
proto_close_data
proto_add_ipv6_address "$wireguard_ip" "128"
proto_send_update "$ifname"
## wgpeerselector
json_init
json_add_string name "${ifname}_peerselector"
json_add_string ifname "$ifname"
json_add_string proto 'wgpeerselector'
json_add_string unix_group 'gluon-mesh-vpn'
json_close_object
ubus call network add_dynamic "$(json_dump)"
## vxlan
json_init
json_add_string name "mesh-vpn"
json_add_string proto 'vxlan6'
json_add_string tunlink "$ifname"
# ip6addr (the lower interface ip6) is used by the vxlan.sh proto
json_add_string ip6addr "$wireguard_ip"
json_add_string peer6addr "fe80::1"
json_add_int vid "$(lua -e 'print(tonumber(require("gluon.util").domain_seed_bytes("gluon-mesh-vxlan", 3), 16))')"
json_add_boolean rxcsum '0'
json_add_boolean txcsum '0'
json_close_object
ubus call network add_dynamic "$(json_dump)"
proto_init_update "$ifname" 1
proto_send_update "$config"
}
proto_gluon_wireguard_teardown() {
local config="$1"
proto_init_update "*" 0
proto_send_update "$config"
}
add_protocol gluon_wireguard
#!/usr/bin/lua
local uci = require('simple-uci').cursor()
local unistd = require 'posix.unistd'
local util = require('gluon.util')
local site = require 'gluon.site'
local sp = util.subprocess
local wait = require 'posix.sys.wait'
local vpn_core = require('gluon.mesh-vpn')
local _, active_vpn = vpn_core.get_active_provider()
local wg_private_key = uci:get("network_gluon-old", 'wg_mesh', "private_key")
local function valid_fastd_key(fastd_key)
return fastd_key and fastd_key:match(('%x'):rep(64))
end
local function valid_wireguard_key(wireguard_key)
return wireguard_key and wireguard_key:match("^" .. ("[%a%d+/]"):rep(42) .. "[AEIMQUYcgkosw480]=$")
end
local function migrate_from_fastd_secret(fastd_secret)
local options = {
stdin = sp.PIPE,
stdout = sp.PIPE,
}
local pid, pipe = sp.popen('gluon-hex-to-b64', {}, options)
if not pid then
return
end
local inw = pipe.stdin
local out = pipe.stdout
unistd.write(inw, string.format('%s\n', fastd_secret))
unistd.close(inw)
local wpid, status, code = wait.wait(pid)
if wpid and status == 'exited' and code == 0 then
local result = unistd.read(out, 44)
unistd.close(out)
return result
end
end
if not valid_wireguard_key(wg_private_key) then
local fastd_secret = uci:get('fastd', 'mesh_vpn', 'secret')
if valid_fastd_key(fastd_secret) then
wg_private_key = migrate_from_fastd_secret(fastd_secret)
end
end
if not valid_wireguard_key(wg_private_key) then
wg_private_key = "generate"
end
uci:section('network', 'interface', 'wg_mesh', {
proto = 'wireguard',
fwmark = 1,
private_key = wg_private_key,
-- Add 70 bytes for IPv6 VXLAN overhead
mtu = active_vpn.mtu() + 70,
})
uci:section('network', 'interface', 'mesh_wg_mesh', {
ifname = 'wg_mesh',
proto = 'gluon_wireguard'
})
-- Clean up previous configuration
uci:delete_all('wgpeerselector', 'peer', function(peer)
return peer.preserve ~= '1'
end)
for name, peer in pairs(site.mesh_vpn.wireguard.peers()) do
uci:section("wgpeerselector", "peer", name, {
enabled = true,
endpoint = peer.endpoint,
public_key = peer.public_key,
allowed_ips = { "fe80::1/128" },
ifname = 'wg_mesh',
})
end
uci:save("wgpeerselector")
uci:save("network")
local uci = require('simple-uci').cursor()
local site = require 'gluon.site'
local util = require 'gluon.util'
local vpn_core = require 'gluon.mesh-vpn'
local M = {}
function M.public_key()
local key = util.trim(util.exec("/lib/gluon/mesh-vpn/wireguard_pubkey.sh"))
if key == '' then
key = nil
end
return key
end
function M.enable(val)
uci:set('network', 'wg_mesh', 'disabled', not val)
uci:save('network')
end
function M.active()
return site.mesh_vpn.wireguard() ~= nil
end
function M.set_limit(ingress_limit, egress_limit)
uci:delete('simple-tc', 'mesh_vpn')
if ingress_limit ~= nil and egress_limit ~= nil then
uci:section('simple-tc', 'interface', 'mesh_vpn', {
ifname = vpn_core.get_interface(),
enabled = true,
limit_egress = egress_limit,
limit_ingress = ingress_limit,
})
end
uci:save('simple-tc')
end
function M.mtu()
return site.mesh_vpn.wireguard.mtu()
end
return M
all: respondd.so gluon-hex-to-b64
CFLAGS += -Wall -Werror-implicit-function-declaration
gluon-hex-to-b64: gluon-hex-to-b64.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS) -lubox
respondd.so: respondd.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -o $@ $^ $(LDLIBS) -lgluonutil -lubus
// SPDX-FileCopyrightText: 2022 Jan-Niklas Burfeind <gluon@aiyionpri.me>
// SPDX-License-Identifier: BSD-2-Clause
// SPDX-FileContributor: read_hex() by Matthias Schiffer <mschiffer@universe-factory.net>
#include <libubox/utils.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
* how many blocks should be encoded at once - can be configured
*/
#define BLOCK_AMOUNT 32
/**
* smallest possible block size to encode in b64 without further contex
* is three bytes - do not change
*/
#define CHUNK_SIZE (3*BLOCK_AMOUNT)
/** print usage info and exit as failed */
static void usage(void) {
fprintf(stderr, "Usage: gluon-hex-to-b64\n");
exit(1);
}
/**
* read a string of hexadecimal characters and return them as bytes
* return false in case any non-hexadecimal characters are provided
* return true on success
*/
static bool read_hex(uint8_t key[CHUNK_SIZE], const char *hexstr) {
if (strspn(hexstr, "0123456789abcdefABCDEF") != strlen(hexstr))
return false;
size_t i;
for (i = 0; i < CHUNK_SIZE; i++)
sscanf(&hexstr[2 * i], "%02hhx", &key[i]);
return true;
}
int main(int argc, char *argv[]) {
if (argc != 1)
usage();
unsigned char hex_input[CHUNK_SIZE * 2 + 1];
uint8_t as_bytes[CHUNK_SIZE];
int byte_count;
int b64_buflen = B64_ENCODE_LEN(CHUNK_SIZE);
int b64_return;
size_t ret;
char str[b64_buflen];
do {
ret = fread(hex_input, 1, sizeof(hex_input) - 1, stdin);
hex_input[ret] = '\0';
/* in case fread did not fill six characters */
if (ret != sizeof(hex_input)-1) {
/* drop newline by replacing it with a null character */
hex_input[strcspn(hex_input, "\n")] = 0;
/*
* count length of resulting string and make sure it's even,
* as bytes are represented using pairs of hex characters
*/
ret = strlen(hex_input);
if (ret % 2 == 1) {
fprintf(stderr, "Error: Incomplete hex representation of a byte.\n");
exit(EXIT_FAILURE);
}
}
byte_count = ret / 2;
b64_buflen = B64_ENCODE_LEN(byte_count);
/* in case read_hex fails due to invalid characters */
if (!read_hex(as_bytes, hex_input)) {
fprintf(stderr, "Error: Invalid hexadecimal input.\n");
exit(EXIT_FAILURE);
}
b64_return = b64_encode(as_bytes, byte_count, str, b64_buflen);
/* trailing '\0' is not counted by b64_encode(), so we subtract one character */
if (b64_buflen - 1 != b64_return) {
fprintf(stderr, "Error: Encoding bytes as b64 failed.\n");
exit(EXIT_FAILURE);
}
printf("%s", str);
/* repeat until a non full block is read */
} while (ret == sizeof(hex_input)-1);
printf("\n");
exit(EXIT_SUCCESS);
}
/* SPDX-FileCopyrightText: 2020, Leonardo Mörlein <me@irrelefant.net> */
/* SPDX-FileCopyrightText: 2016, Matthias Schiffer <mschiffer@universe-factory.net> */
/* SPDX-License-Identifier: BSD-2-Clause */
#include <respondd.h>
#include <json-c/json.h>
#include <libgluonutil.h>
#include <uci.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "libubus.h"
static struct json_object * stdout_read(const char *cmd, const char *skip, bool oneword) {
FILE *f = popen(cmd, "r");
if (!f)
return NULL;
char *line = NULL;
size_t len = 0;
size_t skiplen = strlen(skip);
ssize_t read_chars = getline(&line, &len, f);
pclose(f);
if (read_chars < 1) {
free(line);
return NULL;
}
if (line[read_chars-1] == '\n')
line[read_chars-1] = '\0';
const char *content = line;
if (strncmp(content, skip, skiplen) == 0)
content += skiplen;
if (oneword) {
for (int i = 0; i < len; i++) {
if (isspace(line[i])) {
line[i] = 0;
}
}
}
struct json_object *ret = gluonutil_wrap_string(content);
free(line);
return ret;
}
static struct json_object * get_wireguard_public_key(void) {
return stdout_read("exec /lib/gluon/mesh-vpn/wireguard_pubkey.sh", "", false);
}
static struct json_object * get_wireguard_version(void) {
return stdout_read("exec wg -v", "wireguard-tools ", true);
}
static bool wireguard_enabled(void) {
bool enabled = true;
struct uci_context *ctx = uci_alloc_context();
if (!ctx)
goto disabled_nofree;
ctx->flags &= ~UCI_FLAG_STRICT;
struct uci_package *p;
if (uci_load(ctx, "network", &p))
goto disabled;
struct uci_section *s = uci_lookup_section(ctx, p, "wg_mesh");
if (!s)
goto disabled;
const char *disabled_str = uci_lookup_option_string(ctx, s, "disabled");
if (!disabled_str || !strcmp(disabled_str, "1"))
enabled = false;
disabled:
uci_free_context(ctx);
disabled_nofree:
return enabled;
}
static bool get_pubkey_privacy(void) {
bool ret = true;
struct json_object *site = NULL;
site = gluonutil_load_site_config();
if (!site)
goto end;
struct json_object *mesh_vpn;
if (!json_object_object_get_ex(site, "mesh_vpn", &mesh_vpn))
goto end;
struct json_object *pubkey_privacy;
if (!json_object_object_get_ex(mesh_vpn, "pubkey_privacy", &pubkey_privacy))
goto end;
ret = json_object_get_boolean(pubkey_privacy);
end:
json_object_put(site);
return ret;
}
static struct json_object * get_wireguard(void) {
bool wg_enabled = wireguard_enabled();
struct json_object *ret = json_object_new_object();
json_object_object_add(ret, "version", get_wireguard_version());
json_object_object_add(ret, "enabled", json_object_new_boolean(wg_enabled));
if (wg_enabled && !get_pubkey_privacy())
json_object_object_add(ret, "public_key", get_wireguard_public_key());
return ret;
}
static struct json_object * respondd_provider_nodeinfo(void) {
struct json_object *ret = json_object_new_object();
struct json_object *software = json_object_new_object();
json_object_object_add(software, "wireguard", get_wireguard());
json_object_object_add(ret, "software", software);
return ret;
}
static json_object *blobmsg_attr2json(struct blob_attr *attr, int type)
{
int len = blobmsg_data_len(attr);
struct blobmsg_data *data = blobmsg_data(attr);
struct blob_attr *inner_attr;
json_object *res = NULL;
switch(type) {
case BLOBMSG_TYPE_STRING:
return gluonutil_wrap_string(blobmsg_get_string(attr));
case BLOBMSG_TYPE_BOOL:
return json_object_new_boolean(blobmsg_get_bool(attr));
case BLOBMSG_TYPE_INT16:
return json_object_new_double(blobmsg_get_u16(attr));
case BLOBMSG_TYPE_INT32:
return json_object_new_double(blobmsg_get_u32(attr));
case BLOBMSG_TYPE_INT64:
return json_object_new_double(blobmsg_get_u64(attr));
case BLOBMSG_TYPE_DOUBLE:
return json_object_new_double(blobmsg_get_double(attr));
case BLOBMSG_TYPE_TABLE:
res = json_object_new_object();
__blob_for_each_attr(inner_attr, data, len) {
json_object_object_add(res, blobmsg_name(inner_attr), blobmsg_attr2json(inner_attr, blobmsg_type(inner_attr)));
};
break;
case BLOBMSG_TYPE_ARRAY:
res = json_object_new_array();
__blob_for_each_attr(inner_attr, data, len) {
json_object_array_add(res, blobmsg_attr2json(inner_attr, blobmsg_type(inner_attr)));
}
break;
}
return res;
}
static void cb_wgpeerselector_vpn(struct ubus_request *req, int type, struct blob_attr *msg)
{
json_object_object_add(req->priv, "mesh_vpn", blobmsg_attr2json(msg, type));
}
static struct json_object * respondd_provider_statistics(void) {
struct json_object *ret = json_object_new_object();
struct ubus_context *ctx = ubus_connect(NULL);
uint32_t ubus_path_id;
if (!ctx) {
fprintf(stderr, "Error in gluon-mesh-vpn-wireguard.so: Failed to connect to ubus.\n");
goto err;
}
if (ubus_lookup_id(ctx, "wgpeerselector.wg_mesh", &ubus_path_id)) {
goto err;
}
ubus_invoke(ctx, ubus_path_id, "status", NULL, cb_wgpeerselector_vpn, ret, 1000);
err:
if (ctx)
ubus_free(ctx);
return ret;
}
const struct respondd_provider_info respondd_providers[] = {
{"nodeinfo", respondd_provider_nodeinfo},
{"statistics", respondd_provider_statistics},
{}
};
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-mesh-wireless-sae
include ../gluon.mk
define Package/gluon-mesh-wireless-sae
TITLE:=Encryption of 802.11s Mesh Links through SAE
DEPENDS:=+gluon-core +wpa-supplicant-mesh-mbedtls
endef
$(eval $(call BuildPackageGluon,gluon-mesh-wireless-sae))
need_boolean({'wifi', 'mesh', 'sae'}, false)
need_string({'wifi', 'mesh', 'sae_passphrase'}, false)
#!/usr/bin/lua
local site = require 'gluon.site'
local wireless = require 'gluon.wireless'
local hash = require 'hash'
local uci = require('simple-uci').cursor()
local function configure_sae(vif)
uci:set('wireless', vif, 'encryption', 'sae')
uci:set('wireless', vif, 'key', site.wifi.mesh.sae_passphrase() or hash.md5(site.prefix6()))
end
wireless.foreach_radio(uci, function(radio)
local radio_name = radio['.name']
local vif = 'mesh_' .. radio_name
local enable = site.wifi.mesh.sae(false)
if uci:get('wireless', vif) then
uci:delete('wireless', vif, 'encryption')
uci:delete('wireless', vif, 'key')
if enable then
configure_sae(vif)
end
end
end)
uci:save('wireless')
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-mmfd
include ../gluon.mk
define Package/gluon-mmfd
TITLE:=Mesh multicast forwarding daemon - Gluon integration
DEPENDS:=+mmfd +uc +gluon-core
endef
$(eval $(call BuildPackageGluon,gluon-mmfd))
#!/bin/sh /etc/rc.common
USE_PROCD=1
START=50
DAEMON=/usr/sbin/mmfd
SOCKET=/var/run/mmfd.sock
waitforsocket() {
while ! echo "get_neighbours" | uc $SOCKET
do
sleep 1
echo "waiting for successful socket connection for mmfd"
done
}
start_service() {
local interfaces
interfaces=$(for dev in $(gluon-list-mesh-interfaces); do echo " -i $dev"; done)
procd_open_instance
# shellcheck disable=SC2086
procd_set_param command "$DAEMON" -s "$SOCKET" $interfaces
procd_set_param respawn "${respawn_threshold:-60}" "${respawn_timeout:-1}" "${respawn_retry:-0}"
procd_set_param stderr 1
procd_set_param stdout 1
procd_close_instance
}
mmfd_get_interfaces() {
echo get_meshifs | uc $SOCKET | jsonfilter -e "@.mesh_interfaces[@]"
}
mmfd_has_interface() {
mmfd_get_interfaces | grep -qxF "$1"
}
addif() {
echo "add_meshif $1" | uc $SOCKET
}
delif() {
echo "del_meshif $1" | uc $SOCKET
}
reload_service() {
waitforsocket
for i in $(ubus call network.interface dump | jsonfilter -e "@.interface[@.proto='gluon_mesh' && @.up=true].device")
do
if ! mmfd_has_interface "$i"; then
addif "$i"
fi
done
for i in $(mmfd_get_interfaces)
do
if ! ubus call network.interface dump | jsonfilter -e "@.interface[@.proto='gluon_mesh' && @.up=true].device" | grep -qxF "$i"; then
delif "$i"
fi
done
}
service_triggers() {
local script name
# shellcheck disable=SC2154
script=$(readlink "$initscript")
name=$(basename "${script:-$initscript}")
procd_open_trigger
procd_add_raw_trigger "interface.*" 0 "/etc/init.d/$name" reload
procd_close_trigger
}
......@@ -3,15 +3,6 @@
local uci = require('simple-uci').cursor()
local site = require "gluon.site"
uci:section('firewall', 'zone', 'l3roamd', {
name = 'l3roamd',
input = 'ACCEPT',
output = 'ACCEPT',
forward = 'REJECT',
device = 'l3roam+',
log = '1',
})
uci:section('firewall', 'zone', 'mmfd', {
name = 'mmfd',
input = 'REJECT',
......@@ -21,35 +12,12 @@ uci:section('firewall', 'zone', 'mmfd', {
log = '1',
})
-- forwardings and respective rules
uci:section('firewall', 'forwarding', 'fcc', {
src = 'local_client',
dest = 'local_client',
})
uci:section('firewall', 'forwarding', 'fcm', {
src = 'local_client',
dest = 'mesh',
})
uci:section('firewall', 'forwarding', 'fmc', {
src = 'mesh',
dest = 'local_client',
})
uci:section('firewall', 'forwarding', 'fmm', {
uci:section('firewall', 'rule', 'mesh_mmfd', {
src = 'mesh',
dest = 'mesh',
})
uci:section('firewall', 'forwarding', 'flc', {
src = 'l3roamd',
dest = 'local_client',
})
uci:section('firewall', 'forwarding', 'fcl', {
src = 'local_client',
dest = 'l3roamd',
src_ip = 'fe80::/64',
dest_port = '27275',
proto = 'udp',
target = 'ACCEPT',
})
uci:section('firewall', 'rule', 'mesh_respondd_mcast_ll', {
......@@ -62,7 +30,7 @@ uci:section('firewall', 'rule', 'mesh_respondd_mcast_ll', {
uci:section('firewall', 'rule', 'mesh_respondd_mcast2', {
src = 'mesh',
src_ip = site.node_prefix6(),
src_ip = site.node_prefix6() or site.prefix6(),
dest_port = '1001',
proto = 'udp',
target = 'ACCEPT',
......@@ -78,26 +46,10 @@ uci:section('firewall', 'rule', 'mmfd_respondd_ll', {
uci:section('firewall', 'rule', 'mmfd_respondd_mesh', {
src = 'mmfd',
src_ip = site.node_prefix6(),
src_ip = site.node_prefix6() or site.prefix6(),
dest_port = '1001',
proto = 'udp',
target = 'ACCEPT',
})
uci:section('firewall', 'rule', 'mesh_mmfd', {
src = 'mesh',
src_ip = 'fe80::/64',
dest_port = '27275',
proto = 'udp',
target = 'ACCEPT',
})
uci:section('firewall', 'rule', 'mesh_babel', {
src = 'mesh',
src_ip = 'fe80::/64',
dest_port = '6696',
proto = 'udp',
target = 'ACCEPT',
})
uci:save('firewall')
......@@ -2,10 +2,10 @@
local uci = require('simple-uci').cursor()
uci:delete('network', 'mmfd')
uci:section('network', 'interface', 'mmfd', {
proto = 'static',
ifname = 'mmfd0',
ip6addr = 'fe80::1/64'
})
uci:save('network')
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-neighbour-info
PKG_VERSION:=1
PKG_RELEASE:=1
include ../gluon.mk
......
......@@ -4,8 +4,7 @@ local uci = require('simple-uci').cursor()
-- Allow incoming respondd replies to queries on WAN
-- If the query was via multicast, the response isn't matched by --state RELATED
uci:section('firewall', 'rule', 'wan_respondd_reply',
{
uci:section('firewall', 'rule', 'wan_respondd_reply', {
name = 'wan_respondd_reply',
src = 'wan',
src_ip = 'fe80::/64',
......@@ -13,11 +12,9 @@ uci:section('firewall', 'rule', 'wan_respondd_reply',
dest_port = '32768:61000', -- see /proc/sys/net/ipv4/ip_local_port_range
proto = 'udp',
target = 'ACCEPT',
}
)
})
uci:section('firewall', 'rule', 'mesh_respondd_reply',
{
uci:section('firewall', 'rule', 'mesh_respondd_reply', {
name = 'mesh_respondd_reply',
src = 'mesh',
src_ip = 'fe80::/64',
......@@ -25,7 +22,6 @@ uci:section('firewall', 'rule', 'mesh_respondd_reply',
dest_port = '32768:61000', -- see /proc/sys/net/ipv4/ip_local_port_range
proto = 'udp',
target = 'ACCEPT',
}
)
})
uci:save('firewall')
/*
Copyright (c) 2014, Nils Schneider <nils@nilsschneider.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* SPDX-FileCopyrightText: 2014, Nils Schneider <nils@nilsschneider.net> */
/* SPDX-License-Identifier: BSD-2-Clause */
#include <stdbool.h>
#include <stdio.h>
......@@ -37,14 +15,15 @@
void usage() {
puts("Usage: gluon-neighbour-info [-h] [-s] [-l] [-c <count>] [-t <sec>] -d <dest> -p <port> -i <if0> -r <request>");
puts(" -p <int> UDP port");
puts(" -d <ip6> destination address (unicast ip6 or multicast group, e.g. ff02:0:0:0:0:0:2:1001)");
puts(" -p <int> UDP port (default: 1001)");
puts(" -d <ip6> destination address (unicast ip6 or multicast group, e.g. ff02:0:0:0:0:0:2:1001, default: ::1)");
puts(" -i <string> interface, e.g. eth0 ");
puts(" -r <string> request, e.g. nodeinfo");
puts(" -t <sec> timeout in seconds (default: 3)");
puts(" -s <event> output as server-sent events of type <event>");
puts(" or without type if <event> is the empty string");
puts(" -c <count> only wait for at most <count> replies");
puts(" -c <count> only wait for at most <count> replies (default: 1");
puts(" if -l is not given for unicast destination addresses)");
puts(" -l after timeout (or <count> replies if -c is given),");
puts(" send another request and loop forever");
puts(" -h this help\n");
......@@ -68,8 +47,23 @@ void tv_subtract (struct timeval *r, const struct timeval *a, const struct timev
}
}
ssize_t recvtimeout(int socket, void *buffer, size_t length, int flags, const struct timeval *timeout) {
void resize_recvbuffer(char **recvbuffer, size_t *recvbuffer_len, size_t recvlen)
{
free(*recvbuffer);
*recvbuffer = malloc(recvlen);
if (!(*recvbuffer)) {
perror("Could not resize recvbuffer");
exit(EXIT_FAILURE);
}
*recvbuffer_len = recvlen;
}
ssize_t recvtimeout(int socket, char **recvbuffer, size_t *recvbuffer_len,
const struct timeval *timeout) {
struct timeval now, timeout_left;
ssize_t recvlen;
getclock(&now);
tv_subtract(&timeout_left, timeout, &now);
......@@ -78,18 +72,28 @@ ssize_t recvtimeout(int socket, void *buffer, size_t length, int flags, const st
return -1;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &timeout_left, sizeof(timeout_left));
return recv(socket, buffer, length, flags);
recvlen = recv(socket, *recvbuffer, 0, MSG_PEEK | MSG_TRUNC);
if (recvlen < 0)
return recvlen;
if (recvlen > *recvbuffer_len)
resize_recvbuffer(recvbuffer, recvbuffer_len, recvlen);
return recv(socket, *recvbuffer, *recvbuffer_len, 0);
}
int request(const int sock, const struct sockaddr_in6 *client_addr, const char *request, const char *sse, double timeout, unsigned int max_count) {
int request(const int sock, char **recvbuffer, size_t *recvbuffer_len,
const struct sockaddr_in6 *client_addr, const char *request,
const char *sse, double timeout, unsigned int max_count) {
ssize_t ret;
char buffer[8192];
unsigned int count = 0;
ret = sendto(sock, request, strlen(request), 0, (struct sockaddr *)client_addr, sizeof(struct sockaddr_in6));
if (ret < 0) {
perror("Error in sendto()");
free(*recvbuffer);
exit(EXIT_FAILURE);
}
......@@ -104,7 +108,7 @@ int request(const int sock, const struct sockaddr_in6 *client_addr, const char *
}
do {
ret = recvtimeout(sock, buffer, sizeof(buffer), 0, &tv_timeout);
ret = recvtimeout(sock, recvbuffer, recvbuffer_len, &tv_timeout);
if (ret < 0)
break;
......@@ -115,7 +119,7 @@ int request(const int sock, const struct sockaddr_in6 *client_addr, const char *
fputs("data: ", stdout);
}
fwrite(buffer, sizeof(char), ret, stdout);
fwrite(*recvbuffer, sizeof(char), ret, stdout);
if (sse)
fputs("\n\n", stdout);
......@@ -136,6 +140,8 @@ int main(int argc, char **argv) {
int sock;
struct sockaddr_in6 client_addr = {};
char *request_string = NULL;
char *recvbuffer = NULL;
size_t recvbuffer_len = 0;
sock = socket(PF_INET6, SOCK_DGRAM, 0);
......@@ -144,6 +150,8 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}
client_addr.sin6_addr = in6addr_loopback;
client_addr.sin6_port = htons(1001);
client_addr.sin6_family = AF_INET6;
opterr = 0;
......@@ -162,7 +170,7 @@ int main(int argc, char **argv) {
break;
case 'd':
if (!inet_pton(AF_INET6, optarg, &client_addr.sin6_addr)) {
perror("Invalid IPv6 address. This message will probably confuse you");
fprintf(stderr, "Invalid destination address\n");
exit(EXIT_FAILURE);
}
break;
......@@ -201,7 +209,8 @@ int main(int argc, char **argv) {
exit(EXIT_SUCCESS);
break;
default:
fprintf(stderr, "Invalid parameter %c ignored.\n", c);
fprintf(stderr, "Invalid parameter %c\n", optopt);
exit(EXIT_FAILURE);
}
if (request_string == NULL) {
......@@ -219,17 +228,35 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}
if (client_addr.sin6_scope_id) {
if (setsockopt(
sock, IPPROTO_IPV6, IPV6_MULTICAST_IF,
&client_addr.sin6_scope_id, sizeof(client_addr.sin6_scope_id)
) < 0) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
}
if (!loop && !IN6_IS_ADDR_MULTICAST(&client_addr.sin6_addr)) {
max_count=1;
}
if (sse) {
fputs("Content-Type: text/event-stream\n\n", stdout);
fflush(stdout);
}
resize_recvbuffer(&recvbuffer, &recvbuffer_len, 8192);
do {
ret = request(sock, &client_addr, request_string, sse, timeout, max_count);
ret = request(sock, &recvbuffer, &recvbuffer_len, &client_addr,
request_string, sse, timeout, max_count);
} while(loop);
if (sse)
fputs("event: eot\ndata: null\n\n", stdout);
free(recvbuffer);
return ret;
}
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-node-info
PKG_VERSION:=1
PKG_RELEASE:=1
include ../gluon.mk
......@@ -11,4 +9,8 @@ define Package/gluon-node-info
DEPENDS:=+gluon-core +libgluonutil
endef
define Package/gluon-node-info/conffiles
/etc/config/gluon-node-info
endef
$(eval $(call BuildPackageGluon,gluon-node-info))
#!/usr/bin/lua
local uci = require('simple-uci').cursor()
local util = require 'gluon.util'
local sname = uci:get_first('gluon-node-info', 'location')
if sname then
local options = {'longitude', 'latitude', 'altitude'}
for _, option in ipairs(options) do
local value = uci:get('gluon-node-info', sname, option)
if value then
uci:set('gluon-node-info', sname, option, util.trim(value))
end
end
uci:save('gluon-node-info')
end
/*
Copyright (c) 2016, Matthias Schiffer <mschiffer@universe-factory.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* SPDX-FileCopyrightText: 2016, Matthias Schiffer <mschiffer@universe-factory.net> */
/* SPDX-License-Identifier: BSD-2-Clause */
#include <respondd.h>
......