blob: 8b9c65a5f5623e639702f17dfc17be2cb8d02886 [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.
17 *
18 */
19
20/* TODO clean out old ARP entries out of the cache periodically. We currently
21 * don't do this which means the cache memory size will never decrease. We already
22 * have a periodic thread that can be used to do this in ProxyArpManager.
23 */
24public class ArpCache {
25 private final static Logger log = LoggerFactory.getLogger(ArpCache.class);
26
27 private final long ARP_ENTRY_TIMEOUT = 60000; //ms (1 min)
28
29 //Protected by locking on the ArpCache object
30 private final Map<InetAddress, ArpCacheEntry> arpCache;
31
32 private static class ArpCacheEntry {
33 private final MACAddress macAddress;
34 private long timeLastSeen;
35
36 public ArpCacheEntry(MACAddress macAddress) {
37 this.macAddress = macAddress;
38 this.timeLastSeen = System.currentTimeMillis();
39 }
40
41 public MACAddress getMacAddress() {
42 return macAddress;
43 }
44
45 public long getTimeLastSeen() {
46 return timeLastSeen;
47 }
48
49 public void setTimeLastSeen(long time){
50 timeLastSeen = time;
51 }
52 }
53
54 public ArpCache() {
55 arpCache = new HashMap<InetAddress, ArpCacheEntry>();
56 }
57
58 public synchronized MACAddress lookup(InetAddress ipAddress){
59 ArpCacheEntry arpEntry = arpCache.get(ipAddress);
60
61 if (arpEntry == null){
62 return null;
63 }
64
65 if (System.currentTimeMillis() - arpEntry.getTimeLastSeen()
66 > ARP_ENTRY_TIMEOUT){
67 //Entry has timed out so we'll remove it and return null
68 log.trace("Removing expired ARP entry for {}", ipAddress.getHostAddress());
69
70 arpCache.remove(ipAddress);
71 return null;
72 }
73
74 return arpEntry.getMacAddress();
75 }
76
77 public synchronized void update(InetAddress ipAddress, MACAddress macAddress){
78 ArpCacheEntry arpEntry = arpCache.get(ipAddress);
79
80 if (arpEntry != null && arpEntry.getMacAddress().equals(macAddress)){
81 arpEntry.setTimeLastSeen(System.currentTimeMillis());
82 }
83 else {
84 arpCache.put(ipAddress, new ArpCacheEntry(macAddress));
85 }
86 }
87}