()
let add_nic_to_vm ~xs state nic =
- nic.nic_bridge_gen <- (
- match nic.nic_bridge with
- | None ->
- let l = Netdev.Bridge.list () in
- if List.length l > 0 then
- List.hd l
- else
- ""
- | Some bridge ->
- if Netdev.Bridge.exists bridge then
- bridge
- else
- ""
- );
- if nic.nic_mac_gen = "" then (
- let generate_random_mac () =
- String.concat ":" (List.map (sprintf "%02x")
- ([0x00; 0x16; 0x3e] @
- List.map Random.int [0x80; 0x100; 0x100]))
- in
- let generate_vm_mac nic_id nic_model vm_uuid =
- let s_of_c c1 c2 =
- let s = String.create 2 in
- s.[0] <- c1; s.[1] <- c2; s
- in
- let unicast_local h =
- let v = int_of_string ("0x" ^ (List.hd h)) in
- let n = sprintf "%02x" (0x2 lor (v land 0xfe)) in
- n :: (List.tl h)
- in
- let vector =
- (if nic_id = -1 then [] else [ string_of_int nic_id ]) @
- (match nic_model with None -> [] | Some x -> [ x ]) @
- [ vm_uuid ]
- in
- let digest = Digest.to_hex (Digest.string (String.concat " " vector)) in
- let hexs = List.map (fun i -> s_of_c digest.[i] digest.[i + 12]) [ 0; 2; 1; 7; 6; 4 ] in
- String.concat ":" (unicast_local hexs)
- in
- let is_valid_mac s =
- let x = String.split ':' s in
- if List.length x != 6 then
- false
- else (
- try ignore (List.map (fun s -> int_of_string ("0x" ^ s)) x); true
- with _ -> false
- )
- in
- nic.nic_mac_gen <- (
- match nic.nic_mac with
- | Some "random" -> generate_random_mac ();
- | None | Some "vm" -> generate_vm_mac nic.nic_id nic.nic_model state.vm_uuid
- | Some mac ->
- if is_valid_mac mac then mac else generate_vm_mac nic.nic_id nic.nic_model state.vm_uuid
- )
- );
- let netty = Netman.Bridge nic.nic_bridge_gen in
+ let netty = Netman.Bridge nic.nic_bridge in
let (_: Device_common.device) =
- Device.Vif.add ~xs ~devid:nic.nic_id ~netty ~mac:nic.nic_mac_gen
+ Device.Vif.add ~xs ~devid:nic.nic_id ~netty ~mac:nic.nic_mac
~protocol:(devproto_of_state state) state.vm_domid in
()
let dm_info_of_cfg cfg =
let nics = get_nics cfg in
- let nics = List.map (fun nic -> nic.nic_mac_gen, nic.nic_bridge_gen, nic.nic_model) nics in
+ let nics = List.map (fun nic -> nic.nic_mac, nic.nic_bridge, if nic.nic_model="" then None else Some nic.nic_model) nics in
let disp =
match cfg.display with
| DisplayNone -> Device.Dm.NONE
let nic_list args =
let l = List.map (fun nic ->
sprintf "id: %d, bridge:%s, mac:%s\n"
- nic.nic_id nic.nic_bridge_gen nic.nic_mac_gen
+ nic.nic_id nic.nic_bridge nic.nic_mac
) cfg.nics in
Xenvmlib.Msg (String.concat "" l)
in
match state.vm_next_cfg with
| None -> state.vm_cfg
| Some cfg -> cfg
-
+
let set_new_config state cfg =
state.vm_next_cfg <- Some cfg
Xenvmlib.Ok
let add_nic state bridge mac model =
- let nic = { Vmconfig.default_nic with
- Vmconfig.nic_bridge = bridge;
- Vmconfig.nic_mac = mac;
- Vmconfig.nic_model = model;
- } in
+ let nic = Vmconfig.default_nic in
+ let nic = match bridge with Some x -> {nic with nic_bridge=x} | None -> nic in
+ let nic = match mac with Some x -> {nic with nic_mac=x} | None -> nic in
+ let nic = match model with Some x -> {nic with nic_model=x} | None -> nic in
let cfg = get_new_config state in
- let cfg = { cfg with nics = cfg.nics @ [ nic ] } in
+ let nics = Vmconfig.Config.sanitise_nics state.vm_uuid (cfg.nics @ [ nic ]) in
+ let cfg = { cfg with nics = nics } in
set_new_config state cfg;
Xenvmlib.Ok
type config_nic = {
nic_id: int;
- nic_bridge: string option;
- mutable nic_bridge_gen: string;
- nic_mac: string option;
- mutable nic_mac_gen: string;
- nic_model: string option;
+ nic_bridge: string;
+ nic_mac: string;
+ nic_model: string;
nic_dynadded: bool;
}
let default_nic =
{
nic_id = -1;
- nic_bridge = None;
- nic_bridge_gen = "";
- nic_mac = None;
- nic_mac_gen = "";
- nic_model = None;
+ nic_bridge = "";
+ nic_mac = "";
+ nic_model = "";
nic_dynadded = false;
}
let ls = if s = "" then [] else String.split ',' s in
let id = ref (-1)
- and bridge = ref None
- and model = ref None
- and mac = ref None in
+ and bridge = ref ""
+ and model = ref ""
+ and mac = ref "" in
List.iter (fun v ->
let lv = String.split '=' v in
match lvalue with
| "id" -> id := int_of_string value
- | "bridge" -> bridge := Some value
- | "model" -> model := Some value
- | "mac" -> mac := Some value
+ | "bridge" -> bridge := value
+ | "model" -> model := value
+ | "mac" -> mac := value
| _ -> ()
) ls;
nic_model = !model;
}
-(* Where NIC IDs have been left blank (or explicitly set to -1), here we allocate them a reasonable number *)
-let assign_nic_ids nics =
+(* Where NIC IDs have been left blank (or explicitly set to -1), here we allocate them a reasonable number. We also allocate a bridge and a mac, if necessary *)
+let sanitise_nics vm_uuid nics =
let sort_nics nics = List.sort (fun nic1 nic2 -> compare nic1.nic_id nic2.nic_id) nics in
let assert_ok nics =
ignore(List.fold_left (fun last_id nic ->
let (assigned,unassigned) = List.partition (fun nic -> nic.nic_id >= 0) nics in
let nics = List.fold_right allocate_nic_id unassigned (sort_nics assigned) in
assert_ok nics;
- nics
+
+ let fix_bridge nic =
+ {nic with nic_bridge =
+ match nic.nic_bridge with
+ | "" ->
+ let l = Netdev.Bridge.list () in
+ if List.length l > 0 then
+ List.hd l
+ else
+ ""
+ | bridge ->
+ if Netdev.Bridge.exists bridge then
+ bridge
+ else
+ ""} in
+
+ let nics = List.map fix_bridge nics in
+
+ let fix_mac nic =
+ {nic with nic_mac =
+ if nic.nic_mac <> "" then nic.nic_mac else (
+ let generate_random_mac () =
+ String.concat ":" (List.map (sprintf "%02x")
+ ([0x00; 0x16; 0x3e] @
+ List.map Random.int [0x80; 0x100; 0x100]))
+ in
+ let generate_vm_mac nic_id nic_model vm_uuid =
+ let s_of_c c1 c2 =
+ let s = String.create 2 in
+ s.[0] <- c1; s.[1] <- c2; s
+ in
+ let unicast_local h =
+ let v = int_of_string ("0x" ^ (List.hd h)) in
+ let n = sprintf "%02x" (0x2 lor (v land 0xfe)) in
+ n :: (List.tl h)
+ in
+ let vector =
+ (if nic_id = -1 then [] else [ string_of_int nic_id ]) @
+ (match nic_model with "" -> [] | x -> [ x ]) @
+ [ vm_uuid ]
+ in
+ let digest = Digest.to_hex (Digest.string (String.concat " " vector)) in
+ let hexs = List.map (fun i -> s_of_c digest.[i] digest.[i + 12]) [ 0; 2; 1; 7; 6; 4 ] in
+ String.concat ":" (unicast_local hexs)
+ in
+ let is_valid_mac s =
+ let x = String.split ':' s in
+ if List.length x != 6 then
+ false
+ else (
+ try ignore (List.map (fun s -> int_of_string ("0x" ^ s)) x); true
+ with _ -> false
+ )
+ in
+ match nic.nic_mac with
+ | "random" -> generate_random_mac ();
+ | "" | "vm" -> generate_vm_mac nic.nic_id nic.nic_model vm_uuid
+ | mac ->
+ if is_valid_mac mac then mac else generate_vm_mac nic.nic_id nic.nic_model vm_uuid
+ )
+ }
+ in
+ List.map fix_mac nics
let config_disk_of_string s =
(* physpath:phystype:virtpath:mode:devtype *)
Config.Error ls -> error_report ls
end;
- let nics = assign_nic_ids !cfg.nics in
+ let nics = sanitise_nics uuid !cfg.nics in
{ !cfg with
__uuid = !__uuid;
let online = Hotplug.device_is_online ~xs device in
let connected = Hotplug.device_is_connected ~xs device in
if online && not connected then (
- let netty = Netman.Bridge nic.nic_bridge_gen in
- let mac = nic.nic_mac_gen in
+ let netty = Netman.Bridge nic.nic_bridge in
+ let mac = nic.nic_mac in
let protocol = Vmact.devproto_of_state state in
let (_: Device_common.device) = Device.Vif.plug ~xs ~netty ~mac ~protocol device in
()