106 lines
1.9 KiB
Go
106 lines
1.9 KiB
Go
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
|
|
}
|
|
|
|
func FlattenFlowOp(fop FlowOp) []FlowOp {
|
|
return collectFlowOps(nil, fop)
|
|
}
|
|
|
|
func collectFlowOps(into []FlowOp, fop FlowOp) []FlowOp {
|
|
if fop == nil {
|
|
return into
|
|
}
|
|
|
|
if mfop, ok := fop.(*MultiFlowOp); ok {
|
|
for _, op := range mfop.ops {
|
|
into = collectFlowOps(into, op)
|
|
}
|
|
|
|
return into
|
|
}
|
|
|
|
return append(into, fop)
|
|
}
|