Skip to content

Commit 0a62668

Browse files
committed
Code dump
1 parent ab9aa5a commit 0a62668

File tree

3 files changed

+134
-79
lines changed

3 files changed

+134
-79
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
We create the interfaces on our own, and set their MAC addresses
2+
remove this check (which are for hostapd created ap interfaces)
3+
4+
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
5+
index a57a151fa..43d31d16c 100644
6+
--- a/src/ap/hostapd.c
7+
+++ b/src/ap/hostapd.c
8+
@@ -940,18 +940,6 @@ skip_mask_ext:
9+
if (!auto_addr)
10+
return 0;
11+
12+
- for (i = 0; i < ETH_ALEN; i++) {
13+
- if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
14+
- wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR
15+
- " for start address " MACSTR ".",
16+
- MAC2STR(mask), MAC2STR(hapd->own_addr));
17+
- wpa_printf(MSG_ERROR, "Start address must be the "
18+
- "first address in the block (i.e., addr "
19+
- "AND mask == addr).");
20+
- return -1;
21+
- }
22+
- }
23+
-
24+
return 0;
25+
}
26+

src/confd/src/core.c

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -149,18 +149,23 @@ static confd_dependency_t handle_dependencies(struct lyd_node **diff, struct lyd
149149
struct lyd_node *diff_iface = diff_ifaces->dnodes[i];
150150
const char *ifname = lydx_get_cattr(diff_iface, "name");
151151
struct lyd_node *config_iface;
152+
const char *type = NULL;
152153

153154
if (!ifname)
154155
continue;
155156

156157
/* Look up the interface in config to check its type */
157158
config_iface = lydx_get_xpathf(config, "/ietf-interfaces:interfaces/interface[name='%s']", ifname);
158159
if (config_iface) {
159-
const char *type = lydx_get_cattr(config_iface, "type");
160-
if (type && strstr(type, "wifi-ap")) {
161-
has_wifi_ap_change = true;
162-
break;
163-
}
160+
type = lydx_get_cattr(config_iface, "type");
161+
} else {
162+
/* Interface not in config (being deleted), check diff node */
163+
type = lydx_get_cattr(diff_iface, "type");
164+
}
165+
166+
if (type && strstr(type, "wifi-ap")) {
167+
has_wifi_ap_change = true;
168+
break;
164169
}
165170
}
166171

@@ -191,33 +196,29 @@ static confd_dependency_t handle_dependencies(struct lyd_node **diff, struct lyd
191196

192197
/* Add the radio attribute to the diff */
193198
radio_node = lydx_get_child(wifi_node, "radio");
194-
if (radio_node) {
195-
radio_name = lyd_get_value(radio_node);
196-
if (radio_name) {
197-
/* Add radio attribute to wifi-ap interface in diff */
198-
snprintf(xpath, sizeof(xpath),
199-
"/ietf-interfaces:interfaces/interface[name='%s']/infix-interfaces:wifi/radio",
200-
ifname);
201-
result = add_dependencies(diff, xpath, radio_name);
202-
if (result == CONFD_DEP_ERROR) {
203-
ERROR("Failed to add radio attribute to wifi-ap %s in diff", ifname);
204-
ly_set_free(wifi_ap_ifaces, NULL);
205-
ly_set_free(diff_ifaces, NULL);
206-
return result;
207-
}
208-
209-
/* Add the referenced radio interface (type wifi) to diff */
210-
snprintf(xpath, sizeof(xpath),
211-
"/ietf-interfaces:interfaces/interface[name='%s']/infix-interfaces:wifi",
212-
radio_name);
213-
result = add_dependencies(diff, xpath, "");
214-
if (result == CONFD_DEP_ERROR) {
215-
ERROR("Failed to add radio interface %s to diff", radio_name);
216-
ly_set_free(wifi_ap_ifaces, NULL);
217-
ly_set_free(diff_ifaces, NULL);
218-
return result;
219-
}
220-
}
199+
radio_name = lyd_get_value(radio_node);
200+
/* Add radio attribute to wifi-ap interface in diff */
201+
snprintf(xpath, sizeof(xpath),
202+
"/ietf-interfaces:interfaces/interface[name='%s']/infix-interfaces:wifi/radio",
203+
ifname);
204+
result = add_dependencies(diff, xpath, radio_name);
205+
if (result == CONFD_DEP_ERROR) {
206+
ERROR("Failed to add radio attribute to wifi-ap %s in diff", ifname);
207+
ly_set_free(wifi_ap_ifaces, NULL);
208+
ly_set_free(diff_ifaces, NULL);
209+
return result;
210+
}
211+
212+
/* Add the referenced radio interface (type wifi) to diff */
213+
snprintf(xpath, sizeof(xpath),
214+
"/ietf-interfaces:interfaces/interface[name='%s']/infix-interfaces:wifi",
215+
radio_name);
216+
result = add_dependencies(diff, xpath, "");
217+
if (result == CONFD_DEP_ERROR) {
218+
ERROR("Failed to add radio interface %s to diff", radio_name);
219+
ly_set_free(wifi_ap_ifaces, NULL);
220+
ly_set_free(diff_ifaces, NULL);
221+
return result;
221222
}
222223
}
223224
}

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

