@@ -336,6 +336,12 @@ module Interface = struct
336
336
Sysfs. is_physical name
337
337
) ()
338
338
339
+ let has_vlan _ dbg ~name ~vlan =
340
+ (* Identify the vlan is used by kernel which is unknown to XAPI *)
341
+ Debug. with_thread_associated dbg (fun () ->
342
+ List. exists (fun (_ , v , p ) -> v = vlan && p = name) (Proc. get_vlans () )
343
+ ) ()
344
+
339
345
let bring_up _ dbg ~name =
340
346
Debug. with_thread_associated dbg (fun () ->
341
347
debug " Bringing up interface %s" name;
@@ -507,18 +513,7 @@ module Bridge = struct
507
513
match vlan with
508
514
| None -> ()
509
515
| Some (parent , vlan ) ->
510
- (* Robustness enhancement: ensure there are no other VLANs in the bridge *)
511
- let current_interfaces = List. filter (fun n ->
512
- String. startswith " eth" n || String. startswith " bond" n
513
- ) (Sysfs. bridge_to_interfaces name) in
514
- debug " Removing these non-VIF interfaces found on the bridge: %s"
515
- (String. concat " , " current_interfaces);
516
- List. iter (fun interface ->
517
- Brctl. destroy_port name interface;
518
- Interface. bring_down () dbg ~name: interface
519
- ) current_interfaces;
520
-
521
- (* Now create the new VLAN device and add it to the bridge *)
516
+ let bridge_interfaces = Sysfs. bridge_to_interfaces name in
522
517
let parent_bridge_interface = List. hd (List. filter (fun n ->
523
518
String. startswith " eth" n || String. startswith " bond" n
524
519
) (Sysfs. bridge_to_interfaces parent)) in
@@ -532,8 +527,27 @@ module Bridge = struct
532
527
end else
533
528
parent_bridge_interface
534
529
in
535
- Ip. create_vlan parent_interface vlan;
536
530
let vlan_name = Ip. vlan_name parent_interface vlan in
531
+ (* Check if the VLAN is already in use by something else *)
532
+ List. iter (fun (device , vlan' , parent' ) ->
533
+ (* A device for the same VLAN (parent + tag), but with a different
534
+ * device name or not on the requested bridge is bad. *)
535
+ if parent' = parent && vlan' = vlan &&
536
+ (device <> vlan_name || not (List. mem device bridge_interfaces)) then
537
+ raise (Vlan_in_use (parent, vlan))
538
+ ) (Proc. get_vlans () );
539
+ (* Robustness enhancement: ensure there are no other VLANs in the bridge *)
540
+ let current_interfaces = List. filter (fun n ->
541
+ String. startswith " eth" n || String. startswith " bond" n
542
+ ) bridge_interfaces in
543
+ debug " Removing these non-VIF interfaces found on the bridge: %s"
544
+ (String. concat " , " current_interfaces);
545
+ List. iter (fun interface ->
546
+ Brctl. destroy_port name interface;
547
+ Interface. bring_down () dbg ~name: interface
548
+ ) current_interfaces;
549
+ (* Now create the new VLAN device and add it to the bridge *)
550
+ Ip. create_vlan parent_interface vlan;
537
551
Interface. bring_up () dbg ~name: vlan_name;
538
552
Brctl. create_port name vlan_name
539
553
end ;
0 commit comments