diff --git a/src/main/java/net/floodlightcontroller/firewall/Firewall.java b/src/main/java/net/floodlightcontroller/firewall/Firewall.java
index 0b2a849b2d4f936d9d3a49bf6f3e8cbdcb6265e2..3a78c9d1eb6f5089b41831e621538eb808b3e80a 100644
--- a/src/main/java/net/floodlightcontroller/firewall/Firewall.java
+++ b/src/main/java/net/floodlightcontroller/firewall/Firewall.java
@@ -28,6 +28,7 @@ import org.projectfloodlight.openflow.protocol.OFMessage;
 import org.projectfloodlight.openflow.protocol.OFPacketIn;
 import org.projectfloodlight.openflow.protocol.OFType;
 import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.protocol.match.Match;
 import org.projectfloodlight.openflow.protocol.match.MatchField;
 import org.projectfloodlight.openflow.types.DatapathId;
 import org.projectfloodlight.openflow.types.EthType;
@@ -52,12 +53,15 @@ import java.util.ArrayList;
 
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.packet.IPv4;
+import net.floodlightcontroller.packet.TCP;
+import net.floodlightcontroller.packet.UDP;
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.routing.IRoutingDecision;
 import net.floodlightcontroller.routing.RoutingDecision;
 import net.floodlightcontroller.storage.IResultSet;
 import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.storage.StorageException;
+import net.floodlightcontroller.util.MatchUtils;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -481,7 +485,38 @@ public class Firewall implements IFirewallService, IOFMessageListener,
         // make a pair of rule and wildcards, then return it
         RuleMatchPair rmp = new RuleMatchPair();
         rmp.rule = matched_rule;
