Skip to content

Commit 3c706ae

Browse files
committed
Add af_packet
Signed-off-by: Artem Glazychev <[email protected]>
1 parent f0d1aec commit 3c706ae

File tree

13 files changed

+273
-47
lines changed

13 files changed

+273
-47
lines changed

pkg/networkservice/mechanisms/kernel/client.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,10 @@
1919
package kernel
2020

2121
import (
22-
"os"
23-
2422
"git.fd.io/govpp.git/api"
2523
"github.com/networkservicemesh/api/pkg/api/networkservice"
2624

2725
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/kernel/kernelvethpair"
28-
29-
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/kernel/kerneltap"
3026
)
3127

3228
// NewClient - returns a new Client chain element implementing the kernel mechanism with vpp
@@ -36,8 +32,8 @@ func NewClient(vppConn api.Connection, opts ...Option) networkservice.NetworkSer
3632
opt(o)
3733
}
3834

39-
if _, err := os.Stat(vnetFilename); err == nil {
40-
return kerneltap.NewClient(vppConn, kerneltap.WithDump(o.dumpOpt))
41-
}
35+
//if _, err := os.Stat(vnetFilename); err == nil {
36+
// return kerneltap.NewClient(vppConn, kerneltap.WithDump(o.dumpOpt))
37+
//}
4238
return kernelvethpair.NewClient(vppConn)
4339
}

pkg/networkservice/mechanisms/kernel/kernelvethpair/afpacket/client.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ package afpacket
2020

2121
import (
2222
"context"
23+
"github.com/networkservicemesh/sdk-vpp/pkg/tools/dumptool"
24+
"github.com/networkservicemesh/sdk/pkg/tools/log"
2325

2426
"git.fd.io/govpp.git/api"
2527
"github.com/golang/protobuf/ptypes/empty"
@@ -34,12 +36,30 @@ import (
3436

3537
type afPacketClient struct {
3638
vppConn api.Connection
39+
dumpMap *dumptool.Map
3740
}
3841

3942
// NewClient - return a new Server chain element implementing the kernel mechanism with vpp using afpacket
40-
func NewClient(vppConn api.Connection) networkservice.NetworkServiceClient {
43+
func NewClient(vppConn api.Connection, opts ...Option) networkservice.NetworkServiceClient {
44+
o := &options{}
45+
for _, opt := range opts {
46+
opt(o)
47+
}
48+
49+
ctx := context.Background()
50+
dumpMap := dumptool.NewMap(ctx, 0)
51+
if o.dumpOpt != nil {
52+
var err error
53+
dumpMap, err = dump(ctx, vppConn, o.dumpOpt.PodName, o.dumpOpt.Timeout, true)
54+
if err != nil {
55+
log.FromContext(ctx).Errorf("failed to Dump: %v", err)
56+
/* TODO: set empty dumpMap here? */
57+
}
58+
}
59+
4160
return &afPacketClient{
4261
vppConn: vppConn,
62+
dumpMap: dumpMap,
4363
}
4464
}
4565

@@ -51,7 +71,7 @@ func (a *afPacketClient) Request(ctx context.Context, request *networkservice.Ne
5171
return nil, err
5272
}
5373

54-
if err := create(ctx, conn, a.vppConn, metadata.IsClient(a)); err != nil {
74+
if err := create(ctx, conn, a.vppConn, a.dumpMap, metadata.IsClient(a)); err != nil {
5575
closeCtx, cancelClose := postponeCtxFunc()
5676
defer cancelClose()
5777

@@ -66,6 +86,6 @@ func (a *afPacketClient) Request(ctx context.Context, request *networkservice.Ne
6686
}
6787

6888
func (a *afPacketClient) Close(ctx context.Context, conn *networkservice.Connection, opts ...grpc.CallOption) (*empty.Empty, error) {
69-
_ = del(ctx, conn, a.vppConn, metadata.IsClient(a))
89+
_ = del(ctx, conn, a.vppConn, a.dumpMap, metadata.IsClient(a))
7090
return next.Client(ctx).Close(ctx, conn, opts...)
7191
}

pkg/networkservice/mechanisms/kernel/kernelvethpair/afpacket/common.go

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ package afpacket
2020

2121
import (
2222
"context"
23+
"github.com/networkservicemesh/sdk-vpp/pkg/tools/dumptool"
24+
"github.com/vishvananda/netlink"
25+
"io"
2326
"time"
2427

2528
"git.fd.io/govpp.git/api"
@@ -38,8 +41,12 @@ import (
3841
"github.com/networkservicemesh/sdk-vpp/pkg/tools/types"
3942
)
4043

41-
func create(ctx context.Context, conn *networkservice.Connection, vppConn api.Connection, isClient bool) error {
44+
func create(ctx context.Context, conn *networkservice.Connection, vppConn api.Connection, dumpMap *dumptool.Map, isClient bool) error {
4245
if mechanism := kernel.ToMechanism(conn.GetMechanism()); mechanism != nil {
46+
if val, loaded := dumpMap.LoadAndDelete(conn.GetId()); loaded {
47+
ifindex.Store(ctx, isClient, val.(interface_types.InterfaceIndex))
48+
}
49+
4350
if _, ok := ifindex.Load(ctx, isClient); ok {
4451
return nil
4552
}
@@ -78,8 +85,12 @@ func create(ctx context.Context, conn *networkservice.Connection, vppConn api.Co
7885
return nil
7986
}
8087

81-
func del(ctx context.Context, conn *networkservice.Connection, vppConn api.Connection, isClient bool) error {
88+
func del(ctx context.Context, conn *networkservice.Connection, vppConn api.Connection, dumpMap *dumptool.Map, isClient bool) error {
8289
if mechanism := kernel.ToMechanism(conn.GetMechanism()); mechanism != nil {
90+
if val, loaded := dumpMap.LoadAndDelete(conn.GetId()); loaded {
91+
ifindex.Store(ctx, isClient, val.(interface_types.InterfaceIndex))
92+
}
93+
8394
swIfIndex, ok := ifindex.LoadAndDelete(ctx, isClient)
8495
if !ok {
8596
return nil
@@ -103,3 +114,41 @@ func del(ctx context.Context, conn *networkservice.Connection, vppConn api.Conne
103114
}
104115
return nil
105116
}
117+
118+
func dump(ctx context.Context, vppConn api.Connection, podName string, timeout time.Duration, isClient bool) (*dumptool.Map, error) {
119+
return dumptool.DumpInterfaces(ctx, vppConn, podName, timeout, isClient,
120+
/* Function on dump */
121+
func(details *interfaces.SwInterfaceDetails) (interface{}, error) {
122+
if details.InterfaceDevType == dumptool.DevTypeAfPacket {
123+
return details.SwIfIndex, nil
124+
}
125+
return nil, errors.New("Doesn't match the af_packet interface")
126+
},
127+
/* Function on delete */
128+
func(val interface{}) error {
129+
swIfIndex := val.(interface_types.InterfaceIndex)
130+
afClient, err := af_packet.NewServiceClient(vppConn).AfPacketDump(ctx, &af_packet.AfPacketDump{})
131+
if err != nil {
132+
return err
133+
}
134+
defer func() { _ = afClient.Close() }()
135+
136+
for {
137+
afDetails, err := afClient.Recv()
138+
if err == io.EOF {
139+
break
140+
}
141+
if afDetails == nil || afDetails.SwIfIndex != swIfIndex {
142+
continue
143+
}
144+
145+
if _, err := af_packet.NewServiceClient(vppConn).AfPacketDelete(ctx, &af_packet.AfPacketDelete{
146+
HostIfName: afDetails.HostIfName,
147+
}); err != nil {
148+
return err
149+
}
150+
return nil
151+
}
152+
return netlink.LinkDel(val.(netlink.Link))
153+
})
154+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) 2022 Cisco and/or its affiliates.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at:
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
// +build linux
18+
19+
package afpacket
20+
21+
import "github.com/networkservicemesh/sdk-vpp/pkg/tools/dumptool"
22+
23+
type options struct {
24+
dumpOpt *dumptool.DumpOption
25+
}
26+
27+
// Option is an option pattern for kernel
28+
type Option func(o *options)
29+
30+
// WithDump - sets dump parameters
31+
func WithDump(dump *dumptool.DumpOption) Option {
32+
return func(o *options) {
33+
o.dumpOpt = dump
34+
}
35+
}

pkg/networkservice/mechanisms/kernel/kernelvethpair/afpacket/server.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ package afpacket
2020

2121
import (
2222
"context"
23+
"github.com/networkservicemesh/sdk-vpp/pkg/tools/dumptool"
24+
"github.com/networkservicemesh/sdk/pkg/tools/log"
2325

2426
"git.fd.io/govpp.git/api"
2527
"github.com/golang/protobuf/ptypes/empty"
@@ -33,12 +35,30 @@ import (
3335

3436
type afPacketServer struct {
3537
vppConn api.Connection
38+
dumpMap *dumptool.Map
3639
}
3740

3841
// NewServer - return a new Server chain element implementing the kernel mechanism with vpp using afpacket
39-
func NewServer(vppConn api.Connection) networkservice.NetworkServiceServer {
42+
func NewServer(vppConn api.Connection, opts ...Option) networkservice.NetworkServiceServer {
43+
o := &options{}
44+
for _, opt := range opts {
45+
opt(o)
46+
}
47+
48+
ctx := context.Background()
49+
dumpMap := dumptool.NewMap(ctx, 0)
50+
if o.dumpOpt != nil {
51+
var err error
52+
dumpMap, err = dump(ctx, vppConn, o.dumpOpt.PodName, o.dumpOpt.Timeout, true)
53+
if err != nil {
54+
log.FromContext(ctx).Errorf("failed to Dump: %v", err)
55+
/* TODO: set empty dumpMap here? */
56+
}
57+
}
58+
4059
return &afPacketServer{
4160
vppConn: vppConn,
61+
dumpMap: dumpMap,
4262
}
4363
}
4464

@@ -50,7 +70,7 @@ func (a *afPacketServer) Request(ctx context.Context, request *networkservice.Ne
5070
return nil, err
5171
}
5272

53-
if err := create(ctx, conn, a.vppConn, metadata.IsClient(a)); err != nil {
73+
if err := create(ctx, conn, a.vppConn, a.dumpMap, metadata.IsClient(a)); err != nil {
5474
closeCtx, cancelClose := postponeCtxFunc()
5575
defer cancelClose()
5676

@@ -65,6 +85,6 @@ func (a *afPacketServer) Request(ctx context.Context, request *networkservice.Ne
6585
}
6686

6787
func (a *afPacketServer) Close(ctx context.Context, conn *networkservice.Connection) (*empty.Empty, error) {
68-
_ = del(ctx, conn, a.vppConn, false)
88+
_ = del(ctx, conn, a.vppConn, a.dumpMap,false)
6989
return next.Server(ctx).Close(ctx, conn)
7090
}

pkg/networkservice/mechanisms/kernel/kernelvethpair/client.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package kernelvethpair
2020

2121
import (
2222
"context"
23+
"github.com/networkservicemesh/sdk-vpp/pkg/tools/dumptool"
2324

2425
"git.fd.io/govpp.git/api"
2526
"github.com/golang/protobuf/ptypes/empty"
@@ -39,15 +40,34 @@ import (
3940
"github.com/networkservicemesh/sdk-vpp/pkg/networkservice/mechanisms/kernel/kernelvethpair/ipneighbor"
4041
)
4142

42-
type kernelVethPairClient struct{}
43+
type kernelVethPairClient struct{
44+
podName string
45+
dumpMap *dumptool.Map
46+
}
4347

4448
// NewClient - return a new Client chain element implementing the kernel mechanism with vpp using a veth pair
45-
func NewClient(vppConn api.Connection) networkservice.NetworkServiceClient {
49+
func NewClient(vppConn api.Connection, opts ...Option) networkservice.NetworkServiceClient {
50+
o := &options{}
51+
for _, opt := range opts {
52+
opt(o)
53+
}
54+
55+
ctx := context.Background()
56+
podName := "forwarder"
57+
dumpMap := dumptool.NewMap(ctx, 0)
58+
if o.dumpOpt != nil {
59+
podName = o.dumpOpt.PodName
60+
dumpMap, _ = dump(ctx, o.dumpOpt.PodName, o.dumpOpt.Timeout, true)
61+
}
62+
4663
return chain.NewNetworkServiceClient(
4764
ipneighbor.NewClient(vppConn),
4865
afpacket.NewClient(vppConn),
4966
mtu.NewClient(),
50-
&kernelVethPairClient{},
67+
&kernelVethPairClient{
68+
podName: podName,
69+
dumpMap: dumpMap,
70+
},
5171
)
5272
}
5373

@@ -66,7 +86,7 @@ func (k *kernelVethPairClient) Request(ctx context.Context, request *networkserv
6686
return nil, err
6787
}
6888

69-
if err := create(ctx, conn, metadata.IsClient(k)); err != nil {
89+
if err := create(ctx, conn, k.podName, k.dumpMap, metadata.IsClient(k)); err != nil {
7090
closeCtx, cancelClose := postponeCtxFunc()
7191
defer cancelClose()
7292

0 commit comments

Comments
 (0)