Skip to content

Commit 6868c78

Browse files
committed
Wi-Fi: Add support for accesspoint
Simple configuration: admin@rpi4:/config/> edit interface wifi0 wifi admin@rpi4:/config/interface/wifi0/wifi/> set country-code SE admin@rpi4:/config/interface/wifi0/wifi/> set band 2.4GHz 5GHz admin@rpi4:/config/interface/wifi0/wifi/> set band 2.4GHz admin@rpi4:/config/interface/wifi0/wifi/> edit ssid test admin@rpi4:/config/interface/wifi0/wifi/ssid/test/> set secret se admin@rpi4:/config/interface/wifi0/wifi/ssid/test/> set encryption admin@rpi4:/config/interface/wifi0/wifi/ssid/test/>
1 parent 51cfef3 commit 6868c78

File tree

2 files changed

+139
-29
lines changed

2 files changed

+139
-29
lines changed

src/confd/src/infix-if-wifi.c

Lines changed: 136 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
#define WPA_SUPPLICANT_FINIT_CONF "/etc/finit.d/available/wpa_supplicant-%s.conf"
77
#define WPA_SUPPLICANT_CONF "/etc/wpa_supplicant-%s.conf"
8+
#define HOSTAPD_SUPPLICANT_CONF "/etc/hostapd-%s.conf"
89

