mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-30 04:33:00 +02:00
confd: wifi: Refactor radio setup (access point)
Use common function for configure main SSID and bss SSID.
This commit is contained in:
+93
-149
@@ -231,30 +231,22 @@ static int wifi_find_radio_aps(struct lyd_node *cifs, const char *radio_name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generate BSS section for secondary AP (multi-SSID) */
|
||||
static int wifi_gen_bss_section(FILE *hostapd, struct lyd_node *cifs, const char *ifname, struct lyd_node *config)
|
||||
/* Helper: Write SSID and security configuration (shared between primary and BSS) */
|
||||
static void wifi_gen_ssid_config(FILE *hostapd, struct lyd_node *cif, struct lyd_node *config, bool is_bss)
|
||||
{
|
||||
const char *ssid, *hidden, *security_mode, *secret_name, *secret;
|
||||
struct lyd_node *cif, *wifi, *ap, *security, *secret_node;
|
||||
struct lyd_node *wifi, *ap, *security, *secret_node;
|
||||
const char *ifname;
|
||||
char bssid[18];
|
||||
|
||||
/* Find the interface node for this BSS */
|
||||
LYX_LIST_FOR_EACH(cifs, cif, "interface") {
|
||||
const char *name = lydx_get_cattr(cif, "name");
|
||||
if (strcmp(name, ifname) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!cif) {
|
||||
ERROR("Failed to find interface %s for BSS section", ifname);
|
||||
return SR_ERR_INVAL_ARG;
|
||||
}
|
||||
|
||||
ifname = lydx_get_cattr(cif, "name");
|
||||
wifi = lydx_get_child(cif, "wifi");
|
||||
ap = lydx_get_child(wifi, "access-point");
|
||||
|
||||
fprintf(hostapd, "\n# BSS %s\n", ifname);
|
||||
fprintf(hostapd, "bss=%s\n", ifname);
|
||||
if (is_bss) {
|
||||
fprintf(hostapd, "\n# BSS %s\n", ifname);
|
||||
fprintf(hostapd, "bss=%s\n", ifname);
|
||||
}
|
||||
|
||||
/* Set BSSID if custom MAC is configured */
|
||||
if (!interface_get_phys_addr(cif, bssid))
|
||||
@@ -270,6 +262,7 @@ static int wifi_gen_bss_section(FILE *hostapd, struct lyd_node *cifs, const char
|
||||
fprintf(hostapd, "ignore_broadcast_ssid=1\n");
|
||||
|
||||
fprintf(hostapd, "wmm_enabled=1\n");
|
||||
|
||||
/* Security configuration */
|
||||
security = lydx_get_child(ap, "security");
|
||||
security_mode = lydx_get_cattr(security, "mode");
|
||||
@@ -319,119 +312,25 @@ static int wifi_gen_bss_section(FILE *hostapd, struct lyd_node *cifs, const char
|
||||
}
|
||||
fprintf(hostapd, "ieee80211w=1\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generate hostapd config for all APs on a radio (multi-SSID support) */
|
||||
static int wifi_gen_aps_on_radio(const char *radio_name, struct lyd_node *cifs,
|
||||
struct lyd_node *radio_node, struct lyd_node *config)
|
||||
/* Helper: Write radio-specific configuration */
|
||||
static void wifi_gen_radio_config(FILE *hostapd, struct lyd_node *radio_node)
|
||||
{
|
||||
const char *ssid, *hidden, *security_mode, *secret_name, *secret;
|
||||
struct lyd_node *primary_cif, *cif;
|
||||
struct lyd_node *primary_wifi, *primary_ap;
|
||||
struct lyd_node *security, *secret_node;
|
||||
const char *country, *channel, *band;
|
||||
const char *primary_ifname;
|
||||
char hostapd_conf[256];
|
||||
char **ap_list = NULL;
|
||||
FILE *hostapd = NULL;
|
||||
bool ax_enabled;
|
||||
int ap_count = 0;
|
||||
char bssid[18];
|
||||
int i;
|
||||
|
||||
int rc = SR_ERR_OK;
|
||||
|
||||
wifi_find_radio_aps(cifs, radio_name, &ap_list, &ap_count);
|
||||
|
||||
if (ap_count == 0) {
|
||||
DEBUG("No APs found on radio %s", radio_name);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
DEBUG("Generating hostapd config for radio %s (%d APs)", radio_name, ap_count);
|
||||
|
||||
primary_ifname = ap_list[0];
|
||||
primary_cif = NULL;
|
||||
LYX_LIST_FOR_EACH(cifs, cif, "interface") {
|
||||
if (!strcmp(lydx_get_cattr(cif, "name"), primary_ifname)) {
|
||||
primary_cif = cif;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!primary_cif) {
|
||||
ERROR("Failed to find primary AP interface %s", primary_ifname);
|
||||
rc = SR_ERR_INVAL_ARG;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
primary_wifi = lydx_get_child(primary_cif, "wifi");
|
||||
primary_ap = lydx_get_child(primary_wifi, "access-point");
|
||||
|
||||
/* Get AP configuration */
|
||||
ssid = lydx_get_cattr(primary_ap, "ssid");
|
||||
hidden = lydx_get_cattr(primary_ap, "hidden");
|
||||
security = lydx_get_child(primary_ap, "security");
|
||||
security_mode = lydx_get_cattr(security, "mode");
|
||||
secret_name = lydx_get_cattr(security, "secret");
|
||||
secret = NULL;
|
||||
|
||||
/* Get radio configuration */
|
||||
country = lydx_get_cattr(radio_node, "country-code");
|
||||
band = lydx_get_cattr(radio_node, "band");
|
||||
channel = lydx_get_cattr(radio_node, "channel");
|
||||
ax_enabled = lydx_get_bool(radio_node, "enable-80211ax");
|
||||
|
||||
/* Get secret from keystore if not open network */
|
||||
if (secret_name && strcmp(security_mode, "open") != 0) {
|
||||
secret_node = lydx_get_xpathf(config,
|
||||
"/keystore/symmetric-keys/symmetric-key[name='%s']/symmetric-key",
|
||||
secret_name);
|
||||
if (secret_node) {
|
||||
secret = lyd_get_value(secret_node);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(hostapd_conf, sizeof(hostapd_conf), HOSTAPD_CONF_NEXT, radio_name);
|
||||
|
||||
hostapd = fopen(hostapd_conf, "w");
|
||||
if (!hostapd) {
|
||||
ERROR("Failed to create hostapd config: %s", hostapd_conf);
|
||||
rc = SR_ERR_INTERNAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fprintf(hostapd, "# Generated by Infix confd - WiFi Radio %s\n", radio_name);
|
||||
fprintf(hostapd, "# Primary BSS: %s", primary_ifname);
|
||||
if (ap_count > 1)
|
||||
fprintf(hostapd, " (%d total APs)\n\n", ap_count);
|
||||
else
|
||||
fprintf(hostapd, "\n\n");
|
||||
|
||||
fprintf(hostapd, "interface=%s\n", primary_ifname);
|
||||
fprintf(hostapd, "driver=nl80211\n");
|
||||
fprintf(hostapd, "ctrl_interface=/run/hostapd\n");
|
||||
|
||||
/* Set BSSID if custom MAC is configured */
|
||||
if (!interface_get_phys_addr(primary_cif, bssid))
|
||||
fprintf(hostapd, "bssid=%s\n", bssid);
|
||||
fprintf(hostapd, "\n");
|
||||
|
||||
fprintf(hostapd, "ssid=%s\n", ssid);
|
||||
if (hidden && !strcmp(hidden, "true"))
|
||||
fprintf(hostapd, "ignore_broadcast_ssid=1\n");
|
||||
fprintf(hostapd, "\n");
|
||||
|
||||
if (country)
|
||||
fprintf(hostapd, "country_code=%s\n", country);
|
||||
|
||||
/* Enable 802.11d (regulatory domain) and 802.11h (spectrum management/DFS) */
|
||||
fprintf(hostapd, "ieee80211d=1\n");
|
||||
fprintf(hostapd, "ieee80211h=1\n");
|
||||
fprintf(hostapd, "wmm_enabled=1\n");
|
||||
|
||||
/* Band and channel configuration */
|
||||
if (band) {
|
||||
@@ -467,23 +366,19 @@ static int wifi_gen_aps_on_radio(const char *radio_name, struct lyd_node *cifs,
|
||||
fprintf(hostapd, "channel=%s\n", channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (band) {
|
||||
/* 802.11n/ac/ax configuration */
|
||||
if (!strcmp(band, "2.4GHz")) {
|
||||
/* 2.4GHz: Enable 802.11n (HT), optionally 802.11ax */
|
||||
fprintf(hostapd, "ieee80211n=1\n");
|
||||
if (ax_enabled) {
|
||||
if (ax_enabled)
|
||||
fprintf(hostapd, "ieee80211ax=1\n");
|
||||
}
|
||||
} else if (!strcmp(band, "5GHz")) {
|
||||
/* 5GHz: Enable 802.11n and 802.11ac, optionally 802.11ax */
|
||||
fprintf(hostapd, "ieee80211n=1\n");
|
||||
fprintf(hostapd, "ieee80211ac=1\n");
|
||||
if (ax_enabled) {
|
||||
if (ax_enabled)
|
||||
fprintf(hostapd, "ieee80211ax=1\n");
|
||||
}
|
||||
} else if (!strcmp(band, "6GHz")) {
|
||||
/* 6GHz: Enable 802.11ax (required for 6GHz) */
|
||||
fprintf(hostapd, "ieee80211n=1\n");
|
||||
@@ -492,43 +387,92 @@ static int wifi_gen_aps_on_radio(const char *radio_name, struct lyd_node *cifs,
|
||||
}
|
||||
}
|
||||
fprintf(hostapd, "\n");
|
||||
}
|
||||
|
||||
/* Security configuration */
|
||||
if (!strcmp(security_mode, "open")) {
|
||||
fprintf(hostapd, "# Open network (no encryption)\n");
|
||||
fprintf(hostapd, "auth_algs=1\n");
|
||||
} else if (!strcmp(security_mode, "wpa2-personal")) {
|
||||
fprintf(hostapd, "# WPA2-Personal\n");
|
||||
fprintf(hostapd, "wpa=2\n");
|
||||
fprintf(hostapd, "wpa_key_mgmt=WPA-PSK\n");
|
||||
fprintf(hostapd, "wpa_pairwise=CCMP\n");
|
||||
fprintf(hostapd, "wpa_passphrase=%s\n", secret);
|
||||
} else if (!strcmp(security_mode, "wpa3-personal")) {
|
||||
fprintf(hostapd, "# WPA3-Personal\n");
|
||||
fprintf(hostapd, "wpa=2\n");
|
||||
fprintf(hostapd, "wpa_key_mgmt=SAE\n");
|
||||
fprintf(hostapd, "rsn_pairwise=CCMP\n");
|
||||
fprintf(hostapd, "sae_password=%s\n", secret);
|
||||
fprintf(hostapd, "ieee80211w=2\n");
|
||||
} else if (!strcmp(security_mode, "wpa2-wpa3-personal")) {
|
||||
fprintf(hostapd, "# WPA2/WPA3 Mixed Mode\n");
|
||||
fprintf(hostapd, "wpa=2\n");
|
||||
fprintf(hostapd, "wpa_key_mgmt=WPA-PSK SAE\n");
|
||||
fprintf(hostapd, "rsn_pairwise=CCMP\n");
|
||||
fprintf(hostapd, "wpa_passphrase=%s\n", secret);
|
||||
fprintf(hostapd, "sae_password=%s\n", secret);
|
||||
fprintf(hostapd, "ieee80211w=1\n");
|
||||
/* Generate hostapd config for all APs on a radio (multi-SSID support) */
|
||||
static int wifi_gen_aps_on_radio(const char *radio_name, struct lyd_node *cifs,
|
||||
struct lyd_node *radio_node, struct lyd_node *config)
|
||||
{
|
||||
struct lyd_node *primary_cif, *cif;
|
||||
const char *primary_ifname;
|
||||
char hostapd_conf[256];
|
||||
char **ap_list = NULL;
|
||||
FILE *hostapd = NULL;
|
||||
int ap_count = 0;
|
||||
int rc = SR_ERR_OK;
|
||||
int i;
|
||||
|
||||
wifi_find_radio_aps(cifs, radio_name, &ap_list, &ap_count);
|
||||
|
||||
if (ap_count == 0) {
|
||||
DEBUG("No APs found on radio %s", radio_name);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
DEBUG("Generating hostapd config for radio %s (%d APs)", radio_name, ap_count);
|
||||
|
||||
primary_ifname = ap_list[0];
|
||||
primary_cif = NULL;
|
||||
LYX_LIST_FOR_EACH(cifs, cif, "interface") {
|
||||
if (!strcmp(lydx_get_cattr(cif, "name"), primary_ifname)) {
|
||||
primary_cif = cif;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!primary_cif) {
|
||||
ERROR("Failed to find primary AP interface %s", primary_ifname);
|
||||
rc = SR_ERR_INVAL_ARG;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
snprintf(hostapd_conf, sizeof(hostapd_conf), HOSTAPD_CONF_NEXT, radio_name);
|
||||
|
||||
hostapd = fopen(hostapd_conf, "w");
|
||||
if (!hostapd) {
|
||||
ERROR("Failed to create hostapd config: %s", hostapd_conf);
|
||||
rc = SR_ERR_INTERNAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fprintf(hostapd, "# Generated by Infix confd - WiFi Radio %s\n", radio_name);
|
||||
fprintf(hostapd, "# Primary BSS: %s", primary_ifname);
|
||||
if (ap_count > 1)
|
||||
fprintf(hostapd, " (%d total APs)\n\n", ap_count);
|
||||
else
|
||||
fprintf(hostapd, "\n\n");
|
||||
|
||||
fprintf(hostapd, "interface=%s\n", primary_ifname);
|
||||
fprintf(hostapd, "driver=nl80211\n");
|
||||
fprintf(hostapd, "ctrl_interface=/run/hostapd\n\n");
|
||||
|
||||
/* Primary AP SSID and security configuration */
|
||||
wifi_gen_ssid_config(hostapd, primary_cif, config, false);
|
||||
fprintf(hostapd, "\n");
|
||||
|
||||
/* Radio-specific configuration */
|
||||
wifi_gen_radio_config(hostapd, radio_node);
|
||||
|
||||
/* Add BSS sections for secondary APs (multi-SSID) */
|
||||
for (i = 1; i < ap_count; i++) {
|
||||
DEBUG("Adding BSS section for secondary AP %s", ap_list[i]);
|
||||
rc = wifi_gen_bss_section(hostapd, cifs, ap_list[i], config);
|
||||
if (rc != SR_ERR_OK) {
|
||||
ERROR("Failed to generate BSS section for %s", ap_list[i]);
|
||||
struct lyd_node *bss_cif = NULL;
|
||||
|
||||
LYX_LIST_FOR_EACH(cifs, cif, "interface") {
|
||||
if (!strcmp(lydx_get_cattr(cif, "name"), ap_list[i])) {
|
||||
bss_cif = cif;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bss_cif) {
|
||||
ERROR("Failed to find interface %s for BSS section", ap_list[i]);
|
||||
fclose(hostapd);
|
||||
rc = SR_ERR_INVAL_ARG;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
DEBUG("Adding BSS section for secondary AP %s", ap_list[i]);
|
||||
wifi_gen_ssid_config(hostapd, bss_cif, config, true);
|
||||
}
|
||||
|
||||
fclose(hostapd);
|
||||
|
||||
Reference in New Issue
Block a user