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

Delete tap interfaces on startup #545

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
11 changes: 9 additions & 2 deletions pkg/networkservice/chains/forwarder/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import (
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/tag"
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/up"
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/xconnect"
"github.com/networkservicemesh/sdk-vpp/pkg/tools/dumptool"
)

// Connection aggregates the api.Connection and api.ChannelProvider interfaces
Expand All @@ -87,6 +88,12 @@ func NewServer(ctx context.Context, tokenGenerator token.GeneratorFunc, vppConn
for _, opt := range options {
opt(opts)
}

// Create a function, that will dump NSM interfaces and apply to them onDump func
dumper := func(onDump dumptool.OnDumpFn, isClient bool) error {
return dumptool.DumpVppInterfaces(ctx, vppConn, opts.name, isClient, onDump)
}

nseClient := registryclient.NewNetworkServiceEndpointRegistryClient(ctx, opts.clientURL,
registryclient.WithNSEAdditionalFunctionality(
registryrecvfd.NewNetworkServiceEndpointRegistryClient(),
Expand All @@ -113,7 +120,7 @@ func NewServer(ctx context.Context, tokenGenerator token.GeneratorFunc, vppConn
memif.MECHANISM: memif.NewServer(ctx, vppConn,
memif.WithDirectMemif(),
memif.WithChangeNetNS()),
kernel.MECHANISM: kernel.NewServer(vppConn),
kernel.MECHANISM: kernel.NewServer(vppConn, kernel.WithDump(dumper)),
vxlan.MECHANISM: vxlan.NewServer(vppConn, tunnelIP, opts.vxlanOpts...),
wireguard.MECHANISM: wireguard.NewServer(vppConn, tunnelIP),
}),
Expand All @@ -136,7 +143,7 @@ func NewServer(ctx context.Context, tokenGenerator token.GeneratorFunc, vppConn
memif.NewClient(vppConn,
memif.WithChangeNetNS(),
),
kernel.NewClient(vppConn),
kernel.NewClient(vppConn, kernel.WithDump(dumper)),
vxlan.NewClient(vppConn, tunnelIP, opts.vxlanOpts...),
wireguard.NewClient(vppConn, tunnelIP),
vlan.NewClient(vppConn, opts.domain2Device),
Expand Down
11 changes: 8 additions & 3 deletions pkg/networkservice/mechanisms/kernel/client.go
Original file line number Diff line number Diff line change
@@ -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
//
Expand Down Expand Up @@ -30,9 +30,14 @@ import (
)

// NewClient - returns a new Client chain element implementing the kernel mechanism with vpp
func NewClient(vppConn api.Connection) networkservice.NetworkServiceClient {
func NewClient(vppConn api.Connection, opts ...Option) networkservice.NetworkServiceClient {
o := &options{}
for _, opt := range opts {
opt(o)
}

if _, err := os.Stat(vnetFilename); err == nil {
return kerneltap.NewClient(vppConn)
return kerneltap.NewClient(vppConn, kerneltap.WithDump(o.dump))
}
return kernelvethpair.NewClient(vppConn)
}
15 changes: 13 additions & 2 deletions pkg/networkservice/mechanisms/kernel/kerneltap/client.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020-2021 Cisco and/or its affiliates.
glazychev-art marked this conversation as resolved.
Show resolved Hide resolved
// Copyright (c) 2020-2022 Cisco and/or its affiliates.
//
// SPDX-License-Identifier: Apache-2.0
//
Expand Down Expand Up @@ -39,7 +39,18 @@ type kernelTapClient struct {
}

// NewClient - return a new Client chain element implementing the kernel mechanism with vpp using tapv2
func NewClient(vppConn api.Connection) networkservice.NetworkServiceClient {
func NewClient(vppConn api.Connection, opts ...Option) networkservice.NetworkServiceClient {
o := &options{}
for _, opt := range opts {
opt(o)
}

if o.dump != nil {
if err := o.dump(onDump, false); err != nil {
log.FromContext(context.Background()).Error(err)
}
}

return &kernelTapClient{
glazychev-art marked this conversation as resolved.
Show resolved Hide resolved
vppConn: vppConn,
}
Expand Down
35 changes: 23 additions & 12 deletions pkg/networkservice/mechanisms/kernel/kerneltap/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,18 +147,29 @@ func del(ctx context.Context, conn *networkservice.Connection, vppConn api.Conne
if !ok {
return nil
}
now := time.Now()
_, err := tapv2.NewServiceClient(vppConn).TapDeleteV2(ctx, &tapv2.TapDeleteV2{
SwIfIndex: swIfIndex,
})
if err != nil {
return errors.Wrapf(err, "unable to delete connection with SwIfIndex %v", swIfIndex)
}
log.FromContext(ctx).
WithField("SwIfIndex", swIfIndex).
WithField("duration", time.Since(now)).
WithField("vppapi", "TapDeleteV2").Debug("completed")
return nil
return delVpp(ctx, vppConn, swIfIndex)
}
return nil
}

func delVpp(ctx context.Context, vppConn api.Connection, swIfIndex interface_types.InterfaceIndex) error {
now := time.Now()
_, err := tapv2.NewServiceClient(vppConn).TapDeleteV2(ctx, &tapv2.TapDeleteV2{
SwIfIndex: swIfIndex,
})
if err != nil {
return errors.Wrapf(err, "unable to delete connection with SwIfIndex %v", swIfIndex)
}
log.FromContext(ctx).
WithField("SwIfIndex", swIfIndex).
WithField("duration", time.Since(now)).
WithField("vppapi", "TapDeleteV2").Debug("completed")
return nil
}

func onDump(ctx context.Context, vppConn api.Connection, details *interfaces.SwInterfaceDetails) error {
if details.InterfaceDevType == DevTypeTap {
return delVpp(ctx, vppConn, details.SwIfIndex)
}
return nil
}
5 changes: 4 additions & 1 deletion pkg/networkservice/mechanisms/kernel/kerneltap/constants.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020 Cisco and/or its affiliates.
// Copyright (c) 2020-2022 Cisco and/or its affiliates.
//
// SPDX-License-Identifier: Apache-2.0
//
Expand All @@ -21,4 +21,7 @@ import "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/kern
const (
// MECHANISM string
MECHANISM = kernel.MECHANISM

// DevTypeTap - tap interface dev type
DevTypeTap = "virtio"
)
35 changes: 35 additions & 0 deletions pkg/networkservice/mechanisms/kernel/kerneltap/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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 kerneltap

import "github.com/networkservicemesh/sdk-vpp/pkg/tools/dumptool"

type options struct {
dump dumptool.DumpNSMFn
}

// Option is an option pattern for kernel
type Option func(o *options)

// WithDump - sets dump parameters
func WithDump(dump dumptool.DumpNSMFn) Option {
return func(o *options) {
o.dump = dump
}
}
15 changes: 13 additions & 2 deletions pkg/networkservice/mechanisms/kernel/kerneltap/server.go
Original file line number Diff line number Diff line change
@@ -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
//
Expand Down Expand Up @@ -37,7 +37,18 @@ type kernelTapServer struct {
}

// NewServer - return a new Server chain element implementing the kernel mechanism with vpp using tapv2
func NewServer(vppConn api.Connection) networkservice.NetworkServiceServer {
func NewServer(vppConn api.Connection, opts ...Option) networkservice.NetworkServiceServer {
o := &options{}
for _, opt := range opts {
opt(o)
}

if o.dump != nil {
if err := o.dump(onDump, true); err != nil {
log.FromContext(context.Background()).Error(err)
}
}

return &kernelTapServer{
vppConn: vppConn,
}
Expand Down
35 changes: 35 additions & 0 deletions pkg/networkservice/mechanisms/kernel/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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 kernel

import "github.com/networkservicemesh/sdk-vpp/pkg/tools/dumptool"

type options struct {
dump dumptool.DumpNSMFn
}

// Option is an option pattern for kernel
type Option func(o *options)

// WithDump - sets dump parameters
func WithDump(dump dumptool.DumpNSMFn) Option {
return func(o *options) {
o.dump = dump
}
}
11 changes: 8 additions & 3 deletions pkg/networkservice/mechanisms/kernel/server.go
Original file line number Diff line number Diff line change
@@ -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
//
Expand Down Expand Up @@ -30,9 +30,14 @@ import (
)

// NewServer return a NetworkServiceServer chain element that correctly handles the kernel Mechanism
func NewServer(vppConn api.Connection) networkservice.NetworkServiceServer {
func NewServer(vppConn api.Connection, opts ...Option) networkservice.NetworkServiceServer {
o := &options{}
for _, opt := range opts {
opt(o)
}

if _, err := os.Stat(vnetFilename); err == nil {
return kerneltap.NewServer(vppConn)
return kerneltap.NewServer(vppConn, kerneltap.WithDump(o.dump))
}
return kernelvethpair.NewServer(vppConn)
}
10 changes: 8 additions & 2 deletions pkg/networkservice/tag/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/pkg/errors"

"github.com/networkservicemesh/sdk-vpp/pkg/tools/ifindex"
"github.com/networkservicemesh/sdk-vpp/pkg/tools/tagtool"
)

func create(ctx context.Context, conn *networkservice.Connection, vppConn api.Connection, isClient bool) error {
Expand All @@ -36,16 +37,21 @@ func create(ctx context.Context, conn *networkservice.Connection, vppConn api.Co
}

now := time.Now()
tag := tagtool.ConvertToString(&tagtool.Tag{
TagPrefix: conn.Path.PathSegments[conn.Path.Index].Name,
ConnID: conn.GetId(),
IsClient: isClient,
})
if _, err := interfaces.NewServiceClient(vppConn).SwInterfaceTagAddDel(ctx, &interfaces.SwInterfaceTagAddDel{
IsAdd: true,
SwIfIndex: swIfIndex,
Tag: conn.GetId(),
Tag: tag,
}); err != nil {
return errors.WithStack(err)
}
log.FromContext(ctx).
WithField("swIfIndex", swIfIndex).
WithField("tag", conn.GetId()).
WithField("tag", tag).
WithField("duration", time.Since(now)).
WithField("vppapi", "SwInterfaceTagAddDel").Debug("completed")
return nil
Expand Down
66 changes: 66 additions & 0 deletions pkg/tools/dumptool/dumptool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// 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.

// Package dumptool provides utilities for vpp interfaces dump
package dumptool

import (
"context"
"io"

"git.fd.io/govpp.git/api"
interfaces "github.com/edwarnicke/govpp/binapi/interface"
"github.com/networkservicemesh/sdk/pkg/tools/log"
"github.com/pkg/errors"

"github.com/networkservicemesh/sdk-vpp/pkg/tools/tagtool"
)

// DumpNSMFn - dumps NSM interfaces applies onDump func for each of them
type DumpNSMFn func(onDump OnDumpFn, isClient bool) error

// OnDumpFn - action with dumped NSM interfaces
type OnDumpFn func(ctx context.Context, vppConn api.Connection, details *interfaces.SwInterfaceDetails) error

// DumpVppInterfaces - dumps vpp interfaces by tag.
// - onDump - determines what to do if we found an NSM interface during the dump
func DumpVppInterfaces(ctx context.Context, vppConn api.Connection, tagPrefix string, isClient bool, onDump OnDumpFn) error {
client, err := interfaces.NewServiceClient(vppConn).SwInterfaceDump(ctx, &interfaces.SwInterfaceDump{})
if err != nil {
return errors.Wrap(err, "SwInterfaceDump error")
}
defer func() { _ = client.Close() }()

for {
details, err := client.Recv()
if err == io.EOF || details == nil {
break
}

t, err := tagtool.ConvertFromString(details.Tag)
if err != nil {
continue
}
if t.TagPrefix != tagPrefix || t.IsClient != isClient {
continue
}

if err := onDump(ctx, vppConn, details); err != nil {
log.FromContext(ctx).Error(err)
}
}
return nil
}
Loading