blob: 4af4b056084488e7ab45ebb08c29ee31277ee479 [file] [log] [blame]
Jonathan Hartabad6a52013-09-30 18:17:21 +13001package net.onrc.onos.ofcontroller.proxyarp;
2
3import java.net.InetAddress;
4import java.util.HashMap;
5import java.util.Map;
6
7import net.floodlightcontroller.util.MACAddress;
8
9import org.slf4j.Logger;
10import org.slf4j.LoggerFactory;
11
12/**
13 * Implements a basic ARP cache which maps IPv4 addresses to MAC addresses.
14 * Mappings time out after a short period of time (currently 1 min). We don't
15 * try and refresh the mapping before the entry times out because as a controller
16 * we don't know if the mapping is still needed.
Jonathan Hartabad6a52013-09-30 18:17:21 +130017 */
18
19/* TODO clean out old ARP entries out of the cache periodically. We currently
20 * don't do this which means the cache memory size will never decrease. We already
21 * have a periodic thread that can be used to do this in ProxyArpManager.
22 */
23public class ArpCache {
24 private final static Logger log = LoggerFactory.getLogger(ArpCache.class);
25
26 private final long ARP_ENTRY_TIMEOUT = 60000; //ms (1 min)
27
28 //Protected by locking on the ArpCache object
29 private final Map<InetAddress, ArpCacheEntry> arpCache;
30
31 private static class ArpCacheEntry {
32 private final MACAddress macAddress;
33 private long timeLastSeen;
34
35 public ArpCacheEntry(MACAddress macAddress) {
36 this.macAddress = macAddress;
37 this.timeLastSeen = System.currentTimeMillis();
38 }
39
40 public MACAddress getMacAddress() {
41 return macAddress;
42 }
43
44 public long getTimeLastSeen() {
45 return timeLastSeen;
46 }
47
48 public void setTimeLastSeen(long time){
49 timeLastSeen = time;
50 }
51 }
52
53 public ArpCache() {
54 arpCache = new HashMap<InetAddress, ArpCacheEntry>();
55 }
56
57 public synchronized MACAddress lookup(InetAddress ipAddress){
58 ArpCacheEntry arpEntry = arpCache.get(ipAddress);
59
60 if (arpEntry == null){
61 return null;
62 }
63
64 if (System.currentTimeMillis() - arpEntry.getTimeLastSeen()
65 > ARP_ENTRY_TIMEOUT){
66 //Entry has timed out so we'll remove it and return null
67 log.trace("Removing expired ARP entry for {}", ipAddress.getHostAddress());
68
69 arpCache.remove(ipAddress);
70 return null;
71 }
72
73 return arpEntry.getMacAddress();
74 }
75
76 public synchronized void update(InetAddress ipAddress, MACAddress macAddress){
77 ArpCacheEntry arpEntry = arpCache.get(ipAddress);
78
79 if (arpEntry != null && arpEntry.getMacAddress().equals(macAddress)){
80 arpEntry.setTimeLastSeen(System.currentTimeMillis());
81 }
82 else {
83 arpCache.put(ipAddress, new ArpCacheEntry(macAddress));
84 }
85 }
86}