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.
35 lines
725 B
Go
35 lines
725 B
Go
package router
|
|
|
|
// Interface to packet handling on the local virtual bridge
|
|
type Bridge interface {
|
|
// Inject a packet to be delivered locally
|
|
InjectPacket(PacketKey) FlowOp
|
|
|
|
// Start consuming packets from the bridge
|
|
StartConsumingPackets(BridgeConsumer) error
|
|
|
|
String() string
|
|
Stats() map[string]int
|
|
}
|
|
|
|
// A function that determines how to handle locally captured packets.
|
|
type BridgeConsumer func(PacketKey) FlowOp
|
|
|
|
type NullBridge struct{}
|
|
|
|
func (NullBridge) InjectPacket(PacketKey) FlowOp {
|
|
return nil
|
|
}
|
|
|
|
func (NullBridge) StartConsumingPackets(BridgeConsumer) error {
|
|
return nil
|
|
}
|
|
|
|
func (NullBridge) String() string {
|
|
return "<no bridge networking>"
|
|
}
|
|
|
|
func (NullBridge) Stats() map[string]int {
|
|
return nil
|
|
}
|