Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add options to the forwarder to use it with an external vpp #530

Merged
merged 2 commits into from
Mar 18, 2022
Merged
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
4 changes: 4 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,7 @@ issues:
linters:
- funlen
text: "Function 'addDel'"
- path: pkg/networkservice/chains/forwarder/server.go
linters:
- funlen
text: "Function 'NewServer'"
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ require (
git.fd.io/govpp.git v0.3.6-0.20210927044411-385ccc0d8ba9
github.com/edwarnicke/govpp v0.0.0-20220311182453-f32f292e0e91
github.com/golang/protobuf v1.5.2
github.com/google/uuid v1.1.2
github.com/hashicorp/go-multierror v1.1.1
github.com/networkservicemesh/api v1.2.1-0.20220315001249-f33f8c3f2feb
github.com/networkservicemesh/sdk v0.5.1-0.20220316101237-288caa7bbc1c
github.com/networkservicemesh/sdk v0.5.1-0.20220316105041-b88289b9022e
github.com/networkservicemesh/sdk-kernel v0.0.0-20220316101641-0103343013f0
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.7.0
Expand Down
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,9 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
github.com/nats-io/stan.go v0.10.2/go.mod h1:vo2ax8K2IxaR3JtEMLZRFKIdoK/3o1/PKueapB7ezX0=
github.com/networkservicemesh/api v1.2.1-0.20220315001249-f33f8c3f2feb h1:5047nbh591kIjLNlFrO0NbpRVkOtCGRSvkKKjQyEDyI=
github.com/networkservicemesh/api v1.2.1-0.20220315001249-f33f8c3f2feb/go.mod h1:B6meq/SWjWR6bGXZdXPfbOeaBK+T1JayLdtEJQCsXKU=
github.com/networkservicemesh/sdk v0.5.1-0.20220316101237-288caa7bbc1c h1:R0DVEMRYMg5SAuPQ48R3lTUD5Dpu+epJfrsmbDMY8mw=
github.com/networkservicemesh/sdk v0.5.1-0.20220316101237-288caa7bbc1c/go.mod h1:fK/G5mfEDIefFXxRSNXqj1jjd8SEUeZMpQUdCuc7owY=
github.com/networkservicemesh/sdk v0.5.1-0.20220316105041-b88289b9022e h1:IXzvAfoU6tCTEZxAGfJGbKjVfome2Iymm1vkiM9MhZ8=
github.com/networkservicemesh/sdk v0.5.1-0.20220316105041-b88289b9022e/go.mod h1:fK/G5mfEDIefFXxRSNXqj1jjd8SEUeZMpQUdCuc7owY=
github.com/networkservicemesh/sdk-kernel v0.0.0-20220316101641-0103343013f0 h1:PpT01M2DzAt6vBLbmjbTn3u7vrzHUuLoE6WbUy9pk2M=
github.com/networkservicemesh/sdk-kernel v0.0.0-20220316101641-0103343013f0/go.mod h1:nbwaNH+kCji5C8R0RxdZHqAPTNXvX7St/NUJ+bwmbIs=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
Expand Down
113 changes: 113 additions & 0 deletions pkg/networkservice/chains/forwarder/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// 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.

// +build linux

package forwarder

import (
"net/url"
"time"

"google.golang.org/grpc"

"github.com/networkservicemesh/api/pkg/api/networkservice"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/cleanup"

"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/vxlan"
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/stats"
)

type forwarderOptions struct {
name string
authorizeServer networkservice.NetworkServiceServer
clientURL *url.URL
dialTimeout time.Duration
domain2Device map[string]string
statsOpts []stats.Option
cleanupOpts []cleanup.Option
vxlanOpts []vxlan.Option
dialOpts []grpc.DialOption
}

// Option is an option pattern for forwarder chain elements
type Option func(o *forwarderOptions)

// WithName - set a forwarder name
func WithName(name string) Option {
return func(o *forwarderOptions) {
o.name = name
}
}

// WithAuthorizeServer sets authorization server chain element
func WithAuthorizeServer(authorizeServer networkservice.NetworkServiceServer) Option {
if authorizeServer == nil {
panic("Authorize server cannot be nil")
}
return func(o *forwarderOptions) {
o.authorizeServer = authorizeServer
}
}

// WithClientURL sets clientURL.
func WithClientURL(clientURL *url.URL) Option {
return func(c *forwarderOptions) {
c.clientURL = clientURL
}
}

// WithDialTimeout sets dial timeout for the client
func WithDialTimeout(dialTimeout time.Duration) Option {
return func(o *forwarderOptions) {
o.dialTimeout = dialTimeout
}
}

// WithVlanDomain2Device sets vlan option
func WithVlanDomain2Device(domain2Device map[string]string) Option {
return func(o *forwarderOptions) {
o.domain2Device = domain2Device
}
}

// WithStatsOptions sets stats options
func WithStatsOptions(opts ...stats.Option) Option {
return func(o *forwarderOptions) {
o.statsOpts = opts
}
}

// WithCleanupOptions sets cleanup options
func WithCleanupOptions(opts ...cleanup.Option) Option {
return func(o *forwarderOptions) {
o.cleanupOpts = opts
}
}

// WithVxlanOptions sets vxlan options
func WithVxlanOptions(opts ...vxlan.Option) Option {
return func(o *forwarderOptions) {
o.vxlanOpts = opts
}
}

// WithDialOptions sets dial options
func WithDialOptions(opts ...grpc.DialOption) Option {
return func(o *forwarderOptions) {
o.dialOpts = opts
}
}
59 changes: 36 additions & 23 deletions pkg/networkservice/chains/forwarder/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,30 @@ import (
"time"

"git.fd.io/govpp.git/api"
"github.com/networkservicemesh/sdk/pkg/networkservice/chains/client"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/connect"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/filtermechanisms"
"google.golang.org/grpc"
"github.com/google/uuid"

"github.com/networkservicemesh/api/pkg/api/networkservice"
"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/cleanup"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/connect"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/discover"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/filtermechanisms"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/mechanisms"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/mechanisms/recvfd"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/mechanisms/sendfd"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/mechanismtranslation"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/roundrobin"
"github.com/networkservicemesh/sdk/pkg/tools/token"

"github.com/networkservicemesh/sdk-kernel/pkg/kernel/networkservice/connectioncontextkernel"
"github.com/networkservicemesh/sdk-kernel/pkg/kernel/networkservice/ethernetcontext"

"github.com/networkservicemesh/sdk/pkg/networkservice/common/discover"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/roundrobin"
registryclient "github.com/networkservicemesh/sdk/pkg/registry/chains/client"
registryrecvfd "github.com/networkservicemesh/sdk/pkg/registry/common/recvfd"
registrysendfd "github.com/networkservicemesh/sdk/pkg/registry/common/sendfd"

"github.com/networkservicemesh/sdk-kernel/pkg/kernel/networkservice/connectioncontextkernel"
"github.com/networkservicemesh/sdk-kernel/pkg/kernel/networkservice/ethernetcontext"

"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/connectioncontext/mtu"
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/kernel"
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/memif"
Expand All @@ -73,23 +75,33 @@ type xconnectNSServer struct {
}

// NewServer - returns an implementation of the xconnectns network service
func NewServer(ctx context.Context, name string, authzServer networkservice.NetworkServiceServer, tokenGenerator token.GeneratorFunc, clientURL *url.URL, vppConn Connection, tunnelIP net.IP, tunnelPort uint16, dialTimeout time.Duration, domain2Device map[string]string, clientDialOptions ...grpc.DialOption) endpoint.Endpoint {
nseClient := registryclient.NewNetworkServiceEndpointRegistryClient(ctx, clientURL,
func NewServer(ctx context.Context, tokenGenerator token.GeneratorFunc, vppConn Connection, tunnelIP net.IP, options ...Option) endpoint.Endpoint {
opts := &forwarderOptions{
Copy link
Member

@denis-tingaikin denis-tingaikin Mar 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed default parameters for:

authorizeServer -> null server
clientURL -> default connectTo
dialTimeout   ->  200ms
domain2Device  ->empty map

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it was the responsibility of each individual chain element. Forwarder just passes options. Otherwise, it will turn out that at each iteration we will set new default parameters:

func AnyOtherNewServer(opts ...Options) {
  /* set default parameters */
  ...
  forwarder.NewServer(..., forwarder.WithOption(opts.AnyOption)) <- new default parameters inside forwarder.NewServer
  ...
}

Name is set, because we want to keep consistency inside the forwarder (used in the client and endpoint chain).
And, do we have a constant for dialTimeout or clientURL?

@denis-tingaikin Any thoughts?

Copy link
Member

@denis-tingaikin denis-tingaikin Mar 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@glazychev-art option means that the value is not required. I don't think that clientURL== nil and dialTimeout == 0 are good values by default. Also I'm fine to make these values as required.

name: "forwarder-vpp-" + uuid.New().String(),
authorizeServer: authorize.NewServer(authorize.Any()),
clientURL: &url.URL{Scheme: "unix", Host: "connect.to.socket"},
dialTimeout: time.Millisecond * 200,
domain2Device: make(map[string]string),
}
for _, opt := range options {
opt(opts)
}
nseClient := registryclient.NewNetworkServiceEndpointRegistryClient(ctx, opts.clientURL,
registryclient.WithNSEAdditionalFunctionality(
registryrecvfd.NewNetworkServiceEndpointRegistryClient(),
registrysendfd.NewNetworkServiceEndpointRegistryClient(),
),
registryclient.WithDialOptions(clientDialOptions...),
registryclient.WithDialOptions(opts.dialOpts...),
)
nsClient := registryclient.NewNetworkServiceRegistryClient(ctx, clientURL, registryclient.WithDialOptions(clientDialOptions...))
nsClient := registryclient.NewNetworkServiceRegistryClient(ctx, opts.clientURL, registryclient.WithDialOptions(opts.dialOpts...))

rv := &xconnectNSServer{}
additionalFunctionality := []networkservice.NetworkServiceServer{
recvfd.NewServer(),
sendfd.NewServer(),
discover.NewServer(nsClient, nseClient),
roundrobin.NewServer(),
stats.NewServer(ctx),
stats.NewServer(ctx, opts.statsOpts...),
up.NewServer(ctx, vppConn),
xconnect.NewServer(vppConn),
connectioncontextkernel.NewServer(),
Expand All @@ -101,20 +113,21 @@ func NewServer(ctx context.Context, name string, authzServer networkservice.Netw
memif.WithDirectMemif(),
memif.WithChangeNetNS()),
kernel.MECHANISM: kernel.NewServer(vppConn),
vxlan.MECHANISM: vxlan.NewServer(vppConn, tunnelIP, vxlan.WithVniPort(tunnelPort)),
vxlan.MECHANISM: vxlan.NewServer(vppConn, tunnelIP, opts.vxlanOpts...),
wireguard.MECHANISM: wireguard.NewServer(vppConn, tunnelIP),
}),
pinhole.NewServer(vppConn),
connect.NewServer(
client.NewClient(ctx,
client.WithoutRefresh(),
client.WithName(name),
client.WithDialOptions(clientDialOptions...),
client.WithDialTimeout(dialTimeout),
client.WithName(opts.name),
client.WithDialOptions(opts.dialOpts...),
client.WithDialTimeout(opts.dialTimeout),
client.WithAdditionalFunctionality(
cleanup.NewClient(ctx, opts.cleanupOpts...),
mechanismtranslation.NewClient(),
connectioncontextkernel.NewClient(),
stats.NewClient(ctx),
stats.NewClient(ctx, opts.statsOpts...),
up.NewClient(ctx, vppConn),
mtu.NewClient(vppConn),
tag.NewClient(ctx, vppConn),
Expand All @@ -123,9 +136,9 @@ func NewServer(ctx context.Context, name string, authzServer networkservice.Netw
memif.WithChangeNetNS(),
),
kernel.NewClient(vppConn),
vxlan.NewClient(vppConn, tunnelIP, vxlan.WithVniPort(tunnelPort)),
vxlan.NewClient(vppConn, tunnelIP, opts.vxlanOpts...),
wireguard.NewClient(vppConn, tunnelIP),
vlan.NewClient(vppConn, domain2Device),
vlan.NewClient(vppConn, opts.domain2Device),
filtermechanisms.NewClient(),
pinhole.NewClient(vppConn),
recvfd.NewClient(),
Expand All @@ -135,8 +148,8 @@ func NewServer(ctx context.Context, name string, authzServer networkservice.Netw
}

rv.Endpoint = endpoint.NewServer(ctx, tokenGenerator,
endpoint.WithName(name),
endpoint.WithAuthorizeServer(authzServer),
endpoint.WithName(opts.name),
endpoint.WithAuthorizeServer(opts.authorizeServer),
endpoint.WithAdditionalFunctionality(additionalFunctionality...))

return rv
Expand Down
8 changes: 4 additions & 4 deletions pkg/networkservice/mechanisms/vxlan/option.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) 2020-2021 Cisco and/or its affiliates.
// Copyright (c) 2020-2022 Cisco and/or its affiliates.
//
// Copyright (c) 2021 Nordix Foundation.
// Copyright (c) 2021-2022 Nordix Foundation.
//
// SPDX-License-Identifier: Apache-2.0
//
Expand All @@ -21,8 +21,8 @@ package vxlan
// Option is an option pattern for vxlan server/client
type Option func(o *vxlanOptions)

// WithVniPort sets vni port
func WithVniPort(port uint16) Option {
// WithPort sets vxlan udp port
func WithPort(port uint16) Option {
return func(o *vxlanOptions) {
if port != 0 {
o.vxlanPort = port
Expand Down