Skip to content

Commit

Permalink
Merge pull request #6 from edwarnicke/kernel
Browse files Browse the repository at this point in the history
Add kernel mechanism chain elements
  • Loading branch information
fkautz authored Nov 18, 2020
2 parents a4a4d7d + f262332 commit 6ec28c5
Show file tree
Hide file tree
Showing 21 changed files with 1,031 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,8 @@ issues:
exclude-use-default: false
max-issues-per-linter: 0
max-same-issues: 0
exclude-rules:
- path: pkg/networkservice/mechanisms/kernel/kernelvethpair/common.go
linters:
- funlen
text: "Function 'create' has too many statements"
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ require (
github.com/networkservicemesh/sdk v0.0.0-20201118015836-556282f04005
github.com/pkg/errors v0.9.1
github.com/vishvananda/netlink v1.1.0
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df
google.golang.org/grpc v1.33.2
)
38 changes: 38 additions & 0 deletions pkg/networkservice/mechanisms/kernel/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2020 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 (
"os"

"git.fd.io/govpp.git/api"
"github.com/networkservicemesh/api/pkg/api/networkservice"

"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/kernel/kernelvethpair"

"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/kernel/kerneltap"
)

// NewClient - returns a new Client chain element implementing the kernel mechanism with vpp
func NewClient(vppConn api.Connection) networkservice.NetworkServiceClient {
if _, err := os.Stat(vnetFilename); err == nil {
return kerneltap.NewClient(vppConn)
}
return kernelvethpair.NewClient(vppConn)
}
27 changes: 27 additions & 0 deletions pkg/networkservice/mechanisms/kernel/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2020 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 kernel

import (
"github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/kernel"
)

const (
// MECHANISM string
MECHANISM = kernel.MECHANISM
vnetFilename = "/dev/vhost-net"
)
18 changes: 18 additions & 0 deletions pkg/networkservice/mechanisms/kernel/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2020 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 kernel provides chain elements for implementing the kernel mechanism with vpp
package kernel
72 changes: 72 additions & 0 deletions pkg/networkservice/mechanisms/kernel/kerneltap/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright (c) 2020 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 (
"context"

"git.fd.io/govpp.git/api"
"github.com/golang/protobuf/ptypes/empty"
"github.com/networkservicemesh/api/pkg/api/networkservice"
"github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/cls"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/next"
"google.golang.org/grpc"

"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata"
)

type kernelTapClient struct {
vppConn api.Connection
}

// NewClient - return a new Client chain element implementing the kernel mechanism with vpp using tapv2
func NewClient(vppConn api.Connection) networkservice.NetworkServiceClient {
return &kernelTapClient{
vppConn: vppConn,
}
}

func (k *kernelTapClient) Request(ctx context.Context, request *networkservice.NetworkServiceRequest, opts ...grpc.CallOption) (*networkservice.Connection, error) {
mechanism := &networkservice.Mechanism{
Cls: cls.LOCAL,
Type: MECHANISM,
Parameters: make(map[string]string),
}
request.MechanismPreferences = append(request.MechanismPreferences, mechanism)
conn, err := next.Client(ctx).Request(ctx, request, opts...)
if err != nil {
return nil, err
}
if err := create(ctx, conn, k.vppConn, metadata.IsClient(k)); err != nil {
_, _ = k.Close(ctx, conn, opts...)
return nil, err
}
return conn, nil
}

