Skip to content

Commit

Permalink
Merge pull request #86 from sharady/CA-201728
Browse files Browse the repository at this point in the history
CA-201728: Add new function `is_vlan_in_use`
  • Loading branch information
robhoes authored Jul 22, 2016
2 parents 7aa4234 + 0b1198a commit 6cc2616
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 13 deletions.
13 changes: 13 additions & 0 deletions lib/network_utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,19 @@ module Proc = struct
else
raise Not_found

let get_vlans () =
try
Unixext.file_lines_fold (fun vlans line ->
try
let x = Scanf.sscanf line "%s | %d | %s" (fun device vlan parent -> device, vlan, parent) in
x :: vlans
with _ ->
vlans
) [] "/proc/net/vlan/config"
with e ->
error "Error: could not read /proc/net/vlan/config";
[]

let get_bond_links_up name =
let statusses = get_bond_slave_info name "MII Status" in
List.fold_left (fun x (_, y) -> x + (if y = "up" then 1 else 0)) 0 statusses
Expand Down
40 changes: 27 additions & 13 deletions networkd/network_server.ml
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,12 @@ module Interface = struct
Sysfs.is_physical name
) ()

let has_vlan _ dbg ~name ~vlan =
(* Identify the vlan is used by kernel which is unknown to XAPI *)
Debug.with_thread_associated dbg (fun () ->
List.exists (fun (_, v, p) -> v = vlan && p = name) (Proc.get_vlans ())
) ()

let bring_up _ dbg ~name =
Debug.with_thread_associated dbg (fun () ->
debug "Bringing up interface %s" name;
Expand Down Expand Up @@ -507,18 +513,7 @@ module Bridge = struct
match vlan with
| None -> ()
| Some (parent, vlan) ->
(* Robustness enhancement: ensure there are no other VLANs in the bridge *)
let current_interfaces = List.filter (fun n ->
String.startswith "eth" n || String.startswith "bond" n
) (Sysfs.bridge_to_interfaces name) in
debug "Removing these non-VIF interfaces found on the bridge: %s"
(String.concat ", " current_interfaces);
List.iter (fun interface ->
Brctl.destroy_port name interface;
Interface.bring_down () dbg ~name:interface
) current_interfaces;

(* Now create the new VLAN device and add it to the bridge *)
let bridge_interfaces = Sysfs.bridge_to_interfaces name in
let parent_bridge_interface = List.hd (List.filter (fun n ->
String.startswith "eth" n || String.startswith "bond" n
) (Sysfs.bridge_to_interfaces parent)) in
Expand All @@ -532,8 +527,27 @@ module Bridge = struct
end else
parent_bridge_interface
in
Ip.create_vlan parent_interface vlan;
let vlan_name = Ip.vlan_name parent_interface vlan in
(* Check if the VLAN is already in use by something else *)
List.iter (fun (device, vlan', parent') ->
(* A device for the same VLAN (parent + tag), but with a different
* device name or not on the requested bridge is bad. *)
if parent' = parent && vlan' = vlan &&
(device <> vlan_name || not (List.mem device bridge_interfaces)) then
raise (Vlan_in_use (parent, vlan))
) (Proc.get_vlans ());
(* Robustness enhancement: ensure there are no other VLANs in the bridge *)
let current_interfaces = List.filter (fun n ->
String.startswith "eth" n || String.startswith "bond" n
) bridge_interfaces in
debug "Removing these non-VIF interfaces found on the bridge: %s"
(String.concat ", " current_interfaces);
List.iter (fun interface ->
Brctl.destroy_port name interface;
Interface.bring_down () dbg ~name:interface
) current_interfaces;
(* Now create the new VLAN device and add it to the bridge *)
Ip.create_vlan parent_interface vlan;
Interface.bring_up () dbg ~name:vlan_name;
Brctl.create_port name vlan_name
end;
Expand Down

0 comments on commit 6cc2616

Please sign in to comment.