From aded7ca0bcf3eedcd78f1b91d24fae2d8248d1db Mon Sep 17 00:00:00 2001
From: Ryan Izard <rizard@g.clemson.edu>
Date: Thu, 7 Aug 2014 18:55:19 -0700
Subject: [PATCH] Forwarding with port, L2, and, L3 matches. OFPBMC_BAD_VALUE
 sent back from switch for matching FL's no-VLAN notation; need to update all
 VLAN's = -1 to NO_VLAN instead.

---
 .../forwarding/Forwarding.java                | 32 ++++++++++++++++++-
 .../routing/ForwardingBase.java               | 11 ++++---
 .../util/MatchMaskUtils.java                  | 14 +++++---
 .../util/OFMessageDamper.java                 |  2 +-
 4 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
index 2c5739cae..e341d6dc9 100644
--- a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
@@ -41,6 +41,7 @@ import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.core.util.AppCookie;
 import net.floodlightcontroller.debugcounter.IDebugCounterService;
 import net.floodlightcontroller.packet.Ethernet;
+import net.floodlightcontroller.packet.IPv4;
 import net.floodlightcontroller.routing.ForwardingBase;
 import net.floodlightcontroller.routing.IRoutingDecision;
 import net.floodlightcontroller.routing.IRoutingService;
@@ -55,9 +56,14 @@ import org.projectfloodlight.openflow.protocol.OFFlowModCommand;
 import org.projectfloodlight.openflow.protocol.OFPacketIn;
 import org.projectfloodlight.openflow.protocol.OFPacketOut;
 import org.projectfloodlight.openflow.types.DatapathId;
+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;
 import org.projectfloodlight.openflow.types.U64;
