Skip to content

Commit 604819c

Browse files
authored
Merge pull request #163 from robhoes/master
CA-323523: Ensure that dhclients get restarted when gateway/DNS changes
2 parents b547737 + 6a85f86 commit 604819c

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

lib/network_utils.ml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,17 @@ module Linux_bonding = struct
722722
error "Bond %s does not exist; cannot set properties" master
723723
end
724724

725-
module Dhclient = struct
725+
module Dhclient :
726+
sig
727+
type interface = string
728+
val remove_conf_file : ?ipv6:bool -> interface -> unit
729+
val is_running : ?ipv6:bool -> interface -> bool
730+
val stop : ?ipv6:bool -> interface -> unit
731+
val ensure_running : ?ipv6:bool -> interface -> [> `dns of string | `gateway of string ] list -> unit
732+
end =
733+
struct
734+
type interface = string
735+
726736
let pid_file ?(ipv6=false) interface =
727737
let ipv6' = if ipv6 then "6" else "" in
728738
Printf.sprintf "/var/run/dhclient%s-%s.pid" ipv6' interface
@@ -759,6 +769,12 @@ module Dhclient = struct
759769
let conf = generate_conf ~ipv6 interface options in
760770
Xapi_stdext_unix.Unixext.write_string_to_file (conf_file ~ipv6 interface) conf
761771

772+
let remove_conf_file ?(ipv6=false) interface =
773+
let file = conf_file ~ipv6 interface in
774+
try
775+
Unix.unlink file
776+
with _ -> ()
777+
762778
let start ?(ipv6=false) interface options =
763779
(* If we have a gateway interface, pass it to dhclient-script via -e *)
764780
(* This prevents the default route being set erroneously on CentOS *)

networkd/network_server.ml

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,23 +74,28 @@ let reset_state () =
7474
config := Network_config.read_management_conf ()
7575

7676
let set_gateway_interface _dbg name =
77-
(* Update dhclient conf for interface on changing default gateway.
78-
* If new default gateway is not same as gateway_interface from networkd.db then
79-
* we need to remove gateway information from gateway_interface *)
77+
(* Remove dhclient conf (if any) for the old and new gateway interfaces.
78+
* This ensures that dhclient gets restarted with an updated conf file when
79+
* necessary. *)
8080
begin match !config.gateway_interface with
81-
| Some gateway_iface when name <> gateway_iface ->
82-
let opts =
83-
match !config.dns_interface with
84-
| Some dns_iface when gateway_iface = dns_iface -> [`set_dns]
85-
| _ -> []
86-
in
87-
Dhclient.write_conf_file gateway_iface opts
81+
| Some old_iface when name <> old_iface ->
82+
Dhclient.remove_conf_file name;
83+
Dhclient.remove_conf_file old_iface
8884
| _ -> ()
8985
end;
9086
debug "Setting gateway interface to %s" name;
9187
config := {!config with gateway_interface = Some name}
9288

9389
let set_dns_interface _dbg name =
90+
(* Remove dhclient conf (if any) for the old and new DNS interfaces.
91+
* This ensures that dhclient gets restarted with an updated conf file when
92+
* necessary. *)
93+
begin match !config.dns_interface with
94+
| Some old_iface when name <> old_iface ->
95+
Dhclient.remove_conf_file name;
96+
Dhclient.remove_conf_file old_iface
97+
| _ -> ()
98+
end;
9499
debug "Setting DNS interface to %s" name;
95100
config := {!config with dns_interface = Some name}
96101

@@ -322,7 +327,7 @@ module Interface = struct
322327
Sysctl.set_ipv6_autoconf name false;
323328
Ip.flush_ip_addr ~ipv6:true name;
324329
Ip.set_ipv6_link_local_addr name;
325-
ignore (Dhclient.start ~ipv6:true name [])
330+
ignore (Dhclient.ensure_running ~ipv6:true name [])
326331
| Autoconf6 ->
327332
if Dhclient.is_running ~ipv6:true name then
328333
ignore (Dhclient.stop ~ipv6:true name);
@@ -566,7 +571,7 @@ module Bridge = struct
566571

567572
(* Destroy any existing OVS bridge that isn't the "wanted bridge" and has the
568573
* given VLAN on it. *)
569-
let destroy_existing_vlan_ovs_bridge wanted_bridge (parent, vlan) =
574+
let destroy_existing_vlan_ovs_bridge dbg wanted_bridge (parent, vlan) =
570575
let vlan_bridges =
571576
let raw = Ovs.vsctl ["--bare"; "-f"; "table"; "--"; "--columns=name"; "find"; "port"; "fake_bridge=true"; "tag=" ^ (string_of_int vlan)] in
572577
if raw <> "" then Astring.String.cuts ~empty:false ~sep:"\n" (String.trim raw) else []
@@ -581,6 +586,7 @@ module Bridge = struct
581586
if bridge <> wanted_bridge then begin
582587
debug "Destroying existing bridge %s" bridge;
583588
remove_config bridge;
589+
Interface.set_ipv4_conf dbg bridge None4;
584590
ignore (Ovs.destroy_bridge bridge)
585591
end
586592
) existing_bridges
@@ -595,6 +601,7 @@ module Bridge = struct
595601
debug "Destroying existing bridge %s" bridge;
596602
Interface.bring_down dbg bridge;
597603
remove_config bridge;
604+
Interface.set_ipv4_conf dbg bridge None4;
598605
List.iter (fun dev ->
599606
Brctl.destroy_port bridge dev;
600607
) ifaces_on_bridge;
@@ -654,7 +661,7 @@ module Bridge = struct
654661
None)
655662
in
656663
let old_igmp_snooping = Ovs.get_mcast_snooping_enable ~name in
657-
Xapi_stdext_monadic.Opt.iter (destroy_existing_vlan_ovs_bridge name) vlan;
664+
Xapi_stdext_monadic.Opt.iter (destroy_existing_vlan_ovs_bridge dbg name) vlan;
658665
ignore (Ovs.create_bridge ?mac ~fail_mode ?external_id ?disable_in_band ?igmp_snooping
659666
vlan vlan_bug_workaround name);
660667
if igmp_snooping = Some true && not old_igmp_snooping then

0 commit comments

Comments
 (0)