From 459443a466b884dd3f36b89444b8b244a88ba620 Mon Sep 17 00:00:00 2001 From: Artem Glazychev Date: Tue, 6 Dec 2022 19:13:18 +0700 Subject: [PATCH] Add IPSec mechanism (#762) Signed-off-by: Artem Glazychev Signed-off-by: Artem Glazychev --- Dockerfile | 2 +- go.mod | 2 +- go.sum | 4 +- internal/config/config.go | 1 + internal/imports/imports_linux.go | 2 + internal/tests/suite_combinatronics_test.go | 15 +++ internal/tests/suite_ipsec_test.go | 130 ++++++++++++++++++++ internal/tests/suite_wireguard_test.go | 9 +- internal/xconnectns/options.go | 8 ++ internal/xconnectns/server.go | 1 + main.go | 1 + 11 files changed, 167 insertions(+), 8 deletions(-) create mode 100644 internal/tests/suite_ipsec_test.go diff --git a/Dockerfile b/Dockerfile index abcb91f7..e7516b8b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG VPP_VERSION=v22.06-rc0-150-gd38fa55fa +ARG VPP_VERSION=v22.06-rc0-151-g1af463082 FROM ghcr.io/edwarnicke/govpp/vpp:${VPP_VERSION} as go COPY --from=golang:1.18.2-buster /usr/local/go/ /go ENV PATH ${PATH}:/go/bin diff --git a/go.mod b/go.mod index 829c30be..7c09315c 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/networkservicemesh/sdk v0.5.1-0.20221206103812-b6979bfe147d github.com/networkservicemesh/sdk-k8s v0.0.0-20221128102348-7b25c04bed9e github.com/networkservicemesh/sdk-sriov v0.0.0-20221206105157-ce61d862f46f - github.com/networkservicemesh/sdk-vpp v0.0.0-20221206105447-23a527c0a2c4 + github.com/networkservicemesh/sdk-vpp v0.0.0-20221206112452-c9d7291b5e3b github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.9.0 github.com/spiffe/go-spiffe/v2 v2.0.0 diff --git a/go.sum b/go.sum index a98a3c4d..3119eeb8 100644 --- a/go.sum +++ b/go.sum @@ -374,8 +374,8 @@ github.com/networkservicemesh/sdk-kernel v0.0.0-20221206104345-fd91dd9e8f6d h1:e github.com/networkservicemesh/sdk-kernel v0.0.0-20221206104345-fd91dd9e8f6d/go.mod h1:t4A46Ph49k1kfuiEUPjmFvnIeaU3cfigQjUxr+gSmwE= github.com/networkservicemesh/sdk-sriov v0.0.0-20221206105157-ce61d862f46f h1:WOicK+q0roBwdWQqriWKk3YYqRniVszIAd0FafH2+tg= github.com/networkservicemesh/sdk-sriov v0.0.0-20221206105157-ce61d862f46f/go.mod h1:pVMdEtwTPziKjhbqFEQWpz3DhXfOfJ+FfVyzENdNCb8= -github.com/networkservicemesh/sdk-vpp v0.0.0-20221206105447-23a527c0a2c4 h1:E+WcbzILudVP9fUvlLOeaNUcGirY4C3K4SM6DsVcypo= -github.com/networkservicemesh/sdk-vpp v0.0.0-20221206105447-23a527c0a2c4/go.mod h1:9XCG5+2GxZs2jN9PkQb08iQ2Qg1mx22/OTbtLhpbcxc= +github.com/networkservicemesh/sdk-vpp v0.0.0-20221206112452-c9d7291b5e3b h1:tJrY7VBHaTc6u5BLh3w1cPs362eiSD/dbTxdEWSDVSM= +github.com/networkservicemesh/sdk-vpp v0.0.0-20221206112452-c9d7291b5e3b/go.mod h1:9XCG5+2GxZs2jN9PkQb08iQ2Qg1mx22/OTbtLhpbcxc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= diff --git a/internal/config/config.go b/internal/config/config.go index d66c6c28..0218de66 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -58,6 +58,7 @@ type Config struct { PCIDriversPath string `default:"/sys/bus/pci/drivers" desc:"path to the PCI drivers directory" split_words:"true"` CgroupPath string `default:"/host/sys/fs/cgroup/devices" desc:"path to the host cgroup directory" split_words:"true"` VFIOPath string `default:"/host/dev/vfio" desc:"path to the host VFIO directory" split_words:"true"` + PriorityMechanisms []string `default:"" desc:"sets priorities for mechanisms" split_words:"true"` } // Process reads config from env diff --git a/internal/imports/imports_linux.go b/internal/imports/imports_linux.go index 1845330c..1b5d797d 100644 --- a/internal/imports/imports_linux.go +++ b/internal/imports/imports_linux.go @@ -27,6 +27,7 @@ import ( _ "github.com/kelseyhightower/envconfig" _ "github.com/networkservicemesh/api/pkg/api/networkservice" _ "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/cls" + _ "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/ipsec" _ "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/kernel" _ "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/memif" _ "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/noop" @@ -47,6 +48,7 @@ import ( _ "github.com/networkservicemesh/sdk-sriov/pkg/tools/yamlhelper" _ "github.com/networkservicemesh/sdk-vpp/pkg/networkservice/chains/forwarder" _ "github.com/networkservicemesh/sdk-vpp/pkg/networkservice/connectioncontext" + _ "github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/ipsec" _ "github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/memif" _ "github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/vxlan" _ "github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/wireguard" diff --git a/internal/tests/suite_combinatronics_test.go b/internal/tests/suite_combinatronics_test.go index 2aa31ed8..96fbffc9 100644 --- a/internal/tests/suite_combinatronics_test.go +++ b/internal/tests/suite_combinatronics_test.go @@ -41,6 +41,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials" + ipsecapi "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/ipsec" "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/kernel" "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/memif" "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/vxlan" @@ -86,6 +87,12 @@ func (f *ForwarderTestSuite) TestCombinations() { f.vppServerConn, ) }, + ipsecapi.MECHANISM: func(ctx context.Context) verifiableEndpoint { + return newIpsecVerifiableEndpoint(ctx, prefix1, prefix2, + spiffejwt.TokenGeneratorFunc(f.x509source, f.config.MaxTokenLifetime), + f.vppServerConn, + ) + }, } clients := map[string]func(ctx context.Context) verifiableClient{ kernel.MECHANISM: func(ctx context.Context) verifiableClient { @@ -111,6 +118,12 @@ func (f *ForwarderTestSuite) TestCombinations() { f.vppClientConn, ) }, + ipsecapi.MECHANISM: func(ctx context.Context) verifiableClient { + return newIpsecVerifiableClient(ctx, + f.sutCC, + f.vppClientConn, + ) + }, } payloads := map[string][]string{ @@ -118,6 +131,7 @@ func (f *ForwarderTestSuite) TestCombinations() { kernel.MECHANISM, memif.MECHANISM, wireguard.MECHANISM, + ipsecapi.MECHANISM, }, payload.Ethernet: { kernel.MECHANISM, @@ -128,6 +142,7 @@ func (f *ForwarderTestSuite) TestCombinations() { isRemote := map[string]bool{ wireguard.MECHANISM: true, vxlan.MECHANISM: true, + ipsecapi.MECHANISM: true, } for _, pl := range []string{payload.Ethernet, payload.IP} { payloadName := pl diff --git a/internal/tests/suite_ipsec_test.go b/internal/tests/suite_ipsec_test.go new file mode 100644 index 00000000..9dcb6b39 --- /dev/null +++ b/internal/tests/suite_ipsec_test.go @@ -0,0 +1,130 @@ +// Copyright (c) 2022 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. + +// nolint:dupl +package tests + +import ( + "context" + "net" + + "github.com/edwarnicke/vpphelper" + "google.golang.org/grpc" + + "github.com/networkservicemesh/api/pkg/api/networkservice" + ipsecapi "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/ipsec" + + "github.com/networkservicemesh/sdk/pkg/networkservice/chains/client" + "github.com/networkservicemesh/sdk/pkg/networkservice/chains/endpoint" + "github.com/networkservicemesh/sdk/pkg/networkservice/common/authorize" + "github.com/networkservicemesh/sdk/pkg/networkservice/common/mechanisms" + "github.com/networkservicemesh/sdk/pkg/networkservice/ipam/point2pointipam" + "github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata" + "github.com/networkservicemesh/sdk/pkg/tools/token" + + "github.com/networkservicemesh/sdk-vpp/pkg/networkservice/connectioncontext" + "github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/ipsec" + "github.com/networkservicemesh/sdk-vpp/pkg/networkservice/pinhole" + "github.com/networkservicemesh/sdk-vpp/pkg/networkservice/up" +) + +type ipsecVerifiableEndpoint struct { + ctx context.Context + vppConn vpphelper.Connection + endpoint.Endpoint +} + +func newIpsecVerifiableEndpoint(ctx context.Context, + prefix1, prefix2 *net.IPNet, + tokenGenerator token.GeneratorFunc, + vppConn vpphelper.Connection) verifiableEndpoint { + rv := &ipsecVerifiableEndpoint{ + ctx: ctx, + vppConn: vppConn, + } + name := "ipsecVerifiableEndpoint" + rv.Endpoint = endpoint.NewServer(ctx, + tokenGenerator, + endpoint.WithName(name), + endpoint.WithAuthorizeServer(authorize.NewServer()), + endpoint.WithAdditionalFunctionality( + metadata.NewServer(), + point2pointipam.NewServer(prefix1), + point2pointipam.NewServer(prefix2), + up.NewServer(ctx, vppConn), + pinhole.NewServer(vppConn), + connectioncontext.NewServer(vppConn), + mechanisms.NewServer(map[string]networkservice.NetworkServiceServer{ + ipsecapi.MECHANISM: ipsec.NewServer(vppConn, net.ParseIP(serverIP)), + }), + ), + ) + return rv +} + +func (v *ipsecVerifiableEndpoint) VerifyConnection(conn *networkservice.Connection) error { + for _, ip := range conn.GetContext().GetIpContext().GetSrcIpAddrs() { + if err := pingVpp(v.ctx, v.vppConn, ip); err != nil { + return err + } + } + return nil +} + +func (v *ipsecVerifiableEndpoint) VerifyClose(conn *networkservice.Connection) error { + return nil +} + +type ipsecVerifiableClient struct { + ctx context.Context + vppConn vpphelper.Connection + networkservice.NetworkServiceClient +} + +func newIpsecVerifiableClient( + ctx context.Context, + sutCC grpc.ClientConnInterface, + vppConn vpphelper.Connection, +) verifiableClient { + return &ipsecVerifiableClient{ + ctx: ctx, + vppConn: vppConn, + NetworkServiceClient: client.NewClient( + ctx, + client.WithName("ipsecVerifiableClient"), + client.WithClientConn(sutCC), + client.WithAdditionalFunctionality( + up.NewClient(ctx, vppConn), + connectioncontext.NewClient(vppConn), + ipsec.NewClient(vppConn, net.ParseIP(clientIP)), + pinhole.NewClient(vppConn), + ), + ), + } +} + +func (v *ipsecVerifiableClient) VerifyConnection(conn *networkservice.Connection) error { + for _, ip := range conn.GetContext().GetIpContext().GetDstIpAddrs() { + if err := pingVpp(v.ctx, v.vppConn, ip); err != nil { + return err + } + } + return nil +} + +func (v *ipsecVerifiableClient) VerifyClose(conn *networkservice.Connection) error { + return nil +} diff --git a/internal/tests/suite_wireguard_test.go b/internal/tests/suite_wireguard_test.go index 14734356..1c26ff4e 100644 --- a/internal/tests/suite_wireguard_test.go +++ b/internal/tests/suite_wireguard_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2021 Cisco and/or its affiliates. +// Copyright (c) 2020-2022 Cisco and/or its affiliates. // // SPDX-License-Identifier: Apache-2.0 // @@ -14,6 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// nolint:dupl package tests import ( @@ -51,7 +52,7 @@ func newWireguardVerifiableEndpoint(ctx context.Context, prefix1, prefix2 *net.IPNet, tokenGenerator token.GeneratorFunc, vppConn vpphelper.Connection) verifiableEndpoint { - rv := &vxlanVerifiableEndpoint{ + rv := &wireguardVerifiableEndpoint{ ctx: ctx, vppConn: vppConn, } @@ -99,12 +100,12 @@ func newWireguardVerifiableClient( sutCC grpc.ClientConnInterface, vppConn vpphelper.Connection, ) verifiableClient { - return &vxlanVerifiableClient{ + return &wireguardVerifiableClient{ ctx: ctx, vppConn: vppConn, NetworkServiceClient: client.NewClient( ctx, - client.WithName("vxlanVerifiableClient"), + client.WithName("wireguardVerifiableClient"), client.WithClientConn(sutCC), client.WithAdditionalFunctionality( up.NewClient(ctx, vppConn), diff --git a/internal/xconnectns/options.go b/internal/xconnectns/options.go index 1c30c608..b3dc4f3b 100644 --- a/internal/xconnectns/options.go +++ b/internal/xconnectns/options.go @@ -37,6 +37,7 @@ type xconnOptions struct { clientURL *url.URL dialTimeout time.Duration domain2Device map[string]string + prioriyMechanismList []string statsOpts []stats.Option cleanupOpts []cleanup.Option vxlanOpts []vxlan.Option @@ -115,6 +116,13 @@ func WithVxlanOptions(opts ...vxlan.Option) Option { } } +// WithPriorityMechanisms sets prioritymechanisms options +func WithPriorityMechanisms(priorityList []string) Option { + return func(o *xconnOptions) { + o.prioriyMechanismList = priorityList + } +} + // WithDialOptions sets dial options func WithDialOptions(opts ...grpc.DialOption) Option { return func(o *xconnOptions) { diff --git a/internal/xconnectns/server.go b/internal/xconnectns/server.go index 65d605f1..877af317 100644 --- a/internal/xconnectns/server.go +++ b/internal/xconnectns/server.go @@ -80,6 +80,7 @@ func NewServer( vppforwarder.WithClientURL(xconnOpts.clientURL), vppforwarder.WithDialTimeout(xconnOpts.dialTimeout), vppforwarder.WithVlanDomain2Device(xconnOpts.domain2Device), + vppforwarder.WithPriorityMechanisms(xconnOpts.prioriyMechanismList), vppforwarder.WithCleanupOptions(xconnOpts.cleanupOpts...), vppforwarder.WithStatsOptions(xconnOpts.statsOpts...), vppforwarder.WithVxlanOptions(xconnOpts.vxlanOpts...), diff --git a/main.go b/main.go index ab1dd434..76afab44 100644 --- a/main.go +++ b/main.go @@ -248,6 +248,7 @@ func main() { xconnectns.WithAuthorizeServer(authorize.NewServer(authorize.WithSpiffeIDConnectionMap(&spiffeIDConnMap))), xconnectns.WithAuthorizeMonitorConnectionsServer(authmonitor.NewMonitorConnectionServer(authmonitor.WithSpiffeIDConnectionMap(&spiffeIDConnMap))), xconnectns.WithVlanDomain2Device(deviceMap), + xconnectns.WithPriorityMechanisms(cfg.PriorityMechanisms), xconnectns.WithClientURL(&cfg.ConnectTo), xconnectns.WithDialTimeout(cfg.DialTimeout), xconnectns.WithStatsOptions(statsOpts...),