Skip to content

Commit

Permalink
Delete previous tap interfaces by tag
Browse files Browse the repository at this point in the history
Signed-off-by: Artem Glazychev <[email protected]>
  • Loading branch information
glazychev-art committed Apr 6, 2022
1 parent 3234734 commit 193d7bd
Show file tree
Hide file tree
Showing 12 changed files with 302 additions and 27 deletions.
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,
}

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.
// 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{
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

0 comments on commit 193d7bd

Please sign in to comment.