diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java
index bb17f34f9400fea90755c996c5341e869ee8b863..5756d5487af3a253aa9a67e102e5ff52ebeaba89 100644
--- a/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java
+++ b/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java
@@ -41,11 +41,21 @@ import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv4Code;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv4Type;
+
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv6Code;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv6Type;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpDscp;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpEcn;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpProto;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4Dst;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4Src;
+
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6Dst;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6Flabel;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6NdSll;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6NdTarget;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6NdTll;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6Src;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmMetadata;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsBos;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsLabel;
@@ -203,7 +213,13 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> {
                     jsonGenerator.writeStringField(MatchUtils.STR_ARP_SPA, ((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) {
                     jsonGenerator.writeStringField(MatchUtils.STR_ARP_DPA, ((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString()); 
-                } 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdSll) {                		
+                	jsonGenerator.writeStringField(MatchUtils.STR_IPV6_ND_SSL, ((OFOxmIpv6NdSll) ((OFActionSetField) a).getField()).getValue().toString());
+            	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdTll) {                		
+            		jsonGenerator.writeStringField(MatchUtils.STR_IPV6_ND_TTL, ((OFOxmIpv6NdTll) ((OFActionSetField) a).getField()).getValue().toString());
+            	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdTarget) {                		
+            		jsonGenerator.writeStringField(MatchUtils.STR_IPV6_ND_TARGET, ((OFOxmIpv6NdTarget) ((OFActionSetField) a).getField()).getValue().toString()); 
+            	}
                 /* DATA LAYER */
                 else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) {
                     jsonGenerator.writeNumberField(MatchUtils.STR_DL_TYPE, ((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue());
@@ -220,7 +236,11 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> {
                     jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_CODE, ((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) {
                     jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_TYPE, ((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType()); 
-                } 
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv6Code) {                		
+                	jsonGenerator.writeNumberField(MatchUtils.STR_ICMPV6_CODE, ((OFOxmIcmpv6Code) ((OFActionSetField) a).getField()).getValue().getRaw()); 
+            	}  else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv6Type) {                		
+            		jsonGenerator.writeNumberField(MatchUtils.STR_ICMPV6_TYPE, ((OFOxmIcmpv6Type) ((OFActionSetField) a).getField()).getValue().getRaw()); 
+            	}
                 /* NETWORK LAYER */
                 else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) {
                     jsonGenerator.writeNumberField(MatchUtils.STR_NW_PROTO, ((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber()); 
@@ -228,7 +248,13 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> {
                     jsonGenerator.writeStringField(MatchUtils.STR_NW_SRC, ((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) {
                     jsonGenerator.writeStringField(MatchUtils.STR_NW_DST, ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); 
-                } else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) {
+                } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Src) {                		
+                	jsonGenerator.writeStringField(MatchUtils.STR_IPV6_SRC, ((OFOxmIpv6Src) ((OFActionSetField) a).getField()).getValue().toString()); 
+            	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Dst) {                		
+            		jsonGenerator.writeStringField(MatchUtils.STR_IPV6_DST, ((OFOxmIpv6Dst) ((OFActionSetField) a).getField()).getValue().toString()); 
+            	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Flabel) {                		
+            		jsonGenerator.writeStringField(MatchUtils.STR_IPV6_FLOW_LABEL, ((OFOxmIpv6Flabel) ((OFActionSetField) a).getField()).getValue().toString()); 
+            	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) {
                     jsonGenerator.writeNumberField(MatchUtils.STR_NW_ECN, ((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue()); 
                 } else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) {
                     jsonGenerator.writeNumberField(MatchUtils.STR_NW_DSCP, ((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue()); 
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java
index 8dcb12baf8bd2a642fdf4cfde90581c5159644e4..4399c95abcf833f5fae04b27f38285f0330e9f86 100644
--- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java
+++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java
@@ -24,6 +24,7 @@ import java.util.Map;
 
 import net.floodlightcontroller.core.annotations.LogMessageCategory;
 import net.floodlightcontroller.core.util.AppCookie;
+import net.floodlightcontroller.staticflowentry.web.StaticFlowEntryPusherResource;
 import net.floodlightcontroller.util.ActionUtils;
 import net.floodlightcontroller.util.InstructionUtils;
 
@@ -137,7 +138,7 @@ public class StaticFlowEntries {
 	 * @param name The name of this static flow entry
 	 * @return A Map representation of the storage entry 
 	 */
-	public static Map<String, Object> flowModToStorageEntry(OFFlowMod fm, String sw, String name) {
+	public static Map<String, Object> flowModToStorageEntry(OFFlowMod fm, String sw, String name) throws Exception {
 		Map<String, Object> entry = new HashMap<String, Object>();
 		entry.put(StaticFlowEntryPusher.COLUMN_NAME, name);
 		entry.put(StaticFlowEntryPusher.COLUMN_SWITCH, sw);
@@ -271,6 +272,35 @@ public class StaticFlowEntries {
 			case ARP_TPA:
 				entry.put(StaticFlowEntryPusher.COLUMN_ARP_DPA, match.get(MatchField.ARP_TPA).toString());
 				break;
+				
+//sanjivini				
+			case IPV6_SRC:				
+				entry.put(StaticFlowEntryPusher.COLUMN_NW6_SRC, match.get(MatchField.IPV6_SRC).toString());
+				break;
+			case IPV6_DST:			
+				entry.put(StaticFlowEntryPusher.COLUMN_NW6_DST, match.get(MatchField.IPV6_DST).toString());
+				break;	
+			case IPV6_FLABEL:			
+				entry.put(StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL, match.get(MatchField.IPV6_FLABEL).toString());
+				break;	
+			case ICMPV6_TYPE:				
+				entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE, String.valueOf(match.get(MatchField.ICMPV6_TYPE).getValue()));
+				break;
+			case ICMPV6_CODE:				
+				entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_CODE, match.get(MatchField.ICMPV6_CODE).getValue());
+				break;
+			case IPV6_ND_SLL:			
+				entry.put(StaticFlowEntryPusher.COLUMN_ND_SLL, match.get(MatchField.IPV6_ND_SLL).toString());
+				break;
+			case IPV6_ND_TLL:				
+				entry.put(StaticFlowEntryPusher.COLUMN_ND_TLL, match.get(MatchField.IPV6_ND_TLL).toString());
+				break;	
+			case IPV6_ND_TARGET:				
+				entry.put(StaticFlowEntryPusher.COLUMN_ND_TARGET, match.get(MatchField.IPV6_ND_TARGET).toString());
+				break;	
+				
+//sanjivini	
+				
 			case MPLS_LABEL:
 				entry.put(StaticFlowEntryPusher.COLUMN_MPLS_LABEL, match.get(MatchField.MPLS_LABEL).getValue());
 				break;
@@ -293,6 +323,10 @@ public class StaticFlowEntries {
 			} // end switch-case
 		} // end while
 				
+		int result = StaticFlowEntryPusherResource.checkActions(entry);
+		if (result == -1)
+			throw new Exception("Invalid action/instructions");
+		
 		return entry;
 	}
 
@@ -458,6 +492,34 @@ public class StaticFlowEntries {
 			case StaticFlowEntryPusher.COLUMN_ARP_DPA:
 				entry.put(StaticFlowEntryPusher.COLUMN_ARP_DPA, jp.getText());
 				break;
+				
+//sanjivini				
+			case StaticFlowEntryPusher.COLUMN_NW6_SRC:				
+				entry.put(StaticFlowEntryPusher.COLUMN_NW6_SRC, jp.getText());
+				break;	
+			case StaticFlowEntryPusher.COLUMN_NW6_DST:				
+				entry.put(StaticFlowEntryPusher.COLUMN_NW6_DST, jp.getText());
+				break;
+			case StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL:								
+				entry.put(StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL, jp.getText());
+				break;	
+			case StaticFlowEntryPusher.COLUMN_ICMP6_TYPE:				
+				entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE, jp.getText());
+				break;
+			case StaticFlowEntryPusher.COLUMN_ICMP6_CODE:						
+				entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_CODE, jp.getText());
+				break;
+			case StaticFlowEntryPusher.COLUMN_ND_SLL:				
+				entry.put(StaticFlowEntryPusher.COLUMN_ND_SLL, jp.getText());
+				break;
+			case StaticFlowEntryPusher.COLUMN_ND_TLL:			
+				entry.put(StaticFlowEntryPusher.COLUMN_ND_TLL, jp.getText());
+				break;
+			case StaticFlowEntryPusher.COLUMN_ND_TARGET:					
+				entry.put(StaticFlowEntryPusher.COLUMN_ND_TARGET, jp.getText());
+				break;
+//sanjivini	
+				
 			case StaticFlowEntryPusher.COLUMN_MPLS_LABEL:
 				entry.put(StaticFlowEntryPusher.COLUMN_MPLS_LABEL, jp.getText());
 				break;
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
index 489a8f949e8f7f5eb51a0fa92bd2445b684056ed..9153b1245103d6d2789aa12808835146be486afc 100644
--- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
+++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
@@ -131,6 +131,18 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
 	public static final String COLUMN_ARP_DHA = MatchUtils.STR_ARP_DHA;
 	public static final String COLUMN_ARP_SPA = MatchUtils.STR_ARP_SPA;
 	public static final String COLUMN_ARP_DPA = MatchUtils.STR_ARP_DPA;
+	
+//sanjivini
+	//IPv6 related columns
+	public static final String COLUMN_NW6_SRC = MatchUtils.STR_IPV6_SRC;
+	public static final String COLUMN_NW6_DST = MatchUtils.STR_IPV6_DST;
+	public static final String COLUMN_IPV6_FLOW_LABEL = MatchUtils.STR_IPV6_FLOW_LABEL;
+	public static final String COLUMN_ICMP6_TYPE = MatchUtils.STR_ICMPV6_TYPE;
+	public static final String COLUMN_ICMP6_CODE = MatchUtils.STR_ICMPV6_CODE;
+	public static final String COLUMN_ND_SLL = MatchUtils.STR_IPV6_ND_SSL;
+	public static final String COLUMN_ND_TLL = MatchUtils.STR_IPV6_ND_TTL;
+	public static final String COLUMN_ND_TARGET = MatchUtils.STR_IPV6_ND_TARGET;	
+//sanjivini
 
 	public static final String COLUMN_MPLS_LABEL = MatchUtils.STR_MPLS_LABEL;
 	public static final String COLUMN_MPLS_TC = MatchUtils.STR_MPLS_TC;
@@ -164,6 +176,13 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
 		COLUMN_ICMP_TYPE, COLUMN_ICMP_CODE, 
 		COLUMN_ARP_OPCODE, COLUMN_ARP_SHA, COLUMN_ARP_DHA, 
 		COLUMN_ARP_SPA, COLUMN_ARP_DPA,
+		
+//sanjivini		
+		//IPv6 related matches
+		COLUMN_NW6_SRC, COLUMN_NW6_DST, COLUMN_ICMP6_TYPE, COLUMN_ICMP6_CODE, 
+		COLUMN_IPV6_FLOW_LABEL, COLUMN_ND_SLL, COLUMN_ND_TLL, COLUMN_ND_TARGET,
+//sanjivini		
+		
 		COLUMN_MPLS_LABEL, COLUMN_MPLS_TC, COLUMN_MPLS_BOS, 
 		COLUMN_METADATA, COLUMN_TUNNEL_ID, COLUMN_PBB_ISID,
 		/* end newly added matches */
@@ -408,6 +427,13 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
 			log.debug("ignoring flow entry {} on switch {} with illegal OFMatch() key: " + match, entryName, switchName);
 			return;
 		}
+//sanjivini		
+		catch (Exception e) {
+			log.error("OF version incompatible for the match: " + match);
+			e.printStackTrace();
+			return;
+		}
+//sanjivini
 
 		entries.get(switchName).put(entryName, fmb.build()); // add the FlowMod message to the table
 	}
@@ -754,8 +780,13 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
 
 	@Override
 	public void addFlow(String name, OFFlowMod fm, DatapathId swDpid) {
-		Map<String, Object> fmMap = StaticFlowEntries.flowModToStorageEntry(fm, swDpid.toString(), name);
-		storageSourceService.insertRowAsync(TABLE_NAME, fmMap);
+		try {
+			Map<String, Object> fmMap = StaticFlowEntries.flowModToStorageEntry(fm, swDpid.toString(), name);
+			storageSourceService.insertRowAsync(TABLE_NAME, fmMap);
+		} catch (Exception e) {
+			log.error("Error! Check the fields specified for the flow.Make sure IPv4 fields are not mixed with IPv6 fields or all "
+            		+ "mandatory fields are specified. ");
+		}
 	}
 
 	@Override
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java
index c4945a46e7c51a4588a56e8b7ce4227f2a6df1c2..c2cd26aa6602f45017656eae866a90de1bbe664a 100644
--- a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java
+++ b/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java
@@ -32,6 +32,7 @@ import net.floodlightcontroller.core.annotations.LogMessageDoc;
 import net.floodlightcontroller.staticflowentry.StaticFlowEntries;
 import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher;
 import net.floodlightcontroller.storage.IStorageSourceService;
+import net.floodlightcontroller.util.MatchUtils;
 
 /**
  * Pushes a static flow entry to the storage source
@@ -43,137 +44,236 @@ public class StaticFlowEntryPusherResource extends ServerResource {
 	protected static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusherResource.class);
 
 	/**
-	 * Checks to see if the user matches IP information without
-	 * checking for the correct ether-type (2048).
-	 * @param rows The Map that is a string representation of
-	 * the static flow.
-	 * @reutrn True if they checked the ether-type, false otherwise
+	 * Validates if all the mandatory fields are set properly while adding an IPv6 flow
+	 * @param Map containing the fields of the flow
+	 * @return state indicating whether a flow is valid or not
 	 */
-	private boolean checkMatchIp(Map<String, Object> rows) {
-		boolean matchEther = false;
-		String val = (String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE);
-		if (val != null) {
-			int type = 0;
-			// check both hex and decimal
-			if (val.startsWith("0x")) {
-				type = Integer.parseInt(val.substring(2), 16);
+	private int checkFlow(Map<String, Object> rows) {    
+		//Declaring & Initializing flags
+		int state = 0;
+		boolean dl_type = false;
+		boolean nw_proto = false;
+		boolean nw_layer = false;
+		boolean icmp6_type = false;
+		boolean icmp6_code = false;
+		boolean nd_target = false;
+		boolean nd_sll = false;
+		boolean nd_tll = false; 
+		boolean ip6 = false;
+		boolean ip4 = false;
+
+		int eth_type = -1;
+		int nw_protocol = -1;
+		int icmp_type = -1;
+
+		//Determine the dl_type if set
+		if (rows.containsKey(StaticFlowEntryPusher.COLUMN_DL_TYPE)) {
+			if (((String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE)).startsWith("0x")) {
+				eth_type = Integer.parseInt(((String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE)).replaceFirst("0x", ""), 16);
+				dl_type = true;
+			} else {
+				eth_type = Integer.parseInt((String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE));
+				dl_type = true;
+			}
+			if (eth_type == 0x86dd) { /* or 34525 */
+				ip6 = true;
+				dl_type = true;
+			} else if (eth_type == 0x800 || /* or 2048 */
+					eth_type == 0x806 || /* or 2054 */
+					eth_type == 0x8035) { /* or 32821*/
+				ip4 = true;
+				dl_type = true;
+			}	
+			//else {
+			//	state = 2;    
+			//	return state;
+			//}
+		}
+		if (rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_DST) ||
+				rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_SRC)) {
+			nw_layer = true;
+			ip4 = true;
+		}
+		if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP_CODE) ||
+				rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP_TYPE) ||
+				rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_DHA) ||
+				rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_SHA) ||
+				rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_SPA) ||
+				rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_DPA) ||
+				rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_OPCODE)) {
+			ip4 = true;
+		}
+		if (rows.containsKey(StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL) || 
+				rows.containsKey(StaticFlowEntryPusher.COLUMN_NW6_SRC) ||
+				rows.containsKey(StaticFlowEntryPusher.COLUMN_NW6_DST)) {
+			nw_layer = true;
+			ip6 = true;
+		}
+		if (rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_PROTO)) {
+			nw_proto = true;
+			if (((String) rows.get(StaticFlowEntryPusher.COLUMN_NW_PROTO)).startsWith("0x")) {
+				nw_protocol = Integer.parseInt(((String) rows.get(StaticFlowEntryPusher.COLUMN_NW_PROTO)).replaceFirst("0x", ""), 16);
 			} else {
-				try {
-					type = Integer.parseInt(val);
-				} catch (NumberFormatException e) { /* fail silently */}
+				nw_protocol = Integer.parseInt((String) rows.get(StaticFlowEntryPusher.COLUMN_NW_PROTO));
 			}
-			if (type == 2048) matchEther = true;
 		}
+		if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP6_CODE)) {
+			icmp6_code = true;
+			ip6 = true;
+		}
+		if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE)) {
+			icmp6_type = true;
+			ip6 = true;
+			if (((String) rows.get(StaticFlowEntryPusher.COLUMN_ICMP_TYPE)).startsWith("0x")) {
+				icmp_type = Integer.parseInt(((String) rows.get(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE)).replaceFirst("0x", ""), 16);
+			} else {
+				icmp_type = Integer.parseInt((String) rows.get(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE));
+			}
+		}
+		if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ND_SLL)) {
+			nd_sll = true;
+			ip6 = true;
+		}
+		if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ND_TLL)) {
+			nd_tll = true;
+			ip6 = true;
+		}
+		if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ND_TARGET)) {
+			nd_target = true;
+			ip6 = true;
+		}    
 
