diff --git a/ocaml/networkd/bin/network_server.ml b/ocaml/networkd/bin/network_server.ml index 5e056f73eb7..59c76e319f3 100644 --- a/ocaml/networkd/bin/network_server.ml +++ b/ocaml/networkd/bin/network_server.ml @@ -554,8 +554,7 @@ module Interface = struct let set_dns _ dbg ~name ~nameservers ~domains = Debug.with_thread_associated dbg (fun () -> - update_config name - {(get_config name) with dns= Some (nameservers, domains)} ; + update_config name {(get_config name) with dns= (nameservers, domains)} ; debug "Configuring DNS for %s: nameservers: [%s]; domains: [%s]" name (String.concat ", " (List.map Unix.string_of_inet_addr nameservers)) (String.concat ", " domains) ; @@ -728,7 +727,7 @@ module Interface = struct ; ipv6_conf ; ipv6_gateway ; ipv4_routes - ; dns + ; dns= nameservers, domains ; mtu ; ethtool_settings ; ethtool_offload @@ -737,10 +736,15 @@ module Interface = struct ) ) -> update_config name c ; exec (fun () -> - match dns with - | Some (nameservers, domains) -> + (* We only apply the DNS settings when not in a DHCP mode + to avoid conflicts. The `dns` field + should really be an option type so that we don't have to + derive the intention of the caller by looking at other + fields. *) + match (ipv4_conf, ipv6_conf) with + | Static4 _, _ | _, Static6 _ | _, Autoconf6 -> set_dns () dbg ~name ~nameservers ~domains - | None -> + | _ -> () ) ; exec (fun () -> set_ipv4_conf dbg name ipv4_conf) ; diff --git a/ocaml/networkd/bin_db/networkd_db.ml b/ocaml/networkd/bin_db/networkd_db.ml index bffe93a32bc..f62021828fa 100644 --- a/ocaml/networkd/bin_db/networkd_db.ml +++ b/ocaml/networkd/bin_db/networkd_db.ml @@ -74,25 +74,20 @@ let _ = [("gateway", Unix.string_of_inet_addr addr)] in let dns = - interface_config.dns - |> Option.map fst - |> Option.map (List.map Unix.string_of_inet_addr) - |> Option.fold ~none:[] ~some:(function - | [] -> - [] - | dns' -> - [("dns", String.concat "," dns')] - ) + let dns' = + List.map Unix.string_of_inet_addr (fst interface_config.dns) + in + if dns' = [] then + [] + else + [("dns", String.concat "," dns')] in let domains = - interface_config.dns - |> Option.map snd - |> Option.fold ~none:[] ~some:(function - | [] -> - [] - | domains' -> - [("domain", String.concat "," domains')] - ) + let domains' = snd interface_config.dns in + if domains' = [] then + [] + else + [("domain", String.concat "," domains')] in mode @ addrs @ gateway @ dns @ domains | None4 -> diff --git a/ocaml/networkd/lib/network_config.ml b/ocaml/networkd/lib/network_config.ml index 3d034f05284..56eef61ce3d 100644 --- a/ocaml/networkd/lib/network_config.ml +++ b/ocaml/networkd/lib/network_config.ml @@ -37,6 +37,7 @@ let bridge_naming_convention (device : string) = let get_list_from ~sep ~key args = List.assoc_opt key args |> Option.map (fun v -> Astring.String.cuts ~empty:false ~sep v) + |> Option.value ~default:[] let parse_ipv4_config args = function | Some "static" -> @@ -72,13 +73,11 @@ let parse_ipv6_config args = function (None6, None) let parse_dns_config args = - let ( let* ) = Option.bind in - let* nameservers = - get_list_from ~sep:"," ~key:"DNS" args - |> Option.map (List.map Unix.inet_addr_of_string) + let nameservers = + get_list_from ~sep:"," ~key:"DNS" args |> List.map Unix.inet_addr_of_string in - let* domains = get_list_from ~sep:" " ~key:"DOMAIN" args in - Some (nameservers, domains) + let domains = get_list_from ~sep:" " ~key:"DOMAIN" args in + (nameservers, domains) let read_management_conf () = try @@ -104,7 +103,7 @@ let read_management_conf () = let device = (* Take 1st member of bond *) match (bond_mode, bond_members) with - | None, _ | _, (None | Some []) -> ( + | None, _ | _, [] -> ( match List.assoc_opt "LABEL" args with | Some x -> x @@ -112,7 +111,7 @@ let read_management_conf () = error "%s: missing LABEL in %s" __FUNCTION__ management_conf ; raise Read_error ) - | _, Some (hd :: _) -> + | _, hd :: _ -> hd in Inventory.reread_inventory () ; diff --git a/ocaml/xapi-idl/network/network_interface.ml b/ocaml/xapi-idl/network/network_interface.ml index 06d38ff1a87..2f3368fc131 100644 --- a/ocaml/xapi-idl/network/network_interface.ml +++ b/ocaml/xapi-idl/network/network_interface.ml @@ -158,10 +158,7 @@ type interface_config_t = { ; ipv6_conf: ipv6 [@default None6] ; ipv6_gateway: Unix.inet_addr option [@default None] ; ipv4_routes: ipv4_route_t list [@default []] - ; dns: (Unix.inet_addr list * string list) option [@default None] - (** the list - of nameservers and domains to persist in /etc/resolv.conf. Must be None when - using a DHCP mode *) + ; dns: Unix.inet_addr list * string list [@default [], []] ; mtu: int [@default 1500] ; ethtool_settings: (string * string) list [@default []] ; ethtool_offload: (string * string) list [@default [("lro", "off")]] @@ -203,7 +200,7 @@ let default_interface = ; ipv6_conf= None6 ; ipv6_gateway= None ; ipv4_routes= [] - ; dns= None + ; dns= ([], []) ; mtu= 1500 ; ethtool_settings= [] ; ethtool_offload= [("lro", "off")] diff --git a/ocaml/xapi/nm.ml b/ocaml/xapi/nm.ml index fbc37a5fedc..229b53adbe2 100644 --- a/ocaml/xapi/nm.ml +++ b/ocaml/xapi/nm.ml @@ -634,25 +634,28 @@ let bring_pif_up ~__context ?(management_interface = false) (pif : API.ref_PIF) rc.API.pIF_ip_configuration_mode = `Static | `IPv6 -> rc.API.pIF_ipv6_configuration_mode = `Static - || rc.API.pIF_ipv6_configuration_mode = `Autoconf in let dns = match (static, rc.API.pIF_DNS) with | false, _ | true, "" -> - None + ([], []) | true, pif_dns -> let nameservers = List.map Unix.inet_addr_of_string - (String.split_on_char ',' pif_dns) + (String.split ',' pif_dns) in let domains = match List.assoc_opt "domain" rc.API.pIF_other_config with - | None | Some "" -> + | None -> [] - | Some domains -> - String.split_on_char ',' domains + | Some domains -> ( + try String.split ',' domains + with _ -> + warn "Invalid DNS search domains: %s" domains ; + [] + ) in - Some (nameservers, domains) + (nameservers, domains) in let mtu = determine_mtu rc net_rc in let ethtool_settings, ethtool_offload =