@@ -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.
11401251func (sw * saiSwitch ) createFIBSelector (ctx context.Context ) error {
11411252 fieldID := & fwdpb.PacketFieldId {
0 commit comments