/
flow_counter.go
80 lines (69 loc) · 2.83 KB
/
flow_counter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Copyright 2022 Google LLC
//
// 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 actions
import (
"fmt"
log "github.com/golang/glog"
"github.com/openconfig/lemming/dataplane/forwarding/fwdaction"
"github.com/openconfig/lemming/dataplane/forwarding/infra/fwdcontext"
"github.com/openconfig/lemming/dataplane/forwarding/infra/fwdflowcounter"
"github.com/openconfig/lemming/dataplane/forwarding/infra/fwdobject"
"github.com/openconfig/lemming/dataplane/forwarding/infra/fwdpacket"
fwdpb "github.com/openconfig/lemming/proto/forwarding"
)
// flowcounter is an action that increments the per flow counters based on the packet.
type flowcounter struct {
counter *fwdflowcounter.FlowCounter
}
// String formats the type of the action as a string.
func (f *flowcounter) String() string {
if f.counter == nil {
return fmt.Sprintf("Type=%v;<FlowCounter=nil>", fwdpb.ActionType_ACTION_TYPE_FLOW_COUNTER)
}
return fmt.Sprintf("Type=%v;<FlowCounter=%v>", fwdpb.ActionType_ACTION_TYPE_FLOW_COUNTER, f.counter.ID())
}
// Cleanup releases the flowCounter.
func (f *flowcounter) Cleanup() {
if err := fwdflowcounter.Release(f.counter); err != nil {
log.Errorf("actions: Cleanup failed for action flowcounter, err %s", err)
}
f.counter = nil
}
// Process increments the octet and packet counter fields, based on the packet.
func (f *flowcounter) Process(packet fwdpacket.Packet, _ fwdobject.Counters) (fwdaction.Actions, fwdaction.State) {
if f.counter != nil {
octetCount := uint32(packet.Length())
const packetCount = 1
f.counter.Process(octetCount, packetCount)
}
return nil, fwdaction.CONTINUE
}
// flowcounterBuilder builds flowcounter actions.
type flowcounterBuilder struct{}
// init registers a builder for the flowcounter action type.
func init() {
fwdaction.Register(fwdpb.ActionType_ACTION_TYPE_FLOW_COUNTER, &flowcounterBuilder{})
}
// Build creates a new flowcounter action.
func (*flowcounterBuilder) Build(desc *fwdpb.ActionDesc, ctx *fwdcontext.Context) (fwdaction.Action, error) {
fc, ok := desc.Action.(*fwdpb.ActionDesc_Flow)
if !ok {
return nil, fmt.Errorf("actions: Build for flowcounter action failed, missing desc")
}
fctr, err := fwdflowcounter.Acquire(ctx, fc.Flow.GetCounterId())
if err != nil {
return nil, fmt.Errorf("actions: Build for flowcounter action failed, err %v", err)
}
return &flowcounter{counter: fctr}, nil
}