From 57077b83f53c2a9ad808306aeeeab4f52b2bf0db Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Mon, 17 Jul 2023 21:34:31 +0200 Subject: [PATCH] Interfaces: LAGG: migrate to MVC closes https://github.com/opnsense/core/issues/6384 Migrate ui to MVC, wrap model around existing configuration area to remain backward compatibility. To avoid laggs configured via console not being reachable from the gui, add a uuid to it. --- plist | 10 +- src/etc/inc/console.inc | 1 + .../Interfaces/Api/LaggSettingsController.php | 173 ++++++++ .../OPNsense/Interfaces/LaggController.php | 43 ++ .../OPNsense/Interfaces/forms/dialogLagg.xml | 60 +++ .../mvc/app/models/OPNsense/Core/ACL/ACL.xml | 12 - .../app/models/OPNsense/Core/Menu/Menu.xml | 3 - .../models/OPNsense/Interfaces/ACL/ACL.xml | 7 + .../FieldTypes/LaggInterfaceField.php | 61 +++ .../app/models/OPNsense/Interfaces/Lagg.php | 86 ++++ .../app/models/OPNsense/Interfaces/Lagg.xml | 71 ++++ .../models/OPNsense/Interfaces/Menu/Menu.xml | 1 + .../app/views/OPNsense/Interface/lagg.volt | 69 +++ .../scripts/interfaces/list_interfaces.php | 40 +- .../scripts/interfaces/reconfigure_laggs.php | 77 ++++ .../conf/actions.d/actions_interface.conf | 5 + src/www/interfaces_lagg.php | 142 ------- src/www/interfaces_lagg_edit.php | 393 ------------------ 18 files changed, 701 insertions(+), 553 deletions(-) create mode 100644 src/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/LaggSettingsController.php create mode 100644 src/opnsense/mvc/app/controllers/OPNsense/Interfaces/LaggController.php create mode 100644 src/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogLagg.xml create mode 100644 src/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/LaggInterfaceField.php create mode 100644 src/opnsense/mvc/app/models/OPNsense/Interfaces/Lagg.php create mode 100644 src/opnsense/mvc/app/models/OPNsense/Interfaces/Lagg.xml create mode 100644 src/opnsense/mvc/app/views/OPNsense/Interface/lagg.volt create mode 100755 src/opnsense/scripts/interfaces/reconfigure_laggs.php delete mode 100644 src/www/interfaces_lagg.php delete mode 100644 src/www/interfaces_lagg_edit.php diff --git a/plist b/plist index fb7d9fae4..c3a1ff718 100644 --- a/plist +++ b/plist @@ -378,14 +378,17 @@ /usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/forms/dialogRemote.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/forms/dialogSPD.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/forms/dialogVTI.xml +/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/LaggSettingsController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/LoopbackSettingsController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/VipSettingsController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/VlanSettingsController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/VxlanSettingsController.php +/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/LaggController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/LoopbackController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/VipController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/VlanController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/VxlanController.php +/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogLagg.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogLoopback.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogVip.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogVlan.xml @@ -657,9 +660,12 @@ /usr/local/opnsense/mvc/app/models/OPNsense/IPsec/Swanctl.php /usr/local/opnsense/mvc/app/models/OPNsense/IPsec/Swanctl.xml /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/ACL/ACL.xml +/usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/LaggInterfaceField.php /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/VipInterfaceField.php /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/VipNetworkField.php /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/VlanInterfaceField.php +/usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/Lagg.php +/usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/Lagg.xml /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/Loopback.php /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/Loopback.xml /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/Menu/Menu.xml @@ -764,6 +770,7 @@ /usr/local/opnsense/mvc/app/views/OPNsense/IPsec/spd.volt /usr/local/opnsense/mvc/app/views/OPNsense/IPsec/tunnels.volt /usr/local/opnsense/mvc/app/views/OPNsense/IPsec/vti.volt +/usr/local/opnsense/mvc/app/views/OPNsense/Interface/lagg.volt /usr/local/opnsense/mvc/app/views/OPNsense/Interface/loopback.volt /usr/local/opnsense/mvc/app/views/OPNsense/Interface/vip.volt /usr/local/opnsense/mvc/app/views/OPNsense/Interface/vlan.volt @@ -959,6 +966,7 @@ /usr/local/opnsense/scripts/interfaces/ppp-linkup.sh /usr/local/opnsense/scripts/interfaces/ppp-rename.sh /usr/local/opnsense/scripts/interfaces/ppp-uptime.sh +/usr/local/opnsense/scripts/interfaces/reconfigure_laggs.php /usr/local/opnsense/scripts/interfaces/reconfigure_vips.php /usr/local/opnsense/scripts/interfaces/reconfigure_vlans.php /usr/local/opnsense/scripts/interfaces/rtsold_resolvconf.sh @@ -2002,8 +2010,6 @@ /usr/local/www/interfaces_gif_edit.php /usr/local/www/interfaces_gre.php /usr/local/www/interfaces_gre_edit.php -/usr/local/www/interfaces_lagg.php -/usr/local/www/interfaces_lagg_edit.php /usr/local/www/interfaces_ppps.php /usr/local/www/interfaces_ppps_edit.php /usr/local/www/interfaces_wireless.php diff --git a/src/etc/inc/console.inc b/src/etc/inc/console.inc index e9020c724..f6af760fc 100644 --- a/src/etc/inc/console.inc +++ b/src/etc/inc/console.inc @@ -538,6 +538,7 @@ EOD; while (1) { $lagg = []; + $lagg['@attributes'] = ['uuid' => generate_uuid()]; echo "\nLAGG-capable interfaces:\n\n"; diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/LaggSettingsController.php b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/LaggSettingsController.php new file mode 100644 index 000000000..55780eeba --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/LaggSettingsController.php @@ -0,0 +1,173 @@ +searchBase("lagg", ['laggif', 'descr', 'members', 'proto'], "descr"); + } + + /** + * Update lagg with given properties + * @param string $uuid internal id + * @return array save result + validation output + */ + public function setItemAction($uuid) + { + $node = $this->getModel()->getNodeByReference('lagg.' . $uuid); + $overlay = null; + if (!empty($node)) { + // not allowed to change lagg interface name + $overlay['laggif'] = (string)$node->laggif; + } + + $result = $this->setBase("lagg", "lagg", $uuid, $overlay); + if ($result['result'] != 'failed') { + $this->stashUpdate($overlay !== null ? $overlay['laggif'] : $this->request->get('lagg')['laggif']); + } + return $result; + } + + /** + * Add new lagg and set with attributes from post + * @return array save result + validation output + */ + public function addItemAction() + { + Config::getInstance()->lock(); + $overlay = []; + $ifnames = []; + foreach ($this->getModel()->lagg->iterateItems() as $node) { + $ifnames[] = (string)$node->laggif; + } + for ($i=0; true ; ++$i) { + $laggif = sprintf('lagg%d', $i); + if (!in_array($laggif, $ifnames)) { + $overlay['laggif'] = $laggif; + break; + } + } + $result = $this->addBase("lagg", "lagg", $overlay); + if ($result['result'] != 'failed') { + $this->stashUpdate($overlay['laggif']); + } + return $result; + } + + /** + * Retrieve lagg settings or return defaults for new one + * @param $uuid item unique id + * @return array lagg content + */ + public function getItemAction($uuid = null) + { + return $this->getBase("lagg", "lagg", $uuid); + } + + /** + * Delete lagg by uuid + * @param string $uuid internal id + * @return array save status + */ + public function delItemAction($uuid) + { + Config::getInstance()->lock(); + $node = $this->getModel()->getNodeByReference('lagg.' . $uuid); + $laggif = $node != null ? (string)$node->laggif : null; + $uses = []; + $cfg = Config::getInstance()->object(); + foreach ($cfg->interfaces->children() as $key => $value) { + if ((string)$value->if == $laggif) { + $uses['interfaces.'.$key] = !empty($value->descr) ? (string)$value->descr : $key; + } + } + if (isset($cfg->vlans) && isset($cfg->vlans->vlan)) { + foreach ($cfg->vlans->children() as $vlan) { + if ((string)$vlan->if == $laggif) { + $uses[(string)$vlan->vlanif] = !empty($vlan->descr) ? (string)$vlan->descr : $key; + } + } + } + if (!empty($uses)) { + $message = ""; + foreach ($uses as $key => $value) { + $message .= htmlspecialchars(sprintf("\n[%s] %s", $key, $value), ENT_NOQUOTES | ENT_HTML401); + } + $message = sprintf(gettext("Cannot delete lagg. Currently in use by %s"), $message); + throw new \OPNsense\Base\UserException($message, gettext("Lagg in use")); + } + $result = $this->delBase("lagg", $uuid); + if ($result['result'] != 'failed' && !empty($laggif)) { + $this->stashUpdate($laggif); + } + return $result; + } + + /** + * reconfigure laggs + */ + public function reconfigureAction() + { + if ($this->request->isPost()) { + (new Backend())->configdRun("interface lagg configure"); + return array("status" => "ok"); + } else { + return array("status" => "failed"); + } + } +} diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/LaggController.php b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/LaggController.php new file mode 100644 index 000000000..70b9f44cc --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/LaggController.php @@ -0,0 +1,43 @@ +view->formDialogEdit = $this->getForm("dialogLagg"); + $this->view->pick('OPNsense/Interface/lagg'); + } +} diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogLagg.xml b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogLagg.xml new file mode 100644 index 000000000..141f28f99 --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogLagg.xml @@ -0,0 +1,60 @@ +
+ + lagg.laggif + + info + + + + lagg.members + + select_multiple + Choose the members that will be used for the link aggregation + + + lagg.proto + + dropdown + The protocol to use, please refer to the documentation for a detailed explanation of the various types available + + + lagg.lacp_fast_timeout + + checkbox + + Enable lacp fast-timeout on the interface. + + + lagg.use_flowid + + dropdown + + Use the RSS hash from the network card if available, otherwise a hash is locally calculated. The default depends on the system tunable in net.link.lagg.default_use_flowid. + + + lagg.lagghash + + select_multiple + + Set the packet layers to hash for aggregation protocols which load balance. + + + lagg.lacp_strict + + dropdown + + Enable lacp strict compliance on the interface. The default depends on the system tunable in net.link.lagg.lacp.default_strict_mode. + + + lagg.mtu + + text + If you leave this field blank, the smallest mtu of this laggs children will be used. + + + lagg.descr + + text + You may enter a description here for your reference (not parsed). + +
diff --git a/src/opnsense/mvc/app/models/OPNsense/Core/ACL/ACL.xml b/src/opnsense/mvc/app/models/OPNsense/Core/ACL/ACL.xml index ab562fd5d..8b0c7abcb 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Core/ACL/ACL.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Core/ACL/ACL.xml @@ -389,18 +389,6 @@ api/firewall/group/* - - Interfaces: LAGG: Edit - - interfaces_lagg_edit.php* - - - - Interfaces: LAGG - - interfaces_lagg.php* - - Interfaces: PPPs diff --git a/src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml b/src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml index 50eda25f9..578a1920f 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml @@ -127,9 +127,6 @@ - - - diff --git a/src/opnsense/mvc/app/models/OPNsense/Interfaces/ACL/ACL.xml b/src/opnsense/mvc/app/models/OPNsense/Interfaces/ACL/ACL.xml index 4940e5f4a..6f5038da3 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Interfaces/ACL/ACL.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Interfaces/ACL/ACL.xml @@ -36,4 +36,11 @@ api/interfaces/vlan_settings/* + + Interfaces: LAGG: Edit + + ui/interfaces/lagg + api/interfaces/lagg_settings/* + + diff --git a/src/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/LaggInterfaceField.php b/src/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/LaggInterfaceField.php new file mode 100644 index 000000000..6448c5a04 --- /dev/null +++ b/src/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/LaggInterfaceField.php @@ -0,0 +1,61 @@ +object()->interfaces->children() as $ifname => $node) { + if (!empty((string)$node->if)) { + $skip[] = (string)$node->if; + } + } + $itfs = json_decode((new Backend())->configdRun("interface list ifconfig") ?? '', true) ?? []; + foreach ($itfs as $ifname => $ifinfo) { + if (in_array($ifname, $skip) || !$ifinfo['is_physical']) { + continue; + } + self::$parent_interfaces[$ifname] = sprintf("%s (%s)", $ifname, $ifinfo['macaddr'] ?? ''); + } + } + $this->internalOptionList = self::$parent_interfaces; + return parent::actionPostLoadingEvent(); + } +} diff --git a/src/opnsense/mvc/app/models/OPNsense/Interfaces/Lagg.php b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Lagg.php new file mode 100644 index 000000000..43c069359 --- /dev/null +++ b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Lagg.php @@ -0,0 +1,86 @@ +getFlatNodes() as $key => $node) { + if ($node->getInternalXMLTagName() == 'members') { + foreach (explode(',', (string)$node) as $intf) { + if (!isset($members[$intf])) { + $members[$intf] = []; + } + $members[$intf][] = $node->getParentNode()->getAttributes()['uuid']; + } + } + } + foreach ($this->getFlatNodes() as $key => $node) { + if ($validateFullModel || $node->isFieldChanged()) { + if ($node->getParentNode()->getInternalXMLTagName() === 'lagg') { + $uuid = $node->getParentNode()->getAttributes()['uuid']; + if ($node->getInternalXMLTagName() == 'members') { + $tmp = []; + foreach (explode(',', (string)$node) as $intf) { + if (!empty($members[$intf]) && count($members[$intf]) > 1) { + $tmp[] = $intf; + } + } + if (!empty($tmp)) { + $messages->appendMessage( + new Message( + sprintf(gettext('Members %s are already used in other laggs.'), implode(',', $tmp)), + $key + ) + ); + } + } + } + } + } + return $messages; + } +} diff --git a/src/opnsense/mvc/app/models/OPNsense/Interfaces/Lagg.xml b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Lagg.xml new file mode 100644 index 000000000..1e5685749 --- /dev/null +++ b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Lagg.xml @@ -0,0 +1,71 @@ + + /laggs + 1.0.0 + Lagg interfaces + + + + Y + + + Lagg already exists! + UniqueConstraint + + + /^lagg(\d)*$/ + + + Y + Y + At least one valid member is required + + + Y + lacp + + None + lacp + failover + fec + loadbalance + roundrobin + + + + 0 + Y + + + + Default + Yes + No + + + + Y + + L2: src/dst MAC address and optional VLAN number. + L3: src/dst address for IPv4 or IPv6. + L4: src/dst port for TCP/UDP/SCTP. + + + + + Default + Yes + No + + + + N + 576 + 65535 + + + /^([\t\n\v\f\r 0-9a-zA-Z.\-,_\x{00A0}-\x{FFFF}]){0,255}$/u + Description should be a string between 1 and 255 characters + + + + diff --git a/src/opnsense/mvc/app/models/OPNsense/Interfaces/Menu/Menu.xml b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Menu/Menu.xml index 1047c49d7..9aac3118a 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Interfaces/Menu/Menu.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Menu/Menu.xml @@ -8,6 +8,7 @@ + diff --git a/src/opnsense/mvc/app/views/OPNsense/Interface/lagg.volt b/src/opnsense/mvc/app/views/OPNsense/Interface/lagg.volt new file mode 100644 index 000000000..f272dd076 --- /dev/null +++ b/src/opnsense/mvc/app/views/OPNsense/Interface/lagg.volt @@ -0,0 +1,69 @@ + +
+ + + + + + + + + + + + + + + + + + + +
{{ lang._('ID') }}{{ lang._('Device') }}{{ lang._('Members') }}{{ lang._('Protocol') }}{{ lang._('Description') }}{{ lang._('Commands') }}
+ + +
+
+ +
+ +

+
+
+ + +{{ partial("layout_partials/base_dialog",['fields':formDialogEdit,'id':'DialogEdit','label':lang._('Edit Lagg')])}} diff --git a/src/opnsense/scripts/interfaces/list_interfaces.php b/src/opnsense/scripts/interfaces/list_interfaces.php index d39ec3924..9f823f893 100755 --- a/src/opnsense/scripts/interfaces/list_interfaces.php +++ b/src/opnsense/scripts/interfaces/list_interfaces.php @@ -28,5 +28,43 @@ */ require_once("interfaces.inc"); +require_once("interfaces.lib.inc"); -echo json_encode(legacy_interfaces_details()); +$vfaces = [ + '_stf', + '_vlan', + '_wlan', + 'bridge', + 'carp', + 'enc', + 'gif', + 'gre', + 'ipfw', /* ipfw logging device, not enabled by default */ + 'ipsec', + 'l2tp', + 'lagg', + 'lo', + 'ng', + 'ovpnc', + 'ovpns', + 'pflog', + 'pfsync', + 'plip', + 'ppp', + 'pppoe', + 'pptp', + 'qinq', + 'tap', + 'tun', + 'vlan', + 'vxlan', +]; + +$response = legacy_interfaces_details(); + +foreach ($response as $ifname => &$intf) { + $tmp_ifnames = preg_split('/\d+/', $ifname); + $intf['is_physical'] = !count(array_intersect($tmp_ifnames, $vfaces)); +} + +echo json_encode($response); diff --git a/src/opnsense/scripts/interfaces/reconfigure_laggs.php b/src/opnsense/scripts/interfaces/reconfigure_laggs.php new file mode 100755 index 000000000..85afc8592 --- /dev/null +++ b/src/opnsense/scripts/interfaces/reconfigure_laggs.php @@ -0,0 +1,77 @@ +#!/usr/local/bin/php + 0) { + $handle = fopen($vfilename, 'r+'); + if (flock($handle, LOCK_EX)) { + fseek($handle, 0); + foreach (explode("\n", fread($handle, filesize($vfilename))) as $line) { + if (!isset($laggs_todo[$line]) && trim($line) != '') { + $laggs_todo[$line] = []; + } + } + fseek($handle, 0); + ftruncate($handle, 0); + flock($handle, LOCK_UN); + } +} + +/* collect changed laggs to reconfigure */ +$lagg_configure = []; +foreach ((new OPNsense\Interfaces\Lagg())->lagg->iterateItems() as $item) { + $lagg = []; + foreach ($item->iterateItems() as $node) { + $lagg[$node->getInternalXMLTagName()] = (string)$node; + } + if (isset($laggs_todo[$lagg['laggif']])) { + $lagg_configure[] = $lagg; + unset($laggs_todo[$lagg['laggif']]); + } +} + +/* remove non existing interfaces */ +foreach (array_keys($laggs_todo) as $laggif) { + legacy_interface_destroy($laggif); +} + +/* + reconfigure still existing laggs, + removal should happen first as it may free parent interfaces. +*/ +foreach ($lagg_configure as $lagg) { + _interfaces_lagg_configure($lagg); +} \ No newline at end of file diff --git a/src/opnsense/service/conf/actions.d/actions_interface.conf b/src/opnsense/service/conf/actions.d/actions_interface.conf index 125127b27..b992dfcad 100644 --- a/src/opnsense/service/conf/actions.d/actions_interface.conf +++ b/src/opnsense/service/conf/actions.d/actions_interface.conf @@ -145,6 +145,11 @@ command: /usr/local/opnsense/scripts/interfaces/reconfigure_vlans.php message: Reconfiguring vlan type: script +[lagg.configure] +command: /usr/local/opnsense/scripts/interfaces/reconfigure_laggs.php +message: Reconfiguring laggs +type: script + [loopback.configure] command: /usr/local/sbin/pluginctl -c loopback message: Reconfiguring loopbacks diff --git a/src/www/interfaces_lagg.php b/src/www/interfaces_lagg.php deleted file mode 100644 index d66bdc85f..000000000 --- a/src/www/interfaces_lagg.php +++ /dev/null @@ -1,142 +0,0 @@ - - - - -
-
-
- 0) print_input_errors($input_errors); ?> -
-
-
- - -
- - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - -
-
-
-
-
-
-
-
- diff --git a/src/www/interfaces_lagg_edit.php b/src/www/interfaces_lagg_edit.php deleted file mode 100644 index 8886db94b..000000000 --- a/src/www/interfaces_lagg_edit.php +++ /dev/null @@ -1,393 +0,0 @@ - false])) as $intf) { - $configured_interfaces[] = get_real_interface($intf); - } - // lagg members from other lagg interfaces - $lagg_member_interfaces = array(); - foreach ($config['laggs']['lagg'] as $lagg_idx => $lagg) { - if ($lagg_idx == $selected_id) { - continue; - } - foreach (explode(",", $lagg['members']) as $lagg_member) { - $lagg_member_interfaces[] = get_real_interface($lagg_member); - } - } - - $interfaces = array(); - foreach (get_interface_list() as $intf => $intf_info) { - if (in_array($intf, $lagg_member_interfaces)) { - // skip members of other lagg interfaces - continue; - } elseif (in_array($intf, $configured_interfaces)) { - // skip configured interfaces - continue; - } - $interfaces[$intf] = $intf_info; - } - - return $interfaces; -} - -$laggprotos = array("none", "lacp", "failover", "fec", "loadbalance", "roundrobin"); - -$a_laggs = &config_read_array('laggs', 'lagg'); - - -if ($_SERVER['REQUEST_METHOD'] === 'GET') { - // read form data - if (!empty($a_laggs[$_GET['id']])) { - $id = $_GET['id']; - } - $pconfig = array(); - $pconfig['laggif'] = isset($a_laggs[$id]['laggif']) ? $a_laggs[$id]['laggif'] : null; - $pconfig['members'] = isset($a_laggs[$id]['members']) ? explode(",", $a_laggs[$id]['members']) : array(); - $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['use_flowid'] = isset($a_laggs[$id]['use_flowid']) ? $a_laggs[$id]['use_flowid'] : null; - $pconfig['lagghash'] = isset($a_laggs[$id]['lagghash']) ? explode(',', $a_laggs[$id]['lagghash']) : []; - $pconfig['lacp_strict'] = isset($a_laggs[$id]['lacp_strict']) ? $a_laggs[$id]['lacp_strict'] : null; - $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']])) { - $id = $_POST['id']; - } - $input_errors = array(); - $pconfig = $_POST; - - /* input validation */ - $reqdfields = explode(" ", "members proto"); - $reqdfieldsn = array(gettext("Member interfaces"), gettext("Lagg protocol")); - - do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors); - - if (isset($pconfig['members'])) { - foreach ($pconfig['members'] as $member) { - if (!does_interface_exist($member)) { - $input_errors[] = sprintf(gettext('Interface \'%s\' supplied as member does not exist'), $member); - } - } - } - - if (!empty($pconfig['lagghash'])){ - foreach ((array)$pconfig['lagghash'] as $item) { - if (!in_array($item, ['l2', 'l3', 'l4'])) { - $input_errors[] = sprintf(gettext('Invalid lagghash value \'%s\''), $item); - } - } - } - - if (!in_array($pconfig['proto'], $laggprotos)) { - $input_errors[] = gettext("Protocol supplied is invalid"); - } - - if (!empty($pconfig['mtu'])) { - $mtu_low = 576; - $mtu_high = 65535; - if ($pconfig['mtu'] < $mtu_low || $pconfig['mtu'] > $mtu_high || (string)((int)$pconfig['mtu']) != $pconfig['mtu'] ) { - $input_errors[] = sprintf(gettext('The MTU must be greater than %s bytes and less than %s.'), $mtu_low, $mtu_high); - } - } - - if (count($input_errors) == 0) { - $lagg = array(); - $lagg['members'] = implode(',', $pconfig['members']); - $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 (in_array($pconfig['use_flowid'] ?? '', ['0', '1'])) { - $lagg['use_flowid'] = $pconfig['use_flowid']; - } - if (in_array($pconfig['lacp_strict'] ?? '', ['0', '1'])) { - $lagg['lacp_strict'] = $pconfig['lacp_strict']; - } - if (!empty($pconfig['lagghash'])) { - $lagg['lagghash'] = implode(',', $pconfig['lagghash']); - } - if (isset($id)) { - $lagg['laggif'] = $a_laggs[$id]['laggif']; - } - - if (empty($lagg['laggif'])) { - $lagg['laggif'] = legacy_interface_create('lagg'); /* XXX find another strategy */ - } - - if (empty($lagg['laggif']) || strpos($lagg['laggif'], 'lagg') !== 0) { - $input_errors[] = gettext("Error occurred creating interface, please retry."); - } else { - if (isset($id)) { - $a_laggs[$id] = $lagg; - } else { - $a_laggs[] = $lagg; - } - write_config(); - _interfaces_lagg_configure($lagg); - $confif = convert_real_interface_to_friendly_interface_name($lagg['laggif']); - if ($confif != '') { - interface_configure(false, $confif); - } - header(url_safe('Location: /interfaces_lagg.php')); - exit; - } - } -} - -include("head.inc"); -legacy_html_escape_form_data($pconfig); -?> - - - - - -
-
-
- 0) print_input_errors($input_errors); ?> -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -   -
- - -
- - -
- - -
- /> - -
- - -
- - - -
- - -
- - -
  - - - - - - -
-
-
-
-
-
-
-
-