Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ require (
github.com/vishvananda/netlink v1.1.0
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae
google.golang.org/grpc v1.38.0
google.golang.org/protobuf v1.26.0
)
1 change: 1 addition & 0 deletions internal/imports/imports_linux.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions internal/tests/routes/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) 2021 Cisco and/or its affiliates.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package routes provides a simple cahin element for adding routes
package routes

import (
"context"

"google.golang.org/protobuf/types/known/emptypb"

"github.com/networkservicemesh/api/pkg/api/networkservice"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/next"
)

type testRoutesServer struct {
srcRoutes []*networkservice.Route
dstRoutes []*networkservice.Route
}

// NewServer - add routes to response
func NewServer(srcRoutes, dstRoutes []*networkservice.Route) networkservice.NetworkServiceServer {
return &testRoutesServer{
srcRoutes: srcRoutes,
dstRoutes: dstRoutes,
}
}

func (r *testRoutesServer) Request(ctx context.Context, request *networkservice.NetworkServiceRequest) (*networkservice.Connection, error) {
if request.GetConnection() == nil {
request.Connection = &networkservice.Connection{}
}
if request.GetConnection().GetContext() == nil {
request.GetConnection().Context = &networkservice.ConnectionContext{}
}
if request.GetConnection().GetContext().GetIpContext() == nil {
request.GetConnection().GetContext().IpContext = &networkservice.IPContext{}
}
request.GetConnection().GetContext().GetIpContext().SrcRoutes = append(request.GetConnection().GetContext().GetIpContext().SrcRoutes, r.srcRoutes...)
request.GetConnection().GetContext().GetIpContext().DstRoutes = append(request.GetConnection().GetContext().GetIpContext().DstRoutes, r.dstRoutes...)
return next.Server(ctx).Request(ctx, request)
}

func (r *testRoutesServer) Close(ctx context.Context, conn *networkservice.Connection) (*emptypb.Empty, error) {
return next.Server(ctx).Close(ctx, conn)
}
32 changes: 31 additions & 1 deletion internal/tests/suite_combinatronics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package tests

