Skip to content

Commit b4aa50a

Browse files
committed
Code dump
1 parent d6819c4 commit b4aa50a

File tree

6 files changed

+120
-89
lines changed

6 files changed

+120
-89
lines changed
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
# Only rename physical interfaces, skip virtual ones created by hostapd
2-
SUBSYSTEM=="net", ACTION=="add", TEST=="/sys/class/net/$name/wireless", TEST=="/sys/class/net/$name/device", KERNEL!="*_*", NAME="wifi%n"
1+
# Only rename physical interfaces, skip virtual ones created by hostapd/iw
2+
# Virtual interfaces created by iw have name_assign_type=3 (userspace assigned)
3+
SUBSYSTEM=="net", ACTION=="add", TEST=="/sys/class/net/$name/wireless", ATTR{name_assign_type}!="3", NAME="wifi%n"

src/confd/src/core.c

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,83 @@ static confd_dependency_t handle_dependencies(struct lyd_node **diff, struct lyd
138138
}
139139
}
140140

141+
/* Check if any wifi-ap interface changed, add all wifi-ap interfaces and their radios to diff */
142+
struct ly_set *diff_ifaces = lydx_find_xpathf(*diff, "/ietf-interfaces:interfaces/interface");
143+
if (diff_ifaces && diff_ifaces->count > 0) {
144+
bool has_wifi_ap_change = false;
145+
uint32_t i;
146+
147+
/* Check if any changed interface is a wifi-ap interface */
148+
for (i = 0; i < diff_ifaces->count; i++) {
149+
struct lyd_node *diff_iface = diff_ifaces->dnodes[i];
150+
const char *ifname = lydx_get_cattr(diff_iface, "name");
151+
struct lyd_node *config_iface;
152+
153+
if (!ifname)
154+
continue;
155+
156+
/* Look up the interface in config to check its type */
157+
config_iface = lydx_get_xpathf(config, "/ietf-interfaces:interfaces/interface[name='%s']", ifname);
158+
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+
}
164+
}
165+
}
166+
167+
if (has_wifi_ap_change) {
168+
/* Add all wifi-ap interfaces from config to diff */
169+
struct ly_set *wifi_ap_ifaces = lydx_find_xpathf(config, "/ietf-interfaces:interfaces/interface[type='infix-if-type:wifi-ap']");
170+
for (i = 0; wifi_ap_ifaces && i < wifi_ap_ifaces->count; i++) {
171+
struct lyd_node *iface = wifi_ap_ifaces->dnodes[i];
172+
struct lyd_node *wifi_node, *radio_node;
173+
const char *ifname, *radio_name;
174+
char xpath[256];
175+
176+
ifname = lydx_get_cattr(iface, "name");
177+
wifi_node = lydx_get_child(iface, "wifi");
178+
179+
if (wifi_node) {
180+
/* Add wifi node to trigger reprocessing of all wifi-ap interfaces */
181+
snprintf(xpath, sizeof(xpath),
182+
"/ietf-interfaces:interfaces/interface[name='%s']/infix-interfaces:wifi",
183+
ifname);
184+
result = add_dependencies(diff, xpath, "");
185+
if (result == CONFD_DEP_ERROR) {
186+
ERROR("Failed to add wifi-ap %s to diff", ifname);
187+
ly_set_free(wifi_ap_ifaces, NULL);
188+
ly_set_free(diff_ifaces, NULL);
189+
return result;
190+
}
191+
192+
/* Add the referenced radio interface (type wifi) to diff */
193+
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+
snprintf(xpath, sizeof(xpath),
198+
"/ietf-interfaces:interfaces/interface[name='%s']/infix-interfaces:wifi",
199+
radio_name);
200+
result = add_dependencies(diff, xpath, "");
201+
if (result == CONFD_DEP_ERROR) {
202+
ERROR("Failed to add radio interface %s to diff", radio_name);
203+
ly_set_free(wifi_ap_ifaces, NULL);
204+
ly_set_free(diff_ifaces, NULL);
205+
return result;
206+
}
207+
}
208+
}
209+
}
210+
}
211+
if (wifi_ap_ifaces)
212+
ly_set_free(wifi_ap_ifaces, NULL);
213+
}
214+
215+
ly_set_free(diff_ifaces, NULL);
216+
}
217+
141218
return result;
142219
}
143220

