- 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/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