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
  • experimental
  • hoodselector
  • master
  • nrb/gluon-master-cpe510
  • nrb/test-radv-filter
  • nrbffs/fastd-remove-delay
  • nrbffs/netgear-ex6120
  • radv-filterd
  • v2015.1.x
  • v2016.1.x
  • v2016.2.4-batmanbug
  • v2016.2.x
  • v2018.2.2-ffs
  • v2018.2.3-ffs
  • v2018.2.x
  • 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
  • v2020.2.x
  • v2021.1-ffs
  • v2021.1.1-ffs
  • v2021.1.2-ffs
  • 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
  • v2018.2.3-ffs0.1
  • v2019.1-ffs0.1
  • v2019.1.1-ffs0.1
  • v2019.1.2-ffs0.1
  • v2020.1-ffs0.1
  • v2020.1.1-ffs0.1
  • v2020.1.3-ffs0.1
  • v2020.2
  • v2020.2-ffs0.1
  • v2020.2.1-ffs0.1
  • v2020.2.2-ffs0.1
  • v2020.2.3-ffs0.1
  • v2020.2.3-ffs0.2
  • v2020.2.3-ffs0.3
  • v2020.2.x-ffs0.1
  • v2021.1-ffs0.1
  • v2021.1.1-ffs0.1
  • v2021.1.1-ffs0.2
  • v2021.1.1-ffs0.3
  • v2021.1.1-ffs0.4
  • v2021.1.2-ffs0.1
  • v2021.1.2-ffs0.2
