-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add xconnectns, l2ovsconnect and mechanism chain elements
Signed-off-by: Periyasamy Palanisamy <periyasamy.palanisamy@est.tech>
- Loading branch information
1 parent
4982523
commit 8ae1a4a
Showing
15 changed files
with
2,259 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,17 @@ | ||
module github.com/networkservicemesh/sdk-ovs | ||
|
||
go 1.16 | ||
|
||
require ( | ||
github.com/Mellanox/sriovnet v1.0.2 | ||
github.com/golang/protobuf v1.4.3 | ||
github.com/networkservicemesh/api v0.0.0-20210527182901-ea452d7e044c | ||
github.com/networkservicemesh/sdk v0.0.0-20210528062336-1864bcaad34d | ||
github.com/networkservicemesh/sdk-kernel v0.0.0-20210528062716-20d39a8e1bc9 | ||
github.com/networkservicemesh/sdk-sriov v0.0.0-20210523200748-80fab22ffef1 | ||
github.com/ovn-org/ovn-kubernetes/go-controller v0.0.0-20210526211758-faa6b74b102b | ||
github.com/pkg/errors v0.9.1 | ||
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852 | ||
google.golang.org/grpc v1.35.0 | ||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
// Copyright (c) 2021 Nordix Foundation. | ||
// | ||
// 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 xconnectns | ||
|
||
import ( | ||
"context" | ||
"net" | ||
"net/url" | ||
"sync" | ||
|
||
"github.com/networkservicemesh/api/pkg/api/networkservice" | ||
kernelmech "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/kernel" | ||
vxlanmech "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/vxlan" | ||
"github.com/networkservicemesh/sdk-kernel/pkg/kernel/networkservice/connectioncontextkernel" | ||
"github.com/networkservicemesh/sdk-kernel/pkg/kernel/networkservice/inject" | ||
"github.com/networkservicemesh/sdk-kernel/pkg/kernel/networkservice/rename" | ||
"github.com/networkservicemesh/sdk-sriov/pkg/networkservice/common/resourcepool" | ||
"github.com/networkservicemesh/sdk-sriov/pkg/sriov" | ||
"github.com/networkservicemesh/sdk-sriov/pkg/sriov/config" | ||
"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/chain" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata" | ||
"github.com/networkservicemesh/sdk/pkg/tools/log" | ||
"github.com/networkservicemesh/sdk/pkg/tools/token" | ||
ovsutil "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util" | ||
"google.golang.org/grpc" | ||
kexec "k8s.io/utils/exec" | ||
|
||
"github.com/networkservicemesh/sdk-ovs/pkg/networkservice/l2ovsconnect" | ||
"github.com/networkservicemesh/sdk-ovs/pkg/networkservice/mechanisms/kernel" | ||
"github.com/networkservicemesh/sdk-ovs/pkg/networkservice/mechanisms/vxlan" | ||
"github.com/networkservicemesh/sdk-ovs/pkg/tools/util" | ||
) | ||
|
||
type ovsConnectNSServer struct { | ||
endpoint.Endpoint | ||
} | ||
|
||
// NewSriovServer - returns sriov implementation of the ovsconnectns network service | ||
func NewSriovServer(ctx context.Context, name string, authzServer networkservice.NetworkServiceServer, | ||
tokenGenerator token.GeneratorFunc, clientURL *url.URL, bridgeName string, tunnelIpCidr net.IP, | ||
pciPool resourcepool.PCIPool, resourcePool resourcepool.ResourcePool, sriovConfig *config.Config, | ||
clientDialOptions ...grpc.DialOption) (endpoint.Endpoint, error) { | ||
resourceLock := &sync.Mutex{} | ||
tunnelIP, err := util.ParseTunnelIP(tunnelIpCidr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
vxlanInterfacesMutex := &sync.Mutex{} | ||
vxlanInterfaces := make(map[string]int) | ||
rv := &ovsConnectNSServer{} | ||
additionalFunctionality := []networkservice.NetworkServiceServer{ | ||
metadata.NewServer(), | ||
recvfd.NewServer(), | ||
// Statically set the url we use to the unix file socket for the NSMgr | ||
clienturl.NewServer(clientURL), | ||
connect.NewServer( | ||
ctx, | ||
func(ctx context.Context, cc grpc.ClientConnInterface) networkservice.NetworkServiceClient { | ||
return client.NewClient(ctx, | ||
cc, | ||
client.WithName(name), | ||
client.WithAdditionalFunctionality( | ||
mechanismtranslation.NewClient(), | ||
connectioncontextkernel.NewClient(), | ||
// TODO: uncomment once inject chain element has NewClient | ||
//inject.NewClient(), | ||
// mechanisms | ||
kernel.NewClient(bridgeName), | ||
// TODO: uncomment once resourcepool chain element has NewClient | ||
//resourcepool.NewClient(sriov.KernelDriver, resourceLock, pciPool, resourcePool, sriovConfig), | ||
vxlan.NewClient(tunnelIP, bridgeName, vxlanInterfacesMutex, vxlanInterfaces), | ||
recvfd.NewClient(), | ||
sendfd.NewClient(), | ||
), | ||
) | ||
}, | ||
connect.WithDialOptions(clientDialOptions...), | ||
), | ||
mechanisms.NewServer(map[string]networkservice.NetworkServiceServer{ | ||
kernelmech.MECHANISM: chain.NewNetworkServiceServer( | ||
kernel.NewServer(bridgeName), | ||
resourcepool.NewServer(sriov.KernelDriver, resourceLock, pciPool, resourcePool, sriovConfig), | ||
rename.NewServer(), | ||
), | ||
vxlanmech.MECHANISM: vxlan.NewServer(tunnelIP, bridgeName, vxlanInterfacesMutex, vxlanInterfaces), | ||
}), | ||
inject.NewServer(), | ||
connectioncontextkernel.NewServer(), | ||
l2ovsconnect.NewServer(bridgeName), | ||
sendfd.NewServer(), | ||
} | ||
|
||
rv.Endpoint = endpoint.NewServer(ctx, tokenGenerator, | ||
endpoint.WithName(name), | ||
endpoint.WithAuthorizeServer(authzServer), | ||
endpoint.WithAdditionalFunctionality(additionalFunctionality...)) | ||
|
||
return rv, nil | ||
} | ||
|
||
// NewKernelServer - returns kernel implementation of the ovsconnectns network service | ||
func NewKernelServer(ctx context.Context, name string, authzServer networkservice.NetworkServiceServer, | ||
tokenGenerator token.GeneratorFunc, clientURL *url.URL, bridgeName string, tunnelIpCidr net.IP, | ||
clientDialOptions ...grpc.DialOption) (endpoint.Endpoint, error) { | ||
tunnelIP, err := util.ParseTunnelIP(tunnelIpCidr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
vxlanInterfacesMutex := &sync.Mutex{} | ||
vxlanInterfaces := make(map[string]int) | ||
rv := &ovsConnectNSServer{} | ||
additionalFunctionality := []networkservice.NetworkServiceServer{ | ||
metadata.NewServer(), | ||
recvfd.NewServer(), | ||
// Statically set the url we use to the unix file socket for the NSMgr | ||
clienturl.NewServer(clientURL), | ||
connect.NewServer( | ||
ctx, | ||
func(ctx context.Context, cc grpc.ClientConnInterface) networkservice.NetworkServiceClient { | ||
return client.NewClient(ctx, | ||
cc, | ||
client.WithName(name), | ||
client.WithAdditionalFunctionality( | ||
mechanismtranslation.NewClient(), | ||
connectioncontextkernel.NewClient(), | ||
// TODO: uncomment once inject chain element has NewClient | ||
//inject.NewClient(), | ||
// mechanisms | ||
kernel.NewClient(bridgeName), | ||
vxlan.NewClient(tunnelIP, bridgeName, vxlanInterfacesMutex, vxlanInterfaces), | ||
recvfd.NewClient(), | ||
sendfd.NewClient(), | ||
), | ||
) | ||
}, | ||
connect.WithDialOptions(clientDialOptions...), | ||
), | ||
mechanisms.NewServer(map[string]networkservice.NetworkServiceServer{ | ||
kernelmech.MECHANISM: chain.NewNetworkServiceServer( | ||
kernel.NewServer(bridgeName), | ||
rename.NewServer(), | ||
), | ||
vxlanmech.MECHANISM: vxlan.NewServer(tunnelIP, bridgeName, vxlanInterfacesMutex, vxlanInterfaces), | ||
}), | ||
inject.NewServer(), | ||
connectioncontextkernel.NewServer(), | ||
l2ovsconnect.NewServer(bridgeName), | ||
sendfd.NewServer(), | ||
} | ||
|
||
rv.Endpoint = endpoint.NewServer(ctx, tokenGenerator, | ||
endpoint.WithName(name), | ||
endpoint.WithAuthorizeServer(authzServer), | ||
endpoint.WithAdditionalFunctionality(additionalFunctionality...)) | ||
|
||
return rv, nil | ||
} | ||
|
||
func configureOvS(ctx context.Context, bridgeName string) { | ||
// Initialize the ovs utility wrapper. | ||
exec := kexec.New() | ||
if err := ovsutil.SetExec(exec); err != nil { | ||
log.FromContext(ctx).Warnf("failed to initialize ovs exec helper: %v", err) | ||
} | ||
|
||
// Create ovs bridge for client and endpoint connections | ||
stdout, stderr, err := ovsutil.RunOVSVsctl("--", "--may-exist", "add-br", bridgeName) | ||
if err != nil { | ||
log.FromContext(ctx).Warnf("Failed to add bridge %s, stdout: %q, stderr: %q, error: %v", bridgeName, stdout, stderr, err) | ||
} | ||
|
||
// Clean the flows from the above created ovs bridge | ||
stdout, stderr, err = ovsutil.RunOVSOfctl("del-flows", bridgeName) | ||
if err != nil { | ||
log.FromContext(ctx).Warnf("Failed to cleanup flows on %s "+ | ||
"stdout: %q, stderr: %q, error: %v", bridgeName, stdout, stderr, err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright (c) 2021 Nordix Foundation. | ||
// | ||
// 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 l2ovsconnect | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/networkservicemesh/sdk/pkg/tools/log" | ||
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util" | ||
|
||
"github.com/networkservicemesh/sdk-ovs/pkg/tools/ifnames" | ||
) | ||
|
||
func createLocalCrossConnect(ctx context.Context, logger log.Logger, bridgeName string, endpointOvsPortInfo, | ||
clientOvsPortInfo ifnames.OvsPortInfo) error { | ||
stdout, stderr, err := util.RunOVSOfctl("add-flow", bridgeName, fmt.Sprintf("priority=100, in_port=%d,"+ | ||
" actions=output:%d", endpointOvsPortInfo.PortNo, clientOvsPortInfo.PortNo)) | ||
if err != nil { | ||
logger.Infof("Failed to add flow on %s for port %s stdout: %s"+ | ||
" stderr: %s, error: %v", bridgeName, endpointOvsPortInfo.PortName, stdout, stderr, err) | ||
return err | ||
} | ||
if stderr != "" { | ||
logger.Errorf("Failed to add flow on %s for port %s stdout: %s"+ | ||
" stderr: %s", bridgeName, endpointOvsPortInfo.PortName, stdout, stderr) | ||
} | ||
|
||
stdout, stderr, err = util.RunOVSOfctl("add-flow", bridgeName, fmt.Sprintf("priority=100, in_port=%d,"+ | ||
" actions=output:%d", clientOvsPortInfo.PortNo, endpointOvsPortInfo.PortNo)) | ||
if err != nil { | ||
logger.Errorf("Failed to add flow on %s for port %s stdout: %s"+ | ||
" stderr: %s, error: %v", bridgeName, clientOvsPortInfo.PortName, stdout, stderr, err) | ||
return err | ||
} | ||
|
||
if stderr != "" { | ||
logger.Errorf("Failed to add flow on %s for port %s stdout: %s"+ | ||
" stderr: %s", bridgeName, clientOvsPortInfo.PortName, stdout, stderr) | ||
} | ||
return nil | ||
} | ||
|
||
func deleteLocalCrossConnect(ctx context.Context, logger log.Logger, bridgeName string, endpointOvsPortInfo, | ||
clientOvsPortInfo ifnames.OvsPortInfo) error { | ||
stdout, stderr, err := util.RunOVSOfctl("del-flows", bridgeName, fmt.Sprintf("in_port=%d", | ||
endpointOvsPortInfo.PortNo)) | ||
if err != nil { | ||
logger.Errorf("Failed to delete flow on %s for port "+ | ||
"%s, stdout: %q, stderr: %q, error: %v", bridgeName, endpointOvsPortInfo.PortName, stdout, stderr, err) | ||
return err | ||
} | ||
|
||
stdout, stderr, err = util.RunOVSOfctl("del-flows", bridgeName, fmt.Sprintf("in_port=%d", clientOvsPortInfo.PortNo)) | ||
if err != nil { | ||
logger.Errorf("Failed to delete flow on %s for port "+ | ||
"%s, stdout: %q, stderr: %q, error: %v", bridgeName, clientOvsPortInfo.PortName, stdout, stderr, err) | ||
} | ||
return nil | ||
} |
Oops, something went wrong.