github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/osl/sandbox_linux_test.go (about) 1 package osl 2 3 import ( 4 "crypto/rand" 5 "encoding/hex" 6 "io" 7 "net" 8 "os" 9 "path/filepath" 10 "syscall" 11 "testing" 12 "time" 13 14 "github.com/docker/libnetwork/testutils" 15 "github.com/docker/libnetwork/types" 16 "github.com/vishvananda/netlink" 17 "github.com/vishvananda/netlink/nl" 18 "github.com/vishvananda/netns" 19 ) 20 21 const ( 22 vethName1 = "wierdlongname1" 23 vethName2 = "wierdlongname2" 24 vethName3 = "wierdlongname3" 25 vethName4 = "wierdlongname4" 26 sboxIfaceName = "containername" 27 ) 28 29 func generateRandomName(prefix string, size int) (string, error) { 30 id := make([]byte, 32) 31 if _, err := io.ReadFull(rand.Reader, id); err != nil { 32 return "", err 33 } 34 return prefix + hex.EncodeToString(id)[:size], nil 35 } 36 37 func newKey(t *testing.T) (string, error) { 38 name, err := generateRandomName("netns", 12) 39 if err != nil { 40 return "", err 41 } 42 43 name = filepath.Join("/tmp", name) 44 if _, err := os.Create(name); err != nil { 45 return "", err 46 } 47 48 // Set the rpmCleanupPeriod to be low to make the test run quicker 49 gpmLock.Lock() 50 gpmCleanupPeriod = 2 * time.Second 51 gpmLock.Unlock() 52 53 return name, nil 54 } 55 56 func newInfo(hnd *netlink.Handle, t *testing.T) (Sandbox, error) { 57 veth := &netlink.Veth{ 58 LinkAttrs: netlink.LinkAttrs{Name: vethName1, TxQLen: 0}, 59 PeerName: vethName2} 60 if err := hnd.LinkAdd(veth); err != nil { 61 return nil, err 62 } 63 64 // Store the sandbox side pipe interface 65 // This is needed for cleanup on DeleteEndpoint() 66 intf1 := &nwIface{} 67 intf1.srcName = vethName2 68 intf1.dstName = sboxIfaceName 69 70 ip4, addr, err := net.ParseCIDR("192.168.1.100/24") 71 if err != nil { 72 return nil, err 73 } 74 intf1.address = addr 75 intf1.address.IP = ip4 76 77 // ip6, addrv6, err := net.ParseCIDR("2001:DB8::ABCD/48") 78 ip6, addrv6, err := net.ParseCIDR("fe80::2/64") 79 if err != nil { 80 return nil, err 81 } 82 intf1.addressIPv6 = addrv6 83 intf1.addressIPv6.IP = ip6 84 85 _, route, err := net.ParseCIDR("192.168.2.1/32") 86 if err != nil { 87 return nil, err 88 } 89 90 intf1.routes = []*net.IPNet{route} 91 92 intf2 := &nwIface{} 93 intf2.srcName = "testbridge" 94 intf2.dstName = sboxIfaceName 95 intf2.bridge = true 96 97 veth = &netlink.Veth{ 98 LinkAttrs: netlink.LinkAttrs{Name: vethName3, TxQLen: 0}, 99 PeerName: vethName4} 100 101 if err := hnd.LinkAdd(veth); err != nil { 102 return nil, err 103 } 104 105 intf3 := &nwIface{} 106 intf3.srcName = vethName4 107 intf3.dstName = sboxIfaceName 108 intf3.master = "testbridge" 109 110 info := &networkNamespace{iFaces: []*nwIface{intf1, intf2, intf3}} 111 112 info.gw = net.ParseIP("192.168.1.1") 113 // sinfo.GatewayIPv6 = net.ParseIP("2001:DB8::1") 114 info.gwv6 = net.ParseIP("fe80::1") 115 116 return info, nil 117 } 118 119 func verifySandbox(t *testing.T, s Sandbox, ifaceSuffixes []string) { 120 _, ok := s.(*networkNamespace) 121 if !ok { 122 t.Fatalf("The sandox interface returned is not of type networkNamespace") 123 } 124 125 sbNs, err := netns.GetFromPath(s.Key()) 126 if err != nil { 127 t.Fatalf("Failed top open network namespace path %q: %v", s.Key(), err) 128 } 129 defer sbNs.Close() 130 131 nh, err := netlink.NewHandleAt(sbNs) 132 if err != nil { 133 t.Fatal(err) 134 } 135 defer nh.Delete() 136 137 for _, suffix := range ifaceSuffixes { 138 _, err = nh.LinkByName(sboxIfaceName + suffix) 139 if err != nil { 140 t.Fatalf("Could not find the interface %s inside the sandbox: %v", 141 sboxIfaceName+suffix, err) 142 } 143 } 144 } 145 146 func verifyCleanup(t *testing.T, s Sandbox, wait bool) { 147 if wait { 148 time.Sleep(time.Duration(gpmCleanupPeriod * 2)) 149 } 150 151 if _, err := os.Stat(s.Key()); err == nil { 152 if wait { 153 t.Fatalf("The sandbox path %s is not getting cleaned up even after twice the cleanup period", s.Key()) 154 } else { 155 t.Fatalf("The sandbox path %s is not cleaned up after running gc", s.Key()) 156 } 157 } 158 } 159 160 func TestScanStatistics(t *testing.T) { 161 data := 162 "Inter-| Receive | Transmit\n" + 163 " face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed\n" + 164 " eth0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + 165 " wlan0: 7787685 11141 0 0 0 0 0 0 1681390 7220 0 0 0 0 0 0\n" + 166 " lo: 783782 1853 0 0 0 0 0 0 783782 1853 0 0 0 0 0 0\n" + 167 "lxcbr0: 0 0 0 0 0 0 0 0 9006 61 0 0 0 0 0 0\n" 168 169 i := &types.InterfaceStatistics{} 170 171 if err := scanInterfaceStats(data, "wlan0", i); err != nil { 172 t.Fatal(err) 173 } 174 if i.TxBytes != 1681390 || i.TxPackets != 7220 || i.RxBytes != 7787685 || i.RxPackets != 11141 { 175 t.Fatalf("Error scanning the statistics") 176 } 177 178 if err := scanInterfaceStats(data, "lxcbr0", i); err != nil { 179 t.Fatal(err) 180 } 181 if i.TxBytes != 9006 || i.TxPackets != 61 || i.RxBytes != 0 || i.RxPackets != 0 { 182 t.Fatalf("Error scanning the statistics") 183 } 184 } 185 186 func TestDisableIPv6DAD(t *testing.T) { 187 if testutils.RunningOnCircleCI() { 188 t.Skipf("Skipping as not supported on CIRCLE CI kernel") 189 } 190 191 defer testutils.SetupTestOSContext(t)() 192 193 ipv6, _ := types.ParseCIDR("2001:db8::44/64") 194 iface := &nwIface{addressIPv6: ipv6} 195 196 veth := &netlink.Veth{ 197 LinkAttrs: netlink.LinkAttrs{Name: "sideA"}, 198 PeerName: "sideB", 199 } 200 nlh, err := netlink.NewHandle(syscall.NETLINK_ROUTE) 201 if err != nil { 202 t.Fatal(err) 203 } 204 err = nlh.LinkAdd(veth) 205 if err != nil { 206 t.Fatal(err) 207 } 208 209 link, err := nlh.LinkByName("sideA") 210 if err != nil { 211 t.Fatal(err) 212 } 213 214 err = setInterfaceIPv6(nlh, link, iface) 215 if err != nil { 216 t.Fatal(err) 217 } 218 219 addrList, err := nlh.AddrList(link, nl.FAMILY_V6) 220 if err != nil { 221 t.Fatal(err) 222 } 223 224 if addrList[0].Flags&syscall.IFA_F_NODAD == 0 { 225 t.Fatalf("Unexpected interface flags: 0x%x. Expected to contain 0x%x", addrList[0].Flags, syscall.IFA_F_NODAD) 226 } 227 }