Merge branch 'onos-spring' of ssh://gerrit.onlab.us:29418/ONOS into onos-spring
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java b/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
new file mode 100644
index 0000000..c98bde8
--- /dev/null
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
@@ -0,0 +1,464 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Open Networking Laboratory.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ ******************************************************************************/
+
+package net.onrc.onos.apps.segmentrouting;
+
+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;
+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 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;
+
+import com.esotericsoftware.minlog.Log;
+
+/**
+ * Handling ARP requests to switches for Segment Routing.
+ * <p/>
+ * The module is for handling ARP requests to switches. It sends ARP response for any known
+ * hosts to the controllers.
+ * TODO: need to check the network config file for all hosts and packets
+ */
+public class ArpHandler implements IFloodlightModule, IOFMessageListener, IPacketListener {
+
+ private static final Logger log = LoggerFactory
+ .getLogger(ArpHandler.class);
+
+ private IFloodlightProviderService floodlightProvider;
+ private IPacketService packetService;
+ private IFlowPusherService flowPusher;
+ private ITopologyService topologyService;
+ private MutableTopology mutableTopology;
+ private List<ArpEntry> arpEntries;
+
+ private static final short IDLE_TIMEOUT = 0;
+ private static final short HARD_TIMEOUT = 0;
+
+ 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;
+
+
+ @Override
+ public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+ 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 {
+ this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+ this.packetService = context.getServiceImpl(IPacketService.class);
+ this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
+ this.topologyService = context.getServiceImpl(ITopologyService.class);
+
+ 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);
+
+ if (arp.getOpCode() == ARP.OP_REQUEST) {
+
+ handleArpRequest(sw, inPort, arp);
+ }
+
+ }
+ 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
+ *
+ * @param sw Switch
+ * @param inPort port to send ARP response to
+ * @param arpRequest ARP request packet to handle
+ */
+ private void handleArpRequest(Switch sw, Port inPort, ARP arpRequest) {
+
+ String switchIpAddressSlash = sw.getStringAttribute("routerIp");
+ String switchMacAddressStr = sw.getStringAttribute("routerMac");
+ if (switchIpAddressSlash != null && switchMacAddressStr != null) {
+
+ String switchIpAddressStr = switchIpAddressSlash.substring(0, switchIpAddressSlash.indexOf('/'));
+ IPv4Address switchIpAddress = IPv4Address.of(switchIpAddressStr);
+ IPv4Address targetProtocolAddress = IPv4Address.of(arpRequest.getTargetProtocolAddress());
+ if (targetProtocolAddress.equals(switchIpAddress)) {
+ MACAddress targetMac = MACAddress.valueOf(switchMacAddressStr);
+
+ ARP arpReply = new ARP();
+ arpReply.setHardwareType(ARP.HW_TYPE_ETHERNET)
+ .setProtocolType(ARP.PROTO_TYPE_IP)
+ .setHardwareAddressLength(
+ (byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
+ .setProtocolAddressLength((byte) IPv4.ADDRESS_LENGTH)
+ .setOpCode(ARP.OP_REPLY)
+ .setSenderHardwareAddress(targetMac.toBytes())
+ .setSenderProtocolAddress(arpRequest.getTargetProtocolAddress())
+ .setTargetHardwareAddress(arpRequest.getSenderHardwareAddress())
+ .setTargetProtocolAddress(arpRequest.getSenderProtocolAddress());
+
+ Ethernet eth = new Ethernet();
+ eth.setDestinationMACAddress(arpRequest.getSenderHardwareAddress())
+ .setSourceMACAddress(targetMac.toBytes())
+ .setEtherType(Ethernet.TYPE_ARP).setPayload(arpReply);
+
+ packetService.sendPacket(eth, new SwitchPort(sw.getDpid(), inPort.getPortNumber()));
+ }
+ }
+ }
+
+ /**
+ * 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
+ * @param addr1 - IP address to check
+ * @return true if the IP address matches to the subnet, otherwise false
+ */
+
+ public static 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("/");
+ String ip = parts[0];
+ int prefix;
+
+ if (parts.length < 2) {
+ prefix = 0;
+ } else {
+ prefix = Integer.parseInt(parts[1]);
+ }
+
+ Inet4Address a =null;
+ Inet4Address a1 =null;
+ try {
+ a = (Inet4Address) InetAddress.getByName(ip);
+ a1 = (Inet4Address) InetAddress.getByName(addr1);
+ } catch (UnknownHostException e){}
+
+ byte[] b = a.getAddress();
+ int ipInt = ((b[0] & 0xFF) << 24) |
+ ((b[1] & 0xFF) << 16) |
+ ((b[2] & 0xFF) << 8) |
+ ((b[3] & 0xFF) << 0);
+
+ byte[] b1 = a1.getAddress();
+ int ipInt1 = ((b1[0] & 0xFF) << 24) |
+ ((b1[1] & 0xFF) << 16) |
+ ((b1[2] & 0xFF) << 8) |
+ ((b1[3] & 0xFF) << 0);
+
+ int mask = ~((1 << (32 - prefix)) - 1);
+
+ if ((ipInt & mask) == (ipInt1 & mask)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+
+
+
+}
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
index 8d7aecb..24a326b 100644
--- a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
@@ -34,7 +34,6 @@
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.OFOxmMetadataMasked;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsLabel;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanVid;
import org.projectfloodlight.openflow.types.EthType;
@@ -42,7 +41,6 @@
import org.projectfloodlight.openflow.types.MacAddress;
import org.projectfloodlight.openflow.types.OFBufferId;
import org.projectfloodlight.openflow.types.OFGroup;
-import org.projectfloodlight.openflow.types.OFMetadata;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.OFVlanVidMatch;
import org.projectfloodlight.openflow.types.TableId;
@@ -79,7 +77,7 @@
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_IPv4_UNICAST = 2;
private static final int TABLE_MPLS = 3;
private static final int TABLE_META = 4;
private static final int TABLE_ACL = 5;
@@ -125,41 +123,31 @@
if (!usePipeline13) {
// Send packet-in to controller if a packet misses the first table
populateTableMissEntry(0, true, false, false, 0);
- } // else {
- // configureSwitch();
- // }
+ } else {
+ configureSwitch();
+ }
sendBarrier(true);
}
+
@Override
public boolean isDriverHandshakeComplete() {
- if (!startDriverHandshakeCalled) {
+ if (!startDriverHandshakeCalled)
throw new SwitchDriverSubHandshakeNotStarted();
- }
return driverHandshakeComplete.get();
}
@Override
public void processDriverHandshakeMessage(OFMessage m) {
- if (!startDriverHandshakeCalled) {
+ if (!startDriverHandshakeCalled)
throw new SwitchDriverSubHandshakeNotStarted();
- }
- if (driverHandshakeComplete.get()) {
+ if (driverHandshakeComplete.get())
throw new SwitchDriverSubHandshakeCompleted(m);
- }
-
- if (!startDriverHandshakeCalled) {
- throw new SwitchDriverSubHandshakeNotStarted();
- }
- if (driverHandshakeComplete.get()) {
- throw new SwitchDriverSubHandshakeCompleted(m);
- }
switch (m.getType()) {
case BARRIER_REPLY:
- if (m.getXid() == barrierXidToWaitFor) {
+ if (m.getXid() == barrierXidToWaitFor)
driverHandshakeComplete.set(true);
- }
break;
case ERROR:
@@ -254,11 +242,11 @@
private void decodeAsyncGetReply(OFAsyncGetReply rep) {
long frm = rep.getFlowRemovedMaskEqualMaster();
- //long frs = rep.getFlowRemovedMaskSlave();
+ long frs = rep.getFlowRemovedMaskSlave();
long pim = rep.getPacketInMaskEqualMaster();
- //long pis = rep.getPacketInMaskSlave();
+ long pis = rep.getPacketInMaskSlave();
long psm = rep.getPortStatusMaskEqualMaster();
- //long pss = rep.getPortStatusMaskSlave();
+ long pss = rep.getPortStatusMaskSlave();
if (role == Role.MASTER || role == Role.EQUAL) { // should separate
log.info("FRM:{}", HexString.toHexString((frm & TEST_FLOW_REMOVED_MASK)));
@@ -306,7 +294,7 @@
.setPort(p.getPortNo()).build();
OFAction popVlan = factory.actions().popVlan();
List<OFAction> actions = new ArrayList<OFAction>();
- actions.add(popVlan);
+ // actions.add(popVlan);
actions.add(out);
OFBucket bucket = factory.buildBucket()
.setActions(actions).build();
@@ -336,12 +324,10 @@
}
private MacAddress getRouterMacAddr() {
- if (getId() == 0x3) {
+ if (getId() == 0x3)
return MacAddress.of("00:00:07:07:07:80"); // router mac
- }
- if (getId() == 0x1) {
+ if (getId() == 0x1)
return MacAddress.of("00:00:01:01:01:80");
- }
// switch 0x2
return MacAddress.of("00:00:02:02:02:80");
}
@@ -401,15 +387,14 @@
List<OFAction> actions = new ArrayList<OFAction>();
actions.add(decTtl); // decrement the IP TTL/do-checksum/check TTL
// and MTU
- actions.add(setVlan); // set the vlan-id of the exit-port (and
- // l2group)
+ // actions.add(setVlan); // set the vlan-id of the exit-port (and
+ // l2group)
actions.add(setSA); // set this routers mac address
// make L3Unicast group setDA for known (configured) ports
// that connect to other routers
OFAction setDA = getDestAction(portnum);
- if (setDA != null) {
+ if (setDA != null)
actions.add(setDA);
- }
actions.add(group);
OFBucket bucket = factory.buildBucket()
@@ -458,7 +443,8 @@
List<OFAction> actions = new ArrayList<OFAction>();
actions.add(decMplsTtl); // decrement the MPLS
// TTL/do-checksum/check TTL and MTU
- actions.add(setVlan); // set the vlan-id of the exit-port (and
+ // actions.add(setVlan); // set the vlan-id of the exit-port
+ // (and
// l2group)
actions.add(setSA); // set this routers mac address
actions.add(setDA);
@@ -483,31 +469,31 @@
*
* OFGroup group47 = OFGroup.of(47);
OFAction outgroup1 = factory.actions()
- .buildGroup()
- .setGroup(group61)
- .build();
+ .buildGroup()
+ .setGroup(group61)
+ .build();
OFBucket buc47_1 = factory.buildBucket()
- .setWeight(1)
- .setActions(Collections.singletonList(outgroup1))
- .build();
+ .setWeight(1)
+ .setActions(Collections.singletonList(outgroup1))
+ .build();
OFAction outgroup2 = factory.actions()
- .buildGroup()
- .setGroup(group62)
- .build();
+ .buildGroup()
+ .setGroup(group62)
+ .build();
OFBucket buc47_2 = factory.buildBucket()
- .setWeight(1)
- .setActions(Collections.singletonList(outgroup2))
- .build();
+ .setWeight(1)
+ .setActions(Collections.singletonList(outgroup2))
+ .build();
List<OFBucket> buckets47 = new ArrayList<OFBucket>();
buckets47.add(buc47_1);
buckets47.add(buc47_2);
OFMessage gmS12 = factory.buildGroupAdd()
- .setGroup(group47)
- .setBuckets(buckets47)
- .setGroupType(OFGroupType.SELECT)
- .setXid(getNextTransactionId())
- .build();
- write(gmS12, null); */
+ .setGroup(group47)
+ .setBuckets(buckets47)
+ .setGroupType(OFGroupType.SELECT)
+ .setXid(getNextTransactionId())
+ .build();
+ write(gmS12, null); */
private void processStatsReply(OFStatsReply sr) {
switch (sr.getStatsType()) {
@@ -574,7 +560,7 @@
OFInstruction gotoTbl = factory.instructions().buildGotoTable()
.setTableId(TableId.of(TABLE_TMAC)).build();
List<OFInstruction> instructions = new ArrayList<OFInstruction>();
- instructions.add(appAction);
+ // instructions.add(appAction);
instructions.add(gotoTbl);
OFMessage flowEntry = factory.buildFlowAdd()
.setTableId(TableId.of(TABLE_VLAN))
@@ -603,7 +589,7 @@
OFMatchV3 matchIp = factory.buildMatchV3()
.setOxmList(oxmListIp).build();
OFInstruction gotoTblIp = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_IPV4_UNICAST)).build();
+ .setTableId(TableId.of(TABLE_IPv4_UNICAST)).build();
List<OFInstruction> instructionsIp = Collections.singletonList(gotoTblIp);
OFMessage ipEntry = factory.buildFlowAdd()
.setTableId(TableId.of(TABLE_TMAC))
@@ -672,16 +658,15 @@
subnetIps.add("10.0.3.0");
subnetIps.add("10.0.1.0");
}
- // TODO needed?
- //if (getId() == 0x2) {
- //}
+ if (getId() == 0x2) {
+ }
if (getId() == 0x3) {
subnetIps.add("7.7.7.0");
}
return subnetIps;
}
- private static class RouteEntry {
+ private class RouteEntry {
String prefix;
String mask;
int nextHopPort;
@@ -712,7 +697,7 @@
.add(new RouteEntry("192.168.0.3", "255.255.255.255", 6, 103));
routerNextHopIps.add(new RouteEntry("7.7.7.0", "255.255.255.0", 6, 103));
}
- //if (getId() == 0x2) {
+ if (getId() == 0x2) {
/* These are required for normal IP routing without labels.
routerNextHopIps.add(new RouteEntry("192.168.0.1","255.255.255.255",1));
routerNextHopIps.add(new RouteEntry("192.168.0.3","255.255.255.255",2));
@@ -720,7 +705,7 @@
routerNextHopIps.add(new RouteEntry("10.0.2.0","255.255.255.0",1));
routerNextHopIps.add(new RouteEntry("10.0.3.0","255.255.255.0",1));
routerNextHopIps.add(new RouteEntry("7.7.7.0","255.255.255.0",2));*/
- //}
+ }
if (getId() == 0x3) {
routerNextHopIps
.add(new RouteEntry("192.168.0.2", "255.255.255.255", 2, 102));
@@ -737,12 +722,12 @@
private List<RouteEntry> getHostNextHopIps() {
List<RouteEntry> hostNextHopIps = new ArrayList<RouteEntry>();
if (getId() == 0x1) {
+ //hostNextHopIps.add(new RouteEntry("10.0.1.1", 1, "00:00:00:00:01:01")); // Just for Test - SSH
hostNextHopIps.add(new RouteEntry("10.0.2.1", 4, "00:00:00:00:02:01"));
hostNextHopIps.add(new RouteEntry("10.0.3.1", 5, "00:00:00:00:03:01"));
}
- // TODO needed?
- //if (getId() == 0x2) {
- //}
+ if (getId() == 0x2) {
+ }
if (getId() == 0x3) {
hostNextHopIps.add(new RouteEntry("7.7.7.7", 1, "00:00:07:07:07:07"));
}
@@ -750,14 +735,14 @@
}
private void populateIpTable() throws IOException {
- populateMyIps();
- populateMySubnets();
+ // populateMyIps();
+ // populateMySubnets();
populateRoutes();
populateHostRoutes();
// match for everything else to send to ACL table. Essentially
// the table miss flow entry
- populateTableMissEntry(TABLE_IPV4_UNICAST, false, true,
+ populateTableMissEntry(TABLE_IPv4_UNICAST, false, true,
true, TABLE_ACL);
}
@@ -785,7 +770,7 @@
instructions.add(writeInstr);
instructions.add(gotoInstr);
OFMessage myIpEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_IPV4_UNICAST))
+ .setTableId(TableId.of(TABLE_IPv4_UNICAST))
.setMatch(match)
.setInstructions(instructions)
.setPriority(MAX_PRIORITY) // highest priority for exact
@@ -828,7 +813,7 @@
instructions.add(writeInstr);
instructions.add(gotoInstr);
OFMessage myIpEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_IPV4_UNICAST))
+ .setTableId(TableId.of(TABLE_IPv4_UNICAST))
.setMatch(match)
.setInstructions(instructions)
.setPriority(SLASH_24_PRIORITY)
@@ -877,47 +862,44 @@
// OFAction setBos =
// factory.actions().buildSetField().setField(bos).build();
- /*
- writeActions.add(pushlabel); // need to be apply actions so can be
- writeActions.add(copyTtlOut); // matched in pseudo-table
- //writeActions.add(setlabelid); // bad support in cpqd
- //writeActions.add(setBos); no support in loxigen
- */
-
- List<OFAction> applyActions = new ArrayList<OFAction>();
- applyActions.add(pushlabel);
- applyActions.add(copyTtlOut);
- OFInstruction applyInstr = factory.instructions().buildApplyActions()
- .setActions(applyActions).build();
List<OFAction> writeActions = new ArrayList<OFAction>();
+ writeActions.add(pushlabel);
+ writeActions.add(copyTtlOut);
+ writeActions.add(setlabelid);
+ // writeActions.add(setBos); no support in loxigen
+
+ // List<OFAction> applyActions = new ArrayList<OFAction>();
+ // applyActions.add(pushlabel);
+ // applyActions.add(copyTtlOut);
+ // OFInstruction applyInstr =
+ // factory.instructions().buildApplyActions()
+ // .setActions(applyActions).build();
writeActions.add(outg); // group will decr mpls-ttl, set mac-sa/da,
// vlan
OFInstruction writeInstr = factory.instructions().buildWriteActions()
.setActions(writeActions).build();
+ OFInstruction gotoInstr = factory.instructions().buildGotoTable()
+ .setTableId(TableId.of(TABLE_ACL)).build();
+ List<OFInstruction> instructions = new ArrayList<OFInstruction>();
+ instructions.add(writeInstr);
// necessary to match in pseudo-table to overcome cpqd 1.3 flaw
- OFInstruction writeMeta = factory.instructions().buildWriteMetadata()
+ /*OFInstruction writeMeta = factory.instructions().buildWriteMetadata()
.setMetadata(U64.of(routerNextHopIps.get(i).label))
.setMetadataMask(METADATA_MASK).build();
- /*OFInstruction gotoInstr = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_ACL)).build();*/
OFInstruction gotoInstr = factory.instructions().buildGotoTable()
- .setTableId(TableId.of(TABLE_META)).build();
- List<OFInstruction> instructions = new ArrayList<OFInstruction>();
- instructions.add(applyInstr);
- // instructions.add(writeInstr);// cannot write here - causes switch
- // to crash
- instructions.add(writeMeta);
- instructions.add(gotoInstr);
+ .setTableId(TableId.of(TABLE_META)).build();*/
+ /*instructions.add(applyInstr);
+ instructions.add(writeMeta);*/
+ instructions.add(gotoInstr);
int priority = -1;
- if (routerNextHopIps.get(i).mask.equals("255.255.255.255")) {
+ if (routerNextHopIps.get(i).mask.equals("255.255.255.255"))
priority = MAX_PRIORITY;
- } else {
+ else
priority = SLASH_24_PRIORITY;
- }
OFMessage myIpEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_IPV4_UNICAST))
+ .setTableId(TableId.of(TABLE_IPv4_UNICAST))
.setMatch(match)
.setInstructions(instructions)
.setPriority(priority)
@@ -931,7 +913,7 @@
// need to also handle psuedo-table entries to match-metadata and
// set mpls
// label-id
- OFOxmEthType ethTypeMpls = factory.oxms()
+ /*OFOxmEthType ethTypeMpls = factory.oxms()
.ethType(EthType.MPLS_UNICAST);
OFOxmMetadataMasked meta = factory.oxms()
.metadataMasked(
@@ -944,7 +926,7 @@
writeActions2.add(setlabelid);
OFAction outg2 = factory.actions().buildGroup()
.setGroup(OFGroup.of(routerNextHopIps.get(i).nextHopPort |
- (192 << VLAN_ID_OFFSET)))
+ (192 << VLAN_ID_OFFSET)))
.build();
writeActions2.add(outg2);
OFInstruction writeInstr2 = factory.instructions().buildWriteActions()
@@ -955,23 +937,23 @@
// unfortunately have to apply this action too
OFInstruction applyInstr2 = factory.instructions().buildApplyActions()
.setActions(writeActions2).build();
- instructions2.add(applyInstr2);
+ instructions2.add(applyInstr2); */
// instructions2.add(writeInstr2);
// instructions2.add(gotoInstr2);
/*OFMatchV3 match3 = factory.buildMatchV3()
- .setOxmList(OFOxmList.of(meta)).build();
+ .setOxmList(OFOxmList.of(meta)).build();
OFInstruction clearInstruction = factory.instructions().clearActions();
List<OFInstruction> instructions3 = new ArrayList<OFInstruction>();
OFAction outc = factory.actions().buildOutput()
- .setPort(OFPort.CONTROLLER).setMaxLen(OFPCML_NO_BUFFER)
- .build();
+ .setPort(OFPort.CONTROLLER).setMaxLen(OFPCML_NO_BUFFER)
+ .build();
OFInstruction writec = factory.instructions()
- .writeActions(Collections.singletonList(outc));
+ .writeActions(Collections.singletonList(outc));
instructions3.add(clearInstruction);
instructions3.add(writec);
instructions3.add(gotoInstr2); */
- OFMessage myMetaEntry = factory.buildFlowAdd()
+ /*OFMessage myMetaEntry = factory.buildFlowAdd()
.setTableId(TableId.of(TABLE_META))
.setMatch(matchMeta)
.setInstructions(instructions2)
@@ -981,7 +963,7 @@
.setHardTimeout(0)
.setXid(getNextTransactionId())
.build();
- msglist.add(myMetaEntry);
+ msglist.add(myMetaEntry); */
}
write(msglist);
@@ -1030,7 +1012,7 @@
instructions.add(writeInstr);
instructions.add(gotoInstr);
OFMessage myIpEntry = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_IPV4_UNICAST))
+ .setTableId(TableId.of(TABLE_IPv4_UNICAST))
.setMatch(match)
.setInstructions(instructions)
.setPriority(MAX_PRIORITY) // highest priority for exact
@@ -1046,7 +1028,7 @@
log.debug("Adding {} next-hop-host-rules in sw {}", msglist.size(), getStringId());
}
- private static class MplsEntry {
+ private class MplsEntry {
int labelid;
int portnum;
@@ -1086,15 +1068,18 @@
OFMatchV3 matchlabel = factory.buildMatchV3()
.setOxmList(oxmList).build();
OFAction poplabel = factory.actions().popMpls(EthType.IPv4);
+ OFAction copyttlin = factory.actions().copyTtlIn();
OFAction sendTo = null;
if (lfibEntries.get(i).portnum == OFPort.CONTROLLER.getPortNumber()) {
sendTo = factory.actions().output(OFPort.CONTROLLER,
OFPCML_NO_BUFFER);
} else {
+ // after popping send to L3 intf, not MPLS intf
sendTo = factory.actions().group(OFGroup.of(
- 0xa0000000 | lfibEntries.get(i).portnum));
+ 0x20000000 | lfibEntries.get(i).portnum));
}
List<OFAction> writeActions = new ArrayList<OFAction>();
+ writeActions.add(copyttlin);
writeActions.add(poplabel);
writeActions.add(sendTo);
OFInstruction writeInstr = factory.instructions().buildWriteActions()
diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index 8197724..5c61f6e 100644
--- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -28,3 +28,4 @@
net.onrc.onos.core.matchaction.MatchActionModule
net.onrc.onos.core.flowmanager.FlowManagerModule
net.onrc.onos.core.configmanager.NetworkConfigManager
+net.onrc.onos.apps.segmentrouting.ArpHandler