Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions osl/namespace_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,11 @@ func NewSandbox(key string, osCreate, isRestore bool) (Sandbox, error) {
if err != nil {
logrus.Warnf("Failed to set the timeout on the sandbox netlink handle sockets: %v", err)
}

// In live-restore mode, IPV6 entries are getting cleaned up due to below code
// We should retain IPV6 configrations in live-restore mode when Docker Daemon
// comes back. It should work as it is on other cases
// As starting point, disable IPv6 on all interfaces
if !n.isDefault {
if !isRestore && !n.isDefault {
err = setIPv6(n.path, "all", false)
if err != nil {
logrus.Warnf("Failed to disable IPv6 on all interfaces on network namespace %q: %v", n.path, err)
Expand Down
92 changes: 92 additions & 0 deletions osl/sandbox_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,95 @@ func TestSetInterfaceIP(t *testing.T) {
t.Fatalf("Unexpected error: %v", err)
}
}

func TestLiveRestore(t *testing.T) {

defer testutils.SetupTestOSContext(t)()

key, err := newKey(t)
if err != nil {
t.Fatalf("Failed to obtain a key: %v", err)
}

s, err := NewSandbox(key, true, false)
if err != nil {
t.Fatalf("Failed to create a new sandbox: %v", err)
}
runtime.LockOSThread()
defer s.Destroy()

n, ok := s.(*networkNamespace)
if !ok {
t.Fatal(ok)
}
nlh := n.nlHandle

ipv4, _ := types.ParseCIDR("172.30.0.33/24")
ipv6, _ := types.ParseCIDR("2001:db8::44/64")
iface := &nwIface{address: ipv4, addressIPv6: ipv6, ns: n, dstName: "sideA"}

if err := nlh.LinkAdd(&netlink.Veth{
LinkAttrs: netlink.LinkAttrs{Name: "sideA"},
PeerName: "sideB",
}); err != nil {
t.Fatal(err)
}

linkA, err := nlh.LinkByName("sideA")
if err != nil {
t.Fatal(err)
}

linkB, err := nlh.LinkByName("sideB")
if err != nil {
t.Fatal(err)
}

if err := nlh.LinkSetUp(linkA); err != nil {
t.Fatal(err)
}

if err := nlh.LinkSetUp(linkB); err != nil {
t.Fatal(err)
}

if err := setInterfaceIP(nlh, linkA, iface); err != nil {
t.Fatal(err)
}

if err := setInterfaceIPv6(nlh, linkA, iface); err != nil {
t.Fatal(err)
}

err = setInterfaceIP(nlh, linkB, iface)
if err == nil {
t.Fatalf("Expected route conflict error, but succeeded")
}
if !strings.Contains(err.Error(), "conflicts with existing route") {
t.Fatalf("Unexpected error: %v", err)
}

err = setInterfaceIPv6(nlh, linkB, iface)
if err == nil {
t.Fatalf("Expected route conflict error, but succeeded")
}
if !strings.Contains(err.Error(), "conflicts with existing route") {
t.Fatalf("Unexpected error: %v", err)
}

// Create newsandbox with Restore - TRUE
s, err = NewSandbox(key, true, true)
if err != nil {
t.Fatalf("Failed to create a new sandbox: %v", err)
}

// Check if the IPV4 & IPV6 entry present
// If present , we should get error in below call
// It shows us , we don't delete any config in live-restore case
if err := setInterfaceIPv6(nlh, linkA, iface); err == nil {
t.Fatalf("Expected route conflict error, but succeeded for IPV6 ")
}
if err := setInterfaceIP(nlh, linkA, iface); err == nil {
t.Fatalf("Expected route conflict error, but succeeded for IPV4 ")
}
}