Injected packets shouldn't happen in handleCapturedPacket
Check for them just in case, but don't take an extra lock to do it.
This commit is contained in:
1 parent
20b35f3139
commit
f7ce6a1fdb
3 files changed
+36
-17
No files matched your search
+2
-1
@@ -5,7 +5,8 @@ type Bridge interface {
|
||||
// Inject a packet to be delivered locally
|
||||
InjectPacket(PacketKey) FlowOp
|
||||
|
||||
// Start consuming packets from the bridge
|
||||
// Start consuming packets from the bridge. Injected packets
|
||||
// should not be included.
|
||||
StartConsumingPackets(BridgeConsumer) error
|
||||
|
||||
String() string
|
||||
|
||||
+23
-6
@@ -28,32 +28,49 @@ func NewMacCache(maxAge time.Duration, onExpiry func(net.HardwareAddr, *Peer)) *
|
||||
return cache
|
||||
}
|
||||
|
||||
func (cache *MacCache) Enter(mac net.HardwareAddr, peer *Peer) bool {
|
||||
func (cache *MacCache) add(mac net.HardwareAddr, peer *Peer, force bool) (bool, *Peer) {
|
||||
key := macint(mac)
|
||||
now := time.Now()
|
||||
|
||||
cache.RLock()
|
||||
entry, found := cache.table[key]
|
||||
if found && entry.peer == peer && now.Before(entry.lastSeen.Add(cache.maxAge/10)) {
|
||||
cache.RUnlock()
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
cache.RUnlock()
|
||||
|
||||
cache.Lock()
|
||||
defer cache.Unlock()
|
||||
|
||||
entry, found = cache.table[key]
|
||||
if !found {
|
||||
cache.table[key] = &MacCacheEntry{lastSeen: now, peer: peer}
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if entry.peer != peer {
|
||||
entry.lastSeen = now
|
||||
if !force {
|
||||
return false, entry.peer
|
||||
}
|
||||
|
||||
entry.peer = peer
|
||||
return true
|
||||
}
|
||||
|
||||
if now.After(entry.lastSeen.Add(cache.maxAge / 10)) {
|
||||
entry.lastSeen = now
|
||||
}
|
||||
return false
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (cache *MacCache) Add(mac net.HardwareAddr, peer *Peer) (bool, *Peer) {
|
||||
return cache.add(mac, peer, false)
|
||||
}
|
||||
|
||||
func (cache *MacCache) AddForced(mac net.HardwareAddr, peer *Peer) bool {
|
||||
newMac, _ := cache.add(mac, peer, true)
|
||||
return newMac
|
||||
}
|
||||
|
||||
func (cache *MacCache) Lookup(mac net.HardwareAddr) *Peer {
|
||||
|
||||
+11
-10
@@ -103,17 +103,18 @@ func (router *Router) UsingPassword() bool {
|
||||
func (router *Router) handleCapturedPacket(key PacketKey) FlowOp {
|
||||
router.PacketLogging.LogPacket("Captured", key)
|
||||
srcMac := net.HardwareAddr(key.SrcMAC[:])
|
||||
srcPeer := router.Macs.Lookup(srcMac)
|
||||
|
||||
// We need to filter out frames we injected ourselves. For such
|
||||
// frames, the srcMAC will have been recorded as associated with a
|
||||
// different peer.
|
||||
if srcPeer != nil && srcPeer != router.Ourself.Peer {
|
||||
return nil
|
||||
}
|
||||
|
||||
if router.Macs.Enter(srcMac, router.Ourself.Peer) {
|
||||
switch newSrcMac, conflictPeer := router.Macs.Add(srcMac, router.Ourself.Peer); {
|
||||
case newSrcMac:
|
||||
log.Println("Discovered local MAC", srcMac)
|
||||
|
||||
case conflictPeer != nil:
|
||||
// The MAC cache has an entry for the source MAC
|
||||
// associated with another peer. This probably means
|
||||
// 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
|
||||
}
|
||||
|
||||
// Discard STP broadcasts
|
||||
@@ -183,7 +184,7 @@ func (router *Router) handleForwardedPacket(key ForwardPacketKey) FlowOp {
|
||||
|
||||
srcMac := net.HardwareAddr(key.SrcMAC[:])
|
||||
dstMac := net.HardwareAddr(key.DstMAC[:])
|
||||
if router.Macs.Enter(srcMac, key.SrcPeer) {
|
||||
if router.Macs.AddForced(srcMac, key.SrcPeer) {
|
||||
log.Println("Discovered remote MAC", srcMac, "at", key.SrcPeer)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user