diff options
31 files changed, 846 insertions, 237 deletions
| diff --git a/data/templates/dhcp-server/kea-dhcp6.conf.j2 b/data/templates/dhcp-server/kea-dhcp6.conf.j2 index 3ce4e6370..3ab21551b 100644 --- a/data/templates/dhcp-server/kea-dhcp6.conf.j2 +++ b/data/templates/dhcp-server/kea-dhcp6.conf.j2 @@ -1,7 +1,11 @@  {      "Dhcp6": {          "interfaces-config": { +{% if listen_interface is vyos_defined %} +            "interfaces": {{ listen_interface | tojson }}, +{% else %}              "interfaces": [ "*" ], +{% endif %}              "service-sockets-max-retries": 5,              "service-sockets-retry-wait-time": 5000          }, diff --git a/data/templates/frr/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2 index 679ba8b04..e02fdd1bb 100644 --- a/data/templates/frr/bgpd.frr.j2 +++ b/data/templates/frr/bgpd.frr.j2 @@ -402,6 +402,9 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }}  {%         if afi_config.flooding.head_end_replication is vyos_defined %}    flooding head-end-replication  {%         endif %} +{%         if afi_config.nexthop.vpn.export is vyos_defined %} +  nexthop vpn export {{ afi_config.nexthop.vpn.export }} +{%         endif %}  {%         if afi_config.rd.vpn.export is vyos_defined %}    rd vpn export {{ afi_config.rd.vpn.export }}  {%         endif %} @@ -436,6 +439,9 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }}  {%         if afi_config.route_map.vpn.import is vyos_defined %}    route-map vpn import {{ afi_config.route_map.vpn.import }}  {%         endif %} +{%         if afi_config.sid.vpn.export is vyos_defined %} + sid vpn export {{ afi_config.sid.vpn.export }} +{%         endif %}  {%         if afi_config.vni is vyos_defined %}  {%             for vni, vni_config in afi_config.vni.items() %}    vni {{ vni }} diff --git a/data/templates/ipsec/swanctl/peer.j2 b/data/templates/ipsec/swanctl/peer.j2 index 9d95271fe..86a44a0ff 100644 --- a/data/templates/ipsec/swanctl/peer.j2 +++ b/data/templates/ipsec/swanctl/peer.j2 @@ -83,8 +83,7 @@                  start_action = none  {%     endif %}  {%     if ike.dead_peer_detection is vyos_defined %} -{%         set dpd_translate = {'clear': 'clear', 'hold': 'trap', 'restart': 'restart'} %} -                dpd_action = {{ dpd_translate[ike.dead_peer_detection.action] }} +                dpd_action = {{ ike.dead_peer_detection.action }}  {%     endif %}                  close_action = {{ {'none': 'none', 'hold': 'trap', 'restart': 'start'}[ike.close_action] }}              } @@ -134,8 +133,7 @@                  start_action = none  {%         endif %}  {%         if ike.dead_peer_detection is vyos_defined %} -{%             set dpd_translate = {'clear': 'clear', 'hold': 'trap', 'restart': 'restart'} %} -                dpd_action = {{ dpd_translate[ike.dead_peer_detection.action] }} +                dpd_action = {{ ike.dead_peer_detection.action }}  {%         endif %}                  close_action = {{ {'none': 'none', 'hold': 'trap', 'restart': 'start'}[ike.close_action] }}  {%         if peer_conf.vti.bind is vyos_defined %} diff --git a/interface-definitions/include/bgp/afi-nexthop-vpn-export.xml.i b/interface-definitions/include/bgp/afi-nexthop-vpn-export.xml.i new file mode 100644 index 000000000..d90597f37 --- /dev/null +++ b/interface-definitions/include/bgp/afi-nexthop-vpn-export.xml.i @@ -0,0 +1,32 @@ +<!-- include start from bgp/afi-nexthop-vpn-export.xml.i --> +<node name="nexthop"> +  <properties> +    <help>Specify next hop to use for VRF advertised prefixes</help> +  </properties> +  <children> +    <node name="vpn"> +      <properties> +        <help>Between current address-family and vpn</help> +      </properties> +      <children> +        <leafNode name="export"> +          <properties> +            <help>For routes leaked from current address-family to vpn</help> +            <valueHelp> +                <format>ipv4</format> +                <description>BGP neighbor IP address</description> +              </valueHelp> +              <valueHelp> +                <format>ipv6</format> +                <description>BGP neighbor IPv6 address</description> +              </valueHelp> +              <constraint> +                <validator name="ip-address"/> +              </constraint> +          </properties> +        </leafNode> +      </children> +    </node> +  </children> +</node> +  <!-- include end --> diff --git a/interface-definitions/include/bgp/afi-sid.xml.i b/interface-definitions/include/bgp/afi-sid.xml.i new file mode 100644 index 000000000..38a3dcf9b --- /dev/null +++ b/interface-definitions/include/bgp/afi-sid.xml.i @@ -0,0 +1,36 @@ +<!-- include start from bgp/sid.xml.i --> +<node name="sid"> +    <properties> +      <help>SID value for VRF</help> +    </properties> +    <children> +      <node name="vpn"> +        <properties> +          <help>Between current VRF and VPN</help> +        </properties> +        <children> +          <leafNode name="export"> +            <properties> +              <help>For routes leaked from current VRF to VPN</help> +              <completionHelp> +                <list>auto</list> +              </completionHelp> +              <valueHelp> +                <format>u32:1-1048575</format> +                <description>SID allocation index</description> +              </valueHelp> +              <valueHelp> +                <format>auto</format> +                <description>Automatically assign a label</description> +              </valueHelp> +              <constraint> +                <regex>auto</regex> +                <validator name="numeric" argument="--range 1-1048575"/> +              </constraint> +            </properties> +          </leafNode> +        </children> +      </node> +    </children> +  </node> +  <!-- include end --> diff --git a/interface-definitions/include/bgp/protocol-common-config.xml.i b/interface-definitions/include/bgp/protocol-common-config.xml.i index bb35efe94..9895b025c 100644 --- a/interface-definitions/include/bgp/protocol-common-config.xml.i +++ b/interface-definitions/include/bgp/protocol-common-config.xml.i @@ -120,6 +120,7 @@          #include <include/bgp/afi-rd.xml.i>          #include <include/bgp/afi-route-map-vpn.xml.i>          #include <include/bgp/afi-route-target-vpn.xml.i> +        #include <include/bgp/afi-nexthop-vpn-export.xml.i>          <node name="redistribute">            <properties>              <help>Redistribute routes from other protocols into BGP</help> @@ -188,6 +189,7 @@              </leafNode>            </children>          </node> +        #include <include/bgp/afi-sid.xml.i>        </children>      </node>      <node name="ipv4-multicast"> @@ -495,6 +497,7 @@          #include <include/bgp/afi-rd.xml.i>          #include <include/bgp/afi-route-map-vpn.xml.i>          #include <include/bgp/afi-route-target-vpn.xml.i> +        #include <include/bgp/afi-nexthop-vpn-export.xml.i>          <node name="redistribute">            <properties>              <help>Redistribute routes from other protocols into BGP</help> @@ -555,6 +558,7 @@              </leafNode>            </children>          </node> +        #include <include/bgp/afi-sid.xml.i>        </children>      </node>      <node name="ipv6-multicast"> diff --git a/interface-definitions/include/dhcp/option-v6.xml.i b/interface-definitions/include/dhcp/option-v6.xml.i new file mode 100644 index 000000000..1df0c3934 --- /dev/null +++ b/interface-definitions/include/dhcp/option-v6.xml.i @@ -0,0 +1,110 @@ +<!-- include start from dhcp/option-v6.xml.i --> +<node name="option"> +  <properties> +    <help>DHCPv6 option</help> +  </properties> +  <children> +    #include <include/dhcp/captive-portal.xml.i> +    #include <include/dhcp/domain-search.xml.i> +    #include <include/name-server-ipv6.xml.i> +    <leafNode name="nis-domain"> +      <properties> +        <help>NIS domain name for client to use</help> +        <constraint> +          #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> +        </constraint> +        <constraintErrorMessage>Invalid NIS domain name</constraintErrorMessage> +      </properties> +    </leafNode> +    <leafNode name="nis-server"> +      <properties> +        <help>IPv6 address of a NIS Server</help> +        <valueHelp> +          <format>ipv6</format> +          <description>IPv6 address of NIS server</description> +        </valueHelp> +        <constraint> +          <validator name="ipv6-address"/> +        </constraint> +        <multi/> +      </properties> +    </leafNode> +    <leafNode name="nisplus-domain"> +      <properties> +        <help>NIS+ domain name for client to use</help> +        <constraint> +          #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> +        </constraint> +        <constraintErrorMessage>Invalid NIS+ domain name. May only contain letters, numbers and .-_</constraintErrorMessage> +      </properties> +    </leafNode> +    <leafNode name="nisplus-server"> +      <properties> +        <help>IPv6 address of a NIS+ Server</help> +        <valueHelp> +          <format>ipv6</format> +          <description>IPv6 address of NIS+ server</description> +        </valueHelp> +        <constraint> +          <validator name="ipv6-address"/> +        </constraint> +        <multi/> +      </properties> +    </leafNode> +    <leafNode name="sip-server"> +      <properties> +        <help>IPv6 address of SIP server</help> +        <valueHelp> +          <format>ipv6</format> +          <description>IPv6 address of SIP server</description> +        </valueHelp> +        <valueHelp> +          <format>hostname</format> +          <description>FQDN of SIP server</description> +        </valueHelp> +        <constraint> +          <validator name="ipv6-address"/> +          <validator name="fqdn"/> +        </constraint> +        <multi/> +      </properties> +    </leafNode> +    <leafNode name="sntp-server"> +      <properties> +        <help>IPv6 address of an SNTP server for client to use</help> +        <constraint> +          <validator name="ipv6-address"/> +        </constraint> +        <multi/> +      </properties> +    </leafNode> +    <node name="vendor-option"> +      <properties> +        <help>Vendor Specific Options</help> +      </properties> +      <children> +        <node name="cisco"> +          <properties> +            <help>Cisco specific parameters</help> +          </properties> +          <children> +            <leafNode name="tftp-server"> +              <properties> +                <help>TFTP server name</help> +                <valueHelp> +                  <format>ipv6</format> +                  <description>TFTP server IPv6 address</description> +                </valueHelp> +                <constraint> +                  <validator name="ipv6-address"/> +                </constraint> +                <multi/> +              </properties> +            </leafNode> +          </children> +        </node> +      </children> +    </node> +  </children> +</node> +<!-- include end --> diff --git a/interface-definitions/include/version/ipsec-version.xml.i b/interface-definitions/include/version/ipsec-version.xml.i index de7a9c088..a4d556cfc 100644 --- a/interface-definitions/include/version/ipsec-version.xml.i +++ b/interface-definitions/include/version/ipsec-version.xml.i @@ -1,3 +1,3 @@  <!-- include start from include/version/ipsec-version.xml.i --> -<syntaxVersion component='ipsec' version='12'></syntaxVersion> +<syntaxVersion component='ipsec' version='13'></syntaxVersion>  <!-- include end --> diff --git a/interface-definitions/service_dhcpv6-server.xml.in b/interface-definitions/service_dhcpv6-server.xml.in index 6934ceeec..07cbfc85d 100644 --- a/interface-definitions/service_dhcpv6-server.xml.in +++ b/interface-definitions/service_dhcpv6-server.xml.in @@ -9,6 +9,7 @@          </properties>          <children>            #include <include/generic-disable-node.xml.i> +          #include <include/listen-interface-multi-broadcast.xml.i>            <node name="global-parameters">              <properties>                <help>Additional global parameters for DHCPv6 server</help> @@ -89,11 +90,17 @@                    </constraint>                  </properties>                  <children> -                  <node name="address-range"> +                  #include <include/dhcp/option-v6.xml.i> +                  <tagNode name="range">                      <properties>                        <help>Parameters setting ranges for assigning IPv6 addresses</help> +                      <constraint> +                        #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> +                      </constraint> +                      <constraintErrorMessage>Invalid range name, may only be alphanumeric, dot and hyphen</constraintErrorMessage>                      </properties>                      <children> +                      #include <include/dhcp/option-v6.xml.i>                        <leafNode name="prefix">                          <properties>                            <help>IPv6 prefix defining range of addresses to assign</help> @@ -104,10 +111,9 @@                            <constraint>                              <validator name="ipv6-prefix"/>                            </constraint> -                          <multi/>                          </properties>                        </leafNode> -                      <tagNode name="start"> +                      <leafNode name="start">                          <properties>                            <help>First in range of consecutive IPv6 addresses to assign</help>                            <valueHelp> @@ -118,25 +124,21 @@                              <validator name="ipv6-address"/>                            </constraint>                          </properties> -                        <children> -                          <leafNode name="stop"> -                            <properties> -                              <help>Last in range of consecutive IPv6 addresses</help> -                              <valueHelp> -                                <format>ipv6</format> -                                <description>IPv6 address</description> -                              </valueHelp> -                              <constraint> -                                <validator name="ipv6-address"/> -                              </constraint> -                            </properties> -                          </leafNode> -                        </children> -                      </tagNode> +                      </leafNode> +                      <leafNode name="stop"> +                        <properties> +                          <help>Last in range of consecutive IPv6 addresses</help> +                          <valueHelp> +                            <format>ipv6</format> +                            <description>IPv6 address</description> +                          </valueHelp> +                          <constraint> +                            <validator name="ipv6-address"/> +                          </constraint> +                        </properties> +                      </leafNode>                      </children> -                  </node> -                  #include <include/dhcp/captive-portal.xml.i> -                  #include <include/dhcp/domain-search.xml.i> +                  </tagNode>                    <node name="lease-time">                      <properties>                        <help>Parameters relating to the lease time</help> @@ -180,51 +182,6 @@                        </leafNode>                      </children>                    </node> -                  #include <include/name-server-ipv6.xml.i> -                  <leafNode name="nis-domain"> -                    <properties> -                      <help>NIS domain name for client to use</help> -                      <constraint> -                        #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> -                      </constraint> -                      <constraintErrorMessage>Invalid NIS domain name</constraintErrorMessage> -                    </properties> -                  </leafNode> -                  <leafNode name="nis-server"> -                    <properties> -                      <help>IPv6 address of a NIS Server</help> -                      <valueHelp> -                        <format>ipv6</format> -                        <description>IPv6 address of NIS server</description> -                      </valueHelp> -                      <constraint> -                        <validator name="ipv6-address"/> -                      </constraint> -                      <multi/> -                    </properties> -                  </leafNode> -                  <leafNode name="nisplus-domain"> -                    <properties> -                      <help>NIS+ domain name for client to use</help> -                      <constraint> -                        #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> -                      </constraint> -                      <constraintErrorMessage>Invalid NIS+ domain name. May only contain letters, numbers and .-_</constraintErrorMessage> -                    </properties> -                  </leafNode> -                  <leafNode name="nisplus-server"> -                    <properties> -                      <help>IPv6 address of a NIS+ Server</help> -                      <valueHelp> -                        <format>ipv6</format> -                        <description>IPv6 address of NIS+ server</description> -                      </valueHelp> -                      <constraint> -                        <validator name="ipv6-address"/> -                      </constraint> -                      <multi/> -                    </properties> -                  </leafNode>                    <node name="prefix-delegation">                      <properties>                        <help>Parameters relating to IPv6 prefix delegation</help> @@ -272,33 +229,6 @@                        </tagNode>                      </children>                    </node> -                  <leafNode name="sip-server"> -                    <properties> -                      <help>IPv6 address of SIP server</help> -                      <valueHelp> -                        <format>ipv6</format> -                        <description>IPv6 address of SIP server</description> -                      </valueHelp> -                      <valueHelp> -                        <format>hostname</format> -                        <description>FQDN of SIP server</description> -                      </valueHelp> -                      <constraint> -                        <validator name="ipv6-address"/> -                        <validator name="fqdn"/> -                      </constraint> -                      <multi/> -                    </properties> -                  </leafNode> -                  <leafNode name="sntp-server"> -                    <properties> -                      <help>IPv6 address of an SNTP server for client to use</help> -                      <constraint> -                        <validator name="ipv6-address"/> -                      </constraint> -                      <multi/> -                    </properties> -                  </leafNode>                    <tagNode name="static-mapping">                      <properties>                        <help>Hostname for static mapping reservation</help> @@ -308,6 +238,7 @@                        <constraintErrorMessage>Invalid static mapping hostname</constraintErrorMessage>                      </properties>                      <children> +                      #include <include/dhcp/option-v6.xml.i>                        #include <include/generic-disable-node.xml.i>                        #include <include/interface/mac.xml.i>                        #include <include/interface/duid.xml.i> @@ -349,33 +280,6 @@                        </constraint>                      </properties>                    </leafNode> -                  <node name="vendor-option"> -                    <properties> -                      <help>Vendor Specific Options</help> -                    </properties> -                    <children> -                      <node name="cisco"> -                        <properties> -                          <help>Cisco specific parameters</help> -                        </properties> -                        <children> -                          <leafNode name="tftp-server"> -                            <properties> -                              <help>TFTP server name</help> -                              <valueHelp> -                                <format>ipv6</format> -                                <description>TFTP server IPv6 address</description> -                              </valueHelp> -                              <constraint> -                                <validator name="ipv6-address"/> -                              </constraint> -                              <multi/> -                            </properties> -                          </leafNode> -                        </children> -                      </node> -                    </children> -                  </node>                  </children>                </tagNode>              </children> diff --git a/interface-definitions/vpn_ipsec.xml.in b/interface-definitions/vpn_ipsec.xml.in index 1847401b5..76c71949f 100644 --- a/interface-definitions/vpn_ipsec.xml.in +++ b/interface-definitions/vpn_ipsec.xml.in @@ -280,10 +280,10 @@                      <properties>                        <help>Keep-alive failure action</help>                        <completionHelp> -                        <list>hold clear restart</list> +                        <list>trap clear restart</list>                        </completionHelp>                        <valueHelp> -                        <format>hold</format> +                        <format>trap</format>                          <description>Attempt to re-negotiate the connection when matching traffic is seen</description>                        </valueHelp>                        <valueHelp> @@ -295,7 +295,7 @@                          <description>Attempt to re-negotiate the connection immediately</description>                        </valueHelp>                        <constraint> -                        <regex>(hold|clear|restart)</regex> +                        <regex>(trap|clear|restart)</regex>                        </constraint>                      </properties>                      <defaultValue>clear</defaultValue> diff --git a/python/vyos/kea.py b/python/vyos/kea.py index aa4fb7ae5..fb5afc2ce 100644 --- a/python/vyos/kea.py +++ b/python/vyos/kea.py @@ -175,16 +175,6 @@ def kea_parse_subnet(subnet, config):  def kea6_parse_options(config):      options = [] -    if 'common_options' in config: -        common_opt = config['common_options'] - -        for node, option_name in kea6_options.items(): -            if node not in common_opt: -                continue - -            value = ", ".join(common_opt[node]) if isinstance(common_opt[node], list) else common_opt[node] -            options.append({'name': option_name, 'data': value}) -      for node, option_name in kea6_options.items():          if node not in config:              continue @@ -218,20 +208,27 @@ def kea6_parse_options(config):  def kea6_parse_subnet(subnet, config):      out = {'subnet': subnet, 'id': int(config['subnet_id'])} -    options = kea6_parse_options(config) -    if 'address_range' in config: -        addr_range = config['address_range'] +    if 'option' in config: +        out['option-data'] = kea6_parse_options(config['option']) + +    if 'range' in config:          pools = [] +        for num, range_config in config['range'].items(): +            pool = {} -        if 'prefix' in addr_range: -            for prefix in addr_range['prefix']: -                pools.append({'pool': prefix}) +            if 'prefix' in range_config: +                pool['pool'] = range_config['prefix'] -        if 'start' in addr_range: -            for start, range_conf in addr_range['start'].items(): -                stop = range_conf['stop'] -                pools.append({'pool': f'{start} - {stop}'}) +            if 'start' in range_config: +                start = range_config['start'] +                stop = range_config['stop'] +                pool['pool'] = f'{start} - {stop}' + +            if 'option' in range_config: +                pool['option-data'] = kea6_parse_options(range_config['option']) + +            pools.append(pool)          out['pools'] = pools @@ -278,13 +275,13 @@ def kea6_parse_subnet(subnet, config):              if 'ipv6_prefix' in host_config:                  reservation['prefixes'] = [ host_config['ipv6_prefix'] ] +            if 'option' in host_config: +                reservation['option-data'] = kea6_parse_options(host_config['option']) +              reservations.append(reservation)          out['reservations'] = reservations -    if options: -        out['option-data'] = options -      return out  def kea_parse_leases(lease_path): diff --git a/python/vyos/template.py b/python/vyos/template.py index 1368f1f61..456239568 100644 --- a/python/vyos/template.py +++ b/python/vyos/template.py @@ -894,7 +894,9 @@ def kea6_shared_network_json(shared_networks):              'name': name,              'subnet6': []          } -        options = kea6_parse_options(config) + +        if 'common_options' in config: +            network['option-data'] = kea6_parse_options(config['common_options'])          if 'interface' in config:              network['interface'] = config['interface'] @@ -903,9 +905,6 @@ def kea6_shared_network_json(shared_networks):              for subnet, subnet_config in config['subnet'].items():                  network['subnet6'].append(kea6_parse_subnet(subnet, subnet_config)) -        if options: -            network['option-data'] = options -          out.append(network)      return dumps(out, indent=4) diff --git a/smoketest/config-tests/bgp-medium-confederation b/smoketest/config-tests/bgp-medium-confederation new file mode 100644 index 000000000..ea3c2d144 --- /dev/null +++ b/smoketest/config-tests/bgp-medium-confederation @@ -0,0 +1,73 @@ +set interfaces dummy dum0 address '1.1.1.1/32' +set interfaces dummy dum0 address '2001:db8::1/128' +set interfaces ethernet eth0 address 'fd52:100:200:fffe::1/64' +set interfaces ethernet eth0 address '192.168.253.1/24' +set interfaces ethernet eth1 +set interfaces ethernet eth2 +set policy route-map BGP-IN rule 10 action 'permit' +set policy route-map BGP-OUT rule 10 action 'permit' +set policy route-map BGP-REDISTRIBUTE rule 10 action 'deny' +set policy route-map DEFAULT-ZEBRA-IN rule 10 action 'deny' +set protocols bgp address-family ipv4-unicast redistribute connected route-map 'BGP-REDISTRIBUTE' +set protocols bgp address-family ipv4-unicast redistribute static route-map 'BGP-REDISTRIBUTE' +set protocols bgp address-family ipv6-unicast redistribute connected route-map 'BGP-REDISTRIBUTE' +set protocols bgp neighbor 192.168.253.14 peer-group 'WDC07' +set protocols bgp neighbor 192.168.253.16 peer-group 'WDC07' +set protocols bgp neighbor 192.168.253.17 peer-group 'WDC07' +set protocols bgp neighbor 192.168.253.18 peer-group 'WDC07' +set protocols bgp neighbor 192.168.253.19 peer-group 'WDC07' +set protocols bgp neighbor eth1 interface v6only peer-group 'BACKBONE' +set protocols bgp neighbor eth1 interface v6only remote-as '666' +set protocols bgp neighbor eth2 interface v6only peer-group 'BACKBONE' +set protocols bgp neighbor eth2 interface v6only remote-as '666' +set protocols bgp neighbor fd52:100:200:fffe::14 address-family ipv6-unicast +set protocols bgp neighbor fd52:100:200:fffe::14 peer-group 'WDC07v6' +set protocols bgp neighbor fd52:100:200:fffe::16 address-family ipv6-unicast +set protocols bgp neighbor fd52:100:200:fffe::16 peer-group 'WDC07v6' +set protocols bgp neighbor fd52:100:200:fffe::17 address-family ipv6-unicast +set protocols bgp neighbor fd52:100:200:fffe::17 peer-group 'WDC07v6' +set protocols bgp neighbor fd52:100:200:fffe::18 address-family ipv6-unicast +set protocols bgp neighbor fd52:100:200:fffe::18 peer-group 'WDC07v6' +set protocols bgp neighbor fd52:100:200:fffe::19 address-family ipv6-unicast +set protocols bgp neighbor fd52:100:200:fffe::19 peer-group 'WDC07v6' +set protocols bgp parameters bestpath as-path confed +set protocols bgp parameters bestpath as-path multipath-relax +set protocols bgp parameters confederation identifier '696' +set protocols bgp parameters confederation peers '668' +set protocols bgp parameters confederation peers '669' +set protocols bgp parameters confederation peers '666' +set protocols bgp parameters graceful-restart +set protocols bgp parameters router-id '192.168.253.15' +set protocols bgp peer-group BACKBONE address-family ipv4-unicast nexthop-self +set protocols bgp peer-group BACKBONE address-family ipv4-unicast route-map export 'BGP-OUT' +set protocols bgp peer-group BACKBONE address-family ipv4-unicast route-map import 'BGP-IN' +set protocols bgp peer-group BACKBONE address-family ipv4-unicast soft-reconfiguration inbound +set protocols bgp peer-group BACKBONE address-family ipv6-unicast nexthop-self +set protocols bgp peer-group BACKBONE address-family ipv6-unicast route-map export 'BGP-OUT' +set protocols bgp peer-group BACKBONE address-family ipv6-unicast route-map import 'BGP-IN' +set protocols bgp peer-group BACKBONE address-family ipv6-unicast soft-reconfiguration inbound +set protocols bgp peer-group BACKBONE capability extended-nexthop +set protocols bgp peer-group WDC07 address-family ipv4-unicast default-originate +set protocols bgp peer-group WDC07 address-family ipv4-unicast nexthop-self +set protocols bgp peer-group WDC07 address-family ipv4-unicast route-map export 'BGP-OUT' +set protocols bgp peer-group WDC07 address-family ipv4-unicast route-map import 'BGP-IN' +set protocols bgp peer-group WDC07 address-family ipv4-unicast soft-reconfiguration inbound +set protocols bgp peer-group WDC07 remote-as '670' +set protocols bgp peer-group WDC07 update-source 'dum0' +set protocols bgp peer-group WDC07v6 address-family ipv6-unicast default-originate +set protocols bgp peer-group WDC07v6 address-family ipv6-unicast nexthop-self +set protocols bgp peer-group WDC07v6 address-family ipv6-unicast route-map export 'BGP-OUT' +set protocols bgp peer-group WDC07v6 address-family ipv6-unicast route-map import 'BGP-IN' +set protocols bgp peer-group WDC07v6 address-family ipv6-unicast soft-reconfiguration inbound +set protocols bgp peer-group WDC07v6 remote-as '670' +set protocols bgp peer-group WDC07v6 update-source 'dum0' +set protocols bgp system-as '670' +set system config-management commit-revisions '200' +set system console device ttyS0 speed '115200' +set system domain-name 'vyos.net' +set system host-name 'vyos' +set system ip protocol bgp route-map 'DEFAULT-ZEBRA-IN' +set system login user vyos authentication encrypted-password '$6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0' +set system login user vyos authentication plaintext-password '' +set system syslog global facility all level 'notice' +set system syslog global facility local7 level 'debug' diff --git a/smoketest/configs/basic-vyos b/smoketest/configs/basic-vyos index fca4964bf..c42f14841 100644 --- a/smoketest/configs/basic-vyos +++ b/smoketest/configs/basic-vyos @@ -95,10 +95,15 @@ service {          shared-network-name LAN6 {              subnet fe88::/56 {                  address-range { -                    prefix fe88::/56 { +                    prefix fe88::/60 {                          temporary                      } +                    start fe88:0000:0000:fe:: { +                        stop fe88:0000:0000:ff:: +                    }                  } +                domain-search vyos.net +                name-server fe88::1                  prefix-delegation {                      start fe88:0000:0000:0001:: {                          prefix-length 64 diff --git a/smoketest/configs/bgp-azure-ipsec-gateway b/smoketest/configs/bgp-azure-ipsec-gateway index ddcd459ae..5803e8ce9 100644 --- a/smoketest/configs/bgp-azure-ipsec-gateway +++ b/smoketest/configs/bgp-azure-ipsec-gateway @@ -226,6 +226,31 @@ protocols {      }  }  service { +    snmp { +        v3 { +            engineid 0xff42 +            group default { +                mode ro +                seclevel priv +                view default +            } +            user VyOS { +                auth { +                    encrypted-key 0x1ad73f4620b8c0dd2de066622f875b161a14adad +                    type sha +                } +                group default +                privacy { +                    encrypted-key 0x1ad73f4620b8c0dd2de066622f875b16 +                    type aes +                } +            } +            view default { +                oid 1 { +                } +            } +        } +    }      ssh {          disable-host-validation          port 22 diff --git a/smoketest/configs/bgp-medium-confederation b/smoketest/configs/bgp-medium-confederation new file mode 100644 index 000000000..dfb944d09 --- /dev/null +++ b/smoketest/configs/bgp-medium-confederation @@ -0,0 +1,247 @@ +interfaces { +    dummy dum0 { +        address 1.1.1.1/32 +        address 2001:db8::1/128 +    } +    ethernet eth0 { +        address 192.168.253.1/24 +        address fd52:100:200:fffe::1/64 +    } +    ethernet eth1 { +    } +    ethernet eth2 { +    } +} +policy { +    route-map BGP-IN { +        rule 10 { +            action permit +        } +    } +    route-map BGP-OUT { +        rule 10 { +            action permit +        } +    } +    route-map BGP-REDISTRIBUTE { +        rule 10 { +            action deny +        } +    } +    route-map DEFAULT-ZEBRA-IN { +        rule 10 { +            action deny +        } +    } +} +protocols { +  bgp 670 { +        address-family { +            ipv4-unicast { +                redistribute { +                    connected { +                        route-map BGP-REDISTRIBUTE +                    } +                    static { +                        route-map BGP-REDISTRIBUTE +                    } +                } +            } +            ipv6-unicast { +                redistribute { +                    connected { +                        route-map BGP-REDISTRIBUTE +                    } +                } +            } +        } +        neighbor 192.168.253.14 { +            peer-group WDC07 +        } +        neighbor 192.168.253.16 { +            peer-group WDC07 +        } +        neighbor 192.168.253.17 { +            peer-group WDC07 +        } +        neighbor 192.168.253.18 { +            peer-group WDC07 +        } +        neighbor 192.168.253.19 { +            peer-group WDC07 +        } +        neighbor eth1 { +            interface { +                v6only { +                    peer-group BACKBONE +                    remote-as 666 +                } +            } +        } +        neighbor eth2 { +            interface { +                v6only { +                    peer-group BACKBONE +                    remote-as 666 +                } +            } +        } +        neighbor fd52:100:200:fffe::14 { +            address-family { +                ipv6-unicast { +                    peer-group WDC07v6 +                } +            } +        } +        neighbor fd52:100:200:fffe::16 { +            address-family { +                ipv6-unicast { +                    peer-group WDC07v6 +                } +            } +        } +        neighbor fd52:100:200:fffe::17 { +            address-family { +                ipv6-unicast { +                    peer-group WDC07v6 +                } +            } +        } +        neighbor fd52:100:200:fffe::18 { +            address-family { +                ipv6-unicast { +                    peer-group WDC07v6 +                } +            } +        } +        neighbor fd52:100:200:fffe::19 { +            address-family { +                ipv6-unicast { +                    peer-group WDC07v6 +                } +            } +        } +        parameters { +            bestpath { +                as-path { +                    confed +                    multipath-relax +                } +            } +            confederation { +                identifier 696 +                peers 668 +                peers 669 +                peers 666 +            } +            default { +                no-ipv4-unicast +            } +            graceful-restart { +            } +            router-id 192.168.253.15 +        } +        peer-group BACKBONE { +            address-family { +                ipv4-unicast { +                    nexthop-self { +                    } +                    route-map { +                        export BGP-OUT +                        import BGP-IN +                    } +                    soft-reconfiguration { +                        inbound +                    } +                } +                ipv6-unicast { +                    nexthop-self { +                    } +                    route-map { +                        export BGP-OUT +                        import BGP-IN +                    } +                    soft-reconfiguration { +                        inbound +                    } +                } +            } +            capability { +                extended-nexthop +            } +        } +        peer-group WDC07 { +            address-family { +                ipv4-unicast { +                    default-originate { +                    } +                    nexthop-self { +                    } +                    route-map { +                        export BGP-OUT +                        import BGP-IN +                    } +                    soft-reconfiguration { +                        inbound +                    } +                } +            } +            remote-as 670 +            update-source dum0 +        } +        peer-group WDC07v6 { +            address-family { +                ipv6-unicast { +                    default-originate { +                    } +                    nexthop-self { +                    } +                    route-map { +                        export BGP-OUT +                        import BGP-IN +                    } +                    soft-reconfiguration { +                        inbound +                    } +                } +            } +            remote-as 670 +            update-source dum0 +        } +        route-map DEFAULT-ZEBRA-IN +    } +} +system { +    config-management { +        commit-revisions 200 +    } +    console { +        device ttyS0 { +            speed 115200 +        } +    } +    domain-name vyos.net +    host-name vyos +    login { +        user vyos { +            authentication { +                encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0 +                plaintext-password "" +            } +        } +    } +    syslog { +        global { +            facility all { +                level notice +            } +            facility protocols { +                level debug +            } +        } +    } +} + +// Warning: Do not remove the following line. +// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@3:conntrack-sync@2:container@1:dhcp-relay@2:dhcp-server@6:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@22:ipoe-server@1:ipsec@5:isis@1:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@8:rpki@1:salt@1:snmp@2:ssh@2:sstp@3:system@21:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1" +// Release version: 1.3.5 diff --git a/smoketest/configs/ospf-small b/smoketest/configs/ospf-small index b3002b1af..c55627b77 100644 --- a/smoketest/configs/ospf-small +++ b/smoketest/configs/ospf-small @@ -1,13 +1,63 @@  interfaces {      dummy dum0 { -        address 172.18.254.201/32 +        address 172.18.254.200/32      }      ethernet eth0 {          duplex auto          smp-affinity auto          speed auto          vif 201 { -            address 172.18.201.10/24 +            address 172.18.201.9/24 +            ip { +                ospf { +                    authentication { +                        md5 { +                            key-id 10 { +                                md5-key OSPFVyOSNET +                            } +                        } +                    } +                    dead-interval 40 +                    hello-interval 10 +                    priority 1 +                    retransmit-interval 5 +                    transmit-delay 1 +                } +            } +            ipv6 { +                ospfv3 { +                    bfd +                    cost 40 +                } +            } +        } +        vif 202 { +            address 172.18.202.9/24 +            ip { +                ospf { +                    authentication { +                        md5 { +                            key-id 10 { +                                md5-key OSPFVyOSNET +                            } +                        } +                    } +                    dead-interval 40 +                    hello-interval 10 +                    priority 1 +                    retransmit-interval 5 +                    transmit-delay 1 +                } +            } +            ipv6 { +                ospfv3 { +                    bfd +                    cost 40 +                } +            } +        } +        vif 203 { +            address 172.18.203.9/24              ip {                  ospf {                      authentication { @@ -51,48 +101,31 @@ protocols {      ospf {          area 0 {              network 172.18.201.0/24 -            network 172.18.254.201/32 +            network 172.18.202.0/24 +            network 172.18.203.0/24 +            network 172.18.254.200/32          }          log-adjacency-changes {          }          parameters {              abr-type cisco -            router-id 172.18.254.201 +            router-id 172.18.254.200          }          passive-interface default          passive-interface-exclude eth0.201 +        passive-interface-exclude eth0.202 +        passive-interface-exclude eth0.203      }      ospfv3 {          area 0.0.0.0 { -            interface eth0 +            interface eth0.201 +            interface eth0.202 +            interface eth0.203              interface eth1 -            interface eth2 -        } -    } -    static { -        route 0.0.0.0/0 { -            next-hop 172.18.201.254 { -                distance 10 -            }          }      }  }  service { -    lldp { -        interface all { -        } -        snmp { -            enable -        } -    } -    snmp { -        community public { -            authorization ro -            network 172.16.100.0/24 -        } -        contact "VyOS maintainers and contributors <maintainers@vyos.io>" -        location "Jenkins" -    }      ssh {          disable-host-validation          port 22 @@ -120,11 +153,9 @@ system {      }      name-server 172.16.254.30      ntp { -        server 0.pool.ntp.org { -        } -        server 1.pool.ntp.org { +        server time1.vyos.net {          } -        server 2.pool.ntp.org { +        server time2.vyos.net {          }      }      sysctl { diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index d5efae12c..2dbc30a41 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -1139,10 +1139,16 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):      def test_bgp_24_srv6_sid(self):          locator_name = 'VyOS_foo'          sid = 'auto' +        nexthop_ipv4 = '192.0.0.1' +        nexthop_ipv6 = '2001:db8:100:200::2'          self.cli_set(base_path + ['srv6', 'locator', locator_name])          self.cli_set(base_path + ['sid', 'vpn', 'per-vrf', 'export', sid]) - +        self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'sid', 'vpn', 'export', sid]) +        # verify() - SID per VRF and SID per address-family are mutually exclusive! +        with self.assertRaises(ConfigSessionError): +            self.cli_commit() +        self.cli_delete(base_path + ['address-family', 'ipv4-unicast', 'sid'])          self.cli_commit()          frrconfig = self.getFRRconfig(f'router bgp {ASN}') @@ -1151,6 +1157,27 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase):          self.assertIn(f'  locator {locator_name}', frrconfig)          self.assertIn(f' sid vpn per-vrf export {sid}', frrconfig) +        # Now test AFI SID +        self.cli_delete(base_path + ['sid']) +        self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'sid', 'vpn', 'export', sid]) +        self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'nexthop', 'vpn', 'export', nexthop_ipv4]) +        self.cli_set(base_path + ['address-family', 'ipv6-unicast', 'sid', 'vpn', 'export', sid]) +        self.cli_set(base_path + ['address-family', 'ipv6-unicast', 'nexthop', 'vpn', 'export', nexthop_ipv6]) + +        self.cli_commit() + +        frrconfig = self.getFRRconfig(f'router bgp {ASN}') +        self.assertIn(f'router bgp {ASN}', frrconfig) +        self.assertIn(f' segment-routing srv6', frrconfig) +        self.assertIn(f'  locator {locator_name}', frrconfig) + +        afiv4_config = self.getFRRconfig(' address-family ipv4 unicast') +        self.assertIn(f' sid vpn export {sid}', afiv4_config) +        self.assertIn(f' nexthop vpn export {nexthop_ipv4}', afiv4_config) +        afiv6_config = self.getFRRconfig(' address-family ipv6 unicast') +        self.assertIn(f' sid vpn export {sid}', afiv6_config) +        self.assertIn(f' nexthop vpn export {nexthop_ipv6}', afiv4_config) +      def test_bgp_25_ipv4_ipv6_labeled_unicast_peer_group(self):          pg_ipv4 = 'foo4'          pg_ipv6 = 'foo6' diff --git a/smoketest/scripts/cli/test_service_dhcpv6-server.py b/smoketest/scripts/cli/test_service_dhcpv6-server.py index fcbfeb7be..dcce30f55 100755 --- a/smoketest/scripts/cli/test_service_dhcpv6-server.py +++ b/smoketest/scripts/cli/test_service_dhcpv6-server.py @@ -104,24 +104,25 @@ class TestServiceDHCPv6Server(VyOSUnitTestSHIM.TestCase):          self.cli_set(base_path + ['preference', preference])          self.cli_set(pool + ['subnet-id', '1'])          # we use the first subnet IP address as default gateway -        self.cli_set(pool + ['name-server', dns_1]) -        self.cli_set(pool + ['name-server', dns_2]) -        self.cli_set(pool + ['name-server', dns_2])          self.cli_set(pool + ['lease-time', 'default', lease_time])          self.cli_set(pool + ['lease-time', 'maximum', max_lease_time])          self.cli_set(pool + ['lease-time', 'minimum', min_lease_time]) -        self.cli_set(pool + ['nis-domain', domain]) -        self.cli_set(pool + ['nisplus-domain', domain]) -        self.cli_set(pool + ['sip-server', sip_server]) -        self.cli_set(pool + ['sntp-server', sntp_server]) -        self.cli_set(pool + ['address-range', 'start', range_start, 'stop', range_stop]) +        self.cli_set(pool + ['option', 'name-server', dns_1]) +        self.cli_set(pool + ['option', 'name-server', dns_2]) +        self.cli_set(pool + ['option', 'name-server', dns_2]) +        self.cli_set(pool + ['option', 'nis-domain', domain]) +        self.cli_set(pool + ['option', 'nisplus-domain', domain]) +        self.cli_set(pool + ['option', 'sip-server', sip_server]) +        self.cli_set(pool + ['option', 'sntp-server', sntp_server]) +        self.cli_set(pool + ['range', '1', 'start', range_start]) +        self.cli_set(pool + ['range', '1', 'stop', range_stop])          for server in nis_servers: -            self.cli_set(pool + ['nis-server', server]) -            self.cli_set(pool + ['nisplus-server', server]) +            self.cli_set(pool + ['option', 'nis-server', server]) +            self.cli_set(pool + ['option', 'nisplus-server', server])          for search in search_domains: -            self.cli_set(pool + ['domain-search', search]) +            self.cli_set(pool + ['option', 'domain-search', search])          client_base = 1          for client in ['client1', 'client2', 'client3']: @@ -217,7 +218,8 @@ class TestServiceDHCPv6Server(VyOSUnitTestSHIM.TestCase):          pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet]          self.cli_set(pool + ['subnet-id', '1']) -        self.cli_set(pool + ['address-range', 'start', range_start, 'stop', range_stop]) +        self.cli_set(pool + ['range', '1', 'start', range_start]) +        self.cli_set(pool + ['range', '1', 'stop', range_stop])          self.cli_set(pool + ['prefix-delegation', 'prefix', delegate_start, 'delegated-length', delegate_len])          self.cli_set(pool + ['prefix-delegation', 'prefix', delegate_start, 'prefix-length', prefix_len]) diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py index 89e2aab8c..f6f3370c3 100755 --- a/src/conf_mode/protocols_bgp.py +++ b/src/conf_mode/protocols_bgp.py @@ -220,9 +220,12 @@ def verify_afi(peer_config, bgp_config):      # If address_family configured under peer-group      # if neighbor interface configured -    peer_group_name = '' +    peer_group_name = None      if dict_search('interface.peer_group', peer_config):          peer_group_name = peer_config['interface']['peer_group'] +    elif dict_search('interface.v6only.peer_group', peer_config): +        peer_group_name = peer_config['interface']['v6only']['peer_group'] +      # if neighbor IP configured.      if 'peer_group' in peer_config:          peer_group_name = peer_config['peer_group'] @@ -542,6 +545,10 @@ def verify(bgp):                      tmp = dict_search(f'route_map.vpn.{export_import}', afi_config)                      if tmp: verify_route_map(tmp, bgp) +                # per-vrf sid and per-af sid are mutually exclusive +                if 'sid' in afi_config and 'sid' in bgp: +                    raise ConfigError('SID per VRF and SID per address-family are mutually exclusive!') +              # Checks only required for L2VPN EVPN              if afi in ['l2vpn_evpn']:                  if 'vni' in afi_config: diff --git a/src/conf_mode/service_dhcpv6-server.py b/src/conf_mode/service_dhcpv6-server.py index 7cd801cdd..214531904 100755 --- a/src/conf_mode/service_dhcpv6-server.py +++ b/src/conf_mode/service_dhcpv6-server.py @@ -81,26 +81,29 @@ def verify(dhcpv6):              subnet_ids.append(subnet_config['subnet_id']) -            if 'address_range' in subnet_config: -                if 'start' in subnet_config['address_range']: -                    range6_start = [] -                    range6_stop = [] -                    for start, start_config in subnet_config['address_range']['start'].items(): -                        if 'stop' not in start_config: -                            raise ConfigError(f'address-range stop address for start "{start}" is not defined!') -                        stop = start_config['stop'] +            if 'range' in subnet_config: +                range6_start = [] +                range6_stop = [] + +                for num, range_config in subnet_config['range'].items(): +                    if 'start' in range_config: +                        start = range_config['start'] + +                        if 'stop' not in range_config: +                            raise ConfigError(f'Range stop address for start "{start}" is not defined!') +                        stop = range_config['stop']                          # Start address must be inside network                          if not ip_address(start) in ip_network(subnet): -                            raise ConfigError(f'address-range start address "{start}" is not in subnet "{subnet}"!') +                            raise ConfigError(f'Range start address "{start}" is not in subnet "{subnet}"!')                          # Stop address must be inside network                          if not ip_address(stop) in ip_network(subnet): -                             raise ConfigError(f'address-range stop address "{stop}" is not in subnet "{subnet}"!') +                             raise ConfigError(f'Range stop address "{stop}" is not in subnet "{subnet}"!')                          # Stop address must be greater or equal to start address                          if not ip_address(stop) >= ip_address(start): -                            raise ConfigError(f'address-range stop address "{stop}" must be greater then or equal ' \ +                            raise ConfigError(f'Range stop address "{stop}" must be greater then or equal ' \                                                f'to the range start address "{start}"!')                          # DHCPv6 range start address must be unique - two ranges can't @@ -108,6 +111,7 @@ def verify(dhcpv6):                          if start in range6_start:                              raise ConfigError(f'Conflicting DHCPv6 lease range: '\                                                f'Pool start address "{start}" defined multipe times!') +                          range6_start.append(start)                          # DHCPv6 range stop address must be unique - two ranges can't @@ -115,12 +119,14 @@ def verify(dhcpv6):                          if stop in range6_stop:                              raise ConfigError(f'Conflicting DHCPv6 lease range: '\                                                f'Pool stop address "{stop}" defined multipe times!') +                          range6_stop.append(stop) -                if 'prefix' in subnet_config: -                    for prefix in subnet_config['prefix']: -                        if ip_network(prefix) not in ip_network(subnet): -                            raise ConfigError(f'address-range prefix "{prefix}" is not in subnet "{subnet}""') +                    if 'prefix' in range_config: +                        prefix = range_config['prefix'] + +                        if not ip_network(prefix).subnet_of(ip_network(subnet)): +                            raise ConfigError(f'Range prefix "{prefix}" is not in subnet "{subnet}"')              # Prefix delegation sanity checks              if 'prefix_delegation' in subnet_config: @@ -151,13 +157,15 @@ def verify(dhcpv6):                              raise ConfigError(f'Either MAC address or Client identifier (DUID) is required for '                                                f'static mapping "{mapping}" within shared-network "{network}, {subnet}"!') -            if 'vendor_option' in subnet_config: -                if len(dict_search('vendor_option.cisco.tftp_server', subnet_config)) > 2: -                    raise ConfigError(f'No more then two Cisco tftp-servers should be defined for subnet "{subnet}"!') +            if 'option' in subnet_config: +                if 'vendor_option' in subnet_config['option']: +                    if len(dict_search('option.vendor_option.cisco.tftp_server', subnet_config)) > 2: +                        raise ConfigError(f'No more then two Cisco tftp-servers should be defined for subnet "{subnet}"!')              # Subnets must be unique              if subnet in subnets:                  raise ConfigError(f'DHCPv6 subnets must be unique! Subnet {subnet} defined multiple times!') +              subnets.append(subnet)          # DHCPv6 requires at least one configured address range or one static mapping diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/03-vyos-dhclient-hook b/src/etc/dhcp/dhclient-exit-hooks.d/03-vyos-dhclient-hook index 35721d009..d5e6462ba 100644 --- a/src/etc/dhcp/dhclient-exit-hooks.d/03-vyos-dhclient-hook +++ b/src/etc/dhcp/dhclient-exit-hooks.d/03-vyos-dhclient-hook @@ -29,6 +29,7 @@ fi  if [ "$RUN" = "yes" ]; then          BASE_PATH=$(python3 -c "from vyos.defaults import directories; print(directories['isc_dhclient_dir'])") +        mkdir -p ${BASE_PATH}          LOG=${BASE_PATH}/dhclient_"$interface"."$proto"lease          echo `date` > $LOG diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook b/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook index c7a92fe26..e6edc1ac3 100755 --- a/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook +++ b/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook @@ -71,10 +71,6 @@ if __name__ == '__main__':                  conf_lines[i] = line.replace(old_ip, new_ip)                  found = True -        for i, line in enumerate(secrets_lines): -            if line.find(to_match) > 0: -                secrets_lines[i] = line.replace(old_ip, new_ip) -          if found:              write_file(SWANCTL_CONF, conf_lines)              ipsec_down(old_ip) diff --git a/src/migration-scripts/bgp/0-to-1 b/src/migration-scripts/bgp/0-to-1 index 03c45107b..5b8e8a163 100755 --- a/src/migration-scripts/bgp/0-to-1 +++ b/src/migration-scripts/bgp/0-to-1 @@ -14,7 +14,7 @@  # You should have received a copy of the GNU General Public License  # along with this program.  If not, see <http://www.gnu.org/licenses/>. -# T3417: migrate IS-IS tagNode to node as we can only have one IS-IS process +# T3417: migrate BGP tagNode to node as we can only have one BGP process  from sys import argv  from sys import exit diff --git a/src/migration-scripts/bgp/1-to-2 b/src/migration-scripts/bgp/1-to-2 index 96b939b47..a40d86e67 100755 --- a/src/migration-scripts/bgp/1-to-2 +++ b/src/migration-scripts/bgp/1-to-2 @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2021-2022 VyOS maintainers and contributors +# Copyright (C) 2021-2024 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 @@ -15,6 +15,7 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  # T3741: no-ipv4-unicast is now enabled by default +# T5937: Migrate IPv6 BGP Neighbor Peer Groups  from sys import argv  from sys import exit @@ -66,6 +67,15 @@ else:              if not config.exists(afi_ipv4):                  config.set(afi_ipv4) +# Migrate IPv6 AFI peer-group +if config.exists(base + ['neighbor']): +    for neighbor in config.list_nodes(base + ['neighbor']): +        tmp_path = base + ['neighbor', neighbor, 'address-family', 'ipv6-unicast', 'peer-group'] +        if config.exists(tmp_path): +            peer_group = config.return_value(tmp_path) +            config.set(base + ['neighbor', neighbor, 'peer-group'], value=peer_group) +            config.delete(tmp_path) +  try:      with open(file_name, 'w') as f:          f.write(config.to_string()) diff --git a/src/migration-scripts/dhcpv6-server/3-to-4 b/src/migration-scripts/dhcpv6-server/3-to-4 index c065e3d43..4747ebd60 100755 --- a/src/migration-scripts/dhcpv6-server/3-to-4 +++ b/src/migration-scripts/dhcpv6-server/3-to-4 @@ -16,6 +16,8 @@  # T3316:  # - Add subnet IDs to existing subnets +# - Move options to option node +# - Migrate address-range to range tagNode  import sys  import re @@ -37,6 +39,10 @@ if not config.exists(base):      # Nothing to do      sys.exit(0) +option_nodes = ['captive-portal', 'domain-search', 'name-server', +                'nis-domain', 'nis-server', 'nisplus-domain', 'nisplus-server', +                'sip-server', 'sntp-server', 'vendor-option'] +  subnet_id = 1  for network in config.list_nodes(base): @@ -44,6 +50,35 @@ for network in config.list_nodes(base):          for subnet in config.list_nodes(base + [network, 'subnet']):              base_subnet = base + [network, 'subnet', subnet] +            if config.exists(base_subnet + ['address-range']): +                config.set(base_subnet + ['range']) +                config.set_tag(base_subnet + ['range']) + +                range_id = 1 + +                if config.exists(base_subnet + ['address-range', 'prefix']): +                    for prefix in config.return_values(base_subnet + ['address-range', 'prefix']): +                        config.set(base_subnet + ['range', range_id, 'prefix'], value=prefix) + +                        range_id += 1 + +                if config.exists(base_subnet + ['address-range', 'start']): +                    for start in config.list_nodes(base_subnet + ['address-range', 'start']): +                        stop = config.return_value(base_subnet + ['address-range', 'start', start, 'stop']) + +                        config.set(base_subnet + ['range', range_id, 'start'], value=start) +                        config.set(base_subnet + ['range', range_id, 'stop'], value=stop) + +                        range_id += 1 + +                config.delete(base_subnet + ['address-range']) + +            for option in option_nodes: +                if config.exists(base_subnet + [option]): +                    config.set(base_subnet + ['option']) +                    config.copy(base_subnet + [option], base_subnet + ['option', option]) +                    config.delete(base_subnet + [option]) +              config.set(base_subnet + ['subnet-id'], value=subnet_id)              subnet_id += 1 diff --git a/src/migration-scripts/ipsec/12-to-13 b/src/migration-scripts/ipsec/12-to-13 new file mode 100755 index 000000000..504a2e9c7 --- /dev/null +++ b/src/migration-scripts/ipsec/12-to-13 @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 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/>. + +# Changed value of dead-peer-detection.action from hold to trap + +import re + +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 = ['vpn', 'ipsec', 'ike-group'] +config = ConfigTree(config_file) + +if not config.exists(base): +    # Nothing to do +    exit(0) +else: +    for ike_group in config.list_nodes(base): +        base_dpd_action = base + [ike_group, 'dead-peer-detection', 'action'] +        if config.exists(base_dpd_action) and config.return_value(base_dpd_action) == 'hold': +            config.set(base_dpd_action, 'trap', replace=True) + +try: +    with open(file_name, 'w') as f: +        f.write(config.to_string()) +except OSError as e: +    print(f'Failed to save the modified config: {e}') +    exit(1) diff --git a/src/migration-scripts/nat/5-to-6 b/src/migration-scripts/nat/5-to-6 index de3830582..c83b93d84 100755 --- a/src/migration-scripts/nat/5-to-6 +++ b/src/migration-scripts/nat/5-to-6 @@ -51,8 +51,9 @@ for direction in ['source', 'destination']:          for iface in ['inbound-interface','outbound-interface']:              if config.exists(base + [iface]):                  tmp = config.return_value(base + [iface]) -                config.delete(base + [iface]) -                config.set(base + [iface, 'interface-name'], value=tmp) +                if tmp: +                    config.delete(base + [iface]) +                    config.set(base + [iface, 'interface-name'], value=tmp)  try:      with open(file_name, 'w') as f: diff --git a/src/migration-scripts/ospf/0-to-1 b/src/migration-scripts/ospf/0-to-1 index 8f02acada..a6cb9feb8 100755 --- a/src/migration-scripts/ospf/0-to-1 +++ b/src/migration-scripts/ospf/0-to-1 @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2021 VyOS maintainers and contributors +# Copyright (C) 2021-2024 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 @@ -28,6 +28,7 @@ def ospf_passive_migration(config, ospf_base):                      default = True                      continue                  config.set(ospf_base + ['interface', interface, 'passive']) +                config.set_tag(ospf_base + ['interface'])              config.delete(ospf_base + ['passive-interface'])              config.set(ospf_base + ['passive-interface'], value='default') @@ -35,6 +36,7 @@ def ospf_passive_migration(config, ospf_base):          if config.exists(ospf_base + ['passive-interface-exclude']):              for interface in config.return_values(ospf_base + ['passive-interface-exclude']):                  config.set(ospf_base + ['interface', interface, 'passive', 'disable']) +                config.set_tag(ospf_base + ['interface'])              config.delete(ospf_base + ['passive-interface-exclude'])  if len(argv) < 2: diff --git a/src/op_mode/dhcp.py b/src/op_mode/dhcp.py index 02f4d5bbb..a64acec31 100755 --- a/src/op_mode/dhcp.py +++ b/src/op_mode/dhcp.py @@ -194,14 +194,11 @@ def _get_pool_size(pool, family='inet'):      size = 0      subnets = config.list_nodes(f'{base} subnet')      for subnet in subnets: -        if family == 'inet6': -            ranges = config.list_nodes(f'{base} subnet {subnet} address-range start') -        else: -            ranges = config.list_nodes(f'{base} subnet {subnet} range') +        ranges = config.list_nodes(f'{base} subnet {subnet} range')          for range in ranges:              if family == 'inet6': -                start = config.list_nodes(f'{base} subnet {subnet} address-range start')[0] -                stop = config.value(f'{base} subnet {subnet} address-range start {start} stop') +                start = config.value(f'{base} subnet {subnet} range {range} start') +                stop = config.value(f'{base} subnet {subnet} range {range} stop')              else:                  start = config.value(f'{base} subnet {subnet} range {range} start')                  stop = config.value(f'{base} subnet {subnet} range {range} stop') diff --git a/src/op_mode/powerctrl.py b/src/op_mode/powerctrl.py index 3ac5991b4..c07d0c4bd 100755 --- a/src/op_mode/powerctrl.py +++ b/src/op_mode/powerctrl.py @@ -191,7 +191,7 @@ def main():                          nargs="*",                          metavar="HH:MM") -    action.add_argument("--reboot_in", "-i", +    action.add_argument("--reboot-in", "-i",                          help="Reboot the system",                          nargs="*",                          metavar="Minutes") @@ -214,7 +214,7 @@ def main():          if args.reboot is not None:              for r in args.reboot:                  if ':' not in r and '/' not in r and '.' not in r: -                    print("Incorrect  format! Use HH:MM") +                    print("Incorrect format! Use HH:MM")                      exit(1)              execute_shutdown(args.reboot, reboot=True, ask=args.yes)          if args.reboot_in is not None: | 