-		if ((rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_DST) ||
-				rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_SRC) ||
-				rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_PROTO) ||
-				rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_TOS)) &&
-				(matchEther == false))
-			return false;
+		if (nw_layer == true || nw_proto == true) {
+			if (dl_type == true) {
+				if (!(ip4 == true || ip6 == true)) {
+					//invalid dl_type
+					state = 2;    
+					return state;
+				}
+			}
+			else {
+				//dl_type not set
+				state = 1;    
+				return state;
+			}
+		}
+		if (icmp6_type == true || icmp6_code == true ) {
+			if (nw_proto == true) {
+				if (nw_protocol != 0x3A) { /* or 58 */
+					//invalid nw_proto
+					state = 4;    
+					return state;
+				}
+			}
+			else {
+				//nw_proto not set
+				state = 3;    
+				return state;
+			}
+		}
+
+		if (nd_sll == true || nd_tll == true || nd_target == true) {
+			if (icmp6_type == true) {
+				//icmp_type must be set to 135/136 to set ipv6_nd_target
+				if (nd_target == true) {
+					if (!(icmp_type == 135 || icmp_type == 136)) {
+						//invalid icmp6_type
+						state = 6;
+						return state;
+					}
+				}
+				//icmp_type must be set to 136 to set ipv6_nd_tll
+				else if (nd_tll == true) {
+					if (!(icmp_type == 136)) {
+						//invalid icmp6_type
+						state = 6;
+						return state;
+					}
+				}
+				//icmp_type must be set to 135 to set ipv6_nd_sll
+				else if (nd_sll == true) {
+					if (!(icmp_type == 135)) {
+						//invalid icmp6_type
+						state = 6;
+						return state;
+					}
+				}
+			}
+			else {
+				//icmp6_type not set
+				state = 5;    
+				return state;
+			}
+		}
+
+		int result = checkActions(rows);
+
+		if ((ip4 == true && ip6 == true) || (result == -1) ||
+				(result == 1 && ip6 == true) || (result == 2 && ip4 == true)) {
+			//ipv4 & ipv6 conflict
+			state = 7;    
+			return state;
+		}
+
+		return state;
 
