From ab5ca2796c1aad0043cc0db80299e4e2d42c1b22 Mon Sep 17 00:00:00 2001 From: hagbard Date: Thu, 25 Jul 2019 09:48:08 -0700 Subject: [accel-l2tp] - T834: l2tp implementation - node.def deletion for show remote-access - IPSec interface checking for L2TP - IPSec x509 for l2tp - verification of outside-address to warning since it was optional in the previous config --- Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 2e49a204c..063e9b009 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ op_mode_definitions: rm -f $(OP_TMPL_DIR)/restart/node.def rm -f $(OP_TMPL_DIR)/monitor/node.def rm -f $(OP_TMPL_DIR)/generate/node.def + rm -f $(OP_TMPL_DIR)/show/vpn/node.def .PHONY: all all: clean interface_definitions op_mode_definitions -- cgit v1.2.3 From 0faeedf5c381659d62164ee503127bca0b6897fd Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 2 Aug 2019 11:33:35 +0200 Subject: [bridge] T1156: first working implementation using Python and XML --- Makefile | 1 + interface-definitions/interfaces-bridge.xml | 245 ++++++++++++++++++++++++++++ python/vyos/configinterface.py | 77 +++++++++ src/conf_mode/interface-bridge.py | 227 ++++++++++++++++++++++++++ 4 files changed, 550 insertions(+) create mode 100644 interface-definitions/interfaces-bridge.xml create mode 100644 python/vyos/configinterface.py create mode 100755 src/conf_mode/interface-bridge.py (limited to 'Makefile') diff --git a/Makefile b/Makefile index 063e9b009..89b83d4f4 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ interface_definitions: # XXX: delete top level node.def's that now live in other packages rm -f $(TMPL_DIR)/firewall/node.def rm -f $(TMPL_DIR)/interfaces/node.def + rm -f $(TMPL_DIR)/interfaces/bridge/node.tag/ip/node.def rm -f $(TMPL_DIR)/protocols/node.def rm -f $(TMPL_DIR)/protocols/static/node.def rm -f $(TMPL_DIR)/system/node.def diff --git a/interface-definitions/interfaces-bridge.xml b/interface-definitions/interfaces-bridge.xml new file mode 100644 index 000000000..a5f2df5b5 --- /dev/null +++ b/interface-definitions/interfaces-bridge.xml @@ -0,0 +1,245 @@ + + + + + + + Bridge interface name + 310 + + ^br[0-9]+$ + + Bridge interface must be named brN + + brN + Bridge interface name + + + + + + IP address + 320 + + ipv4net + IPv4 address and prefix length + + + ipv6net + IPv6 address and prefix length + + + dhcp + Dynamic Host Configuration Protocol + + + dhcpv6 + Dynamic Host Configuration Protocol for IPv6 + + + + + + + Interval addresses are retained + + 0 + Disable retaining address in bridge (always flood) + + + 10-1000000 + Address aging time for bridge seconds (default 300) + + + + + + + + + Interface description + + ^.{1,256}$ + + Interface description too long (limit 256 characters) + + + + + DHCP options + + + + + DHCP client identifier + + + + + DHCP client host name (overrides the system host name) + + + + + + + DHCPv6 options + 319 + + + + + Acquire only config parameters, no address + + + + + + IPv6 "temporary" address + + + + + + + + Ignore link state changes + + + + + + Disable this bridge interface + + + + + Forwarding delay + + 0-200 + Spanning Tree Protocol forwarding delay in seconds (default 15) + + + + + Forwarding delay must be between 0 and 200 seconds + + + + + Hello packet advertisment interval + + 1-10 + Spanning Tree Protocol hello advertisement interval in seconds (default 2) + + + + + Bridge Hello interval must be between 1 and 10 seconds + + + + + IGMP snooping settings + + + + + Enable or disable IGMP querier + + enable disable + + + enable + Enable IGMP querier + + + disable + Disable IGMP querier + + + (enable|disable) + + + + + + + + + + ARP cache entry timeout in seconds + + 1-86400 + ARP cache entry timout in seconds (default 30) + + + + + Bridge max aging value must be between 6 and 86400 seconds + + + + + + + Media Access Control (MAC) address + + h:h:h:h:h:h + Hardware (MAC) address + + + + + + + + + Interval at which neighbor bridges are removed + + 1-40 + Bridge maximum aging time in seconds (default 20) + + + + + Bridge max aging value must be between 1 and 40 seconds + + + + + Priority for this bridge + + 0-65535 + Bridge priority (default 32768) + + + + + Bridge priority must be between 0 and 65535 (multiples of 4096) + + + + + Enable spanning tree protocol + + true false + + + true + Enable Spanning Tree Protocol + + + false + Disable Spanning Tree Protocol + + + (true|false) + + + + + + + + diff --git a/python/vyos/configinterface.py b/python/vyos/configinterface.py new file mode 100644 index 000000000..b0d766b9c --- /dev/null +++ b/python/vyos/configinterface.py @@ -0,0 +1,77 @@ +# Copyright 2019 VyOS maintainers and contributors +# +# 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 . + +import os + +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) + + +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) + +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)) + +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)) diff --git a/src/conf_mode/interface-bridge.py b/src/conf_mode/interface-bridge.py new file mode 100755 index 000000000..f7f70b15d --- /dev/null +++ b/src/conf_mode/interface-bridge.py @@ -0,0 +1,227 @@ +#!/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 . +# +# + +import os +import sys +import copy +import subprocess + +import vyos.configinterface as VyIfconfig + +from vyos.config import Config +from vyos import ConfigError + +default_config_data = { + 'address': [], + 'aging': '300', + 'br_name': '', + 'description': '', + 'deleted': False, + 'dhcp_client_id': '', + 'dhcp_hostname': '', + 'dhcpv6_parameters_only': False, + 'dhcpv6_temporary': False, + 'disable': False, + 'disable_link_detect': False, + 'forwarding_delay': '15', + 'hello_time': '2', + 'igmp_querier': 0, + 'arp_cache_timeout_ms': '30000', + 'mac' : '', + 'max_age': '20', + 'priority': '32768', + 'stp': 'off' +} + +def subprocess_cmd(command): + process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=True) + proc_stdout = process.communicate()[0].strip() + print(proc_stdout) + +def get_config(): + bridge = copy.deepcopy(default_config_data) + conf = Config() + + # determine tagNode instance + try: + bridge['br_name'] = os.environ['VYOS_TAGNODE_VALUE'] + print("Executing script for interface: " + bridge['br_name']) + except KeyError as E: + print("Interface not specified") + + # Check if bridge has been removed + if not conf.exists('interfaces bridge ' + bridge['br_name']): + bridge['deleted'] = True + return bridge + + # set new configuration level + conf.set_level('interfaces bridge ' + bridge['br_name']) + + # retrieve configured interface addresses + if conf.exists('address'): + bridge['address'] = conf.return_values('address') + + # retrieve aging - how long addresses are retained + if conf.exists('aging'): + bridge['aging'] = conf.return_value('aging') + + # retrieve interface description + if conf.exists('description'): + bridge['description'] = conf.return_value('description') + + # DHCP client identifier + if conf.exists('dhcp-options client-id'): + bridge['dhcp_client_id'] = conf.return_value('dhcp-options client-id') + + # DHCP client hostname + if conf.exists('dhcp-options host-name'): + bridge['dhcp_hostname'] = conf.return_value('dhcp-options host-name') + + # DHCPv6 acquire only config parameters, no address + if conf.exists('dhcpv6-options parameters-only'): + bridge['dhcpv6_parameters_only'] = True + + # DHCPv6 IPv6 "temporary" address + if conf.exists('dhcpv6-options temporary'): + bridge['dhcpv6_temporary'] = True + + # Disable this bridge interface + if conf.exists('disable'): + bridge['disable'] = True + + # Ignore link state changes + if conf.exists('disable-link-detect'): + bridge['disable_link_detect'] = True + + # Forwarding delay + if conf.exists('forwarding-delay'): + bridge['forwarding_delay'] = conf.return_value('forwarding-delay') + + # Hello packet advertisment interval + if conf.exists('hello-time'): + bridge['hello_time'] = conf.return_value('hello-time') + + # Enable or disable IGMP querier + if conf.exists('igmp-snooping querier'): + tmp = conf.return_value('igmp-snooping querier') + if tmp == "enable": + bridge['igmp_querier'] = 1 + + # ARP cache entry timeout in seconds + if conf.exists('ip arp-cache-timeout'): + tmp = 1000 * int(conf.return_value('ip arp-cache-timeout')) + bridge['arp_cache_timeout_ms'] = str(tmp) + + # Media Access Control (MAC) address + if conf.exists('mac'): + bridge['mac'] = conf.return_value('mac') + + # Interval at which neighbor bridges are removed + if conf.exists('max-age'): + bridge['max_age'] = conf.return_value('max-age') + + # Priority for this bridge + if conf.exists('priority'): + bridge['priority'] = conf.return_value('priority') + + # Enable spanning tree protocol + if conf.exists('stp'): + tmp = conf.return_value('stp') + if tmp == "true": + bridge['stp'] = 'on' + + return bridge + +def verify(bridge): + if bridge is None: + return None + + return None + +def generate(bridge): + if bridge is None: + return None + + return None + +def apply(bridge): + if bridge is None: + return None + + if bridge['deleted']: + # bridges need to be shutdown first + os.system("ip link set dev {0} down".format(bridge['br_name'])) + # delete bridge + os.system("brctl delbr {0}".format(bridge['br_name'])) + else: + # create bridge if it does not exist + if not os.path.exists("/sys/class/net/" + bridge['br_name']): + os.system("brctl addbr {0}".format(bridge['br_name'])) + + # assemble bridge configuration + # configuration is passed via subprocess to brctl + cmd = '' + + # set ageing time + cmd += 'brctl setageing {0} {1}'.format(bridge['br_name'], bridge['aging']) + cmd += ' && ' + + # set bridge forward delay + cmd += 'brctl setfd {0} {1}'.format(bridge['br_name'], bridge['forwarding_delay']) + cmd += ' && ' + + # set hello time + cmd += 'brctl sethello {0} {1}'.format(bridge['br_name'], bridge['hello_time']) + cmd += ' && ' + + # set max message age + cmd += 'brctl setmaxage {0} {1}'.format(bridge['br_name'], bridge['max_age']) + cmd += ' && ' + + # set bridge priority + cmd += 'brctl setbridgeprio {0} {1}'.format(bridge['br_name'], bridge['priority']) + cmd += ' && ' + + # turn stp on/off + cmd += 'brctl stp {0} {1}'.format(bridge['br_name'], bridge['stp']) + + subprocess_cmd(cmd) + + # update interface description used e.g. within SNMP + VyIfconfig.set_description(bridge['br_name'], bridge['description']) + + # Ignore link state changes? + VyIfconfig.set_link_detect(bridge['br_name'], bridge['disable_link_detect']) + + # enable or disable IGMP querier + VyIfconfig.set_multicast_querier(bridge['br_name'], bridge['igmp_querier']) + + # ARP cache entry timeout in seconds + VyIfconfig.set_arp_cache_timeout(bridge['br_name'], bridge['arp_cache_timeout_ms']) + + return None + +if __name__ == '__main__': + try: + c = get_config() + verify(c) + generate(c) + apply(c) + except ConfigError as e: + print(e) + sys.exit(1) -- cgit v1.2.3