-        if (matched_rule == null || matched_rule.action == FirewallRule.FirewallAction.DROP) {
+        if (matched_rule == null) {
+        	/*
+        	 * No rule was found, so drop the packet with as specific 
+        	 * of a drop rule as possible as not to interfere with other
+        	 * firewall rules.
+        	 */
+        	Match.Builder mb = MatchUtils.createRetentiveBuilder(pi.getMatch()); // capture the ingress port
+        	mb.setExact(MatchField.ETH_SRC, eth.getSourceMACAddress())
+        		.setExact(MatchField.ETH_DST, eth.getDestinationMACAddress())
+        		.setExact(MatchField.ETH_TYPE, EthType.of(eth.getEtherType()));
+        	
+        	if (mb.get(MatchField.ETH_TYPE).equals(EthType.IPv4)) {
+        		IPv4 ipv4 = (IPv4) eth.getPayload();
+        		mb.setExact(MatchField.IPV4_SRC, ipv4.getSourceAddress())
+        			.setExact(MatchField.IPV4_DST, ipv4.getDestinationAddress())
+        			.setExact(MatchField.IP_PROTO, ipv4.getProtocol());
+        		
+        		if (mb.get(MatchField.IP_PROTO).equals(IpProtocol.TCP)) {
+        			TCP tcp = (TCP) ipv4.getPayload();
+        			mb.setExact(MatchField.TCP_SRC, tcp.getSourcePort())
+        			.setExact(MatchField.TCP_DST, tcp.getDestinationPort());
+        		} else if (mb.get(MatchField.IP_PROTO).equals(IpProtocol.UDP)) {
+        			UDP udp = (UDP) ipv4.getPayload();
+        			mb.setExact(MatchField.UDP_SRC, udp.getSourcePort())
+        			.setExact(MatchField.UDP_DST, udp.getDestinationPort());
+        		} else {
+        			// could be ICMP, which will be taken care of via IPv4 src/dst + ip proto
+        		}
+        	}
+        	rmp.match = mb.build();
+            //rmp.match = adp.drop.build(); This inserted a "drop all" rule if no match was found (not what we want to do...)
+        } else if (matched_rule.action == FirewallRule.FirewallAction.DROP) {
             rmp.match = adp.drop.build();
         } else {
             rmp.match = adp.allow.build();
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java b/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java
index 03f9baef2c2e07c9876f2aebaa6abaf758aa1539..773a450e12480cbe2f845b13dee89d98b1d1fc53 100644
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java
+++ b/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java
@@ -69,7 +69,7 @@ public class FirewallResource extends ServerResource {
         // REST API set local subnet mask -- this only makes sense for one subnet
         // will remove later
         if (op.equalsIgnoreCase("subnet-mask")) {
-            return firewall.getSubnetMask();
+            return "{\"subnet-mask\":\"" + firewall.getSubnetMask() + "\"}";
         }
 
         // no known options found
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
index 9f6fc1e217392610017ee4edb00e1a657ab7c9df..441c4305c3ce2f5e18b4f2a12f10a2981e3ecb65 100644
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
+++ b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
@@ -293,10 +293,14 @@ public class FirewallRule implements Comparable<FirewallRule> {
             return false;
         if (action == FirewallRule.FirewallAction.DROP) {
             //wildcards.drop &= ~OFMatch.OFPFW_IN_PORT;
-            adp.drop.setExact(MatchField.IN_PORT, this.in_port);
+        	if (!OFPort.ANY.equals(this.in_port)) {
+        		adp.drop.setExact(MatchField.IN_PORT, this.in_port);
+        	}
         } else {
             //wildcards.allow &= ~OFMatch.OFPFW_IN_PORT;
-            adp.allow.setExact(MatchField.IN_PORT, this.in_port);
+        	if (!OFPort.ANY.equals(this.in_port)) {
+        		adp.allow.setExact(MatchField.IN_PORT, this.in_port);
+        	}
         }
 
         // mac address (src and dst) match?
@@ -304,20 +308,28 @@ public class FirewallRule implements Comparable<FirewallRule> {
             return false;
         if (action == FirewallRule.FirewallAction.DROP) {
             //wildcards.drop &= ~OFMatch.OFPFW_DL_SRC;
-            adp.drop.setExact(MatchField.ETH_SRC, this.dl_src);
+        	if (!MacAddress.NONE.equals(this.dl_src)) {
+        		adp.drop.setExact(MatchField.ETH_SRC, this.dl_src);
+        	}
         } else {
             //wildcards.allow &= ~OFMatch.OFPFW_DL_SRC;
-            adp.allow.setExact(MatchField.ETH_SRC, this.dl_src);
+        	if (!MacAddress.NONE.equals(this.dl_src)) {
+        		adp.allow.setExact(MatchField.ETH_SRC, this.dl_src);
+        	}
         }
 
         if (any_dl_dst == false && !dl_dst.equals(packet.getDestinationMACAddress()))
             return false;
         if (action == FirewallRule.FirewallAction.DROP) {
             //wildcards.drop &= ~OFMatch.OFPFW_DL_DST;
-            adp.drop.setExact(MatchField.ETH_DST, this.dl_dst);
+        	if (!MacAddress.NONE.equals(this.dl_dst)) {
+        		adp.drop.setExact(MatchField.ETH_DST, this.dl_dst);
+        	}
         } else {
             //wildcards.allow &= ~OFMatch.OFPFW_DL_DST;
-            adp.allow.setExact(MatchField.ETH_DST, this.dl_dst);
+        	if (!MacAddress.NONE.equals(this.dl_dst)) {
+        		adp.allow.setExact(MatchField.ETH_DST, this.dl_dst);
+        	}
         }
 
         // dl_type check: ARP, IP
@@ -331,10 +343,14 @@ public class FirewallRule implements Comparable<FirewallRule> {
                 else {
                     if (action == FirewallRule.FirewallAction.DROP) {
                         //wildcards.drop &= ~OFMatch.OFPFW_DL_TYPE;
-                    	adp.drop.setExact(MatchField.ETH_TYPE, this.dl_type);
+                    	if (!EthType.NONE.equals(this.dl_type)) {
+                    		adp.drop.setExact(MatchField.ETH_TYPE, this.dl_type);
+                    	}
                     } else {
                         //wildcards.allow &= ~OFMatch.OFPFW_DL_TYPE;
-                    	adp.allow.setExact(MatchField.ETH_TYPE, this.dl_type);
+                    	if (!EthType.NONE.equals(this.dl_type)) {
+                    		adp.allow.setExact(MatchField.ETH_TYPE, this.dl_type);
+                    	}
                     }
                 }
             } else if (dl_type.equals(EthType.IPv4)) {
@@ -343,10 +359,14 @@ public class FirewallRule implements Comparable<FirewallRule> {
                 else {
                     if (action == FirewallRule.FirewallAction.DROP) {
                         //wildcards.drop &= ~OFMatch.OFPFW_NW_PROTO;
-                    	adp.drop.setExact(MatchField.IP_PROTO, this.nw_proto);
+                    	if (!IpProtocol.NONE.equals(this.nw_proto)) {
+                    		adp.drop.setExact(MatchField.IP_PROTO, this.nw_proto);
+                    	}
                     } else {
                         //wildcards.allow &= ~OFMatch.OFPFW_NW_PROTO;
-                    	adp.allow.setExact(MatchField.IP_PROTO, this.nw_proto);
+                    	if (!IpProtocol.NONE.equals(this.nw_proto)) {
+                    		adp.allow.setExact(MatchField.IP_PROTO, this.nw_proto);
+                    	}
                     }
                     // IP packets, proceed with ip address check
                     pkt_ip = (IPv4) pkt;
@@ -357,11 +377,15 @@ public class FirewallRule implements Comparable<FirewallRule> {
                     if (action == FirewallRule.FirewallAction.DROP) {
                         //wildcards.drop &= ~OFMatch.OFPFW_NW_SRC_ALL;
                         //wildcards.drop |= (nw_src_maskbits << OFMatch.OFPFW_NW_SRC_SHIFT);
-                    	adp.drop.setMasked(MatchField.IPV4_SRC, nw_src_prefix_and_mask);
+                    	if (!IPv4AddressWithMask.NONE.equals(this.nw_src_prefix_and_mask)) {
+                    		adp.drop.setMasked(MatchField.IPV4_SRC, nw_src_prefix_and_mask);
+                    	}
                     } else {
                         //wildcards.allow &= ~OFMatch.OFPFW_NW_SRC_ALL;
                         //wildcards.allow |= (nw_src_maskbits << OFMatch.OFPFW_NW_SRC_SHIFT);
-                    	adp.allow.setMasked(MatchField.IPV4_SRC, nw_src_prefix_and_mask);
+                    	if (!IPv4AddressWithMask.NONE.equals(this.nw_src_prefix_and_mask)) {
+                    		adp.allow.setMasked(MatchField.IPV4_SRC, nw_src_prefix_and_mask);
+                    	}
                     }
 
                     if (any_nw_dst == false && !nw_dst_prefix_and_mask.matches(pkt_ip.getDestinationAddress()))
@@ -369,11 +393,15 @@ public class FirewallRule implements Comparable<FirewallRule> {
                     if (action == FirewallRule.FirewallAction.DROP) {
                         //wildcards.drop &= ~OFMatch.OFPFW_NW_DST_ALL;
                         //wildcards.drop |= (nw_dst_maskbits << OFMatch.OFPFW_NW_DST_SHIFT);
-                    	adp.drop.setMasked(MatchField.IPV4_DST, nw_dst_prefix_and_mask);
+                    	if (!IPv4AddressWithMask.NONE.equals(this.nw_dst_prefix_and_mask)) {
+                    		adp.drop.setMasked(MatchField.IPV4_DST, nw_dst_prefix_and_mask);
+                    	}
                     } else {
                         //wildcards.allow &= ~OFMatch.OFPFW_NW_DST_ALL;
                         //wildcards.allow |= (nw_dst_maskbits << OFMatch.OFPFW_NW_DST_SHIFT);
-                    	adp.allow.setMasked(MatchField.IPV4_DST, nw_dst_prefix_and_mask);
+                    	if (!IPv4AddressWithMask.NONE.equals(this.nw_dst_prefix_and_mask)) {
+                    		adp.allow.setMasked(MatchField.IPV4_DST, nw_dst_prefix_and_mask);
+                    	}
                     }
 
                     // nw_proto check
@@ -403,10 +431,14 @@ public class FirewallRule implements Comparable<FirewallRule> {
                         }
                         if (action == FirewallRule.FirewallAction.DROP) {
                             //wildcards.drop &= ~OFMatch.OFPFW_NW_PROTO;
-                        	adp.drop.setExact(MatchField.IP_PROTO, this.nw_proto);
+                        	if (!IpProtocol.NONE.equals(this.nw_proto)) {
+                        		adp.drop.setExact(MatchField.IP_PROTO, this.nw_proto);
+                        	}
                         } else {
                             //wildcards.allow &= ~OFMatch.OFPFW_NW_PROTO;
-                        	adp.allow.setExact(MatchField.IP_PROTO, this.nw_proto);
+                        	if (!IpProtocol.NONE.equals(this.nw_proto)) {
+                        		adp.allow.setExact(MatchField.IP_PROTO, this.nw_proto);
+                        	}
                         }
 
                         // TCP/UDP source and destination ports match?
@@ -418,16 +450,24 @@ public class FirewallRule implements Comparable<FirewallRule> {
                             if (action == FirewallRule.FirewallAction.DROP) {
                                 //wildcards.drop &= ~OFMatch.OFPFW_TP_SRC;
                                 if (pkt_tcp != null) {
-                                	adp.drop.setExact(MatchField.TCP_SRC, this.tp_src);
+                                	if (!TransportPort.NONE.equals(this.tp_src)) {
+                                		adp.drop.setExact(MatchField.TCP_SRC, this.tp_src);
+                                	}
                                 } else {
-                                	adp.drop.setExact(MatchField.UDP_SRC, this.tp_src);   
+                                	if (!TransportPort.NONE.equals(this.tp_src)) {
+                                		adp.drop.setExact(MatchField.UDP_SRC, this.tp_src);   
+                                	}
                                 }
                             } else {
                                 //wildcards.allow &= ~OFMatch.OFPFW_TP_SRC;
                                 if (pkt_tcp != null) {
-                                	adp.allow.setExact(MatchField.TCP_SRC, this.tp_src);
+                                	if (!TransportPort.NONE.equals(this.tp_src)) {
+                                		adp.allow.setExact(MatchField.TCP_SRC, this.tp_src);
+                                	}
                                 } else {
-                                	adp.allow.setExact(MatchField.UDP_SRC, this.tp_src);   
+                                	if (!TransportPort.NONE.equals(this.tp_src)) {
+                                		adp.allow.setExact(MatchField.UDP_SRC, this.tp_src);   
+                                	}
                                 }
                             }
 
@@ -438,16 +478,24 @@ public class FirewallRule implements Comparable<FirewallRule> {
                             if (action == FirewallRule.FirewallAction.DROP) {
                                 //wildcards.drop &= ~OFMatch.OFPFW_TP_DST;
                                 if (pkt_tcp != null) {
-                                	adp.drop.setExact(MatchField.TCP_DST, this.tp_dst);
+                                	if (!TransportPort.NONE.equals(this.tp_dst)) {
+                                		adp.drop.setExact(MatchField.TCP_DST, this.tp_dst);
+                                	}
                                 } else {
-                                	adp.drop.setExact(MatchField.UDP_DST, this.tp_dst);   
+                                	if (!TransportPort.NONE.equals(this.tp_dst)) {
+                                		adp.drop.setExact(MatchField.UDP_DST, this.tp_dst);   
+                                	}
                                 }
                             } else {
                                 //wildcards.allow &= ~OFMatch.OFPFW_TP_DST;
                             	if (pkt_tcp != null) {
-                            		adp.allow.setExact(MatchField.TCP_DST, this.tp_dst);
+                                	if (!TransportPort.NONE.equals(this.tp_dst)) {
+                                		adp.allow.setExact(MatchField.TCP_DST, this.tp_dst);
+                                	}
                                 } else {
-                                	adp.allow.setExact(MatchField.UDP_DST, this.tp_dst);   
+                                	if (!TransportPort.NONE.equals(this.tp_dst)) {
+                                		adp.allow.setExact(MatchField.UDP_DST, this.tp_dst);   
+                                	}
                                 }
                             }
                         }
@@ -461,10 +509,14 @@ public class FirewallRule implements Comparable<FirewallRule> {
         }
         if (action == FirewallRule.FirewallAction.DROP) {
             //wildcards.drop &= ~OFMatch.OFPFW_DL_TYPE;
-        	adp.drop.setExact(MatchField.ETH_TYPE, this.dl_type);
+        	if (!EthType.NONE.equals(this.dl_type)) {
+        		adp.drop.setExact(MatchField.ETH_TYPE, this.dl_type);
+        	}
         } else {
             //wildcards.allow &= ~OFMatch.OFPFW_DL_TYPE;
-        	adp.allow.setExact(MatchField.ETH_TYPE, this.dl_type);
+        	if (!EthType.NONE.equals(this.dl_type)) {
+        		adp.allow.setExact(MatchField.ETH_TYPE, this.dl_type);
+        	}
         }
 
         // all applicable checks passed
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 b78286cb5786bdfe789940612061b096e130127b..35e68d9da1a7cea34969cfbf1e47a01cdf015a50 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
@@ -22,4 +22,5 @@ net.floodlightcontroller.topology.TopologyManager
 net.floodlightcontroller.forwarding.Forwarding
 net.floodlightcontroller.loadbalancer.LoadBalancer
 net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager
-net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl
\ No newline at end of file
+net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl
+net.floodlightcontroller.firewall.Firewall
\ No newline at end of file
diff --git a/src/main/resources/floodlightdefault.properties b/src/main/resources/floodlightdefault.properties
index 108f661d8f847afa785584b1e30ec821df7d5351..9dc689f7c13e5747767911972295aa0c94604088 100644
--- a/src/main/resources/floodlightdefault.properties
+++ b/src/main/resources/floodlightdefault.properties
@@ -13,6 +13,7 @@ net.floodlightcontroller.forwarding.Forwarding,\
 net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager,\
 net.floodlightcontroller.ui.web.StaticWebRoutable,\
 net.floodlightcontroller.loadbalancer.LoadBalancer,\
+net.floodlightcontroller.firewall.Firewall,\
 net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl
 org.sdnplatform.sync.internal.SyncManager.authScheme=CHALLENGE_RESPONSE
 org.sdnplatform.sync.internal.SyncManager.keyStorePath=/etc/floodlight/auth_credentials.jceks
diff --git a/src/main/resources/logback-test.xml b/src/main/resources/logback-test.xml
index 7255c24f726da5ee346747672ce4df92648e8909..c78003320228840936488f4a459e35369629a41e 100644
--- a/src/main/resources/logback-test.xml
+++ b/src/main/resources/logback-test.xml
@@ -19,4 +19,5 @@
   <logger name="net.floodlightcontroller.forwarding" level="INFO"></logger>
   <logger name="net.floodlightcontroller.routing" level="INFO"></logger>
   <logger name="net.floodlightcontroller.core" level="INFO"></logger>
+  <logger level="DEBUG" name="net.floodlightcontroller.firewall"></logger>
 </configuration>