-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Set memif_rx_mode on a separate chain element (#670)
Signed-off-by: Artem Glazychev <artem.glazychev@xored.com> Signed-off-by: Artem Glazychev <artem.glazychev@xored.com>
- Loading branch information
1 parent
28ae94b
commit 4bc0261
Showing
10 changed files
with
349 additions
and
20 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
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
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
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
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,88 @@ | ||
// Copyright (c) 2022 Cisco and/or its affiliates. | ||
// | ||
// 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 | ||
|
||
package memifrxmode | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/pkg/errors" | ||
"google.golang.org/grpc" | ||
|
||
"github.com/golang/protobuf/ptypes/empty" | ||
|
||
"github.com/networkservicemesh/api/pkg/api/networkservice" | ||
|
||
memifMech "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/memif" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/core/next" | ||
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata" | ||
"github.com/networkservicemesh/sdk/pkg/tools/postpone" | ||
|
||
"github.com/networkservicemesh/sdk-vpp/pkg/tools/ifindex" | ||
) | ||
|
||
type memifrxmodeClient struct { | ||
chainCtx context.Context | ||
vppConn Connection | ||
} | ||
|
||
// NewClient provides a NetworkServiceClient chain elements that support the memif Mechanism | ||
func NewClient(chainCtx context.Context, vppConn Connection) networkservice.NetworkServiceClient { | ||
return &memifrxmodeClient{ | ||
chainCtx: chainCtx, | ||
vppConn: vppConn, | ||
} | ||
} | ||
|
||
func (m *memifrxmodeClient) Request(ctx context.Context, request *networkservice.NetworkServiceRequest, opts ...grpc.CallOption) (*networkservice.Connection, error) { | ||
postponeCtxFunc := postpone.ContextWithValues(ctx) | ||
|
||
conn, err := next.Client(ctx).Request(ctx, request, opts...) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if mechanism := memifMech.ToMechanism(conn.GetMechanism()); mechanism == nil { | ||
return conn, err | ||
} | ||
|
||
if ok := load(ctx, metadata.IsClient(m)); !ok { | ||
swIfIndex, _ := ifindex.Load(ctx, metadata.IsClient(m)) | ||
|
||
cancelCtx, cancel := context.WithCancel(m.chainCtx) | ||
store(ctx, metadata.IsClient(m), cancel) | ||
|
||
if err := setRxMode(cancelCtx, m.vppConn, swIfIndex); 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 | ||
} | ||
} | ||
return conn, nil | ||
} | ||
|
||
func (m *memifrxmodeClient) Close(ctx context.Context, conn *networkservice.Connection, opts ...grpc.CallOption) (*empty.Empty, error) { | ||
if oldCancel, loaded := loadAndDelete(ctx, metadata.IsClient(m)); loaded { | ||
oldCancel() | ||
} | ||
return next.Client(ctx).Close(ctx, conn, opts...) | ||
} |
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,86 @@ | ||
// Copyright (c) 2022 Cisco and/or its affiliates. | ||
// | ||
// 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 | ||
|
||
package memifrxmode | ||
|
||
import ( | ||
"context" | ||
"time" | ||
|
||
"git.fd.io/govpp.git/api" | ||
|
||
interfaces "github.com/edwarnicke/govpp/binapi/interface" | ||
"github.com/edwarnicke/govpp/binapi/interface_types" | ||
|
||
"github.com/networkservicemesh/sdk/pkg/tools/log" | ||
) | ||
|
||
// Connection aggregates the api.Connection and api.ChannelProvider interfaces | ||
type Connection interface { | ||
api.Connection | ||
api.ChannelProvider | ||
} | ||
|
||
func setRxMode(ctx context.Context, vppConn Connection, swIfIndex interface_types.InterfaceIndex) error { | ||
apiChannel, err := vppConn.NewAPIChannelBuffered(256, 256) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
notifCh := make(chan api.Message, 256) | ||
subscription, err := apiChannel.SubscribeNotification(notifCh, &interfaces.SwInterfaceEvent{}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
go func() { | ||
defer apiChannel.Close() | ||
defer func() { _ = subscription.Unsubscribe() }() | ||
for { | ||
select { | ||
case <-ctx.Done(): | ||
return | ||
case rawMsg := <-notifCh: | ||
if msg, ok := rawMsg.(*interfaces.SwInterfaceEvent); ok && | ||
msg.SwIfIndex == swIfIndex && | ||
msg.Flags&interface_types.IF_STATUS_API_FLAG_LINK_UP != 0 { | ||
now := time.Now() | ||
_, err = interfaces.NewServiceClient(vppConn).SwInterfaceSetRxMode(ctx, &interfaces.SwInterfaceSetRxMode{ | ||
SwIfIndex: swIfIndex, | ||
Mode: interface_types.RX_MODE_API_ADAPTIVE, | ||
}) | ||
if err != nil { | ||
log.FromContext(ctx). | ||
WithField("swIfIndex", swIfIndex). | ||
WithField("mode", interface_types.RX_MODE_API_ADAPTIVE). | ||
WithField("duration", time.Since(now)). | ||
WithField("vppapi", "SwInterfaceSetRxMode").Debugf("error: %v", err.Error()) | ||
return | ||
} | ||
log.FromContext(ctx). | ||
WithField("swIfIndex", swIfIndex). | ||
WithField("mode", interface_types.RX_MODE_API_ADAPTIVE). | ||
WithField("duration", time.Since(now)). | ||
WithField("vppapi", "SwInterfaceSetRxMode").Debug("completed") | ||
return | ||
} | ||
} | ||
} | ||
}() | ||
return nil | ||
} |
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,18 @@ | ||
// Copyright (c) 2022 Cisco and/or its affiliates. | ||
// | ||
// 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 memifrxmode provides a NetworkService chain elements to set ADAPTIVE rx mode for memif interfaces | ||
package memifrxmode |
54 changes: 54 additions & 0 deletions
54
pkg/networkservice/mechanisms/memif/memifrxmode/metadata.go
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,54 @@ | ||
// Copyright (c) 2020-2022 Cisco and/or its affiliates. | ||
// | ||
// Copyright (c) 2021-2022 Doc.ai and/or its affiliates. | ||
// | ||
// 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 | ||
|
||
package memifrxmode | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata" | ||
) | ||
|
||
type key struct{} | ||
|
||
// store sets the context.CancelFunc stored in per Connection.Id metadata. | ||
func store(ctx context.Context, isClient bool, cancel context.CancelFunc) { | ||
metadata.Map(ctx, isClient).Store(key{}, cancel) | ||
} | ||
|
||
// loadAndDelete deletes the context.CancelFunc stored in per Connection.Id metadata. | ||
func loadAndDelete(ctx context.Context, isClient bool) (value context.CancelFunc, ok bool) { | ||
rawValue, ok := metadata.Map(ctx, isClient).LoadAndDelete(key{}) | ||
if !ok { | ||
return | ||
} | ||
value, ok = rawValue.(context.CancelFunc) | ||
return value, ok | ||
} | ||
|
||
// load returns the context.CancelFunc stored in per Connection.Id metadata. | ||
func load(ctx context.Context, isClient bool) (ok bool) { | ||
rawValue, ok := metadata.Map(ctx, isClient).Load(key{}) | ||
if !ok { | ||
return | ||
} | ||
_, ok = rawValue.(context.CancelFunc) | ||
return ok | ||
} |
Oops, something went wrong.