For fast datapath, the router core will only be invoked upon datapath misses. And it needs to yield routing decisions in a form that can be used to configure the in-kernel datapath. So here we make the router core yield FlowOps, which represent operations which actually do something with a packet. The router core obtains these in turn from the Bridge or the Overlay, depending on what it wants to do with a packet. For fast datapath, it's critical that the router makes decisions based only on the required packet header information (as the same header information will be used when configuring the ODP flow rules). So we pass only that information into the router core, in the form of PacketKeys. The overall effect is to curry the router core: Rather than taking a packet and doing something with it, it takes packet header information and returns a function that does something with a packet.
51 lines
1010 B
Go
51 lines
1010 B
Go
package router
|
|
|
|
import "net"
|
|
|
|
// 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 *Peer
|
|
DstPeer *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)
|
|
}
|
|
|
|
type MultiFlowOp struct {
|
|
broadcast bool
|
|
ops []FlowOp
|
|
}
|
|
|
|
func NewMultiFlowOp(broadcast bool) *MultiFlowOp {
|
|
return &MultiFlowOp{broadcast: broadcast}
|
|
}
|
|
|
|
func (mfop *MultiFlowOp) Add(ops ...FlowOp) {
|
|
mfop.ops = append(mfop.ops, ops...)
|
|
}
|
|
|
|
func (mfop *MultiFlowOp) Process(frame []byte, dec *EthernetDecoder,
|
|
broadcast bool) {
|
|
for _, op := range mfop.ops {
|
|
op.Process(frame, dec, mfop.broadcast)
|
|
}
|
|
}
|