diff options
56 files changed, 445 insertions, 497 deletions
diff --git a/data/templates/accel-ppp/config_ip_pool.j2 b/data/templates/accel-ppp/config_ip_pool.j2 index c567236a4..6ac04e1a1 100644 --- a/data/templates/accel-ppp/config_ip_pool.j2 +++ b/data/templates/accel-ppp/config_ip_pool.j2 @@ -12,10 +12,16 @@ gw-ip-address={{ gateway_address }} {% endif %} {% for pool in ordered_named_pools %} {% for pool_name, pool_config in pool.items() %} +{% set iprange_str = pool_config.range %} +{% set iprange_list = pool_config.range.split('-') %} +{% if iprange_list | length == 2 %} +{% set last_ip_oct = iprange_list[1].split('.') %} +{% set iprange_str = iprange_list[0] + '-' + last_ip_oct[last_ip_oct | length - 1] %} +{% endif %} {% if pool_config.next_pool is vyos_defined %} -{{ pool_config.range }},name={{ pool_name }},next={{ pool_config.next_pool }} +{{ iprange_str }},name={{ pool_name }},next={{ pool_config.next_pool }} {% else %} -{{ pool_config.range }},name={{ pool_name }} +{{ iprange_str }},name={{ pool_name }} {% endif %} {% endfor %} {% endfor %} diff --git a/data/templates/dhcp-server/10-override.conf.j2 b/data/templates/dhcp-server/10-override.conf.j2 new file mode 100644 index 000000000..6cf9e0a11 --- /dev/null +++ b/data/templates/dhcp-server/10-override.conf.j2 @@ -0,0 +1,2 @@ +[Unit] +ConditionFileNotEmpty= diff --git a/data/templates/firewall/nftables-policy.j2 b/data/templates/firewall/nftables-policy.j2 index d77e3f6e9..9e28899b0 100644 --- a/data/templates/firewall/nftables-policy.j2 +++ b/data/templates/firewall/nftables-policy.j2 @@ -28,6 +28,9 @@ table ip vyos_mangle { {{ rule_conf | nft_rule('route', route_text, rule_id, 'ip') }} {% endfor %} {% endif %} +{% if conf.default_log is vyos_defined %} + counter log prefix "[ipv4-{{ (route_text)[:19] }}-default]" +{% endif %} } {% endfor %} {% endif %} @@ -57,6 +60,9 @@ table ip6 vyos_mangle { {{ rule_conf | nft_rule('route6', route_text, rule_id, 'ip6') }} {% endfor %} {% endif %} +{% if conf.default_log is vyos_defined %} + counter log prefix "[ipv6-{{ (route_text)[:19] }}-default]" +{% endif %} } {% endfor %} {% endif %} diff --git a/data/templates/lldp/lldpd.j2 b/data/templates/lldp/lldpd.j2 index 3c499197d..6ae063c4b 100644 --- a/data/templates/lldp/lldpd.j2 +++ b/data/templates/lldp/lldpd.j2 @@ -1,2 +1,2 @@ ### Autogenerated by lldp.py ### -DAEMON_ARGS="-M 4 {{ '-x' if snmp.enable is vyos_defined }} {{ '-c' if legacy_protocols.cdp is vyos_defined }} {{ '-e' if legacy_protocols.edp is vyos_defined }} {{ '-f' if legacy_protocols.fdp is vyos_defined }} {{ '-s' if legacy_protocols.sonmp is vyos_defined }}" +DAEMON_ARGS="-M 4 {{ '-x' if snmp is vyos_defined }} {{ '-c' if legacy_protocols.cdp is vyos_defined }} {{ '-e' if legacy_protocols.edp is vyos_defined }} {{ '-f' if legacy_protocols.fdp is vyos_defined }} {{ '-s' if legacy_protocols.sonmp is vyos_defined }}" diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in index 70afdc995..a4023058f 100644 --- a/interface-definitions/firewall.xml.in +++ b/interface-definitions/firewall.xml.in @@ -368,7 +368,7 @@ </properties> <children> #include <include/generic-description.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> <leafNode name="default-action"> <properties> <help>Default-action for traffic coming into this zone</help> diff --git a/interface-definitions/include/firewall/bridge-custom-name.xml.i b/interface-definitions/include/firewall/bridge-custom-name.xml.i index a85fd5a19..654493c0e 100644 --- a/interface-definitions/include/firewall/bridge-custom-name.xml.i +++ b/interface-definitions/include/firewall/bridge-custom-name.xml.i @@ -8,7 +8,7 @@ </properties> <children> #include <include/firewall/default-action.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> #include <include/generic-description.xml.i> <leafNode name="default-jump-target"> <properties> @@ -36,4 +36,4 @@ </tagNode> </children> </tagNode> -<!-- include end -->
\ No newline at end of file +<!-- include end --> diff --git a/interface-definitions/include/firewall/bridge-hook-forward.xml.i b/interface-definitions/include/firewall/bridge-hook-forward.xml.i index ff86bf466..99f66ec77 100644 --- a/interface-definitions/include/firewall/bridge-hook-forward.xml.i +++ b/interface-definitions/include/firewall/bridge-hook-forward.xml.i @@ -10,7 +10,7 @@ </properties> <children> #include <include/firewall/default-action-base-chains.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> #include <include/generic-description.xml.i> <tagNode name="rule"> <properties> @@ -32,4 +32,4 @@ </node> </children> </node> -<!-- include end -->
\ No newline at end of file +<!-- include end --> diff --git a/interface-definitions/include/firewall/common-rule-bridge.xml.i b/interface-definitions/include/firewall/common-rule-bridge.xml.i index a27cae43b..6de770c79 100644 --- a/interface-definitions/include/firewall/common-rule-bridge.xml.i +++ b/interface-definitions/include/firewall/common-rule-bridge.xml.i @@ -24,7 +24,7 @@ </properties> </leafNode> #include <include/firewall/log.xml.i> -#include <include/firewall/rule-log-options.xml.i> +#include <include/firewall/log-options.xml.i> <node name="source"> <properties> <help>Source parameters</help> @@ -36,4 +36,4 @@ #include <include/firewall/inbound-interface.xml.i> #include <include/firewall/outbound-interface.xml.i> #include <include/firewall/match-vlan.xml.i> -<!-- include end -->
\ No newline at end of file +<!-- include end --> diff --git a/interface-definitions/include/firewall/common-rule-inet.xml.i b/interface-definitions/include/firewall/common-rule-inet.xml.i index aabefcb27..6f56ecc85 100644 --- a/interface-definitions/include/firewall/common-rule-inet.xml.i +++ b/interface-definitions/include/firewall/common-rule-inet.xml.i @@ -83,7 +83,7 @@ </children> </node> #include <include/firewall/log.xml.i> -#include <include/firewall/rule-log-options.xml.i> +#include <include/firewall/log-options.xml.i> <node name="connection-status"> <properties> <help>Connection status</help> diff --git a/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i b/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i index e040c9b13..0d749aa27 100644 --- a/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i +++ b/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i @@ -144,7 +144,7 @@ </constraint> </properties> </leafNode> -#include <include/firewall/rule-log-options.xml.i> +#include <include/firewall/log-options.xml.i> <node name="connection-status"> <properties> <help>Connection status</help> diff --git a/interface-definitions/include/firewall/common-rule.xml.i b/interface-definitions/include/firewall/common-rule.xml.i deleted file mode 100644 index c62bf2c5f..000000000 --- a/interface-definitions/include/firewall/common-rule.xml.i +++ /dev/null @@ -1,387 +0,0 @@ -<!-- include start from firewall/common-rule.xml.i --> -#include <include/firewall/action.xml.i> -#include <include/generic-description.xml.i> -<node name="destination"> - <properties> - <help>Destination parameters</help> - </properties> - <children> - #include <include/firewall/mac-address.xml.i> - </children> -</node> -<leafNode name="disable"> - <properties> - <help>Option to disable firewall rule</help> - <valueless/> - </properties> -</leafNode> -<node name="fragment"> - <properties> - <help>IP fragment match</help> - </properties> - <children> - <leafNode name="match-frag"> - <properties> - <help>Second and further fragments of fragmented packets</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="match-non-frag"> - <properties> - <help>Head fragments or unfragmented packets</help> - <valueless/> - </properties> - </leafNode> - </children> -</node> -<node name="inbound-interface"> - <properties> - <help>Match inbound-interface</help> - </properties> - <children> - #include <include/firewall/match-interface.xml.i> - </children> -</node> -<node name="outbound-interface"> - <properties> - <help>Match outbound-interface</help> - </properties> - <children> - #include <include/firewall/match-interface.xml.i> - </children> -</node> -<node name="ipsec"> - <properties> - <help>Inbound IPsec packets</help> - </properties> - <children> - <leafNode name="match-ipsec"> - <properties> - <help>Inbound IPsec packets</help> - <valueless/> - </properties> - </leafNode> - <leafNode name="match-none"> - <properties> - <help>Inbound non-IPsec packets</help> - <valueless/> - </properties> - </leafNode> - </children> -</node> -<node name="limit"> - <properties> - <help>Rate limit using a token bucket filter</help> - </properties> - <children> - <leafNode name="burst"> - <properties> - <help>Maximum number of packets to allow in excess of rate</help> - <valueHelp> - <format>u32:0-4294967295</format> - <description>Maximum number of packets to allow in excess of rate</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 0-4294967295"/> - </constraint> - </properties> - </leafNode> - <leafNode name="rate"> - <properties> - <help>Maximum average matching rate</help> - <valueHelp> - <format>txt</format> - <description>integer/unit (Example: 5/minute)</description> - </valueHelp> - <constraint> - <regex>\d+/(second|minute|hour|day)</regex> - </constraint> - </properties> - </leafNode> - </children> -</node> -<leafNode name="log"> - <properties> - <help>Option to log packets matching rule</help> - <completionHelp> - <list>enable disable</list> - </completionHelp> - <valueHelp> - <format>enable</format> - <description>Enable log</description> - </valueHelp> - <valueHelp> - <format>disable</format> - <description>Disable log</description> - </valueHelp> - <constraint> - <regex>(enable|disable)</regex> - </constraint> - </properties> -</leafNode> -#include <include/firewall/rule-log-options.xml.i> -<node name="connection-status"> - <properties> - <help>Connection status</help> - </properties> - <children> - <leafNode name="nat"> - <properties> - <help>NAT connection status</help> - <completionHelp> - <list>destination source</list> - </completionHelp> - <valueHelp> - <format>destination</format> - <description>Match connections that are subject to destination NAT</description> - </valueHelp> - <valueHelp> - <format>source</format> - <description>Match connections that are subject to source NAT</description> - </valueHelp> - <constraint> - <regex>^(destination|source)$</regex> - </constraint> - </properties> - </leafNode> - </children> -</node> -<leafNode name="protocol"> - <properties> - <help>Protocol to match (protocol name, number, or "all")</help> - <completionHelp> - <script>${vyos_completion_dir}/list_protocols.sh</script> - <list>all tcp_udp</list> - </completionHelp> - <valueHelp> - <format>all</format> - <description>All IP protocols</description> - </valueHelp> - <valueHelp> - <format>tcp_udp</format> - <description>Both TCP and UDP</description> - </valueHelp> - <valueHelp> - <format>u32:0-255</format> - <description>IP protocol number</description> - </valueHelp> - <valueHelp> - <format><protocol></format> - <description>IP protocol name</description> - </valueHelp> - <valueHelp> - <format>!<protocol></format> - <description>IP protocol name</description> - </valueHelp> - <constraint> - <validator name="ip-protocol"/> - </constraint> - </properties> -</leafNode> -<node name="recent"> - <properties> - <help>Parameters for matching recently seen sources</help> - </properties> - <children> - <leafNode name="count"> - <properties> - <help>Source addresses seen more than N times</help> - <valueHelp> - <format>u32:1-255</format> - <description>Source addresses seen more than N times</description> - </valueHelp> - <constraint> - <validator name="numeric" argument="--range 1-255"/> - </constraint> - </properties> - </leafNode> - <leafNode name="time"> - <properties> - <help>Source addresses seen in the last second/minute/hour</help> - <completionHelp> - <list>second minute hour</list> - </completionHelp> - <valueHelp> - <format>second</format> - <description>Source addresses seen COUNT times in the last second</description> - </valueHelp> - <valueHelp> - <format>minute</format> - <description>Source addresses seen COUNT times in the last minute</description> - </valueHelp> - <valueHelp> - <format>hour</format> - <description>Source addresses seen COUNT times in the last hour</description> - </valueHelp> - <constraint> - <regex>(second|minute|hour)</regex> - </constraint> - </properties> - </leafNode> - </children> -</node> -<node name="source"> - <properties> - <help>Source parameters</help> - </properties> - <children> - #include <include/firewall/address.xml.i> - #include <include/firewall/source-destination-group.xml.i> - #include <include/firewall/mac-address.xml.i> - #include <include/firewall/port.xml.i> - </children> -</node> -<node name="state"> - <properties> - <help>Session state</help> - </properties> - <children> - <leafNode name="established"> - <properties> - <help>Established state</help> - <completionHelp> - <list>enable disable</list> - </completionHelp> - <valueHelp> - <format>enable</format> - <description>Enable</description> - </valueHelp> - <valueHelp> - <format>disable</format> - <description>Disable</description> - </valueHelp> - <constraint> - <regex>(enable|disable)</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="invalid"> - <properties> - <help>Invalid state</help> - <completionHelp> - <list>enable disable</list> - </completionHelp> - <valueHelp> - <format>enable</format> - <description>Enable</description> - </valueHelp> - <valueHelp> - <format>disable</format> - <description>Disable</description> - </valueHelp> - <constraint> - <regex>(enable|disable)</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="new"> - <properties> - <help>New state</help> - <completionHelp> - <list>enable disable</list> - </completionHelp> - <valueHelp> - <format>enable</format> - <description>Enable</description> - </valueHelp> - <valueHelp> - <format>disable</format> - <description>Disable</description> - </valueHelp> - <constraint> - <regex>(enable|disable)</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="related"> - <properties> - <help>Related state</help> - <completionHelp> - <list>enable disable</list> - </completionHelp> - <valueHelp> - <format>enable</format> - <description>Enable</description> - </valueHelp> - <valueHelp> - <format>disable</format> - <description>Disable</description> - </valueHelp> - <constraint> - <regex>(enable|disable)</regex> - </constraint> - </properties> - </leafNode> - </children> -</node> -#include <include/firewall/tcp-flags.xml.i> -#include <include/firewall/tcp-mss.xml.i> -<node name="time"> - <properties> - <help>Time to match rule</help> - </properties> - <children> - <leafNode name="startdate"> - <properties> - <help>Date to start matching rule</help> - <valueHelp> - <format>txt</format> - <description>Enter date using following notation - YYYY-MM-DD</description> - </valueHelp> - <constraint> - <regex>(\d{4}\-\d{2}\-\d{2})</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="starttime"> - <properties> - <help>Time of day to start matching rule</help> - <valueHelp> - <format>txt</format> - <description>Enter time using using 24 hour notation - hh:mm:ss</description> - </valueHelp> - <constraint> - <regex>([0-2][0-9](\:[0-5][0-9]){1,2})</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="stopdate"> - <properties> - <help>Date to stop matching rule</help> - <valueHelp> - <format>txt</format> - <description>Enter date using following notation - YYYY-MM-DD</description> - </valueHelp> - <constraint> - <regex>(\d{4}\-\d{2}\-\d{2})</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="stoptime"> - <properties> - <help>Time of day to stop matching rule</help> - <valueHelp> - <format>txt</format> - <description>Enter time using using 24 hour notation - hh:mm:ss</description> - </valueHelp> - <constraint> - <regex>([0-2][0-9](\:[0-5][0-9]){1,2})</regex> - </constraint> - </properties> - </leafNode> - <leafNode name="weekdays"> - <properties> - <help>Comma separated weekdays to match rule on</help> - <valueHelp> - <format>txt</format> - <description>Name of day (Monday, Tuesday, Wednesday, Thursdays, Friday, Saturday, Sunday)</description> - </valueHelp> - <valueHelp> - <format>u32:0-6</format> - <description>Day number (0 = Sunday ... 6 = Saturday)</description> - </valueHelp> - </properties> - </leafNode> - </children> -</node> -<!-- include end --> diff --git a/interface-definitions/include/firewall/default-log.xml.i b/interface-definitions/include/firewall/default-log.xml.i new file mode 100644 index 000000000..dceacdb89 --- /dev/null +++ b/interface-definitions/include/firewall/default-log.xml.i @@ -0,0 +1,8 @@ +<!-- include start from firewall/default-log.xml.i --> +<leafNode name="default-log"> + <properties> + <help>Log packets hitting default-action</help> + <valueless/> + </properties> +</leafNode> +<!-- include end --> diff --git a/interface-definitions/include/firewall/enable-default-log.xml.i b/interface-definitions/include/firewall/enable-default-log.xml.i deleted file mode 100644 index 0efd8341b..000000000 --- a/interface-definitions/include/firewall/enable-default-log.xml.i +++ /dev/null @@ -1,8 +0,0 @@ -<!-- include start from firewall/enable-default-log.xml.i --> -<leafNode name="enable-default-log"> - <properties> - <help>Log packets hitting default-action</help> - <valueless/> - </properties> -</leafNode> -<!-- include end -->
\ No newline at end of file diff --git a/interface-definitions/include/firewall/ipv4-custom-name.xml.i b/interface-definitions/include/firewall/ipv4-custom-name.xml.i index c6420fe1f..8199d15fe 100644 --- a/interface-definitions/include/firewall/ipv4-custom-name.xml.i +++ b/interface-definitions/include/firewall/ipv4-custom-name.xml.i @@ -8,7 +8,7 @@ </properties> <children> #include <include/firewall/default-action.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> #include <include/generic-description.xml.i> <leafNode name="default-jump-target"> <properties> @@ -39,4 +39,4 @@ </tagNode> </children> </tagNode> -<!-- include end -->
\ No newline at end of file +<!-- include end --> diff --git a/interface-definitions/include/firewall/ipv4-hook-forward.xml.i b/interface-definitions/include/firewall/ipv4-hook-forward.xml.i index 100f1c3d9..de2c70482 100644 --- a/interface-definitions/include/firewall/ipv4-hook-forward.xml.i +++ b/interface-definitions/include/firewall/ipv4-hook-forward.xml.i @@ -10,7 +10,7 @@ </properties> <children> #include <include/firewall/default-action-base-chains.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> #include <include/generic-description.xml.i> <tagNode name="rule"> <properties> @@ -36,4 +36,4 @@ </node> </children> </node> -<!-- include end -->
\ No newline at end of file +<!-- include end --> diff --git a/interface-definitions/include/firewall/ipv4-hook-input.xml.i b/interface-definitions/include/firewall/ipv4-hook-input.xml.i index 22546640b..5d32657ea 100644 --- a/interface-definitions/include/firewall/ipv4-hook-input.xml.i +++ b/interface-definitions/include/firewall/ipv4-hook-input.xml.i @@ -10,7 +10,7 @@ </properties> <children> #include <include/firewall/default-action-base-chains.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> #include <include/generic-description.xml.i> <tagNode name="rule"> <properties> @@ -33,4 +33,4 @@ </node> </children> </node> -<!-- include end -->
\ No newline at end of file +<!-- include end --> diff --git a/interface-definitions/include/firewall/ipv4-hook-output.xml.i b/interface-definitions/include/firewall/ipv4-hook-output.xml.i index 80c30cdeb..2b537ce5e 100644 --- a/interface-definitions/include/firewall/ipv4-hook-output.xml.i +++ b/interface-definitions/include/firewall/ipv4-hook-output.xml.i @@ -10,7 +10,7 @@ </properties> <children> #include <include/firewall/default-action-base-chains.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> #include <include/generic-description.xml.i> <tagNode name="rule"> <properties> @@ -33,4 +33,4 @@ </node> </children> </node> -<!-- include end -->
\ No newline at end of file +<!-- include end --> diff --git a/interface-definitions/include/firewall/ipv6-custom-name.xml.i b/interface-definitions/include/firewall/ipv6-custom-name.xml.i index 2cc45a60c..5748b3927 100644 --- a/interface-definitions/include/firewall/ipv6-custom-name.xml.i +++ b/interface-definitions/include/firewall/ipv6-custom-name.xml.i @@ -8,7 +8,7 @@ </properties> <children> #include <include/firewall/default-action.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> #include <include/generic-description.xml.i> <leafNode name="default-jump-target"> <properties> @@ -39,4 +39,4 @@ </tagNode> </children> </tagNode> -<!-- include end -->
\ No newline at end of file +<!-- include end --> diff --git a/interface-definitions/include/firewall/ipv6-hook-forward.xml.i b/interface-definitions/include/firewall/ipv6-hook-forward.xml.i index fb38267eb..b53f09f59 100644 --- a/interface-definitions/include/firewall/ipv6-hook-forward.xml.i +++ b/interface-definitions/include/firewall/ipv6-hook-forward.xml.i @@ -10,7 +10,7 @@ </properties> <children> #include <include/firewall/default-action-base-chains.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> #include <include/generic-description.xml.i> <tagNode name="rule"> <properties> @@ -36,4 +36,4 @@ </node> </children> </node> -<!-- include end -->
\ No newline at end of file +<!-- include end --> diff --git a/interface-definitions/include/firewall/ipv6-hook-input.xml.i b/interface-definitions/include/firewall/ipv6-hook-input.xml.i index 49d4493cc..493611fb1 100644 --- a/interface-definitions/include/firewall/ipv6-hook-input.xml.i +++ b/interface-definitions/include/firewall/ipv6-hook-input.xml.i @@ -10,7 +10,7 @@ </properties> <children> #include <include/firewall/default-action-base-chains.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> #include <include/generic-description.xml.i> <tagNode name="rule"> <properties> @@ -33,4 +33,4 @@ </node> </children> </node> -<!-- include end -->
\ No newline at end of file +<!-- include end --> diff --git a/interface-definitions/include/firewall/ipv6-hook-output.xml.i b/interface-definitions/include/firewall/ipv6-hook-output.xml.i index 452b9027f..ffe1c72b8 100644 --- a/interface-definitions/include/firewall/ipv6-hook-output.xml.i +++ b/interface-definitions/include/firewall/ipv6-hook-output.xml.i @@ -10,7 +10,7 @@ </properties> <children> #include <include/firewall/default-action-base-chains.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> #include <include/generic-description.xml.i> <tagNode name="rule"> <properties> @@ -33,4 +33,4 @@ </node> </children> </node> -<!-- include end -->
\ No newline at end of file +<!-- include end --> diff --git a/interface-definitions/include/firewall/rule-log-options.xml.i b/interface-definitions/include/firewall/log-options.xml.i index e8b0cdec3..e8b0cdec3 100644 --- a/interface-definitions/include/firewall/rule-log-options.xml.i +++ b/interface-definitions/include/firewall/log-options.xml.i diff --git a/interface-definitions/include/firewall/log.xml.i b/interface-definitions/include/firewall/log.xml.i index 21b883e6a..21548f3fb 100644 --- a/interface-definitions/include/firewall/log.xml.i +++ b/interface-definitions/include/firewall/log.xml.i @@ -1,7 +1,7 @@ <!-- include start from firewall/log.xml.i --> <leafNode name="log"> <properties> - <help>Enable log</help> + <help>Log packets hitting this rule</help> <valueless/> </properties> </leafNode> diff --git a/interface-definitions/include/version/firewall-version.xml.i b/interface-definitions/include/version/firewall-version.xml.i index 299eebb00..6702ee041 100644 --- a/interface-definitions/include/version/firewall-version.xml.i +++ b/interface-definitions/include/version/firewall-version.xml.i @@ -1,3 +1,3 @@ <!-- include start from include/version/firewall-version.xml.i --> -<syntaxVersion component='firewall' version='13'></syntaxVersion> +<syntaxVersion component='firewall' version='14'></syntaxVersion> <!-- include end --> diff --git a/interface-definitions/include/version/lldp-version.xml.i b/interface-definitions/include/version/lldp-version.xml.i index 0deb73279..b41d80451 100644 --- a/interface-definitions/include/version/lldp-version.xml.i +++ b/interface-definitions/include/version/lldp-version.xml.i @@ -1,3 +1,3 @@ <!-- include start from include/version/lldp-version.xml.i --> -<syntaxVersion component='lldp' version='1'></syntaxVersion> +<syntaxVersion component='lldp' version='2'></syntaxVersion> <!-- include end --> diff --git a/interface-definitions/include/version/policy-version.xml.i b/interface-definitions/include/version/policy-version.xml.i index 4fbe757f5..db727fea9 100644 --- a/interface-definitions/include/version/policy-version.xml.i +++ b/interface-definitions/include/version/policy-version.xml.i @@ -1,3 +1,3 @@ <!-- include start from include/version/policy-version.xml.i --> -<syntaxVersion component='policy' version='7'></syntaxVersion> +<syntaxVersion component='policy' version='8'></syntaxVersion> <!-- include end --> diff --git a/interface-definitions/interfaces-virtual-ethernet.xml.in b/interface-definitions/interfaces-virtual-ethernet.xml.in index 5f205f354..0fc89efc0 100644 --- a/interface-definitions/interfaces-virtual-ethernet.xml.in +++ b/interface-definitions/interfaces-virtual-ethernet.xml.in @@ -9,7 +9,7 @@ <constraint> <regex>veth[0-9]+</regex> </constraint> - <constraintErrorMessage>Virutal Ethernet interface must be named vethN</constraintErrorMessage> + <constraintErrorMessage>Virtual Ethernet interface must be named vethN</constraintErrorMessage> <valueHelp> <format>vethN</format> <description>Virtual Ethernet interface name</description> diff --git a/interface-definitions/lldp.xml.in b/interface-definitions/lldp.xml.in index 738bb11c1..25fb575b6 100644 --- a/interface-definitions/lldp.xml.in +++ b/interface-definitions/lldp.xml.in @@ -175,19 +175,12 @@ <multi/> </properties> </leafNode> - <node name="snmp"> + <leafNode name="snmp"> <properties> - <help>SNMP parameters for LLDP</help> + <help>Enable SNMP queries of the LLDP database</help> + <valueless/> </properties> - <children> - <leafNode name="enable"> - <properties> - <help>Enable SNMP queries of the LLDP database</help> - <valueless/> - </properties> - </leafNode> - </children> - </node> + </leafNode> </children> </node> </children> diff --git a/interface-definitions/nat64.xml.in b/interface-definitions/nat64.xml.in index baf13e6cb..dfdd295d2 100644 --- a/interface-definitions/nat64.xml.in +++ b/interface-definitions/nat64.xml.in @@ -26,6 +26,25 @@ <children> #include <include/generic-description.xml.i> #include <include/generic-disable-node.xml.i> + <node name="match"> + <properties> + <help>Match</help> + </properties> + <children> + <leafNode name="mark"> + <properties> + <help>Match fwmark value</help> + <valueHelp> + <format>u32:1-2147483647</format> + <description>Fwmark value to match against</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 1-2147483647"/> + </constraint> + </properties> + </leafNode> + </children> + </node> <node name="source"> <properties> <help>IPv6 source prefix options</help> diff --git a/interface-definitions/policy-route.xml.in b/interface-definitions/policy-route.xml.in index d4ec75786..92e7a0cb4 100644 --- a/interface-definitions/policy-route.xml.in +++ b/interface-definitions/policy-route.xml.in @@ -12,7 +12,7 @@ </properties> <children> #include <include/generic-description.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> #include <include/generic-interface-multi-wildcard.xml.i> <tagNode name="rule"> <properties> @@ -67,7 +67,7 @@ </properties> <children> #include <include/generic-description.xml.i> - #include <include/firewall/enable-default-log.xml.i> + #include <include/firewall/default-log.xml.i> #include <include/generic-interface-multi-wildcard.xml.i> <tagNode name="rule"> <properties> diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index 075ffe466..6a421485f 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -104,6 +104,10 @@ def list_diff(first, second): return [item for item in first if item not in second] def is_node_changed(conf, path): + """ + Check if any key under path has been changed and return True. + If nothing changed, return false + """ from vyos.configdiff import get_config_diff D = get_config_diff(conf, key_mangling=('-', '_')) return D.is_node_changed(path) @@ -139,17 +143,27 @@ def leaf_node_changed(conf, path): return None -def node_changed(conf, path, key_mangling=None, recursive=False): +def node_changed(conf, path, key_mangling=None, recursive=False, expand_nodes=None) -> list: """ - Check if a leaf node was altered. If it has been altered - values has been - changed, or it was added/removed, we will return the old value. If nothing - has been changed, None is returned + Check if node under path (or anything under path if recursive=True) was changed. By default + we only check if a node or subnode (recursive) was deleted from path. If expand_nodes + is set to Diff.ADD we can also check if something was added to the path. + + If nothing changed, an empty list is returned. """ - from vyos.configdiff import get_config_diff, Diff + from vyos.configdiff import get_config_diff + from vyos.configdiff import Diff + # to prevent circular dependencies we assign the default here + if not expand_nodes: expand_nodes = Diff.DELETE D = get_config_diff(conf, key_mangling) - # get_child_nodes() will return dict_keys(), mangle this into a list with PEP448 - keys = D.get_child_nodes_diff(path, expand_nodes=Diff.DELETE, recursive=recursive)['delete'].keys() - return list(keys) + # get_child_nodes_diff() will return dict_keys() + tmp = D.get_child_nodes_diff(path, expand_nodes=expand_nodes, recursive=recursive) + output = [] + if expand_nodes & Diff.DELETE: + output.extend(list(tmp['delete'].keys())) + if expand_nodes & Diff.ADD: + output.extend(list(tmp['add'].keys())) + return output def get_removed_vlans(conf, path, dict): """ diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index f19632719..ba638b280 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -23,6 +23,7 @@ from vyos.utils.process import popen _drivers_without_speed_duplex_flow = ['vmxnet3', 'virtio_net', 'xen_netfront', 'iavf', 'ice', 'i40e', 'hv_netvsc', 'veth', 'ixgbevf', 'tun'] +_drivers_without_eee = ['vmxnet3', 'virtio_net', 'xen_netfront', 'hv_netvsc'] class Ethtool: """ @@ -55,16 +56,18 @@ class Ethtool: _auto_negotiation_supported = None _flow_control = False _flow_control_enabled = None + _eee = False + _eee_enabled = None def __init__(self, ifname): # Get driver used for interface - out, err = popen(f'ethtool --driver {ifname}') + out, _ = popen(f'ethtool --driver {ifname}') driver = re.search(r'driver:\s(\w+)', out) if driver: self._driver_name = driver.group(1) # Build a dictinary of supported link-speed and dupley settings. - out, err = popen(f'ethtool {ifname}') + out, _ = popen(f'ethtool {ifname}') reading = False pattern = re.compile(r'\d+base.*') for line in out.splitlines()[1:]: @@ -95,7 +98,7 @@ class Ethtool: self._auto_negotiation = bool(tmp == 'on') # Now populate features dictionaty - out, err = popen(f'ethtool --show-features {ifname}') + out, _ = popen(f'ethtool --show-features {ifname}') # skip the first line, it only says: "Features for eth0": for line in out.splitlines()[1:]: if ":" in line: @@ -108,7 +111,7 @@ class Ethtool: 'fixed' : fixed } - out, err = popen(f'ethtool --show-ring {ifname}') + out, _ = popen(f'ethtool --show-ring {ifname}') # We are only interested in line 2-5 which contains the device maximum # ringbuffers for line in out.splitlines()[2:6]: @@ -133,13 +136,22 @@ class Ethtool: # Get current flow control settings, but this is not supported by # all NICs (e.g. vmxnet3 does not support is) - out, err = popen(f'ethtool --show-pause {ifname}') + out, _ = popen(f'ethtool --show-pause {ifname}') if len(out.splitlines()) > 1: self._flow_control = True # read current flow control setting, this returns: # ['Autonegotiate:', 'on'] self._flow_control_enabled = out.splitlines()[1].split()[-1] + # Get current Energy Efficient Ethernet (EEE) settings, but this is + # not supported by all NICs (e.g. vmxnet3 does not support is) + out, _ = popen(f'ethtool --show-eee {ifname}') + if len(out.splitlines()) > 1: + self._eee = True + # read current EEE setting, this returns: + # EEE status: disabled || EEE status: enabled - inactive || EEE status: enabled - active + self._eee_enabled = bool('enabled' in out.splitlines()[2]) + def check_auto_negotiation_supported(self): """ Check if the NIC supports changing auto-negotiation """ return self._auto_negotiation_supported @@ -227,3 +239,15 @@ class Ethtool: raise ValueError('Interface does not support changing '\ 'flow-control settings!') return self._flow_control_enabled + + def check_eee(self): + """ Check if the NIC supports eee """ + if self.get_driver_name() in _drivers_without_eee: + return False + return self._eee + + def get_eee(self): + if self._eee_enabled == None: + raise ValueError('Interface does not support changing '\ + 'EEE settings!') + return self._eee_enabled diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py index aa1e87744..aaf903acd 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -399,6 +399,34 @@ class EthernetIf(Interface): print(f'could not set "{rx_tx}" ring-buffer for {ifname}') return output + def set_eee(self, enable): + """ + Enable/Disable Energy Efficient Ethernet (EEE) settings + + Example: + >>> from vyos.ifconfig import EthernetIf + >>> i = EthernetIf('eth0') + >>> i.set_eee(enable=False) + """ + if not isinstance(enable, bool): + raise ValueError('Value out of range') + + if not self.ethtool.check_eee(): + self._debug_msg(f'NIC driver does not support changing EEE settings!') + return False + + current = self.ethtool.get_eee() + if current != enable: + # Assemble command executed on system. Unfortunately there is no way + # to change this setting via sysfs + cmd = f'ethtool --set-eee {self.ifname} eee ' + cmd += 'on' if enable else 'off' + output, code = self._popen(cmd) + if code: + Warning(f'could not change "{self.ifname}" EEE setting!') + return output + return None + def update(self, config): """ General helper function which works on a dictionary retrived by get_config_dict(). It's main intention is to consolidate the scattered @@ -409,6 +437,9 @@ class EthernetIf(Interface): value = 'off' if 'disable_flow_control' in config else 'on' self.set_flow_control(value) + # Always disable Energy Efficient Ethernet + self.set_eee(False) + # GRO (generic receive offload) self.set_gro(dict_search('offload.gro', config) != None) diff --git a/python/vyos/template.py b/python/vyos/template.py index f0a50e728..77b6a5ab0 100644 --- a/python/vyos/template.py +++ b/python/vyos/template.py @@ -584,7 +584,7 @@ def nft_default_rule(fw_conf, fw_name, family): default_action = fw_conf['default_action'] #family = 'ipv6' if ipv6 else 'ipv4' - if 'enable_default_log' in fw_conf: + if 'default_log' in fw_conf: action_suffix = default_action[:1].upper() output.append(f'log prefix "[{family}-{fw_name[:19]}-default-{action_suffix}]"') diff --git a/scripts/override-default b/scripts/override-default index 0c49087c8..5058e79b3 100755 --- a/scripts/override-default +++ b/scripts/override-default @@ -41,6 +41,14 @@ if debug: else: logger.setLevel(logging.INFO) +def clear_empty_path(el): + # on the odd chance of interleaved comments + tmp = [l for l in el if isinstance(l.tag, str)] + if not tmp: + p = el.getparent() + p.remove(el) + clear_empty_path(p) + def override_element(l: list): """ Allow multiple override elements; use the final one (in document order). @@ -59,7 +67,9 @@ def override_element(l: list): # remove all but overridden element for el in parents: - el.getparent().remove(el) + tmp = el.getparent() + tmp.remove(el) + clear_empty_path(tmp) def merge_remaining(l: list, elementtree): """ @@ -81,7 +91,9 @@ def merge_remaining(l: list, elementtree): # override_element() has already run for child in el: rp[0].append(deepcopy(child)) - el.getparent().remove(el) + tmp = el.getparent() + tmp.remove(el) + clear_empty_path(tmp) def collect_and_override(dir_name): """ @@ -104,7 +116,7 @@ def collect_and_override(dir_name): for k, v in defv.items(): if len(v) > 1: - logger.info(f"overridding default in path '{k}'") + logger.info(f"overriding default in path '{k}'") override_element(v) to_merge = list(defv) diff --git a/smoketest/configs/ospf-small b/smoketest/configs/ospf-small index 767f4e21f..b3002b1af 100644 --- a/smoketest/configs/ospf-small +++ b/smoketest/configs/ospf-small @@ -81,6 +81,9 @@ service { lldp { interface all { } + snmp { + enable + } } snmp { community public { diff --git a/smoketest/scripts/cli/base_accel_ppp_test.py b/smoketest/scripts/cli/base_accel_ppp_test.py index 32624719f..fad765c0d 100644 --- a/smoketest/scripts/cli/base_accel_ppp_test.py +++ b/smoketest/scripts/cli/base_accel_ppp_test.py @@ -365,6 +365,7 @@ class BasicAccelPPPTest: first_pool = "POOL1" second_pool = "POOL2" range = "192.0.2.10-192.0.2.20" + range_config = "192.0.2.10-20" self.set(["gateway-address", gateway]) self.set(["client-ip-pool", first_pool, "range", subnet]) @@ -382,7 +383,7 @@ class BasicAccelPPPTest: self.assertEqual( f"{first_pool},next={second_pool}", conf["ip-pool"][f"{subnet},name"] ) - self.assertEqual(second_pool, conf["ip-pool"][f"{range},name"]) + self.assertEqual(second_pool, conf["ip-pool"][f"{range_config},name"]) self.assertEqual(gateway, conf["ip-pool"]["gw-ip-address"]) self.assertEqual(first_pool, conf[self._protocol_section]["ip-pool"]) diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index 5cfddb269..2be616da1 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -209,7 +209,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): conn_mark = '555' self.cli_set(['firewall', 'ipv4', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv4', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'default-log']) self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'action', 'accept']) self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'source', 'address', '172.16.20.10']) self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'destination', 'address', '172.16.10.10']) @@ -226,7 +226,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'ttl', 'gt', '102']) self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'enable-default-log']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'default-log']) self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '3', 'action', 'accept']) self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '3', 'protocol', 'tcp']) self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '3', 'destination', 'port', '22']) @@ -250,7 +250,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '6', 'connection-mark', conn_mark]) self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'enable-default-log']) + self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'default-log']) self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '5', 'action', 'drop']) self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '5', 'protocol', 'gre']) self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '5', 'outbound-interface', 'name', interface_inv]) @@ -292,7 +292,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): interface = 'eth0' self.cli_set(['firewall', 'ipv4', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv4', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'default-log']) self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'action', 'accept']) self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'packet-length', '64']) @@ -379,7 +379,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'group', 'address-group', 'mask_group', 'address', '1.1.1.1']) self.cli_set(['firewall', 'ipv4', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv4', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'default-log']) self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'action', 'drop']) self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'destination', 'address', '0.0.1.2']) @@ -413,7 +413,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'global-options', 'state-policy', 'invalid', 'action', 'drop']) self.cli_set(['firewall', 'ipv6', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv6', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'default-log']) self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'action', 'accept']) self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'source', 'address', '2002::1']) @@ -422,14 +422,14 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'log-options', 'level', 'crit']) self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'default-action', 'accept']) - self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'enable-default-log']) + self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'default-log']) self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'action', 'reject']) self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'protocol', 'tcp_udp']) self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'destination', 'port', '8888']) self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'inbound-interface', 'name', interface]) self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'enable-default-log']) + self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'default-log']) self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '3', 'action', 'return']) self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '3', 'protocol', 'gre']) self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '3', 'outbound-interface', 'name', interface]) @@ -472,7 +472,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): interface = 'eth0' self.cli_set(['firewall', 'ipv6', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv6', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'default-log']) self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '3', 'action', 'accept']) self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '3', 'packet-length', '65']) @@ -516,7 +516,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'group', 'ipv6-address-group', 'mask_group', 'address', '::beef']) self.cli_set(['firewall', 'ipv6', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv6', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'default-log']) self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'action', 'drop']) self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'destination', 'address', '::1111:2222:3333:4444']) @@ -596,7 +596,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): vlan_prior = '3' self.cli_set(['firewall', 'bridge', 'name', name, 'default-action', 'accept']) - self.cli_set(['firewall', 'bridge', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'bridge', 'name', name, 'default-log']) self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'action', 'accept']) self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'source', 'mac-address', mac_address]) self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'inbound-interface', 'name', interface_in]) @@ -604,7 +604,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'log-options', 'level', 'crit']) self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'default-action', 'drop']) - self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'enable-default-log']) + self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'default-log']) self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '1', 'action', 'accept']) self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '1', 'vlan', 'id', vlan_id]) self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '2', 'action', 'jump']) diff --git a/smoketest/scripts/cli/test_policy_route.py b/smoketest/scripts/cli/test_policy_route.py index 32e86ea7e..c0b7c1fe7 100755 --- a/smoketest/scripts/cli/test_policy_route.py +++ b/smoketest/scripts/cli/test_policy_route.py @@ -33,6 +33,9 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase): @classmethod def setUpClass(cls): super(TestPolicyRoute, cls).setUpClass() + # Clear out current configuration to allow running this test on a live system + cls.cli_delete(cls, ['policy', 'route']) + cls.cli_delete(cls, ['policy', 'route6']) cls.cli_set(cls, ['interfaces', 'ethernet', interface, 'address', interface_ip]) cls.cli_set(cls, ['protocols', 'static', 'table', table_id, 'route', '0.0.0.0/0', 'interface', interface]) @@ -189,6 +192,7 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase): def test_pbr_matching_criteria(self): + self.cli_set(['policy', 'route', 'smoketest', 'default-log']) self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'protocol', 'udp']) self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'action', 'drop']) self.cli_set(['policy', 'route', 'smoketest', 'rule', '1', 'mark', '2020']) @@ -216,6 +220,7 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase): self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'mark', '!456-500']) self.cli_set(['policy', 'route', 'smoketest', 'rule', '5', 'set', 'table', table_id]) + self.cli_set(['policy', 'route6', 'smoketest6', 'default-log']) self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'protocol', 'udp']) self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '1', 'action', 'drop']) self.cli_set(['policy', 'route6', 'smoketest6', 'rule', '2', 'protocol', 'tcp']) @@ -255,7 +260,8 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase): ['tcp flags syn / syn,ack', 'meta mark 0x00000002-0x00000bb8', 'meta mark set ' + mark_hex], ['ct state new', 'tcp dport 22', 'ip saddr 198.51.100.0/24', 'ip ttl > 2', 'meta mark != 0x000001c8', 'meta mark set ' + mark_hex], ['log prefix "[ipv4-route-smoketest-4-A]"', 'icmp type echo-request', 'ip length { 128, 1024-2048 }', 'meta pkttype other', 'meta mark set ' + mark_hex], - ['ip dscp { 0x29, 0x39-0x3b }', 'meta mark != 0x000001c8-0x000001f4', 'meta mark set ' + mark_hex] + ['ip dscp { 0x29, 0x39-0x3b }', 'meta mark != 0x000001c8-0x000001f4', 'meta mark set ' + mark_hex], + ['log prefix "[ipv4-smoketest-default]"'] ] self.verify_nftables(nftables_search, 'ip vyos_mangle') @@ -267,7 +273,8 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase): ['tcp flags syn / syn,ack', 'meta mark set ' + mark_hex], ['ct state new', 'tcp dport 22', 'ip6 saddr 2001:db8::/64', 'ip6 hoplimit > 2', 'meta mark set ' + mark_hex], ['log prefix "[ipv6-route6-smoketest6-4-A]"', 'icmpv6 type echo-request', 'ip6 length != { 128, 1024-2048 }', 'meta pkttype multicast', 'meta mark set ' + mark_hex], - ['ip6 dscp != { 0x0e-0x13, 0x3d }', 'meta mark set ' + mark_hex] + ['ip6 dscp != { 0x0e-0x13, 0x3d }', 'meta mark set ' + mark_hex], + ['log prefix "[ipv6-smoketest6-default]"'] ] self.verify_nftables(nftables6_search, 'ip6 vyos_mangle') diff --git a/smoketest/scripts/cli/test_service_ipoe-server.py b/smoketest/scripts/cli/test_service_ipoe-server.py index 358668e0d..6e95b3bd1 100755 --- a/smoketest/scripts/cli/test_service_ipoe-server.py +++ b/smoketest/scripts/cli/test_service_ipoe-server.py @@ -117,6 +117,7 @@ class TestServiceIPoEServer(BasicAccelPPPTest.TestCase): first_pool = "POOL1" second_pool = "POOL2" range = "192.0.2.10-192.0.2.20" + range_config = "192.0.2.10-20" for gw in gateway: self.set(["gateway-address", gw]) @@ -141,7 +142,7 @@ class TestServiceIPoEServer(BasicAccelPPPTest.TestCase): self.assertIn( f"{first_pool},next={second_pool}", conf["ip-pool"][f"{subnet},name"] ) - self.assertIn(second_pool, conf["ip-pool"][f"{range},name"]) + self.assertIn(second_pool, conf["ip-pool"][f"{range_config},name"]) gw_pool_config_list = conf.get("ip-pool", "gw-ip-address") gw_ipoe_config_list = conf.get(self._protocol_section, "gw-ip-address") diff --git a/smoketest/scripts/cli/test_service_lldp.py b/smoketest/scripts/cli/test_service_lldp.py index ee26844ab..7e30b43f5 100755 --- a/smoketest/scripts/cli/test_service_lldp.py +++ b/smoketest/scripts/cli/test_service_lldp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2022 VyOS maintainers and contributors +# Copyright (C) 2022-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 @@ -122,6 +122,20 @@ class TestServiceLLDP(VyOSUnitTestSHIM.TestCase): self.assertIn(f'configure ports {interface} med location elin "{elin}"', config) self.assertIn(f'configure system interface pattern "{interface}"', config) + def test_06_lldp_snmp(self): + self.cli_set(base_path + ['snmp']) + + # verify - can not start lldp snmp without snmp beeing configured + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_set(['service', 'snmp']) + self.cli_commit() + + # SNMP required process to be started with -x option + tmp = read_file('/etc/default/lldpd') + self.assertIn('-x', tmp) + + self.cli_delete(['service', 'snmp']) if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/dhcp_server.py b/src/conf_mode/dhcp_server.py index abccdb6a9..c1308cda7 100755 --- a/src/conf_mode/dhcp_server.py +++ b/src/conf_mode/dhcp_server.py @@ -40,6 +40,7 @@ ctrl_config_file = '/run/kea/kea-ctrl-agent.conf' ctrl_socket = '/run/kea/dhcp4-ctrl-socket' config_file = '/run/kea/kea-dhcp4.conf' lease_file = '/config/dhcp4.leases' +systemd_override = r'/run/systemd/system/kea-ctrl-agent.service.d/10-override.conf' ca_cert_file = '/run/kea/kea-failover-ca.pem' cert_file = '/run/kea/kea-failover.pem' @@ -332,6 +333,8 @@ def generate(dhcp): dhcp['failover']['ca_cert_file'] = ca_cert_file + render(systemd_override, 'dhcp-server/10-override.conf.j2', dhcp) + render(ctrl_config_file, 'dhcp-server/kea-ctrl-agent.conf.j2', dhcp) render(config_file, 'dhcp-server/kea-dhcp4.conf.j2', dhcp) diff --git a/src/conf_mode/dns_dynamic.py b/src/conf_mode/dns_dynamic.py index 809c650d9..99fa8feee 100755 --- a/src/conf_mode/dns_dynamic.py +++ b/src/conf_mode/dns_dynamic.py @@ -15,7 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import os - +import re from sys import exit from vyos.base import Warning @@ -103,6 +103,16 @@ def verify(dyndns): raise ConfigError(f'"web-options" is applicable only when using HTTP(S) ' f'web request to obtain the IP address') + # Warn if using checkip.dyndns.org, as it does not support HTTPS + # See: https://github.com/ddclient/ddclient/issues/597 + if 'web_options' in config: + if 'url' not in config['web_options']: + raise ConfigError(f'"url" in "web-options" {error_msg_req} ' + f'with protocol "{config["protocol"]}"') + elif re.search("^(https?://)?checkip\.dyndns\.org", config['web_options']['url']): + Warning(f'"checkip.dyndns.org" does not support HTTPS requests for IP address ' + f'lookup. Please use a different IP address lookup service.') + # RFC2136 uses 'key' instead of 'password' if config['protocol'] != 'nsupdate' and 'password' not in config: raise ConfigError(f'"password" {error_msg_req}') diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index ceed0cf31..da6724fde 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -23,7 +23,7 @@ from sys import exit from vyos.base import Warning from vyos.config import Config -from vyos.configdict import node_changed +from vyos.configdict import is_node_changed from vyos.configdiff import get_config_diff, Diff from vyos.configdep import set_dependents, call_dependents from vyos.configverify import verify_interface_exists @@ -133,7 +133,7 @@ def get_config(config=None): with_recursive_defaults=True) - firewall['group_resync'] = bool('group' in firewall or node_changed(conf, base + ['group'])) + firewall['group_resync'] = bool('group' in firewall or is_node_changed(conf, base + ['group'])) if firewall['group_resync']: # Update nat and policy-route as firewall groups were updated set_dependents('group_resync', conf) diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py index 31508a3c5..29991e2da 100755 --- a/src/conf_mode/interfaces-bridge.py +++ b/src/conf_mode/interfaces-bridge.py @@ -49,7 +49,7 @@ def get_config(config=None): ifname, bridge = get_interface_dict(conf, base) # determine which members have been removed - tmp = node_changed(conf, base + [ifname, 'member', 'interface'], key_mangling=('-', '_')) + tmp = node_changed(conf, base + [ifname, 'member', 'interface']) if tmp: if 'member' in bridge: bridge['member'].update({'interface_remove' : tmp }) diff --git a/src/conf_mode/lldp.py b/src/conf_mode/lldp.py index c2e87d171..3c647a0e8 100755 --- a/src/conf_mode/lldp.py +++ b/src/conf_mode/lldp.py @@ -86,9 +86,9 @@ def verify(lldp): raise ConfigError(f'Must define both longitude and latitude for "{interface}" location!') # check options - if 'snmp' in lldp and 'enable' in lldp['snmp']: + if 'snmp' in lldp: if 'system_snmp_enabled' not in lldp: - raise ConfigError('SNMP must be configured to enable LLDP SNMP') + raise ConfigError('SNMP must be configured to enable LLDP SNMP!') def generate(lldp): @@ -121,4 +121,3 @@ if __name__ == '__main__': except ConfigError as e: print(e) exit(1) - diff --git a/src/conf_mode/nat64.py b/src/conf_mode/nat64.py index a8b90fb11..6026c61d0 100755 --- a/src/conf_mode/nat64.py +++ b/src/conf_mode/nat64.py @@ -148,6 +148,11 @@ def generate(nat64) -> None: if dict_search("translation.pool", instance): pool4 = [] + # mark + mark = '' + if dict_search("match.mark", instance): + mark = instance["match"]["mark"] + for pool in instance["translation"]["pool"].values(): if "disable" in pool: continue @@ -159,6 +164,8 @@ def generate(nat64) -> None: "prefix": pool["address"], "port range": pool["port"], } + if mark: + obj["mark"] = int(mark) if "description" in pool: obj["comment"] = pool["description"] diff --git a/src/conf_mode/netns.py b/src/conf_mode/netns.py index 95ab83dbc..7cee33bc6 100755 --- a/src/conf_mode/netns.py +++ b/src/conf_mode/netns.py @@ -77,8 +77,8 @@ def verify(netns): if 'netns_remove' in netns: for name, config in netns['netns_remove'].items(): if 'interface' in config: - raise ConfigError(f'Can not remove NETNS "{name}", it still has '\ - f'member interfaces!') + raise ConfigError(f'Can not remove network namespace "{name}", it '\ + f'still has member interfaces!') if 'name' in netns: for name, config in netns['name'].items(): @@ -87,7 +87,6 @@ def verify(netns): return None - def generate(netns): if not netns: return None diff --git a/src/conf_mode/protocols_nhrp.py b/src/conf_mode/protocols_nhrp.py index 5ec0bc9e5..c339c6391 100755 --- a/src/conf_mode/protocols_nhrp.py +++ b/src/conf_mode/protocols_nhrp.py @@ -37,7 +37,7 @@ def get_config(config=None): nhrp = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True) - nhrp['del_tunnels'] = node_changed(conf, base + ['tunnel'], key_mangling=('-', '_')) + nhrp['del_tunnels'] = node_changed(conf, base + ['tunnel']) if not conf.exists(base): return nhrp diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index d2ed5414f..6565ffd60 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2018-2021 VyOS maintainers and contributors +# Copyright (C) 2018-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 @@ -54,7 +54,7 @@ def get_config(config=None): if not conf.exists(base): snmp.update({'deleted' : ''}) - if conf.exists(['service', 'lldp', 'snmp', 'enable']): + if conf.exists(['service', 'lldp', 'snmp']): snmp.update({'lldp_snmp' : ''}) if 'deleted' in snmp: @@ -86,7 +86,7 @@ def get_config(config=None): return snmp def verify(snmp): - if not snmp: + if 'deleted' in snmp: return None if {'deleted', 'lldp_snmp'} <= set(snmp): @@ -178,8 +178,6 @@ def verify(snmp): return None def generate(snmp): - - # # As we are manipulating the snmpd user database we have to stop it first! # This is even save if service is going to be removed call(f'systemctl stop {systemd_service}') @@ -190,7 +188,7 @@ def generate(snmp): if os.path.isfile(file): os.unlink(file) - if not snmp: + if 'deleted' in snmp: return None if 'v3' in snmp: @@ -244,7 +242,7 @@ def apply(snmp): # Always reload systemd manager configuration call('systemctl daemon-reload') - if not snmp: + if 'deleted' in snmp: return None # start SNMP daemon @@ -256,9 +254,7 @@ def apply(snmp): # Following daemons from FRR 9.0/stable have SNMP module compiled in VyOS frr_daemons_list = ['zebra', 'bgpd', 'ospf6d', 'ospfd', 'ripd', 'isisd', 'ldpd'] for frr_daemon in frr_daemons_list: - call( - f'vtysh -c "configure terminal" -d {frr_daemon} -c "agentx" >/dev/null' - ) + call(f'vtysh -c "configure terminal" -d {frr_daemon} -c "agentx" >/dev/null') return None diff --git a/src/migration-scripts/dns-dynamic/0-to-1 b/src/migration-scripts/dns-dynamic/0-to-1 index 4f6083eab..b7674a9c8 100755 --- a/src/migration-scripts/dns-dynamic/0-to-1 +++ b/src/migration-scripts/dns-dynamic/0-to-1 @@ -25,8 +25,10 @@ # to "service dns dynamic address <address> service <config> username ..." # - apply global 'ipv6-enable' to per <config> 'ip-version: ipv6' # - apply service protocol mapping upfront, they are not 'auto-detected' anymore +# - migrate web-options url to stricter format import sys +import re from vyos.configtree import ConfigTree service_protocol_mapping = { @@ -104,8 +106,17 @@ for address in config.list_nodes(new_base_path): new_base_path + ['web', svc_type, f'{svc_cfg}-{address}']) # Multiple web-options were not supported, so copy only the first one + # Also, migrate web-options url to stricter format and transition + # checkip.dyndns.org to https://domains.google.com/checkip for better + # TLS support (see: https://github.com/ddclient/ddclient/issues/597) if not config.exists(new_base_path + ['web', 'web-options']): config.copy(new_base_path + [address, 'use-web'], new_base_path + ['web', 'web-options']) + if config.exists(new_base_path + ['web', 'web-options', 'url']): + url = config.return_value(new_base_path + ['web', 'web-options', 'url']) + if re.search("^(https?://)?checkip\.dyndns\.org", url): + config.set(new_base_path + ['web', 'web-options', 'url'], 'https://domains.google.com/checkip') + if not url.startswith(('http://', 'https://')): + config.set(new_base_path + ['web', 'web-options', 'url'], f'https://{url}') config.delete(new_base_path + [address]) diff --git a/src/migration-scripts/dns-dynamic/2-to-3 b/src/migration-scripts/dns-dynamic/2-to-3 index e5910f7b4..4e0aa37d5 100755 --- a/src/migration-scripts/dns-dynamic/2-to-3 +++ b/src/migration-scripts/dns-dynamic/2-to-3 @@ -37,7 +37,7 @@ def normalize_name(name): # Normalize unicode characters to ASCII (NFKD) # Replace all separators with hypens, strip leading and trailing hyphens name = normalize('NFKD', name).encode('ascii', 'ignore').decode() - name = re.sub(r'(\s|\W)+', '-', name).strip('-') + name = re.sub(r'(\s|_|\W)+', '-', name).strip('-') return name diff --git a/src/migration-scripts/firewall/13-to-14 b/src/migration-scripts/firewall/13-to-14 new file mode 100755 index 000000000..f45ff0674 --- /dev/null +++ b/src/migration-scripts/firewall/13-to-14 @@ -0,0 +1,59 @@ +#!/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/>. + +# T5834: Rename 'enable-default-log' to 'default-log' +# From + # set firewall ... filter enable-default-log + # set firewall ... name <name> enable-default-log +# To + # set firewall ... filter default-log + # set firewall ... name <name> default-log + +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 = ['firewall'] +config = ConfigTree(config_file) + +if not config.exists(base): + # Nothing to do + exit(0) + +for family in ['ipv4', 'ipv6', 'bridge']: + if config.exists(base + [family]): + for hook in ['forward', 'input', 'output', 'name']: + if config.exists(base + [family, hook]): + for priority in config.list_nodes(base + [family, hook]): + if config.exists(base + [family, hook, priority, 'enable-default-log']): + config.rename(base + [family, hook, priority, 'enable-default-log'], 'default-log') + +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) diff --git a/src/migration-scripts/lldp/0-to-1 b/src/migration-scripts/lldp/0-to-1 index a936cbdfc..a99356062 100755 --- a/src/migration-scripts/lldp/0-to-1 +++ b/src/migration-scripts/lldp/0-to-1 @@ -1,4 +1,18 @@ #!/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/>. # Delete "set service lldp interface <interface> location civic-based" option # as it was broken most of the time anyways diff --git a/src/migration-scripts/lldp/1-to-2 b/src/migration-scripts/lldp/1-to-2 new file mode 100755 index 000000000..35efb25db --- /dev/null +++ b/src/migration-scripts/lldp/1-to-2 @@ -0,0 +1,48 @@ +#!/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/>. + +# T5855: migrate "set service lldp snmp enable" -> `set service lldp snmp" + +import sys + +from vyos.configtree import ConfigTree + +if len(sys.argv) < 2: + print("Must specify file name!") + sys.exit(1) + +file_name = sys.argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +config = ConfigTree(config_file) +base = ['service', 'lldp'] +if not config.exists(base): + # Nothing to do + sys.exit(0) + +if config.exists(base + ['snmp']): + enabled = config.exists(base + ['snmp', 'enable']) + config.delete(base + ['snmp']) + if enabled: config.set(base + ['snmp']) + +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)) + sys.exit(1) diff --git a/src/migration-scripts/policy/7-to-8 b/src/migration-scripts/policy/7-to-8 new file mode 100755 index 000000000..73eece1a6 --- /dev/null +++ b/src/migration-scripts/policy/7-to-8 @@ -0,0 +1,56 @@ +#!/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/>. + +# T5834: Rename 'enable-default-log' to 'default-log' +# From + # set policy [route | route 6] <route> enable-default-log +# To + # set policy [route | route 6] <route> default-log + +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 = ['policy'] +config = ConfigTree(config_file) + +if not config.exists(base): + # Nothing to do + exit(0) + +for family in ['route', 'route6']: + if config.exists(base + [family]): + + for policy_name in config.list_nodes(base + [family]): + if config.exists(base + [family, policy_name, 'enable-default-log']): + config.rename(base + [family, policy_name, 'enable-default-log'], 'default-log') + +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) |