9-
static int wifi_gen_client_config(const char *ifname, const char *ssid, const char *country, const char *secret, const char* encryption, struct dagger *net, bool first)
10+
static int wifi_gen_client_config(const char *ifname, const char *ssid, const char *country, const char *secret, const char* encryption, struct dagger *net, int counter)
1011
{
1112
FILE *wpa_supplicant = NULL, *wpa = NULL;
1213
char *encryption_str;
@@ -49,7 +50,7 @@ static int wifi_gen_client_config(const char *ifname, const char *ssid, const ch
4950
} else {
5051
asprintf(&encryption_str, "key_mgmt=SAE WPA-PSK\npsk=\"%s\"", secret);
5152
}
52-
if (first) {
53+
if (!counter) { /* First SSID */
5354
fprintf(wpa_supplicant,
5455
"country=%s\n"
5556
"ctrl_interface=/run/wpa_supplicant\n"
@@ -69,56 +70,162 @@ static int wifi_gen_client_config(const char *ifname, const char *ssid, const ch
6970
return rc;
7071

7172
}
73+
static int wifi_gen_accesspoint_config(const char *ifname, const char *ssid, const char *country, const char *secret, const char* encryption, const char *band, const char *channel, struct dagger *net, int counter)
74+
{
75+
FILE *hostapd_conf, *hostapd_finit;
76+
int rc = 0;
77+
78+
hostapd_finit = dagger_fopen_net_init(net, ifname, NETDAG_INIT_POST, "hostapd.sh");
79+
if (!hostapd_finit) {
80+
rc = SR_ERR_INTERNAL;
81+
goto out;
82+
}
83+
84+
fprintf(hostapd_finit, "# Generated by Infix confd\n");
85+
86+
fprintf(hostapd_finit, "if [ -f '/etc/finit.d/enabled/hostapd@%s.conf' ];then\n", ifname);
87+
fprintf(hostapd_finit, "initctl -bfqn touch hostapd@%s\n", ifname);
88+
fprintf(hostapd_finit, "else\n");
89+
fprintf(hostapd_finit, "initctl -bfqn enable hostapd@%s\n", ifname);
90+
fprintf(hostapd_finit, "fi\n");
91+
fclose(hostapd_finit);
92+
hostapd_conf = fopenf("a+", HOSTAPD_SUPPLICANT_CONF, ifname);
93+
if (!hostapd_conf) {
94+
rc = SR_ERR_INTERNAL;
95+
goto out;
96+
}
97+
98+
if (!counter) { /* First SSID */
99+
bool freq_24GHz = !strcmp(band, "2.4GHz");
100+
fprintf(hostapd_conf, "# Generated by Infix confd\n");
101+
102+
if (!strcmp(channel, "auto"))
103+
channel = freq_24GHz ? "6" : "149";
104+
105+
fprintf(hostapd_conf,
106+
"interface=%s\n"
107+
"driver=nl80211\n"
108+
"hw_mode=%c\n"
109+
"country_code=%s\n"
110+
"wmm_enabled=1\n" /* QoS */
111+
"channel=%s\n"
112+
"logger_syslog=-1\n"
113+
"logger_syslog_level=0\n\n"
114+
"logger_stdout=0\n",
115+
ifname, freq_24GHz ? 'g' : 'a', country, channel);
116+
if (freq_24GHz)
117+
fprintf(hostapd_conf, "ieee80211n=1\n");
118+
else
119+
fprintf(hostapd_conf, "ieee80211ac=1\n");
120+
}
121+
122+
123+
fprintf (hostapd_conf,
124+
"\n\n#################################\n"
125+
"# SSID %s\n"
126+
"#################################\n\n",
127+
ssid);
128+
if (counter)
129+
fprintf(hostapd_conf, "bss=%s_%d\n", ifname, counter);
130+
131+
fprintf(hostapd_conf, "ssid=%s\n", ssid);
132+
if (encryption) {
133+
fprintf(hostapd_conf, "wpa_key_mgmt=WPA-PSK SAE\n");
134+
fprintf(hostapd_conf, "wpa_passphrase=%s\n", secret);
135+
fprintf(hostapd_conf, "sae_password=%s\n", secret);
136+
fputs("wpa_pairwise=CCMP\n",hostapd_conf);
137+
fputs("rsn_pairwise=CCMP\n", hostapd_conf);
138+
fputs("ieee80211w=1\n",hostapd_conf); /* This to allow WPA2 clients */
139+
fputs("wpa=2\n",hostapd_conf);
140+
}
141+
fputs("ignore_broadcast_ssid=0\n", hostapd_conf);
142+
fputs("\n", hostapd_conf);
143+
fclose(hostapd_conf);
144+
out:
145+
return rc;
146+
147+
}
148+
static void disable_wifi(const char *ifname, FILE *fp)
149+
{
150+
fprintf(fp, "# Generated by Infix confd\n");
151+
fprintf(fp, "iw dev %s disconnect\n", ifname);
152+
fprintf(fp, "initctl -bfqn disable wifi@%s\n", ifname);
153+
fprintf(fp, "initctl -bfqn disable hostapd@%s\n", ifname);
154+
erasef(WPA_SUPPLICANT_CONF, ifname);
155+
erasef(HOSTAPD_SUPPLICANT_CONF, ifname);
156+
}
72157
int wifi_gen(struct lyd_node *dif, struct lyd_node *cif, struct dagger *net)
73158
{
74-
const char *ssid_name, *secret_name, *secret, *ifname, *country, *encryption, *mode;
159+
const char *ssid_name, *secret_name, *secret = NULL, *ifname, *country;
160+
const char *encryption, *mode, *band, *channel;;
75161
struct lyd_node *wifi, *secret_node, *ssid;
76-
bool first = true;
77162
bool enabled;
78-
ifname = lydx_get_cattr(cif, "name");
79-
enabled = lydx_get_bool(cif, "enabled");
163+
int counter = 0;
164+
FILE *fp;
80165

81-
if (!enabled)
82-
return wifi_gen_del(cif, net);
166+
ifname = lydx_get_cattr(cif, "name");
167+
fp = dagger_fopen_net_init(net, ifname, NETDAG_INIT_POST, "disable-wifi.sh");
83168

169+
if (!fp) {
170+
ERROR("Could not open disable-wifi.sh");
171+
return SR_ERR_INTERNAL;
172+
}
173+
enabled = lydx_get_bool(cif, "enabled");
84174
wifi = lydx_get_child(cif, "wifi");
85-
if (!wifi)
86-
return wifi_gen_del(cif, net);
175+
176+
if (!enabled || !wifi) {
177+
disable_wifi(ifname, fp);
178+
goto out;
179+
}
87180

88181
if (wifi && !lydx_get_child(wifi, "ssid")) { /* Only the precense container is set. */
89-
return wifi_gen_client_config(ifname, NULL, NULL, NULL, NULL, net, true);
182+
wifi_gen_client_config(ifname, NULL, NULL, NULL, NULL, net, 0);
183+
goto out;
90184
}
185+
91186
country = lydx_get_cattr(wifi, "country-code");
92187
mode = lydx_get_cattr(wifi, "mode");
188+
band = lydx_get_cattr(wifi, "band"); /* Only set in AP mode */
189+
channel = lydx_get_cattr(wifi, "channel"); /* Only set in AP mode */
93190

94-
95-
if (!strcmp(mode, "client")) {
191+
if (!strcmp(mode, "client"))
96192
erasef(WPA_SUPPLICANT_CONF, ifname);
97-
98-
LYX_LIST_FOR_EACH(lyd_child(wifi), ssid, "ssid") {
99-
ssid_name = lydx_get_cattr(ssid, "name");
100-
secret_name = lydx_get_cattr(ssid, "secret");
101-
encryption = lydx_get_cattr(ssid, "encryption");
193+
else
194+
erasef(HOSTAPD_SUPPLICANT_CONF, ifname);
195+
LYX_LIST_FOR_EACH(lyd_child(wifi), ssid, "ssid") {
196+
ssid_name = lydx_get_cattr(ssid, "name");
197+
secret_name = lydx_get_cattr(ssid, "secret");
198+
encryption = lydx_get_cattr(ssid, "encryption");
199+
if (encryption) {
102200
secret_node = lydx_get_xpathf(cif, "../../keystore/symmetric-keys/symmetric-key[name='%s']", secret_name);
103201
secret = lydx_get_cattr(secret_node, "cleartext-key");
104-
wifi_gen_client_config(ifname, ssid_name, country, secret, encryption, net, first);
105-
first = false;
106202
}
203+
if (!strcmp(mode, "client")) {
204+
wifi_gen_client_config(ifname, ssid_name, country, secret, encryption, net, counter);
205+
} else {
206+
wifi_gen_accesspoint_config(ifname, ssid_name, country, secret, encryption, band, channel, net, counter);
207+
}
208+
counter++;
209+
107210
}
108211

212+
out:
213+
fclose(fp);
109214
return SR_ERR_OK;
110215
}
111216

112217
int wifi_gen_del(struct lyd_node *iface, struct dagger *net)
113218
{
114-
const char *ifname = lydx_get_cattr(iface, "name");
115-
FILE *iw = dagger_fopen_net_exit(net, ifname, NETDAG_EXIT_PRE, "iw.sh");
116-
117-
fprintf(iw, "# Generated by Infix confd\n");
118-
fprintf(iw, "iw dev %s disconnect\n", ifname);
119-
fprintf(iw, "initctl -bfqn disable wifi@%s\n", ifname);
120-
fclose(iw);
121-
erasef(WPA_SUPPLICANT_CONF, ifname);
122-
219+
const char *ifname;
220+
FILE *fp;
221+
222+
ifname = lydx_get_cattr(iface, "name");
223+
fp = dagger_fopen_net_exit(net, ifname, NETDAG_EXIT_PRE, "disable-wifi.sh");
224+
if (!fp) {
225+
ERROR("Failed to open disable-wifi.sh");
226+
return SR_ERR_INTERNAL;
227+
}
228+
disable_wifi(ifname, fp);
229+
fclose(fp);
123230
return SR_ERR_OK;
124231
}

src/confd/yang/confd/infix-if-wifi.yang

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ submodule infix-if-wifi {
183183
Manual selection available for common channels.";
184184
}
185185
list ssid {
186+
max-elements 1;
187+
description "WiFi network configuration (currently limited to 1 SSID).";
188+
186189
must "../country-code" {
187190
error-message "Country code is required when SSIDs are configured.";
188191
}

0 commit comments

Comments
 (0)