Page Menu
Home
VyOS Platform
Search
Configure Global Search
Log In
Files
F119062183
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/interface-definitions/interfaces-dummy.xml b/interface-definitions/interfaces-dummy.xml
new file mode 100644
index 000000000..7c425480a
--- /dev/null
+++ b/interface-definitions/interfaces-dummy.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="interfaces">
+ <children>
+ <tagNode name="dummy" owner="${vyos_conf_scripts_dir}/interface-dummy.py">
+ <properties>
+ <help>Dummy interface name</help>
+ <priority>300</priority>
+ <constraint>
+ <regex>dum[0-9]+$</regex>
+ </constraint>
+ <constraintErrorMessage>Dummy interface must be named dumN</constraintErrorMessage>
+ <valueHelp>
+ <format>dumN</format>
+ <description>Dummy interface name</description>
+ </valueHelp>
+ </properties>
+ <children>
+ <leafNode name="address">
+ <properties>
+ <help>IP address</help>
+ <valueHelp>
+ <format>ipv4net</format>
+ <description>IPv4 address and prefix length</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6net</format>
+ <description>IPv6 address and prefix length</description>
+ </valueHelp>
+ <multi/>
+ </properties>
+ </leafNode>
+ <leafNode name="description">
+ <properties>
+ <help>Interface description</help>
+ <constraint>
+ <regex>^.{1,256}$</regex>
+ </constraint>
+ <constraintErrorMessage>Interface description too long (limit 256 characters)</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ <leafNode name="disable">
+ <properties>
+ <help>Disable interface</help>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/python/vyos/configinterface.py b/python/vyos/configinterface.py
index 0f5b0842c..188d5b9e2 100644
--- a/python/vyos/configinterface.py
+++ b/python/vyos/configinterface.py
@@ -1,153 +1,172 @@
# Copyright 2019 VyOS maintainers and contributors <maintainers@vyos.io>
#
# 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, see <http://www.gnu.org/licenses/>.
import os
import vyos.validate
def validate_mac_address(addr):
# a mac address consits out of 6 octets
octets = len(addr.split(':'))
if octets != 6:
raise ValueError('wrong number of MAC octets: {} '.format(octets))
# validate against the first mac address byte if it's a multicast address
if int(addr.split(':')[0]) & 1:
raise ValueError('{} is a multicast MAC address'.format(addr))
# overall mac address is not allowed to be 00:00:00:00:00:00
if sum(int(i, 16) for i in addr.split(':')) == 0:
raise ValueError('00:00:00:00:00:00 is not a valid MAC address')
# check for VRRP mac address
if addr.split(':')[0] == '0' and addr.split(':')[1] == '0' and addr.split(':')[2] == '94' and addr.split(':')[3] == '0' and addr.split(':')[4] == '1':
raise ValueError('{} is a VRRP MAC address')
pass
def set_mac_address(intf, addr):
"""
Configure interface mac address using iproute2 command
"""
validate_mac_address(addr)
os.system('ip link set {} address {}'.format(intf, addr))
pass
def set_description(intf, desc):
"""
Sets the interface secription reported usually by SNMP
"""
with open('/sys/class/net/' + intf + '/ifalias', 'w') as f:
f.write(desc)
pass
def set_arp_cache_timeout(intf, tmoMS):
"""
Configure the ARP cache entry timeout in milliseconds
"""
with open('/proc/sys/net/ipv4/neigh/' + intf + '/base_reachable_time_ms', 'w') as f:
f.write(tmoMS)
pass
def set_multicast_querier(intf, enable):
"""
Sets whether the bridge actively runs a multicast querier or not. When a
bridge receives a 'multicast host membership' query from another network host,
that host is tracked based on the time that the query was received plus the
multicast query interval time.
use enable=1 to enable or enable=0 to disable
"""
if int(enable) >= 0 and int(enable) <= 1:
with open('/sys/devices/virtual/net/' + intf + '/bridge/multicast_querier', 'w') as f:
f.write(str(enable))
else:
raise ValueError("malformed configuration string on interface {}: enable={}".format(intf, enable))
pass
def set_link_detect(intf, enable):
"""
0 - Allow packets to be received for the address on this interface
even if interface is disabled or no carrier.
1 - Ignore packets received if interface associated with the incoming
address is down.
2 - Ignore packets received if interface associated with the incoming
address is down or has no carrier.
Kernel Source: Documentation/networking/ip-sysctl.txt
"""
# Note can't use sysctl it is broken for vif name because of dots
# link_filter values:
# 0 - always receive
# 1 - ignore receive if admin_down
# 2 - ignore receive if admin_down or link down
with open('/proc/sys/net/ipv4/conf/' + intf + '/link_filter', 'w') as f:
if enable == True or enable == 1:
f.write('2')
if os.path.isfile('/usr/bin/vtysh'):
os.system('/usr/bin/vtysh -c "configure terminal" -c "interface {}" -c "link-detect"'.format(intf))
else:
f.write('1')
if os.path.isfile('/usr/bin/vtysh'):
os.system('/usr/bin/vtysh -c "configure terminal" -c "interface {}" -c "no link-detect"'.format(intf))
pass
def add_interface_address(intf, addr):
"""
Configure an interface IPv4/IPv6 address
"""
if addr == "dhcp":
os.system('/opt/vyatta/sbin/vyatta-interfaces.pl --dev="{}" --dhcp=start'.format(intf))
elif addr == "dhcpv6":
os.system('/opt/vyatta/sbin/vyatta-dhcpv6-client.pl --start -ifname "{}"'.format(intf))
elif vyos.validate.is_ipv4(addr):
if not vyos.validate.is_intf_addr_assigned(intf, addr):
- print("Assigning {} to {}".format(addr, intf))
os.system('sudo ip -4 addr add "{}" broadcast + dev "{}"'.format(addr, intf))
elif vyos.validate.is_ipv6(addr):
if not vyos.validate.is_intf_addr_assigned(intf, addr):
- print("Assigning {} to {}".format(addr, intf))
os.system('sudo ip -6 addr add "{}" dev "{}"'.format(addr, intf))
else:
raise ConfigError('{} is not a valid interface address'.format(addr))
pass
def remove_interface_address(intf, addr):
"""
Remove IPv4/IPv6 address from given interface
"""
if addr == "dhcp":
os.system('/opt/vyatta/sbin/vyatta-interfaces.pl --dev="{}" --dhcp=stop'.format(intf))
elif addr == "dhcpv6":
os.system('/opt/vyatta/sbin/vyatta-dhcpv6-client.pl --stop -ifname "{}"'.format(intf))
elif vyos.validate.is_ipv4(addr):
os.system('ip -4 addr del "{}" dev "{}"'.format(addr, intf))
elif vyos.validate.is_ipv6(addr):
os.system('ip -6 addr del "{}" dev "{}"'.format(addr, intf))
else:
raise ConfigError('{} is not a valid interface address'.format(addr))
pass
+
+def remove_interface(ifname):
+ """
+ Remove given interface from operating system, e.g. 'dum0'
+ """
+
+ if os.path.isdir('/sys/class/net/' + ifname):
+ os.system('ip link delete "{}"'.format(ifname))
+
+ pass
+
+def add_interface(type, ifname):
+ """
+ Add given interface to operating system, e.g. add 'dummy' interface with
+ name 'dum0'
+ """
+
+ if not os.path.isdir('/sys/class/net/' + ifname):
+ os.system('ip link add "{}" type "{}"'.format(ifname, type))
+
+ pass
diff --git a/src/conf_mode/interface-dummy.py b/src/conf_mode/interface-dummy.py
new file mode 100755
index 000000000..668e4acc7
--- /dev/null
+++ b/src/conf_mode/interface-dummy.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2019 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/>.
+#
+#
+
+import os
+import sys
+import copy
+
+import vyos.configinterface as VyIfconfig
+
+from vyos.config import Config
+from vyos import ConfigError
+
+default_config_data = {
+ 'address': [],
+ 'address_remove': [],
+ 'deleted': False,
+ 'description': '',
+ 'disable': False,
+ 'intf': ''
+}
+
+def diff(first, second):
+ second = set(second)
+ return [item for item in first if item not in second]
+
+def get_config():
+ dummy = copy.deepcopy(default_config_data)
+ conf = Config()
+
+ # determine tagNode instance
+ try:
+ dummy['intf'] = os.environ['VYOS_TAGNODE_VALUE']
+ except KeyError as E:
+ print("Interface not specified")
+
+ # Check if interface has been removed
+ if not conf.exists('interfaces dummy ' + dummy['intf']):
+ dummy['deleted'] = True
+ return dummy
+
+ # set new configuration level
+ conf.set_level('interfaces dummy ' + dummy['intf'])
+
+ # retrieve configured interface addresses
+ if conf.exists('address'):
+ dummy['address'] = conf.return_values('address')
+
+ # retrieve interface description
+ if conf.exists('description'):
+ dummy['description'] = conf.return_value('description')
+
+ # Disable this interface
+ if conf.exists('disable'):
+ dummy['disable'] = True
+
+ # Determine interface addresses (currently effective) - to determine which
+ # address is no longer valid and needs to be removed from the interface
+ eff_addr = conf.return_effective_values('address')
+ act_addr = conf.return_values('address')
+ dummy['address_remove'] = diff(eff_addr, act_addr)
+
+ return dummy
+
+def verify(dummy):
+ if dummy is None:
+ return None
+
+ return None
+
+def generate(dummy):
+ if dummy is None:
+ return None
+
+ return None
+
+def apply(dummy):
+ if dummy is None:
+ return None
+
+ # Remove dummy interface
+ if dummy['deleted']:
+ VyIfconfig.remove_interface(dummy['intf'])
+ else:
+ # Interface will only be added if it yet does not exist
+ VyIfconfig.add_interface('dummy', dummy['intf'])
+
+ # update interface description used e.g. within SNMP
+ VyIfconfig.set_description(dummy['intf'], dummy['description'])
+
+ # Configure interface address(es)
+ for addr in dummy['address_remove']:
+ VyIfconfig.remove_interface_address(dummy['intf'], addr)
+
+ for addr in dummy['address']:
+ VyIfconfig.add_interface_address(dummy['intf'], addr)
+
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ sys.exit(1)
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Nov 6, 6:20 AM (2 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4652704
Default Alt Text
(11 KB)
Attached To
Mode
rVYOSONEX vyos-1x
Attached
Detach File
Event Timeline
Log In to Comment