mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-16 09:34:39 +00:00
Interfaces: Other Types: VLAN - refactor to MVC framework detaching configuration using configd while. In preparation for https://github.com/opnsense/core/issues/5560
This commit is contained in:
parent
892ab932a6
commit
88c27bfe4c
@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Interfaces\Api;
|
||||
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
use OPNsense\Base\UserException;
|
||||
use OPNsense\Base\ApiMutableModelControllerBase;
|
||||
|
||||
class VlanSettingsController extends ApiMutableModelControllerBase
|
||||
{
|
||||
protected static $internalModelName = 'vlan';
|
||||
protected static $internalModelClass = 'OPNsense\Interfaces\Vlan';
|
||||
|
||||
private function generateVlanIfName()
|
||||
{
|
||||
$tmp = $this->request->getPost("vlan");
|
||||
return "{$tmp['if']}_vlan{$tmp['tag']}";
|
||||
}
|
||||
|
||||
private function interfaceAssigned($if)
|
||||
{
|
||||
$configHandle = Config::getInstance()->object();
|
||||
if (!empty($configHandle->interfaces)) {
|
||||
foreach ($configHandle->interfaces->children() as $ifname => $node) {
|
||||
if ((string)$node->if == $if) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function searchItemAction()
|
||||
{
|
||||
return $this->searchBase("vlan", ['vlanif','if','tag','pcp','descr'], "vlanif");
|
||||
}
|
||||
|
||||
public function setItemAction($uuid)
|
||||
{
|
||||
$node = $this->getModel()->getNodeByReference('vlan.' . $uuid);
|
||||
$old_vlanif = $node != null ? (string)$node->vlanif : null;
|
||||
$new_vlanif = $this->generateVlanIfName();
|
||||
if ($old_vlanif != null && $old_vlanif != $new_vlanif && $this->interfaceAssigned($old_vlanif)) {
|
||||
$tmp = $this->request->getPost("vlan");
|
||||
if ($tmp['tag'] != (string)$node->tag) {
|
||||
$result = [
|
||||
"result" => "failed",
|
||||
"validations" => [
|
||||
"vlan.tag" => gettext("Interface is assigned and you cannot change the VLAN tag while assigned.")
|
||||
]
|
||||
];
|
||||
} else {
|
||||
$result = [
|
||||
"result" => "failed",
|
||||
"validations" => [
|
||||
"vlan.if" => gettext("Interface is assigned and you cannot change the parent while assigned.")
|
||||
]
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$result = $this->setBase("vlan", "vlan", $uuid, ["vlanif" => $new_vlanif]);
|
||||
// store interface name for apply action
|
||||
if ($result['result'] != 'failed' && $old_vlanif != $new_vlanif) {
|
||||
file_put_contents("/tmp/.vlans.removed", "{$old_vlanif}\n", FILE_APPEND|LOCK_EX);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function addItemAction()
|
||||
{
|
||||
return $this->addBase("vlan", "vlan", [
|
||||
"vlanif" => $this->generateVlanIfName()
|
||||
]);
|
||||
}
|
||||
|
||||
public function getItemAction($uuid = null)
|
||||
{
|
||||
return $this->getBase("vlan", "vlan", $uuid);
|
||||
}
|
||||
|
||||
public function delItemAction($uuid)
|
||||
{
|
||||
$node = $this->getModel()->getNodeByReference('vlan.' . $uuid);
|
||||
$old_vlanif = $node != null ? (string)$node->vlanif : null;
|
||||
if ($old_vlanif != null && $this->interfaceAssigned($old_vlanif)) {
|
||||
throw new UserException(gettext("This VLAN cannot be deleted because it is assigned as an interface."));
|
||||
} else {
|
||||
$result = $this->delBase("vlan", $uuid);
|
||||
// store interface name for apply action
|
||||
if ($result['result'] != 'failed') {
|
||||
file_put_contents("/tmp/.vlans.removed", "{$old_vlanif}\n", FILE_APPEND|LOCK_EX);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
public function reconfigureAction()
|
||||
{
|
||||
$result = array("status" => "failed");
|
||||
if ($this->request->isPost()) {
|
||||
$result['status'] = strtolower(trim((new Backend())->configdRun('interface vlan configure')));
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Interfaces;
|
||||
|
||||
class VlanController extends \OPNsense\Base\IndexController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->pick('OPNsense/Interface/vlan');
|
||||
$this->view->formDialogVlan = $this->getForm("dialogVlan");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>vlan.vlanif</id>
|
||||
<label>deviceId</label>
|
||||
<type>info</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>vlan.if</id>
|
||||
<label>Parent interface</label>
|
||||
<type>dropdown</type>
|
||||
<help>Only VLAN capable interfaces will be shown.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>vlan.tag</id>
|
||||
<label>VLAN tag</label>
|
||||
<type>text</type>
|
||||
<help>802.1Q VLAN tag (between 1 and 4094)</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>vlan.pcp</id>
|
||||
<label>VLAN priority</label>
|
||||
<type>dropdown</type>
|
||||
<help>802.1Q VLAN PCP (priority code point)</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>vlan.descr</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
<help>You may enter a description here for your reference (not parsed).</help>
|
||||
</field>
|
||||
</form>
|
||||
@ -410,18 +410,6 @@
|
||||
<pattern>interfaces_ppps_edit.php*</pattern>
|
||||
</patterns>
|
||||
</page-interfaces-ppps-edit>
|
||||
<page-interfaces-vlan>
|
||||
<name>Interfaces: VLAN</name>
|
||||
<patterns>
|
||||
<pattern>interfaces_vlan.php*</pattern>
|
||||
</patterns>
|
||||
</page-interfaces-vlan>
|
||||
<page-interfaces-vlan-edit>
|
||||
<name>Interfaces: VLAN: Edit</name>
|
||||
<patterns>
|
||||
<pattern>interfaces_vlan_edit.php*</pattern>
|
||||
</patterns>
|
||||
</page-interfaces-vlan-edit>
|
||||
<page-interfaces>
|
||||
<name>Interfaces: WAN</name>
|
||||
<patterns>
|
||||
|
||||
@ -138,9 +138,6 @@
|
||||
<LAGG url="/interfaces_lagg.php">
|
||||
<Edit url="/interfaces_lagg_edit.php*" visibility="hidden"/>
|
||||
</LAGG>
|
||||
<VLAN url="/interfaces_vlan.php">
|
||||
<Edit url="/interfaces_vlan_edit.php*" visibility="hidden"/>
|
||||
</VLAN>
|
||||
</Types>
|
||||
<Diagnostics order="970" cssClass="fa fa-medkit fa-fw">
|
||||
<DNSLookup VisibleName="DNS Lookup" url="/diag_dns.php">
|
||||
|
||||
@ -13,4 +13,11 @@
|
||||
<pattern>api/interfaces/loopback</pattern>
|
||||
</patterns>
|
||||
</page-interfaces-loopback>
|
||||
<page-interfaces-vlan-edit>
|
||||
<name>Interfaces: VLAN</name>
|
||||
<patterns>
|
||||
<pattern>ui/interfaces/vlan</pattern>
|
||||
<pattern>api/interfaces/vlan</pattern>
|
||||
</patterns>
|
||||
</page-interfaces-vlan-edit>
|
||||
</acl>
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2022 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OPNsense\Interfaces\FieldTypes;
|
||||
|
||||
use OPNsense\Base\FieldTypes\BaseListField;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
|
||||
class VlanInterfaceField extends BaseListField
|
||||
{
|
||||
private static $interface_devices = null;
|
||||
|
||||
protected function actionPostLoadingEvent()
|
||||
{
|
||||
if (self::$interface_devices === null) {
|
||||
$configHandle = Config::getInstance()->object();
|
||||
$ifnames = [];
|
||||
if (!empty($configHandle->interfaces)) {
|
||||
foreach ($configHandle->interfaces->children() as $ifname => $node) {
|
||||
$ifnames[(string)$node->if] = !empty((string)$node->descr) ? (string)$node->descr : $key;
|
||||
}
|
||||
}
|
||||
self::$interface_devices = [];
|
||||
$ifconfig = json_decode((new Backend())->configdRun('interface list ifconfig'), true);
|
||||
if (!empty($ifconfig)) {
|
||||
foreach ($ifconfig as $ifname => $details) {
|
||||
// XXX: skip same interface types as legacy, may need to revise later
|
||||
if (strpos($ifname, "_vlan") > 1 || strpos($ifname, "lo") === 0 || strpos($ifname, "enc") === 0 ||
|
||||
strpos($ifname, "pflog") === 0 || strpos($ifname, "pfsync") === 0 ||
|
||||
strpos($ifname, "bridge") === 0 ||
|
||||
strpos($ifname, "gre") === 0 || strpos($ifname, "gif") === 0 || strpos($ifname, "ipsec") === 0
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
self::$interface_devices[$ifname] = sprintf(
|
||||
"%s (%s) [%s]",
|
||||
$ifname,
|
||||
$details['macaddr'],
|
||||
!empty($ifnames[$ifname]) ? $ifnames[$ifname] : ""
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->internalOptionList = self::$interface_devices;
|
||||
return parent::actionPostLoadingEvent();
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@
|
||||
<Types>
|
||||
<VXLAN url="/ui/interfaces/vxlan"/>
|
||||
<Loopback url="/ui/interfaces/loopback"/>
|
||||
<VLAN url="/ui/interfaces/vlan"/>
|
||||
</Types>
|
||||
</Interfaces>
|
||||
</menu>
|
||||
|
||||
35
src/opnsense/mvc/app/models/OPNsense/Interfaces/Vlan.php
Normal file
35
src/opnsense/mvc/app/models/OPNsense/Interfaces/Vlan.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Interfaces;
|
||||
|
||||
use OPNsense\Base\BaseModel;
|
||||
|
||||
class Vlan extends BaseModel
|
||||
{
|
||||
}
|
||||
45
src/opnsense/mvc/app/models/OPNsense/Interfaces/Vlan.xml
Normal file
45
src/opnsense/mvc/app/models/OPNsense/Interfaces/Vlan.xml
Normal file
@ -0,0 +1,45 @@
|
||||
<model>
|
||||
<mount>//vlans</mount>
|
||||
<version>1.0.0</version>
|
||||
<description>
|
||||
VLAN configuration
|
||||
</description>
|
||||
<items>
|
||||
<vlan type="ArrayField">
|
||||
<if type=".\VlanInterfaceField">
|
||||
<Required>Y</Required>
|
||||
</if>
|
||||
<tag type="IntegerField">
|
||||
<MinimumValue>1</MinimumValue>
|
||||
<MaximumValue>4094</MaximumValue>
|
||||
<Required>Y</Required>
|
||||
</tag>
|
||||
<pcp type="OptionField">
|
||||
<Required>Y</Required>
|
||||
<default>0</default>
|
||||
<OptionValues>
|
||||
<pcp1 value="1">Background (1, lowest)</pcp1>
|
||||
<pcp0 value="0">Best Effort (0, default)</pcp0>
|
||||
<pcp2 value="2">Excellent Effort (2)</pcp2>
|
||||
<pcp3 value="3">Critical Applications (3)</pcp3>
|
||||
<pcp4 value="4">Video (4)</pcp4>
|
||||
<pcp5 value="5">Voice (5)</pcp5>
|
||||
<pcp6 value="6">Internetwork Control (6)</pcp6>
|
||||
<pcp7 value="7">Network Control (7, highest)</pcp7>
|
||||
</OptionValues>
|
||||
</pcp>
|
||||
<descr type="TextField">
|
||||
<Required>N</Required>
|
||||
</descr>
|
||||
<vlanif type="TextField">
|
||||
<Required>Y</Required>
|
||||
<Constraints>
|
||||
<check001>
|
||||
<ValidationMessage>The interface name should be unique.</ValidationMessage>
|
||||
<type>UniqueConstraint</type>
|
||||
</check001>
|
||||
</Constraints>
|
||||
</vlanif>
|
||||
</vlan>
|
||||
</items>
|
||||
</model>
|
||||
55
src/opnsense/mvc/app/views/OPNsense/Interface/vlan.volt
Normal file
55
src/opnsense/mvc/app/views/OPNsense/Interface/vlan.volt
Normal file
@ -0,0 +1,55 @@
|
||||
<script>
|
||||
$( document ).ready(function() {
|
||||
$("#grid-vlans").UIBootgrid(
|
||||
{ search:'/api/interfaces/vlan_settings/searchItem/',
|
||||
get:'/api/interfaces/vlan_settings/getItem/',
|
||||
set:'/api/interfaces/vlan_settings/setItem/',
|
||||
add:'/api/interfaces/vlan_settings/addItem/',
|
||||
del:'/api/interfaces/vlan_settings/delItem/'
|
||||
}
|
||||
);
|
||||
$("#reconfigureAct").SimpleActionButton();
|
||||
});
|
||||
</script>
|
||||
<div class="tab-content content-box">
|
||||
<table id="grid-vlans" class="table table-condensed table-hover table-striped" data-editDialog="DialogVlan" data-editAlert="VlanChangeMessage">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
|
||||
<th data-column-id="if" data-type="string">{{ lang._('Parent Interface') }}</th>
|
||||
<th data-column-id="vlanif" data-type="string" data-visible="false">{{ lang._('Interface') }}</th>
|
||||
<th data-column-id="tag" data-type="string">{{ lang._('Tag') }}</th>
|
||||
<th data-column-id="pcp" data-type="string">{{ lang._('PCP') }}</th>
|
||||
<th data-column-id="descr" data-type="string">{{ lang._('Description') }}</th>
|
||||
<th data-column-id="commands" data-width="7em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-primary"><span class="fa fa-fw fa-plus"></span></button>
|
||||
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-fw fa-trash-o"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<div class="col-md-12">
|
||||
<div id="VlanChangeMessage" class="alert alert-info" style="display: none" role="alert">
|
||||
{{ lang._('After changing settings, please remember to apply them with the button below') }}
|
||||
</div>
|
||||
<hr/>
|
||||
<button class="btn btn-primary" id="reconfigureAct"
|
||||
data-endpoint='/api/interfaces/vlan_settings/reconfigure'
|
||||
data-label="{{ lang._('Apply') }}"
|
||||
data-error-title="{{ lang._('Error reconfiguring vlan') }}"
|
||||
type="button"
|
||||
></button>
|
||||
<br/><br/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogVlan,'id':'DialogVlan','label':lang._('Edit Vlan')])}}
|
||||
90
src/opnsense/scripts/interfaces/reconfigure_vlans.php
Executable file
90
src/opnsense/scripts/interfaces/reconfigure_vlans.php
Executable file
@ -0,0 +1,90 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
require_once("config.inc");
|
||||
require_once("filter.inc");
|
||||
require_once("interfaces.inc");
|
||||
require_once("util.inc");
|
||||
|
||||
// gather all relevant vlan's (new/updated and removed) into a single list
|
||||
$all_vlans = [];
|
||||
$vfilename = "/tmp/.vlans.removed";
|
||||
if (file_exists($vfilename) && filesize($vfilename) > 0) {
|
||||
$handle = fopen($vfilename, "r+");
|
||||
if (flock($handle, LOCK_EX)) {
|
||||
fseek($handle, 0);
|
||||
foreach (explode("\n", fread($handle, filesize($vfilename))) as $line) {
|
||||
if (!isset($all_vlans[$line]) && trim($line) != "") {
|
||||
$all_vlans[$line] = [];
|
||||
}
|
||||
}
|
||||
fseek($handle, 0);
|
||||
ftruncate($handle, 0);
|
||||
flock($handle, LOCK_UN);
|
||||
}
|
||||
}
|
||||
// merge configured vlans
|
||||
if (!empty($config['vlans']['vlan'])) {
|
||||
foreach ($config['vlans']['vlan'] as $vlan) {
|
||||
$all_vlans[$vlan['vlanif']] = $vlan;
|
||||
}
|
||||
}
|
||||
|
||||
// handle existing vlan's
|
||||
foreach (legacy_interfaces_details() as $ifname => $ifdetails) {
|
||||
if (empty($ifdetails['vlan'])) {
|
||||
continue;
|
||||
}
|
||||
if (isset($all_vlans[$ifname])){
|
||||
$vlan = $all_vlans[$ifname];
|
||||
$cvlan = $ifdetails['vlan'];
|
||||
if (empty($vlan)) {
|
||||
// option 1: removed vlan
|
||||
legacy_interface_destroy($ifname);
|
||||
} elseif ($vlan['pcp'] != $cvlan['pcp']) {
|
||||
// option 2: pcp changed, which can be altered instantly
|
||||
exec('/sbin/ifconfig ' . escapeshellarg($vlan['vlanif']) . ' vlanpcp ' . escapeshellarg($vlan['pcp']). ' 2>&1', $out, $ret);
|
||||
} elseif ($vlan['tag'] != $cvlan['tag'] || $vlan['if'] != $cvlan['parent']){
|
||||
// option 3: changed vlan, recreate with appropriate settings
|
||||
// XXX: legacy code used interface_configure() in these cases, but since you can't change a tag or a parent
|
||||
// for an assigned interface. At the moment that doesn't seem to make much sense
|
||||
interface_vlan_configure($vlan);
|
||||
}
|
||||
unset($all_vlans[$ifname]);
|
||||
}
|
||||
}
|
||||
|
||||
// configure new
|
||||
foreach ($all_vlans as $ifname => $vlan) {
|
||||
if (!empty($vlan)) {
|
||||
interface_vlan_configure($vlan);
|
||||
}
|
||||
}
|
||||
|
||||
ifgroup_setup();
|
||||
@ -115,6 +115,11 @@ command: /usr/local/sbin/pluginctl -c vxlan_prepare
|
||||
message: Reconfiguring vxlan
|
||||
type: script
|
||||
|
||||
[vlan.configure]
|
||||
command: /usr/local/opnsense/scripts/interfaces/reconfigure_vlans.php
|
||||
message: Reconfiguring vlan
|
||||
type: script
|
||||
|
||||
[loopback.configure]
|
||||
command: /usr/local/sbin/pluginctl -c loopback_prepare
|
||||
message: Reconfiguring loopbacks
|
||||
|
||||
@ -1,145 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Deciso B.V.
|
||||
* Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
require_once("guiconfig.inc");
|
||||
require_once("interfaces.inc");
|
||||
|
||||
$a_vlans = &config_read_array('vlans', 'vlan');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$input_errors = array();
|
||||
if (!empty($a_vlans[$_POST['id']])) {
|
||||
$id = $_POST['id'];
|
||||
}
|
||||
|
||||
if (!empty($_POST['action']) && $_POST['action'] == "del" && isset($id)) {
|
||||
if (is_interface_assigned($a_vlans[$id]['vlanif'])) {
|
||||
$input_errors[] = gettext("This VLAN cannot be deleted because it is assigned as an interface.");
|
||||
} else {
|
||||
if (does_interface_exist($a_vlans[$id]['vlanif'])) {
|
||||
legacy_interface_destroy($a_vlans[$id]['vlanif']);
|
||||
}
|
||||
unset($a_vlans[$id]);
|
||||
write_config();
|
||||
header(url_safe('Location: /interfaces_vlan.php'));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
include("head.inc");
|
||||
|
||||
legacy_html_escape_form_data($a_vlans);
|
||||
|
||||
?>
|
||||
<body>
|
||||
<script>
|
||||
$( document ).ready(function() {
|
||||
// link delete buttons
|
||||
$(".act_delete").click(function(event){
|
||||
event.preventDefault();
|
||||
var id = $(this).data("id");
|
||||
// delete single
|
||||
BootstrapDialog.show({
|
||||
type:BootstrapDialog.TYPE_DANGER,
|
||||
title: "<?= gettext("VLAN");?>",
|
||||
message: "<?=gettext("Do you really want to delete this VLAN?");?>",
|
||||
buttons: [{
|
||||
label: "<?= gettext("No");?>",
|
||||
action: function(dialogRef) {
|
||||
dialogRef.close();
|
||||
}}, {
|
||||
label: "<?= gettext("Yes");?>",
|
||||
action: function(dialogRef) {
|
||||
$("#id").val(id);
|
||||
$("#action").val("del");
|
||||
$("#iform").submit()
|
||||
}
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<?php include("fbegin.inc"); ?>
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<?php if (isset($input_errors) && count($input_errors) > 0) print_input_errors($input_errors); ?>
|
||||
<section class="col-xs-12">
|
||||
<div class="tab-content content-box col-xs-12">
|
||||
<form method="post" name="iform" id="iform">
|
||||
<input type="hidden" id="action" name="action" value="">
|
||||
<input type="hidden" id="id" name="id" value="">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?=gettext("Interface");?></th>
|
||||
<th><?=gettext("Tag");?></th>
|
||||
<th><?=gettext("PCP");?></th>
|
||||
<th><?=gettext("Description");?></th>
|
||||
<th class="text-nowrap">
|
||||
<a href="interfaces_vlan_edit.php" class="btn btn-primary btn-xs" data-toggle="tooltip" title="<?= html_safe(gettext('Add')) ?>">
|
||||
<i class="fa fa-plus fa-fw"></i>
|
||||
</a>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$i = 0;
|
||||
foreach ($a_vlans as $vlan): ?>
|
||||
<tr>
|
||||
<td><?=$vlan['if'];?></td>
|
||||
<td><?=$vlan['tag'];?></td>
|
||||
<td><?= isset($vlan['pcp']) ? $vlan['pcp'] : 0 ?></td>
|
||||
<td><?=$vlan['descr'];?></td>
|
||||
<td class="text-nowrap">
|
||||
<a href="interfaces_vlan_edit.php?id=<?=$i;?>" class="btn btn-xs btn-default" data-toggle="tooltip" title="<?= html_safe(gettext('Edit')) ?>">
|
||||
<i class="fa fa-pencil fa-fw"></i>
|
||||
</a>
|
||||
<button title="<?= html_safe(gettext('Delete')) ?>" data-toggle="tooltip" data-id="<?=$i;?>" class="btn btn-default btn-xs act_delete" type="submit">
|
||||
<i class="fa fa-trash fa-fw"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
$i++;
|
||||
endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php include("foot.inc"); ?>
|
||||
@ -1,251 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Deciso B.V.
|
||||
* Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
require_once("guiconfig.inc");
|
||||
require_once("system.inc");
|
||||
require_once("interfaces.inc");
|
||||
require_once("filter.inc");
|
||||
|
||||
$a_vlans = &config_read_array('vlans', 'vlan');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
// read form data
|
||||
if (!empty($a_vlans[$_GET['id']])) {
|
||||
$id = $_GET['id'];
|
||||
}
|
||||
$pconfig['if'] = isset($a_vlans[$id]['if']) ? $a_vlans[$id]['if'] : null;
|
||||
$pconfig['vlanif'] = isset($a_vlans[$id]['vlanif']) ? $a_vlans[$id]['vlanif'] : null;
|
||||
$pconfig['tag'] = isset($a_vlans[$id]['tag']) ? $a_vlans[$id]['tag'] : null;
|
||||
$pconfig['pcp'] = isset($a_vlans[$id]['pcp']) ? $a_vlans[$id]['pcp'] : 0;
|
||||
$pconfig['descr'] = isset($a_vlans[$id]['descr']) ? $a_vlans[$id]['descr'] : null;
|
||||
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// validate / save form data
|
||||
if (!empty($a_vlans[$_POST['id']])) {
|
||||
$id = $_POST['id'];
|
||||
}
|
||||
|
||||
$input_errors = [];
|
||||
$pconfig = $_POST;
|
||||
|
||||
/* input validation */
|
||||
$reqdfields = explode(" ", "if tag");
|
||||
$reqdfieldsn = [gettext('Parent interface'), gettext('VLAN tag')];
|
||||
|
||||
do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors);
|
||||
|
||||
if ($pconfig['tag'] && (!is_numericint($pconfig['tag']) || ($pconfig['tag'] < '1') || ($pconfig['tag'] > '4094'))) {
|
||||
$input_errors[] = gettext("The VLAN tag must be an integer between 1 and 4094.");
|
||||
}
|
||||
|
||||
if (isset($pconfig['pcp']) && (!is_numericint($pconfig['pcp']) || $pconfig['pcp'] < 0 || $pconfig['pcp'] > 7)) {
|
||||
$input_errors[] = gettext("The VLAN priority must be an integer between 0 and 7.");
|
||||
}
|
||||
|
||||
if (!does_interface_exist($pconfig['if'])) {
|
||||
$input_errors[] = gettext("Interface supplied as parent is invalid");
|
||||
}
|
||||
|
||||
if (isset($id) && $pconfig['tag'] && $pconfig['tag'] != $a_vlans[$id]['tag']) {
|
||||
if (!empty($a_vlans[$id]['vlanif']) && convert_real_interface_to_friendly_interface_name($a_vlans[$id]['vlanif']) != NULL) {
|
||||
$input_errors[] = gettext("Interface is assigned and you cannot change the VLAN tag while assigned.");
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($a_vlans as $vlan) {
|
||||
if (isset($id) && $a_vlans[$id] === $vlan) {
|
||||
continue;
|
||||
}
|
||||
if (($vlan['if'] == $pconfig['if']) && ($vlan['tag'] == $pconfig['tag'])) {
|
||||
$input_errors[] = sprintf(gettext("A VLAN with the tag %s is already defined on this interface."), $vlan['tag']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($input_errors) == 0) {
|
||||
$confif = "";
|
||||
$vlan = [];
|
||||
$vlan['if'] = $pconfig['if'];
|
||||
$vlan['tag'] = $pconfig['tag'];
|
||||
$vlan['pcp'] = $pconfig['pcp'];
|
||||
$vlan['descr'] = $pconfig['descr'];
|
||||
$vlan['vlanif'] = "{$pconfig['if']}_vlan{$pconfig['tag']}";
|
||||
if (isset($id)) {
|
||||
if (($a_vlans[$id]['if'] != $pconfig['if']) || ($a_vlans[$id]['tag'] != $pconfig['tag']) || ($a_vlans[$id]['pcp'] != $pconfig['pcp'])) {
|
||||
$confif = convert_real_interface_to_friendly_interface_name($a_vlans[$id]['vlanif']);
|
||||
legacy_interface_destroy($a_vlans[$id]['vlanif']);
|
||||
if ($confif != '') {
|
||||
$config['interfaces'][$confif]['if'] = $vlan['vlanif'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Since VLAN name is calculated we do not need to fetch one from the
|
||||
* system. However, we would still like to know if the system can create
|
||||
* another VLAN if it is being added like is done for other devices.
|
||||
* Eventually we want to change VLAN device names to a simpler "vlanX" style.
|
||||
*/
|
||||
$vlan['vlanif'] = legacy_interface_create('vlan', $vlan['vlanif']); /* XXX find another strategy */
|
||||
}
|
||||
|
||||
if (empty($vlan['vlanif']) || strpos($vlan['vlanif'], '_vlan') === false) {
|
||||
$input_errors[] = gettext("Error occurred creating interface, please retry.");
|
||||
} else {
|
||||
if (isset($id)) {
|
||||
$a_vlans[$id] = $vlan;
|
||||
} else {
|
||||
$a_vlans[] = $vlan;
|
||||
}
|
||||
write_config();
|
||||
interface_vlan_configure($vlan);
|
||||
ifgroup_setup();
|
||||
if ($confif != '') {
|
||||
interface_configure(false, $confif);
|
||||
}
|
||||
header(url_safe('Location: /interfaces_vlan.php'));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
include("head.inc");
|
||||
legacy_html_escape_form_data($pconfig);
|
||||
?>
|
||||
|
||||
<body>
|
||||
<?php include("fbegin.inc"); ?>
|
||||
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<?php if (isset($input_errors) && count($input_errors) > 0) print_input_errors($input_errors); ?>
|
||||
<section class="col-xs-12">
|
||||
<div class="content-box">
|
||||
<div class="table-responsive">
|
||||
<form method="post" name="iform" id="iform">
|
||||
<table class="table table-striped opnsense_standard_table_form">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width:22%"><strong><?=gettext("Interface VLAN Edit");?></strong></td>
|
||||
<td style="width:78%; text-align:right">
|
||||
<small><?=gettext("full help"); ?> </small>
|
||||
<i class="fa fa-toggle-off text-danger" style="cursor: pointer;" id="show_all_help_page"></i>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a id="help_for_if" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Parent interface");?></td>
|
||||
<td>
|
||||
<select name="if" class="selectpicker">
|
||||
<?php
|
||||
$all_interfaces = legacy_config_get_interfaces(['virtual' => false]);
|
||||
$all_interface_data = legacy_interfaces_details();
|
||||
foreach ($all_interfaces as $intf) {
|
||||
if (!empty($intf['if']) && !empty($all_interface_data[$intf['if']])) {
|
||||
$all_interface_data[$intf['if']]['descr'] = $intf['descr'];
|
||||
}
|
||||
}
|
||||
foreach ($all_interface_data as $ifn => $ifinfo):
|
||||
if (strpos($ifn, "_vlan") > 1 || strpos($ifn, "lo") === 0 || strpos($ifn, "enc") === 0 ||
|
||||
strpos($ifn, "pflog") === 0 || strpos($ifn, "pfsync") === 0 || strpos($ifn, "bridge") === 0 ||
|
||||
strpos($ifn, "gre") === 0 || strpos($ifn, "gif") === 0 || strpos($ifn, "ipsec") === 0) {
|
||||
continue;
|
||||
}?>
|
||||
|
||||
<option value="<?=$ifn;?>" <?=$ifn == $pconfig['if'] ? " selected=\"selected\"" : "";?>>
|
||||
<?=htmlspecialchars($ifn);?>
|
||||
( <?= !empty($ifinfo['macaddr']) ? $ifinfo['macaddr'] :"" ;?> )
|
||||
<?php
|
||||
if (!empty($ifinfo['descr'])):?>
|
||||
[<?=htmlspecialchars($ifinfo['descr']);?>]
|
||||
<?php
|
||||
endif;?>
|
||||
</option>
|
||||
<?php
|
||||
endforeach;?>
|
||||
|
||||
</select>
|
||||
<div class="hidden" data-for="help_for_if">
|
||||
<?=gettext("Only VLAN capable interfaces will be shown.");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_tag" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("VLAN tag");?></td>
|
||||
<td>
|
||||
<input name="tag" type="text" value="<?=$pconfig['tag'];?>" />
|
||||
<div class="hidden" data-for="help_for_tag">
|
||||
<?=gettext("802.1Q VLAN tag (between 1 and 4094)");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_pcp" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("VLAN priority");?></td>
|
||||
<td>
|
||||
<select name="pcp">
|
||||
<?php foreach (interfaces_vlan_priorities() as $pcp => $priority): ?>
|
||||
<option value="<?=$pcp;?>"<?=($pconfig['pcp'] == $pcp ? ' selected="selected"' : '');?>><?=htmlspecialchars($priority);?></option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
<div class="hidden" data-for="help_for_pcp">
|
||||
<?=gettext('802.1Q VLAN PCP (priority code point)');?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a id="help_for_descr" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Description"); ?></td>
|
||||
<td>
|
||||
<input name="descr" type="text" value="<?=$pconfig['descr'];?>" />
|
||||
<div class="hidden" data-for="help_for_descr">
|
||||
<?=gettext("You may enter a description here for your reference (not parsed).");?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width:22%"> </td>
|
||||
<td style="width:78%">
|
||||
<input type="hidden" name="vlanif" value="<?=$pconfig['vlanif']; ?>" />
|
||||
<input name="Submit" type="submit" class="btn btn-primary" value="<?=html_safe(gettext('Save'));?>" />
|
||||
<input type="button" class="btn btn-default" value="<?=html_safe(gettext('Cancel'));?>" onclick="window.location.href='/interfaces_vlan.php'" />
|
||||
<?php if (isset($id)): ?>
|
||||
<input name="id" type="hidden" value="<?=$id;?>" />
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php include("foot.inc"); ?>
|
||||
Loading…
x
Reference in New Issue
Block a user