Skip to content

Commit

Permalink
Fix MTU adjustment in case of remote vlan mechanism
Browse files Browse the repository at this point in the history
The MTU should be updated in connection context based on the base interface MTU

Relates PR: networkservicemesh/sdk-vpp/pull/656

Signed-off-by: Laszlo Kiraly <laszlo.kiraly@est.tech>
  • Loading branch information
ljkiraly committed Nov 15, 2022
1 parent e19ec59 commit 447a692
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 447a692

Please sign in to comment.