Reconfigure dynamic assigned addresses if subnet is modified removing IP out of configured netmask if present
Signed-off-by: Lorenzo Bianconi <[email protected]> --- northd/ovn-northd.c | 48 ++++++++++++++++++++++++++------------------- tests/ovn.at | 10 ++++++++++ 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 5fddc5e3e..e527e90fa 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -1665,24 +1665,6 @@ ipam_get_unused_mac(ovs_be32 ip) return mac64; } -static uint32_t -ipam_get_unused_ip(struct ovn_datapath *od) -{ - if (!od || !od->ipam_info.allocated_ipv4s) { - return 0; - } - - size_t new_ip_index = bitmap_scan(od->ipam_info.allocated_ipv4s, 0, 0, - od->ipam_info.total_ipv4s - 1); - if (new_ip_index == od->ipam_info.total_ipv4s - 1) { - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); - VLOG_WARN_RL( &rl, "Subnet address space has been exhausted."); - return 0; - } - - return od->ipam_info.start_ipv4 + new_ip_index; -} - enum dynamic_update_type { NONE, /* No change to the address */ REMOVE, /* Address is no longer dynamic */ @@ -1705,6 +1687,32 @@ struct dynamic_address_update { enum dynamic_update_type ipv6; }; +static uint32_t +ipam_get_unused_ip(struct dynamic_address_update *update) +{ + struct ovn_datapath *od = update->od; + + if (!od || !od->ipam_info.allocated_ipv4s) { + return 0; + } + + size_t new_ip_index = bitmap_scan(od->ipam_info.allocated_ipv4s, 0, 0, + od->ipam_info.total_ipv4s - 1); + if (new_ip_index == od->ipam_info.total_ipv4s - 1) { + const struct nbrec_logical_switch_port *nbsp = update->op->nbsp; + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); + VLOG_WARN_RL( &rl, "Subnet address space has been exhausted."); + + if (nbsp->dynamic_addresses) { + nbrec_logical_switch_port_set_dynamic_addresses(nbsp, NULL); + } + + return 0; + } + + return od->ipam_info.start_ipv4 + new_ip_index; +} + static enum dynamic_update_type dynamic_mac_changed(const char *lsp_addresses, struct dynamic_address_update *update) @@ -1758,7 +1766,7 @@ dynamic_ip4_changed(const char *lsp_addrs, } uint32_t index = ip4 - ipam->start_ipv4; - if (index > ipam->total_ipv4s || + if (index >= ipam->total_ipv4s - 1 || bitmap_is_set(ipam->allocated_ipv4s, index)) { /* Previously assigned dynamic IPv4 address can no longer be used. * It's either outside the subnet, conflicts with an excluded IP, @@ -1964,7 +1972,7 @@ update_dynamic_addresses(struct dynamic_address_update *update) ip4 = update->static_ip; break; case DYNAMIC: - ip4 = htonl(ipam_get_unused_ip(update->od)); + ip4 = htonl(ipam_get_unused_ip(update)); VLOG_INFO("Assigned dynamic IPv4 address '"IP_FMT"' to port '%s'", IP_ARGS(ip4), update->op->nbsp->name); } diff --git a/tests/ovn.at b/tests/ovn.at index 7769b69ed..e27a74081 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -7473,6 +7473,16 @@ AT_CHECK([ovn-nbctl get Logical-Switch-Port p103 dynamic_addresses], [0], ["22:33:44:55:66:77 172.16.1.250" ]) +ovn-nbctl ls-add sw12 +for i in $(seq 1 200); do + ovn-nbctl lsp-add sw12 sw12-p$i -- lsp-set-addresses sw12-p$i "00:00:00:00:00:$i dynamic" +done +ovn-nbctl set Logical-Switch sw12 other_config:subnet=192.10.2.0/24 +ovn-nbctl set Logical-Switch sw12 other_config:subnet=192.10.2.0/25 +AT_CHECK([ovn-nbctl list Logical-Switch-Port | grep -q 192.10.2.127], [1]) +AT_CHECK([ovn-nbctl list Logical-Switch-Port | grep -q 192.10.2.128], [1]) +AT_CHECK([ovn-nbctl list Logical-Switch-Port | grep -q 192.10.2.180], [1]) + as ovn-sb OVS_APP_EXIT_AND_WAIT([ovsdb-server]) -- 2.26.2 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