func (k *kernelTapClient) Close(ctx context.Context, conn *networkservice.Connection, opts ...grpc.CallOption) (*empty.Empty, error) {
rv, err := next.Client(ctx).Close(ctx, conn, opts...)
if err != nil {
return nil, err
}
if err := del(ctx, conn, k.vppConn, metadata.IsClient(k)); err != nil {
return nil, err
}
return rv, nil
}
99 changes: 99 additions & 0 deletions pkg/networkservice/mechanisms/kernel/kerneltap/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright (c) 2020 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 (
"context"
"time"

"git.fd.io/govpp.git/api"
interfaces "github.com/edwarnicke/govpp/binapi/interface"
"github.com/edwarnicke/govpp/binapi/interface_types"
"github.com/edwarnicke/govpp/binapi/tapv2"
"github.com/networkservicemesh/api/pkg/api/networkservice"
"github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/kernel"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/trace"

"github.com/pkg/errors"

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

func create(ctx context.Context, conn *networkservice.Connection, vppConn api.Connection, isClient bool) error {
if mechanism := kernel.ToMechanism(conn.GetMechanism()); mechanism != nil {
if _, ok := ifindex.Load(ctx, isClient); ok {
return nil
}
now := time.Now()
rsp, err := tapv2.NewServiceClient(vppConn).TapCreateV2(ctx, &tapv2.TapCreateV2{
ID: ^uint32(0),
UseRandomMac: true,
NumRxQueues: 1,
HostIfNameSet: true,
HostIfName: linuxIfaceName(mechanism.GetInterfaceName(conn)),
//TapFlags: 0, // TODO - TUN support for v3 payloads
})
if err != nil {
return errors.WithStack(err)
}
trace.Log(ctx).
WithField("swIfIndex", rsp.SwIfIndex).
WithField("duration", time.Since(now)).
WithField("vppapi", "TapCreateV2").Debug("completed")
ifindex.Store(ctx, isClient, rsp.SwIfIndex)

now = time.Now()
if _, err := interfaces.NewServiceClient(vppConn).SwInterfaceSetRxMode(ctx, &interfaces.SwInterfaceSetRxMode{
SwIfIndex: rsp.SwIfIndex,
Mode: interface_types.RX_MODE_API_ADAPTIVE,
}); err != nil {
return errors.WithStack(err)
}
trace.Log(ctx).
WithField("swIfIndex", rsp.SwIfIndex).
WithField("mode", interface_types.RX_MODE_API_ADAPTIVE).
WithField("duration", time.Since(now)).
WithField("vppapi", "SwInterfaceSetRxMode").Debug("completed")
}
return nil
}

func del(ctx context.Context, conn *networkservice.Connection, vppConn api.Connection, isClient bool) error {
if mechanism := kernel.ToMechanism(conn.GetMechanism()); mechanism != nil {
swIfIndex, ok := ifindex.Load(ctx, isClient)
if !ok {
return nil
}
_, err := tapv2.NewServiceClient(vppConn).TapDeleteV2(ctx, &tapv2.TapDeleteV2{
SwIfIndex: swIfIndex,
})
if err != nil {
return errors.WithStack(err)
}
return nil
}
return nil
}

func linuxIfaceName(ifaceName string) string {
if len(ifaceName) <= kernel.LinuxIfMaxLength {
return ifaceName
}
return ifaceName[:kernel.LinuxIfMaxLength]
}
24 changes: 24 additions & 0 deletions pkg/networkservice/mechanisms/kernel/kerneltap/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2020 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 kerneltap

import "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/kernel"

const (
// MECHANISM string
MECHANISM = kernel.MECHANISM
)
18 changes: 18 additions & 0 deletions pkg/networkservice/mechanisms/kernel/kerneltap/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2020 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 kerneltap provides chain elements for implementing the kernel mechanism with vpp tapv2
package kerneltap
59 changes: 59 additions & 0 deletions pkg/networkservice/mechanisms/kernel/kerneltap/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) 2020 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 (
"context"

"git.fd.io/govpp.git/api"
"github.com/golang/protobuf/ptypes/empty"
"github.com/networkservicemesh/api/pkg/api/networkservice"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/next"

"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata"
)

type kernelTapServer struct {
vppConn api.Connection
}

// NewServer - return a new Server chain element implementing the kernel mechanism with vpp using tapv2
func NewServer(vppConn api.Connection) networkservice.NetworkServiceServer {
return &kernelTapServer{
vppConn: vppConn,
}
}

func (k *kernelTapServer) Request(ctx context.Context, request *networkservice.NetworkServiceRequest) (*networkservice.Connection, error) {
if err := create(ctx, request.GetConnection(), k.vppConn, metadata.IsClient(k)); err != nil {
return nil, err
}
conn, err := next.Server(ctx).Request(ctx, request)
if err != nil {
_ = del(ctx, conn, k.vppConn, false)
}
return conn, err
}

func (k *kernelTapServer) Close(ctx context.Context, conn *networkservice.Connection) (*empty.Empty, error) {
if err := del(ctx, conn, k.vppConn, metadata.IsClient(k)); err != nil {
return nil, err
}
return next.Server(ctx).Close(ctx, conn)
}
Loading

0 comments on commit 6ec28c5

Please sign in to comment.