This repository has been archived by the owner on Jun 20, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 663
/
flow.go
102 lines (78 loc) · 1.88 KB
/
flow.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package router
import (
"net"
"github.com/weaveworks/mesh"
)
// Just enough flow machinery for the weave router
type MAC [6]byte
func (mac MAC) String() string {
return net.HardwareAddr(mac[:]).String()
}
type PacketKey struct {
SrcMAC MAC
DstMAC MAC
}
type ForwardPacketKey struct {
SrcPeer *mesh.Peer
DstPeer *mesh.Peer
PacketKey
}
type FlowOp interface {
// The caller must supply an EthernetDecoder specific to this
// thread, which has already been used to decode the frame.
// The broadcast parameter is a hint whether the packet is
// being broadcast.
Process(frame []byte, dec *EthernetDecoder, broadcast bool)
// Does the FlowOp discard the packet?
Discards() bool
}
type DiscardingFlowOp struct{}
func (DiscardingFlowOp) Process([]byte, *EthernetDecoder, bool) {
}
func (DiscardingFlowOp) Discards() bool {
return true
}
type NonDiscardingFlowOp struct{}
func (NonDiscardingFlowOp) Discards() bool {
return false
}
type MultiFlowOp struct {
broadcast bool
ops []FlowOp
}
func NewMultiFlowOp(broadcast bool, ops ...FlowOp) *MultiFlowOp {
mfop := &MultiFlowOp{broadcast: broadcast}
for _, op := range ops {
mfop.Add(op)
}
return mfop
}
func (mfop *MultiFlowOp) Add(op FlowOp) {
mfop.ops = append(mfop.ops, op)
}
func (mfop *MultiFlowOp) Process(frame []byte, dec *EthernetDecoder, broadcast bool) {
for _, op := range mfop.ops {
op.Process(frame, dec, mfop.broadcast)
}
}
func (mfop *MultiFlowOp) Discards() bool {
for _, op := range mfop.ops {
if !op.Discards() {
return false
}
}
return true
}
// Flatten out a FlowOp to eliminate any MultiFlowOps
func FlattenFlowOp(fop FlowOp) []FlowOp {
return collectFlowOps(nil, fop)
}
func collectFlowOps(into []FlowOp, fop FlowOp) []FlowOp {
if mfop, ok := fop.(*MultiFlowOp); ok {
for _, op := range mfop.ops {
into = collectFlowOps(into, op)
}
return into
}
return append(into, fop)
}