summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2020-05-25 21:02:35 +0200
committerChristian Poessinger <christian@poessinger.com>2020-05-26 17:09:33 +0200
commitd5b58517f88358c686e6c8ea039a7a9a64d6c6ee (patch)
tree416632fd648499c40b8f4b8975c1da568af5401f
parent0cdfa72d5ccd8a2d382164a1ec39865802d1be7c (diff)
downloadvyos-1x-d5b58517f88358c686e6c8ea039a7a9a64d6c6ee.tar.gz
vyos-1x-d5b58517f88358c686e6c8ea039a7a9a64d6c6ee.zip
dhcpv6-pd: pppoe: T2506: restructure CLI
Rename the CLI nodes for prefix delegation from "dhcpv6-options delegate <interface>" to "dhcpv6-options prefix-delegation interface <interface>". The change is required to add the possibility to request for specific prefix sized via the CLI. That option was not possible with the old configuration tree.
-rw-r--r--data/templates/dhcp-client/ipv6.tmpl6
-rw-r--r--data/templates/pppoe/ip-down.script.tmpl2
-rw-r--r--data/templates/pppoe/ipv6-up.script.tmpl2
-rw-r--r--interface-definitions/include/dhcpv6-options.xml.i85
-rw-r--r--python/vyos/configdict.py4
-rw-r--r--python/vyos/ifconfig/dhcp.py3
-rw-r--r--python/vyos/ifconfig_vlan.py4
-rwxr-xr-xsrc/conf_mode/interfaces-bonding.py4
-rwxr-xr-xsrc/conf_mode/interfaces-bridge.py4
-rwxr-xr-xsrc/conf_mode/interfaces-ethernet.py4
-rwxr-xr-xsrc/conf_mode/interfaces-pppoe.py20
-rwxr-xr-xsrc/conf_mode/interfaces-pseudo-ethernet.py4
-rwxr-xr-xsrc/conf_mode/interfaces-wireless.py4
-rwxr-xr-xsrc/migration-scripts/interfaces/9-to-1065
14 files changed, 150 insertions, 61 deletions
diff --git a/data/templates/dhcp-client/ipv6.tmpl b/data/templates/dhcp-client/ipv6.tmpl
index 6cfe24d3e..8957516e2 100644
--- a/data/templates/dhcp-client/ipv6.tmpl
+++ b/data/templates/dhcp-client/ipv6.tmpl
@@ -10,7 +10,7 @@ interface {{ ifname }} {
{% if not dhcpv6_temporary %}
send ia-na 1; # non-temporary address
{% endif %}
-{% if dhcpv6_pd %}
+{% if dhcpv6_pd_interfaces %}
send ia-pd 2; # prefix delegation
{% endif %}
};
@@ -21,9 +21,9 @@ id-assoc na 1 {
};
{% endif %}
-{% if dhcpv6_pd %}
+{% if dhcpv6_pd_interfaces %}
id-assoc pd 2 {
-{% for intf in dhcpv6_pd %}
+{% for intf in dhcpv6_pd_interfaces %}
prefix-interface {{ intf.ifname }} {
{% if intf.sla_id %}
sla-id {{ intf.sla_id }};
diff --git a/data/templates/pppoe/ip-down.script.tmpl b/data/templates/pppoe/ip-down.script.tmpl
index fe8fd7584..c4e11b6b4 100644
--- a/data/templates/pppoe/ip-down.script.tmpl
+++ b/data/templates/pppoe/ip-down.script.tmpl
@@ -27,7 +27,7 @@ fi
vtysh -c "conf t" ${VRF_NAME} -c "no ip route 0.0.0.0/0 {{ intf }} ${VRF_NAME}"
{% endif %}
-{% if dhcpv6_pd %}
+{% if dhcpv6_pd_interfaces %}
# Start wide dhcpv6 client
systemctl stop dhcp6c@{{ intf }}.service
{% endif %}
diff --git a/data/templates/pppoe/ipv6-up.script.tmpl b/data/templates/pppoe/ipv6-up.script.tmpl
index 90873229a..e795d5b0c 100644
--- a/data/templates/pppoe/ipv6-up.script.tmpl
+++ b/data/templates/pppoe/ipv6-up.script.tmpl
@@ -40,7 +40,7 @@ echo 2 > /proc/sys/net/ipv6/conf/{{ intf }}/accept_ra
echo 1 > /proc/sys/net/ipv6/conf/{{ intf }}/autoconfigure
{% endif %}
-{% if dhcpv6_pd %}
+{% if dhcpv6_pd_interfaces %}
# Start wide dhcpv6 client
systemctl start dhcp6c@{{ intf }}.service
{% endif %}
diff --git a/interface-definitions/include/dhcpv6-options.xml.i b/interface-definitions/include/dhcpv6-options.xml.i
index 2c5058d2c..98a87dba2 100644
--- a/interface-definitions/include/dhcpv6-options.xml.i
+++ b/interface-definitions/include/dhcpv6-options.xml.i
@@ -3,52 +3,71 @@
<help>DHCPv6 options</help>
</properties>
<children>
- <tagNode name="delegate">
+ <node name="prefix-delegation">
<properties>
- <help>Delegate IPv6 prefix from provider to this interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces.py --broadcast</script>
- </completionHelp>
+ <help>DHCPv6 Prefix Delegation Options</help>
</properties>
<children>
- <leafNode name="interface-id">
+ <leafNode name="length">
<properties>
- <help>Interface address identifier</help>
+ <help>Request IPv6 prefix length from peer</help>
<valueHelp>
- <format>0-</format>
- <description>Used to form IPv6 interface address (default: EUI-64)</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--non-negative"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="sla-id">
- <properties>
- <help>Interface site-Level aggregator (SLA)</help>
- <valueHelp>
- <format>0-128</format>
- <description>Decimal integer which fits in the length of SLA IDs</description>
+ <format>32-64</format>
+ <description>Length of delegated prefix</description>
</valueHelp>
<constraint>
- <validator name="numeric" argument="--range 0-128"/>
+ <validator name="numeric" argument="--range 32-64"/>
</constraint>
</properties>
</leafNode>
- <leafNode name="sla-len">
+ <tagNode name="interface">
<properties>
- <help>Site-Level aggregator (SLA) length</help>
- <valueHelp>
- <format>0-128</format>
- <description>Length of delegated prefix</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-128"/>
- </constraint>
+ <help>Delegate IPv6 prefix from provider to this interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py --broadcast</script>
+ </completionHelp>
</properties>
- </leafNode>
+ <children>
+ <leafNode name="address">
+ <properties>
+ <help>Local interface address assigned to interface</help>
+ <valueHelp>
+ <format>&gt;0</format>
+ <description>Used to form IPv6 interface address (default: EUI-64)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--non-negative"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="sla-id">
+ <properties>
+ <help>Interface site-Level aggregator (SLA)</help>
+ <valueHelp>
+ <format>0-128</format>
+ <description>Decimal integer which fits in the length of SLA IDs</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-128"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="sla-len">
+ <properties>
+ <help>Site-Level aggregator (SLA) length</help>
+ <valueHelp>
+ <format>0-128</format>
+ <description>Length of delegated prefix</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-128"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
</children>
- </tagNode>
+ </node>
<leafNode name="parameters-only">
<properties>
<help>Acquire only config parameters, no address</help>
diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py
index eec64e964..6afc78039 100644
--- a/python/vyos/configdict.py
+++ b/python/vyos/configdict.py
@@ -112,7 +112,7 @@ interface_default_data = {
'dhcp_vendor_class_id': '',
'dhcpv6_prm_only': False,
'dhcpv6_temporary': False,
- 'dhcpv6_pd': [],
+ 'dhcpv6_pd_interfaces': [],
'disable': False,
'disable_link_detect': 1,
'ip_disable_arp_filter': 1,
@@ -248,7 +248,7 @@ def intf_to_dict(conf, default):
if conf.exists(['interface-id']):
pd['if_id'] = conf.return_value(['interface-id'])
- intf['dhcpv6_pd'].append(pd)
+ intf['dhcpv6_pd_interfaces'].append(pd)
# re-set config level
conf.set_level(current_level)
diff --git a/python/vyos/ifconfig/dhcp.py b/python/vyos/ifconfig/dhcp.py
index f8fdeb6a9..a8b9a2a87 100644
--- a/python/vyos/ifconfig/dhcp.py
+++ b/python/vyos/ifconfig/dhcp.py
@@ -86,7 +86,8 @@ class _DHCPv6 (Control):
'ifname': ifname,
'dhcpv6_prm_only': False,
'dhcpv6_temporary': False,
- 'dhcpv6_pd': [],
+ 'dhcpv6_pd_interfaces': [],
+ 'dhcpv6_pd_length': ''
})
self._conf_file = f'/run/dhcp6c/dhcp6c.{ifname}.conf'
diff --git a/python/vyos/ifconfig_vlan.py b/python/vyos/ifconfig_vlan.py
index a53136ebf..ec4d1da42 100644
--- a/python/vyos/ifconfig_vlan.py
+++ b/python/vyos/ifconfig_vlan.py
@@ -87,8 +87,8 @@ def apply_vlan_config(vlan, config):
if config['dhcpv6_temporary']:
vlan.dhcp.v6.options['dhcpv6_temporary'] = True
- if config['dhcpv6_pd']:
- vlan.dhcp.v6.options['dhcpv6_pd'] = config['dhcpv6_pd']
+ if config['dhcpv6_pd_interfaces']:
+ vlan.dhcp.v6.options['dhcpv6_pd_interfaces'] = config['dhcpv6_pd_interfaces']
# update interface description used e.g. within SNMP
vlan.set_alias(config['description'])
diff --git a/src/conf_mode/interfaces-bonding.py b/src/conf_mode/interfaces-bonding.py
index bdca9d170..b531e97fc 100755
--- a/src/conf_mode/interfaces-bonding.py
+++ b/src/conf_mode/interfaces-bonding.py
@@ -299,8 +299,8 @@ def apply(bond):
if bond['dhcpv6_temporary']:
b.dhcp.v6.options['dhcpv6_temporary'] = True
- if bond['dhcpv6_pd']:
- b.dhcp.v6.options['dhcpv6_pd'] = bond['dhcpv6_pd']
+ if bond['dhcpv6_pd_interfaces']:
+ b.dhcp.v6.options['dhcpv6_pd_interfaces'] = bond['dhcpv6_pd_interfaces']
# ignore link state changes
b.set_link_detect(bond['disable_link_detect'])
diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py
index 3ff339f0f..865d8a999 100755
--- a/src/conf_mode/interfaces-bridge.py
+++ b/src/conf_mode/interfaces-bridge.py
@@ -321,8 +321,8 @@ def apply(bridge):
if bridge['dhcpv6_temporary']:
br.dhcp.v6.options['dhcpv6_temporary'] = True
- if bridge['dhcpv6_pd']:
- br.dhcp.v6.options['dhcpv6_pd'] = br['dhcpv6_pd']
+ if bridge['dhcpv6_pd_interfaces']:
+ br.dhcp.v6.options['dhcpv6_pd_interfaces'] = br['dhcpv6_pd_interfaces']
# assign/remove VRF
br.set_vrf(bridge['vrf'])
diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py
index 0d73a30f1..8ffefc7cf 100755
--- a/src/conf_mode/interfaces-ethernet.py
+++ b/src/conf_mode/interfaces-ethernet.py
@@ -201,8 +201,8 @@ def apply(eth):
if eth['dhcpv6_temporary']:
e.dhcp.v6.options['dhcpv6_temporary'] = True
- if eth['dhcpv6_pd']:
- e.dhcp.v6.options['dhcpv6_pd'] = eth['dhcpv6_pd']
+ if eth['dhcpv6_pd_interfaces']:
+ e.dhcp.v6.options['dhcpv6_pd_interfaces'] = eth['dhcpv6_pd_interfaces']
# ignore link state changes
e.set_link_detect(eth['disable_link_detect'])
diff --git a/src/conf_mode/interfaces-pppoe.py b/src/conf_mode/interfaces-pppoe.py
index 6cde850c9..e8aeb810f 100755
--- a/src/conf_mode/interfaces-pppoe.py
+++ b/src/conf_mode/interfaces-pppoe.py
@@ -36,7 +36,7 @@ default_config_data = {
'deleted': False,
'description': '\0',
'disable': False,
- 'dhcpv6_pd': [],
+ 'dhcpv6_pd_interfaces': [],
'intf': '',
'idle_timeout': '',
'ipv6_autoconf': False,
@@ -137,15 +137,19 @@ def get_config():
if conf.exists('vrf'):
pppoe['vrf'] = conf.return_value(['vrf'])
- if conf.exists(['dhcpv6-options', 'delegate']):
- for interface in conf.list_nodes(['dhcpv6-options', 'delegate']):
+ if conf.exists(['dhcpv6-options', 'prefix-delegation']):
+ dhcpv6_pd_path = base_path + [pppoe['intf'],
+ 'dhcpv6-options', 'prefix-delegation']
+ conf.set_level(dhcpv6_pd_path)
+
+ for interface in conf.list_nodes(['interface']):
+ conf.set_level(dhcpv6_pd_path + ['interface', interface])
pd = {
'ifname': interface,
'sla_id': '',
'sla_len': '',
'if_id': ''
}
- conf.set_level(base_path + [pppoe['intf'], 'dhcpv6-options', 'delegate', interface])
if conf.exists(['sla-id']):
pd['sla_id'] = conf.return_value(['sla-id'])
@@ -153,10 +157,10 @@ def get_config():
if conf.exists(['sla-len']):
pd['sla_len'] = conf.return_value(['sla-len'])
- if conf.exists(['interface-id']):
- pd['if_id'] = conf.return_value(['interface-id'])
+ if conf.exists(['address']):
+ pd['if_id'] = conf.return_value(['address'])
- pppoe['dhcpv6_pd'].append(pd)
+ pppoe['dhcpv6_pd_interfaces'].append(pd)
return pppoe
@@ -223,7 +227,7 @@ def generate(pppoe):
render(script_pppoe_ipv6_up, 'pppoe/ipv6-up.script.tmpl',
pppoe, trim_blocks=True, permission=0o755)
- if len(pppoe['dhcpv6_pd']) > 0:
+ if len(pppoe['dhcpv6_pd_interfaces']) > 0:
# ipv6.tmpl relies on ifname - this should be made consitent in the
# future better then double key-ing the same value
pppoe['ifname'] = intf
diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py
index 3e036a753..c1f52d42c 100755
--- a/src/conf_mode/interfaces-pseudo-ethernet.py
+++ b/src/conf_mode/interfaces-pseudo-ethernet.py
@@ -171,8 +171,8 @@ def apply(peth):
if peth['dhcpv6_temporary']:
p.dhcp.v6.options['dhcpv6_temporary'] = True
- if peth['dhcpv6_pd']:
- p.dhcp.v6.options['dhcpv6_pd'] = peth['dhcpv6_pd']
+ if peth['dhcpv6_pd_interfaces']:
+ p.dhcp.v6.options['dhcpv6_pd_interfaces'] = peth['dhcpv6_pd_interfaces']
# ignore link state changes
p.set_link_detect(peth['disable_link_detect'])
diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py
index 0fa20c5f4..54420acd1 100755
--- a/src/conf_mode/interfaces-wireless.py
+++ b/src/conf_mode/interfaces-wireless.py
@@ -591,8 +591,8 @@ def apply(wifi):
if wifi['dhcpv6_temporary']:
w.dhcp.v6.options['dhcpv6_temporary'] = True
- if wifi['dhcpv6_pd']:
- w.dhcp.v6.options['dhcpv6_pd'] = wifi['dhcpv6_pd']
+ if wifi['dhcpv6_pd_interfaces']:
+ w.dhcp.v6.options['dhcpv6_pd_interfaces'] = wifi['dhcpv6_pd_interfaces']
# ignore link state changes
w.set_link_detect(wifi['disable_link_detect'])
diff --git a/src/migration-scripts/interfaces/9-to-10 b/src/migration-scripts/interfaces/9-to-10
new file mode 100755
index 000000000..ce28627b8
--- /dev/null
+++ b/src/migration-scripts/interfaces/9-to-10
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020 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/>.
+
+# - rename CLI node 'dhcpv6-options delgate' to 'dhcpv6-options prefix-delegation
+# interface'
+# - rename CLI node 'interface-id' for prefix-delegation to 'address' as it
+# represents the local interface IPv6 address assigned by DHCPv6-PD
+
+from sys import exit, argv
+from vyos.configtree import ConfigTree
+
+if __name__ == '__main__':
+ if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+ file_name = argv[1]
+ with open(file_name, 'r') as f:
+ config_file = f.read()
+
+ config = ConfigTree(config_file)
+
+ for intf_type in config.list_nodes(['interfaces']):
+ for intf in config.list_nodes(['interfaces', intf_type]):
+ # cache current config tree
+ base_path = ['interfaces', intf_type, intf, 'dhcpv6-options',
+ 'delegate']
+
+ if config.exists(base_path):
+ # cache new config tree
+ new_path = ['interfaces', intf_type, intf, 'dhcpv6-options',
+ 'prefix-delegation']
+ if not config.exists(new_path):
+ config.set(new_path)
+
+ # copy to new node
+ config.copy(base_path, new_path + ['interface'])
+ print(new_path + ['interface'])
+
+ # rename interface-id to address
+ for interface in config.list_nodes(new_path + ['interface']):
+ config.rename(new_path + ['interface', interface, 'interface-id'], 'address')
+
+ # delete old noe
+ config.delete(base_path)
+
+ try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+ except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ exit(1)