go.ligato.io/vpp-agent/v3@v3.5.0/tests/integration/vpp/020_routes_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 vpp 16 17 import ( 18 "net" 19 "testing" 20 21 "go.ligato.io/cn-infra/v2/logging/logrus" 22 23 netalloc_mock "go.ligato.io/vpp-agent/v3/plugins/netalloc/mock" 24 "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx" 25 ifplugin_vppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/vppcalls" 26 l3plugin_vppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vppcalls" 27 "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vrfidx" 28 vpp_l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" 29 30 _ "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin" 31 ) 32 33 func TestRouteDumpDefaults(t *testing.T) { 34 ctx := setupVPP(t) 35 defer ctx.teardownVPP() 36 37 ifIndexes := ifaceidx.NewIfaceIndex(logrus.NewLogger("test-if"), "test-if") 38 vrfIndexes := vrfidx.NewVRFIndex(logrus.NewLogger("test-vrf"), "test-vrf") 39 vrfIndexes.Put("vrf1-ipv4", &vrfidx.VRFMetadata{Index: 0, Protocol: vpp_l3.VrfTable_IPV4}) 40 vrfIndexes.Put("vrf1-ipv6", &vrfidx.VRFMetadata{Index: 0, Protocol: vpp_l3.VrfTable_IPV6}) 41 42 h := l3plugin_vppcalls.CompatibleL3VppHandler(ctx.vppClient, ifIndexes, vrfIndexes, 43 netalloc_mock.NewMockNetAlloc(), logrus.NewLogger("test")) 44 45 routes, err := h.DumpRoutes() 46 if err != nil { 47 t.Fatalf("dumping routes failed: %v", err) 48 } 49 t.Logf("%d routes dumped", len(routes)) 50 51 var hasIPv4, hasIPv6 bool 52 for _, route := range routes { 53 t.Logf(" - route: %+v", route.Route) 54 55 ip, _, err := net.ParseCIDR(route.Route.DstNetwork) 56 if err != nil { 57 t.Fatalf("invalid dst network: %v", route.Route.DstNetwork) 58 } 59 if ip.To4() == nil { 60 hasIPv4 = true 61 } else { 62 hasIPv6 = true 63 } 64 } 65 66 if !hasIPv4 || !hasIPv6 { 67 t.Fatalf("expected dump to contain both IPv4 and IPv6 routes") 68 } 69 } 70 71 func TestRouteIP4(t *testing.T) { 72 test := setupVPP(t) 73 defer test.teardownVPP() 74 75 ih := ifplugin_vppcalls.CompatibleInterfaceVppHandler(test.vppClient, logrus.NewLogger("test")) 76 const ifName = "loop1" 77 ifIdx, err := ih.AddLoopbackInterface(ifName) 78 if err != nil { 79 t.Fatalf("creating interface failed: %v", err) 80 } 81 t.Logf("interface created %v", ifIdx) 82 83 ifIndexes := ifaceidx.NewIfaceIndex(logrus.NewLogger("test-iface1"), "test-iface1") 84 ifIndexes.Put(ifName, &ifaceidx.IfaceMetadata{ 85 SwIfIndex: ifIdx, 86 }) 87 88 var vrfMetaIdx uint32 89 vrfIndexes := vrfidx.NewVRFIndex(logrus.NewLogger("test-vrf"), "test-vrf") 90 vrfIndexes.Put("vrf1-ipv4-vrf0", &vrfidx.VRFMetadata{Index: vrfMetaIdx, Protocol: vpp_l3.VrfTable_IPV4}) 91 92 h := l3plugin_vppcalls.CompatibleL3VppHandler(test.vppClient, ifIndexes, vrfIndexes, 93 netalloc_mock.NewMockNetAlloc(), logrus.NewLogger("test")) 94 95 routes, errx := h.DumpRoutes() 96 if errx != nil { 97 t.Fatalf("dumping routes failed: %v", err) 98 } 99 routesCnt := len(routes) 100 t.Logf("%d routes dumped", routesCnt) 101 102 newRoute := &vpp_l3.Route{VrfId: 0, DstNetwork: "192.168.10.0/24", NextHopAddr: "192.168.30.1", OutgoingInterface: ifName} 103 err = h.VppAddRoute(test.Ctx, newRoute) 104 if err != nil { 105 t.Fatalf("adding route failed: %v", err) 106 } 107 t.Logf("route added: %+v", newRoute) 108 109 routes, err = h.DumpRoutes() 110 routesCnt2 := len(routes) 111 if err != nil { 112 t.Fatalf("dumping routes failed: %v", err) 113 } 114 t.Logf("%d routes dumped", routesCnt2) 115 116 if routesCnt+1 != routesCnt2 { 117 t.Errorf("Number of routes after adding of one route is not incremented by 1") 118 } 119 120 newRouteIsPresent := false 121 for _, route := range routes { 122 if (route.Route.DstNetwork == newRoute.DstNetwork) && (route.Route.NextHopAddr == newRoute.NextHopAddr) && (route.Route.OutgoingInterface == newRoute.OutgoingInterface) { 123 newRouteIsPresent = true 124 break 125 } 126 } 127 if !newRouteIsPresent { 128 t.Error("Added route is not present in route dump") 129 } 130 131 err = h.VppDelRoute(test.Ctx, newRoute) 132 if err != nil { 133 t.Fatalf("deleting route failed: %v", err) 134 } 135 t.Logf("route deleted") 136 137 routes, err = h.DumpRoutes() 138 routesCnt3 := len(routes) 139 if err != nil { 140 t.Fatalf("dumping routes failed: %v", err) 141 } 142 t.Logf("%d routes dumped", routesCnt3) 143 if routesCnt2-1 != routesCnt3 { 144 t.Errorf("Number of routes after deleting of one route is not decremented by 1") 145 } 146 147 for _, route := range routes { 148 if (route.Route.DstNetwork == newRoute.DstNetwork) && (route.Route.NextHopAddr == newRoute.NextHopAddr) && (route.Route.OutgoingInterface == newRoute.OutgoingInterface) { 149 t.Error("Added route is still present in route dump - should be deleted") 150 } 151 } 152 153 vrfMetaIdx = 2 154 err = h.AddVrfTable(&vpp_l3.VrfTable{Id: vrfMetaIdx, Protocol: vpp_l3.VrfTable_IPV4, Label: "table1"}) 155 if err != nil { 156 t.Fatalf("creating vrf table failed: %v", err) 157 } 158 t.Logf("vrf table 2 created") 159 vrfIndexes.Put("vrf1-ipv4-vrf2", &vrfidx.VRFMetadata{Index: vrfMetaIdx, Protocol: vpp_l3.VrfTable_IPV4}) 160 161 routes, errx = h.DumpRoutes() 162 if errx != nil { 163 t.Fatalf("dumping routes failed: %v", err) 164 } 165 routesCnt = len(routes) 166 t.Logf("%d routes dumped", routesCnt) 167 168 newRoute = &vpp_l3.Route{VrfId: 2, DstNetwork: "192.168.10.0/24", NextHopAddr: "192.168.30.1", OutgoingInterface: ifName} 169 err = h.VppAddRoute(test.Ctx, newRoute) 170 if err != nil { 171 t.Fatalf("adding route failed: %v", err) 172 } 173 t.Logf("route added: %+v", newRoute) 174 175 routes, err = h.DumpRoutes() 176 routesCnt2 = len(routes) 177 if err != nil { 178 t.Fatalf("dumping routes failed: %v", err) 179 } 180 t.Logf("%d routes dumped", routesCnt2) 181 182 if routesCnt+1 != routesCnt2 { 183 t.Errorf("Number of routes after adding of one route is not incremented by 1") 184 } 185 186 newRouteIsPresent = false 187 for _, route := range routes { 188 if (route.Route.DstNetwork == newRoute.DstNetwork) && (route.Route.NextHopAddr == newRoute.NextHopAddr) && (route.Route.OutgoingInterface == newRoute.OutgoingInterface) { 189 newRouteIsPresent = true 190 break 191 } 192 } 193 if !newRouteIsPresent { 194 t.Error("Added route is not present in route dump") 195 } 196 197 err = h.VppDelRoute(test.Ctx, newRoute) 198 if err != nil { 199 t.Fatalf("deleting route failed: %v", err) 200 } 201 t.Logf("route deleted") 202 203 routes, err = h.DumpRoutes() 204 routesCnt3 = len(routes) 205 if err != nil { 206 t.Fatalf("dumping routes failed: %v", err) 207 } 208 t.Logf("%d routes dumped", routesCnt3) 209 if routesCnt2-1 != routesCnt3 { 210 t.Errorf("Number of routes after deleting of one route is not decremented by 1") 211 } 212 213 for _, route := range routes { 214 if (route.Route.DstNetwork == newRoute.DstNetwork) && (route.Route.NextHopAddr == newRoute.NextHopAddr) && (route.Route.OutgoingInterface == newRoute.OutgoingInterface) { 215 t.Error("Added route is still present in route dump - should be deleted") 216 } 217 } 218 } 219 220 func TestRouteIP6(t *testing.T) { 221 test := setupVPP(t) 222 defer test.teardownVPP() 223 224 ih := ifplugin_vppcalls.CompatibleInterfaceVppHandler(test.vppClient, logrus.NewLogger("test")) 225 const ifName = "loop1" 226 ifIdx, err := ih.AddLoopbackInterface(ifName) 227 if err != nil { 228 t.Fatalf("creating interface failed: %v", err) 229 } 230 t.Logf("interface created %v", ifIdx) 231 232 ifIndexes := ifaceidx.NewIfaceIndex(logrus.NewLogger("test-iface1"), "test-iface1") 233 ifIndexes.Put(ifName, &ifaceidx.IfaceMetadata{ 234 SwIfIndex: ifIdx, 235 }) 236 237 var vrfMetaIdx uint32 238 vrfIndexes := vrfidx.NewVRFIndex(logrus.NewLogger("test-vrf"), "test-vrf") 239 vrfIndexes.Put("vrf1-ipv6-vrf0", &vrfidx.VRFMetadata{Index: vrfMetaIdx, Protocol: vpp_l3.VrfTable_IPV6}) 240 241 h := l3plugin_vppcalls.CompatibleL3VppHandler(test.vppClient, ifIndexes, vrfIndexes, 242 netalloc_mock.NewMockNetAlloc(), logrus.NewLogger("test")) 243 244 routes, errx := h.DumpRoutes() 245 if errx != nil { 246 t.Fatalf("dumping routes failed: %v", err) 247 } 248 routesCnt := len(routes) 249 t.Logf("%d routes dumped", routesCnt) 250 251 newRoute := &vpp_l3.Route{VrfId: 0, DstNetwork: "fd30:0:0:1::/64", NextHopAddr: "fd31::1:1:0:0:1", OutgoingInterface: ifName} 252 err = h.VppAddRoute(test.Ctx, newRoute) 253 if err != nil { 254 t.Fatalf("adding route failed: %v", err) 255 } 256 t.Logf("route added: %+v", newRoute) 257 258 routes, err = h.DumpRoutes() 259 routesCnt2 := len(routes) 260 if err != nil { 261 t.Fatalf("dumping routes failed: %v", err) 262 } 263 t.Logf("%d routes dumped", routesCnt2) 264 265 if routesCnt+1 != routesCnt2 { 266 t.Errorf("Number of routes after adding of one route is not incremented by 1") 267 } 268 269 newRouteIsPresent := false 270 for _, route := range routes { 271 if (route.Route.DstNetwork == newRoute.DstNetwork) && (route.Route.NextHopAddr == newRoute.NextHopAddr) && (route.Route.OutgoingInterface == newRoute.OutgoingInterface) { 272 newRouteIsPresent = true 273 } 274 } 275 if !newRouteIsPresent { 276 t.Error("Added route is not present in route dump") 277 } 278 279 err = h.VppDelRoute(test.Ctx, newRoute) 280 if err != nil { 281 t.Fatalf("deleting route failed: %v", err) 282 } 283 t.Logf("route deleted") 284 285 routes, err = h.DumpRoutes() 286 routesCnt3 := len(routes) 287 if err != nil { 288 t.Fatalf("dumping routes failed: %v", err) 289 } 290 t.Logf("%d routes dumped", routesCnt3) 291 if routesCnt2-1 != routesCnt3 { 292 t.Errorf("Number of routes after deleting of one route is not decremented by 1") 293 } 294 295 for _, route := range routes { 296 if (route.Route.DstNetwork == newRoute.DstNetwork) && (route.Route.NextHopAddr == newRoute.NextHopAddr) && (route.Route.OutgoingInterface == newRoute.OutgoingInterface) { 297 t.Error("Added route is still present in route dump - should be deleted") 298 } 299 } 300 301 vrfMetaIdx = 2 302 err = h.AddVrfTable(&vpp_l3.VrfTable{Id: vrfMetaIdx, Protocol: vpp_l3.VrfTable_IPV6, Label: "table1"}) 303 if err != nil { 304 t.Fatalf("creating vrf table failed: %v", err) 305 } 306 t.Logf("vrf table 2 created") 307 vrfIndexes.Put("vrf1-ipv6-vrf2", &vrfidx.VRFMetadata{Index: vrfMetaIdx, Protocol: vpp_l3.VrfTable_IPV6}) 308 309 routes, errx = h.DumpRoutes() 310 if errx != nil { 311 t.Fatalf("dumping routes failed: %v", err) 312 } 313 routesCnt = len(routes) 314 t.Logf("%d routes dumped", routesCnt) 315 316 newRoute = &vpp_l3.Route{VrfId: 2, DstNetwork: "fd30:0:0:1::/64", NextHopAddr: "fd31::1:1:0:0:1", OutgoingInterface: ifName} 317 err = h.VppAddRoute(test.Ctx, newRoute) 318 if err != nil { 319 t.Fatalf("adding route failed: %v", err) 320 } 321 t.Logf("route added: %+v", newRoute) 322 323 routes, err = h.DumpRoutes() 324 routesCnt2 = len(routes) 325 if err != nil { 326 t.Fatalf("dumping routes failed: %v", err) 327 } 328 t.Logf("%d routes dumped", routesCnt2) 329 330 if routesCnt+1 != routesCnt2 { 331 t.Errorf("Number of routes after adding of one route is not incremented by 1") 332 } 333 334 newRouteIsPresent = false 335 for _, route := range routes { 336 if (route.Route.DstNetwork == newRoute.DstNetwork) && (route.Route.NextHopAddr == newRoute.NextHopAddr) && (route.Route.OutgoingInterface == newRoute.OutgoingInterface) { 337 newRouteIsPresent = true 338 } 339 } 340 if !newRouteIsPresent { 341 t.Error("Added route is not present in route dump") 342 } 343 344 err = h.VppDelRoute(test.Ctx, newRoute) 345 if err != nil { 346 t.Fatalf("deleting route failed: %v", err) 347 } 348 t.Logf("route deleted") 349 350 routes, err = h.DumpRoutes() 351 routesCnt3 = len(routes) 352 if err != nil { 353 t.Fatalf("dumping routes failed: %v", err) 354 } 355 t.Logf("%d routes dumped", routesCnt3) 356 if routesCnt2-1 != routesCnt3 { 357 t.Errorf("Number of routes after deleting of one route is not decremented by 1") 358 } 359 360 for _, route := range routes { 361 if (route.Route.DstNetwork == newRoute.DstNetwork) && (route.Route.NextHopAddr == newRoute.NextHopAddr) && (route.Route.OutgoingInterface == newRoute.OutgoingInterface) { 362 t.Error("Added route is still present in route dump - should be deleted") 363 } 364 } 365 }