Skip to content

Commit

Permalink
MTU fix for cmd-forwarder-vpp#557 (#554)
Browse files Browse the repository at this point in the history
Signed-off-by: Ed Warnicke <hagbard@gmail.com>
  • Loading branch information
edwarnicke authored Apr 11, 2022
1 parent c508e18 commit dc652f0
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 78 deletions.
20 changes: 4 additions & 16 deletions pkg/networkservice/connectioncontext/mtu/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (

"github.com/networkservicemesh/api/pkg/api/networkservice"
"github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/vlan"
"github.com/networkservicemesh/api/pkg/api/networkservice/payload"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/next"
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata"
"github.com/networkservicemesh/sdk/pkg/tools/postpone"
Expand Down Expand Up @@ -81,22 +80,11 @@ func (m *mtuClient) Request(ctx context.Context, request *networkservice.Network
return conn, nil
}

if conn.GetPayload() == payload.Ethernet {
if err := setVPPL2MTU(ctx, conn, m.vppConn, metadata.IsClient(m)); err != nil {
if closeErr := m.closeOnFailure(postponeCtxFunc, conn, opts); closeErr != nil {
err = errors.Wrapf(err, "connection closed with error: %s", closeErr.Error())
}
return nil, err
}
}

if conn.GetPayload() == payload.IP {
if err := setVPPL3MTU(ctx, conn, m.vppConn, metadata.IsClient(m)); err != nil {
if closeErr := m.closeOnFailure(postponeCtxFunc, conn, opts); closeErr != nil {
err = errors.Wrapf(err, "connection closed with error: %s", closeErr.Error())
}
return nil, err
if err := setVPPMTU(ctx, conn, m.vppConn, metadata.IsClient(m)); err != nil {
if closeErr := m.closeOnFailure(postponeCtxFunc, conn, opts); closeErr != nil {
err = errors.Wrapf(err, "connection closed with error: %s", closeErr.Error())
}
return nil, err
}

return conn, nil
Expand Down
33 changes: 2 additions & 31 deletions pkg/networkservice/connectioncontext/mtu/common.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2021 Cisco and/or its affiliates.
// Copyright (c) 2021-2022 Cisco and/or its affiliates.
//
// SPDX-License-Identifier: Apache-2.0
//
Expand Down Expand Up @@ -34,36 +34,7 @@ const (
jumboFrameSize = 9000
)

func setVPPL2MTU(ctx context.Context, conn *networkservice.Connection, vppConn api.Connection, isClient bool) error {
now := time.Now()
swIfIndex, ok := ifindex.Load(ctx, isClient)
if !ok || conn.GetContext().GetMTU() == 0 {
return nil
}
setMTU := &interfaces.HwInterfaceSetMtu{
SwIfIndex: swIfIndex,
Mtu: uint16(conn.GetContext().GetMTU()),
}
_, err := interfaces.NewServiceClient(vppConn).HwInterfaceSetMtu(ctx, setMTU)
if err != nil {
err = errors.WithStack(err)
log.FromContext(ctx).
WithField("SwIfIndex", setMTU.SwIfIndex).
WithField("MTU", setMTU.Mtu).
WithField("duration", time.Since(now)).
WithField("error", err).
WithField("vppapi", "HwInterfaceSetMtu").Debug("error")
return err
}
log.FromContext(ctx).
WithField("SwIfIndex", setMTU.SwIfIndex).
WithField("MTU", setMTU.Mtu).
WithField("duration", time.Since(now)).
WithField("vppapi", "HwInterfaceSetMtu").Debug("completed")
return nil
}

func setVPPL3MTU(ctx context.Context, conn *networkservice.Connection, vppConn api.Connection, isClient bool) error {
func setVPPMTU(ctx context.Context, conn *networkservice.Connection, vppConn api.Connection, isClient bool) error {
now := time.Now()
swIfIndex, ok := ifindex.Load(ctx, isClient)
if !ok || conn.GetContext().GetMTU() == 0 {
Expand Down
22 changes: 5 additions & 17 deletions pkg/networkservice/connectioncontext/mtu/server.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2021 Cisco and/or its affiliates.
// Copyright (c) 2021-2022 Cisco and/or its affiliates.
//
// SPDX-License-Identifier: Apache-2.0
//
Expand All @@ -24,7 +24,6 @@ import (
"github.com/pkg/errors"

"github.com/networkservicemesh/api/pkg/api/networkservice"
"github.com/networkservicemesh/api/pkg/api/networkservice/payload"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/next"
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata"
"github.com/networkservicemesh/sdk/pkg/tools/postpone"
Expand Down Expand Up @@ -72,22 +71,11 @@ func (m *mtuServer) Request(ctx context.Context, request *networkservice.Network
return nil, err
}

if conn.GetPayload() == payload.Ethernet {
if err := setVPPL2MTU(ctx, conn, m.vppConn, metadata.IsClient(m)); err != nil {
if closeErr := m.closeOnFailure(postponeCtxFunc, conn); closeErr != nil {
err = errors.Wrapf(err, "connection closed with error: %s", closeErr.Error())
}
return nil, err
}
}

if conn.GetPayload() == payload.IP {
if err := setVPPL3MTU(ctx, conn, m.vppConn, metadata.IsClient(m)); err != nil {
if closeErr := m.closeOnFailure(postponeCtxFunc, conn); closeErr != nil {
err = errors.Wrapf(err, "connection closed with error: %s", closeErr.Error())
}
return nil, err
if err := setVPPMTU(ctx, conn, m.vppConn, metadata.IsClient(m)); err != nil {
if closeErr := m.closeOnFailure(postponeCtxFunc, conn); closeErr != nil {
err = errors.Wrapf(err, "connection closed with error: %s", closeErr.Error())
}
return nil, err
}

return conn, nil
Expand Down
29 changes: 22 additions & 7 deletions pkg/networkservice/mechanisms/vxlan/mtu/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ import (
"github.com/networkservicemesh/sdk-vpp/pkg/tools/types"
)

const (
overhead = 50
)

func getMTU(ctx context.Context, vppConn api.Connection, tunnelIP net.IP) (uint32, error) {
client, err := interfaces.NewServiceClient(vppConn).SwInterfaceDump(ctx, &interfaces.SwInterfaceDump{})
if err != nil {
Expand Down Expand Up @@ -67,10 +63,29 @@ func getMTU(ctx context.Context, vppConn api.Connection, tunnelIP net.IP) (uint3
if err != nil {
return 0, errors.Wrapf(err, "error attempting to get interface ip address for %q (swIfIndex: %q) to determine MTU for tunnelIP %q", details.InterfaceName, details.SwIfIndex, tunnelIP)
}
if types.FromVppAddressWithPrefix(ipAddressDetails.Prefix).IP.Equal(tunnelIP) {
return (uint32(details.LinkMtu) - overhead), nil
if types.FromVppAddressWithPrefix(ipAddressDetails.Prefix).IP.Equal(tunnelIP) && details.Mtu[0] != 0 {
return (details.Mtu[0] - overhead(tunnelIP.To4() == nil)), nil
}
}
}
return 0, errors.Errorf("unable to find interface in vpp with tunnelIP: %q", tunnelIP)
return 0, errors.Errorf("unable to find interface in vpp with tunnelIP: %q or interface IP MTU is zero", tunnelIP)
}

func overhead(isV6 bool) uint32 {
if !isV6 {
// outer ipv4 header - 20 bytes
// outer udp header - 8 bytes
// vxlan header - 8 bytes
// inner ethernet header - 14 bytes
// optional overhead for 802.1q vlan tags - 4 bytes
// total - 54 bytes
return 54
}
// outer ipv6 header - 40 bytes
// outer udp header - 8 bytes
// vxlan header - 8 bytes
// inner ethernet header - 14 bytes
// optional overhead for 802.1q vlan tags - 4 bytes
// total - 74 bytes
return 74
}
32 changes: 25 additions & 7 deletions pkg/networkservice/mechanisms/wireguard/mtu/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ import (
"github.com/networkservicemesh/sdk-vpp/pkg/tools/types"
)

const (
overhead = 80
)

func getMTU(ctx context.Context, vppConn api.Connection, tunnelIP net.IP) (uint32, error) {
client, err := interfaces.NewServiceClient(vppConn).SwInterfaceDump(ctx, &interfaces.SwInterfaceDump{})
if err != nil {
Expand Down Expand Up @@ -67,10 +63,32 @@ func getMTU(ctx context.Context, vppConn api.Connection, tunnelIP net.IP) (uint3
if err != nil {
return 0, errors.Wrapf(err, "error attempting to get interface ip address for %q (swIfIndex: %q) to determine MTU for tunnelIP %q", details.InterfaceName, details.SwIfIndex, tunnelIP)
}
if types.FromVppAddressWithPrefix(ipAddressDetails.Prefix).IP.Equal(tunnelIP) {
return (uint32(details.LinkMtu) - overhead), nil
if types.FromVppAddressWithPrefix(ipAddressDetails.Prefix).IP.Equal(tunnelIP) && details.Mtu[0] != 0 {
return (details.Mtu[0] - overhead(tunnelIP.To4() == nil)), nil
}
}
}
return 0, errors.Errorf("unable to find interface in vpp with tunnelIP: %q", tunnelIP)
return 0, errors.Errorf("unable to find interface in vpp with tunnelIP: %q or interface IP MTU is zero", tunnelIP)
}

func overhead(isV6 bool) uint32 {
// https://lists.zx2c4.com/pipermail/wireguard/2017-December/002201.html
if !isV6 {
// 20-byte outer IPv4 header
// 8-byte outer UDP header
// 4-byte type
// 4-byte key index
// 8-byte nonce
// 16-byte authentication tag
// 60 byte total
return 60
}
// 40-byte outer IPv4 header
// 8-byte outer UDP header
// 4-byte type
// 4-byte key index
// 8-byte nonce
// 16-byte authentication tag
// 80 bytes total
return 80
}

0 comments on commit dc652f0

Please sign in to comment.