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  }