Lines changed: 75 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@ static int compare_ap_interfaces(const void *a, const void *b)
1818
return strcmp(name_a, name_b);
1919
}
2020

21-
/* Comparison function for sorting AP interfaces by name (descending) */
22-
static int compare_ap_interfaces_reverse(const void *a, const void *b)
23-
{
24-
return -compare_ap_interfaces(a, b);
25-
}
26-
2721
struct lyd_node *wifi_ap_get_radio(struct lyd_node *cif) {
2822
struct lyd_node *wifi = lydx_get_child(cif, "wifi");
2923
if (wifi) {
@@ -221,9 +215,7 @@ int wifi_ap_del_iface(struct lyd_node *dif, struct lyd_node *cif, struct dagger
221215
{
222216
const char *ifname, *radio;
223217
struct lyd_node *wifi;
224-
struct ly_set *ap_interfaces = NULL;
225218
FILE *iw;
226-
int rc;
227219
bool is_last_ap = false;
228220

229221
ifname = lydx_get_cattr(dif, "name");
@@ -234,41 +226,81 @@ int wifi_ap_del_iface(struct lyd_node *dif, struct lyd_node *cif, struct dagger
234226
radio = lydx_get_cattr(wifi, "radio");
235227
ERROR("Found radio: %s for interface %s", radio, ifname);
236228
if (radio) {
237-
/* Find all wifi-ap interfaces from diff config to determine position */
238-
rc = lyd_find_xpath(dif, "../interface[derived-from-or-self(type, 'infix-if-type:wifi-ap') and wifi/radio = current()/wifi/radio]", &ap_interfaces);
239-
ERROR("XPath result: rc=%d, count=%u", rc, ap_interfaces ? ap_interfaces->count : 0);
240-
if (rc == LY_SUCCESS && ap_interfaces && ap_interfaces->count > 0) {
241-
/* Sort interfaces by name in REVERSE order for deletion (ap2, ap1, ap0) */
242-
qsort(ap_interfaces->dnodes, ap_interfaces->count, sizeof(struct lyd_node *), compare_ap_interfaces_reverse);
243-
/* Find our position - last one (ap0) restores radio, others delete virtual */
244-
ERROR("Searching for %s in %d AP interfaces", ifname, ap_interfaces->count);
245-
for (uint32_t i = 0; i < ap_interfaces->count; i++) {
246-
const char *ap_ifname = lydx_get_cattr(ap_interfaces->dnodes[i], "name");
247-
ERROR(" AP[%d]: %s (comparing with %s)", i, ap_ifname, ifname);
229+
struct lyd_node *iface, *sibling;
230+
struct lyd_node **matching;
231+
uint32_t match_count = 0, alloc_count = 8;
232+
233+
/* Iterate through sibling interfaces, filter for
234+
* non-created wifi-ap interfaces with matching radio.
235+
*/
236+
matching = calloc(alloc_count, sizeof(struct lyd_node *));
237+
if (!matching)
238+
goto skip_position_check;
239+
240+
sibling = lyd_first_sibling(dif);
241+
LYX_LIST_FOR_EACH(sibling, iface, "interface") {
242+
struct lyd_node *iface_radio_node;
243+
const char *iface_radio;
244+
245+
/* Skip created interfaces - only consider deleted/modified */
246+
if (lydx_get_op(iface) == LYDX_OP_CREATE)
247+
continue;
248+
249+
/* Check wifi/radio to identify wifi-ap interfaces */
250+
iface_radio_node = lydx_get_descendant(lyd_child(iface), "wifi", "radio", NULL);
251+
if (!iface_radio_node)
252+
continue;
253+
254+
iface_radio = lyd_get_value(iface_radio_node);
255+
if (!iface_radio || strcmp(iface_radio, radio))
256+
continue;
257+
258+
if (match_count >= alloc_count) {
259+
alloc_count *= 2;
260+
matching = realloc(matching, alloc_count * sizeof(struct lyd_node *));
261+
}
262+
matching[match_count++] = iface;
263+
}
264+
265+
ERROR("Found %u non-created interfaces matching radio %s", match_count, radio);
266+
if (match_count > 0) {
267+
/* Sort in normal order to find the last AP (renamed radio) */
268+
qsort(matching, match_count, sizeof(struct lyd_node *), compare_ap_interfaces);
269+
270+
for (uint32_t i = 0; i < match_count; i++) {
271+
const char *ap_ifname = lydx_get_cattr(matching[i], "name");
272+
ERROR(" AP[%d]: %s", i, ap_ifname);
248273
if (!strcmp(ap_ifname, ifname)) {
249-
is_last_ap = (i == ap_interfaces->count - 1);
250-
ERROR(" MATCH! Interface %s is at position %d of %d, is_last_ap=%d", ifname, i, ap_interfaces->count, is_last_ap);
274+
is_last_ap = (i == match_count - 1);
275+
ERROR(" MATCH! is_last_ap=%d", is_last_ap);
251276
break;
252277
}
253278
}
254-
ERROR("After loop: is_last_ap=%d", is_last_ap);
255-
ly_set_free(ap_interfaces, NULL);
256279
}
280+
281+
free(matching);
257282
}
258283
}
284+
skip_position_check:
259285

260286
iw = dagger_fopen_net_exit(net, ifname, NETDAG_EXIT_POST, "exit-iw.sh");
261287

262288
if (is_last_ap) {
263-
/* Last AP in deletion order (originally first: wifi0-ap0) - restore original radio name */
264-
fprintf(iw, "# Last AP to delete (wifi0-ap0), restore original radio name\n");
289+
/* Last AP (e.g., wifi0-ap2) is the renamed radio - restore original radio name and MAC */
290+
fprintf(iw, "# Last AP is renamed radio, restore original radio name and MAC\n");
265291
fprintf(iw, "logger -t confd -p daemon.info \"Restoring radio name from %s to %s\"\n", ifname, radio);
266292
fprintf(iw, "ip link set dev %s down\n", ifname);
267293
fprintf(iw, "ip link property del dev %s altname %s 2>/dev/null || true\n", ifname, radio);
268294
fprintf(iw, "ip link set dev %s name %s\n", ifname, radio);
295+
/* Restore original MAC address from permaddr */
296+
fprintf(iw, "permaddr=$(ip -d -j link show dev %s | jq -rM '.[].permaddr // empty')\n", radio);
297+
fprintf(iw, "if [ -n \"$permaddr\" ]; then\n");
298+
fprintf(iw, " logger -t confd -p daemon.info \"Restoring original MAC $permaddr on %s\"\n", radio);
299+
fprintf(iw, " ip link set dev %s address $permaddr\n", radio);
300+
fprintf(iw, "fi\n");
269301
} else {
270-
/* Subsequent AP interface - delete virtual interface */
271-
fprintf(iw, "# Additional AP interface, delete virtual interface\n");
302+
/* Not last AP - delete virtual interface */
303+
fprintf(iw, "# Virtual AP interface, delete it\n");
272304
fprintf(iw, "logger -t confd -p daemon.info \"Deleting virtual AP interface %s\"\n", ifname);
273305
fprintf(iw, "iw dev %s del\n", ifname);
274306
}
@@ -313,11 +345,11 @@ int wifi_ap_add_iface(struct lyd_node *cif,struct dagger *net)
313345
qsort(ap_interfaces->dnodes, ap_interfaces->count, sizeof(struct lyd_node *), compare_ap_interfaces);
314346

315347
/* Find our position in the AP list */
316-
bool is_first_ap = false;
317-
const char *first_ap_name = lydx_get_cattr(ap_interfaces->dnodes[0], "name");
348+
bool is_last_ap = false;
349+
uint32_t last_idx = ap_interfaces->count - 1;
318350
for (uint32_t i = 0; i < ap_interfaces->count; i++) {
319351
if (ap_interfaces->dnodes[i] == cif) {
320-
is_first_ap = (i == 0);
352+
is_last_ap = (i == last_idx);
321353
/* If not first, add dependency to previous AP for sequential creation */
322354
if (i > 0) {
323355
const char *prev_ap_name = lydx_get_cattr(ap_interfaces->dnodes[i-1], "name");
@@ -331,18 +363,18 @@ int wifi_ap_add_iface(struct lyd_node *cif,struct dagger *net)
331363

332364
iw = dagger_fopen_net_init(net, ifname, NETDAG_INIT_PRE, "init-iw.sh");
333365

334-
if (is_first_ap) {
335-
/* First AP interface - rename radio to AP name and preserve radio name as altname */
336-
fprintf(iw, "# First AP interface, rename radio to AP name\n");
366+
if (is_last_ap) {
367+
/* Last AP interface - rename radio to AP name and preserve radio name as altname */
368+
fprintf(iw, "# Last AP interface, rename radio to AP name\n");
337369
fprintf(iw, "logger -t confd -p daemon.info \"Renaming radio %s to AP interface %s\"\n", radio, ifname);
338370
fprintf(iw, "ip link set dev %s down\n", radio);
339371
fprintf(iw, "ip link set dev %s name %s\n", radio, ifname);
340372
fprintf(iw, "ip link property add dev %s altname %s\n", ifname, radio);
341373
} else {
342-
/* Subsequent AP interface - create virtual interface on the renamed radio */
343-
fprintf(iw, "# Additional AP interface, create virtual interface\n");
344-
fprintf(iw, "logger -t confd -p daemon.info \"Creating virtual AP interface %s on %s (radio %s)\"\n", ifname, first_ap_name, radio);
345-
fprintf(iw, "iw dev %s interface add %s type __ap\n", first_ap_name, ifname);
374+
/* Not last AP - create virtual interface on the radio */
375+
fprintf(iw, "# Virtual AP interface, create on radio\n");
376+
fprintf(iw, "logger -t confd -p daemon.info \"Creating virtual AP interface %s on %s\"\n", ifname, radio);
377+
fprintf(iw, "iw dev %s interface add %s type __ap\n", radio, ifname);
346378
}
347379

348380
fclose(iw);
@@ -398,16 +430,12 @@ int wifi_ap_gen(struct lyd_node *cif, struct dagger *net)
398430
/* Sort interfaces by name to ensure consistent ordering */
399431
qsort(ap_interfaces->dnodes, ap_interfaces->count, sizeof(struct lyd_node *), compare_ap_interfaces);
400432

401-
/* The first AP interface becomes the main interface (radio gets renamed to this) */
402-
ap_interface = ap_interfaces->dnodes[0];
433+
/* The last AP interface becomes the main interface (radio gets renamed to this) */
434+
ap_interface = ap_interfaces->dnodes[ap_interfaces->count - 1];
403435
main_interface_name = lydx_get_cattr(ap_interface, "name");
404436

405-
/* Radio depends on first AP interface since radio will be renamed to it */
406-
dagger_add_dep(&confd.netdag, ifname, main_interface_name);
407-
ERROR("Adding dependency: radio %s depends on first AP %s", ifname, main_interface_name);
408-
409437
ERROR("Generating hostapd config for radio %s, main interface %s with %d total APs",
410-
ifname, ifname, ap_interfaces->count);
438+
ifname, main_interface_name, ap_interfaces->count);
411439

412440
/* Clean up any existing AP configuration */
413441
erasef(HOSTAPD_SUPPLICANT_CONF, ifname);
@@ -443,7 +471,7 @@ int wifi_ap_gen(struct lyd_node *cif, struct dagger *net)
443471
else
444472
fprintf(hostapd_conf, "ieee80211ac=1\n");
445473

446-
/* Configure first AP interface as main SSID */
474+
/* Configure last AP interface as main SSID (it's the renamed radio) */
447475
struct lyd_node *main_wifi = lydx_get_child(ap_interface, "wifi");
448476
if (main_wifi) {
449477
const char *ssid = lydx_get_cattr(main_wifi, "ssid");
@@ -472,8 +500,8 @@ int wifi_ap_gen(struct lyd_node *cif, struct dagger *net)
472500
fputs("ignore_broadcast_ssid=0\n", hostapd_conf);
473501
}
474502

475-
/* Add additional AP interfaces as BSS entries */
476-
for (uint32_t i = 1; i < ap_interfaces->count; i++) {
503+
/* Add other AP interfaces as BSS entries (all except the last one) */
504+
for (uint32_t i = 0; i < ap_interfaces->count - 1; i++) {
477505
ap_interface = ap_interfaces->dnodes[i];
478506
const char *ap_ifname = lydx_get_cattr(ap_interface, "name");
479507
struct lyd_node *ap_wifi = lydx_get_child(ap_interface, "wifi");

0 commit comments

Comments
 (0)