Commit 7f06e5ad authored by Ad Schellevis's avatar Ad Schellevis Committed by Franco Fichtner

lagg: multiple fixes

PR: https://github.com/opnsense/core/issues/1709
PR: https://github.com/opnsense/core/issues/1710

(cherry picked from commit 093895e3)
(cherry picked from commit cebc6c7e)
(cherry picked from commit e5e914c9)
(cherry picked from commit 4ff07cad)
(cherry picked from commit 576799a1)
(cherry picked from commit 8236ddcc)
(cherry picked from commit 5525a08a)
(cherry picked from commit 46c460bb)
parent 61d816fd
......@@ -704,34 +704,47 @@ function interface_lagg_configure(&$lagg)
if (!count($members)) {
return -1;
}
$interface_stats = legacy_interfaces_details();
if (file_exists("/var/run/booting") || !(empty($lagg['laggif']))) {
legacy_interface_destroy($lagg['laggif']);
legacy_interface_create($lagg['laggif']);
if (!empty($lagg['laggif'])) {
$laggif = $lagg['laggif'];
if (empty($interface_stats[$laggif])) {
legacy_interface_create($lagg['laggif']);
} else {
// Already configured, detach child interfaces before attempting to configure.
// Prevents vlans to loose parent.
if (!empty($interface_stats[$laggif]['laggport'])) {
foreach ($interface_stats[$laggif]['laggport'] as $laggport) {
mwexec("/sbin/ifconfig {$laggif} -laggport {$laggport}");
}
}
}
} else {
$laggif = legacy_interface_create('lagg');
}
/* Calculate smaller mtu and enforce it */
// determine mtu value to use, either the provided one for the lagg or smallest of it's children
$mtu = null;
foreach ($members as $member) {
$opts = legacy_interface_stats($member);
if (!empty($opts['mtu']) && ($mtu == null || $opts['mtu'] < $mtu)) {
$mtu = $opts['mtu'];
if (!empty($lagg['mtu'])) {
// mtu provided for lagg
$mtu = $lagg['mtu'];
} else {
// min() mtu of children
foreach ($members as $member) {
if (!empty($interface_stats[$member]['mtu']) && ($mtu == null || $interface_stats[$member]['mtu'] < $mtu)) {
$mtu = $interface_stats[$member]['mtu'];
}
}
}
$checklist = get_interface_list();
foreach ($members as $member) {
if (!array_key_exists($member, $checklist)) {
continue;
if (!empty($interface_stats[$member])) {
legacy_interface_mtu($member, $mtu);
configure_interface_hardware($member);
interfaces_bring_up($member);
mwexec("/sbin/ifconfig {$laggif} laggport {$member}");
}
legacy_interface_mtu($member, $mtu);
configure_interface_hardware($member);
interfaces_bring_up($member);
mwexec("/sbin/ifconfig {$laggif} laggport {$member}");
}
mwexec("/sbin/ifconfig {$laggif} laggproto " . escapeshellarg($lagg['proto']));
......@@ -1081,7 +1094,7 @@ function interface_vip_bring_down($vip)
}
}
function interface_bring_down($interface = "wan", $destroy = false, $ifacecfg = false)
function interface_bring_down($interface = "wan", $ifacecfg = false)
{
global $config;
......@@ -1263,12 +1276,6 @@ function interface_bring_down($interface = "wan", $destroy = false, $ifacecfg =
mwexec(kill_wpasupplicant($realif));
}
if ($destroy == true) {
if (preg_match("/^[a-z0-9]+^tun|^ovpn|^gif|^gre|^lagg|^bridge|vlan|_stf$/i", $realif)) {
legacy_interface_destroy($realif);
}
}
return;
}
......@@ -2510,37 +2517,6 @@ function interface_virtual_create($interface)
}
}
function interface_vlan_adapt_mtu($vlanifs, $mtu)
{
global $config;
if (!is_array($vlanifs)) {
return;
}
/* All vlans need to use the same mtu value as their parent. */
foreach ($vlanifs as $vlan) {
$assignedport = convert_real_interface_to_friendly_interface_name($vlan['vlanif']);
if (!empty($assignedport)) {
if (!empty($config['interfaces'][$assignedport]['mtu'])) {
/*
* XXX: This is really never going to happen just keep the code for safety and readbility.
* It never happens since interface_vlan_mtu_configured finds the biggest mtu on vlans.
* Also if it has a lower mtu configured just respect user choice.
*/
if (intval($config['interfaces'][$assignedport]['mtu']) > $mtu) {
legacy_interface_mtu($vlan['vlanif'], $mtu);
}
} else {
if (legacy_interface_stats($vlan['vlanif'])['mtu'] != $mtu) {
legacy_interface_mtu($vlan['vlanif'], $mtu);
}
}
} elseif (legacy_interface_stats($vlan['vlanif'])['mtu'] != $mtu) {
legacy_interface_mtu($vlan['vlanif'], $mtu);
}
}
}
function interface_configure($interface = 'wan', $reloadall = false, $linkupevent = false, $verbose = false)
{
......@@ -2694,34 +2670,27 @@ function interface_configure($interface = 'wan', $reloadall = false, $linkupeven
break;
}
}
$intf_stats = legacy_interface_stats();
if (!empty($wancfg['mtu'])) {
if (stristr($realif, "_vlan")) {
$assignedparent = convert_real_interface_to_friendly_interface_name($realhwif);
if (!empty($assignedparent) && !empty($config['interfaces'][$assignedparent]['mtu'])) {
$parentmtu = $config['interfaces'][$assignedparent]['mtu'];
} else {
$parentmtu = interface_vlan_mtu_configured($realhwif, $wancfg['mtu']);
// max mtu to parent
$mtu = $wancfg['mtu'] < $intf_stats[$realhwif]['mtu'] ? $wancfg['mtu'] : $intf_stats[$realhwif]['mtu'];
if ($mtu != $intf_stats[$realif]['mtu']) {
legacy_interface_mtu($realif, $mtu);
}
} elseif ($wancfg['mtu'] != $intf_stats['mtu']) {
legacy_interface_mtu($realhwif, $wancfg['mtu']);
}
}
if ($wancfg['mtu'] > $parentmtu) {
if (legacy_interface_stats($realhwif)['mtu'] != $wancfg['mtu']) {
legacy_interface_mtu($realhwif, $wancfg['mtu']);
}
/* All vlans need to use the same mtu value as their parent. */
interface_vlan_adapt_mtu(link_interface_to_vlans($realhwif), $wancfg['mtu']);
} else {
legacy_interface_mtu($realif, $wancfg['mtu']);
}
} else {
if ($wancfg['mtu'] != legacy_interface_stats($realhwif)['mtu']) {
legacy_interface_mtu($realhwif, $wancfg['mtu']);
// in case this interface has vlan's configured, make sure none of them has an mtu set higher than it's parent
if (!empty($config['vlans']['vlan'])) {
$intf_stats = legacy_interface_stats();
foreach ($config['vlans']['vlan'] as $vlan) {
if ($realhwif == $vlan['if'] && $intf_stats[$realhwif]['mtu'] < $intf_stats[$vlan['vlanif']]['mtu']) {
legacy_interface_mtu($vlan['vlanif'], $intf_stats[$realhwif]['mtu']);
}
/* This case is needed when the parent of vlans is being configured */
interface_vlan_adapt_mtu(link_interface_to_vlans($realif), $wancfg['mtu']);
}
/* XXX: What about gre/gif/lagg/.. ? */
}
if (does_interface_exist($wancfg['if'])) {
......@@ -4071,31 +4040,6 @@ function link_interface_to_track6($int, $action = '')
}
}
function link_interface_to_vlans($int, $action = '')
{
global $config;
if (empty($int)) {
return;
}
if (isset($config['vlans']['vlan'])) {
$ifaces = array();
foreach ($config['vlans']['vlan'] as $vlan) {
if ($int == $vlan['if']) {
if ($action == "update") {
interfaces_bring_up($int);
} elseif ($action == "") {
$ifaces[$vlan['tag']] = $vlan;
}
}
}
if (!empty($ifaces)) {
return $ifaces;
}
}
}
function link_interface_to_vips($int, $action = '')
{
global $config;
......
......@@ -211,7 +211,7 @@ function legacy_interfaces_details($intf = null)
$current_interface = null;
foreach ($ifconfig_data as $line) {
$line_parts = explode(' ', $line);
if (strpos(trim($line), 'flags=') !== false) {
if (strpos(trim($line), 'flags=') !== false && $line[0] != "\t") {
$current_interface = explode(':', $line)[0];
$result[$current_interface] = array();
$result[$current_interface]["capabilities"] = array();
......@@ -219,6 +219,9 @@ function legacy_interfaces_details($intf = null)
$result[$current_interface]["macaddr"] = "00:00:00:00:00:00";
$result[$current_interface]["ipv4"] = array();
$result[$current_interface]["ipv6"] = array();
if (preg_match("/ mtu ([0-9]*).*$/", $line, $matches)) {
$result[$current_interface]["mtu"] = $matches[1];
}
} elseif (empty($current_interface)) {
// skip parsing, no interface found (yet)
continue;
......@@ -284,7 +287,7 @@ function legacy_interfaces_details($intf = null)
if (empty($result[$current_interface]['laggport'])) {
$result[$current_interface]['laggport'] = array();
}
$result[$current_interface]['laggport'][] = $matches[1];
$result[$current_interface]['laggport'][] = explode(' ', trim($matches[1]))[0];
}
}
......
......@@ -514,10 +514,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$toapplylist = unserialize(file_get_contents('/tmp/.interfaces.apply'));
foreach ($toapplylist as $ifapply => $ifcfgo) {
if (isset($config['interfaces'][$ifapply]['enable'])) {
interface_bring_down($ifapply, false, $ifcfgo);
interface_bring_down($ifapply, $ifcfgo);
interface_configure($ifapply, true);
} else {
interface_bring_down($ifapply, true, $ifcfgo);
interface_bring_down($ifapply, $ifcfgo);
}
}
}
......@@ -814,14 +814,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
}
if (stristr($a_interfaces[$if]['if'], "_vlan")) {
$realhwif_array = get_parent_interface($a_interfaces[$if]['if']);
// Need code to handle MLPPP if we ever use $realhwif for MLPPP handling
$parent_realhwif = $realhwif_array[0];
$parent_if = convert_real_interface_to_friendly_interface_name($parent_realhwif);
if (!empty($parent_if) && !empty($config['interfaces'][$parent_if]['mtu'])) {
if ($pconfig['mtu'] > intval($config['interfaces'][$parent_if]['mtu'])) {
$input_errors[] = gettext("MTU of a vlan should not be bigger than parent interface.");
}
$parentif = get_parent_interface($a_interfaces[$if]['if'])[0];
$intf_details = legacy_interface_details($parentif);
if ($intf_details['mtu'] < $pconfig['mtu']) {
$input_errors[] = gettext("MTU of a vlan should not be bigger than parent interface.");
}
} else {
foreach ($config['interfaces'] as $idx => $ifdata) {
......
......@@ -35,6 +35,20 @@ require_once("system.inc");
require_once("interfaces.inc");
require_once("services.inc");
function link_interface_to_vlans($int)
{
global $config;
if (isset($config['vlans']['vlan'])) {
foreach ($config['vlans']['vlan'] as $vlan) {
if ($int == $vlan['if']) {
interfaces_bring_up($int);
}
}
}
}
function list_interfaces() {
global $config;
$interfaces = array();
......@@ -170,7 +184,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// no validation errors, delete entry
unset($config['interfaces'][$id]['enable']);
$realid = get_real_interface($id);
interface_bring_down($id, true); /* down the interface */
interface_bring_down($id); /* down the interface */
unset($config['interfaces'][$id]); /* delete the specified OPTn or LAN*/
......@@ -202,7 +216,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if(!empty($config['interfaces']['lan']) && !empty($config['dhcpd']['wan']) && !empty($config['dhcpd']['wan']) ) {
unset($config['dhcpd']['wan']);
}
link_interface_to_vlans($realid, "update");
link_interface_to_vlans($realid);
header(url_safe('Location: /interfaces_assign.php'));
exit;
}
......@@ -264,7 +278,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!is_array($ifport) && ($ifname == 'lan' || $ifname == 'wan' || substr($ifname, 0, 3) == 'opt')) {
$reloadif = false;
if (!empty($config['interfaces'][$ifname]['if']) && $config['interfaces'][$ifname]['if'] <> $ifport) {
interface_bring_down($ifname, true);
interface_bring_down($ifname);
/* Mark this to be reconfigured in any case. */
$reloadif = true;
}
......
......@@ -93,6 +93,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$pconfig['proto'] = isset($a_laggs[$id]['proto']) ? $a_laggs[$id]['proto'] : null;
$pconfig['descr'] = isset($a_laggs[$id]['descr']) ? $a_laggs[$id]['descr'] : null;
$pconfig['lacp_fast_timeout'] = !empty($a_laggs[$id]['lacp_fast_timeout']);
$pconfig['mtu'] = isset($a_laggs[$id]['mtu']) ? $a_laggs[$id]['mtu'] : null;
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
// validate and save form data
if (!empty($a_laggs[$_POST['id']])) {
......@@ -118,6 +119,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (!in_array($pconfig['proto'], $laggprotos)) {
$input_errors[] = gettext("Protocol supplied is invalid");
}
if (!empty($pconfig['mtu']) && ($pconfig['mtu'] < 576 || $pconfig['mtu'] > 9000)) {
$input_errors[] = gettext("The MTU must be greater than 576 bytes and less than 9000.");
}
if (count($input_errors) == 0) {
$lagg = array();
......@@ -125,6 +129,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$lagg['descr'] = $pconfig['descr'];
$lagg['laggif'] = $pconfig['laggif'];
$lagg['proto'] = $pconfig['proto'];
$lagg['mtu'] = $pconfig['mtu'];
$lagg['lacp_fast_timeout'] = !empty($pconfig['lacp_fast_timeout']);
if (isset($id)) {
$lagg['laggif'] = $a_laggs[$id]['laggif'];
......@@ -282,6 +287,15 @@ legacy_html_escape_form_data($pconfig);
</div>
</td>
</tr>
<tr>
<td><a id="help_for_mtu" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("MTU"); ?></td>
<td>
<input name="mtu" id="mtu" type="text" value="<?=$pconfig['mtu'];?>" />
<div class="hidden" for="help_for_mtu">
<?= gettext("If you leave this field blank, the smallest mtu of this laggs children will be used.");?>
</div>
</td>
</tr>
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment