Skip to content

Commit fa36390

Browse files
committed
Added support for debug counters LPM4_MISS and LPM6_MISS in Lucius
1 parent 4aefff8 commit fa36390

6 files changed

Lines changed: 347 additions & 10 deletions

File tree

dataplane/saiserver/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ go_library(
44
name = "saiserver",
55
srcs = [
66
"acl.go",
7+
"debug_counter.go",
78
"fdb.go",
89
"hostif.go",
910
"isolation_group.go",
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package saiserver
16+
17+
import (
18+
"context"
19+
20+
saipb "github.com/openconfig/lemming/dataplane/proto/sai"
21+
"github.com/openconfig/lemming/dataplane/saiserver/attrmgr"
22+
"google.golang.org/grpc"
23+
"google.golang.org/protobuf/proto"
24+
)
25+
26+
type debugCounter struct {
27+
saipb.UnimplementedDebugCounterServer
28+
mgr *attrmgr.AttrMgr
29+
dataplane switchDataplaneAPI
30+
}
31+
32+
func newDebugCounter(mgr *attrmgr.AttrMgr, engine switchDataplaneAPI, s *grpc.Server) *debugCounter {
33+
d := &debugCounter{
34+
mgr: mgr,
35+
dataplane: engine,
36+
}
37+
saipb.RegisterDebugCounterServer(s, d)
38+
return d
39+
}
40+
41+
func (d *debugCounter) CreateDebugCounter(ctx context.Context, req *saipb.CreateDebugCounterRequest) (*saipb.CreateDebugCounterResponse, error) {
42+
oid := d.mgr.NextID()
43+
index := uint32(0)
44+
for _, reason := range req.InDropReasonList {
45+
if reason == saipb.InDropReason_IN_DROP_REASON_LPM4_MISS {
46+
index = 0
47+
break
48+
}
49+
if reason == saipb.InDropReason_IN_DROP_REASON_LPM6_MISS {
50+
index = 1
51+
break
52+
}
53+
}
54+
55+
d.mgr.StoreAttributes(oid, &saipb.DebugCounterAttribute{
56+
Index: proto.Uint32(index),
57+
})
58+
return &saipb.CreateDebugCounterResponse{Oid: oid}, nil
59+
}
60+
61+
func (d *debugCounter) RemoveDebugCounter(ctx context.Context, req *saipb.RemoveDebugCounterRequest) (*saipb.RemoveDebugCounterResponse, error) {
62+
return &saipb.RemoveDebugCounterResponse{}, nil
63+
}
64+
65+
func (d *debugCounter) SetDebugCounterAttribute(ctx context.Context, req *saipb.SetDebugCounterAttributeRequest) (*saipb.SetDebugCounterAttributeResponse, error) {
66+
return &saipb.SetDebugCounterAttributeResponse{}, nil
67+
}
68+

dataplane/saiserver/routing.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,21 @@ func (r *route) CreateRouteEntry(ctx context.Context, req *saipb.CreateRouteEntr
704704
}
705705
} else {
706706
actions = append(actions, fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_BIT_WRITE, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_ACTION).WithBitOp(1, 0).WithValue([]byte{0}))
707+
708+
isZeroMask := true
709+
for _, b := range req.GetEntry().GetDestination().GetMask() {
710+
if b != 0 {
711+
isZeroMask = false
712+
break
713+
}
714+
}
715+
if isZeroMask {
716+
counterID := "LPM6_MISS_COUNTER"
717+
if fib == FIBV4Table {
718+
counterID = "LPM4_MISS_COUNTER"
719+
}
720+
actions = append(actions, fwdconfig.FlowCounterAction(counterID))
721+
}
707722
}
708723
if req.MetaData != nil {
709724
actions = append(actions, fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_SET, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_ATTRIBUTE_32).
@@ -829,6 +844,21 @@ func (r *route) SetRouteEntryAttribute(ctx context.Context, req *saipb.SetRouteE
829844
}
830845
} else {
831846
actions = append(actions, fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_BIT_WRITE, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_ACTION).WithBitOp(1, 0).WithValue([]byte{0}))
847+
848+
isZeroMask := true
849+
for _, b := range req.GetEntry().GetDestination().GetMask() {
850+
if b != 0 {
851+
isZeroMask = false
852+
break
853+
}
854+
}
855+
if isZeroMask {
856+
counterID := "LPM6_MISS_COUNTER"
857+
if fib == FIBV4Table {
858+
counterID = "LPM4_MISS_COUNTER"
859+
}
860+
actions = append(actions, fwdconfig.FlowCounterAction(counterID))
861+
}
832862
}
833863
if metaData != nil {
834864
actions = append(actions, fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_SET, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_ATTRIBUTE_32).

dataplane/saiserver/saiserver.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@ type counter struct {
3939
saipb.UnimplementedCounterServer
4040
}
4141

42-
type debugCounter struct {
43-
saipb.UnimplementedDebugCounterServer
44-
}
4542

4643
type dtel struct {
4744
saipb.UnimplementedDtelServer
@@ -209,7 +206,7 @@ func New(ctx context.Context, mgr *attrmgr.AttrMgr, s *grpc.Server, opts *dplane
209206
forwardingContext: fwdCtx,
210207
bfd: &bfd{},
211208
counter: &counter{},
212-
debugCounter: &debugCounter{},
209+
debugCounter: newDebugCounter(mgr, fwdCtx, s),
213210
dtel: &dtel{},
214211
fdb: fdb,
215212
ipmcGroup: &ipmcGroup{},
@@ -232,7 +229,6 @@ func New(ctx context.Context, mgr *attrmgr.AttrMgr, s *grpc.Server, opts *dplane
232229
saipb.RegisterEntrypointServer(s, srv)
233230
saipb.RegisterBfdServer(s, srv.bfd)
234231
saipb.RegisterCounterServer(s, srv.counter)
235-
saipb.RegisterDebugCounterServer(s, srv.debugCounter)
236232
saipb.RegisterDtelServer(s, srv.dtel)
237233
saipb.RegisterIpmcGroupServer(s, srv.ipmcGroup)
238234
saipb.RegisterIpmcServer(s, srv.ipmc)

dataplane/saiserver/switch.go

Lines changed: 114 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,33 @@ func (sw *saiSwitch) CreateSwitch(ctx context.Context, _ *saipb.CreateSwitchRequ
268268
swID := sw.mgr.NextID()
269269
slog.InfoContext(ctx, "Creating new switch id", "id", swID)
270270

271+
// Create LPM miss flow counters if they don't exist.
272+
qResp, err := sw.dataplane.FlowCounterQuery(ctx, &fwdpb.FlowCounterQueryRequest{
273+
ContextId: &fwdpb.ContextId{Id: sw.dataplane.ID()},
274+
Ids: []*fwdpb.FlowCounterId{{ObjectId: &fwdpb.ObjectId{Id: "LPM4_MISS_COUNTER"}}},
275+
})
276+
if err != nil || len(qResp.GetCounters()) == 0 {
277+
if _, err := sw.dataplane.FlowCounterCreate(ctx, &fwdpb.FlowCounterCreateRequest{
278+
ContextId: &fwdpb.ContextId{Id: sw.dataplane.ID()},
279+
Id: &fwdpb.FlowCounterId{ObjectId: &fwdpb.ObjectId{Id: "LPM4_MISS_COUNTER"}},
280+
}); err != nil {
281+
return nil, err
282+
}
283+
}
284+
285+
qResp6, err := sw.dataplane.FlowCounterQuery(ctx, &fwdpb.FlowCounterQueryRequest{
286+
ContextId: &fwdpb.ContextId{Id: sw.dataplane.ID()},
287+
Ids: []*fwdpb.FlowCounterId{{ObjectId: &fwdpb.ObjectId{Id: "LPM6_MISS_COUNTER"}}},
288+
})
289+
if err != nil || len(qResp6.GetCounters()) == 0 {
290+
if _, err := sw.dataplane.FlowCounterCreate(ctx, &fwdpb.FlowCounterCreateRequest{
291+
ContextId: &fwdpb.ContextId{Id: sw.dataplane.ID()},
292+
Id: &fwdpb.FlowCounterId{ObjectId: &fwdpb.ObjectId{Id: "LPM6_MISS_COUNTER"}},
293+
}); err != nil {
294+
return nil, err
295+
}
296+
}
297+
271298
// Setup forwarding tables.
272299
ingressVRF := &fwdpb.TableCreateRequest{
273300
ContextId: &fwdpb.ContextId{Id: sw.dataplane.ID()},
@@ -295,7 +322,17 @@ func (sw *saiSwitch) CreateSwitch(ctx context.Context, _ *saipb.CreateSwitchRequ
295322
Desc: &fwdpb.TableDesc{
296323
TableType: fwdpb.TableType_TABLE_TYPE_PREFIX,
297324
TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: FIBV4Table}},
298-
Actions: []*fwdpb.ActionDesc{fwdconfig.Action(fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_BIT_WRITE, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_ACTION).WithBitOp(1, 0).WithValue([]byte{0})).Build()},
325+
Actions: []*fwdpb.ActionDesc{
326+
fwdconfig.Action(fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_BIT_WRITE, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_ACTION).WithBitOp(1, 0).WithValue([]byte{0})).Build(),
327+
{
328+
ActionType: fwdpb.ActionType_ACTION_TYPE_FLOW_COUNTER,
329+
Action: &fwdpb.ActionDesc_Flow{
330+
Flow: &fwdpb.FlowCounterActionDesc{
331+
CounterId: &fwdpb.FlowCounterId{ObjectId: &fwdpb.ObjectId{Id: "LPM4_MISS_COUNTER"}},
332+
},
333+
},
334+
},
335+
},
299336
Table: &fwdpb.TableDesc_Prefix{
300337
Prefix: &fwdpb.PrefixTableDesc{
301338
FieldIds: []*fwdpb.PacketFieldId{{
@@ -319,7 +356,17 @@ func (sw *saiSwitch) CreateSwitch(ctx context.Context, _ *saipb.CreateSwitchRequ
319356
Desc: &fwdpb.TableDesc{
320357
TableType: fwdpb.TableType_TABLE_TYPE_PREFIX,
321358
TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: FIBV6Table}},
322-
Actions: []*fwdpb.ActionDesc{fwdconfig.Action(fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_BIT_WRITE, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_ACTION).WithBitOp(1, 0).WithValue([]byte{0})).Build()},
359+
Actions: []*fwdpb.ActionDesc{
360+
fwdconfig.Action(fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_BIT_WRITE, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_ACTION).WithBitOp(1, 0).WithValue([]byte{0})).Build(),
361+
{
362+
ActionType: fwdpb.ActionType_ACTION_TYPE_FLOW_COUNTER,
363+
Action: &fwdpb.ActionDesc_Flow{
364+
Flow: &fwdpb.FlowCounterActionDesc{
365+
CounterId: &fwdpb.FlowCounterId{ObjectId: &fwdpb.ObjectId{Id: "LPM6_MISS_COUNTER"}},
366+
},
367+
},
368+
},
369+
},
323370
Table: &fwdpb.TableDesc_Prefix{
324371
Prefix: &fwdpb.PrefixTableDesc{
325372
FieldIds: []*fwdpb.PacketFieldId{{
@@ -515,7 +562,7 @@ func (sw *saiSwitch) CreateSwitch(ctx context.Context, _ *saipb.CreateSwitchRequ
515562
if _, err := sw.dataplane.TableCreate(ctx, nexthopAction); err != nil {
516563
return nil, err
517564
}
518-
_, err := sw.dataplane.TableCreate(ctx, &fwdpb.TableCreateRequest{
565+
_, err = sw.dataplane.TableCreate(ctx, &fwdpb.TableCreateRequest{
519566
ContextId: &fwdpb.ContextId{Id: sw.dataplane.ID()},
520567
Desc: &fwdpb.TableDesc{
521568
TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: portToHostifTable}},
@@ -875,6 +922,26 @@ func (sw *saiSwitch) CreateSwitch(ctx context.Context, _ *saipb.CreateSwitchRequ
875922
SwitchShellEnable: proto.Bool(false),
876923
SwitchProfileId: proto.Uint32(0),
877924
NatZoneCounterObjectId: proto.Uint64(0),
925+
SupportedObjectTypeList: []saipb.ObjectType{
926+
saipb.ObjectType_OBJECT_TYPE_PORT,
927+
saipb.ObjectType_OBJECT_TYPE_VLAN,
928+
saipb.ObjectType_OBJECT_TYPE_VIRTUAL_ROUTER,
929+
saipb.ObjectType_OBJECT_TYPE_NEXT_HOP,
930+
saipb.ObjectType_OBJECT_TYPE_NEXT_HOP_GROUP,
931+
saipb.ObjectType_OBJECT_TYPE_ROUTE_ENTRY,
932+
saipb.ObjectType_OBJECT_TYPE_FDB_ENTRY,
933+
saipb.ObjectType_OBJECT_TYPE_ACL_TABLE,
934+
saipb.ObjectType_OBJECT_TYPE_ACL_ENTRY,
935+
saipb.ObjectType_OBJECT_TYPE_DEBUG_COUNTER,
936+
},
937+
SupportedDebugCounterTypeList: []saipb.DebugCounterType{
938+
saipb.DebugCounterType_DEBUG_COUNTER_TYPE_SWITCH_IN_DROP_REASONS,
939+
},
940+
SupportedIngressDropReasonList: []saipb.InDropReason{
941+
saipb.InDropReason_IN_DROP_REASON_LPM4_MISS,
942+
saipb.InDropReason_IN_DROP_REASON_LPM6_MISS,
943+
},
944+
AvailableSwitchIngressDropCounters: proto.Uint32(2),
878945
}
879946
sw.mgr.StoreAttributes(swID, attrs)
880947
return &saipb.CreateSwitchResponse{
@@ -1136,6 +1203,50 @@ func (sw *saiSwitch) Reset() {
11361203
sw.hostif.Reset()
11371204
}
11381205

1206+
// GetSwitchStats returns the statistics for the switch.
1207+
func (sw *saiSwitch) GetSwitchStats(ctx context.Context, req *saipb.GetSwitchStatsRequest) (*saipb.GetSwitchStatsResponse, error) {
1208+
slog.ErrorContext(ctx, "GetSwitchStats called", "req", req)
1209+
resp := &saipb.GetSwitchStatsResponse{}
1210+
for _, id := range req.GetCounterIds() {
1211+
var val uint64
1212+
switch id {
1213+
case saipb.SwitchStat_SWITCH_STAT_IN_CONFIGURED_DROP_REASONS_0_DROPPED_PKTS:
1214+
count, err := sw.dataplane.FlowCounterQuery(ctx, &fwdpb.FlowCounterQueryRequest{
1215+
ContextId: &fwdpb.ContextId{Id: sw.dataplane.ID()},
1216+
Ids: []*fwdpb.FlowCounterId{{ObjectId: &fwdpb.ObjectId{Id: "LPM4_MISS_COUNTER"}}},
1217+
})
1218+
if err != nil {
1219+
return nil, err
1220+
}
1221+
if len(count.GetCounters()) > 0 {
1222+
val = count.GetCounters()[0].GetPackets()
1223+
slog.ErrorContext(ctx, "GetSwitchStats: LPM4_MISS_COUNTER", "packets", val)
1224+
} else {
1225+
slog.InfoContext(ctx, "GetSwitchStats: LPM4_MISS_COUNTER not found in response")
1226+
}
1227+
case saipb.SwitchStat_SWITCH_STAT_IN_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS:
1228+
count, err := sw.dataplane.FlowCounterQuery(ctx, &fwdpb.FlowCounterQueryRequest{
1229+
ContextId: &fwdpb.ContextId{Id: sw.dataplane.ID()},
1230+
Ids: []*fwdpb.FlowCounterId{{ObjectId: &fwdpb.ObjectId{Id: "LPM6_MISS_COUNTER"}}},
1231+
})
1232+
if err != nil {
1233+
return nil, err
1234+
}
1235+
if len(count.GetCounters()) > 0 {
1236+
val = count.GetCounters()[0].GetPackets()
1237+
slog.ErrorContext(ctx, "GetSwitchStats: LPM6_MISS_COUNTER", "packets", val)
1238+
} else {
1239+
slog.InfoContext(ctx, "GetSwitchStats: LPM6_MISS_COUNTER not found in response")
1240+
}
1241+
default:
1242+
val = 0
1243+
}
1244+
resp.Values = append(resp.Values, val)
1245+
}
1246+
1247+
return resp, nil
1248+
}
1249+
11391250
// createFIBSelector creates a table that controls which forwarding table is used.
11401251
func (sw *saiSwitch) createFIBSelector(ctx context.Context) error {
11411252
fieldID := &fwdpb.PacketFieldId{

0 commit comments

Comments
 (0)