Skip to content

Commit

Permalink
interfaces: deal with problematic <wireless/> handling #5939
Browse files Browse the repository at this point in the history
The wireless code "integration" is horrible even by moderate standards
in our code base.  In the future the best way would be to ditch all of
it and rebuild (parts) required by users.
  • Loading branch information
fichtner committed Aug 11, 2022
1 parent fd8ae82 commit 475cb8e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 29 deletions.
23 changes: 14 additions & 9 deletions src/etc/inc/interfaces.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1470,35 +1470,40 @@ function interface_wireless_clone($realif, $wlcfg)
* If it has not been cloned then go ahead and clone it.
*/
$needs_clone = false;
if (isset($wlcfg['wireless']) && is_array($wlcfg['wireless'])) {

if (!empty($wlcfg['wireless']['mode'])) {
/* XXX this is interfaces wireless config */
$wlcfg_mode = $wlcfg['wireless']['mode'];
} else {
$wlcfg_mode = $wlcfg['mode'];
/* XXX this is wireless clone config or fallback */
$wlcfg_mode = $wlcfg['mode'] ?? 'bss';
}

switch ($wlcfg_mode) {
case "hostap":
$mode = "wlanmode hostap";
$mode = 'wlanmode hostap';
break;
case "adhoc":
$mode = "wlanmode adhoc";
$mode = 'wlanmode adhoc';
break;
default:
$mode = "";
$mode = '';
break;
}

$baseif = interface_get_wireless_base($wlcfg['if']);
if (does_interface_exist($realif)) {
exec("/sbin/ifconfig " . escapeshellarg($realif), $output, $ret);
$ifconfig_str = implode(PHP_EOL, $output);
if (($wlcfg_mode == "hostap") && (! preg_match("/hostap/si", $ifconfig_str))) {
if (($wlcfg_mode == 'hostap') && !preg_match('/hostap/si', $ifconfig_str)) {
log_error("Interface {$realif} changed to hostap mode");
$needs_clone = true;
}
if (($wlcfg_mode == "adhoc") && (! preg_match("/adhoc/si", $ifconfig_str))) {
if (($wlcfg_mode == 'adhoc') && !preg_match('/adhoc/si', $ifconfig_str)) {
log_error("Interface {$realif} changed to adhoc mode");
$needs_clone = true;
}
if (($wlcfg_mode == "bss") && (preg_match("/hostap|adhoc/si", $ifconfig_str))) {
if (($wlcfg_mode == 'bss') && preg_match('/hostap|adhoc/si', $ifconfig_str)) {
log_error("Interface {$realif} changed to infrastructure mode");
$needs_clone = true;
}
Expand Down Expand Up @@ -2056,8 +2061,8 @@ EOD;
$friendly_if = convert_real_interface_to_friendly_interface_name($clone_if);
if (
!empty($friendly_if)
&& $config['interfaces'][$friendly_if]['wireless']['mode'] == "bss"
&& isset($config['interfaces'][$friendly_if]['wireless']['wpa']['enable'])
&& $config['interfaces'][$friendly_if]['wireless']['mode'] == 'bss'
) {
mwexec('/bin/sh /tmp/' . escapeshellarg($clone_if) . '_setup.sh');
}
Expand Down
41 changes: 21 additions & 20 deletions src/www/interfaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ function get_wireless_channel_info($interface) {
}

if (isset($a_interfaces[$if]['wireless'])) {
config_read_array('interfaces', $if, 'wireless');
/* Sync first to be sure it displays the actual settings that will be used */
interface_sync_wireless_clones($a_interfaces[$if], false);
/* Get wireless modes */
Expand Down Expand Up @@ -606,6 +607,7 @@ interface_configure(false, $ifapply, true);
unset($a_interfaces[$if]['lock']);
}
if (isset($a_interfaces[$if]['wireless'])) {
config_read_array('interfaces', $if, 'wireless');
interface_sync_wireless_clones($a_interfaces[$if], false);
}
$a_interfaces[$if]['descr'] = preg_replace('/[^a-z_0-9]/i', '', $pconfig['descr']);
Expand Down Expand Up @@ -918,6 +920,7 @@ interface_sync_wireless_clones($a_interfaces[$if], false);
Wireless interface
*/
if (isset($a_interfaces[$if]['wireless'])) {
config_read_array('interfaces', $if, 'wireless');
$reqdfields = array("mode");
$reqdfieldsn = array(gettext("Mode"));
if ($pconfig['mode'] == 'hostap') {
Expand All @@ -926,8 +929,10 @@ interface_sync_wireless_clones($a_interfaces[$if], false);
}
do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors);

// check_wireless_mode (more wireless weirdness)
// validations shouldn't perform actual actions, needs serious fixing at some point
/* XXX validations should not even perform temporary actions, needs serious fixing at some point */
if (empty($a_interfaces[$if]['wireless']['mode'])) {
$a_interfaces[$if]['wireless']['mode'] = 'bss';
}
if ($a_interfaces[$if]['wireless']['mode'] != $pconfig['mode']) {
if (does_interface_exist(interface_get_wireless_clone($wlanbaseif))) {
$clone_count = 1;
Expand All @@ -942,15 +947,14 @@ interface_sync_wireless_clones($a_interfaces[$if], false);
}
}
if ($clone_count > 1) {
$wlanif = get_real_interface($if);
$old_wireless_mode = $a_interfaces[$if]['wireless']['mode'];
$a_interfaces[$if]['wireless']['mode'] = $pconfig['mode'];
if (!interface_wireless_clone("{$wlanif}_", $a_interfaces[$if])) {
$input_errors[] = sprintf(gettext("Unable to change mode to %s. You may already have the maximum number of wireless clones supported in this mode."), $wlan_modes[$a_interfaces[$if]['wireless']['mode']]);
} else {
mwexec("/sbin/ifconfig " . escapeshellarg($wlanif) . "_ destroy");
}
}
$wlanif = get_real_interface($if);
$a_interfaces[$if]['wireless']['mode'] = $pconfig['mode'];
if (!interface_wireless_clone("{$wlanif}_", $a_interfaces[$if])) {
$input_errors[] = sprintf(gettext("Unable to change mode to %s. You may already have the maximum number of wireless clones supported in this mode."), $wlan_modes[$a_interfaces[$if]['wireless']['mode']]);
} else {
legacy_interface_destroy("{$wlanif}_");
}
}
}

/* loop through keys and enforce size */
Expand Down Expand Up @@ -1382,6 +1386,7 @@ interface_sync_wireless_clones($new_config, true);

// some wireless settings require additional details to build the listbox
if (isset($a_interfaces[$if]['wireless'])) {
config_read_array('interfaces', $if, 'wireless');
$wl_modes = get_wireless_modes($if);
$wlanbaseif = interface_get_wireless_base($a_interfaces[$if]['if']);
preg_match("/^(.*?)([0-9]*)$/", $wlanbaseif, $wlanbaseif_split);
Expand Down Expand Up @@ -3332,17 +3337,13 @@ function toggle_wirelesscfg() {
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Mode"); ?></td>
<td>
<select name="mode" class="selectpicker" data-style="btn-default" id="mode">
<?php
if (test_wireless_capability(get_real_interface($pconfig['if']), 'hostap')): ?>
<option <?=$pconfig['mode'] == 'hostap' ? "selected=\"selected\"" : "";?> value="hostap"><?=gettext("Access Point"); ?></option>
<?php
endif; ?>
<option <?=$pconfig['mode'] == 'bss' ? "selected=\"selected\"" : "";?> value="bss"><?=gettext("Infrastructure (BSS)"); ?></option>
<?php
if (test_wireless_capability(get_real_interface($pconfig['if']), 'adhoc')): ?>
<?php if (test_wireless_capability(get_real_interface($pconfig['if']), 'adhoc')): ?>
<option <?=$pconfig['mode'] == 'adhoc' ? "selected=\"selected\"" : "";?> value="adhoc"><?=gettext("Ad-hoc (IBSS)"); ?></option>
<?php
endif; ?>
<?php endif ?>
<?php if (test_wireless_capability(get_real_interface($pconfig['if']), 'hostap')): ?>
<option <?=$pconfig['mode'] == 'hostap' ? "selected=\"selected\"" : "";?> value="hostap"><?=gettext("Access Point"); ?></option>
<?php endif ?>
</select>
</td>
</tr>
Expand Down

0 comments on commit 475cb8e

Please sign in to comment.