-		return true;
 	}
 
 	/**
-	 * The check for flow entry validity will happen only when the SFP's 
-	 * storage listener detects the row entry is inserted. This, unfortunately,
-	 * is after the REST API returns the message to the user who's inserting
-	 * the flow.
+	 * Validates actions/instructions
 	 * 
-	 * This function will perform the same error checking that will happen
-	 * automatically later when the OFFlowMod is composed and built. This is
-	 * somewhat redundant, since the flow entry will only be sent to the
-	 * switch if it's valid, but this is the only way to tell the user something
-	 * wasn't correct in their flow definition.
+	 * -1 --> IPv4/IPv6 conflict
+	 * 0 --> no IPv4 or IPv6 actions
+	 * 1 --> IPv4 only actions
+	 * 2 --> IPv6 only actions
 	 * 
-	 * @param row
-	 * @return A String describing the error if there is one; the empty string if all checks
-	 *
-	private String validateFlowEntry(Map<String, Object> row) {
-		/*
-		 * First, build the match string and try to turn it into a
-		 * Match.Builder with all the fields set. Then, before the
-		 * it's built, check all prerequisites.
-		 *
-		IOFSwitchService switchService = (IOFSwitchService) getContext()
-				.getAttributes()
-				.get(IOFSwitchService.class.getCanonicalName());
-		String switchName = (String) row.get(StaticFlowEntryPusher.COLUMN_SWITCH);
-		String entryName = (String) row.get(StaticFlowEntryPusher.COLUMN_NAME);
-		String matchString;
-		DatapathId dpid;
-		
-		try {
-			dpid = DatapathId.of(switchName);
-		} catch (NumberFormatException e) {
-			return "Invalid switch DPID " + switchName + ".";
-		}
-		
-		IOFSwitch theSwitch = switchService.getSwitch(DatapathId.of(switchName));
-		
-		if (theSwitch == null) {
-			return "Switch " + switchName + " is not connected to the controller.";		
-		}
-		
-		for (String key : row.keySet()) {
-			// get the correct builder for the OF version supported by the switch
-			OFFlowModify.Builder fmb = theSwitch.getOFFactory().buildFlowModify();
-
-			StaticFlowEntries.initDefaultFlowMod(fmb, entryName);
-
-			if (row.get(key) == null
-					|| key.equals(StaticFlowEntryPusher.COLUMN_SWITCH) 
-					|| key.equals(StaticFlowEntryPusher.COLUMN_NAME) 
-					|| key.equals("id")
-					|| key.equals(StaticFlowEntryPusher.COLUMN_HARD_TIMEOUT) 
-					|| key.equals(StaticFlowEntryPusher.COLUMN_IDLE_TIMEOUT)) {
-				continue;
-			}
-
-			if (key.equals(StaticFlowEntryPusher.COLUMN_ACTIVE)) {
-				if  (!Boolean.valueOf((String) row.get(StaticFlowEntryPusher.COLUMN_ACTIVE))) {
-					log.debug("Flow entry is inactive; verifying it anyway."); 
-				}
-			} else if (key.equals(StaticFlowEntryPusher.COLUMN_TABLE_ID)) {
-				if (fmb.getVersion() != OFVersion.OF_10) { // all except 1.0 support tables 
-					fmb.setTableId(TableId.of(Integer.parseInt((String) row.get(key)))); // support multiple flow tables for OF1.1+
-				} else {
-					return "Tables not supported in OpenFlow 1.0.";
-				}
-			} else if (key.equals(StaticFlowEntryPusher.COLUMN_ACTIONS)) {
-				ActionUtils.fromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_ACTIONS), log);
-			} else if (key.equals(StaticFlowEntryPusher.COLUMN_COOKIE)) {
-				fmb.setCookie(StaticFlowEntries.computeEntryCookie(Integer.valueOf((String) row.get(StaticFlowEntryPusher.COLUMN_COOKIE)), entryName));
-			} else if (key.equals(StaticFlowEntryPusher.COLUMN_PRIORITY)) {
-				fmb.setPriority(U16.t(Integer.valueOf((String) row.get(StaticFlowEntryPusher.COLUMN_PRIORITY))));
-			} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS)) {
-				InstructionUtils.applyActionsFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS), log);
-			} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_CLEAR_ACTIONS)) {
-				InstructionUtils.clearActionsFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_CLEAR_ACTIONS), log);
-			} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_EXPERIMENTER)) {
-				InstructionUtils.experimenterFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_EXPERIMENTER), log);
-			} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_GOTO_METER)) {
-				InstructionUtils.meterFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_GOTO_METER), log);
-			} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_GOTO_TABLE)) {
-				InstructionUtils.gotoTableFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_GOTO_TABLE), log);
-			} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS)) {
-				InstructionUtils.writeActionsFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS), log);
-			} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_METADATA)) {
-				InstructionUtils.writeMetadataFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_METADATA), log);
-			} else { // the rest of the keys are for Match().fromString()
-				if (matchString.length() > 0) {
-					matchString.append(",");
-				}
-				matchString.append(key + "=" + row.get(key).toString());
+	 * @param Map containing the fields of the flow
+	 * @return state indicating whether a flow is valid or not
+	 */
+	public static int checkActions(Map<String, Object> entry) {
+
+		boolean ip6 = false;
+		boolean ip4 = false;
+		String actions = null;
+
+		if (entry.containsKey(StaticFlowEntryPusher.COLUMN_ACTIONS) || 
+				entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS) ||
+				entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS)) {
+			if (entry.containsKey(StaticFlowEntryPusher.COLUMN_ACTIONS)) {
+				actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_ACTIONS);
+			}
+			else if (entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS)) {
+				actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS);
+			}
+			else if (entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS)) {
+				actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS);
 			}
