diff options
-rw-r--r-- | data/templates/accel-ppp/l2tp.config.tmpl | 3 | ||||
-rw-r--r-- | data/templates/dhcp-client/ipv4.tmpl | 7 | ||||
-rw-r--r-- | data/templates/lcd/LCDd.conf.tmpl | 7 | ||||
-rw-r--r-- | data/templates/ntp/ntpd.conf.tmpl | 2 | ||||
-rw-r--r-- | debian/control | 1 | ||||
-rw-r--r-- | interface-definitions/containers.xml.in | 24 | ||||
-rw-r--r-- | interface-definitions/system-lcd.xml.in | 8 | ||||
-rw-r--r-- | interface-definitions/vpn_l2tp.xml.in | 8 | ||||
-rw-r--r-- | python/vyos/configdict.py | 38 | ||||
-rwxr-xr-x | python/vyos/ifconfig/interface.py | 10 | ||||
-rwxr-xr-x | src/conf_mode/containers.py | 10 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-tunnel.py | 15 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-wireless.py | 5 | ||||
-rwxr-xr-x | src/conf_mode/vpn_l2tp.py | 2 | ||||
-rwxr-xr-x | src/validators/bgp-large-community-list | 2 |
15 files changed, 110 insertions, 32 deletions
diff --git a/data/templates/accel-ppp/l2tp.config.tmpl b/data/templates/accel-ppp/l2tp.config.tmpl index 44c96b935..9fcda76d4 100644 --- a/data/templates/accel-ppp/l2tp.config.tmpl +++ b/data/templates/accel-ppp/l2tp.config.tmpl @@ -57,6 +57,9 @@ bind={{ outside_addr }} {% if lns_shared_secret %} secret={{ lns_shared_secret }} {% endif %} +{% if lns_host_name %} +host-name={{ lns_host_name }} +{% endif %} [client-ip-range] 0.0.0.0/0 diff --git a/data/templates/dhcp-client/ipv4.tmpl b/data/templates/dhcp-client/ipv4.tmpl index c934b7cdb..11e961166 100644 --- a/data/templates/dhcp-client/ipv4.tmpl +++ b/data/templates/dhcp-client/ipv4.tmpl @@ -7,7 +7,12 @@ retry 300; interface "{{ ifname }}" { send host-name "{{ dhcp_options.host_name }}"; {% if dhcp_options.client_id is defined and dhcp_options.client_id is not none %} - send dhcp-client-identifier "{{ dhcp_options.client_id }}"; +{% set client_id = dhcp_options.client_id %} +{# Use HEX representation of client-id as it is send in MAC-address style using hex characters. If not HEX, use double quotes ASCII format #} +{% if not dhcp_options.client_id.split(':') | length >= 5 %} +{% set client_id = '"' + dhcp_options.client_id + '"' %} +{% endif %} + send dhcp-client-identifier {{ client_id }}; {% endif %} {% if dhcp_options.vendor_class_id is defined and dhcp_options.vendor_class_id is not none %} send vendor-class-identifier "{{ dhcp_options.vendor_class_id }}"; diff --git a/data/templates/lcd/LCDd.conf.tmpl b/data/templates/lcd/LCDd.conf.tmpl index 6cf6a440f..2c7ad920f 100644 --- a/data/templates/lcd/LCDd.conf.tmpl +++ b/data/templates/lcd/LCDd.conf.tmpl @@ -53,6 +53,8 @@ DriverPath=/usr/lib/x86_64-linux-gnu/lcdproc/ Driver=CFontzPacket {% elif model == 'sdec' %} Driver=sdeclcd +{% elif model == 'hd44780' %} +Driver=hd44780 {% endif %} {% endif %} @@ -128,5 +130,10 @@ USB=yes ## SDEC driver for Lanner, Watchguard, Sophos sppliances ## [sdeclcd] # No options +{% elif model == 'hd44780' %} +[hd44780] +ConnectionType=ezio +Device={{ device }} +Size=16x2 {% endif %} {% endif %} diff --git a/data/templates/ntp/ntpd.conf.tmpl b/data/templates/ntp/ntpd.conf.tmpl index 2b56b53c3..38e68f24f 100644 --- a/data/templates/ntp/ntpd.conf.tmpl +++ b/data/templates/ntp/ntpd.conf.tmpl @@ -6,6 +6,8 @@ driftfile /var/lib/ntp/ntp.drift # By default, only allow ntpd to query time sources, ignore any incoming requests restrict default noquery nopeer notrap nomodify +# Allow pool associations +restrict source nomodify notrap noquery # Local users have unrestricted access, allowing reconfiguration via ntpdc restrict 127.0.0.1 restrict -6 ::1 diff --git a/debian/control b/debian/control index f3a26e73e..6c0f2f886 100644 --- a/debian/control +++ b/debian/control @@ -72,6 +72,7 @@ Depends: iw, keepalived (>=2.0.5), lcdproc, + lcdproc-extra-drivers, libatomic1, libcharon-extra-plugins (>=5.9), libcharon-extauth-plugins (>=5.9), diff --git a/interface-definitions/containers.xml.in b/interface-definitions/containers.xml.in index fb8241d71..24d1870af 100644 --- a/interface-definitions/containers.xml.in +++ b/interface-definitions/containers.xml.in @@ -21,6 +21,30 @@ <valueless/> </properties> </leafNode> + <leafNode name="cap-add"> + <properties> + <help>Add capabilities</help> + <completionHelp> + <list>net-admin setpcap sys-time</list> + </completionHelp> + <valueHelp> + <format>net-admin</format> + <description>Net-admin option</description> + </valueHelp> + <valueHelp> + <format>setpcap</format> + <description>Setpcap option</description> + </valueHelp> + <valueHelp> + <format>sys-time</format> + <description>Sys-time option</description> + </valueHelp> + <constraint> + <regex>^(net-admin|setpcap|sys-time)$</regex> + </constraint> + <multi/> + </properties> + </leafNode> #include <include/generic-description.xml.i> #include <include/generic-disable-node.xml.i> <tagNode name="environment"> diff --git a/interface-definitions/system-lcd.xml.in b/interface-definitions/system-lcd.xml.in index 36116ae1b..4c9d5c92e 100644 --- a/interface-definitions/system-lcd.xml.in +++ b/interface-definitions/system-lcd.xml.in @@ -12,7 +12,7 @@ <properties> <help>Model of the display attached to this system [REQUIRED]</help> <completionHelp> - <list>cfa-533 cfa-631 cfa-633 cfa-635 sdec</list> + <list>cfa-533 cfa-631 cfa-633 cfa-635 hd44780 sdec</list> </completionHelp> <valueHelp> <format>cfa-533</format> @@ -31,11 +31,15 @@ <description>Crystalfontz CFA-635</description> </valueHelp> <valueHelp> + <format>hd44780</format> + <description>Hitachi HD44780, Caswell Appliances</description> + </valueHelp> + <valueHelp> <format>sdec</format> <description>Lanner, Watchguard, Nexcom NSA, Sophos UTM appliances</description> </valueHelp> <constraint> - <regex>^(cfa-533|cfa-631|cfa-633|cfa-635|sdec)$</regex> + <regex>^(cfa-533|cfa-631|cfa-633|cfa-635|hd44780|sdec)$</regex> </constraint> </properties> </leafNode> diff --git a/interface-definitions/vpn_l2tp.xml.in b/interface-definitions/vpn_l2tp.xml.in index cbd5e38e7..6a88756a7 100644 --- a/interface-definitions/vpn_l2tp.xml.in +++ b/interface-definitions/vpn_l2tp.xml.in @@ -34,6 +34,14 @@ <help>Tunnel password used to authenticate the client (LAC)</help> </properties> </leafNode> + <leafNode name="host-name"> + <properties> + <help>Sent to the client (LAC) in the Host-Name attribute</help> + <constraint> + <regex>[A-Za-z0-9][-.A-Za-z0-9]*[A-Za-z0-9]</regex> + </constraint> + </properties> + </leafNode> </children> </node> <leafNode name="ccp-disable"> diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index 5c6836e97..8308f0e9b 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -368,9 +368,11 @@ def get_interface_dict(config, base, ifname=''): del default_values['dhcpv6_options'] # We have gathered the dict representation of the CLI, but there are - # default options which we need to update into the dictionary - # retrived. - dict = dict_merge(default_values, dict) + # default options which we need to update into the dictionary retrived. + # But we should only add them when interface is not deleted - as this might + # confuse parsers + if 'deleted' not in dict: + dict = dict_merge(default_values, dict) # XXX: T2665: blend in proper DHCPv6-PD default values dict = T2665_set_dhcpv6pd_defaults(dict) @@ -423,9 +425,12 @@ def get_interface_dict(config, base, ifname=''): if not 'dhcpv6_options' in vif_config: del default_vif_values['dhcpv6_options'] - dict['vif'][vif] = dict_merge(default_vif_values, vif_config) - # XXX: T2665: blend in proper DHCPv6-PD default values - dict['vif'][vif] = T2665_set_dhcpv6pd_defaults(dict['vif'][vif]) + # Only add defaults if interface is not about to be deleted - this is + # to keep a cleaner config dict. + if 'deleted' not in dict: + dict['vif'][vif] = dict_merge(default_vif_values, vif_config) + # XXX: T2665: blend in proper DHCPv6-PD default values + dict['vif'][vif] = T2665_set_dhcpv6pd_defaults(dict['vif'][vif]) # Check if we are a member of a bridge device bridge = is_member(config, f'{ifname}.{vif}', 'bridge') @@ -441,10 +446,12 @@ def get_interface_dict(config, base, ifname=''): if not 'dhcpv6_options' in vif_s_config: del default_vif_s_values['dhcpv6_options'] - dict['vif_s'][vif_s] = dict_merge(default_vif_s_values, vif_s_config) - # XXX: T2665: blend in proper DHCPv6-PD default values - dict['vif_s'][vif_s] = T2665_set_dhcpv6pd_defaults( - dict['vif_s'][vif_s]) + # Only add defaults if interface is not about to be deleted - this is + # to keep a cleaner config dict. + if 'deleted' not in dict: + dict['vif_s'][vif_s] = dict_merge(default_vif_s_values, vif_s_config) + # XXX: T2665: blend in proper DHCPv6-PD default values + dict['vif_s'][vif_s] = T2665_set_dhcpv6pd_defaults(dict['vif_s'][vif_s]) # Check if we are a member of a bridge device bridge = is_member(config, f'{ifname}.{vif_s}', 'bridge') @@ -458,11 +465,14 @@ def get_interface_dict(config, base, ifname=''): if not 'dhcpv6_options' in vif_c_config: del default_vif_c_values['dhcpv6_options'] - dict['vif_s'][vif_s]['vif_c'][vif_c] = dict_merge( + # Only add defaults if interface is not about to be deleted - this is + # to keep a cleaner config dict. + if 'deleted' not in dict: + dict['vif_s'][vif_s]['vif_c'][vif_c] = dict_merge( default_vif_c_values, vif_c_config) - # XXX: T2665: blend in proper DHCPv6-PD default values - dict['vif_s'][vif_s]['vif_c'][vif_c] = T2665_set_dhcpv6pd_defaults( - dict['vif_s'][vif_s]['vif_c'][vif_c]) + # XXX: T2665: blend in proper DHCPv6-PD default values + dict['vif_s'][vif_s]['vif_c'][vif_c] = T2665_set_dhcpv6pd_defaults( + dict['vif_s'][vif_s]['vif_c'][vif_c]) # Check if we are a member of a bridge device bridge = is_member(config, f'{ifname}.{vif_s}.{vif_c}', 'bridge') diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index e6dbd861b..c73ffb634 100755 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -461,15 +461,19 @@ class Interface(Control): # Get processor ID number cpu_id = self._cmd('sudo dmidecode -t 4 | grep ID | head -n1 | sed "s/.*ID://;s/ //g"') - # Get system eth0 base MAC address - every system has eth0 - eth0_mac = Interface('eth0').get_mac() + + # XXX: T3894 - it seems not all systems have eth0 - get a list of all + # available Ethernet interfaces on the system (without VLAN subinterfaces) + # and then take the first one. + all_eth_ifs = [x for x in Section.interfaces('ethernet') if '.' not in x] + first_mac = Interface(all_eth_ifs[0]).get_mac() sha = sha256() # Calculate SHA256 sum based on the CPU ID number, eth0 mac address and # this interface identifier - this is as predictable as an interface # MAC address and thus can be used in the same way sha.update(cpu_id.encode()) - sha.update(eth0_mac.encode()) + sha.update(first_mac.encode()) sha.update(self.ifname.encode()) # take the most significant 48 bits from the SHA256 string tmp = sha.hexdigest()[:12] diff --git a/src/conf_mode/containers.py b/src/conf_mode/containers.py index 1e0197a13..cc34f9d39 100755 --- a/src/conf_mode/containers.py +++ b/src/conf_mode/containers.py @@ -271,6 +271,14 @@ def apply(container): tmp = run(f'podman image exists {image}') if tmp != 0: print(os.system(f'podman pull {image}')) + # Add capability options. Should be in uppercase + cap_add = '' + if 'cap_add' in container_config: + for c in container_config['cap_add']: + c = c.upper() + c = c.replace('-', '_') + cap_add += f' --cap-add={c}' + # Check/set environment options "-e foo=bar" env_opt = '' if 'environment' in container_config: @@ -299,7 +307,7 @@ def apply(container): dvol = vol_config['destination'] volume += f' -v {svol}:{dvol}' - container_base_cmd = f'podman run --detach --interactive --tty --replace ' \ + container_base_cmd = f'podman run --detach --interactive --tty --replace {cap_add} ' \ f'--memory {memory}m --memory-swap 0 --restart {restart} ' \ f'--name {name} {port} {volume} {env_opt}' if 'allow_host_networks' in container_config: diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index ef385d2e7..51127127d 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -108,18 +108,17 @@ def verify(tunnel): # Prevent the same key for 2 tunnels with same source-address/encap. T2920 for tunnel_if in Section.interfaces('tunnel'): tunnel_cfg = get_interface_config(tunnel_if) - exist_encap = tunnel_cfg['linkinfo']['info_kind'] - exist_source_address = tunnel_cfg['address'] - exist_key = tunnel_cfg['linkinfo']['info_data']['ikey'] + # no match on encapsulation - bail out + if dict_search('linkinfo.info_kind', tunnel_cfg) != tunnel['encapsulation']: + continue new_source_address = tunnel['source_address'] # Convert tunnel key to ip key, format "ip -j link show" # 1 => 0.0.0.1, 999 => 0.0.3.231 - orig_new_key = int(tunnel['parameters']['ip']['key']) - new_key = IPv4Address(orig_new_key) + orig_new_key = dict_search('parameters.ip.key', tunnel) + new_key = IPv4Address(int(orig_new_key)) new_key = str(new_key) - if tunnel['encapsulation'] == exist_encap and \ - new_source_address == exist_source_address and \ - new_key == exist_key: + if dict_search('address', tunnel_cfg) == new_source_address and \ + dict_search('linkinfo.info_data.ikey', tunnel_cfg) == new_key: raise ConfigError(f'Key "{orig_new_key}" for source-address "{new_source_address}" ' \ f'is already used for tunnel "{tunnel_if}"!') diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py index 7b3de6e8a..af35b5f03 100755 --- a/src/conf_mode/interfaces-wireless.py +++ b/src/conf_mode/interfaces-wireless.py @@ -82,11 +82,12 @@ def get_config(config=None): tmp = conf.get_config_dict([], key_mangling=('-', '_'), get_first_key=True) if not (dict_search('security.wpa.passphrase', tmp) or dict_search('security.wpa.radius', tmp)): - del wifi['security']['wpa'] + if 'deleted' not in wifi: + del wifi['security']['wpa'] # defaults include RADIUS server specifics per TAG node which need to be # added to individual RADIUS servers instead - so we can simply delete them - if dict_search('security.wpa.radius.server.port', wifi): + if dict_search('security.wpa.radius.server.port', wifi) != None: del wifi['security']['wpa']['radius']['server']['port'] if not len(wifi['security']['wpa']['radius']['server']): del wifi['security']['wpa']['radius'] diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py index 9c52f77ca..818e8fa0b 100755 --- a/src/conf_mode/vpn_l2tp.py +++ b/src/conf_mode/vpn_l2tp.py @@ -290,6 +290,8 @@ def get_config(config=None): # LNS secret if conf.exists(['lns', 'shared-secret']): l2tp['lns_shared_secret'] = conf.return_value(['lns', 'shared-secret']) + if conf.exists(['lns', 'host-name']): + l2tp['lns_host_name'] = conf.return_value(['lns', 'host-name']) if conf.exists(['ccp-disable']): l2tp['ccp_disable'] = True diff --git a/src/validators/bgp-large-community-list b/src/validators/bgp-large-community-list index c07268e81..80112dfdc 100755 --- a/src/validators/bgp-large-community-list +++ b/src/validators/bgp-large-community-list @@ -30,7 +30,7 @@ if __name__ == '__main__': sys.exit(1) if not (re.match(pattern, sys.argv[1]) and - (is_ipv4(value[0]) or value[0].isdigit()) and value[1].isdigit()): + (is_ipv4(value[0]) or value[0].isdigit()) and (value[1].isdigit() or value[1] == '*')): sys.exit(1) sys.exit(0) |