Skip to content

Commit 2a99c2d

Browse files
authored
fix(net): stop dhcp client and release all v4 addr on linkdown (#16)
This commit fixes #12 by disabling the udhcpc client when the link goes down, it then removes all the active IPv4 addresses from the deivce. Once the link comes back up, it re-activates the udhcpc client so it can fetch a new IPv4 address for the device. This doesn't make any changes to the IPv6 side of things yet.
1 parent 0b5033f commit 2a99c2d

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

network.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"golang.org/x/net/ipv4"
77
"golang.org/x/net/ipv6"
88
"net"
9+
"os/exec"
910
"time"
1011

1112
"github.com/vishvananda/netlink"
@@ -25,6 +26,23 @@ type LocalIpInfo struct {
2526
MAC string
2627
}
2728

29+
// setDhcpClientState sends signals to udhcpc to change it's current mode
30+
// of operation. Setting active to true will force udhcpc to renew the DHCP lease.
31+
// Setting active to false will put udhcpc into idle mode.
32+
func setDhcpClientState(active bool) {
33+
var signal string;
34+
if active {
35+
signal = "-SIGUSR1"
36+
} else {
37+
signal = "-SIGUSR2"
38+
}
39+
40+
cmd := exec.Command("/usr/bin/killall", signal, "udhcpc");
41+
if err := cmd.Run(); err != nil {
42+
fmt.Printf("network: setDhcpClientState: failed to change udhcpc state: %s\n", err)
43+
}
44+
}
45+
2846
func checkNetworkState() {
2947
iface, err := netlink.LinkByName("eth0")
3048
if err != nil {
@@ -47,9 +65,26 @@ func checkNetworkState() {
4765
fmt.Printf("failed to get addresses for eth0: %v\n", err)
4866
}
4967

68+
// If the link is going down, put udhcpc into idle mode.
69+
// If the link is coming back up, activate udhcpc and force it to renew the lease.
70+
if newState.Up != networkState.Up {
71+
setDhcpClientState(newState.Up)
72+
}
73+
5074
for _, addr := range addrs {
5175
if addr.IP.To4() != nil {
52-
newState.IPv4 = addr.IP.String()
76+
if !newState.Up && networkState.Up {
77+
// If the network is going down, remove all IPv4 addresses from the interface.
78+
fmt.Printf("network: state transitioned to down, removing IPv4 address %s\n", addr.IP.String())
79+
err := netlink.AddrDel(iface, &addr)
80+
if err != nil {
81+
fmt.Printf("network: failed to delete %s", addr.IP.String())
82+
}
83+
84+
newState.IPv4 = "..."
85+
} else {
86+
newState.IPv4 = addr.IP.String()
87+
}
5388
} else if addr.IP.To16() != nil && newState.IPv6 == "" {
5489
newState.IPv6 = addr.IP.String()
5590
}

0 commit comments

Comments
 (0)