nix/lib/config: begin treating aps as manageable switches

This commit is contained in:
Astro 2021-11-04 19:17:31 +01:00
parent 8acc37b5d5
commit 9852920ee8
6 changed files with 325 additions and 251 deletions

View File

@ -31,6 +31,14 @@ let
net == "pub" ||
net == "serv" ||
builtins.match "priv[[:digit:]]+" net != null;
whoLinksTo = target:
builtins.attrNames (
lib.filterAttrs (hostName: { ports, ... }:
hostName != target &&
ports ? ${target}
) pillar.switches
);
in
{
options.salt-pillar = lib.mkOption {};
@ -385,6 +393,7 @@ in
(builtins.mapAttrs (_: switch: {
inherit (switch) model location password;
role = "switch";
interfaces.mgmt.type = "phys";
links = builtins.mapAttrs (_: { ports, group ? null, ... }: {
group = if group != null
then toString group
@ -397,7 +406,7 @@ in
}) switch.ports;
}) pillar.switches)
(builtins.mapAttrs (_: ap: {
(builtins.mapAttrs (hostName: ap: {
inherit (ap) model location password;
role = "ap";
@ -416,6 +425,35 @@ in
map ({ net, ... }: net) (builtins.attrValues ssids)
) (builtins.attrValues ap.radios)
);
links =
let
wanTargets = whoLinksTo hostName;
model = self.lib.getOpenwrtModel ap.model;
getPorts = regex:
map (port: {
port = port.port;
phys = port.port;
}.${port.type}) (
builtins.filter (port:
port ? port &&
builtins.match regex port.port != null
) (builtins.attrValues model.ports)
);
in
if model ? ports
then
lib.optionalAttrs (builtins.length wanTargets > 0) {
"${builtins.head wanTargets}".ports = getPorts "wan";
} // lib.optionalAttrs (ap ? lan-access) {
"${ap.lan-access}".ports = getPorts "lan.*";
}
else
builtins.trace "No known ports for OpenWRT model ${ap.model}"
{};
wifi = ap.radios;
}) pillar.cpe)
(builtins.mapAttrs (name: container:

View File

@ -2,41 +2,34 @@
with lib;
let
getLinkNets = link:
getHostNets = link:
let
hostConfig = config.site.hosts.${link};
sort = builtins.sort (net1: net2:
config.site.net.${net1}.vlan < config.site.net.${net2}.vlan
sort = nets: lib.unique (
builtins.sort (net1: net2:
config.site.net.${net1}.vlan < config.site.net.${net2}.vlan
) nets
);
in
if config.site.hosts ? ${link}
then
if builtins.elem hostConfig.role [ "container" "server" "ap" ]
then sort (builtins.attrNames hostConfig.interfaces)
else if hostConfig.role == "switch"
then sort (getSwitchNets link)
else if hostConfig.role == "client"
then if hostConfig.interfaces == {}
then builtins.trace "No known networks implemented for client \"${link}\"" []
else sort (builtins.attrNames hostConfig.interfaces)
else throw "getHostNets not implemented for role \"${hostConfig.role}\""
sort (
builtins.attrNames hostConfig.interfaces ++
getLinksNets link
)
else if config.site.net ? ${link}
then [ link ]
else builtins.trace "Don't know what nets to configure for link to \"${link}\"" [];
# breaks the getLinkNets recursion for switches,
# breaks the getHostNets recursion for switches,
# requiring any net to be used by at >1 links
getSwitchNets = hostName:
getLinksNets = hostName:
let
linksNets = builtins.mapAttrs (link: _:
unique (
getSwitchNets' { "${hostName}" = true; } [ link ]
getLinkNets { "${hostName}" = true; } [ link ]
)
) config.site.hosts.${hostName}.links;
allNets = unique (
@ -51,9 +44,9 @@ let
nets = builtins.filter (net:
netLinkCount net > 1
) allNets;
in nets; #builtins.trace "getSwitchNets ${hostName} = ${concatStringsSep "," nets}" nets;
in nets;
getSwitchNets' = seen: links:
getLinkNets = seen: links:
if links == []
then []
else
@ -62,18 +55,17 @@ let
seen' = seen // {
"${link}" = true;
};
onlyUnseen = builtins.filter (link: ! seen' ? ${link});
links' = builtins.tail links;
in
if config.site.hosts ? ${link} &&
config.site.hosts.${link}.role == "switch"
then getSwitchNets' seen' (
links' ++ (builtins.attrNames config.site.hosts.${link}.links)
if config.site.hosts ? ${link}
then getLinkNets seen' (
links' ++ (
onlyUnseen (builtins.attrNames config.site.hosts.${link}.links)
)
)
else getLinkNets link ++
getSwitchNets' seen' (
builtins.filter (link: ! seen' ? ${link})
links'
);
else getHostNets link ++
getLinkNets seen' (onlyUnseen links');
dhcpOpts = {
start = mkOption {
@ -245,6 +237,13 @@ let
Include the container system in the server's `build-container` script.
'';
};
firstboot = mkOption {
type = types.bool;
default = false;
description = ''
true if host is a newly flashed OpenWRT device with a default address
'';
};
role = mkOption {
type = types.enum [ "ap" "switch" "server" "container" "client" ];
default = "client";
@ -385,6 +384,36 @@ let
default = {};
type = with types; attrsOf (submodule linkOpts);
};
wifi = mkOption {
default = {};
type = with types; attrsOf (submodule (
{ name, ... }: {
options = {
htmode = mkOption {
type = enum [ "HT20" "HT40-" "HT40+" "VHT80" ];
};
channel = mkOption {
type = int;
};
ssids = mkOption {
type = attrsOf (submodule (
{ name, ... }: {
options = {
net = mkOption {
type = str;
};
psk = mkOption {
type = nullOr str;
default = null;
};
};
}
));
};
};
}
));
};
};
};
@ -417,15 +446,15 @@ let
};
nets = mkOption {
type = with types; listOf str;
description = "Set for clients, automatically generated for others";
default = getLinkNets name;
description = "Automatically generated";
default = getHostNets name;
};
vlans = mkOption {
type = with types; listOf int;
description = "Automatically generated, do not set";
default = map (net:
config.site.net.${net}.vlan
) (getLinkNets name);
) (getHostNets name);
};
};
};