-		}
-		String match = matchString.toString();
 
-		fmb.setMatch(MatchUtils.fromString(match, fmb.getVersion()));
+			if (actions.contains(MatchUtils.STR_ICMPV6_CODE) || actions.contains(MatchUtils.STR_ICMPV6_TYPE) ||
+					actions.contains(MatchUtils.STR_IPV6_DST) || actions.contains(MatchUtils.STR_IPV6_SRC) || 
+					actions.contains(MatchUtils.STR_IPV6_FLOW_LABEL) || actions.contains(MatchUtils.STR_IPV6_ND_SSL) ||
+					actions.contains(MatchUtils.STR_IPV6_ND_TARGET) || actions.contains(MatchUtils.STR_IPV6_ND_TTL)) {
+				ip6 = true;
+			}
+			if (actions.contains(MatchUtils.STR_NW_SRC) || actions.contains(MatchUtils.STR_NW_DST) || 
+					actions.contains(MatchUtils.STR_ARP_OPCODE) || actions.contains(MatchUtils.STR_ARP_SHA) || 
+					actions.contains(MatchUtils.STR_ARP_DHA) || actions.contains(MatchUtils.STR_ARP_SPA) || 
+					actions.contains(MatchUtils.STR_ARP_DPA) || actions.contains(MatchUtils.STR_ICMP_CODE) || 
+					actions.contains(MatchUtils.STR_ICMP_TYPE)) {
+				ip4 = true;
+			}
+		}
 
