diff --git a/plist b/plist index cad0df89c3..ab6cad4410 100644 --- a/plist +++ b/plist @@ -367,6 +367,7 @@ /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/IPsec/forms/settings.xml +/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/AssignmentController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/BridgeSettingsController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/GifSettingsController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/GreSettingsController.php @@ -378,6 +379,7 @@ /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/AssignmentController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/BridgeController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/GifController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/GreController.php @@ -389,6 +391,7 @@ /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/dialogAssignment.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogBridge.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogGif.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogGre.xml @@ -810,6 +813,8 @@ /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/Assignment.php +/usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/Assignment.xml /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/Bridge.php /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/Bridge.xml /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/BridgeMemberField.php @@ -999,6 +1004,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/assignment.volt /usr/local/opnsense/mvc/app/views/OPNsense/Interface/bridge.volt /usr/local/opnsense/mvc/app/views/OPNsense/Interface/gif.volt /usr/local/opnsense/mvc/app/views/OPNsense/Interface/gre.volt @@ -1266,6 +1272,7 @@ /usr/local/opnsense/scripts/interfaces/ifctl.sh /usr/local/opnsense/scripts/interfaces/lib/__init__.py /usr/local/opnsense/scripts/interfaces/list_arp.py +/usr/local/opnsense/scripts/interfaces/list_assign_options.php /usr/local/opnsense/scripts/interfaces/list_hosts.py /usr/local/opnsense/scripts/interfaces/list_macdb.py /usr/local/opnsense/scripts/interfaces/list_ndp.py diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/AssignmentController.php b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/AssignmentController.php new file mode 100644 index 0000000000..bd990913ee --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/AssignmentController.php @@ -0,0 +1,77 @@ +searchBase("interface"); + } + + public function setItemAction($uuid) + { + return $this->setBase("interface", "interface", $uuid, $overlay); + } + + public function addItemAction() + { + return $this->addBase("interface", "interface", $overlay); + } + + public function getItemAction($uuid = null) + { + return $this->getBase("interface", "interface", $uuid); + } + + public function delItemAction($uuid) + { + return $this->delBase("interface", $uuid); + } + + public function reconfigureAction() + { + if ($this->request->isPost()) { + //(new Backend())->configdRun("interface xxx"); + return ["status" => "ok"]; + } else { + return ["status" => "failed"]; + } + } +} diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/AssignmentController.php b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/AssignmentController.php new file mode 100644 index 0000000000..973b3b5475 --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/AssignmentController.php @@ -0,0 +1,40 @@ +view->pick('OPNsense/Interface/assignment'); + + $this->view->formDialogAssignment = $this->getForm("dialogAssignment"); + $this->view->formGridAssignment = $this->getFormGrid("dialogAssignment"); + } +} diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogAssignment.xml b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogAssignment.xml new file mode 100644 index 0000000000..00d8a9b20f --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogAssignment.xml @@ -0,0 +1,20 @@ +
+ + interface.descr + + text + You may enter a description here for your reference (not parsed). + + + interface.identifier + + text + Technical identifier of the interface, used by hasync for example. + + + interface.if + + dropdown + Device name to connect this interface to. + +
diff --git a/src/opnsense/mvc/app/models/OPNsense/Interfaces/Assignment.php b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Assignment.php new file mode 100644 index 0000000000..1357f4cf78 --- /dev/null +++ b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Assignment.php @@ -0,0 +1,50 @@ +object()->interfaces->children() as $key => $intf) { + $node = $this->interface->add($key); + $node->descr = (string)$intf->descr; + $node->identifier = $key; + $node->if = (string)$intf->if; + } + } +} diff --git a/src/opnsense/mvc/app/models/OPNsense/Interfaces/Assignment.xml b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Assignment.xml new file mode 100644 index 0000000000..1510e59dff --- /dev/null +++ b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Assignment.xml @@ -0,0 +1,15 @@ + + :memory: + 0.0.1 + Interface assignments + + + + + + interface list assign-opts + Y + + + + diff --git a/src/opnsense/mvc/app/views/OPNsense/Interface/assignment.volt b/src/opnsense/mvc/app/views/OPNsense/Interface/assignment.volt new file mode 100644 index 0000000000..942a602888 --- /dev/null +++ b/src/opnsense/mvc/app/views/OPNsense/Interface/assignment.volt @@ -0,0 +1,45 @@ +{# + # Copyright (c) 2026 Deciso B.V. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without modification, + # are permitted provided that the following conditions are met: + # + # 1. Redistributions of source code must retain the above copyright notice, + # this list of conditions and the following disclaimer. + # + # 2. Redistributions in binary form must reproduce the above copyright notice, + # this list of conditions and the following disclaimer in the documentation + # and/or other materials provided with the distribution. + # + # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + # POSSIBILITY OF SUCH DAMAGE. + #} + + +
+ {{ partial('layout_partials/base_bootgrid_table', formGridAssignment)}} +
+{{ partial('layout_partials/base_apply_button', {'data_endpoint': '/api/interfaces/assignment/reconfigure'}) }} +{{ partial('layout_partials/base_dialog',['fields':formDialogAssignment,'id':formGridAssignment['edit_dialog_id'],'label':lang._('Edit Assignment')])}} diff --git a/src/opnsense/scripts/interfaces/list_assign_options.php b/src/opnsense/scripts/interfaces/list_assign_options.php new file mode 100755 index 0000000000..0a55b3317c --- /dev/null +++ b/src/opnsense/scripts/interfaces/list_assign_options.php @@ -0,0 +1,79 @@ +#!/usr/local/bin/php + [] + ]; + $excludes = []; + + /* add physical network interfaces */ + foreach (get_interface_list() as $key => $item) { + $interfaces['hardware'][$key] = $key . ' (' . $item['mac'] . ')'; + } + + /* add virtual network interfaces */ + foreach ($devices as $device) { + if (!empty($device['names'])) { + foreach ($device['names'] as $key => $values) { + if (!empty($values)) { + if (!isset($interfaces[$device['type']])) { + $interfaces[$device['type']] = []; + } + $interfaces[$device['type']][] = $values['descr']; + if (!empty($values['exclude'])) { + $excludes = array_merge($excludes, $values['exclude']); + } + } + } + } + } + + /* enforce constraints */ + foreach ($excludes as $device) { + if (isset($interfaces[$device])) { + unset($interfaces[$device]); + } + } + + return $interfaces; +} + +$a_devices = plugins_devices(); +echo json_encode(list_devices($a_devices)); diff --git a/src/opnsense/service/conf/actions.d/actions_interface.conf b/src/opnsense/service/conf/actions.d/actions_interface.conf index 84fee40625..3a4e441f33 100644 --- a/src/opnsense/service/conf/actions.d/actions_interface.conf +++ b/src/opnsense/service/conf/actions.d/actions_interface.conf @@ -66,6 +66,15 @@ type:script_output cache_ttl:30 message:request arp table + +[list.assign-opts] +command:/usr/local/opnsense/scripts/interfaces/list_assign_options.php +parameters: +type:script_output +cache_ttl:30 +message:show assignable interfaces + + [remove.arp] command:/usr/sbin/arp -d parameters:%s 2> /dev/null