This add ipam support for nic using sdn vnets.

- if ips are specified manally, we verify that subnet exist on vnet, and we 
register ip in ipam
- if nic is on a vnet, but no ip is specified, we auto find the next available 
ips in this vnet subnet
- if a gateway is defined on the subnet, we override current vm nc gateway
- extra informations like mac address,hostname are registered in external ipam.
- if dns server exist in the zone, we register vm hostname in ipam for each ip 
address

- ips addresses are removed on ct destroy, nic destroy, ip change or vnet change
- snapshot rollback: if ip from snapshot is already used, we keep the current 
running ip
- backup restore to new vmid: if ip from backup is already used, we set ips has 
undef
---
 src/PVE/LXC.pm                                | 144 ++++++++++++++++++
 src/PVE/LXC/Config.pm                         |  58 +++++++
 src/PVE/LXC/Create.pm                         |  33 +++-
 src/test/Makefile                             |   5 +-
 .../ipam.db                                   |  18 +++
 .../ipam.db.expected                          |  17 +++
 .../ipam_config                               |   7 +
 .../net                                       |   7 +
 .../net.expected                              |   7 +
 .../oldnet                                    |   7 +
 .../sdn_config                                |  35 +++++
 .../ipam.db                                   |  18 +++
 .../ipam.db.expected                          |  18 +++
 .../ipam_config                               |   7 +
 .../net                                       |   7 +
 .../net.expected                              |   7 +
 .../oldnet                                    |   7 +
 .../sdn_config                                |  35 +++++
 .../ipam.db                                   |  18 +++
 .../ipam.db.expected                          |  17 +++
 .../ipam_config                               |   7 +
 .../net                                       |   7 +
 .../net.expected                              |   7 +
 .../oldnet                                    |   7 +
 .../sdn_config                                |  35 +++++
 .../ipam.db                                   |  18 +++
 .../ipam.db.expected                          |  18 +++
 .../ipam_config                               |   7 +
 .../net                                       |   6 +
 .../net.expected                              |   7 +
 .../oldnet                                    |   7 +
 .../sdn_config                                |  35 +++++
 .../ipam.db                                   |  18 +++
 .../ipam.db.expected                          |  18 +++
 .../ipam_config                               |   7 +
 .../net                                       |   6 +
 .../net.expected                              |   7 +
 .../oldnet                                    |   7 +
 .../sdn_config                                |  35 +++++
 .../ipv4_changeip_samevnet_with_ipam/ipam.db  |  18 +++
 .../ipam.db.expected                          |  18 +++
 .../ipam_config                               |   7 +
 .../ipv4_changeip_samevnet_with_ipam/net      |   7 +
 .../net.expected                              |   7 +
 .../ipv4_changeip_samevnet_with_ipam/oldnet   |   7 +
 .../sdn_config                                |  35 +++++
 .../ipv4_changeip_vmbr0_to_ipamvnet/ipam.db   |  17 +++
 .../ipam.db.expected                          |  18 +++
 .../ipam_config                               |   7 +
 .../ipams/ipv4_changeip_vmbr0_to_ipamvnet/net |   7 +
 .../net.expected                              |   7 +
 .../ipv4_changeip_vmbr0_to_ipamvnet/oldnet    |   7 +
 .../sdn_config                                |  35 +++++
 .../ipv4_changeip_vmbr0_to_noipamvnet/ipam.db |  17 +++
 .../ipam.db.expected                          |  17 +++
 .../ipam_config                               |   7 +
 .../ipv4_changeip_vmbr0_to_noipamvnet/net     |   7 +
 .../net.expected                              |   7 +
 .../ipv4_changeip_vmbr0_to_noipamvnet/oldnet  |   7 +
 .../sdn_config                                |  35 +++++
 .../ipam.db                                   |  18 +++
 .../ipam.db.expected                          |  18 +++
 .../ipam_config                               |   7 +
 .../net                                       |   7 +
 .../net.expected                              |   8 +
 .../oldnet                                    |   7 +
 .../sdn_config                                |  38 +++++
 .../ipam.db                                   |  18 +++
 .../ipam.db.expected                          |  17 +++
 .../ipam_config                               |   7 +
 .../net                                       |   8 +
 .../net.expected                              |   8 +
 .../oldnet                                    |   7 +
 .../sdn_config                                |  38 +++++
 .../ipam.db                                   |  18 +++
 .../ipam.db.expected                          |  18 +++
 .../ipam_config                               |   7 +
 .../net                                       |   7 +
 .../net.expected                              |   7 +
 .../oldnet                                    |   8 +
 .../sdn_config                                |  36 +++++
 .../ipams/ipv4_updateipam_ipamvnet/ipam.db    |  18 +++
 .../ipv4_updateipam_ipamvnet/ipam.db.expected |  18 +++
 .../ipv4_updateipam_ipamvnet/ipam_config      |   7 +
 src/test/ipams/ipv4_updateipam_ipamvnet/net   |   7 +
 .../ipv4_updateipam_ipamvnet/net.expected     |   7 +
 .../ipams/ipv4_updateipam_ipamvnet/oldnet     |   7 +
 .../ipams/ipv4_updateipam_ipamvnet/sdn_config |  35 +++++
 .../ipam.db                                   |  19 +++
 .../ipam.db.expected                          |  19 +++
 .../ipam_config                               |   7 +
 .../ipv4v6_next_free_samevnet_with_ipam/net   |   6 +
 .../net.expected                              |   8 +
 .../oldnet                                    |   8 +
 .../sdn_config                                |  39 +++++
 .../ipam.db                                   |  20 +++
 .../ipam.db.expected                          |  20 +++
 .../ipam_config                               |   7 +
 .../net                                       |   6 +
 .../net.expected                              |   8 +
 .../oldnet                                    |   8 +
 .../sdn_config                                |  39 +++++
 .../ipams/ipv4v6_updateipam_ipamvnet/ipam.db  |  19 +++
 .../ipam.db.expected                          |  19 +++
 .../ipv4v6_updateipam_ipamvnet/ipam_config    |   7 +
 src/test/ipams/ipv4v6_updateipam_ipamvnet/net |   8 +
 .../ipv4v6_updateipam_ipamvnet/net.expected   |   8 +
 .../ipams/ipv4v6_updateipam_ipamvnet/oldnet   |   8 +
 .../ipv4v6_updateipam_ipamvnet/sdn_config     |  39 +++++
 .../ipam.db                                   |  19 +++
 .../ipam.db.expected                          |  19 +++
 .../ipam_config                               |   7 +
 .../ipv4v6_updateipam_ipamvnet_failingv6/net  |   8 +
 .../net.expected                              |   8 +
 .../oldnet                                    |   8 +
 .../sdn_config                                |  35 +++++
 .../ipam.db                                   |  18 +++
 .../ipam.db.expected                          |  18 +++
 .../ipam_config                               |   7 +
 .../net                                       |   7 +
 .../net.expected                              |   7 +
 .../oldnet                                    |   7 +
 .../sdn_config                                |  35 +++++
 .../ipam.db                                   |  18 +++
 .../ipam.db.expected                          |  18 +++
 .../ipam_config                               |   7 +
 .../net                                       |   7 +
 .../net.expected                              |   8 +
 .../oldnet                                    |   7 +
 .../sdn_config                                |  37 +++++
 .../ipams/ipv6_updateipam_ipamvnet/ipam.db    |  14 ++
 .../ipv6_updateipam_ipamvnet/ipam.db.expected |  14 ++
 .../ipv6_updateipam_ipamvnet/ipam_config      |   7 +
 src/test/ipams/ipv6_updateipam_ipamvnet/net   |   7 +
 .../ipv6_updateipam_ipamvnet/net.expected     |   7 +
 .../ipams/ipv6_updateipam_ipamvnet/oldnet     |   7 +
 .../ipams/ipv6_updateipam_ipamvnet/sdn_config |  35 +++++
 src/test/run_ipam_tests.pl                    | 126 +++++++++++++++
 src/test/snapshot-input/sdn/subnets.cfg       |   0
 src/test/snapshot-test.pm                     |   1 -
 140 files changed, 2266 insertions(+), 10 deletions(-)
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/ipam.db
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/ipam_config
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/net
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/net.expected
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/oldnet
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/sdn_config
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/ipam.db
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/ipam_config
 create mode 100644 src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/net
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/net.expected
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/oldnet
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/sdn_config
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/ipam.db
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/ipam_config
 create mode 100644 src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/net
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/net.expected
 create mode 100644 src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/oldnet
 create mode 100644 
src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/sdn_config
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/ipam.db
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/ipam_config
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/net
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/net.expected
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/oldnet
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/sdn_config
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/ipam.db
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/ipam_config
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/net
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/net.expected
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/oldnet
 create mode 100644 
src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/sdn_config
 create mode 100644 src/test/ipams/ipv4_changeip_samevnet_with_ipam/ipam.db
 create mode 100644 
src/test/ipams/ipv4_changeip_samevnet_with_ipam/ipam.db.expected
 create mode 100644 src/test/ipams/ipv4_changeip_samevnet_with_ipam/ipam_config
 create mode 100644 src/test/ipams/ipv4_changeip_samevnet_with_ipam/net
 create mode 100644 src/test/ipams/ipv4_changeip_samevnet_with_ipam/net.expected
 create mode 100644 src/test/ipams/ipv4_changeip_samevnet_with_ipam/oldnet
 create mode 100644 src/test/ipams/ipv4_changeip_samevnet_with_ipam/sdn_config
 create mode 100644 src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/ipam.db
 create mode 100644 
src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/ipam.db.expected
 create mode 100644 src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/ipam_config
 create mode 100644 src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/net
 create mode 100644 src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/net.expected
 create mode 100644 src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/oldnet
 create mode 100644 src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/sdn_config
 create mode 100644 src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/ipam.db
 create mode 100644 
src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/ipam.db.expected
 create mode 100644 src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/ipam_config
 create mode 100644 src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/net
 create mode 100644 
src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/net.expected
 create mode 100644 src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/oldnet
 create mode 100644 src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/sdn_config
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam_config
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net.expected
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/oldnet
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/sdn_config
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/ipam.db
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/ipam_config
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/net
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/net.expected
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/oldnet
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/sdn_config
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/ipam.db
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/ipam_config
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/net
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/net.expected
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/oldnet
 create mode 100644 
src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/sdn_config
 create mode 100644 src/test/ipams/ipv4_updateipam_ipamvnet/ipam.db
 create mode 100644 src/test/ipams/ipv4_updateipam_ipamvnet/ipam.db.expected
 create mode 100644 src/test/ipams/ipv4_updateipam_ipamvnet/ipam_config
 create mode 100644 src/test/ipams/ipv4_updateipam_ipamvnet/net
 create mode 100644 src/test/ipams/ipv4_updateipam_ipamvnet/net.expected
 create mode 100644 src/test/ipams/ipv4_updateipam_ipamvnet/oldnet
 create mode 100644 src/test/ipams/ipv4_updateipam_ipamvnet/sdn_config
 create mode 100644 src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/ipam.db
 create mode 100644 
src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/ipam_config
 create mode 100644 src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/net
 create mode 100644 
src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/net.expected
 create mode 100644 src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/oldnet
 create mode 100644 
src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/sdn_config
 create mode 100644 
src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/ipam.db
 create mode 100644 
src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/ipam_config
 create mode 100644 
src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/net
 create mode 100644 
src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/net.expected
 create mode 100644 
src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/oldnet
 create mode 100644 
src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/sdn_config
 create mode 100644 src/test/ipams/ipv4v6_updateipam_ipamvnet/ipam.db
 create mode 100644 src/test/ipams/ipv4v6_updateipam_ipamvnet/ipam.db.expected
 create mode 100644 src/test/ipams/ipv4v6_updateipam_ipamvnet/ipam_config
 create mode 100644 src/test/ipams/ipv4v6_updateipam_ipamvnet/net
 create mode 100644 src/test/ipams/ipv4v6_updateipam_ipamvnet/net.expected
 create mode 100644 src/test/ipams/ipv4v6_updateipam_ipamvnet/oldnet
 create mode 100644 src/test/ipams/ipv4v6_updateipam_ipamvnet/sdn_config
 create mode 100644 src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/ipam.db
 create mode 100644 
src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/ipam_config
 create mode 100644 src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/net
 create mode 100644 
src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/net.expected
 create mode 100644 src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/oldnet
 create mode 100644 
src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/sdn_config
 create mode 100644 
src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/ipam.db
 create mode 100644 
src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/ipam_config
 create mode 100644 src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/net
 create mode 100644 
src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/net.expected
 create mode 100644 
src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/oldnet
 create mode 100644 
src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/sdn_config
 create mode 100644 
src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db
 create mode 100644 
src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db.expected
 create mode 100644 
src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam_config
 create mode 100644 
src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net
 create mode 100644 
src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net.expected
 create mode 100644 
src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/oldnet
 create mode 100644 
src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/sdn_config
 create mode 100644 src/test/ipams/ipv6_updateipam_ipamvnet/ipam.db
 create mode 100644 src/test/ipams/ipv6_updateipam_ipamvnet/ipam.db.expected
 create mode 100644 src/test/ipams/ipv6_updateipam_ipamvnet/ipam_config
 create mode 100644 src/test/ipams/ipv6_updateipam_ipamvnet/net
 create mode 100644 src/test/ipams/ipv6_updateipam_ipamvnet/net.expected
 create mode 100644 src/test/ipams/ipv6_updateipam_ipamvnet/oldnet
 create mode 100644 src/test/ipams/ipv6_updateipam_ipamvnet/sdn_config
 create mode 100755 src/test/run_ipam_tests.pl
 create mode 100644 src/test/snapshot-input/sdn/subnets.cfg

diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index 7e6f378..a1eee0e 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -847,6 +847,9 @@ sub destroy_lxc_container {
     rmdir "/var/lib/lxc/$vmid/rootfs";
     unlink "/var/lib/lxc/$vmid/config";
     rmdir "/var/lib/lxc/$vmid";
+
+    PVE::LXC::destroy_net_ip($conf);
+
     if (defined $replacement_conf) {
        PVE::LXC::Config->write_config($vmid, $replacement_conf);
     } else {
@@ -1077,6 +1080,147 @@ sub update_ipconfig {
 
 }
 
+sub is_static_ip {
+    my ($ip) = @_;
+
+    return 1 if $ip !~ m/(dhcp|manual|auto)$/;
+}
+
+sub ip_has_changed {
+    my ($oldip, $ip) = @_;
+
+    return 1 if !$oldip && $ip;
+    return 1 if !$ip && $oldip;
+    return 1 if $ip && $oldip && $ip ne $oldip;
+}
+
+my $add_net_ip = sub {
+    my ($version, $net, $oldnet, $hostname, $oldhostname, $description) = @_;
+
+    my $oldbridge = $oldnet->{bridge};
+    my $bridge = $net->{bridge};
+    my $mac = $net->{hwaddr};
+    my $ipfield = $version == 4 ? "ip" : "ip6";
+    my $ip = $net->{$ipfield};
+    my $oldip = $oldnet->{$ipfield};
+    my $subnets = PVE::Network::SDN::Vnets::get_subnets($bridge);
+    return if !keys %{$subnets};
+
+    eval {
+       if (!$ip) {
+           my $next_free_ip = 
PVE::Network::SDN::Vnets::get_next_free_cidr($bridge, $hostname, $mac, 
$description, $version);
+           $net->{$ipfield} = $next_free_ip if $next_free_ip;
+       } elsif (is_static_ip($ip)) {
+           if (!ip_has_changed($oldip, $ip)) {
+               #update ip attributes if no ip address change
+               PVE::Network::SDN::Vnets::update_cidr($bridge, $ip, $hostname, 
$oldhostname, $mac, $description);
+           } else {
+               PVE::Network::SDN::Vnets::add_cidr($bridge, $ip, $hostname, 
$mac, $description);
+           }
+       }
+    };
+    if ($@) {
+       die $@;
+    }
+};
+
+my $del_net_ip = sub {
+    my ($version, $oldnet, $net, $hostname, $description) = @_;
+
+    my $oldbridge = $oldnet->{bridge};
+    my $bridge = $net->{bridge};
+    my $ip = $version == 4 ? $net->{ip} : $net->{ip6};
+    my $oldip = $version == 4 ? $oldnet->{ip} : $oldnet->{ip6};
+
+    return if !$oldip || !is_static_ip($oldip);
+
+    my $subnets = PVE::Network::SDN::Vnets::get_subnets($oldbridge);
+    return if !keys %{$subnets};
+
+    eval {
+       PVE::Network::SDN::Vnets::del_cidr($oldbridge, $oldip, $hostname, 
$description) if !$bridge || $bridge ne $oldbridge || !$ip || $ip ne $oldip;
+    };
+    warn $@ if $@;
+};
+
+
+my $update_net_gateway = sub {
+    my ($version, $net) = @_;
+
+    my $bridge = $net->{bridge};
+    my $netip = $version == 4 ? $net->{ip} : $net->{ip6};
+    my $gwfield = $version == 4 ? "gw" : "gw6";
+
+    return if (!$netip || !is_static_ip($netip));
+
+    my $subnets = PVE::Network::SDN::Vnets::get_subnets($bridge);
+    return if !keys %{$subnets};
+
+    #update gateway
+    my ($ip, $mask) = split(/\//, $netip);
+    my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, 
$mask, $subnets);
+    my $gw = $subnet->{gateway} if $subnet->{gateway};
+    $net->{$gwfield} = $gw if $gw;
+
+};
+
+sub destroy_net_ip {
+    my ($conf) = @_;
+
+    return if !$have_sdn;
+
+    foreach my $opt (keys %$conf) {
+       next if $opt !~ m/^net(\d+)$/;
+       my $netid = $1;
+       my $oldnet = PVE::LXC::Config->parse_lxc_network($conf->{$opt});
+       my $hostname = $conf->{hostname};
+       my $description = '';
+       delete_net_ip($hostname, $oldnet, undef, $description);
+    }
+}
+
+sub update_net_ip {
+    my ($net, $oldnet, $hostname, $oldhostname, $description) = @_;
+
+    return if !$have_sdn;
+
+    eval {
+       &$add_net_ip(4, $net, $oldnet, $hostname, $oldhostname, $description);
+    };
+    if ($@) {
+       $net->{ip} = $oldnet->{ip};
+       die "can't change ip4: $@\n";
+    }
+
+    eval {
+       &$add_net_ip(6, $net, $oldnet, $hostname, $oldhostname, $description);
+    };
+    if ($@) {
+       my $err = $@;
+       #if error, delete previously added ipv4
+       eval {
+           PVE::Network::SDN::Vnets::del_cidr($net->{bridge}, $net->{ip}, 
$hostname, $description) if ip_has_changed($oldnet->{ip}, $net->{ip});
+       };
+       $net->{ip6} = $oldnet->{ip6};
+       $net->{ip} = $oldnet->{ip};
+       die "error change ipv6: $err\n";
+    }
+
+    delete_net_ip($oldhostname, $oldnet, $net, $description);
+
+    &$update_net_gateway(4, $net);
+    &$update_net_gateway(6, $net);
+}
+
+sub delete_net_ip {
+    my ($hostname, $oldnet, $net, $description) = @_;
+
+    return if !$have_sdn;
+
+    &$del_net_ip(4, $oldnet, $net, $hostname, $description);
+    &$del_net_ip(6, $oldnet, $net, $hostname, $description);
+}
+
 my $open_namespace = sub {
     my ($vmid, $pid, $kind) = @_;
     sysopen my $fd, "/proc/$pid/ns/$kind", O_RDONLY
diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
index 7b82f65..da8cbfa 100644
--- a/src/PVE/LXC/Config.pm
+++ b/src/PVE/LXC/Config.pm
@@ -213,6 +213,43 @@ sub __snapshot_delete_vol_snapshot {
     push @$unused, $mountpoint->{volume};
 }
 
+sub __snapshot_rollback_hook {
+    my ($class, $vmid, $conf, $snap, $prepare, $data) = @_;
+
+    if($prepare) {
+       $data->{oldconf} = $conf;
+    } else {
+       my $noerr = 1;  #if ip change and already use, we keep the current ip
+       my $oldconf = $data->{oldconf};
+       #update ip of current and new net interface
+       foreach my $opt (keys %$conf) {
+           next if $opt !~ m/^net(\d+)$/;
+           my $netid = $1;
+           my $oldnet = $class->parse_lxc_network($oldconf->{$opt});
+           my $net = $class->parse_lxc_network($conf->{$opt});
+           my $hostname = $conf->{hostname};
+           my $description = "vm:$vmid net:$netid";
+           eval {
+               PVE::LXC::update_net_ip($net, $oldnet, $hostname, $hostname, 
$description);
+           };
+           if ($@) {
+               warn "error: $@ : keep current ip configuration\n";
+               $conf->{$opt} = $class->print_lxc_network($net);
+           }
+       }
+
+       #remove ip of removed net interface
+       foreach my $opt (keys %$oldconf) {
+           next if $opt !~ m/^net(\d+)$/;
+           next if defined($conf->{$opt});
+           my $netid = $1;
+           my $oldnet = $class->parse_lxc_network($oldconf->{$opt});
+           my $hostname = $oldconf->{hostname};
+           my $description = "vm:$vmid net:$netid";
+           PVE::LXC::delete_net_ip($hostname, $oldnet, undef, "vm:$vmid 
net:$netid");
+       }
+    }
+}
 sub __snapshot_rollback_vol_possible {
     my ($class, $mountpoint, $snapname) = @_;
 
@@ -1044,6 +1081,10 @@ sub update_pct_config {
            $class->check_protection($conf, "can't remove CT $vmid drive 
'$opt'");
        } elsif ($opt eq 'unprivileged') {
            die "unable to delete read-only option: '$opt'\n";
+       } elsif ($opt =~ m/^net(\d+)$/) {
+           my $netid = $1;
+           my $oldnet = $class->parse_lxc_network($conf->{$opt});
+           PVE::LXC::delete_net_ip($conf->{hostname}, $oldnet, undef, 
"vm:$vmid net:$netid");
        }
        $class->add_to_pending_delete($conf, $opt);
     }
@@ -1071,7 +1112,23 @@ sub update_pct_config {
            $value = PVE::LXC::verify_searchdomain_list($value);
        } elsif ($opt eq 'unprivileged') {
            die "unable to modify read-only option: '$opt'\n";
+       } elsif ($opt =~ m/^net(\d+)$/) {
+               my $netid = $1;
+               my $net = $class->parse_lxc_network($value);
+               my $oldnet = $class->parse_lxc_network($conf->{$opt});
+               my $hostname = $param->{hostname} ? $param->{hostname} : 
$conf->{hostname};
+               PVE::LXC::update_net_ip($net, $oldnet, $hostname, $hostname, 
"vm:$vmid net:$netid");
+               $value = $class->print_lxc_network($net);
+       } elsif ($opt eq 'hostname') {
+           #if hostname change, update ipam + dns for each ip
+           foreach my $netopt (sort keys %$conf) {
+               next if $netopt !~ m/^net(\d+)$/;
+               my $netid = $1;
+               my $net = $class->parse_lxc_network($conf->{$netopt});
+               PVE::LXC::update_net_ip($net, $net, $value, $conf->{hostname}, 
"vm:$vmid net:$netid");
+           }
        }
+
        $conf->{pending}->{$opt} = $value;
        $class->remove_from_pending_delete($conf, $opt);
     }
@@ -1663,4 +1720,5 @@ sub get_backup_volumes {
     return $return_volumes;
 }
 
+
 1;
diff --git a/src/PVE/LXC/Create.pm b/src/PVE/LXC/Create.pm
index 82d7ad9..e43433b 100644
--- a/src/PVE/LXC/Create.pm
+++ b/src/PVE/LXC/Create.pm
@@ -278,7 +278,7 @@ sub restore_configuration_from_proxmox_backup {
 
     my $oldconf = recover_config_from_proxmox_backup($storage_cfg, $archive, 
$vmid);
 
-    sanitize_and_merge_config($conf, $oldconf, $restricted, $unique);
+    sanitize_and_merge_config($conf, $oldconf, $restricted, $unique, $vmid);
 
     my $cmd = "files";
 
@@ -304,7 +304,7 @@ sub restore_configuration_from_proxmox_backup {
 }
 
 sub sanitize_and_merge_config {
-    my ($conf, $oldconf, $restricted, $unique) = @_;
+    my ($conf, $oldconf, $restricted, $unique, $vmid) = @_;
 
     foreach my $key (keys %$oldconf) {
        next if $key eq 'digest' || $key eq 'rootfs' || $key eq 'snapshots' || 
$key eq 'unprivileged' || $key eq 'parent';
@@ -325,12 +325,29 @@ sub sanitize_and_merge_config {
            next;
        }
 
-       if ($unique && $key =~ /^net\d+$/) {
+       if ($key =~ m/^net(\d+)$/) {
+           my $netid = $1;
            my $net = PVE::LXC::Config->parse_lxc_network($oldconf->{$key});
-           my $dc = PVE::Cluster::cfs_read_file('datacenter.cfg');
-           $net->{hwaddr} = PVE::Tools::random_ether_addr($dc->{mac_prefix});
-           $conf->{$key} = PVE::LXC::Config->print_lxc_network($net);
-           next;
+           my $hostname = $oldconf->{hostname};
+           my $description = "vm:$vmid net:$netid";
+
+           if ($unique) {
+               my $dc = PVE::Cluster::cfs_read_file('datacenter.cfg');
+               $net->{hwaddr} = 
PVE::Tools::random_ether_addr($dc->{mac_prefix});
+               $conf->{$key} = PVE::LXC::Config->print_lxc_network($net);
+           }
+
+           eval {
+               PVE::LXC::update_net_ip($net, undef, $hostname, $hostname, 
$description);
+           };
+           if ($@) {
+               warn "error: $@ : remove ipconfig from net$netid\n";
+               $net->{ip} = undef;
+               $net->{gw} = undef;
+               $net->{ip6} = undef;
+               $net->{gw6} = undef;
+               $conf->{$key} = PVE::LXC::Config->print_lxc_network($net);
+           }
        }
        $conf->{$key} = $oldconf->{$key} if !defined($conf->{$key});
     }
@@ -348,7 +365,7 @@ sub restore_configuration_from_etc_vzdump {
        my $raw = PVE::Tools::file_get_contents($pct_cfg_fn);
        my $oldconf = PVE::LXC::Config::parse_pct_config("/lxc/$vmid.conf", 
$raw);
 
-       sanitize_and_merge_config($conf, $oldconf, $restricted, $unique);
+       sanitize_and_merge_config($conf, $oldconf, $restricted, $unique, $vmid);
 
        unlink($pct_cfg_fn);
 
diff --git a/src/test/Makefile b/src/test/Makefile
index 8734879..68133aa 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -2,7 +2,7 @@ RUN_USERNS := lxc-usernsexec -m "u:0:`id -u`:1" -m "g:0:`id 
-g`:1" --
 
 all: test
 
-test: test_setup test_snapshot test_bindmount
+test: test_setup test_snapshot test_bindmount test_ipam
 
 test_setup: run_setup_tests.pl
        $(RUN_USERNS) ./run_setup_tests.pl
@@ -13,5 +13,8 @@ test_snapshot: run_snapshot_tests.pl
 test_bindmount: bindmount_test.pl
        $(RUN_USERNS) ./bindmount_test.pl
 
+test_ipam: run_ipam_tests.pl
+       ./run_ipam_tests.pl
+
 clean:
        rm -rf tmprootfs
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/ipam.db 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/ipam.db
new file mode 100644
index 0000000..d03cc04
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/ipam.db
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/ipam.db.expected 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/ipam.db.expected
new file mode 100644
index 0000000..3d36a24
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/ipam.db.expected
@@ -0,0 +1,17 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/ipam_config 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/net 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/net
new file mode 100644
index 0000000..26740b4
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/net
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet3',
+    'ip' => '192.168.2.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/net.expected 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/net.expected
new file mode 100644
index 0000000..26740b4
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/net.expected
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet3',
+    'ip' => '192.168.2.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/oldnet 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/oldnet
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/sdn_config 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/sdn_config
new file mode 100644
index 0000000..43e142f
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnet_noipam/sdn_config
@@ -0,0 +1,35 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/ipam.db 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/ipam.db
new file mode 100644
index 0000000..d03cc04
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/ipam.db
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/ipam.db.expected 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/ipam.db.expected
new file mode 100644
index 0000000..f576915
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/ipam.db.expected
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                       "192.168.1.1" => {}
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/ipam_config 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/net 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/net
new file mode 100644
index 0000000..4031d65
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/net
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet2',
+    'ip' => '192.168.1.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/net.expected 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/net.expected
new file mode 100644
index 0000000..4031d65
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/net.expected
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet2',
+    'ip' => '192.168.1.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/oldnet 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/oldnet
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/sdn_config 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/sdn_config
new file mode 100644
index 0000000..43e142f
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_othervnetipam/sdn_config
@@ -0,0 +1,35 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/ipam.db 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/ipam.db
new file mode 100644
index 0000000..d03cc04
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/ipam.db
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/ipam.db.expected 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/ipam.db.expected
new file mode 100644
index 0000000..3d36a24
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/ipam.db.expected
@@ -0,0 +1,17 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/ipam_config 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/net 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/net
new file mode 100644
index 0000000..908f573
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/net
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'vmbr0',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/net.expected 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/net.expected
new file mode 100644
index 0000000..908f573
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/net.expected
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'vmbr0',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/oldnet 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/oldnet
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/sdn_config 
b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/sdn_config
new file mode 100644
index 0000000..43e142f
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_ipamvnet_to_vmbr0_noipam/sdn_config
@@ -0,0 +1,35 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/ipam.db 
b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/ipam.db
new file mode 100644
index 0000000..d03cc04
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/ipam.db
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/ipam.db.expected 
b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/ipam.db.expected
new file mode 100644
index 0000000..f576915
--- /dev/null
+++ 
b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/ipam.db.expected
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                       "192.168.1.1" => {}
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/ipam_config 
b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/net 
b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/net
new file mode 100644
index 0000000..a73e889
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/net
@@ -0,0 +1,6 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet2',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/net.expected 
b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/net.expected
new file mode 100644
index 0000000..4031d65
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/net.expected
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet2',
+    'ip' => '192.168.1.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/oldnet 
b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/oldnet
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/sdn_config 
b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/sdn_config
new file mode 100644
index 0000000..43e142f
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_othervnet_with_ipam/sdn_config
@@ -0,0 +1,35 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/ipam.db 
b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/ipam.db
new file mode 100644
index 0000000..d03cc04
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/ipam.db
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/ipam.db.expected 
b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/ipam.db.expected
new file mode 100644
index 0000000..2287b85
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/ipam.db.expected
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.2" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/ipam_config 
b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/net 
b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/net
new file mode 100644
index 0000000..b68d367
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/net
@@ -0,0 +1,6 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/net.expected 
b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/net.expected
new file mode 100644
index 0000000..97a3915
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/net.expected
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.2/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/oldnet 
b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/oldnet
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/sdn_config 
b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/sdn_config
new file mode 100644
index 0000000..43e142f
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_next_free_samevnet_with_ipam/sdn_config
@@ -0,0 +1,35 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv4_changeip_samevnet_with_ipam/ipam.db 
b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/ipam.db
new file mode 100644
index 0000000..d03cc04
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/ipam.db
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4_changeip_samevnet_with_ipam/ipam.db.expected 
b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/ipam.db.expected
new file mode 100644
index 0000000..2287b85
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/ipam.db.expected
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.2" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4_changeip_samevnet_with_ipam/ipam_config 
b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4_changeip_samevnet_with_ipam/net 
b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/net
new file mode 100644
index 0000000..97a3915
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/net
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.2/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_samevnet_with_ipam/net.expected 
b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/net.expected
new file mode 100644
index 0000000..97a3915
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/net.expected
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.2/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_samevnet_with_ipam/oldnet 
b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/oldnet
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_samevnet_with_ipam/sdn_config 
b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/sdn_config
new file mode 100644
index 0000000..43e142f
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_samevnet_with_ipam/sdn_config
@@ -0,0 +1,35 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/ipam.db 
b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/ipam.db
new file mode 100644
index 0000000..3d36a24
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/ipam.db
@@ -0,0 +1,17 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/ipam.db.expected 
b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/ipam.db.expected
new file mode 100644
index 0000000..e0906aa
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/ipam.db.expected
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       '192.168.0.1' => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/ipam_config 
b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/net 
b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/net
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/net
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/net.expected 
b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/net.expected
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/net.expected
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/oldnet 
b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/oldnet
new file mode 100644
index 0000000..dbd70c4
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'vmbr0',
+    'ip' => '10.0.0.1/24',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/sdn_config 
b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/sdn_config
new file mode 100644
index 0000000..43e142f
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_ipamvnet/sdn_config
@@ -0,0 +1,35 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/ipam.db 
b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/ipam.db
new file mode 100644
index 0000000..3d36a24
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/ipam.db
@@ -0,0 +1,17 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/ipam.db.expected 
b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/ipam.db.expected
new file mode 100644
index 0000000..3d36a24
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/ipam.db.expected
@@ -0,0 +1,17 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/ipam_config 
b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/net 
b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/net
new file mode 100644
index 0000000..26740b4
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/net
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet3',
+    'ip' => '192.168.2.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/net.expected 
b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/net.expected
new file mode 100644
index 0000000..26740b4
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/net.expected
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet3',
+    'ip' => '192.168.2.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/oldnet 
b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/oldnet
new file mode 100644
index 0000000..dbd70c4
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'vmbr0',
+    'ip' => '10.0.0.1/24',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/sdn_config 
b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/sdn_config
new file mode 100644
index 0000000..43e142f
--- /dev/null
+++ b/src/test/ipams/ipv4_changeip_vmbr0_to_noipamvnet/sdn_config
@@ -0,0 +1,35 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db
new file mode 100644
index 0000000..d03cc04
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db.expected
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db.expected
new file mode 100644
index 0000000..f576915
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db.expected
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                       "192.168.1.1" => {}
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam_config
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net
new file mode 100644
index 0000000..4031d65
--- /dev/null
+++ b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet2',
+    'ip' => '192.168.1.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net.expected
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net.expected
new file mode 100644
index 0000000..d79ce80
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net.expected
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet2',
+    'ip' => '192.168.1.1/30',
+    'gw' => '192.168.1.2',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/oldnet 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/oldnet
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/sdn_config
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/sdn_config
new file mode 100644
index 0000000..da2eded
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetipam/sdn_config
@@ -0,0 +1,38 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                       'gateway' => 
'192.168.0.2'
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                       'gateway' => 
'192.168.1.2'
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                       'gateway' => 
'192.168.2.3'
+                                                  },
+                     }
+
+             }
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/ipam.db
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/ipam.db
new file mode 100644
index 0000000..d03cc04
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/ipam.db
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/ipam.db.expected
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/ipam.db.expected
new file mode 100644
index 0000000..3d36a24
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/ipam.db.expected
@@ -0,0 +1,17 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/ipam_config
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/net 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/net
new file mode 100644
index 0000000..ae2b7bc
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/net
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet3',
+    'ip' => '192.168.2.1/30',
+    'gw' => '192.168.2.2',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/net.expected
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/net.expected
new file mode 100644
index 0000000..ae2b7bc
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/net.expected
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet3',
+    'ip' => '192.168.2.1/30',
+    'gw' => '192.168.2.2',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/oldnet
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/oldnet
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/sdn_config
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/sdn_config
new file mode 100644
index 0000000..56b17ae
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_gateway_othervnetnoipam/sdn_config
@@ -0,0 +1,38 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                       'gateway' => 
'192.168.0.2'
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                       'gateway' => 
'192.168.1.2'
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                       'gateway' => 
'192.168.2.2'
+                                                  },
+                     }
+
+             }
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/ipam.db
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/ipam.db
new file mode 100644
index 0000000..d03cc04
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/ipam.db
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/ipam.db.expected
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/ipam.db.expected
new file mode 100644
index 0000000..f576915
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/ipam.db.expected
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                       "192.168.1.1" => {}
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/ipam_config
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/net 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/net
new file mode 100644
index 0000000..4031d65
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/net
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet2',
+    'ip' => '192.168.1.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/net.expected
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/net.expected
new file mode 100644
index 0000000..4031d65
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/net.expected
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet2',
+    'ip' => '192.168.1.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/oldnet
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/oldnet
new file mode 100644
index 0000000..e3e093c
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/oldnet
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'gw' => '192.168.0.2',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/sdn_config
 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/sdn_config
new file mode 100644
index 0000000..20785d0
--- /dev/null
+++ 
b/src/test/ipams/ipv4_gateway_changeip_ipamvnet_to_nogateway_othervnetipam/sdn_config
@@ -0,0 +1,36 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                       'gateway' => 
'192.168.0.2'
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv4_updateipam_ipamvnet/ipam.db 
b/src/test/ipams/ipv4_updateipam_ipamvnet/ipam.db
new file mode 100644
index 0000000..d03cc04
--- /dev/null
+++ b/src/test/ipams/ipv4_updateipam_ipamvnet/ipam.db
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4_updateipam_ipamvnet/ipam.db.expected 
b/src/test/ipams/ipv4_updateipam_ipamvnet/ipam.db.expected
new file mode 100644
index 0000000..d03cc04
--- /dev/null
+++ b/src/test/ipams/ipv4_updateipam_ipamvnet/ipam.db.expected
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+               "192.168.1.0/30" => {
+                   "ips" =>{
+                   }
+               },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4_updateipam_ipamvnet/ipam_config 
b/src/test/ipams/ipv4_updateipam_ipamvnet/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4_updateipam_ipamvnet/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4_updateipam_ipamvnet/net 
b/src/test/ipams/ipv4_updateipam_ipamvnet/net
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ b/src/test/ipams/ipv4_updateipam_ipamvnet/net
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_updateipam_ipamvnet/net.expected 
b/src/test/ipams/ipv4_updateipam_ipamvnet/net.expected
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ b/src/test/ipams/ipv4_updateipam_ipamvnet/net.expected
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_updateipam_ipamvnet/oldnet 
b/src/test/ipams/ipv4_updateipam_ipamvnet/oldnet
new file mode 100644
index 0000000..fe003a3
--- /dev/null
+++ b/src/test/ipams/ipv4_updateipam_ipamvnet/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4_updateipam_ipamvnet/sdn_config 
b/src/test/ipams/ipv4_updateipam_ipamvnet/sdn_config
new file mode 100644
index 0000000..43e142f
--- /dev/null
+++ b/src/test/ipams/ipv4_updateipam_ipamvnet/sdn_config
@@ -0,0 +1,35 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/ipam.db 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/ipam.db
new file mode 100644
index 0000000..252c95a
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/ipam.db
@@ -0,0 +1,19 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:370:7334" => {}
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/ipam.db.expected 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/ipam.db.expected
new file mode 100644
index 0000000..8dcf09b
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/ipam.db.expected
@@ -0,0 +1,19 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.2" => {}
+                   }
+               },
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:370:7335" => {}
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/ipam_config 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/net 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/net
new file mode 100644
index 0000000..b68d367
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/net
@@ -0,0 +1,6 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/net.expected 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/net.expected
new file mode 100644
index 0000000..3b6e3c5
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/net.expected
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.2/30',
+    'ip6' => '2001:db8:85a3::8a2e:370:7335/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/oldnet 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/oldnet
new file mode 100644
index 0000000..929f90d
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/oldnet
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'ip6' => '2001:db8:85a3::8a2e:370:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/sdn_config 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/sdn_config
new file mode 100644
index 0000000..171cb08
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam/sdn_config
@@ -0,0 +1,39 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-2001:db8:85a3::8a2e:370:7334-127' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git 
a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/ipam.db 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/ipam.db
new file mode 100644
index 0000000..de920d7
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/ipam.db
@@ -0,0 +1,20 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:370:7334" => {},
+                       "2001:db8:85a3::8a2e:370:7335" => {}
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/ipam.db.expected 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/ipam.db.expected
new file mode 100644
index 0000000..de920d7
--- /dev/null
+++ 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/ipam.db.expected
@@ -0,0 +1,20 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:370:7334" => {},
+                       "2001:db8:85a3::8a2e:370:7335" => {}
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/ipam_config 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/net 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/net
new file mode 100644
index 0000000..b68d367
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/net
@@ -0,0 +1,6 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/net.expected 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/net.expected
new file mode 100644
index 0000000..929f90d
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/net.expected
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'ip6' => '2001:db8:85a3::8a2e:370:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/oldnet 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/oldnet
new file mode 100644
index 0000000..929f90d
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/oldnet
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'ip6' => '2001:db8:85a3::8a2e:370:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/sdn_config 
b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/sdn_config
new file mode 100644
index 0000000..171cb08
--- /dev/null
+++ b/src/test/ipams/ipv4v6_next_free_samevnet_with_ipam_failingv6/sdn_config
@@ -0,0 +1,39 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-2001:db8:85a3::8a2e:370:7334-127' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet/ipam.db 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet/ipam.db
new file mode 100644
index 0000000..252c95a
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet/ipam.db
@@ -0,0 +1,19 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:370:7334" => {}
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet/ipam.db.expected 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet/ipam.db.expected
new file mode 100644
index 0000000..adb6fc7
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet/ipam.db.expected
@@ -0,0 +1,19 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:370:7335" => {}
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet/ipam_config 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet/net 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet/net
new file mode 100644
index 0000000..e7052bc
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet/net
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'ip6' => '2001:db8:85a3::8a2e:370:7335/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet/net.expected 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet/net.expected
new file mode 100644
index 0000000..e7052bc
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet/net.expected
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'ip6' => '2001:db8:85a3::8a2e:370:7335/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet/oldnet 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet/oldnet
new file mode 100644
index 0000000..929f90d
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet/oldnet
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'ip6' => '2001:db8:85a3::8a2e:370:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet/sdn_config 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet/sdn_config
new file mode 100644
index 0000000..171cb08
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet/sdn_config
@@ -0,0 +1,39 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-2001:db8:85a3::8a2e:370:7334-127' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/ipam.db 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/ipam.db
new file mode 100644
index 0000000..252c95a
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/ipam.db
@@ -0,0 +1,19 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:370:7334" => {}
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/ipam.db.expected 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/ipam.db.expected
new file mode 100644
index 0000000..252c95a
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/ipam.db.expected
@@ -0,0 +1,19 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+               "192.168.0.0/30" => {
+                   "ips" =>{
+                       "192.168.0.1" => {}
+                   }
+               },
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:370:7334" => {}
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/ipam_config 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/net 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/net
new file mode 100644
index 0000000..872a354
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/net
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'ip6' => '2001:db8:85a3::8a2e:370:7336/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/net.expected 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/net.expected
new file mode 100644
index 0000000..929f90d
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/net.expected
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'ip6' => '2001:db8:85a3::8a2e:370:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/oldnet 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/oldnet
new file mode 100644
index 0000000..929f90d
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/oldnet
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip' => '192.168.0.1/30',
+    'ip6' => '2001:db8:85a3::8a2e:370:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/sdn_config 
b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/sdn_config
new file mode 100644
index 0000000..43e142f
--- /dev/null
+++ b/src/test/ipams/ipv4v6_updateipam_ipamvnet_failingv6/sdn_config
@@ -0,0 +1,35 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-192.168.0.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-192.168.1.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-192.168.2.0-30' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/ipam.db 
b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/ipam.db
new file mode 100644
index 0000000..16c5af3
--- /dev/null
+++ b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/ipam.db
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:370:7334" => {}
+                    }
+                },
+                "2001:db8:85a3::8a2e:371:7334/127" => {
+                    "ips" =>{
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/ipam.db.expected 
b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/ipam.db.expected
new file mode 100644
index 0000000..4039793
--- /dev/null
+++ b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/ipam.db.expected
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                    }
+                },
+                "2001:db8:85a3::8a2e:371:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:371:7334" => {}
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/ipam_config 
b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/net 
b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/net
new file mode 100644
index 0000000..b4bee3a
--- /dev/null
+++ b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/net
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet2',
+    'ip6' => '2001:db8:85a3::8a2e:371:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/net.expected 
b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/net.expected
new file mode 100644
index 0000000..b4bee3a
--- /dev/null
+++ b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/net.expected
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet2',
+    'ip6' => '2001:db8:85a3::8a2e:371:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/oldnet 
b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/oldnet
new file mode 100644
index 0000000..b1c5472
--- /dev/null
+++ b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip6' => '2001:db8:85a3::8a2e:370:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/sdn_config 
b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/sdn_config
new file mode 100644
index 0000000..5d48a4e
--- /dev/null
+++ b/src/test/ipams/ipv6_changeip_ipamvnet_to_othervnetipam/sdn_config
@@ -0,0 +1,35 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-2001:db8:85a3::8a2e:370:7334-127' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-2001:db8:85a3::8a2e:371:7334-127' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-2001:db8:85a3::8a2e:372:7334-127' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git 
a/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db
 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db
new file mode 100644
index 0000000..16c5af3
--- /dev/null
+++ 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:370:7334" => {}
+                    }
+                },
+                "2001:db8:85a3::8a2e:371:7334/127" => {
+                    "ips" =>{
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db.expected
 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db.expected
new file mode 100644
index 0000000..4039793
--- /dev/null
+++ 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam.db.expected
@@ -0,0 +1,18 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                    }
+                },
+                "2001:db8:85a3::8a2e:371:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:371:7334" => {}
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git 
a/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam_config
 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git 
a/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net
new file mode 100644
index 0000000..b4bee3a
--- /dev/null
+++ b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet2',
+    'ip6' => '2001:db8:85a3::8a2e:371:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net.expected
 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net.expected
new file mode 100644
index 0000000..689f7cc
--- /dev/null
+++ 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/net.expected
@@ -0,0 +1,8 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet2',
+    'gw6' => '2001:db8:85a3::8a2e:371:7335',
+    'ip6' => '2001:db8:85a3::8a2e:371:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/oldnet 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/oldnet
new file mode 100644
index 0000000..b1c5472
--- /dev/null
+++ 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip6' => '2001:db8:85a3::8a2e:370:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git 
a/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/sdn_config
 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/sdn_config
new file mode 100644
index 0000000..3652eca
--- /dev/null
+++ 
b/src/test/ipams/ipv6_gateway_changeip_ipamvnet_to_gateway_othervnetipam/sdn_config
@@ -0,0 +1,37 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-2001:db8:85a3::8a2e:370:7334-127' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                       'gateway' => 
'2001:db8:85a3::8a2e:370:7335'
+                                                  },
+                       'myzone-2001:db8:85a3::8a2e:371:7334-127' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                       'gateway' => 
'2001:db8:85a3::8a2e:371:7335'
+                                                  },
+                       'myzone2-2001:db8:85a3::8a2e:372:7334-127' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/ipams/ipv6_updateipam_ipamvnet/ipam.db 
b/src/test/ipams/ipv6_updateipam_ipamvnet/ipam.db
new file mode 100644
index 0000000..d8e3ce5
--- /dev/null
+++ b/src/test/ipams/ipv6_updateipam_ipamvnet/ipam.db
@@ -0,0 +1,14 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:370:7334" => {}
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv6_updateipam_ipamvnet/ipam.db.expected 
b/src/test/ipams/ipv6_updateipam_ipamvnet/ipam.db.expected
new file mode 100644
index 0000000..89b6e8c
--- /dev/null
+++ b/src/test/ipams/ipv6_updateipam_ipamvnet/ipam.db.expected
@@ -0,0 +1,14 @@
+{
+   "zones" => {
+       "myzone" => {
+           "subnets" => {
+                "2001:db8:85a3::8a2e:370:7334/127" => {
+                    "ips" =>{
+                       "2001:db8:85a3::8a2e:370:7335" => {}
+                    }
+                },
+           }
+       },
+    }
+}
+
diff --git a/src/test/ipams/ipv6_updateipam_ipamvnet/ipam_config 
b/src/test/ipams/ipv6_updateipam_ipamvnet/ipam_config
new file mode 100644
index 0000000..f5f36ad
--- /dev/null
+++ b/src/test/ipams/ipv6_updateipam_ipamvnet/ipam_config
@@ -0,0 +1,7 @@
+{
+          'ids' => {
+                     'pve' => {
+                                'type' => 'pve'
+                              },
+                   },
+}
diff --git a/src/test/ipams/ipv6_updateipam_ipamvnet/net 
b/src/test/ipams/ipv6_updateipam_ipamvnet/net
new file mode 100644
index 0000000..4f83ab2
--- /dev/null
+++ b/src/test/ipams/ipv6_updateipam_ipamvnet/net
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip6' => '2001:db8:85a3::8a2e:370:7335/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv6_updateipam_ipamvnet/net.expected 
b/src/test/ipams/ipv6_updateipam_ipamvnet/net.expected
new file mode 100644
index 0000000..4f83ab2
--- /dev/null
+++ b/src/test/ipams/ipv6_updateipam_ipamvnet/net.expected
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip6' => '2001:db8:85a3::8a2e:370:7335/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv6_updateipam_ipamvnet/oldnet 
b/src/test/ipams/ipv6_updateipam_ipamvnet/oldnet
new file mode 100644
index 0000000..b1c5472
--- /dev/null
+++ b/src/test/ipams/ipv6_updateipam_ipamvnet/oldnet
@@ -0,0 +1,7 @@
+{
+    'name' => 'eth0',
+    'bridge' => 'myvnet',
+    'ip6' => '2001:db8:85a3::8a2e:370:7334/127',
+    'type' => 'veth',
+    'hwaddr' => '8A:4C:75:11:58:1D'
+}
diff --git a/src/test/ipams/ipv6_updateipam_ipamvnet/sdn_config 
b/src/test/ipams/ipv6_updateipam_ipamvnet/sdn_config
new file mode 100644
index 0000000..5d48a4e
--- /dev/null
+++ b/src/test/ipams/ipv6_updateipam_ipamvnet/sdn_config
@@ -0,0 +1,35 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { type => "vnet", zone => "myzone" },
+                        myvnet2 => { type => "vnet", zone => "myzone" },
+                        myvnet3 => { type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+               ids => { 
+                       myzone => { ipam => "pve", type =>"simple" },
+                       myzone2 => { type =>"simple" },
+                     },
+             },
+
+  subnets => {
+              ids => { 
+                       'myzone-2001:db8:85a3::8a2e:370:7334-127' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet',
+                                                  },
+                       'myzone-2001:db8:85a3::8a2e:371:7334-127' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet2',
+                                                  },
+                       'myzone2-2001:db8:85a3::8a2e:372:7334-127' => {
+                                                        'type' => 'subnet',
+                                                        'vnet' => 'myvnet3',
+                                                  },
+                     }
+
+             }
+}
diff --git a/src/test/run_ipam_tests.pl b/src/test/run_ipam_tests.pl
new file mode 100755
index 0000000..ab8c7ac
--- /dev/null
+++ b/src/test/run_ipam_tests.pl
@@ -0,0 +1,126 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use lib qw(..);
+use File::Slurp;
+use NetAddr::IP qw(:lower);
+
+use Test::More;
+use Test::MockModule;
+
+use PVE::Network::SDN;
+use PVE::Network::SDN::Zones;
+use PVE::INotify;
+use PVE::LXC;
+use JSON;
+
+use Data::Dumper qw(Dumper);
+$Data::Dumper::Sortkeys = 1;
+
+sub read_sdn_config {
+    my ($file) = @_;
+    # Read structure back in again
+    open my $in, '<', $file or die $!;
+    my $sdn_config;
+    {
+       local $/;    # slurp mode
+       $sdn_config = eval <$in>;
+    }
+    close $in;
+    return $sdn_config;
+}
+
+
+my @plugins = read_dir( './ipams/', prefix => 1 ) ;
+
+foreach my $path (@plugins) {
+
+    my (undef, $testid) = split(/\//, $path);
+
+    print "test: $testid\n";
+    my $sdn_config = read_sdn_config ("$path/sdn_config");
+    my $pve_sdn_zones;
+    $pve_sdn_zones = Test::MockModule->new('PVE::Network::SDN::Zones');
+    $pve_sdn_zones->mock(
+       config => sub {
+           return $sdn_config->{zones};
+       },
+    );
+
+    my $pve_sdn_vnets;
+    $pve_sdn_vnets = Test::MockModule->new('PVE::Network::SDN::Vnets');
+    $pve_sdn_vnets->mock(
+       config => sub {
+           return $sdn_config->{vnets};
+       },
+    );
+
+    my $pve_sdn_subnets;
+    $pve_sdn_subnets = Test::MockModule->new('PVE::Network::SDN::Subnets');
+    $pve_sdn_subnets->mock(
+       config => sub {
+           return $sdn_config->{subnets};
+       },
+       verify_dns_zone => sub {
+           return;
+       },
+       add_dns_record => sub {
+           return;
+       }
+    );
+
+    my $js = JSON->new;
+    $js->canonical(1);
+  
+    my $hostname = "myhostname";
+    my $mac = "da:65:8f:18:9b:6f";
+    my $description = "mydescription";
+    my $ipamdb = read_sdn_config ("$path/ipam.db");
+
+    my $plugin;
+    my $sdn_ipam_plugin;
+    $plugin = PVE::Network::SDN::Ipams::Plugin->lookup('pve');
+    $sdn_ipam_plugin = Test::MockModule->new($plugin);
+    $sdn_ipam_plugin->mock(
+        read_db => sub {
+           return $ipamdb;
+       },
+       write_db => sub {
+           my ($cfg) = @_;
+           $ipamdb = $cfg;
+       }
+    );
+
+    my $pve_sdn_ipams;
+    $pve_sdn_ipams = Test::MockModule->new('PVE::Network::SDN::Ipams');
+    $pve_sdn_ipams->mock(
+       config => sub {
+           my $ipam_config = read_sdn_config ("$path/ipam_config");
+           return $ipam_config;
+       },
+    );
+
+
+    ## add_ip
+    my $test = "update_net";
+    my $name = "$testid $test";
+    my $oldnet = read_sdn_config("$path/oldnet");
+    my $net = read_sdn_config("$path/net");
+    my $expected_net = read_sdn_config("$path/net.expected");
+    my $expected_ipamdb = read_sdn_config("$path/ipam.db.expected");
+
+    eval {
+        PVE::LXC::update_net_ip($net, $oldnet, $hostname, $hostname, 
"description");
+    };
+    is(Dumper($net), Dumper($expected_net), "verify net");
+    is(Dumper($ipamdb), Dumper($expected_ipamdb), "verify ipam.db");
+
+
+
+}
+
+done_testing();
+
+
diff --git a/src/test/snapshot-input/sdn/subnets.cfg 
b/src/test/snapshot-input/sdn/subnets.cfg
new file mode 100644
index 0000000..e69de29
diff --git a/src/test/snapshot-test.pm b/src/test/snapshot-test.pm
index 91a2af9..73a0532 100644
--- a/src/test/snapshot-test.pm
+++ b/src/test/snapshot-test.pm
@@ -281,7 +281,6 @@ sub mocked_write_config {
 
 # END mocked PVE::LXC methods
 
-
 PVE::Tools::run_command("rm -rf snapshot-working");
 PVE::Tools::run_command("cp -a snapshot-input snapshot-working");
 
-- 
2.20.1


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to