diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/VlanSettingsController.php b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/VlanSettingsController.php
index 64429c477..978e14a5c 100644
--- a/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/VlanSettingsController.php
+++ b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/VlanSettingsController.php
@@ -42,7 +42,10 @@ class VlanSettingsController extends ApiMutableModelControllerBase
{
$tmp = $this->request->getPost('vlan');
$prefix = (strpos($tmp['if'], 'vlan') === false ? 'vlan' : 'qinq');
- if ($current != null && (string)$current->vlanif == "{$tmp['if']}_vlan{$tmp['tag']}") {
+ if (!empty($tmp['vlanif'])) {
+ // user provided vlan name, field validation applies so we may just paste it in here
+ return $tmp['vlanif'];
+ } elseif ($current != null && (string)$current->vlanif == "{$tmp['if']}_vlan{$tmp['tag']}") {
/* keep legacy naming */
return "{$tmp['if']}_vlan{$tmp['tag']}";
} elseif (
@@ -55,7 +58,7 @@ class VlanSettingsController extends ApiMutableModelControllerBase
/* auto-number new device */
$ifid = 0;
foreach ($this->getModel()->vlan->iterateItems() as $node) {
- if (strpos((string)$node->vlanif, $prefix) === 0) {
+ if (preg_match("/^({$prefix})(\d)*$/i",(string)$node->vlanif)) {
$ifid = max($ifid, (int)filter_var((string)$node->vlanif, FILTER_SANITIZE_NUMBER_INT));
}
}
diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogVlan.xml b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogVlan.xml
index d97c5160d..b6580c217 100644
--- a/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogVlan.xml
+++ b/src/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogVlan.xml
@@ -2,7 +2,12 @@
vlan.vlanif
- info
+ text
+
+ Leave empty to generate a device name for you. Custom names are possible,
+ but only if the start of the name matches the type and contains standard alphanumeric characters
+ or underscores (e.g. vlan_1_2_3, qinq_1_2_3).
+
vlan.if
diff --git a/src/opnsense/mvc/app/models/OPNsense/Interfaces/Vlan.php b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Vlan.php
index 83709376f..37d96aca4 100644
--- a/src/opnsense/mvc/app/models/OPNsense/Interfaces/Vlan.php
+++ b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Vlan.php
@@ -28,8 +28,44 @@
namespace OPNsense\Interfaces;
+use Phalcon\Messages\Message;
use OPNsense\Base\BaseModel;
class Vlan extends BaseModel
{
+ /**
+ * {@inheritdoc}
+ */
+ public function performValidation($validateFullModel = false)
+ {
+ $messages = parent::performValidation($validateFullModel);
+ $all_nodes = $this->getFlatNodes();
+ foreach ($all_nodes as $key => $node) {
+ if ($validateFullModel || $node->isFieldChanged()) {
+ // the item container may have different validations attached.
+ $parent = $node->getParentNode();
+ // perform plugin specific validations
+ switch ($node->getInternalXMLTagName()) {
+ case 'vlanif':
+ $prefix = (strpos((string)$parent->if, 'vlan') === false ? 'vlan' : 'qinq');
+ if ((string)$node == "{$parent->if}_vlan{$parent->tag}") {
+ // legacy device name
+ break;
+ } elseif (!(strpos((string)$node, (string)$prefix) === 0)) {
+ $messages->appendMessage(new Message(
+ sprintf(gettext("device name does not match type (e.g. %s_xxx)."), (string)$prefix) ,
+ $key
+ ));
+ } elseif (!preg_match("/^([a-zA-Z0-9_]){1,16}$/", (string)$node)) {
+ $messages->appendMessage(new Message(
+ gettext("Invalid device name, only up to 16 alphanumeric characters are supported."),
+ $key
+ ));
+ }
+ break;
+ }
+ }
+ }
+ return $messages;
+ }
}