diff --git a/pkg/networkservice/mechanisms/vxlan/mtu/client.go b/pkg/networkservice/mechanisms/vxlan/mtu/client.go index 7824e54d..e0d10f18 100644 --- a/pkg/networkservice/mechanisms/vxlan/mtu/client.go +++ b/pkg/networkservice/mechanisms/vxlan/mtu/client.go @@ -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 // @@ -20,12 +20,14 @@ import ( "context" "net" "sync" + "sync/atomic" "git.fd.io/govpp.git/api" - "github.com/networkservicemesh/sdk/pkg/networkservice/core/next" "google.golang.org/grpc" "google.golang.org/protobuf/types/known/emptypb" + "github.com/networkservicemesh/sdk/pkg/networkservice/core/next" + "github.com/networkservicemesh/api/pkg/api/networkservice" "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/vxlan" ) @@ -34,8 +36,9 @@ type mtuClient struct { vppConn api.Connection tunnelIP net.IP mtu uint32 - initOnce sync.Once - err error + + inited uint32 + initMutex sync.Mutex } // NewClient - returns client chain element to manage vxlan MTU @@ -70,8 +73,19 @@ func (m *mtuClient) Close(ctx context.Context, conn *networkservice.Connection, } func (m *mtuClient) init(ctx context.Context) error { - m.initOnce.Do(func() { - m.mtu, m.err = setMTU(ctx, m.vppConn, m.tunnelIP) - }) - return m.err + if atomic.LoadUint32(&m.inited) > 0 { + return nil + } + m.initMutex.Lock() + defer m.initMutex.Unlock() + if atomic.LoadUint32(&m.inited) > 0 { + return nil + } + + var err error + m.mtu, err = getMTU(ctx, m.vppConn, m.tunnelIP) + if err == nil { + atomic.StoreUint32(&m.inited, 1) + } + return err } diff --git a/pkg/networkservice/mechanisms/vxlan/mtu/common.go b/pkg/networkservice/mechanisms/vxlan/mtu/common.go index f388b004..7e1e067f 100644 --- a/pkg/networkservice/mechanisms/vxlan/mtu/common.go +++ b/pkg/networkservice/mechanisms/vxlan/mtu/common.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2021 Cisco and/or its affiliates. +// Copyright (c) 2020-2022 Cisco and/or its affiliates. // // SPDX-License-Identifier: Apache-2.0 // @@ -34,7 +34,7 @@ const ( overhead = 50 ) -func setMTU(ctx context.Context, vppConn api.Connection, tunnelIP net.IP) (uint32, error) { +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 { return 0, errors.Wrapf(err, "error attempting to get interface dump client to determine MTU for tunnelIP %q", tunnelIP) diff --git a/pkg/networkservice/mechanisms/vxlan/mtu/server.go b/pkg/networkservice/mechanisms/vxlan/mtu/server.go index 66e9cf0d..a1fd0c9b 100644 --- a/pkg/networkservice/mechanisms/vxlan/mtu/server.go +++ b/pkg/networkservice/mechanisms/vxlan/mtu/server.go @@ -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 // @@ -20,11 +20,13 @@ import ( "context" "net" "sync" + "sync/atomic" "git.fd.io/govpp.git/api" - "github.com/networkservicemesh/sdk/pkg/networkservice/core/next" "google.golang.org/protobuf/types/known/emptypb" + "github.com/networkservicemesh/sdk/pkg/networkservice/core/next" + "github.com/networkservicemesh/api/pkg/api/networkservice" "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/vxlan" ) @@ -33,8 +35,9 @@ type mtuServer struct { vppConn api.Connection tunnelIP net.IP mtu uint32 - initOnce sync.Once - err error + + inited uint32 + initMutex sync.Mutex } // NewServer - server chain element to manage vxlan MTU @@ -76,8 +79,19 @@ func (m *mtuServer) Close(ctx context.Context, conn *networkservice.Connection) } func (m *mtuServer) init(ctx context.Context) error { - m.initOnce.Do(func() { - m.mtu, m.err = setMTU(ctx, m.vppConn, m.tunnelIP) - }) - return m.err + if atomic.LoadUint32(&m.inited) > 0 { + return nil + } + m.initMutex.Lock() + defer m.initMutex.Unlock() + if atomic.LoadUint32(&m.inited) > 0 { + return nil + } + + var err error + m.mtu, err = getMTU(ctx, m.vppConn, m.tunnelIP) + if err == nil { + atomic.StoreUint32(&m.inited, 1) + } + return err } diff --git a/pkg/networkservice/mechanisms/wireguard/mtu/client.go b/pkg/networkservice/mechanisms/wireguard/mtu/client.go index cc837c43..3d3a8d6d 100644 --- a/pkg/networkservice/mechanisms/wireguard/mtu/client.go +++ b/pkg/networkservice/mechanisms/wireguard/mtu/client.go @@ -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 // @@ -20,6 +20,7 @@ import ( "context" "net" "sync" + "sync/atomic" "git.fd.io/govpp.git/api" "google.golang.org/grpc" @@ -35,8 +36,9 @@ type mtuClient struct { vppConn api.Connection tunnelIP net.IP mtu uint32 - initOnce sync.Once - err error + + inited uint32 + initMutex sync.Mutex } // NewClient - returns client chain element to manage wireguard MTU @@ -71,8 +73,19 @@ func (m *mtuClient) Close(ctx context.Context, conn *networkservice.Connection, } func (m *mtuClient) init(ctx context.Context) error { - m.initOnce.Do(func() { - m.mtu, m.err = setMTU(ctx, m.vppConn, m.tunnelIP) - }) - return m.err + if atomic.LoadUint32(&m.inited) > 0 { + return nil + } + m.initMutex.Lock() + defer m.initMutex.Unlock() + if atomic.LoadUint32(&m.inited) > 0 { + return nil + } + + var err error + m.mtu, err = getMTU(ctx, m.vppConn, m.tunnelIP) + if err == nil { + atomic.StoreUint32(&m.inited, 1) + } + return err } diff --git a/pkg/networkservice/mechanisms/wireguard/mtu/common.go b/pkg/networkservice/mechanisms/wireguard/mtu/common.go index 68b1afff..f8e498cf 100644 --- a/pkg/networkservice/mechanisms/wireguard/mtu/common.go +++ b/pkg/networkservice/mechanisms/wireguard/mtu/common.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2021 Cisco and/or its affiliates. +// Copyright (c) 2020-2022 Cisco and/or its affiliates. // // SPDX-License-Identifier: Apache-2.0 // @@ -34,7 +34,7 @@ const ( overhead = 80 ) -func setMTU(ctx context.Context, vppConn api.Connection, tunnelIP net.IP) (uint32, error) { +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 { return 0, errors.Wrapf(err, "error attempting to get interface dump client to determine MTU for tunnelIP %q", tunnelIP) diff --git a/pkg/networkservice/mechanisms/wireguard/mtu/server.go b/pkg/networkservice/mechanisms/wireguard/mtu/server.go index edd46879..0bd7c46c 100644 --- a/pkg/networkservice/mechanisms/wireguard/mtu/server.go +++ b/pkg/networkservice/mechanisms/wireguard/mtu/server.go @@ -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 // @@ -20,6 +20,7 @@ import ( "context" "net" "sync" + "sync/atomic" "git.fd.io/govpp.git/api" "google.golang.org/protobuf/types/known/emptypb" @@ -34,8 +35,9 @@ type mtuServer struct { vppConn api.Connection tunnelIP net.IP mtu uint32 - initOnce sync.Once - err error + + inited uint32 + initMutex sync.Mutex } // NewServer - server chain element to manage wireguard MTU @@ -77,8 +79,19 @@ func (m *mtuServer) Close(ctx context.Context, conn *networkservice.Connection) } func (m *mtuServer) init(ctx context.Context) error { - m.initOnce.Do(func() { - m.mtu, m.err = setMTU(ctx, m.vppConn, m.tunnelIP) - }) - return m.err + if atomic.LoadUint32(&m.inited) > 0 { + return nil + } + m.initMutex.Lock() + defer m.initMutex.Unlock() + if atomic.LoadUint32(&m.inited) > 0 { + return nil + } + + var err error + m.mtu, err = getMTU(ctx, m.vppConn, m.tunnelIP) + if err == nil { + atomic.StoreUint32(&m.inited, 1) + } + return err } diff --git a/pkg/networkservice/up/client.go b/pkg/networkservice/up/client.go index d3e629fc..6c0b5f92 100644 --- a/pkg/networkservice/up/client.go +++ b/pkg/networkservice/up/client.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2021 Cisco and/or its affiliates. +// Copyright (c) 2020-2022 Cisco and/or its affiliates. // // SPDX-License-Identifier: Apache-2.0 // @@ -20,6 +20,7 @@ package up import ( "context" "sync" + "sync/atomic" "github.com/golang/protobuf/ptypes/empty" "github.com/pkg/errors" @@ -36,12 +37,12 @@ import ( ) type upClient struct { - ctx context.Context - vppConn Connection - sync.Once - initErr error - + ctx context.Context + vppConn Connection loadIfIndex ifIndexFunc + + inited uint32 + initMutex sync.Mutex } // NewClient provides a NetworkServiceClient chain elements that 'up's the swIfIndex @@ -94,8 +95,18 @@ func (u *upClient) Close(ctx context.Context, conn *networkservice.Connection, o } func (u *upClient) init(ctx context.Context) error { - u.Do(func() { - u.initErr = initFunc(ctx, u.vppConn) - }) - return u.initErr + if atomic.LoadUint32(&u.inited) > 0 { + return nil + } + u.initMutex.Lock() + defer u.initMutex.Unlock() + if atomic.LoadUint32(&u.inited) > 0 { + return nil + } + + err := initFunc(ctx, u.vppConn) + if err == nil { + atomic.StoreUint32(&u.inited, 1) + } + return err } diff --git a/pkg/networkservice/up/peerup/client.go b/pkg/networkservice/up/peerup/client.go index 3d8e84e0..51d2f82d 100644 --- a/pkg/networkservice/up/peerup/client.go +++ b/pkg/networkservice/up/peerup/client.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Doc.ai and/or its affiliates. +// Copyright (c) 2021-2022 Doc.ai and/or its affiliates. // // SPDX-License-Identifier: Apache-2.0 // @@ -19,7 +19,6 @@ package peerup import ( "context" - "sync" "github.com/golang/protobuf/ptypes/empty" "github.com/pkg/errors" @@ -35,7 +34,6 @@ import ( type peerupClient struct { ctx context.Context vppConn Connection - sync.Once } // NewClient provides a NetworkServiceClient chain elements that 'up's the peer diff --git a/pkg/networkservice/up/server.go b/pkg/networkservice/up/server.go index a9bde838..addaf32d 100644 --- a/pkg/networkservice/up/server.go +++ b/pkg/networkservice/up/server.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2021 Cisco and/or its affiliates. +// Copyright (c) 2020-2022 Cisco and/or its affiliates. // // SPDX-License-Identifier: Apache-2.0 // @@ -19,6 +19,7 @@ package up import ( "context" "sync" + "sync/atomic" "github.com/golang/protobuf/ptypes/empty" "github.com/pkg/errors" @@ -32,12 +33,12 @@ import ( ) type upServer struct { - ctx context.Context - vppConn Connection - sync.Once - initErr error - + ctx context.Context + vppConn Connection loadIfIndex ifIndexFunc + + inited uint32 + initMutex sync.Mutex } // NewServer provides a NetworkServiceServer chain elements that 'up's the swIfIndex @@ -99,8 +100,18 @@ func (u *upServer) Close(ctx context.Context, conn *networkservice.Connection) ( } func (u *upServer) init(ctx context.Context) error { - u.Do(func() { - u.initErr = initFunc(ctx, u.vppConn) - }) - return u.initErr + if atomic.LoadUint32(&u.inited) > 0 { + return nil + } + u.initMutex.Lock() + defer u.initMutex.Unlock() + if atomic.LoadUint32(&u.inited) > 0 { + return nil + } + + err := initFunc(ctx, u.vppConn) + if err == nil { + atomic.StoreUint32(&u.inited, 1) + } + return err }