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 @@
+
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') }} |
+
+
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
+
+ {{ lang._('After changing settings, please remember to apply them with the button below') }}
+
+
+
+
+
+
+
+
+{{ 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); ?>
-
-
-
-
-