X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Farphandler%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Farphandler%2Finternal%2FArpHandler.java;h=abe104a40638f1a58e47fdcc5f91eda6b1f87359;hb=5c0caf3a94c0ad62c266922b8b303006b633ae0c;hp=e345d65f7e527754981de650e8c75e47a72b47d8;hpb=9438cd96bbebb06f5b67c81f313eacd6e382f0d7;p=controller.git diff --git a/opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java b/opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java index e345d65f7e..abe104a406 100644 --- a/opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java +++ b/opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java @@ -41,6 +41,7 @@ import org.opendaylight.controller.hosttracker.IfHostListener; import org.opendaylight.controller.hosttracker.IfIptoHost; import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector; import org.opendaylight.controller.hosttracker.hostAware.IHostFinder; +import org.opendaylight.controller.sal.connection.ConnectionLocality; import org.opendaylight.controller.sal.core.ConstructionException; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; @@ -52,6 +53,7 @@ import org.opendaylight.controller.sal.packet.IPv4; import org.opendaylight.controller.sal.packet.Packet; import org.opendaylight.controller.sal.packet.PacketResult; import org.opendaylight.controller.sal.packet.RawPacket; +import org.opendaylight.controller.sal.routing.IRouting; import org.opendaylight.controller.sal.utils.EtherTypes; import org.opendaylight.controller.sal.utils.HexEncode; import org.opendaylight.controller.sal.utils.NetUtils; @@ -68,6 +70,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA private ISwitchManager switchManager; private ITopologyManager topologyManager; private IDataPacketService dataPacketService; + private IRouting routing; private IClusterContainerServices clusterContainerService; private IConnectionManager connectionManager; private Set hostListeners = new CopyOnWriteArraySet(); @@ -107,6 +110,16 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA } } + void setRouting(IRouting r) { + this.routing = r; + } + + void unsetRouting(IRouting r) { + if (this.routing == r) { + this.routing = null; + } + } + void setHostListener(IfHostListener s) { if (this.hostListeners != null) { this.hostListeners.add(s); @@ -253,7 +266,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA */ if ((targetIP.equals(subnet.getNetworkAddress())) && (NetUtils.isBroadcastMACAddr(targetMAC) || Arrays.equals(targetMAC, getControllerMAC()))) { - if (connectionManager.isLocal(p.getNode())){ + if (connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL){ if (log.isTraceEnabled()){ log.trace("Received local ARP req. for default gateway. Replying with controller MAC: {}", HexEncode.bytesToHexString(getControllerMAC())); @@ -292,7 +305,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA */ if (NetUtils.isBroadcastMACAddr(targetMAC) || Arrays.equals(host.getDataLayerAddressBytes(), targetMAC)) { log.trace("Received ARP req. for known host {}, sending reply...", targetIP); - if (connectionManager.isLocal(p.getNode())) { + if (connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL) { sendARPReply(p, host.getDataLayerAddressBytes(), host.getNetworkAddress(), @@ -317,7 +330,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA } } - /* + /** * Send a broadcast ARP Request to the switch/ ports using * the networkAddress of the subnet as sender IP * the controller's MAC as sender MAC @@ -335,9 +348,11 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA nodeConnectors = subnet.getNodeConnectors(); } byte[] targetHardwareAddress = new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 }; + + //TODO: should use IBroadcastHandler instead for (NodeConnector p : nodeConnectors) { - //fiter out any non-local or internal ports - if (! connectionManager.isLocal(p.getNode()) || topologyManager.isInternal(p)) { + //filter out any non-local or internal ports + if (!(connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL) || topologyManager.isInternal(p)) { continue; } log.trace("Sending toward nodeConnector:{}", p); @@ -357,7 +372,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA } } - /* + /** * Send a unicast ARP Request to the known host on a specific switch/port as * defined in the host. * The sender IP is the networkAddress of the subnet @@ -418,7 +433,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA return; } - if (connectionManager.isLocal(host.getnodeconnectorNode())){ + if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL){ log.trace("Send a ucast ARP req. to: {}", host); sendUcastARPRequest(host, subnet); } else { @@ -427,10 +442,13 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA } } - /* + /** * An IP packet is punted to the controller, this means that the * destination host is not known to the controller. * Need to discover it by sending a Broadcast ARP Request + * + * @param pkt + * @param p */ protected void handlePuntedIPPacket(IPv4 pkt, NodeConnector p) { @@ -439,6 +457,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA return; } + // try to find a matching subnet Subnet subnet = null; if (switchManager != null) { subnet = switchManager.getSubnetByNetworkAddress(dIP); @@ -447,12 +466,43 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA log.debug("Can't find subnet matching {}, drop packet", dIP); return; } - log.trace("Punted IP pkt from {}, sending bcast ARP event...", dIP); - /* - * unknown destination host, initiate bcast ARP request - */ - arpRequestReplyEvent.put(new ARPRequest(dIP, subnet), false); - return; + + // see if we know about the host + HostNodeConnector host = hostTracker.hostFind(dIP); + + if (host == null) { + // if we don't, know about the host, try to find it + log.trace("Punted IP pkt to {}, sending bcast ARP event...", + dIP); + /* + * unknown destination host, initiate bcast ARP request + */ + arpRequestReplyEvent.put(new ARPRequest(dIP, subnet), false); + + } else if (routing == null || + routing.getRoute(p.getNode(), host.getnodeconnectorNode()) != null) { + /* if IRouting is available, make sure that this packet can get it's + * destination normally before teleporting it there. If it's not + * available, then assume it's reachable. + * + * TODO: come up with a way to do this in the absence of IRouting + */ + + log.trace("forwarding punted IP pkt to {} received at {}", dIP, p); + + /* if we know where the host is and there's a path from where this + * packet was punted to where the host is, then deliver it to the + * host for now */ + NodeConnector nc = host.getnodeConnector(); + + // re-encode the Ethernet packet (the parent of the IPv4 packet) + RawPacket rp = this.dataPacketService.encodeDataPacket(pkt.getParent()); + rp.setOutgoingNodeConnector(nc); + this.dataPacketService.transmitDataPacket(rp); + } else { + log.trace("ignoring punted IP pkt to {} because there is no route from {}", + dIP, p); + } } public byte[] getControllerMAC() { @@ -476,7 +526,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA retrieveCaches(); } - @SuppressWarnings({ "unchecked", "deprecation" }) + @SuppressWarnings({ "unchecked" }) private void retrieveCaches() { ConcurrentMap map; @@ -493,7 +543,6 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA } } - @SuppressWarnings("deprecation") private void allocateCaches() { if (clusterContainerService == null){ nonClusterObjectCreate(); @@ -610,7 +659,6 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA private void startPeriodicTimer() { this.periodicTimer = new Timer("ArpHandler Periodic Timer"); this.periodicTimer.scheduleAtFixedRate(new TimerTask() { - @SuppressWarnings("deprecation") @Override public void run() { Set targetIPs = countDownTimers.keySet(); @@ -670,7 +718,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA HexEncode.bytesToHexString(host.getDataLayerAddressBytes()), host.getNetworkAddress() }); } - if (connectionManager.isLocal(host.getnodeconnectorNode())){ + if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL){ sendARPReply(host.getnodeConnector(), sourceMAC, sourceIP, @@ -740,7 +788,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA sendBcastARPRequest(req.getTargetIP(), req.getSubnet()); //If unicast and local, send reply - } else if (connectionManager.isLocal(req.getHost().getnodeconnectorNode())) { + } else if (connectionManager.getLocalityStatus(req.getHost().getnodeconnectorNode()) == ConnectionLocality.LOCAL) { log.trace("ARPCacheEventHandler - sendUcatARPRequest upon receipt of {}", req); sendUcastARPRequest(req.getHost(), req.getSubnet()); } @@ -751,7 +799,7 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA log.trace("Trigger a generateAndSendReply in response to {}", rep); generateAndSendReply(rep.getTargetIP(), rep.getTargetMac()); // Otherwise, a specific reply. If local, send out. - } else if (connectionManager.isLocal(rep.getPort().getNode())) { + } else if (connectionManager.getLocalityStatus(rep.getPort().getNode()) == ConnectionLocality.LOCAL) { log.trace("ARPCacheEventHandler - sendUcatARPReply locally in response to {}", rep); sendARPReply(rep.getPort(), rep.getSourceMac(),