confd: Add basic Wi-Fi client support

Support implemented:
* WPA2/3 support
* scanning (in background, results in operational)
* Unencrypted networks

No certificate support, only PSK

*only* client so far, no AP
This commit is contained in:
Mattias Walström
2025-06-19 15:23:28 +02:00
parent 57d5bf1577
commit b53c1612f0
22 changed files with 814 additions and 48 deletions
+12
View File
@@ -25,6 +25,11 @@ else
CONFD_CONF_OPTS += --disable-containers
endif
ifeq ($(BR2_PACKAGE_FEATURE_WIFI),y)
CONFD_CONF_OPTS += --enable-wifi
else
CONFD_CONF_OPTS += --disable-wifi
endif
define CONFD_INSTALL_EXTRA
for fn in confd.conf resolvconf.conf; do \
cp $(CONFD_PKGDIR)/$$fn $(FINIT_D)/available/; \
@@ -69,6 +74,12 @@ define CONFD_INSTALL_YANG_MODULES_CONTAINERS
$(BR2_EXTERNAL_INFIX_PATH)/utils/srload $(@D)/yang/containers.inc
endef
endif
ifeq ($(BR2_PACKAGE_FEATURE_WIFI),y)
define CONFD_INSTALL_YANG_MODULES_WIFI
$(COMMON_SYSREPO_ENV) \
$(BR2_EXTERNAL_INFIX_PATH)/utils/srload $(@D)/yang/wifi.inc
endef
endif
# PER_PACKAGE_DIR
# Since the last package in the dependency chain that runs sysrepoctl is confd, we need to
@@ -97,6 +108,7 @@ CONFD_PRE_BUILD_HOOKS += CONFD_CLEANUP
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_EXTRA
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES_CONTAINERS
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES_WIFI
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_IN_ROMFS
CONFD_TARGET_FINALIZE_HOOKS += CONFD_CLEANUP
-31
View File
@@ -1,31 +0,0 @@
#!/bin/sh
if [ ! -e "/etc/wpa-supplicant-${INTERFACE}.conf" ]; then
cat <<EOF > /etc/wpa-supplicant-${INTERFACE}.conf
ctrl_interface=/run/wpa_supplicant
update_config=0
autoscan=periodic:10
disable_scan_offload=1
ap_scan=1
# Empty network block to enable scanning without connecting
bgscan="simple: 30:-45:300"
EOF
cat <<EOF > /etc/finit.d/available/wpa-supplicant-${INTERFACE}.conf
# Generated by Infix wifi interface detected
service <!> name:wpa_supplicant :${INTERFACE} <> \
[2345] wpa_supplicant -s -i ${INTERFACE} -c /etc/wpa-supplicant-${INTERFACE}.conf \
-- WPA supplicant @${INTERFACE} (scanning only)
EOF
initctl -bfqn enable wpa-supplicant-${INTERFACE}
initctl reload
TIMEOUT=300
status=$(wpa_cli -i ${INTERFACE} scan)
while [ "$status" != "OK" ]; do
status=$(wpa_cli -i ${INTERFACE} scan)
TIMEOUT=$((TIMEOUT-1))
[ $TIMEOUT -eq 0 ] && logger -t wifi-detect "Failed to start scanning on $INTERFACE" && break
sleep 0.5
done
fi
+8
View File
@@ -41,6 +41,10 @@ AC_ARG_ENABLE(containers,
AS_HELP_STRING([--enable-containers], [Enable support for containers]),,[
enable_containers=no])
AC_ARG_ENABLE(wifi,
AS_HELP_STRING([--enable-wifi], [Enable support for Wi-Fi]),,[
enable_wifi=no])
AC_ARG_WITH(login-shell,
AS_HELP_STRING([--with-login-shell=shell], [Login shell for new users, default: /bin/false]),
[login_shell=$withval], [login_shell=yes])
@@ -52,6 +56,9 @@ AC_ARG_WITH(crypt,
AS_IF([test "x$enable_containers" = "xyes"], [
AC_DEFINE(CONTAINERS, 1, [Built with container support])])
AS_IF([test "x$enable_wifi" = "xyes"], [
AC_DEFINE(HAVE_WIFI, 1, [Built with Wi-Fi support])])
AS_IF([test "x$with_login_shell" != "xno"], [
AS_IF([test "x$login_shell" = "xyes"], [login_shell=/bin/false])
AC_DEFINE_UNQUOTED(LOGIN_SHELL, "$login_shell", [Default: /bin/false])],[
@@ -122,6 +129,7 @@ cat <<EOF
Optional features:
Container support ....: $enable_containers
Wi-Fi support ........: $enable_wifi
Login shell ..........: $login_shell
Default crypt algo ...: $crypt
+1
View File
@@ -37,6 +37,7 @@ confd_plugin_la_SOURCES = \
infix-if-vlan.c \
infix-if-gre.c \
infix-if-vxlan.c \
infix-if-wifi.c \
ietf-keystore.c \
ietf-system.c \
ietf-syslog.c \
+3
View File
@@ -52,6 +52,9 @@ enum netdag_exit {
};
enum netdag_init {
/* Timeout for slow interfaces */
NETDAG_INIT_TIMEOUT = 00,
/* Configure link layer */
NETDAG_INIT_PHYS = 10,
+102 -10
View File
@@ -9,8 +9,11 @@
#include <srx/common.h>
#include <srx/lyx.h>
#include <srx/srx_val.h>
#include <libyang/libyang.h>
#include "ietf-interfaces.h"
#define IFACE_PROBE_TIMEOUT 40
bool iface_has_quirk(const char *ifname, const char *quirkname)
{
@@ -27,6 +30,7 @@ bool iface_has_quirk(const char *ifname, const char *quirkname)
return quirk ? json_is_true(quirk) : false;
}
static bool iface_is_phys(const char *ifname)
{
bool is_phys = false;
@@ -84,7 +88,9 @@ static int ifchange_cand_infer_type(sr_session_ctx_t *session, const char *path)
goto out;
}
if (iface_is_phys(ifname))
if (!fnmatch("wifi+([0-9])", ifname, FNM_EXTMATCH))
inferred.data.string_val = "infix-if-type:wifi";
else if (iface_is_phys(ifname))
inferred.data.string_val = "infix-if-type:ethernet";
else if (!fnmatch("br+([0-9])", ifname, FNM_EXTMATCH))
inferred.data.string_val = "infix-if-type:bridge";
@@ -112,6 +118,7 @@ static int ifchange_cand_infer_type(sr_session_ctx_t *session, const char *path)
inferred.data.string_val = "infix-if-type:gretap";
else if (!fnmatch("vxlan+([0-9])", ifname, FNM_EXTMATCH))
inferred.data.string_val = "infix-if-type:vxlan";
free(ifname);
if (inferred.data.string_val)
@@ -416,6 +423,8 @@ static int netdag_gen_afspec_add(sr_session_ctx_t *session, struct dagger *net,
return vlan_gen(NULL, cif, ip);
case IFT_VXLAN:
return vxlan_gen(NULL, cif, ip);
case IFT_WIFI:
return wifi_gen(NULL, cif, net);
case IFT_ETH:
return netdag_gen_ethtool(net, cif, dif);
case IFT_LO:
@@ -444,7 +453,8 @@ static int netdag_gen_afspec_set(sr_session_ctx_t *session, struct dagger *net,
return vlan_gen(dif, cif, ip);
case IFT_ETH:
return netdag_gen_ethtool(net, cif, dif);
case IFT_WIFI:
return wifi_gen(dif, cif, net);
case IFT_DUMMY:
case IFT_GRE:
case IFT_GRETAP:
@@ -469,10 +479,11 @@ static bool netdag_must_del(struct lyd_node *dif, struct lyd_node *cif)
case IFT_DUMMY:
case IFT_LO:
break;
case IFT_WIFI:
case IFT_ETH:
/* case IFT_LAG: */
/* ... REMEMBER WHEN ADDING BOND SUPPORT ... */
return lydx_get_child(dif, "custom-phys-address");
case IFT_GRE:
case IFT_GRETAP:
return lydx_get_descendant(lyd_child(dif), "gre", NULL);
@@ -522,12 +533,12 @@ static int link_gen_del(struct lyd_node *dif, FILE *ip)
return 0;
}
static int veth_gen_del(struct lyd_node *dif, FILE *ip)
static int veth_gen_del(struct lyd_node *dif, FILE *sh)
{
if (!veth_is_primary(dif))
return 0;
return link_gen_del(dif, ip);
return link_gen_del(dif, sh);
}
static int netdag_gen_iface_del(struct dagger *net, struct lyd_node *dif,
@@ -557,6 +568,10 @@ static int netdag_gen_iface_del(struct dagger *net, struct lyd_node *dif,
case IFT_LO:
eth_gen_del(dif, ip);
break;
case IFT_WIFI:
eth_gen_del(dif, ip);
wifi_gen_del(dif, net);
break;
case IFT_VETH:
veth_gen_del(dif, ip);
break;
@@ -576,15 +591,35 @@ static int netdag_gen_iface_del(struct dagger *net, struct lyd_node *dif,
return 0;
}
static sr_error_t netdag_gen_iface_timeout(struct dagger *net, const char *ifname, const char *iftype)
{
if (!strcmp(iftype, "infix-if-type:ethernet") || !strcmp(iftype, "infix-if-type:wifi")) {
FILE *wait = dagger_fopen_net_init(net, ifname, NETDAG_INIT_TIMEOUT, "wait-interface.sh");
if (!wait) {
return -EIO;
}
fprintf(wait, "/usr/libexec/confd/wait-interface %s %d\n", ifname, IFACE_PROBE_TIMEOUT);
fclose(wait);
}
return SR_ERR_OK;
}
static sr_error_t netdag_gen_iface(sr_session_ctx_t *session, struct dagger *net,
struct lyd_node *dif, struct lyd_node *cif)
{
const char *ifname = lydx_get_cattr(dif, "name");
const char *iftype = lydx_get_cattr(dif, "type")?:lydx_get_cattr(cif, "type");
enum lydx_op op = lydx_get_op(dif);
const char *attr;
int err = 0;
FILE *ip;
err = netdag_gen_iface_timeout(net, ifname, iftype);
if (err)
goto err;
if ((err = cni_netdag_gen_iface(net, ifname, dif, cif))) {
/* error or managed by CNI/podman */
if (err > 0)
@@ -708,6 +743,7 @@ static int netdag_init_iface(struct lyd_node *cif)
case IFT_DUMMY:
case IFT_ETH:
case IFT_WIFI:
case IFT_GRE:
case IFT_GRETAP:
case IFT_LO:
@@ -788,7 +824,7 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu
if (err)
return err;
err = sr_get_data(session, "/interfaces/interface", 0, 0, 0, &cfg);
err = sr_get_data(session, "//.", 0, 0, 0, &cfg);
if (err || !cfg)
goto err_abandon;
@@ -798,7 +834,6 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu
cifs = lydx_get_descendant(cfg->tree, "interfaces", "interface", NULL);
difs = lydx_get_descendant(diff, "interfaces", "interface", NULL);
err = netdag_init(session, &confd->netdag, cifs, difs);
if (err)
goto err_free_diff;
@@ -827,15 +862,72 @@ err_abandon:
return err;
}
static int keystorecb(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *xpath, sr_event_t event, unsigned request_id, void *_confd)
{
const struct lyd_node *diff;
const char *secret_name;
struct confd *confd = _confd;
struct lyd_node *interfaces, *interface, *dkeys, *dkey, *wifi;
sr_data_t *cfg = NULL;
int err = SR_ERR_OK;
switch (event) {
case SR_EV_CHANGE:
break;
default:
return SR_ERR_OK;
}
err = sr_get_data(session, "/interfaces/interface", 0, 0, 0, &cfg);
if (err || !cfg)
return err;
diff = sr_get_change_diff(session);
if (!diff)
goto cleanup;
interfaces = lydx_get_descendant(cfg->tree, "interfaces", "interface", NULL);
dkeys = lydx_get_descendant((struct lyd_node*) diff, "keystore", "symmetric-keys", "symmetric-key", NULL);
LYX_LIST_FOR_EACH(dkeys, dkey, "symmetric-key") {
secret_name = lydx_get_cattr(dkey, "name");
if (!secret_name)
continue;
LYX_LIST_FOR_EACH(interfaces, interface, "interface") {
const char *name;
if (iftype_from_iface(interface) != IFT_WIFI)
continue;
wifi = lydx_get_child(interface, "wifi");
if (!wifi)
continue;
name = lydx_get_cattr(wifi, "secret");
if (!name || strcmp(name, secret_name))
continue;
wifi_gen(NULL, interface, &confd->netdag);
}
}
cleanup:
if (cfg)
sr_release_data(cfg);
return err;
}
int ietf_interfaces_init(struct confd *confd)
{
int rc;
REGISTER_CHANGE(confd->session, "ietf-interfaces", "/ietf-interfaces:interfaces//.",
0, ifchange, confd, &confd->sub);
SR_SUBSCR_CHANGE_ALL_MODULES, ifchange, confd, &confd->sub);
REGISTER_CHANGE(confd->session, "ietf-keystore", "//*",
SR_SUBSCR_CHANGE_ALL_MODULES, keystorecb, confd, &confd->sub);
REGISTER_CHANGE(confd->cand, "ietf-interfaces", "/ietf-interfaces:interfaces//.",
SR_SUBSCR_UPDATE, ifchange_cand, confd, &confd->sub);
return SR_ERR_OK;
fail:
ERROR("failed, error %d: %s", rc, sr_strerror(rc));
+5
View File
@@ -25,6 +25,7 @@
_map(IFT_BRIDGE, "infix-if-type:bridge") \
_map(IFT_DUMMY, "infix-if-type:dummy") \
_map(IFT_ETH, "infix-if-type:ethernet") \
_map(IFT_WIFI, "infix-if-type:wifi") \
_map(IFT_GRE, "infix-if-type:gre") \
_map(IFT_GRETAP, "infix-if-type:gretap") \
_map(IFT_LAG, "infix-if-type:lag") \
@@ -119,6 +120,10 @@ int bridge_mcd_gen(struct lyd_node *cifs);
/* infix-if-bridge-port.c */
int bridge_port_gen(struct lyd_node *dif, struct lyd_node *cif, FILE *ip);
/* infix-if-wifi.c */
int wifi_gen(struct lyd_node *dif, struct lyd_node *cif, struct dagger *net);
int wifi_gen_del(struct lyd_node *dif, struct dagger *net);
/* infix-if-gre.c */
int gre_gen(struct lyd_node *dif, struct lyd_node *cif, FILE *ip);
+111
View File
@@ -0,0 +1,111 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#include <srx/lyx.h>
#include "ietf-interfaces.h"
#define WPA_SUPPLICANT_FINIT_CONF "/etc/finit.d/available/wpa_supplicant-%s.conf"
#define WPA_SUPPLICANT_CONF "/etc/wpa_supplicant-%s.conf"
static int wifi_gen_config(const char *ifname, const char *ssid, const char *country, const char *secret, const char* encryption, struct dagger *net)
{
FILE *wpa_supplicant = NULL, *wpa = NULL;
char *encryption_str;
int rc = SR_ERR_OK;
if (!secret || !ssid || !country || !encryption) {
/* Not an error, updated from two ways, interface cb and keystore cb. */
return 0;
}
wpa = dagger_fopen_net_init(net, ifname, NETDAG_INIT_POST, "wpa_supplicant.sh");
if (!wpa) {
rc = SR_ERR_INTERNAL;
goto out;
}
fprintf(wpa, "# Generated by Infix confd\n");
fprintf(wpa, "initctl -bfqn enable wifi@%s\n", ifname);
fclose(wpa);
wpa_supplicant = fopenf("w", WPA_SUPPLICANT_CONF, ifname);
if (!wpa_supplicant) {
rc = SR_ERR_INTERNAL;
goto out;
}
if (ssid) {
if (!strcmp(encryption, "disabled")) {
asprintf(&encryption_str, "key_mgmt=NONE");
} else {
asprintf(&encryption_str, "key_mgmt=SAE WPA-PSK\npsk=\"%s\"", secret);
}
fprintf(wpa_supplicant,
"country=%s\n"
"ctrl_interface=/run/wpa_supplicant\n"
"autoscan=periodic:10\n"
"ap_scan=1\n"
"network={\n"
"bgscan=\"simple: 30:-45:300\"\n"
"ssid=\"%s\"\n"
"%s\n"
"}\n", country, ssid, encryption_str);
free(encryption_str);
} else {
fprintf(wpa_supplicant,
"ctrl_interface=/run/wpa_supplicant\n"
"autoscan=periodic:10\n"
"ap_scan=1\n");
}
fclose(wpa_supplicant);
out:
return rc;
}
int wifi_gen(struct lyd_node *dif, struct lyd_node *cif, struct dagger *net)
{
const char *ssid, *secret_name, *secret, *ifname, *country, *encryption;
struct lyd_node *wifi, *secret_node;
bool enabled;
ifname = lydx_get_cattr(cif, "name");
if (cif && !lydx_get_child(cif, "wifi")) {
return wifi_gen_config(ifname, NULL, NULL, NULL, NULL, net);
}
if (dif && !lydx_get_child(dif, "wifi")) {
return SR_ERR_OK;
}
enabled = lydx_get_bool(cif, "enabled");
wifi = lydx_get_child(cif, "wifi");
ssid = lydx_get_cattr(wifi, "ssid");
secret_name = lydx_get_cattr(wifi, "secret");
country = lydx_get_cattr(wifi, "country-code");
encryption = lydx_get_cattr(wifi, "encryption");
secret_node = lydx_get_xpathf(cif, "../../keystore/symmetric-keys/symmetric-key[name='%s']", secret_name);
secret = lydx_get_cattr(secret_node, "cleartext-key");
if (!enabled)
return wifi_gen_del(cif, net);
return wifi_gen_config(ifname, ssid, country, secret, encryption, net);
}
int wifi_gen_del(struct lyd_node *dif, struct dagger *net)
{
const char *ifname = lydx_get_cattr(dif, "name");
FILE *iw = dagger_fopen_net_exit(net, ifname, NETDAG_EXIT_PRE, "iw.sh");
fprintf(iw, "# Generated by Infix confd\n");
fprintf(iw, "iw dev %s disconnect\n", ifname);
fprintf(iw, "initctl -bfqn disable wifi@%s\n", ifname);
fclose(iw);
erasef(WPA_SUPPLICANT_CONF, ifname);
return SR_ERR_OK;
}
+5 -3
View File
@@ -34,7 +34,9 @@ MODULES=(
"ieee802-ethernet-interface@2019-06-21.yang"
"infix-ethernet-interface@2024-02-27.yang"
"infix-factory-default@2023-06-28.yang"
"infix-interfaces@2025-01-09.yang -e vlan-filtering"
"infix-crypto-types@2025-02-04.yang"
"infix-keystore@2025-02-04.yang"
"infix-interfaces@2025-06-17.yang -e vlan-filtering"
"ietf-crypto-types -e cleartext-symmetric-keys"
"infix-crypto-types@2025-06-17.yang"
"ietf-keystore -e symmetric-keys"
"infix-keystore@2025-06-17.yang"
)
@@ -5,6 +5,10 @@ module infix-crypto-types {
import ietf-crypto-types {
prefix ct;
}
revision 2025-06-17 {
description "Add Wi-Fi secret support.";
}
revision 2025-02-04 {
description "Initial";
}
@@ -24,4 +28,14 @@ module infix-crypto-types {
base public-key-format;
base ct:ssh-public-key-format;
}
identity symmetric-key-format {
description
"Base for symmetric key format";
}
identity wifi-preshared-key-format {
base ct:symmetric-key-format;
base symmetric-key-format;
description
"WiFi secret key";
}
}
+14
View File
@@ -38,6 +38,14 @@ module infix-if-type {
reference "internal";
}
/*
* Features
*/
feature wifi {
description "WiFi support is an optional build-time feature in Infix.";
}
/*
* Identities
*/
@@ -98,4 +106,10 @@ module infix-if-type {
base ianaift:l2vlan;
description "Layer 2 Virtual LAN using 802.1Q.";
}
identity wifi {
if-feature wifi;
base infix-interface-type;
base ianaift:ieee80211;
description "WiFi interface";
}
}
+185
View File
@@ -0,0 +1,185 @@
submodule infix-if-wifi {
yang-version 1.1;
belongs-to infix-interfaces {
prefix infix-if;
}
import ietf-interfaces {
prefix if;
}
import ietf-yang-types {
prefix yang;
}
import ietf-netconf-acm {
prefix nacm;
}
import ietf-keystore {
prefix ks;
}
import infix-crypto-types {
prefix ixct;
}
import infix-if-type {
prefix infixift;
}
import infix-wifi-country-codes {
prefix iwcc;
}
organization "KernelKit";
contact "kernelkit@googlegroups.com";
description
"WiFi-specific extensions to the standard IETF interfaces model.
This submodule defines configuration and operational data relevant to
WiFi interfaces, including security settings, network
discovery, and regulatory compliance.
It supports WiFi client mode and enables comprehensive management of
wireless connections, including encryption, country codes, and scanning.";
revision 2025-05-27 {
description "Initial revision.";
reference "internal";
}
feature wifi {
description "WiFi support is an optional build-time feature in Infix.";
}
typedef encryption {
type enumeration {
enum auto {
description
"Enables WPA/WPA2/WPA3 encryption with automatic protocol
negotiation. The system uses the strongest supported variant supported by Access Point.";
}
enum disabled {
description
"Disables encryption for an open network.
WARNING: Open networks transmit data unencrypted and should only
be used in trusted environments.";
}
}
description
"Encryption modes available for WiFi connections.
- auto: Secure connection using WPA3/WPA2/WPA (auto-selected)
- disabled: Open network (unencrypted)";
}
augment "/if:interfaces/if:interface" {
when "derived-from-or-self(if:type, 'infixift:wifi')" {
description
"Applies only to interfaces of type 'wifi'.";
}
container wifi {
if-feature wifi;
presence "Configure Wi-Fi settings";
description
"WiFi-specific configuration and operational data.";
leaf country-code {
type iwcc:country-code;
mandatory true;
description
"Two-letter ISO 3166-1 country code for regulatory compliance.
Examples: 'US', 'DE', 'JP'.
WARNING: Incorrect values may violate local laws.";
}
leaf encryption {
default auto;
type encryption;
description
"WiFi encryption method.
- auto (default): Enables WPA2/WPA3 auto-negotiation
- disabled: Disables encryption (open network)";
}
leaf ssid {
type string {
length "1..32";
}
mandatory true;
description
"WiFi network name (SSID).
Case-sensitive, must match the target network.
Length: 132 characters.";
}
leaf secret {
type ks:symmetric-key-ref;
mandatory true;
must "../encryption != 'disabled'" {
error-message
"Pre-shared key required unless encryption is disabled.";
}
description
"Pre-shared key (PSK) for WPA-secured networks.";
}
leaf rssi {
config false;
type int16;
units "dBm";
description
"Current received signal strength (RSSI) in dBm.
Lower (more negative) values indicate stronger signals.";
}
list scan-results {
config false;
key ssid;
description
"List of discovered networks.";
leaf ssid {
type string;
description
"SSID of the discovered network.";
}
leaf bssid {
type string;
description
"BSSID of the discovered network.";
}
leaf rssi {
type int16;
units "dBm";
description
"Signal strength of the network.";
}
leaf channel {
type int16;
description
"Channel on which the network was detected.";
}
leaf-list encryption {
ordered-by user;
type string;
description
"Human-readable description of the detected security.";
}
}
}
}
}
+1
View File
@@ -0,0 +1 @@
infix-if-wifi.yang
+13 -4
View File
@@ -3,9 +3,6 @@ module infix-interfaces {
namespace "urn:infix:interfaces:ns:yang:1.0";
prefix infix-if;
import infix-if-type {
prefix infix-ift;
}
import ietf-interfaces {
prefix if;
}
@@ -15,6 +12,12 @@ module infix-interfaces {
import ietf-inet-types {
prefix inet;
}
import ietf-keystore {
prefix ks;
}
import infix-if-type {
prefix infix-ift;
}
include infix-if-base;
include infix-if-bridge;
@@ -24,12 +27,18 @@ module infix-interfaces {
include infix-if-vlan;
include infix-if-gre;
include infix-if-vxlan;
include infix-if-wifi;
organization "KernelKit";
contact "kernelkit@googlegroups.com";
description "Linux bridge and lag extensions for ietf-interfaces.";
revision 2025-01-09 {
revision 2025-06-17 {
description "Add support for Wi-Fi client.";
reference "internal";
}
revision 2025-01-09 {
description "Add support for link aggregation, static and LACP.";
reference "internal";
}
+37
View File
@@ -5,9 +5,15 @@ module infix-keystore {
import ietf-keystore {
prefix ks;
}
import ietf-crypto-types {
prefix ct;
}
import infix-crypto-types {
prefix infix-ct;
}
revision 2025-06-17 {
description "Add Wi-Fi secrets support";
}
revision 2025-02-04 {
description "Initial";
}
@@ -25,4 +31,35 @@ module infix-keystore {
}
}
}
deviation "/ks:keystore/ks:symmetric-keys/ks:symmetric-key/ks:key-format" {
deviate not-supported;
}
augment "/ks:keystore/ks:symmetric-keys/ks:symmetric-key" {
leaf key-format {
type identityref {
base infix-ct:symmetric-key-format;
}
description
"Identifies the symmetric key's format
Valid symmetric key formats are:
wifi-preshared-key-format - WiFi preshared key";
}
}
deviation "/ks:keystore/ks:symmetric-keys/ks:symmetric-key/ks:key-type/ks:cleartext-key/ks:cleartext-key" {
deviate not-supported;
}
augment "/ks:keystore/ks:symmetric-keys/ks:symmetric-key/ks:key-type" {
case cleartext-key {
leaf cleartext-key {
type string;
must "../../ks:key-format != 'infix-ct:wifi-preshared-key-format' or " +
"(string-length(.) >= 8 and string-length(.) <= 63)" {
error-message "WiFi pre-shared key must be 8-63 characters long";
}
description "WiFi pre-shared key: 8-63 printable ASCII characters";
}
}
}
}
+11
View File
@@ -3,10 +3,15 @@ module infix-meta {
namespace "urn:infix:meta:ns:yang:1.0";
prefix infix-meta;
import ietf-yang-metadata {
prefix md;
}
organization "KernelKit";
contact "kernelkit@googlegroups.com";
description "Infix metadata.";
revision 2024-10-18 {
description "Mark entire meta container obsolete.";
reference "internal";
@@ -16,6 +21,12 @@ module infix-meta {
reference "internal";
}
md:annotation dirty {
type string;
description
"data";
}
container meta {
description "Meta data";
status obsolete;
@@ -0,0 +1,287 @@
module infix-wifi-country-codes {
yang-version 1.1;
namespace "urn:infix:wifi-country-codes";
prefix iwcc;
organization "KernelKit";
contact "kernelkit@googlegroups.com";
description
"This module defines country codes for WiFi regulatory domain
configuration based on ISO 3166-1 alpha-2 standard.
This model provides country code definitions for use in
802.11 wireless LAN regulatory compliance configuration.
The regulatory domain configuration follows the principles
established in IETF RFCs for wireless access point management.";
revision 2025-06-02 {
description
"Initial revision for WiFi country code support.";
reference
"RFC 5415: Control And Provisioning of Wireless Access Points (CAPWAP) Protocol Specification
RFC 5416: Control and Provisioning of Wireless Access Points (CAPWAP) Protocol Binding for IEEE 802.11";
}
typedef country-code {
type enumeration {
enum "AD" { description "Andorra"; }
enum "AE" { description "United Arab Emirates"; }
enum "AF" { description "Afghanistan"; }
enum "AG" { description "Antigua and Barbuda"; }
enum "AI" { description "Anguilla"; }
enum "AL" { description "Albania"; }
enum "AM" { description "Armenia"; }
enum "AO" { description "Angola"; }
enum "AQ" { description "Antarctica"; }
enum "AR" { description "Argentina"; }
enum "AS" { description "American Samoa"; }
enum "AT" { description "Austria"; }
enum "AU" { description "Australia"; }
enum "AW" { description "Aruba"; }
enum "AX" { description "Åland Islands"; }
enum "AZ" { description "Azerbaijan"; }
enum "BA" { description "Bosnia and Herzegovina"; }
enum "BB" { description "Barbados"; }
enum "BD" { description "Bangladesh"; }
enum "BE" { description "Belgium"; }
enum "BF" { description "Burkina Faso"; }
enum "BG" { description "Bulgaria"; }
enum "BH" { description "Bahrain"; }
enum "BI" { description "Burundi"; }
enum "BJ" { description "Benin"; }
enum "BL" { description "Saint Barthélemy"; }
enum "BM" { description "Bermuda"; }
enum "BN" { description "Brunei Darussalam"; }
enum "BO" { description "Bolivia"; }
enum "BQ" { description "Bonaire, Sint Eustatius and Saba"; }
enum "BR" { description "Brazil"; }
enum "BS" { description "Bahamas"; }
enum "BT" { description "Bhutan"; }
enum "BV" { description "Bouvet Island"; }
enum "BW" { description "Botswana"; }
enum "BY" { description "Belarus"; }
enum "BZ" { description "Belize"; }
enum "CA" { description "Canada"; }
enum "CC" { description "Cocos (Keeling) Islands"; }
enum "CD" { description "Congo, Democratic Republic of the"; }
enum "CF" { description "Central African Republic"; }
enum "CG" { description "Congo"; }
enum "CH" { description "Switzerland"; }
enum "CI" { description "Côte d'Ivoire"; }
enum "CK" { description "Cook Islands"; }
enum "CL" { description "Chile"; }
enum "CM" { description "Cameroon"; }
enum "CN" { description "China"; }
enum "CO" { description "Colombia"; }
enum "CR" { description "Costa Rica"; }
enum "CU" { description "Cuba"; }
enum "CV" { description "Cabo Verde"; }
enum "CW" { description "Curaçao"; }
enum "CX" { description "Christmas Island"; }
enum "CY" { description "Cyprus"; }
enum "CZ" { description "Czechia"; }
enum "DE" { description "Germany"; }
enum "DJ" { description "Djibouti"; }
enum "DK" { description "Denmark"; }
enum "DM" { description "Dominica"; }
enum "DO" { description "Dominican Republic"; }
enum "DZ" { description "Algeria"; }
enum "EC" { description "Ecuador"; }
enum "EE" { description "Estonia"; }
enum "EG" { description "Egypt"; }
enum "EH" { description "Western Sahara"; }
enum "ER" { description "Eritrea"; }
enum "ES" { description "Spain"; }
enum "ET" { description "Ethiopia"; }
enum "FI" { description "Finland"; }
enum "FJ" { description "Fiji"; }
enum "FK" { description "Falkland Islands (Malvinas)"; }
enum "FM" { description "Micronesia"; }
enum "FO" { description "Faroe Islands"; }
enum "FR" { description "France"; }
enum "GA" { description "Gabon"; }
enum "GB" { description "United Kingdom"; }
enum "GD" { description "Grenada"; }
enum "GE" { description "Georgia"; }
enum "GF" { description "French Guiana"; }
enum "GG" { description "Guernsey"; }
enum "GH" { description "Ghana"; }
enum "GI" { description "Gibraltar"; }
enum "GL" { description "Greenland"; }
enum "GM" { description "Gambia"; }
enum "GN" { description "Guinea"; }
enum "GP" { description "Guadeloupe"; }
enum "GQ" { description "Equatorial Guinea"; }
enum "GR" { description "Greece"; }
enum "GS" { description "South Georgia and the South Sandwich Islands"; }
enum "GT" { description "Guatemala"; }
enum "GU" { description "Guam"; }
enum "GW" { description "Guinea-Bissau"; }
enum "GY" { description "Guyana"; }
enum "HK" { description "Hong Kong"; }
enum "HM" { description "Heard Island and McDonald Islands"; }
enum "HN" { description "Honduras"; }
enum "HR" { description "Croatia"; }
enum "HT" { description "Haiti"; }
enum "HU" { description "Hungary"; }
enum "ID" { description "Indonesia"; }
enum "IE" { description "Ireland"; }
enum "IL" { description "Israel"; }
enum "IM" { description "Isle of Man"; }
enum "IN" { description "India"; }
enum "IO" { description "British Indian Ocean Territory"; }
enum "IQ" { description "Iraq"; }
enum "IR" { description "Iran"; }
enum "IS" { description "Iceland"; }
enum "IT" { description "Italy"; }
enum "JE" { description "Jersey"; }
enum "JM" { description "Jamaica"; }
enum "JO" { description "Jordan"; }
enum "JP" { description "Japan"; }
enum "KE" { description "Kenya"; }
enum "KG" { description "Kyrgyzstan"; }
enum "KH" { description "Cambodia"; }
enum "KI" { description "Kiribati"; }
enum "KM" { description "Comoros"; }
enum "KN" { description "Saint Kitts and Nevis"; }
enum "KP" { description "Korea, Democratic People's Republic of"; }
enum "KR" { description "Korea, Republic of"; }
enum "KW" { description "Kuwait"; }
enum "KY" { description "Cayman Islands"; }
enum "KZ" { description "Kazakhstan"; }
enum "LA" { description "Lao People's Democratic Republic"; }
enum "LB" { description "Lebanon"; }
enum "LC" { description "Saint Lucia"; }
enum "LI" { description "Liechtenstein"; }
enum "LK" { description "Sri Lanka"; }
enum "LR" { description "Liberia"; }
enum "LS" { description "Lesotho"; }
enum "LT" { description "Lithuania"; }
enum "LU" { description "Luxembourg"; }
enum "LV" { description "Latvia"; }
enum "LY" { description "Libya"; }
enum "MA" { description "Morocco"; }
enum "MC" { description "Monaco"; }
enum "MD" { description "Moldova"; }
enum "ME" { description "Montenegro"; }
enum "MF" { description "Saint Martin (French part)"; }
enum "MG" { description "Madagascar"; }
enum "MH" { description "Marshall Islands"; }
enum "MK" { description "North Macedonia"; }
enum "ML" { description "Mali"; }
enum "MM" { description "Myanmar"; }
enum "MN" { description "Mongolia"; }
enum "MO" { description "Macao"; }
enum "MP" { description "Northern Mariana Islands"; }
enum "MQ" { description "Martinique"; }
enum "MR" { description "Mauritania"; }
enum "MS" { description "Montserrat"; }
enum "MT" { description "Malta"; }
enum "MU" { description "Mauritius"; }
enum "MV" { description "Maldives"; }
enum "MW" { description "Malawi"; }
enum "MX" { description "Mexico"; }
enum "MY" { description "Malaysia"; }
enum "MZ" { description "Mozambique"; }
enum "NA" { description "Namibia"; }
enum "NC" { description "New Caledonia"; }
enum "NE" { description "Niger"; }
enum "NF" { description "Norfolk Island"; }
enum "NG" { description "Nigeria"; }
enum "NI" { description "Nicaragua"; }
enum "NL" { description "Netherlands"; }
enum "NO" { description "Norway"; }
enum "NP" { description "Nepal"; }
enum "NR" { description "Nauru"; }
enum "NU" { description "Niue"; }
enum "NZ" { description "New Zealand"; }
enum "OM" { description "Oman"; }
enum "PA" { description "Panama"; }
enum "PE" { description "Peru"; }
enum "PF" { description "French Polynesia"; }
enum "PG" { description "Papua New Guinea"; }
enum "PH" { description "Philippines"; }
enum "PK" { description "Pakistan"; }
enum "PL" { description "Poland"; }
enum "PM" { description "Saint Pierre and Miquelon"; }
enum "PN" { description "Pitcairn"; }
enum "PR" { description "Puerto Rico"; }
enum "PS" { description "Palestine, State of"; }
enum "PT" { description "Portugal"; }
enum "PW" { description "Palau"; }
enum "PY" { description "Paraguay"; }
enum "QA" { description "Qatar"; }
enum "RE" { description "Réunion"; }
enum "RO" { description "Romania"; }
enum "RS" { description "Serbia"; }
enum "RU" { description "Russian Federation"; }
enum "RW" { description "Rwanda"; }
enum "SA" { description "Saudi Arabia"; }
enum "SB" { description "Solomon Islands"; }
enum "SC" { description "Seychelles"; }
enum "SD" { description "Sudan"; }
enum "SE" { description "Sweden"; }
enum "SG" { description "Singapore"; }
enum "SH" { description "Saint Helena, Ascension and Tristan da Cunha"; }
enum "SI" { description "Slovenia"; }
enum "SJ" { description "Svalbard and Jan Mayen"; }
enum "SK" { description "Slovakia"; }
enum "SL" { description "Sierra Leone"; }
enum "SM" { description "San Marino"; }
enum "SN" { description "Senegal"; }
enum "SO" { description "Somalia"; }
enum "SR" { description "Suriname"; }
enum "SS" { description "South Sudan"; }
enum "ST" { description "Sao Tome and Principe"; }
enum "SV" { description "El Salvador"; }
enum "SX" { description "Sint Maarten (Dutch part)"; }
enum "SY" { description "Syrian Arab Republic"; }
enum "SZ" { description "Eswatini"; }
enum "TC" { description "Turks and Caicos Islands"; }
enum "TD" { description "Chad"; }
enum "TF" { description "French Southern Territories"; }
enum "TG" { description "Togo"; }
enum "TH" { description "Thailand"; }
enum "TJ" { description "Tajikistan"; }
enum "TK" { description "Tokelau"; }
enum "TL" { description "Timor-Leste"; }
enum "TM" { description "Turkmenistan"; }
enum "TN" { description "Tunisia"; }
enum "TO" { description "Tonga"; }
enum "TR" { description "Turkey"; }
enum "TT" { description "Trinidad and Tobago"; }
enum "TV" { description "Tuvalu"; }
enum "TW" { description "Taiwan"; }
enum "TZ" { description "Tanzania"; }
enum "UA" { description "Ukraine"; }
enum "UG" { description "Uganda"; }
enum "UM" { description "United States Minor Outlying Islands"; }
enum "US" { description "United States of America"; }
enum "UY" { description "Uruguay"; }
enum "UZ" { description "Uzbekistan"; }
enum "VA" { description "Holy See (Vatican City State)"; }
enum "VC" { description "Saint Vincent and the Grenadines"; }
enum "VE" { description "Venezuela"; }
enum "VG" { description "Virgin Islands, British"; }
enum "VI" { description "Virgin Islands, U.S."; }
enum "VN" { description "Viet Nam"; }
enum "VU" { description "Vanuatu"; }
enum "WF" { description "Wallis and Futuna"; }
enum "WS" { description "Samoa"; }
enum "YE" { description "Yemen"; }
enum "YT" { description "Mayotte"; }
enum "ZA" { description "South Africa"; }
enum "ZM" { description "Zambia"; }
enum "ZW" { description "Zimbabwe"; }
}
description
"Complete list of ISO 3166-1 alpha-2 country codes for
regulatory domain configuration.";
reference
"ISO 3166-1:2020 Codes for the representation of names of countries
and their subdivisions -- Part 1: Country codes";
}
}
@@ -0,0 +1 @@
infix-wifi-country-codes.yang
+4
View File
@@ -0,0 +1,4 @@
MODULES=(
"infix-interfaces -e wifi"
"infix-if-type -e wifi"
)