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;
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.topology.TopoEdgeUpdate;
import org.opendaylight.controller.sal.utils.EtherTypes;
import org.opendaylight.controller.sal.utils.HexEncode;
import org.opendaylight.controller.sal.utils.NetUtils;
byte[] tMAC, InetAddress tIP) {
byte[] senderIP = sIP.getAddress();
byte[] targetIP = tIP.getAddress();
- ARP arp = new ARP();
- arp.setHardwareType(ARP.HW_TYPE_ETHERNET)
- .setProtocolType(EtherTypes.IPv4.shortValue())
- .setHardwareAddressLength((byte) 6)
- .setProtocolAddressLength((byte) 4)
- .setOpCode(ARP.REPLY)
- .setSenderHardwareAddress(sMAC)
- .setSenderProtocolAddress(senderIP)
- .setTargetHardwareAddress(tMAC)
- .setTargetProtocolAddress(targetIP);
+ ARP arp = createARP(ARP.REPLY,sMAC,senderIP,tMAC,targetIP);
- Ethernet ethernet = new Ethernet();
- ethernet.setSourceMACAddress(sMAC)
- .setDestinationMACAddress(tMAC)
- .setEtherType(EtherTypes.ARP.shortValue())
- .setPayload(arp);
+ Ethernet ethernet = createEthernet(sMAC, tMAC, arp);
RawPacket destPkt = this.dataPacketService.encodeDataPacket(ethernet);
destPkt.setOutgoingNodeConnector(p);
*/
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()));
*/
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(),
}
}
- /*
+ /**
* 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
} else {
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);
- ARP arp = new ARP();
byte[] senderIP = subnet.getNetworkAddress().getAddress();
byte[] targetIPByte = targetIP.getAddress();
- arp.setHardwareType(ARP.HW_TYPE_ETHERNET)
- .setProtocolType(EtherTypes.IPv4.shortValue())
- .setHardwareAddressLength((byte) 6)
- .setProtocolAddressLength((byte) 4)
- .setOpCode(ARP.REQUEST)
- .setSenderHardwareAddress(getControllerMAC())
- .setSenderProtocolAddress(senderIP)
- .setTargetHardwareAddress(
- new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 })
- .setTargetProtocolAddress(targetIPByte);
-
- Ethernet ethernet = new Ethernet();
- ethernet.setSourceMACAddress(getControllerMAC())
- .setDestinationMACAddress(new byte[] {(byte) -1,
- (byte) -1,
- (byte) -1,
- (byte) -1,
- (byte) -1,
- (byte) -1 })
- .setEtherType(EtherTypes.ARP.shortValue()).setPayload(arp);
+ ARP arp = createARP(ARP.REQUEST, getControllerMAC(), senderIP, targetHardwareAddress, targetIPByte);
+
+ byte[] destMACAddress = NetUtils.getBroadcastMACAddr();
+ Ethernet ethernet = createEthernet(getControllerMAC(), destMACAddress, arp);
// TODO For now send port-by-port, see how to optimize to
// send to multiple ports at once
}
}
- /*
+ /**
* 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
byte[] senderIP = subnet.getNetworkAddress().getAddress();
byte[] targetIP = host.getNetworkAddress().getAddress();
byte[] targetMAC = host.getDataLayerAddressBytes();
- ARP arp = new ARP();
- arp.setHardwareType(ARP.HW_TYPE_ETHERNET)
- .setProtocolType(EtherTypes.IPv4.shortValue())
- .setHardwareAddressLength((byte) 6)
- .setProtocolAddressLength((byte) 4)
- .setOpCode(ARP.REQUEST)
- .setSenderHardwareAddress(getControllerMAC())
- .setSenderProtocolAddress(senderIP)
- .setTargetHardwareAddress(targetMAC)
- .setTargetProtocolAddress(targetIP);
+ ARP arp = createARP(ARP.REQUEST, getControllerMAC(), senderIP, targetMAC, targetIP);
- Ethernet ethernet = new Ethernet();
- ethernet.setSourceMACAddress(getControllerMAC())
- .setDestinationMACAddress(targetMAC)
- .setEtherType(EtherTypes.ARP.shortValue())
- .setPayload(arp);
+ Ethernet ethernet = createEthernet(getControllerMAC(), targetMAC, arp);
RawPacket destPkt = this.dataPacketService.encodeDataPacket(ethernet);
destPkt.setOutgoingNodeConnector(outPort);
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 {
}
}
- /*
+ /**
* 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) {
return;
}
+ // try to find a matching subnet
Subnet subnet = null;
if (switchManager != null) {
subnet = switchManager.getSubnetByNetworkAddress(dIP);
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 from {}, sending bcast ARP event...",
+ dIP);
+ /*
+ * unknown destination host, initiate bcast ARP request
+ */
+ arpRequestReplyEvent.put(new ARPRequest(dIP, subnet), false);
+ }else{
+
+ // we know about the host, send the packet the right place
+ 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);
+ }
}
public byte[] getControllerMAC() {
retrieveCaches();
}
- @SuppressWarnings({ "unchecked", "deprecation" })
+ @SuppressWarnings({ "unchecked" })
private void retrieveCaches() {
ConcurrentMap<?,?> map;
}
}
- @SuppressWarnings("deprecation")
private void allocateCaches() {
if (clusterContainerService == null){
nonClusterObjectCreate();
return PacketResult.IGNORED;
}
+ private ARP createARP(short opCode, byte[] senderMacAddress, byte[] senderIP, byte[] targetMacAddress, byte[] targetIP) {
+ ARP arp = new ARP();
+ arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
+ arp.setProtocolType(EtherTypes.IPv4.shortValue());
+ arp.setHardwareAddressLength((byte) 6);
+ arp.setProtocolAddressLength((byte) 4);
+ arp.setOpCode(opCode);
+ arp.setSenderHardwareAddress(senderMacAddress) ;
+ arp.setSenderProtocolAddress(senderIP);
+ arp.setTargetHardwareAddress(targetMacAddress);
+ arp.setTargetProtocolAddress(targetIP);
+ return arp;
+ }
+
+ private Ethernet createEthernet(byte[] sourceMAC, byte[] targetMAC, ARP arp) {
+ Ethernet ethernet = new Ethernet();
+ ethernet.setSourceMACAddress(sourceMAC);
+ ethernet.setDestinationMACAddress(targetMAC);
+ ethernet.setEtherType(EtherTypes.ARP.shortValue());
+ ethernet.setPayload(arp);
+ return ethernet;
+ }
+
private void startPeriodicTimer() {
this.periodicTimer = new Timer("ArpHandler Periodic Timer");
this.periodicTimer.scheduleAtFixedRate(new TimerTask() {
- @SuppressWarnings("deprecation")
@Override
public void run() {
Set<InetAddress> targetIPs = countDownTimers.keySet();
HexEncode.bytesToHexString(host.getDataLayerAddressBytes()),
host.getNetworkAddress() });
}
- if (connectionManager.isLocal(host.getnodeconnectorNode())){
+ if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL){
sendARPReply(host.getnodeConnector(),
sourceMAC,
sourceIP,
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());
}
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(),