98 results
Show changes
Showing
with 64 additions and 821 deletions
#!/bin/sh
case "$ACTION"
in
ifup)
echo 1 > /sys/devices/virtual/net/br-client/bridge/multicast_snooping
echo 2 > /sys/devices/virtual/net/br-client/bridge/multicast_router
;;
esac
#!/bin/sh /etc/rc.common
USE_PROCD=1
START=45
PORT=33123
DAEMON=/usr/sbin/babeld
pidfile=/var/run/gluon-babeld.pid
CONFIGFILE=/etc/gluon-babeld.conf
BABELOPTSFILE=/tmp/addn-babelopts
touch $BABELOPTSFILE
start_service() {
procd_open_instance
procd_set_param command $DAEMON
procd_append_param command -D -I "$pidfile" -G "$PORT" -c "$CONFIGFILE" $(cat $BABELOPTSFILE) babeldummydoesnotexist
procd_set_param respawn ${respawn_threshold:-60} ${respawn_timeout:-5} ${respawn_retry:-0}
procd_set_param stderr 1
procd_set_param stdout 1
procd_close_instance
}
echotobabel() {
local count=0
local line="$1"
local maxretries=10
while ! (echo -e "$line" | busybox nc ::1 "$PORT" >/dev/null 2>&1)
do
sleep 1
echo retrying to connect to babeld in PID $$, waited ${count}s >&2
count=$((count+1))
if [ $count -gt $maxretries ]; then
return 1
fi
done
return 0
}
waitforsocket() {
echotobabel "dump"
[ $? -gt 0 ] && { echo "Failed to connect to babeld socket on port $PORT, assuming the service was not started properly"; exit 43; }
}
reload_service() {
waitforsocket
for i in $(ubus call network.interface dump | jsonfilter -e "@.interface[@.proto='gluon_mesh' && @.up=true].device")
do
if ! echotobabel dump|grep "add interface"|grep -q $i
then
echotobabel "interface $i update-interval 300"
fi
done
for i in $(echotobabel "dump"|grep "add interface"|cut -d" " -f3)
do
if ! ubus call network.interface dump | jsonfilter -e "@.interface[@.proto='gluon_mesh' && @.up=true].device"|grep -q $i
then
echotobabel "flush interface $i"
fi
done
}
service_triggers() {
local script=$(readlink "$initscript")
local name=$(basename "${script:-$initscript}")
procd_open_trigger
procd_add_raw_trigger "interface.*" 0 "/etc/init.d/$name" reload
procd_close_trigger
}
service_started() {
# make sure the init script does not finish until babeld is actually up.
# unfortunately procd will still start multiple instances of the same script which is why waitforsocket is also run on reload
waitforsocket
}
stop_service(){
kill $(pgrep -P 1 babeld)
}
status() {
kill -USR1 $(pgrep -P 1 babeld)
}
#!/usr/bin/lua
local site = require 'gluon.site'
local uci = require('simple-uci').cursor()
local nodeip = uci:get('network', 'loopback', 'ip6addr'):match('^[^/]+')
local babelconf='/etc/gluon-babeld.conf'
local file = io.open(babelconf, "w")
file:write("ipv6-subtrees true\n")
file:write("reflect-kernel-metric true\n")
file:write("export-table 254\n")
file:write("import-table 254\n")
file:write("out ip " .. site.next_node.ip6() .. "/128 deny\n")
file:write("redistribute ip " .. site.next_node.ip6() .. "/128 deny\n")
file:write("redistribute ip " .. site.prefix6() .. " eq 128 allow\n")
file:write("redistribute ip " .. site.node_client_prefix6() .. " eq 128 allow\n")
file:write("redistribute ip " .. site.node_prefix6() .. " eq 128 allow\n")
file:write("redistribute ip 2000::/3 allow\n")
file:write("redistribute local if br-wan deny\n")
file:write("redistribute local ip 0.0.0.0/0 deny\n")
file:write("install pref-src " .. nodeip .."\n")
file:close()
all: respondd.so neighbours-babel
CFLAGS += -Wall -g -fPIC -D_GNU_SOURCE
ifeq ($(origin PKG_CONFIG), undefined)
PKG_CONFIG = pkg-config
ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null),)
$(error $(PKG_CONFIG) not found)
endif
endif
ifeq ($(origin LIBBABEL_CFLAGS) $(origin LIBBABEL_LDLIBS), undefined undefined)
LIBBABEL_NAME ?= libbabelhelper
ifeq ($(shell $(PKG_CONFIG) --modversion $(LIBBABEL_NAME) 2>/dev/null),)
$(error No $(LIBBABEL_NAME) development libraries found!)
endif
LIBBABEL_CFLAGS += $(shell $(PKG_CONFIG) --cflags $(LIBBABEL_NAME))
LIBBABEL_LDLIBS += $(shell $(PKG_CONFIG) --libs $(LIBBABEL_NAME))
endif
CFLAGS += $(LIBBABEL_CFLAGS)
LDLIBS += $(LIBBABEL_LDLIBS)
CFLAGS_JSONC = $(shell pkg-config --cflags json-c)
LDFLAGS_JSONC = $(shell pkg-config --libs json-c)
respondd.so: respondd.c handle_neighbour.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -shared $(LDFLAGS_JSONC) -o $@ $^ -lgluonutil -lblobmsg_json -lubox -lubus -luci
neighbours-babel: neighbours-babel.c handle_neighbour.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_JSONC) $(LDFLAGS) $(LDLIBS) $(LDFLAGS_JSONC) -o $@ $^
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "handle_neighbour.h"
#include <libbabelhelper/babelhelper.h>
bool handle_neighbour(char **data, void *arg) {
struct json_object *obj = (struct json_object*)arg;
if (data[NEIGHBOUR]) {
struct json_object *neigh = json_object_new_object();
if (data[RXCOST])
json_object_object_add(neigh, "rxcost", json_object_new_int(atoi(data[RXCOST])));
if (data[TXCOST])
json_object_object_add(neigh, "txcost", json_object_new_int(atoi(data[TXCOST])));
if (data[COST])
json_object_object_add(neigh, "cost", json_object_new_int(atoi(data[COST])));
if (data[REACH])
json_object_object_add(neigh, "reachability", json_object_new_double(strtod(data[REACH], NULL)));
if (data[IF])
json_object_object_add(neigh, "ifname", json_object_new_string(data[IF]));
if (data[ADDRESS])
json_object_object_add(obj, data[ADDRESS] , neigh);
}
return true;
}
#include <json-c/json.h>
#include <stdbool.h>
bool handle_neighbour(char **line, void *arg);
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <json-c/json.h>
#include <libbabelhelper/babelhelper.h>
#include "handle_neighbour.h"
int main(void) {
struct json_object *neighbours;
printf("Content-type: text/event-stream\n\n");
fflush(stdout);
struct babelhelper_ctx bhelper_ctx = {};
while (1) {
neighbours = json_object_new_object();
if (!neighbours)
continue;
bhelper_ctx.debug = false;
babelhelper_readbabeldata(&bhelper_ctx, "dump", (void*)neighbours, handle_neighbour);
printf("data: %s\n\n", json_object_to_json_string(neighbours));
fflush(stdout);
json_object_put(neighbours);
neighbours = NULL;
sleep(10);
}
return 0;
}
/*
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.
*/
#include <respondd.h>
#include <json-c/json.h>
#include <libgluonutil.h>
#include <uci.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <errno.h>
#include <libbabelhelper/babelhelper.h>
#include <libubox/blobmsg_json.h>
#include <libubus.h>
#define SOCKET_INPUT_BUFFER_SIZE 255
#define PROTOLEN 32
#define UBUS_TIMEOUT 30000
static struct babelhelper_ctx bhelper_ctx = {};
static void obtain_if_addr(const char *ifname, char *lladdr) {
struct ifaddrs *ifaddr, *ifa;
int family, n;
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
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 (! strncmp("fe80:", lhost, 5) ) {
snprintf( lladdr, NI_MAXHOST, "%s", lhost );
goto cleanup;
}
}
}
cleanup:
freeifaddrs(ifaddr);
}
static char* get_line_from_run(const char* command) {
FILE *fp;
char *line = NULL;
size_t len = 0;
fp = popen(command, "r");
if (fp != NULL) {
ssize_t r = getline(&line, &len, fp);
if (r >= 0) {
len = strlen(line);
if (len && line[len-1] == '\n')
line[len-1] = 0;
}
else {
free(line);
line = NULL;
}
pclose(fp);
}
return line;
}
static struct json_object * get_addresses(void) {
char *primarymac = gluonutil_get_sysconfig("primary_mac");
char *address = malloc(INET6_ADDRSTRLEN+1);
char node_prefix_str[INET6_ADDRSTRLEN+1];
struct in6_addr node_prefix = {};
struct json_object *retval = json_object_new_array();
if (!gluonutil_get_node_prefix6(&node_prefix)) {
fprintf(stderr, "get_addresses: could not obtain mesh-prefix from site.conf. Not adding addresses to json data\n");
goto free;
}
if (inet_ntop(AF_INET6, &(node_prefix.s6_addr), node_prefix_str, INET6_ADDRSTRLEN) == NULL) {
fprintf(stderr, "get_addresses: could not convert mesh-prefix from site.conf to string\n");
goto free;
}
char *prefix_addresspart = strndup(node_prefix_str, INET6_ADDRSTRLEN);
if (! babelhelper_generateip_str(address, primarymac, prefix_addresspart) ) {
fprintf(stderr, "IP-address could not be generated by babelhelper");
}
free(prefix_addresspart);
json_object_array_add(retval, json_object_new_string(address));
free:
free(address);
free(primarymac);
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] = {};
obtain_if_addr(ifname, str_ip);
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);
}
static bool handle_neighbour(char **data, void *obj) {
if (data[NEIGHBOUR]) {
struct json_object *neigh = json_object_new_object();
if (data[RXCOST])
json_object_object_add(neigh, "rxcost", json_object_new_int(atoi(data[RXCOST])));
if (data[TXCOST])
json_object_object_add(neigh, "txcost", json_object_new_int(atoi(data[TXCOST])));
if (data[COST])
json_object_object_add(neigh, "cost", json_object_new_int(atoi(data[COST])));
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 );
nif = json_object_new_object();
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(neighborcollector, data[ADDRESS], neigh);
}
return true;
}
static struct json_object * get_babel_neighbours(void) {
struct json_object *neighbours;
neighbours = json_object_new_object();
if (!neighbours)
return NULL;
babelhelper_readbabeldata(&bhelper_ctx, "dump", (void*)neighbours, handle_neighbour);
return(neighbours);
}
static void blobmsg_handle_list(struct blob_attr *attr, int len, bool array, struct json_object *wireless, struct json_object *tunnel, struct json_object *other);
static void blobmsg_handle_element(struct blob_attr *attr, bool head, char **ifname, char **proto, struct json_object *wireless, struct json_object *tunnel, struct json_object *other) {
void *data;
if (!blobmsg_check_attr(attr, false))
return;
data = blobmsg_data(attr);
switch (blob_id(attr)) {
case BLOBMSG_TYPE_STRING:
if (!strncmp(blobmsg_name(attr), "device", 6)) {
free(*ifname);
*ifname = strndup(data, IF_NAMESIZE);
} else if (!strncmp(blobmsg_name(attr), "proto", 5)) {
free(*proto);
*proto = strndup(data, PROTOLEN);
}
return;
case BLOBMSG_TYPE_ARRAY:
blobmsg_handle_list(data, blobmsg_data_len(attr), true, wireless, tunnel, other);
return;
case BLOBMSG_TYPE_TABLE:
blobmsg_handle_list(data, blobmsg_data_len(attr), false, wireless, tunnel, other);
}
}
static void blobmsg_handle_list(struct blob_attr *attr, int len, bool array, struct json_object *wireless, struct json_object *tunnel, struct json_object *other) {
struct blob_attr *pos;
int rem = len;
char *ifname = NULL;
char *proto = NULL;
__blob_for_each_attr(pos, attr, rem) {
blobmsg_handle_element(pos, array, &ifname, &proto, wireless, tunnel, other);
}
if (ifname && proto) {
if (!strncmp(proto, "gluon_mesh", 10)) {
mesh_add_if(ifname, wireless, tunnel, other);
}
}
free(ifname);
free(proto);
}
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();
struct json_object *tunnel = json_object_new_array();
struct json_object *other = json_object_new_array();
if (!ret || !wireless || !tunnel || !other) {
json_object_put(wireless);
json_object_put(tunnel);
json_object_put(other);
json_object_put(ret);
return;
}
if (!msg) {
printf("empty message\n");
return;
}
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);
*((struct json_object**)(req->priv)) = ret;
}
static struct json_object * get_mesh_ifs() {
struct ubus_context *ubus_ctx;
struct json_object *ret = NULL;
struct blob_buf b = {};
unsigned int id=8;
ubus_ctx = ubus_connect(NULL);
if (!ubus_ctx) {
fprintf(stderr,"could not connect to ubus, not providing mesh-data\n");
goto end;
}
blob_buf_init(&b, 0);
ubus_lookup_id(ubus_ctx, "network.interface", &id);
int uret = ubus_invoke(ubus_ctx, id, "dump", b.head, receive_call_result_data, &ret, UBUS_TIMEOUT);
if (uret > 0)
fprintf(stderr, "ubus command failed: %s\n", ubus_strerror(uret));
else if (uret == -2)
fprintf(stderr, "invalid call, exiting\n");
blob_buf_free(&b);
end:
ubus_free(ubus_ctx);
return ret;
}
static struct json_object * get_mesh(void) {
struct json_object *ret = json_object_new_object();
struct json_object *interfaces = NULL;
interfaces = json_object_new_object();
json_object_object_add(interfaces, "interfaces", get_mesh_ifs());
json_object_object_add(ret, "babel", interfaces);
return ret;
}
static struct json_object * get_babeld_version(void) {
char *version = get_line_from_run("exec babeld -V 2>&1");
struct json_object *ret = gluonutil_wrap_string(version);
free(version);
return ret;
}
static struct json_object * respondd_provider_nodeinfo(void) {
bhelper_ctx.debug=false;
struct json_object *ret = json_object_new_object();
struct json_object *network = json_object_new_object();
json_object_object_add(network, "addresses", get_addresses());
json_object_object_add(network, "mesh", get_mesh());
json_object_object_add(ret, "network", network);
struct json_object *software = json_object_new_object();
struct json_object *software_babeld = json_object_new_object();
json_object_object_add(software_babeld, "version", get_babeld_version());
json_object_object_add(software, "babeld", software_babeld);
json_object_object_add(ret, "software", software);
return ret;
}
static struct json_object * read_number(const char *ifname, const char *stat) {
const char *format = "/sys/class/net/%s/statistics/%s";
struct json_object *ret = NULL;
int64_t i;
char path[strlen(format) + strlen(ifname) + strlen(stat) + 1];
snprintf(path, sizeof(path), format, ifname, stat);
FILE *f = fopen(path, "r");
if (!f)
return NULL;
if (fscanf(f, "%"SCNd64, &i) == 1)
ret = json_object_new_int64(i);
fclose(f);
return ret;
}
static struct json_object * get_traffic(void) {
const char *ifname = "br-client";
struct json_object *ret = NULL;
struct json_object *rx = json_object_new_object();
struct json_object *tx = json_object_new_object();
json_object_object_add(rx, "packets", read_number(ifname, "rx_packets"));
json_object_object_add(rx, "bytes", read_number(ifname, "rx_bytes"));
json_object_object_add(rx, "dropped", read_number(ifname, "rx_dropped"));
json_object_object_add(tx, "packets", read_number(ifname, "tx_packets"));
json_object_object_add(tx, "dropped", read_number(ifname, "tx_dropped"));
json_object_object_add(tx, "bytes", read_number(ifname, "tx_bytes"));
ret = json_object_new_object();
json_object_object_add(ret, "rx", rx);
json_object_object_add(ret, "tx", tx);
return ret;
}
static bool handle_route_addgw_nexthop(char **data, void *arg) {
struct json_object *obj = (struct json_object*) arg;
if (data[PREFIX] && data[FROM] && data[VIA] && data[IF]) {
if ( (! strncmp(data[PREFIX], "::/0", 4) ) && ( ! strncmp(data[FROM], "::/0", 4) ) ) {
int gw_nexthoplen=strlen(data[VIA]) + strlen(data[IF])+2;
char gw_nexthop[gw_nexthoplen];
snprintf(gw_nexthop, gw_nexthoplen , "%s%%%s", data[VIA], data[IF]);
json_object_object_add(obj, "gateway_nexthop", json_object_new_string(gw_nexthop));
}
}
return true;
}
static int json_parse_get_clients(json_object * object) {
if (object) {
json_object_object_foreach(object, key, val) {
if (! strncmp("clients", key, 7)) {
return(json_object_get_int(val));
}
}
}
return(-1);
}
static int ask_l3roamd_for_client_count() {
struct sockaddr_un addr;
const char *socket_path = "/var/run/l3roamd.sock";
int fd;
int clients = -1;
char *buf = NULL;
int already_read = 0;
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "could not setup l3roamd-control-socket\n");
return(-1);
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
fprintf(stderr, "connect error\n");
return(-1);
}
if (write(fd,"get_clients\n",12) != 12) {
perror("could not send command to l3roamd socket: get_clients");
goto end;
}
int rc = 0;
do {
char *buf_tmp = realloc(buf, already_read + SOCKET_INPUT_BUFFER_SIZE + 1);
if (buf_tmp == NULL) {
fprintf(stderr, "could not allocate memory for buffer\n");
goto end;
}
buf = buf_tmp;
rc = read(fd, &buf[already_read], SOCKET_INPUT_BUFFER_SIZE);
already_read+=rc;
if (rc < 0) {
perror("error on read in ask_l3roamd_for_client_count():");
goto end;
}
buf[already_read]='\0';
} while (rc == SOCKET_INPUT_BUFFER_SIZE);
json_object * jobj = json_tokener_parse(buf);
clients = json_parse_get_clients(jobj);
json_object_put(jobj);
end:
free(buf);
close(fd);
return clients;
}
static struct json_object * get_clients(void) {
struct json_object *ret = json_object_new_object();
int total = ask_l3roamd_for_client_count();
if (total >= 0)
json_object_object_add(ret, "total", json_object_new_int(total));
return ret;
}
static struct json_object * respondd_provider_statistics(void) {
struct json_object *ret = json_object_new_object();
json_object_object_add(ret, "clients", get_clients());
json_object_object_add(ret, "traffic", get_traffic());
babelhelper_readbabeldata(&bhelper_ctx, "dump", (void*)ret, handle_route_addgw_nexthop );
return ret;
}
static struct json_object * respondd_provider_neighbours(void) {
struct json_object *ret = json_object_new_object();
struct json_object *babel = get_babel_neighbours();
if (babel)
json_object_object_add(ret, "babel", babel);
return ret;
}
const struct respondd_provider_info respondd_providers[] = {
{"nodeinfo", respondd_provider_nodeinfo},
{"statistics", respondd_provider_statistics},
{"neighbours", respondd_provider_neighbours},
{}
};
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-mesh-batman-adv
PKG_VERSION:=1
include ../gluon.mk
......@@ -19,10 +18,7 @@ define Package/gluon-mesh-batman-adv-15
+kmod-dummy \
+libnl-tiny \
+libbatadv \
+batctl \
+@GLUON_SPECIALIZE_KERNEL:KERNEL_DUMMY \
+@GLUON_SPECIALIZE_KERNEL:KERNEL_CRC16 \
+@GLUON_SPECIALIZE_KERNEL:KERNEL_LIBCRC32C
+batctl
endef
$(eval $(call BuildPackageGluon,gluon-mesh-batman-adv-15))
#!/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
#!/bin/sh
# shellcheck disable=SC3040
set -o pipefail
if ! out=$(batctl gwl -H 2>/dev/null); then
# batctl gwl command failed
exit 1
fi
# node does not have any gateways listed
# and is also not in gw_mode
if [ -z "$out" ] && ! batctl gw_mode | grep -qw '^server'; then
exit 2
fi
#!/bin/sh
out=$(batctl n -H 2>/dev/null) && [ -n "$out" ]
#!/bin/sh
# shellcheck disable=SC1091,SC2034
. /lib/functions.sh
. ../netifd-proto.sh
init_proto "$@"
......@@ -22,22 +24,42 @@ lookup_uci() {
uci -q get "$path" || echo "$default"
}
handle_mesh_interface() {
local proto up device hop_penalty
# Enter item in the array by index
json_select "$2"
json_get_vars proto up device
json_select "data"
json_get_var hop_penalty hop_penalty
json_select ".."
if [ "$proto" = "gluon_mesh" ] && [ "$up" = 1 ]; then
batctl interface add "$device"
batctl hardif "$device" hop_penalty "${hop_penalty:-0}"
fi
json_select ".."
# exit array item at the end of the loop
}
proto_gluon_bat0_renew() {
local config="$1"
lock /var/lock/gluon_bat0.lock
ubus call network.interface dump | jsonfilter \
-e "@.interface[@.proto='gluon_mesh' && @.up=true].device" \
| xargs -r -n 1 batctl interface add
json_load "$(ubus call network.interface dump)"
json_for_each_item handle_mesh_interface interface
lock -u /var/lock/gluon_bat0.lock
}
proto_gluon_bat0_setup() {
local config="$1"
local routing_algo=$(lookup_site 'mesh.batman_adv.routing_algo' 'BATMAN_IV')
local routing_algo
routing_algo="$(lookup_site 'mesh.batman_adv.routing_algo' 'BATMAN_IV')"
local gw_mode
json_get_vars gw_mode
......@@ -47,14 +69,15 @@ proto_gluon_bat0_setup() {
batctl orig_interval 5000
batctl hop_penalty "$(lookup_uci 'gluon.mesh_batman_adv.hop_penalty' 15)"
batctl multicast_mode 0
batctl noflood_mark 0x4/0x4
case "$gw_mode" in
server)
batctl gw_mode "server"
;;
client)
local gw_sel_class="$(lookup_site 'mesh.batman_adv.gw_sel_class')"
local gw_sel_class
gw_sel_class="$(lookup_site 'mesh.batman_adv.gw_sel_class')"
if [ -n "$gw_sel_class" ]; then
batctl gw_mode "client" "$gw_sel_class"
else
......@@ -67,7 +90,8 @@ proto_gluon_bat0_setup() {
esac
local primary0_mac="$(lua -e 'print(require("gluon.util").generate_mac(3))')"
local primary0_mac
primary0_mac="$(lua -e 'print(require("gluon.util").generate_mac_by_name("primary"))')"
ip link add primary0 type dummy
echo 1 > /proc/sys/net/ipv6/conf/primary0/disable_ipv6
......
#!/bin/sh
# shellcheck source=package/gluon-autoupdater/files/lib/gluon/autoupdater/lib.sh
. /lib/gluon/autoupdater/lib.sh
pidof netifd >/dev/null || start_enabled network
#!/bin/sh
# shellcheck source=package/gluon-autoupdater/files/lib/gluon/autoupdater/lib.sh
. /lib/gluon/autoupdater/lib.sh
wifi down
......
......@@ -6,21 +6,15 @@ local util = require 'gluon.util'
local uci = require('simple-uci').cursor()
local gw_mode = uci:get('network', 'gluon_bat0', 'gw_mode') or uci:get('network', 'bat0', 'gw_mode') or 'client'
uci:delete('batman-adv-legacy', 'bat0')
uci:save('batman-adv-legacy')
uci:delete('batman-adv', 'bat0')
uci:save('batman-adv')
uci:delete('network', 'gluon_bat0')
local gw_mode = uci:get('network_gluon-old', 'gluon_bat0', 'gw_mode') or 'client'
uci:section('network', 'interface', 'gluon_bat0', {
proto = 'gluon_bat0',
gw_mode = gw_mode,
})
uci:delete('network', 'bat0')
uci:section('network', 'interface', 'bat0', {
ifname = 'bat0',
proto = 'none',
......
......@@ -21,11 +21,6 @@ uci:section('network', 'interface', 'client', {
query_response_interval = 500,
})
uci:delete('network', 'client_lan')
uci:delete('network', 'local_node_route')
uci:delete('network', 'local_node_route6')
uci:section('network', 'route6', 'local_node_route6', {
interface = 'client',
target = site.prefix6(),
......@@ -42,6 +37,4 @@ networks = uci:get_list('firewall', 'drop', 'network')
util.remove_from_set(networks, 'client')
uci:set_list('firewall', 'drop', 'network', networks)
uci:delete('firewall', 'local_node_dns')
uci:save('firewall')
......@@ -7,9 +7,9 @@ local uci = require('simple-uci').cursor()
-- fix up potentially duplicate MAC addresses (for meshing)
if not site.mesh.vxlan(true) then
uci:set('network', 'wan', 'macaddr', util.generate_mac(0))
else
uci:delete('network', 'wan', 'macaddr')
uci:set('network', 'wan', 'macaddr', util.generate_mac_by_name('wan'))
end
if uci:get('network', 'mesh_other') then
uci:set('network', 'mesh_other', 'macaddr', util.generate_mac_by_name('mesh_other'))
end
uci:set('network', 'mesh_lan', 'macaddr', util.generate_mac(4))
uci:save('network')
/*
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
All rights reserved.
/* SPDX-FileCopyrightText: 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net> */
/* SPDX-License-Identifier: BSD-2-Clause */
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
......
/*
Copyright (c) 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* SPDX-FileCopyrightText: 2016-2019, Matthias Schiffer <mschiffer@universe-factory.net> */
/* SPDX-License-Identifier: BSD-2-Clause */
#include "respondd-common.h"
......