Don't use a nil FlowOp to mean "discard the packet"
This commit is contained in:
1 parent
b36ffe1c9d
commit
e702234fdc
6 files changed
+54
-28
No files matched your search
+9
-12
@@ -443,8 +443,10 @@ func (fastdp *FastDatapath) getVxlanVportID(udpPort int) (odp.VportID, error) {
|
||||
pk := flowKeysToPacketKey(fks)
|
||||
var zeroMAC MAC
|
||||
if pk.SrcMAC == zeroMAC && pk.DstMAC == zeroMAC {
|
||||
return vxlanSpecialPacketFlowOp{fastdp, srcPeer,
|
||||
&net.UDPAddr{
|
||||
return vxlanSpecialPacketFlowOp{
|
||||
fastdp: fastdp,
|
||||
srcPeer: srcPeer,
|
||||
sender: &net.UDPAddr{
|
||||
IP: net.IP(tunKey.Ipv4Src[:]),
|
||||
Port: udpPort,
|
||||
},
|
||||
@@ -477,6 +479,7 @@ func (fastdp *FastDatapath) extractPeers(tunnelID [8]byte) (*Peer, *Peer) {
|
||||
}
|
||||
|
||||
type vxlanSpecialPacketFlowOp struct {
|
||||
NonDiscardingFlowOp
|
||||
fastdp *FastDatapath
|
||||
srcPeer *Peer
|
||||
sender *net.UDPAddr
|
||||
@@ -765,7 +768,7 @@ func (fwd *fastDatapathForwarder) Forward(key ForwardPacketKey) FlowOp {
|
||||
remoteIP, err := ipv4Bytes(fwd.remoteAddr.IP)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return nil
|
||||
return DiscardingFlowOp{}
|
||||
}
|
||||
|
||||
var sta odp.SetTunnelAction
|
||||
@@ -1134,6 +1137,7 @@ func (fastdp *FastDatapath) takeDecoder(lock *fastDatapathLock) *EthernetDecoder
|
||||
}
|
||||
|
||||
type odpActionsFlowOp struct {
|
||||
NonDiscardingFlowOp
|
||||
fastdp *FastDatapath
|
||||
actions []odp.Action
|
||||
}
|
||||
@@ -1157,22 +1161,15 @@ func (fop odpActionsFlowOp) Process(frame []byte, dec *EthernetDecoder,
|
||||
checkWarn(fastdp.dp.Execute(frame, nil, fop.actions))
|
||||
}
|
||||
|
||||
type nopFlowOp struct{}
|
||||
|
||||
func (nopFlowOp) Process([]byte, *EthernetDecoder, bool) {
|
||||
// A nopFlowOp just provides a hint about flow creation, it
|
||||
// doesn't send anything
|
||||
}
|
||||
|
||||
// A vetoFlowCreationFlowOp flags that no flow should be created
|
||||
type vetoFlowCreationFlowOp struct {
|
||||
nopFlowOp
|
||||
DiscardingFlowOp
|
||||
}
|
||||
|
||||
// A odpFlowKeyFlowOp adds a FlowKey to the resulting flow
|
||||
type odpFlowKeyFlowOp struct {
|
||||
DiscardingFlowOp
|
||||
key odp.FlowKey
|
||||
nopFlowOp
|
||||
}
|
||||
|
||||
func odpFlowKey(key odp.FlowKey) FlowOp {
|
||||
|
||||
+33
-7
@@ -27,6 +27,24 @@ type FlowOp interface {
|
||||
// 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 {
|
||||
@@ -36,16 +54,14 @@ type MultiFlowOp struct {
|
||||
|
||||
func NewMultiFlowOp(broadcast bool, ops ...FlowOp) *MultiFlowOp {
|
||||
mfop := &MultiFlowOp{broadcast: broadcast}
|
||||
mfop.Add(ops...)
|
||||
for _, op := range ops {
|
||||
mfop.Add(op)
|
||||
}
|
||||
return mfop
|
||||
}
|
||||
|
||||
func (mfop *MultiFlowOp) Add(ops ...FlowOp) {
|
||||
for _, op := range ops {
|
||||
if op != nil {
|
||||
mfop.ops = append(mfop.ops, op)
|
||||
}
|
||||
}
|
||||
func (mfop *MultiFlowOp) Add(op FlowOp) {
|
||||
mfop.ops = append(mfop.ops, op)
|
||||
}
|
||||
|
||||
func (mfop *MultiFlowOp) Process(frame []byte, dec *EthernetDecoder,
|
||||
@@ -55,6 +71,16 @@ func (mfop *MultiFlowOp) Process(frame []byte, dec *EthernetDecoder,
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ func (NullOverlay) AddFeaturesTo(map[string]string) {
|
||||
}
|
||||
|
||||
func (NullOverlay) Forward(ForwardPacketKey) FlowOp {
|
||||
return nil
|
||||
return DiscardingFlowOp{}
|
||||
}
|
||||
|
||||
func (NullOverlay) Stop() {
|
||||
|
||||
+3
-1
@@ -9,6 +9,8 @@ import (
|
||||
)
|
||||
|
||||
type Pcap struct {
|
||||
NonDiscardingFlowOp
|
||||
|
||||
iface *net.Interface
|
||||
bufSz int
|
||||
|
||||
@@ -131,7 +133,7 @@ func (p *Pcap) sniff(readHandle *pcap.Handle, consumer BridgeConsumer) {
|
||||
continue
|
||||
}
|
||||
|
||||
if fop := consumer(dec.PacketKey()); fop != nil {
|
||||
if fop := consumer(dec.PacketKey()); !fop.Discards() {
|
||||
// We are handing over the frame to
|
||||
// forwarders, so we need to make a copy of it
|
||||
// in order to prevent the next capture from
|
||||
|
||||
+6
-6
@@ -114,12 +114,12 @@ func (router *Router) handleCapturedPacket(key PacketKey) FlowOp {
|
||||
// we are seeing a frame we injected ourself. That
|
||||
// shouldn't happen, but discard it just in case.
|
||||
log.Errorln("Captured frame from MAC (", srcMac, ") associated with another peer", conflictPeer)
|
||||
return nil
|
||||
return DiscardingFlowOp{}
|
||||
}
|
||||
|
||||
// Discard STP broadcasts
|
||||
if key.DstMAC == [...]byte{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00} {
|
||||
return nil
|
||||
return DiscardingFlowOp{}
|
||||
}
|
||||
|
||||
dstMac := net.HardwareAddr(key.DstMAC[:])
|
||||
@@ -130,7 +130,7 @@ func (router *Router) handleCapturedPacket(key PacketKey) FlowOp {
|
||||
// it's likely to be broadcasting the packet to all
|
||||
// ports. So if it happens, just drop the packet to
|
||||
// avoid warnings if we try to forward it.
|
||||
return nil
|
||||
return DiscardingFlowOp{}
|
||||
case nil:
|
||||
// If we don't know which peer corresponds to the dest
|
||||
// MAC, broadcast it.
|
||||
@@ -223,14 +223,14 @@ func (router *Router) relay(key ForwardPacketKey) FlowOp {
|
||||
// Not necessarily an error as there could be a race with the
|
||||
// dst disappearing whilst the frame is in flight
|
||||
log.Println("Received packet for unknown destination:", key.DstPeer)
|
||||
return nil
|
||||
return DiscardingFlowOp{}
|
||||
}
|
||||
|
||||
conn, found := router.Ourself.ConnectionTo(relayPeerName)
|
||||
if !found {
|
||||
// Again, could just be a race, not necessarily an error
|
||||
log.Println("Unable to find connection to relay peer", relayPeerName)
|
||||
return nil
|
||||
return DiscardingFlowOp{}
|
||||
}
|
||||
|
||||
return conn.(*LocalConnection).Forward(key)
|
||||
@@ -239,7 +239,7 @@ func (router *Router) relay(key ForwardPacketKey) FlowOp {
|
||||
func (router *Router) relayBroadcast(srcPeer *Peer, key PacketKey) FlowOp {
|
||||
nextHops := router.Routes.Broadcast(srcPeer.Name)
|
||||
if len(nextHops) == 0 {
|
||||
return nil
|
||||
return DiscardingFlowOp{}
|
||||
}
|
||||
|
||||
op := NewMultiFlowOp(true)
|
||||
|
||||
+2
-1
@@ -427,12 +427,13 @@ func (fwd *sleeveForwarder) ErrorChannel() <-chan error {
|
||||
}
|
||||
|
||||
type curriedForward struct {
|
||||
NonDiscardingFlowOp
|
||||
fwd *sleeveForwarder
|
||||
key ForwardPacketKey
|
||||
}
|
||||
|
||||
func (fwd *sleeveForwarder) Forward(key ForwardPacketKey) FlowOp {
|
||||
return curriedForward{fwd, key}
|
||||
return curriedForward{fwd: fwd, key: key}
|
||||
}
|
||||
|
||||
func (f curriedForward) Process(frame []byte, dec *EthernetDecoder,
|
||||
|
||||
Reference in new issue
Block a user