go.ligato.io/vpp-agent/v3@v3.5.0/tests/e2e/020_netalloc_test.go (about) 1 // Copyright (c) 2019 Cisco and/or its affiliates. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at: 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package e2e 16 17 import ( 18 "context" 19 "testing" 20 21 . "github.com/onsi/gomega" 22 23 "go.ligato.io/vpp-agent/v3/proto/ligato/kvscheduler" 24 linux_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/linux/interfaces" 25 linux_l3 "go.ligato.io/vpp-agent/v3/proto/ligato/linux/l3" 26 linux_namespace "go.ligato.io/vpp-agent/v3/proto/ligato/linux/namespace" 27 "go.ligato.io/vpp-agent/v3/proto/ligato/netalloc" 28 vpp_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" 29 vpp_l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" 30 . "go.ligato.io/vpp-agent/v3/tests/e2e/e2etest" 31 ) 32 33 // test IP address allocation using the netalloc plugin for VPP+Linux interfaces, 34 // Linux routes and Linux ARPs in a topology where the interface is a neighbour 35 // of the associated GW. 36 // 37 // topology + addressing: 38 // 39 // VPP loop (192.168.10.1/24) <--> VPP tap (192.168.11.1/24) <--> Linux tap (192.168.11.2/24) 40 // 41 // topology + addressing AFTER CHANGE: 42 // 43 // VPP loop (192.168.20.1/24) <--> VPP tap (192.168.12.1/24) <--> Linux tap (192.168.12.2/24) 44 func TestIPWithNeighGW(t *testing.T) { 45 ctx := Setup(t) 46 defer ctx.Teardown() 47 48 const ( 49 networkName = "net1" 50 vppLoopName = "vpp-loop" 51 vppTapName = "vpp-tap" 52 linuxTapName = "linux-tap" 53 linuxTapHostname = "tap" 54 vppLoopIP = "192.168.10.1" 55 vppLoopIP2 = "192.168.20.1" 56 vppTapIP = "192.168.11.1" 57 vppTapIP2 = "192.168.12.1" 58 vppTapHw = "aa:aa:aa:bb:bb:bb" 59 linuxTapIP = "192.168.11.2" 60 linuxTapIP2 = "192.168.12.2" 61 linuxTapHw = "cc:cc:cc:dd:dd:dd" 62 netMask = "/24" 63 msName = "microservice1" 64 ) 65 66 // ------- addresses: 67 68 vppLoopAddr := &netalloc.IPAllocation{ 69 NetworkName: networkName, 70 InterfaceName: vppLoopName, 71 Address: vppLoopIP + netMask, 72 } 73 74 vppTapAddr := &netalloc.IPAllocation{ 75 NetworkName: networkName, 76 InterfaceName: vppTapName, 77 Address: vppTapIP + netMask, 78 Gw: linuxTapIP, 79 } 80 81 linuxTapAddr := &netalloc.IPAllocation{ 82 NetworkName: networkName, 83 InterfaceName: linuxTapName, 84 Address: linuxTapIP + netMask, 85 Gw: vppTapIP, 86 } 87 88 // ------- network items: 89 90 vppLoop := &vpp_interfaces.Interface{ 91 Name: vppLoopName, 92 Type: vpp_interfaces.Interface_SOFTWARE_LOOPBACK, 93 Enabled: true, 94 IpAddresses: []string{"alloc:" + networkName}, 95 } 96 97 vppTap := &vpp_interfaces.Interface{ 98 Name: vppTapName, 99 Type: vpp_interfaces.Interface_TAP, 100 Enabled: true, 101 IpAddresses: []string{"alloc:" + networkName}, 102 PhysAddress: vppTapHw, 103 Link: &vpp_interfaces.Interface_Tap{ 104 Tap: &vpp_interfaces.TapLink{ 105 Version: 2, 106 ToMicroservice: MsNamePrefix + msName, 107 }, 108 }, 109 } 110 111 linuxTap := &linux_interfaces.Interface{ 112 Name: linuxTapName, 113 Type: linux_interfaces.Interface_TAP_TO_VPP, 114 Enabled: true, 115 IpAddresses: []string{"alloc:" + networkName}, 116 HostIfName: linuxTapHostname, 117 PhysAddress: linuxTapHw, 118 Link: &linux_interfaces.Interface_Tap{ 119 Tap: &linux_interfaces.TapLink{ 120 VppTapIfName: vppTapName, 121 }, 122 }, 123 Namespace: &linux_namespace.NetNamespace{ 124 Type: linux_namespace.NetNamespace_MICROSERVICE, 125 Reference: MsNamePrefix + msName, 126 }, 127 } 128 129 linuxArp := &linux_l3.ARPEntry{ 130 Interface: linuxTapName, 131 IpAddress: "alloc:" + networkName + "/" + vppTapName, 132 HwAddress: vppTapHw, 133 } 134 135 linuxRoute := &linux_l3.Route{ 136 OutgoingInterface: linuxTapName, 137 Scope: linux_l3.Route_GLOBAL, 138 DstNetwork: "alloc:" + networkName + "/" + vppLoopName, 139 GwAddr: "alloc:" + networkName + "/GW", 140 } 141 142 ctx.StartMicroservice(msName) 143 req := ctx.GenericClient().ChangeRequest() 144 err := req.Update( 145 vppLoopAddr, vppTapAddr, linuxTapAddr, 146 vppLoop, vppTap, linuxTap, 147 linuxArp, linuxRoute, 148 ).Send(context.Background()) 149 ctx.Expect(err).ToNot(HaveOccurred()) 150 151 checkItemsAreConfigured := func(msRestart, withLoopAddr bool) { 152 // configured immediately: 153 if withLoopAddr { 154 ctx.Expect(ctx.GetValueState(vppLoopAddr)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 155 } 156 ctx.Expect(ctx.GetValueState(vppTapAddr)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 157 ctx.Expect(ctx.GetValueState(linuxTapAddr)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 158 ctx.Expect(ctx.GetValueState(vppLoop)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 159 // the rest depends on the microservice 160 if msRestart { 161 ctx.Eventually(ctx.GetValueStateClb(vppTap)).Should(Equal(kvscheduler.ValueState_CONFIGURED)) 162 } else { 163 ctx.Expect(ctx.GetValueState(vppTap)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 164 } 165 ctx.Expect(ctx.GetValueState(linuxTap)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 166 ctx.Expect(ctx.GetValueState(linuxArp)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 167 if withLoopAddr { 168 ctx.Expect(ctx.GetValueState(linuxRoute)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 169 } else { 170 ctx.Expect(ctx.GetValueState(linuxRoute)).To(Equal(kvscheduler.ValueState_PENDING)) 171 } 172 } 173 checkItemsAreConfigured(true, true) 174 175 // check connection with ping 176 ctx.Expect(ctx.PingFromVPP(linuxTapIP)).To(Succeed()) 177 ctx.Expect(ctx.PingFromMs(msName, vppLoopIP)).To(Succeed()) 178 ctx.Expect(ctx.AgentInSync()).To(BeTrue()) 179 180 // restart microservice 181 ctx.StopMicroservice(msName) 182 ctx.StartMicroservice(msName) 183 checkItemsAreConfigured(true, true) 184 185 // check connection with ping (few packets will get lost before tables are refreshed) 186 ctx.PingFromVPP(linuxTapIP) 187 ctx.Expect(ctx.PingFromVPP(linuxTapIP)).To(Succeed()) 188 ctx.Expect(ctx.PingFromMs(msName, vppLoopIP)).To(Succeed()) 189 ctx.Expect(ctx.AgentInSync()).To(BeTrue()) 190 191 // change IP addresses - the network items should be re-created 192 vppLoopAddr.Address = vppLoopIP2 + netMask 193 vppTapAddr.Address = vppTapIP2 + netMask 194 vppTapAddr.Gw = linuxTapIP2 195 linuxTapAddr.Address = linuxTapIP2 + netMask 196 linuxTapAddr.Gw = vppTapIP2 197 198 req = ctx.GenericClient().ChangeRequest() 199 err = req.Update(vppLoopAddr, vppTapAddr, linuxTapAddr).Send(context.Background()) 200 ctx.Expect(err).ToNot(HaveOccurred()) 201 checkItemsAreConfigured(false, true) 202 203 // check connection with ping 204 ctx.Expect(ctx.PingFromVPP(linuxTapIP)).NotTo(Succeed()) 205 206 ctx.Expect(ctx.PingFromMs(msName, vppLoopIP)).NotTo(Succeed()) 207 ctx.Expect(ctx.PingFromVPP(linuxTapIP2)).To(Succeed()) 208 ctx.Expect(ctx.PingFromMs(msName, vppLoopIP2)).To(Succeed()) 209 ctx.Expect(ctx.AgentInSync()).To(BeTrue()) 210 211 // de-allocate loopback IP - the connection should not work anymore 212 req = ctx.GenericClient().ChangeRequest() 213 err = req.Delete(vppLoopAddr).Send(context.Background()) 214 ctx.Expect(err).ToNot(HaveOccurred()) 215 216 // loopback is still created but without IP and route is pending 217 checkItemsAreConfigured(false, false) 218 219 // can ping linux TAP from VPP, but cannot ping loopback 220 ctx.Expect(ctx.PingFromVPP(linuxTapIP2)).To(Succeed()) 221 ctx.Expect(ctx.PingFromMs(msName, vppLoopIP2)).NotTo(Succeed()) 222 223 // TODO: not in-sync - the list of IP addresses is updated in the metadata 224 // - we need to figure out how to get rid of this and how to solve VRF-related 225 // dependencies with netalloc'd IP addresses 226 //Expect(ctx.agentInSync()).To(BeTrue()) 227 } 228 229 // test IP address allocation using the netalloc plugin for VPP+Linux interfaces, 230 // Linux routes and Linux ARPs in a topology where the interface is NOT a neighbour 231 // of the associated GW. 232 // 233 // topology + addressing (note the single-host network mask for Linux TAP): 234 // 235 // VPP loop (192.168.10.1/24) <--> VPP tap (192.168.11.1/24) <--> Linux tap (192.168.11.2/32) 236 // 237 // topology + addressing AFTER CHANGE: 238 // 239 // VPP loop (192.168.20.1/24) <--> VPP tap (192.168.12.1/24) <--> Linux tap (192.168.12.2/32) 240 func TestIPWithNonLocalGW(t *testing.T) { 241 ctx := Setup(t) 242 defer ctx.Teardown() 243 244 const ( 245 networkName = "net1" 246 vppLoopName = "vpp-loop" 247 vppTapName = "vpp-tap" 248 linuxTapName = "linux-tap" 249 linuxTapHostname = "tap" 250 vppLoopIP = "192.168.10.1" 251 vppLoopIP2 = "192.168.20.1" 252 vppTapIP = "192.168.11.1" 253 vppTapIP2 = "192.168.12.1" 254 vppTapHw = "aa:aa:aa:bb:bb:bb" 255 linuxTapIP = "192.168.11.2" 256 linuxTapIP2 = "192.168.12.2" 257 linuxTapHw = "cc:cc:cc:dd:dd:dd" 258 vppNetMask = "/24" 259 linuxNetMask = "/32" 260 msName = "microservice1" 261 ) 262 263 // ------- addresses: 264 265 vppLoopAddr := &netalloc.IPAllocation{ 266 NetworkName: networkName, 267 InterfaceName: vppLoopName, 268 Address: vppLoopIP + vppNetMask, 269 } 270 271 vppTapAddr := &netalloc.IPAllocation{ 272 NetworkName: networkName, 273 InterfaceName: vppTapName, 274 Address: vppTapIP + vppNetMask, 275 Gw: linuxTapIP, 276 } 277 278 linuxTapAddr := &netalloc.IPAllocation{ 279 NetworkName: networkName, 280 InterfaceName: linuxTapName, 281 Address: linuxTapIP + linuxNetMask, 282 Gw: vppTapIP, 283 } 284 285 // ------- network items: 286 287 vppLoop := &vpp_interfaces.Interface{ 288 Name: vppLoopName, 289 Type: vpp_interfaces.Interface_SOFTWARE_LOOPBACK, 290 Enabled: true, 291 IpAddresses: []string{"alloc:" + networkName}, 292 } 293 294 vppTap := &vpp_interfaces.Interface{ 295 Name: vppTapName, 296 Type: vpp_interfaces.Interface_TAP, 297 Enabled: true, 298 IpAddresses: []string{"alloc:" + networkName}, 299 PhysAddress: vppTapHw, 300 Link: &vpp_interfaces.Interface_Tap{ 301 Tap: &vpp_interfaces.TapLink{ 302 Version: 2, 303 ToMicroservice: MsNamePrefix + msName, 304 }, 305 }, 306 } 307 308 linuxTap := &linux_interfaces.Interface{ 309 Name: linuxTapName, 310 Type: linux_interfaces.Interface_TAP_TO_VPP, 311 Enabled: true, 312 IpAddresses: []string{"alloc:" + networkName}, 313 HostIfName: linuxTapHostname, 314 PhysAddress: linuxTapHw, 315 Link: &linux_interfaces.Interface_Tap{ 316 Tap: &linux_interfaces.TapLink{ 317 VppTapIfName: vppTapName, 318 }, 319 }, 320 Namespace: &linux_namespace.NetNamespace{ 321 Type: linux_namespace.NetNamespace_MICROSERVICE, 322 Reference: MsNamePrefix + msName, 323 }, 324 } 325 326 linuxArp := &linux_l3.ARPEntry{ 327 Interface: linuxTapName, 328 IpAddress: "alloc:" + networkName + "/" + vppTapName, 329 HwAddress: vppTapHw, 330 } 331 332 linuxRoute := &linux_l3.Route{ 333 OutgoingInterface: linuxTapName, 334 Scope: linux_l3.Route_GLOBAL, 335 DstNetwork: "alloc:" + networkName + "/" + vppLoopName, 336 GwAddr: "alloc:" + networkName + "/GW", 337 } 338 339 // link route is necessary to route the GW of the linux TAP interface 340 linuxLinkRoute := &linux_l3.Route{ 341 OutgoingInterface: linuxTapName, 342 Scope: linux_l3.Route_LINK, 343 DstNetwork: "alloc:" + networkName + "/" + linuxTapName + "/GW", 344 } 345 346 ctx.StartMicroservice(msName) 347 req := ctx.GenericClient().ChangeRequest() 348 err := req.Update( 349 vppLoopAddr, vppTapAddr, linuxTapAddr, 350 vppLoop, vppTap, linuxTap, 351 linuxArp, linuxRoute, linuxLinkRoute, 352 ).Send(context.Background()) 353 ctx.Expect(err).ToNot(HaveOccurred()) 354 355 checkItemsAreConfigured := func(msRestart, withLinkRoute bool) { 356 // configured immediately: 357 ctx.Expect(ctx.GetValueState(vppLoopAddr)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 358 ctx.Expect(ctx.GetValueState(vppTapAddr)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 359 ctx.Expect(ctx.GetValueState(linuxTapAddr)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 360 ctx.Expect(ctx.GetValueState(vppLoop)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 361 // the rest depends on the microservice 362 if msRestart { 363 ctx.Eventually(ctx.GetValueStateClb(vppTap)).Should(Equal(kvscheduler.ValueState_CONFIGURED)) 364 } else { 365 ctx.Expect(ctx.GetValueState(vppTap)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 366 } 367 ctx.Expect(ctx.GetValueState(linuxTap)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 368 ctx.Expect(ctx.GetValueState(linuxArp)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 369 if withLinkRoute { 370 ctx.Expect(ctx.GetValueState(linuxRoute)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 371 ctx.Expect(ctx.GetValueState(linuxLinkRoute)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 372 } else { 373 ctx.Expect(ctx.GetValueState(linuxRoute)).To(Equal(kvscheduler.ValueState_PENDING)) 374 } 375 } 376 checkItemsAreConfigured(true, true) 377 378 // check connection with ping 379 ctx.Expect(ctx.PingFromVPP(linuxTapIP)).To(Succeed()) 380 ctx.Expect(ctx.PingFromMs(msName, vppLoopIP)).To(Succeed()) 381 ctx.Expect(ctx.AgentInSync()).To(BeTrue()) 382 383 // restart microservice 384 ctx.StopMicroservice(msName) 385 ctx.StartMicroservice(msName) 386 checkItemsAreConfigured(true, true) 387 388 // check connection with ping (few packets will get lost before tables are refreshed) 389 ctx.PingFromVPP(linuxTapIP) 390 ctx.Expect(ctx.PingFromVPP(linuxTapIP)).To(Succeed()) 391 ctx.Expect(ctx.PingFromMs(msName, vppLoopIP)).To(Succeed()) 392 ctx.Expect(ctx.AgentInSync()).To(BeTrue()) 393 394 // change IP addresses - the network items should be re-created 395 vppLoopAddr.Address = vppLoopIP2 + vppNetMask 396 vppTapAddr.Address = vppTapIP2 + vppNetMask 397 vppTapAddr.Gw = linuxTapIP2 398 linuxTapAddr.Address = linuxTapIP2 + linuxNetMask 399 linuxTapAddr.Gw = vppTapIP2 400 401 req = ctx.GenericClient().ChangeRequest() 402 err = req.Update(vppLoopAddr, vppTapAddr, linuxTapAddr).Send(context.Background()) 403 ctx.Expect(err).ToNot(HaveOccurred()) 404 checkItemsAreConfigured(false, true) 405 406 // check connection with ping 407 ctx.Expect(ctx.PingFromVPP(linuxTapIP)).NotTo(Succeed()) 408 409 ctx.Expect(ctx.PingFromMs(msName, vppLoopIP)).NotTo(Succeed()) 410 ctx.Expect(ctx.PingFromVPP(linuxTapIP2)).To(Succeed()) 411 ctx.Expect(ctx.PingFromMs(msName, vppLoopIP2)).To(Succeed()) 412 ctx.Expect(ctx.AgentInSync()).To(BeTrue()) 413 414 // remove link route - this should make the GW for linux TAP non-routable 415 req = ctx.GenericClient().ChangeRequest() 416 err = req.Delete(linuxLinkRoute).Send(context.Background()) 417 ctx.Expect(err).ToNot(HaveOccurred()) 418 419 // the route to VPP is pending 420 checkItemsAreConfigured(false, false) 421 422 // cannot ping anymore from any of the sides 423 ctx.Expect(ctx.PingFromVPP(linuxTapIP2)).NotTo(Succeed()) 424 ctx.Expect(ctx.PingFromMs(msName, vppLoopIP2)).NotTo(Succeed()) 425 ctx.Expect(ctx.AgentInSync()).To(BeTrue()) 426 } 427 428 // test IP address allocation using the netalloc plugin for VPP routes mainly. 429 // 430 // topology + addressing: 431 // 432 // VPP tap (192.168.11.1/24) <--> Linux tap (192.168.11.2/24) <--> Linux loop (192.168.20.1/24, 10.10.10.10/32) 433 // 434 // topology + addressing AFTER CHANGE: 435 // 436 // VPP tap (192.168.12.1/24) <--> Linux tap (192.168.12.2/24) <--> Linux loop (192.168.30.1/24, 10.10.10.10/32) 437 func TestVPPRoutesWithNetalloc(t *testing.T) { 438 ctx := Setup(t) 439 defer ctx.Teardown() 440 441 const ( 442 network1Name = "net1" 443 network2Name = "net2" 444 vppTapName = "vpp-tap" 445 linuxTapName = "linux-tap" 446 linuxTapHostname = "tap" 447 linuxLoopName = "linux-loop" 448 vppTapIP = "192.168.11.1" 449 vppTapIP2 = "192.168.12.1" 450 linuxTapIP = "192.168.11.2" 451 linuxTapIP2 = "192.168.12.2" 452 linuxLoopNet1IP = "192.168.20.1" 453 linuxLoopNet1IP2 = "192.168.30.1" 454 linuxLoopNet2IP = "10.10.10.10" 455 net1Mask = "/24" 456 net2Mask = "/32" 457 msName = "microservice1" 458 ) 459 460 // ------- addresses: 461 462 vppTapAddr := &netalloc.IPAllocation{ 463 NetworkName: network1Name, 464 InterfaceName: vppTapName, 465 Address: vppTapIP + net1Mask, 466 Gw: linuxTapIP, 467 } 468 469 linuxTapAddr := &netalloc.IPAllocation{ 470 NetworkName: network1Name, 471 InterfaceName: linuxTapName, 472 Address: linuxTapIP + net1Mask, 473 Gw: vppTapIP, 474 } 475 476 linuxLoopNet1Addr := &netalloc.IPAllocation{ 477 NetworkName: network1Name, 478 InterfaceName: linuxLoopName, 479 Address: linuxLoopNet1IP + net1Mask, 480 } 481 482 linuxLoopNet2Addr := &netalloc.IPAllocation{ 483 NetworkName: network2Name, 484 InterfaceName: linuxLoopName, 485 Address: linuxLoopNet2IP + net2Mask, 486 } 487 488 // ------- network items: 489 490 vppTap := &vpp_interfaces.Interface{ 491 Name: vppTapName, 492 Type: vpp_interfaces.Interface_TAP, 493 Enabled: true, 494 IpAddresses: []string{"alloc:" + network1Name}, 495 Link: &vpp_interfaces.Interface_Tap{ 496 Tap: &vpp_interfaces.TapLink{ 497 Version: 2, 498 ToMicroservice: MsNamePrefix + msName, 499 }, 500 }, 501 } 502 503 linuxTap := &linux_interfaces.Interface{ 504 Name: linuxTapName, 505 Type: linux_interfaces.Interface_TAP_TO_VPP, 506 Enabled: true, 507 IpAddresses: []string{"alloc:" + network1Name}, 508 HostIfName: linuxTapHostname, 509 Link: &linux_interfaces.Interface_Tap{ 510 Tap: &linux_interfaces.TapLink{ 511 VppTapIfName: vppTapName, 512 }, 513 }, 514 Namespace: &linux_namespace.NetNamespace{ 515 Type: linux_namespace.NetNamespace_MICROSERVICE, 516 Reference: MsNamePrefix + msName, 517 }, 518 } 519 520 linuxLoop := &linux_interfaces.Interface{ 521 Name: linuxLoopName, 522 Type: linux_interfaces.Interface_LOOPBACK, 523 Enabled: true, 524 IpAddresses: []string{ 525 "127.0.0.1/8", "alloc:" + network1Name, "alloc:" + network2Name}, 526 Namespace: &linux_namespace.NetNamespace{ 527 Type: linux_namespace.NetNamespace_MICROSERVICE, 528 Reference: MsNamePrefix + msName, 529 }, 530 } 531 532 vppRouteLoopNet1 := &vpp_l3.Route{ 533 OutgoingInterface: vppTapName, 534 DstNetwork: "alloc:" + network1Name + "/" + linuxLoopName, 535 NextHopAddr: "alloc:" + network1Name + "/GW", 536 } 537 538 vppRouteLoopNet2 := &vpp_l3.Route{ 539 OutgoingInterface: vppTapName, 540 DstNetwork: "alloc:" + network2Name + "/" + linuxLoopName, 541 NextHopAddr: "alloc:" + network1Name + "/GW", 542 } 543 544 ctx.StartMicroservice(msName) 545 req := ctx.GenericClient().ChangeRequest() 546 err := req.Update( 547 vppTapAddr, linuxTapAddr, linuxLoopNet1Addr, linuxLoopNet2Addr, 548 vppTap, linuxTap, linuxLoop, 549 vppRouteLoopNet1, vppRouteLoopNet2, 550 ).Send(context.Background()) 551 ctx.Expect(err).ToNot(HaveOccurred()) 552 553 checkItemsAreConfigured := func(msRestart, withLoopNet2Addr bool) { 554 // configured immediately: 555 if withLoopNet2Addr { 556 ctx.Expect(ctx.GetValueState(linuxLoopNet2Addr)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 557 } 558 ctx.Expect(ctx.GetValueState(vppTapAddr)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 559 ctx.Expect(ctx.GetValueState(linuxTapAddr)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 560 ctx.Expect(ctx.GetValueState(linuxLoopNet1Addr)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 561 // the rest depends on the microservice 562 if msRestart { 563 ctx.Eventually(ctx.GetValueStateClb(vppTap)).Should(Equal(kvscheduler.ValueState_CONFIGURED)) 564 } else { 565 ctx.Expect(ctx.GetValueState(vppTap)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 566 } 567 ctx.Expect(ctx.GetValueState(linuxTap)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 568 ctx.Expect(ctx.GetValueState(linuxLoop)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 569 ctx.Expect(ctx.GetValueState(vppRouteLoopNet1)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 570 if withLoopNet2Addr { 571 ctx.Expect(ctx.GetValueState(vppRouteLoopNet2)).To(Equal(kvscheduler.ValueState_CONFIGURED)) 572 } else { 573 ctx.Expect(ctx.GetValueState(vppRouteLoopNet2)).To(Equal(kvscheduler.ValueState_PENDING)) 574 } 575 } 576 checkItemsAreConfigured(true, true) 577 578 // check connection with ping 579 ctx.Expect(ctx.PingFromVPP(linuxLoopNet1IP)).To(Succeed()) 580 ctx.Expect(ctx.PingFromVPP(linuxLoopNet2IP)).To(Succeed()) 581 ctx.Expect(ctx.AgentInSync()).To(BeTrue()) 582 583 // restart microservice 584 ctx.StopMicroservice(msName) 585 ctx.StartMicroservice(msName) 586 checkItemsAreConfigured(true, true) 587 588 // check connection with ping (few packets will get lost before tables are refreshed) 589 ctx.PingFromVPP(linuxLoopNet1IP) 590 ctx.PingFromVPP(linuxLoopNet2IP) 591 ctx.Expect(ctx.PingFromVPP(linuxLoopNet1IP)).To(Succeed()) 592 ctx.Expect(ctx.PingFromVPP(linuxLoopNet2IP)).To(Succeed()) 593 ctx.Expect(ctx.AgentInSync()).To(BeTrue()) 594 595 // change IP addresses - the network items should be re-created 596 linuxLoopNet1Addr.Address = linuxLoopNet1IP2 + net1Mask 597 vppTapAddr.Address = vppTapIP2 + net1Mask 598 vppTapAddr.Gw = linuxTapIP2 599 linuxTapAddr.Address = linuxTapIP2 + net1Mask 600 linuxTapAddr.Gw = vppTapIP2 601 602 req = ctx.GenericClient().ChangeRequest() 603 err = req.Update(linuxLoopNet1Addr, vppTapAddr, linuxTapAddr).Send(context.Background()) 604 ctx.Expect(err).ToNot(HaveOccurred()) 605 checkItemsAreConfigured(false, true) 606 607 // check connection with ping 608 ctx.Expect(ctx.PingFromVPP(linuxLoopNet1IP)).NotTo(Succeed()) 609 ctx.Expect(ctx.PingFromVPP(linuxLoopNet1IP2)).To(Succeed()) 610 ctx.Expect(ctx.PingFromVPP(linuxLoopNet2IP)).To(Succeed()) 611 ctx.Expect(ctx.AgentInSync()).To(BeTrue()) 612 613 // de-allocate loopback IP in net2 - the connection to that IP should not work anymore 614 req = ctx.GenericClient().ChangeRequest() 615 err = req.Delete(linuxLoopNet2Addr).Send(context.Background()) 616 ctx.Expect(err).ToNot(HaveOccurred()) 617 618 // loopback is still created but without IP and route is pending 619 checkItemsAreConfigured(false, false) 620 621 // can ping loop1, but cannot ping loop2 622 ctx.Expect(ctx.PingFromVPP(linuxLoopNet1IP2)).To(Succeed()) 623 ctx.Expect(ctx.PingFromVPP(linuxLoopNet2IP)).NotTo(Succeed()) 624 ctx.Expect(ctx.AgentInSync()).To(BeTrue()) 625 }