summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-definitions/include/version/interfaces-version.xml.i2
-rw-r--r--interface-definitions/interfaces-vxlan.xml.in2
-rwxr-xr-xscripts/import-conf-mode-commands255
-rw-r--r--smoketest/configs/bgp-evpn-l2vpn-leaf1
-rw-r--r--smoketest/configs/cluster-basic62
-rwxr-xr-xsrc/conf_mode/interfaces-vxlan.py7
-rwxr-xr-xsrc/migration-scripts/interfaces/31-to-3246
7 files changed, 117 insertions, 258 deletions
diff --git a/interface-definitions/include/version/interfaces-version.xml.i b/interface-definitions/include/version/interfaces-version.xml.i
index 76c5d3c05..854e60f4e 100644
--- a/interface-definitions/include/version/interfaces-version.xml.i
+++ b/interface-definitions/include/version/interfaces-version.xml.i
@@ -1,3 +1,3 @@
<!-- include start from include/version/interfaces-version.xml.i -->
-<syntaxVersion component='interfaces' version='31'></syntaxVersion>
+<syntaxVersion component='interfaces' version='32'></syntaxVersion>
<!-- include end -->
diff --git a/interface-definitions/interfaces-vxlan.xml.in b/interface-definitions/interfaces-vxlan.xml.in
index b246d9a09..3fae17178 100644
--- a/interface-definitions/interfaces-vxlan.xml.in
+++ b/interface-definitions/interfaces-vxlan.xml.in
@@ -93,7 +93,7 @@
</node>
#include <include/port-number.xml.i>
<leafNode name="port">
- <defaultValue>8472</defaultValue>
+ <defaultValue>4789</defaultValue>
</leafNode>
#include <include/source-address-ipv4-ipv6.xml.i>
#include <include/source-interface.xml.i>
diff --git a/scripts/import-conf-mode-commands b/scripts/import-conf-mode-commands
deleted file mode 100755
index 996b31c9c..000000000
--- a/scripts/import-conf-mode-commands
+++ /dev/null
@@ -1,255 +0,0 @@
-#!/usr/bin/env python3
-#
-# build-command-template: converts old style commands definitions to XML
-#
-# Copyright (C) 2019 VyOS maintainers <maintainers@vyos.net>
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
-# USA
-
-
-import os
-import re
-import sys
-
-from lxml import etree
-
-
-# Node types
-NODE = 0
-LEAF_NODE = 1
-TAG_NODE = 2
-
-def parse_command_data(t):
- regs = {
- 'help': r'\bhelp:(.*)(?:\n|$)',
- 'priority': r'\bpriority:(.*)(?:\n|$)',
- 'type': r'\btype:(.*)(?:\n|$)',
- 'syntax_expression_var': r'\bsyntax:expression: \$VAR\(\@\) in (.*)'
- }
-
- data = {'multi': False, 'help': ""}
-
- for r in regs:
- try:
- data[r] = re.search(regs[r], t).group(1).strip()
- except:
- data[r] = None
-
- # val_help is special: there can be multiple instances
- val_help_strings = re.findall(r'\bval_help:(.*)(?:\n|$)', t)
- val_help = []
- for v in val_help_strings:
- try:
- fmt, msg = re.match(r'\s*(.*)\s*;\s*(.*)\s*(?:\n|$)', v).groups()
- except:
- fmt = "<text>"
- msg = v
- val_help.append((fmt, msg))
- data['val_help'] = val_help
-
- # multi is on/off
- if re.match(r'\bmulti:', t):
- data['multi'] = True
-
- return(data)
-
-def walk(tree, base_path, name):
- path = os.path.join(base_path, name)
-
- contents = os.listdir(path)
-
- # Determine node type and create XML element for the node
- # Tag node dirs will always have 'node.tag' subdir and 'node.def' file
- # Leaf node dirs have nothing but a 'node.def' file
- # Everything that doesn't match either of these patterns is a normal node
- if 'node.tag' in contents:
- print("Creating a tag node from {0}".format(path))
- elem = etree.Element('tagNode')
- node_type = TAG_NODE
- elif contents == ['node.def']:
- print("Creating a leaf node from {0}".format(path))
- elem = etree.Element('leafNode')
- node_type = LEAF_NODE
- else:
- print("Creating a node from {0}".format(path))
- elem = etree.Element('node')
- node_type = NODE
-
- # Read and parse the command definition data (the 'node.def' file)
- with open(os.path.join(path, 'node.def'), 'r') as f:
- node_def = f.read()
- data = parse_command_data(node_def)
-
- # Import the data into the properties element
- props_elem = etree.Element('properties')
-
- if data['priority']:
- # Priority values sometimes come with comments that explain the value choice
- try:
- prio, prio_comment = re.match(r'\s*(\d+)\s*#(.*)', data['priority']).groups()
- except:
- prio = data['priority'].strip()
- prio_comment = None
- prio_elem = etree.Element('priority')
- prio_elem.text = prio
- props_elem.append(prio_elem)
- if prio_comment:
- prio_comment_elem = etree.Comment(prio_comment)
- props_elem.append(prio_comment_elem)
-
- if data['multi']:
- multi_elem = etree.Element('multi')
- props_elem.append(multi_elem)
-
- if data['help']:
- help_elem = etree.Element('help')
- help_elem.text = data['help']
- props_elem.append(help_elem)
-
- # For leaf nodes, absense of a type: tag means they take no values
- # For any other nodes, it doesn't mean anything
- if not data['type'] and (node_type == LEAF_NODE):
- valueless = etree.Element('valueless')
- props_elem.append(valueless)
-
- # There can be only one constraint element in the definition
- # Create it now, we'll modify it in the next two cases, then append
- constraint_elem = etree.Element('constraint')
- has_constraint = False
-
- # Add regexp field for multiple options
- if data['syntax_expression_var']:
- regex = etree.Element('regex')
- constraint_error=etree.Element('constraintErrorMessage')
- values = re.search(r'(.+) ; (.+)', data['syntax_expression_var']).group(1)
- message = re.search(r'(.+) ; (.+)', data['syntax_expression_var']).group(2)
- values = re.findall(r'\"(.+?)\"', values)
- regex.text = '|'.join(values)
- constraint_error.text = re.sub('\".*?VAR.*?\"', '', message)
- constraint_error.text = re.sub(r'[\"|\\]', '', message)
- constraint_elem.append(regex)
- props_elem.append(constraint_elem)
- props_elem.append(constraint_error)
-
- if data['val_help']:
- for vh in data['val_help']:
- vh_elem = etree.Element('valueHelp')
-
- vh_fmt_elem = etree.Element('format')
- # Many commands use special "u32:<start>-<end>" format for ranges
- if re.match(r'u32:', vh[0]):
- vh_fmt = re.match(r'u32:(.*)', vh[0]).group(1).strip()
-
- # If valid range of values is specified in val_help, we can automatically
- # create a constraint for it
- # Extracting it from syntax:expression: would be much more complicated
- vh_validator = etree.Element('validator')
- vh_validator.set("name", "numeric")
- vh_validator.set("argument", "--range {0}".format(vh_fmt))
- constraint_elem.append(vh_validator)
- has_constraint = True
- else:
- vh_fmt = vh[0]
- vh_fmt_elem.text = vh_fmt
-
- vh_help_elem = etree.Element('description')
- vh_help_elem.text = vh[1]
-
- vh_elem.append(vh_fmt_elem)
- vh_elem.append(vh_help_elem)
- props_elem.append(vh_elem)
-
- # Translate the "type:" to the new validator system
- if data['type']:
- t = data['type']
- if t == 'txt':
- # Can't infer anything from the generic "txt" type
- pass
- else:
- validator = etree.Element('validator')
- if t == 'u32':
- validator.set('name', 'numeric')
- validator.set('argument', '--non-negative')
- elif t == 'ipv4':
- validator.set('name', 'ipv4-address')
- elif t == 'ipv4net':
- validator.set('name', 'ipv4-prefix')
- elif t == 'ipv6':
- validator.set('name', 'ipv6-address')
- elif t == 'ipv6net':
- validator.set('name', 'ipv6-prefix')
- elif t == 'macaddr':
- validator.set('name', 'mac-address')
- else:
- print("Warning: unsupported type \'{0}\'".format(t))
- validator = None
-
- if (validator is not None) and (not has_constraint):
- # If has_constraint is true, it means a more specific validator
- # was already extracted from another option
- constraint_elem.append(validator)
- has_constraint = True
-
- if has_constraint:
- props_elem.append(constraint_elem)
-
- elem.append(props_elem)
-
- elem.set("name", name)
-
- if node_type != LEAF_NODE:
- children = etree.Element('children')
-
- # Create the next level dir path,
- # accounting for the "virtual" node.tag subdir for tag nodes
- next_level = path
- if node_type == TAG_NODE:
- next_level = os.path.join(path, 'node.tag')
-
- # Walk the subdirs of the next level
- for d in os.listdir(next_level):
- dp = os.path.join(next_level, d)
- if os.path.isdir(dp):
- walk(children, next_level, d)
-
- elem.append(children)
-
- tree.append(elem)
-
-if __name__ == '__main__':
- if len(sys.argv) < 2:
- print("Usage: {0} <base path>".format(sys.argv[0]))
- sys.exit(1)
- else:
- base_path = sys.argv[1]
-
- root = etree.Element('interfaceDefinition')
- contents = os.listdir(base_path)
- elem = etree.Element('node')
- elem.set('name', os.path.basename(base_path))
- children = etree.Element('children')
-
- for c in contents:
- path = os.path.join(base_path, c)
- if os.path.isdir(path):
- walk(children, base_path, c)
-
- elem.append(children)
- root.append(elem)
-
- xml_data = etree.tostring(root, pretty_print=True).decode()
- with open('output.xml', 'w') as f:
- f.write(xml_data)
diff --git a/smoketest/configs/bgp-evpn-l2vpn-leaf b/smoketest/configs/bgp-evpn-l2vpn-leaf
index 020490186..ab46fbb02 100644
--- a/smoketest/configs/bgp-evpn-l2vpn-leaf
+++ b/smoketest/configs/bgp-evpn-l2vpn-leaf
@@ -33,7 +33,6 @@ interfaces {
parameters {
nolearning
}
- port 4789
source-address 172.29.0.1
vni 100
}
diff --git a/smoketest/configs/cluster-basic b/smoketest/configs/cluster-basic
new file mode 100644
index 000000000..1e34999c1
--- /dev/null
+++ b/smoketest/configs/cluster-basic
@@ -0,0 +1,62 @@
+cluster {
+ dead-interval 500
+ group VyOS {
+ auto-failback true
+ primary vyos1
+ secondary vyos2
+ service 192.0.2.10/24/eth1
+ service 192.0.2.20/24
+ }
+ interface eth1
+ keepalive-interval 100
+ monitor-dead-interval 420
+ pre-shared-secret qwerty
+}
+interfaces {
+ ethernet eth0 {
+ duplex auto
+ smp-affinity auto
+ speed auto
+ }
+ ethernet eth1 {
+ address 192.0.2.1/24
+ duplex auto
+ smp-affinity auto
+ speed auto
+ }
+ loopback lo {
+ }
+}
+system {
+ config-management {
+ commit-revisions 100
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0
+ plaintext-password ""
+ }
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level info
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ }
+ time-zone Antarctica/South_Pole
+}
+// Warning: Do not remove the following line.
+// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@3:conntrack-sync@2:container@1:dhcp-relay@2:dhcp-server@6:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@22:ipoe-server@1:ipsec@5:isis@1:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@8:rpki@1:salt@1:snmp@2:ssh@2:sstp@3:system@21:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1"
+// Release version: 1.3.3
diff --git a/src/conf_mode/interfaces-vxlan.py b/src/conf_mode/interfaces-vxlan.py
index 05f68112a..ff8144e74 100755
--- a/src/conf_mode/interfaces-vxlan.py
+++ b/src/conf_mode/interfaces-vxlan.py
@@ -168,6 +168,13 @@ def verify(vxlan):
verify_address(vxlan)
verify_bond_bridge_member(vxlan)
verify_mirror_redirect(vxlan)
+
+ # We use a defaultValue for port, thus it's always safe to use
+ if vxlan['port'] == '8472':
+ Warning('Starting from VyOS 1.4, the default port for VXLAN '\
+ 'has been changed to 4789. This matches the IANA assigned '\
+ 'standard port number!')
+
return None
def generate(vxlan):
diff --git a/src/migration-scripts/interfaces/31-to-32 b/src/migration-scripts/interfaces/31-to-32
new file mode 100755
index 000000000..35b397c39
--- /dev/null
+++ b/src/migration-scripts/interfaces/31-to-32
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# T5671: change port to IANA assigned default port
+
+from sys import argv
+from sys import exit
+from vyos.configtree import ConfigTree
+
+if len(argv) < 2:
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+with open(file_name, 'r') as f:
+ config_file = f.read()
+ base = ['interfaces', 'vxlan']
+
+config = ConfigTree(config_file)
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+for vxlan in config.list_nodes(base):
+ if not config.exists(base + ['port']):
+ config.set(base + [vxlan, 'port'], value='8472')
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print(f'Failed to save the modified config: {e}')
+ exit(1)