github.com/kata-containers/runtime@v0.0.0-20210505125100-04f29832a923/virtcontainers/network_test.go (about) 1 // Copyright (c) 2016 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 6 package virtcontainers 7 8 import ( 9 "fmt" 10 "net" 11 "os" 12 "reflect" 13 "testing" 14 15 ktu "github.com/kata-containers/runtime/pkg/katatestutils" 16 vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types" 17 "github.com/stretchr/testify/assert" 18 "github.com/vishvananda/netlink" 19 ) 20 21 func TestCreateDeleteNetNS(t *testing.T) { 22 assert := assert.New(t) 23 if tc.NotValid(ktu.NeedRoot()) { 24 t.Skip(testDisabledAsNonRoot) 25 } 26 27 netNSPath, err := createNetNS() 28 assert.NoError(err) 29 assert.NotEmpty(netNSPath) 30 31 _, err = os.Stat(netNSPath) 32 assert.NoError(err) 33 34 err = deleteNetNS(netNSPath) 35 assert.NoError(err) 36 } 37 38 func TestGenerateInterfacesAndRoutes(t *testing.T) { 39 // 40 //Create a couple of addresses 41 // 42 address1 := &net.IPNet{IP: net.IPv4(172, 17, 0, 2), Mask: net.CIDRMask(16, 32)} 43 address2 := &net.IPNet{IP: net.IPv4(182, 17, 0, 2), Mask: net.CIDRMask(16, 32)} 44 address3 := &net.IPNet{IP: net.ParseIP("2001:db8:1::242:ac11:2"), Mask: net.CIDRMask(64, 128)} 45 46 addrs := []netlink.Addr{ 47 {IPNet: address1, Label: "phyaddr1"}, 48 {IPNet: address2, Label: "phyaddr2"}, 49 {IPNet: address3, Label: "phyaddr3"}, 50 } 51 52 // Create a couple of routes: 53 dst2 := &net.IPNet{IP: net.IPv4(172, 17, 0, 0), Mask: net.CIDRMask(16, 32)} 54 src2 := net.IPv4(172, 17, 0, 2) 55 gw2 := net.IPv4(172, 17, 0, 1) 56 57 dstV6 := &net.IPNet{IP: net.ParseIP("2001:db8:1::"), Mask: net.CIDRMask(64, 128)} 58 gatewayV6 := net.ParseIP("2001:db8:1::1") 59 60 routes := []netlink.Route{ 61 {LinkIndex: 329, Dst: nil, Src: nil, Gw: net.IPv4(172, 17, 0, 1), Scope: netlink.Scope(254)}, 62 {LinkIndex: 329, Dst: dst2, Src: src2, Gw: gw2}, 63 {LinkIndex: 329, Dst: dstV6, Src: nil, Gw: nil}, 64 {LinkIndex: 329, Dst: nil, Src: nil, Gw: gatewayV6}, 65 } 66 67 arpMAC, _ := net.ParseMAC("6a:92:3a:59:70:aa") 68 69 neighs := []netlink.Neigh{ 70 {LinkIndex: 329, IP: net.IPv4(192, 168, 0, 101), State: netlink.NUD_PERMANENT, HardwareAddr: arpMAC}, 71 } 72 73 networkInfo := NetworkInfo{ 74 Iface: NetlinkIface{ 75 LinkAttrs: netlink.LinkAttrs{MTU: 1500}, 76 Type: "", 77 }, 78 Addrs: addrs, 79 Routes: routes, 80 Neighbors: neighs, 81 } 82 83 ep0 := &PhysicalEndpoint{ 84 IfaceName: "eth0", 85 HardAddr: net.HardwareAddr{0x02, 0x00, 0xca, 0xfe, 0x00, 0x04}.String(), 86 EndpointProperties: networkInfo, 87 } 88 89 endpoints := []Endpoint{ep0} 90 91 nns := NetworkNamespace{NetNsPath: "foobar", NetNsCreated: true, Endpoints: endpoints} 92 93 resInterfaces, resRoutes, resNeighs, err := generateVCNetworkStructures(nns) 94 95 // 96 // Build expected results: 97 // 98 expectedAddresses := []*vcTypes.IPAddress{ 99 {Family: netlink.FAMILY_V4, Address: "172.17.0.2", Mask: "16"}, 100 {Family: netlink.FAMILY_V4, Address: "182.17.0.2", Mask: "16"}, 101 {Family: netlink.FAMILY_V6, Address: "2001:db8:1::242:ac11:2", Mask: "64"}, 102 } 103 104 expectedInterfaces := []*vcTypes.Interface{ 105 {Device: "eth0", Name: "eth0", IPAddresses: expectedAddresses, Mtu: 1500, HwAddr: "02:00:ca:fe:00:04"}, 106 } 107 108 expectedRoutes := []*vcTypes.Route{ 109 {Dest: "", Gateway: "172.17.0.1", Device: "eth0", Source: "", Scope: uint32(254)}, 110 {Dest: "172.17.0.0/16", Gateway: "172.17.0.1", Device: "eth0", Source: "172.17.0.2"}, 111 {Dest: "2001:db8:1::/64", Gateway: "", Device: "eth0", Source: ""}, 112 {Dest: "", Gateway: "2001:db8:1::1", Device: "eth0", Source: ""}, 113 } 114 115 expectedNeighs := []*vcTypes.ARPNeighbor{ 116 { 117 Device: "eth0", 118 State: netlink.NUD_PERMANENT, 119 LLAddr: "6a:92:3a:59:70:aa", 120 ToIPAddress: &vcTypes.IPAddress{Address: "192.168.0.101", Family: netlink.FAMILY_V4}, 121 }, 122 } 123 124 for _, r := range resRoutes { 125 fmt.Printf("resRoute: %+v\n", r) 126 } 127 128 assert.Nil(t, err, "unexpected failure when calling generateKataInterfacesAndRoutes") 129 assert.True(t, reflect.DeepEqual(resInterfaces, expectedInterfaces), 130 "Interfaces returned didn't match: got %+v, expecting %+v", resInterfaces, expectedInterfaces) 131 assert.True(t, reflect.DeepEqual(resRoutes, expectedRoutes), 132 "Routes returned didn't match: got %+v, expecting %+v", resRoutes, expectedRoutes) 133 assert.True(t, reflect.DeepEqual(resNeighs, expectedNeighs), 134 "ARP Neighbors returned didn't match: got %+v, expecting %+v", resNeighs, expectedNeighs) 135 } 136 137 func TestNetInterworkingModelIsValid(t *testing.T) { 138 tests := []struct { 139 name string 140 n NetInterworkingModel 141 want bool 142 }{ 143 {"Invalid Model", NetXConnectInvalidModel, false}, 144 {"Default Model", NetXConnectDefaultModel, true}, 145 {"TC Filter Model", NetXConnectTCFilterModel, true}, 146 {"Macvtap Model", NetXConnectMacVtapModel, true}, 147 } 148 for _, tt := range tests { 149 t.Run(tt.name, func(t *testing.T) { 150 if got := tt.n.IsValid(); got != tt.want { 151 t.Errorf("NetInterworkingModel.IsValid() = %v, want %v", got, tt.want) 152 } 153 }) 154 } 155 } 156 157 func TestNetInterworkingModelSetModel(t *testing.T) { 158 var n NetInterworkingModel 159 tests := []struct { 160 name string 161 modelName string 162 wantErr bool 163 }{ 164 {"Invalid Model", "Invalid", true}, 165 {"default Model", defaultNetModelStr, false}, 166 {"macvtap Model", macvtapNetModelStr, false}, 167 {"tcfilter Model", tcFilterNetModelStr, false}, 168 {"none Model", noneNetModelStr, false}, 169 } 170 171 for _, tt := range tests { 172 t.Run(tt.name, func(t *testing.T) { 173 if err := n.SetModel(tt.modelName); (err != nil) != tt.wantErr { 174 t.Errorf("NetInterworkingModel.SetModel() error = %v, wantErr %v", err, tt.wantErr) 175 } 176 }) 177 } 178 } 179 180 func TestGenerateRandomPrivateMacAdd(t *testing.T) { 181 assert := assert.New(t) 182 183 addr1, err := generateRandomPrivateMacAddr() 184 assert.NoError(err) 185 186 _, err = net.ParseMAC(addr1) 187 assert.NoError(err) 188 189 addr2, err := generateRandomPrivateMacAddr() 190 assert.NoError(err) 191 192 _, err = net.ParseMAC(addr2) 193 assert.NoError(err) 194 195 assert.NotEqual(addr1, addr2) 196 } 197 198 func TestCreateGetTunTapLink(t *testing.T) { 199 if tc.NotValid(ktu.NeedRoot()) { 200 t.Skip(testDisabledAsNonRoot) 201 } 202 203 assert := assert.New(t) 204 205 netHandle, err := netlink.NewHandle() 206 defer netHandle.Delete() 207 208 assert.NoError(err) 209 210 tapName := "testtap0" 211 tapLink, fds, err := createLink(netHandle, tapName, &netlink.Tuntap{}, 1) 212 assert.NoError(err) 213 assert.NotNil(tapLink) 214 assert.NotZero(len(fds)) 215 216 tapLink, err = getLinkByName(netHandle, tapName, &netlink.Tuntap{}) 217 assert.NoError(err) 218 219 err = netHandle.LinkDel(tapLink) 220 assert.NoError(err) 221 } 222 223 func TestCreateMacVtap(t *testing.T) { 224 if tc.NotValid(ktu.NeedRoot()) { 225 t.Skip(testDisabledAsNonRoot) 226 } 227 228 assert := assert.New(t) 229 230 netHandle, err := netlink.NewHandle() 231 defer netHandle.Delete() 232 233 assert.NoError(err) 234 235 tapName := "testtap0" 236 tapLink, _, err := createLink(netHandle, tapName, &netlink.Tuntap{}, 1) 237 assert.NoError(err) 238 239 attrs := tapLink.Attrs() 240 241 mcLink := &netlink.Macvtap{ 242 Macvlan: netlink.Macvlan{ 243 LinkAttrs: netlink.LinkAttrs{ 244 TxQLen: attrs.TxQLen, 245 ParentIndex: attrs.Index, 246 }, 247 }, 248 } 249 250 macvtapName := "testmc0" 251 _, err = createMacVtap(netHandle, macvtapName, mcLink, 1) 252 assert.NoError(err) 253 254 macvtapLink, err := getLinkByName(netHandle, macvtapName, &netlink.Macvtap{}) 255 assert.NoError(err) 256 257 err = netHandle.LinkDel(macvtapLink) 258 assert.NoError(err) 259 260 tapLink, err = getLinkByName(netHandle, tapName, &netlink.Tuntap{}) 261 assert.NoError(err) 262 263 err = netHandle.LinkDel(tapLink) 264 assert.NoError(err) 265 } 266 267 func TestTcRedirectNetwork(t *testing.T) { 268 if tc.NotValid(ktu.NeedRoot()) { 269 t.Skip(testDisabledAsNonRoot) 270 } 271 272 assert := assert.New(t) 273 274 netHandle, err := netlink.NewHandle() 275 assert.NoError(err) 276 defer netHandle.Delete() 277 278 // Create a test veth interface. 279 vethName := "foo" 280 veth := &netlink.Veth{LinkAttrs: netlink.LinkAttrs{Name: vethName, TxQLen: 200, MTU: 1400}, PeerName: "bar"} 281 282 err = netlink.LinkAdd(veth) 283 assert.NoError(err) 284 285 endpoint, err := createVethNetworkEndpoint(1, vethName, NetXConnectTCFilterModel) 286 assert.NoError(err) 287 288 link, err := netlink.LinkByName(vethName) 289 assert.NoError(err) 290 291 err = netHandle.LinkSetUp(link) 292 assert.NoError(err) 293 294 err = setupTCFiltering(endpoint, 1, true) 295 assert.NoError(err) 296 297 err = removeTCFiltering(endpoint) 298 assert.NoError(err) 299 300 // Remove the veth created for testing. 301 err = netHandle.LinkDel(link) 302 assert.NoError(err) 303 }