Skip to content

Commit

Permalink
Merge pull request #203 from Nordix/fix-mtu
Browse files Browse the repository at this point in the history
Fix MTU adjustment in case of remote vlan mechanism
  • Loading branch information
denis-tingaikin authored Nov 29, 2022
2 parents 0ca8e13 + 447a692 commit 0a3b60a
Show file tree
Hide file tree
Showing 7 changed files with 275 additions and 2 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/vishvananda/netlink v1.2.1-beta.2.0.20220630165224-c591ada0fb2b
google.golang.org/grpc v1.49.0
google.golang.org/protobuf v1.28.1
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b
)

Expand Down Expand Up @@ -95,7 +96,6 @@ require (
golang.org/x/tools v0.1.12 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220908141613-51c1cc9bc6d0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
gopkg.in/gcfg.v1 v1.2.3 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
Expand Down
7 changes: 6 additions & 1 deletion pkg/networkservice/mechanisms/vlan/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ import (
"github.com/networkservicemesh/api/pkg/api/networkservice"
"github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/cls"
vlanmech "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/vlan"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/chain"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/next"
"github.com/networkservicemesh/sdk/pkg/tools/log"
"github.com/networkservicemesh/sdk/pkg/tools/postpone"
"github.com/pkg/errors"
"google.golang.org/grpc"

"github.com/networkservicemesh/sdk-ovs/pkg/networkservice/mechanisms/vlan/mtu"
"github.com/networkservicemesh/sdk-ovs/pkg/tools/ifnames"
ovsutil "github.com/networkservicemesh/sdk-ovs/pkg/tools/utils"
)
Expand All @@ -51,7 +53,10 @@ type vlanClient struct {

// NewClient returns a client chain element implementing VLAN breakout for NS client
func NewClient(bridgeName string, l2Connections map[string]*ovsutil.L2ConnectionPoint) networkservice.NetworkServiceClient {
return &vlanClient{bridgeName: bridgeName, l2Connections: l2Connections}
return chain.NewNetworkServiceClient(
mtu.NewClient(l2Connections),
&vlanClient{bridgeName: bridgeName, l2Connections: l2Connections},
)
}

func (c *vlanClient) Request(ctx context.Context, request *networkservice.NetworkServiceRequest, opts ...grpc.CallOption) (*networkservice.Connection, error) {
Expand Down
100 changes: 100 additions & 0 deletions pkg/networkservice/mechanisms/vlan/mtu/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) 2022 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.

//go:build linux
// +build linux

package mtu

import (
"context"

"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/emptypb"

"github.com/networkservicemesh/api/pkg/api/networkservice"
"github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/vlan"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/next"
"github.com/networkservicemesh/sdk/pkg/tools/log"
"github.com/networkservicemesh/sdk/pkg/tools/postpone"

ovsutil "github.com/networkservicemesh/sdk-ovs/pkg/tools/utils"
)

const (
viaLabel = "via"
)

type mtuClient struct {
l2Connections map[string]*ovsutil.L2ConnectionPoint
mtus mtuMap
}

// NewClient - returns client chain element to manage vlan MTU
func NewClient(l2Connections map[string]*ovsutil.L2ConnectionPoint) networkservice.NetworkServiceClient {
return &mtuClient{
l2Connections: l2Connections,
}
}

func (m *mtuClient) Request(ctx context.Context, request *networkservice.NetworkServiceRequest, opts ...grpc.CallOption) (*networkservice.Connection, error) {
postponeCtxFunc := postpone.ContextWithValues(ctx)
logger := log.FromContext(ctx).WithField("vlanClient", "Request")

conn, err := next.Client(ctx).Request(ctx, request, opts...)
if err != nil {
return nil, err
}

if mechanism := vlan.ToMechanism(conn.GetMechanism()); mechanism != nil {
viaSelector, ok := conn.GetLabels()[viaLabel]
if !ok {
return conn, nil
}
l2Point, ok := m.l2Connections[viaSelector]
if !ok {
return conn, nil
}
if l2Point.Interface == "" {
return conn, nil
}
localMTU, loaded := m.mtus.Load(l2Point.Interface)
if !loaded {
localMTU, err = getMTU(l2Point, logger)
if err != nil {
closeCtx, cancelClose := postponeCtxFunc()
defer cancelClose()
if _, closeErr := m.Close(closeCtx, conn, opts...); closeErr != nil {
err = errors.Wrapf(err, "connection closed with error: %s", closeErr.Error())
}
return nil, err
}
m.mtus.Store(l2Point.Interface, localMTU)
}
if localMTU > 0 && (conn.GetContext().GetMTU() > localMTU || conn.GetContext().GetMTU() == 0) {
if conn.GetContext() == nil {
conn.Context = &networkservice.ConnectionContext{}
}
conn.GetContext().MTU = localMTU
}
}
return conn, nil
}

func (m *mtuClient) Close(ctx context.Context, conn *networkservice.Connection, opts ...grpc.CallOption) (*emptypb.Empty, error) {
return next.Client(ctx).Close(ctx, conn, opts...)
}
48 changes: 48 additions & 0 deletions pkg/networkservice/mechanisms/vlan/mtu/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2022 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.

//go:build linux
// +build linux

package mtu

import (
"time"

"github.com/networkservicemesh/sdk/pkg/tools/log"
"github.com/pkg/errors"
"github.com/vishvananda/netlink"

ovsutil "github.com/networkservicemesh/sdk-ovs/pkg/tools/utils"
)

func getMTU(l2CP *ovsutil.L2ConnectionPoint, logger log.Logger) (uint32, error) {
now := time.Now()
link, err := netlink.LinkByName(l2CP.Interface)
if err != nil {
return 0, nil
}
mtu := link.Attrs().MTU
logger.WithField("link.Name", link.Attrs().Name).
WithField("link.MTU", mtu).
WithField("duration", time.Since(now)).
WithField("netlink", "LinkByName").Debug("completed")
if mtu >= 0 && mtu <= 65535 {
return uint32(mtu), nil
}

return 0, errors.New("invalid MTU value")
}
21 changes: 21 additions & 0 deletions pkg/networkservice/mechanisms/vlan/mtu/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2022 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.

//go:build linux
// +build linux

// Package mtu computes the mtu for the vlan interface and adds it to context
package mtu
26 changes: 26 additions & 0 deletions pkg/networkservice/mechanisms/vlan/mtu/gen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2022 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 mtu

import (
"sync"
)

//go:generate go-syncmap -output mtu_map.gen.go -type mtuMap<string,uint32>

// mtuMap - sync.Map with key as interface name and value as MTU
type mtuMap sync.Map
73 changes: 73 additions & 0 deletions pkg/networkservice/mechanisms/vlan/mtu/mtu_map.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0a3b60a

Please sign in to comment.