@@ -180,7 +257,7 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod
180257
}
181258
max_dep--;
182259
}
183-
#if 0
260+
#if 1
184261
/* Debug: print diff to file */
185262
FILE *f = fopen("/tmp/confd-diff.json", "w");
186263
if (f) {

src/confd/src/ietf-interfaces.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ static int ifchange_cand_infer_type(sr_session_ctx_t *session, const char *path)
8080

8181
if (!fnmatch("wifi+([0-9])", ifname, FNM_EXTMATCH))
8282
inferred.data.string_val = "infix-if-type:wifi";
83+
if (!fnmatch("wifi([0-9])-ap+([0-9])", ifname, FNM_EXTMATCH))
84+
inferred.data.string_val = "infix-if-type:wifi-ap";
8385
else if (iface_is_phys(ifname))
8486
inferred.data.string_val = "infix-if-type:ethernet";
8587
else if (!fnmatch("br+([0-9])", ifname, FNM_EXTMATCH))
@@ -416,7 +418,7 @@ static int netdag_gen_afspec_add(sr_session_ctx_t *session, struct dagger *net,
416418
case IFT_WIFI:
417419
return wifi_gen(NULL, cif, net);
418420
case IFT_WIFI_AP:
419-
return wifi_ap_add_iface(cif, net) || wifi_gen(NULL, wifi_ap_get_radio(cif), net);
421+
return wifi_ap_add_iface(cif, net);
420422
case IFT_ETH:
421423
return netdag_gen_ethtool(net, cif, dif);
422424
case IFT_LO:
@@ -447,11 +449,7 @@ static int netdag_gen_afspec_set(sr_session_ctx_t *session, struct dagger *net,
447449
return netdag_gen_ethtool(net, cif, dif);
448450
case IFT_WIFI:
449451
return wifi_gen(dif, cif, net);
450-
case IFT_WIFI_AP: {
451-
struct lyd_node *radio_if = wifi_ap_get_radio(cif);
452-
return wifi_gen(NULL, radio_if, net);
453-
return 0;
454-
}
452+
case IFT_WIFI_AP: /* Is generated from radio interface */
455453
case IFT_DUMMY:
456454
case IFT_GRE:
457455
case IFT_GRETAP:
@@ -481,8 +479,7 @@ static bool netdag_must_del(struct lyd_node *dif, struct lyd_node *cif)
481479
case IFT_ETH:
482480
return lydx_get_child(dif, "custom-phys-address");
483481
case IFT_WIFI_AP:
484-
return lydx_get_child(dif, "custom-phys-address");
485-
482+
return lydx_get_child(dif, "custom-phys-address") || lydx_get_child((dif), "wifi");
486483
case IFT_GRE:
487484
case IFT_GRETAP:
488485
return lydx_get_descendant(lyd_child(dif), "gre", NULL);
@@ -622,6 +619,9 @@ static sr_error_t netdag_gen_iface(sr_session_ctx_t *session, struct dagger *net
622619
if (err)
623620
goto err;
624621

622+
if (!strcmp(iftype, "infix-if-type:wifi") && wifi_is_accesspoint(cif))
623+
return SR_ERR_OK;
624+
625625
if ((err = cni_netdag_gen_iface(net, ifname, dif, cif))) {
626626
/* error or managed by CNI/podman */
627627
if (err > 0)

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

Lines changed: 25 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,13 @@ int wifi_gen(struct lyd_node *dif, struct lyd_node *cif, struct dagger *net) {
105105
return SR_ERR_OK;
106106
cmode = lydx_get_child(cwifi, "mode");
107107

108-
ERROR("NOW GENERATE WIFI");
109108
fp = dagger_fopen_net_init(net, ifname, NETDAG_INIT_POST, "disable-wifi.sh");
110109
if (dif) {
111110
dwifi = lydx_get_child(dif, "wifi");
112111
if (dwifi)
113112
dmode = lydx_get_child(dwifi, "mode");
114113
}
115114
if (!lydx_get_cattr(cif, "enabled")) {
116-
ERROR("INTERFACE DISSABLED");
117115
if (dwifi) {
118116
if (dmode && !strcmp(lyd_get_value(dmode), "accesspoint"))
119117
disable_wifi_ap(ifname, fp);
@@ -124,13 +122,11 @@ int wifi_gen(struct lyd_node *dif, struct lyd_node *cif, struct dagger *net) {
124122
}
125123

126124
if (cmode && !strcmp(lyd_get_value(cmode), "accesspoint")) {
127-
ERROR("Should now configure AP");
128125
if (dmode && strcmp(lyd_get_value(dmode), "accesspoint"))
129126
disable_wifi_station(ifname, fp);
130127
wifi_ap_gen(cif, net);
131128

132129
} else {
133-
ERROR("Should now configure station");
134130
if (dmode && strcmp(lyd_get_value(dmode), "station"))
135131
disable_wifi_ap(ifname, fp);
136132
/* Client */
@@ -149,7 +145,6 @@ int wifi_station_gen(struct lyd_node *cif, struct dagger *net)
149145
int counter = 0;
150146
FILE *fp;
151147

152-
ERROR("GENERATE STATION");
153148
ifname = lydx_get_cattr(cif, "name");
154149
fp = dagger_fopen_net_init(net, ifname, NETDAG_INIT_POST, "disable-wifi.sh");
155150

@@ -203,61 +198,33 @@ int wifi_station_gen(struct lyd_node *cif, struct dagger *net)
203198

204199
int wifi_ap_del_iface(struct lyd_node *cif,struct dagger *net)
205200
{
206-
const char *ifname, *radio;
207-
struct lyd_node *wifi;
208-
struct ly_set *remaining_aps = NULL;
209-
bool is_last_ap = false;
201+
const char *ifname;
210202
FILE *iw;
211-
int rc;
212203

213204
ifname = lydx_get_cattr(cif, "name");
214-
wifi = lydx_get_child(cif, "wifi");
215-
216-
if (wifi) {
217-
radio = lydx_get_cattr(wifi, "radio");
218-
219-
/* Check if this is the last AP interface for this radio */
220-
if (radio) {
221-
rc = lyd_find_xpath(cif, "../interface[derived-from-or-self(type, 'infix-if-type:wifi-ap') and wifi/radio = current()/wifi/radio and name != current()/name]", &remaining_aps);
222-
if (rc != LY_SUCCESS || !remaining_aps || remaining_aps->count == 0) {
223-
is_last_ap = true;
224-
ERROR("Interface %s is the last AP for radio %s - will restore radio name", ifname, radio);
225-
} else {
226-
ERROR("Interface %s removal leaves %d other APs for radio %s", ifname, remaining_aps->count, radio);
227-
}
228-
229-
if (remaining_aps)
230-
ly_set_free(remaining_aps, NULL);
231-
}
232-
}
233-
234205
iw = dagger_fopen_net_exit(net, ifname, NETDAG_EXIT, "exit-iw.sh");
235206

236-
if (is_last_ap && radio) {
237-
/* Last AP interface: restore original radio name */
238-
fprintf(iw, "# Restore radio name from %s back to %s\n", ifname, radio);
239-
fprintf(iw, "ip link set dev %s name %s\n", ifname, radio);
240-
fprintf(iw, "ip link property del dev %s altname %s\n", radio, radio);
241-
} else {
242-
/* Virtual AP interface: delete it */
243-
fprintf(iw, "# Delete virtual AP interface %s\n", ifname);
244-
fprintf(iw, "iw dev %s del\n", ifname);
245-
}
207+
fprintf(iw, "# Check if interface has altname, if so restore it, else delete interface\n");
208+
fprintf(iw, "ALTNAME=$(ip -j link show dev %s | jq -r '.[0].altnames[0] // empty')\n", ifname);
209+
fprintf(iw, "if [ -n \"$ALTNAME\" ]; then\n");
210+
fprintf(iw, " # Restore original radio name\n");
211+
fprintf(iw, " ip link set dev %s name \"$ALTNAME\"\n", ifname);
212+
fprintf(iw, " ip link property del dev \"$ALTNAME\" altname \"$ALTNAME\"\n");
213+
fprintf(iw, "else\n");
214+
fprintf(iw, " # Delete virtual AP interface\n");
215+
fprintf(iw, " iw dev %s del\n", ifname);
216+
fprintf(iw, "fi\n");
246217

247218
fclose(iw);
248219

249220
return 0;
250221
}
251222

252-
253223
int wifi_ap_add_iface(struct lyd_node *cif,struct dagger *net)
254224
{
255225
const char *ifname, *radio;
256226
struct lyd_node *wifi;
257-
struct ly_set *existing_aps = NULL;
258-
bool is_first_ap = false;
259227
FILE *iw;
260-
int rc;
261228

262229
ifname = lydx_get_cattr(cif, "name");
263230

@@ -273,39 +240,22 @@ int wifi_ap_add_iface(struct lyd_node *cif,struct dagger *net)
273240
return SR_ERR_INVAL_ARG;
274241
}
275242

276-
/* Check if this is the first AP interface for this radio by finding all APs for this radio */
277-
rc = lyd_find_xpath(cif, "../interface[derived-from-or-self(type, 'infix-if-type:wifi-ap') and wifi/radio = current()/wifi/radio]", &existing_aps);
278-
if (rc == LY_SUCCESS && existing_aps && existing_aps->count > 0) {
279-
/* Check if current interface is the first one in the list */
280-
const char *first_ap_name = lydx_get_cattr(existing_aps->dnodes[0], "name");
281-
if (!strcmp(ifname, first_ap_name)) {
282-
is_first_ap = true;
283-
ERROR("Interface %s is the first AP for radio %s - will rename radio", ifname, radio);
284-
} else {
285-
ERROR("Interface %s is additional AP for radio %s - will create virtual interface", ifname, radio);
286-
}
287-
} else {
288-
/* Fallback: if we can't determine, assume first */
289-
is_first_ap = true;
290-
ERROR("Interface %s assumed to be first AP for radio %s", ifname, radio);
291-
}
292-
293-
if (existing_aps)
294-
ly_set_free(existing_aps, NULL);
295-
296243
dagger_add_dep(&confd.netdag, ifname, radio);
297244
iw = dagger_fopen_net_init(net, ifname, NETDAG_INIT_PRE, "init-iw.sh");
298245

299-
if (is_first_ap) {
300-
/* First AP interface: rename radio interface to AP name */
301-
fprintf(iw, "# Rename radio %s to first AP interface %s\n", radio, ifname);
302-
fprintf(iw, "ip link set dev %s name %s\n", radio, ifname);
303-
fprintf(iw, "ip link property add dev %s altname %s\n", ifname, radio);
304-
} else {
305-
/* Additional AP interfaces: create virtual interface as before */
306-
fprintf(iw, "# Create virtual AP interface %s on radio %s\n", ifname, radio);
307-
fprintf(iw, "iw dev %s interface add %s type __ap\n", radio, ifname);
308-
}
246+
fprintf(iw, "# Check if radio has altname, if so create virtual interface, else rename radio\n");
247+
fprintf(iw, "ALTNAME=$(ip -j link show dev %s | jq -r '.[0].altnames[0] // empty')\n", radio);
248+
fprintf(iw, "if [ -n \"$ALTNAME\" ]; then\n");
249+
fprintf(iw, " # Radio already renamed, create virtual AP interface\n");
250+
fprintf(iw, " logger -t confd -p daemon.info \"Creating virtual AP interface %s on radio %s\"\n", ifname, radio);
251+
fprintf(iw, " iw dev %s interface add %s type __ap\n", radio, ifname);
252+
fprintf(iw, "else\n");
253+
fprintf(iw, " # First AP interface, rename radio to AP name\n");
254+
fprintf(iw, " logger -t confd -p daemon.info \"Renaming radio %s to AP interface %s\"\n", radio, ifname);
255+
fprintf(iw, " ip link set dev %s down\n", radio);
256+
fprintf(iw, " ip link set dev %s name %s\n", radio, ifname);
257+
fprintf(iw, " ip link property add dev %s altname %s\n", ifname, radio);
258+
fprintf(iw, "fi\n");
309259

310260
fclose(iw);
311261

@@ -348,6 +298,7 @@ int wifi_ap_gen(struct lyd_node *cif, struct dagger *net)
348298
if (!channel || !strcmp(channel, "auto"))
349299
channel = freq_24GHz ? "6" : "149";
350300

301+
ERROR("Searching radio");
351302
/* Find all wifi-ap interfaces that reference this radio */
352303
rc = lyd_find_xpath(cif, "../interface[derived-from-or-self(type, 'infix-if-type:wifi-ap') and wifi/radio = current()/name]", &ap_interfaces);
353304
if (rc != LY_SUCCESS || !ap_interfaces || ap_interfaces->count == 0) {

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ submodule infix-if-wifi {
131131
must "derived-from-or-self(/if:interfaces/if:interface[if:name=current()]/if:type, 'infixift:wifi')" {
132132
error-message "Referenced interface must be of type 'wifi'.";
133133
}
134+
must "/if:interfaces/if:interface[if:name=current()]/infix-if:wifi/mode = 'accesspoint'" {
135+
error-message "Referenced wifi interface must be in accesspoint mode.";
136+
}
134137
mandatory true;
135138
description
136139
"Reference to the underlying WiFi radio interface.
@@ -151,6 +154,9 @@ submodule infix-if-wifi {
151154

152155
leaf mode {
153156
type mode;
157+
must "not(. = 'accesspoint' and derived-from-or-self(../../if:type, 'infixift:wifi')) or ../band" {
158+
error-message "Band must be specified when mode is accesspoint for wifi interfaces.";
159+
}
154160
description
155161
"WiFi interface operating mode.
156162
@@ -162,9 +168,6 @@ submodule infix-if-wifi {
162168
when "derived-from-or-self(../../if:type, 'infixift:wifi') and ../mode = 'accesspoint'" {
163169
description "Only available for wifi interfaces in accesspoint mode.";
164170
}
165-
must "not(derived-from-or-self(../../if:type, 'infixift:wifi') and ../mode = 'accesspoint') or ." {
166-
error-message "Band is mandatory for WiFi interfaces in accesspoint mode.";
167-
}
168171
description
169172
"WiFi frequency band for radio operation.
170173

src/statd/python/yanger/ietf_interfaces/wifi.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ def wifi(ifname):
2525
wifi_data["active-ssid"] = v
2626

2727
data=HOST.run(tuple(f"wpa_cli -i {ifname} signal_poll".split()), default="FAIL")
28-
2928
# signal_poll return FAIL not connected
3029
if data.strip() != "FAIL":
3130
for line in data.splitlines():

0 commit comments

Comments
 (0)