Skip to content

Commit

Permalink
Add interface counters (#414)
Browse files Browse the repository at this point in the history
* Add interface counters

* test fix
  • Loading branch information
DanG100 authored May 2, 2024
1 parent ab375a6 commit 2a1f90e
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
28 changes: 28 additions & 0 deletions dataplane/forwarding/fwdconfig/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,31 @@ func (u *DropActionBuilder) set(*fwdpb.ActionDesc) {
func (u *DropActionBuilder) actionType() fwdpb.ActionType {
return fwdpb.ActionType_ACTION_TYPE_DROP
}

// FlowActionBuilder is a builder for a flow action.
type FlowCounterActionBuilder struct {
id string
}

// FlowAction returns a new flow action builder.
func FlowCounterAction(id string) *FlowCounterActionBuilder {
return &FlowCounterActionBuilder{
id: id,
}
}

func (u *FlowCounterActionBuilder) set(a *fwdpb.ActionDesc) {
a.Action = &fwdpb.ActionDesc_Flow{
Flow: &fwdpb.FlowCounterActionDesc{
CounterId: &fwdpb.FlowCounterId{
ObjectId: &fwdpb.ObjectId{
Id: u.id,
},
},
},
}
}

func (u *FlowCounterActionBuilder) actionType() fwdpb.ActionType {
return fwdpb.ActionType_ACTION_TYPE_FLOW_COUNTER
}
60 changes: 60 additions & 0 deletions dataplane/saiserver/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,13 @@ func newRouterInterface(mgr *attrmgr.AttrMgr, dataplane switchDataplaneAPI, s *g
return r
}

func ifaceCounterID(oid uint64, input bool) string {
if input {
return fmt.Sprintf("%d-in-counter", oid)
}
return fmt.Sprintf("%d-out-counter", oid)
}

// CreateRouterInterfaces creates a new router interface.
func (ri *routerInterface) CreateRouterInterface(ctx context.Context, req *saipb.CreateRouterInterfaceRequest) (*saipb.CreateRouterInterfaceResponse, error) {
id := ri.mgr.NextID()
Expand All @@ -594,11 +601,30 @@ func (ri *routerInterface) CreateRouterInterface(ctx context.Context, req *saipb
return nil, err
}

inCounter := ifaceCounterID(id, true)
outCounter := ifaceCounterID(id, false)

_, err = ri.dataplane.FlowCounterCreate(ctx, &fwdpb.FlowCounterCreateRequest{
ContextId: &fwdpb.ContextId{Id: ri.dataplane.ID()},
Id: &fwdpb.FlowCounterId{ObjectId: &fwdpb.ObjectId{Id: inCounter}},
})
if err != nil {
return nil, err
}
_, err = ri.dataplane.FlowCounterCreate(ctx, &fwdpb.FlowCounterCreateRequest{
ContextId: &fwdpb.ContextId{Id: ri.dataplane.ID()},
Id: &fwdpb.FlowCounterId{ObjectId: &fwdpb.ObjectId{Id: outCounter}},
})
if err != nil {
return nil, err
}

// Link the port to the interface.
_, err = ri.dataplane.TableEntryAdd(ctx, fwdconfig.TableEntryAddRequest(ri.dataplane.ID(), inputIfaceTable).
AppendEntry(
fwdconfig.EntryDesc(fwdconfig.ExactEntry(fwdconfig.PacketFieldBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_PACKET_PORT_INPUT).WithUint64(uint64(obj.NID())))),
fwdconfig.Action(fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_SET, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_INPUT_IFACE).WithUint64Value(id)),
fwdconfig.Action(fwdconfig.FlowCounterAction(inCounter)),
).Build())
if err != nil {
return nil, err
Expand All @@ -608,6 +634,7 @@ func (ri *routerInterface) CreateRouterInterface(ctx context.Context, req *saipb
AppendEntry(
fwdconfig.EntryDesc(fwdconfig.ExactEntry(fwdconfig.PacketFieldBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_OUTPUT_IFACE).WithUint64(id))),
fwdconfig.Action(fwdconfig.TransmitAction(fmt.Sprint(req.GetPortId()))),
fwdconfig.Action(fwdconfig.FlowCounterAction(outCounter)),
).Build())
if err != nil {
return nil, err
Expand Down Expand Up @@ -693,6 +720,39 @@ func (ri *routerInterface) SetRouterInterfaceAttribute(context.Context, *saipb.S
return &saipb.SetRouterInterfaceAttributeResponse{}, nil
}

func (ri *routerInterface) GetRouterInterfaceStats(ctx context.Context, req *saipb.GetRouterInterfaceStatsRequest) (*saipb.GetRouterInterfaceStatsResponse, error) {
counters, err := ri.dataplane.FlowCounterQuery(ctx, &fwdpb.FlowCounterQueryRequest{
ContextId: &fwdpb.ContextId{Id: ri.dataplane.ID()},
Ids: []*fwdpb.FlowCounterId{{
ObjectId: &fwdpb.ObjectId{Id: ifaceCounterID(req.GetOid(), true)},
}, {
ObjectId: &fwdpb.ObjectId{Id: ifaceCounterID(req.GetOid(), false)},
}},
})
if err != nil {
return nil, err
}

vals := []uint64{}

for _, counter := range req.GetCounterIds() {
switch counter {
case saipb.RouterInterfaceStat_ROUTER_INTERFACE_STAT_IN_OCTETS:
vals = append(vals, counters.GetCounters()[0].Octets)
case saipb.RouterInterfaceStat_ROUTER_INTERFACE_STAT_IN_PACKETS:
vals = append(vals, counters.GetCounters()[0].Packets)
case saipb.RouterInterfaceStat_ROUTER_INTERFACE_STAT_OUT_OCTETS:
vals = append(vals, counters.GetCounters()[1].Octets)
case saipb.RouterInterfaceStat_ROUTER_INTERFACE_STAT_OUT_PACKETS:
vals = append(vals, counters.GetCounters()[1].Packets)
default: // TODO: Support more stats.
vals = append(vals, 0)
}
}

return &saipb.GetRouterInterfaceStatsResponse{Values: vals}, nil
}

type vlan struct {
saipb.UnimplementedVlanServer
mgr *attrmgr.AttrMgr
Expand Down
9 changes: 9 additions & 0 deletions dataplane/saiserver/routing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,15 @@ func TestCreateRouterInterface(t *testing.T) {
Value: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
},
},
}, {
ActionType: fwdpb.ActionType_ACTION_TYPE_FLOW_COUNTER,
Action: &fwdpb.ActionDesc_Flow{
Flow: &fwdpb.FlowCounterActionDesc{
CounterId: &fwdpb.FlowCounterId{
ObjectId: &fwdpb.ObjectId{Id: "1-in-counter"},
},
},
},
}},
}},
},
Expand Down

0 comments on commit 2a1f90e

Please sign in to comment.