diff --git a/ocaml/networkd/bin_db/networkd_db.ml b/ocaml/networkd/bin_db/networkd_db.ml index f62021828fa..f4a0f507445 100644 --- a/ocaml/networkd/bin_db/networkd_db.ml +++ b/ocaml/networkd/bin_db/networkd_db.ml @@ -16,6 +16,10 @@ open Network_interface let name = "networkd_db" +type error = Skip | Msg of string + +let ( let* ) = Result.bind + let _ = let bridge = ref "" in let iface = ref "" in @@ -31,22 +35,59 @@ let _ = (Printf.sprintf "Usage: %s [-bridge | -iface ]" name) ; try let config = Network_config.read_config () in - if !bridge <> "" then - if List.mem_assoc !bridge config.bridge_config then ( - let bridge_config = List.assoc !bridge config.bridge_config in - let ifaces = - List.concat_map (fun (_, port) -> port.interfaces) bridge_config.ports + let r = + let* bridge = if !bridge = "" then Error Skip else Ok !bridge in + let* bridge_config = + let error = Msg (Printf.sprintf "Could not find bridge %s\n" bridge) in + List.assoc_opt bridge config.bridge_config + |> Option.to_result ~none:error + in + let ifaces = + List.concat_map (fun (_, port) -> port.interfaces) bridge_config.ports + in + let* macs = + let to_mac ~order name = + match List.find_opt (fun dev -> dev.name = name) order with + | Some dev -> + Either.Left (Macaddr.to_string dev.mac) + | None -> + Either.Right name in - Printf.printf "interfaces=%s\n" (String.concat "," ifaces) ; - match bridge_config.vlan with - | None -> - () - | Some (parent, id) -> - Printf.printf "vlan=%d\nparent=%s\n" id parent - ) else ( + match (config.interface_order, ifaces) with + | Some order, _ :: _ -> + let oks, errs = List.partition_map (to_mac ~order) ifaces in + if errs = [] then + Ok oks + else + Error + (Msg + (Printf.sprintf "Could not find MAC address(es) for %s" + (String.concat ", " errs) + ) + ) + | _, [] -> + (* No ifaces, no hwaddrs. *) + Ok [] + | None, _ :: _ -> + (* Fallback to use the bridge MAC address when the interface_order + is not available. This can work only because the host installer + requires only one network interface to setup its own networking so far. *) + Ok (Option.to_list bridge_config.bridge_mac) + in + Printf.printf "interfaces=%s\n" (String.concat "," ifaces) ; + Printf.printf "hwaddrs=%s\n" (String.concat "," macs) ; + Option.iter + (fun (parent, id) -> Printf.printf "vlan=%d\nparent=%s\n" id parent) + bridge_config.vlan ; + Ok () + in + ( match r with + | Ok () | Error Skip -> + () + | Error (Msg msg) -> rc := 1 ; - Printf.fprintf stderr "Could not find bridge %s\n" !bridge - ) ; + Printf.fprintf stderr "%s" msg + ) ; if !iface <> "" then if List.mem_assoc !iface config.interface_config then let interface_config = List.assoc !iface config.interface_config in