From f78420f5beba619dfad9b95d166959cb489d01e7 Mon Sep 17 00:00:00 2001 From: Benjamin Reis Date: Wed, 21 Feb 2024 14:43:27 +0100 Subject: [PATCH] Filter our link IPv6 when migrating VMs - New pif helper: `get_non_link_ipv6` to get the 1st non link IPv6 of a PIF - Use the helper in `migrate_receive` and `get_primary_address` used in host evacuation to have a valid IPv6 of the destination host Signed-off-by: Benjamin Reis --- ocaml/xapi/xapi_host.ml | 9 +++------ ocaml/xapi/xapi_pif_helpers.ml | 14 +++++++++++++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/ocaml/xapi/xapi_host.ml b/ocaml/xapi/xapi_host.ml index 875b3be5cf2..768f33aba7b 100644 --- a/ocaml/xapi/xapi_host.ml +++ b/ocaml/xapi/xapi_host.ml @@ -20,6 +20,7 @@ let with_lock = Xapi_stdext_threads.Threadext.Mutex.execute module Unixext = Xapi_stdext_unix.Unixext open Xapi_host_helpers +open Xapi_pif_helpers open Db_filter_types open Workload_balancing @@ -2555,14 +2556,10 @@ let migrate_receive ~__context ~host ~network ~options:_ = let configuration_mode = Db.PIF.get_ipv6_configuration_mode ~__context ~self:pif in - match Db.PIF.get_IPv6 ~__context ~self:pif with + match Xapi_pif_helpers.get_non_link_ipv6 ~__context ~pif with | [] -> ("", configuration_mode) - | ip :: _ -> - (* The CIDR is also stored in the IPv6 field of a PIF. *) - let ipv6 = - match String.split_on_char '/' ip with hd :: _ -> hd | _ -> "" - in + | ipv6 :: _ -> (ipv6, configuration_mode) ) in diff --git a/ocaml/xapi/xapi_pif_helpers.ml b/ocaml/xapi/xapi_pif_helpers.ml index fc6c9708511..4d8771730f4 100644 --- a/ocaml/xapi/xapi_pif_helpers.ml +++ b/ocaml/xapi/xapi_pif_helpers.ml @@ -255,10 +255,22 @@ let is_device_underneath_same_type ~__context pif1 pif2 = in get_device_info pif1 = get_device_info pif2 +let get_non_link_ipv6 ~__context ~pif = + let non_link_ip6s = List.map (fun ip6 -> + match (Ipaddr.V6.Prefix.of_string ip6) with + | Error _ -> None + | Ok ip6 -> + let ip6 = Ipaddr.V6.Prefix.address ip6 in + if (Ipaddr.V6.scope ip6) = Ipaddr.Link then None else Some (Ipaddr.V6.to_string ip6) + ) + (Db.PIF.get_IPv6 ~__context ~self:pif) + in + List.map (Option.fold ~none:"" ~some:Fun.id) non_link_ip6s |> List.filter ((<>) "") + let get_primary_address ~__context ~pif = match Db.PIF.get_primary_address_type ~__context ~self:pif with | `IPv4 -> ( match Db.PIF.get_IP ~__context ~self:pif with "" -> None | ip -> Some ip ) | `IPv6 -> - List.nth_opt (Db.PIF.get_IPv6 ~__context ~self:pif) 0 + List.nth_opt (get_non_link_ipv6 ~__context ~pif) 0