+import org.projectfloodlight.openflow.types.VlanVid;
 import org.projectfloodlight.openflow.protocol.action.OFAction;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -265,11 +271,35 @@ public class Forwarding extends ForwardingBase implements IFloodlightModule {
 											if (decision != null) {
 												routeMatch = decision.getMatch();
 											} else {
+												// The packet in match will only contain the port number.
+												// We need to add in specifics for the hosts we're routing between.
+												Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
+												VlanVid vlan = VlanVid.ofVlan(eth.getVlanID());
+												MacAddress srcMac = eth.getSourceMACAddress();
+												MacAddress dstMac = eth.getDestinationMACAddress();
+												
+												Match.Builder mb = m.createBuilder(); // TODO @Ryan based on packet in's match, m; ingress port should be included already, but it's not....
+												mb.setExact(MatchField.IN_PORT, m.get(MatchField.IN_PORT))
+												.setExact(MatchField.ETH_SRC, srcMac)
+												.setExact(MatchField.ETH_DST, dstMac);
+												//.setExact(MatchField.VLAN_VID, OFVlanVidMatch.ofVlanVid(vlan));
+												
+												if (eth.getEtherType() == Ethernet.TYPE_IPv4) {
+													IPv4 ip = (IPv4) eth.getPayload();
+													IPv4Address srcIp = ip.getSourceAddress();
+													IPv4Address dstIp = ip.getDestinationAddress();
+													mb.setExact(MatchField.IPV4_SRC, srcIp)
+													.setExact(MatchField.IPV4_DST, dstIp)
+													.setExact(MatchField.ETH_TYPE, EthType.IPv4);
+												} else if (eth.getEtherType() == Ethernet.TYPE_ARP) {
+													mb.setExact(MatchField.ETH_TYPE, EthType.ARP);
+												} //TODO @Ryan should probably include other ethertypes
+												
 												// A Match will contain only what you want to match on.
 												// Absence of a MatchField --> it can be anything (wildcarded).
 												// Remove all matches except for L2 and L3 addresses & VLAN
 												// to allow forwarding on a (V)LAN
-												routeMatch = MatchMaskUtils.maskL4AndUp(m);
+												routeMatch = /*MatchMaskUtils.maskL4AndUp(*/mb.build()/*)*/;
 											}
 
 											pushRoute(route, routeMatch, pi, sw.getId(), cookie,
diff --git a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
index 32580559e..594ec51a3 100644
--- a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
+++ b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
@@ -247,23 +247,24 @@ public abstract class ForwardingBase implements IOFMessageListener {
 			
 			OFActionOutput.Builder aob = sw.getOFFactory().actions().buildOutput();
 			List<OFAction> actions = new ArrayList<OFAction>();	
-			Match.Builder mb = match.createBuilder();
+			//Match.Builder mb = match.createBuilder();
 
 			// set input and output ports on the switch
 			OFPort outPort = switchPortList.get(indx).getPortId();
-			OFPort inPort = switchPortList.get(indx - 1).getPortId();
-			mb.setExact(MatchField.IN_PORT, inPort);
+			//OFPort inPort = switchPortList.get(indx - 1).getPortId();
+			//mb.setExact(MatchField.IN_PORT, inPort);
 			aob.setPort(outPort);
 			aob.setMaxLen(Integer.MAX_VALUE);
 			actions.add(aob.build());
 			
 			// compile
-			fmb.setMatch(mb.build())
+			fmb.setMatch(match) //mb.build()
 			.setActions(actions)
 			.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
 			.setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
 			.setBufferId(OFBufferId.NO_BUFFER)
-			.setCookie(cookie);
+			.setCookie(cookie)
+			.setOutPort(outPort); // TODO @Ryan why does this need to be set in addition to the action???
 
 			try {
 				//TODO @Ryan counterStore.updatePktOutFMCounterStoreLocal(sw, fm);
diff --git a/src/main/java/net/floodlightcontroller/util/MatchMaskUtils.java b/src/main/java/net/floodlightcontroller/util/MatchMaskUtils.java
index f4620e5ae..67b0a6576 100644
--- a/src/main/java/net/floodlightcontroller/util/MatchMaskUtils.java
+++ b/src/main/java/net/floodlightcontroller/util/MatchMaskUtils.java
@@ -28,13 +28,17 @@ public class MatchMaskUtils {
 	public static Match maskL4AndUp(Match m) {
 		// cannot create builder from existing match; will retain all MatchFields set
 		Match.Builder mb = OFFactories.getFactory(m.getVersion()).buildMatch(); 
-		return mb.setExact(MatchField.IN_PORT, m.get(MatchField.IN_PORT))
+		mb.setExact(MatchField.IN_PORT, m.get(MatchField.IN_PORT))
 		.setExact(MatchField.VLAN_VID, m.get(MatchField.VLAN_VID))
 		.setExact(MatchField.ETH_SRC, m.get(MatchField.ETH_SRC))
-		.setExact(MatchField.ETH_DST, m.get(MatchField.ETH_DST))
-		.setExact(MatchField.IPV4_SRC, m.get(MatchField.IPV4_SRC))
-		.setExact(MatchField.IPV4_DST, m.get(MatchField.IPV4_DST))
-		.build();
+		.setExact(MatchField.ETH_DST, m.get(MatchField.ETH_DST));
+		if (m.get(MatchField.IPV4_SRC) != null) {
+			mb.setExact(MatchField.IPV4_SRC, m.get(MatchField.IPV4_SRC));
+		}
+		if (m.get(MatchField.IPV4_DST) != null) {
+			mb.setExact(MatchField.IPV4_DST, m.get(MatchField.IPV4_DST));
+		}
+		return mb.build();
 	}
 	
 	
diff --git a/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java b/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java
index ba4f01d3a..e599968ec 100644
--- a/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java
+++ b/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java
@@ -144,7 +144,7 @@ public class OFMessageDamper {
             // entry exists in cache. Dampening.
             return false; 
         } else {
-            sw.write(msg, LogicalOFMessageCategory.MAIN);
+            sw.write(msg);
             if (flush) {
                 sw.flush();
             }
-- 
GitLab