View File

@ -16,4 +16,22 @@ rec {
dns = import ./dns.nix { inherit pkgs config; };
openwrtModels = import ./openwrt-models.nix { inherit self openwrt; };
getOpenwrtModel = wantedModel:
let
models =
builtins.filter ({ models, ... }:
self.lib.any ({ model, ... }:
model == wantedModel
) models
) openwrtModels;
result =
builtins.foldl' (result: { data, ... }:
self.lib.recursiveUpdate result data
) {} models;
in
if builtins.length models > 0
then result
else builtins.trace "No data found for OpenWRT model ${wantedModel}"
{};
}

View File

@ -16,20 +16,31 @@ let
parseCommand = line:
let
tokens = builtins.split "[[:space:]]+" line;
words =
builtins.map (word:
let m = builtins.match "\"(.+)\"" word;
in if m != null
then builtins.head m
else word
tokens =
builtins.concatMap (frag:
if builtins.isString frag
then builtins.split "[[:space:]]+" frag
else frag
) (
builtins.filter (word:
word != [] && word != ""
) tokens
builtins.split "\"([^\"]*)\"" line
);
words =
builtins.filter (word:
word != [] && word != ""
) tokens;
command = builtins.head words;
args = builtins.tail words;
makeLinkFromArg = port: arg:
builtins.foldl' (result: interface:
if port != []
then result // {
type = "phys";
inherit interface port;
}
else result
) {} (builtins.split "[[:space:]]+" arg);
commands = {
ucidef_add_switch.ports = builtins.foldl' (ports: arg:
let
@ -62,6 +73,21 @@ let
}
else builtins.trace "Unimplemented port scheme: ${arg}" ports
) {} (builtins.tail args);
ucidef_set_interface_wan.ports = {
"${builtins.head args}" = {
type = "phys";
interface = builtins.head args;
port = "wan";
};
};
ucidef_set_interface_lan.ports =
makeLinkFromArg "lan" (builtins.elemAt args 0);
ucidef_set_interfaces_lan_wan.ports =
makeLinkFromArg "lan" (builtins.elemAt args 0) //
makeLinkFromArg "wan" (builtins.elemAt args 1);
};
in
if commands ? ${command}
@ -74,7 +100,7 @@ in (
builtins.foldl' ({ state, result, models ? null, data ? {} }: line:
if state == "start"
then
if builtins.match "[[:space:]]*case \"\\$board\" in" line != null
if builtins.match "[[:space:]]*case \"?\\$board\"? in" line != null
then { state = "case"; inherit result; }
else { inherit state result; }

View File

@ -1,14 +1,24 @@
{ pkgs, hostName, config, hostConfig, ... }:
{ self, pkgs, hostName, config, hostConfig, ... }:
with pkgs;
with lib;
let
ports = self.lib.getOpenwrtPorts hostConfig.model;
uciDeleteAll = key: ''
while uci -q delete ${key}[-1]; do :; done
'';
uciNetworkMgmt = ifname: ''
set network.mgmt=interface
set network.mgmt.ifname={{ ifname }}
set network.mgmt.ifname=${ifname}
set network.mgmt.proto=static
set network.mgmt.ipaddr={{ pillar['hosts-inet']['mgmt'][hostName] }}
set network.mgmt.netmask=255.255.255.0
set network.mgmt.gateway={{ pillar['hosts-inet']['mgmt']['mgmt-gw'] }}
set network.mgmt.ip6addr={{ pillar['hosts-inet6']['dn42']['mgmt'][hostName] }}/64
set network.mgmt.ip6gw={{ pillar['hosts-inet6']['dn42']['mgmt']['mgmt-gw'] }}
set network.mgmt.ipaddr=${config.site.net.mgmt.hosts4.${hostName}}
set network.mgmt.netmask=${self.lib.netmasks.${elemAt (
builtins.split "/" config.site.net.mgmt.subnet4
) 2}}
set network.mgmt.gateway=${config.site.net.mgmt.hosts4."mgmt-gw"}
set network.mgmt.ip6addr=${config.site.net.mgmt.hosts6.dn42.${hostName}}
set network.mgmt.ip6gw=${config.site.net.mgmt.hosts6.dn42."mgmt-gw"}
delete network.mgmt.dns
add_list network.mgmt.dns={{ pillar['hosts-inet']['serv']['dnscache'] }}
add_list network.mgmt.dns={{ pillar['hosts-inet6']['dn42']['serv']['dnscache'] }}
@ -16,35 +26,37 @@ let
in ''
#! ${pkgs.runtimeShell} -e
{%- if conf.get('firstboot') %}
ssh-keygen -R 192.168.1.1
${if hostConfig.firstboot
then ''
ssh-keygen -R 192.168.1.1
ssh root@192.168.1.1 \
"ash -e -x" <<__SSH__
'' else ''
ssh root@{{ pillar['hosts-inet']['mgmt'][hostName] }} \
"ash -e -x" <<__SSH__
''}
ssh root@192.168.1.1 \
"ash -e -x" <<__SSH__
{%- else %}
ssh root@{{ pillar['hosts-inet']['mgmt'][hostName] }} \
"ash -e -x" <<__SSH__
{%- endif %}
# Set root password
echo -e '${hostConfig.password}\n${hostConfig.password}' | passwd
# Set root password
echo -e '{{ conf['password'] }}\n{{ conf['password'] }}' | passwd
# add ssh pubkeys
${concatMapStrings (sshPubKey: ''
echo "${sshPubKey}" > /etc/dropbear/authorized_keys
'') config.site.sshPubKeys}
# add ssh pubkey
echo "{{ pillar['ssh']['pubkey'] }}" > /etc/dropbear/authorized_keys
# System configuration
uci batch <<__UCI__
set system.@system[0].hostName=${hostName}
set dhcp.@dnsmasq[0].enabled=0
set system.@system[0].log_ip=${config.site.net.mgmt.hosts4.logging}
set system.@system[0].log_proto=udp
# System configuration
uci batch <<__UCI__
set system.@system[0].hostName={{ hostName }}
set dhcp.@dnsmasq[0].enabled=0
set system.@system[0].log_ip={{ pillar['hosts-inet']['mgmt']['logging'] }}
set system.@system[0].log_proto=udp
delete network.globals.ula_prefix
delete network.lan
delete network.wan
delete network.wan6
delete wireless.default_radio0
delete wireless.default_radio1
delete network.globals.ula_prefix
delete network.lan
delete network.wan
delete network.wan6
delete wireless.default_radio0
delete wireless.default_radio1
{%- set bridges = {} %}
{%- if conf.get('lan-access') %}
@ -369,116 +381,93 @@ set network.{{ net }}.ifname='{{ ' '.join(ports) }}'
{%- endif %}
{%- set index = { 'radio': 0, 'iface': 0 } %}
{%- for path, radio in conf['radios'].items() %}
set wireless.radio{{ index.radio }}=wifi-device
set wireless.radio{{ index.radio }}.type=mac80211
set wireless.radio{{ index.radio }}.country=DE
set wireless.radio{{ index.radio }}.channel={{ radio['channel'] }}
set wireless.radio{{ index.radio }}.path={{ path }}
set wireless.radio{{ index.radio }}.hwmode={{ radio.get('hwmode') or '11n' }}
set wireless.radio{{ index.radio }}.htmode={{ radio.get('htmode') or 'HT20' }}
set wireless.radio{{ index.radio }}.noscan=1
delete wireless.radio{{ index.radio }}.disabled
${uciDeleteAll "wireless.@wifi"}
{%- for ssid, ssidconf in radio['ssids'].items() %}
set wireless.wifi{{ index.iface }}=wifi-iface
{%- if radio['channel'] < 15 %}
{%- if conf['version'] == "nightly" %}
{%- set ifprefix = 'wlan2_' %}
{%- else %}
{%- set ifprefix = 'wlan2-' %}
{%- endif %}
{%- else %}
{%- if conf['version'] == "nightly" %}
{%- set ifprefix = 'wlan5_' %}
{%- else %}
{%- set ifprefix = 'wlan5-' %}
{%- endif %}
{%- endif %}
{%- if ssidconf.get('wpa-eap') %}
{%- if conf['version'] == "nightly" %}
{%- set ifsuffix = '_eap' %}
{%- else %}
{%- set ifsuffix = '-eap' %}
{%- endif %}
{%- else %}
{%- set ifsuffix = "" %}
{%- endif %}
set wireless.wifi{{ index.iface }}.ifname={{ ifprefix }}{{ ssidconf['net'] }}{{ ifsuffix }}
set wireless.wifi{{ index.iface }}.device=radio{{ index.radio }}
set wireless.wifi{{ index.iface }}.ssid='{{ ssid }}'
set wireless.wifi{{ index.iface }}.mode=ap
set wireless.wifi{{ index.iface }}.network={{ ssidconf['net'] }}
{%- if ssidconf.get('psk') %}
set wireless.wifi{{ index.iface }}.encryption=psk2
set wireless.wifi{{ index.iface }}.key='{{ ssidconf['psk'] }}'
{%- elif ssidconf.get('wpa-eap') %}
set wireless.wifi{{ index.iface }}.encryption=wpa2
set wireless.wifi{{ index.iface }}.server='{{ ssidconf['wpa-eap']['server'] }}'
set wireless.wifi{{ index.iface }}.port='{{ ssidconf['wpa-eap']['port'] }}'
set wireless.wifi{{ index.iface }}.auth_secret='{{ ssidconf['wpa-eap']['secret'] }}'
{%- else %}
set wireless.wifi{{ index.iface }}.encryption=none
delete wireless.wifi{{ index.iface }}.key
{%- endif %}
set wireless.wifi{{ index.iface }}.mcast_rate=18000
${concatStrings (imap0 (index: path:
let
radioConfig = hostConfig.wifi.${path};
ifPrefix = if radioConfig.channel < 15
then "wlan2"
else "wlan5";
in ''
set wireless.radio${toString index}=wifi-device
set wireless.radio${toString index}=wifi-device
set wireless.radio${toString index}.type=mac80211
set wireless.radio${toString index}.country=DE
set wireless.radio${toString index}.channel=${toString radioConfig.channel}
set wireless.radio${toString index}.path=${path}
set wireless.radio${toString index}.htmode=${radioConfig.htmode}
set wireless.radio${toString index}.noscan=1
delete wireless.radio${toString index}.disabled
${concatMapStrings (ssid:
let
ssidConfig = radioConfig.ssids.${ssid};
in ''
add wireless wifi
set wireless.@wifi-iface[-1].ifname=${ifPrefix}-${ssidConfig.net}
set wireless.@wifi-iface[-1].device=radio${toString index}
set wireless.@wifi-iface[-1].ssid='${ssid}'
set wireless.@wifi-iface[-1].mode=ap
set wireless.@wifi-iface[-1].network=${ssidConfig.net}
set wireless.@wifi-iface[-1].mcast_rate=18000
${if (ssidConfig.psk != null)
then ''
set wireless.@wifi-iface[-1].encryption=psk2
set wireless.@wifi-iface[-1].key='${ssidConfig.psk}'
''
else ''
set wireless.@wifi-iface[-1].encryption=none
delete wireless.@wifi-iface[-1].key
''}
''
) (builtins.attrNames radioConfig.ssids)}
'') (builtins.attrNames hostConfig.wifi))}
{%- set x = index.update({ 'iface': index.iface + 1 }) %}
{%- endfor %}
{%- set x = index.update({ 'radio': index.radio + 1 }) %}
{%- endfor %}
commit
__UCI__
commit
__UCI__
# Cronjob that makes sure WiFi is only visible when server with all
# the gateways is reachable
cat >/etc/crontabs/root <<__CRON__
* * * * * /usr/sbin/wifi-on-link.sh
__CRON__
cat >/usr/sbin/wifi-on-link.sh <<__SH__
#!/bin/sh
# Cronjob that makes sure WiFi is only visible when server with all
# the gateways is reachable
cat >/etc/crontabs/root <<__CRON__
* * * * * /usr/sbin/wifi-on-link.sh
__CRON__
cat >/usr/sbin/wifi-on-link.sh <<__SH__
#!/bin/sh
if (ping -c 1 -W 3 {{ pillar['hosts-inet']['mgmt']['mgmt-gw'] }}) ; then
REACHABLE=y
else
REACHABLE=n
fi
if (ping -c 1 -W 3 {{ pillar['hosts-inet']['mgmt']['mgmt-gw'] }}) ; then
REACHABLE=y
else
REACHABLE=n
fi
if [ "\\\$(cat /sys/class/net/wlan2-pub/operstate)" == "up" ] ; then
UP=y
else
UP=n
fi
if [ "\\\$(cat /sys/class/net/wlan2-pub/operstate)" == "up" ] ; then
UP=y
else
UP=n
fi
{%- if conf.get("error-led") %}
ERROR_LED=/sys/class/leds/{{ conf["error-led"] }}/brightness
[ \\\$REACHABLE = y ] && echo 0 > \\\$ERROR_LED
[ \\\$REACHABLE = n ] && echo 1 > \\\$ERROR_LED
{%- endif %}
{%- if conf.get("error-led") %}
ERROR_LED=/sys/class/leds/{{ conf["error-led"] }}/brightness
[ \\\$REACHABLE = y ] && echo 0 > \\\$ERROR_LED
[ \\\$REACHABLE = n ] && echo 1 > \\\$ERROR_LED
{%- endif %}
[ \\\$REACHABLE = y ] && [ \\\$UP = n ] && wifi up
[ \\\$REACHABLE = n ] && [ \\\$UP = y ] && wifi down
[ \\\$REACHABLE = y ] && [ \\\$UP = n ] && wifi up
[ \\\$REACHABLE = n ] && [ \\\$UP = y ] && wifi down
exit 0
__SH__
chmod a+rx /usr/sbin/wifi-on-link.sh
/etc/init.d/cron restart
exit 0
__SH__
chmod a+rx /usr/sbin/wifi-on-link.sh
/etc/init.d/cron restart
for svc in dnsmasq uhttpd ; do
rm /etc/rc.d/*\$svc
/etc/init.d/\$svc stop
done
{%- if conf.get('firstboot') %}
reboot
{%- endif %}
__SSH__
echo "Base configuration done \\o/"
echo "Later run: `dirname $0`/ap_install_collectd.sh {{ pillar['hosts-inet']['mgmt'][hostName] }}"
for svc in dnsmasq uhttpd ; do
rm /etc/rc.d/*\$svc
/etc/init.d/\$svc stop
done
${lib.optionalString hostConfig.firstboot "reboot"}
__SSH__
echo "Base configuration done \\o/"
echo "Later run: `dirname $0`/ap_install_collectd.sh ${config.site.net.mgmt.hosts4.${hostName}}"
''

View File

@ -14,7 +14,7 @@ cpe:
4p+9mAt3NWq5
=QPF0
-----END PGP MESSAGE-----
model: tl-wr841n-v10
model: tl-wr841-v10
version: release
location: weg
lan-access: priv6
@ -56,7 +56,7 @@ cpe:
=Tlu+
-----END PGP MESSAGE-----
model: tl-archer-c7-v2
model: archer-c7-v2
version: release
location: C3D2 Backstage
lan-access: c3d2
@ -263,7 +263,7 @@ cpe:
rxgsW3bwIysHRYkg90GDmW505fNiC96aEA==
=Noqk
-----END PGP MESSAGE-----
model: tl-wr841n-v10
model: tl-wr841-v10
version: release
location: Broken flash
lan-access: pub
@ -289,7 +289,7 @@ cpe:
rxgsW3bwIysHRYkg90GDmW505fNiC96aEA==
=Noqk
-----END PGP MESSAGE-----
model: tl-wr841n-v10
model: tl-wr841-v10
version: release
location: Turm D, 5. Etage
lan-access: pub
@ -406,7 +406,7 @@ cpe:
4p+9mAt3NWq5
=QPF0
-----END PGP MESSAGE-----
model: tl-wr841n-v10
model: tl-wr841-v10
version: release
location: Turm D, 2. Etage
lan-access: pub
@ -447,7 +447,7 @@ cpe:
4p+9mAt3NWq5
=QPF0
-----END PGP MESSAGE-----
model: tl-wr841n-v10
model: tl-wr841-v10
version: release
location: Turm D, 1. Etage
lan-access: pub
@ -544,7 +544,7 @@ cpe:
BEELWgTZJzE=
=ECvx
-----END PGP MESSAGE-----
model: tl-wr841n-v8
model: tl-wr841-v8
version: release
location: Turm D, 4. Etage
lan-access: pub
@ -586,57 +586,31 @@ cpe:
=SB6m
-----END PGP MESSAGE-----
ap13:
password: |
-----BEGIN PGP MESSAGE-----
hQEMA2PKcvDMvlKLAQf+KrhJQfg2IAJ2SHEL8x0iAAn1ZYJ4kFVGYkmoEbN6iM4O
d2/0f8/2voMHChSTheQ5Y+Vp8op5gzOhROOShfJG1khugiEPhza+4sV0WD8Oa6Vm
FPXTr1HJdF/LZkCAVBvJOgsUC1U1PrSiSeKp3ziZyByKw6Rox6Krw6fkR2miuixs
fV0EW/H9bIVGru7Dtrgw1zq4QopxuFikMp/YWbmX0TEff6ntFCVwrGRN8Iluyaoy
aLon/Wh4DW8KQkw+s0SWxq/lIkCdvXj8TnGY3h1HNSXEfPE4hWGgwGwhLgNcNGPb
MC3IYHbmy/640GGl/tmqSnKZFuCVebMdIQ/j2iLLM9JHAe57w79qwwXIlUZ4/0I8
gaGTRjFyub+6lP9cdR6nd4FuGZanXQAEND/bwIOQtt1+jgcrgaaF3uv3gWO6Mckl
BEELWgTZJzE=
=ECvx
-----END PGP MESSAGE-----
model: dir-615-h1
version: release
location: 'Stolen? (was: Turm C 1. Etage)'
lan-access: pub
radios:
'platform/10180000.wmac':
channel: 1
htmode: HT40+
ssids:
'ZW public':
net: pub
ap14:
password: |
-----BEGIN PGP MESSAGE-----
# ap14:
# password: |
# -----BEGIN PGP MESSAGE-----
hQEMA2PKcvDMvlKLAQf/couJwoTRzTEycGB3t2aa4NTjOxKmh/Q7ScvHbxEX1VhX
sg0bW+CXQag+zy00oAbXlK/vOSP+NvOlt7vn8X50kmYTHlcZtelry4tAZeBJyw29
Vb/VvrR6F8nft1q2hpiGzAWgy8rkyncAKwCdLfsdOC/A4/QH5jis9fMnkDLbwUb+
cruIIe977BlE1jC5s09F7ZSeHUby2lMhcsxuyS+DTsBIc37Qp/Tpeq/sY7wtbrE2
MbP4mZjtBOgUCCtvauONtKjt2Zg92scob8lHm4m77qh6b4rxJ3lEW+oapelHQGId
ULxd5KM48AqV3AVexmTXNVlU0ppIdPvjxV4WR5VQt9JJAevANNiEBSPbsQwF0QNO
4M1Fl6WH1WTjVf0WQPMmUowiH0hyJuSx46sju9bEJJCaueJtIhCvUbOeOURwZaVe
ZLBzZVhVZJoO9Q==
=bGE5
-----END PGP MESSAGE-----
model: tl-wr1043nd-v1
version: release
location: Auf Halde
lan-access: pub
radios:
'platform/qca955x_wmac':
channel: 1
htmode: HT40+
ssids:
'ZW public':
net: pub
# hQEMA2PKcvDMvlKLAQf/couJwoTRzTEycGB3t2aa4NTjOxKmh/Q7ScvHbxEX1VhX
# sg0bW+CXQag+zy00oAbXlK/vOSP+NvOlt7vn8X50kmYTHlcZtelry4tAZeBJyw29
# Vb/VvrR6F8nft1q2hpiGzAWgy8rkyncAKwCdLfsdOC/A4/QH5jis9fMnkDLbwUb+
# cruIIe977BlE1jC5s09F7ZSeHUby2lMhcsxuyS+DTsBIc37Qp/Tpeq/sY7wtbrE2
# MbP4mZjtBOgUCCtvauONtKjt2Zg92scob8lHm4m77qh6b4rxJ3lEW+oapelHQGId
# ULxd5KM48AqV3AVexmTXNVlU0ppIdPvjxV4WR5VQt9JJAevANNiEBSPbsQwF0QNO
# 4M1Fl6WH1WTjVf0WQPMmUowiH0hyJuSx46sju9bEJJCaueJtIhCvUbOeOURwZaVe
# ZLBzZVhVZJoO9Q==
# =bGE5
# -----END PGP MESSAGE-----
# model: tl-wr1043nd-v1
# version: release
# location: Auf Halde
# lan-access: pub
# radios:
# 'platform/qca955x_wmac':
# channel: 1
# htmode: HT40+
# ssids:
# 'ZW public':
# net: pub
ap15:
password: |
@ -764,7 +738,7 @@ cpe:
ZLBzZVhVZJoO9Q==
=bGE5
-----END PGP MESSAGE-----
model: tl-wr841n-v10
model: tl-wr841-v10
version: release
location: Haus B, 2. Etage, zum Innenhof
lan-access: priv9
@ -805,7 +779,7 @@ cpe:
ZLBzZVhVZJoO9Q==
=bGE5
-----END PGP MESSAGE-----
model: tl-wr841n-v10
model: tl-wr841-v10
version: release
location: Turm C oberste Etage
lan-access: pub
@ -1132,7 +1106,7 @@ cpe:
8jprrw==
=dnNO
-----END PGP MESSAGE-----
model: tl-wr841n-v10
model: tl-wr841-v10
version: release
location: "Weg?"
lan-access: pub
@ -1159,7 +1133,7 @@ cpe:
BEELWgTZJzE=
=ECvx
-----END PGP MESSAGE-----
model: tl-wr841n-v8
model: tl-wr841-v8
version: release
location: Tunnel
lan-access: pub
@ -1185,7 +1159,7 @@ cpe:
WQ7tY7Ma5Jry
=Yjyd
-----END PGP MESSAGE-----
model: tl-archer-c7-v4
model: archer-c7-v4
version: nightly
location: B1.05.07
lan-access: priv13
@ -1519,7 +1493,7 @@ cpe:
ZBOMWyH63lKB+g==
=ugCM
-----END PGP MESSAGE-----
model: tl-wr1043nd-v5
model: tl-wr1043n-v5
version: release
location: B 4.08
lan-access: priv18
@ -1604,7 +1578,7 @@ cpe:
wtRDs5gZULQ=
=eFFg
-----END PGP MESSAGE-----
model: tl-archer-c7-v5
model: archer-c7-v5
version: 18.06.1
location: B3.11.01
lan-access: priv19
@ -1665,7 +1639,7 @@ cpe:
GYuZOJTS2vY=
=Uy9e
-----END PGP MESSAGE-----
model: tl-archer-c7-v4
model: archer-c7-v4
version: 18.06.1
location: ECCE-Raum
lan-access: pub
@ -1798,7 +1772,7 @@ cpe:
wtRDs5gZULQ=
=eFFg
-----END PGP MESSAGE-----
model: tl-archer-c7-v5
model: archer-c7-v5
version: 18.06.4
location: B4.01
lan-access: priv22
@ -1860,7 +1834,7 @@ cpe:
S25QWs7T
=3ci0
-----END PGP MESSAGE-----
model: tl-archer-c7-v5
model: archer-c7-v5
version: 18.06.4
location: B3.01
lan-access: priv26
@ -1922,7 +1896,7 @@ cpe:
kpwuSSzZvXNK
=JLKE
-----END PGP MESSAGE-----
model: tl-archer-c7-v5
model: archer-c7-v5
version: release
location: Dresden School of Lindy Hop
lan-access: priv4
@ -2497,7 +2471,7 @@ cpe:
=Tlu+
-----END PGP MESSAGE-----
model: tl-archer-c7-v2
model: archer-c7-v2
version: release
location: antrares
lan-access: priv17
@ -2622,7 +2596,7 @@ cpe:
4vqWxQ==
=XDXZ
-----END PGP MESSAGE-----
model: tl-wr841n-v10
model: tl-wr841-v10
version: release
location: "B2.05.01"
lan-access: priv11
@ -2663,7 +2637,7 @@ cpe:
uU8h2Z0=
=pYTp
-----END PGP MESSAGE-----
model: tl-archer-c7-v5
model: archer-c7-v5
version: release
location: "B1.05.02"
lan-access: priv35
@ -2725,7 +2699,7 @@ cpe:
s+n2PQ==
=Hv9n
-----END PGP MESSAGE-----
model: tl-archer-c7-v5
model: archer-c7-v5
version: 19.07.7
location: B3.05.03
lan-access: priv6
@ -2787,7 +2761,7 @@ cpe:
s+n2PQ==
=Hv9n
-----END PGP MESSAGE-----
model: tl-archer-c7-v5
model: archer-c7-v5
version: 19.07.7
location: B4.04.01
lan-access: priv6