From 8bd840820e37fedadb56eba97f407a0f7ba1f0b2 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Sun, 14 Feb 2016 15:21:05 -0600 Subject: Add support for multiple span ports on bridge. While here, fix and improve the error detection for the selected ports. Inspired by pull request #2613 from heper/patch-1 Ticket #5871 --- src/etc/inc/interfaces.inc | 9 +- src/usr/local/www/interfaces_bridge_edit.php | 148 ++++++++++++++++----------- 2 files changed, 96 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index fb9a766..800ff42 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -617,9 +617,12 @@ function interface_bridge_configure(&$bridge, $checkmember = 0) { if ($bridge['timeout'] <> "") { mwexec("/sbin/ifconfig {$bridgeif} timeout " . escapeshellarg($bridge['timeout'])); } - if ($bridge['span'] <> "") { - $realif = get_real_interface($bridge['span']); - mwexec("/sbin/ifconfig {$bridgeif} span {$realif}"); + if (!empty($bridge['span'])) { + $spanifs = explode(",", $bridge['span']); + foreach ($spanifs as $spanif) { + $realif = get_real_interface($spanif); + mwexec("/sbin/ifconfig {$bridgeif} span {$realif}"); + } } if (!empty($bridge['edge'])) { $edgeifs = explode(',', $bridge['edge']); diff --git a/src/usr/local/www/interfaces_bridge_edit.php b/src/usr/local/www/interfaces_bridge_edit.php index af49aac..2fa5573 100644 --- a/src/usr/local/www/interfaces_bridge_edit.php +++ b/src/usr/local/www/interfaces_bridge_edit.php @@ -90,15 +90,6 @@ if (isset($id) && $a_bridges[$id]) { $pconfig['members'] = $a_bridges[$id]['members']; $pconfig['maxaddr'] = $a_bridges[$id]['maxaddr']; $pconfig['timeout'] = $a_bridges[$id]['timeout']; - if ($a_bridges[$id]['static']) { - $pconfig['static'] = $a_bridges[$id]['static']; - } - if ($a_bridges[$id]['private']) { - $pconfig['private'] = $a_bridges[$id]['private']; - } - if (isset($a_bridges[$id]['stp'])) { - $pconfig['stp'] = $a_bridges[$id]['stp']; - } $pconfig['maxage'] = $a_bridges[$id]['maxage']; $pconfig['fwdelay'] = $a_bridges[$id]['fwdelay']; $pconfig['hellotime'] = $a_bridges[$id]['hellotime']; @@ -132,7 +123,18 @@ if (isset($id) && $a_bridges[$id]) { $pconfig['ifpathcost'] = $ifpathcost; } - $pconfig['span'] = $a_bridges[$id]['span']; + if (isset($a_bridges[$id]['static'])) { + $pconfig['static'] = $a_bridges[$id]['static']; + } + if (isset($a_bridges[$id]['private'])) { + $pconfig['private'] = $a_bridges[$id]['private']; + } + if (isset($a_bridges[$id]['stp'])) { + $pconfig['stp'] = $a_bridges[$id]['stp']; + } + if (isset($a_bridges[$id]['span'])) { + $pconfig['span'] = $a_bridges[$id]['span']; + } if (isset($a_bridges[$id]['edge'])) { $pconfig['edge'] = $a_bridges[$id]['edge']; } @@ -197,6 +199,65 @@ if ($_POST) { $input_errors[] = gettext("You must select at least one member interface for a bridge."); } + if (is_array($_POST['static'])) { + foreach ($_POST['static'] as $ifstatic) { + if (is_array($_POST['members']) && !in_array($ifstatic, $_POST['members'])) { + $input_errors[] = gettext("Sticky interface ($ifstatic) is not part of the bridge. Remove the sticky interface to continue."); + } + } + $pconfig['static'] = implode(',', $_POST['static']); + } + if (is_array($_POST['private'])) { + foreach ($_POST['private'] as $ifprivate) { + if (is_array($_POST['members']) && !in_array($ifprivate, $_POST['members'])) { + $input_errors[] = gettext("Private interface ($ifprivate) is not part of the bridge. Remove the private interface to continue."); + } + } + $pconfig['private'] = implode(',', $_POST['private']); + } + if (is_array($_POST['stp'])) { + foreach ($_POST['stp'] as $ifstp) { + if (is_array($_POST['members']) && !in_array($ifstp, $_POST['members'])) { + $input_errors[] = gettext("STP interface ($ifstp) is not part of the bridge. Remove the STP interface to continue."); + } + } + $pconfig['stp'] = implode(',', $_POST['stp']); + } + if (is_array($_POST['span'])) { + $pconfig['span'] = implode(',', $_POST['span']); + } + if (is_array($_POST['edge'])) { + foreach ($_POST['edge'] as $ifedge) { + if (is_array($_POST['members']) && !in_array($ifedge, $_POST['members'])) { + $input_errors[] = gettext("Edge interface ($ifedge) is not part of the bridge. Remove the edge interface to continue."); + } + } + $pconfig['edge'] = implode(',', $_POST['edge']); + } + if (is_array($_POST['autoedge'])) { + foreach ($_POST['autoedge'] as $ifautoedge) { + if (is_array($_POST['members']) && !in_array($ifautoedge, $_POST['members'])) { + $input_errors[] = gettext("Auto Edge interface ($ifautoedge) is not part of the bridge. Remove the auto edge interface to continue."); + } + } + $pconfig['autoedge'] = implode(',', $_POST['autoedge']); + } + if (is_array($_POST['ptp'])) { + foreach ($_POST['ptp'] as $ifptp) { + if (is_array($_POST['members']) && !in_array($ifptp, $_POST['members'])) { + $input_errors[] = gettext("PTP interface ($ifptp) is not part of the bridge. Remove the PTP interface to continue."); + } + } + $pconfig['ptp'] = implode(',', $_POST['ptp']); + } + if (is_array($_POST['autoptp'])) { + foreach ($_POST['autoptp'] as $ifautoptp) { + if (is_array($_POST['members']) && !in_array($ifautoptp, $_POST['members'])) { + $input_errors[] = gettext("Auto PTP interface ($ifautoptp) is not part of the bridge. Remove the auto PTP interface to continue."); + } + } + $pconfig['autoptp'] = implode(',', $_POST['autoptp']); + } if (is_array($_POST['members'])) { foreach ($_POST['members'] as $ifmembers) { if (empty($config['interfaces'][$ifmembers])) { @@ -206,8 +267,8 @@ if ($_POST) { $config['interfaces'][$ifmembers]['wireless']['mode'] != "hostap") { $input_errors[] = gettext("Bridging a wireless interface is only possible in hostap mode."); } - if ($_POST['span'] != "none" && $_POST['span'] == $ifmembers) { - $input_errors[] = gettext("Span interface cannot be part of the bridge. Remove the span interface from bridge members to continue."); + if (is_array($_POST['span']) && in_array($ifmembers, $_POST['span'])) { + $input_errors[] = gettext("Span interface ($ifmembers) cannot be part of the bridge. Remove the span interface from bridge members to continue."); } foreach ($a_bridges as $a_bridge) { if ($_POST['bridgeif'] === $a_bridge['bridgeif']) { @@ -231,15 +292,6 @@ if ($_POST) { $bridge['descr'] = $_POST['descr']; $bridge['maxaddr'] = $_POST['maxaddr']; $bridge['timeout'] = $_POST['timeout']; - if ($_POST['static']) { - $bridge['static'] = implode(',', $_POST['static']); - } - if ($_POST['private']) { - $bridge['private'] = implode(',', $_POST['private']); - } - if (isset($_POST['stp'])) { - $bridge['stp'] = implode(',', $_POST['stp']); - } $bridge['maxage'] = $_POST['maxage']; $bridge['fwdelay'] = $_POST['fwdelay']; $bridge['hellotime'] = $_POST['hellotime']; @@ -269,10 +321,17 @@ if ($_POST) { $bridge['ifpriority'] = $ifpriority; $bridge['ifpathcost'] = $ifpathcost; - if ($_POST['span'] != "none") { - $bridge['span'] = $_POST['span']; - } else { - unset($bridge['span']); + if (isset($_POST['static'])) { + $bridge['static'] = implode(',', $_POST['static']); + } + if (isset($_POST['private'])) { + $bridge['private'] = implode(',', $_POST['private']); + } + if (isset($_POST['stp'])) { + $bridge['stp'] = implode(',', $_POST['stp']); + } + if (isset($_POST['span'])) { + $bridge['span'] = implode(',', $_POST['span']); } if (isset($_POST['edge'])) { $bridge['edge'] = implode(',', $_POST['edge']); @@ -287,7 +346,6 @@ if ($_POST) { $bridge['autoptp'] = implode(',', $_POST['autoptp']); } - $bridge['bridgeif'] = $_POST['bridgeif']; interface_bridge_configure($bridge); if ($bridge['bridgeif'] == "" || !stristr($bridge['bridgeif'], "bridge")) { @@ -312,35 +370,6 @@ if ($_POST) { } } -function build_spanport_list() { - global $ifacelist; - - $splist = array('none' => gettext('None')); - - foreach ($ifacelist as $ifn => $ifdescr) { - $splist[$ifn] = $ifdescr; - } - - return($splist); -} - -function build_member_list() { - global $pconfig, $ifacelist; - - $memberlist = array('list' => array(), 'selected' => array()); - - $members_array = explode(',', $pconfig['members']); - foreach ($ifacelist as $ifn => $ifinfo) { - $memberlist['list'][$ifn] = $ifinfo; - - if (in_array($ifn, $members_array)) { - array_push($memberlist['selected'], $ifn); - } - } - unset($members_array); - return($memberlist); -} - function build_port_list($selecton) { global $ifacelist; @@ -369,7 +398,7 @@ $form = new Form(); $section = new Form_Section('Bridge Configuration'); -$memberslist = build_member_list(); +$memberslist = build_port_list($pconfig['members']); $section->addInput(new Form_Select( 'members', @@ -418,11 +447,14 @@ $section->addInput(new Form_Input( $pconfig['timeout'] ))->setHelp('Set the timeout of address cache entries to this number of seconds. If seconds is zero, then address cache entries will not be expired. The default is 240 seconds'); +$spanlist = build_port_list($pconfig['span']); + $section->addInput(new Form_Select( 'span', 'Span Port', - $pconfig['span'], - build_spanport_list() + $spanlist['selected'], + $spanlist['list'], + true ))->setHelp('Add the interface named by interface as a span port on the bridge. Span ports transmit a copy of every frame received by the bridge.' . 'This is most useful for snooping a bridged network passively on another host connected to one of the span ports of the bridge.
' . '%sThe span interface cannot be part of the bridge member interfaces.%s', ['', '']); -- cgit v1.1