├── debian ├── docs ├── source │ └── format ├── triggers ├── libpve-network-api-perl.install ├── libpve-network-perl.install ├── rules ├── copyright ├── libpve-network-perl.postinst └── control ├── src ├── test │ ├── zones │ │ ├── evpn │ │ │ ├── isis_standalone │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ ├── interfaces │ │ │ │ ├── expected_controller_config │ │ │ │ └── sdn_config │ │ │ ├── ospf_fabric │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── expected_controller_config │ │ │ ├── openfabric_fabric │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── expected_controller_config │ │ │ ├── isis │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_controller_config │ │ │ ├── ebgp │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_controller_config │ │ │ ├── exitnode │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── expected_controller_config │ │ │ ├── ipv4 │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── expected_controller_config │ │ │ ├── ipv4ipv6 │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_controller_config │ │ │ ├── ipv6 │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── expected_controller_config │ │ │ ├── exitnode_snat │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ ├── expected_controller_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── multiplezones │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ ├── expected_controller_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── rt_import │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── expected_controller_config │ │ │ ├── vxlanport │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── expected_controller_config │ │ │ ├── advertise_subnets │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── expected_controller_config │ │ │ ├── exitnode_primary │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── expected_controller_config │ │ │ ├── exitnodenullroute │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_controller_config │ │ │ ├── ipv4ipv6nogateway │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_controller_config │ │ │ ├── multipath_relax │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_controller_config │ │ │ ├── exitnode_local_routing │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── expected_controller_config │ │ │ ├── disable_arp_nd_suppression │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── expected_controller_config │ │ │ ├── ipv6underlay │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── expected_controller_config │ │ │ ├── ebgp_loopback │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_controller_config │ │ │ └── isis_loopback │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_controller_config │ │ ├── qinq │ │ │ ├── bridge │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── bridge_notagvnet │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── bridge_vlanawarevnet │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── bridge_vlanprotocol │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── bridge_vlanaware │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── bridge_vlanaware_notagvnet │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── bridge_vlanaware_vlanprotocol │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── bridge_vlanaware_vlanawarevnet │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── ovs │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── ovs_notagvnet │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── ovs_vlanawarevnet │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ │ └── ovs_vlanprotocol │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ ├── simple │ │ │ ├── basic │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── sdn_config │ │ │ ├── ipv4 │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── sdn_config │ │ │ ├── ipv4v6 │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── sdn_config │ │ │ ├── ipv4v6nogateway │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── sdn_config │ │ │ ├── hetzner │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── sdn_config │ │ │ ├── ipv4snat │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── sdn_config │ │ │ └── ipv6snat │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── sdn_config │ │ ├── vlan │ │ │ ├── bridge │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ │ ├── bridge_vlanaware │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ ├── interfaces │ │ │ │ └── sdn_config │ │ │ ├── bridge_vlanaware_vlanawarevnet │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── sdn_config │ │ │ ├── ovs │ │ │ │ ├── interfaces │ │ │ │ ├── expected_sdn_interfaces │ │ │ │ └── sdn_config │ │ │ └── ovs_vlanware_vnet │ │ │ │ ├── interfaces │ │ │ │ ├── sdn_config │ │ │ │ └── expected_sdn_interfaces │ │ └── vxlan │ │ │ ├── basic │ │ │ ├── interfaces │ │ │ ├── expected_sdn_interfaces │ │ │ └── sdn_config │ │ │ ├── vxlanport │ │ │ ├── interfaces │ │ │ ├── expected_sdn_interfaces │ │ │ └── sdn_config │ │ │ └── vlanawarevnet │ │ │ ├── interfaces │ │ │ ├── expected_sdn_interfaces │ │ │ └── sdn_config │ ├── vnets │ │ ├── ipv4 │ │ │ ├── ipam_config │ │ │ ├── ipam.db │ │ │ └── sdn_config │ │ ├── ipv6 │ │ │ ├── ipam_config │ │ │ ├── ipam.db │ │ │ └── sdn_config │ │ └── ipv4noipam │ │ │ ├── ipam_config │ │ │ ├── ipam.db │ │ │ └── sdn_config │ ├── debug │ │ ├── statuscheck.pl │ │ └── generateconfig.pl │ ├── dns │ │ └── powerdns │ │ │ ├── dns_config │ │ │ ├── sdn_config │ │ │ ├── expected.verify_zone │ │ │ ├── expected.del_a_record.ipv6 │ │ │ ├── expected.del_ptr_record.ipv4 │ │ │ ├── expected.del_a_record.ipv4 │ │ │ ├── expected.del_ptr_record.ipv6 │ │ │ ├── expected.add_a_record.ipv4 │ │ │ ├── expected.add_ptr_record.ipv4 │ │ │ ├── expected.del_a_multiple_record.ipv4 │ │ │ ├── expected.add_a_record.ipv6 │ │ │ ├── expected.del_a_multiple_record.ipv6 │ │ │ ├── expected.add_a_multiple_record.ipv4 │ │ │ ├── expected.add_ptr_record.ipv6 │ │ │ └── expected.add_a_multiple_record.ipv6 │ ├── Makefile │ ├── ipams │ │ ├── netbox │ │ │ ├── expected.del_ip │ │ │ ├── expected.add_subnet │ │ │ ├── sdn_config │ │ │ ├── expected.del_subnet │ │ │ ├── expected.add_ip │ │ │ ├── expected.update_ip │ │ │ ├── expected.add_next_freeip │ │ │ ├── expected.add_ip_notgateway │ │ │ └── ipam_config │ │ └── phpipam │ │ │ ├── sdn_config │ │ │ ├── expected.del_ip │ │ │ ├── expected.add_subnet │ │ │ ├── ipam_config │ │ │ ├── expected.del_subnet │ │ │ ├── expected.update_ip │ │ │ ├── expected.add_next_freeip │ │ │ ├── expected.add_ip_notgateway │ │ │ └── expected.add_ip │ └── subnets │ │ ├── noipam │ │ ├── sdn_config │ │ └── ipam_config │ │ ├── ipv4 │ │ ├── sdn_config │ │ └── ipam_config │ │ └── ipv6 │ │ ├── sdn_config │ │ └── ipam_config ├── PVE │ ├── API2 │ │ ├── Makefile │ │ └── Network │ │ │ ├── Makefile │ │ │ └── SDN │ │ │ ├── Fabrics │ │ │ └── Makefile │ │ │ ├── Nodes │ │ │ ├── Makefile │ │ │ ├── Vnets.pm │ │ │ ├── Fabrics.pm │ │ │ ├── Status.pm │ │ │ └── Zones.pm │ │ │ └── Makefile │ ├── Makefile │ └── Network │ │ ├── Makefile │ │ └── SDN │ │ ├── Dhcp │ │ ├── Makefile │ │ └── Plugin.pm │ │ ├── Dns │ │ ├── Makefile │ │ └── Plugin.pm │ │ ├── Ipams │ │ └── Makefile │ │ ├── Controllers │ │ ├── Makefile │ │ ├── FaucetPlugin.pm │ │ └── Plugin.pm │ │ ├── Zones │ │ ├── Makefile │ │ └── FaucetPlugin.pm │ │ ├── Makefile │ │ └── Dns.pm ├── services │ ├── Makefile │ └── 00-dnsmasq-after-networking.conf └── Makefile ├── .gitignore └── Makefile /debian/docs: -------------------------------------------------------------------------------- 1 | debian/SOURCE 2 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /debian/triggers: -------------------------------------------------------------------------------- 1 | activate-noawait pve-api-updates 2 | -------------------------------------------------------------------------------- /debian/libpve-network-api-perl.install: -------------------------------------------------------------------------------- 1 | usr/share/perl5/PVE/API2 2 | -------------------------------------------------------------------------------- /src/test/zones/evpn/isis_standalone/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | -------------------------------------------------------------------------------- /src/PVE/API2/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY: install 3 | install: 4 | make -C Network install 5 | -------------------------------------------------------------------------------- /src/PVE/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | 3 | .PHONY: install 4 | install: 5 | make -C Network install 6 | make -C API2 install 7 | 8 | clean: 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.deb 2 | /*.build 3 | /*.buildinfo 4 | /*.changes 5 | /*.dsc 6 | /.vscode/ 7 | /libpve-network-perl-[0-9]*/ 8 | /libpve-network-perl_[0-9]*.tar.xz 9 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | -------------------------------------------------------------------------------- /src/test/zones/simple/basic/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv4/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv4v6/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | -------------------------------------------------------------------------------- /src/test/zones/vlan/bridge/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | -------------------------------------------------------------------------------- /src/test/zones/simple/basic/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | bridge_ports none 6 | bridge_stp off 7 | bridge_fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_notagvnet/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv4v6nogateway/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanawarevnet/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanprotocol/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv4v6nogateway/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | bridge_ports none 6 | bridge_stp off 7 | bridge_fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/vlan/bridge_vlanaware/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | bridge_ports vmbr0.100 6 | bridge_stp off 7 | bridge_fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ospf_fabric/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 172.20.30.1/32 4 | bridge-ports eth0 5 | bridge-stp off 6 | bridge-fd 0 7 | -------------------------------------------------------------------------------- /debian/libpve-network-perl.install: -------------------------------------------------------------------------------- 1 | lib/systemd/system/dnsmasq@.service.d/00-dnsmasq-after-networking.conf /usr/lib/systemd/system/dnsmasq@.service.d/ 2 | usr/share/perl5/PVE/Network 3 | -------------------------------------------------------------------------------- /src/test/zones/evpn/openfabric_fabric/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 172.20.3.1/32 4 | bridge-ports eth0 5 | bridge-stp off 6 | bridge-fd 0 7 | -------------------------------------------------------------------------------- /src/test/zones/simple/hetzner/interfaces: -------------------------------------------------------------------------------- 1 | auto eth0 2 | iface eth0 inet static 3 | address 144.76.0.1 4 | netmask 255.255.255.255 5 | pointopoint 172.31.1.1 6 | gateway 172.31.1.1 -------------------------------------------------------------------------------- /src/test/zones/evpn/isis/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 -------------------------------------------------------------------------------- /src/test/zones/evpn/ebgp/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv4/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv4ipv6/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv6/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/vxlan/basic/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/vnets/ipv4/ipam_config: -------------------------------------------------------------------------------- 1 | { 2 | 'ids' => { 3 | 'pve' => { 4 | 'type' => 'pve' 5 | }, 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /src/test/vnets/ipv6/ipam_config: -------------------------------------------------------------------------------- 1 | { 2 | 'ids' => { 3 | 'pve' => { 4 | 'type' => 'pve' 5 | }, 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode_snat/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/multiplezones/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/rt_import/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/vxlanport/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanaware/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | bridge-vids 2-4094 7 | bridge-vlan-aware 1 8 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv4/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 192.168.0.1/24 6 | bridge_ports none 7 | bridge_stp off 8 | bridge_fd 0 9 | ip-forward on 10 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv4snat/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv6snat/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/vlan/bridge_vlanaware/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | bridge-vids 2-4094 7 | bridge-vlan-aware 1 8 | -------------------------------------------------------------------------------- /src/test/zones/vxlan/vxlanport/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/vnets/ipv4noipam/ipam_config: -------------------------------------------------------------------------------- 1 | { 2 | 'ids' => { 3 | 'pve' => { 4 | 'type' => 'pve' 5 | }, 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/advertise_subnets/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode_primary/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnodenullroute/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv4ipv6nogateway/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/multipath_relax/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/vxlan/vlanawarevnet/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode_local_routing/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanaware_notagvnet/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | bridge-vids 2-4094 7 | bridge-vlan-aware 1 8 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanaware_vlanprotocol/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | bridge-vids 2-4094 7 | bridge-vlan-aware 1 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/disable_arp_nd_suppression/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv6underlay/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 2a08:2200:100:1::10/64 4 | gateway 2a08:2200:100:1::1 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanaware_vlanawarevnet/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | bridge-vids 2-4094 7 | bridge-vlan-aware 1 8 | -------------------------------------------------------------------------------- /src/test/zones/vlan/bridge_vlanaware_vlanawarevnet/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet manual 3 | bridge-ports eth0 4 | bridge-stp off 5 | bridge-fd 0 6 | bridge-vlan-aware yes 7 | bridge-vids 2-4096 8 | -------------------------------------------------------------------------------- /src/PVE/Network/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=SDN.pm 2 | 3 | 4 | PERL5DIR=${DESTDIR}/usr/share/perl5 5 | 6 | .PHONY: install 7 | install: 8 | for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/Network/$$i; done 9 | make -C SDN install 10 | -------------------------------------------------------------------------------- /src/PVE/Network/SDN/Dhcp/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=Plugin.pm Dnsmasq.pm 2 | 3 | 4 | PERL5DIR=${DESTDIR}/usr/share/perl5 5 | 6 | .PHONY: install 7 | install: 8 | for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/Network/SDN/Dhcp/$$i; done 9 | -------------------------------------------------------------------------------- /src/test/zones/qinq/ovs/interfaces: -------------------------------------------------------------------------------- 1 | auto eth0 2 | iface eth0 inet manual 3 | ovs_type OVSPort 4 | ovs_bridge vmbr0 5 | 6 | auto vmbr0 7 | iface vmbr0 inet manual 8 | ovs_type OVSBridge 9 | ovs_ports eth0 10 | -------------------------------------------------------------------------------- /src/test/zones/vlan/bridge_vlanaware_vlanawarevnet/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | bridge_ports vmbr0.100 6 | bridge_stp off 7 | bridge_fd 0 8 | bridge-vlan-aware yes 9 | bridge-vids 2-4094 10 | -------------------------------------------------------------------------------- /src/test/zones/vlan/ovs/interfaces: -------------------------------------------------------------------------------- 1 | auto eth0 2 | iface eth0 inet manual 3 | ovs_type OVSPort 4 | ovs_bridge vmbr0 5 | 6 | auto vmbr0 7 | iface vmbr0 inet manual 8 | ovs_type OVSBridge 9 | ovs_ports eth0 10 | -------------------------------------------------------------------------------- /src/PVE/Network/SDN/Dns/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=Plugin.pm PowerdnsPlugin.pm 2 | 3 | 4 | PERL5DIR=${DESTDIR}/usr/share/perl5 5 | 6 | .PHONY: install 7 | install: 8 | for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/Network/SDN/Dns/$$i; done 9 | -------------------------------------------------------------------------------- /src/PVE/API2/Network/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=SDN.pm 2 | 3 | 4 | PERL5DIR=${DESTDIR}/usr/share/perl5 5 | 6 | .PHONY: install 7 | install: 8 | for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/API2/Network/$$i; done 9 | make -C SDN install 10 | -------------------------------------------------------------------------------- /src/test/zones/qinq/ovs_notagvnet/interfaces: -------------------------------------------------------------------------------- 1 | auto eth0 2 | iface eth0 inet manual 3 | ovs_type OVSPort 4 | ovs_bridge vmbr0 5 | 6 | auto vmbr0 7 | iface vmbr0 inet manual 8 | ovs_type OVSBridge 9 | ovs_ports eth0 10 | -------------------------------------------------------------------------------- /src/test/zones/qinq/ovs_vlanawarevnet/interfaces: -------------------------------------------------------------------------------- 1 | auto eth0 2 | iface eth0 inet manual 3 | ovs_type OVSPort 4 | ovs_bridge vmbr0 5 | 6 | auto vmbr0 7 | iface vmbr0 inet manual 8 | ovs_type OVSBridge 9 | ovs_ports eth0 10 | -------------------------------------------------------------------------------- /src/test/zones/qinq/ovs_vlanprotocol/interfaces: -------------------------------------------------------------------------------- 1 | auto eth0 2 | iface eth0 inet manual 3 | ovs_type OVSPort 4 | ovs_bridge vmbr0 5 | 6 | auto vmbr0 7 | iface vmbr0 inet manual 8 | ovs_type OVSBridge 9 | ovs_ports eth0 10 | -------------------------------------------------------------------------------- /src/test/zones/vlan/ovs_vlanware_vnet/interfaces: -------------------------------------------------------------------------------- 1 | auto eth0 2 | iface eth0 inet manual 3 | ovs_type OVSPort 4 | ovs_bridge vmbr0 5 | 6 | auto vmbr0 7 | iface vmbr0 inet manual 8 | ovs_type OVSBridge 9 | ovs_ports eth0 10 | -------------------------------------------------------------------------------- /src/PVE/API2/Network/SDN/Fabrics/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=Fabric.pm FabricNode.pm Node.pm 2 | 3 | 4 | PERL5DIR=${DESTDIR}/usr/share/perl5 5 | 6 | .PHONY: install 7 | install: 8 | for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/API2/Network/SDN/Fabrics/$$i; done 9 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv4v6/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 192.168.0.1/24 6 | address 2a08:2142:302:3::1/64 7 | bridge_ports none 8 | bridge_stp off 9 | bridge_fd 0 10 | ip-forward on 11 | ip6-forward on 12 | -------------------------------------------------------------------------------- /src/PVE/Network/SDN/Ipams/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=Plugin.pm PhpIpamPlugin.pm NetboxPlugin.pm PVEPlugin.pm 2 | 3 | 4 | PERL5DIR=${DESTDIR}/usr/share/perl5 5 | 6 | .PHONY: install 7 | install: 8 | for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/Network/SDN/Ipams/$$i; done 9 | -------------------------------------------------------------------------------- /src/test/vnets/ipv4/ipam.db: -------------------------------------------------------------------------------- 1 | { 2 | "zones" => { 3 | "myzone" => { 4 | "subnets" => { 5 | "192.168.0.0/30" => { 6 | "ips" =>{ 7 | } 8 | }, 9 | "192.168.1.0/30" => { 10 | "ips" =>{ 11 | } 12 | }, 13 | } 14 | } 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/test/vnets/ipv4noipam/ipam.db: -------------------------------------------------------------------------------- 1 | { 2 | "zones" => { 3 | "myzone" => { 4 | "subnets" => { 5 | "192.168.0.0/30" => { 6 | "ips" =>{ 7 | } 8 | }, 9 | "192.168.1.0/30" => { 10 | "ips" =>{ 11 | } 12 | }, 13 | } 14 | } 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/PVE/Network/SDN/Controllers/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=Plugin.pm FaucetPlugin.pm EvpnPlugin.pm BgpPlugin.pm IsisPlugin.pm 2 | 3 | 4 | PERL5DIR=${DESTDIR}/usr/share/perl5 5 | 6 | .PHONY: install 7 | install: 8 | for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/Network/SDN/Controllers/$$i; done 9 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ebgp_loopback/interfaces: -------------------------------------------------------------------------------- 1 | auto eth0 2 | iface eth0 inet static 3 | address 172.16.0.1/24 4 | 5 | auto eth1 6 | iface eth1 inet static 7 | address 172.17.0.1/24 8 | 9 | auto dummy1 10 | iface dummy1 inet static 11 | address 192.168.0.1/32 12 | link-type dummy 13 | 14 | -------------------------------------------------------------------------------- /src/test/vnets/ipv6/ipam.db: -------------------------------------------------------------------------------- 1 | { 2 | "zones" => { 3 | "myzone" => { 4 | "subnets" => { 5 | "2001:db8:85a3::8a2e:370:7334/127" => { 6 | "ips" =>{ 7 | } 8 | }, 9 | "2001:db8:85a3::8a2e:371:7334/127" => { 10 | "ips" =>{ 11 | } 12 | }, 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/debug/statuscheck.pl: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use PVE::Network::SDN; 4 | use Data::Dumper; 5 | 6 | my ($transport_status, $vnet_status, $fabric_status) = PVE::Network::SDN::status(); 7 | 8 | print Dumper($fabric_status); 9 | print Dumper($vnet_status); 10 | print Dumper($transport_status); 11 | -------------------------------------------------------------------------------- /src/PVE/Network/SDN/Zones/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=Plugin.pm VlanPlugin.pm VxlanPlugin.pm FaucetPlugin.pm EvpnPlugin.pm QinQPlugin.pm SimplePlugin.pm 2 | 3 | 4 | PERL5DIR=${DESTDIR}/usr/share/perl5 5 | 6 | .PHONY: install 7 | install: 8 | for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/Network/SDN/Zones/$$i; done 9 | -------------------------------------------------------------------------------- /src/test/zones/evpn/isis_loopback/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | 9 | auto dummy1 10 | iface dummy1 inet static 11 | address 10.0.0.1/32 12 | link-type dummy -------------------------------------------------------------------------------- /src/test/zones/evpn/isis_standalone/interfaces: -------------------------------------------------------------------------------- 1 | auto vmbr0 2 | iface vmbr0 inet static 3 | address 192.168.0.1/24 4 | gateway 192.168.0.254 5 | bridge-ports eth0 6 | bridge-stp off 7 | bridge-fd 0 8 | 9 | auto dummy1 10 | iface dummy1 inet static 11 | address 10.0.0.1/32 12 | link-type dummy -------------------------------------------------------------------------------- /src/test/zones/vxlan/basic/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | bridge_ports vxlan_myvnet 6 | bridge_stp off 7 | bridge_fd 0 8 | mtu 1450 9 | 10 | auto vxlan_myvnet 11 | iface vxlan_myvnet 12 | vxlan-id 100 13 | vxlan_remoteip 192.168.0.2 14 | vxlan_remoteip 192.168.0.3 15 | mtu 1450 16 | -------------------------------------------------------------------------------- /src/PVE/API2/Network/SDN/Nodes/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=\ 2 | Fabric.pm\ 3 | Fabrics.pm\ 4 | Status.pm\ 5 | Vnet.pm\ 6 | Vnets.pm\ 7 | Zone.pm\ 8 | Zones.pm 9 | 10 | PERL5DIR=${DESTDIR}/usr/share/perl5 11 | 12 | .PHONY: install 13 | install: 14 | for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/API2/Network/SDN/Nodes/$$i; done 15 | -------------------------------------------------------------------------------- /src/services/Makefile: -------------------------------------------------------------------------------- 1 | SERVICEDIR=$(DESTDIR)/lib/systemd/system 2 | 3 | all: 4 | @true 5 | 6 | .PHONY: install 7 | install: 8 | install -d $(SERVICEDIR) 9 | install -d $(SERVICEDIR)/dnsmasq@.service.d 10 | install -t $(SERVICEDIR)/dnsmasq@.service.d -m 0644 00-dnsmasq-after-networking.conf 11 | 12 | .PHONY: clean 13 | clean: 14 | @true 15 | -------------------------------------------------------------------------------- /src/test/zones/vlan/ovs/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myvnet 4 | iface ln_myvnet 5 | ovs_type OVSIntPort 6 | ovs_bridge vmbr0 7 | ovs_options tag=100 8 | 9 | auto myvnet 10 | iface myvnet 11 | bridge_ports ln_myvnet 12 | bridge_stp off 13 | bridge_fd 0 14 | 15 | auto vmbr0 16 | iface vmbr0 17 | ovs_ports ln_myvnet 18 | -------------------------------------------------------------------------------- /src/test/zones/simple/basic/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { ipam => "pve", type => "simple" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/vxlan/vxlanport/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | bridge_ports vxlan_myvnet 6 | bridge_stp off 7 | bridge_fd 0 8 | mtu 1450 9 | 10 | auto vxlan_myvnet 11 | iface vxlan_myvnet 12 | vxlan-id 100 13 | vxlan_remoteip 192.168.0.2 14 | vxlan_remoteip 192.168.0.3 15 | vxlan-port 6000 16 | mtu 1450 17 | -------------------------------------------------------------------------------- /src/PVE/API2/Network/SDN/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=Vnets.pm Zones.pm Controllers.pm Subnets.pm Ipams.pm Dns.pm Ips.pm Fabrics.pm 2 | 3 | 4 | PERL5DIR=${DESTDIR}/usr/share/perl5 5 | 6 | .PHONY: install 7 | install: 8 | for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/API2/Network/SDN/$$i; done 9 | make -C Fabrics install 10 | make -C Nodes install 11 | 12 | -------------------------------------------------------------------------------- /src/test/zones/vlan/ovs/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", ipam => "pve", type => "vlan" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS := PVE services 2 | 3 | all: 4 | set -e && for i in $(SUBDIRS); do $(MAKE) -C $$i; done 5 | 6 | .PHONY: clean 7 | clean: 8 | $(MAKE) -C test $@ 9 | set -e && for i in $(SUBDIRS); do $(MAKE) -C $$i $@; done 10 | 11 | .PHONY: test 12 | test: 13 | $(MAKE) -C $@ 14 | 15 | .PHONY: install 16 | install: 17 | set -e && for i in $(SUBDIRS); do $(MAKE) -C $$i $@; done 18 | -------------------------------------------------------------------------------- /src/test/zones/vlan/bridge_vlanaware/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", ipam => "pve", type => "vlan" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/vxlan/vlanawarevnet/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | bridge_ports vxlan_myvnet 6 | bridge_stp off 7 | bridge_fd 0 8 | bridge-vlan-aware yes 9 | bridge-vids 2-4094 10 | mtu 1450 11 | 12 | auto vxlan_myvnet 13 | iface vxlan_myvnet 14 | vxlan-id 100 15 | vxlan_remoteip 192.168.0.2 16 | vxlan_remoteip 192.168.0.3 17 | mtu 1450 18 | -------------------------------------------------------------------------------- /src/PVE/API2/Network/SDN/Nodes/Vnets.pm: -------------------------------------------------------------------------------- 1 | package PVE::API2::Network::SDN::Nodes::Vnets; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use PVE::API2::Network::SDN::Nodes::Vnet; 7 | 8 | use PVE::RESTHandler; 9 | use base qw(PVE::RESTHandler); 10 | 11 | __PACKAGE__->register_method({ 12 | subclass => "PVE::API2::Network::SDN::Nodes::Vnet", 13 | path => '{vnet}', 14 | }); 15 | 16 | 1; 17 | -------------------------------------------------------------------------------- /src/test/zones/vlan/bridge/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", ipam => "pve", type => "vlan", mtu => "9200" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/PVE/API2/Network/SDN/Nodes/Fabrics.pm: -------------------------------------------------------------------------------- 1 | package PVE::API2::Network::SDN::Nodes::Fabrics; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use PVE::API2::Network::SDN::Nodes::Fabric; 7 | 8 | use PVE::RESTHandler; 9 | use base qw(PVE::RESTHandler); 10 | 11 | __PACKAGE__->register_method({ 12 | subclass => "PVE::API2::Network::SDN::Nodes::Fabric", 13 | path => '{fabric}', 14 | }); 15 | 16 | 1; 17 | -------------------------------------------------------------------------------- /src/test/zones/qinq/ovs_notagvnet/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", vlanaware => "1", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", tag => 10, ipam => "pve", type => "qinq" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/vlan/ovs_vlanware_vnet/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", vlanaware => "1", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", ipam => "pve", type => "vlan" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/vxlan/basic/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { ipam => "pve", type => "vxlan", peers => "192.168.0.1,192.168.0.2,192.168.0.3" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanaware_notagvnet/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", vlanaware => "1", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", tag => 10, ipam => "pve", type => "qinq" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/qinq/ovs_vlanawarevnet/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", vlanaware => "1", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", tag => 10, ipam => "pve", type => "qinq" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanawarevnet/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", vlanaware => "1", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", tag => 10, ipam => "pve", type => "qinq" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/vlan/bridge_vlanaware_vlanawarevnet/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", vlanaware => 1, zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", ipam => "pve", type => "vlan" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanaware_vlanawarevnet/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", vlanaware => "1", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", tag => 10, ipam => "pve", type => "qinq" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanprotocol/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", tag => 10, 'vlan-protocol' => '802.1ad', ipam => "pve", type => "qinq" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/qinq/ovs_vlanprotocol/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", tag => 10, 'vlan-protocol' => '802.1ad', ipam => "pve", type => "qinq" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/vxlan/vlanawarevnet/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", vlanaware => "1", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { ipam => "pve", type => "vxlan", peers => "192.168.0.1,192.168.0.2,192.168.0.3" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/vxlan/vxlanport/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { ipam => "pve", type => "vxlan", 'vxlan-port' => 6000, peers => "192.168.0.1,192.168.0.2,192.168.0.3" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/dns_config: -------------------------------------------------------------------------------- 1 | { 2 | 'ids' => { 3 | 'powerdns' => { 4 | 'url' => 'http://localhost:8881/api/v1/servers/localhost', 5 | 'type' => 'powerdns', 6 | 'key' => '1234', 7 | 'ttl' => '3600' 8 | }, 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanaware_vlanprotocol/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { bridge => "vmbr0", tag => 10, 'vlan-protocol' => '802.1ad', ipam => "pve", type => "qinq" } }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /src/test/zones/simple/hetzner/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 144.76.100.65/29 6 | bridge_ports none 7 | bridge_stp off 8 | bridge_fd 0 9 | ip-forward on 10 | 11 | auto myvnet2 12 | iface myvnet2 13 | address 144.76.0.1/32 14 | up ip route add 144.76.200.65/32 dev myvnet2 15 | up ip route add 144.76.200.66/32 dev myvnet2 16 | bridge_ports none 17 | bridge_stp off 18 | bridge_fd 0 19 | ip-forward on 20 | -------------------------------------------------------------------------------- /src/test/zones/vlan/ovs_vlanware_vnet/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myvnet 4 | iface ln_myvnet 5 | ovs_type OVSIntPort 6 | ovs_bridge vmbr0 7 | ovs_options vlan_mode=dot1q-tunnel other_config:qinq-ethtype=802.1q tag=100 8 | 9 | auto myvnet 10 | iface myvnet 11 | bridge_ports ln_myvnet 12 | bridge_stp off 13 | bridge_fd 0 14 | bridge-vlan-aware yes 15 | bridge-vids 2-4094 16 | 17 | auto vmbr0 18 | iface vmbr0 19 | ovs_ports ln_myvnet 20 | -------------------------------------------------------------------------------- /src/PVE/Network/SDN/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES=Vnets.pm VnetPlugin.pm Zones.pm Controllers.pm Subnets.pm SubnetPlugin.pm Ipams.pm Dns.pm Dhcp.pm Fabrics.pm Frr.pm 2 | 3 | 4 | PERL5DIR=${DESTDIR}/usr/share/perl5 5 | 6 | .PHONY: install 7 | install: 8 | for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/Network/SDN/$$i; done 9 | make -C Controllers install 10 | make -C Zones install 11 | make -C Ipams install 12 | make -C Dns install 13 | make -C Dhcp install 14 | 15 | -------------------------------------------------------------------------------- /src/test/Makefile: -------------------------------------------------------------------------------- 1 | all: test 2 | 3 | test: test_zones test_ipams test_dns test_subnets test_vnets_blackbox 4 | 5 | test_zones: run_test_zones.pl 6 | ./run_test_zones.pl 7 | 8 | test_ipams: run_test_ipams.pl 9 | ./run_test_ipams.pl 10 | 11 | test_dns: run_test_dns.pl 12 | ./run_test_dns.pl 13 | 14 | test_subnets: run_test_subnets.pl 15 | ./run_test_subnets.pl 16 | 17 | test_vnets_blackbox: run_test_vnets_blackbox.pl 18 | ./run_test_vnets_blackbox.pl 19 | 20 | clean: 21 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | %: 13 | dh $@ 14 | -------------------------------------------------------------------------------- /src/test/zones/evpn/isis_standalone/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | interface eth0 9 | ip router isis isis1 10 | ! 11 | interface eth1 12 | ip router isis isis1 13 | ! 14 | router isis isis1 15 | net 47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00 16 | redistribute ipv4 connected level-1 17 | redistribute ipv6 connected level-1 18 | log-adjacency-changes 19 | exit 20 | ! 21 | line vty 22 | ! -------------------------------------------------------------------------------- /src/test/zones/vlan/bridge/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myvnet 4 | iface ln_myvnet 5 | link-type veth 6 | veth-peer-name pr_myvnet 7 | mtu 9200 8 | 9 | auto myvnet 10 | iface myvnet 11 | bridge_ports ln_myvnet 12 | bridge_stp off 13 | bridge_fd 0 14 | mtu 9200 15 | 16 | auto pr_myvnet 17 | iface pr_myvnet 18 | link-type veth 19 | veth-peer-name ln_myvnet 20 | mtu 9200 21 | 22 | auto vmbr0v100 23 | iface vmbr0v100 24 | bridge_ports eth0.100 pr_myvnet 25 | bridge_stp off 26 | bridge_fd 0 27 | mtu 9200 28 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv4snat/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | post-up iptables -t nat -A POSTROUTING -s '10.0.0.0/24' -o vmbr0 -j SNAT --to-source 192.168.0.1 7 | post-down iptables -t nat -D POSTROUTING -s '10.0.0.0/24' -o vmbr0 -j SNAT --to-source 192.168.0.1 8 | post-up iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1 9 | post-down iptables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1 10 | bridge_ports none 11 | bridge_stp off 12 | bridge_fd 0 13 | ip-forward on 14 | -------------------------------------------------------------------------------- /src/services/00-dnsmasq-after-networking.conf: -------------------------------------------------------------------------------- 1 | # dnsmasq@.service comes with 2 | # Requires=network.target 3 | # After=network.target 4 | # Only the After entry makes sense as `network.target` is a passive rule and 5 | # `Require`ing it means that dnsmasq is the "provider" of that unit. 6 | # See https://systemd.io/NETWORK_ONLINE 7 | # 8 | # Additionally, we want ifupdown to have completed its setup, to make sure 9 | # the 'interface=' directives can find the required interfaces at startup. 10 | [Unit] 11 | Requires= 12 | After=networking.service 13 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv6snat/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 2a08:2142:302:3::1/64 6 | post-up ip6tables -t nat -A POSTROUTING -s '2a08:2142:302:3::/64' -o vmbr0 -j SNAT --to-source 192.168.0.1 7 | post-down ip6tables -t nat -D POSTROUTING -s '2a08:2142:302:3::/64' -o vmbr0 -j SNAT --to-source 192.168.0.1 8 | post-up ip6tables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1 9 | post-down ip6tables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1 10 | bridge_ports none 11 | bridge_stp off 12 | bridge_fd 0 13 | ip6-forward on 14 | -------------------------------------------------------------------------------- /src/test/zones/evpn/isis_standalone/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | }, 5 | zones => { 6 | }, 7 | controllers => { 8 | ids => { 9 | localhost => { 10 | type => "isis", 11 | 'isis-domain' => 'isis1', 12 | 'isis-ifaces' => 'eth1,eth0', 13 | 'isis-net' => "47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00", 14 | loopback => 'dummy1', 15 | node => "localhost", 16 | }, 17 | }, 18 | }, 19 | subnets => { 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv4/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { ipam => "pve", type => "simple" } }, 10 | }, 11 | 12 | subnets => { 13 | ids => { 'myzone-192.168.0.0-24' => { 14 | 'type' => 'subnet', 15 | 'vnet' => 'myvnet', 16 | 'gateway' => '192.168.0.1', 17 | } 18 | } 19 | } 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanaware_notagvnet/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myzone 4 | iface ln_myzone 5 | link-type veth 6 | veth-peer-name pr_myzone 7 | 8 | auto myvnet 9 | iface myvnet 10 | bridge_ports pr_myzone 11 | bridge_stp off 12 | bridge_fd 0 13 | bridge-vlan-aware yes 14 | bridge-vids 2-4094 15 | 16 | auto pr_myzone 17 | iface pr_myzone 18 | link-type veth 19 | veth-peer-name ln_myzone 20 | 21 | auto z_myzone 22 | iface z_myzone 23 | bridge-stp off 24 | bridge-ports vmbr0.10 ln_myzone 25 | bridge-fd 0 26 | bridge-vlan-aware yes 27 | bridge-vids 2-4094 28 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanaware_vlanawarevnet/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myzone 4 | iface ln_myzone 5 | link-type veth 6 | veth-peer-name pr_myzone 7 | 8 | auto myvnet 9 | iface myvnet 10 | bridge_ports z_myzone.100 11 | bridge_stp off 12 | bridge_fd 0 13 | bridge-vlan-aware yes 14 | bridge-vids 2-4094 15 | 16 | auto pr_myzone 17 | iface pr_myzone 18 | link-type veth 19 | veth-peer-name ln_myzone 20 | 21 | auto z_myzone 22 | iface z_myzone 23 | bridge-stp off 24 | bridge-ports vmbr0.10 ln_myzone 25 | bridge-fd 0 26 | bridge-vlan-aware yes 27 | bridge-vids 2-4094 28 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv4snat/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { ipam => "pve", type => "simple" } }, 10 | }, 11 | 12 | subnets => { 13 | ids => { 'myzone-10.0.0.0-24' => { 14 | 'type' => 'subnet', 15 | 'vnet' => 'myvnet', 16 | 'gateway' => '10.0.0.1', 17 | 'snat' => 1 18 | } 19 | } 20 | } 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/test/ipams/netbox/expected.del_ip: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '', 3 | '_headers' => bless( { 4 | 'authorization' => 'token 0123456789abcdef0123456789abcdef01234567', 5 | 'content-type' => 'application/json; charset=UTF-8' 6 | }, 'HTTP::Headers' ), 7 | '_max_body_size' => undef, 8 | '_method' => 'DELETE', 9 | '_uri' => bless( do{\(my $o = 'http://localhost:8000/api/ipam/ip-addresses/1/')}, 'URI::http' ) 10 | }, 'HTTP::Request' ); 11 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanprotocol/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myzone 4 | iface ln_myzone 5 | link-type veth 6 | veth-peer-name pr_myzone 7 | 8 | auto myvnet 9 | iface myvnet 10 | bridge_ports z_myzone.100 11 | bridge_stp off 12 | bridge_fd 0 13 | 14 | auto pr_myzone 15 | iface pr_myzone 16 | link-type veth 17 | veth-peer-name ln_myzone 18 | 19 | auto sv_myzone 20 | iface sv_myzone 21 | vlan-raw-device eth0 22 | vlan-id 10 23 | vlan-protocol 802.1ad 24 | 25 | auto z_myzone 26 | iface z_myzone 27 | bridge-stp off 28 | bridge-ports sv_myzone ln_myzone 29 | bridge-fd 0 30 | bridge-vlan-aware yes 31 | bridge-vids 2-4094 32 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv4v6nogateway/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { ipam => "pve", type => "simple" } }, 10 | }, 11 | subnets => { 12 | ids => { 13 | 'myzone-192.168.0.0-24' => { 14 | 'type' => 'subnet', 15 | 'vnet' => 'myvnet', 16 | }, 17 | 'myzone-2a08:2142:302:3::-64' => { 18 | 'type' => 'subnet', 19 | 'vnet' => 'myvnet', 20 | } 21 | } 22 | } 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/test/ipams/netbox/expected.add_subnet: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"prefix":"10.0.0.0/24"}', 3 | '_headers' => bless( { 4 | 'authorization' => 'token 0123456789abcdef0123456789abcdef01234567', 5 | 'content-type' => 'application/json; charset=UTF-8' 6 | }, 'HTTP::Headers' ), 7 | '_max_body_size' => undef, 8 | '_method' => 'POST', 9 | '_uri' => bless( do{\(my $o = 'http://localhost:8000/api/ipam/prefixes/')}, 'URI::http' ) 10 | }, 'HTTP::Request' ); 11 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", zone => "myzone" }, 6 | myvnet2 => { tag => 101, type => "vnet", zone => "myzone" }, 7 | myvnet3 => { tag => 100, type => "vnet", zone => "myzone2" }, 8 | }, 9 | }, 10 | zones => { 11 | ids => { 12 | myzone => { bridge => "vmbr0", tag => 10, ipam => "pve", type => "qinq" }, 13 | myzone2 => { bridge => "vmbr0", tag => 20, ipam => "pve", type => "qinq" }, 14 | }, 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /src/test/zones/qinq/ovs/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", zone => "myzone" }, 6 | myvnet2 => { tag => 101, type => "vnet", zone => "myzone" }, 7 | myvnet3 => { tag => 100, type => "vnet", zone => "myzone2" }, 8 | }, 9 | }, 10 | zones => { 11 | ids => { 12 | myzone => { bridge => "vmbr0", tag => 10, ipam => "pve", type => "qinq" }, 13 | myzone2 => { bridge => "vmbr0", tag => 20, ipam => "pve", type => "qinq" }, 14 | }, 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /src/test/ipams/netbox/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "netbox" } }, 11 | }, 12 | 13 | subnets => { 14 | ids => { 'myzone-10.0.0.0-24' => { 15 | 'type' => 'subnet', 16 | 'vnet' => 'myvnet', 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/subnets/noipam/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { type =>"simple" } }, 11 | }, 12 | 13 | subnets => { 14 | ids => { 'myzone-10.0.0.0-24' => { 15 | 'type' => 'subnet', 16 | 'vnet' => 'myvnet', 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_notagvnet/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { 6 | tag => 100, 7 | type => "vnet", 8 | zone => "myzone" 9 | }, 10 | myvnet2 => { 11 | type => "vnet", 12 | zone => "myzone" 13 | }, 14 | }, 15 | }, 16 | zones => { 17 | ids => { 18 | myzone => { 19 | bridge => "vmbr0", 20 | tag => 10, 21 | ipam => "pve", 22 | type => "qinq", 23 | }, 24 | }, 25 | }, 26 | } 27 | -------------------------------------------------------------------------------- /src/test/ipams/phpipam/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "phpipam" } }, 11 | }, 12 | 13 | subnets => { 14 | ids => { 'myzone-10.0.0.0-24' => { 15 | 'type' => 'subnet', 16 | 'vnet' => 'myvnet', 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanaware/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => 100, type => "vnet", zone => "myzone" }, 6 | myvnet2 => { tag => 101, type => "vnet", zone => "myzone" }, 7 | myvnet3 => { tag => 100, type => "vnet", zone => "myzone2" }, 8 | }, 9 | }, 10 | zones => { 11 | ids => { 12 | myzone => { bridge => "vmbr0", tag => 10, ipam => "pve", type => "qinq" }, 13 | myzone2 => { bridge => "vmbr0", tag => 20, ipam => "pve", type => "qinq" }, 14 | }, 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanawarevnet/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myzone 4 | iface ln_myzone 5 | link-type veth 6 | veth-peer-name pr_myzone 7 | 8 | auto myvnet 9 | iface myvnet 10 | bridge_ports z_myzone.100 11 | bridge_stp off 12 | bridge_fd 0 13 | bridge-vlan-aware yes 14 | bridge-vids 2-4094 15 | 16 | auto pr_myzone 17 | iface pr_myzone 18 | link-type veth 19 | veth-peer-name ln_myzone 20 | 21 | auto sv_myzone 22 | iface sv_myzone 23 | vlan-raw-device eth0 24 | vlan-id 10 25 | 26 | auto z_myzone 27 | iface z_myzone 28 | bridge-stp off 29 | bridge-ports sv_myzone ln_myzone 30 | bridge-fd 0 31 | bridge-vlan-aware yes 32 | bridge-vids 2-4094 33 | -------------------------------------------------------------------------------- /src/test/subnets/ipv4/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type =>"simple" } }, 11 | }, 12 | 13 | subnets => { 14 | ids => { 'myzone-10.0.0.0-24' => { 15 | 'type' => 'subnet', 16 | 'vnet' => 'myvnet', 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanaware_vlanprotocol/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myzone 4 | iface ln_myzone 5 | link-type veth 6 | veth-peer-name pr_myzone 7 | 8 | auto myvnet 9 | iface myvnet 10 | bridge_ports z_myzone.100 11 | bridge_stp off 12 | bridge_fd 0 13 | 14 | auto pr_myzone 15 | iface pr_myzone 16 | link-type veth 17 | veth-peer-name ln_myzone 18 | 19 | auto vmbr0 20 | iface vmbr0 21 | bridge-vlan-protocol 802.1ad 22 | 23 | auto vmbr0.10 24 | iface vmbr0.10 25 | vlan-protocol 802.1ad 26 | 27 | auto z_myzone 28 | iface z_myzone 29 | bridge-stp off 30 | bridge-ports vmbr0.10 ln_myzone 31 | bridge-fd 0 32 | bridge-vlan-aware yes 33 | bridge-vids 2-4094 34 | -------------------------------------------------------------------------------- /src/test/subnets/ipv6/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type =>"simple" } }, 11 | }, 12 | 13 | subnets => { 14 | ids => { 'myzone-2a0a:1580:2000::-56' => { 15 | 'type' => 'subnet', 16 | 'vnet' => 'myvnet', 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/ipams/netbox/expected.del_subnet: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"address":"192.168.0.1/24","description":null,"dns_name":"toto"}', 3 | '_headers' => bless( { 4 | 'authorization' => 'token 0123456789abcdef0123456789abcdef01234567', 5 | 'content-type' => 'application/json; charset=UTF-8' 6 | }, 'HTTP::Headers' ), 7 | '_max_body_size' => undef, 8 | '_method' => 'POST', 9 | '_uri' => bless( do{\(my $o = 'http://localhost:8000/api/ipam/ip-addresses/')}, 'URI::http' ) 10 | }, 'HTTP::Request' ); 11 | -------------------------------------------------------------------------------- /src/test/ipams/netbox/expected.add_ip: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"address":"10.0.0.1/24","description":"gateway","dns_name":"myhostname"}', 3 | '_headers' => bless( { 4 | 'authorization' => 'token 0123456789abcdef0123456789abcdef01234567', 5 | 'content-type' => 'application/json; charset=UTF-8' 6 | }, 'HTTP::Headers' ), 7 | '_max_body_size' => undef, 8 | '_method' => 'POST', 9 | '_uri' => bless( do{\(my $o = 'http://localhost:8000/api/ipam/ip-addresses/')}, 'URI::http' ) 10 | }, 'HTTP::Request' ); 11 | -------------------------------------------------------------------------------- /src/test/ipams/netbox/expected.update_ip: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"address":"10.0.0.1/24","description":"gateway","dns_name":"myhostname"}', 3 | '_headers' => bless( { 4 | 'authorization' => 'token 0123456789abcdef0123456789abcdef01234567', 5 | 'content-type' => 'application/json; charset=UTF-8' 6 | }, 'HTTP::Headers' ), 7 | '_max_body_size' => undef, 8 | '_method' => 'PATCH', 9 | '_uri' => bless( do{\(my $o = 'http://localhost:8000/api/ipam/ip-addresses/1/')}, 'URI::http' ) 10 | }, 'HTTP::Request' ); 11 | -------------------------------------------------------------------------------- /src/test/ipams/netbox/expected.add_next_freeip: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"description":"mac:da:65:8f:18:9b:6f","dns_name":"myhostname"}', 3 | '_headers' => bless( { 4 | 'authorization' => 'token 0123456789abcdef0123456789abcdef01234567', 5 | 'content-type' => 'application/json; charset=UTF-8' 6 | }, 'HTTP::Headers' ), 7 | '_max_body_size' => undef, 8 | '_method' => 'POST', 9 | '_uri' => bless( do{\(my $o = 'http://localhost:8000/api/ipam/prefixes/1/available-ips/')}, 'URI::http' ) 10 | }, 'HTTP::Request' ); 11 | -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_notagvnet/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myzone 4 | iface ln_myzone 5 | link-type veth 6 | veth-peer-name pr_myzone 7 | 8 | auto myvnet 9 | iface myvnet 10 | bridge_ports z_myzone.100 11 | bridge_stp off 12 | bridge_fd 0 13 | 14 | auto myvnet2 15 | iface myvnet2 16 | bridge_ports pr_myzone 17 | bridge_stp off 18 | bridge_fd 0 19 | 20 | auto pr_myzone 21 | iface pr_myzone 22 | link-type veth 23 | veth-peer-name ln_myzone 24 | 25 | auto sv_myzone 26 | iface sv_myzone 27 | vlan-raw-device eth0 28 | vlan-id 10 29 | 30 | auto z_myzone 31 | iface z_myzone 32 | bridge-stp off 33 | bridge-ports sv_myzone ln_myzone 34 | bridge-fd 0 35 | bridge-vlan-aware yes 36 | bridge-vids 2-4094 37 | -------------------------------------------------------------------------------- /src/test/ipams/netbox/expected.add_ip_notgateway: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"address":"10.0.0.1/24","description":"mac:da:65:8f:18:9b:6f","dns_name":"myhostname"}', 3 | '_headers' => bless( { 4 | 'authorization' => 'token 0123456789abcdef0123456789abcdef01234567', 5 | 'content-type' => 'application/json; charset=UTF-8' 6 | }, 'HTTP::Headers' ), 7 | '_max_body_size' => undef, 8 | '_method' => 'POST', 9 | '_uri' => bless( do{\(my $o = 'http://localhost:8000/api/ipam/ip-addresses/')}, 'URI::http' ) 10 | }, 'HTTP::Request' ); 11 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv4v6/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { ipam => "pve", type => "simple" } }, 10 | }, 11 | subnets => { 12 | ids => { 13 | 'myzone-192.168.0.0-24' => { 14 | 'type' => 'subnet', 15 | 'vnet' => 'myvnet', 16 | 'gateway' => '192.168.0.1', 17 | }, 18 | 'myzone-2a08:2142:302:3::-64' => { 19 | 'type' => 'subnet', 20 | 'vnet' => 'myvnet', 21 | 'gateway' => '2a08:2142:302:3::1', 22 | } 23 | } 24 | } 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type =>"simple", dns => "powerdns", reversedns => "powerdns", dnszone => "domain.com" } }, 11 | }, 12 | 13 | subnets => { 14 | ids => { 'myzone-10.0.0.0-24' => { 15 | 'type' => 'subnet', 16 | 'vnet' => 'myvnet', 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/zones/qinq/ovs_vlanprotocol/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myzone 4 | iface ln_myzone 5 | link-type veth 6 | veth-peer-name pr_myzone 7 | 8 | auto myvnet 9 | iface myvnet 10 | bridge_ports z_myzone.100 11 | bridge_stp off 12 | bridge_fd 0 13 | 14 | auto pr_myzone 15 | iface pr_myzone 16 | link-type veth 17 | veth-peer-name ln_myzone 18 | 19 | auto sv_myzone 20 | iface sv_myzone 21 | ovs_type OVSIntPort 22 | ovs_bridge vmbr0 23 | ovs_options vlan_mode=dot1q-tunnel tag=10 other_config:qinq-ethtype=802.1ad 24 | 25 | auto vmbr0 26 | iface vmbr0 27 | ovs_ports sv_myzone 28 | 29 | auto z_myzone 30 | iface z_myzone 31 | bridge-stp off 32 | bridge-ports sv_myzone ln_myzone 33 | bridge-fd 0 34 | bridge-vlan-aware yes 35 | bridge-vids 2-4094 36 | -------------------------------------------------------------------------------- /src/test/debug/generateconfig.pl: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use File::Copy; 4 | use PVE::Cluster qw(cfs_read_file); 5 | 6 | use PVE::Network::SDN; 7 | use PVE::Network::SDN::Zones; 8 | use PVE::Network::SDN::Controllers; 9 | use Data::Dumper; 10 | 11 | PVE::Network::SDN::commit_config(); 12 | my $network_config = PVE::Network::SDN::Zones::generate_etc_network_config(); 13 | 14 | PVE::Network::SDN::Zones::write_etc_network_config($network_config); 15 | print "/etc/network/interfaces.d/sdn\n"; 16 | print $network_config; 17 | print "\n"; 18 | 19 | my $controller_config = PVE::Network::SDN::Controllers::generate_controller_config(); 20 | 21 | if ($controller_config) { 22 | print Dumper($controller_config); 23 | PVE::Network::SDN::Controllers::write_controller_config($controller_config); 24 | } 25 | -------------------------------------------------------------------------------- /src/test/zones/qinq/ovs_notagvnet/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myzone 4 | iface ln_myzone 5 | link-type veth 6 | veth-peer-name pr_myzone 7 | 8 | auto myvnet 9 | iface myvnet 10 | bridge_ports pr_myzone 11 | bridge_stp off 12 | bridge_fd 0 13 | bridge-vlan-aware yes 14 | bridge-vids 2-4094 15 | 16 | auto pr_myzone 17 | iface pr_myzone 18 | link-type veth 19 | veth-peer-name ln_myzone 20 | 21 | auto sv_myzone 22 | iface sv_myzone 23 | ovs_type OVSIntPort 24 | ovs_bridge vmbr0 25 | ovs_options vlan_mode=dot1q-tunnel tag=10 other_config:qinq-ethtype=802.1q 26 | 27 | auto vmbr0 28 | iface vmbr0 29 | ovs_ports sv_myzone 30 | 31 | auto z_myzone 32 | iface z_myzone 33 | bridge-stp off 34 | bridge-ports sv_myzone ln_myzone 35 | bridge-fd 0 36 | bridge-vlan-aware yes 37 | bridge-vids 2-4094 38 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Copyright (C) 2019 Proxmox Server Solutions GmbH 2 | 3 | This software is written by Proxmox Server Solutions GmbH 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Affero General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Affero General Public License for more details. 14 | 15 | You should have received a copy of the GNU Affero General Public License 16 | along with this program. If not, see . 17 | -------------------------------------------------------------------------------- /src/test/zones/qinq/ovs_vlanawarevnet/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myzone 4 | iface ln_myzone 5 | link-type veth 6 | veth-peer-name pr_myzone 7 | 8 | auto myvnet 9 | iface myvnet 10 | bridge_ports z_myzone.100 11 | bridge_stp off 12 | bridge_fd 0 13 | bridge-vlan-aware yes 14 | bridge-vids 2-4094 15 | 16 | auto pr_myzone 17 | iface pr_myzone 18 | link-type veth 19 | veth-peer-name ln_myzone 20 | 21 | auto sv_myzone 22 | iface sv_myzone 23 | ovs_type OVSIntPort 24 | ovs_bridge vmbr0 25 | ovs_options vlan_mode=dot1q-tunnel tag=10 other_config:qinq-ethtype=802.1q 26 | 27 | auto vmbr0 28 | iface vmbr0 29 | ovs_ports sv_myzone 30 | 31 | auto z_myzone 32 | iface z_myzone 33 | bridge-stp off 34 | bridge-ports sv_myzone ln_myzone 35 | bridge-fd 0 36 | bridge-vlan-aware yes 37 | bridge-vids 2-4094 38 | -------------------------------------------------------------------------------- /src/test/ipams/phpipam/expected.del_ip: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'token' => 'Token' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'DELETE', 12 | '_uri' => bless( do{\(my $o = 'https://localhost/api/apiadmin/addresses/1')}, 'URI::https' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv4/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, 'mac' => 'A2:1D:CB:1A:C0:8B' } }, 11 | }, 12 | controllers => { 13 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 14 | }, 15 | 16 | subnets => { 17 | ids => { 'myzone-10.0.0.0-24' => { 18 | 'type' => 'subnet', 19 | 'vnet' => 'myvnet', 20 | 'gateway' => '10.0.0.1', 21 | } 22 | } 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.verify_zone: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'GET', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com?rrsets=false')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, exitnodes => { 'localhost' => 1 } } }, 11 | }, 12 | controllers => { 13 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 14 | }, 15 | 16 | subnets => { 17 | ids => { 'myzone-10.0.0.0-24' => { 18 | 'type' => 'subnet', 19 | 'vnet' => 'myvnet', 20 | 'gateway' => '10.0.0.1', 21 | } 22 | } 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test/zones/simple/ipv6snat/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | zones => { 9 | ids => { myzone => { ipam => "pve", type => "simple" } }, 10 | }, 11 | 12 | subnets => { 13 | ids => { 14 | 'myzone-2a08:2142:302:3::-64' => { 15 | 'type' => 'subnet', 16 | 'vnet' => 'myvnet', 17 | 'gateway' => '2a08:2142:302:3::1', 18 | 'snat' => 1 19 | } 20 | } 21 | } 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/test/zones/evpn/vxlanport/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vxlan-port' => 6000, 'vrf-vxlan' => 1000, 'mac' => 'A2:1D:CB:1A:C0:8B' } }, 11 | }, 12 | controllers => { 13 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 14 | }, 15 | 16 | subnets => { 17 | ids => { 'myzone-10.0.0.0-24' => { 18 | 'type' => 'subnet', 19 | 'vnet' => 'myvnet', 20 | 'gateway' => '10.0.0.1', 21 | } 22 | } 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv6/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, 'mac' => 'A2:1D:CB:1A:C0:8B' } }, 11 | }, 12 | controllers => { 13 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 14 | }, 15 | 16 | subnets => { 17 | ids => { 18 | 'myzone-2a08:2142:302:3::-64' => { 19 | 'type' => 'subnet', 20 | 'vnet' => 'myvnet', 21 | 'gateway' => '2a08:2142:302:3::1', 22 | } 23 | } 24 | } 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/test/ipams/phpipam/expected.add_subnet: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"mask":"24","sectionId":1,"subnet":"10.0.0.0"}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'token' => 'Token' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'POST', 12 | '_uri' => bless( do{\(my $o = 'https://localhost/api/apiadmin/subnets/')}, 'URI::https' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /src/test/zones/evpn/advertise_subnets/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, 'mac' => 'A2:1D:CB:1A:C0:8B', 'advertise-subnets' => 1 } }, 11 | }, 12 | controllers => { 13 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 14 | }, 15 | 16 | subnets => { 17 | ids => { 'myzone-10.0.0.0-24' => { 18 | 'type' => 'subnet', 19 | 'vnet' => 'myvnet', 20 | 'gateway' => '10.0.0.1', 21 | } 22 | } 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test/ipams/netbox/ipam_config: -------------------------------------------------------------------------------- 1 | { 2 | 'ids' => { 3 | 'phpipam' => { 4 | 'url' => 'https://localhost/api/apiadmin', 5 | 'type' => 'phpipam', 6 | 'section' => 1, 7 | 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' 8 | }, 9 | 'pve' => { 10 | 'type' => 'pve' 11 | }, 12 | 'netbox' => { 13 | 'token' => '0123456789abcdef0123456789abcdef01234567', 14 | 'type' => 'netbox', 15 | 'url' => 'http://localhost:8000/api' 16 | } 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /src/test/ipams/phpipam/ipam_config: -------------------------------------------------------------------------------- 1 | { 2 | 'ids' => { 3 | 'phpipam' => { 4 | 'url' => 'https://localhost/api/apiadmin', 5 | 'type' => 'phpipam', 6 | 'section' => 1, 7 | 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' 8 | }, 9 | 'pve' => { 10 | 'type' => 'pve' 11 | }, 12 | 'netbox' => { 13 | 'token' => '0123456789abcdef0123456789abcdef01234567', 14 | 'type' => 'netbox', 15 | 'url' => 'http://localhost:8000/api' 16 | } 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /src/test/subnets/ipv4/ipam_config: -------------------------------------------------------------------------------- 1 | { 2 | 'ids' => { 3 | 'phpipam' => { 4 | 'url' => 'https://localhost/api/apiadmin', 5 | 'type' => 'phpipam', 6 | 'section' => 1, 7 | 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' 8 | }, 9 | 'pve' => { 10 | 'type' => 'pve' 11 | }, 12 | 'netbox' => { 13 | 'token' => '0123456789abcdef0123456789abcdef01234567', 14 | 'type' => 'netbox', 15 | 'url' => 'http://localhost:8000/api' 16 | } 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /src/test/subnets/ipv6/ipam_config: -------------------------------------------------------------------------------- 1 | { 2 | 'ids' => { 3 | 'phpipam' => { 4 | 'url' => 'https://localhost/api/apiadmin', 5 | 'type' => 'phpipam', 6 | 'section' => 1, 7 | 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' 8 | }, 9 | 'pve' => { 10 | 'type' => 'pve' 11 | }, 12 | 'netbox' => { 13 | 'token' => '0123456789abcdef0123456789abcdef01234567', 14 | 'type' => 'netbox', 15 | 'url' => 'http://localhost:8000/api' 16 | } 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /src/test/subnets/noipam/ipam_config: -------------------------------------------------------------------------------- 1 | { 2 | 'ids' => { 3 | 'phpipam' => { 4 | 'url' => 'https://localhost/api/apiadmin', 5 | 'type' => 'phpipam', 6 | 'section' => 1, 7 | 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' 8 | }, 9 | 'pve' => { 10 | 'type' => 'pve' 11 | }, 12 | 'netbox' => { 13 | 'token' => '0123456789abcdef0123456789abcdef01234567', 14 | 'type' => 'netbox', 15 | 'url' => 'http://localhost:8000/api' 16 | } 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode_primary/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, 'exitnodes-primary' => "othernode", exitnodes => { 'localhost' => 1 } } }, 11 | }, 12 | controllers => { 13 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 14 | }, 15 | 16 | subnets => { 17 | ids => { 'myzone-10.0.0.0-24' => { 18 | 'type' => 'subnet', 19 | 'vnet' => 'myvnet', 20 | 'gateway' => '10.0.0.1', 21 | } 22 | } 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test/zones/evpn/disable_arp_nd_suppression/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, 'mac' => 'A2:1D:CB:1A:C0:8B', 'disable-arp-nd-suppression' => 1 } }, 11 | }, 12 | controllers => { 13 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 14 | }, 15 | 16 | subnets => { 17 | ids => { 'myzone-10.0.0.0-24' => { 18 | 'type' => 'subnet', 19 | 'vnet' => 'myvnet', 20 | 'gateway' => '10.0.0.1', 21 | } 22 | } 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test/zones/evpn/rt_import/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, 'mac' => 'A2:1D:CB:1A:C0:8B', 'rt-import' => '65001:1000,65002:1000,65003:1000' } }, 11 | }, 12 | controllers => { 13 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 14 | }, 15 | 16 | subnets => { 17 | ids => { 'myzone-10.0.0.0-24' => { 18 | 'type' => 'subnet', 19 | 'vnet' => 'myvnet', 20 | 'gateway' => '10.0.0.1', 21 | } 22 | } 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv6underlay/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, 'mac' => 'A2:1D:CB:1A:C0:8B' } }, 11 | }, 12 | controllers => { 13 | ids => { evpnctl => { type => "evpn", 'peers' => '2a08:2200:100:1::10,2a08:2200:100:1::11,2a08:2200:100:1::12', asn => "65000" } }, 14 | }, 15 | 16 | subnets => { 17 | ids => { 18 | 'myzone-2a08:2142:302:3::-64' => { 19 | 'type' => 'subnet', 20 | 'vnet' => 'myvnet', 21 | 'gateway' => '2a08:2142:302:3::1', 22 | } 23 | } 24 | } 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode_local_routing/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, exitnodes => { 'localhost' => 1 }, 'exitnodes-local-routing' => 1 }, 11 | }, 12 | }, 13 | controllers => { 14 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 15 | }, 16 | 17 | subnets => { 18 | ids => { 'myzone-10.0.0.0-24' => { 19 | 'type' => 'subnet', 20 | 'vnet' => 'myvnet', 21 | 'gateway' => '10.0.0.1', 22 | }, 23 | } 24 | } 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/test/ipams/phpipam/expected.del_subnet: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"description":null,"hostname":"toto","ip":"192.168.0.1","is_gateway":null,"subnetId":1}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'token' => 'Token' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'POST', 12 | '_uri' => bless( do{\(my $o = 'https://localhost/api/apiadmin/addresses/')}, 'URI::https' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /src/test/zones/evpn/disable_arp_nd_suppression/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | hwaddress A2:1D:CB:1A:C0:8B 7 | bridge_ports vxlan_myvnet 8 | bridge_stp off 9 | bridge_fd 0 10 | mtu 1450 11 | ip-forward on 12 | arp-accept on 13 | vrf vrf_myzone 14 | 15 | auto vrf_myzone 16 | iface vrf_myzone 17 | vrf-table auto 18 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 19 | 20 | auto vrfbr_myzone 21 | iface vrfbr_myzone 22 | bridge-ports vrfvx_myzone 23 | bridge_stp off 24 | bridge_fd 0 25 | mtu 1450 26 | vrf vrf_myzone 27 | 28 | auto vrfvx_myzone 29 | iface vrfvx_myzone 30 | vxlan-id 1000 31 | vxlan-local-tunnelip 192.168.0.1 32 | bridge-learning off 33 | mtu 1450 34 | 35 | auto vxlan_myvnet 36 | iface vxlan_myvnet 37 | vxlan-id 100 38 | vxlan-local-tunnelip 192.168.0.1 39 | bridge-learning off 40 | mtu 1450 41 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ebgp/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | bridge_ports vxlan_myvnet 7 | bridge_stp off 8 | bridge_fd 0 9 | mtu 1450 10 | ip-forward on 11 | arp-accept on 12 | vrf vrf_myzone 13 | 14 | auto vrf_myzone 15 | iface vrf_myzone 16 | vrf-table auto 17 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 18 | 19 | auto vrfbr_myzone 20 | iface vrfbr_myzone 21 | bridge-ports vrfvx_myzone 22 | bridge_stp off 23 | bridge_fd 0 24 | mtu 1450 25 | vrf vrf_myzone 26 | 27 | auto vrfvx_myzone 28 | iface vrfvx_myzone 29 | vxlan-id 1000 30 | vxlan-local-tunnelip 192.168.0.1 31 | bridge-learning off 32 | bridge-arp-nd-suppress on 33 | mtu 1450 34 | 35 | auto vxlan_myvnet 36 | iface vxlan_myvnet 37 | vxlan-id 100 38 | vxlan-local-tunnelip 192.168.0.1 39 | bridge-learning off 40 | bridge-arp-nd-suppress on 41 | mtu 1450 42 | -------------------------------------------------------------------------------- /src/test/zones/evpn/isis/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | bridge_ports vxlan_myvnet 7 | bridge_stp off 8 | bridge_fd 0 9 | mtu 1450 10 | ip-forward on 11 | arp-accept on 12 | vrf vrf_myzone 13 | 14 | auto vrf_myzone 15 | iface vrf_myzone 16 | vrf-table auto 17 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 18 | 19 | auto vrfbr_myzone 20 | iface vrfbr_myzone 21 | bridge-ports vrfvx_myzone 22 | bridge_stp off 23 | bridge_fd 0 24 | mtu 1450 25 | vrf vrf_myzone 26 | 27 | auto vrfvx_myzone 28 | iface vrfvx_myzone 29 | vxlan-id 1000 30 | vxlan-local-tunnelip 192.168.0.1 31 | bridge-learning off 32 | bridge-arp-nd-suppress on 33 | mtu 1450 34 | 35 | auto vxlan_myvnet 36 | iface vxlan_myvnet 37 | vxlan-id 100 38 | vxlan-local-tunnelip 192.168.0.1 39 | bridge-learning off 40 | bridge-arp-nd-suppress on 41 | mtu 1450 42 | -------------------------------------------------------------------------------- /src/test/ipams/phpipam/expected.update_ip: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"description":"mydescription","hostname":"myhostname","is_gateway":1,"mac":"da:65:8f:18:9b:6f"}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'token' => 'Token' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'https://localhost/api/apiadmin/addresses/1')}, 'URI::https' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | bridge_ports vxlan_myvnet 7 | bridge_stp off 8 | bridge_fd 0 9 | mtu 1450 10 | ip-forward on 11 | arp-accept on 12 | vrf vrf_myzone 13 | 14 | auto vrf_myzone 15 | iface vrf_myzone 16 | vrf-table auto 17 | post-up ip route del vrf vrf_myzone unreachable default metric 4278198272 18 | 19 | auto vrfbr_myzone 20 | iface vrfbr_myzone 21 | bridge-ports vrfvx_myzone 22 | bridge_stp off 23 | bridge_fd 0 24 | mtu 1450 25 | vrf vrf_myzone 26 | 27 | auto vrfvx_myzone 28 | iface vrfvx_myzone 29 | vxlan-id 1000 30 | vxlan-local-tunnelip 192.168.0.1 31 | bridge-learning off 32 | bridge-arp-nd-suppress on 33 | mtu 1450 34 | 35 | auto vxlan_myvnet 36 | iface vxlan_myvnet 37 | vxlan-id 100 38 | vxlan-local-tunnelip 192.168.0.1 39 | bridge-learning off 40 | bridge-arp-nd-suppress on 41 | mtu 1450 42 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv4ipv6nogateway/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | hwaddress A2:1D:CB:1A:C0:8B 6 | bridge_ports vxlan_myvnet 7 | bridge_stp off 8 | bridge_fd 0 9 | mtu 1450 10 | arp-accept on 11 | vrf vrf_myzone 12 | 13 | auto vrf_myzone 14 | iface vrf_myzone 15 | vrf-table auto 16 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 17 | 18 | auto vrfbr_myzone 19 | iface vrfbr_myzone 20 | bridge-ports vrfvx_myzone 21 | bridge_stp off 22 | bridge_fd 0 23 | mtu 1450 24 | vrf vrf_myzone 25 | 26 | auto vrfvx_myzone 27 | iface vrfvx_myzone 28 | vxlan-id 1000 29 | vxlan-local-tunnelip 192.168.0.1 30 | bridge-learning off 31 | bridge-arp-nd-suppress on 32 | mtu 1450 33 | 34 | auto vxlan_myvnet 35 | iface vxlan_myvnet 36 | vxlan-id 100 37 | vxlan-local-tunnelip 192.168.0.1 38 | bridge-learning off 39 | bridge-arp-nd-suppress on 40 | mtu 1450 41 | -------------------------------------------------------------------------------- /src/test/zones/evpn/isis_loopback/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | bridge_ports vxlan_myvnet 7 | bridge_stp off 8 | bridge_fd 0 9 | mtu 1450 10 | ip-forward on 11 | arp-accept on 12 | vrf vrf_myzone 13 | 14 | auto vrf_myzone 15 | iface vrf_myzone 16 | vrf-table auto 17 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 18 | 19 | auto vrfbr_myzone 20 | iface vrfbr_myzone 21 | bridge-ports vrfvx_myzone 22 | bridge_stp off 23 | bridge_fd 0 24 | mtu 1450 25 | vrf vrf_myzone 26 | 27 | auto vrfvx_myzone 28 | iface vrfvx_myzone 29 | vxlan-id 1000 30 | vxlan-local-tunnelip 10.0.0.1 31 | bridge-learning off 32 | bridge-arp-nd-suppress on 33 | mtu 1450 34 | 35 | auto vxlan_myvnet 36 | iface vxlan_myvnet 37 | vxlan-id 100 38 | vxlan-local-tunnelip 10.0.0.1 39 | bridge-learning off 40 | bridge-arp-nd-suppress on 41 | mtu 1450 42 | -------------------------------------------------------------------------------- /src/test/ipams/phpipam/expected.add_next_freeip: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"description":"mydescription","hostname":"myhostname","mac":"da:65:8f:18:9b:6f"}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'token' => 'Token' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'POST', 12 | '_uri' => bless( do{\(my $o = 'https://localhost/api/apiadmin/addresses/first_free/1/')}, 'URI::https' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ebgp_loopback/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | bridge_ports vxlan_myvnet 7 | bridge_stp off 8 | bridge_fd 0 9 | mtu 1450 10 | ip-forward on 11 | arp-accept on 12 | vrf vrf_myzone 13 | 14 | auto vrf_myzone 15 | iface vrf_myzone 16 | vrf-table auto 17 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 18 | 19 | auto vrfbr_myzone 20 | iface vrfbr_myzone 21 | bridge-ports vrfvx_myzone 22 | bridge_stp off 23 | bridge_fd 0 24 | mtu 1450 25 | vrf vrf_myzone 26 | 27 | auto vrfvx_myzone 28 | iface vrfvx_myzone 29 | vxlan-id 1000 30 | vxlan-local-tunnelip 192.168.0.1 31 | bridge-learning off 32 | bridge-arp-nd-suppress on 33 | mtu 1450 34 | 35 | auto vxlan_myvnet 36 | iface vxlan_myvnet 37 | vxlan-id 100 38 | vxlan-local-tunnelip 192.168.0.1 39 | bridge-learning off 40 | bridge-arp-nd-suppress on 41 | mtu 1450 42 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.del_a_record.ipv6: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"rrsets":[{"changetype":"DELETE","name":"myhostname.domain.com.","records":[],"type":"AAAA"}]}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.del_ptr_record.ipv4: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"rrsets":[{"changetype":"DELETE","name":"1.0.0.10.in-addr.arpa.","records":[],"type":"PTR"}]}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode_primary/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | bridge_ports vxlan_myvnet 7 | bridge_stp off 8 | bridge_fd 0 9 | mtu 1450 10 | ip-forward on 11 | arp-accept on 12 | vrf vrf_myzone 13 | 14 | auto vrf_myzone 15 | iface vrf_myzone 16 | vrf-table auto 17 | post-up ip route del vrf vrf_myzone unreachable default metric 4278198272 18 | 19 | auto vrfbr_myzone 20 | iface vrfbr_myzone 21 | bridge-ports vrfvx_myzone 22 | bridge_stp off 23 | bridge_fd 0 24 | mtu 1450 25 | vrf vrf_myzone 26 | 27 | auto vrfvx_myzone 28 | iface vrfvx_myzone 29 | vxlan-id 1000 30 | vxlan-local-tunnelip 192.168.0.1 31 | bridge-learning off 32 | bridge-arp-nd-suppress on 33 | mtu 1450 34 | 35 | auto vxlan_myvnet 36 | iface vxlan_myvnet 37 | vxlan-id 100 38 | vxlan-local-tunnelip 192.168.0.1 39 | bridge-learning off 40 | bridge-arp-nd-suppress on 41 | mtu 1450 42 | -------------------------------------------------------------------------------- /src/test/zones/evpn/multipath_relax/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | bridge_ports vxlan_myvnet 7 | bridge_stp off 8 | bridge_fd 0 9 | mtu 1450 10 | ip-forward on 11 | arp-accept on 12 | vrf vrf_myzone 13 | 14 | auto vrf_myzone 15 | iface vrf_myzone 16 | vrf-table auto 17 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 18 | 19 | auto vrfbr_myzone 20 | iface vrfbr_myzone 21 | bridge-ports vrfvx_myzone 22 | bridge_stp off 23 | bridge_fd 0 24 | mtu 1450 25 | vrf vrf_myzone 26 | 27 | auto vrfvx_myzone 28 | iface vrfvx_myzone 29 | vxlan-id 1000 30 | vxlan-local-tunnelip 192.168.0.1 31 | bridge-learning off 32 | bridge-arp-nd-suppress on 33 | mtu 1450 34 | 35 | auto vxlan_myvnet 36 | iface vxlan_myvnet 37 | vxlan-id 100 38 | vxlan-local-tunnelip 192.168.0.1 39 | bridge-learning off 40 | bridge-arp-nd-suppress on 41 | mtu 1450 42 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.del_a_record.ipv4: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"rrsets":[{"changetype":"DELETE","name":"myhostname.domain.com.","records":[],"type":"A"}]}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | 15 | -------------------------------------------------------------------------------- /src/test/ipams/phpipam/expected.add_ip_notgateway: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"description":"mydescription","hostname":"myhostname","ip":"10.0.0.1","mac":"da:65:8f:18:9b:6f","subnetId":1}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'token' => 'Token' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'POST', 12 | '_uri' => bless( do{\(my $o = 'https://localhost/api/apiadmin/addresses/')}, 'URI::https' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /src/test/vnets/ipv4noipam/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { type =>"simple" } }, 11 | }, 12 | 13 | subnets => { 14 | ids => { 15 | 'myzone-192.168.0.0-30' => { 16 | 'type' => 'subnet', 17 | 'vnet' => 'myvnet', 18 | }, 19 | 'myzone-192.168.1.0-30' => { 20 | 'type' => 'subnet', 21 | 'vnet' => 'myvnet', 22 | }, 23 | } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/ipams/phpipam/expected.add_ip: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"description":"mydescription","hostname":"myhostname","ip":"10.0.0.1","is_gateway":1,"mac":"da:65:8f:18:9b:6f","subnetId":1}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'token' => 'Token' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'token' => 'JPHkPSLB4O_XL-GQz4qtEFmNpx-99Htw' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'POST', 12 | '_uri' => bless( do{\(my $o = 'https://localhost/api/apiadmin/addresses/')}, 'URI::https' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv4ipv6nogateway/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, 'mac' => 'A2:1D:CB:1A:C0:8B' } }, 11 | }, 12 | controllers => { 13 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 14 | }, 15 | 16 | subnets => { 17 | ids => { 18 | 'myzone-10.0.0.0-24' => { 19 | 'type' => 'subnet', 20 | 'vnet' => 'myvnet', 21 | }, 22 | 'myzone-2a08:2142:302:3::-64' => { 23 | 'type' => 'subnet', 24 | 'vnet' => 'myvnet', 25 | } 26 | } 27 | } 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/vnets/ipv4/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type =>"simple" } }, 11 | }, 12 | 13 | subnets => { 14 | ids => { 15 | 'myzone-192.168.0.0-30' => { 16 | 'type' => 'subnet', 17 | 'vnet' => 'myvnet', 18 | }, 19 | 'myzone-192.168.1.0-30' => { 20 | 'type' => 'subnet', 21 | 'vnet' => 'myvnet', 22 | }, 23 | } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv4/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | hwaddress A2:1D:CB:1A:C0:8B 7 | bridge_ports vxlan_myvnet 8 | bridge_stp off 9 | bridge_fd 0 10 | mtu 1450 11 | ip-forward on 12 | arp-accept on 13 | vrf vrf_myzone 14 | 15 | auto vrf_myzone 16 | iface vrf_myzone 17 | vrf-table auto 18 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 19 | 20 | auto vrfbr_myzone 21 | iface vrfbr_myzone 22 | bridge-ports vrfvx_myzone 23 | bridge_stp off 24 | bridge_fd 0 25 | mtu 1450 26 | vrf vrf_myzone 27 | 28 | auto vrfvx_myzone 29 | iface vrfvx_myzone 30 | vxlan-id 1000 31 | vxlan-local-tunnelip 192.168.0.1 32 | bridge-learning off 33 | bridge-arp-nd-suppress on 34 | mtu 1450 35 | 36 | auto vxlan_myvnet 37 | iface vxlan_myvnet 38 | vxlan-id 100 39 | vxlan-local-tunnelip 192.168.0.1 40 | bridge-learning off 41 | bridge-arp-nd-suppress on 42 | mtu 1450 43 | -------------------------------------------------------------------------------- /src/test/zones/evpn/rt_import/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | hwaddress A2:1D:CB:1A:C0:8B 7 | bridge_ports vxlan_myvnet 8 | bridge_stp off 9 | bridge_fd 0 10 | mtu 1450 11 | ip-forward on 12 | arp-accept on 13 | vrf vrf_myzone 14 | 15 | auto vrf_myzone 16 | iface vrf_myzone 17 | vrf-table auto 18 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 19 | 20 | auto vrfbr_myzone 21 | iface vrfbr_myzone 22 | bridge-ports vrfvx_myzone 23 | bridge_stp off 24 | bridge_fd 0 25 | mtu 1450 26 | vrf vrf_myzone 27 | 28 | auto vrfvx_myzone 29 | iface vrfvx_myzone 30 | vxlan-id 1000 31 | vxlan-local-tunnelip 192.168.0.1 32 | bridge-learning off 33 | bridge-arp-nd-suppress on 34 | mtu 1450 35 | 36 | auto vxlan_myvnet 37 | iface vxlan_myvnet 38 | vxlan-id 100 39 | vxlan-local-tunnelip 192.168.0.1 40 | bridge-learning off 41 | bridge-arp-nd-suppress on 42 | mtu 1450 43 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv6/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 2a08:2142:302:3::1/64 6 | hwaddress A2:1D:CB:1A:C0:8B 7 | bridge_ports vxlan_myvnet 8 | bridge_stp off 9 | bridge_fd 0 10 | mtu 1450 11 | ip6-forward on 12 | arp-accept on 13 | vrf vrf_myzone 14 | 15 | auto vrf_myzone 16 | iface vrf_myzone 17 | vrf-table auto 18 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 19 | 20 | auto vrfbr_myzone 21 | iface vrfbr_myzone 22 | bridge-ports vrfvx_myzone 23 | bridge_stp off 24 | bridge_fd 0 25 | mtu 1450 26 | vrf vrf_myzone 27 | 28 | auto vrfvx_myzone 29 | iface vrfvx_myzone 30 | vxlan-id 1000 31 | vxlan-local-tunnelip 192.168.0.1 32 | bridge-learning off 33 | bridge-arp-nd-suppress on 34 | mtu 1450 35 | 36 | auto vxlan_myvnet 37 | iface vxlan_myvnet 38 | vxlan-id 100 39 | vxlan-local-tunnelip 192.168.0.1 40 | bridge-learning off 41 | bridge-arp-nd-suppress on 42 | mtu 1450 43 | -------------------------------------------------------------------------------- /src/test/zones/evpn/advertise_subnets/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | hwaddress A2:1D:CB:1A:C0:8B 7 | bridge_ports vxlan_myvnet 8 | bridge_stp off 9 | bridge_fd 0 10 | mtu 1450 11 | ip-forward on 12 | arp-accept on 13 | vrf vrf_myzone 14 | 15 | auto vrf_myzone 16 | iface vrf_myzone 17 | vrf-table auto 18 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 19 | 20 | auto vrfbr_myzone 21 | iface vrfbr_myzone 22 | bridge-ports vrfvx_myzone 23 | bridge_stp off 24 | bridge_fd 0 25 | mtu 1450 26 | vrf vrf_myzone 27 | 28 | auto vrfvx_myzone 29 | iface vrfvx_myzone 30 | vxlan-id 1000 31 | vxlan-local-tunnelip 192.168.0.1 32 | bridge-learning off 33 | bridge-arp-nd-suppress on 34 | mtu 1450 35 | 36 | auto vxlan_myvnet 37 | iface vxlan_myvnet 38 | vxlan-id 100 39 | vxlan-local-tunnelip 192.168.0.1 40 | bridge-learning off 41 | bridge-arp-nd-suppress on 42 | mtu 1450 43 | -------------------------------------------------------------------------------- /src/test/vnets/ipv6/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type =>"simple" } }, 11 | }, 12 | 13 | subnets => { 14 | ids => { 15 | 'myzone-2001:db8:85a3::8a2e:370:7334-127' => { 16 | 'type' => 'subnet', 17 | 'vnet' => 'myvnet', 18 | }, 19 | 'myzone-2001:db8:85a3::8a2e:371:7334-127' => { 20 | 'type' => 'subnet', 21 | 'vnet' => 'myvnet', 22 | }, 23 | } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ebgp_loopback/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000 } }, 11 | }, 12 | controllers => { 13 | ids => { 14 | evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" }, 15 | localhost => { type => "bgp", 'peers' => '172.16.0.254,172.17.0.254', ebgp => "1", asn => "65001", loopback => 'dummy1', node => "localhost" }, 16 | }, 17 | }, 18 | 19 | subnets => { 20 | ids => { 'myzone-10.0.0.0-24' => { 21 | 'type' => 'subnet', 22 | 'vnet' => 'myvnet', 23 | 'gateway' => '10.0.0.1', 24 | } 25 | } 26 | } 27 | } 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv6underlay/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 2a08:2142:302:3::1/64 6 | hwaddress A2:1D:CB:1A:C0:8B 7 | bridge_ports vxlan_myvnet 8 | bridge_stp off 9 | bridge_fd 0 10 | mtu 1450 11 | ip6-forward on 12 | arp-accept on 13 | vrf vrf_myzone 14 | 15 | auto vrf_myzone 16 | iface vrf_myzone 17 | vrf-table auto 18 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 19 | 20 | auto vrfbr_myzone 21 | iface vrfbr_myzone 22 | bridge-ports vrfvx_myzone 23 | bridge_stp off 24 | bridge_fd 0 25 | mtu 1450 26 | vrf vrf_myzone 27 | 28 | auto vrfvx_myzone 29 | iface vrfvx_myzone 30 | vxlan-id 1000 31 | vxlan-local-tunnelip 2a08:2200:100:1::10 32 | bridge-learning off 33 | bridge-arp-nd-suppress on 34 | mtu 1450 35 | 36 | auto vxlan_myvnet 37 | iface vxlan_myvnet 38 | vxlan-id 100 39 | vxlan-local-tunnelip 2a08:2200:100:1::10 40 | bridge-learning off 41 | bridge-arp-nd-suppress on 42 | mtu 1450 43 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.del_ptr_record.ipv6: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"rrsets":[{"changetype":"DELETE","name":"8.8.8.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.6.8.4.0.6.8.4.1.0.0.2.ip6.arpa.","records":[],"type":"PTR"}]}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | 15 | -------------------------------------------------------------------------------- /src/test/zones/evpn/vxlanport/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | hwaddress A2:1D:CB:1A:C0:8B 7 | bridge_ports vxlan_myvnet 8 | bridge_stp off 9 | bridge_fd 0 10 | mtu 1450 11 | ip-forward on 12 | arp-accept on 13 | vrf vrf_myzone 14 | 15 | auto vrf_myzone 16 | iface vrf_myzone 17 | vrf-table auto 18 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 19 | 20 | auto vrfbr_myzone 21 | iface vrfbr_myzone 22 | bridge-ports vrfvx_myzone 23 | bridge_stp off 24 | bridge_fd 0 25 | mtu 1450 26 | vrf vrf_myzone 27 | 28 | auto vrfvx_myzone 29 | iface vrfvx_myzone 30 | vxlan-id 1000 31 | vxlan-local-tunnelip 192.168.0.1 32 | vxlan-port 6000 33 | bridge-learning off 34 | bridge-arp-nd-suppress on 35 | mtu 1450 36 | 37 | auto vxlan_myvnet 38 | iface vxlan_myvnet 39 | vxlan-id 100 40 | vxlan-local-tunnelip 192.168.0.1 41 | vxlan-port 6000 42 | bridge-learning off 43 | bridge-arp-nd-suppress on 44 | mtu 1450 45 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv4ipv6/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | address 2a08:2142:302:3::1/64 7 | hwaddress A2:1D:CB:1A:C0:8B 8 | bridge_ports vxlan_myvnet 9 | bridge_stp off 10 | bridge_fd 0 11 | mtu 1450 12 | ip-forward on 13 | ip6-forward on 14 | arp-accept on 15 | vrf vrf_myzone 16 | 17 | auto vrf_myzone 18 | iface vrf_myzone 19 | vrf-table auto 20 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 21 | 22 | auto vrfbr_myzone 23 | iface vrfbr_myzone 24 | bridge-ports vrfvx_myzone 25 | bridge_stp off 26 | bridge_fd 0 27 | mtu 1450 28 | vrf vrf_myzone 29 | 30 | auto vrfvx_myzone 31 | iface vrfvx_myzone 32 | vxlan-id 1000 33 | vxlan-local-tunnelip 192.168.0.1 34 | bridge-learning off 35 | bridge-arp-nd-suppress on 36 | mtu 1450 37 | 38 | auto vxlan_myvnet 39 | iface vxlan_myvnet 40 | vxlan-id 100 41 | vxlan-local-tunnelip 192.168.0.1 42 | bridge-learning off 43 | bridge-arp-nd-suppress on 44 | mtu 1450 45 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.add_a_record.ipv4: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"myhostname.domain.com.","records":[{"content":"10.0.0.1","disabled":false,"name":"myhostname.domain.com.","type":"A"}],"ttl":"3600","type":"A"}]}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv4ipv6/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | }, 7 | }, 8 | 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, 'mac' => 'A2:1D:CB:1A:C0:8B' } }, 11 | }, 12 | controllers => { 13 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 14 | }, 15 | 16 | subnets => { 17 | ids => { 18 | 'myzone-10.0.0.0-24' => { 19 | 'type' => 'subnet', 20 | 'vnet' => 'myvnet', 21 | 'gateway' => '10.0.0.1', 22 | }, 23 | 'myzone-2a08:2142:302:3::-64' => { 24 | 'type' => 'subnet', 25 | 'vnet' => 'myvnet', 26 | 'gateway' => '2a08:2142:302:3::1', 27 | } 28 | } 29 | } 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.add_ptr_record.ipv4: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"1.0.0.10.in-addr.arpa.","records":[{"content":"myhostname.","disabled":false,"name":"1.0.0.10.in-addr.arpa.","type":"PTR"}],"ttl":"3600","type":"PTR"}]}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | 15 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.del_a_multiple_record.ipv4: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"myhostname.domain.com.","records":[{"content":"127.0.0.1","disabled":false,"name":"myhostname.domain.com.","type":"A"}],"ttl":"3600","type":"A"}]}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | 15 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.add_a_record.ipv6: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"myhostname.domain.com.","records":[{"content":"2001:4860:4860::8888","disabled":false,"name":"myhostname.domain.com.","type":"AAAA"}],"ttl":"3600","type":"AAAA"}]}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | 15 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.del_a_multiple_record.ipv6: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"myhostname.domain.com.","records":[{"content":"2001:4860:4860::8844","disabled":false,"name":"myhostname.domain.com.","type":"AAAA"}],"ttl":"3600","type":"AAAA"}]}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /debian/libpve-network-perl.postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | migrate_ipam_db() { 6 | LEGACY_IPAM_DB_FILE="/etc/pve/priv/ipam.db" 7 | IPAM_DB_FILE="/etc/pve/sdn/pve-ipam-state.json" 8 | 9 | if test -f "$LEGACY_IPAM_DB_FILE" && test ! -f "$IPAM_DB_FILE"; then 10 | echo "copying over existing legacy IPAM state file to new path..." 11 | cp $LEGACY_IPAM_DB_FILE $IPAM_DB_FILE || echo "copying IPAM state file failed!" 12 | fi 13 | } 14 | 15 | migrate_mac_cache() { 16 | LEGACY_MAC_DB_FILE="/etc/pve/priv/macs.db" 17 | MAC_DB_FILE="/etc/pve/sdn/mac-cache.json" 18 | 19 | if test -f "$LEGACY_MAC_DB_FILE" && test ! -f "$MAC_DB_FILE"; then 20 | echo "copying over existing legacy IPAM MAC-map cache file to new path..." 21 | cp $LEGACY_MAC_DB_FILE $MAC_DB_FILE || echo "copying IPAM MAC-map cache file failed!" 22 | fi 23 | } 24 | 25 | case "$1" in 26 | configure) 27 | # TODO: remove with PVE 9+ 28 | if dpkg --compare-versions "$2" 'lt' '0.9.9'; then 29 | migrate_ipam_db 30 | migrate_mac_cache 31 | fi 32 | ;; 33 | esac 34 | 35 | exit 0 36 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv4/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | ! 24 | address-family l2vpn evpn 25 | neighbor VTEP activate 26 | neighbor VTEP route-map MAP_VTEP_IN in 27 | neighbor VTEP route-map MAP_VTEP_OUT out 28 | advertise-all-vni 29 | exit-address-family 30 | exit 31 | ! 32 | router bgp 65000 vrf vrf_myzone 33 | bgp router-id 192.168.0.1 34 | no bgp hard-administrative-reset 35 | no bgp graceful-restart notification 36 | exit 37 | ! 38 | route-map MAP_VTEP_IN permit 1 39 | exit 40 | ! 41 | route-map MAP_VTEP_OUT permit 1 42 | exit 43 | ! 44 | line vty 45 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv6/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | ! 24 | address-family l2vpn evpn 25 | neighbor VTEP activate 26 | neighbor VTEP route-map MAP_VTEP_IN in 27 | neighbor VTEP route-map MAP_VTEP_OUT out 28 | advertise-all-vni 29 | exit-address-family 30 | exit 31 | ! 32 | router bgp 65000 vrf vrf_myzone 33 | bgp router-id 192.168.0.1 34 | no bgp hard-administrative-reset 35 | no bgp graceful-restart notification 36 | exit 37 | ! 38 | route-map MAP_VTEP_IN permit 1 39 | exit 40 | ! 41 | route-map MAP_VTEP_OUT permit 1 42 | exit 43 | ! 44 | line vty 45 | ! -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.add_a_multiple_record.ipv4: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"myhostname.domain.com.","records":[{"content":"127.0.0.1","disabled":false,"name":"myhostname.domain.com.","type":"A"},{"content":"10.0.0.1","disabled":false,"name":"myhostname.domain.com.","type":"A"}],"ttl":"3600","type":"A"}]}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | 15 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv4ipv6/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | ! 24 | address-family l2vpn evpn 25 | neighbor VTEP activate 26 | neighbor VTEP route-map MAP_VTEP_IN in 27 | neighbor VTEP route-map MAP_VTEP_OUT out 28 | advertise-all-vni 29 | exit-address-family 30 | exit 31 | ! 32 | router bgp 65000 vrf vrf_myzone 33 | bgp router-id 192.168.0.1 34 | no bgp hard-administrative-reset 35 | no bgp graceful-restart notification 36 | exit 37 | ! 38 | route-map MAP_VTEP_IN permit 1 39 | exit 40 | ! 41 | route-map MAP_VTEP_OUT permit 1 42 | exit 43 | ! 44 | line vty 45 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/vxlanport/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | ! 24 | address-family l2vpn evpn 25 | neighbor VTEP activate 26 | neighbor VTEP route-map MAP_VTEP_IN in 27 | neighbor VTEP route-map MAP_VTEP_OUT out 28 | advertise-all-vni 29 | exit-address-family 30 | exit 31 | ! 32 | router bgp 65000 vrf vrf_myzone 33 | bgp router-id 192.168.0.1 34 | no bgp hard-administrative-reset 35 | no bgp graceful-restart notification 36 | exit 37 | ! 38 | route-map MAP_VTEP_IN permit 1 39 | exit 40 | ! 41 | route-map MAP_VTEP_OUT permit 1 42 | exit 43 | ! 44 | line vty 45 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv4ipv6nogateway/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | ! 24 | address-family l2vpn evpn 25 | neighbor VTEP activate 26 | neighbor VTEP route-map MAP_VTEP_IN in 27 | neighbor VTEP route-map MAP_VTEP_OUT out 28 | advertise-all-vni 29 | exit-address-family 30 | exit 31 | ! 32 | router bgp 65000 vrf vrf_myzone 33 | bgp router-id 192.168.0.1 34 | no bgp hard-administrative-reset 35 | no bgp graceful-restart notification 36 | exit 37 | ! 38 | route-map MAP_VTEP_IN permit 1 39 | exit 40 | ! 41 | route-map MAP_VTEP_OUT permit 1 42 | exit 43 | ! 44 | line vty 45 | ! -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge_vlanaware/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myzone 4 | iface ln_myzone 5 | link-type veth 6 | veth-peer-name pr_myzone 7 | 8 | auto ln_myzone2 9 | iface ln_myzone2 10 | link-type veth 11 | veth-peer-name pr_myzone2 12 | 13 | auto myvnet 14 | iface myvnet 15 | bridge_ports z_myzone.100 16 | bridge_stp off 17 | bridge_fd 0 18 | 19 | auto myvnet2 20 | iface myvnet2 21 | bridge_ports z_myzone.101 22 | bridge_stp off 23 | bridge_fd 0 24 | 25 | auto myvnet3 26 | iface myvnet3 27 | bridge_ports z_myzone2.100 28 | bridge_stp off 29 | bridge_fd 0 30 | 31 | auto pr_myzone 32 | iface pr_myzone 33 | link-type veth 34 | veth-peer-name ln_myzone 35 | 36 | auto pr_myzone2 37 | iface pr_myzone2 38 | link-type veth 39 | veth-peer-name ln_myzone2 40 | 41 | auto z_myzone 42 | iface z_myzone 43 | bridge-stp off 44 | bridge-ports vmbr0.10 ln_myzone 45 | bridge-fd 0 46 | bridge-vlan-aware yes 47 | bridge-vids 2-4094 48 | 49 | auto z_myzone2 50 | iface z_myzone2 51 | bridge-stp off 52 | bridge-ports vmbr0.20 ln_myzone2 53 | bridge-fd 0 54 | bridge-vlan-aware yes 55 | bridge-vids 2-4094 56 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.add_ptr_record.ipv6: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"8.8.8.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.6.8.4.0.6.8.4.1.0.0.2.ip6.arpa.","records":[{"content":"myhostname.","disabled":false,"name":"8.8.8.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.6.8.4.0.6.8.4.1.0.0.2.ip6.arpa.","type":"PTR"}],"ttl":"3600","type":"PTR"}]}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | -------------------------------------------------------------------------------- /src/test/zones/evpn/disable_arp_nd_suppression/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | ! 24 | address-family l2vpn evpn 25 | neighbor VTEP activate 26 | neighbor VTEP route-map MAP_VTEP_IN in 27 | neighbor VTEP route-map MAP_VTEP_OUT out 28 | advertise-all-vni 29 | exit-address-family 30 | exit 31 | ! 32 | router bgp 65000 vrf vrf_myzone 33 | bgp router-id 192.168.0.1 34 | no bgp hard-administrative-reset 35 | no bgp graceful-restart notification 36 | exit 37 | ! 38 | route-map MAP_VTEP_IN permit 1 39 | exit 40 | ! 41 | route-map MAP_VTEP_OUT permit 1 42 | exit 43 | ! 44 | line vty 45 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/ipv6underlay/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 17.29.105.96 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 2a08:2200:100:1::11 peer-group VTEP 22 | neighbor 2a08:2200:100:1::12 peer-group VTEP 23 | ! 24 | address-family l2vpn evpn 25 | neighbor VTEP activate 26 | neighbor VTEP route-map MAP_VTEP_IN in 27 | neighbor VTEP route-map MAP_VTEP_OUT out 28 | advertise-all-vni 29 | exit-address-family 30 | exit 31 | ! 32 | router bgp 65000 vrf vrf_myzone 33 | bgp router-id 17.29.105.96 34 | no bgp hard-administrative-reset 35 | no bgp graceful-restart notification 36 | exit 37 | ! 38 | route-map MAP_VTEP_IN permit 1 39 | exit 40 | ! 41 | route-map MAP_VTEP_OUT permit 1 42 | exit 43 | ! 44 | line vty 45 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/multiplezones/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | myvnet2 => { tag => "101", type => "vnet", zone => "myzone2" }, 7 | }, 8 | }, 9 | 10 | zones => { 11 | ids => { 12 | myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000 }, 13 | myzone2 => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1001 }, 14 | } 15 | }, 16 | controllers => { 17 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 18 | }, 19 | 20 | subnets => { 21 | ids => { 22 | 'myzone-10.0.0.0-24' => { 23 | 'type' => 'subnet', 24 | 'vnet' => 'myvnet', 25 | 'gateway' => '10.0.0.1', 26 | }, 27 | 'myzone2-172.16.0.0-24' => { 28 | 'type' => 'subnet', 29 | 'vnet' => 'myvnet2', 30 | 'gateway' => '172.16.0.1', 31 | }, 32 | } 33 | } 34 | 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/test/dns/powerdns/expected.add_a_multiple_record.ipv6: -------------------------------------------------------------------------------- 1 | bless( { 2 | '_content' => '{"rrsets":[{"changetype":"REPLACE","name":"myhostname.domain.com.","records":[{"content":"2001:4860:4860::8844","disabled":false,"name":"myhostname.domain.com.","type":"AAAA"},{"content":"2001:4860:4860::8888","disabled":false,"name":"myhostname.domain.com.","type":"AAAA"}],"ttl":"3600","type":"AAAA"}]}', 3 | '_headers' => bless( { 4 | '::std_case' => { 5 | 'x-api-key' => 'X-API-Key' 6 | }, 7 | 'content-type' => 'application/json; charset=UTF-8', 8 | 'x-api-key' => '1234' 9 | }, 'HTTP::Headers' ), 10 | '_max_body_size' => undef, 11 | '_method' => 'PATCH', 12 | '_uri' => bless( do{\(my $o = 'http://localhost:8881/api/v1/servers/localhost/zones/domain.com')}, 'URI::http' ) 13 | }, 'HTTP::Request' ); 14 | 15 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ospf_fabric/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto vnet0 4 | iface vnet0 5 | address 10.123.123.1/24 6 | hwaddress BC:24:11:3B:39:34 7 | bridge_ports vxlan_vnet0 8 | bridge_stp off 9 | bridge_fd 0 10 | mtu 1450 11 | ip-forward on 12 | arp-accept on 13 | vrf vrf_evpn 14 | 15 | auto vrf_evpn 16 | iface vrf_evpn 17 | vrf-table auto 18 | post-up ip route add vrf vrf_evpn unreachable default metric 4278198272 19 | 20 | auto vrfbr_evpn 21 | iface vrfbr_evpn 22 | bridge-ports vrfvx_evpn 23 | bridge_stp off 24 | bridge_fd 0 25 | mtu 1450 26 | vrf vrf_evpn 27 | 28 | auto vrfvx_evpn 29 | iface vrfvx_evpn 30 | vxlan-id 100 31 | vxlan-local-tunnelip 172.20.30.1 32 | bridge-learning off 33 | bridge-arp-nd-suppress on 34 | mtu 1450 35 | 36 | auto vxlan_vnet0 37 | iface vxlan_vnet0 38 | vxlan-id 123456 39 | vxlan-local-tunnelip 172.20.30.1 40 | bridge-learning off 41 | bridge-arp-nd-suppress on 42 | mtu 1450 43 | 44 | auto dummy_test 45 | iface dummy_test inet static 46 | address 172.20.30.1/32 47 | link-type dummy 48 | ip-forward 1 49 | 50 | auto ens19 51 | iface ens19 inet static 52 | address 172.16.3.10/31 53 | ip-forward 1 54 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode_local_routing/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | bridge_ports vxlan_myvnet 7 | bridge_stp off 8 | bridge_fd 0 9 | mtu 1450 10 | ip-forward on 11 | arp-accept on 12 | vrf vrf_myzone 13 | 14 | auto vrf_myzone 15 | iface vrf_myzone 16 | vrf-table auto 17 | post-up ip route del vrf vrf_myzone unreachable default metric 4278198272 18 | 19 | auto vrfbr_myzone 20 | iface vrfbr_myzone 21 | bridge-ports vrfvx_myzone 22 | bridge_stp off 23 | bridge_fd 0 24 | mtu 1450 25 | vrf vrf_myzone 26 | 27 | auto vrfvx_myzone 28 | iface vrfvx_myzone 29 | vxlan-id 1000 30 | vxlan-local-tunnelip 192.168.0.1 31 | bridge-learning off 32 | bridge-arp-nd-suppress on 33 | mtu 1450 34 | 35 | auto vxlan_myvnet 36 | iface vxlan_myvnet 37 | vxlan-id 100 38 | vxlan-local-tunnelip 192.168.0.1 39 | bridge-learning off 40 | bridge-arp-nd-suppress on 41 | mtu 1450 42 | 43 | auto xvrf_myzone 44 | iface xvrf_myzone 45 | link-type veth 46 | address 10.255.255.1/30 47 | veth-peer-name xvrfp_myzone 48 | mtu 1500 49 | 50 | auto xvrfp_myzone 51 | iface xvrfp_myzone 52 | link-type veth 53 | address 10.255.255.2/30 54 | veth-peer-name xvrf_myzone 55 | vrf vrf_myzone 56 | mtu 1500 57 | -------------------------------------------------------------------------------- /src/test/zones/evpn/openfabric_fabric/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto vnet0 4 | iface vnet0 5 | address 10.123.123.1/24 6 | hwaddress BC:24:11:3B:39:34 7 | bridge_ports vxlan_vnet0 8 | bridge_stp off 9 | bridge_fd 0 10 | mtu 1450 11 | ip-forward on 12 | arp-accept on 13 | vrf vrf_evpn 14 | 15 | auto vrf_evpn 16 | iface vrf_evpn 17 | vrf-table auto 18 | post-up ip route add vrf vrf_evpn unreachable default metric 4278198272 19 | 20 | auto vrfbr_evpn 21 | iface vrfbr_evpn 22 | bridge-ports vrfvx_evpn 23 | bridge_stp off 24 | bridge_fd 0 25 | mtu 1450 26 | vrf vrf_evpn 27 | 28 | auto vrfvx_evpn 29 | iface vrfvx_evpn 30 | vxlan-id 100 31 | vxlan-local-tunnelip 172.20.3.1 32 | bridge-learning off 33 | bridge-arp-nd-suppress on 34 | mtu 1450 35 | 36 | auto vxlan_vnet0 37 | iface vxlan_vnet0 38 | vxlan-id 123456 39 | vxlan-local-tunnelip 172.20.3.1 40 | bridge-learning off 41 | bridge-arp-nd-suppress on 42 | mtu 1450 43 | 44 | auto dummy_test 45 | iface dummy_test inet static 46 | address 172.20.3.1/32 47 | link-type dummy 48 | ip-forward 1 49 | 50 | auto ens20 51 | iface ens20 inet static 52 | address 172.20.3.1/32 53 | ip-forward 1 54 | 55 | auto ens21 56 | iface ens21 inet static 57 | address 172.20.3.1/32 58 | ip-forward 1 59 | -------------------------------------------------------------------------------- /src/test/zones/evpn/rt_import/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | ! 24 | address-family l2vpn evpn 25 | neighbor VTEP activate 26 | neighbor VTEP route-map MAP_VTEP_IN in 27 | neighbor VTEP route-map MAP_VTEP_OUT out 28 | advertise-all-vni 29 | exit-address-family 30 | exit 31 | ! 32 | router bgp 65000 vrf vrf_myzone 33 | bgp router-id 192.168.0.1 34 | no bgp hard-administrative-reset 35 | no bgp graceful-restart notification 36 | ! 37 | address-family l2vpn evpn 38 | route-target import 65001:1000 39 | route-target import 65002:1000 40 | route-target import 65003:1000 41 | exit-address-family 42 | exit 43 | ! 44 | route-map MAP_VTEP_IN permit 1 45 | exit 46 | ! 47 | route-map MAP_VTEP_OUT permit 1 48 | exit 49 | ! 50 | line vty 51 | ! -------------------------------------------------------------------------------- /src/test/zones/qinq/bridge/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myzone 4 | iface ln_myzone 5 | link-type veth 6 | veth-peer-name pr_myzone 7 | 8 | auto ln_myzone2 9 | iface ln_myzone2 10 | link-type veth 11 | veth-peer-name pr_myzone2 12 | 13 | auto myvnet 14 | iface myvnet 15 | bridge_ports z_myzone.100 16 | bridge_stp off 17 | bridge_fd 0 18 | 19 | auto myvnet2 20 | iface myvnet2 21 | bridge_ports z_myzone.101 22 | bridge_stp off 23 | bridge_fd 0 24 | 25 | auto myvnet3 26 | iface myvnet3 27 | bridge_ports z_myzone2.100 28 | bridge_stp off 29 | bridge_fd 0 30 | 31 | auto pr_myzone 32 | iface pr_myzone 33 | link-type veth 34 | veth-peer-name ln_myzone 35 | 36 | auto pr_myzone2 37 | iface pr_myzone2 38 | link-type veth 39 | veth-peer-name ln_myzone2 40 | 41 | auto sv_myzone 42 | iface sv_myzone 43 | vlan-raw-device eth0 44 | vlan-id 10 45 | 46 | auto sv_myzone2 47 | iface sv_myzone2 48 | vlan-raw-device eth0 49 | vlan-id 20 50 | 51 | auto z_myzone 52 | iface z_myzone 53 | bridge-stp off 54 | bridge-ports sv_myzone ln_myzone 55 | bridge-fd 0 56 | bridge-vlan-aware yes 57 | bridge-vids 2-4094 58 | 59 | auto z_myzone2 60 | iface z_myzone2 61 | bridge-stp off 62 | bridge-ports sv_myzone2 ln_myzone2 63 | bridge-fd 0 64 | bridge-vlan-aware yes 65 | bridge-vids 2-4094 66 | -------------------------------------------------------------------------------- /src/PVE/Network/SDN/Dns.pm: -------------------------------------------------------------------------------- 1 | package PVE::Network::SDN::Dns; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use JSON; 7 | 8 | use PVE::Tools qw(extract_param dir_glob_regex run_command); 9 | use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file); 10 | use PVE::Network; 11 | 12 | use PVE::Network::SDN::Dns::PowerdnsPlugin; 13 | use PVE::Network::SDN::Dns::Plugin; 14 | 15 | PVE::Network::SDN::Dns::PowerdnsPlugin->register(); 16 | PVE::Network::SDN::Dns::Plugin->init(); 17 | 18 | sub sdn_dns_config { 19 | my ($cfg, $id, $noerr) = @_; 20 | 21 | die "no sdn dns ID specified\n" if !$id; 22 | 23 | my $scfg = $cfg->{ids}->{$id}; 24 | die "sdn '$id' does not exist\n" if (!$noerr && !$scfg); 25 | 26 | return $scfg; 27 | } 28 | 29 | sub config { 30 | my $config = cfs_read_file("sdn/dns.cfg"); 31 | return $config; 32 | } 33 | 34 | sub write_config { 35 | my ($cfg) = @_; 36 | 37 | cfs_write_file("sdn/dns.cfg", $cfg); 38 | } 39 | 40 | sub sdn_dns_ids { 41 | my ($cfg) = @_; 42 | 43 | return keys %{ $cfg->{ids} }; 44 | } 45 | 46 | sub complete_sdn_dns { 47 | my ($cmdname, $pname, $cvalue) = @_; 48 | 49 | my $cfg = PVE::Network::SDN::Dns::config(); 50 | 51 | return $cmdname eq 'add' ? [] : [PVE::Network::SDN::Dns::sdn_dns_ids($cfg)]; 52 | } 53 | 54 | 1; 55 | 56 | -------------------------------------------------------------------------------- /src/test/zones/evpn/multiplezones/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | vrf vrf_myzone2 13 | vni 1001 14 | exit-vrf 15 | ! 16 | router bgp 65000 17 | bgp router-id 192.168.0.1 18 | no bgp hard-administrative-reset 19 | no bgp default ipv4-unicast 20 | coalesce-time 1000 21 | no bgp graceful-restart notification 22 | neighbor VTEP peer-group 23 | neighbor VTEP remote-as 65000 24 | neighbor VTEP bfd 25 | neighbor 192.168.0.2 peer-group VTEP 26 | neighbor 192.168.0.3 peer-group VTEP 27 | ! 28 | address-family l2vpn evpn 29 | neighbor VTEP activate 30 | neighbor VTEP route-map MAP_VTEP_IN in 31 | neighbor VTEP route-map MAP_VTEP_OUT out 32 | advertise-all-vni 33 | exit-address-family 34 | exit 35 | ! 36 | router bgp 65000 vrf vrf_myzone 37 | bgp router-id 192.168.0.1 38 | no bgp hard-administrative-reset 39 | no bgp graceful-restart notification 40 | exit 41 | ! 42 | router bgp 65000 vrf vrf_myzone2 43 | bgp router-id 192.168.0.1 44 | no bgp hard-administrative-reset 45 | no bgp graceful-restart notification 46 | exit 47 | ! 48 | route-map MAP_VTEP_IN permit 1 49 | exit 50 | ! 51 | route-map MAP_VTEP_OUT permit 1 52 | exit 53 | ! 54 | line vty 55 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode_snat/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | myvnet2 => { tag => "200", type => "vnet", zone => "myzone" }, 7 | }, 8 | }, 9 | 10 | zones => { 11 | ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, exitnodes => { 'localhost' => 1 } } }, 12 | }, 13 | controllers => { 14 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 15 | }, 16 | 17 | subnets => { 18 | ids => { 19 | 'myzone-10.0.0.0-24' => { 20 | 'type' => 'subnet', 21 | 'vnet' => 'myvnet', 22 | 'gateway' => '10.0.0.1', 23 | 'snat' => 1 24 | }, 25 | 'myzone-2a08:2142:302:3::-64' => { 26 | 'type' => 'subnet', 27 | 'vnet' => 'myvnet2', 28 | 'gateway' => '2a08:2142:302:3::1', 29 | 'snat' => 1 30 | } 31 | } 32 | } 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ebgp/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { 6 | tag => "100", 7 | type => "vnet", 8 | zone => "myzone", 9 | }, 10 | }, 11 | }, 12 | 13 | zones => { 14 | ids => { 15 | myzone => { 16 | ipam => "pve", 17 | type => "evpn", 18 | controller => "evpnctl", 19 | 'vrf-vxlan' => 1000, 20 | }, 21 | }, 22 | }, 23 | controllers => { 24 | ids => { 25 | evpnctl => { 26 | type => "evpn", 27 | 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', 28 | asn => "65000", 29 | }, 30 | localhost => { 31 | type => "bgp", 32 | 'peers' => '192.168.0.252,192.168.0.253', 33 | ebgp => "1", 34 | 'ebgp-multihop' => '3', 35 | asn => "65001", 36 | node => "localhost", 37 | }, 38 | }, 39 | }, 40 | 41 | subnets => { 42 | ids => { 43 | 'myzone-10.0.0.0-24' => { 44 | 'type' => 'subnet', 45 | 'vnet' => 'myvnet', 46 | 'gateway' => '10.0.0.1', 47 | }, 48 | }, 49 | }, 50 | } 51 | -------------------------------------------------------------------------------- /src/test/zones/evpn/multipath_relax/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { 6 | tag => "100", 7 | type => "vnet", 8 | zone => "myzone", 9 | }, 10 | }, 11 | }, 12 | 13 | zones => { 14 | ids => { 15 | myzone => { 16 | ipam => "pve", 17 | type => "evpn", 18 | controller => "evpnctl", 19 | 'vrf-vxlan' => 1000, 20 | }, 21 | }, 22 | }, 23 | controllers => { 24 | ids => { 25 | evpnctl => { 26 | type => "evpn", 27 | 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', 28 | asn => "65000", 29 | }, 30 | localhost => { 31 | type => "bgp", 32 | 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', 33 | 'bgp-multipath-as-path-relax' => "1", 34 | asn => "65000", 35 | node => "localhost", 36 | }, 37 | }, 38 | }, 39 | 40 | subnets => { 41 | ids => { 42 | 'myzone-10.0.0.0-24' => { 43 | 'type' => 'subnet', 44 | 'vnet' => 'myvnet', 45 | 'gateway' => '10.0.0.1', 46 | }, 47 | }, 48 | }, 49 | } 50 | -------------------------------------------------------------------------------- /src/test/zones/evpn/isis/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { 6 | tag => "100", 7 | type => "vnet", 8 | zone => "myzone", 9 | }, 10 | }, 11 | }, 12 | 13 | zones => { 14 | ids => { 15 | myzone => { 16 | ipam => "pve", 17 | type => "evpn", 18 | controller => "evpnctl", 19 | 'vrf-vxlan' => 1000, 20 | }, 21 | }, 22 | }, 23 | controllers => { 24 | ids => { 25 | evpnctl => { 26 | type => "evpn", 27 | 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', 28 | asn => "65000", 29 | }, 30 | localhost => { 31 | type => "isis", 32 | 'isis-domain' => 'isis1', 33 | 'isis-ifaces' => 'eth1,eth0', 34 | 'isis-net' => "47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00", 35 | node => "localhost", 36 | }, 37 | }, 38 | }, 39 | 40 | subnets => { 41 | ids => { 42 | 'myzone-10.0.0.0-24' => { 43 | 'type' => 'subnet', 44 | 'vnet' => 'myvnet', 45 | 'gateway' => '10.0.0.1', 46 | }, 47 | }, 48 | }, 49 | } 50 | -------------------------------------------------------------------------------- /src/test/zones/evpn/isis/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | interface eth0 13 | ip router isis isis1 14 | ! 15 | interface eth1 16 | ip router isis isis1 17 | ! 18 | router bgp 65000 19 | bgp router-id 192.168.0.1 20 | no bgp hard-administrative-reset 21 | no bgp default ipv4-unicast 22 | coalesce-time 1000 23 | no bgp graceful-restart notification 24 | neighbor VTEP peer-group 25 | neighbor VTEP remote-as 65000 26 | neighbor VTEP bfd 27 | neighbor 192.168.0.2 peer-group VTEP 28 | neighbor 192.168.0.3 peer-group VTEP 29 | ! 30 | address-family l2vpn evpn 31 | neighbor VTEP activate 32 | neighbor VTEP route-map MAP_VTEP_IN in 33 | neighbor VTEP route-map MAP_VTEP_OUT out 34 | advertise-all-vni 35 | exit-address-family 36 | exit 37 | ! 38 | router bgp 65000 vrf vrf_myzone 39 | bgp router-id 192.168.0.1 40 | no bgp hard-administrative-reset 41 | no bgp graceful-restart notification 42 | exit 43 | ! 44 | router isis isis1 45 | net 47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00 46 | redistribute ipv4 connected level-1 47 | redistribute ipv6 connected level-1 48 | log-adjacency-changes 49 | exit 50 | ! 51 | route-map MAP_VTEP_IN permit 1 52 | exit 53 | ! 54 | route-map MAP_VTEP_OUT permit 1 55 | exit 56 | ! 57 | line vty 58 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/isis_loopback/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { 6 | tag => "100", 7 | type => "vnet", 8 | zone => "myzone", 9 | }, 10 | }, 11 | }, 12 | 13 | zones => { 14 | ids => { 15 | myzone => { 16 | ipam => "pve", 17 | type => "evpn", 18 | controller => "evpnctl", 19 | 'vrf-vxlan' => 1000, 20 | }, 21 | }, 22 | }, 23 | controllers => { 24 | ids => { 25 | evpnctl => { 26 | type => "evpn", 27 | 'peers' => '10.0.0.1,10.0.0.2,10.0.0.3', 28 | asn => "65000", 29 | }, 30 | localhost => { 31 | type => "isis", 32 | 'isis-domain' => 'isis1', 33 | 'isis-ifaces' => 'eth1,eth0', 34 | 'isis-net' => "47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00", 35 | loopback => 'dummy1', 36 | node => "localhost", 37 | }, 38 | }, 39 | }, 40 | 41 | subnets => { 42 | ids => { 43 | 'myzone-10.0.0.0-24' => { 44 | 'type' => 'subnet', 45 | 'vnet' => 'myvnet', 46 | 'gateway' => '10.0.0.1', 47 | }, 48 | }, 49 | }, 50 | } 51 | -------------------------------------------------------------------------------- /src/test/zones/evpn/advertise_subnets/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | ! 24 | address-family l2vpn evpn 25 | neighbor VTEP activate 26 | neighbor VTEP route-map MAP_VTEP_IN in 27 | neighbor VTEP route-map MAP_VTEP_OUT out 28 | advertise-all-vni 29 | exit-address-family 30 | exit 31 | ! 32 | router bgp 65000 vrf vrf_myzone 33 | bgp router-id 192.168.0.1 34 | no bgp hard-administrative-reset 35 | no bgp graceful-restart notification 36 | ! 37 | address-family ipv4 unicast 38 | redistribute connected 39 | exit-address-family 40 | ! 41 | address-family ipv6 unicast 42 | redistribute connected 43 | exit-address-family 44 | ! 45 | address-family l2vpn evpn 46 | advertise ipv4 unicast 47 | advertise ipv6 unicast 48 | exit-address-family 49 | exit 50 | ! 51 | route-map MAP_VTEP_IN permit 1 52 | exit 53 | ! 54 | route-map MAP_VTEP_OUT permit 1 55 | exit 56 | ! 57 | line vty 58 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/isis_loopback/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | interface eth0 13 | ip router isis isis1 14 | ! 15 | interface eth1 16 | ip router isis isis1 17 | ! 18 | router bgp 65000 19 | bgp router-id 10.0.0.1 20 | no bgp hard-administrative-reset 21 | no bgp default ipv4-unicast 22 | coalesce-time 1000 23 | no bgp graceful-restart notification 24 | neighbor VTEP peer-group 25 | neighbor VTEP remote-as 65000 26 | neighbor VTEP bfd 27 | neighbor VTEP update-source dummy1 28 | neighbor 10.0.0.2 peer-group VTEP 29 | neighbor 10.0.0.3 peer-group VTEP 30 | ! 31 | address-family l2vpn evpn 32 | neighbor VTEP activate 33 | neighbor VTEP route-map MAP_VTEP_IN in 34 | neighbor VTEP route-map MAP_VTEP_OUT out 35 | advertise-all-vni 36 | exit-address-family 37 | exit 38 | ! 39 | router bgp 65000 vrf vrf_myzone 40 | bgp router-id 10.0.0.1 41 | no bgp hard-administrative-reset 42 | no bgp graceful-restart notification 43 | exit 44 | ! 45 | router isis isis1 46 | net 47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00 47 | redistribute ipv4 connected level-1 48 | redistribute ipv6 connected level-1 49 | log-adjacency-changes 50 | exit 51 | ! 52 | route-map MAP_VTEP_IN permit 1 53 | exit 54 | ! 55 | route-map MAP_VTEP_OUT permit 1 56 | exit 57 | ! 58 | line vty 59 | ! -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include /usr/share/dpkg/pkg-info.mk 2 | 3 | PACKAGE=libpve-network-perl 4 | 5 | BUILDDIR ?= $(PACKAGE)-$(DEB_VERSION_UPSTREAM) 6 | 7 | DEBS=\ 8 | $(PACKAGE)_$(DEB_VERSION_UPSTREAM_REVISION)_all.deb \ 9 | libpve-network-api-perl_$(DEB_VERSION_UPSTREAM_REVISION)_all.deb \ 10 | 11 | DSC=$(PACKAGE)_$(DEB_VERSION_UPSTREAM_REVISION).dsc 12 | 13 | all: deb 14 | 15 | .PHONY: tidy 16 | tidy: 17 | git ls-files ':*.p[ml]'| xargs -n4 -P0 proxmox-perltidy 18 | 19 | .PHONY: dinstall 20 | dinstall: deb 21 | dpkg -i $(DEBS) 22 | 23 | $(BUILDDIR): src debian 24 | rm -rf $@ $@.tmp 25 | cp -a src $@.tmp 26 | cp -a debian $@.tmp/ 27 | echo "git clone git://git.proxmox.com/git/pve-network.git\\ngit checkout $(shell git rev-parse HEAD)" > $@.tmp/debian/SOURCE 28 | mv $@.tmp $@ 29 | 30 | .PHONY: deb 31 | deb: $(DEBS) 32 | $(DEBS) &: $(BUILDDIR) 33 | cd $(BUILDDIR); dpkg-buildpackage -b -us -uc 34 | lintian $(DEBS) 35 | 36 | .PHONY: dsc 37 | dsc: clean 38 | $(MAKE) $(DSC) 39 | lintian $(DSC) 40 | 41 | $(DSC): $(BUILDDIR) 42 | cd $(BUILDDIR); dpkg-buildpackage -S -us -uc -d 43 | 44 | sbuild: $(DSC) 45 | sbuild $(DSC) 46 | 47 | .PHONY: clean distclean 48 | distclean: clean 49 | clean: 50 | rm -rf *~ *.deb *.changes $(PACKAGE)-[0-9]*/ $(PACKAGE)*.tar* *.build *.buildinfo *.dsc 51 | 52 | .PHONY: upload 53 | upload: UPLOAD_DIST ?= $(DEB_DISTRIBUTION) 54 | upload: $(DEBS) 55 | tar cf - $(DEBS)|ssh -X repoman@repo.proxmox.com -- upload --product pve --dist $(UPLOAD_DIST) 56 | -------------------------------------------------------------------------------- /src/test/zones/evpn/multipath_relax/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | bgp bestpath as-path multipath-relax 24 | neighbor BGP peer-group 25 | neighbor BGP remote-as 65000 26 | neighbor BGP bfd 27 | neighbor 192.168.0.1 peer-group BGP 28 | neighbor 192.168.0.2 peer-group BGP 29 | neighbor 192.168.0.3 peer-group BGP 30 | ! 31 | address-family ipv4 unicast 32 | neighbor BGP activate 33 | neighbor BGP soft-reconfiguration inbound 34 | exit-address-family 35 | ! 36 | address-family l2vpn evpn 37 | neighbor VTEP activate 38 | neighbor VTEP route-map MAP_VTEP_IN in 39 | neighbor VTEP route-map MAP_VTEP_OUT out 40 | advertise-all-vni 41 | exit-address-family 42 | exit 43 | ! 44 | router bgp 65000 vrf vrf_myzone 45 | bgp router-id 192.168.0.1 46 | no bgp hard-administrative-reset 47 | no bgp graceful-restart notification 48 | exit 49 | ! 50 | route-map MAP_VTEP_IN permit 1 51 | exit 52 | ! 53 | route-map MAP_VTEP_OUT permit 1 54 | exit 55 | ! 56 | line vty 57 | ! -------------------------------------------------------------------------------- /src/test/zones/qinq/ovs/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto ln_myzone 4 | iface ln_myzone 5 | link-type veth 6 | veth-peer-name pr_myzone 7 | 8 | auto ln_myzone2 9 | iface ln_myzone2 10 | link-type veth 11 | veth-peer-name pr_myzone2 12 | 13 | auto myvnet 14 | iface myvnet 15 | bridge_ports z_myzone.100 16 | bridge_stp off 17 | bridge_fd 0 18 | 19 | auto myvnet2 20 | iface myvnet2 21 | bridge_ports z_myzone.101 22 | bridge_stp off 23 | bridge_fd 0 24 | 25 | auto myvnet3 26 | iface myvnet3 27 | bridge_ports z_myzone2.100 28 | bridge_stp off 29 | bridge_fd 0 30 | 31 | auto pr_myzone 32 | iface pr_myzone 33 | link-type veth 34 | veth-peer-name ln_myzone 35 | 36 | auto pr_myzone2 37 | iface pr_myzone2 38 | link-type veth 39 | veth-peer-name ln_myzone2 40 | 41 | auto sv_myzone 42 | iface sv_myzone 43 | ovs_type OVSIntPort 44 | ovs_bridge vmbr0 45 | ovs_options vlan_mode=dot1q-tunnel tag=10 other_config:qinq-ethtype=802.1q 46 | 47 | auto sv_myzone2 48 | iface sv_myzone2 49 | ovs_type OVSIntPort 50 | ovs_bridge vmbr0 51 | ovs_options vlan_mode=dot1q-tunnel tag=20 other_config:qinq-ethtype=802.1q 52 | 53 | auto vmbr0 54 | iface vmbr0 55 | ovs_ports sv_myzone sv_myzone2 56 | 57 | auto z_myzone 58 | iface z_myzone 59 | bridge-stp off 60 | bridge-ports sv_myzone ln_myzone 61 | bridge-fd 0 62 | bridge-vlan-aware yes 63 | bridge-vids 2-4094 64 | 65 | auto z_myzone2 66 | iface z_myzone2 67 | bridge-stp off 68 | bridge-ports sv_myzone2 ln_myzone2 69 | bridge-fd 0 70 | bridge-vlan-aware yes 71 | bridge-vids 2-4094 72 | -------------------------------------------------------------------------------- /src/PVE/Network/SDN/Dhcp/Plugin.pm: -------------------------------------------------------------------------------- 1 | package PVE::Network::SDN::Dhcp::Plugin; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use PVE::Cluster; 7 | use PVE::JSONSchema qw(get_standard_option); 8 | 9 | use base qw(PVE::SectionConfig); 10 | 11 | my $defaultData = { 12 | propertyList => { 13 | type => { 14 | description => "Plugin type.", 15 | format => 'pve-configid', 16 | type => 'string', 17 | }, 18 | }, 19 | }; 20 | 21 | sub private { 22 | return $defaultData; 23 | } 24 | 25 | sub add_ip_mapping { 26 | my ($class, $dhcpid, $macdb, $mac, $ip4, $ip6) = @_; 27 | die 'implement in sub class'; 28 | } 29 | 30 | sub configure_range { 31 | my ($class, $config, $dhcpid, $vnetid, $subnet_config, $range_config) = @_; 32 | die 'implement in sub class'; 33 | } 34 | 35 | sub configure_subnet { 36 | my ($class, $config, $dhcpid, $vnetid, $subnet_config) = @_; 37 | die 'implement in sub class'; 38 | } 39 | 40 | sub configure_vnet { 41 | my ($class, $config, $dhcpid, $vnetid, $vnet_config) = @_; 42 | die 'implement in sub class'; 43 | } 44 | 45 | sub before_configure { 46 | my ($class, $dhcpid, $zone_config) = @_; 47 | die 'implement in sub class'; 48 | } 49 | 50 | sub after_configure { 51 | my ($class, $dhcpid, $noerr) = @_; 52 | die 'implement in sub class'; 53 | } 54 | 55 | sub before_regenerate { 56 | my ($class, $noerr) = @_; 57 | die 'implement in sub class'; 58 | } 59 | 60 | sub after_regenerate { 61 | my ($class) = @_; 62 | die 'implement in sub class'; 63 | } 64 | 65 | 1; 66 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ospf_fabric/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_evpn 9 | vni 100 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 172.20.30.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor VTEP update-source dummy_test 22 | neighbor 172.20.30.2 peer-group VTEP 23 | neighbor 172.20.30.3 peer-group VTEP 24 | ! 25 | address-family l2vpn evpn 26 | neighbor VTEP activate 27 | neighbor VTEP route-map MAP_VTEP_IN in 28 | neighbor VTEP route-map MAP_VTEP_OUT out 29 | advertise-all-vni 30 | exit-address-family 31 | exit 32 | ! 33 | router bgp 65000 vrf vrf_evpn 34 | bgp router-id 172.20.30.1 35 | no bgp hard-administrative-reset 36 | no bgp graceful-restart notification 37 | exit 38 | ! 39 | route-map MAP_VTEP_IN permit 1 40 | exit 41 | ! 42 | route-map MAP_VTEP_OUT permit 1 43 | exit 44 | router ospf 45 | ospf router-id 172.20.30.1 46 | exit 47 | ! 48 | interface dummy_test 49 | ip ospf area 0 50 | ip ospf passive 51 | exit 52 | ! 53 | interface ens19 54 | ip ospf area 0 55 | exit 56 | ! 57 | access-list pve_ospf_test_ips permit 172.20.30.0/24 58 | ! 59 | route-map pve_ospf permit 100 60 | match ip address pve_ospf_test_ips 61 | set src 172.20.30.1 62 | exit 63 | ! 64 | ip protocol ospf route-map pve_ospf 65 | ! 66 | ! 67 | line vty 68 | ! -------------------------------------------------------------------------------- /src/test/zones/simple/hetzner/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { type => "vnet", zone => "myzone" }, 6 | myvnet2 => { type => "vnet", zone => "myzone" }, 7 | }, 8 | }, 9 | zones => { 10 | ids => { myzone => { ipam => "pve", type => "simple" } }, 11 | }, 12 | 13 | subnets => { 14 | ids => { 15 | 'myzone-144.76.100.64-29' => { 16 | 'type' => 'subnet', 17 | 'vnet' => 'myvnet', 18 | 'gateway' => '144.76.100.65', 19 | }, 20 | 'myzone-144.76.200.65-32' => { 21 | 'type' => 'subnet', 22 | 'vnet' => 'myvnet2', 23 | 'gateway' => '144.76.0.1', 24 | }, 25 | 'myzone-144.76.200.66-32' => { 26 | 'type' => 'subnet', 27 | 'vnet' => 'myvnet2', 28 | 'gateway' => '144.76.0.1', 29 | }, 30 | } 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/test/zones/evpn/ebgp/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65001 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as external 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | neighbor BGP peer-group 24 | neighbor BGP remote-as external 25 | neighbor BGP bfd 26 | neighbor BGP ebgp-multihop 3 27 | neighbor 192.168.0.252 peer-group BGP 28 | neighbor 192.168.0.253 peer-group BGP 29 | ! 30 | address-family ipv4 unicast 31 | neighbor BGP activate 32 | neighbor BGP soft-reconfiguration inbound 33 | exit-address-family 34 | ! 35 | address-family l2vpn evpn 36 | neighbor VTEP activate 37 | neighbor VTEP route-map MAP_VTEP_IN in 38 | neighbor VTEP route-map MAP_VTEP_OUT out 39 | advertise-all-vni 40 | autort as 65000 41 | exit-address-family 42 | exit 43 | ! 44 | router bgp 65001 vrf vrf_myzone 45 | bgp router-id 192.168.0.1 46 | no bgp hard-administrative-reset 47 | no bgp graceful-restart notification 48 | ! 49 | address-family l2vpn evpn 50 | route-target import 65000:1000 51 | route-target export 65000:1000 52 | exit-address-family 53 | exit 54 | ! 55 | route-map MAP_VTEP_IN permit 1 56 | exit 57 | ! 58 | route-map MAP_VTEP_OUT permit 1 59 | exit 60 | ! 61 | line vty 62 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode_local_routing/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | ! 24 | address-family l2vpn evpn 25 | neighbor VTEP activate 26 | neighbor VTEP route-map MAP_VTEP_IN in 27 | neighbor VTEP route-map MAP_VTEP_OUT out 28 | advertise-all-vni 29 | exit-address-family 30 | exit 31 | ! 32 | router bgp 65000 vrf vrf_myzone 33 | bgp router-id 192.168.0.1 34 | no bgp hard-administrative-reset 35 | no bgp graceful-restart notification 36 | ! 37 | address-family l2vpn evpn 38 | default-originate ipv4 39 | default-originate ipv6 40 | exit-address-family 41 | exit 42 | ! 43 | ip prefix-list only_default seq 1 permit 0.0.0.0/0 44 | ! 45 | ipv6 prefix-list only_default_v6 seq 1 permit ::/0 46 | ! 47 | route-map MAP_VTEP_IN deny 1 48 | match ip address prefix-list only_default 49 | exit 50 | ! 51 | route-map MAP_VTEP_IN deny 2 52 | match ipv6 address prefix-list only_default_v6 53 | exit 54 | ! 55 | route-map MAP_VTEP_IN permit 3 56 | exit 57 | ! 58 | route-map MAP_VTEP_OUT permit 1 59 | exit 60 | ! 61 | ip route 10.0.0.0/24 10.255.255.2 xvrf_myzone 62 | ! 63 | line vty 64 | ! -------------------------------------------------------------------------------- /src/PVE/API2/Network/SDN/Nodes/Status.pm: -------------------------------------------------------------------------------- 1 | package PVE::API2::Network::SDN::Nodes::Status; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use PVE::API2::Network::SDN::Nodes::Fabrics; 7 | use PVE::API2::Network::SDN::Nodes::Zones; 8 | use PVE::API2::Network::SDN::Nodes::Vnets; 9 | 10 | use PVE::JSONSchema qw(get_standard_option); 11 | 12 | use PVE::RESTHandler; 13 | use base qw(PVE::RESTHandler); 14 | 15 | __PACKAGE__->register_method({ 16 | subclass => "PVE::API2::Network::SDN::Nodes::Fabrics", 17 | path => 'fabrics', 18 | }); 19 | 20 | __PACKAGE__->register_method({ 21 | subclass => "PVE::API2::Network::SDN::Nodes::Zones", 22 | path => 'zones', 23 | }); 24 | 25 | __PACKAGE__->register_method({ 26 | subclass => "PVE::API2::Network::SDN::Nodes::Vnets", 27 | path => 'vnets', 28 | }); 29 | 30 | __PACKAGE__->register_method({ 31 | name => 'sdnindex', 32 | path => '', 33 | method => 'GET', 34 | permissions => { user => 'all' }, 35 | description => "SDN index.", 36 | proxyto => 'node', 37 | parameters => { 38 | additionalProperties => 0, 39 | properties => { 40 | node => get_standard_option('pve-node'), 41 | }, 42 | }, 43 | returns => { 44 | type => 'array', 45 | items => { 46 | type => "object", 47 | properties => {}, 48 | }, 49 | links => [{ rel => 'child', href => "{name}" }], 50 | }, 51 | code => sub { 52 | my ($param) = @_; 53 | 54 | my $result = [ 55 | { name => 'fabrics' }, { name => 'vnets' }, { name => 'zones' }, 56 | ]; 57 | return $result; 58 | }, 59 | }); 60 | 61 | 1; 62 | -------------------------------------------------------------------------------- /src/test/zones/evpn/openfabric_fabric/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_evpn 9 | vni 100 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 172.20.3.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor VTEP update-source dummy_test 22 | neighbor 172.20.3.2 peer-group VTEP 23 | neighbor 172.20.3.3 peer-group VTEP 24 | ! 25 | address-family l2vpn evpn 26 | neighbor VTEP activate 27 | neighbor VTEP route-map MAP_VTEP_IN in 28 | neighbor VTEP route-map MAP_VTEP_OUT out 29 | advertise-all-vni 30 | exit-address-family 31 | exit 32 | ! 33 | router bgp 65000 vrf vrf_evpn 34 | bgp router-id 172.20.3.1 35 | no bgp hard-administrative-reset 36 | no bgp graceful-restart notification 37 | exit 38 | ! 39 | route-map MAP_VTEP_IN permit 1 40 | exit 41 | ! 42 | route-map MAP_VTEP_OUT permit 1 43 | exit 44 | router openfabric test 45 | net 49.0001.1720.2000.3001.00 46 | exit 47 | ! 48 | interface dummy_test 49 | ip router openfabric test 50 | openfabric passive 51 | exit 52 | ! 53 | interface ens20 54 | ip router openfabric test 55 | openfabric hello-interval 1 56 | exit 57 | ! 58 | interface ens21 59 | ip router openfabric test 60 | openfabric hello-interval 1 61 | exit 62 | ! 63 | access-list pve_openfabric_test_ips permit 172.20.3.0/24 64 | ! 65 | route-map pve_openfabric permit 100 66 | match ip address pve_openfabric_test_ips 67 | set src 172.20.3.1 68 | exit 69 | ! 70 | ip protocol openfabric route-map pve_openfabric 71 | ! 72 | ! 73 | line vty 74 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/multiplezones/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | bridge_ports vxlan_myvnet 7 | bridge_stp off 8 | bridge_fd 0 9 | mtu 1450 10 | ip-forward on 11 | arp-accept on 12 | vrf vrf_myzone 13 | 14 | auto myvnet2 15 | iface myvnet2 16 | address 172.16.0.1/24 17 | bridge_ports vxlan_myvnet2 18 | bridge_stp off 19 | bridge_fd 0 20 | mtu 1450 21 | ip-forward on 22 | arp-accept on 23 | vrf vrf_myzone2 24 | 25 | auto vrf_myzone 26 | iface vrf_myzone 27 | vrf-table auto 28 | post-up ip route add vrf vrf_myzone unreachable default metric 4278198272 29 | 30 | auto vrf_myzone2 31 | iface vrf_myzone2 32 | vrf-table auto 33 | post-up ip route add vrf vrf_myzone2 unreachable default metric 4278198272 34 | 35 | auto vrfbr_myzone 36 | iface vrfbr_myzone 37 | bridge-ports vrfvx_myzone 38 | bridge_stp off 39 | bridge_fd 0 40 | mtu 1450 41 | vrf vrf_myzone 42 | 43 | auto vrfbr_myzone2 44 | iface vrfbr_myzone2 45 | bridge-ports vrfvx_myzone2 46 | bridge_stp off 47 | bridge_fd 0 48 | mtu 1450 49 | vrf vrf_myzone2 50 | 51 | auto vrfvx_myzone 52 | iface vrfvx_myzone 53 | vxlan-id 1000 54 | vxlan-local-tunnelip 192.168.0.1 55 | bridge-learning off 56 | bridge-arp-nd-suppress on 57 | mtu 1450 58 | 59 | auto vrfvx_myzone2 60 | iface vrfvx_myzone2 61 | vxlan-id 1001 62 | vxlan-local-tunnelip 192.168.0.1 63 | bridge-learning off 64 | bridge-arp-nd-suppress on 65 | mtu 1450 66 | 67 | auto vxlan_myvnet 68 | iface vxlan_myvnet 69 | vxlan-id 100 70 | vxlan-local-tunnelip 192.168.0.1 71 | bridge-learning off 72 | bridge-arp-nd-suppress on 73 | mtu 1450 74 | 75 | auto vxlan_myvnet2 76 | iface vxlan_myvnet2 77 | vxlan-id 101 78 | vxlan-local-tunnelip 192.168.0.1 79 | bridge-learning off 80 | bridge-arp-nd-suppress on 81 | mtu 1450 82 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: libpve-network-perl 2 | Section: perl 3 | Priority: optional 4 | Maintainer: Proxmox Support Team 5 | Build-Depends: debhelper-compat (= 13), 6 | lintian, 7 | libfile-slurp-perl, 8 | libpve-common-perl (>= 9.1.1), 9 | libnet-subnet-perl, 10 | libpve-rs-perl (>= 0.11.1), 11 | libtest-mockmodule-perl, 12 | perl, 13 | pve-cluster (>= 9.0.1), 14 | pve-firewall (>= 5.1.0~), 15 | pve-doc-generator (>= 5.3-3), 16 | libpve-access-control (>= 9.0.1), 17 | Standards-Version: 4.6.1 18 | Homepage: https://www.proxmox.com 19 | 20 | Package: libpve-network-perl 21 | Architecture: all 22 | Depends: libpve-common-perl (>= 9.1.1), 23 | pve-cluster (>= 8.0.10), 24 | libio-socket-ssl-perl, 25 | ifupdown2, 26 | libnet-subnet-perl, 27 | libnet-ip-perl, 28 | libnetaddr-ip-perl, 29 | libpve-rs-perl (>= 0.11.1), 30 | libuuid-perl, 31 | ${misc:Depends}, 32 | ${perl:Depends}, 33 | Recommends: frr-pythontools (>= 10.3.1-1+pve2~), 34 | Suggests: dnsmasq, 35 | Description: Proxmox VE's SDN (Software Defined Network) stack 36 | This package contains the perl side of the Software Defined Network 37 | implementation for Proxmox VE. 38 | 39 | Package: libpve-network-api-perl 40 | Architecture: all 41 | Depends: libpve-common-perl (>= 9.0.2), 42 | pve-firewall (>= 5.1.0~), 43 | pve-cluster (>= 9.0.1), 44 | libpve-network-perl (= ${binary:Version}), 45 | ${misc:Depends}, 46 | ${perl:Depends}, 47 | Breaks: libpve-network-perl (<< 0.9.9~), 48 | Replaces: libpve-network-perl (<< 0.9.9~), 49 | Description: API endpoints for Proxmox VE's SDN stack 50 | This package contains the API endpoints for the Software Defined Network of 51 | Proxmox VE. 52 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | ! 24 | address-family ipv4 unicast 25 | import vrf vrf_myzone 26 | exit-address-family 27 | ! 28 | address-family ipv6 unicast 29 | import vrf vrf_myzone 30 | exit-address-family 31 | ! 32 | address-family l2vpn evpn 33 | neighbor VTEP activate 34 | neighbor VTEP route-map MAP_VTEP_IN in 35 | neighbor VTEP route-map MAP_VTEP_OUT out 36 | advertise-all-vni 37 | exit-address-family 38 | exit 39 | ! 40 | router bgp 65000 vrf vrf_myzone 41 | bgp router-id 192.168.0.1 42 | no bgp hard-administrative-reset 43 | no bgp graceful-restart notification 44 | ! 45 | address-family ipv4 unicast 46 | redistribute connected 47 | exit-address-family 48 | ! 49 | address-family ipv6 unicast 50 | redistribute connected 51 | exit-address-family 52 | ! 53 | address-family l2vpn evpn 54 | default-originate ipv4 55 | default-originate ipv6 56 | exit-address-family 57 | exit 58 | ! 59 | ip prefix-list only_default seq 1 permit 0.0.0.0/0 60 | ! 61 | ipv6 prefix-list only_default_v6 seq 1 permit ::/0 62 | ! 63 | route-map MAP_VTEP_IN deny 1 64 | match ip address prefix-list only_default 65 | exit 66 | ! 67 | route-map MAP_VTEP_IN deny 2 68 | match ipv6 address prefix-list only_default_v6 69 | exit 70 | ! 71 | route-map MAP_VTEP_IN permit 3 72 | exit 73 | ! 74 | route-map MAP_VTEP_OUT permit 1 75 | exit 76 | ! 77 | line vty 78 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode_snat/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | ! 24 | address-family ipv4 unicast 25 | import vrf vrf_myzone 26 | exit-address-family 27 | ! 28 | address-family ipv6 unicast 29 | import vrf vrf_myzone 30 | exit-address-family 31 | ! 32 | address-family l2vpn evpn 33 | neighbor VTEP activate 34 | neighbor VTEP route-map MAP_VTEP_IN in 35 | neighbor VTEP route-map MAP_VTEP_OUT out 36 | advertise-all-vni 37 | exit-address-family 38 | exit 39 | ! 40 | router bgp 65000 vrf vrf_myzone 41 | bgp router-id 192.168.0.1 42 | no bgp hard-administrative-reset 43 | no bgp graceful-restart notification 44 | ! 45 | address-family ipv4 unicast 46 | redistribute connected 47 | exit-address-family 48 | ! 49 | address-family ipv6 unicast 50 | redistribute connected 51 | exit-address-family 52 | ! 53 | address-family l2vpn evpn 54 | default-originate ipv4 55 | default-originate ipv6 56 | exit-address-family 57 | exit 58 | ! 59 | ip prefix-list only_default seq 1 permit 0.0.0.0/0 60 | ! 61 | ipv6 prefix-list only_default_v6 seq 1 permit ::/0 62 | ! 63 | route-map MAP_VTEP_IN deny 1 64 | match ip address prefix-list only_default 65 | exit 66 | ! 67 | route-map MAP_VTEP_IN deny 2 68 | match ipv6 address prefix-list only_default_v6 69 | exit 70 | ! 71 | route-map MAP_VTEP_IN permit 3 72 | exit 73 | ! 74 | route-map MAP_VTEP_OUT permit 1 75 | exit 76 | ! 77 | line vty 78 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/ebgp_loopback/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65001 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as external 20 | neighbor VTEP bfd 21 | neighbor VTEP ebgp-multihop 10 22 | neighbor VTEP update-source dummy1 23 | neighbor 192.168.0.2 peer-group VTEP 24 | neighbor 192.168.0.3 peer-group VTEP 25 | bgp disable-ebgp-connected-route-check 26 | neighbor BGP peer-group 27 | neighbor BGP remote-as external 28 | neighbor BGP bfd 29 | neighbor 172.16.0.254 peer-group BGP 30 | neighbor 172.17.0.254 peer-group BGP 31 | ! 32 | address-family ipv4 unicast 33 | network 192.168.0.1/32 34 | neighbor BGP activate 35 | neighbor BGP soft-reconfiguration inbound 36 | exit-address-family 37 | ! 38 | address-family l2vpn evpn 39 | neighbor VTEP activate 40 | neighbor VTEP route-map MAP_VTEP_IN in 41 | neighbor VTEP route-map MAP_VTEP_OUT out 42 | advertise-all-vni 43 | autort as 65000 44 | exit-address-family 45 | exit 46 | ! 47 | router bgp 65001 vrf vrf_myzone 48 | bgp router-id 192.168.0.1 49 | no bgp hard-administrative-reset 50 | no bgp graceful-restart notification 51 | ! 52 | address-family l2vpn evpn 53 | route-target import 65000:1000 54 | route-target export 65000:1000 55 | exit-address-family 56 | exit 57 | ! 58 | ip prefix-list loopbacks_ips seq 10 permit 0.0.0.0/0 le 32 59 | ! 60 | route-map MAP_VTEP_IN permit 1 61 | exit 62 | ! 63 | route-map MAP_VTEP_OUT permit 1 64 | exit 65 | ! 66 | route-map correct_src permit 1 67 | match ip address prefix-list loopbacks_ips 68 | set src 192.168.0.1 69 | exit 70 | ! 71 | ip protocol bgp route-map correct_src 72 | ! 73 | line vty 74 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode_primary/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | exit-vrf 11 | ! 12 | router bgp 65000 13 | bgp router-id 192.168.0.1 14 | no bgp hard-administrative-reset 15 | no bgp default ipv4-unicast 16 | coalesce-time 1000 17 | no bgp graceful-restart notification 18 | neighbor VTEP peer-group 19 | neighbor VTEP remote-as 65000 20 | neighbor VTEP bfd 21 | neighbor 192.168.0.2 peer-group VTEP 22 | neighbor 192.168.0.3 peer-group VTEP 23 | ! 24 | address-family ipv4 unicast 25 | import vrf vrf_myzone 26 | exit-address-family 27 | ! 28 | address-family ipv6 unicast 29 | import vrf vrf_myzone 30 | exit-address-family 31 | ! 32 | address-family l2vpn evpn 33 | neighbor VTEP activate 34 | neighbor VTEP route-map MAP_VTEP_IN in 35 | neighbor VTEP route-map MAP_VTEP_OUT out 36 | advertise-all-vni 37 | exit-address-family 38 | exit 39 | ! 40 | router bgp 65000 vrf vrf_myzone 41 | bgp router-id 192.168.0.1 42 | no bgp hard-administrative-reset 43 | no bgp graceful-restart notification 44 | ! 45 | address-family ipv4 unicast 46 | redistribute connected 47 | exit-address-family 48 | ! 49 | address-family ipv6 unicast 50 | redistribute connected 51 | exit-address-family 52 | ! 53 | address-family l2vpn evpn 54 | default-originate ipv4 55 | default-originate ipv6 56 | exit-address-family 57 | exit 58 | ! 59 | ip prefix-list only_default seq 1 permit 0.0.0.0/0 60 | ! 61 | ipv6 prefix-list only_default_v6 seq 1 permit ::/0 62 | ! 63 | route-map MAP_VTEP_IN permit 1 64 | exit 65 | ! 66 | route-map MAP_VTEP_OUT permit 1 67 | match ip address prefix-list only_default 68 | set metric 200 69 | exit 70 | ! 71 | route-map MAP_VTEP_OUT permit 2 72 | match ipv6 address prefix-list only_default_v6 73 | set metric 200 74 | exit 75 | ! 76 | route-map MAP_VTEP_OUT permit 3 77 | exit 78 | ! 79 | line vty 80 | ! -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnode_snat/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | post-up iptables -t nat -A POSTROUTING -s '10.0.0.0/24' -o vmbr0 -j SNAT --to-source 192.168.0.1 7 | post-down iptables -t nat -D POSTROUTING -s '10.0.0.0/24' -o vmbr0 -j SNAT --to-source 192.168.0.1 8 | post-up iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1 9 | post-down iptables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1 10 | bridge_ports vxlan_myvnet 11 | bridge_stp off 12 | bridge_fd 0 13 | mtu 1450 14 | ip-forward on 15 | arp-accept on 16 | vrf vrf_myzone 17 | 18 | auto myvnet2 19 | iface myvnet2 20 | address 2a08:2142:302:3::1/64 21 | post-up ip6tables -t nat -A POSTROUTING -s '2a08:2142:302:3::/64' -o vmbr0 -j SNAT --to-source 192.168.0.1 22 | post-down ip6tables -t nat -D POSTROUTING -s '2a08:2142:302:3::/64' -o vmbr0 -j SNAT --to-source 192.168.0.1 23 | post-up ip6tables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1 24 | post-down ip6tables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1 25 | bridge_ports vxlan_myvnet2 26 | bridge_stp off 27 | bridge_fd 0 28 | mtu 1450 29 | ip6-forward on 30 | arp-accept on 31 | vrf vrf_myzone 32 | 33 | auto vrf_myzone 34 | iface vrf_myzone 35 | vrf-table auto 36 | post-up ip route del vrf vrf_myzone unreachable default metric 4278198272 37 | 38 | auto vrfbr_myzone 39 | iface vrfbr_myzone 40 | bridge-ports vrfvx_myzone 41 | bridge_stp off 42 | bridge_fd 0 43 | mtu 1450 44 | vrf vrf_myzone 45 | 46 | auto vrfvx_myzone 47 | iface vrfvx_myzone 48 | vxlan-id 1000 49 | vxlan-local-tunnelip 192.168.0.1 50 | bridge-learning off 51 | bridge-arp-nd-suppress on 52 | mtu 1450 53 | 54 | auto vxlan_myvnet 55 | iface vxlan_myvnet 56 | vxlan-id 100 57 | vxlan-local-tunnelip 192.168.0.1 58 | bridge-learning off 59 | bridge-arp-nd-suppress on 60 | mtu 1450 61 | 62 | auto vxlan_myvnet2 63 | iface vxlan_myvnet2 64 | vxlan-id 200 65 | vxlan-local-tunnelip 192.168.0.1 66 | bridge-learning off 67 | bridge-arp-nd-suppress on 68 | mtu 1450 69 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnodenullroute/expected_sdn_interfaces: -------------------------------------------------------------------------------- 1 | #version:1 2 | 3 | auto myvnet 4 | iface myvnet 5 | address 10.0.0.1/24 6 | address 192.168.0.1/24 7 | address 192.168.10.1/24 8 | address 2b0f:1480:4000:6000::1/64 9 | address 2b0f:1480:4000:8000::1/64 10 | address 2b0f:1480::1/64 11 | bridge_ports vxlan_myvnet 12 | bridge_stp off 13 | bridge_fd 0 14 | mtu 1450 15 | ip-forward on 16 | ip6-forward on 17 | arp-accept on 18 | vrf vrf_myzone 19 | 20 | auto myvnet2 21 | iface myvnet2 22 | address 10.0.0.1/24 23 | address 172.16.0.1/24 24 | address 172.16.3.1/24 25 | bridge_ports vxlan_myvnet2 26 | bridge_stp off 27 | bridge_fd 0 28 | mtu 1450 29 | ip-forward on 30 | arp-accept on 31 | vrf vrf_myzone2 32 | 33 | auto vrf_myzone 34 | iface vrf_myzone 35 | vrf-table auto 36 | post-up ip route del vrf vrf_myzone unreachable default metric 4278198272 37 | 38 | auto vrf_myzone2 39 | iface vrf_myzone2 40 | vrf-table auto 41 | post-up ip route del vrf vrf_myzone2 unreachable default metric 4278198272 42 | 43 | auto vrfbr_myzone 44 | iface vrfbr_myzone 45 | bridge-ports vrfvx_myzone 46 | bridge_stp off 47 | bridge_fd 0 48 | mtu 1450 49 | vrf vrf_myzone 50 | 51 | auto vrfbr_myzone2 52 | iface vrfbr_myzone2 53 | bridge-ports vrfvx_myzone2 54 | bridge_stp off 55 | bridge_fd 0 56 | mtu 1450 57 | vrf vrf_myzone2 58 | 59 | auto vrfvx_myzone 60 | iface vrfvx_myzone 61 | vxlan-id 1000 62 | vxlan-local-tunnelip 192.168.0.1 63 | bridge-learning off 64 | bridge-arp-nd-suppress on 65 | mtu 1450 66 | 67 | auto vrfvx_myzone2 68 | iface vrfvx_myzone2 69 | vxlan-id 1001 70 | vxlan-local-tunnelip 192.168.0.1 71 | bridge-learning off 72 | bridge-arp-nd-suppress on 73 | mtu 1450 74 | 75 | auto vxlan_myvnet 76 | iface vxlan_myvnet 77 | vxlan-id 100 78 | vxlan-local-tunnelip 192.168.0.1 79 | bridge-learning off 80 | bridge-arp-nd-suppress on 81 | mtu 1450 82 | 83 | auto vxlan_myvnet2 84 | iface vxlan_myvnet2 85 | vxlan-id 101 86 | vxlan-local-tunnelip 192.168.0.1 87 | bridge-learning off 88 | bridge-arp-nd-suppress on 89 | mtu 1450 90 | -------------------------------------------------------------------------------- /src/PVE/API2/Network/SDN/Nodes/Zones.pm: -------------------------------------------------------------------------------- 1 | package PVE::API2::Network::SDN::Nodes::Zones; 2 | 3 | use PVE::API2::Network::SDN::Nodes::Zone; 4 | use PVE::INotify; 5 | use PVE::JSONSchema qw(get_standard_option); 6 | use PVE::Network::SDN; 7 | use PVE::RPCEnvironment; 8 | 9 | use PVE::RESTHandler; 10 | use base qw(PVE::RESTHandler); 11 | 12 | __PACKAGE__->register_method({ 13 | subclass => "PVE::API2::Network::SDN::Nodes::Zone", 14 | path => '{zone}', 15 | }); 16 | 17 | __PACKAGE__->register_method({ 18 | name => 'index', 19 | path => '', 20 | method => 'GET', 21 | description => "Get status for all zones.", 22 | permissions => { 23 | description => "Only list entries where you have 'SDN.Audit'", 24 | user => 'all', 25 | }, 26 | protected => 1, 27 | proxyto => 'node', 28 | parameters => { 29 | additionalProperties => 0, 30 | properties => { 31 | node => get_standard_option('pve-node'), 32 | }, 33 | }, 34 | returns => { 35 | type => 'array', 36 | items => { 37 | type => "object", 38 | properties => { 39 | zone => get_standard_option('pve-sdn-zone-id'), 40 | status => { 41 | description => "Status of zone", 42 | type => 'string', 43 | enum => ['available', 'pending', 'error'], 44 | }, 45 | }, 46 | }, 47 | links => [{ rel => 'child', href => "{zone}" }], 48 | }, 49 | code => sub { 50 | my ($param) = @_; 51 | 52 | my $rpcenv = PVE::RPCEnvironment::get(); 53 | my $authuser = $rpcenv->get_user(); 54 | 55 | my $localnode = PVE::INotify::nodename(); 56 | 57 | my $res = []; 58 | 59 | my ($zone_status, $vnet_status) = PVE::Network::SDN::Zones::status(); 60 | 61 | foreach my $id (sort keys %{$zone_status}) { 62 | my $item->{zone} = $id; 63 | $item->{status} = $zone_status->{$id}->{'status'}; 64 | push @$res, $item; 65 | } 66 | 67 | return $res; 68 | }, 69 | }); 70 | 71 | 1; 72 | -------------------------------------------------------------------------------- /src/PVE/Network/SDN/Zones/FaucetPlugin.pm: -------------------------------------------------------------------------------- 1 | package PVE::Network::SDN::Zones::FaucetPlugin; 2 | 3 | use strict; 4 | use warnings; 5 | use PVE::Network::SDN::Zones::VlanPlugin; 6 | 7 | use base('PVE::Network::SDN::Zones::VlanPlugin'); 8 | 9 | sub type { 10 | return 'faucet'; 11 | } 12 | 13 | sub properties { 14 | return { 15 | 'dp-id' => { 16 | type => 'integer', 17 | description => 'Faucet dataplane id', 18 | }, 19 | }; 20 | } 21 | 22 | sub options { 23 | 24 | return { 25 | nodes => { optional => 1 }, 26 | 'dp-id' => { optional => 0 }, 27 | # 'uplink-id' => { optional => 0 }, 28 | 'controller' => { optional => 0 }, 29 | dns => { optional => 1 }, 30 | reversedns => { optional => 1 }, 31 | dnszone => { optional => 1 }, 32 | ipam => { optional => 1 }, 33 | }; 34 | } 35 | 36 | # Plugin implementation 37 | sub generate_sdn_config { 38 | my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $controller, $config) = @_; 39 | 40 | my $mtu = $vnet->{mtu}; 41 | my $uplink = $plugin_config->{'uplink-id'}; 42 | my $dpid = $plugin_config->{'dp-id'}; 43 | my $dphex = printf("%x", $dpid); #fixme :should be 16characters hex 44 | 45 | my $iface = $uplinks->{$uplink}->{name}; 46 | $iface = "uplink${uplink}" if !$iface; 47 | 48 | #tagged interface 49 | my @iface_config = (); 50 | push @iface_config, "ovs_type OVSPort"; 51 | push @iface_config, "ovs_bridge $zoneid"; 52 | push @iface_config, "ovs_mtu $mtu" if $mtu; 53 | push(@{ $config->{$iface} }, @iface_config) if !$config->{$iface}; 54 | 55 | #vnet bridge 56 | @iface_config = (); 57 | push @iface_config, "ovs_port $iface"; 58 | push @iface_config, "ovs_type OVSBridge"; 59 | push @iface_config, "ovs_mtu $mtu" if $mtu; 60 | 61 | push @iface_config, "ovs_extra set bridge $zoneid other-config:datapath-id=$dphex"; 62 | push @iface_config, "ovs_extra set bridge $zoneid other-config:disable-in-band=true"; 63 | push @iface_config, "ovs_extra set bridge $zoneid fail_mode=secure"; 64 | push @iface_config, "ovs_extra set-controller $vnetid tcp:127.0.0.1:6653"; 65 | 66 | push(@{ $config->{$zoneid} }, @iface_config) if !$config->{$zoneid}; 67 | 68 | return $config; 69 | } 70 | 71 | 1; 72 | 73 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnodenullroute/sdn_config: -------------------------------------------------------------------------------- 1 | { 2 | version => 1, 3 | vnets => { 4 | ids => { 5 | myvnet => { tag => "100", type => "vnet", zone => "myzone" }, 6 | myvnet2 => { tag => "101", type => "vnet", zone => "myzone2" }, 7 | }, 8 | }, 9 | 10 | zones => { 11 | ids => { 12 | myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, exitnodes => { 'localhost' => 1 } }, 13 | myzone2 => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1001, exitnodes => { 'localhost' => 1 } }, 14 | } 15 | }, 16 | controllers => { 17 | ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } }, 18 | }, 19 | 20 | subnets => { 21 | ids => { 22 | 'myzone-192.168.10.1-24' => { 23 | 'type' => 'subnet', 24 | 'vnet' => 'myvnet', 25 | 'gateway' => '192.168.10.1', 26 | }, 27 | 'myzone-192.168.0.1-24' => { 28 | 'type' => 'subnet', 29 | 'vnet' => 'myvnet', 30 | 'gateway' => '192.168.0.1', 31 | }, 32 | 'myzone-10.0.0.0-24' => { 33 | 'type' => 'subnet', 34 | 'vnet' => 'myvnet', 35 | 'gateway' => '10.0.0.1', 36 | }, 37 | 'myzone2-10.0.0.0-24' => { 38 | 'type' => 'subnet', 39 | 'vnet' => 'myvnet2', 40 | 'gateway' => '10.0.0.1', 41 | }, 42 | 'myzone-2b0f:1480:4000:8000::-64' => { 43 | 'type' => 'subnet', 44 | 'vnet' => 'myvnet', 45 | 'gateway' => '2b0f:1480:4000:8000::1', 46 | }, 47 | 'myzone-2b0f:1480::-64' => { 48 | 'type' => 'subnet', 49 | 'vnet' => 'myvnet', 50 | 'gateway' => '2b0f:1480::1', 51 | }, 52 | 'myzone2-172.16.0.0-24' => { 53 | 'type' => 'subnet', 54 | 'vnet' => 'myvnet2', 55 | 'gateway' => '172.16.0.1', 56 | }, 57 | 'myzone2-172.16.3.0-24' => { 58 | 'type' => 'subnet', 59 | 'vnet' => 'myvnet2', 60 | 'gateway' => '172.16.3.1', 61 | }, 62 | 'myzone-2b0f:1480:4000:6000::-64' => { 63 | 'type' => 'subnet', 64 | 'vnet' => 'myvnet', 65 | 'gateway' => '2b0f:1480:4000:6000::1', 66 | }, 67 | 'myzone2-172.16.1.0-24' => { 68 | 'type' => 'subnet', 69 | 'vnet' => 'myvnet2', 70 | 'gateway' => '172.16.0.1', 71 | }, 72 | } 73 | } 74 | 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/PVE/Network/SDN/Controllers/FaucetPlugin.pm: -------------------------------------------------------------------------------- 1 | package PVE::Network::SDN::Controllers::FaucetPlugin; 2 | 3 | use strict; 4 | use warnings; 5 | use PVE::Network::SDN::Controllers::Plugin; 6 | use PVE::Tools; 7 | use PVE::INotify; 8 | use PVE::JSONSchema qw(get_standard_option); 9 | use CPAN::Meta::YAML; 10 | use Encode; 11 | 12 | use base('PVE::Network::SDN::Controllers::Plugin'); 13 | 14 | sub type { 15 | return 'faucet'; 16 | } 17 | 18 | sub properties { 19 | return {}; 20 | } 21 | 22 | # Plugin implementation 23 | sub generate_controller_config { 24 | my ($class, $plugin_config, $controller_cfg, $id, $uplinks, $config) = @_; 25 | 26 | } 27 | 28 | sub generate_controller_zone_config { 29 | my ($class, $plugin_config, $controller, $controller_cfg, $id, $uplinks, $config) = @_; 30 | 31 | my $dpid = $plugin_config->{'dp-id'}; 32 | my $dphex = printf("%x", $dpid); 33 | 34 | my $zone_config = { 35 | dp_id => $dphex, 36 | hardware => "Open vSwitch", 37 | }; 38 | 39 | $config->{faucet}->{dps}->{$id} = $zone_config; 40 | 41 | } 42 | 43 | sub generate_controller_vnet_config { 44 | my ($class, $plugin_config, $controller, $zone, $zoneid, $vnetid, $config) = @_; 45 | 46 | my $mac = $plugin_config->{mac}; 47 | my $ipv4 = $plugin_config->{ipv4}; 48 | my $ipv6 = $plugin_config->{ipv6}; 49 | my $tag = $plugin_config->{tag}; 50 | my $alias = $plugin_config->{alias}; 51 | 52 | my @ips = (); 53 | push @ips, $ipv4 if $ipv4; 54 | push @ips, $ipv6 if $ipv6; 55 | 56 | my $vlan_config = { vid => $tag }; 57 | 58 | $vlan_config->{description} = $alias if $alias; 59 | $vlan_config->{faucet_mac} = $mac if $mac; 60 | $vlan_config->{faucet_vips} = \@ips if scalar @ips > 0; 61 | 62 | $config->{faucet}->{vlans}->{$vnetid} = $vlan_config; 63 | 64 | push(@{ $config->{faucet}->{routers}->{$zoneid}->{vlans} }, $vnetid); 65 | 66 | } 67 | 68 | sub write_controller_config { 69 | my ($class, $plugin_config, $config) = @_; 70 | 71 | my $rawconfig = encode('UTF-8', CPAN::Meta::YAML::Dump($config->{faucet})); 72 | 73 | return if !$rawconfig; 74 | return if !-d "/etc/faucet"; 75 | 76 | my $frr_config_file = "/etc/faucet/faucet.yaml"; 77 | 78 | my $writefh = IO::File->new($frr_config_file, ">"); 79 | print $writefh $rawconfig; 80 | $writefh->close(); 81 | } 82 | 83 | sub reload_controller { 84 | my ($class) = @_; 85 | 86 | my $conf_file = "/etc/faucet/faucet.yaml"; 87 | my $bin_path = "/usr/bin/faucet"; 88 | 89 | if (-e $conf_file && -e $bin_path) { 90 | PVE::Tools::run_command(['systemctl', 'reload', 'faucet']); 91 | } 92 | } 93 | 94 | 1; 95 | 96 | -------------------------------------------------------------------------------- /src/test/zones/evpn/exitnodenullroute/expected_controller_config: -------------------------------------------------------------------------------- 1 | frr version 10.4.1 2 | frr defaults datacenter 3 | hostname localhost 4 | log syslog informational 5 | service integrated-vtysh-config 6 | ! 7 | ! 8 | vrf vrf_myzone 9 | vni 1000 10 | ip route 10.0.0.0/24 null0 11 | ip route 172.16.0.0/24 null0 12 | ip route 172.16.1.0/24 null0 13 | ip route 172.16.3.0/24 null0 14 | exit-vrf 15 | ! 16 | vrf vrf_myzone2 17 | vni 1001 18 | ip route 10.0.0.0/24 null0 19 | ip route 192.168.0.1/24 null0 20 | ip route 192.168.10.1/24 null0 21 | ipv6 route 2b0f:1480::/64 null0 22 | ipv6 route 2b0f:1480:4000:6000::/64 null0 23 | ipv6 route 2b0f:1480:4000:8000::/64 null0 24 | exit-vrf 25 | ! 26 | router bgp 65000 27 | bgp router-id 192.168.0.1 28 | no bgp hard-administrative-reset 29 | no bgp default ipv4-unicast 30 | coalesce-time 1000 31 | no bgp graceful-restart notification 32 | neighbor VTEP peer-group 33 | neighbor VTEP remote-as 65000 34 | neighbor VTEP bfd 35 | neighbor 192.168.0.2 peer-group VTEP 36 | neighbor 192.168.0.3 peer-group VTEP 37 | ! 38 | address-family ipv4 unicast 39 | import vrf vrf_myzone 40 | import vrf vrf_myzone2 41 | exit-address-family 42 | ! 43 | address-family ipv6 unicast 44 | import vrf vrf_myzone 45 | import vrf vrf_myzone2 46 | exit-address-family 47 | ! 48 | address-family l2vpn evpn 49 | neighbor VTEP activate 50 | neighbor VTEP route-map MAP_VTEP_IN in 51 | neighbor VTEP route-map MAP_VTEP_OUT out 52 | advertise-all-vni 53 | exit-address-family 54 | exit 55 | ! 56 | router bgp 65000 vrf vrf_myzone 57 | bgp router-id 192.168.0.1 58 | no bgp hard-administrative-reset 59 | no bgp graceful-restart notification 60 | ! 61 | address-family ipv4 unicast 62 | redistribute connected 63 | exit-address-family 64 | ! 65 | address-family ipv6 unicast 66 | redistribute connected 67 | exit-address-family 68 | ! 69 | address-family l2vpn evpn 70 | default-originate ipv4 71 | default-originate ipv6 72 | exit-address-family 73 | exit 74 | ! 75 | router bgp 65000 vrf vrf_myzone2 76 | bgp router-id 192.168.0.1 77 | no bgp hard-administrative-reset 78 | no bgp graceful-restart notification 79 | ! 80 | address-family ipv4 unicast 81 | redistribute connected 82 | exit-address-family 83 | ! 84 | address-family ipv6 unicast 85 | redistribute connected 86 | exit-address-family 87 | ! 88 | address-family l2vpn evpn 89 | default-originate ipv4 90 | default-originate ipv6 91 | exit-address-family 92 | exit 93 | ! 94 | ip prefix-list only_default seq 1 permit 0.0.0.0/0 95 | ! 96 | ipv6 prefix-list only_default_v6 seq 1 permit ::/0 97 | ! 98 | route-map MAP_VTEP_IN deny 1 99 | match ip address prefix-list only_default 100 | exit 101 | ! 102 | route-map MAP_VTEP_IN deny 2 103 | match ipv6 address prefix-list only_default_v6 104 | exit 105 | ! 106 | route-map MAP_VTEP_IN deny 3 107 | match ip address prefix-list only_default 108 | exit 109 | ! 110 | route-map MAP_VTEP_IN deny 4 111 | match ipv6 address prefix-list only_default_v6 112 | exit 113 | ! 114 | route-map MAP_VTEP_IN permit 5 115 | exit 116 | ! 117 | route-map MAP_VTEP_OUT permit 1 118 | exit 119 | ! 120 | line vty 121 | ! -------------------------------------------------------------------------------- /src/PVE/Network/SDN/Dns/Plugin.pm: -------------------------------------------------------------------------------- 1 | package PVE::Network::SDN::Dns::Plugin; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use PVE::Tools qw(run_command); 7 | use PVE::JSONSchema; 8 | use PVE::Cluster; 9 | use HTTP::Request; 10 | use LWP::UserAgent; 11 | 12 | use PVE::JSONSchema qw(get_standard_option); 13 | use base qw(PVE::SectionConfig); 14 | 15 | PVE::Cluster::cfs_register_file( 16 | 'sdn/dns.cfg', 17 | sub { __PACKAGE__->parse_config(@_); }, 18 | sub { __PACKAGE__->write_config(@_); }, 19 | ); 20 | 21 | PVE::JSONSchema::register_standard_option( 22 | 'pve-sdn-dns-id', 23 | { 24 | description => "The SDN dns object identifier.", 25 | type => 'string', 26 | format => 'pve-sdn-dns-id', 27 | }, 28 | ); 29 | 30 | PVE::JSONSchema::register_format('pve-sdn-dns-id', \&parse_sdn_dns_id); 31 | 32 | sub parse_sdn_dns_id { 33 | my ($id, $noerr) = @_; 34 | 35 | if ($id !~ m/^[a-z][a-z0-9]*[a-z0-9]$/i) { 36 | return undef if $noerr; 37 | die "dns ID '$id' contains illegal characters\n"; 38 | } 39 | return $id; 40 | } 41 | 42 | my $defaultData = { 43 | 44 | propertyList => { 45 | type => { 46 | description => "Plugin type.", 47 | type => 'string', 48 | format => 'pve-configid', 49 | }, 50 | ttl => { type => 'integer', optional => 1 }, 51 | reversev6mask => { type => 'integer', optional => 1 }, 52 | dns => get_standard_option( 53 | 'pve-sdn-dns-id', 54 | { completion => \&PVE::Network::SDN::Dns::complete_sdn_dns }, 55 | ), 56 | fingerprint => get_standard_option('fingerprint-sha256', { optional => 1 }), 57 | }, 58 | }; 59 | 60 | sub private { 61 | return $defaultData; 62 | } 63 | 64 | sub parse_section_header { 65 | my ($class, $line) = @_; 66 | 67 | if ($line =~ m/^(\S+):\s*(\S+)\s*$/) { 68 | my ($type, $id) = (lc($1), $2); 69 | my $errmsg = undef; # set if you want to skip whole section 70 | eval { PVE::JSONSchema::pve_verify_configid($type); }; 71 | $errmsg = $@ if $@; 72 | my $config = {}; # to return additional attributes 73 | return ($type, $id, $errmsg, $config); 74 | } 75 | return undef; 76 | } 77 | 78 | sub add_a_record { 79 | my ($class, $plugin_config, $zone, $hostname, $ip, $noerr) = @_; 80 | 81 | die "please implement inside plugin"; 82 | } 83 | 84 | sub add_ptr_record { 85 | my ($class, $plugin_config, $zone, $hostname, $ip, $noerr) = @_; 86 | 87 | die "please implement inside plugin"; 88 | } 89 | 90 | sub del_ptr_record { 91 | my ($class, $plugin_config, $zone, $ip, $noerr) = @_; 92 | 93 | die "please implement inside plugin"; 94 | } 95 | 96 | sub del_a_record { 97 | my ($class, $plugin_config, $zone, $hostname, $ip, $noerr) = @_; 98 | 99 | die "please implement inside plugin"; 100 | } 101 | 102 | sub verify_zone { 103 | my ($class, $plugin_config, $zone, $noerr) = @_; 104 | 105 | die "please implement inside plugin"; 106 | } 107 | 108 | sub get_reversedns_zone { 109 | my ($class, $plugin_config, $subnetid, $subnet, $ip) = @_; 110 | 111 | die "please implement inside plugin"; 112 | } 113 | 114 | sub on_update_hook { 115 | my ($class, $plugin_config) = @_; 116 | } 117 | 118 | 1; 119 | -------------------------------------------------------------------------------- /src/PVE/Network/SDN/Controllers/Plugin.pm: -------------------------------------------------------------------------------- 1 | package PVE::Network::SDN::Controllers::Plugin; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use PVE::Tools; 7 | use PVE::JSONSchema; 8 | use PVE::Cluster; 9 | 10 | use PVE::JSONSchema qw(get_standard_option); 11 | use base qw(PVE::SectionConfig); 12 | 13 | PVE::Cluster::cfs_register_file( 14 | 'sdn/controllers.cfg', 15 | sub { __PACKAGE__->parse_config(@_); }, 16 | sub { __PACKAGE__->write_config(@_); }, 17 | ); 18 | 19 | PVE::JSONSchema::register_standard_option( 20 | 'pve-sdn-controller-id', 21 | { 22 | description => "The SDN controller object identifier.", 23 | type => 'string', 24 | format => 'pve-sdn-controller-id', 25 | }, 26 | ); 27 | 28 | PVE::JSONSchema::register_format('pve-sdn-controller-id', \&parse_sdn_controller_id); 29 | 30 | sub parse_sdn_controller_id { 31 | my ($id, $noerr) = @_; 32 | 33 | if ($id !~ m/^[a-z][a-z0-9_-]*[a-z0-9]$/i) { 34 | return undef if $noerr; 35 | die "controller ID '$id' contains illegal characters\n"; 36 | } 37 | die "controller ID '$id' can't be more length than 64 characters\n" if length($id) > 64; 38 | return $id; 39 | } 40 | 41 | my $defaultData = { 42 | 43 | propertyList => { 44 | type => { 45 | description => "Plugin type.", 46 | type => 'string', 47 | format => 'pve-configid', 48 | type => 'string', 49 | }, 50 | controller => get_standard_option( 51 | 'pve-sdn-controller-id', 52 | { completion => \&PVE::Network::SDN::complete_sdn_controller }, 53 | ), 54 | }, 55 | }; 56 | 57 | sub private { 58 | return $defaultData; 59 | } 60 | 61 | sub parse_section_header { 62 | my ($class, $line) = @_; 63 | 64 | if ($line =~ m/^(\S+):\s*(\S+)\s*$/) { 65 | my ($type, $id) = (lc($1), $2); 66 | my $errmsg = undef; # set if you want to skip whole section 67 | eval { PVE::JSONSchema::pve_verify_configid($type); }; 68 | $errmsg = $@ if $@; 69 | my $config = {}; # to return additional attributes 70 | return ($type, $id, $errmsg, $config); 71 | } 72 | return undef; 73 | } 74 | 75 | sub generate_frr_config { 76 | my ($class, $plugin_config, $controller_cfg, $id, $uplinks, $config) = @_; 77 | 78 | die "please implement inside plugin"; 79 | } 80 | 81 | sub generate_zone_frr_config { 82 | my ($class, $plugin_config, $controller, $controller_cfg, $id, $uplinks, $config) = @_; 83 | 84 | die "please implement inside plugin"; 85 | } 86 | 87 | sub generate_vnet_frr_config { 88 | my ($class, $plugin_config, $controller, $zoneid, $vnetid, $config) = @_; 89 | 90 | } 91 | 92 | sub on_delete_hook { 93 | my ($class, $controllerid, $zone_cfg) = @_; 94 | 95 | # do nothing by default 96 | } 97 | 98 | sub on_update_hook { 99 | my ($class, $controllerid, $controller_cfg) = @_; 100 | 101 | # do nothing by default 102 | } 103 | 104 | #helpers 105 | 106 | sub read_iface_mac { 107 | my ($iface) = @_; 108 | return PVE::Tools::file_read_firstline("/sys/class/net/$iface/master/address"); 109 | } 110 | 111 | sub get_router_id { 112 | my ($ip, $iface) = @_; 113 | 114 | return $ip if Net::IP::ip_is_ipv4($ip); 115 | 116 | #for ipv6, use 4 last bytes of iface mac address as unique id 117 | my $mac = read_iface_mac($iface); 118 | 119 | die "can't autofind a router-id value from ip or mac" if !$mac; 120 | 121 | my @mac_bytes = split(':', $mac); 122 | return 123 | hex($mac_bytes[2]) . "." 124 | . hex($mac_bytes[3]) . "." 125 | . hex($mac_bytes[4]) . "." 126 | . hex($mac_bytes[5]); 127 | } 128 | 129 | 1; 130 | --------------------------------------------------------------------------------