1. Added SegmentRoutingManager so that it can spawn any required objects such as ArpHandler or IcmpHandler
2. Added ArpHandler.java so that it handles any ICMP request for any known host
Change-Id: Ifd93318dc4c67fde2fce2fde04fa9df33d231e41
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java b/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
index c98bde8..9f0fa86 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
@@ -11,25 +11,13 @@
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import net.floodlightcontroller.core.FloodlightContext;
import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.api.packet.IPacketListener;
import net.onrc.onos.api.packet.IPacketService;
import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
-import net.onrc.onos.core.main.config.IConfigInfoService;
import net.onrc.onos.core.packet.ARP;
import net.onrc.onos.core.packet.Ethernet;
import net.onrc.onos.core.packet.IPv4;
@@ -39,23 +27,7 @@
import net.onrc.onos.core.topology.Switch;
import net.onrc.onos.core.util.SwitchPort;
-import org.projectfloodlight.openflow.protocol.OFFactory;
-import org.projectfloodlight.openflow.protocol.OFMatchV3;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFOxmList;
-import org.projectfloodlight.openflow.protocol.OFType;
-import org.projectfloodlight.openflow.protocol.action.OFAction;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthDst;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4DstMasked;
-import org.projectfloodlight.openflow.types.EthType;
import org.projectfloodlight.openflow.types.IPv4Address;
-import org.projectfloodlight.openflow.types.MacAddress;
-import org.projectfloodlight.openflow.types.OFBufferId;
-import org.projectfloodlight.openflow.types.OFPort;
-import org.projectfloodlight.openflow.types.TableId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -68,7 +40,7 @@
* hosts to the controllers.
* TODO: need to check the network config file for all hosts and packets
*/
-public class ArpHandler implements IFloodlightModule, IOFMessageListener, IPacketListener {
+public class ArpHandler implements IPacketListener {
private static final Logger log = LoggerFactory
.getLogger(ArpHandler.class);
@@ -78,7 +50,8 @@
private IFlowPusherService flowPusher;
private ITopologyService topologyService;
private MutableTopology mutableTopology;
- private List<ArpEntry> arpEntries;
+ //private List<ArpEntry> arpEntries;
+ private SegmentRoutingManager srManager;
private static final short IDLE_TIMEOUT = 0;
private static final short HARD_TIMEOUT = 0;
@@ -97,83 +70,33 @@
private static final short MIN_PRIORITY = 0x0;
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- return null;
- }
+ /*
+ * Default Constructor
+ */
+ public ArpHandler(FloodlightModuleContext context, SegmentRoutingManager segmentRoutingManager) {
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFloodlightProviderService.class);
- l.add(IConfigInfoService.class);
- l.add(ITopologyService.class);
- l.add(IPacketService.class);
- l.add(IFlowPusherService.class);
- l.add(ITopologyService.class);
-
- return l;
- }
-
- @Override
- public void init(FloodlightModuleContext context) throws FloodlightModuleException {
this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
this.packetService = context.getServiceImpl(IPacketService.class);
this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
this.topologyService = context.getServiceImpl(ITopologyService.class);
+ this.srManager = segmentRoutingManager;
+ this.mutableTopology = topologyService.getTopology();
+
+ packetService.registerPacketListener(this);
+ //arpEntries = new ArrayList<ArpEntry>();
Log.debug("Arp Handler is initialized");
}
@Override
- public String getName() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public boolean isCallbackOrderingPrereq(OFType type, String name) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean isCallbackOrderingPostreq(OFType type, String name) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public net.floodlightcontroller.core.IListener.Command receive(IOFSwitch sw,
- OFMessage msg, FloodlightContext cntx) {
-
- return Command.CONTINUE;
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
-
- packetService.registerPacketListener(this);
- floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- mutableTopology = topologyService.getTopology();
- arpEntries = new ArrayList<ArpEntry>();
- }
-
- @Override
public void receive(Switch sw, Port inPort, Ethernet payload) {
log.debug("Received a packet {} from sw {} ", payload.toString(), sw.getDpid());
if (payload.getEtherType() == Ethernet.TYPE_ARP) {
ARP arp = (ARP)payload.getPayload();
- updateArpCache(arp);
+ srManager.updateArpCache(arp);
if (arp.getOpCode() == ARP.OP_REQUEST) {
@@ -181,130 +104,9 @@
}
}
- else if (payload.getEtherType() == Ethernet.TYPE_IPV4) {
-
- IPv4 ipv4 = (IPv4)payload.getPayload();
- if (ipv4.getProtocol() == IPv4.PROTOCOL_ICMP) {
-
- addRouteToHost(sw, ipv4);
-
- }
-
- }
}
- /**
- * Add routing rules to forward packets to known hosts
- *
- * @param sw Switch
- * @param hostIp Host IP address to forwards packets to
- */
- private void addRouteToHost(Switch sw, IPv4 hostIp) {
-
-
- IOFSwitch ofSwitch = floodlightProvider.getMasterSwitch(sw.getDpid().value());
- OFFactory factory = ofSwitch.getFactory();
- int destinationAddress = hostIp.getDestinationAddress();
- // Check APR entries
- byte[] destinationMacAddress = getMacAddressFromIpAddress(destinationAddress);
-
- // Check TopologyService
- /*
- for (Host host: mutableTopology.getHosts()) {
- IPv4Address hostIpAddress = IPv4Address.of(host.getIpAddress());
- if (hostIpAddress != null && hostIpAddress.getInt() == destinationAddress) {
- destinationMacAddress = host.getMacAddress().toBytes();
- }
- }
- */
-
- // If MAC address is not known to the host, just return
- if (destinationMacAddress == null)
- return;
-
- OFOxmEthType ethTypeIp = factory.oxms()
- .ethType(EthType.IPv4);
- OFOxmIpv4DstMasked ipPrefix = factory.oxms()
- .ipv4DstMasked(
- IPv4Address.of(destinationAddress),
- IPv4Address.NO_MASK); // host addr should be /32
- OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
- OFMatchV3 match = factory.buildMatchV3()
- .setOxmList(oxmListSlash32).build();
- OFAction setDmac = null;
- OFOxmEthDst dmac = factory.oxms()
- .ethDst(MacAddress.of(destinationMacAddress));
- setDmac = factory.actions().buildSetField()
- .setField(dmac).build();
-
- OFAction decTtl = factory.actions().decNwTtl();
-
- // Set the source MAC address with the switch MAC address
- String switchMacAddress = sw.getStringAttribute("routerMac");
- OFOxmEthSrc srcAddr = factory.oxms().ethSrc(MacAddress.of(switchMacAddress));
- OFAction setSA = factory.actions().buildSetField()
- .setField(srcAddr).build();
-
- List<OFAction> actionList = new ArrayList<OFAction>();
- actionList.add(setDmac);
- actionList.add(decTtl);
- actionList.add(setSA);
-
-
- /* TODO : need to check the config file for all packets
- String subnets = sw.getStringAttribute("subnets");
- try {
- JSONArray arry = new JSONArray(subnets);
- for (int i = 0; i < arry.length(); i++) {
- String subnetIp = (String) arry.getJSONObject(i).get("subnetIp");
- int portNo = (int) arry.getJSONObject(i).get("portNo");
-
- if (netMatch(subnetIp, IPv4Address.of(hostIp.getDestinationAddress()).toString())) {
- OFAction out = factory.actions().buildOutput()
- .setPort(OFPort.of(portNo)).build();
- actionList.add(out);
- }
- }
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- */
-
- // Set output port
- net.onrc.onos.core.topology.Host host = mutableTopology.getHostByMac(MACAddress.valueOf(destinationMacAddress));
- if (host != null) {
- for (Port port: host.getAttachmentPoints()) {
- OFAction out = factory.actions().buildOutput()
- .setPort(OFPort.of(port.getPortNumber().shortValue())).build();
- actionList.add(out);
- }
- }
-
- OFInstruction writeInstr = factory.instructions().buildWriteActions()
- .setActions(actionList).build();
-
- List<OFInstruction> instructions = new ArrayList<OFInstruction>();
- instructions.add(writeInstr);
-
- OFMessage myIpEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_IPv4_UNICAST))
- .setMatch(match)
- .setInstructions(instructions)
- .setPriority(MAX_PRIORITY)
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- //.setXid(getNextTransactionId())
- .build();
-
- log.debug("Sending 'Routing information' OF message to the switch {}.", sw.getDpid().toString());
-
- flowPusher.add(sw.getDpid(), myIpEntry);
-
-
- }
/**
* Send an ARP response for the ARP request to the known switches
@@ -348,68 +150,6 @@
}
/**
- * Update ARP Cache using ARP packets
- * It is used to set destination MAC address to forward packets to known hosts.
- * But, it will be replace with Host information of Topology service later.
- *
- * @param arp APR packets to use for updating ARP entries
- */
- private void updateArpCache(ARP arp) {
-
- ArpEntry arpEntry = new ArpEntry(arp.getSenderHardwareAddress(), arp.getSenderProtocolAddress());
- // TODO: Need to check the duplication
- arpEntries.add(arpEntry);
- }
-
- /**
- * Temporary class to to keep ARP entry
- *
- */
-
- private class ArpEntry {
-
- byte[] targetMacAddress;
- byte[] targetIpAddress;
-
- private ArpEntry(byte[] macAddress, byte[] ipAddress) {
- this.targetMacAddress = macAddress;
- this.targetIpAddress = ipAddress;
- }
-
- }
-
- /**
- * Get MAC address to known hosts
- *
- * @param destinationAddress IP address to get MAC address
- * @return MAC Address to given IP address
- */
- private byte[] getMacAddressFromIpAddress(int destinationAddress) {
-
- // Can't we get the host IP address from the TopologyService ??
-
- Iterator<ArpEntry> iterator = arpEntries.iterator();
-
- IPv4Address ipAddress = IPv4Address.of(destinationAddress);
- byte[] ipAddressInByte = ipAddress.getBytes();
-
- while (iterator.hasNext() ) {
- ArpEntry arpEntry = iterator.next();
- byte[] address = arpEntry.targetIpAddress;
-
- IPv4Address a = IPv4Address.of(address);
- IPv4Address b = IPv4Address.of(ipAddressInByte);
-
- if ( a.equals(b)) {
- log.debug("Found an arp entry");
- return arpEntry.targetMacAddress;
- }
- }
-
- return null;
- }
-
- /**
* The function checks if given IP matches to the given subnet mask
*
* @param addr - subnet address to match
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java b/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
new file mode 100644
index 0000000..5126958
--- /dev/null
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
@@ -0,0 +1,208 @@
+package net.onrc.onos.apps.segmentrouting;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.api.packet.IPacketListener;
+import net.onrc.onos.api.packet.IPacketService;
+import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
+import net.onrc.onos.core.packet.Ethernet;
+import net.onrc.onos.core.packet.IPv4;
+import net.onrc.onos.core.topology.ITopologyService;
+import net.onrc.onos.core.topology.MutableTopology;
+import net.onrc.onos.core.topology.Port;
+import net.onrc.onos.core.topology.Switch;
+
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFMatchV3;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFOxmList;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthDst;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4DstMasked;
+import org.projectfloodlight.openflow.types.EthType;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.TableId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IcmpHandler implements IPacketListener {
+
+ private SegmentRoutingManager srManager;
+ private IFloodlightProviderService floodlightProvider;
+ private MutableTopology mutableTopology;
+ private IPacketService packetService;
+ private ITopologyService topologyService;
+ private static final Logger log = LoggerFactory
+ .getLogger(ArpHandler.class);
+
+ private IFlowPusherService flowPusher;
+
+ private static final int TABLE_VLAN = 0;
+ private static final int TABLE_TMAC = 1;
+ private static final int TABLE_IPv4_UNICAST = 2;
+ private static final int TABLE_MPLS = 3;
+ private static final int TABLE_META = 4;
+ private static final int TABLE_ACL = 5;
+
+ private static final short MAX_PRIORITY = (short) 0xffff;
+ private static final short SLASH_24_PRIORITY = (short) 0xfff0;
+ private static final short SLASH_16_PRIORITY = (short) 0xff00;
+ private static final short SLASH_8_PRIORITY = (short) 0xf000;
+ private static final short MIN_PRIORITY = 0x0;
+
+
+ public IcmpHandler(FloodlightModuleContext context, SegmentRoutingManager manager) {
+
+ this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+ this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
+ this.packetService = context.getServiceImpl(IPacketService.class);
+ this.topologyService = context.getServiceImpl(ITopologyService.class);
+ this.mutableTopology = topologyService.getTopology();
+
+ this.srManager = manager;
+
+ packetService.registerPacketListener(this);
+
+ }
+
+ @Override
+ public void receive(Switch sw, Port inPort, Ethernet payload) {
+
+ if (payload.getEtherType() == Ethernet.TYPE_IPV4) {
+
+ IPv4 ipv4 = (IPv4)payload.getPayload();
+ if (ipv4.getProtocol() == IPv4.PROTOCOL_ICMP) {
+
+ addRouteToHost(sw, ipv4);
+
+ }
+
+ }
+
+ }
+
+ /**
+ * Add routing rules to forward packets to known hosts
+ *
+ * @param sw Switch
+ * @param hostIp Host IP address to forwards packets to
+ */
+ private void addRouteToHost(Switch sw, IPv4 hostIp) {
+
+ IOFSwitch ofSwitch = floodlightProvider.getMasterSwitch(sw.getDpid().value());
+ OFFactory factory = ofSwitch.getFactory();
+ int destinationAddress = hostIp.getDestinationAddress();
+ // Check APR entries
+ byte[] destinationMacAddress = null;;
+
+ // srManager.getMacAddressFromIpAddress(destinationAddress);
+
+ // Check TopologyService
+
+ for (net.onrc.onos.core.topology.Host host: mutableTopology.getHosts()) {
+ IPv4Address hostIpAddress = IPv4Address.of(host.getIpAddress());
+ if (hostIpAddress != null && hostIpAddress.getInt() == destinationAddress) {
+ destinationMacAddress = host.getMacAddress().toBytes();
+ }
+ }
+
+
+ // If MAC address is not known to the host, just return
+ if (destinationMacAddress == null)
+ return;
+
+ OFOxmEthType ethTypeIp = factory.oxms()
+ .ethType(EthType.IPv4);
+ OFOxmIpv4DstMasked ipPrefix = factory.oxms()
+ .ipv4DstMasked(
+ IPv4Address.of(destinationAddress),
+ IPv4Address.NO_MASK); // host addr should be /32
+ OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
+ OFMatchV3 match = factory.buildMatchV3()
+ .setOxmList(oxmListSlash32).build();
+ OFAction setDmac = null;
+ OFOxmEthDst dmac = factory.oxms()
+ .ethDst(MacAddress.of(destinationMacAddress));
+ setDmac = factory.actions().buildSetField()
+ .setField(dmac).build();
+
+ OFAction decTtl = factory.actions().decNwTtl();
+
+ // Set the source MAC address with the switch MAC address
+ String switchMacAddress = sw.getStringAttribute("routerMac");
+ OFOxmEthSrc srcAddr = factory.oxms().ethSrc(MacAddress.of(switchMacAddress));
+ OFAction setSA = factory.actions().buildSetField()
+ .setField(srcAddr).build();
+
+ List<OFAction> actionList = new ArrayList<OFAction>();
+ actionList.add(setDmac);
+ actionList.add(decTtl);
+ actionList.add(setSA);
+
+
+ /* TODO : need to check the config file for all packets
+ String subnets = sw.getStringAttribute("subnets");
+ try {
+ JSONArray arry = new JSONArray(subnets);
+ for (int i = 0; i < arry.length(); i++) {
+ String subnetIp = (String) arry.getJSONObject(i).get("subnetIp");
+ int portNo = (int) arry.getJSONObject(i).get("portNo");
+
+ if (netMatch(subnetIp, IPv4Address.of(hostIp.getDestinationAddress()).toString())) {
+ OFAction out = factory.actions().buildOutput()
+ .setPort(OFPort.of(portNo)).build();
+ actionList.add(out);
+ }
+ }
+ } catch (JSONException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ */
+
+ // Set output port
+ net.onrc.onos.core.topology.Host host = mutableTopology.getHostByMac(MACAddress.valueOf(destinationMacAddress));
+ if (host != null) {
+ for (Port port: host.getAttachmentPoints()) {
+ OFAction out = factory.actions().buildOutput()
+ .setPort(OFPort.of(port.getPortNumber().shortValue())).build();
+ actionList.add(out);
+ }
+ }
+
+ OFInstruction writeInstr = factory.instructions().buildWriteActions()
+ .setActions(actionList).build();
+
+ List<OFInstruction> instructions = new ArrayList<OFInstruction>();
+ instructions.add(writeInstr);
+
+ OFMessage myIpEntry = factory.buildFlowAdd()
+ .setTableId(TableId.of(TABLE_IPv4_UNICAST))
+ .setMatch(match)
+ .setInstructions(instructions)
+ .setPriority(MAX_PRIORITY)
+ .setBufferId(OFBufferId.NO_BUFFER)
+ .setIdleTimeout(0)
+ .setHardTimeout(0)
+ //.setXid(getNextTransactionId())
+ .build();
+
+ log.debug("Sending 'Routing information' OF message to the switch {}.", sw.getDpid().toString());
+
+ flowPusher.add(sw.getDpid(), myIpEntry);
+
+
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
new file mode 100644
index 0000000..aa6fbb8
--- /dev/null
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
@@ -0,0 +1,135 @@
+package net.onrc.onos.apps.segmentrouting;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.onrc.onos.api.packet.IPacketService;
+import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
+import net.onrc.onos.core.main.config.IConfigInfoService;
+import net.onrc.onos.core.packet.ARP;
+import net.onrc.onos.core.topology.ITopologyService;
+
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SegmentRoutingManager implements IFloodlightModule {
+
+ private static final Logger log = LoggerFactory
+ .getLogger(SegmentRoutingManager.class);
+
+ private List<ArpEntry> arpEntries;
+
+ @Override
+ public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+ Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
+
+ l.add(IFloodlightProviderService.class);
+ l.add(IConfigInfoService.class);
+ l.add(ITopologyService.class);
+ l.add(IPacketService.class);
+ l.add(IFlowPusherService.class);
+ l.add(ITopologyService.class);
+
+ return l;
+
+ }
+
+ @Override
+ public void init(FloodlightModuleContext context) throws FloodlightModuleException {
+
+ ArpHandler aprHandler = new ArpHandler(context, this);
+ IcmpHandler icmpHandler = new IcmpHandler(context, this);
+ arpEntries = new ArrayList<ArpEntry>();
+
+ }
+
+ @Override
+ public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * Update ARP Cache using ARP packets
+ * It is used to set destination MAC address to forward packets to known hosts.
+ * But, it will be replace with Host information of Topology service later.
+ *
+ * @param arp APR packets to use for updating ARP entries
+ */
+ public void updateArpCache(ARP arp) {
+
+ ArpEntry arpEntry = new ArpEntry(arp.getSenderHardwareAddress(), arp.getSenderProtocolAddress());
+ // TODO: Need to check the duplication
+ arpEntries.add(arpEntry);
+ }
+
+ /**
+ * Get MAC address to known hosts
+ *
+ * @param destinationAddress IP address to get MAC address
+ * @return MAC Address to given IP address
+ */
+ public byte[] getMacAddressFromIpAddress(int destinationAddress) {
+
+ // Can't we get the host IP address from the TopologyService ??
+
+ Iterator<ArpEntry> iterator = arpEntries.iterator();
+
+ IPv4Address ipAddress = IPv4Address.of(destinationAddress);
+ byte[] ipAddressInByte = ipAddress.getBytes();
+
+ while (iterator.hasNext() ) {
+ ArpEntry arpEntry = iterator.next();
+ byte[] address = arpEntry.targetIpAddress;
+
+ IPv4Address a = IPv4Address.of(address);
+ IPv4Address b = IPv4Address.of(ipAddressInByte);
+
+ if ( a.equals(b)) {
+ log.debug("Found an arp entry");
+ return arpEntry.targetMacAddress;
+ }
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Temporary class to to keep ARP entry
+ *
+ */
+ private class ArpEntry {
+
+ byte[] targetMacAddress;
+ byte[] targetIpAddress;
+
+ private ArpEntry(byte[] macAddress, byte[] ipAddress) {
+ this.targetMacAddress = macAddress;
+ this.targetIpAddress = ipAddress;
+ }
+
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/core/hostmanager/Host.java b/src/main/java/net/onrc/onos/core/hostmanager/Host.java
index 45452e0..0f20fac 100644
--- a/src/main/java/net/onrc/onos/core/hostmanager/Host.java
+++ b/src/main/java/net/onrc/onos/core/hostmanager/Host.java
@@ -48,6 +48,12 @@
private MACAddress macAddress;
/**
+ * The IP address associated with this entity.
+ */
+ private int ipAddress;
+
+
+ /**
* The VLAN tag on this entity, or null if untagged.
*/
private Short vlan;
@@ -81,14 +87,16 @@
* Create a new host and its information.
*
* @param macAddress mac address of this host
+ * @param ipAddress ip address of this host (if any)
* @param vlan vlan ID of this host
* @param switchDPID switch DPID where the host is attached
* @param switchPort port number where the host is attached
* @param lastSeenTimestamp last packet-in time of this host
*/
- public Host(MACAddress macAddress, Short vlan, Long switchDPID,
+ public Host(MACAddress macAddress, int ipAddress, Short vlan, Long switchDPID,
Long switchPort, Date lastSeenTimestamp) {
this.macAddress = macAddress;
+ this.ipAddress = ipAddress;
this.vlan = vlan;
this.switchDPID = switchDPID;
this.switchPort = switchPort;
@@ -107,6 +115,10 @@
return macAddress;
}
+ public int getIpAddress() {
+ return ipAddress;
+ }
+
public Short getVlan() {
return vlan;
}
@@ -135,6 +147,7 @@
final int prime = 31;
hashCode = 1;
hashCode = prime * hashCode + (int) (macAddress.toLong() ^ (macAddress.toLong() >>> 32));
+ hashCode = prime * hashCode + ipAddress;
hashCode = prime * hashCode + ((switchDPID == null) ? 0 : switchDPID.hashCode());
hashCode = prime * hashCode + ((switchPort == null) ? 0 : switchPort.hashCode());
hashCode = prime * hashCode + ((vlan == null) ? 0 : vlan.hashCode());
@@ -159,6 +172,9 @@
if (!Objects.equals(macAddress, other.macAddress)) {
return false;
}
+ if (!Objects.equals(ipAddress, other.ipAddress)) {
+ return false;
+ }
if (!Objects.equals(switchDPID, other.switchDPID)) {
return false;
}
@@ -176,6 +192,8 @@
StringBuilder builder = new StringBuilder();
builder.append("Host [macAddress=");
builder.append(macAddress.toString());
+ builder.append(", ipAddressn=");
+ builder.append(ipAddress);
builder.append(", vlan=");
builder.append(vlan);
builder.append(", switchDPID=");
diff --git a/src/main/java/net/onrc/onos/core/hostmanager/HostManager.java b/src/main/java/net/onrc/onos/core/hostmanager/HostManager.java
index 155c3cf..e555ab5 100644
--- a/src/main/java/net/onrc/onos/core/hostmanager/HostManager.java
+++ b/src/main/java/net/onrc/onos/core/hostmanager/HostManager.java
@@ -23,10 +23,12 @@
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.packet.ARP;
import net.onrc.onos.core.packet.Ethernet;
+import net.onrc.onos.core.packet.IPv4;
import net.onrc.onos.core.topology.ITopologyService;
-import net.onrc.onos.core.topology.Port;
import net.onrc.onos.core.topology.MutableTopology;
+import net.onrc.onos.core.topology.Port;
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.PortNumber;
import net.onrc.onos.core.util.PortNumberUtils;
@@ -34,6 +36,7 @@
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPacketIn;
import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.types.IPv4Address;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -214,14 +217,26 @@
protected Host getSourceHostFromPacket(Ethernet eth,
long swdpid, long port) {
MACAddress sourceMac = eth.getSourceMAC();
+ int sourceIp = 0;
+
+
+ if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
+ IPv4 ipv4 = (IPv4)eth.getPayload();
+ sourceIp = ipv4.getSourceAddress();
+ }
+ else if (eth.getEtherType() == Ethernet.TYPE_ARP) {
+ ARP arp = (ARP)eth.getPayload();
+ sourceIp = IPv4Address.of(arp.getSenderProtocolAddress()).getInt();
+ }
// Ignore broadcast/multicast source
- if (sourceMac.isBroadcast() || sourceMac.isBroadcast()) {
+ if (sourceMac.isBroadcast() || sourceMac.isMulticast()) {
return null;
}
short vlan = eth.getVlanID();
return new Host(sourceMac,
+ sourceIp,
((vlan >= 0) ? vlan : null),
swdpid,
port,
@@ -287,6 +302,7 @@
for (Port switchPort : host.getAttachmentPoints()) {
// We don't handle vlan now and multiple attachment points.
deleteHost = new Host(host.getMacAddress(),
+ host.getIpAddress(),
null,
switchPort.getDpid().value(),
switchPort.getNumber().value(),
diff --git a/src/main/java/net/onrc/onos/core/topology/BaseTopologyAdaptor.java b/src/main/java/net/onrc/onos/core/topology/BaseTopologyAdaptor.java
index 274c7ed..63ff94e 100644
--- a/src/main/java/net/onrc/onos/core/topology/BaseTopologyAdaptor.java
+++ b/src/main/java/net/onrc/onos/core/topology/BaseTopologyAdaptor.java
@@ -261,7 +261,7 @@
}
List<Host> list = new ArrayList<>(hosts.size());
for (HostData elm : hosts) {
- list.add(new HostImpl(internalTopology, elm.getMac()));
+ list.add(new HostImpl(internalTopology, elm.getMac(), elm.getIp()));
}
return list;
}
diff --git a/src/main/java/net/onrc/onos/core/topology/Host.java b/src/main/java/net/onrc/onos/core/topology/Host.java
index 4e0c2e4..eda41ae 100644
--- a/src/main/java/net/onrc/onos/core/topology/Host.java
+++ b/src/main/java/net/onrc/onos/core/topology/Host.java
@@ -23,6 +23,14 @@
public MACAddress getMacAddress();
/**
+ * Gets the Host IP address.
+ *
+ * @return the Host IP address.
+ */
+ public int getIpAddress();
+
+
+ /**
* Gets the Host attachment points.
* <p/>
* TODO: There is only 1 attachment point right now.
diff --git a/src/main/java/net/onrc/onos/core/topology/HostData.java b/src/main/java/net/onrc/onos/core/topology/HostData.java
index d799113..e790134 100644
--- a/src/main/java/net/onrc/onos/core/topology/HostData.java
+++ b/src/main/java/net/onrc/onos/core/topology/HostData.java
@@ -1,5 +1,7 @@
package net.onrc.onos.core.topology;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
@@ -12,7 +14,6 @@
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.SwitchPort;
-import static com.google.common.base.Preconditions.checkNotNull;
import org.codehaus.jackson.map.annotate.JsonSerialize;
/**
@@ -22,6 +23,7 @@
public class HostData extends TopologyElement<HostData> {
private final MACAddress mac;
+ private final int ip;
private List<SwitchPort> attachmentPoints;
private long lastSeenTime;
@@ -31,6 +33,7 @@
@Deprecated
protected HostData() {
mac = null;
+ ip = 0;
}
/**
@@ -38,8 +41,9 @@
*
* @param mac the MAC address to identify the host
*/
- public HostData(MACAddress mac) {
+ public HostData(MACAddress mac, int ip) {
this.mac = checkNotNull(mac);
+ this.ip = ip;
this.attachmentPoints = new LinkedList<>();
}
@@ -53,6 +57,7 @@
public HostData(HostData original) {
super(original);
this.mac = original.mac;
+ this.ip = original.ip;
this.attachmentPoints = new ArrayList<>(original.attachmentPoints);
this.lastSeenTime = original.lastSeenTime;
}
@@ -67,6 +72,15 @@
}
/**
+ * Gets the host IP address.
+ *
+ * @return the IP address.
+ */
+ public int getIp() {
+ return ip;
+ }
+
+ /**
* Gets the switch attachment points.
*
* @return the switch attachment points
@@ -185,11 +199,12 @@
HostData other = (HostData) o;
// XXX lastSeenTime excluded from Equality condition, is it OK?
return Objects.equals(mac, other.mac) &&
+ ip == other.ip &&
Objects.equals(this.attachmentPoints, other.attachmentPoints);
}
@Override
public String toString() {
- return "[HostData " + mac + " attachmentPoints:" + attachmentPoints + "]";
+ return "[HostData " + mac + "(ip:" + ip + ")" + " attachmentPoints:" + attachmentPoints + "]";
}
}
diff --git a/src/main/java/net/onrc/onos/core/topology/HostImpl.java b/src/main/java/net/onrc/onos/core/topology/HostImpl.java
index e45e015..1023806 100644
--- a/src/main/java/net/onrc/onos/core/topology/HostImpl.java
+++ b/src/main/java/net/onrc/onos/core/topology/HostImpl.java
@@ -1,9 +1,10 @@
package net.onrc.onos.core.topology;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.util.ArrayList;
import java.util.List;
-import static com.google.common.base.Preconditions.checkNotNull;
import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.core.util.SwitchPort;
@@ -13,6 +14,7 @@
public class HostImpl extends TopologyObject implements Host {
private final MACAddress id;
+ private final int ipAddress;
/**
@@ -24,6 +26,20 @@
HostImpl(BaseInternalTopology topology, MACAddress mac) {
super(topology);
this.id = checkNotNull(mac);
+ this.ipAddress = 0;
+ }
+
+ /**
+ * Creates a Host handler object.
+ *
+ * @param topology Topology instance this object belongs to
+ * @param mac MAC address of the host
+ * @param ipv4Address IP address of ths host
+ */
+ HostImpl(BaseInternalTopology topology, MACAddress mac, int ipv4Address) {
+ super(topology);
+ this.id = checkNotNull(mac);
+ this.ipAddress = ipv4Address;
}
@Override
@@ -93,4 +109,14 @@
public AdminStatus getStatus() {
return AdminStatus.ACTIVE;
}
+
+
+ /**
+ * Returns the IP address of the Host
+ */
+ @Override
+ public int getIpAddress() {
+ // TODO Auto-generated method stub
+ return ipAddress;
+ }
}
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java b/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
index 2ceb2d9..9efd911 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
@@ -10,9 +10,9 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.SortedSet;
import java.util.TreeSet;
-import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
@@ -369,7 +369,7 @@
}
List<Host> list = new ArrayList<>(events.size());
for (HostData elm : events) {
- list.add(new HostImpl(this, elm.getMac()));
+ list.add(new HostImpl(this, elm.getMac(), elm.getIp()));
}
return list;
}
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java b/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java
index 5838483..c53ab76 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java
@@ -614,7 +614,7 @@
SwitchPort sp = new SwitchPort(host.getSwitchDPID(), host.getSwitchPort());
List<SwitchPort> spLists = new ArrayList<SwitchPort>();
spLists.add(sp);
- HostData hostData = new HostData(host.getMacAddress());
+ HostData hostData = new HostData(host.getMacAddress(), host.getIpAddress());
hostData.setAttachmentPoints(spLists);
hostData.setLastSeenTime(host.getLastSeenTimestamp().getTime());
// Does not use vlan info now.