-		return "";
-	} */
+		if (ip6 == false && ip4 == false) {
+			return 0; // no actions involving ipv4 or ipv6
+		} else if (ip6 == false && ip4 == true) {
+			return 1; //ipv4
+		} else if (ip6 == true && ip4 == false) {
+			return 2; //ipv6
+		} else {
+			return -1; // conflict of ipv4 and ipv6 actions
+		}
+	}
 
 	/**
 	 * Takes a Static Flow Pusher string in JSON format and parses it into
@@ -195,19 +295,39 @@ public class StaticFlowEntryPusherResource extends ServerResource {
 		try {
 			rowValues = StaticFlowEntries.jsonToStorageEntry(fmJson);
 			String status = null;
-			if (!checkMatchIp(rowValues)) {
+
+			int state = checkFlow(rowValues);
+			if (state == 1) {
 				status = "Warning! Must specify eth_type of IPv4/IPv6 to " +
 						"match on IPv4/IPv6 fields! The flow has been discarded.";
 				log.error(status);
-			} else {
-				status = "Entry pushed";
+			} else if (state == 2) {
+				status = "Warning! eth_type not recognized! The flow has been discarded.";
+				log.error(status);
+			} else if (state == 3) {
+				status = "Warning! Must specify ip_proto to match! The flow has been discarded.";
+				log.error(status);
+			} else if (state == 4) {
+				status = "Warning! ip_proto invalid! The flow has been discarded.";
+				log.error(status);
+			} else if (state == 5) {
+				status = "Warning! Must specify icmp6_type to match! The flow has been discarded.";
+				log.error(status);
+			} else if (state == 6) {
+				status = "Warning! icmp6_type invalid! The flow has been discarded.";
+				log.error(status);
+			} else if (state == 7) {
+				status = "Warning! IPv4 & IPv6 fields cannot be specified in the same flow! The flow has been discarded.";
+				log.error(status);
+			} else if (state == 0) {
+				status = "Entry pushed";            
+				storageSource.insertRowAsync(StaticFlowEntryPusher.TABLE_NAME, rowValues);
 			}
-			storageSource.insertRowAsync(StaticFlowEntryPusher.TABLE_NAME, rowValues);
 			return ("{\"status\" : \"" + status + "\"}");
 		} catch (IOException e) {
 			log.error("Error parsing push flow mod request: " + fmJson, e);
 			return "{\"status\" : \"Error! Could not parse flod mod, see log for details.\"}";
-		}
+		}        
 	}
 
 	@Delete
diff --git a/src/main/java/net/floodlightcontroller/util/ActionUtils.java b/src/main/java/net/floodlightcontroller/util/ActionUtils.java
index c37d8b55489f00ed4e92b4634b8481f439ac1bd0..f496304ec743ff609cd69bf48fdaa63207fd391f 100644
--- a/src/main/java/net/floodlightcontroller/util/ActionUtils.java
+++ b/src/main/java/net/floodlightcontroller/util/ActionUtils.java
@@ -46,11 +46,19 @@ import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv4Code;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv4Type;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv6Code;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv6Type;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpDscp;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpEcn;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpProto;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4Dst;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4Src;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6Dst;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6Flabel;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6NdSll;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6NdTarget;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6NdTll;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6Src;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmMetadata;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsLabel;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsTc;
@@ -67,6 +75,8 @@ import org.projectfloodlight.openflow.types.EthType;
 import org.projectfloodlight.openflow.types.ICMPv4Code;
 import org.projectfloodlight.openflow.types.ICMPv4Type;
 import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.IPv6Address;
+import org.projectfloodlight.openflow.types.IPv6FlowLabel;
 import org.projectfloodlight.openflow.types.IpDscp;
 import org.projectfloodlight.openflow.types.IpEcn;
 import org.projectfloodlight.openflow.types.IpProtocol;
@@ -134,192 +144,208 @@ public class ActionUtils {
 	 */
 
 	/**
-     * Returns a String representation of all the OpenFlow actions.
-     * @param actions; A list of OFActions to encode into one string
-     * @return A dpctl-style string of the actions
-     */
-    @LogMessageDoc(level="ERROR",
-            message="Could not decode action {action}",
-            explanation="A static flow entry contained an invalid action",
-            recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
-    public static String actionsToString(List<OFAction> actions, Logger log) {
-        StringBuilder sb = new StringBuilder();
-        for (OFAction a : actions) {
-            if (sb.length() > 0) {
-                sb.append(',');
-            }
-            switch(a.getType()) {
-                case OUTPUT:
-                    sb.append(STR_OUTPUT + "=" + Integer.toString(((OFActionOutput)a).getPort().getPortNumber()));
-                    break;
-                case ENQUEUE:
-                    long queue = ((OFActionEnqueue)a).getQueueId();
-                    OFPort port = ((OFActionEnqueue)a).getPort();
-                    sb.append(STR_ENQUEUE + "=" + Integer.toString(port.getPortNumber()) + ":0x" + String.format("%02x", queue));
-                    break;
-                case STRIP_VLAN:
-                    sb.append(STR_VLAN_STRIP);
-                    break;
-                case POP_VLAN:
-                    sb.append(STR_VLAN_POP);
-                    break;
-                case PUSH_VLAN:
-                    sb.append(STR_VLAN_PUSH + "=" + Integer.toString(((OFActionPushVlan)a).getEthertype().getValue()));
-                    break;
-                case SET_VLAN_VID:
-                    sb.append(STR_VLAN_SET_VID + "=" + Short.toString(((OFActionSetVlanVid)a).getVlanVid().getVlan()));
-                    break;
-                case SET_VLAN_PCP:
-                    sb.append(STR_VLAN_SET_PCP + "=" + Byte.toString(((OFActionSetVlanPcp)a).getVlanPcp().getValue()));
-                    break;
-                case SET_QUEUE:
-                	sb.append(STR_QUEUE_SET + "=" + Long.toString(((OFActionSetQueue)a).getQueueId()));
-                case SET_DL_SRC:
-                    sb.append(STR_DL_SRC_SET + "=" +  ((OFActionSetDlSrc)a).getDlAddr().toString());
-                    break;
-                case SET_DL_DST:
-                    sb.append(STR_DL_DST_SET + "=" + ((OFActionSetDlDst)a).getDlAddr().toString());
-                    break;
-                case SET_NW_ECN:
-                    sb.append(STR_NW_ECN_SET + "=" + Byte.toString(((OFActionSetNwEcn)a).getNwEcn().getEcnValue()));
-                    break;
-                case SET_NW_TOS:
-                    sb.append(STR_NW_TOS_SET + "=" + Short.toString(((OFActionSetNwTos)a).getNwTos()));
-                    break;
-                case SET_NW_TTL:
-                    sb.append(STR_NW_TTL_SET + "=" + Short.toString(((OFActionSetNwTtl)a).getNwTtl()));
-                    break;
-                case DEC_NW_TTL:
-                    sb.append(STR_NW_TTL_DEC);
-                    break;
-                case SET_MPLS_LABEL:
-                	sb.append(STR_MPLS_LABEL_SET + "=" + Long.toString(((OFActionSetMplsLabel)a).getMplsLabel()));
-                	break;
-                case SET_MPLS_TC:
-                	sb.append(STR_MPLS_TC_SET + "=" + Short.toString(((OFActionSetMplsTc)a).getMplsTc()));
-                	break;
-                case SET_MPLS_TTL:
-                	sb.append(STR_MPLS_TTL_SET + "=" + Short.toString(((OFActionSetMplsTtl)a).getMplsTtl()));
-                	break;
-                case DEC_MPLS_TTL:
-                	sb.append(STR_MPLS_TTL_DEC);
-                	break;
-                case PUSH_MPLS:
-                    sb.append(STR_MPLS_PUSH + "=" + Integer.toString(((OFActionPushMpls)a).getEthertype().getValue()));
-                    break;
-                case POP_MPLS:
-                    sb.append(STR_MPLS_POP + "=" + Integer.toString(((OFActionPopMpls)a).getEthertype().getValue()));
-                    break;
-                case SET_NW_SRC:
-                    sb.append(STR_NW_SRC_SET + "=" + ((OFActionSetNwSrc)a).getNwAddr().toString());
-                    break;
-                case SET_NW_DST:
-                    sb.append(STR_NW_DST_SET + "=" + ((OFActionSetNwDst)a).getNwAddr().toString());
-                    break;
-                case SET_TP_SRC:
-                    sb.append(STR_TP_SRC_SET + "=" + ((OFActionSetTpSrc)a).getTpPort().toString());
-                    break;
-                case SET_TP_DST:
-                    sb.append(STR_TP_DST_SET + "=" + ((OFActionSetTpDst)a).getTpPort().toString());
-                    break;
-                case COPY_TTL_IN:
-                	sb.append(STR_TTL_IN_COPY);
-                	break;
-                case COPY_TTL_OUT:
-                	sb.append(STR_TTL_OUT_COPY);
-                	break;
-                case PUSH_PBB:
-                	sb.append(STR_PBB_PUSH + "=" + Integer.toString(((OFActionPushPbb)a).getEthertype().getValue()));
-                	break;
-                case POP_PBB:
-                	sb.append(STR_PBB_POP);
-                	break;
-                case EXPERIMENTER:
-                	sb.append(STR_EXPERIMENTER + "=" + Long.toString(((OFActionExperimenter)a).getExperimenter()));
-                	break;
-                case GROUP:
-                	sb.append(STR_GROUP + "=" + Integer.toString(((OFActionGroup)a).getGroup().getGroupNumber()));
-                	break;
-                case SET_FIELD:
-                	log.debug("Got Set-Field action. Setting " + ((OFActionSetField)a));
-                	/* ARP */
-                	if (((OFActionSetField)a).getField() instanceof OFOxmArpOp) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_OPCODE + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmArpOp) ((OFActionSetField) a).getField()).getValue().getOpcode()));
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmArpSha) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_SHA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpSha) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmArpTha) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_DHA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpTha) ((OFActionSetField) a).getField()).getValue().toString());
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmArpSpa) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_SPA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_DPA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString()); 
-                	} 
-                	/* DATA LAYER */
-                	  else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_TYPE + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue()));
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmEthSrc) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_SRC + MatchUtils.SET_FIELD_DELIM + ((OFOxmEthSrc) ((OFActionSetField) a).getField()).getValue().toString());
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmEthDst) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_DST + MatchUtils.SET_FIELD_DELIM + ((OFOxmEthDst) ((OFActionSetField) a).getField()).getValue().toString()); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmVlanVid) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_VLAN + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmVlanVid) ((OFActionSetField) a).getField()).getValue().getVlan())); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmVlanPcp) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_VLAN_PCP + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmVlanPcp) ((OFActionSetField) a).getField()).getValue().getValue())); 
-                	} 
-                	/* ICMP */
-                	  else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Code) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ICMP_CODE + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode())); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ICMP_TYPE + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType())); 
-                	} 
-                	/* NETWORK LAYER */
-                	  else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_PROTO + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber())); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Src) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_SRC + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString()); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_DST + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) { //TODO @Ryan ECN and DSCP need to have their own columns for OF1.3....
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_ECN + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue())); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_DSCP + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue())); 
-                	} 
-                	/* TRANSPORT LAYER, TCP, UDP, and SCTP */
-                	  else if (((OFActionSetField)a).getField() instanceof OFOxmTcpSrc) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_TCP_SRC + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmTcpSrc) ((OFActionSetField) a).getField()).getValue().getPort())); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmTcpDst) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_TCP_DST + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmTcpDst) ((OFActionSetField) a).getField()).getValue().getPort())); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmUdpSrc) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_UDP_SRC + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmUdpSrc) ((OFActionSetField) a).getField()).getValue().getPort())); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmUdpDst) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_UDP_DST + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmUdpDst) ((OFActionSetField) a).getField()).getValue().getPort())); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmSctpSrc) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_SCTP_SRC + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmSctpSrc) ((OFActionSetField) a).getField()).getValue().getPort())); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmSctpDst) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_SCTP_DST + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmSctpDst) ((OFActionSetField) a).getField()).getValue().getPort())); 
-                	}
-                	/* MPLS */
-                	  else if (((OFActionSetField)a).getField() instanceof OFOxmMplsLabel) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_MPLS_LABEL + MatchUtils.SET_FIELD_DELIM + Long.toString(((OFOxmMplsLabel) ((OFActionSetField) a).getField()).getValue().getValue())); 
-                	} else if (((OFActionSetField)a).getField() instanceof OFOxmMplsTc) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_MPLS_TC + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmMplsTc) ((OFActionSetField) a).getField()).getValue().getValue())); 
-                	} // MPLS_BOS not implemented in loxi
-                	/* METADATA */
-                	else if (((OFActionSetField)a).getField() instanceof OFOxmMetadata) {
-                    	sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_METADATA + MatchUtils.SET_FIELD_DELIM + Long.toString(((OFOxmMetadata) ((OFActionSetField) a).getField()).getValue().getValue().getValue())); 
-                	} else {
-                		log.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a));
-                	}
-                	break;
-                default:
-                    log.error("Could not decode action: {}", a);
-                    break;
-            }
-                
-        }
-        return sb.toString();
-    }
-	
+	 * Returns a String representation of all the OpenFlow actions.
+	 * @param actions; A list of OFActions to encode into one string
+	 * @return A dpctl-style string of the actions
+	 */
+	@LogMessageDoc(level="ERROR",
+			message="Could not decode action {action}",
+			explanation="A static flow entry contained an invalid action",
+			recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
+	public static String actionsToString(List<OFAction> actions, Logger log) {
+		StringBuilder sb = new StringBuilder();
+		for (OFAction a : actions) {
+			if (sb.length() > 0) {
+				sb.append(',');
+			}
+			switch(a.getType()) {
+			case OUTPUT:
+				sb.append(STR_OUTPUT + "=" + Integer.toString(((OFActionOutput)a).getPort().getPortNumber()));
+				break;
+			case ENQUEUE:
+				long queue = ((OFActionEnqueue)a).getQueueId();
+				OFPort port = ((OFActionEnqueue)a).getPort();
+				sb.append(STR_ENQUEUE + "=" + Integer.toString(port.getPortNumber()) + ":0x" + String.format("%02x", queue));
+				break;
+			case STRIP_VLAN:
+				sb.append(STR_VLAN_STRIP);
+				break;
+			case POP_VLAN:
+				sb.append(STR_VLAN_POP);
+				break;
+			case PUSH_VLAN:
+				sb.append(STR_VLAN_PUSH + "=" + Integer.toString(((OFActionPushVlan)a).getEthertype().getValue()));
+				break;
+			case SET_VLAN_VID:
+				sb.append(STR_VLAN_SET_VID + "=" + Short.toString(((OFActionSetVlanVid)a).getVlanVid().getVlan()));
+				break;
+			case SET_VLAN_PCP:
+				sb.append(STR_VLAN_SET_PCP + "=" + Byte.toString(((OFActionSetVlanPcp)a).getVlanPcp().getValue()));
+				break;
+			case SET_QUEUE:
+				sb.append(STR_QUEUE_SET + "=" + Long.toString(((OFActionSetQueue)a).getQueueId()));
+			case SET_DL_SRC:
+				sb.append(STR_DL_SRC_SET + "=" +  ((OFActionSetDlSrc)a).getDlAddr().toString());
+				break;
+			case SET_DL_DST:
+				sb.append(STR_DL_DST_SET + "=" + ((OFActionSetDlDst)a).getDlAddr().toString());
+				break;
+			case SET_NW_ECN:
+				sb.append(STR_NW_ECN_SET + "=" + Byte.toString(((OFActionSetNwEcn)a).getNwEcn().getEcnValue()));
+				break;
+			case SET_NW_TOS:
+				sb.append(STR_NW_TOS_SET + "=" + Short.toString(((OFActionSetNwTos)a).getNwTos()));
+				break;
+			case SET_NW_TTL:
+				sb.append(STR_NW_TTL_SET + "=" + Short.toString(((OFActionSetNwTtl)a).getNwTtl()));
+				break;
+			case DEC_NW_TTL:
+				sb.append(STR_NW_TTL_DEC);
+				break;
+			case SET_MPLS_LABEL:
+				sb.append(STR_MPLS_LABEL_SET + "=" + Long.toString(((OFActionSetMplsLabel)a).getMplsLabel()));
+				break;
+			case SET_MPLS_TC:
+				sb.append(STR_MPLS_TC_SET + "=" + Short.toString(((OFActionSetMplsTc)a).getMplsTc()));
+				break;
+			case SET_MPLS_TTL:
+				sb.append(STR_MPLS_TTL_SET + "=" + Short.toString(((OFActionSetMplsTtl)a).getMplsTtl()));
+				break;
+			case DEC_MPLS_TTL:
+				sb.append(STR_MPLS_TTL_DEC);
+				break;
+			case PUSH_MPLS:
+				sb.append(STR_MPLS_PUSH + "=" + Integer.toString(((OFActionPushMpls)a).getEthertype().getValue()));
+				break;
+			case POP_MPLS:
+				sb.append(STR_MPLS_POP + "=" + Integer.toString(((OFActionPopMpls)a).getEthertype().getValue()));
+				break;
+			case SET_NW_SRC:
+				sb.append(STR_NW_SRC_SET + "=" + ((OFActionSetNwSrc)a).getNwAddr().toString());
+				break;
+			case SET_NW_DST:
+				sb.append(STR_NW_DST_SET + "=" + ((OFActionSetNwDst)a).getNwAddr().toString());
+				break;
+			case SET_TP_SRC:
+				sb.append(STR_TP_SRC_SET + "=" + ((OFActionSetTpSrc)a).getTpPort().toString());
+				break;
+			case SET_TP_DST:
+				sb.append(STR_TP_DST_SET + "=" + ((OFActionSetTpDst)a).getTpPort().toString());
+				break;
+			case COPY_TTL_IN:
+				sb.append(STR_TTL_IN_COPY);
+				break;
+			case COPY_TTL_OUT:
+				sb.append(STR_TTL_OUT_COPY);
+				break;
+			case PUSH_PBB:
+				sb.append(STR_PBB_PUSH + "=" + Integer.toString(((OFActionPushPbb)a).getEthertype().getValue()));
+				break;
+			case POP_PBB:
+				sb.append(STR_PBB_POP);
+				break;
+			case EXPERIMENTER:
+				sb.append(STR_EXPERIMENTER + "=" + Long.toString(((OFActionExperimenter)a).getExperimenter()));
+				break;
+			case GROUP:
+				sb.append(STR_GROUP + "=" + Integer.toString(((OFActionGroup)a).getGroup().getGroupNumber()));
+				break;
+			case SET_FIELD:
+				log.debug("Got Set-Field action. Setting " + ((OFActionSetField)a));
+				/* ARP */
+				if (((OFActionSetField)a).getField() instanceof OFOxmArpOp) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_OPCODE + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmArpOp) ((OFActionSetField) a).getField()).getValue().getOpcode()));
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmArpSha) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_SHA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpSha) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmArpTha) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_DHA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpTha) ((OFActionSetField) a).getField()).getValue().toString());
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmArpSpa) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_SPA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_DPA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString()); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdSll) {                		
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_IPV6_ND_SSL + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv6NdSll) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdTll) {                		
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_IPV6_ND_TTL + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv6NdTll) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdTarget) {                		
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_IPV6_ND_TARGET + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv6NdTarget) ((OFActionSetField) a).getField()).getValue().toString()); 
+				}
+				/* DATA LAYER */
+				else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_TYPE + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue()));
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmEthSrc) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_SRC + MatchUtils.SET_FIELD_DELIM + ((OFOxmEthSrc) ((OFActionSetField) a).getField()).getValue().toString());
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmEthDst) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_DST + MatchUtils.SET_FIELD_DELIM + ((OFOxmEthDst) ((OFActionSetField) a).getField()).getValue().toString()); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmVlanVid) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_VLAN + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmVlanVid) ((OFActionSetField) a).getField()).getValue().getVlan())); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmVlanPcp) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_VLAN_PCP + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmVlanPcp) ((OFActionSetField) a).getField()).getValue().getValue())); 
+				} 
+				/* ICMP */
+				else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Code) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ICMP_CODE + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode())); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ICMP_TYPE + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType())); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv6Code) {                		
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ICMPV6_CODE + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIcmpv6Code) ((OFActionSetField) a).getField()).getValue().getRaw())); 
+				}  else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv6Type) {                		
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ICMPV6_TYPE + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIcmpv6Type) ((OFActionSetField) a).getField()).getValue().getRaw())); 
+				}
+				/* NETWORK LAYER */
+				else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_PROTO + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber())); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Src) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_SRC + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString()); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_DST + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Src) {                		
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_IPV6_SRC + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv6Src) ((OFActionSetField) a).getField()).getValue().toString()); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Dst) {                		
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_IPV6_DST + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv6Dst) ((OFActionSetField) a).getField()).getValue().toString()); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Flabel) {                		
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_IPV6_FLOW_LABEL + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv6Flabel) ((OFActionSetField) a).getField()).getValue().toString()); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) { //TODO @Ryan ECN and DSCP need to have their own columns for OF1.3....
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_ECN + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue())); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_DSCP + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue())); 
+				} 
+				/* TRANSPORT LAYER, TCP, UDP, and SCTP */
+				else if (((OFActionSetField)a).getField() instanceof OFOxmTcpSrc) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_TCP_SRC + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmTcpSrc) ((OFActionSetField) a).getField()).getValue().getPort())); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmTcpDst) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_TCP_DST + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmTcpDst) ((OFActionSetField) a).getField()).getValue().getPort())); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmUdpSrc) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_UDP_SRC + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmUdpSrc) ((OFActionSetField) a).getField()).getValue().getPort())); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmUdpDst) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_UDP_DST + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmUdpDst) ((OFActionSetField) a).getField()).getValue().getPort())); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmSctpSrc) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_SCTP_SRC + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmSctpSrc) ((OFActionSetField) a).getField()).getValue().getPort())); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmSctpDst) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_SCTP_DST + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmSctpDst) ((OFActionSetField) a).getField()).getValue().getPort())); 
+				}
+				/* MPLS */
+				else if (((OFActionSetField)a).getField() instanceof OFOxmMplsLabel) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_MPLS_LABEL + MatchUtils.SET_FIELD_DELIM + Long.toString(((OFOxmMplsLabel) ((OFActionSetField) a).getField()).getValue().getValue())); 
+				} else if (((OFActionSetField)a).getField() instanceof OFOxmMplsTc) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_MPLS_TC + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmMplsTc) ((OFActionSetField) a).getField()).getValue().getValue())); 
+				} // MPLS_BOS not implemented in loxi
+				/* METADATA */
+				else if (((OFActionSetField)a).getField() instanceof OFOxmMetadata) {
+					sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_METADATA + MatchUtils.SET_FIELD_DELIM + Long.toString(((OFOxmMetadata) ((OFActionSetField) a).getField()).getValue().getValue().getValue())); 
+				} else {
+					log.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a));
+				}
+				break;
+			default:
+				log.error("Could not decode action: {}", a);
+				break;
+			}
+
+		}
+		return sb.toString();
+	}
+
 	/**
 	 * Parses OFFlowMod actions from strings.
 	 * @param fmb The OFFlowMod.Builder to set the actions for
@@ -335,7 +361,7 @@ public class ActionUtils {
 		if (bigString != null) {
 			bigString = bigString.toLowerCase();
 			String[] bigStringSplit = bigString.split(","); // split into separate action=value or action=key@value pairs
-			
+
 			String[] tmp;
 			ArrayDeque<String[]> actionToDecode = new ArrayDeque<String[]>();
 			for (int i = 0; i < bigStringSplit.length; i++) {
@@ -345,7 +371,7 @@ public class ActionUtils {
 				}
 				actionToDecode.add(tmp); // actionToDecode contains [key, value] pairs. Create a queue of pairs to process.
 			}	
-				
+
 			while (!actionToDecode.isEmpty()) {
 				String[] keyPair = actionToDecode.pollFirst();
 				String key;
@@ -358,9 +384,9 @@ public class ActionUtils {
 					key = keyPair[0];
 					pair = keyPair[1];
 				}
-				
+
 				OFAction a = null;
-				
+
 				switch (key) {
 				case STR_OUTPUT:
 					a = decode_output(pair, fmb.getVersion(), log);
@@ -415,6 +441,25 @@ public class ActionUtils {
 						.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildArpTpa().setValue(IPv4Address.of(actionData[1])).build())
 						.build();
 						break;
+
+						//sanjivini						
+					case MatchUtils.STR_IPV6_ND_SSL:
+						a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+						.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6NdSll().setValue(MacAddress.of(actionData[1])).build())
+						.build();
+						break;
+					case MatchUtils.STR_IPV6_ND_TTL:
+						a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+						.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6NdTll().setValue(MacAddress.of(actionData[1])).build())
+						.build();
+						break;
+					case MatchUtils.STR_IPV6_ND_TARGET:
+						a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+						.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6NdTarget().setValue(IPv6Address.of(actionData[1])).build())
+						.build();
+						break;
+						//sanjivini		
+
 					case MatchUtils.STR_DL_TYPE:
 						if (actionData[1].startsWith("0x")) {
 							a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
@@ -477,9 +522,35 @@ public class ActionUtils {
 						} else {
 							a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
 									.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIcmpv4Type().setValue(ICMPv4Type.of(Short.parseShort(actionData[1]))).build())
-							.build();
+									.build();
 						}
 						break;
+
+						//sanjivini
+					case MatchUtils.STR_ICMPV6_CODE:
+						if (actionData[1].startsWith("0x")) {
+							a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+									.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIcmpv6Code().setValue(U8.of(Short.parseShort(actionData[1].replaceFirst("0x", ""), 16))).build())
+									.build();
+						} else {
+							a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+									.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIcmpv6Code().setValue(U8.of(Short.parseShort(actionData[1]))).build())
+									.build();
+						}
+						break;
+					case MatchUtils.STR_ICMPV6_TYPE:
+						if (actionData[1].startsWith("0x")) {
+							a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+									.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIcmpv6Type().setValue(U8.of(Short.parseShort(actionData[1].replaceFirst("0x", ""), 16))).build())
+									.build();
+						} else {
+							a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+									.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIcmpv6Type().setValue(U8.of(Short.parseShort(actionData[1]))).build())
+									.build();
+						}
+						break;
+						//sanjivini						
+
 					case MatchUtils.STR_NW_PROTO:
 						if (actionData[1].startsWith("0x")) {
 							a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
@@ -501,6 +572,31 @@ public class ActionUtils {
 						.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv4Dst().setValue(IPv4Address.of(actionData[1])).build())
 						.build();						
 						break;
+
+						//sanjivini						
+					case MatchUtils.STR_IPV6_SRC:
+						a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+						.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6Src().setValue(IPv6Address.of(actionData[1])).build())
+						.build();						
+						break;
+					case MatchUtils.STR_IPV6_DST:
+						a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+						.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6Dst().setValue(IPv6Address.of(actionData[1])).build())
+						.build();						
+						break;
+					case MatchUtils.STR_IPV6_FLOW_LABEL:
+						if (actionData[1].startsWith("0x")) {
+							a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+									.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6Flabel().setValue(IPv6FlowLabel.of(Integer.parseInt(actionData[1].replaceFirst("0x", ""), 16))).build())
+									.build();			
+						} else {
+							a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
+									.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6Flabel().setValue(IPv6FlowLabel.of(Integer.parseInt(actionData[1]))).build())
+									.build();
+						}
+						break;
+						//sanjivini						
+
 					case MatchUtils.STR_NW_ECN:
 						if (actionData[1].startsWith("0x")) {
 							a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
@@ -577,8 +673,8 @@ public class ActionUtils {
 						break;
 					case MatchUtils.STR_MPLS_BOS:
 						a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
-								.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildMplsBos().setValue(OFBooleanValue.of(Boolean.parseBoolean(actionData[1]))).build()) // interprets anything other than "true" as false
-								.build();
+						.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildMplsBos().setValue(OFBooleanValue.of(Boolean.parseBoolean(actionData[1]))).build()) // interprets anything other than "true" as false
+						.build();
 						break;
 					case MatchUtils.STR_METADATA:
 						if (actionData[1].startsWith("0x")) {
@@ -967,7 +1063,7 @@ public class ActionUtils {
 		}
 		return null;
 	}
-	
+
 	/**
 	 * Parse set_dl_dst actions.
 	 * The key and delimiter for the action should be omitted, and only the
diff --git a/src/main/java/net/floodlightcontroller/util/InstructionUtils.java b/src/main/java/net/floodlightcontroller/util/InstructionUtils.java
index 013c87d36073f4b7d8f189822f4779a39d0d1882..43a6110ce7984ccc3f7c7e1cf8fc3ecce720ef20 100644
--- a/src/main/java/net/floodlightcontroller/util/InstructionUtils.java
+++ b/src/main/java/net/floodlightcontroller/util/InstructionUtils.java
@@ -28,7 +28,7 @@ import sun.reflect.generics.reflectiveObjects.NotImplementedException;
  *
  */
 public class InstructionUtils {
-	public static final String STR_GOTO_TABLE = "goto_table";
+	public static final String STR_GOTO_TABLE = "instruction_goto_table";
 	public static final String STR_WRITE_METADATA = "instruction_write_metadata";
 	public static final String STR_WRITE_ACTIONS = "instruction_write_actions";
 	public static final String STR_APPLY_ACTIONS = "instruction_apply_actions";
@@ -169,7 +169,7 @@ public class InstructionUtils {
 	 * @param log
 	 * @return
 	 */
-	public static String writeActionsToString(OFInstructionWriteActions inst, Logger log) {
+	public static String writeActionsToString(OFInstructionWriteActions inst, Logger log) throws Exception {
 		return ActionUtils.actionsToString(inst.getActions(), log);
 	}
 
@@ -200,7 +200,7 @@ public class InstructionUtils {
 	 * @param log
 	 * @return
 	 */
-	public static String applyActionsToString(OFInstructionApplyActions inst, Logger log) {
+	public static String applyActionsToString(OFInstructionApplyActions inst, Logger log) throws Exception {
 		return ActionUtils.actionsToString(inst.getActions(), log);
 	}
 
diff --git a/src/main/java/net/floodlightcontroller/util/MatchUtils.java b/src/main/java/net/floodlightcontroller/util/MatchUtils.java
index ef7a94abed4f88e0cd7c9915620bbf7af0c9a1cb..f0828c93967d5b4c64df1fa0d035aa61e0bae641 100644
--- a/src/main/java/net/floodlightcontroller/util/MatchUtils.java
+++ b/src/main/java/net/floodlightcontroller/util/MatchUtils.java
@@ -13,6 +13,9 @@ import org.projectfloodlight.openflow.types.ICMPv4Code;
 import org.projectfloodlight.openflow.types.ICMPv4Type;
 import org.projectfloodlight.openflow.types.IPv4Address;
 import org.projectfloodlight.openflow.types.IPv4AddressWithMask;
+import org.projectfloodlight.openflow.types.IPv6Address;
+import org.projectfloodlight.openflow.types.IPv6AddressWithMask;
+import org.projectfloodlight.openflow.types.IPv6FlowLabel;
 import org.projectfloodlight.openflow.types.IpDscp;
 import org.projectfloodlight.openflow.types.IpEcn;
 import org.projectfloodlight.openflow.types.IpProtocol;
@@ -330,6 +333,9 @@ public class MatchUtils {
 	 *             on unexpected key or value
 	 */
 	public static Match fromString(String match, OFVersion ofVersion) throws IllegalArgumentException {
+		
+		boolean ver10 = false;
+		
 		if (match.equals("") || match.equalsIgnoreCase("any") || match.equalsIgnoreCase("all") || match.equals("[]")) {
 			match = "Match[]";
 		}
@@ -356,6 +362,14 @@ public class MatchUtils {
 
 		Match.Builder mb = OFFactories.getFactory(ofVersion).buildMatch();
 
+//sanjivini		
+
+		//Determine if the OF version is 1.0 before adding a flow
+				if (ofVersion.equals(OFVersion.OF_10)) {
+					ver10 = true;
+				}
+//sanjivini
+		
 		while (!llValues.isEmpty()) {
 			IpProtocol ipProto = null;
 			String[] key_value = llValues.pollFirst(); // pop off the first element; this completely removes it from the queue.
@@ -396,6 +410,28 @@ public class MatchUtils {
 			case STR_NW_SRC:
 				mb.setMasked(MatchField.IPV4_SRC, IPv4AddressWithMask.of(key_value[1]));
 				break;
+				
+//sanjivini
+			case STR_IPV6_DST:
+				if (ver10 == true) {
+					throw new IllegalArgumentException("OF Version incompatible");
+				}
+				mb.setMasked(MatchField.IPV6_DST, IPv6AddressWithMask.of(key_value[1]));
+				break;
+			case STR_IPV6_SRC:
+				if (ver10 == true) {
+					throw new IllegalArgumentException("OF Version incompatible");
+				}
+				mb.setMasked(MatchField.IPV6_SRC, IPv6AddressWithMask.of(key_value[1]));
+				break;
+			case STR_IPV6_FLOW_LABEL:
+				if (ver10 == true) {
+					throw new IllegalArgumentException("OF Version incompatible");
+				}
+				mb.setExact(MatchField.IPV6_FLABEL, IPv6FlowLabel.of(Integer.parseInt(key_value[1])));
+				break;
+//sanjivini	
+				
 			case STR_NW_PROTO:
 				if (key_value[1].startsWith("0x")) {
 					mb.setExact(MatchField.IP_PROTO, IpProtocol.of(Short.valueOf(key_value[1].replaceFirst("0x", ""), 16)));
@@ -504,6 +540,45 @@ public class MatchUtils {
 					mb.setExact(MatchField.ICMPV4_CODE, ICMPv4Code.of(Short.parseShort(key_value[1])));
 				}
 				break;
+				
+//sanjivini
+			case STR_ICMPV6_TYPE:
+				if (ver10 == true) {
+					throw new IllegalArgumentException("OF Version incompatible");
+					//throw new Exception("OF Version incompatible");
+				}
+				mb.setExact(MatchField.ICMPV6_TYPE, U8.of(Short.parseShort(key_value[1])));
+				break;
+			case STR_ICMPV6_CODE:
+				if (ver10 == true) {
+					throw new IllegalArgumentException("OF Version incompatible");
+					//throw new Exception("OF Version incompatible");
+				}
+				mb.setExact(MatchField.ICMPV6_CODE, U8.of(Short.parseShort(key_value[1])));
+				break;
+			case STR_IPV6_ND_SSL:
+				if (ver10 == true) {
+					throw new IllegalArgumentException("OF Version incompatible");
+					//throw new Exception("OF Version incompatible");
+				}
+				mb.setExact(MatchField.IPV6_ND_SLL, MacAddress.of(key_value[1]));
+				break;
+			case STR_IPV6_ND_TTL:
+				if (ver10 == true) {
+					throw new IllegalArgumentException("OF Version incompatible");
+					//throw new Exception("OF Version incompatible");
+				}
+				mb.setExact(MatchField.IPV6_ND_TLL, MacAddress.of(key_value[1]));
+				break;
+			case STR_IPV6_ND_TARGET:
+				if (ver10 == true) {
+					throw new IllegalArgumentException("OF Version incompatible");
+					//throw new Exception("OF Version incompatible");
+				}
+				mb.setExact(MatchField.IPV6_ND_TARGET, IPv6Address.of(key_value[1]));
+				break;
+//sanjivini	
+				
 			case STR_ARP_OPCODE:
 				if (key_value[1].startsWith("0x")) {
 					mb.setExact(MatchField.ARP_OP, ArpOpcode.of(Integer.parseInt(key_value[1].replaceFirst("0x", ""), 16)));