import (
"context"
"fmt"
"io/ioutil"
"net"
"net/url"
Expand Down Expand Up @@ -53,30 +54,59 @@ import (
func (f *ForwarderTestSuite) TestCombinations() {
_, prefix1, err := net.ParseCIDR("10.0.0.0/24")
f.Require().NoError(err)
_, prefix2, err := net.ParseCIDR("fc00::/7")
_, prefix2, err := net.ParseCIDR("fc00::/64")
f.Require().NoError(err)
srcRoutes := []*networkservice.Route{}
dstRoutes := []*networkservice.Route{}
for i := 1; i < 6; i++ {
srcRoutes = append(srcRoutes,
&networkservice.Route{
Prefix: fmt.Sprintf("10.0.%d.0/24", i),
},
&networkservice.Route{
Prefix: fmt.Sprintf("fc00:0:%d::/64", i),
},
)
dstRoutes = append(dstRoutes,
&networkservice.Route{
Prefix: fmt.Sprintf("10.0.%d.1/24", i),
},
&networkservice.Route{
Prefix: fmt.Sprintf("fc00:0:%d::1/64", i),
},
)
}

endpoints := map[string]func(ctx context.Context) verifiableEndpoint{
kernel.MECHANISM: func(ctx context.Context) verifiableEndpoint {
return newKernelVerifiableEndpoint(ctx,
prefix1,
prefix2,
srcRoutes,
dstRoutes,
spiffejwt.TokenGeneratorFunc(f.x509source, f.config.MaxTokenLifetime),
)
},
memif.MECHANISM: func(ctx context.Context) verifiableEndpoint {
return newMemifVerifiableEndpoint(ctx, prefix1, prefix2,
srcRoutes,
dstRoutes,
spiffejwt.TokenGeneratorFunc(f.x509source, f.config.MaxTokenLifetime),
f.vppServerConn,
)
},
vxlan.MECHANISM: func(ctx context.Context) verifiableEndpoint {
return newVxlanVerifiableEndpoint(ctx, prefix1, prefix2,
srcRoutes,
dstRoutes,
spiffejwt.TokenGeneratorFunc(f.x509source, f.config.MaxTokenLifetime),
f.vppServerConn,
)
},
wireguard.MECHANISM: func(ctx context.Context) verifiableEndpoint {
return newWireguardVerifiableEndpoint(ctx, prefix1, prefix2,
srcRoutes,
dstRoutes,
spiffejwt.TokenGeneratorFunc(f.x509source, f.config.MaxTokenLifetime),
f.vppServerConn,
)
Expand Down
69 changes: 69 additions & 0 deletions internal/tests/suite_kernel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ import (
"github.com/vishvananda/netns"
"google.golang.org/grpc"

"github.com/networkservicemesh/cmd-forwarder-vpp/internal/tests/routes"
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata"

"github.com/networkservicemesh/api/pkg/api/networkservice"
"github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/cls"
"github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/kernel"
Expand Down Expand Up @@ -74,6 +77,7 @@ type kernelVerifiableEndpoint struct {

func newKernelVerifiableEndpoint(ctx context.Context,
prefix1, prefix2 *net.IPNet,
srcRoutes, dstRoutes []*networkservice.Route,
tokenGenerator token.GeneratorFunc,
) verifiableEndpoint {
rootNSHandle, err := netns.Get()
Expand Down Expand Up @@ -108,6 +112,7 @@ func newKernelVerifiableEndpoint(ctx context.Context,
endpoint.WithAdditionalFunctionality(
point2pointipam.NewServer(prefix1),
point2pointipam.NewServer(prefix2),
routes.NewServer(srcRoutes, dstRoutes),
mechanisms.NewServer(map[string]networkservice.NetworkServiceServer{
kernel.MECHANISM: chain.NewNetworkServiceServer(
kernelmechanism.NewServer(kernelmechanism.WithInterfaceName(endpointNSName)),
Expand All @@ -134,6 +139,9 @@ func (k *kernelVerifiableEndpoint) VerifyConnection(conn *networkservice.Connect
if err := checkKernelInterface(namingConn, conn.GetContext().GetIpContext().GetDstIPNets(), k.endpointNSHandle); err != nil {
return err
}
if err := checkRoutes(namingConn, k.endpointNSHandle, metadata.IsClient(k)); err != nil {
return err
}
for _, ip := range conn.GetContext().GetIpContext().GetSrcIPNets() {
if err := pingKernel(ip, k.endpointNSHandle); err != nil {
return err
Expand Down Expand Up @@ -195,6 +203,9 @@ func (k *kernelVerifiableClient) VerifyConnection(conn *networkservice.Connectio
if err := checkKernelInterface(conn, conn.GetContext().GetIpContext().GetSrcIPNets(), k.clientNSHandle); err != nil {
return err
}
if err := checkRoutes(conn, k.clientNSHandle, metadata.IsClient(k)); err != nil {
return err
}
for _, ip := range conn.GetContext().GetIpContext().GetDstIPNets() {
if err := pingKernel(ip, k.clientNSHandle); err != nil {
return err
Expand Down Expand Up @@ -277,3 +288,61 @@ func pingKernel(ipnet *net.IPNet, handle netns.NsHandle) error {
}
return nil
}

func checkRoutes(conn *networkservice.Connection, nsHandle netns.NsHandle, isClient bool) error {
if mechanism := kernel.ToMechanism(conn.GetMechanism()); mechanism != nil {
curNetNS, err := netns.Get()
if err != nil {
return errors.Wrap(err, "unable to get current netns")
}
netlinkHandle, err := netlink.NewHandleAtFrom(nsHandle, curNetNS)
if err != nil {
return errors.Wrap(err, "unable to get netlink Handle in target netNs")
}
kernelRoutes, err := netlinkHandle.RouteList(nil, netlink.FAMILY_ALL)
if err != nil {
return errors.Wrap(err, "unable to get routes")
}
nsmRoutes := conn.GetContext().GetIpContext().GetDstRoutesWithExplicitNextHop()
if isClient {
nsmRoutes = conn.GetContext().GetIpContext().GetSrcRoutesWithExplicitNextHop()
}

link, err := netlinkHandle.LinkByName((mechanism.GetInterfaceName()))
if err != nil {
return errors.Wrapf(err, "unable to find link %s", mechanism.GetInterfaceName())
}

for _, nsmRoute := range nsmRoutes {
routeFound := false
for i := range kernelRoutes {
if !(kernelRoutes[i].Dst.IP.Equal(nsmRoute.GetPrefixIPNet().IP.Mask(nsmRoute.GetPrefixIPNet().Mask))) {
continue
}
kernelOnes, kernelBit := kernelRoutes[i].Dst.Mask.Size()
nsmOnes, nsmBits := nsmRoute.GetPrefixIPNet().Mask.Size()
if kernelOnes != nsmOnes {
continue
}
if kernelBit != nsmBits {
continue
}

if !kernelRoutes[i].Gw.Equal(nsmRoute.GetNextHopIP()) {
continue
}

if kernelRoutes[i].LinkIndex != link.Attrs().Index {
continue
}

routeFound = true
break
}
if !routeFound {
return errors.Errorf("unable to find expected route: %s in routes %+v", nsmRoute, kernelRoutes)
}
}
}
return nil
}
3 changes: 3 additions & 0 deletions internal/tests/suite_memif_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/edwarnicke/vpphelper"
"github.com/pkg/errors"

"github.com/networkservicemesh/cmd-forwarder-vpp/internal/tests/routes"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/mechanisms"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/mechanisms/sendfd"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/chain"
Expand Down Expand Up @@ -61,6 +62,7 @@ type memifVerifiableEndpoint struct {

func newMemifVerifiableEndpoint(ctx context.Context,
prefix1, prefix2 *net.IPNet,
srcRoutes, dstRoutes []*networkservice.Route,
tokenGenerator token.GeneratorFunc,
vppConn vpphelper.Connection,
) verifiableEndpoint {
Expand All @@ -76,6 +78,7 @@ func newMemifVerifiableEndpoint(ctx context.Context,
sendfd.NewServer(),
point2pointipam.NewServer(prefix1),
point2pointipam.NewServer(prefix2),
routes.NewServer(srcRoutes, dstRoutes),
mechanisms.NewServer(map[string]networkservice.NetworkServiceServer{
memif.MECHANISM: chain.NewNetworkServiceServer(
metadata.NewServer(),
Expand Down
2 changes: 1 addition & 1 deletion internal/tests/suite_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
)

const (
contextTimeout = 100 * time.Second
contextTimeout = 10000 * time.Second
forwarderIP = "10.0.2.1"
clientIP = "10.0.2.2"
serverIP = "10.0.2.3"
Expand Down
3 changes: 3 additions & 0 deletions internal/tests/suite_vxlan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"git.fd.io/govpp.git/api"
"google.golang.org/grpc"

"github.com/networkservicemesh/cmd-forwarder-vpp/internal/tests/routes"
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/pinhole"

"github.com/networkservicemesh/sdk/pkg/networkservice/common/mechanisms"
Expand All @@ -48,6 +49,7 @@ type vxlanVerifiableEndpoint struct {

func newVxlanVerifiableEndpoint(ctx context.Context,
prefix1, prefix2 *net.IPNet,
srcRoutes, dstRoutes []*networkservice.Route,
tokenGenerator token.GeneratorFunc,
vppConn api.Connection) verifiableEndpoint {
rv := &vxlanVerifiableEndpoint{
Expand All @@ -63,6 +65,7 @@ func newVxlanVerifiableEndpoint(ctx context.Context,
metadata.NewServer(),
point2pointipam.NewServer(prefix1),
point2pointipam.NewServer(prefix2),
routes.NewServer(srcRoutes, dstRoutes),
connectioncontext.NewServer(vppConn),
pinhole.NewServer(vppConn),
mechanisms.NewServer(map[string]networkservice.NetworkServiceServer{
Expand Down
3 changes: 3 additions & 0 deletions internal/tests/suite_wireguard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/edwarnicke/vpphelper"
"google.golang.org/grpc"

"github.com/networkservicemesh/cmd-forwarder-vpp/internal/tests/routes"
"github.com/networkservicemesh/sdk/pkg/networkservice/chains/client"

"github.com/networkservicemesh/sdk/pkg/networkservice/common/authorize"
Expand All @@ -49,6 +50,7 @@ type wireguardVerifiableEndpoint struct {

func newWireguardVerifiableEndpoint(ctx context.Context,
prefix1, prefix2 *net.IPNet,
srcRoutes, dstRoutes []*networkservice.Route,
tokenGenerator token.GeneratorFunc,
vppConn vpphelper.Connection) verifiableEndpoint {
rv := &vxlanVerifiableEndpoint{
Expand All @@ -64,6 +66,7 @@ func newWireguardVerifiableEndpoint(ctx context.Context,
metadata.NewServer(),
point2pointipam.NewServer(prefix1),
point2pointipam.NewServer(prefix2),
routes.NewServer(srcRoutes, dstRoutes),
up.NewServer(ctx, vppConn),
pinhole.NewServer(vppConn),
connectioncontext.NewServer(vppConn),
Expand Down