- Modified IcmpHandler and ArpHandler to check both routerIP and gateway information for all subnets
- Added GenericIpHandler to set a routing rule to any known host for any IPv4 packets
- Modified ArpHandler so that as soon as it receives ARP response, it sets a routing rule to the host
- Use FlowPusher instead of PacketService in ArpHandler
Change-Id: Ie7d72e688a7d19624b5595f344c6f201f58ee9c1
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 fc6c02e..a0b6aa7 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
@@ -8,7 +8,12 @@
package net.onrc.onos.apps.segmentrouting;
+import java.util.ArrayList;
+import java.util.Iterator;
+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;
@@ -21,9 +26,16 @@
import net.onrc.onos.core.topology.MutableTopology;
import net.onrc.onos.core.topology.Port;
import net.onrc.onos.core.topology.Switch;
-import net.onrc.onos.core.util.SwitchPort;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFPacketOut;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.U32;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -95,9 +107,16 @@
srManager.updateArpCache(arp);
if (arp.getOpCode() == ARP.OP_REQUEST) {
-
handleArpRequest(sw, inPort, arp);
}
+ else {
+ byte[] senderMacAddressByte = arp.getSenderHardwareAddress();
+ String targetMacAddressStr = MacAddress.of(senderMacAddressByte).toString();
+ if (targetMacAddressStr.equals(sw.getStringAttribute("routerMac"))) {
+ IPv4Address hostIpAddress = IPv4Address.of(arp.getSenderProtocolAddress());
+ srManager.addRouteToHost(sw,hostIpAddress.getInt(), senderMacAddressByte);
+ }
+ }
}
@@ -113,14 +132,12 @@
*/
private void handleArpRequest(Switch sw, Port inPort, ARP arpRequest) {
- String switchIpAddressSlash = sw.getStringAttribute("routerIp");
+ List<String> subnetGatewayIPs = getSubnetGatewayIps(sw);
String switchMacAddressStr = sw.getStringAttribute("routerMac");
- if (switchIpAddressSlash != null && switchMacAddressStr != null) {
-
- String switchIpAddressStr = switchIpAddressSlash.substring(0, switchIpAddressSlash.indexOf('/'));
- IPv4Address switchIpAddress = IPv4Address.of(switchIpAddressStr);
+ if (!subnetGatewayIPs.isEmpty()) {
IPv4Address targetProtocolAddress = IPv4Address.of(arpRequest.getTargetProtocolAddress());
- if (targetProtocolAddress.equals(switchIpAddress)) {
+ // Do we have to check port also ??
+ if (subnetGatewayIPs.contains(targetProtocolAddress.toString())) {
MACAddress targetMac = MACAddress.valueOf(switchMacAddressStr);
ARP arpReply = new ARP();
@@ -140,14 +157,117 @@
.setSourceMACAddress(targetMac.toBytes())
.setEtherType(Ethernet.TYPE_ARP).setPayload(arpReply);
- packetService.sendPacket(eth, new SwitchPort(sw.getDpid(), inPort.getPortNumber()));
+ sendPacketOut(sw, eth, inPort.getPortNumber().shortValue());
}
}
}
+ /**
+ * Retrieve Gateway IP address of all subnets defined in net config file
+ *
+ * @param sw Switch to retrieve subnet GW IPs for
+ * @return list of GW IP addresses for all subnets
+ */
+ private List<String> getSubnetGatewayIps(Switch sw) {
+ List<String> gatewayIps = new ArrayList<String>();
+ String subnets = sw.getStringAttribute("subnets");
+ try {
+ JSONArray arry = new JSONArray(subnets);
+ for (int i = 0; i < arry.length(); i++) {
+ String subnetIpSlash = (String) arry.getJSONObject(i).get("subnetIp");
+ if (subnetIpSlash != null) {
+ String subnetIp = subnetIpSlash.substring(0, subnetIpSlash.indexOf('/'));
+ gatewayIps.add(subnetIp);
+ }
+ }
+ } catch (JSONException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return gatewayIps;
+ }
+ /**
+ * Send an ARP request
+ *
+ * @param sw Switch
+ * @param targetAddress Target IP address
+ * @param inPort Port to send the ARP request
+ *
+ */
+ public void sendArpRequest(Switch sw, int targetAddressInt, Port inPort) {
+
+ IPv4Address targetAddress = IPv4Address.of(targetAddressInt);
+ String senderMacAddressStr = sw.getStringAttribute("routerMac");
+ String senderIpAddressSlash = sw.getStringAttribute("routerIp");
+ if (senderMacAddressStr == null || senderIpAddressSlash == null)
+ return;
+ String senderIpAddressStr =
+ senderIpAddressSlash.substring(0, senderIpAddressSlash.indexOf('/'));
+ byte[] senderMacAddress = MacAddress.of(senderMacAddressStr).getBytes();
+ byte[] senderIpAddress = IPv4Address.of(senderIpAddressStr).getBytes();
+
+ ARP arpRequest = new ARP();
+ arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET)
+ .setProtocolType(ARP.PROTO_TYPE_IP)
+ .setHardwareAddressLength(
+ (byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
+ .setProtocolAddressLength((byte) IPv4.ADDRESS_LENGTH)
+ .setOpCode(ARP.OP_REQUEST)
+ .setSenderHardwareAddress(senderMacAddress)
+ .setTargetHardwareAddress(MacAddress.NONE.getBytes())
+ .setSenderProtocolAddress(senderIpAddress)
+ .setTargetProtocolAddress(targetAddress.getBytes());
+
+ Ethernet eth = new Ethernet();
+ eth.setDestinationMACAddress(MacAddress.BROADCAST.getBytes())
+ .setSourceMACAddress(senderMacAddress)
+ .setEtherType(Ethernet.TYPE_ARP).setPayload(arpRequest);
+
+ sendPacketOut(sw, eth, (short)-1);
+
+ }
+
+ /**
+ * Send PACKET_OUT packet to switch
+ *
+ * @param sw Switch to send the packet to
+ * @param packet Packet to send
+ * @param switchPort port to send (if -1, broadcast)
+ */
+ private void sendPacketOut(Switch sw, Ethernet packet, short port) {
+
+ IOFSwitch ofSwitch = floodlightProvider.getMasterSwitch(sw.getDpid().value());
+ OFFactory factory = ofSwitch.getFactory();
+
+ List<OFAction> actions = new ArrayList<>();
+
+ if (port > 0) {
+ OFAction outport = factory.actions().output(OFPort.of(port), Short.MAX_VALUE);
+ actions.add(outport);
+ }
+ else {
+ Iterator<Port> iter = sw.getPorts().iterator();
+ while (iter.hasNext()) {
+ Port p = iter.next();
+ int pnum = p.getPortNumber().shortValue();
+ if (U32.of(pnum).compareTo(U32.of(OFPort.MAX.getPortNumber())) < 1) {
+ OFAction outport = factory.actions().output(OFPort.of(p.getNumber().shortValue()),
+ Short.MAX_VALUE);
+ actions.add(outport);
+ }
+ }
+ }
+
+ OFPacketOut po = factory.buildPacketOut()
+ .setData(packet.serialize())
+ .setActions(actions)
+ .build();
+
+ flowPusher.add(sw.getDpid(), po);
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/GenericIpHandler.java b/src/main/java/net/onrc/onos/apps/segmentrouting/GenericIpHandler.java
new file mode 100644
index 0000000..7e6d2ac
--- /dev/null
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/GenericIpHandler.java
@@ -0,0 +1,202 @@
+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 GenericIpHandler implements IPacketListener {
+
+ private MutableTopology mutableTopology;
+ private ITopologyService topologyService;
+ private IFloodlightProviderService floodlightProvider;
+ private IFlowPusherService flowPusher;
+ private IPacketService packetService;
+ private SegmentRoutingManager srManager;
+
+ private static final Logger log = LoggerFactory
+ .getLogger(GenericIpHandler.class);
+
+ 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 GenericIpHandler(FloodlightModuleContext context, SegmentRoutingManager sr) {
+ this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+ this.topologyService = context.getServiceImpl(ITopologyService.class);
+ this.mutableTopology = topologyService.getTopology();
+ this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
+ this.packetService = context.getServiceImpl(IPacketService.class);
+ this.srManager = sr;
+
+ packetService.registerPacketListener(this);
+
+ }
+
+ @Override
+ public void receive(Switch sw, Port inPort, Ethernet payload) {
+ // TODO Auto-generated method stub
+ if (payload.getEtherType() == Ethernet.TYPE_IPV4) {
+
+ IPv4 ipv4 = (IPv4)payload.getPayload();
+ int destinationAddress = ipv4.getDestinationAddress();
+
+ // Check if the destination is any host known to TopologyService
+ for (net.onrc.onos.core.topology.Host host: mutableTopology.getHosts()) {
+ IPv4Address hostIpAddress = IPv4Address.of(host.getIpAddress());
+ if (hostIpAddress != null && hostIpAddress.getInt() == destinationAddress) {
+ byte[] destinationMacAddress = host.getMacAddress().toBytes();
+ addRouteToHost(sw, destinationAddress, destinationMacAddress);
+ return;
+ }
+ }
+
+ // Check if the destination is within subnets of the swtich
+ if (isWithinSubnets(sw, IPv4Address.of(destinationAddress).toString())) {
+ srManager.sendArpRequest(sw, destinationAddress, inPort);
+ }
+ }
+ }
+
+ private boolean isWithinSubnets(Switch sw, String ipAddress) {
+
+ return true;
+ }
+
+
+ /**
+ * Add routing rules to forward packets to known hosts
+ *
+ * @param sw Switch
+ * @param hostIp Host IP address to forwards packets to
+ */
+ public void addRouteToHost(Switch sw, int destinationAddress, byte[] destinationMacAddress) {
+
+ IOFSwitch ofSwitch = floodlightProvider.getMasterSwitch(sw.getDpid().value());
+ OFFactory factory = ofSwitch.getFactory();
+
+
+ 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/IcmpHandler.java b/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
index 8e58eac..b548e18 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
@@ -6,7 +6,6 @@
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;
@@ -28,16 +27,11 @@
import org.projectfloodlight.openflow.protocol.OFPacketOut;
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.OFOxmInPort;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4DstMasked;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsLabel;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanVid;
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.OFVlanVidMatch;
@@ -99,34 +93,53 @@
if (ipv4.getProtocol() == IPv4.PROTOCOL_ICMP) {
int destinationAddress = ipv4.getDestinationAddress();
+ String destAddressStr = IPv4Address.of(destinationAddress).toString();
// Check if it is ICMP request to the switch
String switchIpAddressSlash = sw.getStringAttribute("routerIp");
if (switchIpAddressSlash != null) {
- String switchIpAddressStr = switchIpAddressSlash.substring(0, switchIpAddressSlash.indexOf('/'));
+ String switchIpAddressStr
+ = switchIpAddressSlash.substring(0, switchIpAddressSlash.indexOf('/'));
IPv4Address switchIpAddress = IPv4Address.of(switchIpAddressStr);
-
+ List<String> gatewayIps = getSubnetGatewayIps(sw);
if (((ICMP)ipv4.getPayload()).getIcmpType() == ICMP_TYPE_ECHO &&
- destinationAddress == switchIpAddress.getInt()) {
+ (destinationAddress == switchIpAddress.getInt() ||
+ gatewayIps.contains(destAddressStr))) {
sendICMPResponse(sw, inPort, payload);
return;
}
}
-
-
- // Check if the destination is any host known to TopologyService
- for (net.onrc.onos.core.topology.Host host: mutableTopology.getHosts()) {
- IPv4Address hostIpAddress = IPv4Address.of(host.getIpAddress());
- if (hostIpAddress != null && hostIpAddress.getInt() == destinationAddress) {
- byte[] destinationMacAddress = host.getMacAddress().toBytes();
- addRouteToHost(sw, destinationAddress, destinationMacAddress);
- return;
- }
- }
}
}
+ }
+ /**
+ * Retrieve Gateway IP address of all subnets defined in net config file
+ *
+ * @param sw Switch to retrieve subnet GW IPs for
+ * @return list of GW IP addresses for all subnets
+ */
+ private List<String> getSubnetGatewayIps(Switch sw) {
+
+ List<String> gatewayIps = new ArrayList<String>();
+
+ String subnets = sw.getStringAttribute("subnets");
+ try {
+ JSONArray arry = new JSONArray(subnets);
+ for (int i = 0; i < arry.length(); i++) {
+ String subnetIpSlash = (String) arry.getJSONObject(i).get("subnetIp");
+ if (subnetIpSlash != null) {
+ String subnetIp = subnetIpSlash.substring(0, subnetIpSlash.indexOf('/'));
+ gatewayIps.add(subnetIp);
+ }
+ }
+ } catch (JSONException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ return gatewayIps;
}
@@ -273,99 +286,7 @@
return mplsLabel;
}
- /**
- * 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, int destinationAddress, byte[] destinationMacAddress) {
- IOFSwitch ofSwitch = floodlightProvider.getMasterSwitch(sw.getDpid().value());
- OFFactory factory = ofSwitch.getFactory();
-
-
- 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);
-
- }
/**
* Add a new rule to VLAN table to forward packets from any port to the next table
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
index 457a626..eedc1c9 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
@@ -24,6 +24,7 @@
import net.onrc.onos.core.topology.ITopologyService;
import net.onrc.onos.core.topology.LinkData;
import net.onrc.onos.core.topology.MutableTopology;
+import net.onrc.onos.core.topology.Port;
import net.onrc.onos.core.topology.Switch;
import net.onrc.onos.core.topology.TopologyEvents;
import net.onrc.onos.core.util.Dpid;
@@ -41,6 +42,8 @@
private MutableTopology mutableTopology;
private List<ArpEntry> arpEntries;
+ private ArpHandler arpHandler;
+ private GenericIpHandler ipHandler;
@Override
public Collection<Class<? extends IFloodlightService>> getModuleServices() {
@@ -72,8 +75,9 @@
@Override
public void init(FloodlightModuleContext context) throws FloodlightModuleException {
- ArpHandler aprHandler = new ArpHandler(context, this);
+ arpHandler = new ArpHandler(context, this);
IcmpHandler icmpHandler = new IcmpHandler(context, this);
+ ipHandler = new GenericIpHandler(context, this);
arpEntries = new ArrayList<ArpEntry>();
topologyService = context.getServiceImpl(ITopologyService.class);
mutableTopology = topologyService.getTopology();
@@ -132,6 +136,16 @@
return null;
}
+ /**
+ * Send an ARP request via ArpHandler
+ * @param destinationAddress
+ * @param sw
+ * @param inPort
+ *
+ */
+ public void sendArpRequest(Switch sw, int destinationAddress, Port inPort) {
+ arpHandler.sendArpRequest(sw, destinationAddress, inPort);
+ }
/**
* Temporary class to to keep ARP entry
@@ -146,8 +160,8 @@
this.targetMacAddress = macAddress;
this.targetIpAddress = ipAddress;
}
-
}
+
/**
* Topology events that have been generated.
*
@@ -230,25 +244,70 @@
*/
private void setSegmentRoutingRule(Switch sw, ArrayList<Path> paths) {
- log.debug("Set routing infor for {} to .. ", sw.getDpid());
+ log.debug("Set routing info for {} to .. ", sw.getDpid());
for (Path path: paths) {
for (Object obj : path.toArray()) {
LinkData link = (LinkData)obj;
- log.debug(" ---- Set a rule in {} [Forward to {}] " , link.getSrc(), link.getDst().getDpid());
+ String destMplsLabel = getMplslabel(link.getDst().getDpid());
+ String targetMplsLabel = getMplslabel(sw.getDpid());
+ if (destMplsLabel != null && targetMplsLabel != null)
+ setTransitRouterRule(targetMplsLabel, destMplsLabel);
+ }
+ }
+ }
+
+ /**
+ * Get MPLS label reading the config file
+ *
+ * @param dipid DPID of the switch
+ * @return MPLS label for the switch
+ */
+
+ private String getMplslabel(Dpid dpid) {
+
+ String mplsLabel = null;
+ for (Switch sw: mutableTopology.getSwitches()) {
+ String dpidStr = sw.getStringAttribute("nodeDpid");
+ if (dpid.toString().endsWith(dpidStr)) {
+ mplsLabel = sw.getStringAttribute("nodeSid");
+ break;
}
}
+ return mplsLabel;
}
/**
+ * Test function
+ *
+ *
+ */
+ private void setTransitRouterRule(String targetMplsLabel, String destMplsLabel) {
+
+ log.debug("Match: MPLS label {}, action: forward to {}", targetMplsLabel, destMplsLabel);
+
+ }
+
+ /**
+ * Test function
+ *
+ */
+ private void setBorderRouterRule() {
+
+
+
+ }
+
+
+
+ /**
* The function checks if given IP matches to the given subnet mask
*
* @param addr - subnet address to match
* @param addr1 - IP address to check
* @return true if the IP address matches to the subnet, otherwise false
*/
-
public boolean netMatch(String addr, String addr1){ //addr is subnet address and addr1 is ip address. Function will return true, if addr1 is within addr(subnet)
String[] parts = addr.split("/");
@@ -289,4 +348,9 @@
return false;
}
}
+
+ public void addRouteToHost(Switch sw, int hostIpAddress, byte[] hostMacAddress) {
+ ipHandler.addRouteToHost(sw, hostIpAddress, hostMacAddress);
+
+ }
}