@@ -15,6 +15,7 @@ import (
1515
1616const (
1717 arpRequestsRepeatInterval = 1 * time .Second
18+ arpEntryCleanup = 60 * time .Second
1819)
1920
2021type NeighboursLookupTable struct {
@@ -30,15 +31,58 @@ type NeighboursLookupTable struct {
3031 checkv6 func (ipv6 types.IPv6Address ) bool
3132}
3233
34+ type neighboursLookupTableEntry struct {
35+ MAC types.MACAddress
36+ LastUsed time.Time
37+ }
38+
3339func NewNeighbourTable (index uint16 , mac types.MACAddress ,
3440 checkv4 func (ipv4 types.IPv4Address ) bool ,
3541 checkv6 func (ipv6 types.IPv6Address ) bool ) * NeighboursLookupTable {
36- return & NeighboursLookupTable {
42+
43+ return NewTimeoutNeighbourTable (index , mac , checkv4 , checkv6 , 0 )
44+ }
45+
46+ func NewTimeoutNeighbourTable (index uint16 , mac types.MACAddress ,
47+ checkv4 func (ipv4 types.IPv4Address ) bool ,
48+ checkv6 func (ipv6 types.IPv6Address ) bool ,
49+ cleanupInterval time.Duration ) * NeighboursLookupTable {
50+
51+ nlt := & NeighboursLookupTable {
3752 portIndex : index ,
3853 interfaceMAC : mac ,
3954 checkv4 : checkv4 ,
4055 checkv6 : checkv6 ,
4156 }
57+
58+ if cleanupInterval <= 0 {
59+ return nlt
60+ }
61+
62+ go func () {
63+ ticker := time .NewTicker (cleanupInterval )
64+
65+ for {
66+ select {
67+ case <- ticker .C :
68+ nlt .cleanup ()
69+ }
70+ }
71+ }()
72+
73+ return nlt
74+ }
75+
76+ func (table * NeighboursLookupTable ) cleanup () {
77+ table .ipv4Table .Range (func (k interface {}, v interface {}) bool {
78+ entry := v .(neighboursLookupTableEntry )
79+ if time .Since (entry .LastUsed ) >= arpEntryCleanup {
80+ ipv4 := k .(types.IPv4Address )
81+ table .ipv4Table .Delete (ipv4 )
82+ common .LogDebug (common .Debug , "Removed ARP Entry for" , ipv4 , ":" , entry .MAC )
83+ }
84+ return true
85+ })
4286}
4387
4488// HandleIPv4ARPRequest processes IPv4 ARP request and reply packets
@@ -52,7 +96,12 @@ func (table *NeighboursLookupTable) HandleIPv4ARPPacket(pkt *Packet) error {
5296 // Handle ARP reply and record information in lookup table
5397 if SwapBytesUint16 (arp .Operation ) == ARPReply {
5498 ipv4 := types .ArrayToIPv4 (arp .SPA )
55- table .ipv4Table .Store (ipv4 , arp .SHA )
99+ entry := neighboursLookupTableEntry {
100+ MAC : arp .SHA ,
101+ LastUsed : time .Now (),
102+ }
103+ table .ipv4Table .Store (ipv4 , entry )
104+ common .LogDebug (common .Debug , "Added ARP Entry for" , ipv4 , ":" , entry .MAC )
56105 }
57106 return nil
58107 }
@@ -85,7 +134,10 @@ func (table *NeighboursLookupTable) HandleIPv4ARPPacket(pkt *Packet) error {
85134func (table * NeighboursLookupTable ) LookupMACForIPv4 (ipv4 types.IPv4Address ) (types.MACAddress , bool ) {
86135 v , found := table .ipv4Table .Load (ipv4 )
87136 if found {
88- return v .(types.MACAddress ), true
137+ entry := v .(neighboursLookupTableEntry )
138+ entry .LastUsed = time .Now ()
139+ table .ipv4Table .Store (ipv4 , entry )
140+ return entry .MAC , true
89141 }
90142 return [types .EtherAddrLen ]byte {}, false
91143}
0 commit comments