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 1 commit
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)
}

dumpOption := &dumptool.DumpOption{
Ctx: ctx,
PodName: opts.name,
Copy link
Member

Choose a reason for hiding this comment

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

Is this actually just a prefix for the tag? If so, could we name it something like TagPrefix rather than PodName? With the advent of networkservicemesh/cmd-nse-simple-vl3-docker#1 we will be using SDK components in non-K8s environments.

Copy link
Member

Choose a reason for hiding this comment

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

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Thank you.
I've simplified a little this PR - now TagPrefix is not passed to the mechanism chain element as parameter.
Instead, there is only DumpNSM func as option, that applies OnDump func of the mechainsm

}

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(dumpOption)),
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(dumpOption)),
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.dumpOpt))
}
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.dumpOpt != nil {
if err := dumpAndDelete(o.dumpOpt.Ctx, vppConn, o.dumpOpt.PodName, false); err != nil {
log.FromContext(o.dumpOpt.Ctx).Error(err)
}
}

return &kernelTapClient{
glazychev-art marked this conversation as resolved.
Show resolved Hide resolved
vppConn: vppConn,
}
Expand Down
41 changes: 29 additions & 12 deletions pkg/networkservice/mechanisms/kernel/kerneltap/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
kernellink "github.com/networkservicemesh/sdk-kernel/pkg/kernel"
"github.com/networkservicemesh/sdk/pkg/tools/log"

"github.com/networkservicemesh/sdk-vpp/pkg/tools/dumptool"
"github.com/networkservicemesh/sdk-vpp/pkg/tools/ifindex"
"github.com/networkservicemesh/sdk-vpp/pkg/tools/mechutils"
)
Expand Down Expand Up @@ -147,18 +148,34 @@ 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 dumpAndDelete(ctx context.Context, vppConn api.Connection, podName string, isClient bool) error {
log.FromContext(ctx).WithField("dump", "TapV2").Debug("started")
return dumptool.DumpVppInterfaces(ctx, vppConn, podName, isClient,
/* Function on dump */
func(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 {
dumpOpt *dumptool.DumpOption
}

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

// WithDump - sets dump parameters
func WithDump(dump *dumptool.DumpOption) Option {
return func(o *options) {
o.dumpOpt = 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.dumpOpt != nil {
if err := dumpAndDelete(o.dumpOpt.Ctx, vppConn, o.dumpOpt.PodName, true); err != nil {
log.FromContext(o.dumpOpt.Ctx).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 {
dumpOpt *dumptool.DumpOption
}

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

// WithDump - sets dump parameters
func WithDump(dump *dumptool.DumpOption) Option {
return func(o *options) {
o.dumpOpt = 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.dumpOpt))
}
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{
PodName: 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
69 changes: 69 additions & 0 deletions pkg/tools/dumptool/dumptool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// 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"
)

// DumpFn - action with dumped NSM interfaces
type DumpFn func(details *interfaces.SwInterfaceDetails) error

// DumpOption - option that configures chain elements
type DumpOption struct {
Ctx context.Context
PodName string
}

// 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, podName string, isClient bool, onDump DumpFn) 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.PodName != podName || t.IsClient != isClient {
continue
}

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