Skip to content

Commit

Permalink
Vxlan implementation. (#53)
Browse files Browse the repository at this point in the history
Signed-off-by: Ed Warnicke <hagbard@gmail.com>
  • Loading branch information
edwarnicke authored Jan 13, 2021
1 parent fe5a6c8 commit 54ae665
Show file tree
Hide file tree
Showing 22 changed files with 1,190 additions and 21 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
git.fd.io/govpp.git v0.3.6-0.20200903151113-c94a96227985
github.com/edwarnicke/govpp v0.0.0-20201111163523-106f68b6ba26
github.com/golang/protobuf v1.4.3
github.com/networkservicemesh/api v0.0.0-20201229064852-7d9663ff679a
github.com/networkservicemesh/api v0.0.0-20210112152104-45029fb10e27
github.com/networkservicemesh/sdk v0.0.0-20210109184324-006d62c50a0a
github.com/pkg/errors v0.9.1
github.com/thanhpk/randstr v1.0.4
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ github.com/edwarnicke/govpp v0.0.0-20201111163523-106f68b6ba26 h1:DBIEXF3iaF3RU3
github.com/edwarnicke/govpp v0.0.0-20201111163523-106f68b6ba26/go.mod h1:wQua0G5mhpwGNG4HuudYCikLZviQI8g7CngtH9fJFCo=
github.com/edwarnicke/grpcfd v0.0.0-20200920223154-d5b6e1f19bd0 h1:FHjcIM6YU8DnCw94+29EZX0bUqh016oqrtJrO8ZYiIY=
github.com/edwarnicke/grpcfd v0.0.0-20200920223154-d5b6e1f19bd0/go.mod h1:rHihB9YvNMixz8rS+ZbwosI2kj65VLkeyYAI2M+/cGA=
github.com/edwarnicke/serialize v0.0.0-20200705214914-ebc43080eecf h1:/lViRfaDxKINb2X6kOR3EJKJGR+MxUvqfgtYt5nh+qc=
github.com/edwarnicke/serialize v0.0.0-20200705214914-ebc43080eecf/go.mod h1:XvbCO/QGsl3X8RzjBMoRpkm54FIAZH5ChK2j+aox7pw=
github.com/edwarnicke/serialize v1.0.7 h1:geX8vmyu8Ij2S5fFIXjy9gBDkKxXnrMIzMoDvV0Ddac=
github.com/edwarnicke/serialize v1.0.7/go.mod h1:y79KgU2P7ALH/4j37uTSIdNavHFNttqN7pzO6Y8B2aw=
Expand Down Expand Up @@ -289,8 +288,9 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nats-io/stan.go v0.6.0/go.mod h1:eIcD5bi3pqbHT/xIIvXMwvzXYElgouBvaVRftaE+eac=
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
github.com/networkservicemesh/api v0.0.0-20201229064852-7d9663ff679a h1:kVCdG/y5MxZUKye7G+n7Sre7afg6fTa68VMJIYgLWB8=
github.com/networkservicemesh/api v0.0.0-20201229064852-7d9663ff679a/go.mod h1:qvxdY1Zt4QTtiG+uH1XmjpegeHjlt5Jj4A8iK55iJPI=
github.com/networkservicemesh/api v0.0.0-20210112152104-45029fb10e27 h1:J0UPj3sYfEvXwMHyAOiQ++NU7a3cZGZST1s1ftyC0uQ=
github.com/networkservicemesh/api v0.0.0-20210112152104-45029fb10e27/go.mod h1:qvxdY1Zt4QTtiG+uH1XmjpegeHjlt5Jj4A8iK55iJPI=
github.com/networkservicemesh/sdk v0.0.0-20210109184324-006d62c50a0a h1:8LZ+feSJ/aQNZR1FAVMiMDsTT+9UZ0aruXV7VoIA0X8=
github.com/networkservicemesh/sdk v0.0.0-20210109184324-006d62c50a0a/go.mod h1:Zpdjr7DejxfXXbZJyCFkJGwj4zG/vOsGJsRu8Raf3nw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
Expand Down
48 changes: 30 additions & 18 deletions pkg/networkservice/chains/xconnectns/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,39 @@ package xconnectns

import (
"context"
"net"
"net/url"

"git.fd.io/govpp.git/api"

"github.com/networkservicemesh/sdk/pkg/networkservice/common/mechanismtranslation"

"github.com/networkservicemesh/api/pkg/api/networkservice"

"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/up"
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/xconnect/l2xconnect"

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

"google.golang.org/grpc"

"github.com/networkservicemesh/sdk/pkg/networkservice/chains/client"
"github.com/networkservicemesh/sdk/pkg/networkservice/chains/endpoint"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/clienturl"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/connect"
"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/core/adapters"
"github.com/networkservicemesh/sdk/pkg/tools/addressof"
"github.com/networkservicemesh/sdk/pkg/tools/token"
"google.golang.org/grpc"

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

"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/connectioncontextkernel"
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/kernel"
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/memif"
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/tag"
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/up"
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/xconnect/l2xconnect"
)

// Connection aggregates the api.Connection and api.ChannelProvider interfaces
Expand All @@ -58,7 +66,7 @@ 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, baseDir string, clientDialOptions ...grpc.DialOption) endpoint.Endpoint {
func NewServer(ctx context.Context, name string, authzServer networkservice.NetworkServiceServer, tokenGenerator token.GeneratorFunc, clientURL *url.URL, vppConn Connection, baseDir string, tunnelIP net.IP, clientDialOptions ...grpc.DialOption) endpoint.Endpoint {
var lastSocketID uint32
rv := &xconnectNSServer{}
rv.Endpoint = endpoint.NewServer(ctx, name,
Expand All @@ -70,24 +78,28 @@ func NewServer(ctx context.Context, name string, authzServer networkservice.Netw
clienturl.NewServer(clientURL),
connect.NewServer(
ctx,
client.NewClientFactory(
name,
// What to call onHeal
addressof.NetworkServiceClient(adapters.NewServerToClient(rv)),
tokenGenerator,
mechanismtranslation.NewClient(),
connectioncontextkernel.NewClient(),
tag.NewClient(ctx, vppConn),
// mechanisms
memif.NewClient(vppConn, &lastSocketID),
kernel.NewClient(vppConn),
recvfd.NewClient(),
),
func(ctx context.Context, cc grpc.ClientConnInterface) networkservice.NetworkServiceClient {
return client.NewClient(ctx,
name,
addressof.NetworkServiceClient(adapters.NewServerToClient(rv)),
tokenGenerator,
cc,
mechanismtranslation.NewClient(),
connectioncontextkernel.NewClient(),
tag.NewClient(ctx, vppConn),
// mechanisms
memif.NewClient(vppConn, &lastSocketID),
kernel.NewClient(vppConn),
vxlan.NewClient(vppConn, tunnelIP),
recvfd.NewClient(),
)
},
clientDialOptions...,
),
mechanisms.NewServer(map[string]networkservice.NetworkServiceServer{
memif.MECHANISM: memif.NewServer(vppConn, baseDir, &lastSocketID),
kernel.MECHANISM: kernel.NewServer(vppConn),
vxlan.MECHANISM: vxlan.NewServer(vppConn, tunnelIP),
}),
tag.NewServer(ctx, vppConn),
connectioncontextkernel.NewServer(),
Expand Down
8 changes: 8 additions & 0 deletions pkg/networkservice/mechanisms/kernel/kernelvethpair/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ import (

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

"github.com/networkservicemesh/sdk-vpp/pkg/tools/ethtool"

"github.com/networkservicemesh/sdk/pkg/networkservice/core/trace"
"github.com/pkg/errors"
"github.com/thanhpk/randstr"
Expand Down Expand Up @@ -58,6 +61,11 @@ func create(ctx context.Context, conn *networkservice.Connection, isClient bool)
WithField("duration", time.Since(now)).
WithField("netlink", "LinkAdd").Debug("completed")

err := ethtool.DisableVethChkSumOffload(veth)
if err != nil {
return errors.WithStack(err)
}

// Construct the nsHandle and netlink handle for the target namespace for this kernel interface
nsHandle, err := mechutils.ToNSHandle(mechanism)
if err != nil {
Expand Down
82 changes: 82 additions & 0 deletions pkg/networkservice/mechanisms/vxlan/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// 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 vxlan

import (
"context"
"net"

"git.fd.io/govpp.git/api"
"github.com/golang/protobuf/ptypes/empty"

"github.com/networkservicemesh/sdk/pkg/networkservice/core/chain"

"github.com/networkservicemesh/api/pkg/api/networkservice"
"github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/cls"

"google.golang.org/grpc"

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

"github.com/networkservicemesh/sdk/pkg/networkservice/core/next"

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

type vxlanClient struct {
vppConn api.Connection
}

// NewClient - returns a new client for the vxlan remote mechanism
func NewClient(vppConn api.Connection, tunnelIP net.IP) networkservice.NetworkServiceClient {
return chain.NewNetworkServiceClient(
&vxlanClient{
vppConn: vppConn,
},
vni.NewClient(tunnelIP),
)
}

func (v *vxlanClient) Request(ctx context.Context, request *networkservice.NetworkServiceRequest, opts ...grpc.CallOption) (*networkservice.Connection, error) {
mechanism := &networkservice.Mechanism{
Cls: cls.REMOTE,
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 := addDel(ctx, conn, v.vppConn, true, metadata.IsClient(v)); err != nil {
_, _ = v.Close(ctx, conn, opts...)
return nil, err
}
return conn, nil
}

func (v *vxlanClient) 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 := addDel(ctx, conn, v.vppConn, false, metadata.IsClient(v)); err != nil {
return nil, err
}
return rv, nil
}
78 changes: 78 additions & 0 deletions pkg/networkservice/mechanisms/vxlan/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// 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 vxlan

import (
"context"
"time"

"git.fd.io/govpp.git/api"
"github.com/edwarnicke/govpp/binapi/vxlan"
"github.com/pkg/errors"

"github.com/networkservicemesh/api/pkg/api/networkservice"
vxlanMech "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/vxlan"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/trace"

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

func addDel(ctx context.Context, conn *networkservice.Connection, vppConn api.Connection, isAdd, isClient bool) error {
if mechanism := vxlanMech.ToMechanism(conn.GetMechanism()); mechanism != nil {
_, ok := ifindex.Load(ctx, isClient)
if isAdd && ok {
return nil
}
if !isAdd && !ok {
return nil
}
if mechanism.SrcIP() == nil {
return errors.Errorf("no vxlan SrcIP not provided")
}
if mechanism.DstIP() == nil {
return errors.Errorf("no vxlan DstIP not provided")
}

now := time.Now()
vxlanAddDelTunnel := &vxlan.VxlanAddDelTunnel{
IsAdd: isAdd,
Instance: ^uint32(0),
SrcAddress: types.ToVppAddress(mechanism.SrcIP()),
DstAddress: types.ToVppAddress(mechanism.DstIP()),
DecapNextIndex: ^uint32(0),
Vni: mechanism.VNI(),
}
if !isClient {
vxlanAddDelTunnel.SrcAddress = types.ToVppAddress(mechanism.DstIP())
vxlanAddDelTunnel.DstAddress = types.ToVppAddress(mechanism.SrcIP())
}
rsp, err := vxlan.NewServiceClient(vppConn).VxlanAddDelTunnel(ctx, vxlanAddDelTunnel)
if err != nil {
return errors.WithStack(err)
}
trace.Log(ctx).
WithField("swIfIndex", rsp.SwIfIndex).
WithField("SrcAddress", vxlanAddDelTunnel.SrcAddress).
WithField("DstAddress", vxlanAddDelTunnel.DstAddress).
WithField("Vni", vxlanAddDelTunnel.Vni).
WithField("duration", time.Since(now)).
WithField("vppapi", "VxlanAddDelTunnel").Debug("completed")
ifindex.Store(ctx, isClient, rsp.SwIfIndex)
}
return nil
}
26 changes: 26 additions & 0 deletions pkg/networkservice/mechanisms/vxlan/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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 vxlan

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

const (
// MECHANISM string
MECHANISM = vxlan.MECHANISM
)
18 changes: 18 additions & 0 deletions pkg/networkservice/mechanisms/vxlan/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 vxlan provides networkservice.NetworkService{Client,Server} chain elements for the vxlan mechanism
package vxlan
Loading

0 comments on commit 54ae665

Please sign in to comment.